1 /* *****************************************************************
2     MESQUITE -- The Mesh Quality Improvement Toolkit
3 
4     Copyright 2004 Sandia Corporation and Argonne National
5     Laboratory.  Under the terms of Contract DE-AC04-94AL85000
6     with Sandia Corporation, the U.S. Government retains certain
7     rights in 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     diachin2@llnl.gov, djmelan@sandia.gov, mbrewer@sandia.gov,
24     pknupp@sandia.gov, tleurent@mcs.anl.gov, tmunson@mcs.anl.gov
25 
26   ***************************************************************** */
27 // -*- Mode : c++; tab-width: 3; c-tab-always-indent: t; indent-tabs-mode: nil; c-basic-offset: 3 -*-
28 
29 /*! \file ShapeImprovementWrapper.cpp
30 
31 Member functions of the MBMesquite::ShapeImprovementWrapper class
32 
33   \author Michael Brewer
34   \date   June 6, 2003
35  */
36 
37 #include "InstructionQueue.hpp"
38 #include "ShapeImprovementWrapper.hpp"
39 #include "MsqTimer.hpp"
40 #include "MsqDebug.hpp"
41 #include "UntangleBetaQualityMetric.hpp"
42 #include "LPtoPTemplate.hpp"
43 #include "ConjugateGradient.hpp"
44 #include "TerminationCriterion.hpp"
45 #include "IdealWeightInverseMeanRatio.hpp"
46 #include "FeasibleNewton.hpp"
47 #include "InstructionQueue.hpp"
48 #include "QualityAssessor.hpp"
49 
50 namespace MBMesquite {
51 
52 const double DEF_UNT_BETA = 1e-8;
53 const double DEF_SUC_EPS = 1e-4;
54 
55 /*! The consturctor allows for two values.  The first is a
56   time bound (in seconds) used as a termination criterion.  If
57   this value is non-positive, no time bound will be set.
58   By default, the value is set to zero and no time bound
59   is used.  The second value is the tolerance for the gradient
60   norm termination criteria.  The default value is 1.e-6.*/
ShapeImprovementWrapper(MsqError &,double cpu_time,double grad_norm,int parallel_iterations)61 ShapeImprovementWrapper::ShapeImprovementWrapper(MsqError& ,
62                                                  double cpu_time,
63                                                  double grad_norm,
64                                                  int parallel_iterations)
65  : maxTime(cpu_time),
66    gradNorm(grad_norm),
67    untBeta(DEF_UNT_BETA),
68    successiveEps(DEF_SUC_EPS),
69    parallelIterations(parallel_iterations)
70 {}
71 
ShapeImprovementWrapper(double cpu_time,double grad_norm,int parallel_iterations)72 ShapeImprovementWrapper::ShapeImprovementWrapper(double cpu_time,
73                                                  double grad_norm,
74                                                  int parallel_iterations)
75  : maxTime(cpu_time),
76    gradNorm(grad_norm),
77    untBeta(DEF_UNT_BETA),
78    successiveEps(DEF_SUC_EPS),
79    parallelIterations(parallel_iterations)
80 {}
81 
82 
run_wrapper(MeshDomainAssoc * mesh_and_domain,ParallelMesh * pmesh,Settings * settings,QualityAssessor * qa,MsqError & err)83 void ShapeImprovementWrapper::run_wrapper( MeshDomainAssoc* mesh_and_domain,
84                                            ParallelMesh* pmesh,
85                                            Settings* settings,
86                                            QualityAssessor* qa,
87                                            MsqError& err )
88 {
89     // Define an untangler
90   UntangleBetaQualityMetric untangle_metric( untBeta );
91   LPtoPTemplate untangle_func( 2, &untangle_metric );
92   ConjugateGradient untangle_global( &untangle_func );
93   TerminationCriterion untangle_inner, untangle_outer;
94   untangle_global.use_global_patch();
95   untangle_inner.add_absolute_quality_improvement( 0.0 );
96   untangle_inner.add_absolute_successive_improvement( successiveEps );
97   untangle_outer.add_iteration_limit( 1 );
98   untangle_global.set_inner_termination_criterion( &untangle_inner );
99   untangle_global.set_outer_termination_criterion( &untangle_outer );
100 
101     // define shape improver
102   IdealWeightInverseMeanRatio inverse_mean_ratio;
103   inverse_mean_ratio.set_averaging_method( QualityMetric::LINEAR );
104   LPtoPTemplate obj_func( 2, &inverse_mean_ratio );
105   FeasibleNewton feas_newt( &obj_func );
106   TerminationCriterion term_inner, term_outer;
107   feas_newt.use_global_patch();
108   qa->add_quality_assessment( &inverse_mean_ratio );
109   term_inner.add_absolute_gradient_L2_norm( gradNorm );
110   term_inner.add_relative_successive_improvement( successiveEps );
111   term_outer.add_iteration_limit( pmesh ? parallelIterations : 1 );
112   feas_newt.set_inner_termination_criterion( &term_inner );
113   feas_newt.set_outer_termination_criterion( &term_outer );
114 
115     // Apply CPU time limit to untangler
116   if (maxTime > 0.0)
117     untangle_inner.add_cpu_time( maxTime );
118 
119     // Run untangler
120   InstructionQueue q1;
121   Timer totalTimer;
122   q1.set_master_quality_improver( &untangle_global, err ); MSQ_ERRRTN(err);
123   q1.add_quality_assessor( qa, err ); MSQ_ERRRTN(err);
124   q1.run_common( mesh_and_domain, pmesh, settings, err ); MSQ_ERRRTN(err);
125 
126     // If limited by CPU time, limit next step to remaning time
127   if (maxTime > 0.0) {
128     double remaining = maxTime - totalTimer.since_birth();
129     if (remaining <= 0.0 ){
130       MSQ_DBGOUT(2) << "Optimization is terminating without perfoming shape improvement." << std::endl;
131       remaining = 0.0;
132     }
133     term_inner.add_cpu_time( remaining );
134   }
135 
136     // Run shape improver
137   InstructionQueue q2;
138   q2.set_master_quality_improver( &feas_newt, err ); MSQ_ERRRTN(err);
139   q2.add_quality_assessor( qa, err ); MSQ_ERRRTN(err);
140   q2.run_common( mesh_and_domain, pmesh, settings, err ); MSQ_ERRRTN(err);
141 }
142 
143 } // namespace MBMesquite
144 
145 
146