10 #ifdef MOOSE_MFEM_ENABLED 25 "Builds a mfem::ParFiniteElementSpaceHierarchy from a base FESpace by applying a " 26 "sequence of h-refinements ('h') and/or p-refinements (integer order strings).");
28 "Name of the base (coarsest-level) FESpace object.");
31 "Ordered sequence of refinements. Each entry is 'h' for uniform h-refinement or " 32 "an integer string for p-refinement to that polynomial order (must be strictly " 33 "increasing across p-entries).");
46 const auto & fespace_name = getParam<MFEMFESpaceName>(
"fespace");
47 const auto & refinements = getParam<std::vector<std::string>>(
"refinements");
49 if (refinements.empty())
50 paramError(
"refinements",
"must not be empty.");
52 const auto & base_fespace_object =
58 auto base_fespace = base_fespace_object.getFESpace();
59 mfem::ParMesh * base_mesh = base_fespace->GetParMesh();
60 const int vdim = base_fespace->GetVDim();
61 const int ordering = base_fespace->GetOrdering();
65 _hierarchy = std::make_shared<mfem::ParFiniteElementSpaceHierarchy>(
66 base_mesh, base_fespace.get(),
false,
false);
68 for (
const auto & entry : refinements)
71 _hierarchy->AddUniformlyRefinedLevel(vdim, ordering);
78 new_order = std::stoi(entry);
80 catch (
const std::exception &)
85 "' is neither 'h' nor a valid integer polynomial order.");
89 paramError(
"refinements",
"p-refinement order must be >= 1, got ", new_order,
".");
92 const std::string current_fec_name =
_hierarchy->GetFinestFESpace().FEColl()->Name();
93 const auto pos = current_fec_name.rfind(
"_P");
94 if (pos == std::string::npos)
96 "cannot infer polynomial order from FEC name '",
98 "' - expected a '_P<N>' suffix.");
100 const int current_order = std::stoi(current_fec_name.substr(pos + 2));
101 if (new_order <= current_order)
103 "p-refinement orders must be strictly increasing; requested order ",
105 " is not greater than the current finest level's order ",
109 const std::string new_fec_name =
110 current_fec_name.substr(0, pos + 2) + std::to_string(new_order);
112 auto new_fec = std::unique_ptr<mfem::FiniteElementCollection>(
113 mfem::FiniteElementCollection::New(new_fec_name.c_str()));
114 _hierarchy->AddOrderRefinedLevel(new_fec.get(), vdim, ordering);
Thin base for MFEM objects backed directly by MooseObject instead of UserObject.
MFEMProblem & getMFEMProblem()
Return the owning MFEM problem.
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
std::vector< std::unique_ptr< mfem::FiniteElementCollection > > _level_fecs
FECs for p-refined levels.
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.
static InputParameters validParams()
MFEMFESpaceHierarchy(const InputParameters ¶meters)
std::shared_ptr< mfem::ParFiniteElementSpaceHierarchy > _hierarchy
The hierarchy - shared_ptr so that MFEMGeometricMultigridSolver and ProblemData can co-own...
Builds and owns a mfem::ParFiniteElementSpaceHierarchy from a base FESpace by applying a sequence of ...
registerMooseObject("MooseApp", MFEMFESpaceHierarchy)
Constructs and stores an mfem::ParFiniteElementSpace object.
static InputParameters validParams()
Declare the common parameters required by MFEM MooseObject-backed classes.