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 "Executioner.h" 13 : #include "MFEMProblemSolve.h" 14 : #include "MFEMProblem.h" 15 : 16 : InputParameters 17 7122 : MFEMProblemSolve::validParams() 18 : { 19 7122 : InputParameters params = emptyInputParameters(); 20 14244 : params.addClassDescription("Solve object for MFEM problems."); 21 28488 : params.addParam<std::string>("device", "Run app on the chosen device."); 22 28488 : params.addParam<bool>("gpu_aware_mpi", false, "Use GPU-aware MPI."); 23 28488 : MooseEnum assembly_levels("legacy full element partial none", "legacy", true); 24 21366 : params.addParam<MooseEnum>("assembly_level", assembly_levels, "Matrix assembly level."); 25 14244 : return params; 26 7122 : } 27 : 28 1463 : MFEMProblemSolve::MFEMProblemSolve( 29 : Executioner & ex, 30 1463 : std::vector<std::shared_ptr<Moose::MFEM::ProblemOperatorBase>> & problem_operators) 31 : : SolveObject(ex), 32 1463 : _mfem_problem(dynamic_cast<MFEMProblem &>(_problem)), 33 1463 : _problem_operators(problem_operators) 34 : { 35 1463 : if (const auto compute_device = _app.getComputeDevice()) 36 926 : _app.setMFEMDevice( 37 3704 : *compute_device, getParam<bool>("gpu_aware_mpi"), Moose::PassKey<MFEMProblemSolve>()); 38 : else 39 1611 : _app.setMFEMDevice(isParamValid("device") ? getParam<std::string>("device") 40 187 : : _app.isUltimateMaster() ? "cpu" 41 : : "", 42 1611 : getParam<bool>("gpu_aware_mpi"), 43 2000 : Moose::PassKey<MFEMProblemSolve>()); 44 1463 : } 45 : 46 : bool 47 2714 : MFEMProblemSolve::solve() 48 : { 49 2714 : if (_mfem_problem.shouldSolve()) 50 : { 51 4316 : for (const auto & problem_operator : _problem_operators) 52 2158 : problem_operator->Solve(); 53 : 54 : // Short-circuit evaluation guarantees we only do one of p- or h-refinement between solves 55 2184 : while (_mfem_problem.pRefine() || _mfem_problem.hRefine()) 56 : { 57 : // Reset linear solver and its preconditioner now the problem size has changed 58 26 : if (auto & solver = _mfem_problem.getProblemData().jacobian_solver) 59 : { 60 26 : if (auto * prec = solver->GetPreconditioner()) 61 26 : prec->ConstructSolver(); 62 26 : solver->ConstructSolver(); 63 : } 64 : 65 : // Reset gridfunctions 66 52 : for (const auto & problem_operator : _problem_operators) 67 26 : problem_operator->SetGridFunctions(); 68 : 69 : // Solve again 70 52 : for (const auto & problem_operator : _problem_operators) 71 26 : problem_operator->Solve(); 72 : } 73 : } 74 : 75 2714 : _mfem_problem.displaceMesh(); 76 : 77 2714 : return true; 78 : } 79 : 80 : #endif