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

Generated by: LCOV version 1.14