Flow123d  release_3.0.0-1106-ga3b2e4c
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().bitmap_ << dec );
34 }
35 
36 const TimeMark::Type TimeMark::every_type = TimeMark::Type(~0x0, std::numeric_limits<unsigned char>::min() );
37 const TimeMark::Type TimeMark::none_type = TimeMark::Type(0x0, std::numeric_limits<unsigned char>::max() );
38 
39 
40 // ------------------------------------------------------
41 // implementation of members of class TimeMarks
42 // ------------------------------------------------------
43 
45 {
46  this->reinit();
47 }
48 
49 
50 
52 {
53  marks_.resize(1);
54  marks_[0].clear();
56 
57  // add predefined base mark types
59  type_output_ = TimeMark::Type(0x02, 0);
60  type_input_ = TimeMark::Type(0x04, 0);
62 
63  // insert start and end stoppers
64  marks_[0].push_back(TimeMark(-INFINITY, TimeMark::every_type));
65  marks_[0].push_back(TimeMark(+INFINITY, TimeMark::every_type));
66 }
67 
69  ASSERT(next_mark_type_.equation_index_ != 0).error("Can not allocate new mark type. The limit is 255 mark types.\n");
70  TimeMark::Type current_type = next_mark_type_;
71 
72  // add new subvector to marks_, insert start and end stoppers
73  marks_.push_back( std::vector<TimeMark>() );
76 
78  return current_type;
79 }
80 
82  // find first mark with time greater or equal to the new mark
83  vector<TimeMark>::iterator first_ge = std::lower_bound(marks_[mark.mark_type_.equation_index_].begin(),
84  marks_[mark.mark_type_.equation_index_].end(), mark);
85 
86  // check equivalence with found mark
87  if (fabs(first_ge->time() - mark.time()) < TimeGovernor::time_step_precision) {
88  //if times are "equal" do bitwise OR with the mark type at the first_ge iterator position
89  first_ge->add_to_type(mark.mark_type());
90  return *first_ge;
91  }
92  // possibly check equivalence with previous mark
93  if (first_ge != marks_[mark.mark_type_.equation_index_].begin()) {
94  vector<TimeMark>::iterator previous = first_ge;
95  --previous;
96  if (fabs(previous->time() - mark.time()) < TimeGovernor::time_step_precision) {
97  previous->add_to_type(mark.mark_type());
98  return *previous;
99  }
100  }
101 
102  marks_[mark.mark_type_.equation_index_].insert(first_ge, mark);
103  return mark;
104 }
105 
106 void TimeMarks::add_time_marks(double time, double dt, double end_time, TimeMark::Type type) {
107  OLD_ASSERT(end_time != TimeGovernor::inf_time, "Can not add time marks on infinite interval.\n");
108  OLD_ASSERT(dt > numeric_limits<double>::epsilon(), "TimeMark's step less then machine precision.\n");
109 
110  unsigned int n_steps=((end_time-time)/dt + TimeGovernor::time_step_precision);
111  for (unsigned int i = 0; i<=n_steps;i++) {
112  auto mark = TimeMark(time+i*dt, type);
113  add(mark);
114  }
115 }
116 
117 
119  ASSERT(filter_type.equation_index_ != 0).error();
120  ASSERT( (filter_type.equation_index_ == add_type.equation_index_) || (add_type.equation_index_ == 0) )
121  ((unsigned int)filter_type.equation_index_)((unsigned int)add_type.equation_index_).error();
122 
123  for(auto &mark : marks_[filter_type.equation_index_])
124  if (mark.match_mask(filter_type)) mark.add_to_type(add_type);
125 
126 }
127 
128 /*
129 bool TimeMarks::is_current(const TimeStep &time_step, const TimeMark::Type &mask) const
130 {
131  return ( current(time_step, mask) != this->end(mask) );
132 
133  if (tg.t() == TimeGovernor::inf_time) return tg.is_end();
134  const TimeMark &tm = *last(tg, mask);
135 
136  return tg.step().lt(tm.time() + tg.dt()); // last_t + dt < mark_t + dt
137 
138 }*/
139 
140 
141 TimeMarks::iterator TimeMarks::current(const TimeStep &time_step, const TimeMark::Type &mask) const
142 {
143  //if (time_step.end() == TimeGovernor::inf_time) return tg.is_end();
144  auto it = last(time_step, mask);
145  if ( time_step.contains(it->time()) ) return it;
146  else return this->end(mask);
147 }
148 
150 {
152  ((unsigned int)tg.equation_mark_type().equation_index_)((unsigned int)mask.equation_index_).error();
153 
154  unsigned char eq_index = mask.equation_index_;
155  // first time mark which does not compare less then then actual tg time
157  std::lower_bound(marks_[eq_index].begin(), marks_[eq_index].end(), TimeMark(tg.t(),mask));
158  while ( ! tg.step().lt(first_ge->time()) || ! first_ge->match_mask(mask) ) {
159  ++first_ge;
160  if (first_ge == marks_[eq_index].end()) { --first_ge; break; }
161  }
162  return TimeMarksIterator(marks_[eq_index], first_ge, mask);
163 }
164 
165 TimeMarks::iterator TimeMarks::last(const TimeStep &time_step, const TimeMark::Type &mask) const
166 {
167  unsigned char eq_index = mask.equation_index_;
168  // first time mark which does compare strictly greater then actual tg time
170  std::lower_bound(marks_[eq_index].begin(), marks_[eq_index].end(), TimeMark(time_step.end()+0.01*time_step.length(),mask));
171  while ( ! time_step.ge(first_ge->time()) || ! first_ge->match_mask(mask) ) {
172  --first_ge;
173  }
174  return TimeMarksIterator(marks_[eq_index], first_ge, mask);
175 }
176 
178 {
179  return last(tg.step(), mask);
180 }
181 
182 
184 {
185  auto it = TimeMarksIterator(marks_[mask.equation_index_], --marks_[mask.equation_index_].end(), mask); // +INF time mark
186  --it;
187  return it;
188 }
189 
190 
191 
193 {
194  return TimeMarksIterator(marks_[mask.equation_index_], marks_[mask.equation_index_].begin(), mask);
195 }
196 
197 
198 
199 TimeMarks::iterator TimeMarks::begin(unsigned char ei) const
200 {
201  return this->begin( TimeMark::Type(TimeMark::every_type.bitmap_, ei) );
202 }
203 
204 
205 
207 {
208  return TimeMarksIterator(marks_[mask.equation_index_], --marks_[mask.equation_index_].end(), mask);
209 }
210 
211 
212 
213 TimeMarks::iterator TimeMarks::end(unsigned char ei) const
214 {
215  return this->end( TimeMark::Type(TimeMark::every_type.bitmap_, ei) );
216 }
217 
218 
219 
220 ostream& operator<<(ostream& stream, const TimeMarks &marks)
221 {
222  stream << "==============================" << endl;
223  stream << "time marks:" << endl;
224  for(unsigned int i=0; i<marks.marks_.size(); ++i) {
225  stream << "------------------------------" << endl;
226  stream << "equation_index: " << i << endl;
227  for(vector<TimeMark>::const_iterator it = marks.marks_[i].begin(); it != marks.marks_[i].end(); ++it)
228  stream << *it << endl;
229  }
230  stream << "==============================" << endl;
231  return stream;
232 }
void add_time_marks(double time, double dt, double end_time, TimeMark::Type type)
Definition: time_marks.cc:106
Type mark_type() const
Getter for mark type.
Definition: time_marks.hh:110
TimeMarks::iterator next(const TimeGovernor &tg, const TimeMark::Type &mask) const
Definition: time_marks.cc:149
Iterator over TimeMark objects in TimeMarks object (database of TimeMark objects).
Definition: time_marks.hh:351
bool lt(double other_time) const
IntFormatSpec< int, TypeSpec<'x'> > hex(int value)
Type mark_type_
The type of the TimeMark.
Definition: time_marks.hh:151
bool contains(double other_time) const
TimeMarks::iterator begin(TimeMark::Type mask) const
Iterator for the begin mimics container-like of TimeMarks.
Definition: time_marks.cc:192
ostream & operator<<(ostream &stream, const TimeMark &mark)
Definition: time_marks.cc:30
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
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:95
std::vector< std::vector< TimeMark > > marks_
TimeMarks list sorted according to the their time.
Definition: time_marks.hh:331
Basic time management class.
TimeMarks::iterator last(const TimeStep &time_step, const TimeMark::Type &mask) const
Definition: time_marks.cc:165
static const Type every_type
Mark Type with all bits set.
Definition: time_marks.hh:93
#define OLD_ASSERT(...)
Definition: global_defs.h:131
Global macros to enhance readability and debugging, general constants.
bool ge(double other_time) const
static const double time_step_precision
TimeMark::Type equation_mark_type() const
friend std::ostream & operator<<(std::ostream &stream, const TimeMarks &marks)
Friend output operator.
TimeMark::Type new_mark_type()
Definition: time_marks.cc:68
double length() const
double end() const
This class is a collection of time marks to manage various events occurring during simulation time...
Definition: time_marks.hh:206
TimeMark add(const TimeMark &mark)
Definition: time_marks.cc:81
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
void add_to_type_all(TimeMark::Type filter_type, TimeMark::Type add_type)
Definition: time_marks.cc:118
double time() const
Getter for the time of the TimeMark.
Definition: time_marks.hh:115
TimeMarks::iterator end(TimeMark::Type mask) const
Iterator for the end mimics container-like of TimeMarks.
Definition: time_marks.cc:206
TimeMarks::iterator current(const TimeStep &time_step, const TimeMark::Type &mask) const
Definition: time_marks.cc:141
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
static const double inf_time
Infinity time used for steady case.
Representation of one time step..
TimeMark::Type type_output_
Predefined type for output.
Definition: time_marks.hh:336