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 : #include "AdaptivityAction.h" 11 : 12 : #ifdef LIBMESH_ENABLE_AMR 13 : 14 : #include "FEProblem.h" 15 : #include "NonlinearSystemBase.h" 16 : #include "Adaptivity.h" 17 : #include "Executioner.h" 18 : #include "MooseEnum.h" 19 : #include "MooseVariableFE.h" 20 : #include "RelationshipManager.h" 21 : #include "SetAdaptivityOptionsAction.h" 22 : 23 : // libMesh includes 24 : #include "libmesh/transient_system.h" 25 : #include "libmesh/system_norm.h" 26 : #include "libmesh/enum_norm_type.h" 27 : 28 : using namespace libMesh; 29 : 30 : registerMooseAction("MooseApp", AdaptivityAction, "setup_adaptivity"); 31 : registerMooseAction("MooseApp", AdaptivityAction, "add_geometric_rm"); 32 : registerMooseAction("MooseApp", AdaptivityAction, "add_algebraic_rm"); 33 : 34 : InputParameters 35 637 : AdaptivityAction::validParams() 36 : { 37 637 : InputParameters params = Moose::commonAdaptivityParams(); 38 637 : params.addClassDescription( 39 : "Add libMesh based adaptation schemes via the Executioner/Adaptivity input syntax."); 40 : MooseEnum estimators("KellyErrorEstimator LaplacianErrorEstimator PatchRecoveryErrorEstimator", 41 637 : "KellyErrorEstimator"); 42 : 43 1911 : params.addParam<unsigned int>( 44 : "initial_adaptivity", 45 1274 : 0, 46 : "The number of adaptivity steps to perform using the initial conditions"); 47 1911 : params.addParam<Real>("refine_fraction", 48 1274 : 0.0, 49 : "The fraction of elements or error to refine. Should be between 0 and 1."); 50 1911 : params.addParam<Real>("coarsen_fraction", 51 1274 : 0.0, 52 : "The fraction of elements or error to coarsen. Should be between 0 and 1."); 53 637 : params.addParam<MooseEnum>( 54 : "error_estimator", estimators, "The class name of the error estimator you want to use."); 55 1911 : params.addDeprecatedParam<bool>( 56 : "print_changed_info", 57 1274 : false, 58 : "Determines whether information about the mesh is printed when adaptivity occurs", 59 : "Use the Console output parameter 'print_mesh_changed_info'"); 60 637 : params.addParam<std::vector<std::string>>( 61 : "weight_names", {}, "List of names of variables that will be associated with weight_values"); 62 637 : params.addParam<std::vector<Real>>( 63 : "weight_values", 64 : {}, 65 : "List of values between 0 and 1 to weight the associated weight_names error by"); 66 1911 : params.addParam<bool>( 67 1274 : "show_initial_progress", true, "Show the progress of the initial adaptivity"); 68 1274 : return params; 69 637 : } 70 : 71 430 : AdaptivityAction::AdaptivityAction(const InputParameters & params) : Action(params) {} 72 : 73 : void 74 1282 : AdaptivityAction::act() 75 : { 76 : // Here we are going to mostly mimic the default ghosting in libmesh 77 : // By default libmesh adds: 78 : // 1) GhostPointNeighbors on the mesh 79 : // 2) DefaultCoupling with 1 layer as an algebraic ghosting functor on the dof_map, which also 80 : // gets added to the mesh at the time a new System is added 81 : // 3) DefaultCoupling with 0 layers as a coupling functor on the dof_map, which also gets added to 82 : // the mesh at the time a new System is added 83 : // 84 : // What we will do differently is: 85 : // - The 3rd ghosting functor adds nothing so we will not add it at all 86 : 87 1282 : if (_current_task == "add_algebraic_rm") 88 : { 89 426 : auto rm_params = _factory.getValidParams("ElementSideNeighborLayers"); 90 : 91 426 : rm_params.set<std::string>("for_whom") = "Adaptivity"; 92 426 : rm_params.set<MooseMesh *>("mesh") = _mesh.get(); 93 426 : rm_params.set<Moose::RelationshipManagerType>("rm_type") = 94 : Moose::RelationshipManagerType::ALGEBRAIC; 95 : 96 426 : if (rm_params.areAllRequiredParamsValid()) 97 : { 98 426 : auto rm_obj = _factory.create<RelationshipManager>( 99 426 : "ElementSideNeighborLayers", "adaptivity_algebraic_ghosting", rm_params); 100 : 101 : // Delete the resources created on behalf of the RM if it ends up not being added to the 102 : // App. 103 426 : if (!_app.addRelationshipManager(rm_obj)) 104 82 : _factory.releaseSharedObjects(*rm_obj); 105 426 : } 106 : else 107 0 : mooseError("Invalid initialization of ElementSideNeighborLayers"); 108 426 : } 109 : 110 856 : else if (_current_task == "add_geometric_rm") 111 : { 112 430 : auto rm_params = _factory.getValidParams("ElementPointNeighborLayers"); 113 : 114 430 : rm_params.set<std::string>("for_whom") = "Adaptivity"; 115 430 : rm_params.set<MooseMesh *>("mesh") = _mesh.get(); 116 430 : rm_params.set<Moose::RelationshipManagerType>("rm_type") = 117 : Moose::RelationshipManagerType::GEOMETRIC; 118 : 119 430 : if (rm_params.areAllRequiredParamsValid()) 120 : { 121 430 : auto rm_obj = _factory.create<RelationshipManager>( 122 430 : "ElementPointNeighborLayers", "adaptivity_geometric_ghosting", rm_params); 123 : 124 : // Delete the resources created on behalf of the RM if it ends up not being added to the 125 : // App. 126 430 : if (!_app.addRelationshipManager(rm_obj)) 127 0 : _factory.releaseSharedObjects(*rm_obj); 128 430 : } 129 : else 130 0 : mooseError("Invalid initialization of ElementPointNeighborLayers"); 131 430 : } 132 : 133 426 : else if (_current_task == "setup_adaptivity") 134 : { 135 426 : NonlinearSystemBase & system = _problem->getNonlinearSystemBase(/*nl_sys_num=*/0); 136 : 137 426 : Adaptivity & adapt = _problem->adaptivity(); 138 : 139 : // we don't need to run mesh modifiers *again* after they ran already during the mesh 140 : // splitting process. Adaptivity::init must be called for any adaptivity to work, however, so we 141 : // can't just skip it for the useSplit case. 142 426 : if (_mesh->isSplit()) 143 0 : adapt.init(0, 0, getParam<bool>("switch_h_to_p_refinement")); 144 : else 145 426 : adapt.init(getParam<unsigned int>("steps"), 146 852 : getParam<unsigned int>("initial_adaptivity"), 147 852 : getParam<bool>("switch_h_to_p_refinement")); 148 : 149 426 : adapt.setErrorEstimator(getParam<MooseEnum>("error_estimator")); 150 : 151 426 : adapt.setParam("cycles_per_step", getParam<unsigned int>("cycles_per_step")); 152 426 : adapt.setParam("refine fraction", getParam<Real>("refine_fraction")); 153 426 : adapt.setParam("coarsen fraction", getParam<Real>("coarsen_fraction")); 154 426 : adapt.setParam("max h-level", getParam<unsigned int>("max_h_level")); 155 426 : adapt.setParam("recompute_markers_during_cycles", 156 : getParam<bool>("recompute_markers_during_cycles")); 157 : 158 426 : adapt.setPrintMeshChanged(getParam<bool>("print_changed_info")); 159 : 160 : const std::vector<std::string> & weight_names = 161 426 : getParam<std::vector<std::string>>("weight_names"); 162 426 : const std::vector<Real> & weight_values = getParam<std::vector<Real>>("weight_values"); 163 : 164 426 : auto num_weight_names = weight_names.size(); 165 426 : auto num_weight_values = weight_values.size(); 166 : 167 426 : if (num_weight_names) 168 : { 169 12 : if (num_weight_names != num_weight_values) 170 0 : mooseError("Number of weight_names must be equal to number of weight_values in " 171 : "Execution/Adaptivity"); 172 : 173 : // If weights have been specified then set the default weight to zero 174 12 : std::vector<Real> weights(system.nVariables(), 0); 175 : 176 24 : for (MooseIndex(num_weight_names) i = 0; i < num_weight_names; i++) 177 : { 178 12 : std::string name = weight_names[i]; 179 12 : auto value = weight_values[i]; 180 : 181 12 : weights[system.getVariable(0, name).number()] = value; 182 12 : } 183 : 184 12 : std::vector<FEMNormType> norms(system.nVariables(), H1_SEMINORM); 185 : 186 12 : SystemNorm sys_norm(norms, weights); 187 : 188 12 : adapt.setErrorNorm(sys_norm); 189 12 : } 190 : 191 426 : adapt.setTimeActive(getParam<Real>("start_time"), getParam<Real>("stop_time")); 192 426 : adapt.setInterval(getParam<unsigned int>("interval")); 193 : } 194 1282 : } 195 : 196 : #endif // LIBMESH_ENABLE_AMR