Flow123d  release_1.8.2-1603-g0109a2b
time_marks.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_marks.cc
15  * @brief
16  * @author Jan Brezina
17  */
18 
19 #include <algorithm>
20 #include <limits>
21 #include "system/system.hh"
22 #include "system/global_defs.h"
23 #include "time_governor.hh"
24 #include "time_marks.hh"
25 
26 // ------------------------------------------------------
27 // implementation of members of class TimeMark
28 // ------------------------------------------------------
29 
30 ostream& operator<<(ostream& stream, const TimeMark &mark)
31 {
32  //return ( stream << mark.time()<<": 0o" << oct << mark.mark_type() << dec ); //octal output
33  return ( stream << mark.time()<<": 0x" << hex << mark.mark_type() << dec );
34 }
35 
38 
39 
40 // ------------------------------------------------------
41 // implementation of members of class TimeMarks
42 // ------------------------------------------------------
43 
45 {
46  this->reinit();
47 }
48 
49 
50 
52 {
53  marks_.clear();
54  next_mark_type_ = 0x1;
55 
56  // add predefined base mark types
60 
61  // insert start and end stoppers
62  marks_.push_back(TimeMark(-INFINITY, TimeMark::every_type));
63  marks_.push_back(TimeMark(+INFINITY, TimeMark::every_type));
64 }
65 
67  OLD_ASSERT(next_mark_type_ != 0, "Can not allocate new mark type. The limit is 32 mark types.\n");
68  TimeMark::Type current_type = next_mark_type_;
69 
70  next_mark_type_ <<= 1;
71  return current_type;
72 }
73 
74 void TimeMarks::add(const TimeMark &mark) {
75  // find first mark with time greater or equal to the new mark
76  vector<TimeMark>::iterator first_ge = std::lower_bound(marks_.begin(), marks_.end(), mark);
77 
78  // check equivalence with found mark
79  if (fabs(first_ge->time() - mark.time()) < TimeGovernor::time_step_precision) {
80  //if "equal" does bitwise OR with the mark type at the first_ge iterator position
81  first_ge->add_to_type(mark.mark_type());
82  return;
83  }
84  // possibly check equivalence with previous mark
85  if (first_ge != marks_.begin()) {
86  vector<TimeMark>::iterator previous = first_ge;
87  --previous;
88  if (fabs(previous->time() - mark.time()) < TimeGovernor::time_step_precision) {
89  previous->add_to_type(mark.mark_type());
90  return;
91  }
92  }
93 
94  marks_.insert(first_ge, mark);
95 }
96 
97 void TimeMarks::add_time_marks(double time, double dt, double end_time, TimeMark::Type type) {
98  OLD_ASSERT(end_time != TimeGovernor::inf_time, "Can not add time marks on infinite interval.\n");
99  OLD_ASSERT(dt > numeric_limits<double>::epsilon(), "TimeMark's step less then machine precision.\n");
100 
101  unsigned int n_steps=((end_time-time)/dt + TimeGovernor::time_step_precision);
102  for (unsigned int i = 0; i<=n_steps;i++) {
103  auto mark = TimeMark(time+i*dt, type);
104  add(mark);
105  }
106 }
107 
108 bool TimeMarks::is_current(const TimeGovernor &tg, const TimeMark::Type &mask) const
109 {
110  if (tg.t() == TimeGovernor::inf_time) return tg.is_end();
111  const TimeMark &tm = *last(tg, mask);
112 
113  return tg.step().lt(tm.time() + tg.dt()); // last_t + dt < mark_t + dt
114 }
115 
117 {
118  // first time mark which does not compare less then then actual tg time
120  std::lower_bound(marks_.begin(), marks_.end(), TimeMark(tg.t(),mask));
121  while ( ! tg.step().lt(first_ge->time()) || ! first_ge->match_mask(mask) ) {
122  ++first_ge;
123  }
124  return TimeMarksIterator(marks_, first_ge, mask);
125 }
126 
128 {
129  // first time mark which does compare strictly greater then actual tg time
131  std::lower_bound(marks_.begin(), marks_.end(), TimeMark(tg.t()+0.01*tg.dt(),mask));
132  while ( ! tg.step().ge(first_ge->time()) || ! first_ge->match_mask(mask) ) {
133  --first_ge;
134  }
135  return TimeMarksIterator(marks_, first_ge, mask);
136 }
137 
138 
139 
141 {
142  auto it = TimeMarksIterator(marks_, --marks_.end(), mask); // +INF time mark
143  --it;
144  return it;
145 }
146 
147 
148 
150 {
151  return TimeMarksIterator(marks_, marks_.begin(), mask);
152 }
153 
154 
155 
157 {
158  return TimeMarksIterator(marks_, --marks_.end(), mask);
159 }
160 
161 
162 
163 ostream& operator<<(ostream& stream, const TimeMarks &marks)
164 {
165  stream << "time marks:" << endl;
166  for(vector<TimeMark>::const_iterator it = marks.marks_.begin(); it != marks.marks_.end(); ++it)
167  stream << *it << endl;
168  return stream;
169 }
void add_time_marks(double time, double dt, double end_time, TimeMark::Type type)
Definition: time_marks.cc:97
Type mark_type() const
Getter for mark type.
Definition: time_marks.hh:71
unsigned long int Type
Definition: time_marks.hh:51
TimeMarks::iterator next(const TimeGovernor &tg, const TimeMark::Type &mask) const
Definition: time_marks.cc:116
Iterator over TimeMark objects in TimeMarks object (database of TimeMark objects).
Definition: time_marks.hh:281
TimeMarks::iterator begin(TimeMark::Type mask=TimeMark::every_type) const
Iterator for the begin mimics container-like of TimeMarks.
Definition: time_marks.cc:149
bool lt(double other_time) const
bool is_end() const
Returns true if the actual time is greater than or equal to the end time.
ostream & operator<<(ostream &stream, const TimeMark &mark)
Definition: time_marks.cc:30
TimeMark::Type type_input_
Predefined type for change of boundary condition.
Definition: time_marks.hh:270
void reinit()
Definition: time_marks.cc:51
const TimeStep & step(int index=-1) const
double t() const
Basic time management functionality for unsteady (and steady) solvers (class Equation).
static const Type none_type
Mark Type with all bits unset.
Definition: time_marks.hh:56
Basic time management class.
static const Type every_type
Mark Type with all bits set.
Definition: time_marks.hh:54
#define OLD_ASSERT(...)
Definition: global_defs.h:128
void add(const TimeMark &mark)
Definition: time_marks.cc:74
Global macros to enhance readability and debugging, general constants.
bool is_current(const TimeGovernor &tg, const TimeMark::Type &mask) const
Definition: time_marks.cc:108
std::vector< TimeMark > marks_
TimeMarks list sorted according to the their time.
Definition: time_marks.hh:263
bool ge(double other_time) const
static const double time_step_precision
friend std::ostream & operator<<(std::ostream &stream, const TimeMarks &marks)
Friend output operator.
TimeMark::Type new_mark_type()
Definition: time_marks.cc:66
This class is a collection of time marks to manage various events occurring during simulation time...
Definition: time_marks.hh:157
TimeMark::Type next_mark_type_
MarkType that will be used at next new_time_mark() call.
Definition: time_marks.hh:260
const double epsilon
Definition: mathfce.h:23
double dt() const
double time() const
Getter for the time of the TimeMark.
Definition: time_marks.hh:76
Class used for marking specified times at which some events occur.
Definition: time_marks.hh:36
TimeMarks::iterator end(TimeMark::Type mask=TimeMark::every_type) const
Iterator for the end mimics container-like of TimeMarks.
Definition: time_marks.cc:156
TimeMark::Type type_fixed_time_
Predefined type for fixed time.
Definition: time_marks.hh:266
static const double inf_time
Infinity time used for steady case.
TimeMark::Type type_output_
Predefined type for output.
Definition: time_marks.hh:268
TimeMarks::iterator last(const TimeGovernor &tg, const TimeMark::Type &mask) const
Definition: time_marks.cc:127