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 "MFEMTransient.h" 13 : #include "MFEMProblem.h" 14 : #include "TimeDependentEquationSystemProblemOperator.h" 15 : #include "TimeStepper.h" 16 : 17 : registerMooseObject("MooseApp", MFEMTransient); 18 : 19 : InputParameters 20 2740 : MFEMTransient::validParams() 21 : { 22 2740 : InputParameters params = MFEMProblemSolve::validParams(); 23 2740 : params += TransientBase::validParams(); 24 2740 : params.addClassDescription("Executioner for transient MFEM problems."); 25 2740 : return params; 26 0 : } 27 : 28 321 : MFEMTransient::MFEMTransient(const InputParameters & params) 29 : : TransientBase(params), 30 321 : _mfem_problem(dynamic_cast<MFEMProblem &>(feProblem())), 31 321 : _mfem_problem_data(_mfem_problem.getProblemData()), 32 642 : _mfem_problem_solve(*this, getProblemOperators()) 33 : { 34 : // If no ProblemOperators have been added by the user, add a default 35 321 : if (getProblemOperators().empty()) 36 : { 37 321 : _mfem_problem_data.eqn_system = std::make_shared<Moose::MFEM::TimeDependentEquationSystem>( 38 321 : _mfem_problem_data.time_derivative_map); 39 : auto problem_operator = 40 321 : std::make_shared<Moose::MFEM::TimeDependentEquationSystemProblemOperator>(_mfem_problem); 41 321 : addProblemOperator(std::move(problem_operator)); 42 321 : } 43 321 : } 44 : 45 : void 46 321 : MFEMTransient::init() 47 : { 48 321 : TransientBase::init(); 49 : 50 321 : if (_mfem_problem_data.nonlinear_solver) 51 24 : _mfem_problem_data.eqn_system->SetSolverRequiresGradient( 52 24 : _mfem_problem_data.nonlinear_solver->RequiresGradient()); 53 : 54 : // Set up initial conditions 55 321 : _mfem_problem_data.eqn_system->Init( 56 321 : _mfem_problem_data.gridfunctions, 57 321 : _mfem_problem_data.cmplx_gridfunctions, 58 963 : getParam<MooseEnum>("assembly_level").getEnum<mfem::AssemblyLevel>()); 59 : 60 642 : for (const auto & problem_operator : getProblemOperators()) 61 : { 62 321 : problem_operator->SetGridFunctions(); 63 321 : problem_operator->Init(_mfem_problem_data.f); 64 : } 65 321 : } 66 : 67 : void 68 1572 : MFEMTransient::takeStep(Real input_dt) 69 : { 70 1572 : _dt_old = _dt; 71 : 72 1572 : if (input_dt == -1.0) 73 1294 : _dt = computeConstrainedDT(); 74 : else 75 278 : _dt = input_dt; 76 : 77 1572 : _time_stepper->preSolve(); 78 : 79 : // Unfortunately, time needs to be temporarily incremented so we get 80 : // meaningful console output in timestepSetup(). We decrement it back 81 : // immediately after so step() below behaves as expected. 82 1572 : _time += _dt; 83 1572 : _problem.timestepSetup(); 84 1572 : _time -= _dt; 85 : 86 1572 : _problem.onTimestepBegin(); 87 1572 : _problem.execTransfers(EXEC_TIMESTEP_BEGIN); 88 1572 : if (!_problem.execMultiApps(EXEC_TIMESTEP_BEGIN, true)) 89 : { 90 0 : _last_solve_converged = false; 91 0 : return; 92 : } 93 1572 : _problem.execute(EXEC_TIMESTEP_BEGIN); 94 : 95 : // Advance time step of the MFEM problem. Time is also updated here, and 96 : // _problem_operator->SetTime is called inside the ode_solver->Step method to 97 : // update the time used by time dependent (function) coefficients. 98 1572 : _time_stepper->step(); 99 : 100 : // Continue with usual TransientBase::takeStep() finalisation 101 1572 : _last_solve_converged = _time_stepper->converged(); 102 : 103 1572 : if (!lastSolveConverged()) 104 : { 105 0 : _console << "Aborting as solve did not converge" << std::endl; 106 0 : return; 107 : } 108 : 109 1572 : _problem.execute(EXEC_TIMESTEP_END); 110 1572 : _problem.execTransfers(EXEC_TIMESTEP_END); 111 1572 : _problem.execMultiApps(EXEC_TIMESTEP_END, true); 112 : 113 1572 : if (lastSolveConverged()) 114 1572 : _time_stepper->acceptStep(); 115 : else 116 0 : _time_stepper->rejectStep(); 117 : 118 : // Set time to time old, since final time is updated in TransientBase::endStep() 119 1572 : _time = _time_old; 120 : 121 1572 : _time_stepper->postSolve(); 122 : } 123 : 124 : #endif