https://mooseframework.inl.gov
Loading...
Searching...
No Matches
MFEMLORLinearSolverBase.h
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#pragma once
13
15
16namespace Moose::MFEM
17{
25template <class MFEMSolverType>
27{
28public:
30
32
33protected:
35 virtual void SetSolverParameters(MFEMSolverType & solver) = 0;
36
37 virtual void UpdateEquationSystemContext() override;
38
40 bool _lor;
41 mfem::ParBilinearForm * _a;
42 mfem::Array<int> _ess_bdr_markers;
43 mfem::Array<int> _ess_tdofs;
44
45private:
47
49 virtual void CheckSpectralEquivalence(mfem::ParBilinearForm & blf) const;
50
55 virtual void SetupLOR(std::shared_ptr<Moose::MFEM::EquationSystem> equation_system);
56};
57
58template <class MFEMSolverType>
61{
63 params.addParam<bool>("low_order_refined", false, "Set usage of Low-Order Refined solver.");
64 return params;
65}
66
67template <class MFEMSolverType>
69 : LinearSolverBase(parameters), _lor(parameters.get<bool>("low_order_refined"))
70{
71}
72
73template <typename T, typename... Ts>
74constexpr bool is_any_of_v = (std::is_same_v<T, Ts> || ...);
75
76template <class MFEMSolverType>
77void
79{
80 if (auto fec = dynamic_cast<const mfem::H1_FECollection *>(blf.FESpace()->FEColl()))
81 {
82 if (fec->GetBasisType() != mfem::BasisType::GaussLobatto)
83 mooseError("Low-Order-Refined solver requires the FESpace basis to be GaussLobatto "
84 "for H1 elements.");
85 }
86 else if (auto fec = dynamic_cast<const mfem::ND_FECollection *>(blf.FESpace()->FEColl()))
87 {
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.");
92 }
93 else if (auto fec = dynamic_cast<const mfem::RT_FECollection *>(blf.FESpace()->FEColl()))
94 {
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.");
99 }
100}
101
102template <class MFEMSolverType>
103void
105{
107 if (_lor && GetPreconditioner())
108 mooseError("LOR solver cannot take a preconditioner");
109 if (_lor)
110 {
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.");
115 SetLORSolver();
116 }
117 else if constexpr (!is_any_of_v<MFEMSolverType,
118 mfem::OperatorJacobiSmoother,
119 mfem::HypreBoomerAMG,
120 mfem::HypreAMS,
121 mfem::HypreADS>)
122 SetPreconditioner(static_cast<MFEMSolverType &>(GetSolver()));
123}
124
125template <class MFEMSolverType>
126void
128 std::shared_ptr<Moose::MFEM::EquationSystem> equation_system)
129{
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");
136
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);
142}
143
144template <class MFEMSolverType>
145void
147{
148 mfem::LORSolver<MFEMSolverType> * lor_solver;
149 if constexpr (is_any_of_v<MFEMSolverType, mfem::HypreGMRES, mfem::HypreFGMRES, mfem::HyprePCG>)
150 {
151 mfem::ParLORDiscretization lor_disc(*_a, _ess_tdofs);
152 lor_solver = new mfem::LORSolver<MFEMSolverType>(lor_disc, _a->ParFESpace()->GetComm());
153 }
154 else
155 lor_solver = new mfem::LORSolver<MFEMSolverType>(*_a, _ess_tdofs);
156 SetSolverParameters(lor_solver->GetSolver());
157 SetSolver(lor_solver);
158}
159
160} // namespace Moose::MFEM
161
162#endif
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
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.
const InputParameters & parameters() const
Get the parameters of the object.
Definition MooseBase.h:131
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.
LORLinearSolverBase(const InputParameters &parameters)
virtual void UpdateEquationSystemContext() override
Update the solver following any changes to the EquationSystem it is responsible for solving.
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.
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