10#ifdef MOOSE_MFEM_ENABLED
25template <
class MFEMSolverType>
41 mfem::ParBilinearForm *
_a;
55 virtual void SetupLOR(std::shared_ptr<Moose::MFEM::EquationSystem> equation_system);
58template <
class MFEMSolverType>
63 params.
addParam<
bool>(
"low_order_refined",
false,
"Set usage of Low-Order Refined solver.");
67template <
class MFEMSolverType>
69 :
LinearSolverBase(parameters), _lor(parameters.get<bool>(
"low_order_refined"))
73template <
typename T,
typename... Ts>
76template <
class MFEMSolverType>
80 if (
auto fec =
dynamic_cast<const mfem::H1_FECollection *
>(blf.FESpace()->FEColl()))
82 if (fec->GetBasisType() != mfem::BasisType::GaussLobatto)
83 mooseError(
"Low-Order-Refined solver requires the FESpace basis to be GaussLobatto "
86 else if (
auto fec =
dynamic_cast<const mfem::ND_FECollection *
>(blf.FESpace()->FEColl()))
88 if (fec->GetClosedBasisType() != mfem::BasisType::GaussLobatto ||
89 fec->GetOpenBasisType() != mfem::BasisType::IntegratedGLL)
90 mooseError(
"Low-Order-Refined solver requires the FESpace closed-basis to be GaussLobatto "
91 "and the open-basis to be IntegratedGLL for ND elements.");
93 else if (
auto fec =
dynamic_cast<const mfem::RT_FECollection *
>(blf.FESpace()->FEColl()))
95 if (fec->GetClosedBasisType() != mfem::BasisType::GaussLobatto ||
96 fec->GetOpenBasisType() != mfem::BasisType::IntegratedGLL)
97 mooseError(
"Low-Order-Refined solver requires the FESpace closed-basis to be GaussLobatto "
98 "and the open-basis to be IntegratedGLL for RT elements.");
102template <
class MFEMSolverType>
107 if (_lor && GetPreconditioner())
108 mooseError(
"LOR solver cannot take a preconditioner");
111 SetupLOR(_equation_system);
112 if constexpr (is_any_of_v<MFEMSolverType, mfem::HypreAMS, mfem::HypreADS>)
113 if (_a->ParFESpace()->GetMesh()->GetTypicalElementGeometry() != mfem::Geometry::Type::CUBE)
114 mooseError(
"LOR HypreAMS/ADS Solver only supports hex meshes.");
118 mfem::OperatorJacobiSmoother,
119 mfem::HypreBoomerAMG,
122 SetPreconditioner(
static_cast<MFEMSolverType &
>(GetSolver()));
125template <
class MFEMSolverType>
128 std::shared_ptr<Moose::MFEM::EquationSystem> equation_system)
130 if (!equation_system)
131 mooseError(
"LOR solver setup requires an EquationSystem to be defined.");
132 if (equation_system->IsComplex())
133 mooseError(
"LOR solve is not supported for complex equation systems.");
134 if (equation_system->IsMultivariate())
135 mooseError(
"LOR solve is only supported for single-variable systems");
137 const auto & test_var_name = equation_system->GetTestVarNames().at(0);
138 _a = &equation_system->GetBilinearForm(test_var_name);
139 CheckSpectralEquivalence(*_a);
140 _ess_bdr_markers = equation_system->GetEssentialBoundaryMarkers(test_var_name);
141 _a->ParFESpace()->GetEssentialTrueDofs(_ess_bdr_markers, _ess_tdofs);
144template <
class MFEMSolverType>
148 mfem::LORSolver<MFEMSolverType> * lor_solver;
149 if constexpr (is_any_of_v<MFEMSolverType, mfem::HypreGMRES, mfem::HypreFGMRES, mfem::HyprePCG>)
151 mfem::ParLORDiscretization lor_disc(*_a, _ess_tdofs);
152 lor_solver =
new mfem::LORSolver<MFEMSolverType>(lor_disc, _a->ParFESpace()->GetComm());
155 lor_solver =
new mfem::LORSolver<MFEMSolverType>(*_a, _ess_tdofs);
156 SetSolverParameters(lor_solver->GetSolver());
157 SetSolver(lor_solver);
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
const InputParameters & parameters() const
Get the parameters of the object.
Base class for LOR compatible linear MFEM solvers and preconditioners.
bool _lor
Variable defining whether to use LOR solver.
virtual void SetupLOR(std::shared_ptr< Moose::MFEM::EquationSystem > equation_system)
Rebuild any Low-Order-Refined components from the unreduced bilinear form.
mfem::Array< int > _ess_bdr_markers
LORLinearSolverBase(const InputParameters ¶meters)
virtual void UpdateEquationSystemContext() override
Update the solver following any changes to the EquationSystem it is responsible for solving.
static InputParameters validParams()
virtual void SetSolverParameters(MFEMSolverType &solver)=0
Update the wrapped MFEM solver parameters.
virtual void CheckSpectralEquivalence(mfem::ParBilinearForm &blf) const
Checks for the correct configuration of quadrature bases for LOR spectral equivalence.
mfem::ParBilinearForm * _a
mfem::Array< int > _ess_tdofs
Base class for linear MFEM solvers and preconditioners.
virtual void UpdateEquationSystemContext() override
Update the solver following any changes to the EquationSystem it is responsible for solving.
static InputParameters validParams()
Utilities for converting between vector(s) of libMesh Points and MFEM Vector(s).
constexpr bool is_any_of_v