Branch data Line data Source code
1 : : /* *****************************************************************
2 : : MESQUITE -- The Mesh Quality Improvement Toolkit
3 : :
4 : : Copyright 2010 Sandia National Laboratories. Developed at the
5 : : University of Wisconsin--Madison under SNL contract number
6 : : 624796. The U.S. Government and the University of Wisconsin
7 : : retain certain rights to this software.
8 : :
9 : : This library is free software; you can redistribute it and/or
10 : : modify it under the terms of the GNU Lesser General Public
11 : : License as published by the Free Software Foundation; either
12 : : version 2.1 of the License, or (at your option) any later version.
13 : :
14 : : This library is distributed in the hope that it will be useful,
15 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : Lesser General Public License for more details.
18 : :
19 : : You should have received a copy of the GNU Lesser General Public License
20 : : (lgpl.txt) along with this library; if not, write to the Free Software
21 : : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 : :
23 : : (2010) [email protected]
24 : :
25 : : ***************************************************************** */
26 : :
27 : : /** \file ShapeImprover.cpp
28 : : * \brief
29 : : * \author Jason Kraftcheck
30 : : * \author Boyd Tidwell
31 : : * \date 10-23-12
32 : : */
33 : :
34 : : #include "ShapeImprover.hpp"
35 : : #include "MsqTimer.hpp"
36 : : #include "MsqDebug.hpp"
37 : : #include "PMeanPTemplate.hpp"
38 : : #include "ElementPMeanP.hpp"
39 : : #include "ConjugateGradient.hpp"
40 : : #include "TerminationCriterion.hpp"
41 : : #include "InstructionQueue.hpp"
42 : : #include "QualityAssessor.hpp"
43 : : #include "ElementPatches.hpp"
44 : :
45 : : #include "TShapeB1.hpp"
46 : : #include "TShapeNB1.hpp"
47 : : #include "TQualityMetric.hpp"
48 : : #include "IdealShapeTarget.hpp"
49 : :
50 : : namespace MBMesquite
51 : : {
52 : :
53 : : const double DEFAULT_BETA = 0.0;
54 : : const int DEFUALT_PARALLEL_ITERATIONS = 10;
55 : :
56 : 2 : ShapeImprover::ShapeImprover()
57 : 2 : : maxTime( 300.0 ), mBeta( DEFAULT_BETA ), parallelIterations( DEFUALT_PARALLEL_ITERATIONS )
58 : : {
59 : 2 : }
60 : :
61 : 0 : void ShapeImprover::set_vertex_movement_limit_factor( double beta )
62 : : {
63 [ # # ]: 0 : assert( beta > 0.0 );
64 [ # # ]: 0 : assert( beta < 1.0 );
65 : 0 : mBeta = beta;
66 : 0 : }
67 : :
68 : 0 : void ShapeImprover::set_cpu_time_limit( double limit )
69 : : {
70 [ # # ]: 0 : assert( limit >= 0.0 );
71 : 0 : maxTime = limit;
72 : 0 : }
73 : :
74 : 0 : void ShapeImprover::set_parallel_iterations( int count )
75 : : {
76 [ # # ]: 0 : if( count < 1 )
77 : : {
78 : 0 : assert( false );
79 : : count = 1;
80 : : }
81 : 0 : parallelIterations = count;
82 : 0 : }
83 : :
84 : 3 : void ShapeImprover::run_wrapper( MeshDomainAssoc* mesh_and_domain, ParallelMesh* pmesh, Settings* settings,
85 : : QualityAssessor* qa, MsqError& err )
86 : : {
87 : : // Quality Metrics
88 : 3 : IdealShapeTarget target;
89 [ + - ]: 3 : Mesh* mesh = mesh_and_domain->get_mesh();
90 [ + - ]: 3 : MeshDomain* domain = mesh_and_domain->get_domain();
91 : :
92 : : // only calc min edge length if user hasn't set the vertex_movement_limit_factor
93 [ + + ]: 3 : if( !mBeta )
94 : : {
95 : : // Calculate minimum edge length in mesh
96 : :
97 : : // create a temp global patch to get min edge len from
98 [ + - ]: 2 : PatchData patch;
99 [ + - ]: 2 : patch.set_mesh( mesh );
100 [ + - ]: 2 : patch.set_domain( domain );
101 [ + - ][ + - ]: 2 : if( settings ) patch.attach_settings( settings );
102 [ + - ]: 4 : std::vector< Mesh::ElementHandle > patch_elems;
103 [ + - ]: 4 : std::vector< Mesh::VertexHandle > patch_verts;
104 [ + - ]: 2 : mesh->get_all_elements( patch_elems, err );
105 [ + - ]: 2 : mesh->get_all_vertices( patch_verts, err );
106 [ + - ]: 2 : patch.set_mesh_entities( patch_elems, patch_verts, err );
107 : :
108 : : // get min edge length from temp global patch
109 : 2 : double min_edge_len = 0.0, max_edge_len = 0.0;
110 [ + - ]: 2 : patch.get_minmax_edge_length( min_edge_len, max_edge_len );
111 : 2 : mBeta = min_edge_len / 10.0;
112 : : }
113 : :
114 [ + - ][ + - ]: 6 : TerminationCriterion inner_b;
[ + - ]
115 : :
116 : : // check for inverted elements
117 : :
118 : : // create QualityAssessor instance without a Quality Metric
119 [ + - ][ + - ]: 6 : QualityAssessor check_inverted( false, false );
[ + - ]
120 [ + - ][ + - ]: 6 : InstructionQueue q_invert_check;
121 : : // a QuallityAssessor without a metric will just check for inverted elements and samples
122 [ + - ]: 3 : q_invert_check.add_quality_assessor( &check_inverted, err );
123 [ + - ][ + - ]: 3 : q_invert_check.run_common( mesh_and_domain, pmesh, settings, err );MSQ_ERRRTN( err );
[ - + ][ # # ]
[ # # ][ - + ]
124 : 3 : int inverted_elems = 0, inverted_samples = 0;
125 [ + - ]: 3 : check_inverted.get_inverted_element_count( inverted_elems, inverted_samples, err );
126 [ + + ][ - + ]: 3 : if( inverted_elems || inverted_samples )
127 : : {
128 : : // use non barrier shape improvement on tangled mesh
129 : 1 : TShapeNB1 mu_no;
130 [ + - ][ + - ]: 2 : TQualityMetric metric_no_0( &target, &mu_no );
131 [ + - ][ + - ]: 2 : ElementPMeanP metric_no( 1.0, &metric_no_0 );
132 : :
133 : : // QualityAssessor
134 [ + - ]: 1 : qa->add_quality_assessment( &metric_no );
135 : :
136 [ + - ][ + - ]: 2 : PMeanPTemplate obj_func_no( 1.0, &metric_no );
137 [ + - ][ + - ]: 2 : ConjugateGradient improver_no( &obj_func_no );
138 [ + - ]: 1 : improver_no.use_global_patch();
139 [ + - ][ + - ]: 2 : TerminationCriterion inner_no;
[ + - ]
140 [ + - ][ + - ]: 1 : if( maxTime > 0.0 ) inner_no.add_cpu_time( maxTime );
141 [ + - ]: 1 : inner_no.add_absolute_vertex_movement_edge_length( mBeta );
142 [ + - ]: 1 : improver_no.set_inner_termination_criterion( &inner_no );
143 [ + - ][ + - ]: 2 : InstructionQueue q_no;
144 [ + - ][ + - ]: 1 : q_no.add_quality_assessor( qa, err );MSQ_ERRRTN( err );
[ - + ][ # # ]
[ # # ][ - + ]
145 [ + - ][ + - ]: 1 : q_no.set_master_quality_improver( &improver_no, err );MSQ_ERRRTN( err );
[ - + ][ # # ]
[ # # ][ - + ]
146 [ + - ][ + - ]: 1 : q_no.add_quality_assessor( qa, err );MSQ_ERRRTN( err );
[ - + ][ # # ]
[ # # ][ - + ]
147 [ + - ][ + - ]: 2 : q_no.run_common( mesh_and_domain, pmesh, settings, err );MSQ_ERRRTN( err );
[ - + ][ # # ]
[ # # ][ - + ]
[ + - ]
148 : : }
149 : : else
150 : : {
151 : : // use barrer metric on non-tangled mesh
152 : :
153 [ + - ]: 2 : Timer totalTimer;
154 : 2 : TShapeB1 mu_b;
155 [ + - ][ + - ]: 4 : TQualityMetric metric_b_0( &target, &mu_b );
156 [ + - ][ + - ]: 4 : ElementPMeanP metric_b( 1.0, &metric_b_0 );
157 [ + - ]: 2 : qa->add_quality_assessment( &metric_b );
158 [ + - ][ + - ]: 4 : PMeanPTemplate obj_func_b( 1.0, &metric_b );
159 [ + - ][ + - ]: 4 : ConjugateGradient improver_b( &obj_func_b );
160 [ + - ]: 2 : improver_b.use_global_patch();
161 : :
162 [ + - ][ + - ]: 2 : if( maxTime > 0.0 ) inner_b.add_cpu_time( maxTime );
163 [ + - ]: 2 : inner_b.add_absolute_vertex_movement_edge_length( mBeta );
164 : :
165 [ + - ]: 2 : improver_b.set_inner_termination_criterion( &inner_b );
166 [ + - ][ + - ]: 4 : InstructionQueue q_b;
167 [ + - ][ + - ]: 2 : q_b.add_quality_assessor( qa, err );MSQ_ERRRTN( err );
[ - + ][ # # ]
[ # # ][ - + ]
168 [ + - ][ + - ]: 2 : q_b.set_master_quality_improver( &improver_b, err );MSQ_ERRRTN( err );
[ - + ][ # # ]
[ # # ][ - + ]
169 [ + - ][ + - ]: 2 : q_b.add_quality_assessor( qa, err );MSQ_ERRRTN( err );
[ - + ][ # # ]
[ # # ][ - + ]
170 [ + - ][ + - ]: 5 : q_b.run_common( mesh_and_domain, pmesh, settings, err );MSQ_ERRRTN( err );
[ - + ][ # # ]
[ # # ][ - + ]
[ + - ][ + - ]
171 : 3 : }
172 : : }
173 : :
174 [ + - ][ + - ]: 8 : } // namespace MBMesquite
|