www.mooseframework.org
TimeSequenceStepperBase.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 {
126  _current_step++;
127 }
128 
129 Real
131 {
132  return computeDT();
133 }
134 
135 Real
137 {
138  const auto standard_dt = _time_sequence[_current_step + 1] - _time_sequence[_current_step];
139 
141  {
142  // last *provided* time value index; actual last index corresponds to end time
143  const auto last_t_index = _time_sequence.size() - 2;
144  if (_current_step + 1 > last_t_index)
145  return _time_sequence[last_t_index] - _time_sequence[last_t_index - 1];
146  else
147  return standard_dt;
148  }
149  else
150  return standard_dt;
151 }
152 
153 Real
155 {
156  if (computeDT() <= _dt_min)
157  mooseError("Solve failed and timestep already at or below dtmin, cannot continue!");
158 
159  // cut the time step in a half if possible
161  if (dt < _dt_min)
162  dt = _dt_min;
163  _time_sequence.insert(_time_sequence.begin() + _current_step + 1,
165  return computeDT();
166 }
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:346
virtual Real computeFailedDT() override
Called to compute _current_dt after a solve has failed.
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)
Transient & _executioner
Reference to transient executioner.
Definition: TimeStepper.h:128
void setupSequence(const std::vector< Real > &times)
virtual bool converged() const
If the time step converged.
Definition: TimeStepper.C:197
const Real _cutback_factor_at_failure
Cutback factor if a time step fails to converge.
Definition: TimeStepper.h:149
bool isRestarting() const
Whether or not this is a "restart" calculation.
Definition: MooseApp.C:1173
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:522
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:69
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 ...
bool XFEMRepeatStep() const
This function checks the _xfem_repeat_step flag set by solve.
virtual Real computeDT() override
Called to compute _current_dt for a normal step.
Real & endTime()
Get a modifiable reference to the end time.
Definition: Transient.h:183
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual Real computeInitialDT() override
Called to compute _current_dt for the first timestep.
FixedPointSolve & fixedPointSolve()
Definition: Executioner.h:134
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:135
virtual void step() override
Take a time step.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
virtual void step()
Take a time step.
Definition: TimeStepper.C:166
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object...
Real getStartTime() const
Return the start time.
Definition: Transient.h:171
bool isRecovering() const
Whether or not this is a "recover" calculation.
Definition: MooseApp.C:1167
void ErrorVector unsigned int