Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #pragma once 11 : 12 : #include "libmesh/libmesh_config.h" 13 : 14 : #ifdef LIBMESH_ENABLE_AMR 15 : 16 : #include "Moose.h" 17 : #include "MooseError.h" 18 : #include "ConsoleStreamInterface.h" 19 : #include "MooseTypes.h" 20 : #include "PerfGraphInterface.h" 21 : 22 : #include "libmesh/parallel_object.h" 23 : 24 : // libMesh 25 : #include "libmesh/mesh_refinement.h" 26 : 27 : class FEProblemBase; 28 : class MooseMesh; 29 : class DisplacedProblem; 30 : template <typename> 31 : class MooseVariableFE; 32 : typedef MooseVariableFE<Real> MooseVariable; 33 : typedef MooseVariableFE<libMesh::VectorValue<Real>> VectorMooseVariable; 34 : class MooseEnum; 35 : class MultiMooseEnum; 36 : 37 : // Forward declare classes in libMesh 38 : namespace libMesh 39 : { 40 : class SystemNorm; 41 : class ErrorVector; 42 : class ErrorEstimator; 43 : } 44 : 45 : /** 46 : * Takes care of everything related to mesh adaptivity 47 : * 48 : */ 49 : class Adaptivity : public ConsoleStreamInterface, 50 : public PerfGraphInterface, 51 : public libMesh::ParallelObject 52 : { 53 : public: 54 : Adaptivity(FEProblemBase & fe_problem); 55 : virtual ~Adaptivity(); 56 : 57 : /** 58 : * Initialize and turn on adaptivity for the simulation. initial_steps specifies the number of 59 : * adaptivity cycles to perform before the simulation starts and steps indicates the 60 : * number of adaptivity cycles to run during a steady (not transient) solve. steps is not used 61 : * for transient or eigen solves. 62 : * p_refinement indicates whether the refinement will be p-refinement or h-refinement. 63 : */ 64 : void init(const unsigned int steps, const unsigned int initial_steps, const bool p_refinement); 65 : 66 : /** 67 : * Set adaptivity parameter 68 : * 69 : * @param param_name the name of the parameter 70 : * @param param_value the value of parameter 71 : */ 72 : template <typename T> 73 : void setParam(const std::string & param_name, const T & param_value); 74 : 75 : /** 76 : * Set the error estimator 77 : * 78 : * @param error_estimator_name the name of the error estimator (currently: Laplacian, Kelly, and 79 : * PatchRecovery) 80 : */ 81 : void setErrorEstimator(const MooseEnum & error_estimator_name); 82 : 83 : /** 84 : * Set the error norm (FIXME: improve description) 85 : */ 86 : void setErrorNorm(libMesh::SystemNorm & sys_norm); 87 : 88 : /** 89 : * 90 : */ 91 426 : void setPrintMeshChanged(bool state = true) { _print_mesh_changed = state; } 92 : 93 : /** 94 : * Pull out the number of initial steps previously set by calling init() 95 : * 96 : * @return the number of initial steps 97 : */ 98 102786 : unsigned int getInitialSteps() const { return _initial_steps; } 99 : 100 : /** 101 : * Pull out the number of steps previously set by calling init() 102 : * 103 : * @return the number of steps 104 : */ 105 26288 : unsigned int getSteps() const { return _steps; } 106 : 107 : /** 108 : * Pull out the number of cycles_per_step previously set through the AdaptivityAction 109 : * 110 : * @return the number of cycles per step 111 : */ 112 4536 : unsigned int getCyclesPerStep() const { return _cycles_per_step; } 113 : 114 : /** 115 : * Set the number of cycles_per_step 116 : * @param num The number of cycles per step to execute 117 : */ 118 1776 : void setCyclesPerStep(const unsigned int & num) { _cycles_per_step = num; } 119 : 120 : /** 121 : * Pull out the _recompute_markers_during_cycles flag previously set through the AdaptivityAction 122 : * 123 : * @return the flag to recompute markers during adaptivity cycles 124 : */ 125 4689 : bool getRecomputeMarkersFlag() const { return _recompute_markers_during_cycles; } 126 : 127 : /** 128 : * Set the flag to recompute markers during adaptivity cycles 129 : * @param flag The flag to recompute markers 130 : */ 131 1776 : void setRecomputeMarkersFlag(const bool flag) { _recompute_markers_during_cycles = flag; } 132 : 133 : /** 134 : * Adapts the mesh based on the error estimator used 135 : * 136 : * This method calls DisplacedProblem::undisplaceMesh, so it is necessary to 137 : * update the displaced problem's mesh (undoing the undisplacement) before any 138 : * objects relying on the displaced mesh are executed. However, projection of 139 : * the displacement variables is required before doing so; therefore, the 140 : * DisplacedProblem::updateMesh call needs to happen outside of this method. 141 : * @see FEProblemBase::adaptMesh and FEProblemMase::meshChangedHelper. 142 : * 143 : * @return a boolean that indicates whether the mesh was changed 144 : */ 145 : bool adaptMesh(std::string marker_name = std::string()); 146 : 147 : /** 148 : * Used during initial adaptivity. 149 : * 150 : * @return a boolean that indicates whether the mesh was changed 151 : */ 152 : bool initialAdaptMesh(); 153 : 154 : /** 155 : * Performs uniform refinement of the passed Mesh object. The 156 : * number of levels of refinement performed is stored in the 157 : * MooseMesh object. No solution projection is performed in this 158 : * version. 159 : */ 160 : static void uniformRefine(MooseMesh * mesh, unsigned int level = libMesh::invalid_uint); 161 : 162 : /** 163 : * Performs uniform refinement on the meshes in the current 164 : * object. Projections are performed of the solution vectors. 165 : */ 166 : void uniformRefineWithProjection(); 167 : 168 : /** 169 : * Allow adaptivity to be toggled programatically. 170 : * @param state The adaptivity state (on/off). 171 : */ 172 : void setAdaptivityOn(bool state); 173 : 174 : /** 175 : * Is adaptivity on? 176 : * 177 : * @return true if mesh adaptivity is on, otherwise false 178 : */ 179 167024 : bool isOn() { return _mesh_refinement_on; } 180 : 181 : /** 182 : * Returns whether or not Adaptivity::init() has ran. Can 183 : * be used to indicate if mesh adaptivity is available. 184 : * 185 : * @return true if the Adaptivity system is ready to be used, otherwise false 186 : */ 187 : bool isInitialized() { return _initialized; } 188 : 189 : /** 190 : * Sets the time when the adaptivity is active 191 : * @param start_time The time when adaptivity starts 192 : * @param stop_time The time when adaptivity stops 193 : */ 194 : void setTimeActive(Real start_time, Real stop_time); 195 : 196 : /** 197 : * Tells this object we're using the "new" adaptivity system. 198 : */ 199 : void setUseNewSystem(); 200 : 201 : /** 202 : * Sets the name of the field variable to actually use to flag elements for refinement / 203 : * coarsening. 204 : * This must be a CONSTANT, MONOMIAL Auxiliary Variable Name that contains values 205 : * corresponding to libMesh::Elem::RefinementState. 206 : * 207 : * @param marker_field The name of the field to use for refinement / coarsening. 208 : */ 209 : void setMarkerVariableName(std::string marker_field); 210 : 211 : /** 212 : * Sets the name of the field variable to actually use to flag elements for initial refinement / 213 : * coarsening. 214 : * This must be a CONSTANT, MONOMIAL Auxiliary Variable Name that contains values 215 : * corresponding to libMesh::Elem::RefinementState. 216 : * 217 : * @param marker_field The name of the field to use for refinement / coarsening. 218 : */ 219 : void setInitialMarkerVariableName(std::string marker_field); 220 : 221 : /** 222 : * Set the maximum refinement level (for the new Adaptivity system). 223 : */ 224 1776 : void setMaxHLevel(unsigned int level) { _max_h_level = level; } 225 : 226 : /** 227 : * Return the maximum h-level. 228 : */ 229 : unsigned int getMaxHLevel() { return _max_h_level; } 230 : 231 : /** 232 : * Set the interval (number of timesteps) between refinement steps. 233 : */ 234 2202 : void setInterval(unsigned int interval) { _interval = interval; } 235 : 236 : /** 237 : * Get an ErrorVector that will be filled up with values corresponding to the 238 : * indicator field name passed in. 239 : * 240 : * Note that this returns a reference... and the return value should be stored as a reference! 241 : * 242 : * @param indicator_field The name of the field to get an ErrorVector for. 243 : */ 244 : libMesh::ErrorVector & getErrorVector(const std::string & indicator_field); 245 : 246 : /** 247 : * Update the ErrorVectors that have been requested through calls to getErrorVector(). 248 : */ 249 : void updateErrorVectors(); 250 : 251 : /** 252 : * Query if an adaptivity step should be performed at the current time / time step 253 : */ 254 : bool isAdaptivityDue(); 255 : 256 : protected: 257 : FEProblemBase & _fe_problem; 258 : MooseMesh & _mesh; 259 : 260 : /// on/off flag reporting if the adaptivity is being used 261 : bool _mesh_refinement_on; 262 : /// on/off flag reporting if the adaptivity system has been initialized 263 : bool _initialized; 264 : /// A mesh refinement object to be used either with initial refinement or with Adaptivity. 265 : std::unique_ptr<libMesh::MeshRefinement> _mesh_refinement; 266 : /// Error estimator to be used by the apps. 267 : std::unique_ptr<libMesh::ErrorEstimator> _error_estimator; 268 : /// Error vector for use with the error estimator. 269 : std::unique_ptr<libMesh::ErrorVector> _error; 270 : 271 : std::shared_ptr<DisplacedProblem> _displaced_problem; 272 : 273 : /// A mesh refinement object for displaced mesh 274 : std::unique_ptr<libMesh::MeshRefinement> _displaced_mesh_refinement; 275 : 276 : /// the number of adaptivity steps to do at the beginning of simulation 277 : unsigned int _initial_steps; 278 : /// steps of adaptivity to perform 279 : unsigned int _steps; 280 : 281 : /// True if we want to print out info when mesh has changed 282 : bool _print_mesh_changed; 283 : 284 : /// Time 285 : Real & _t; 286 : /// Time Step 287 : int & _step; 288 : /// intreval between adaptivity runs 289 : unsigned int _interval; 290 : /// When adaptivity start 291 : Real _start_time; 292 : /// When adaptivity stops 293 : Real _stop_time; 294 : /// The number of adaptivity cycles per step 295 : unsigned int _cycles_per_step; 296 : 297 : /// Whether or not to use the "new" adaptivity system 298 : bool _use_new_system; 299 : 300 : /// Name of the marker variable if using the new adaptivity system 301 : std::string _marker_variable_name; 302 : 303 : /// Name of the initial marker variable if using the new adaptivity system 304 : std::string _initial_marker_variable_name; 305 : 306 : /// The maximum number of refinement levels 307 : unsigned int _max_h_level; 308 : 309 : /// Whether or not to recompute markers during adaptivity cycles 310 : bool _recompute_markers_during_cycles; 311 : 312 : /// Stores pointers to ErrorVectors associated with indicator field names 313 : std::map<std::string, std::unique_ptr<libMesh::ErrorVector>> _indicator_field_to_error_vector; 314 : 315 : bool _p_refinement_flag = false; 316 : }; 317 : 318 : template <typename T> 319 : void 320 2130 : Adaptivity::setParam(const std::string & param_name, const T & param_value) 321 : { 322 2130 : if (param_name == "refine fraction") 323 : { 324 426 : _mesh_refinement->refine_fraction() = param_value; 325 426 : if (_displaced_mesh_refinement) 326 34 : _displaced_mesh_refinement->refine_fraction() = param_value; 327 : } 328 1704 : else if (param_name == "coarsen fraction") 329 : { 330 426 : _mesh_refinement->coarsen_fraction() = param_value; 331 426 : if (_displaced_mesh_refinement) 332 34 : _displaced_mesh_refinement->coarsen_fraction() = param_value; 333 : } 334 1278 : else if (param_name == "max h-level") 335 : { 336 426 : _mesh_refinement->max_h_level() = param_value; 337 426 : if (_displaced_mesh_refinement) 338 34 : _displaced_mesh_refinement->max_h_level() = param_value; 339 : } 340 852 : else if (param_name == "cycles_per_step") 341 426 : _cycles_per_step = param_value; 342 426 : else if (param_name == "recompute_markers_during_cycles") 343 426 : _recompute_markers_during_cycles = param_value; 344 : else 345 0 : mooseError("Invalid Param in adaptivity object"); 346 2130 : } 347 : #endif // LIBMESH_ENABLE_AMR