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();
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{
106 if (!_lor)
107 return;
108
109 if (isParamSetByUser("preconditioner"))
110 paramError("preconditioner", "LOR solver cannot take a preconditioner");
111
112 SetupLOR();
113
114 if constexpr (is_any_of_v<MFEMSolverType, mfem::HypreAMS, mfem::HypreADS>)
115 if (_a->ParFESpace()->GetMesh()->GetTypicalElementGeometry() != mfem::Geometry::Type::CUBE)
116 mooseError("LOR HypreAMS/ADS Solver only supports hex meshes.");
117
118 SetLORSolver();
119}
120
121template <class MFEMSolverType>
122void
124{
125 if (!_equation_system)
126 mooseError("LOR solver setup requires an EquationSystem to be defined.");
127 if (_equation_system->IsComplex())
128 mooseError("LOR solve is not supported for complex equation systems.");
129 if (_equation_system->IsMultivariate())
130 mooseError("LOR solve is only supported for single-variable systems");
131
132 const auto & test_var_name = _equation_system->GetTestVarNames().at(0);
133 _a = &_equation_system->GetBilinearForm(test_var_name);
134 CheckSpectralEquivalence(*_a);
135 _ess_bdr_markers = _equation_system->GetEssentialBoundaryMarkers(test_var_name);
136 _a->ParFESpace()->GetEssentialTrueDofs(_ess_bdr_markers, _ess_tdofs);
137}
138
139template <class MFEMSolverType>
140void
142{
143 mfem::LORSolver<MFEMSolverType> * lor_solver;
144 if constexpr (is_any_of_v<MFEMSolverType, mfem::HypreGMRES, mfem::HypreFGMRES, mfem::HyprePCG>)
145 {
146 mfem::ParLORDiscretization lor_disc(*_a, _ess_tdofs);
147 lor_solver = new mfem::LORSolver<MFEMSolverType>(lor_disc, _a->ParFESpace()->GetComm());
148 }
149 else
150 lor_solver = new mfem::LORSolver<MFEMSolverType>(*_a, _ess_tdofs);
151 SetSolverParameters(lor_solver->GetSolver());
152 SetSolver(lor_solver);
153}
154
155} // namespace Moose::MFEM
156
157#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.
LORLinearSolverBase(const InputParameters &parameters)
virtual void UpdateEquationSystemContext() override
Update the solver following any changes to the weak form it is responsible for solving.
virtual void SetupLOR()
Rebuild any Low-Order-Refined components from the unreduced bilinear form.
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.
static InputParameters validParams()
Utilities for converting between vector(s) of libMesh Points and MFEM Vector(s).
constexpr bool is_any_of_v