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 UntangleWrapper.cpp
28 : : * \brief
29 : : * \author Jason Kraftcheck
30 : : */
31 : :
32 : : #include "Mesquite.hpp"
33 : : #include "UntangleWrapper.hpp"
34 : : #include "MeshUtil.hpp"
35 : : #include "SimpleStats.hpp"
36 : : #include "MsqError.hpp"
37 : :
38 : : #include "LambdaConstant.hpp"
39 : : #include "IdealShapeTarget.hpp"
40 : : #include "TQualityMetric.hpp"
41 : : #include "PMeanPTemplate.hpp"
42 : : #include "TerminationCriterion.hpp"
43 : : #include "SteepestDescent.hpp"
44 : : #include "ConjugateGradient.hpp"
45 : : #include "QualityAssessor.hpp"
46 : : #include "InstructionQueue.hpp"
47 : : #include "ElementPMeanP.hpp"
48 : : #include "Instruction.hpp"
49 : :
50 : : #include "TUntangleBeta.hpp"
51 : : #include "TUntangleMu.hpp"
52 : : #include "TSizeNB1.hpp"
53 : : #include "TShapeSize2DNB1.hpp"
54 : : #include "TShapeSize3DNB1.hpp"
55 : : #include "TMixed.hpp"
56 : :
57 : : #include <memory>
58 : :
59 : : const int NUM_INNER_ITERATIONS = 1;
60 : : const double DEFAULT_MOVEMENT_FACTOR = 0.001;
61 : : const bool CULLING_DEFAULT = true;
62 : : const bool JACOBI_DEFAULT = false;
63 : :
64 : : namespace MBMesquite
65 : : {
66 : :
67 : 0 : UntangleWrapper::UntangleWrapper()
68 : : : qualityMetric( SIZE ), maxTime( -1 ), movementFactor( DEFAULT_MOVEMENT_FACTOR ), metricConstant( -1 ),
69 : 0 : maxIterations( -1 ), doCulling( CULLING_DEFAULT ), doJacobi( JACOBI_DEFAULT )
70 : : {
71 : 0 : }
72 : :
73 : 16 : UntangleWrapper::UntangleWrapper( UntangleMetric m )
74 : : : qualityMetric( m ), maxTime( -1 ), movementFactor( DEFAULT_MOVEMENT_FACTOR ), metricConstant( -1 ),
75 : 16 : maxIterations( -1 ), doCulling( CULLING_DEFAULT ), doJacobi( JACOBI_DEFAULT )
76 : : {
77 : 16 : }
78 : :
79 [ - + ]: 32 : UntangleWrapper::~UntangleWrapper() {}
80 : :
81 : 0 : void UntangleWrapper::set_untangle_metric( UntangleMetric metric )
82 : : {
83 : 0 : qualityMetric = metric;
84 : 0 : }
85 : :
86 : 0 : void UntangleWrapper::set_metric_constant( double value )
87 : : {
88 : 0 : metricConstant = value;
89 : 0 : }
90 : :
91 : 0 : void UntangleWrapper::set_cpu_time_limit( double seconds )
92 : : {
93 : 0 : maxTime = seconds;
94 : 0 : }
95 : :
96 : 0 : void UntangleWrapper::set_outer_iteration_limit( int maxIt )
97 : : {
98 : 0 : maxIterations = maxIt;
99 : 0 : }
100 : :
101 : 16 : void UntangleWrapper::set_vertex_movement_limit_factor( double f )
102 : : {
103 : 16 : movementFactor = f;
104 : 16 : }
105 : :
106 : 20 : void UntangleWrapper::run_wrapper( MeshDomainAssoc* mesh_and_domain, ParallelMesh* pmesh, Settings* settings,
107 : : QualityAssessor* qa, MsqError& err )
108 : : {
109 [ + - ][ + - ]: 40 : Instruction::initialize_vertex_byte( mesh_and_domain, settings, err );MSQ_ERRRTN( err );
[ - + ][ # # ]
[ # # ][ - + ]
110 : :
111 [ + - ]: 20 : Mesh* mesh = mesh_and_domain->get_mesh();
112 : :
113 : : // get some global mesh properties
114 [ + - ][ + - ]: 20 : SimpleStats edge_len, lambda;
115 [ + - ][ + - ]: 20 : std::auto_ptr< MeshUtil > tool( new MeshUtil( mesh, settings ) );
116 [ + - ][ + - ]: 20 : tool->edge_length_distribution( edge_len, err );MSQ_ERRRTN( err );
[ - + ][ # # ]
[ # # ][ - + ]
117 [ + - ][ + - ]: 20 : tool->lambda_distribution( lambda, err );MSQ_ERRRTN( err );
[ - + ][ # # ]
[ # # ][ - + ]
118 : 20 : tool.reset( 0 );
119 : :
120 : : // get target metrics from user perferences
121 [ + - ]: 20 : TSizeNB1 mu_size;
122 [ + - ]: 20 : TShapeSize2DNB1 mu_shape_2d;
123 [ + - ][ + - ]: 40 : TShapeSize3DNB1 mu_shape_3d;
124 [ + - ][ + - ]: 40 : TMixed mu_shape( &mu_shape_2d, &mu_shape_3d );
125 [ + - ]: 40 : std::auto_ptr< TMetric > mu;
126 [ + + ]: 20 : if( qualityMetric == BETA )
127 : : {
128 : 7 : double beta = metricConstant;
129 [ + - ][ + - ]: 7 : if( beta < 0 ) beta = ( lambda.average() * lambda.average() ) / 20;
[ + - ]
130 : : // std::cout << "beta= " << beta << std::endl;
131 [ + - ][ + - ]: 7 : mu.reset( new TUntangleBeta( beta ) );
132 : : }
133 : : else
134 : : {
135 : 13 : TMetric* sub = 0;
136 [ + + ]: 13 : if( qualityMetric == SIZE )
137 : 7 : sub = &mu_size;
138 : : else
139 : 6 : sub = &mu_shape;
140 [ - + ]: 13 : if( metricConstant >= 0 )
141 [ # # ][ # # ]: 0 : mu.reset( new TUntangleMu( sub, metricConstant ) );
142 : : else
143 [ + - ][ + - ]: 13 : mu.reset( new TUntangleMu( sub ) );
144 : : }
145 : :
146 : : // define objective function
147 [ + - ]: 20 : IdealShapeTarget base_target;
148 [ + - ][ + - ]: 40 : LambdaConstant target( lambda.average(), &base_target );
[ + - ]
149 [ + - ][ + - ]: 40 : TQualityMetric metric_0( &target, mu.get() );
150 [ + - ][ + - ]: 40 : ElementPMeanP metric( 1.0, &metric_0 );
151 [ + - ][ + - ]: 40 : PMeanPTemplate objfunc( 1.0, &metric );
152 : :
153 : : // define termination criterion
154 [ + - ][ + - ]: 20 : double eps = movementFactor * ( edge_len.average() - edge_len.standard_deviation() );
155 [ + - ][ + - ]: 40 : TerminationCriterion inner( "<type:untangle_inner>", TerminationCriterion::TYPE_INNER ),
[ + - ]
156 [ + - ][ + - ]: 40 : outer( "<type:untangle_outer>", TerminationCriterion::TYPE_OUTER );
[ + - ]
157 [ + - ]: 20 : outer.add_untangled_mesh();
158 [ + - ]: 20 : if( doCulling )
159 [ + - ]: 20 : inner.cull_on_absolute_vertex_movement( eps );
160 : : else
161 [ # # ]: 0 : outer.add_absolute_vertex_movement( eps );
162 [ - + ][ # # ]: 20 : if( maxTime > 0.0 ) outer.add_cpu_time( maxTime );
163 [ + - ]: 20 : inner.add_iteration_limit( NUM_INNER_ITERATIONS );
164 [ - + ][ # # ]: 20 : if( maxIterations > 0 ) outer.add_iteration_limit( maxIterations );
165 : :
166 : : // construct solver
167 [ + - ][ + - ]: 40 : SteepestDescent solver( &objfunc );
168 [ + - ]: 20 : solver.use_element_on_vertex_patch();
169 [ + - ]: 20 : solver.set_inner_termination_criterion( &inner );
170 [ + - ]: 20 : solver.set_outer_termination_criterion( &outer );
171 [ - + ]: 20 : if( doJacobi )
172 [ # # ]: 0 : solver.do_jacobi_optimization();
173 : : else
174 [ + - ]: 20 : solver.do_gauss_optimization();
175 : :
176 : : // Run
177 [ + - ]: 20 : qa->add_quality_assessment( &metric );
178 [ + - ][ + - ]: 40 : InstructionQueue q;
179 [ + - ][ + - ]: 20 : q.add_quality_assessor( qa, err );MSQ_ERRRTN( err );
[ - + ][ # # ]
[ # # ][ - + ]
180 [ + - ][ + - ]: 20 : q.set_master_quality_improver( &solver, err );MSQ_ERRRTN( err );
[ - + ][ # # ]
[ # # ][ - + ]
181 [ + - ][ + - ]: 20 : q.add_quality_assessor( qa, err );MSQ_ERRRTN( err );
[ - + ][ # # ]
[ # # ][ - + ]
182 [ + - ][ + - ]: 40 : q.run_common( mesh_and_domain, pmesh, settings, err );MSQ_ERRRTN( err );
[ - + ][ # # ]
[ # # ][ - + ]
[ + - ]
183 : : }
184 : :
185 [ + - ][ + - ]: 8 : } // namespace MBMesquite
|