LCOV - code coverage report
Current view: top level - src/controls - TimesEnableControl.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 38 39 97.4 %
Date: 2025-07-17 01:28:37 Functions: 3 3 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 "TimesEnableControl.h"
      11             : #include "Times.h"
      12             : 
      13             : registerMooseObject("MooseApp", TimesEnableControl);
      14             : 
      15             : InputParameters
      16       14313 : TimesEnableControl::validParams()
      17             : {
      18       14313 :   InputParameters params = ConditionalEnableControl::validParams();
      19             : 
      20       14313 :   params.addRequiredParam<UserObjectName>(
      21             :       "times", "The Times object providing the list of times to turn on/off the objects.");
      22             : 
      23       42939 :   params.addParam<Real>(
      24             :       "time_window",
      25       28626 :       1e-8,
      26             :       "Window / tolerance on the absolute difference between the time step and the simulation");
      27       42939 :   params.addParam<bool>(
      28             :       "act_on_time_stepping_across_a_time_point",
      29       28626 :       true,
      30             :       "Whether to still perform the control action (enable/disable) if a time step went over a "
      31             :       "'time point' in the Times object without stopping near that exact time");
      32             : 
      33       14313 :   params.addClassDescription(
      34             :       "Control for enabling/disabling objects when a certain time is reached.");
      35             : 
      36       14313 :   return params;
      37           0 : }
      38             : 
      39          24 : TimesEnableControl::TimesEnableControl(const InputParameters & parameters)
      40             :   : ConditionalEnableControl(parameters),
      41          24 :     _times(getUserObject<Times>("times")),
      42          24 :     _time_window(getParam<Real>("time_window")),
      43          24 :     _act_on_time_stepping_across_time_point(
      44          24 :         getParam<bool>("act_on_time_stepping_across_a_time_point")),
      45          24 :     _prev_time_point_current(std::numeric_limits<Real>::max()),
      46          24 :     _prev_time_point(declareRestartableData<Real>("prev_time", std::numeric_limits<Real>::max())),
      47          48 :     _t_current(_fe_problem.time())
      48             : {
      49          24 : }
      50             : 
      51             : bool
      52         488 : TimesEnableControl::conditionMet(const unsigned int & /*i*/)
      53             : {
      54             :   // Retrieve time points around the current time
      55         488 :   const auto prev_time_point = _times.getPreviousTime(_t);
      56         488 :   const auto next_time_point = _times.getNextTime(_t, false);
      57             : 
      58             :   // Initialize the previous time point for the first time
      59             :   // By doing this here instead of the constructor, we avoid creating a construction dependency
      60             :   // between 'Times' and 'Controls'
      61         488 :   if (_prev_time_point == std::numeric_limits<Real>::max())
      62          46 :     _prev_time_point = _times.getTimeAtIndex(0);
      63             : 
      64             :   // Check if we are near a time point
      65             :   // We could have just missed the previous one or be right before the next one
      66         488 :   if (MooseUtils::absoluteFuzzyEqual(_t, prev_time_point, _time_window))
      67             :   {
      68             :     // Avoid always triggering on the next time step based on the prev_time_point value
      69         134 :     if (_act_on_time_stepping_across_time_point)
      70         134 :       _prev_time_point = next_time_point;
      71         134 :     return true;
      72             :   }
      73         354 :   else if (MooseUtils::absoluteFuzzyEqual(_t, next_time_point, _time_window))
      74             :   {
      75          22 :     if (_act_on_time_stepping_across_time_point)
      76          22 :       _prev_time_point = _times.getNextTime(next_time_point, false);
      77          22 :     return true;
      78             :   }
      79             : 
      80             :   // Update prev_time_point_current only if we changed time step since the last time conditionMet
      81             :   // was called
      82         332 :   if (_t != _t_current)
      83             :   {
      84         166 :     _prev_time_point_current = _prev_time_point;
      85         166 :     _t_current = _t;
      86             :   }
      87             : 
      88             :   // Check if we passed a time point
      89         332 :   if (_act_on_time_stepping_across_time_point && _t > _prev_time_point_current)
      90             :   {
      91             :     // We will need to pass the next time point next time to trigger the condition
      92          68 :     _prev_time_point = next_time_point;
      93             :     // we do not update prev_time_point_current in case conditionMet is called again in the same
      94             :     // time step
      95          68 :     return true;
      96             :   }
      97             : 
      98         264 :   return false;
      99             : }

Generated by: LCOV version 1.14