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 "MFEMHypreBoomerAMG.h" 13 : #include "MFEMFESpace.h" 14 : #include "MFEMProblem.h" 15 : 16 : registerMooseObject("MooseApp", MFEMHypreBoomerAMG); 17 : 18 : InputParameters 19 3624 : MFEMHypreBoomerAMG::validParams() 20 : { 21 3624 : InputParameters params = Moose::MFEM::LinearSolverBase::validParams(); 22 7248 : params.addClassDescription("Hypre BoomerAMG solver and preconditioner for the iterative solution " 23 : "of MFEM equation systems."); 24 14496 : params.addParam<mfem::real_t>("l_tol", 1e-5, "Set the relative tolerance."); 25 14496 : params.addParam<int>("l_max_its", 10000, "Set the maximum number of iterations."); 26 14496 : params.addParam<int>("print_level", 2, "Set the solver verbosity."); 27 14496 : params.addParam<MFEMFESpaceName>( 28 : "fespace", "H1 FESpace to use in HypreBoomerAMG setup for elasticity problems."); 29 10872 : params.addParam<mfem::real_t>( 30 7248 : "strength_threshold", 0.25, "HypreBoomerAMG strong threshold. Defaults to 0.25."); 31 14496 : MooseEnum errmode("ignore=0 warn=1 abort=2", "abort", false); 32 10872 : params.addParam<MooseEnum>("error_mode", errmode, "Set the behavior for treating hypre errors."); 33 7248 : return params; 34 3624 : } 35 : 36 763 : MFEMHypreBoomerAMG::MFEMHypreBoomerAMG(const InputParameters & parameters) 37 : : Moose::MFEM::LinearSolverBase(parameters), 38 759 : _mfem_fespace( 39 763 : isParamSetByUser("fespace") 40 763 : ? getMFEMProblem() 41 779 : .getMFEMObject<MFEMFESpace>("MFEMFESpace", getParam<MFEMFESpaceName>("fespace")) 42 : .getFESpace() 43 763 : : nullptr) 44 : { 45 763 : ConstructSolver(); 46 763 : } 47 : 48 763 : MFEMHypreBoomerAMG::~MFEMHypreBoomerAMG() { _solver.reset(); } 49 : 50 : void 51 789 : MFEMHypreBoomerAMG::ConstructSolver() 52 : { 53 789 : auto solver = std::make_unique<mfem::HypreBoomerAMG>(); 54 : 55 1578 : solver->iterative_mode = getParam<bool>("use_initial_guess"); 56 1578 : solver->SetTol(getParam<mfem::real_t>("l_tol")); 57 1578 : solver->SetMaxIter(getParam<int>("l_max_its")); 58 1578 : solver->SetPrintLevel(getParam<int>("print_level")); 59 1578 : solver->SetStrengthThresh(getParam<mfem::real_t>("strength_threshold")); 60 1578 : solver->SetErrorMode(mfem::HypreSolver::ErrorMode(int(getParam<MooseEnum>("error_mode")))); 61 : 62 789 : if (_mfem_fespace && !mfem::HypreUsingGPU()) 63 4 : solver->SetElasticityOptions(_mfem_fespace.get()); 64 : 65 789 : _solver = std::move(solver); 66 789 : } 67 : 68 : void 69 4 : MFEMHypreBoomerAMG::SetupLOR(mfem::ParBilinearForm & a, mfem::Array<int> & tdofs) 70 : { 71 4 : if (_lor) 72 : { 73 2 : CheckSpectralEquivalence(a); 74 2 : auto lor_solver = new mfem::LORSolver<mfem::HypreBoomerAMG>(a, tdofs); 75 4 : lor_solver->GetSolver().SetTol(getParam<mfem::real_t>("l_tol")); 76 4 : lor_solver->GetSolver().SetMaxIter(getParam<int>("l_max_its")); 77 4 : lor_solver->GetSolver().SetPrintLevel(getParam<int>("print_level")); 78 4 : lor_solver->GetSolver().SetStrengthThresh(getParam<mfem::real_t>("strength_threshold")); 79 : 80 : /// HypreBoomerAMG options for elasticity problems are not compatible with GPU execution 81 2 : if (_mfem_fespace && !mfem::HypreUsingGPU()) 82 0 : lor_solver->GetSolver().SetElasticityOptions(_mfem_fespace.get()); 83 : 84 2 : _solver.reset(lor_solver); 85 : } 86 4 : } 87 : 88 : #endif