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