https://mooseframework.inl.gov
TimeSequenceStepperBase.C
Go to the documentation of this file.
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 
11 #include "FEProblem.h"
12 #include "Transient.h"
13 
14 #include <algorithm>
15 #include <functional>
16 
19 {
21  params.addParam<bool>(
22  "use_last_dt_after_last_t",
23  false,
24  "If true, uses the final time step size for times after the last time in the sequence, "
25  "instead of taking a single step directly to the simulation end time");
26  params.addParam<bool>(
27  "use_last_t_for_end_time", false, "Use last time in sequence as 'end_time' in Executioner.");
28  return params;
29 }
30 
32  : TimeStepper(parameters),
33  _use_last_dt_after_last_t(getParam<bool>("use_last_dt_after_last_t")),
34  _current_step(declareRestartableData<unsigned int>("current_step", 0)),
35  _time_sequence(declareRestartableData<std::vector<Real>>("time_sequence")),
36  _set_end_time(getParam<bool>("use_last_t_for_end_time"))
37 {
38 }
39 
40 void
41 TimeSequenceStepperBase::setupSequence(const std::vector<Real> & times)
42 {
43  // In case of half transient, transient's end time needs to be reset to
44  // be able to imprint TimeSequenceStepperBase's end time
47 
48  // only set up _time_sequence if the app is _not_ recovering
49  if (!_app.isRecovering())
50  {
51  // also we need to do something different when restarting
52  if (!_app.isRestarting() || _time_sequence.empty())
53  updateSequence(times);
54  else
55  {
56  // in case of restart it should be allowed to modify _time_sequence if it follows the
57  // following rule:
58  // all times up to _current_step are identical
59  // 1. start time cannot be modified
60  // 2. the entries in _time_sequence and times must be equal up to entry with index
61  // _current_step
62 
64  mooseError("Timesequencestepper does not allow the start time to be modified.");
65 
66  // sync _executioner.endTime with _time_sequence
67  Real end_time = _executioner.endTime();
68 
69  // make sure time sequence is in ascending order
70  for (unsigned int j = 0; j < times.size() - 1; ++j)
71  if (times[j + 1] <= times[j])
72  mooseError("time_sequence must be in ascending order.");
73 
74  if (times.size() < _current_step + 1)
75  mooseError("The timesequence provided in the restart file must be identical to "
76  "the one in the old file up to entry number ",
77  _current_step + 1,
78  " but there are only ",
79  times.size(),
80  " value(s) provided for the timesequence in the restart input.");
81 
82  // save the restarted time_sequence
83  std::vector<Real> saved_time_sequence = _time_sequence;
84 
85  _time_sequence.clear();
86 
87  // step 1: fill in the entries up to _current_step
88  for (unsigned int j = 0; j <= _current_step; ++j)
89  {
90  if (!MooseUtils::absoluteFuzzyEqual(times[j], saved_time_sequence[j]))
91  mooseError("The timesequence provided in the restart file must be identical to "
92  "the one in the old file up to entry number ",
93  _current_step + 1,
94  " but entry ",
95  j + 1,
96  " is ",
97  times[j],
98  " in the restart input but ",
99  saved_time_sequence[j],
100  " in the restarted input.");
101 
102  _time_sequence.push_back(saved_time_sequence[j]);
103  }
104 
105  // step 2: fill in the entries up after _current_step
106  for (unsigned int j = _current_step + 1; j < times.size(); ++j)
107  {
108  if (times[j] < end_time)
109  _time_sequence.push_back(times[j]);
110  }
111 
112  if (!_set_end_time)
113  _time_sequence.push_back(end_time);
114  }
115  }
116 
117  // Set end time to last time in sequence if requested
118  if (_set_end_time)
119  {
120  auto & end_time = _executioner.endTime();
121  end_time = _time_sequence.back();
122  }
123 
125  {
126  unsigned int half = (_time_sequence.size() - 1) / 2;
128  }
129 }
130 
131 void
132 TimeSequenceStepperBase::updateSequence(const std::vector<Real> & times)
133 {
134  Real start_time = _executioner.getStartTime();
135  Real end_time = _executioner.endTime();
136 
137  // make sure time sequence is in strictly ascending order
138  if (!std::is_sorted(times.begin(), times.end(), std::less_equal<Real>()))
139  paramError("time_sequence", "Time points must be in strictly ascending order.");
140 
141  _time_sequence.push_back(start_time);
142  for (unsigned int j = 0; j < times.size(); ++j)
143  {
144  if (times[j] > start_time && times[j] < end_time)
145  _time_sequence.push_back(times[j]);
146  }
147 
148  if (!_set_end_time)
149  _time_sequence.push_back(end_time);
150 }
151 
152 void
154 {
155  _time_sequence.clear();
156 }
157 
158 void
160 {
164 }
165 
166 Real
168 {
169  return computeDT();
170 }
171 
172 Real
174 {
176  {
177  // last *provided* time value index; actual last index corresponds to end time
178  const auto last_t_index = _time_sequence.size() - 2;
179  if (_current_step + 1 > last_t_index)
180  return _time_sequence[last_t_index] - _time_sequence[last_t_index - 1];
181  else
183  }
184  else
186 }
187 
188 Real
190 {
191  if (computeDT() <= _dt_min)
192  mooseError("Solve failed and timestep already at or below dtmin, cannot continue!");
193 
194  // cut the time step in a half if possible
196  if (dt < _dt_min)
197  dt = _dt_min;
198  _time_sequence.insert(_time_sequence.begin() + _current_step + 1,
200  return computeDT();
201 }
TransientBase & _executioner
Reference to transient executioner.
Definition: TimeStepper.h:122
static InputParameters validParams()
Definition: TimeStepper.C:16
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
Definition: MooseUtils.h:380
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition: MooseBase.h:435
virtual Real computeFailedDT() override
Computes time step size after a failed time step.
unsigned int & _current_step
the step that the time stepper is currently at
Base class for time stepping.
Definition: TimeStepper.h:22
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
TimeSequenceStepperBase(const InputParameters &parameters)
Real getStartTime() const
Return the start time.
void setupSequence(const std::vector< Real > &times)
const Real _cutback_factor_at_failure
Cutback factor if a time step fails to converge.
Definition: TimeStepper.h:143
bool isRestarting() const
Whether or not this is a "restart" calculation.
Definition: MooseApp.C:1807
const bool _set_end_time
Whether to use the last t in sequence as Executioner end_time.
virtual void acceptStep()
This gets called when time step is accepted.
Definition: TimeStepper.C:175
std::vector< Real > & _time_sequence
stores the sequence of time points
bool testCheckpointHalfTransient() const
Whether or not this simulation should only run half its transient (useful for testing recovery) ...
Definition: MooseApp.h:511
constexpr bool is_sorted()
Check if the given index sequence is sorted ()internal function)
MooseApp & _app
The MOOSE application this is associated with.
Definition: MooseBase.h:353
virtual Real computeDT() override
Computes time step size after the initial time step.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Real & endTime()
Get a modifiable reference to the end time.
virtual Real computeInitialDT() override
Computes time step size for the initial time step.
static InputParameters validParams()
const bool _use_last_dt_after_last_t
Whether to use the final dt past the last t in sequence.
Real & _dt_min
Definition: TimeStepper.h:129
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition: MooseBase.h:267
bool absoluteFuzzyGreaterEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether a variable is greater than or equal to another variable within an absolute ...
Definition: MooseUtils.h:404
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
virtual void acceptStep() override
This gets called when time step is accepted.
bool isRecovering() const
Whether or not this is a "recover" calculation.
Definition: MooseApp.C:1801
void ErrorVector unsigned int
Real & _time
Values from executioner.
Definition: TimeStepper.h:125
void updateSequence(const std::vector< Real > &times)