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 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, ParallelMesh* pmesh, Settings* settings, 00085 QualityAssessor* qa, MsqError& err ) 00086 { 00087 // Quality Metrics 00088 IdealShapeTarget target; 00089 Mesh* mesh = mesh_and_domain->get_mesh(); 00090 MeshDomain* domain = mesh_and_domain->get_domain(); 00091 00092 // only calc min edge length if user hasn't set the vertex_movement_limit_factor 00093 if( !mBeta ) 00094 { 00095 // Calculate minimum edge length in mesh 00096 00097 // create a temp global patch to get min edge len from 00098 PatchData patch; 00099 patch.set_mesh( mesh ); 00100 patch.set_domain( domain ); 00101 if( settings ) patch.attach_settings( settings ); 00102 std::vector< Mesh::ElementHandle > patch_elems; 00103 std::vector< Mesh::VertexHandle > patch_verts; 00104 mesh->get_all_elements( patch_elems, err ); 00105 mesh->get_all_vertices( patch_verts, err ); 00106 patch.set_mesh_entities( patch_elems, patch_verts, err ); 00107 00108 // get min edge length from temp global patch 00109 double min_edge_len = 0.0, max_edge_len = 0.0; 00110 patch.get_minmax_edge_length( min_edge_len, max_edge_len ); 00111 mBeta = min_edge_len / 10.0; 00112 } 00113 00114 TerminationCriterion inner_b; 00115 00116 // check for inverted elements 00117 00118 // create QualityAssessor instance without a Quality Metric 00119 QualityAssessor check_inverted( false, false ); 00120 InstructionQueue q_invert_check; 00121 // a QuallityAssessor without a metric will just check for inverted elements and samples 00122 q_invert_check.add_quality_assessor( &check_inverted, err ); 00123 q_invert_check.run_common( mesh_and_domain, pmesh, settings, err );MSQ_ERRRTN( err ); 00124 int inverted_elems = 0, inverted_samples = 0; 00125 check_inverted.get_inverted_element_count( inverted_elems, inverted_samples, err ); 00126 if( inverted_elems || inverted_samples ) 00127 { 00128 // use non barrier shape improvement on tangled mesh 00129 TShapeNB1 mu_no; 00130 TQualityMetric metric_no_0( &target, &mu_no ); 00131 ElementPMeanP metric_no( 1.0, &metric_no_0 ); 00132 00133 // QualityAssessor 00134 qa->add_quality_assessment( &metric_no ); 00135 00136 PMeanPTemplate obj_func_no( 1.0, &metric_no ); 00137 ConjugateGradient improver_no( &obj_func_no ); 00138 improver_no.use_global_patch(); 00139 TerminationCriterion inner_no; 00140 if( maxTime > 0.0 ) inner_no.add_cpu_time( maxTime ); 00141 inner_no.add_absolute_vertex_movement_edge_length( mBeta ); 00142 improver_no.set_inner_termination_criterion( &inner_no ); 00143 InstructionQueue q_no; 00144 q_no.add_quality_assessor( qa, err );MSQ_ERRRTN( err ); 00145 q_no.set_master_quality_improver( &improver_no, err );MSQ_ERRRTN( err ); 00146 q_no.add_quality_assessor( qa, err );MSQ_ERRRTN( err ); 00147 q_no.run_common( mesh_and_domain, pmesh, settings, err );MSQ_ERRRTN( err ); 00148 } 00149 else 00150 { 00151 // use barrer metric on non-tangled mesh 00152 00153 Timer totalTimer; 00154 TShapeB1 mu_b; 00155 TQualityMetric metric_b_0( &target, &mu_b ); 00156 ElementPMeanP metric_b( 1.0, &metric_b_0 ); 00157 qa->add_quality_assessment( &metric_b ); 00158 PMeanPTemplate obj_func_b( 1.0, &metric_b ); 00159 ConjugateGradient improver_b( &obj_func_b ); 00160 improver_b.use_global_patch(); 00161 00162 if( maxTime > 0.0 ) inner_b.add_cpu_time( maxTime ); 00163 inner_b.add_absolute_vertex_movement_edge_length( mBeta ); 00164 00165 improver_b.set_inner_termination_criterion( &inner_b ); 00166 InstructionQueue q_b; 00167 q_b.add_quality_assessor( qa, err );MSQ_ERRRTN( err ); 00168 q_b.set_master_quality_improver( &improver_b, err );MSQ_ERRRTN( err ); 00169 q_b.add_quality_assessor( qa, err );MSQ_ERRRTN( err ); 00170 q_b.run_common( mesh_and_domain, pmesh, settings, err );MSQ_ERRRTN( err ); 00171 } 00172 } 00173 00174 } // namespace MBMesquite