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  return params;
27 }
28 
30  : TimeStepper(parameters),
31  _use_last_dt_after_last_t(getParam<bool>("use_last_dt_after_last_t")),
32  _current_step(declareRestartableData<unsigned int>("current_step", 0)),
33  _time_sequence(declareRestartableData<std::vector<Real>>("time_sequence"))
34 {
35 }
36 
37 void
38 TimeSequenceStepperBase::setupSequence(const std::vector<Real> & times)
39 {
40  // In case of half transient, transient's end time needs to be reset to
41  // be able to imprint TimeSequenceStepperBase's end time
44 
45  // only set up _time_sequence if the app is _not_ recovering
46  if (!_app.isRecovering())
47  {
48  // also we need to do something different when restarting
49  if (!_app.isRestarting())
50  {
51  // sync _executioner.startTime and endTime with _time_sequence
52  Real start_time = _executioner.getStartTime();
53  Real end_time = _executioner.endTime();
54 
55  // make sure time sequence is in strictly ascending order
56  if (!std::is_sorted(times.begin(), times.end(), std::less_equal<Real>()))
57  paramError("time_sequence", "Time points must be in strictly ascending order.");
58 
59  _time_sequence.push_back(start_time);
60  for (unsigned int j = 0; j < times.size(); ++j)
61  {
62  if (times[j] > start_time && times[j] < end_time)
63  _time_sequence.push_back(times[j]);
64  }
65  _time_sequence.push_back(end_time);
66  }
67  else
68  {
69  // in case of restart it should be allowed to modify _time_sequence if it follows the
70  // following rule:
71  // all times up to _current_step are identical
72  // 1. start time cannot be modified
73  // 2. the entries in _time_sequence and times must be equal up to entry with index
74  // _current_step
75 
77  mooseError("Timesequencestepper does not allow the start time to be modified.");
78 
79  // sync _executioner.endTime with _time_sequence
80  Real end_time = _executioner.endTime();
81 
82  // make sure time sequence is in ascending order
83  for (unsigned int j = 0; j < times.size() - 1; ++j)
84  if (times[j + 1] <= times[j])
85  mooseError("time_sequence must be in ascending order.");
86 
87  // save the restarted time_sequence
88  std::vector<Real> saved_time_sequence = _time_sequence;
89  _time_sequence.clear();
90 
91  // step 1: fill in the entries up to _current_step
92  for (unsigned int j = 0; j <= _current_step; ++j)
93  {
94  if (!MooseUtils::absoluteFuzzyEqual(times[j], saved_time_sequence[j]))
95  mooseError("The timesequence provided in the restart file must be identical to "
96  "the one in the old file up to entry number ",
97  _current_step + 1,
98  " = ",
99  saved_time_sequence[_current_step]);
100 
101  _time_sequence.push_back(saved_time_sequence[j]);
102  }
103 
104  // step 2: fill in the entries up after _current_step
105  for (unsigned int j = _current_step + 1; j < times.size(); ++j)
106  {
107  if (times[j] < end_time)
108  _time_sequence.push_back(times[j]);
109  }
110  _time_sequence.push_back(end_time);
111  }
112  }
113 
115  {
116  unsigned int half = (_time_sequence.size() - 1) / 2;
118  }
119 }
120 
121 void
123 {
127 }
128 
129 Real
131 {
132  return computeDT();
133 }
134 
135 Real
137 {
139  {
140  // last *provided* time value index; actual last index corresponds to end time
141  const auto last_t_index = _time_sequence.size() - 2;
142  if (_current_step + 1 > last_t_index)
143  return _time_sequence[last_t_index] - _time_sequence[last_t_index - 1];
144  else
146  }
147  else
149 }
150 
151 Real
153 {
154  if (computeDT() <= _dt_min)
155  mooseError("Solve failed and timestep already at or below dtmin, cannot continue!");
156 
157  // cut the time step in a half if possible
159  if (dt < _dt_min)
160  dt = _dt_min;
161  _time_sequence.insert(_time_sequence.begin() + _current_step + 1,
163  return computeDT();
164 }
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
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:1817
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:544
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:84
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 ...
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
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 mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
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:1811
void ErrorVector unsigned int
Real & _time
Values from executioner.
Definition: TimeStepper.h:125