https://mooseframework.inl.gov
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 
14 #include "MFEMLinearSolverBase.h"
15 
16 namespace Moose::MFEM
17 {
25 template <class MFEMSolverType>
27 {
28 public:
30 
32 
33 protected:
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 
45 private:
46  void SetLORSolver();
47 
49  virtual void CheckSpectralEquivalence(mfem::ParBilinearForm & blf) const;
50 
55  virtual void SetupLOR(std::shared_ptr<Moose::MFEM::EquationSystem> equation_system);
56 };
57 
58 template <class MFEMSolverType>
61 {
63  params.addParam<bool>("low_order_refined", false, "Set usage of Low-Order Refined solver.");
64  return params;
65 }
66 
67 template <class MFEMSolverType>
69  : LinearSolverBase(parameters), _lor(parameters.get<bool>("low_order_refined"))
70 {
71 }
72 
73 template <typename T, typename... Ts>
74 constexpr bool is_any_of_v = (std::is_same_v<T, Ts> || ...);
75 
76 template <class MFEMSolverType>
77 void
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 
102 template <class MFEMSolverType>
103 void
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 
125 template <class MFEMSolverType>
126 void
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 
144 template <class MFEMSolverType>
145 void
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
const InputParameters & parameters() const
Get the parameters of the object.
Definition: MooseBase.h:131
virtual void SetSolverParameters(MFEMSolverType &solver)=0
Update the wrapped MFEM solver parameters.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
constexpr bool is_any_of_v
virtual void SetupLOR(std::shared_ptr< Moose::MFEM::EquationSystem > equation_system)
Rebuild any Low-Order-Refined components from the unreduced bilinear form.
static InputParameters validParams()
virtual void UpdateEquationSystemContext() override
Update the solver following any changes to the EquationSystem it is responsible for solving...
Base class for linear MFEM solvers and preconditioners.
bool _lor
Variable defining whether to use LOR solver.
virtual void CheckSpectralEquivalence(mfem::ParBilinearForm &blf) const
Checks for the correct configuration of quadrature bases for LOR spectral equivalence.
virtual void UpdateEquationSystemContext() override
Update the solver following any changes to the EquationSystem it is responsible for solving...
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...
Utilities for converting between vector(s) of libMesh Points and MFEM Vector(s).
Base class for LOR compatible linear MFEM solvers and preconditioners.
const Elem & get(const ElemType type_in)
LORLinearSolverBase(const InputParameters &parameters)