LCOV - code coverage report
Current view: top level - src/timesteppers - FunctionDT.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 54 76 71.1 %
Date: 2025-07-17 01:28:37 Functions: 7 7 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 "FunctionDT.h"
      11             : #include "Function.h"
      12             : #include "PiecewiseBase.h"
      13             : #include <limits>
      14             : 
      15             : registerMooseObject("MooseApp", FunctionDT);
      16             : 
      17             : InputParameters
      18       14581 : FunctionDT::validParams()
      19             : {
      20       14581 :   InputParameters params = TimeStepper::validParams();
      21             :   // TODO: This will be required when time_t and time_dt is removed
      22       14581 :   params.addParam<FunctionName>(
      23             :       "function", "The name of the time-dependent function that prescribes the time step size.");
      24       14581 :   params.addParam<std::vector<Real>>("time_t", {}, "The values of t");
      25       14581 :   params.addParam<std::vector<Real>>("time_dt", {}, "The values of dt");
      26       43743 :   params.addParam<Real>("growth_factor",
      27       29162 :                         std::numeric_limits<Real>::max(),
      28             :                         "Maximum ratio of new to previous timestep sizes.");
      29       14581 :   params.addParam<Real>("min_dt", 0, "The minimal dt to take.");
      30             :   // TODO: this can be removed when time_t and time_dt is removed
      31       43743 :   params.addParam<bool>("interpolate",
      32       29162 :                         true,
      33             :                         "Whether or not to interpolate DT between times.  "
      34             :                         "This is true by default for historical reasons.");
      35       14581 :   params.addClassDescription(
      36             :       "Timestepper whose steps vary over time according to a user-defined function");
      37             : 
      38       14581 :   return params;
      39           0 : }
      40             : 
      41         158 : FunctionDT::FunctionDT(const InputParameters & parameters)
      42             :   : TimeStepper(parameters),
      43             :     FunctionInterface(this),
      44         158 :     _time_t(getParam<std::vector<Real>>("time_t")),
      45         158 :     _time_dt(getParam<std::vector<Real>>("time_dt")),
      46         158 :     _function(nullptr),
      47         158 :     _growth_factor(getParam<Real>("growth_factor")),
      48         158 :     _min_dt(getParam<Real>("min_dt")),
      49         474 :     _interpolate(getParam<bool>("interpolate"))
      50             : {
      51             :   // TODO: remove this when `time_t` and `time_dt` is removed
      52         158 :   if ((_time_t.size() && _time_dt.size()) && !isParamValid("function"))
      53           0 :     mooseDeprecated(name(),
      54             :                     ": Using `time_t` and `time_dt` parameter is deprecated. Switch your input "
      55             :                     "file to using `function` parameter.\n",
      56             :                     "  1. Build a new function. If `interpolate` parameter is true use type = "
      57             :                     "PiecewiseLinear. If it was false, use PiecewiseConstant.\n",
      58             :                     "  2. Copy `time_t` parameter into your function and rename it to `x`.\n",
      59             :                     "  3. Copy `time_dt` parameter into your function and rename it to `y`.\n",
      60             :                     "  4. Use the `function` parameter in your time stepper and pass your new "
      61             :                     "function name into it.\n");
      62         158 :   else if ((_time_t.size() && _time_dt.size()) && isParamValid("function"))
      63           0 :     mooseError(name(),
      64             :                ": Using `time_t`, `_time_dt` and `function` at the same time. Use only `function`, "
      65             :                "`time_t` and _time_dt is deprecated.");
      66         158 :   else if (!isParamValid("function"))
      67           0 :     mooseError(name(),
      68             :                ": Please, specify a function (using the `function` parameter) that will prescribe "
      69             :                "the time step size.");
      70             : 
      71         158 :   if (_time_t.size() && _time_dt.size())
      72             :   {
      73             :     try
      74             :     {
      75           0 :       _time_ipol = std::make_unique<LinearInterpolation>(_time_t, _time_dt);
      76             :     }
      77           0 :     catch (std::domain_error & e)
      78             :     {
      79           0 :       mooseError("In FunctionDT ", _name, ": ", e.what());
      80           0 :     }
      81             : 
      82           0 :     _time_knots = _time_t;
      83           0 :     _use_function = false;
      84             :   }
      85             :   else
      86             :   {
      87         158 :     _function = &getFunction("function");
      88             :     // If dt is given by piece-wise linear and constant function, we add the domain into
      89             :     // _time_knots, so that the time stepper hits those time points
      90         158 :     const PiecewiseBase * pw = dynamic_cast<const PiecewiseBase *>(_function);
      91         158 :     if (pw)
      92             :     {
      93         108 :       unsigned int n_knots = pw->functionSize();
      94         396 :       for (unsigned int i = 0; i < n_knots; i++)
      95         288 :         _time_knots.push_back(pw->domain(i));
      96             :     }
      97             : 
      98         158 :     _use_function = true;
      99             :   }
     100         158 : }
     101             : 
     102             : void
     103         158 : FunctionDT::init()
     104             : {
     105         158 :   removeOldKnots();
     106         158 : }
     107             : 
     108             : void
     109        3218 : FunctionDT::removeOldKnots()
     110             : {
     111        4345 :   while ((_time_knots.size() > 0) &&
     112        4345 :          (*_time_knots.begin() <= _time || std::abs(*_time_knots.begin() - _time) < 1e-10))
     113         223 :     _time_knots.erase(_time_knots.begin());
     114        3218 : }
     115             : 
     116             : Real
     117         298 : FunctionDT::computeInitialDT()
     118             : {
     119         298 :   return computeDT();
     120             : }
     121             : 
     122             : Real
     123        3197 : FunctionDT::computeDT()
     124             : {
     125        3197 :   Real local_dt = 0;
     126             : 
     127        3197 :   if (_use_function)
     128        3197 :     local_dt = _function->value(_time, _point_zero);
     129             :   else
     130             :   {
     131           0 :     if (_interpolate)
     132           0 :       local_dt = _time_ipol->sample(_time);
     133             :     else // Find where we are
     134             :     {
     135           0 :       unsigned int i = 0;
     136           0 :       if (MooseUtils::relativeFuzzyGreaterEqual(_time, _time_t.back()))
     137             :       {
     138           0 :         i = _time_t.size();
     139             :       }
     140             :       else
     141             :       {
     142           0 :         for (; i < _time_t.size() - 1; i++)
     143           0 :           if (MooseUtils::relativeFuzzyLessThan(_time, _time_t[i + 1]))
     144           0 :             break;
     145             :       }
     146             : 
     147             :       // Use the last dt after the end
     148           0 :       if (i == _time_t.size())
     149           0 :         local_dt = _time_dt.back();
     150             :       else
     151           0 :         local_dt = _time_dt[i];
     152             :     }
     153             :   }
     154             : 
     155             :   // sync to time knot
     156        3197 :   if ((_time_knots.size() > 0) && (_time + local_dt >= (*_time_knots.begin())))
     157         165 :     local_dt = (*_time_knots.begin()) - _time;
     158             :   // honor minimal dt
     159        3197 :   if (local_dt < _min_dt)
     160          11 :     local_dt = _min_dt;
     161             : 
     162        3197 :   if ((local_dt > (_dt * _growth_factor)) && _dt > 0)
     163           0 :     local_dt = _dt * _growth_factor;
     164             : 
     165        3197 :   return local_dt;
     166             : }
     167             : 
     168             : void
     169        3060 : FunctionDT::postStep()
     170             : {
     171        3060 :   removeOldKnots();
     172        3060 : }

Generated by: LCOV version 1.14