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