MOAB: Mesh Oriented datABase  (version 5.2.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) 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::auto_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::auto_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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines