https://mooseframework.inl.gov
MFEMLinearSolverBase.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 "MFEMLinearSolverBase.h"
13 #include "MFEMProblem.h"
14 #include "MFEMEigensolverBase.h"
15 
16 namespace Moose::MFEM
17 {
20 {
22  params.addClassDescription(
23  "Base class for defining linear mfem::Solver derived classes for Moose.");
24  params.addParam<bool>("low_order_refined", false, "Set usage of Low-Order Refined solver.");
25  return params;
26 }
27 
29  : SolverBase(parameters), _lor{getParam<bool>("low_order_refined")}, _preconditioner{nullptr}
30 {
31 }
32 
33 template <typename T>
34 void
36 {
37  if (isParamSetByUser("preconditioner"))
38  {
39  if (!_preconditioner)
40  {
42  "Moose::MFEM::SolverBase", getParam<MFEMSolverName>("preconditioner"));
43  // Take shared ownership so the preconditioner outlives the solver
44  _preconditioner = std::static_pointer_cast<LinearSolverBase>(pre.shared_from_this());
45  }
46 
47  if (dynamic_cast<const EigensolverBase *>(GetPreconditioner()))
48  mooseError("Eigensolvers cannot be used as preconditioners.");
49 
50  auto & mfem_pre = _preconditioner->GetSolver();
51  if constexpr (std::is_base_of_v<mfem::HypreSolver, T> || std::is_same_v<mfem::HypreAME, T>)
52  if (auto * const hypre_pre = dynamic_cast<mfem::HypreSolver *>(&mfem_pre))
53  solver.SetPreconditioner(*hypre_pre);
54  else
55  mooseError("hypre solver preconditioners must themselves be hypre solvers");
56  else
57  solver.SetPreconditioner(mfem_pre);
58  }
59 }
60 
61 template void LinearSolverBase::SetPreconditioner(mfem::CGSolver &);
62 template void LinearSolverBase::SetPreconditioner(mfem::GMRESSolver &);
63 template void LinearSolverBase::SetPreconditioner(mfem::HypreFGMRES &);
64 template void LinearSolverBase::SetPreconditioner(mfem::HypreGMRES &);
65 template void LinearSolverBase::SetPreconditioner(mfem::HyprePCG &);
66 template void LinearSolverBase::SetPreconditioner(mfem::HypreLOBPCG &);
67 template void LinearSolverBase::SetPreconditioner(mfem::HypreAME &);
68 
69 void
70 LinearSolverBase::SetOperator(mfem::OperatorHandle & op)
71 {
72  mooseAssert(_solver, "setOperator called before the solver was constructed");
73  _solver->SetOperator(*op);
74 }
75 
76 void
77 LinearSolverBase::CheckSpectralEquivalence(mfem::ParBilinearForm & blf) const
78 {
79  if (auto fec = dynamic_cast<const mfem::H1_FECollection *>(blf.FESpace()->FEColl()))
80  {
81  if (fec->GetBasisType() != mfem::BasisType::GaussLobatto)
82  mooseError("Low-Order-Refined solver requires the FESpace basis to be GaussLobatto "
83  "for H1 elements.");
84  }
85  else if (auto fec = dynamic_cast<const mfem::ND_FECollection *>(blf.FESpace()->FEColl()))
86  {
87  if (fec->GetClosedBasisType() != mfem::BasisType::GaussLobatto ||
88  fec->GetOpenBasisType() != mfem::BasisType::IntegratedGLL)
89  mooseError("Low-Order-Refined solver requires the FESpace closed-basis to be GaussLobatto "
90  "and the open-basis to be IntegratedGLL for ND elements.");
91  }
92  else if (auto fec = dynamic_cast<const mfem::RT_FECollection *>(blf.FESpace()->FEColl()))
93  {
94  if (fec->GetClosedBasisType() != mfem::BasisType::GaussLobatto ||
95  fec->GetOpenBasisType() != mfem::BasisType::IntegratedGLL)
96  mooseError("Low-Order-Refined solver requires the FESpace closed-basis to be GaussLobatto "
97  "and the open-basis to be IntegratedGLL for RT elements.");
98  }
99 }
100 } // namespace Moose::MFEM
101 
102 #endif
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:377
virtual void SetOperator(mfem::OperatorHandle &op)
Updates the solver at the operator level.
LinearSolverBase(const InputParameters &parameters)
std::unique_ptr< mfem::Solver > _solver
Solver to be used for the problem.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
LinearSolverBase * GetPreconditioner()
Returns this solver&#39;s preconditioner.
static InputParameters validParams()
std::shared_ptr< LinearSolverBase > _preconditioner
Preconditioner to be used for the problem.
Base class for linear MFEM solvers and preconditioners.
static InputParameters validParams()
Base class for wrapping mfem::Solver-derived classes.
void SetPreconditioner(T &solver)
Retrieves the preconditioner userobject if present, sets the member pointer to said object if still u...
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...
Utilities for converting between vector(s) of libMesh Points and MFEM Vector(s).
virtual void CheckSpectralEquivalence(mfem::ParBilinearForm &blf) const
Checks for the correct configuration of quadrature bases for LOR spectral equivalence.
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