LCOV - code coverage report
Current view: top level - src/mfem/solvers - MFEMSolverBase.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #31653 (2d163b) with base 0cc44f Lines: 31 36 86.1 %
Date: 2025-11-04 20:38:02 Functions: 10 10 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 "MFEMSolverBase.h"
      13             : 
      14             : InputParameters
      15       94896 : MFEMSolverBase::validParams()
      16             : {
      17       94896 :   InputParameters params = MFEMGeneralUserObject::validParams();
      18      189792 :   params.addClassDescription("Base class for defining mfem::Solver derived classes for Moose.");
      19      189792 :   params.registerBase("MFEMSolverBase");
      20      284688 :   params.addParam<bool>("low_order_refined", false, "Set usage of Low-Order Refined solver.");
      21             : 
      22       94896 :   return params;
      23           0 : }
      24             : 
      25         688 : MFEMSolverBase::MFEMSolverBase(const InputParameters & parameters)
      26             :   : MFEMGeneralUserObject(parameters),
      27         688 :     _lor{getParam<bool>("low_order_refined")},
      28         688 :     _solver{nullptr},
      29         688 :     _preconditioner{nullptr}
      30             : {
      31         688 : }
      32             : 
      33             : template <typename T>
      34             : void
      35        1110 : MFEMSolverBase::setPreconditioner(T & solver)
      36             : {
      37        3330 :   if (isParamSetByUser("preconditioner"))
      38             :   {
      39        1082 :     if (!_preconditioner)
      40         277 :       _preconditioner =
      41         831 :           &const_cast<MFEMSolverBase &>(getUserObject<MFEMSolverBase>("preconditioner"));
      42             : 
      43        1082 :     auto & mfem_pre = _preconditioner->getSolver();
      44             :     if constexpr (std::is_base_of_v<mfem::HypreSolver, T>)
      45         923 :       if (auto * const hypre_pre = dynamic_cast<mfem::HypreSolver *>(&mfem_pre))
      46         923 :         solver.SetPreconditioner(*hypre_pre);
      47             :       else
      48           0 :         mooseError("hypre solver preconditioners must themselves be hypre solvers");
      49             :     else
      50         159 :       solver.SetPreconditioner(mfem_pre);
      51             :   }
      52        1110 : }
      53             : 
      54             : template void MFEMSolverBase::setPreconditioner(mfem::CGSolver &);
      55             : template void MFEMSolverBase::setPreconditioner(mfem::GMRESSolver &);
      56             : template void MFEMSolverBase::setPreconditioner(mfem::HypreFGMRES &);
      57             : template void MFEMSolverBase::setPreconditioner(mfem::HypreGMRES &);
      58             : template void MFEMSolverBase::setPreconditioner(mfem::HyprePCG &);
      59             : 
      60             : template void MFEMSolverBase::setPreconditioner(mfem::patched::HypreGMRES &);
      61             : template void MFEMSolverBase::setPreconditioner(mfem::patched::HyprePCG &);
      62             : 
      63             : void
      64          65 : MFEMSolverBase::checkSpectralEquivalence(mfem::ParBilinearForm & blf) const
      65             : {
      66          65 :   if (auto fec = dynamic_cast<const mfem::H1_FECollection *>(blf.FESpace()->FEColl()))
      67             :   {
      68          48 :     if (fec->GetBasisType() != mfem::BasisType::GaussLobatto)
      69           0 :       mooseError("Low-Order-Refined solver requires the FESpace basis to be GaussLobatto "
      70             :                  "for H1 elements.");
      71             :   }
      72          17 :   else if (auto fec = dynamic_cast<const mfem::ND_FECollection *>(blf.FESpace()->FEColl()))
      73             :   {
      74          18 :     if (fec->GetClosedBasisType() != mfem::BasisType::GaussLobatto ||
      75           9 :         fec->GetOpenBasisType() != mfem::BasisType::IntegratedGLL)
      76           0 :       mooseError("Low-Order-Refined solver requires the FESpace closed-basis to be GaussLobatto "
      77             :                  "and the open-basis to be IntegratedGLL for ND elements.");
      78             :   }
      79           8 :   else if (auto fec = dynamic_cast<const mfem::RT_FECollection *>(blf.FESpace()->FEColl()))
      80             :   {
      81          16 :     if (fec->GetClosedBasisType() != mfem::BasisType::GaussLobatto ||
      82           8 :         fec->GetOpenBasisType() != mfem::BasisType::IntegratedGLL)
      83           0 :       mooseError("Low-Order-Refined solver requires the FESpace closed-basis to be GaussLobatto "
      84             :                  "and the open-basis to be IntegratedGLL for RT elements.");
      85             :   }
      86          65 : }
      87             : 
      88             : #endif

Generated by: LCOV version 1.14