https://mooseframework.inl.gov
MFEMRefinementMarker.C
Go to the documentation of this file.
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 #ifdef MOOSE_MFEM_ENABLED
11 
12 #include "MFEMRefinementMarker.h"
13 #include "MFEMProblem.h"
14 
16 
19 {
21  params.registerBase("Marker");
22  params.registerSystemAttributeName("Marker");
23 
24  params.addRequiredParam<std::string>("indicator", "Estimator to use");
25  params.addRangeCheckedParam<Real>("threshold",
26  0,
27  "threshold>=0 & threshold<=1",
28  "Elements above this percentage of the max error will "
29  "be refined. Must be between 0 and 1!");
30  params.addParam<bool>("rebalance", false, "Whether to rebalance the mesh after h-refinement");
31  params.addRangeCheckedParam<unsigned>(
32  "max_h_level", 0, "max_h_level>=0 & max_h_level<=10", "Max number of h-refinement steps");
33  params.addRangeCheckedParam<unsigned>(
34  "max_p_level", 0, "max_p_level>=0 & max_p_level<=10", "Max number of p-refinement steps");
35  return params;
36 }
37 
39  : MFEMObject(params),
40  _estimator_name(getParam<std::string>("indicator")),
41  _error_threshold(getParam<Real>("threshold")),
42  _rebalance(getParam<bool>("rebalance")),
43  _max_h_level(getParam<unsigned>("max_h_level")),
44  _max_p_level(getParam<unsigned>("max_p_level"))
45 {
46 }
47 
48 void
50 {
51  // fetch const ref to the estimator
53 
54  // Check if p-refinement is supported by the fespace supplied with the variable
55  if (_max_p_level and !_estimator->getFESpace().PRefinementSupported())
56  {
57  mooseWarning("Specified p-refinement on an unsupported FESpace or geometry. Only H1 and L2 "
58  "spaces on quad/hex meshes are supported by mfem. Disabling p-refinement.");
60  }
61 
62  // For now, we only allow one level of p-refinement exclusively.
63  if ((_max_h_level and _max_p_level) or _max_p_level > 1)
64  {
65  mooseWarning("At present, only either a) h-refinement or b) one level of p-refinement is "
66  "supported. Disabling p-refinement.");
68  }
69 
70  // We do not want to allow rebalancing if p-refinement is enabled, because that mesh-only
71  // operation has no notion of p-refinement and the computational imbalance that may result.
72  if (_max_p_level and _rebalance)
73  {
74  mooseWarning("Asked for rebalancing as well as p-refinement, which is not supported.");
75  _rebalance = false;
76  }
77 
78  _threshold_refiner = std::make_unique<mfem::ThresholdRefiner>(*(_estimator->getEstimator()));
79  _threshold_refiner->SetTotalErrorFraction(_error_threshold);
80 }
81 
82 bool
84 {
85  // Nothing to do if we've reached the max level of refinement
87  return false;
88 
89  mfem::Array<mfem::Refinement> refinements;
90  _threshold_refiner->MarkWithoutRefining(_estimator->getParMesh(), refinements);
91 
92  const bool refined = _estimator->getParMesh().ReduceInt(refinements.Size()) != 0LL;
93 
94  if (refined)
95  {
96  mfem::Array<mfem::pRefinement> prefinements(refinements.Size());
97  for (const auto i : make_range(refinements.Size()))
98  prefinements[i] = mfem::pRefinement(refinements[i].index, 1);
99 
100  // Perform p-refinement
101  _estimator->getFESpace().PRefineAndUpdate(prefinements);
102  // Update all gridfunctions since the same fespace can be shared by multiple gridfunctions
104  }
105 
106  // Return whether we actually refined and increase the counter if we did
107  return refined && ++_p_ref_counter;
108 }
109 
110 bool
112 {
113  // Nothing to do if we've reached the max level of refinement
115  return false;
116 
117  // Perform h-refinement
119 
120  const bool refined = !_threshold_refiner->Stop();
121 
122  if (refined)
123  {
124  // Update all fespaces since the same mesh can be shared by multiple fespaces
126  // Update all gridfunctions now we have updated all fespaces
128  if (_rebalance)
130  }
131 
132  // Return whether we actually refined and increase the counter if we did
133  return refined && ++_h_ref_counter;
134 }
135 
136 #endif
Thin base for MFEM objects backed directly by MooseObject instead of UserObject.
Definition: MFEMObject.h:25
std::shared_ptr< mfem::ErrorEstimator > getEstimator() const
Method to fetch the error estimator after creation.
Definition: MFEMIndicator.h:58
const std::string & _estimator_name
The estimator/indicator&#39;s name.
MFEMProblem & getMFEMProblem()
Return the owning MFEM problem.
Definition: MFEMObject.h:45
const unsigned _max_h_level
The max no. of times h-refinement can be performed.
T & getMFEMObject(const std::string &system, const std::string &name, const THREAD_ID tid=0) const
Retrieve an MFEM object from the warehouse by system and name.
Definition: MFEMProblem.h:373
mfem::ParMesh & getParMesh() const
Get reference to the FE space&#39;s underlying mesh.
Definition: MFEMIndicator.h:38
bool _rebalance
Whether to rebalance the mesh after h-refinement.
void registerSystemAttributeName(const std::string &value)
This method is used to define the MOOSE system name that is used by the TheWarehouse object for stori...
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
Class to construct threshold refiner.
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
mfem::ParFiniteElementSpace & getFESpace() const
Get reference to FE space using the name we store when setting up this class.
Definition: MFEMIndicator.h:35
void registerBase(const std::string &value)
This method must be called from every base "Moose System" to create linkage with the Action System...
void mooseWarning(Args &&... args) const
void rebalanceMesh(mfem::ParMesh &pmesh)
Rebalance the (necessarily nonconforming) mesh.
Definition: MFEMProblem.C:609
bool pRefine()
Applies p-refinement wherever the refiner sees fit.
const unsigned _max_p_level
The max no. of times h-refinement can be performed.
registerMooseObject("MooseApp", MFEMRefinementMarker)
std::unique_ptr< mfem::ThresholdRefiner > _threshold_refiner
Unique pointer to underlying mfem::ThresholdRefiner object.
MFEMRefinementMarker(const InputParameters &params)
unsigned _p_ref_counter
The no. of times p-refinement has been performed.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void updateGridFunctions()
Calls Update() on all gridfunctions.
Definition: MFEMProblem.C:627
static InputParameters validParams()
Declare the common parameters required by MFEM MooseObject-backed classes.
Definition: MFEMObject.C:17
IntRange< T > make_range(T beg, T end)
bool hRefine()
Applies h-refinement wherever the refiner sees fit.
void updateFESpaces()
Calls Update() on all FE spaces.
Definition: MFEMProblem.C:620
static InputParameters validParams()
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
const MFEMIndicator * _estimator
Pointer to the estimator/indicator.
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
unsigned _h_ref_counter
The no. of times h-refinement has been performed.
const mfem::real_t _error_threshold
The error threshold determining which elements to refine.
void initialSetup()
Constructs associated mfem::ThresholdRefiner once mfem::ErrorEstimator is guaranteed to exist...