https://mooseframework.inl.gov
MFEMSolverBase.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 "MFEMSolverBase.h"
13 #include "MFEMProblem.h"
14 #include "MFEMEigensolverBase.h"
15 
18 {
20  params.addClassDescription("Base class for defining mfem::Solver derived classes for Moose.");
21  params.registerBase("MFEMSolverBase");
22  params.registerSystemAttributeName("MFEMSolverBase");
23  params.addParam<bool>("low_order_refined", false, "Set usage of Low-Order Refined solver.");
24 
25  return params;
26 }
27 
29  : MFEMObject(parameters),
30  _lor{getParam<bool>("low_order_refined")},
31  _solver{nullptr},
32  _preconditioner{nullptr}
33 {
34 }
35 
36 template <typename T>
37 void
39 {
40  if (isParamSetByUser("preconditioner"))
41  {
42  if (!_preconditioner)
43  {
44  auto & pre = const_cast<MFEMSolverBase &>(getMFEMProblem().getMFEMObject<MFEMSolverBase>(
45  "MFEMSolverBase", getParam<MFEMSolverName>("preconditioner")));
46  // Take shared ownership so the preconditioner outlives the solver
47  _preconditioner = std::static_pointer_cast<MFEMSolverBase>(pre.shared_from_this());
48  }
49 
50  if (dynamic_cast<const MFEMEigensolverBase *>(getPreconditioner()))
51  mooseError("Eigensolvers cannot be used as preconditioners.");
52 
53  auto & mfem_pre = _preconditioner->getSolver();
54  if constexpr (std::is_base_of_v<mfem::HypreSolver, T> || std::is_same_v<mfem::HypreAME, T>)
55  if (auto * const hypre_pre = dynamic_cast<mfem::HypreSolver *>(&mfem_pre))
56  solver.SetPreconditioner(*hypre_pre);
57  else
58  mooseError("hypre solver preconditioners must themselves be hypre solvers");
59  else
60  solver.SetPreconditioner(mfem_pre);
61  }
62 }
63 
64 template void MFEMSolverBase::setPreconditioner(mfem::CGSolver &);
65 template void MFEMSolverBase::setPreconditioner(mfem::GMRESSolver &);
66 template void MFEMSolverBase::setPreconditioner(mfem::HypreFGMRES &);
67 template void MFEMSolverBase::setPreconditioner(mfem::HypreGMRES &);
68 template void MFEMSolverBase::setPreconditioner(mfem::HyprePCG &);
69 template void MFEMSolverBase::setPreconditioner(mfem::HypreLOBPCG &);
70 template void MFEMSolverBase::setPreconditioner(mfem::HypreAME &);
71 
72 void
73 MFEMSolverBase::setOperator(mfem::OperatorHandle & op)
74 {
75  mooseAssert(_solver, "setOperator called before the solver was constructed");
76  _solver->SetOperator(*op);
77 }
78 
79 void
80 MFEMSolverBase::checkSpectralEquivalence(mfem::ParBilinearForm & blf) const
81 {
82  if (auto fec = dynamic_cast<const mfem::H1_FECollection *>(blf.FESpace()->FEColl()))
83  {
84  if (fec->GetBasisType() != mfem::BasisType::GaussLobatto)
85  mooseError("Low-Order-Refined solver requires the FESpace basis to be GaussLobatto "
86  "for H1 elements.");
87  }
88  else if (auto fec = dynamic_cast<const mfem::ND_FECollection *>(blf.FESpace()->FEColl()))
89  {
90  if (fec->GetClosedBasisType() != mfem::BasisType::GaussLobatto ||
91  fec->GetOpenBasisType() != mfem::BasisType::IntegratedGLL)
92  mooseError("Low-Order-Refined solver requires the FESpace closed-basis to be GaussLobatto "
93  "and the open-basis to be IntegratedGLL for ND elements.");
94  }
95  else if (auto fec = dynamic_cast<const mfem::RT_FECollection *>(blf.FESpace()->FEColl()))
96  {
97  if (fec->GetClosedBasisType() != mfem::BasisType::GaussLobatto ||
98  fec->GetOpenBasisType() != mfem::BasisType::IntegratedGLL)
99  mooseError("Low-Order-Refined solver requires the FESpace closed-basis to be GaussLobatto "
100  "and the open-basis to be IntegratedGLL for RT elements.");
101  }
102 }
103 
104 #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
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:386
virtual void checkSpectralEquivalence(mfem::ParBilinearForm &blf) const
Checks for the correct configuration of quadrature bases for LOR spectral equivalence.
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...
static InputParameters validParams()
void setPreconditioner(T &solver)
Retrieves the preconditioner userobject if present, sets the member pointer to said object if still u...
void registerBase(const std::string &value)
This method must be called from every base "Moose System" to create linkage with the Action System...
MFEMSolverBase(const InputParameters &parameters)
MFEMSolverBase * getPreconditioner()
Returns this solver&#39;s preconditioner.
static InputParameters validParams()
Declare the common parameters required by MFEM MooseObject-backed classes.
Definition: MFEMObject.C:17
Base class for wrapping mfem::Solver-derived classes.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition: MooseBase.h:281
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...
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...
virtual void setOperator(mfem::OperatorHandle &op)
Sets an already-assembled operator on the wrapped solver.
bool isParamSetByUser(const std::string &name) const
Test if the supplied parameter is set by a user, as opposed to not set or set to default.
Definition: MooseBase.h:215
std::unique_ptr< mfem::Solver > _solver
Solver to be used for the problem.
std::shared_ptr< MFEMSolverBase > _preconditioner
Preconditioner to be used for the problem.