https://mooseframework.inl.gov
Loading...
Searching...
No Matches
CompositionDT.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
10#include "CompositionDT.h"
11#include "MooseApp.h"
12#include "Transient.h"
14#include "IterationAdaptiveDT.h"
15#include "FEProblemBase.h"
16
17#include <limits>
18
20
23{
24 auto params = emptyInputParameters();
25
26 params.addParam<Real>("initial_dt", "Initial value of dt");
27 params.addParam<std::vector<std::string>>(
28 "lower_bound",
29 {},
30 "The maximum of these TimeSteppers will form the lower bound on the time "
31 "step size. A single or multiple time steppers may be specified.");
32
33 return params;
34}
35
38{
41
42 params.addClassDescription("The time stepper takes all the other time steppers as input and "
43 "returns the minimum time step size.");
44
45 return params;
46}
47
49 : TimeStepper(parameters),
50 _has_initial_dt(isParamValid("initial_dt")),
51 _initial_dt(_has_initial_dt ? getParam<Real>("initial_dt") : 0.),
52 _lower_bound(getParam<std::vector<std::string>>("lower_bound").begin(),
53 getParam<std::vector<std::string>>("lower_bound").end()),
54 _current_time_stepper(nullptr),
55 _largest_bound_time_stepper(nullptr),
56 _closest_time_sequence_stepper(nullptr)
57{
58 // Make sure the steppers in "lower_bound" exist
59 const auto time_steppers = getTimeSteppers();
60 for (const auto & time_stepper_name : _lower_bound)
61 if (std::find_if(time_steppers.begin(),
62 time_steppers.end(),
63 [&time_stepper_name](const auto & ts)
64 { return ts->name() == time_stepper_name; }) == time_steppers.end() &&
65 _lower_bound.size() != 0)
67 "lower_bound", "Failed to find a timestepper with the name '", time_stepper_name, "'");
68}
69
70template <typename Lambda>
71void
73{
74 for (auto & ts : getTimeSteppers())
75 act(*ts);
76}
77
78void
80{
82 {
83 const auto half_end_time = _executioner.endTime();
85 [this, half_end_time](auto & ts)
86 {
87 _executioner.endTime() = half_end_time;
88 ts.init();
89 });
90 _executioner.endTime() = half_end_time;
91 }
92 else
93 actOnTimeSteppers([](auto & ts) { ts.init(); });
94}
95
96void
98{
99 actOnTimeSteppers([](auto & ts) { ts.preExecute(); });
100}
101
102void
104{
105 actOnTimeSteppers([](auto & ts) { ts.preSolve(); });
106}
107
108void
110{
111 actOnTimeSteppers([](auto & ts) { ts.postSolve(); });
112}
113
114void
116{
117 actOnTimeSteppers([](auto & ts) { ts.postExecute(); });
118}
119
120void
122{
123 actOnTimeSteppers([](auto & ts) { ts.preStep(); });
124}
125
126void
128{
129 actOnTimeSteppers([](auto & ts) { ts.postStep(); });
130}
131
132bool
134{
135 bool at_sync_point = TimeStepper::constrainStep(dt);
136 const auto time_steppers = getTimeSteppers();
137 for (auto & ts : time_steppers)
138 if (ts->constrainStep(dt))
139 return true;
140 return at_sync_point;
141}
142
143Real
148
149Real
151{
152 const auto time_steppers = getTimeSteppers();
153 // Note : compositionDT requires other active time steppers as input so no active time steppers
154 // or only compositionDT is active is not allowed
155 if (time_steppers.size() < 1)
156 mooseError("No TimeStepper(s) are currently active to compute a timestep");
157
158 std::set<std::pair<Real, TimeStepper *>, CompareFirst> dts, bound_dt;
159
160 for (auto & ts : time_steppers)
161 if (!dynamic_cast<TimeSequenceStepperBase *>(ts))
162 {
163 ts->computeStep();
164 const auto dt = ts->getCurrentDT();
165
166 if (_lower_bound.count(ts->name()))
167 bound_dt.emplace(dt, ts);
168 else
169 dts.emplace(dt, ts);
170 }
171
172 _current_time_stepper = dts.size() ? dts.begin()->second : nullptr;
173 _largest_bound_time_stepper = bound_dt.size() ? (--bound_dt.end())->second : nullptr;
174
175 _dt = produceCompositionDT(dts, bound_dt);
176
177 return _dt;
178}
179
180Real
182{
183 const auto time_steppers = getTimeSteppers();
184
185 std::vector<TimeSequenceStepperBase *> time_sequence_steppers;
186 for (auto & ts : time_steppers)
187 if (auto tss = dynamic_cast<TimeSequenceStepperBase *>(ts))
188 time_sequence_steppers.push_back(tss);
189
190 if (time_sequence_steppers.empty())
191 return 0;
192
193 Real next_time_to_hit = std::numeric_limits<Real>::max();
194 for (auto & tss : time_sequence_steppers)
195 {
196 Real ts_time_to_hit;
197 if (!tss->advanceToFutureTime(_time, _dt_min, ts_time_to_hit))
198 continue;
199
200 if (next_time_to_hit > ts_time_to_hit)
201 {
203 next_time_to_hit = ts_time_to_hit;
204 }
205 }
206 return next_time_to_hit;
207}
208
209Real
211 std::set<std::pair<Real, TimeStepper *>, CompareFirst> & dts,
212 std::set<std::pair<Real, TimeStepper *>, CompareFirst> & bound_dts)
213{
214 Real minDT, lower_bound, dt;
215 minDT = lower_bound = dt = 0.0;
216 if (!dts.empty())
217 minDT = dts.begin()->first;
218 if (!bound_dts.empty())
219 lower_bound = bound_dts.rbegin()->first;
220
221 if (minDT > lower_bound)
222 dt = minDT;
223 else
224 {
225 dt = lower_bound;
227 }
228
229 auto ts = getSequenceSteppersNextTime();
230
231 if (ts != 0 && (ts - _time) < dt)
232 {
234 return std::min((ts - _time), dt);
235 }
236 else
237 return dt;
238}
239
240std::vector<TimeStepper *>
242{
243 std::vector<TimeStepper *> time_steppers;
245 .query()
246 .condition<AttribSystem>("TimeStepper")
247 .queryInto(time_steppers);
248
249 // Remove CompositionDT from time_steppers vector to avoid recursive call
250 time_steppers.erase(std::remove(time_steppers.begin(), time_steppers.end(), this),
251 time_steppers.end());
252 return time_steppers;
253}
254
255void
257{
259 {
261 if (!converged())
263 }
264 else
266}
267
268void
270{
271 actOnTimeSteppers([](auto & ts) { ts.acceptStep(); });
272}
273
274void
276{
277 actOnTimeSteppers([](auto & ts) { ts.rejectStep(); });
278}
279
280bool
registerMooseObject("MooseApp", CompositionDT)
InputParameters emptyInputParameters()
A TimeStepper that takes time steppers as inputs and computes the minimum time step size among all ti...
virtual void preStep() override final
virtual void preExecute() override final
virtual void postSolve() override final
virtual bool constrainStep(Real &dt) override final
Called after computeStep() is called.
virtual void step() override final
Functions called after the current DT is computed.
virtual void preSolve() override final
const bool _has_initial_dt
const std::set< std::string > _lower_bound
virtual void postExecute() override final
Real getSequenceSteppersNextTime()
CompositionDT(const InputParameters &parameters)
TimeStepper * _current_time_stepper
Real produceCompositionDT(std::set< std::pair< Real, TimeStepper * >, CompareFirst > &dts, std::set< std::pair< Real, TimeStepper * >, CompareFirst > &bound_dts)
Find the composed time step size by selecting the minimum value and compare it with the lower bound i...
static InputParameters validParams()
virtual void postStep() override final
TimeSequenceStepperBase * _closest_time_sequence_stepper
std::vector< TimeStepper * > getTimeSteppers()
Internal method for querying TheWarehouse for the currently active timesteppers.
const Real _initial_dt
TimeStepper * _largest_bound_time_stepper
virtual bool converged() const override final
The _current_time_stepper is used to check whether convergence was reached on the time step.
virtual void rejectStep() override final
This gets called when time step is rejected for all input time steppers.
virtual void acceptStep() override final
This gets called when time step is accepted for all input time steppers.
virtual void init() override final
Initialize all the input time stepper(s).
virtual Real computeDT() override final
Computes time step size after the initial time step.
virtual Real computeInitialDT() override final
Computes time step size for the initial time step.
void actOnTimeSteppers(Lambda &&act)
static InputParameters compositionDTParams()
TheWarehouse & theWarehouse() const
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
bool testCheckpointHalfTransient() const
Whether or not this simulation should only run half its transient (useful for testing recovery)
Definition MooseApp.h:524
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:457
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:271
MooseApp & _app
The MOOSE application this is associated with.
Definition MooseBase.h:375
QueryCache & condition(Args &&... args)
Adds a new condition to the query.
Query query()
query creates and returns an initialized a query object for querying objects from the warehouse.
Solves the PDEs at a sequence of given time points.
Base class for time stepping.
Definition TimeStepper.h:23
virtual bool converged() const
If the time step converged.
unsigned int _failure_count
Cumulative amount of steps that have failed.
FEProblemBase & _fe_problem
static InputParameters validParams()
Definition TimeStepper.C:16
TransientBase & _executioner
Reference to transient executioner.
Real & _dt_min
virtual void step()
Take a time step.
virtual bool constrainStep(Real &dt)
Called after computeStep() is called.
Real & _time
Values from executioner.
Real & endTime()
Get a modifiable reference to the end time.
Comparator for sorting by the value of dt for the TimeStepper sets which stored the pairs of the dt a...