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