MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2004 Sandia Corporation and Argonne National 00005 Laboratory. Under the terms of Contract DE-AC04-94AL85000 00006 with Sandia Corporation, the U.S. Government retains certain 00007 rights in this software. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 (lgpl.txt) along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 diachin2@llnl.gov, djmelan@sandia.gov, mbrewer@sandia.gov, 00024 pknupp@sandia.gov, tleurent@mcs.anl.gov, tmunson@mcs.anl.gov 00025 00026 ***************************************************************** */ 00027 // -*- Mode : c++; tab-width: 3; c-tab-always-indent: t; indent-tabs-mode: nil; c-basic-offset: 3 00028 // -*- 00029 00030 /*! \file TerminationCriterion.hpp 00031 00032 Header file for the TerminationCriterion classes. 00033 00034 \author Michael Brewer 00035 \author Thomas Leurent 00036 \date Feb. 14, 2003 00037 */ 00038 00039 #ifndef TerminationCriterion_hpp 00040 #define TerminationCriterion_hpp 00041 00042 #include "Mesquite.hpp" 00043 #include "MsqTimer.hpp" 00044 #include "Vector3D.hpp" 00045 00046 #include <string> 00047 #include <vector> 00048 #include <fstream> 00049 00050 namespace MBMesquite 00051 { 00052 class MsqError; 00053 class OFEvaluator; 00054 class PatchData; 00055 class PatchDataVerticesMemento; 00056 class Mesh; 00057 class MeshDomain; 00058 class MeshDomainAssoc; 00059 class Settings; 00060 class VertexMover; 00061 00062 /*! \class TerminationCriterion 00063 00064 \brief The TerminationCriterion class contains functionality to 00065 terminate the VertexMover's optimization. 00066 00067 The Termination Criterion class has three roles. It 00068 is used to terminate the optimization on a single patch; it 00069 is used to terminate the iterations over all patches in the 00070 mesh; and it is used to cull vertices from the optimization 00071 processes. Thus, for each optimization, two TerminationCriterion 00072 objects are used. The class contains five important member 00073 functions used in the VertexMover: initialize(), reset(), 00074 terminate(), cull_vertices(), and cleanup(). These functions 00075 are each explained in detail below. In general, the only one 00076 of these functions called directly from a concrete VertexMover 00077 is terminate() which allows the concrete VertexMover to determine 00078 when to stop producing new iterates on a given patch. All other 00079 functionality is handled from the base VertexMover base class. 00080 00081 There are several different types of termination criteria 00082 available. Multiple criteria types can be set on a given 00083 Termination Criterion object, and when this occurs, the 00084 optimization process will terminate whenever any of the 00085 criteria have been satisfied. 00086 00087 The following is a brief description of how TerminationCriterion 00088 is used within Mesquite. Functions called during QualityImprovement 00089 can be divided into three groups: 00090 reset_* - Initialize data for an iteration 00091 accumulate_* - Update TC for changed data during iteration 00092 terminate - Check if the termination criterion has been met. 00093 There are three different forms of the reset_* and accumulate_* 00094 functions which are called on the inner, outer, or both 00095 TerminationCriterion classes: 00096 *_outer - Called on outer termination criterion. 00097 *_inner - Called on inner termination criterion. 00098 *_patch - Called on outer termination criterion for 00099 each patch and on inner termination criterion 00100 for each inner iteration. 00101 00102 If implementing a new TerminationCriterion, the following rules 00103 should be followed. If the value must be calculated on a global 00104 patch for the outer TC, then: 00105 o The functionality should be added to *_inner (yes, INNER) 00106 o The *_outer methods should be updated to call the *_inner 00107 with a global patch when your TC is requested. 00108 o The internal data for any such TC should be initialized 00109 in the reset_inner method. 00110 If the value for the outer criterion can be calculated from each 00111 local patch when iterating over the mesh with local patches, then: 00112 o The functionality should be added to *_patch 00113 o Any state values pertaining to the entire iteration must be 00114 initialized in reset_inner(..) and cleared in terminate() 00115 o Any patch-specific data should be initialized in reset_patch 00116 o Care should be taken that terminate() does not check 00117 uninitialized data if called before the first call to 00118 accumulate_patch() 00119 00120 */ 00121 class TerminationCriterion 00122 { 00123 public: 00124 //! checks the gradient \f$\nabla f \f$ of objective function 00125 //! \f$f : I\!\!R^{3N} \rightarrow I\!\!R \f$ against a double \f$d\f$ 00126 //! and stops when \f$\sqrt{\sum_{i=1}^{3N}\nabla f_i^2}<d\f$ 00127 MESQUITE_EXPORT void add_absolute_gradient_L2_norm( double value ); 00128 00129 //! checks the gradient \f$\nabla f \f$ of objective function 00130 //! \f$f : I\!\!R^{3N} \rightarrow I\!\!R \f$ against a double \f$d\f$ 00131 //! and stops when \f$ \max_{i=1}^{3N} \nabla f_i < d \f$ 00132 MESQUITE_EXPORT void add_absolute_gradient_inf_norm( double value ); 00133 00134 //! terminates on the j_th iteration when 00135 //! \f$\sqrt{\sum_{i=1}^{3N}\nabla f_{i,j}^2}<d\sqrt{\sum_{i=1}^{3N}\nabla f_{i,0}^2}\f$ 00136 //! That is, terminates when the norm of the gradient is smaller 00137 //! than the specified fraction of the initial norm of the gradient. 00138 MESQUITE_EXPORT void add_relative_gradient_L2_norm( double value ); 00139 00140 //! terminates on the j_th iteration when 00141 //! \f$\max_{i=1 \cdots 3N}\nabla f_{i,j}<d \max_{i=1 \cdots 3N}\nabla f_{i,0}\f$ 00142 //! That is, terminates when the norm of the gradient is small 00143 //! than some scaling factor times the norm of the original gradient. 00144 //! (Using the infinity norm.) 00145 MESQUITE_EXPORT void add_relative_gradient_inf_norm( double value ); 00146 00147 //! Terminates when the objective function value is smaller than 00148 //! the given scalar value. 00149 MESQUITE_EXPORT void add_absolute_quality_improvement( double value ); 00150 00151 //! Terminates when the objective function value is smaller than 00152 //! the given scalar value times the original objective function 00153 //! value. 00154 MESQUITE_EXPORT void add_relative_quality_improvement( double value ); 00155 00156 //! Terminates when a the maximum distance moved by any vertex 00157 //! during the previous iteration is below the given value. 00158 MESQUITE_EXPORT void add_absolute_vertex_movement( double value ); 00159 00160 //! Terminates when a the maximum distance moved by any vertex 00161 //! during the previous iteration is below the given value 00162 //! times the maximum distance moved by any vertex over the 00163 //! entire course of the optimization. 00164 MESQUITE_EXPORT void add_relative_vertex_movement( double value ); 00165 00166 //! Calculates a constant \f$ \delta = \beta \times (a - \sigma) \f$ 00167 //! and terminates when the maximum vertex movement of an iteration 00168 //! is less than delta. 00169 //! 00170 //! \f$ \beta \f$ is the passed value, \f$ a \f$ 00171 //! is the average edge length of the initial mesh and \f$ \sigma \f$ 00172 //! is the standard deviation of the edge lengths of the initial 00173 //! mesh. The initial mesh values are (re)calcualted for each 00174 //! time the instruction queue is run. 00175 //! 00176 //!\param value \f$ beta \f$. Must be in range (0,1), exclusive. 00177 MESQUITE_EXPORT void add_absolute_vertex_movement_edge_length( double value ); 00178 00179 //! Terminates when the decrease in the objective function value since 00180 //! the previous iteration is below the given value. 00181 MESQUITE_EXPORT void add_absolute_successive_improvement( double value ); 00182 00183 //! Terminates when the decrease in the objective function value since 00184 //! the previous iteration is below the given value times the 00185 //! decrease in the objective function value since the beginning 00186 //! of this optimization process. 00187 MESQUITE_EXPORT void add_relative_successive_improvement( double value ); 00188 00189 //! Terminates when the algorithm exceeds an allotted time limit 00190 //! (given in seconds). 00191 MESQUITE_EXPORT void add_cpu_time( double seconds ); 00192 00193 //! Terminates when the number of iterations exceeds a given integer. 00194 MESQUITE_EXPORT void add_iteration_limit( unsigned int max_iterations ); 00195 00196 //! Terminates when any vertex leaves the bounding box, defined 00197 //! by the given value, d. That is, when the absolute value of 00198 //! a single coordinate of vertex's position exceeds d. 00199 MESQUITE_EXPORT void add_bounded_vertex_movement( double value ); 00200 00201 //! Terminates when the mesh is detected to be untangled. 00202 //! Uses the same approach as QualityAssessor, 00203 //! checks the tau values at all the sample points. 00204 MESQUITE_EXPORT void add_untangled_mesh(); 00205 00206 MESQUITE_EXPORT void remove_all_criteria(); 00207 00208 //! Cull when the objective function value is smaller than 00209 //! the given scalar value. 00210 MESQUITE_EXPORT void cull_on_absolute_quality_improvement( double limit ); 00211 //! Cull when the objective function value is smaller than 00212 //! the given scalar value times the original objective function 00213 //! value. 00214 MESQUITE_EXPORT void cull_on_relative_quality_improvement( double limit ); 00215 //! Cull when a the maximum distance moved by any vertex 00216 //! during the previous iteration is below the given value. 00217 MESQUITE_EXPORT void cull_on_absolute_vertex_movement( double limit ); 00218 //! Cull when a the maximum distance moved by any vertex 00219 //! during the previous iteration is below the given value 00220 //! times the maximum distance moved by any vertex over the 00221 //! entire course of the optimization. 00222 MESQUITE_EXPORT void cull_on_relative_vertex_movement( double limit ); 00223 //! Cull when the decrease in the objective function value since 00224 //! the previous iteration is below the given value. 00225 MESQUITE_EXPORT void cull_on_absolute_successive_improvement( double limit ); 00226 //! Calculates a constant \f$ \delta = \beta \times (a - \sigma) \f$ 00227 //! and culls when the vertex movement is less than delta. 00228 //! 00229 //! \f$ \beta \f$ is the passed value, \f$ a \f$ 00230 //! is the average edge length of the initial mesh and \f$ \sigma \f$ 00231 //! is the standard deviation of the edge lengths of the initial 00232 //! mesh. The initial mesh values are (re)calcualted for each 00233 //! time the instruction queue is run. 00234 //! 00235 //!\param value \f$ beta \f$. Must be in range (0,1), exclusive. 00236 MESQUITE_EXPORT void cull_on_absolute_vertex_movement_edge_length( double value ); 00237 //! Cull when the decrease in the objective function value since 00238 //! the previous iteration is below the given value times the 00239 //! decrease in the objective function value since the beginning 00240 //! of this optimization process. 00241 MESQUITE_EXPORT void cull_on_relative_successive_improvement( double limit ); 00242 00243 //! Cull for a global patch - sets soft fixed flags for vertices 00244 //! that touch elements that are culled by above flags. 00245 MESQUITE_EXPORT void cull_for_global_patch( bool val = true ); 00246 00247 //! Cull when the mesh is detected to be untangled. 00248 //! Uses the same approach as QualityAssessor, 00249 //! checks the tau values at all the sample points. 00250 MESQUITE_EXPORT void cull_untangled_mesh(); 00251 00252 MESQUITE_EXPORT void remove_culling(); 00253 00254 enum InnerOuterType 00255 { 00256 TYPE_UNKNOWN, 00257 TYPE_INNER, 00258 TYPE_OUTER 00259 }; 00260 00261 //! Constructor which does not take any arguements 00262 MESQUITE_EXPORT TerminationCriterion( std::string name = "", InnerOuterType innerOuterType = TYPE_UNKNOWN ); 00263 00264 //! Destructor 00265 MESQUITE_EXPORT ~TerminationCriterion(){}; 00266 00267 //! This function returns the current function value. 00268 /*! \todo Michael: this function is not reliable. It 00269 needs to be more robust. How do we know whether 00270 currentOFValue got updated or not? We may want to 00271 make sure that all the criteria get checked.*/ 00272 MESQUITE_EXPORT double get_current_function_value() 00273 { 00274 return currentOFValue; 00275 } 00276 00277 MESQUITE_EXPORT void set_debug_output_level( int i ) 00278 { 00279 debugLevel = i; 00280 } 00281 00282 enum TimeStepFileType 00283 { 00284 NOTYPE = 0, 00285 VTK, 00286 GNUPLOT 00287 }; 00288 00289 /**\brief Write mesh improvement animation 00290 * 00291 * Write mesh at each iteration such that the sequence of mesh files can be used 00292 * to produce an animation of the mesh through the quality improvement process. 00293 * 00294 * Files can be written either as VTK timesteps for viewing in a tool such as Paraview 00295 * or as GNU plot data files and a GNU plot script which, in combination with recent 00296 * versions of GNU plot, can be used to produce an animated GIF image. 00297 * 00298 * Writing of mesh steps can be disabled by calling this function with type == NOTYPE 00299 * and filename ==NULL. 00300 */ 00301 MESQUITE_EXPORT void write_mesh_steps( const char* filename, TimeStepFileType type = VTK ) 00302 { 00303 timeStepFileName = filename; 00304 timeStepFileType = type; 00305 } 00306 00307 /*\brief Write data for generating plots of optimization process. 00308 * 00309 * Write data files in a format suitable for use with GNU plot and other applications. 00310 * The file will contain data corresponding to all termination criteria, 00311 * however, some values may be invalid if they are not calculated for 00312 * use in a termination criterion. 00313 */ 00314 MESQUITE_EXPORT void write_iterations( const char* filename, MsqError& err ); 00315 00316 MESQUITE_EXPORT int get_iteration_count() const 00317 { 00318 return iterationCounter; 00319 } 00320 00321 //! Clear any data accumulated during an outer iteration 00322 void reset_outer( Mesh* ms, MeshDomain* dm, OFEvaluator& of, const Settings* settings, MsqError& err ); 00323 00324 //! Clear any data accumulated during an inner iteration 00325 void reset_inner( PatchData& pd, OFEvaluator& of, MsqError& err ); 00326 00327 //! Shared inner and outer initialization during inner loop 00328 void reset_patch( PatchData& pd, MsqError& err ); 00329 00330 //! Accumulate data during inner iteration 00331 void accumulate_inner( PatchData& pd, OFEvaluator& eval, MsqError& err ); 00332 00333 //! Accumulate data during inner iteration 00334 void accumulate_inner( PatchData& pd, double of_value, Vector3D* of_grads, MsqError& err ); 00335 00336 //! Common code for both inner and outer termination 00337 //! criteria during inner iteration. 00338 void accumulate_patch( PatchData& pd, MsqError& err ); 00339 00340 void accumulate_outer( Mesh* ms, MeshDomain* dm, OFEvaluator& eval, const Settings* settings, MsqError& err ); 00341 00342 //! Check if termination criterion has been met 00343 MESQUITE_EXPORT bool terminate(); 00344 00345 //! Check if at least one termination criterion is set 00346 MESQUITE_EXPORT bool criterion_is_set(); 00347 00348 //! Function which determines whether this patch should be 'culled' 00349 bool cull_vertices( PatchData& pd, OFEvaluator& obj_ptr, MsqError& err ); 00350 00351 //! experimental, first cut at culling for global patches - not finished 00352 bool cull_vertices_global( PatchData& global_patch, 00353 Mesh* mesh, 00354 MeshDomain* domain, 00355 const Settings* settings, 00356 OFEvaluator& of_eval, 00357 MsqError& err ); 00358 00359 //! Cleans up after the TerminationCriterion is finished. 00360 void cleanup( Mesh* ms, MeshDomain* domain, MsqError& err ); 00361 00362 void initialize_queue( MeshDomainAssoc* mesh_and_domain, const Settings* settings, MsqError& err ); 00363 00364 friend class VertexMover; 00365 00366 protected: 00367 void write_timestep( PatchData& pd, const Vector3D* gradient, MsqError& err ); 00368 00369 static size_t count_inverted( PatchData& pd, MsqError& err ); 00370 00371 std::string par_string(); // for debug print of parallel rank 00372 00373 private: 00374 // PRIVATE DATA MEMBERS 00375 long unsigned int terminationCriterionFlag; //!< Bit flag of termination crit 00376 long unsigned int cullingMethodFlag; /*!<Bit flag of criterion for culling*/ 00377 // epsiloon used in culling methods. 00378 double cullingEps; 00379 00380 bool cullingGlobalPatch; /*!<enable culling of pieces of a global patch*/ 00381 00382 // Data not specific to a single criterion 00383 double initialOFValue; 00384 double previousOFValue; 00385 double currentOFValue; 00386 double lowerOFBound; 00387 00388 // Data specific to termination criterion 1 (gradient bounds) 00389 std::vector< Vector3D > mGrad; 00390 double initialGradL2NormSquared; 00391 double currentGradL2NormSquared; 00392 double gradL2NormAbsoluteEpsSquared; 00393 double gradL2NormRelativeEpsSquared; 00394 double initialGradInfNorm; 00395 double currentGradInfNorm; 00396 double gradInfNormAbsoluteEps; 00397 double gradInfNormRelativeEps; 00398 // Data specific to termination criterion 2 (KKT) 00399 //??????????????????????????????????????????? 00400 // Data specific to termination criterion 3 (Quality Improvement) 00401 double qualityImprovementAbsoluteEps; 00402 double qualityImprovementRelativeEps; 00403 // Data specific to termination criterion 4 (inner iterations) 00404 int iterationBound; 00405 int iterationCounter; 00406 // Data specific to termination criterion 5 (cpu time) 00407 Timer mTimer; 00408 double timeBound; 00409 // Data specific to termination criterion 6 (vertex movement) 00410 PatchDataVerticesMemento* initialVerticesMemento; 00411 PatchDataVerticesMemento* previousVerticesMemento; // if we want relative 00412 double vertexMovementAbsoluteEps; 00413 double vertexMovementRelativeEps; 00414 double vertexMovementAvgBeta; //!< input beta value used to calculate \c vertexMovementAbsoluteAvg 00415 double vertexMovementAbsoluteAvgEdge; //!< calculated constant for \c 00416 //!< VERTEX_MOVEMENT_ABS_EDGE_LENGTH 00417 double maxSquaredInitialMovement; 00418 double maxSquaredMovement; 00419 00420 // Data specific to termination criterion 7 (successive improvement to F) 00421 double successiveImprovementsAbsoluteEps; 00422 double successiveImprovementsRelativeEps; 00423 // crit 8 00424 double boundedVertexMovementEps; 00425 int vertexMovementExceedsBound; 00426 00427 // Data for untangled criterion 00428 size_t globalInvertedCount; //!< number of inverted elements in entire mesh 00429 size_t patchInvertedCount; //!< number of inverted elements in previously tested patch 00430 00431 int debugLevel; 00432 00433 //! Plot data 00434 std::ofstream plotFile; 00435 00436 //! Base name for timestep files 00437 std::string timeStepFileName; 00438 TimeStepFileType timeStepFileType; 00439 std::string moniker; 00440 InnerOuterType innerOuterType; 00441 }; 00442 00443 } // namespace MBMesquite 00444 00445 #endif // TerminationCriterion_hpp