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 "MFEMSteady.h" 13 : #include "MFEMProblem.h" 14 : #include "MFEMEigenproblem.h" 15 : #include "EigenproblemEquationSystem.h" 16 : #include "EquationSystemProblemOperator.h" 17 : #include "EigenproblemESProblemOperator.h" 18 : 19 : registerMooseObject("MooseApp", MFEMSteady); 20 : 21 : InputParameters 22 4502 : MFEMSteady::validParams() 23 : { 24 4502 : InputParameters params = MFEMProblemSolve::validParams(); 25 4502 : params += Executioner::validParams(); 26 9004 : params.addClassDescription("Executioner for steady state MFEM problems."); 27 13506 : params.addParam<Real>("time", 0.0, "System time"); 28 4502 : return params; 29 0 : } 30 : 31 1188 : MFEMSteady::MFEMSteady(const InputParameters & params) 32 : : Executioner(params), 33 1188 : _mfem_problem(dynamic_cast<MFEMProblem &>(feProblem())), 34 1188 : _mfem_problem_data(_mfem_problem.getProblemData()), 35 1188 : _mfem_problem_solve(*this, getProblemOperators()), 36 2376 : _system_time(getParam<Real>("time")), 37 1188 : _time_step(_mfem_problem.timeStep()), 38 2376 : _time([this]() -> Real & { return this->_mfem_problem.time() = this->_system_time; }()), 39 1188 : _last_solve_converged(false) 40 : { 41 : // If no ProblemOperators have been added by the user, add a default 42 1188 : if (getProblemOperators().empty()) 43 : { 44 1188 : if (_mfem_problem.getNumericType() == MFEMProblem::NumericType::REAL) 45 : { 46 1125 : if (dynamic_cast<MFEMEigenproblem *>(&_mfem_problem)) 47 : { 48 26 : _mfem_problem_data.eqn_system = std::make_shared<Moose::MFEM::EigenproblemEquationSystem>(); 49 : auto problem_operator = 50 26 : std::make_shared<Moose::MFEM::EigenproblemESProblemOperator>(_mfem_problem); 51 26 : addProblemOperator(std::move(problem_operator)); 52 26 : } 53 : else 54 : { 55 1099 : _mfem_problem_data.eqn_system = std::make_shared<Moose::MFEM::EquationSystem>(); 56 : auto problem_operator = 57 1099 : std::make_shared<Moose::MFEM::EquationSystemProblemOperator>(_mfem_problem); 58 1099 : addProblemOperator(std::move(problem_operator)); 59 1099 : } 60 : } 61 63 : else if (_mfem_problem.getNumericType() == MFEMProblem::NumericType::COMPLEX) 62 : { 63 63 : _mfem_problem_data.eqn_system = std::make_shared<Moose::MFEM::ComplexEquationSystem>(); 64 : auto problem_operator = 65 63 : std::make_shared<Moose::MFEM::ComplexEquationSystemProblemOperator>(_mfem_problem); 66 63 : addProblemOperator(std::move(problem_operator)); 67 63 : } 68 : else 69 0 : mooseError("Unknown numeric type. " 70 : "Please set the Problem numeric type to either 'real' or 'complex'."); 71 : } 72 1188 : } 73 : 74 : void 75 1188 : MFEMSteady::init() 76 : { 77 1188 : _mfem_problem.execute(EXEC_PRE_MULTIAPP_SETUP); 78 1188 : _mfem_problem.initialSetup(); 79 : 80 1188 : if (_mfem_problem_data.nonlinear_solver) 81 18 : _mfem_problem_data.eqn_system->SetSolverRequiresGradient( 82 18 : _mfem_problem_data.nonlinear_solver->RequiresGradient()); 83 : 84 1188 : _mfem_problem_data.eqn_system->SetCoefficientManager(_mfem_problem_data.coefficients); 85 : 86 : // Set up initial conditions 87 1188 : _mfem_problem_data.eqn_system->Init( 88 1188 : _mfem_problem_data.gridfunctions, 89 1188 : _mfem_problem_data.cmplx_gridfunctions, 90 3564 : getParam<MooseEnum>("assembly_level").getEnum<mfem::AssemblyLevel>()); 91 : 92 2376 : for (const auto & problem_operator : getProblemOperators()) 93 : { 94 1188 : problem_operator->SetGridFunctions(); 95 1188 : problem_operator->Init(_mfem_problem_data.f); 96 : } 97 1188 : } 98 : 99 : void 100 1188 : MFEMSteady::execute() 101 : { 102 1188 : if (_app.isRecovering()) 103 : { 104 0 : _console << "\nCannot recover steady solves!\nExiting...\n" << std::endl; 105 0 : return; 106 : } 107 : 108 1188 : _time_step = 0; 109 1188 : _time = _time_step; 110 1188 : _mfem_problem.outputStep(EXEC_INITIAL); 111 1188 : _time = _system_time; 112 : 113 1188 : preExecute(); 114 : 115 1188 : _mfem_problem.advanceState(); 116 : 117 : // first step in any steady state solve is always 1 (preserving backwards compatibility) 118 1188 : _time_step = 1; 119 1188 : _mfem_problem.timestepSetup(); 120 1188 : _mfem_problem.execTransfers(EXEC_TIMESTEP_BEGIN); 121 1188 : if (!_mfem_problem.execMultiApps(EXEC_TIMESTEP_BEGIN, true)) 122 : { 123 0 : _last_solve_converged = false; 124 0 : return; 125 : } 126 1188 : _mfem_problem.execute(EXEC_TIMESTEP_BEGIN); 127 : 128 1188 : _last_solve_converged = _mfem_problem_solve.solve(); 129 : 130 1186 : _mfem_problem.computeIndicators(); 131 1186 : _mfem_problem.computeMarkers(); 132 : 133 : // need to keep _time in sync with _time_step to get correct output 134 1186 : _time = _time_step; 135 1186 : _mfem_problem.execute(EXEC_TIMESTEP_END); 136 1186 : _mfem_problem.execTransfers(EXEC_TIMESTEP_END); 137 1186 : _mfem_problem.execMultiApps(EXEC_TIMESTEP_END, true); 138 1186 : _mfem_problem.outputStep(EXEC_TIMESTEP_END); 139 1186 : _time = _system_time; 140 : 141 : { 142 5930 : TIME_SECTION("final", 1, "Executing Final Objects") 143 1186 : _mfem_problem.execMultiApps(EXEC_FINAL); 144 1186 : _mfem_problem.finalizeMultiApps(); 145 1186 : _mfem_problem.postExecute(); 146 1186 : _mfem_problem.execute(EXEC_FINAL); 147 1186 : _time = _time_step; 148 1186 : _mfem_problem.outputStep(EXEC_FINAL); 149 1186 : _time = _system_time; 150 1186 : } 151 : 152 1186 : postExecute(); 153 : } 154 : 155 : #endif