46 using namespace Input::Type;
53 "Setting of the simulation time. (can be specific to one equation)")
56 "Start time of the simulation.")
58 "End time of the simulation.")
60 "Initial guess for the time step.\n"
61 "The time step is fixed if the hard time step limits are not set.\n"
62 "If set to 0.0, the time step is determined in fully autonomous way if the equation supports it.")
64 "Hard lower limit for the time step.")
66 "Hard upper limit for the time step.");
77 init_common(input.
val<
double>(
"init_dt"),
78 input.
val<
double>(
"start_time"),
79 input.
val<
double>(
"end_time", inf_time),
83 set_permanent_constraint(
84 input.
val<
double>(
"min_dt", min_time_step_),
85 input.
val<
double>(
"max_dt", max_time_step_)
87 }
catch(ExcTimeGovernorMessage &exc) {
106 init_common(0.0, init_time, inf_time, eq_mark_type);
117 if (init_time < 0.0) {
118 THROW(ExcTimeGovernorMessage()
119 << EI_Message(
"Start time has to be greater or equal to 0.0\n")
124 init_time_ = time_ = init_time;
125 last_time_ = -inf_time;
126 last_time_step_ = inf_time;
129 if (end_time < init_time) {
130 THROW(ExcTimeGovernorMessage() << EI_Message(
"End time must be greater than start time.\n") );
133 end_time_ = end_time;
137 fixed_time_step_=0.0;
138 is_time_step_fixed_=
false;
139 time_step_changed_=
true;
140 end_of_fixed_dt_interval_ = time_;
142 min_time_step_=lower_constraint_=time_step_lower_bound;
143 if (end_time_ == inf_time) {
144 max_time_step_=upper_constraint_=inf_time;
146 max_time_step_=upper_constraint_= end_time - time_;
149 time_step_=max_time_step_;
152 if (dt < time_step_lower_bound)
153 THROW(ExcTimeGovernorMessage() << EI_Message(
"Fixed time step small then machine precision. \n") );
156 is_time_step_fixed_=
true;
157 time_step_changed_=
true;
158 end_of_fixed_dt_interval_ = inf_time;
160 upper_constraint_=max_time_step_=dt;
161 lower_constraint_=min_time_step_=dt;
168 time_marks_.add(
TimeMark(time_, equation_fixed_mark_type()) );
169 if (end_time_ != inf_time)
170 time_marks_.add(
TimeMark(end_time_, equation_fixed_mark_type()) );
180 if (min_dt < time_step_lower_bound) {
181 THROW(ExcTimeGovernorMessage() << EI_Message(
"'min_dt' smaller then machine precision.\n") );
183 if (max_dt < min_dt) {
184 THROW(ExcTimeGovernorMessage() << EI_Message(
"'max_dt' smaller then 'min_dt'.\n") );
187 lower_constraint_ = min_time_step_ = max(min_dt, time_step_lower_bound);
188 upper_constraint_ = max_time_step_ = min(max_dt, end_time_-time_);
200 if (upper_constraint_ < upper)
206 if (lower_constraint_ <= upper)
209 upper_constraint_ = upper;
213 if (lower_constraint_ > upper)
224 if (upper_constraint_ < lower)
230 if (min_time_step_ <= lower)
233 lower_constraint_ = lower;
237 if (min_time_step_ > lower)
250 if (end_time() == inf_time) {
251 THROW(ExcTimeGovernorMessage()
252 << EI_Message(
"Missing end time for making output grid required by key 'time_step' of the output stream.\n")
256 marks().add_time_marks(init_time_, step, end_time(), mark_type | eq_mark_type_);
258 marks().add(
TimeMark(init_time_, mark_type | eq_mark_type_));
259 marks().add(
TimeMark(end_time(), mark_type | eq_mark_type_));
265 if (is_end())
return 0.0;
267 if (this->lt(end_of_fixed_dt_interval_))
return fixed_time_step_;
272 double full_step = fix_time_it->
time() - time_;
274 double step_estimate = min(full_step, upper_constraint_);
275 step_estimate = max(step_estimate, lower_constraint_);
277 if (step_estimate == inf_time)
return step_estimate;
281 int n_steps = ceil( full_step / step_estimate );
285 int n_floor_steps = floor(full_step / step_estimate);
286 if ( abs(full_step / step_estimate - n_floor_steps) < round_n_steps_precision) n_steps = n_floor_steps;
288 step_estimate = full_step / n_steps;
292 if (step_estimate < lower_constraint_)
293 xprintf(
Warn,
"Time step estimate is below the lower constraint of time step. The difference is: %.16f.\n",
294 lower_constraint_ - step_estimate);
296 return step_estimate;
304 if (is_end())
return;
306 if (this->lt(end_of_fixed_dt_interval_)) {
310 if (end_of_fixed_dt_interval_ < inf_time) {
311 fixed_time_step_ = (end_of_fixed_dt_interval_-time_) / round( (end_of_fixed_dt_interval_-time_) / fixed_time_step_ );
314 last_time_step_ = time_step_;
315 time_step_ = fixed_time_step_;
318 if (is_time_step_fixed_)
320 is_time_step_fixed_ =
false;
323 time_step_changed_ = (last_time_step_ != time_step_);
326 time_step_changed_ =
false;
331 last_time_step_ = time_step_;
332 time_step_ = estimate_dt();
333 time_step_changed_= (last_time_step_ != time_step_);
340 upper_constraint_ = min(end_time_ - time_, max_time_step_);
341 lower_constraint_ = min_time_step_;
349 xprintf(
Msg,
"\nTG[%s]:%06d t:%10.4f dt:%10.6f dt_int<%10.6f,%10.6f>",
350 name, time_level_, time_, time_step_, lower_constraint_, upper_constraint_ );
351 #ifdef DEBUG_MESSAGES
352 xprintf(
Msg,
" end_time: %f end_fixed_time: %f type: 0x%x\n" , end_time_, end_of_fixed_dt_interval_, eq_mark_type_);
361 static char buffer[1024];
362 sprintf(buffer,
"\n%06d t:%10.4f dt:%10.6f dt_int<%10.6f,%10.6f>\n",
364 return (out << buffer);
void init_common(double dt, double init_time, double end_time, TimeMark::Type type)
Common part of the constructors. Set most important parameters, check they are valid and set default ...
static const double round_n_steps_precision
Rounding precision for computing number of steps. Used in estimate_dt().
Iterator over TimeMark objects in TimeMarks object (database of TimeMark objects).
static TimeMarks time_marks_
double upper_constraint() const
TimeGovernor(const Input::Record &input, TimeMark::Type fixed_time_mask=TimeMark::none_type)
Constructor for unsteady solvers.
void set_permanent_constraint(double min_dt, double max_dt)
Sets permanent constraints for time step.
void next_time()
Proceed to the next time according to current estimated time step.
Basic time management functionality for unsteady (and steady) solvers (class Equation).
static const Type none_type
Mask that matches no type of TimeMark.
Basic time management class.
double estimate_dt() const
Estimate choice of next time step according to actual setting of constraints.
void view(const char *name="") const
void add_time_marks_grid(double step, TimeMark::Type mark_type=TimeMark::none_type) const
int set_lower_constraint(double lower)
Sets lower constraint for the next time step estimating.
double lower_constraint() const
static Input::Type::Record input_type
This class is a collection of time marks to manage various events occurring during simulation time...
int set_upper_constraint(double upper)
Sets upper constraint for the next time step estimating.
static const double time_step_lower_bound
Technical bound for the time step given by finite precision.
double time() const
Getter for the time of the TimeMark.
Class used for marking specified times at which some events occur.
static const double inf_time
Infinity time used for steady case.
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.