MOAB: Mesh Oriented datABase  (version 5.4.1)
UntangleWrapper.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines