MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2010 Sandia National Laboratories. Developed at the 00005 University of Wisconsin--Madison under SNL contract number 00006 624796. The U.S. Government and the University of Wisconsin 00007 retain certain rights to 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 (2010) [email protected] 00024 00025 ***************************************************************** */ 00026 00027 /** \file UntangleWrapper.cpp 00028 * \brief 00029 * \author Jason Kraftcheck 00030 */ 00031 00032 #include "Mesquite.hpp" 00033 #include "UntangleWrapper.hpp" 00034 #include "MeshUtil.hpp" 00035 #include "SimpleStats.hpp" 00036 #include "MsqError.hpp" 00037 00038 #include "LambdaConstant.hpp" 00039 #include "IdealShapeTarget.hpp" 00040 #include "TQualityMetric.hpp" 00041 #include "PMeanPTemplate.hpp" 00042 #include "TerminationCriterion.hpp" 00043 #include "SteepestDescent.hpp" 00044 #include "ConjugateGradient.hpp" 00045 #include "QualityAssessor.hpp" 00046 #include "InstructionQueue.hpp" 00047 #include "ElementPMeanP.hpp" 00048 #include "Instruction.hpp" 00049 00050 #include "TUntangleBeta.hpp" 00051 #include "TUntangleMu.hpp" 00052 #include "TSizeNB1.hpp" 00053 #include "TShapeSize2DNB1.hpp" 00054 #include "TShapeSize3DNB1.hpp" 00055 #include "TMixed.hpp" 00056 00057 #include <memory> 00058 00059 const int NUM_INNER_ITERATIONS = 1; 00060 const double DEFAULT_MOVEMENT_FACTOR = 0.001; 00061 const bool CULLING_DEFAULT = true; 00062 const bool JACOBI_DEFAULT = false; 00063 00064 namespace MBMesquite 00065 { 00066 00067 UntangleWrapper::UntangleWrapper() 00068 : qualityMetric( SIZE ), maxTime( -1 ), movementFactor( DEFAULT_MOVEMENT_FACTOR ), metricConstant( -1 ), 00069 maxIterations( -1 ), doCulling( CULLING_DEFAULT ), doJacobi( JACOBI_DEFAULT ) 00070 { 00071 } 00072 00073 UntangleWrapper::UntangleWrapper( UntangleMetric m ) 00074 : qualityMetric( m ), maxTime( -1 ), movementFactor( DEFAULT_MOVEMENT_FACTOR ), metricConstant( -1 ), 00075 maxIterations( -1 ), doCulling( CULLING_DEFAULT ), doJacobi( JACOBI_DEFAULT ) 00076 { 00077 } 00078 00079 UntangleWrapper::~UntangleWrapper() {} 00080 00081 void UntangleWrapper::set_untangle_metric( UntangleMetric metric ) 00082 { 00083 qualityMetric = metric; 00084 } 00085 00086 void UntangleWrapper::set_metric_constant( double value ) 00087 { 00088 metricConstant = value; 00089 } 00090 00091 void UntangleWrapper::set_cpu_time_limit( double seconds ) 00092 { 00093 maxTime = seconds; 00094 } 00095 00096 void UntangleWrapper::set_outer_iteration_limit( int maxIt ) 00097 { 00098 maxIterations = maxIt; 00099 } 00100 00101 void UntangleWrapper::set_vertex_movement_limit_factor( double f ) 00102 { 00103 movementFactor = f; 00104 } 00105 00106 void UntangleWrapper::run_wrapper( MeshDomainAssoc* mesh_and_domain, 00107 ParallelMesh* pmesh, 00108 Settings* settings, 00109 QualityAssessor* qa, 00110 MsqError& err ) 00111 { 00112 Instruction::initialize_vertex_byte( mesh_and_domain, settings, err );MSQ_ERRRTN( err ); 00113 00114 Mesh* mesh = mesh_and_domain->get_mesh(); 00115 00116 // get some global mesh properties 00117 SimpleStats edge_len, lambda; 00118 std::unique_ptr< MeshUtil > tool( new MeshUtil( mesh, settings ) ); 00119 tool->edge_length_distribution( edge_len, err );MSQ_ERRRTN( err ); 00120 tool->lambda_distribution( lambda, err );MSQ_ERRRTN( err ); 00121 tool.reset( 0 ); 00122 00123 // get target metrics from user perferences 00124 TSizeNB1 mu_size; 00125 TShapeSize2DNB1 mu_shape_2d; 00126 TShapeSize3DNB1 mu_shape_3d; 00127 TMixed mu_shape( &mu_shape_2d, &mu_shape_3d ); 00128 std::unique_ptr< TMetric > mu; 00129 if( qualityMetric == BETA ) 00130 { 00131 double beta = metricConstant; 00132 if( beta < 0 ) beta = ( lambda.average() * lambda.average() ) / 20; 00133 // std::cout << "beta= " << beta << std::endl; 00134 mu.reset( new TUntangleBeta( beta ) ); 00135 } 00136 else 00137 { 00138 TMetric* sub = 0; 00139 if( qualityMetric == SIZE ) 00140 sub = &mu_size; 00141 else 00142 sub = &mu_shape; 00143 if( metricConstant >= 0 ) 00144 mu.reset( new TUntangleMu( sub, metricConstant ) ); 00145 else 00146 mu.reset( new TUntangleMu( sub ) ); 00147 } 00148 00149 // define objective function 00150 IdealShapeTarget base_target; 00151 LambdaConstant target( lambda.average(), &base_target ); 00152 TQualityMetric metric_0( &target, mu.get() ); 00153 ElementPMeanP metric( 1.0, &metric_0 ); 00154 PMeanPTemplate objfunc( 1.0, &metric ); 00155 00156 // define termination criterion 00157 double eps = movementFactor * ( edge_len.average() - edge_len.standard_deviation() ); 00158 TerminationCriterion inner( "<type:untangle_inner>", TerminationCriterion::TYPE_INNER ), 00159 outer( "<type:untangle_outer>", TerminationCriterion::TYPE_OUTER ); 00160 outer.add_untangled_mesh(); 00161 if( doCulling ) 00162 inner.cull_on_absolute_vertex_movement( eps ); 00163 else 00164 outer.add_absolute_vertex_movement( eps ); 00165 if( maxTime > 0.0 ) outer.add_cpu_time( maxTime ); 00166 inner.add_iteration_limit( NUM_INNER_ITERATIONS ); 00167 if( maxIterations > 0 ) outer.add_iteration_limit( maxIterations ); 00168 00169 // construct solver 00170 SteepestDescent solver( &objfunc ); 00171 solver.use_element_on_vertex_patch(); 00172 solver.set_inner_termination_criterion( &inner ); 00173 solver.set_outer_termination_criterion( &outer ); 00174 if( doJacobi ) 00175 solver.do_jacobi_optimization(); 00176 else 00177 solver.do_gauss_optimization(); 00178 00179 // Run 00180 qa->add_quality_assessment( &metric ); 00181 InstructionQueue q; 00182 q.add_quality_assessor( qa, err );MSQ_ERRRTN( err ); 00183 q.set_master_quality_improver( &solver, err );MSQ_ERRRTN( err ); 00184 q.add_quality_assessor( qa, err );MSQ_ERRRTN( err ); 00185 q.run_common( mesh_and_domain, pmesh, settings, err );MSQ_ERRRTN( err ); 00186 } 00187 00188 } // namespace MBMesquite