MOAB: Mesh Oriented datABase
(version 5.3.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) kraftche@cae.wisc.edu 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, ParallelMesh* pmesh, Settings* settings, 00107 QualityAssessor* qa, MsqError& err ) 00108 { 00109 Instruction::initialize_vertex_byte( mesh_and_domain, settings, err );MSQ_ERRRTN( err ); 00110 00111 Mesh* mesh = mesh_and_domain->get_mesh(); 00112 00113 // get some global mesh properties 00114 SimpleStats edge_len, lambda; 00115 std::unique_ptr< MeshUtil > tool( new MeshUtil( mesh, settings ) ); 00116 tool->edge_length_distribution( edge_len, err );MSQ_ERRRTN( err ); 00117 tool->lambda_distribution( lambda, err );MSQ_ERRRTN( err ); 00118 tool.reset( 0 ); 00119 00120 // get target metrics from user perferences 00121 TSizeNB1 mu_size; 00122 TShapeSize2DNB1 mu_shape_2d; 00123 TShapeSize3DNB1 mu_shape_3d; 00124 TMixed mu_shape( &mu_shape_2d, &mu_shape_3d ); 00125 std::unique_ptr< TMetric > mu; 00126 if( qualityMetric == BETA ) 00127 { 00128 double beta = metricConstant; 00129 if( beta < 0 ) beta = ( lambda.average() * lambda.average() ) / 20; 00130 // std::cout << "beta= " << beta << std::endl; 00131 mu.reset( new TUntangleBeta( beta ) ); 00132 } 00133 else 00134 { 00135 TMetric* sub = 0; 00136 if( qualityMetric == SIZE ) 00137 sub = &mu_size; 00138 else 00139 sub = &mu_shape; 00140 if( metricConstant >= 0 ) 00141 mu.reset( new TUntangleMu( sub, metricConstant ) ); 00142 else 00143 mu.reset( new TUntangleMu( sub ) ); 00144 } 00145 00146 // define objective function 00147 IdealShapeTarget base_target; 00148 LambdaConstant target( lambda.average(), &base_target ); 00149 TQualityMetric metric_0( &target, mu.get() ); 00150 ElementPMeanP metric( 1.0, &metric_0 ); 00151 PMeanPTemplate objfunc( 1.0, &metric ); 00152 00153 // define termination criterion 00154 double eps = movementFactor * ( edge_len.average() - edge_len.standard_deviation() ); 00155 TerminationCriterion inner( "<type:untangle_inner>", TerminationCriterion::TYPE_INNER ), 00156 outer( "<type:untangle_outer>", TerminationCriterion::TYPE_OUTER ); 00157 outer.add_untangled_mesh(); 00158 if( doCulling ) 00159 inner.cull_on_absolute_vertex_movement( eps ); 00160 else 00161 outer.add_absolute_vertex_movement( eps ); 00162 if( maxTime > 0.0 ) outer.add_cpu_time( maxTime ); 00163 inner.add_iteration_limit( NUM_INNER_ITERATIONS ); 00164 if( maxIterations > 0 ) outer.add_iteration_limit( maxIterations ); 00165 00166 // construct solver 00167 SteepestDescent solver( &objfunc ); 00168 solver.use_element_on_vertex_patch(); 00169 solver.set_inner_termination_criterion( &inner ); 00170 solver.set_outer_termination_criterion( &outer ); 00171 if( doJacobi ) 00172 solver.do_jacobi_optimization(); 00173 else 00174 solver.do_gauss_optimization(); 00175 00176 // Run 00177 qa->add_quality_assessment( &metric ); 00178 InstructionQueue q; 00179 q.add_quality_assessor( qa, err );MSQ_ERRRTN( err ); 00180 q.set_master_quality_improver( &solver, err );MSQ_ERRRTN( err ); 00181 q.add_quality_assessor( qa, err );MSQ_ERRRTN( err ); 00182 q.run_common( mesh_and_domain, pmesh, settings, err );MSQ_ERRRTN( err ); 00183 } 00184 00185 } // namespace MBMesquite