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

Generated by: LCOV version 1.14