https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
13#include "MFEMFESpace.h"
14#include "MFEMProblem.h"
15
17
20{
22 params.registerBase("MFEMFESpaceHierarchy");
23 params.registerSystemAttributeName("MFEMFESpaceHierarchy");
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
42
43void
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
56 // Retrieve the base (coarsest) ParFiniteElementSpace from ProblemData.
57 auto base_fespace = base_fespace_object.getFESpace();
58 mfem::ParMesh * base_mesh = base_fespace->GetParMesh();
59 const int vdim = base_fespace->GetVDim();
60 const int ordering = base_fespace->GetOrdering();
61
62 // Construct the hierarchy with the coarse level.
63 // MOOSE owns the mesh and fespace, so pass ownM=false, ownFES=false.
64 _hierarchy = std::make_shared<mfem::ParFiniteElementSpaceHierarchy>(
65 base_mesh, base_fespace.get(), /*ownM=*/false, /*ownFES=*/false);
66
67 for (const auto & entry : refinements)
68 {
69 if (entry == "h")
70 _hierarchy->AddUniformlyRefinedLevel(vdim, ordering);
71 else
72 {
73 // p-refinement: parse the target polynomial order.
74 int new_order = 0;
75 try
76 {
77 new_order = std::stoi(entry);
78 }
79 catch (const std::exception &)
80 {
81 paramError("refinements",
82 "entry '",
83 entry,
84 "' is neither 'h' nor a valid integer polynomial order.");
85 }
86
87 if (new_order < 1)
88 paramError("refinements", "p-refinement order must be >= 1, got ", new_order, ".");
89
90 // Derive the new FEC name from the current finest level's FEC.
91 const std::string current_fec_name = _hierarchy->GetFinestFESpace().FEColl()->Name();
92 const auto pos = current_fec_name.rfind("_P");
93 if (pos == std::string::npos)
94 paramError("refinements",
95 "cannot infer polynomial order from FEC name '",
96 current_fec_name,
97 "' - expected a '_P<N>' suffix.");
98
99 const int current_order = std::stoi(current_fec_name.substr(pos + 2));
100 if (new_order <= current_order)
101 paramError("refinements",
102 "p-refinement orders must be strictly increasing; requested order ",
103 new_order,
104 " is not greater than the current finest level's order ",
105 current_order,
106 ".");
107
108 const std::string new_fec_name =
109 current_fec_name.substr(0, pos + 2) + std::to_string(new_order);
110
111 auto new_fec = std::unique_ptr<mfem::FiniteElementCollection>(
112 mfem::FiniteElementCollection::New(new_fec_name.c_str()));
113 _hierarchy->AddOrderRefinedLevel(new_fec.get(), vdim, ordering);
114 _level_fecs.push_back(std::move(new_fec));
115 }
116 }
117}
118#endif
registerMooseObject("MooseApp", MFEMFESpaceHierarchy)
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
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...
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...
void registerBase(const std::string &value)
This method must be called from every base "Moose System" to create linkage with the Action System.
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.
Builds and owns a mfem::ParFiniteElementSpaceHierarchy from a base FESpace by applying a sequence of ...
static InputParameters validParams()
std::shared_ptr< mfem::ParFiniteElementSpaceHierarchy > _hierarchy
The hierarchy - shared_ptr so that MFEMGeometricMultigridSolver and ProblemData can co-own.
std::vector< std::unique_ptr< mfem::FiniteElementCollection > > _level_fecs
FECs for p-refined levels.
MFEMFESpaceHierarchy(const InputParameters &parameters)
Constructs and stores an mfem::ParFiniteElementSpace object.
Definition MFEMFESpace.h:21
virtual bool isScalar() const =0
Thin base for MFEM objects backed directly by MooseObject instead of UserObject.
Definition MFEMObject.h:30
static InputParameters validParams()
Declare the common parameters required by MFEM MooseObject-backed classes.
Definition MFEMObject.C:17
MFEMProblem & getMFEMProblem()
Return the owning MFEM problem.
Definition MFEMObject.h:45
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.
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:457