Flow123d  release_1.8.2-1603-g0109a2b
time_marks.hh
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.hh
15  * @brief
16  * @author Jan Brezina
17  * Created on: Jun 15, 2011
18  */
19 
20 #ifndef TIME_MARKS_HH_
21 #define TIME_MARKS_HH_
22 
23 #include <ostream>
24 #include <vector>
25 
26 #include "system/system.hh"
27 #include "system/global_defs.h"
28 
29 
30 /**
31  * @brief Class used for marking specified times at which some events occur.
32  *
33  * This class represents one record in the TimeMarks simple database.
34  * Class members can not be modified after the item is created.
35  */
36 class TimeMark {
37 public:
38 
39  /**
40  * MarkType is a bitmap where each bit represents one base type such as (Output, Input, BC change, Fixed...)
41  * This allow more complex queries through bitwise operations. Also one TimeMark can be shared by more events.
42  * In the context of TimeMarks the Type can be either fixed or vague. If a TimeGovernor is connected to the TimeMarks object
43  * the TimeMarks with fixed Type are used to match exactly their times. Base Types should be created/obtained from TimeMarks class
44  * through the TimeMarks::new_mark_type method.
45  * There are three Types predefined in TimeMarks constructor:
46  * - type_fixed_time (hex 0x01)
47  * - type_output (hex 0x02)
48  * - type_bc_change (hex 0x04)
49  * @see TimeMarks
50  */
51  typedef unsigned long int Type;
52 
53  /// Mark Type with all bits set.
54  static const Type every_type;
55  /// Mark Type with all bits unset.
56  static const Type none_type;
57 
58  /**
59  * Constructor for a TimeMarks::Mark
60  * @param time time of the mark
61  * @param type type of the mark
62  *
63  * In order to create a fixed TimeMark (at time=0.1) with base TimeMark::Type my_type, use the TimeMarks class:
64  * TimeMark( 0.1, timemarks.type_fixed_time() | my_type)
65  */
66  TimeMark(double time, Type type) :
67  time_(time), mark_type_(type) {}
68 
69 
70  /// Getter for mark type.
71  inline Type mark_type() const {
72  return mark_type_;
73  }
74 
75  /// Getter for the time of the TimeMark.
76  inline double time() const {
77  return time_;
78  }
79 
80  /**
81  * Returns true if TimeMark's type has 1 on all positions where mask has 1.
82  * @param mask {Select bits that should be 1 for matching mark types.
83  */
84 
85  inline bool match_mask(const TimeMark::Type &mask) const {
86  return ( mask & (~mark_type_) ) == 0;
87  }
88 
89  /// Add more bits that a mark satisfies.
90  /// @param type type that should be modified
91  inline void add_to_type(const TimeMark::Type &type) {
92  mark_type_ |= type;
93  }
94 
95  /// Comparison of time marks according to their time.
96  /// @param another is another Timemark which should be compared.
97  bool operator<(const TimeMark& another) const
98  { return time_ < another.time(); }
99 
100 
101 private:
102  /// The marked time.
103  double time_;
104  /// The type of the TimeMark.
106 };
107 
108 /**
109  * Output to stream operator for TimeMark class.
110  */
111 std::ostream& operator<<(std::ostream& stream, const TimeMark &marks);
112 
113 
114 
115 
116 /***************************************************************************************/
117 
118 
119 
120 
121 
122 /***************************************************************************************/
123 class TimeGovernor;
124 class TimeMarksIterator;
125 
126 /**
127  * @brief This class is a collection of time marks to manage various events occurring during simulation time.
128  *
129  * <b> TimeMark and their types </b>
130  *
131  * One TimeMark consists of time and type (TimeMark::Type), see the constructor TimeMark::TimeMark.
132  * The type of mark is bitmap where individual bits corresponds to some base event types like changing a BC, output solution, coupling time with another
133  * equation and so on. Base types can be combined by bitwise or (operator|).
134  *
135  * Special types are predefined in TimeMarks class. These are returned by their getters:
136  * - type_fixed_time() - marks of this type are considered as fixed times by a TimeGovernor which is connected to particular TimeMarks object.
137  * - type_output() - this type marks times at which solution should be computed and written to output.
138  * - type_bc_change() - this type marks times at which BC is is changed and model has to be updated.
139  *
140  * <b> TimeMarks collection </b>
141  *
142  * TimeMarks collect marks of various types and provides methods for iterating over stored marks. You can selectively access only marks matching given
143  * type mask. See TimeMark::match_mask.
144  *
145  * You can add one new mark through method add or add evenly spaced marks of same type by TimeMarks::add_time_marks.
146  *
147  * You can allocate new TimeMark::Type in the context of one TimeMarks object by TimeMarks::new_mark_type.
148  *
149  * For a given TimeGovernor (not necessarily connected one) you can ask about existence of mark in current time interval (TimeMarks::is_current) and see TimeMarks
150  * close to the current time (TimeMarks::next and TimeMarks::last). The current time interval is left-open and right-closed: (t,t+dt]. Repeatedly used TimeMarks::next always returns the same TimeMark if the time of the TimeGovernor is not changed.
151  *
152  * In most cases there will be only one TimeMarks object for the whole solved problem and used by TimeGovernors of individual equations. However
153  * this is not necessary.
154  *
155  * @see TimeMark
156  */
157 class TimeMarks {
158 
159 public:
160  /// Iterator class for iteration over time marks of particular type. This is always const_iterator.
162 
163  /**
164  * Default constructor.
165  */
166  TimeMarks();
167 
168  /**
169  * Reset state after construction (through default constructor).
170  * Useful for unit tests.
171  */
172  void reinit();
173 
174  /**
175  * Add a new base mark within the context of the particular TimeMarks instance.
176  * User should keep the returned value (MarkType is basically a bitmap) for further queries and
177  * TimeMark insertions. ATTENTION: You can not use the TimeMark::Type with other TimeMarks instance!
178  * Types are added as they are prepared in next_mark_type_.
179  * Next mark type is updated by (left) bit shifting operator.
180  */
181  TimeMark::Type new_mark_type();
182 
183  /// Predefined base TimeMark type that is taken into account by the TimeGovernor.
184  /// Is defined by constructor as 0x01.
186  { return type_fixed_time_;}
187 
188  /// Predefined base TimeMark type for output times.
189  /// Is defined by constructor as 0x02.
191  { return type_output_;}
192 
193  /// Predefined base TimeMark type for times when the boundary condition is changed.
194  /// Is defined by constructor as 0x04.
196  { return type_input_;}
197 
198 
199  /**
200  * Basic method for inserting TimeMarks.
201  * @param mark Reference to TimeMark object.
202  */
203  void add(const TimeMark &mark);
204 
205  /**
206  * Method for creating and inserting equally spaced TimeMarks.
207  * @param time Time of the first TimeMark.
208  * @param dt Lenght of interval between equally spaced TimeMarks.
209  * @param end_time No marks after the end_time.
210  * @param type Type of inserted TimeMarks or their combinations.
211  *
212  * Current lazy implementation have complexity O(m*n) where m is number of inserted time marks and n number of time marks in the array.
213  * TODO: O(n+m) implementation
214  */
215  void add_time_marks(double time, double dt, double end_time, TimeMark::Type type);
216 
217  /**
218  * Find the last time mark matching given mask, and returns true if it is in the time interval of
219  * current time step.
220  */
221  bool is_current(const TimeGovernor &tg, const TimeMark::Type &mask) const;
222 
223  /**
224  * Return the first TimeMark with time strictly greater then tg.time() that match the mask.
225  * The time governor tg is used also for time comparisons.
226  *
227  * @param tg the time governor
228  * @param mask mask of marks to iterate on
229  *
230  * TODO: have also method which accepts double (time) instead of the whole TimeGovernor.
231  * and compare without safety.
232  */
233  TimeMarks::iterator next(const TimeGovernor &tg, const TimeMark::Type &mask) const;
234 
235  /**
236  * Return the last TimeMark with time less or equal to tg.time() that match the mask.
237  * The time governor tg is used also for time comparisons.
238  * @param tg the time governor
239  * @param mask mask of marks to iterate on
240  */
241  TimeMarks::iterator last(const TimeGovernor &tg, const TimeMark::Type &mask) const;
242 
243  /**
244  * Returns iterator to the last time mark matching given @p mask.
245  */
246  TimeMarks::iterator last(const TimeMark::Type &mask) const;
247 
248  /// Iterator for the begin mimics container-like of TimeMarks
250 
251  /// Iterator for the end mimics container-like of TimeMarks
253 
254  /// Friend output operator.
255  friend std::ostream& operator<<(std::ostream& stream, const TimeMarks &marks);
256 
257 private:
258 
259  /// MarkType that will be used at next new_time_mark() call.
261 
262  /// TimeMarks list sorted according to the their time.
264 
265  /// Predefined type for fixed time.
267  /// Predefined type for output.
269  /// Predefined type for change of boundary condition.
271 };
272 
273 
274 
275 /**
276  * @brief Iterator over TimeMark objects in TimeMarks object (database of TimeMark objects).
277  *
278  * Iterator over the TimeMarks of particular mask. This is always const iterator, i.e. it points to const TimeMark.
279  * While iterating over TimeMarks with different types, all non matching types are skipped.
280  */
282 public:
283  /**Constructor. It is used in TimeMarks class which has the vector of TimeMark objects.
284  * @param marks is vector of TimeMark objects.
285  * @param it is iterator over the vector of TimeMark objects.
286  * @param mask is the type of marks over which we iterate.
287  */
289  : marks_(marks), it_(it), mask_(mask) {}
290 
292  {OLD_ASSERT(&marks_ == &it.marks_, "Can not assign TimeMarks::iterator of different container.\n");
293  it_=it.it_;
294  mask_=it.mask_;
295  return *this;
296  }
297 
298  /// Prefix increment. Skip non matching marks.
300  {
301  while ( it_ != marks_.end() ) {
302  ++it_;
303  if (it_->match_mask(mask_)) break;
304  }
305  return (*this);
306  }
307 
308  /// Prefix decrement. Skip non matching marks.
310  {
311  while ( it_ != marks_.begin() ) {
312  --it_;
313  if (it_->match_mask(mask_)) break;
314  }
315  return (*this);
316  }
317 
318  /// * dereference operator
319  inline const TimeMark & operator *() const
320  {
321  OLD_ASSERT(it_!= marks_.end(), "Out of marks vector.\n");
322  return *it_;
323  }
324 
325  /// -> dereference operator
326  inline const TimeMark * operator ->() const
327  {
328  OLD_ASSERT(it_!= marks_.end(), "Out of marks vector.\n");
329  return &(*(it_));
330  }
331 
332  inline bool operator ==(const TimeMarksIterator &other) const
333  {return it_ == other.it_; }
334 
335  inline bool operator !=(const TimeMarksIterator &other) const
336  {return it_ != other.it_; }
337 
338  /// Returns mask.
340  { return mask_; }
341 
342 private:
343  /// Reference to the vector of TimeMark objects.
345  /// Iterator over the vector of TimeMark objects.
347  /// Mask type.
349 };
350 
351 #endif /* TIME_MARKS_HH_ */
TimeMark::Type type_fixed_time()
Definition: time_marks.hh:185
Type mark_type() const
Getter for mark type.
Definition: time_marks.hh:71
unsigned long int Type
Definition: time_marks.hh:51
bool operator<(const TimeMark &another) const
Definition: time_marks.hh:97
Iterator over TimeMark objects in TimeMarks object (database of TimeMark objects).
Definition: time_marks.hh:281
TimeMarksIterator & operator=(const TimeMarksIterator &it)
Definition: time_marks.hh:291
Type mark_type_
The type of the TimeMark.
Definition: time_marks.hh:105
TimeMark::Type type_output()
Definition: time_marks.hh:190
TimeMark(double time, Type type)
Definition: time_marks.hh:66
TimeMark::Type type_input_
Predefined type for change of boundary condition.
Definition: time_marks.hh:270
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
static const Type every_type
Mark Type with all bits set.
Definition: time_marks.hh:54
TimeMarksIterator & operator--()
Prefix decrement. Skip non matching marks.
Definition: time_marks.hh:309
TimeMark::Type mask_
Mask type.
Definition: time_marks.hh:348
UnitSI operator*(const UnitSI &a, const UnitSI &b)
Product of two units.
Definition: unit_si.cc:200
double time_
The marked time.
Definition: time_marks.hh:103
bool operator==(const Null &, const Null &)
#define OLD_ASSERT(...)
Definition: global_defs.h:128
Global macros to enhance readability and debugging, general constants.
TimeMarksIterator & operator++()
Prefix increment. Skip non matching marks.
Definition: time_marks.hh:299
std::vector< TimeMark > marks_
TimeMarks list sorted according to the their time.
Definition: time_marks.hh:263
TimeMarksIterator iterator
Iterator class for iteration over time marks of particular type. This is always const_iterator.
Definition: time_marks.hh:161
This class is a collection of time marks to manage various events occurring during simulation time...
Definition: time_marks.hh:157
std::ostream & operator<<(std::ostream &stream, const TimeMark &marks)
Definition: time_marks.cc:30
TimeMark::Type next_mark_type_
MarkType that will be used at next new_time_mark() call.
Definition: time_marks.hh:260
bool match_mask(const TimeMark::Type &mask) const
Definition: time_marks.hh:85
TimeMark::Type mask()
Returns mask.
Definition: time_marks.hh:339
TimeMark::Type type_input()
Definition: time_marks.hh:195
TimeMarksIterator(const std::vector< TimeMark > &marks, const std::vector< TimeMark >::const_iterator &it, const TimeMark::Type &mask)
Definition: time_marks.hh:288
void add_to_type(const TimeMark::Type &type)
Definition: time_marks.hh:91
double time() const
Getter for the time of the TimeMark.
Definition: time_marks.hh:76
std::vector< TimeMark >::const_iterator it_
Iterator over the vector of TimeMark objects.
Definition: time_marks.hh:346
Class used for marking specified times at which some events occur.
Definition: time_marks.hh:36
TimeMark::Type type_fixed_time_
Predefined type for fixed time.
Definition: time_marks.hh:266
const std::vector< TimeMark > & marks_
Reference to the vector of TimeMark objects.
Definition: time_marks.hh:344
TimeMark::Type type_output_
Predefined type for output.
Definition: time_marks.hh:268