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 6918 : MFEMProblemSolve::validParams() 18 : { 19 6918 : InputParameters params = emptyInputParameters(); 20 13836 : params.addClassDescription("Solve object for MFEM problems."); 21 27672 : params.addParam<unsigned int>("nl_max_its", 1, "Max Nonlinear Iterations"); 22 27672 : params.addParam<Real>("nl_abs_tol", 1.0e-50, "Nonlinear Absolute Tolerance"); 23 27672 : params.addParam<Real>("nl_rel_tol", 1.0e-8, "Nonlinear Relative Tolerance"); 24 27672 : params.addParam<unsigned int>("print_level", 1, "Print level"); 25 27672 : params.addParam<std::string>("device", "Run app on the chosen device."); 26 27672 : MooseEnum assembly_levels("legacy full element partial none", "legacy", true); 27 20754 : params.addParam<MooseEnum>("assembly_level", assembly_levels, "Matrix assembly level."); 28 13836 : return params; 29 6918 : } 30 : 31 1361 : MFEMProblemSolve::MFEMProblemSolve( 32 : Executioner & ex, 33 1361 : std::vector<std::shared_ptr<Moose::MFEM::ProblemOperatorBase>> & problem_operators) 34 : : SolveObject(ex), 35 1361 : _mfem_problem(dynamic_cast<MFEMProblem &>(_problem)), 36 1361 : _problem_operators(problem_operators), 37 2722 : _nl_max_its(getParam<unsigned int>("nl_max_its")), 38 2722 : _nl_abs_tol(getParam<mfem::real_t>("nl_abs_tol")), 39 2722 : _nl_rel_tol(getParam<mfem::real_t>("nl_rel_tol")), 40 4083 : _print_level(getParam<unsigned int>("print_level")) 41 : { 42 1361 : if (const auto compute_device = _app.getComputeDevice()) 43 853 : _app.setMFEMDevice(*compute_device, Moose::PassKey<MFEMProblemSolve>()); 44 : else 45 2032 : _app.setMFEMDevice(isParamValid("device") ? getParam<std::string>("device") 46 162 : : _app.isUltimateMaster() ? "cpu" 47 : : "", 48 1869 : Moose::PassKey<MFEMProblemSolve>()); 49 1361 : _mfem_problem.addMFEMNonlinearSolver(_nl_max_its, _nl_abs_tol, _nl_rel_tol, _print_level); 50 1361 : } 51 : 52 : bool 53 2371 : MFEMProblemSolve::solve() 54 : { 55 : // FixedPointSolve::solve() is libMesh specific, so we need 56 : // to include all steps therein relevant to the MFEM backend here. 57 : 58 2371 : bool converged = true; 59 : 60 : // need to back up multi-apps even when not doing fixed point iteration for recovering from failed 61 : // multiapp solve 62 2371 : _mfem_problem.backupMultiApps(EXEC_MULTIAPP_FIXED_POINT_BEGIN); 63 2371 : _mfem_problem.backupMultiApps(EXEC_TIMESTEP_BEGIN); 64 2371 : _mfem_problem.backupMultiApps(EXEC_TIMESTEP_END); 65 2371 : _mfem_problem.backupMultiApps(EXEC_MULTIAPP_FIXED_POINT_END); 66 : 67 : // Solve step begins 68 2371 : _executioner.preSolve(); 69 2371 : _mfem_problem.execTransfers(EXEC_TIMESTEP_BEGIN); 70 : 71 2371 : _mfem_problem.execute(EXEC_MULTIAPP_FIXED_POINT_BEGIN); 72 2371 : _mfem_problem.execTransfers(EXEC_MULTIAPP_FIXED_POINT_BEGIN); 73 2371 : _mfem_problem.execMultiApps(EXEC_MULTIAPP_FIXED_POINT_BEGIN, true); 74 2371 : _mfem_problem.outputStep(EXEC_MULTIAPP_FIXED_POINT_BEGIN); 75 : 76 2371 : _mfem_problem.execMultiApps(EXEC_TIMESTEP_BEGIN, true); 77 2371 : _mfem_problem.execute(EXEC_TIMESTEP_BEGIN); 78 2371 : _mfem_problem.outputStep(EXEC_TIMESTEP_BEGIN); 79 : 80 : // Update warehouse active objects 81 2371 : _mfem_problem.updateActiveObjects(); 82 : 83 2371 : if (_mfem_problem.shouldSolve()) 84 : { 85 3654 : for (const auto & problem_operator : _problem_operators) 86 1827 : problem_operator->Solve(); 87 : 88 : // Short-circuit evaluation guarantees we only do one of p- or h-refinement between solves 89 1853 : while (_mfem_problem.pRefine() || _mfem_problem.hRefine()) 90 : { 91 : // Remove me: reconstruct the solver due to possible mfem/hypre bug 92 26 : _mfem_problem.getProblemData().jacobian_solver->constructSolver(); 93 : 94 : // Reset gridfunctions 95 52 : for (const auto & problem_operator : _problem_operators) 96 26 : problem_operator->SetGridFunctions(); 97 : 98 : // Solve again 99 52 : for (const auto & problem_operator : _problem_operators) 100 26 : problem_operator->Solve(); 101 : } 102 : } 103 2371 : _mfem_problem.displaceMesh(); 104 : 105 : // Execute user objects, transfers, and multiapps at timestep end 106 2371 : _mfem_problem.onTimestepEnd(); 107 2371 : _mfem_problem.execute(EXEC_TIMESTEP_END); 108 2371 : _mfem_problem.execTransfers(EXEC_TIMESTEP_END); 109 2371 : _mfem_problem.execMultiApps(EXEC_TIMESTEP_END, true); 110 2371 : _executioner.postSolve(); 111 : // Solve step ends 112 : 113 2371 : if (converged) 114 : { 115 : // Fixed point iteration loop ends right above 116 2371 : _mfem_problem.execute(EXEC_MULTIAPP_FIXED_POINT_END); 117 2371 : _mfem_problem.execTransfers(EXEC_MULTIAPP_FIXED_POINT_END); 118 2371 : _mfem_problem.execMultiApps(EXEC_MULTIAPP_FIXED_POINT_END, true); 119 2371 : _mfem_problem.outputStep(EXEC_MULTIAPP_FIXED_POINT_END); 120 : } 121 : 122 2371 : return converged; 123 : } 124 : 125 : #endif