https://mooseframework.inl.gov
MFEMFESpaceHierarchy.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 "MFEMFESpaceHierarchy.h"
13 #include "MFEMFESpace.h"
14 #include "MFEMProblem.h"
15 
17 
20 {
22  params.registerBase("MFEMFESpaceHierarchy");
23  params.registerSystemAttributeName("MFEMFESpaceHierarchy");
24  params.addClassDescription(
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).");
27  params.addRequiredParam<MFEMFESpaceName>("fespace",
28  "Name of the base (coarsest-level) FESpace object.");
29  params.addRequiredParam<std::vector<std::string>>(
30  "refinements",
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).");
34  return params;
35 }
36 
38  : MFEMObject(parameters)
39 {
41 }
42 
43 void
45 {
46  const auto & fespace_name = getParam<MFEMFESpaceName>("fespace");
47  const auto & refinements = getParam<std::vector<std::string>>("refinements");
48 
49  if (refinements.empty())
50  paramError("refinements", "must not be empty.");
51 
52  const auto & base_fespace_object =
53  getMFEMProblem().getMFEMObject<MFEMFESpace>("MFEMFESpace", fespace_name);
54  _is_scalar = base_fespace_object.isScalar();
55  _is_vector = base_fespace_object.isVector();
56 
57  // Retrieve the base (coarsest) ParFiniteElementSpace from ProblemData.
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();
62 
63  // Construct the hierarchy with the coarse level.
64  // MOOSE owns the mesh and fespace, so pass ownM=false, ownFES=false.
65  _hierarchy = std::make_shared<mfem::ParFiniteElementSpaceHierarchy>(
66  base_mesh, base_fespace.get(), /*ownM=*/false, /*ownFES=*/false);
67 
68  for (const auto & entry : refinements)
69  {
70  if (entry == "h")
71  _hierarchy->AddUniformlyRefinedLevel(vdim, ordering);
72  else
73  {
74  // p-refinement: parse the target polynomial order.
75  int new_order = 0;
76  try
77  {
78  new_order = std::stoi(entry);
79  }
80  catch (const std::exception &)
81  {
82  paramError("refinements",
83  "entry '",
84  entry,
85  "' is neither 'h' nor a valid integer polynomial order.");
86  }
87 
88  if (new_order < 1)
89  paramError("refinements", "p-refinement order must be >= 1, got ", new_order, ".");
90 
91  // Derive the new FEC name from the current finest level's FEC.
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)
95  paramError("refinements",
96  "cannot infer polynomial order from FEC name '",
97  current_fec_name,
98  "' - expected a '_P<N>' suffix.");
99 
100  const int current_order = std::stoi(current_fec_name.substr(pos + 2));
101  if (new_order <= current_order)
102  paramError("refinements",
103  "p-refinement orders must be strictly increasing; requested order ",
104  new_order,
105  " is not greater than the current finest level's order ",
106  current_order,
107  ".");
108 
109  const std::string new_fec_name =
110  current_fec_name.substr(0, pos + 2) + std::to_string(new_order);
111 
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);
115  _level_fecs.push_back(std::move(new_fec));
116  }
117  }
118 }
119 #endif
Thin base for MFEM objects backed directly by MooseObject instead of UserObject.
Definition: MFEMObject.h:25
MFEMProblem & getMFEMProblem()
Return the owning MFEM problem.
Definition: MFEMObject.h:45
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition: MooseBase.h:467
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.
Definition: MFEMProblem.h:404
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...
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...
static InputParameters validParams()
void registerBase(const std::string &value)
This method must be called from every base "Moose System" to create linkage with the Action System...
MFEMFESpaceHierarchy(const InputParameters &parameters)
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.
Definition: MFEMFESpace.h:20
static InputParameters validParams()
Declare the common parameters required by MFEM MooseObject-backed classes.
Definition: MFEMObject.C:17
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...