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 14317 : TimesEnableControl::validParams() 17 : { 18 14317 : InputParameters params = ConditionalEnableControl::validParams(); 19 : 20 14317 : params.addRequiredParam<UserObjectName>( 21 : "times", "The Times object providing the list of times to turn on/off the objects."); 22 : 23 42951 : params.addParam<Real>( 24 : "time_window", 25 28634 : 1e-8, 26 : "Window / tolerance on the absolute difference between the time step and the simulation"); 27 42951 : params.addParam<bool>( 28 : "act_on_time_stepping_across_a_time_point", 29 28634 : 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 14317 : params.addClassDescription( 34 : "Control for enabling/disabling objects when a certain time is reached."); 35 : 36 14317 : return params; 37 0 : } 38 : 39 26 : TimesEnableControl::TimesEnableControl(const InputParameters & parameters) 40 : : ConditionalEnableControl(parameters), 41 26 : _times(getUserObject<Times>("times")), 42 26 : _time_window(getParam<Real>("time_window")), 43 26 : _act_on_time_stepping_across_time_point( 44 26 : getParam<bool>("act_on_time_stepping_across_a_time_point")), 45 26 : _prev_time_point_current(std::numeric_limits<Real>::max()), 46 26 : _prev_time_point(declareRestartableData<Real>("prev_time", std::numeric_limits<Real>::max())), 47 52 : _t_current(_fe_problem.time()) 48 : { 49 26 : } 50 : 51 : bool 52 532 : TimesEnableControl::conditionMet(const unsigned int & /*i*/) 53 : { 54 : // Retrieve time points around the current time 55 532 : const auto prev_time_point = _times.getPreviousTime(_t); 56 532 : 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 532 : if (_prev_time_point == std::numeric_limits<Real>::max()) 62 50 : _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 532 : 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 146 : if (_act_on_time_stepping_across_time_point) 70 146 : _prev_time_point = next_time_point; 71 146 : return true; 72 : } 73 386 : else if (MooseUtils::absoluteFuzzyEqual(_t, next_time_point, _time_window)) 74 : { 75 24 : if (_act_on_time_stepping_across_time_point) 76 24 : _prev_time_point = _times.getNextTime(next_time_point, false); 77 24 : 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 362 : if (_t != _t_current) 83 : { 84 181 : _prev_time_point_current = _prev_time_point; 85 181 : _t_current = _t; 86 : } 87 : 88 : // Check if we passed a time point 89 362 : 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 74 : _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 74 : return true; 96 : } 97 : 98 288 : return false; 99 : }