Flow123d
time_marks.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2007 Technical University of Liberec. All rights reserved.
4  *
5  * Please make a following refer to Flow123d on your project site if you use the program for any purpose,
6  * especially for academic research:
7  * Flow123d, Research Centre: Advanced Remedial Technologies, Technical University of Liberec, Czech Republic
8  *
9  * This program is free software; you can redistribute it and/or modify it under the terms
10  * of the GNU General Public License version 3 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along with this program; if not,
17  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 021110-1307, USA.
18  *
19  *
20  * $Id: time_marks.hh 1974 2012-11-14 13:46:11Z pavel.exner $
21  * $Revision: 1974 $
22  * $LastChangedBy: pavel.exner $
23  * $LastChangedDate: 2012-11-14 14:46:11 +0100 (St, 14 lis 2012) $
24  *
25  * @file
26  * @brief
27  *
28  * @author Jan Brezina
29  * Created on: Jun 15, 2011
30  *
31  */
32 
33 #ifndef TIME_MARKS_HH_
34 #define TIME_MARKS_HH_
35 
36 #include "system/global_defs.h"
37 
38 /**
39  * @brief Class used for marking specified times at which some events occur.
40  *
41  * This class represents one record in the TimeMarks simple database.
42  * Class members can not be modified after the item is created.
43  */
44 class TimeMark {
45 public:
46 
47  /**
48  * MarkType is a bitmap where each bit represents one base type such as (Output, Input, BC change, Fixed...)
49  * This allow more complex queries through bitwise operations. Also one TimeMark can be shared by more events.
50  * In the context of TimeMarks the Type can be either fixed or vague. If a TimeGovernor is connected to the TimeMarks object
51  * the TimeMarks with fixed Type are used to match exactly their times. Base Types should be created/obtained from TimeMarks class
52  * through the TimeMarks::new_mark_type method.
53  * There are three Types predefined in TimeMarks constructor:
54  * - type_fixed_time (hex 0x01)
55  * - type_output (hex 0x02)
56  * - type_bc_change (hex 0x04)
57  * @see TimeMarks
58  */
59  typedef unsigned long int Type;
60 
61  /// Mask that matches every type of TimeMark.
62  static const Type every_type;
63  /// Mask that matches no type of TimeMark.
64  static const Type none_type;
65 
66  //This mask is replaced by type_fixed_time_ defined in constructor of TimeMarks //OBSOLETE
67  //static const Type strict;
68 
69  /**
70  * Constructor for a TimeMarks::Mark
71  * @param time time of the mark
72  * @param type type of the mark
73  *
74  * In order to create a fixed TimeMark (at time=0.1) with base TimeMark::Type my_type, use the TimeMarks class:
75  * TimeMark( 0.1, timemarks.type_fixed_time() | my_type)
76  */
77  TimeMark(double time, Type type) :
78  time_(time), mark_type_(type) {}
79 
80 
81  /// Getter for mark type.
82  inline Type mark_type() const {
83  return mark_type_;
84  }
85 
86  /// Getter for the time of the TimeMark.
87  inline double time() const {
88  return time_;
89  }
90 
91  /**
92  * Returns true if TimeMark's type has 1 on all positions where mask has 1.
93  * @param mask {Select bits that should be 1 for matching mark types.
94  */
95 
96  inline bool match_mask(const TimeMark::Type &mask) const {
97  return ( mask & (~mark_type_) ) == 0;
98  }
99 
100  /// Add more bits that a mark satisfies.
101  /// @param type type that should be modified
102  inline void add_to_type(const TimeMark::Type &type) {
103  mark_type_ |= type;
104  }
105 
106  /// Comparison of time marks according to their time.
107  /// @param another is another Timemark which should be compared.
108  bool operator<(const TimeMark& another) const
109  { return time_ < another.time(); }
110 
111 
112 private:
113  /// The marked time.
114  double time_;
115  /// The type of the TimeMark.
117 };
118 
119 /**
120  * Output to stream operator for TimeMark class.
121  */
122 ostream& operator<<(ostream& stream, const TimeMark &marks);
123 
124 
125 
126 
127 /***************************************************************************************/
128 
129 
130 
131 
132 
133 /***************************************************************************************/
134 class TimeGovernor;
135 class TimeMarksIterator;
136 
137 /**
138  * @brief This class is a collection of time marks to manage various events occurring during simulation time.
139  *
140  * <b> TimeMark and their types </b>
141  *
142  * One TimeMark consists of time and type (TimeMark::Type), see the constructor TimeMark::TimeMark.
143  * 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
144  * equation and so on. Base types can be combined by bitwise or (operator|).
145  *
146  * Special types are predefined in TimeMarks class. These are returned by their getters:
147  * - type_fixed_time() - marks of this type are considered as fixed times by a TimeGovernor which is connected to particular TimeMarks object.
148  * - type_output() - this type marks times at which solution should be computed and written to output.
149  * - type_bc_change() - this type marks times at which BC is is changed and model has to be updated.
150  *
151  * <b> TimeMarks collection </b>
152  *
153  * TimeMarks collect marks of various types and provides methods for iterating over stored marks. You can selectively access only marks matching given
154  * type mask. See TimeMark::match_mask.
155  *
156  * You can add one new mark through method add or add evenly spaced marks of same type by TimeMarks::add_time_marks.
157  *
158  * You can allocate new TimeMark::Type in the context of one TimeMarks object by TimeMarks::new_mark_type.
159  *
160  * 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
161  * 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.
162  *
163  * In most cases there will be only one TimeMarks object for the whole solved problem and used by TimeGovernors of individual equations. However
164  * this is not necessary.
165  *
166  * @see TimeMark
167  */
168 class TimeMarks {
169 
170 public:
171  /// Iterator class for iteration over time marks of particular type. This is always const_iterator.
173 
174  /**
175  * Default constructor.
176  */
177  TimeMarks();
178 
179  /**
180  * Add a new base mark within the context of the particular TimeMarks instance.
181  * User should keep the returned value (MarkType is basically a bitmap) for further queries and
182  * TimeMark insertions. ATTENTION: You can not use the TimeMark::Type with other TimeMarks instance!
183  * Types are added as they are prepared in next_mark_type_.
184  * Next mark type is updated by (left) bit shifting operator.
185  */
187 
188  /// Predefined base TimeMark type that is taken into account by the TimeGovernor.
189  /// Is defined by constructor as 0x01.
191  { return type_fixed_time_;}
192 
193  /// Predefined base TimeMark type for output times.
194  /// Is defined by constructor as 0x02.
196  { return type_output_;}
197 
198  /// Predefined base TimeMark type for times when the boundary condition is changed.
199  /// Is defined by constructor as 0x04.
201  { return type_input_;}
202 
203 
204  /**
205  * Basic method for inserting TimeMarks.
206  * @param mark Reference to TimeMark object.
207  */
208  void add(const TimeMark &mark);
209 
210  /**
211  * Method for creating and inserting equally spaced TimeMarks.
212  * @param time Time of the first TimeMark.
213  * @param dt Lenght of interval between equally spaced TimeMarks.
214  * @param end_time No marks after the end_time.
215  * @param type Type of inserted TimeMarks or their combinations.
216  *
217  * 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.
218  * TODO: O(n+m) implementation
219  */
220  void add_time_marks(double time, double dt, double end_time, TimeMark::Type type);
221 
222  /**
223  * Find the last time mark matching given mask, and returns true if it is in the time interval of
224  * current time step.
225  */
226  bool is_current(const TimeGovernor &tg, const TimeMark::Type &mask) const;
227 
228  /**
229  * Return the first TimeMark with time strictly greater then tg.time() that match the mask.
230  * The time governor tg is used also for time comparisons.
231  *
232  * @param tg the time governor
233  * @param mask mask of marks to iterate on
234  *
235  * TODO: have also method which accepts double (time) instead of the whole TimeGovernor.
236  * and compare without safety.
237  */
238  TimeMarks::iterator next(const TimeGovernor &tg, const TimeMark::Type &mask) const;
239 
240  /**
241  * Return the last TimeMark with time less or equal to tg.time() that match the mask.
242  * The time governor tg is used also for time comparisons.
243  * @param tg the time governor
244  * @param mask mask of marks to iterate on
245  */
246  TimeMarks::iterator last(const TimeGovernor &tg, const TimeMark::Type &mask) const;
247 
248  /**
249  * Returns iterator to the last time mark matching given @p mask.
250  */
251  TimeMarks::iterator last(const TimeMark::Type &mask) const;
252 
253  /// Iterator for the begin mimics container-like of TimeMarks
255 
256  /// Iterator for the end mimics container-like of TimeMarks
258 
259  /// Friend output operator.
260  friend ostream& operator<<(ostream& stream, const TimeMarks &marks);
261 
262 private:
263 
264  /// MarkType that will be used at next new_time_mark() call.
266 
267  /// TimeMarks list sorted according to the their time.
268  vector<TimeMark> marks_;
269 
270  /// Predefined type for fixed time.
272  /// Predefined type for output.
274  /// Predefined type for change of boundary condition.
276 };
277 
278 
279 
280 /**
281  * @brief Iterator over TimeMark objects in TimeMarks object (database of TimeMark objects).
282  *
283  * Iterator over the TimeMarks of particular mask. This is always const iterator, i.e. it points to const TimeMark.
284  * While iterating over TimeMarks with different types, all non matching types are skipped.
285  */
287 public:
288  /**Constructor. It is used in TimeMarks class which has the vector of TimeMark objects.
289  * @param marks is vector of TimeMark objects.
290  * @param it is iterator over the vector of TimeMark objects.
291  * @param mask is the type of marks over which we iterate.
292  */
293  TimeMarksIterator(const vector<TimeMark> &marks,const vector<TimeMark>::const_iterator &it, const TimeMark::Type &mask)
294  : marks_(marks), it_(it), mask_(mask) {}
295 
297  {ASSERT(&marks_ == &it.marks_, "Can not assign TimeMarks::iterator of different container.\n");
298  it_=it.it_;
299  mask_=it.mask_;
300  return *this;
301  }
302 
303  /// Prefix increment. Skip non matching marks.
305  {
306  while ( it_ != marks_.end() ) {
307  ++it_;
308  if (it_->match_mask(mask_)) break;
309  }
310  return (*this);
311  }
312 
313  /// Prefix decrement. Skip non matching marks.
315  {
316  while ( it_ != marks_.begin() ) {
317  --it_;
318  if (it_->match_mask(mask_)) break;
319  }
320  return (*this);
321  }
322 
323  /// * dereference operator
324  inline const TimeMark & operator *() const
325  {
326  ASSERT(it_!= marks_.end(), "Out of marks vector.\n");
327  return *it_;
328  }
329 
330  /// -> dereference operator
331  inline const TimeMark * operator ->() const
332  {
333  ASSERT(it_!= marks_.end(), "Out of marks vector.\n");
334  return &(*(it_));
335  }
336 
337  inline bool operator ==(const TimeMarksIterator &other) const
338  {return it_ == other.it_; }
339 
340  inline bool operator !=(const TimeMarksIterator &other) const
341  {return it_ != other.it_; }
342 
343  /// Returns mask.
345  { return mask_; }
346 
347 private:
348  /// Reference to the vector of TimeMark objects.
349  const vector<TimeMark> &marks_;
350  /// Iterator over the vector of TimeMark objects.
351  vector<TimeMark>::const_iterator it_;
352  /// Mask type.
354 };
355 
356 #endif /* TIME_MARKS_HH_ */