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