Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
QualityImprover/VertexMover/VertexMover.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  ***************************************************************** */
38 #include "VertexMover.hpp"
39 #include "MeshSet.hpp"
40 #include "MsqTimer.hpp"
41 #include "MsqDebug.hpp"
42 
43 namespace Mesquite {
44 
47 {
48  objFunc=NULL;
49 }
50 
51 
52 /*
53 
54  +-----------+
55  |Reset Outer|
56  |Criterion |
57  +-----------+
58  |
59  V
60  +
61  / \
62  /Outer\ YES
63 +--> <Criterion>-----> DONE
64 | \Done?/
65 | \ /
66 | +
67 | |NO
68 | V
69 | +-----------+
70 1 |Reset Mesh |
71 | | Iteration |
72 | +-----------+
73 | |
74 | V
75 | +
76 | / \
77 | NO /Next\
78 +-----<Patch > <-----+
79  \ / |
80  \ / |
81  + |
82  YES| |
83  V |
84  +-----------+ |
85  |Reset Inner| |
86  |Criterion | 2
87  +-----------+ |
88  | |
89  V |
90  + |
91  / \ |
92  /Inner\ YES |
93 +--> <Criterion>-----+ --------------+
94 | \Done?/ |
95 | \ / |
96 | + |
97 | |NO |
98 | V Inside
99 3 +-----------+ Smoother
100 | | Smooth | |
101 | | Patch | |
102 | +-----------+ |
103 | | |
104 ----------+ --------------+
105 
106 */
107 
108 
109 
119 {
120  set_mesh_set(&ms);
121 
122  // Get the patch data to use for the first iteration
123  bool next_patch = true;
124  PatchData local_patch_data;
125  PatchData* patch_data=0;
126  if (get_global_patch() != 0) {
128  MSQ_SETERR(err)("PatchDataUser::globalPatch should be NULL.", MsqError::INVALID_STATE);
129  return 0;
130  }
131  patch_data = get_global_patch();
132  }
133  else {
134  patch_data = &local_patch_data;
135  }
136 
137  // Get termination criteria
140  if(outer_crit == 0){
141  MSQ_SETERR(err)("Termination Criterion pointer is Null", MsqError::INVALID_STATE);
142  return 0.;
143  }
144  if(inner_crit == 0){
145  MSQ_SETERR(err)("Termination Criterion pointer for inner loop is Null", MsqError::INVALID_STATE);
146  return 0.;
147  }
148 
149  // If using a local patch, suppress output of inner termination criterion
151  inner_crit->set_debug_output_level(3);
152  }
153 
154  // Initialize outer loop
155 
156  this->initialize(*patch_data, err);
157  if (MSQ_CHKERR(err)) goto ERROR;
158 
159  outer_crit->reset_outer(ms, objFunc, err);
160  if (MSQ_CHKERR(err)) goto ERROR;
161 
162  // Loop until outer termination criterion is met
163  while (!outer_crit->terminate())
164  {
165  if (get_global_patch() == 0)
166  {
167  next_patch = ms.get_next_patch( *patch_data, this, err );
168  if (MSQ_CHKERR(err)) goto ERROR;
169  }
170 
171  if (!next_patch) // all vertices culled
172  break;
173 
174  // Loop over each patch
175  do
176  {
177  // Initialize for inner iteration
178 
179  this->initialize_mesh_iteration(*patch_data, err);
180  if (MSQ_CHKERR(err)) goto ERROR;
181 
182  outer_crit->reset_patch( *patch_data, err );
183  if (MSQ_CHKERR(err)) goto ERROR;
184 
185  inner_crit->reset_inner( *patch_data, objFunc, err );
186  if (MSQ_CHKERR(err)) goto ERROR;
187 
188  inner_crit->reset_patch( *patch_data, err );
189  if (MSQ_CHKERR(err)) goto ERROR;
190 
191  // Don't even call optimizer if inner termination
192  // criterion has already been met.
193  if (!inner_crit->terminate())
194  {
195  // Call optimizer - should loop on inner_crit->terminate()
196  this->optimize_vertex_positions( *patch_data, err );
197  if (MSQ_CHKERR(err)) goto ERROR;
198 
199  // Update for changes during inner iteration
200  // (during optimizer loop)
201 
202  outer_crit->accumulate_patch( *patch_data, err );
203  if (MSQ_CHKERR(err)) goto ERROR;
204 
205  inner_crit->cull_vertices( *patch_data, objFunc, err );
206  if (MSQ_CHKERR(err)) goto ERROR;
207 
208  patch_data->update_mesh( err );
209  if (MSQ_CHKERR(err)) goto ERROR;
210  }
211 
212  // If a global patch, then we're done with the inner loop.
213  next_patch = false;
215  {
216  next_patch = ms.get_next_patch( *patch_data, this, err );
217  if (MSQ_CHKERR(err)) goto ERROR;
218  }
219 
220  } while (next_patch);
221 
222  this->terminate_mesh_iteration(*patch_data, err);
223  if (MSQ_CHKERR(err)) goto ERROR;
224 
225  if (get_global_patch() == 0)
226  {
227  ms.reset(err);
228  if (MSQ_CHKERR(err)) goto ERROR;
229  }
230 
231  outer_crit->accumulate_outer( ms, err );
232  if (MSQ_CHKERR(err)) goto ERROR;
233  }
234 
235 
236 ERROR:
237  //call the criteria's cleanup funtions.
238  outer_crit->cleanup(ms,err);
239  inner_crit->cleanup(ms,err);
240  //call the optimization cleanup function.
241  this->cleanup();
242 
243  return 0.;
244 }
245 
246 } // namespace Mesquite
void update_mesh(MsqError &err)
Updates the underlying mesh (the Mesquite::Mesh implementation) with new node coordinates and flag va...
virtual void terminate_mesh_iteration(PatchData &, MsqError &err)=0
void cleanup(MeshSet &ms, MsqError &err)
Cleans up after the TerminationCriterion is finished.
Used to hold the error state and return it to the application.
void accumulate_patch(PatchData &pd, MsqError &err)
Common code for both inner and outer termination criteria during inner iteration. ...
Base class for all quality improvers. Mote that the PatchData settings are inherited from the PathDat...
The TerminationCriterion class contains functionality to terminate the VertexMover&#39;s optimization...
void reset_outer(MeshSet &ms, ObjectiveFunction *of, MsqError &err)
Clear any data accumulated during an outer iteration.
void reset_inner(PatchData &pd, ObjectiveFunction *of, MsqError &err)
Clear any data accumulated during an inner iteration.
bool terminate()
Check if termination criterion has been met.
bool cull_vertices(PatchData &pd, ObjectiveFunction *obj_ptr, MsqError &err)
Function which determines whether this patch should be &#39;culled&#39;.
void reset_patch(PatchData &pd, MsqError &err)
Shared inner and outer initialization during inner loop.
virtual double loop_over_mesh(MeshSet &ms, MsqError &err)
Improves the quality of the MeshSet, calling some methods specified in a class derived from VertexMov...
#define MSQ_CHKERR(err)
Mesquite&#39;s Error Checking macro.
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
PatchData::PatchType get_patch_type()
Returns the Patch Type.
virtual void initialize(PatchData &pd, MsqError &err)=0
TerminationCriterion * get_inner_termination_criterion()
return the inner termination criterion pointer
virtual void cleanup()=0
TerminationCriterion * get_outer_termination_criterion()
return the outer termination criterion pointer
PatchData * get_global_patch()
Returns the Global Patch.
virtual void optimize_vertex_positions(PatchData &pd, MsqError &err)=0
object is in an invalid state
void accumulate_outer(MeshSet &ms, MsqError &err)
The MeshSet class stores one or more Mesquite::Mesh pointers and manages access to the mesh informati...
void reset(MsqError &err)
Resets the MeshSet object so that get_next_patch() will restart its iterations at the first vertex...
bool get_next_patch(PatchData &pd, PatchDataUser *pd_user, MsqError &err)
Gets the next PatchData.
virtual void initialize_mesh_iteration(PatchData &pd, MsqError &err)=0