Flow123d  release_3.0.0-968-gc87a28e79
time_governor.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file time_governor.cc
15  * @ingroup application
16  * @brief Basic time management class.
17  */
18 
19 #include <limits>
20 #include "system/system.hh"
21 #include "input/accessors.hh"
22 #include "time_governor.hh"
23 #include "time_marks.hh"
24 #include "unit_si.hh"
25 
26 /*******************************************************************
27  * implementation of TimeGovernor static values and methods
28  */
29 
30 //initialize constant pointer to TimeMarks object
32 
33 //const double TimeGovernor::time_step_lower_bound = numeric_limits<double>::epsilon();
34 
35 #define MAX_END_TIME 5.0e+17
36 #define MAX_END_TIME_STR "5.0e+17"
37 
38 const double TimeGovernor::inf_time = numeric_limits<double>::infinity();
39 const double TimeGovernor::max_end_time = MAX_END_TIME; // more then age of universe in seconds.
40 const double TimeGovernor::time_step_precision = 16*numeric_limits<double>::epsilon();
41 
42 
43 using namespace Input::Type;
44 
45 
46 const Tuple & TimeGovernor::get_input_time_type(double lower_bound, double upper_bound)
47 {
48  return Tuple("TimeValue", "A time with unit specification.")
49  .declare_key("time", Double(lower_bound, upper_bound), Default::obligatory(),
50  "Numeric value of time." )
51  .declare_key("unit", String(), Default::read_time("Common time unit of equation defined in Time Governor"),
52  "Specify unit of an input time value.")
53  .close();
54 }
55 
56 
58  static const Tuple &dt_step =
59  Tuple("DtLimits", "Time dependent changes in min_dt and max_dt limits.")
61  "The start time of dt step set.")
62  .declare_key("min_dt", TimeGovernor::get_input_time_type(), Default::read_time("'min_dt' value of TimeGovernor."),
63  "Soft lower limit for the time step.")
64  .declare_key("max_dt", TimeGovernor::get_input_time_type(), Default::read_time("'max_dt' value of TimeGovernor."),
65  "Whole time of the simulation if specified, infinity else.")
66  .close();
67 
68  return Record("TimeGovernor",
69  "Time axis settings of the simulation.\n"
70  "The settings is specific to a particular equation.\n"
71  "TimeGovernor allows to:\n"
72  " - define start time and end time of simulation\n"
73  " - define lower and upper limits of time steps\n"
74  " - direct fixed time marks of whole simulation\n"
75  " - set global time unit of equation (see 'common_time_unit' key)\n"
76  "Limits of time steps are defined by keys 'min_dt', 'max_dt', 'init_dt' and 'dt_limits'. Key "
77  "'init_dt' has the highest priority and allows set fix size of time steps. Pair of keys 'min_dt' "
78  "and 'max_dt' define interval of time steps. Both previous cases ('init_dt' or pair 'min_dt' "
79  "and 'max_dt') set global limits of whole simulation. In contrasts, 'dt_limits' allow set "
80  "time-dependent function of min_dt/max_dt. Used time steps of simulation can be printed to YAML "
81  "output file (see 'write_used_timesteps'.\n"
82  "Fixed time marks define exact values of time steps. They are defined in:\n"
83  " - start time and end time of simulation\n"
84  " - output times printed to output mesh file\n"
85  " - times defined in 'dt_limits' table (optional, see 'add_dt_limits_time_marks' key)")
86  .allow_auto_conversion("max_dt")
87  .declare_key("start_time", TimeGovernor::get_input_time_type(), Default("0.0"),
88  "Start time of the simulation.")
90  "End time of the simulation.\n"
91  "The default value is higher than the age of the Universe (given in seconds).")
92  .declare_key("init_dt", TimeGovernor::get_input_time_type(0.0), Default("0.0"),
93  "Initial guess for the time step.\n"
94  "It applies to equations that use an adaptive time stepping. "
95  "If set to 0.0, the time step is determined in fully autonomous "
96  "way, assuming the equation supports it.")
98  Default::read_time("Machine precision."),
99  "Soft lower limit for the time step.\n"
100  "Equation using an adaptive time stepping cannot suggest smaller time step. "
101  "The actual time step can only decrease below the limit in order to match "
102  "the prescribed input or output times.")
104  Default::read_time("Whole time of the simulation if specified, infinity else."),
105  "Hard upper limit for the time step.\n"
106  "The actual time step can only increase above the limit in order to match "
107  "the prescribed input or output times.")
108  .declare_key("dt_limits", Array(dt_step), Default::optional(),
109  "Allow to set a time dependent changes in ``min_dt`` and ``max_dt`` limits. This list is processed "
110  "at individual times overwriting previous values of ``min_dt``/``max_dt``. Limits equal to 0 are "
111  "ignored and replaced with ``min_dt``/``max_dt`` values.")
112  .declare_key("add_dt_limits_time_marks", Bool(), Default("false"), "Add all times defined in ``dt_limits`` "
113  "table to the list of fixed TimeMarks.")
114  .declare_key("write_used_timesteps", FileName::output(), Default::optional(),
115  "Write used time steps to the given file in YAML format corresponding with the format of ``dt_limits``.")
116  .declare_key("common_time_unit", String(), Default("\"s\""),
117  "Common time unit of the equation.\nThis unit will be used for all time inputs and outputs "
118  "within the equation. Individually, the common time unit can be overwritten for every declared time.\n"
119  "Time units are used in the following cases:\n"
120  "1) Time units of time value keys in: TimeGovernor, FieldDescriptors.\n"
121  " The common time unit can be overwritten for every declared time.\n"
122  "2) Time units in: \n"
123  " a) input fields: FieldFE and FieldTimeFunction\n"
124  " b) time steps definition of OutputTimeSet\n"
125  " Common time unit can be overwritten by one unit value for every whole mesh data file or time function.\n"
126  "3) Time units in output files: observation times, balance times, frame times of VTK and GMSH\n"
127  " Common time unit cannot be overwritten in these cases."
128  )
129  .close();
130 }
131 
132 
133 
134 /*******************************************************************
135  * implementation of TimeUnitConversion
136  */
137 
138 TimeUnitConversion::TimeUnitConversion(std::string user_defined_unit)
139 : unit_string_(user_defined_unit)
140 {
141  coef_ = UnitSI().s().convert_unit_from(user_defined_unit);
142 }
143 
144 
145 
147 : coef_(1.0), unit_string_("s") {}
148 
149 
150 
151 double TimeUnitConversion::read_time(Input::Iterator<Input::Tuple> time_it, double default_time) const {
152  if (time_it) {
153  double time = time_it->val<double>("time");
154  string time_unit;
155  if (time_it->opt_val<string>("unit", time_unit)) {
156  return ( time * UnitSI().s().convert_unit_from(time_unit) );
157  } else {
158  return ( time * coef_ );
159  }
160  } else {
161  ASSERT(default_time!=std::numeric_limits<double>::quiet_NaN()).error("Undefined default time!");
162  return default_time;
163  }
164 }
165 
166 
167 
169  if (unit_it) {
170  return UnitSI().s().convert_unit_from(*unit_it);
171  } else {
172  return coef_;
173  }
174 }
175 
176 
177 
178 /*******************************************************************
179  * implementation of TimeStep
180  */
181 
182 TimeStep::TimeStep(double init_time, std::shared_ptr<TimeUnitConversion> time_unit_conversion) :
183 index_(0),
184 length_(1.0),
185 end_(init_time),
186 time_unit_conversion_(time_unit_conversion)
187 {}
188 
189 
190 
192 index_(0),
193 length_(TimeGovernor::inf_time),
194 end_(-TimeGovernor::inf_time)
195 {
196  time_unit_conversion_ = std::make_shared<TimeUnitConversion>();
197 }
198 
199 
200 
201 
203 index_(other.index_),
204 length_(other.length_),
205 end_(other.end_),
206 time_unit_conversion_(other.time_unit_conversion_)
207 {}
208 
209 
210 
211 TimeStep TimeStep::make_next(double new_length) const
212 {
213  return make_next(new_length, this->end_+new_length);
214 }
215 
216 
217 
218 TimeStep TimeStep::make_next(double new_lenght, double end_time) const
219 {
220  TimeStep ts;
221  ts.index_=this->index_ +1;
222  ts.length_=new_lenght;
223  ts.end_=end_time;
225  return ts;
226 }
227 
228 
229 
230 bool TimeStep::safe_compare(double t1, double t0) const
231 {
232  return t1 >= t0
233  - 16*numeric_limits<double>::epsilon()*(1.0+max(abs(t1),abs(t0)));
234 }
235 
236 
237 
238 double TimeStep::read_time(Input::Iterator<Input::Tuple> time_it, double default_time) const {
239  return time_unit_conversion_->read_time(time_it, default_time);
240 }
241 
242 
243 
245  return time_unit_conversion_->read_coef(unit_it);
246 }
247 
248 
249 
250 double TimeStep::get_coef() const {
251  return time_unit_conversion_->get_coef();
252 }
253 
254 
255 
256 ostream& operator<<(ostream& out, const TimeStep& t_step) {
257  out << "time: " << t_step.end() << "step: " << t_step.length() << endl;
258  return out;
259 }
260 
261 
262 
263 /*******************************************************************
264  * implementation of TimeGovernor
265  */
266 
267 TimeGovernor::TimeGovernor(const Input::Record &input, TimeMark::Type eq_mark_type, bool timestep_output)
268 : timestep_output_(timestep_output)
269 {
270  // use new mark type as default
271  if (eq_mark_type == TimeMark::none_type) eq_mark_type = marks().new_mark_type();
272 
273  try {
274 
275  string common_unit_string=input.val<string>("common_time_unit");
276  time_unit_conversion_ = std::make_shared<TimeUnitConversion>(common_unit_string);
277  limits_time_marks_ = input.val<bool>("add_dt_limits_time_marks");
278 
279  // Get rid of rounding errors.
280  double end_time = read_time( input.find<Input::Tuple>("end_time") );
282 
283  // set permanent limits
284  init_common(read_time( input.find<Input::Tuple>("start_time") ),
285  end_time,
286  eq_mark_type);
287  Input::Array limits_array = Input::Array();
288  input.opt_val("dt_limits", limits_array);
290  read_time( input.find<Input::Tuple>("min_dt"), min_time_step_),
291  read_time( input.find<Input::Tuple>("max_dt"), max_time_step_),
292  limits_array
293  );
294 
295  // check key write_used_timesteps, open YAML file, print first time step
296  if (timestep_output_)
297  if (input.opt_val("write_used_timesteps", timesteps_output_file_) ) {
298  try {
300  } INPUT_CATCH(FilePath::ExcFileOpen, FilePath::EI_Address_String, input)
301  timesteps_output_ << "- [ " << t() << ", " << dt_limits_table_[0].min_dt << ", " << dt_limits_table_[0].max_dt << " ]\n";
303  }
304 
305  double init_dt=read_time( input.find<Input::Tuple>("init_dt") );
306  if (init_dt > 0.0) {
307  // set first time step suggested by user
308  //time_step_=min(init_dt, time_step_);
309  lower_constraint_=init_dt;
310  lower_constraint_message_ = "Initial time step set by user.";
311  upper_constraint_=init_dt;
312  upper_constraint_message_ = "Initial time step set by user.";
313  }
314 
315 
316  } catch(ExcTimeGovernorMessage &exc) {
317  exc << input.ei_address();
318  throw;
319  }
320 
321 }
322 
323 TimeGovernor::TimeGovernor(double init_time, double dt)
324 : dt_limits_pos_(0), timestep_output_(false)
325 {
326  time_unit_conversion_ = std::make_shared<TimeUnitConversion>();
328  // fixed time step
329  if (dt < time_step_precision)
330  THROW(ExcTimeGovernorMessage() << EI_Message("Fixed time step smaller then machine precision. \n") );
331 
333  is_time_step_fixed_=true;
334  time_step_changed_=true;
336 
337  // fill table limits with two records (start time, end time)
338  dt_limits_table_.push_back( DtLimitRow(init_time, dt, dt) );
339  dt_limits_table_.push_back( DtLimitRow(inf_time, dt, dt) );
340 
342  lower_constraint_message_ = "Initial time step set by user.";
344  upper_constraint_message_ = "Initial time step set by user.";
345 
346  //time_step_=dt;
347 }
348 
349 
350 // steady time governor constructor
351 TimeGovernor::TimeGovernor(double init_time, TimeMark::Type eq_mark_type)
352 : dt_limits_pos_(0), timestep_output_(false)
353 {
354  // use new mark type as default
355  if (eq_mark_type == TimeMark::none_type) eq_mark_type = marks().new_mark_type();
356 
357  time_unit_conversion_ = std::make_shared<TimeUnitConversion>();
358  init_common(init_time, inf_time, eq_mark_type);
359 
360  // fill table limits with two records (start time, end time)
363 
364  steady_ = true;
365 }
366 
367 
369 {
371  timesteps_output_.close();
372  }
373 }
374 
375 
376 // common part of constructors
377 void TimeGovernor::init_common(double init_time, double end_time, TimeMark::Type type)
378 {
379 
380  if (init_time < 0.0) {
381  THROW(ExcTimeGovernorMessage()
382  << EI_Message("Start time has to be greater or equal to 0.0\n")
383 
384  );
385  }
386 
387  recent_steps_.set_capacity(size_of_recent_steps_);
390 
391  if (end_time < init_time) {
392  THROW(ExcTimeGovernorMessage() << EI_Message("End time must be greater than start time.\n") );
393  } else {
395  }
396 
397  //if (dt == 0.0) {
398  // variable time step
399  fixed_time_step_=0.0;
400  is_time_step_fixed_=false;
401  time_step_changed_=true;
403 
405  lower_constraint_message_ = "Permanent minimal constraing, default, time_step_precision.";
407  upper_constraint_message_ = "Permanent maximal constraint, default, total simulation time.";
408  // choose maximum possible time step
409  //time_step_=max_time_step_;
410  /*} else {
411  // fixed time step
412  if (dt < time_step_lower_bound)
413  THROW(ExcTimeGovernorMessage() << EI_Message("Fixed time step smaller then machine precision. \n") );
414 
415  fixed_time_step_=dt;
416  is_time_step_fixed_=true;
417  time_step_changed_=true;
418  end_of_fixed_dt_interval_ = inf_time;
419 
420  upper_constraint_=max_time_step_=dt;
421  lower_constraint_=min_time_step_=dt;
422  time_step_=dt;
423 
424  }*/
425 
426  eq_mark_type_=type;
427  steady_=false;
429  //if (end_time_ != inf_time)
431 }
432 
433 
434 
435 void TimeGovernor::set_dt_limits( double min_dt, double max_dt, Input::Array dt_limits_list)
436 {
437  dt_limits_table_.clear();
438 
439  // check min_dt and max_dt set by user
440  if (min_dt < time_step_precision) {
441  THROW(ExcTimeGovernorMessage() << EI_Message("'min_dt' smaller than machine precision.\n") );
442  }
443  if (max_dt < min_dt) {
444  THROW(ExcTimeGovernorMessage() << EI_Message("'max_dt' smaller than 'min_dt'.\n") );
445  }
446 
447  bool first_step = true;
448  if (dt_limits_list.size())
449  for(auto it = dt_limits_list.begin<Input::Tuple>(); it != dt_limits_list.end(); ++it) {
450  double time = read_time( it->find<Input::Tuple>("time"));
451 
452  if (first_step) { // we need special check before setting first time step to the table
453  if (time > init_time_) { // table starts later than simulation, we need to add start time to the table
454  dt_limits_table_.push_back( DtLimitRow(init_time_, min_dt, max_dt) );
455  }
456  first_step = false;
457  }
458 
459  // next cases will be skipped
460  if (time < init_time_) {
461  WarningOut().fmt("Time {} define in 'dt_limits' table at address {} is lesser than start time of simulation "
462  "and can be skipped.\n", time, dt_limits_list.address_string());
463  }
464  if (dt_limits_table_.size() && (time <= dt_limits_table_[dt_limits_table_.size()-1].time) ) {
465  WarningOut().fmt("Time {} define in 'dt_limits' table at address {} is in incorrect order "
466  "and will be skipped.\n", time, dt_limits_list.address_string());
467  continue;
468  }
469  if ((time > end_time_) ) {
470  WarningOut().fmt("Time {} define in 'dt_limits' table at address {} is greater than end time of simulation "
471  "and will be skipped.\n", time, dt_limits_list.address_string());
472  continue;
473  }
474 
475  double min = read_time( it->find<Input::Tuple>("min_dt"), 0.0);
476  if (min == 0.0) min = min_dt;
477  double max = read_time( it->find<Input::Tuple>("max_dt"), 0.0);
478  if (max == 0.0) max = max_dt;
479 
480  if (min < time_step_precision) {
481  THROW(ExcTimeGovernorMessage() << EI_Message("'min_dt' in 'dt_limits' smaller than machine precision.\n") );
482  }
483  if (max < min) {
484  THROW(ExcTimeGovernorMessage() << EI_Message("'max_dt' in 'dt_limits' smaller than 'min_dt'.\n") );
485  }
486 
487  dt_limits_table_.push_back( DtLimitRow(time, min, max) );
488  if (limits_time_marks_) this->marks().add(TimeMark(time, this->equation_fixed_mark_type()));
489  }
490 
491  if (dt_limits_table_.size() == 0) {
492  // add start time to limit table if it is empty
493  dt_limits_table_.push_back( DtLimitRow(init_time_, min_dt, max_dt) );
494  }
495  if (dt_limits_table_[dt_limits_table_.size()-1].time < end_time_) {
496  // add time == end_time_ to limits table, we need only for check time, not for limits
497  dt_limits_table_.push_back( DtLimitRow(end_time_, min_dt, max_dt) );
498  }
499 
500  dt_limits_pos_ = 0;
501  while (dt_limits_table_[dt_limits_pos_+1].time <= init_time_) {
502  ++dt_limits_pos_;
503  }
504 
506 }
507 
508 
510 {
512  lower_constraint_message_ = "Permanent minimal constraint, custom.";
514  upper_constraint_message_ = "Permanent maximal constraint, custom.";
515  ++dt_limits_pos_;
516 }
517 
518 
519 // int set_constrain - dle nastaveni constraint
520 // interval - constraint - jako v cmp u Qsortu
521 // -1 vetsi nez interval (min_dt,max_dt)
522 // +1 mensi
523 // 0 OK
524 
525 int TimeGovernor::set_upper_constraint (double upper, std::string message)
526 {
527  if (upper_constraint_ < upper) {
528  //do not change upper_constraint_
529  return -1;
530  } else
531  if (lower_constraint_ > upper) {
532  // set upper constraint to the lower constraint
534  upper_constraint_message_ = "Forced lower constraint. " + message;
535  return 1;
536  } else {
537  //change upper_constraint_ to upper
538  upper_constraint_ = upper;
539  upper_constraint_message_ = message;
540  return 0;
541  }
542 }
543 
544 
545 
546 int TimeGovernor::set_lower_constraint (double lower, std::string message)
547 {
548  if (upper_constraint_ < lower) {
549  // set lower constraint to the upper constraint
551  return -1;
552  } else
553  if (lower_constraint_ > lower) {
554  //do not change lower_constraint_
555  return 1;
556  } else {
557  //change lower_constraint_ to lower
558  lower_constraint_ = lower;
559  lower_constraint_message_ = message;
560  return 0;
561  }
562 }
563 
564 
565 
566 
568  if (steady_) return 0.0;
569  end_of_fixed_dt_interval_=-inf_time; // release previous fixed interval
571  is_time_step_fixed_ = true; //flag means fixed step has been set since now
573 }
574 
575 
576 
577 
578 void TimeGovernor::add_time_marks_grid(double step, TimeMark::Type mark_type) const
579 {
580  if (end_time() == inf_time) {
581  THROW(ExcTimeGovernorMessage()
582  << EI_Message("Missing end time for making output grid required by key 'time_step' of the output stream.\n")
583  );
584  }
585 
587  // always add start time and end time
588  marks().add(TimeMark(init_time_, mark_type | eq_mark_type_));
589  marks().add(TimeMark(end_time(), mark_type | eq_mark_type_));
590 }
591 
592 
594 {
595  TimeMark::Type type = equation_mark_type() | mask;
596  return time_marks_.current(step(), type) != time_marks_.end(type);
597 }
598 
599 
600 
602  if (is_end()) return 0.0;
603 
604  if (this->step().lt(end_of_fixed_dt_interval_)) return fixed_time_step_;
605 
606  // jump to the first future fix time
608  // compute step to next fix time and apply constraints
609  double full_step = fix_time_it->time() - t();
610 
611  double step_estimate = min(full_step, upper_constraint_);
612  step_estimate = max(step_estimate, lower_constraint_); //these two must be in this order
613 
614  if (step_estimate == inf_time) return step_estimate;
615 
616  // round the time step to have integer number of steps till next fix time
617  // this always selects shorter time step,
618  // but allows time step larger then constraint by a number close to machine epsilon
619  //
620  double n_steps = ceil( full_step / step_estimate - time_step_precision);
621  step_estimate = full_step / n_steps;
622 
623  // try to avoid time_step changes
624  if (n_steps > 1 && abs(step_estimate - step().length()) < time_step_precision) {
625  step_estimate=step().length();
626  }
627 
628  // if the step estimate gets by rounding lower than lower constraint program will not crash
629  // will just output a user warning.
630  if (step_estimate < lower_constraint_) {
631  DebugOut().fmt("Time step estimate is below the lower constraint of time step. The difference is: {:.16f}.\n",
632  lower_constraint_ - step_estimate);
633  }
634 
635  return step_estimate;
636 }
637 
638 
639 
641 {
642  OLD_ASSERT_LE(0.0, t());
643  if (is_end()) return;
644 
645 
646  if (this->step().lt(end_of_fixed_dt_interval_)) {
647  // this is done for fixed step
648  // make tiny correction of time step in order to avoid big rounding errors
649  // tiny correction means that dt_changed 'is NOT changed'
652  }
653 
654  recent_steps_.push_front(recent_steps_.front().make_next(fixed_time_step_));
655 
656 
657  //checking whether fixed time step has been changed (by fix_dt_until_mark() method) since last time
659  {
660  is_time_step_fixed_ = false;
661 
662  //is true unless new fixed_dt is not equal previous time_step
663  time_step_changed_ = (step(-2).length() != step().length());
664  }
665  else
666  time_step_changed_ = false;
667  }
668  else
669  {
670  // this is done if end_of_fixed_dt_interval is not set (means it is equal to -infinity)
671  double dt=estimate_dt();
672  TimeStep step_ = recent_steps_.front().make_next(dt);
673  //DebugOut().fmt("step: {}, end: {}\n", step_.length(), step_.end());
674  recent_steps_.push_front(step_);
675  //DebugOut().fmt("last: {}, new: {}\n",step(-1).length(),step().length());
676  time_step_changed_= (step(-2).length() != step().length());
677  }
678 
681  // refreshing the upper_constraint_
684  lower_constraint_message_ = "Permanent minimal constraint, in next time.";
685  upper_constraint_message_ = "Permanent maximal constraint, in next time.";
686 
688 
689  // write time step to YAML file
691  double time = t();
692  if (time > last_printed_timestep_) {
693  if (is_end()) timesteps_output_ << "- [ " << time << ", 0, 0 ]\n";
694  else timesteps_output_ << "- [ " << time << ", " << lower_constraint_ << ", " << upper_constraint_ << " ]\n";
695  last_printed_timestep_ = time;
696  }
697  }
698 }
699 
700 
701 double TimeGovernor::reduce_timestep(double factor) {
702  double prior_dt = dt();
703  double new_upper_constraint = factor * dt();
704 
705  // Revert time.
706 // DebugOut().fmt("tg idx: {}\n", recent_steps_.front().index());
707  recent_steps_.pop_front();
708 // DebugOut().fmt("tg idx: {}\n", recent_steps_.back().index());
711 
712  // Set constraint.
713  int current_minus_new = set_upper_constraint(new_upper_constraint, "Reduce time step.");
714  if (current_minus_new < 0)
715  // current constraint < reduced dt, should not happen
716  THROW(ExcMessage() << EI_Message("Internal error."));
717 
718  next_time();
719 
720  // Return false if we hit lower time step constraint.
721  return dt() / prior_dt;
722 }
723 
724 
725 
726 const TimeStep &TimeGovernor::step(int index) const {
727  unsigned int back_idx;
728  if (index < 0) {
729  back_idx = static_cast<unsigned int>(-index-1);
730  } else {
731  back_idx = static_cast<unsigned int>(recent_steps_[0].index() - index);
732  }
733  if ( back_idx >= recent_steps_.size())
734  THROW(ExcMissingTimeStep() << EI_Index(index) << EI_BackIndex(back_idx) << EI_HistorySize(recent_steps_.size()));
735 
736  return recent_steps_[back_idx];
737 }
738 
739 
740 
741 
742 void TimeGovernor::view(const char *name) const
743 {
744  static char buffer[1024];
745 #ifdef FLOW123D_DEBUG_MESSAGES
746  MessageOut().fmt(
747  "TG[{}]:{:06d} t:{:10.4f} dt:{:10.6f} dt_int<{:10.6f},{:10.6f}> "
748  "end_time: {} end_fixed_time: {} type: {:#x}\n",
751 
752  MessageOut().fmt("Lower time step constraint [{}]: {} \nUpper time step constraint [{}]: {} \n",
755 #else
756  MessageOut().fmt(
757  "TG[{}]:{:06d} t:{:10.4f} dt:{:10.6f} dt_int<{:10.6f},{:10.6f}>\n",
758  name, tlevel(), t(), dt(), lower_constraint_, upper_constraint_);
759 
760  //sprintf(buffer, "TG[%s]:%06d t:%10.4f dt:%10.6f dt_int<%10.6f,%10.6f>\n",
761  // name, tlevel(), t(), dt(), lower_constraint_, upper_constraint_ );
762 #endif
763 }
764 
765 
766 
767 double TimeGovernor::read_time(Input::Iterator<Input::Tuple> time_it, double default_time) const {
768  return time_unit_conversion_->read_time(time_it, default_time);
769 }
770 
771 
772 
774  return time_unit_conversion_->read_coef(unit_it);
775 }
776 
777 
778 
779 double TimeGovernor::get_coef() const {
780  return time_unit_conversion_->get_coef();
781 }
782 
783 
784 
786  return time_unit_conversion_->get_unit_string();
787 }
788 
789 
790 
791 
792 ostream& operator<<(ostream& out, const TimeGovernor& tg)
793 {
794  static char buffer[1024];
795  sprintf(buffer, "\n%06d t:%10.4f dt:%10.6f dt_int<%10.6f,%10.6f>\n",
796  tg.tlevel(), tg.t(), tg.dt(), tg.lower_constraint(), tg.upper_constraint());
797  return (out << buffer);
798 }
799 
800 
TimeStep::get_coef
double get_coef() const
Definition: time_governor.cc:250
TimeMark::Type::bitmap_
unsigned long int bitmap_
Definition: time_marks.hh:88
TimeGovernor::add_time_marks_grid
void add_time_marks_grid(double step, TimeMark::Type mark_type=TimeMark::none_type) const
Definition: time_governor.cc:578
TimeStep::safe_compare
bool safe_compare(double t1, double t0) const
Definition: time_governor.cc:230
Input::Type::Bool
Class for declaration of the input of type Bool.
Definition: type_base.hh:452
TimeMarks::next
TimeMarks::iterator next(const TimeGovernor &tg, const TimeMark::Type &mask) const
Definition: time_marks.cc:149
TimeGovernor::~TimeGovernor
~TimeGovernor()
Definition: time_governor.cc:368
TimeMarks::current
TimeMarks::iterator current(const TimeStep &time_step, const TimeMark::Type &mask) const
Definition: time_marks.cc:141
TimeGovernor::dt
double dt() const
Definition: time_governor.hh:542
TimeMarks::new_mark_type
TimeMark::Type new_mark_type()
Definition: time_marks.cc:68
TimeGovernor::last_printed_timestep_
double last_printed_timestep_
Store last printed time to YAML output, try multiplicity output of one time.
Definition: time_governor.hh:729
TimeGovernor::set_permanent_constraint
void set_permanent_constraint()
Sets permanent constraints for actual time step.
Definition: time_governor.cc:509
time_governor.hh
Basic time management class.
TimeGovernor::end_time
double end_time() const
End time.
Definition: time_governor.hh:568
TimeGovernor::dt_limits_pos_
unsigned int dt_limits_pos_
Index to actual position of DT limits.
Definition: time_governor.hh:720
TimeGovernor::upper_constraint_message_
std::string upper_constraint_message_
Description of the upper constraint.
Definition: time_governor.hh:682
TimeUnitConversion::read_time
double read_time(Input::Iterator< Input::Tuple > time_it, double default_time) const
Definition: time_governor.cc:151
TimeGovernor::init_time_
double init_time_
Initial time.
Definition: time_governor.hh:668
ASSERT
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library.
Definition: asserts.hh:346
TimeGovernor::fixed_time_step_
double fixed_time_step_
Next fixed time step.
Definition: time_governor.hh:675
TimeGovernor::TimeGovernor
TimeGovernor(const Input::Record &input, TimeMark::Type fixed_time_mask=TimeMark::none_type, bool timestep_output=true)
Constructor for unsteady solvers.
Definition: time_governor.cc:267
TimeGovernor::equation_fixed_mark_type
TimeMark::Type equation_fixed_mark_type() const
Definition: time_governor.hh:458
Input::Record::val
const Ret val(const string &key) const
Definition: accessors_impl.hh:31
TimeGovernor::set_upper_constraint
int set_upper_constraint(double upper, std::string message)
Sets upper constraint for the next time step estimating.
Definition: time_governor.cc:525
TimeGovernor::end_of_fixed_dt_interval_
double end_of_fixed_dt_interval_
End of interval if fixed time step.
Definition: time_governor.hh:670
TimeGovernor::size_of_recent_steps_
static const unsigned int size_of_recent_steps_
Definition: time_governor.hh:663
FilePath
Dedicated class for storing path to input and output files.
Definition: file_path.hh:54
Input::Type::Double
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:534
TimeGovernor::recent_steps_
boost::circular_buffer< TimeStep > recent_steps_
Circular buffer of recent time steps. Implicit size is 3.
Definition: time_governor.hh:666
TimeGovernor::upper_constraint_
double upper_constraint_
Upper constraint for the choice of the next time step.
Definition: time_governor.hh:686
TimeGovernor::time_marks_
static TimeMarks time_marks_
Definition: time_governor.hh:705
THROW
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
Input::Type::Default::read_time
static Default read_time(const std::string &description)
The factory function to make an default value that will be specified at the time when a key will be r...
Definition: type_record.hh:97
Input::Type::FileName::output
static FileName output()
The factory function for declaring type FileName for input files.
Definition: type_base.cc:532
TimeMarks::end
TimeMarks::iterator end(TimeMark::Type mask) const
Iterator for the end mimics container-like of TimeMarks.
Definition: time_marks.cc:206
fmt::sprintf
std::string sprintf(CStringRef format, ArgList args)
Definition: printf.h:457
system.hh
Input::Type::Tuple
Tuple type proxy class.
Definition: type_tuple.hh:45
UnitSI::convert_unit_from
double convert_unit_from(std::string actual_unit) const
Convert and check user-defined unit.
Definition: unit_si.cc:217
TimeGovernor::min_time_step_
double min_time_step_
Permanent lower limit for the time step.
Definition: time_governor.hh:692
TimeStep::read_time
double read_time(Input::Iterator< Input::Tuple > time_it, double default_time=std::numeric_limits< double >::quiet_NaN()) const
Definition: time_governor.cc:238
TimeGovernor::steady_
bool steady_
True if the time governor is used for steady problem.
Definition: time_governor.hh:711
FilePath::open_stream
void open_stream(Stream &stream) const
Definition: file_path.cc:211
Input::Array::begin
Iterator< ValueType > begin() const
Definition: accessors_impl.hh:145
TimeGovernor::set_lower_constraint
int set_lower_constraint(double lower, std::string message)
Sets lower constraint for the next time step estimating.
Definition: time_governor.cc:546
TimeGovernor::set_dt_limits
void set_dt_limits(double min_dt, double max_dt, Input::Array dt_limits_list)
Sets dt limits for time dependent DT limits in simulation.
Definition: time_governor.cc:435
TimeGovernor::last_lower_constraint_
double last_lower_constraint_
Lower constraint used for choice of current time.
Definition: time_governor.hh:697
TimeGovernor::init_common
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 ...
Definition: time_governor.cc:377
Input::Iterator
Definition: accessors.hh:143
TimeUnitConversion::TimeUnitConversion
TimeUnitConversion()
Definition: time_governor.cc:146
TimeGovernor::is_end
bool is_end() const
Returns true if the actual time is greater than or equal to the end time.
Definition: time_governor.hh:572
TimeGovernor::lower_constraint_message_
std::string lower_constraint_message_
Description of the upper constraint.
Definition: time_governor.hh:684
TimeGovernor::last_upper_constraint_
double last_upper_constraint_
Upper constraint used for choice of current time.
Definition: time_governor.hh:695
Input::Type::Default
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:61
TimeStep::length_
double length_
Definition: time_governor.hh:224
TimeGovernor::timestep_output_
bool timestep_output_
Special flag allows forbid output time steps during multiple initialization of TimeGovernor.
Definition: time_governor.hh:732
TimeMark
Class used for marking specified times at which some events occur.
Definition: time_marks.hh:45
TimeStep::end
double end() const
Definition: time_governor.hh:151
TimeGovernor::limits_time_marks_
bool limits_time_marks_
Allows add all times defined in dt_limits_table_ to list of TimeMarks.
Definition: time_governor.hh:735
Input::Record
Accessor to the data with type Type::Record.
Definition: accessors.hh:291
TimeGovernor::time_step_precision
static const double time_step_precision
Definition: time_governor.hh:627
TimeStep::time_unit_conversion_
std::shared_ptr< TimeUnitConversion > time_unit_conversion_
Conversion unit of all time values within the equation.
Definition: time_governor.hh:228
TimeGovernor::get_unit_string
std::string get_unit_string() const
Definition: time_governor.cc:785
TimeGovernor::tlevel
int tlevel() const
Definition: time_governor.hh:584
TimeGovernor::upper_constraint
double upper_constraint() const
Definition: time_governor.hh:488
TimeGovernor::end_time_
double end_time_
End time of the simulation.
Definition: time_governor.hh:672
TimeGovernor::reduce_timestep
double reduce_timestep(double factor)
Force timestep reduction in particular in the case of failure of the non-linear solver.
Definition: time_governor.cc:701
Input::Type::Tuple::close
const Tuple & close() const
Close the Tuple for further declarations of keys.
Definition: type_tuple.cc:70
Input::Type::Record::allow_auto_conversion
virtual Record & allow_auto_conversion(const string &from_key)
Allows shorter input of the Record providing only value of the from_key given as the parameter.
Definition: type_record.cc:132
accessors.hh
INPUT_CATCH
#define INPUT_CATCH(ExceptionType, AddressEITag, input_accessor)
Definition: accessors.hh:63
TimeStep
Representation of one time step..
Definition: time_governor.hh:113
TimeGovernor
Basic time management functionality for unsteady (and steady) solvers (class Equation).
Definition: time_governor.hh:294
TimeGovernor::step
const TimeStep & step(int index=-1) const
Definition: time_governor.cc:726
MAX_END_TIME
#define MAX_END_TIME
Definition: time_governor.cc:35
Input::Type::Default::obligatory
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:110
TimeMark::Type
Definition: time_marks.hh:60
TimeGovernor::DtLimitRow
Structure that stores one record of DT limit.
Definition: time_governor.hh:632
Input::Record::ei_address
EI_Address ei_address() const
Definition: accessors.cc:178
UnitSI
Class for representation SI units of Fields.
Definition: unit_si.hh:40
Input::Type::Tuple::declare_key
Tuple & declare_key(const string &key, std::shared_ptr< TypeBase > type, const Default &default_value, const string &description, TypeBase::attribute_map key_attributes=TypeBase::attribute_map())
Overrides Record::declare_key(const string &, std::shared_ptr<TypeBase>, const Default &,...
Definition: type_tuple.cc:169
Input::Record::opt_val
bool opt_val(const string &key, Ret &value) const
Definition: accessors_impl.hh:107
TimeMark::every_type
static const Type every_type
Mark Type with all bits set.
Definition: time_marks.hh:93
Input::Type::Record::declare_key
Record & declare_key(const string &key, std::shared_ptr< TypeBase > type, const Default &default_value, const string &description, TypeBase::attribute_map key_attributes=TypeBase::attribute_map())
Declares a new key of the Record.
Definition: type_record.cc:501
Input::Array::size
unsigned int size() const
Definition: accessors_impl.hh:163
TimeStep::end_
double end_
End time point of the time step.
Definition: time_governor.hh:226
Input::Record::find
Iterator< Ret > find(const string &key) const
Definition: accessors_impl.hh:91
TimeUnitConversion::coef_
double coef_
Conversion coefficient of all time values within the equation.
Definition: time_governor.hh:94
TimeGovernor::estimate_dt
double estimate_dt() const
Estimate choice of next time step according to actual setting of constraints.
Definition: time_governor.cc:601
TimeMarks::add
TimeMark add(const TimeMark &mark)
Definition: time_marks.cc:81
TimeGovernor::get_input_type
static const Input::Type::Record & get_input_type()
Definition: time_governor.cc:57
TimeGovernor::view
void view(const char *name="") const
Definition: time_governor.cc:742
Input::Type::Record::close
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:303
Input::Type
Definition: balance.hh:38
TimeGovernor::lower_constraint_
double lower_constraint_
Lower constraint for the choice of the next time step.
Definition: time_governor.hh:688
Input::Type::Record
Record type proxy class.
Definition: type_record.hh:182
TimeMark::none_type
static const Type none_type
Mark Type with all bits unset.
Definition: time_marks.hh:95
TimeStep::make_next
TimeStep make_next(double new_length) const
Definition: time_governor.cc:211
TimeStep::index_
unsigned int index_
Index of the step is index if the end time. Zero time step is artificial.
Definition: time_governor.hh:221
TimeMarks
This class is a collection of time marks to manage various events occurring during simulation time.
Definition: time_marks.hh:206
TimeGovernor::dt_limits_table_
std::vector< DtLimitRow > dt_limits_table_
Table of DT limits.
Definition: time_governor.hh:717
OLD_ASSERT_LE
#define OLD_ASSERT_LE(a, b)
Definition: global_defs.h:135
TimeGovernor::read_time
double read_time(Input::Iterator< Input::Tuple > time_it, double default_time=std::numeric_limits< double >::quiet_NaN()) const
Definition: time_governor.cc:767
Input::Type::Array
Class for declaration of inputs sequences.
Definition: type_base.hh:339
TimeGovernor::marks
static TimeMarks & marks()
Definition: time_governor.hh:315
Input::Type::String
Class for declaration of the input data that are in string format.
Definition: type_base.hh:582
TimeGovernor::timesteps_output_
std::ofstream timesteps_output_
Handle for file for output time steps to YAML format.
Definition: time_governor.hh:726
Input::Array
Accessor to input data conforming to declared Array.
Definition: accessors.hh:566
unit_si.hh
TimeGovernor::get_coef
double get_coef() const
Definition: time_governor.cc:779
WarningOut
#define WarningOut()
Macro defining 'warning' record of log.
Definition: logger.hh:246
Input::Tuple
Accessor to the data with type Type::Tuple.
Definition: accessors.hh:411
UnitSI::s
UnitSI & s(int exp=1)
Definition: unit_si.cc:76
TimeGovernor::time_unit_conversion_
std::shared_ptr< TimeUnitConversion > time_unit_conversion_
Conversion unit of all time values within the equation.
Definition: time_governor.hh:714
Input::Array::address_string
string address_string() const
Definition: accessors.cc:321
TimeGovernor::inf_time
static const double inf_time
Infinity time used for steady case.
Definition: time_governor.hh:621
TimeStep::TimeStep
TimeStep()
Definition: time_governor.cc:191
TimeGovernor::equation_mark_type
TimeMark::Type equation_mark_type() const
Definition: time_governor.hh:452
TimeGovernor::max_time_step_
double max_time_step_
Permanent upper limit for the time step.
Definition: time_governor.hh:690
TimeGovernor::read_coef
double read_coef(Input::Iterator< std::string > unit_it) const
Definition: time_governor.cc:773
TimeGovernor::max_end_time
static const double max_end_time
Definition: time_governor.hh:618
TimeGovernor::timesteps_output_file_
FilePath timesteps_output_file_
File path for timesteps_output_ stream.
Definition: time_governor.hh:723
TimeGovernor::is_current
bool is_current(const TimeMark::Type &mask) const
Definition: time_governor.cc:593
TimeGovernor::get_input_time_type
static const Input::Type::Tuple & get_input_time_type(double lower_bound=-std::numeric_limits< double >::max(), double upper_bound=std::numeric_limits< double >::max())
Definition: time_governor.cc:46
time_marks.hh
TimeMark::time
double time() const
Getter for the time of the TimeMark.
Definition: time_marks.hh:115
TimeMarks::add_time_marks
void add_time_marks(double time, double dt, double end_time, TimeMark::Type type)
Definition: time_marks.cc:106
TimeGovernor::lower_constraint
double lower_constraint() const
Definition: time_governor.hh:494
DebugOut
#define DebugOut()
Macro defining 'debug' record of log.
Definition: logger.hh:252
TimeGovernor::next_time
void next_time()
Proceed to the next time according to current estimated time step.
Definition: time_governor.cc:640
TimeStep::length
double length() const
Definition: time_governor.hh:150
TimeGovernor::time_step_changed_
bool time_step_changed_
Flag is set if the time step has been changed (lasts only one time step).
Definition: time_governor.hh:679
Input::Type::Default::optional
static Default optional()
The factory function to make an empty default value which is optional.
Definition: type_record.hh:124
TimeGovernor::fix_dt_until_mark
double fix_dt_until_mark()
Fixing time step until fixed time mark.
Definition: time_governor.cc:567
TimeGovernor::init_time
double init_time() const
Definition: time_governor.hh:513
Input::Array::end
IteratorBase end() const
Definition: accessors_impl.hh:157
MAX_END_TIME_STR
#define MAX_END_TIME_STR
Definition: time_governor.cc:36
TimeMarksIterator
Iterator over TimeMark objects in TimeMarks object (database of TimeMark objects).
Definition: time_marks.hh:351
TimeGovernor::eq_mark_type_
TimeMark::Type eq_mark_type_
TimeMark type of the equation.
Definition: time_governor.hh:708
TimeStep::read_coef
double read_coef(Input::Iterator< std::string > unit_it) const
Definition: time_governor.cc:244
operator<<
ostream & operator<<(ostream &out, const TimeStep &t_step)
Definition: time_governor.cc:256
TimeGovernor::is_time_step_fixed_
bool is_time_step_fixed_
Flag that is set when the fixed step is set (lasts only one time step).
Definition: time_governor.hh:677
MessageOut
#define MessageOut()
Macro defining 'message' record of log.
Definition: logger.hh:243
TimeUnitConversion::read_coef
double read_coef(Input::Iterator< std::string > unit_it) const
Definition: time_governor.cc:168
TimeGovernor::t
double t() const
Definition: time_governor.hh:519