Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
inks/InstructionQueue.cpp
Go to the documentation of this file.
1 /* *****************************************************************
2  MESQUITE -- The Mesh Quality Improvement Toolkit
3 
4  Copyright 2004 Sandia Corporation and Argonne National
5  Laboratory. Under the terms of Contract DE-AC04-94AL85000
6  with Sandia Corporation, the U.S. Government retains certain
7  rights in this software.
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Lesser General Public
11  License as published by the Free Software Foundation; either
12  version 2.1 of the License, or (at your option) any later version.
13 
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  (lgpl.txt) along with this library; if not, write to the Free Software
21  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 
23  diachin2@llnl.gov, djmelan@sandia.gov, mbrewer@sandia.gov,
24  pknupp@sandia.gov, tleurent@mcs.anl.gov, tmunson@mcs.anl.gov
25 
26  ***************************************************************** */
27 // -*- Mode : c++; tab-width: 3; c-tab-always-indent: t; indent-tabs-mode: nil; c-basic-offset: 3 -*-
28 
37 #ifdef MSQ_USE_OLD_STD_HEADERS
38 # include <string.h>
39 # include <list.h>
40 #else
41 # include <string>
42 # include <list>
43  using namespace std;
44 #endif
45 
46 #include "InstructionQueue.hpp"
47 #include "MeshSet.hpp"
48 #include "MsqInterrupt.hpp"
49 #include "QualityImprover.hpp"
50 #include "QualityAssessor.hpp"
51 #include "MsqError.hpp"
52 #include "MsqDebug.hpp"
53 #include "MeanMidNodeMover.hpp"
54 #include "MsqFPE.hpp"
55 #include "TargetCalculator.hpp"
56 
57 using namespace Mesquite;
58 
59 #ifdef MSQ_TRAP_FPE
60 const bool IQ_TRAP_FPE_DEFAULT = true;
61 #else
62 const bool IQ_TRAP_FPE_DEFAULT = false;
63 #endif
64 
65 
66 InstructionQueue::InstructionQueue() :
67  autoQualAssess(true),
68  autoAdjMidNodes(true),
69  nbPreConditionners(0),
70  isMasterSet(false),
71  masterInstrIndex(0),
72  globalPatch(0),
73  trapFPE(IQ_TRAP_FPE_DEFAULT)
74 {
75 }
76 
77 
78 void InstructionQueue::add_target_calculator( TargetCalculator* tc, MsqError& )
79 {
80  instructions.push_back( tc );
81 }
82 
92  MsqError &err)
93 {
94  if (isMasterSet) {
95  MSQ_SETERR(err)("Cannot add preconditionners once the master "
96  "QualityImprover has been set.", MsqError::INVALID_STATE);
97  return;
98  }
99 
100  instructions.push_back(instr);
102 }
103 
104 
111 void InstructionQueue::remove_preconditioner(size_t index, MsqError &err)
112 {
113  // checks index is valid
114  if ( isMasterSet && index == masterInstrIndex ) {
115  MSQ_SETERR(err)("cannot remove master QualityImprover.", MsqError::INVALID_ARG);
116  return;
117  } else if (index >= instructions.size() ) {
118  MSQ_SETERR(err)("Index points beyond end of list.",MsqError::INVALID_ARG);
119  return;
120  }
121 
122  // position the instruction iterator over the preconditionner to delete
123  msq_std::list<PatchDataUser*>::iterator pos;
124  pos = instructions.begin();
125  advance(pos, index);
126 
127  if ( (*pos)->get_algorithm_type() != PatchDataUser::QUALITY_IMPROVER )
128  {
129  MSQ_SETERR(err)("Index does not point to a QualityImprover.",
131  return;
132  }
133 
134  string name = (*pos)->get_name();
135  instructions.erase(pos);
137 }
138 
139 
149  size_t index, MsqError &err)
150 {
151  // checks index is valid
152  if (isMasterSet==true && index > masterInstrIndex) {
153  MSQ_SETERR(err)("Cannot add a preconditionner after the master "
154  "QualityImprover.", MsqError::INVALID_STATE);
155  return;
156  }
157  if (index >= instructions.size() ) {
158  MSQ_SETERR(err)("index", MsqError::INVALID_ARG);
159  return;
160  }
161 
162  // position the instruction iterator
163  list<PatchDataUser*>::iterator pos;
164  pos = instructions.begin();
165  advance(pos, index);
166  // adds the preconditioner
167  instructions.insert(pos,instr);
169 }
170 
171 
178  MsqError &/*err*/)
179 {
180  instructions.push_back(instr);
181 }
182 
183 
191 {
192  // checks index is valid
193  if (index >= instructions.size() ) {
194  MSQ_SETERR(err)("index", MsqError::INVALID_ARG);
195  return;
196  }
197 
198  // position the instruction iterator over the QualityAssessor to delete
199  list<PatchDataUser*>::iterator pos;
200  pos = instructions.begin();
201  advance(pos, index);
202 
203  if ( (*pos)->get_algorithm_type() != PatchDataUser::QUALITY_ASSESSOR )
204  {
205  MSQ_SETERR(err)("Index does not point to a QualityImprover.",
207  return;
208  }
209 
210  string name = (*pos)->get_name();
211  instructions.erase(pos);
212 }
213 
214 
223  size_t index, MsqError &err)
224 {
225  // checks index is valid
226  if (index > instructions.size()) {
227  MSQ_SETERR(err)("index points two positions beyond end of list.",
229  return;
230  }
231 
232  // position the instruction iterator
233  list<PatchDataUser*>::iterator pos;
234  pos = instructions.begin();
235  advance(pos, index);
236  // adds the QualityAssessor
237  instructions.insert(pos,instr);
238 }
239 
240 
242  MsqError &err)
243 {
244  if (isMasterSet) {
245  MSQ_DBGOUT(1) << "InstructionQueue::set_master_quality_improver():\n"
246  << "\tOverwriting previously specified master quality improver.\n";
247  // if master is already set, clears it and insert the new one at the same position.
248  list<PatchDataUser*>::iterator master_pos;
249  master_pos = this->clear_master(err); MSQ_ERRRTN(err);
250  instructions.insert(master_pos, instr);
251  isMasterSet = true;
252  } else {
253  // if master is not set, add it at the end of the queue.
254  instructions.push_back(instr);
255  isMasterSet = true;
256  masterInstrIndex = instructions.size()-1;
257  }
258 }
259 
261 {
262  MSQ_DBGOUT(1) << version_string(false) << "\n";
263 
264  if (nbPreConditionners != 0 && isMasterSet == false ) {
265  MSQ_SETERR(err)("no pre-conditionners allowed if master QualityImprover "
266  "is not set.", MsqError::INVALID_STATE);
267  return;
268  }
269 
270 #ifdef ENABLE_INTERRUPT
271  // Register SIGINT handler
272  MsqInterrupt msq_interrupt;
273 #endif
274 
275  // Generate SIGFPE on floating point errors
276  MsqFPE( this->trapFPE );
277 
278  msq_std::list<PatchDataUser*>::const_iterator instr_iter;
279 
280  if (autoAdjMidNodes)
281  instructions.push_back( new MeanMidNodeMover );
282 
283  // For each instruction in the list
284  for (instr_iter = instructions.begin();
285  !(instr_iter == instructions.end()); ++instr_iter) {
286 
287  // If instruction uses a global patch, creates one or reuse the existing one.
288  if ((*instr_iter)->get_patch_type() == PatchData::GLOBAL_PATCH) {
289  if (globalPatch == 0) {
290  globalPatch = new PatchData;
291  ms.get_next_patch(*globalPatch, (*instr_iter)->get_all_parameters(), err);
292  MSQ_ERRRTN(err);
293  }
294 
295 
296  (*instr_iter)->set_global_patch(globalPatch, err); MSQ_ERRRTN(err);
297  }
298  // If instruction does not use a Global Patch, make sure we discard any existing patch.
299  else {
300  delete globalPatch;
301  globalPatch = 0;
302  (*instr_iter)->no_global_patch();
303  }
304 
305  // applies the QualityImprover/QualityAssessor to the MeshSet
306  (*instr_iter)->loop_over_mesh(ms, err); MSQ_ERRRTN(err);
307 
308  // If this same instruction is reused in this queue, we can't assume the
309  // global patch will still be valid.
310  (*instr_iter)->no_global_patch();
311  }
312 
313  if (autoAdjMidNodes)
314  {
315  delete *instructions.rbegin();
316  instructions.pop_back( );
317  }
318 
319  if (globalPatch != 0)
320  {
321  delete globalPatch; // clean up once all instructions are executed.
322  globalPatch = 0;
323  }
324 }
325 
326 
328 {
329  instructions.clear();
330  autoQualAssess = true;
331  autoAdjMidNodes = false;
332  isMasterSet = false;
333  masterInstrIndex = 0;
334 }
335 
336 
337 list<PatchDataUser*>::iterator InstructionQueue::clear_master(MsqError &err)
338 {
339  msq_std::list<PatchDataUser*>::iterator instr_iter;
340  msq_std::list<PatchDataUser*>::iterator master_pos;
341 
342  if (!isMasterSet) {
343  MSQ_SETERR(err)("No master quality improver to clear.", MsqError::INVALID_STATE);
344  return instr_iter;
345  }
346 
347  // position the instruction iterator over the master quality improver
348  master_pos = instructions.begin();
349  advance(master_pos, masterInstrIndex);
350 
351  // erases the master quality improver
352  instr_iter = instructions.erase(master_pos);
353  isMasterSet = false;
354 
355  // returns the position where the Master was
356  return instr_iter;
357 }
msq_std::list< PatchDataUser * >::iterator clear_master(MsqError &err)
void remove_quality_assessor(size_t index, MsqError &err)
removes a QualityAssessor* from the instruction queue
Class to adjust positions of higher-order nodes.
Used to hold the error state and return it to the application.
PatchData * globalPatch
Used to prevent reallocating a global patch for successive global algorithms.
void set_master_quality_improver(QualityImprover *instr, MsqError &err)
Base class for all quality improvers. Mote that the PatchData settings are inherited from the PathDat...
const char * version_string(bool include_build_number=false)
void remove_preconditioner(size_t index, MsqError &err)
removes a QualityImprover* from the instruction queue
Utility class used by InstructionQueue SIGFPE option.
msq_std::list< PatchDataUser * > instructions
A QualityAssessor instance can be inserted into an InstructionQueue to calculate and summarize regist...
void add_quality_assessor(QualityAssessor *instr, MsqError &err)
adds a QualityAssessor to the instruction queue.
invalid function argument passed
void add_preconditioner(QualityImprover *instr, MsqError &err)
adds a QualityImprover at the end of the instruction list
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
Base class that provides the interface for computing the target corner matrices used in the context b...
virtual void run_instructions(MeshSet &msc, MsqError &err)
This function is virtual so that it may be redefined in the wraper classes.
object is in an invalid state
const bool IQ_TRAP_FPE_DEFAULT
#define MSQ_DBGOUT(flag)
Check debug flag and return ostream associated with flag.
void insert_quality_assessor(QualityAssessor *instr, size_t index, MsqError &err)
inserts a QualityAssessor* into the instruction queue.
#define MSQ_ERRRTN(err)
If passed error is true, return from a void function.
Class to watch for user-interrupt (SIGINT, ctrl-C)
void insert_preconditioner(QualityImprover *instr, size_t index, MsqError &err)
inserts a QualityImprover* into the instruction queue.
The MeshSet class stores one or more Mesquite::Mesh pointers and manages access to the mesh informati...
bool get_next_patch(PatchData &pd, PatchDataUser *pd_user, MsqError &err)
Gets the next PatchData.