40 return Record(
"TimeGovernor",
41 "Setting of the simulation time. (can be specific to one equation)")
44 "Start time of the simulation.")
46 "End time of the simulation.")
48 "Initial guess for the time step.\n" 49 "Only useful for equations that use adaptive time stepping." 50 "If set to 0.0, the time step is determined in fully autonomous" 51 " way if the equation supports it.")
54 "Soft lower limit for the time step. Equation using adaptive time stepping can not" 55 "suggest smaller time step, but actual time step could be smaller in order to match " 56 "prescribed input or output times.")
59 "Hard upper limit for the time step. Actual length of the time step is also limited" 60 "by input and output times.")
118 out <<
"time: " << t_step.
end() <<
"step: " << t_step.
length() << endl;
130 init_common(input.
val<
double>(
"start_time"),
131 input.
val<
double>(
"end_time", inf_time),
133 set_permanent_constraint(
134 input.
val<
double>(
"min_dt", min_time_step_),
135 input.
val<
double>(
"max_dt", max_time_step_)
138 double init_dt=input.
val<
double>(
"init_dt");
142 lower_constraint_=init_dt;
143 lower_constraint_message_ =
"Initial time step set by user.";
144 upper_constraint_=init_dt;
145 upper_constraint_message_ =
"Initial time step set by user.";
149 }
catch(ExcTimeGovernorMessage &exc) {
160 if (dt < time_step_precision)
161 THROW(ExcTimeGovernorMessage() << EI_Message(
"Fixed time step smaller then machine precision. \n") );
164 is_time_step_fixed_=
true;
165 time_step_changed_=
true;
166 end_of_fixed_dt_interval_ = inf_time;
168 lower_constraint_=min_time_step_=dt;
169 lower_constraint_message_ =
"Initial time step set by user.";
170 upper_constraint_=max_time_step_=dt;
171 upper_constraint_message_ =
"Initial time step set by user.";
183 init_common(init_time, inf_time, eq_mark_type);
194 if (init_time < 0.0) {
195 THROW(ExcTimeGovernorMessage()
196 << EI_Message(
"Start time has to be greater or equal to 0.0\n")
201 recent_steps_.set_capacity(size_of_recent_steps_);
202 recent_steps_.push_front(
TimeStep(init_time));
203 init_time_=init_time;
205 if (end_time < init_time) {
206 THROW(ExcTimeGovernorMessage() << EI_Message(
"End time must be greater than start time.\n") );
208 end_time_ = end_time;
213 fixed_time_step_=0.0;
214 is_time_step_fixed_=
false;
215 time_step_changed_=
true;
216 end_of_fixed_dt_interval_ = init_time_;
218 min_time_step_=lower_constraint_=time_step_precision;
219 lower_constraint_message_ =
"Permanent minimal constraing, default, time_step_precision.";
220 if (end_time_ == inf_time) {
221 max_time_step_=upper_constraint_=inf_time;
223 max_time_step_=upper_constraint_= end_time - init_time_;
225 upper_constraint_message_ =
"Permanent maximal constraint, default, total simulation time.";
246 time_marks_.add(
TimeMark(init_time_, equation_fixed_mark_type()) );
247 if (end_time_ != inf_time)
248 time_marks_.add(
TimeMark(end_time_, equation_fixed_mark_type()) );
258 if (min_dt < time_step_precision) {
259 THROW(ExcTimeGovernorMessage() << EI_Message(
"'min_dt' smaller then machine precision.\n") );
261 if (max_dt < min_dt) {
262 THROW(ExcTimeGovernorMessage() << EI_Message(
"'max_dt' smaller then 'min_dt'.\n") );
265 lower_constraint_ = min_time_step_ = max(min_dt, time_step_precision);
266 lower_constraint_message_ =
"Permanent minimal constraint, custom.";
267 upper_constraint_ = max_time_step_ = min(max_dt, end_time_-t());
268 upper_constraint_message_ =
"Permanent maximal constraint, custom.";
281 if (upper_constraint_ < upper) {
285 if (lower_constraint_ > upper) {
287 upper_constraint_ = lower_constraint_;
288 upper_constraint_message_ =
"Forced lower constraint. " + message;
292 upper_constraint_ = upper;
293 upper_constraint_message_ = message;
302 if (upper_constraint_ < lower) {
304 lower_constraint_ = upper_constraint_;
307 if (lower_constraint_ > lower) {
312 lower_constraint_ = lower;
313 lower_constraint_message_ = message;
322 if (steady_)
return 0.0;
323 end_of_fixed_dt_interval_=-inf_time;
324 fixed_time_step_ = estimate_dt();
325 is_time_step_fixed_ =
true;
326 return end_of_fixed_dt_interval_ = time_marks_.next(*
this, equation_fixed_mark_type())->time();
334 if (end_time() == inf_time) {
335 THROW(ExcTimeGovernorMessage()
336 << EI_Message(
"Missing end time for making output grid required by key 'time_step' of the output stream.\n")
340 marks().add_time_marks(init_time_, step, end_time(), mark_type | eq_mark_type_);
342 marks().add(
TimeMark(init_time_, mark_type | eq_mark_type_));
343 marks().add(
TimeMark(end_time(), mark_type | eq_mark_type_));
350 return time_marks_.current(step(), type) != time_marks_.end(type);
356 if (is_end())
return 0.0;
358 if (this->step().
lt(end_of_fixed_dt_interval_))
return fixed_time_step_;
363 double full_step = fix_time_it->
time() - t();
365 double step_estimate = min(full_step, upper_constraint_);
366 step_estimate = max(step_estimate, lower_constraint_);
368 if (step_estimate == inf_time)
return step_estimate;
374 double n_steps = ceil( full_step / step_estimate - time_step_precision);
375 step_estimate = full_step / n_steps;
378 if (n_steps > 1 && abs(step_estimate - step().
length()) < time_step_precision) {
379 step_estimate=step().length();
384 if (step_estimate < lower_constraint_) {
385 static char buffer[1024];
386 sprintf(buffer,
"Time step estimate is below the lower constraint of time step. The difference is: %.16f.\n",
387 lower_constraint_ - step_estimate);
391 return step_estimate;
399 if (is_end())
return;
402 if (this->step().
lt(end_of_fixed_dt_interval_)) {
406 if (end_of_fixed_dt_interval_ < inf_time) {
407 fixed_time_step_ = (end_of_fixed_dt_interval_-t()) / round( (end_of_fixed_dt_interval_-t()) / fixed_time_step_ );
410 recent_steps_.push_front(recent_steps_.front().make_next(fixed_time_step_));
414 if (is_time_step_fixed_)
416 is_time_step_fixed_ =
false;
419 time_step_changed_ = (step(-2).length() != step().length());
422 time_step_changed_ =
false;
427 double dt=estimate_dt();
430 recent_steps_.push_front(step_);
432 time_step_changed_= (step(-2).length() != step().length());
435 last_lower_constraint_ = lower_constraint_;
436 last_upper_constraint_ = upper_constraint_;
438 upper_constraint_ = min(end_time_ - t(), max_time_step_);
439 lower_constraint_ = min_time_step_;
440 lower_constraint_message_ =
"Permanent minimal constraint, in next time.";
441 upper_constraint_message_ =
"Permanent maximal constraint, in next time.";
446 double prior_dt = dt();
447 double new_upper_constraint = factor * dt();
451 recent_steps_.pop_front();
453 upper_constraint_ = last_upper_constraint_;
454 lower_constraint_ = last_lower_constraint_;
457 int current_minus_new = set_upper_constraint(new_upper_constraint,
"Reduce time step.");
458 if (current_minus_new < 0)
460 THROW(ExcMessage() << EI_Message(
"Internal error."));
465 return dt() / prior_dt;
471 unsigned int back_idx;
473 back_idx =
static_cast<unsigned int>(-index-1);
475 back_idx =
static_cast<unsigned int>(recent_steps_[0].index() -
index);
477 if ( back_idx >= recent_steps_.size())
478 THROW(ExcMissingTimeStep() << EI_Index(index) << EI_BackIndex(back_idx) << EI_HistorySize(recent_steps_.size()));
480 return recent_steps_[back_idx];
488 static char buffer[1024];
489 #ifdef FLOW123D_DEBUG_MESSAGES 490 sprintf(buffer,
"TG[%s]:%06d t:%10.4f dt:%10.6f dt_int<%10.6f,%10.6f> end_time: %f end_fixed_time: %f type: 0x%x\n",
491 name, tlevel(), t(), dt(), lower_constraint_, upper_constraint_, end_time_, end_of_fixed_dt_interval_, eq_mark_type_);
493 sprintf(buffer,
"TG[%s]:%06d t:%10.4f dt:%10.6f dt_int<%10.6f,%10.6f>\n",
494 name, tlevel(), t(), dt(), lower_constraint_, upper_constraint_ );
497 MessageOut().fmt(
"Lower time step constraint [{}]: {} \nUpper time step constraint [{}]: {} \n",
498 lower_constraint_, lower_constraint_message_.c_str(),
499 upper_constraint_, upper_constraint_message_.c_str() );
507 static char buffer[1024];
508 sprintf(buffer,
"\n%06d t:%10.4f dt:%10.6f dt_int<%10.6f,%10.6f>\n",
510 return (out << buffer);
Iterator over TimeMark objects in TimeMarks object (database of TimeMark objects).
double reduce_timestep(double factor)
Force timestep reduction in particular in the case of failure of the non-linear solver.
static TimeMarks time_marks_
bool lt(double other_time) const
double upper_constraint() const
TimeGovernor(const Input::Record &input, TimeMark::Type fixed_time_mask=TimeMark::none_type)
Constructor for unsteady solvers.
#define MessageOut()
Macro defining 'message' record of log.
double fix_dt_until_mark()
Fixing time step until fixed time mark.
int set_lower_constraint(double lower, std::string message)
Sets lower constraint for the next time step estimating.
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.
bool is_current(const TimeMark::Type &mask) const
const TimeStep & step(int index=-1) const
Basic time management functionality for unsteady (and steady) solvers (class Equation).
static const Type none_type
Mark Type with all bits unset.
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
std::string sprintf(CStringRef format, ArgList args)
static const double time_step_precision
double lower_constraint() const
unsigned int index_
Index of the step is index if the end time. Zero time step is artificial.
This class is a collection of time marks to manage various events occurring during simulation time...
TimeStep make_next(double new_length) const
int set_upper_constraint(double upper, std::string message)
Sets upper constraint for the next time step estimating.
void init_common(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 ...
bool safe_compare(double t1, double t0) const
double time() const
Getter for the time of the TimeMark.
static const Input::Type::Record & get_input_type()
#define WarningOut()
Macro defining 'warning' record of log.
unsigned int index() const
Class used for marking specified times at which some events occur.
#define OLD_ASSERT_LE(a, b)
ostream & operator<<(ostream &out, const TimeStep &t_step)
static const double inf_time
Infinity time used for steady case.
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Representation of one time step..
double end_
End time point of the time step.