LCOV - code coverage report
Current view: top level - src/mfem/solvers - MFEMLinearSolverBase.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: fa5e60 Lines: 33 39 84.6 %
Date: 2026-06-24 08:03:36 Functions: 11 11 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : {
      18             : InputParameters
      19       31552 : LinearSolverBase::validParams()
      20             : {
      21       31552 :   InputParameters params = SolverBase::validParams();
      22       63104 :   params.addClassDescription(
      23             :       "Base class for defining linear mfem::Solver derived classes for Moose.");
      24       94656 :   params.addParam<bool>("low_order_refined", false, "Set usage of Low-Order Refined solver.");
      25       31552 :   return params;
      26           0 : }
      27             : 
      28        2139 : LinearSolverBase::LinearSolverBase(const InputParameters & parameters)
      29        6417 :   : SolverBase(parameters), _lor{getParam<bool>("low_order_refined")}, _preconditioner{nullptr}
      30             : {
      31        2139 : }
      32             : 
      33             : template <typename T>
      34             : void
      35         965 : LinearSolverBase::SetPreconditioner(T & solver)
      36             : {
      37        2895 :   if (isParamSetByUser("preconditioner"))
      38             :   {
      39         938 :     if (!_preconditioner)
      40             :     {
      41        1734 :       auto & pre = getMFEMProblem().getMFEMObject<LinearSolverBase>(
      42        2601 :           "Moose::MFEM::SolverBase", getParam<MFEMSolverName>("preconditioner"));
      43             :       // Take shared ownership so the preconditioner outlives the solver
      44         867 :       _preconditioner = std::static_pointer_cast<LinearSolverBase>(pre.shared_from_this());
      45             :     }
      46             : 
      47         938 :     if (dynamic_cast<const EigensolverBase *>(GetPreconditioner()))
      48           0 :       mooseError("Eigensolvers cannot be used as preconditioners.");
      49             : 
      50         938 :     auto & mfem_pre = _preconditioner->GetSolver();
      51             :     if constexpr (std::is_base_of_v<mfem::HypreSolver, T> || std::is_same_v<mfem::HypreAME, T>)
      52         831 :       if (auto * const hypre_pre = dynamic_cast<mfem::HypreSolver *>(&mfem_pre))
      53         831 :         solver.SetPreconditioner(*hypre_pre);
      54             :       else
      55           0 :         mooseError("hypre solver preconditioners must themselves be hypre solvers");
      56             :     else
      57         107 :       solver.SetPreconditioner(mfem_pre);
      58             :   }
      59         965 : }
      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        2154 : LinearSolverBase::SetOperator(mfem::OperatorHandle & op)
      71             : {
      72             :   mooseAssert(_solver, "setOperator called before the solver was constructed");
      73        2154 :   _solver->SetOperator(*op);
      74        2154 : }
      75             : 
      76             : void
      77          57 : LinearSolverBase::CheckSpectralEquivalence(mfem::ParBilinearForm & blf) const
      78             : {
      79          57 :   if (auto fec = dynamic_cast<const mfem::H1_FECollection *>(blf.FESpace()->FEColl()))
      80             :   {
      81          43 :     if (fec->GetBasisType() != mfem::BasisType::GaussLobatto)
      82           0 :       mooseError("Low-Order-Refined solver requires the FESpace basis to be GaussLobatto "
      83             :                  "for H1 elements.");
      84             :   }
      85          14 :   else if (auto fec = dynamic_cast<const mfem::ND_FECollection *>(blf.FESpace()->FEColl()))
      86             :   {
      87          14 :     if (fec->GetClosedBasisType() != mfem::BasisType::GaussLobatto ||
      88           7 :         fec->GetOpenBasisType() != mfem::BasisType::IntegratedGLL)
      89           0 :       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           7 :   else if (auto fec = dynamic_cast<const mfem::RT_FECollection *>(blf.FESpace()->FEColl()))
      93             :   {
      94          14 :     if (fec->GetClosedBasisType() != mfem::BasisType::GaussLobatto ||
      95           7 :         fec->GetOpenBasisType() != mfem::BasisType::IntegratedGLL)
      96           0 :       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          57 : }
     100             : } // namespace Moose::MFEM
     101             : 
     102             : #endif

Generated by: LCOV version 1.14