GRINS-0.6.0
mesh_adaptive_solver_base.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------bl-
2 //--------------------------------------------------------------------------
3 //
4 // GRINS - General Reacting Incompressible Navier-Stokes
5 //
6 // Copyright (C) 2014-2015 Paul T. Bauman, Roy H. Stogner
7 // Copyright (C) 2010-2013 The PECOS Development Team
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the Version 2.1 GNU Lesser General
11 // Public License as published by the Free Software Foundation.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc. 51 Franklin Street, Fifth Floor,
21 // Boston, MA 02110-1301 USA
22 //
23 //-----------------------------------------------------------------------el-
24 
25 // C++
26 #include <numeric>
27 
28 // This class
30 #include "grins/solver_context.h"
31 
32 // libMesh
33 #include "libmesh/getpot.h"
34 #include "libmesh/mesh_base.h"
35 #include "libmesh/error_vector.h"
36 
37 namespace GRINS
38 {
40  : Solver( input ),
41  _max_refinement_steps( input("MeshAdaptivity/max_refinement_steps", 5) ),
42  _coarsen_by_parents(true),
43  _absolute_global_tolerance( input("MeshAdaptivity/absolute_global_tolerance", 0) ),
44  _nelem_target( input("MeshAdaptivity/nelem_target", 0) ),
45  _refine_fraction( input("MeshAdaptivity/refine_percentage", 0.2) ),
46  _coarsen_fraction( input("MeshAdaptivity/coarsen_percentage", 0.2) ),
47  _coarsen_threshold( input("MeshAdaptivity/coarsen_threshold", 0) ),
48  _plot_cell_errors( input("MeshAdaptivity/plot_cell_errors", false) ),
49  _error_plot_prefix( input("MeshAdaptivity/error_plot_prefix", "cell_error") ),
50  _node_level_mismatch_limit( input("MeshAdaptivity/node_level_mismatch_limit", 0) ),
51  _edge_level_mismatch_limit( input("MeshAdaptivity/edge_level_mismatch_limit", 0 ) ),
52  _face_level_mismatch_limit( input("MeshAdaptivity/face_level_mismatch_limit", 1 ) ),
53  _enforce_mismatch_limit_prior_to_refinement( input("MeshAdaptivity/enforce_mismatch_limit_prior_to_refinement", false ) ),
54  _refinement_type(INVALID),
55  _mesh_refinement(NULL)
56  {
57  this->set_refinement_type( input, _refinement_type );
58 
59  return;
60  }
61 
63  {
64  return;
65  }
66 
67  void MeshAdaptiveSolverBase::build_mesh_refinement( libMesh::MeshBase& mesh )
68  {
69  _mesh_refinement.reset( new libMesh::MeshRefinement( mesh ) );
70  _mesh_refinement->coarsen_by_parents() = _coarsen_by_parents;
71  _mesh_refinement->absolute_global_tolerance() = _absolute_global_tolerance;
72  _mesh_refinement->nelem_target() = _nelem_target;
73  _mesh_refinement->refine_fraction() = _refine_fraction;
74  _mesh_refinement->coarsen_fraction() = _coarsen_fraction;
75  _mesh_refinement->coarsen_threshold() = _coarsen_threshold;
76  _mesh_refinement->node_level_mismatch_limit() = _node_level_mismatch_limit;
77  _mesh_refinement->edge_level_mismatch_limit() = _edge_level_mismatch_limit;
78  _mesh_refinement->face_level_mismatch_limit() = _face_level_mismatch_limit;
79  _mesh_refinement->set_enforce_mismatch_limit_prior_to_refinement(_enforce_mismatch_limit_prior_to_refinement);
80 
81  return;
82  }
83 
86  {
87  std::string refinement_stategy = input("MeshAdaptivity/refinement_strategy", "elem_fraction" );
88 
89  if( !input.have_variable("MeshAdaptivity/absolute_global_tolerance" ) )
90  {
91  std::cerr << "Error: Must specify absolute_global_tolerance for" << std::endl
92  << " adaptive refinement algorithms."
93  << std::endl;
94 
95  libmesh_error();
96  }
97 
98  if( refinement_stategy == std::string("error_tolerance") )
99  {
100  refinement_type = ERROR_TOLERANCE;
101  }
102 
103  else if( refinement_stategy == std::string("nelem_target") )
104  {
105  refinement_type = N_ELEM_TARGET;
106 
107  if( !input.have_variable("MeshAdaptivity/nelem_target") )
108  {
109  std::cerr << "Error: Must specify nelem_target for" << std::endl
110  << " for error_tolerance refinement strategy."
111  << std::endl;
112 
113  libmesh_error();
114  }
115  }
116 
117  else if( refinement_stategy == std::string("error_fraction") )
118  {
119  refinement_type = ERROR_FRACTION;
120  }
121 
122  else if( refinement_stategy == std::string("elem_fraction") )
123  {
124  refinement_type = ELEM_FRACTION;
125  }
126 
127  else if( refinement_stategy == std::string("mean_std_dev") )
128  {
129  refinement_type = MEAN_STD_DEV;
130  }
131 
132  else
133  {
134  std::cerr << "Error: Invalid refinement strategy " << refinement_stategy << std::endl
135  << " Valid refinement strategy options are: absolute_global_tolerance" << std::endl
136  << " error_tolerance" << std::endl
137  << " nelem_target" << std::endl
138  << " error_fraction" << std::endl
139  << " elem_fraction" << std::endl
140  << " mean_std_dev" << std::endl;
141 
142  libmesh_error();
143  }
144 
145  return;
146  }
147 
149  const libMesh::ErrorVector& error ) const
150  {
151  bool converged = false;
152 
153  libMesh::Real error_estimate = 0.0;
154 
155  if( context.do_adjoint_solve )
156  {
157  error_estimate = std::accumulate( error.begin(), error.end(), 0.0 );
158  }
159  else
160  {
161  error_estimate = error.l2_norm();
162  }
163 
164  std::cout << "==========================================================" << std::endl
165  << "Error estimate = " << error_estimate << std::endl
166  << "==========================================================" << std::endl;
167 
168  // For now, we just check the norm
169  if( std::fabs(error_estimate) <= _absolute_global_tolerance )
170  {
171  converged = true;
172  }
173 
174  return converged;
175  }
176 
177  void MeshAdaptiveSolverBase::flag_elements_for_refinement( const libMesh::ErrorVector& error )
178  {
179  switch(_refinement_type)
180  {
181  case(ERROR_TOLERANCE):
182  {
183  _mesh_refinement->flag_elements_by_error_tolerance( error );
184  }
185  break;
186 
187  case(N_ELEM_TARGET):
188  {
189  _mesh_refinement->flag_elements_by_nelem_target( error );
190  }
191  break;
192 
193  case( ERROR_FRACTION ):
194  {
195  _mesh_refinement->flag_elements_by_error_fraction( error );
196  }
197  break;
198 
199  case( ELEM_FRACTION ):
200  {
201  _mesh_refinement->flag_elements_by_elem_fraction( error );
202  }
203  break;
204 
205  case( MEAN_STD_DEV ):
206  {
207  _mesh_refinement->flag_elements_by_mean_stddev( error );
208  }
209  break;
210 
211  case(INVALID):
212  {
213  std::cerr << "Error: Invalid refinement option!" << std::endl;
214  libmesh_error();
215  }
216  break;
217 
218  // Wat?!
219  default:
220  {
221  libmesh_error();
222  }
223 
224  } // switch(_refinement_type)
225 
226  return;
227  }
228 
229 } // end namespace GRINS
boost::scoped_ptr< libMesh::MeshRefinement > _mesh_refinement
void build_mesh_refinement(libMesh::MeshBase &mesh)
bool check_for_convergence(SolverContext &context, const libMesh::ErrorVector &error) const
GRINS namespace.
void flag_elements_for_refinement(const libMesh::ErrorVector &error)
Simple class to hold objects passed to Solver::solve.
void set_refinement_type(const GetPot &input, RefinementFlaggingType &refinement_type)

Generated on Mon Jun 22 2015 21:32:20 for GRINS-0.6.0 by  doxygen 1.8.9.1