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 : }