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 ShapeImprover.cpp 00028 * \brief 00029 * \author Jason Kraftcheck 00030 * \author Boyd Tidwell 00031 * \date 10-23-12 00032 */ 00033 00034 #include "ShapeImprover.hpp" 00035 #include "MsqTimer.hpp" 00036 #include "MsqDebug.hpp" 00037 #include "PMeanPTemplate.hpp" 00038 #include "ElementPMeanP.hpp" 00039 #include "ConjugateGradient.hpp" 00040 #include "TerminationCriterion.hpp" 00041 #include "InstructionQueue.hpp" 00042 #include "QualityAssessor.hpp" 00043 #include "ElementPatches.hpp" 00044 00045 #include "TShapeB1.hpp" 00046 #include "TShapeNB1.hpp" 00047 #include "TQualityMetric.hpp" 00048 #include "IdealShapeTarget.hpp" 00049 00050 namespace MBMesquite 00051 { 00052 00053 const double DEFAULT_BETA = 0.0; 00054 const int DEFUALT_PARALLEL_ITERATIONS = 10; 00055 00056 ShapeImprover::ShapeImprover() 00057 : maxTime( 300.0 ), mBeta( DEFAULT_BETA ), parallelIterations( DEFUALT_PARALLEL_ITERATIONS ) 00058 { 00059 } 00060 00061 void ShapeImprover::set_vertex_movement_limit_factor( double beta ) 00062 { 00063 assert( beta > 0.0 ); 00064 assert( beta < 1.0 ); 00065 mBeta = beta; 00066 } 00067 00068 void ShapeImprover::set_cpu_time_limit( double limit ) 00069 { 00070 assert( limit >= 0.0 ); 00071 maxTime = limit; 00072 } 00073 00074 void ShapeImprover::set_parallel_iterations( int count ) 00075 { 00076 if( count < 1 ) 00077 { 00078 assert( false ); 00079 count = 1; 00080 } 00081 parallelIterations = count; 00082 } 00083 00084 void ShapeImprover::run_wrapper( MeshDomainAssoc* mesh_and_domain, 00085 ParallelMesh* pmesh, 00086 Settings* settings, 00087 QualityAssessor* qa, 00088 MsqError& err ) 00089 { 00090 // Quality Metrics 00091 IdealShapeTarget target; 00092 Mesh* mesh = mesh_and_domain->get_mesh(); 00093 MeshDomain* domain = mesh_and_domain->get_domain(); 00094 00095 // only calc min edge length if user hasn't set the vertex_movement_limit_factor 00096 if( !mBeta ) 00097 { 00098 // Calculate minimum edge length in mesh 00099 00100 // create a temp global patch to get min edge len from 00101 PatchData patch; 00102 patch.set_mesh( mesh ); 00103 patch.set_domain( domain ); 00104 if( settings ) patch.attach_settings( settings ); 00105 std::vector< Mesh::ElementHandle > patch_elems; 00106 std::vector< Mesh::VertexHandle > patch_verts; 00107 mesh->get_all_elements( patch_elems, err ); 00108 mesh->get_all_vertices( patch_verts, err ); 00109 patch.set_mesh_entities( patch_elems, patch_verts, err ); 00110 00111 // get min edge length from temp global patch 00112 double min_edge_len = 0.0, max_edge_len = 0.0; 00113 patch.get_minmax_edge_length( min_edge_len, max_edge_len ); 00114 mBeta = min_edge_len / 10.0; 00115 } 00116 00117 TerminationCriterion inner_b; 00118 00119 // check for inverted elements 00120 00121 // create QualityAssessor instance without a Quality Metric 00122 QualityAssessor check_inverted( false, false ); 00123 InstructionQueue q_invert_check; 00124 // a QuallityAssessor without a metric will just check for inverted elements and samples 00125 q_invert_check.add_quality_assessor( &check_inverted, err ); 00126 q_invert_check.run_common( mesh_and_domain, pmesh, settings, err );MSQ_ERRRTN( err ); 00127 int inverted_elems = 0, inverted_samples = 0; 00128 check_inverted.get_inverted_element_count( inverted_elems, inverted_samples, err ); 00129 if( inverted_elems || inverted_samples ) 00130 { 00131 // use non barrier shape improvement on tangled mesh 00132 TShapeNB1 mu_no; 00133 TQualityMetric metric_no_0( &target, &mu_no ); 00134 ElementPMeanP metric_no( 1.0, &metric_no_0 ); 00135 00136 // QualityAssessor 00137 qa->add_quality_assessment( &metric_no ); 00138 00139 PMeanPTemplate obj_func_no( 1.0, &metric_no ); 00140 ConjugateGradient improver_no( &obj_func_no ); 00141 improver_no.use_global_patch(); 00142 TerminationCriterion inner_no; 00143 if( maxTime > 0.0 ) inner_no.add_cpu_time( maxTime ); 00144 inner_no.add_absolute_vertex_movement_edge_length( mBeta ); 00145 improver_no.set_inner_termination_criterion( &inner_no ); 00146 InstructionQueue q_no; 00147 q_no.add_quality_assessor( qa, err );MSQ_ERRRTN( err ); 00148 q_no.set_master_quality_improver( &improver_no, err );MSQ_ERRRTN( err ); 00149 q_no.add_quality_assessor( qa, err );MSQ_ERRRTN( err ); 00150 q_no.run_common( mesh_and_domain, pmesh, settings, err );MSQ_ERRRTN( err ); 00151 } 00152 else 00153 { 00154 // use barrer metric on non-tangled mesh 00155 00156 Timer totalTimer; 00157 TShapeB1 mu_b; 00158 TQualityMetric metric_b_0( &target, &mu_b ); 00159 ElementPMeanP metric_b( 1.0, &metric_b_0 ); 00160 qa->add_quality_assessment( &metric_b ); 00161 PMeanPTemplate obj_func_b( 1.0, &metric_b ); 00162 ConjugateGradient improver_b( &obj_func_b ); 00163 improver_b.use_global_patch(); 00164 00165 if( maxTime > 0.0 ) inner_b.add_cpu_time( maxTime ); 00166 inner_b.add_absolute_vertex_movement_edge_length( mBeta ); 00167 00168 improver_b.set_inner_termination_criterion( &inner_b ); 00169 InstructionQueue q_b; 00170 q_b.add_quality_assessor( qa, err );MSQ_ERRRTN( err ); 00171 q_b.set_master_quality_improver( &improver_b, err );MSQ_ERRRTN( err ); 00172 q_b.add_quality_assessor( qa, err );MSQ_ERRRTN( err ); 00173 q_b.run_common( mesh_and_domain, pmesh, settings, err );MSQ_ERRRTN( err ); 00174 } 00175 } 00176 00177 } // namespace MBMesquite