LCOV - code coverage report
Current view: top level - src/timesteppers - SolutionTimeAdaptiveDT.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 1f9d31 Lines: 40 66 60.6 %
Date: 2025-09-02 20:01:20 Functions: 6 9 66.7 %
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             : #include "SolutionTimeAdaptiveDT.h"
      11             : #include "FEProblem.h"
      12             : #include "Transient.h"
      13             : 
      14             : #include <chrono>
      15             : 
      16             : registerMooseObject("MooseApp", SolutionTimeAdaptiveDT);
      17             : 
      18             : InputParameters
      19       28584 : SolutionTimeAdaptiveDT::validParams()
      20             : {
      21       28584 :   InputParameters params = TimeStepper::validParams();
      22       57168 :   params.addClassDescription("Compute simulation timestep based on actual solution time.");
      23       85752 :   params.addParam<Real>(
      24       57168 :       "percent_change", 0.1, "Fraction to change the timestep by.  Should be between 0 and 1");
      25       85752 :   params.addParam<int>(
      26       57168 :       "initial_direction", 1, "Direction for the first step.  1 for up... -1 for down. ");
      27      114336 :   params.addParam<bool>("adapt_log", false, "Output adaptive time step log");
      28       85752 :   params.addRequiredParam<Real>("dt", "The timestep size between solves");
      29             : 
      30       28584 :   return params;
      31           0 : }
      32             : 
      33          28 : SolutionTimeAdaptiveDT::SolutionTimeAdaptiveDT(const InputParameters & parameters)
      34             :   : TimeStepper(parameters),
      35          84 :     _direction(declareRestartableData<int>("direction", getParam<int>("initial_direction"))),
      36          56 :     _percent_change(getParam<Real>("percent_change")),
      37          28 :     _older_sol_time_vs_dt(
      38          56 :         declareRestartableData<Real>("older_sol_time_vs_dt", std::numeric_limits<Real>::max())),
      39          28 :     _old_sol_time_vs_dt(
      40          56 :         declareRestartableData<Real>("old_sol_time_vs_dt", std::numeric_limits<Real>::max())),
      41          28 :     _sol_time_vs_dt(
      42          56 :         declareRestartableData<Real>("sol_time_vs_dt", std::numeric_limits<Real>::max())),
      43         112 :     _adapt_log(getParam<bool>("adapt_log"))
      44             : {
      45          28 :   if ((_adapt_log) && (processor_id() == 0))
      46             :   {
      47           0 :     static const std::string log("adaptive_log");
      48           0 :     _adaptive_log.open(log);
      49           0 :     if (_adaptive_log.fail())
      50           0 :       mooseError("Unable to open file ", log);
      51           0 :     _adaptive_log << "Adaptive Times Step Log" << std::endl;
      52             :   }
      53          28 : }
      54             : 
      55          24 : SolutionTimeAdaptiveDT::~SolutionTimeAdaptiveDT() { _adaptive_log.close(); }
      56             : 
      57             : void
      58         193 : SolutionTimeAdaptiveDT::step()
      59             : {
      60         193 :   auto elapsed_time = stepAndRecordElapsedTime();
      61             : 
      62             :   // Take the maximum time over all processors so all processors compute and use the same dt
      63         193 :   TimeStepper::_communicator.max(elapsed_time);
      64             : 
      65         193 :   _older_sol_time_vs_dt = _old_sol_time_vs_dt;
      66         193 :   _old_sol_time_vs_dt = _sol_time_vs_dt;
      67         193 :   _sol_time_vs_dt = elapsed_time / _dt;
      68         193 : }
      69             : 
      70             : std::chrono::milliseconds::rep
      71           0 : SolutionTimeAdaptiveDT::stepAndRecordElapsedTime()
      72             : {
      73           0 :   auto start = std::chrono::system_clock::now();
      74           0 :   TimeStepper::step();
      75           0 :   auto end = std::chrono::system_clock::now();
      76           0 :   return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
      77             : }
      78             : 
      79             : Real
      80          54 : SolutionTimeAdaptiveDT::computeInitialDT()
      81             : {
      82         162 :   return getParam<Real>("dt");
      83             : }
      84             : 
      85             : Real
      86         188 : SolutionTimeAdaptiveDT::computeDT()
      87             : {
      88             :   // Ratio grew so switch direction
      89         188 :   if (_sol_time_vs_dt > _old_sol_time_vs_dt && _sol_time_vs_dt > _older_sol_time_vs_dt)
      90             :   {
      91          36 :     _direction *= -1;
      92             : 
      93             :     // Make sure we take at least two steps in this new direction
      94          36 :     _old_sol_time_vs_dt = std::numeric_limits<Real>::max();
      95          36 :     _older_sol_time_vs_dt = std::numeric_limits<Real>::max();
      96             :   }
      97             : 
      98         188 :   Real local_dt = _dt + _dt * _percent_change * _direction;
      99             : 
     100         188 :   if ((_adapt_log) && (processor_id() == 0))
     101             :   {
     102           0 :     Real out_dt = getCurrentDT();
     103           0 :     if (out_dt > _dt_max)
     104           0 :       out_dt = _dt_max;
     105             : 
     106           0 :     _adaptive_log << "***Time step: " << _t_step << ", time = " << _time + out_dt
     107           0 :                   << "\nCur DT: " << out_dt << "\nOlder Ratio: " << _older_sol_time_vs_dt
     108           0 :                   << "\nOld Ratio: " << _old_sol_time_vs_dt << "\nNew Ratio: " << _sol_time_vs_dt
     109           0 :                   << std::endl;
     110             :   }
     111             : 
     112         188 :   return local_dt;
     113             : }
     114             : 
     115             : void
     116           0 : SolutionTimeAdaptiveDT::rejectStep()
     117             : {
     118           0 :   _console << "Solve failed... cutting timestep" << std::endl;
     119           0 :   if (_adapt_log)
     120           0 :     _adaptive_log << "Solve failed... cutting timestep" << std::endl;
     121             : 
     122             :   // Reverse progression of quantities
     123           0 :   _sol_time_vs_dt = _old_sol_time_vs_dt;
     124           0 :   _old_sol_time_vs_dt = _older_sol_time_vs_dt;
     125             : 
     126           0 :   TimeStepper::rejectStep();
     127           0 : }

Generated by: LCOV version 1.14