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