LCOV - code coverage report
Current view: top level - src/mfem/executioners - MFEMTransient.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #33416 (b10b36) with base 9fbd27 Lines: 56 62 90.3 %
Date: 2026-07-23 16:15:30 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14