Flow123d  release_2.2.0-20-gb8056ca
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  struct Type {
52  Type() : bitmap_(0x1), equation_index_(1) {}
53  Type(unsigned long int bitmap, unsigned char equation_index) : bitmap_(bitmap), equation_index_(equation_index) {}
54 
55  /*Type operator&(const Type& other) const {
56  //ASSERT(equation_index_ == other.equation_index_)((unsigned int)equation_index_)((unsigned int)other.equation_index_).error();
57  return Type( (bitmap_ & other.bitmap_), equation_index_);
58  }*/
59 
60  Type operator|(const Type& other) const {
61  // equation_indexes must be same or one of them must be zero
62  if (equation_index_ == 0) {
63  return Type( (bitmap_ | other.bitmap_), other.equation_index_);
64  } else {
65  ASSERT( (equation_index_ == other.equation_index_) || (other.equation_index_ == 0) )
66  ((unsigned int)equation_index_)((unsigned int)other.equation_index_).error();
67  return Type( (bitmap_ | other.bitmap_), equation_index_);
68  }
69  }
70 
71  Type operator~() const {
72  return Type( ~bitmap_, equation_index_);
73  }
74 
75  bool operator==(const Type& other) const {
76  return ( (bitmap_ == other.bitmap_) && ((equation_index_ == other.equation_index_) || (other.equation_index_ == 0)) );
77  }
78 
79  unsigned long int bitmap_;
80  unsigned char equation_index_;
81  };
82 
83  /// Mark Type with all bits set.
84  static const Type every_type;
85  /// Mark Type with all bits unset.
86  static const Type none_type;
87 
88  /**
89  * Constructor for a TimeMarks::Mark
90  * @param time time of the mark
91  * @param type type of the mark
92  *
93  * In order to create a fixed TimeMark (at time=0.1) with base TimeMark::Type my_type, use the TimeMarks class:
94  * TimeMark( 0.1, timemarks.type_fixed_time() | my_type)
95  */
96  TimeMark(double time, Type type) :
97  time_(time), mark_type_(type) {}
98 
99 
100  /// Getter for mark type.
101  inline Type mark_type() const {
102  return mark_type_;
103  }
104 
105  /// Getter for the time of the TimeMark.
106  inline double time() const {
107  return time_;
108  }
109 
110  /**
111  * Returns true if TimeMark's type has 1 on all positions where mask has 1.
112  * @param mask {Select bits that should be 1 for matching mark types.
113  */
114 
115  inline bool match_mask(const TimeMark::Type &mask) const {
116  return (( mask.bitmap_ & (~mark_type_.bitmap_) ) == 0) && (mask.equation_index_ == mark_type_.equation_index_ || mask.equation_index_ == 0);
117  }
118 
119  /// Add more bits that a mark satisfies.
120  /// @param type type that should be modified
121  inline void add_to_type(const TimeMark::Type &type) {
122  ASSERT( (this->mark_type_.equation_index_ == type.equation_index_) || (type.equation_index_ == 0) )
123  ((unsigned int)this->mark_type_.equation_index_)((unsigned int)type.equation_index_).error();
124  mark_type_.bitmap_ |= type.bitmap_;
125  }
126 
127  /// Comparison of time marks according to their time.
128  /// @param another is another Timemark which should be compared.
129  bool operator<(const TimeMark& another) const
130  { return time_ < another.time(); }
131 
132  /// For unordered maps and sets, hashing.
133  bool operator==(const TimeMark & other_mark) const {
134  return (time_ == other_mark.time_) && ( mark_type_ == other_mark.mark_type_);
135  }
136 
137 
138 private:
139  /// The marked time.
140  double time_;
141  /// The type of the TimeMark.
143 
144  friend class TimeMarks;
145 };
146 
147 /**
148  * Output to stream operator for TimeMark class.
149  */
150 std::ostream& operator<<(std::ostream& stream, const TimeMark &marks);
151 
152 
153 
154 
155 /***************************************************************************************/
156 
157 
158 
159 
160 
161 /***************************************************************************************/
162 class TimeStep;
163 class TimeGovernor;
164 class TimeMarksIterator;
165 
166 /**
167  * @brief This class is a collection of time marks to manage various events occurring during simulation time.
168  *
169  * <b> TimeMark and their types </b>
170  *
171  * One TimeMark consists of time and type (TimeMark::Type), see the constructor TimeMark::TimeMark.
172  * 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
173  * equation and so on. Base types can be combined by bitwise or (operator|).
174  *
175  * Special types are predefined in TimeMarks class. These are returned by their getters:
176  * - type_fixed_time() - marks of this type are considered as fixed times by a TimeGovernor which is connected to particular TimeMarks object.
177  * - type_output() - this type marks times at which solution should be computed and written to output.
178  * - type_bc_change() - this type marks times at which BC is is changed and model has to be updated.
179  *
180  * <b> TimeMarks collection </b>
181  *
182  * TimeMarks collect marks of various types and provides methods for iterating over stored marks. You can selectively access only marks matching given
183  * type mask. See TimeMark::match_mask.
184  *
185  * You can add one new mark through method add or add evenly spaced marks of same type by TimeMarks::add_time_marks.
186  *
187  * You can allocate new TimeMark::Type in the context of one TimeMarks object by TimeMarks::new_mark_type.
188  *
189  * 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
190  * 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.
191  *
192  * In most cases there will be only one TimeMarks object for the whole solved problem and used by TimeGovernors of individual equations. However
193  * this is not necessary.
194  *
195  * @see TimeMark
196  */
197 class TimeMarks {
198 
199 public:
200  /// Iterator class for iteration over time marks of particular type. This is always const_iterator.
202 
203  /**
204  * Default constructor.
205  */
206  TimeMarks();
207 
208  /**
209  * Reset state after construction (through default constructor).
210  * Useful for unit tests.
211  */
212  void reinit();
213 
214  /**
215  * Add a new base mark within the context of the particular TimeMarks instance.
216  * User should keep the returned value (MarkType is basically a bitmap) for further queries and
217  * TimeMark insertions. ATTENTION: You can not use the TimeMark::Type with other TimeMarks instance!
218  * Types are added as they are prepared in next_mark_type_.
219  * Next mark type is updated by (left) bit shifting operator.
220  */
221  TimeMark::Type new_mark_type();
222 
223  /// Predefined base TimeMark type that is taken into account by the TimeGovernor.
224  /// Is defined by constructor as 0x01.
226  { return type_fixed_time_;}
227 
228  /// Predefined base TimeMark type for output times.
229  /// Is defined by constructor as 0x02.
231  { return type_output_;}
232 
233  /// Predefined base TimeMark type for times when the boundary condition is changed.
234  /// Is defined by constructor as 0x04.
236  { return type_input_;}
237 
238  /// Predefined base TimeMark type for times of balnace output.
239  /// Is defined by constructor as 0x08.
241  { return type_balance_output_;}
242 
243 
244  /**
245  * Basic method for inserting TimeMarks.
246  * @param mark Reference to TimeMark object.
247  */
248  TimeMark add(const TimeMark &mark);
249 
250  /**
251  * Method for creating and inserting equally spaced TimeMarks.
252  * @param time Time of the first TimeMark.
253  * @param dt Lenght of interval between equally spaced TimeMarks.
254  * @param end_time No marks after the end_time.
255  * @param type Type of inserted TimeMarks or their combinations.
256  *
257  * 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.
258  * TODO: O(n+m) implementation
259  */
260  void add_time_marks(double time, double dt, double end_time, TimeMark::Type type);
261 
262  /**
263  * Apply TimeMark::add_to_type (|=) to all time marks matching the filter type.
264  */
265  void add_to_type_all(TimeMark::Type filter_type, TimeMark::Type add_type);
266 
267  //bool is_current(const TimeStep &time_step, const TimeMark::Type &mask) const;
268 
269  /*
270  * Find the last time mark matching given mask, and returns its iterator if it is in the time interval of
271  * the current time step. Returns end(mask) otherwise.
272  */
273  TimeMarks::iterator current(const TimeStep &time_step, const TimeMark::Type &mask) const;
274 
275  /**
276  * Return the first TimeMark with time strictly greater then tg.time() that match the mask.
277  * The time governor tg is used also for time comparisons.
278  *
279  * @param tg the time governor
280  * @param mask mask of marks to iterate on
281  *
282  * TODO: have also method which accepts double (time) instead of the whole TimeGovernor.
283  * and compare without safety.
284  */
285  TimeMarks::iterator next(const TimeGovernor &tg, const TimeMark::Type &mask) const;
286 
287  /**
288  * Return the last TimeMark with time less or equal to tg.time() that match the mask.
289  * The time governor tg is used also for time comparisons.
290  * @param tg the time governor
291  * @param mask mask of marks to iterate on
292  */
293  TimeMarks::iterator last(const TimeStep &time_step, const TimeMark::Type &mask) const;
294  TimeMarks::iterator last(const TimeGovernor &tg, const TimeMark::Type &mask) const;
295 
296  /**
297  * Returns iterator to the last time mark matching given @p mask.
298  */
299  TimeMarks::iterator last(const TimeMark::Type &mask) const;
300 
301  /// Iterator for the begin mimics container-like of TimeMarks
302  TimeMarks::iterator begin(TimeMark::Type mask) const;
303 
304  /// Same as previous, but constructs TimeMark::Type from equation index
305  TimeMarks::iterator begin(unsigned char ei) const;
306 
307  /// Iterator for the end mimics container-like of TimeMarks
308  TimeMarks::iterator end(TimeMark::Type mask) const;
309 
310  /// Same as previous, but constructs TimeMark::Type from equation index
311  TimeMarks::iterator end(unsigned char ei) const;
312 
313  /// Friend output operator.
314  friend std::ostream& operator<<(std::ostream& stream, const TimeMarks &marks);
315 
316 private:
317 
318  /// MarkType that will be used at next new_time_mark() call.
320 
321  /// TimeMarks list sorted according to the their time.
323 
324  /// Predefined type for fixed time.
326  /// Predefined type for output.
328  /// Predefined type for change of boundary condition.
330  /// Predefined type for balance output
332 };
333 
334 
335 
336 /**
337  * @brief Iterator over TimeMark objects in TimeMarks object (database of TimeMark objects).
338  *
339  * Iterator over the TimeMarks of particular mask. This is always const iterator, i.e. it points to const TimeMark.
340  * While iterating over TimeMarks with different types, all non matching types are skipped.
341  */
343 public:
344  /**Constructor. It is used in TimeMarks class which has the vector of TimeMark objects.
345  * @param marks is vector of TimeMark objects.
346  * @param it is iterator over the vector of TimeMark objects.
347  * @param mask is the type of marks over which we iterate.
348  */
350  : marks_(marks), it_(it), mask_(mask) {}
351 
353  {OLD_ASSERT(&marks_ == &it.marks_, "Can not assign TimeMarks::iterator of different container.\n");
354  it_=it.it_;
355  mask_=it.mask_;
356  return *this;
357  }
358 
359  /// Prefix increment. Skip non matching marks.
361  {
362  while ( it_ != marks_.end() ) {
363  ++it_;
364  if (it_->match_mask(mask_)) break;
365  }
366  return (*this);
367  }
368 
369  /// Prefix decrement. Skip non matching marks.
371  {
372  while ( it_ != marks_.begin() ) {
373  --it_;
374  if (it_->match_mask(mask_)) break;
375  }
376  return (*this);
377  }
378 
379  /// * dereference operator
380  inline const TimeMark & operator *() const
381  {
382  OLD_ASSERT(it_!= marks_.end(), "Out of marks vector.\n");
383  return *it_;
384  }
385 
386  /// -> dereference operator
387  inline const TimeMark * operator ->() const
388  {
389  OLD_ASSERT(it_!= marks_.end(), "Out of marks vector.\n");
390  return &(*(it_));
391  }
392 
393  inline bool operator ==(const TimeMarksIterator &other) const
394  {return it_ == other.it_; }
395 
396  inline bool operator !=(const TimeMarksIterator &other) const
397  {return it_ != other.it_; }
398 
399  /// Returns mask.
401  { return mask_; }
402 
403 private:
404  /// Reference to the vector of TimeMark objects.
406  /// Iterator over the vector of TimeMark objects.
408  /// Mask type.
410 };
411 
412 
413 #endif /* TIME_MARKS_HH_ */
TimeMark::Type type_fixed_time()
Definition: time_marks.hh:225
Type mark_type() const
Getter for mark type.
Definition: time_marks.hh:101
bool operator<(const TimeMark &another) const
Definition: time_marks.hh:129
Iterator over TimeMark objects in TimeMarks object (database of TimeMark objects).
Definition: time_marks.hh:342
TimeMarksIterator & operator=(const TimeMarksIterator &it)
Definition: time_marks.hh:352
Type mark_type_
The type of the TimeMark.
Definition: time_marks.hh:142
TimeMark::Type type_output()
Definition: time_marks.hh:230
TimeMark(double time, Type type)
Definition: time_marks.hh:96
TimeMark::Type type_balance_output_
Predefined type for balance output.
Definition: time_marks.hh:331
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:346
TimeMark::Type type_input_
Predefined type for change of boundary condition.
Definition: time_marks.hh:329
friend class TimeMarks
Definition: time_marks.hh:144
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:86
std::vector< std::vector< TimeMark > > marks_
TimeMarks list sorted according to the their time.
Definition: time_marks.hh:322
static const Type every_type
Mark Type with all bits set.
Definition: time_marks.hh:84
TimeMarksIterator & operator--()
Prefix decrement. Skip non matching marks.
Definition: time_marks.hh:370
TimeMark::Type mask_
Mask type.
Definition: time_marks.hh:409
TimeMark::Type type_balance_output()
Definition: time_marks.hh:240
UnitSI operator*(const UnitSI &a, const UnitSI &b)
Product of two units.
Definition: unit_si.cc:235
double time_
The marked time.
Definition: time_marks.hh:140
#define OLD_ASSERT(...)
Definition: global_defs.h:131
Type operator~() const
Definition: time_marks.hh:71
Global macros to enhance readability and debugging, general constants.
TimeMarksIterator & operator++()
Prefix increment. Skip non matching marks.
Definition: time_marks.hh:360
Type(unsigned long int bitmap, unsigned char equation_index)
Definition: time_marks.hh:53
TimeMarksIterator iterator
Iterator class for iteration over time marks of particular type. This is always const_iterator.
Definition: time_marks.hh:201
This class is a collection of time marks to manage various events occurring during simulation time...
Definition: time_marks.hh:197
std::ostream & operator<<(std::ostream &stream, const TimeMark &marks)
Definition: time_marks.cc:30
bool operator==(const Type &other) const
Definition: time_marks.hh:75
TimeMark::Type next_mark_type_
MarkType that will be used at next new_time_mark() call.
Definition: time_marks.hh:319
unsigned char equation_index_
Definition: time_marks.hh:80
bool match_mask(const TimeMark::Type &mask) const
Definition: time_marks.hh:115
TimeMark::Type mask()
Returns mask.
Definition: time_marks.hh:400
TimeMark::Type type_input()
Definition: time_marks.hh:235
TimeMarksIterator(const std::vector< TimeMark > &marks, const std::vector< TimeMark >::const_iterator &it, const TimeMark::Type &mask)
Definition: time_marks.hh:349
void add_to_type(const TimeMark::Type &type)
Definition: time_marks.hh:121
double time() const
Getter for the time of the TimeMark.
Definition: time_marks.hh:106
std::vector< TimeMark >::const_iterator it_
Iterator over the vector of TimeMark objects.
Definition: time_marks.hh:407
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:325
unsigned long int bitmap_
Definition: time_marks.hh:79
const std::vector< TimeMark > & marks_
Reference to the vector of TimeMark objects.
Definition: time_marks.hh:405
Representation of one time step..
TimeMark::Type type_output_
Predefined type for output.
Definition: time_marks.hh:327
bool operator==(const TimeMark &other_mark) const
For unordered maps and sets, hashing.
Definition: time_marks.hh:133
Type operator|(const Type &other) const
Definition: time_marks.hh:60