Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Tempus_TimeEventRangeIndex_impl.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ****************************************************************************
3 // Tempus: Copyright (2017) Sandia Corporation
4 //
5 // Distributed under BSD 3-clause license (See accompanying file Copyright.txt)
6 // ****************************************************************************
7 // @HEADER
8 
9 #ifndef Tempus_TimeEventRangeIndex_impl_hpp
10 #define Tempus_TimeEventRangeIndex_impl_hpp
11 
12 namespace Tempus {
13 
14 template <class Scalar>
16  : start_(0), stop_(0), stride_(1), numEvents_(1)
17 {
18  this->setType("Range Index");
19  std::ostringstream oss;
20  oss << "TimeEventRangeIndex (" << start_ << "; " << stop_ << "; " << stride_
21  << ")";
22  this->setName(oss.str());
23  setNumEvents();
24 }
25 
26 template <class Scalar>
28  int stride, std::string name)
29  : start_(0), stop_(0), stride_(1), numEvents_(1)
30 {
31  this->setType("Range Index");
32  if (name == "") {
33  std::ostringstream oss;
34  oss << "TimeEventRangeIndex (" << start << "; " << stop << "; " << stride
35  << ")";
36  this->setName(oss.str());
37  }
38  else {
39  this->setName(name);
40  }
41 
42  this->setIndexRange(start, stop, stride);
43 }
44 
45 template <class Scalar>
47 {
48  start_ = start;
49  if (stop_ < start_) {
50  stop_ = start_;
51  }
52  setNumEvents();
53 }
54 
55 template <class Scalar>
57 {
58  stop_ = stop;
59  if (start_ > stop_) {
60  start_ = stop_;
61  setIndexStride(1);
62  }
63  setNumEvents();
64 }
65 
66 template <class Scalar>
68 {
69  stride_ = stride;
70  if (stride_ < 1) {
71  stride_ = 1;
72  }
73  else if (stride_ > (stop_ - start_)) {
74  stride_ = stop_ - start_;
75  }
76  setNumEvents();
77 }
78 
79 template <class Scalar>
81 {
82  if (stride_ == 0 || start_ == stop_)
83  numEvents_ = 1;
84  else
85  numEvents_ = int((stop_ - start_) / stride_) + 1;
86 }
87 
88 template <class Scalar>
90 {
91  const int indexOfLast = start_ + (numEvents_ - 1) * stride_;
92  if (index < start_ || index > indexOfLast) return false;
93  if ((index - start_) % stride_ == 0) return true;
94 
95  return false;
96 }
97 
98 template <class Scalar>
100 {
101  return indexOfNextEvent(index) - index;
102 }
103 
104 template <class Scalar>
106 {
107  // Check if before the first index.
108  if (index < start_) return start_;
109 
110  const int indexOfLast = start_ + (numEvents_ - 1) * stride_;
111  // Check if after or equal to last index.
112  if (index >= indexOfLast) return this->getDefaultIndex();
113 
114  // Check if index is an event. If so, return next event.
115  if (isIndex(index)) return index + stride_;
116 
117  const int numStrides = (index - start_) / stride_ + 1;
118  const Scalar indexOfNext = start_ + numStrides * stride_;
119  return indexOfNext;
120 }
121 
122 template <class Scalar>
124  int index2) const
125 {
126  if (index1 > index2) {
127  int tmp = index1;
128  index1 = index2;
129  index2 = tmp;
130  }
131 
132  // Check if range is completely outside index events.
133  const Scalar indexOfLast = start_ + (numEvents_ - 1) * stride_;
134  if (index2 < start_ || indexOfLast < index1) return false;
135 
136  const int strideJustBeforeIndex1 = std::min(
137  int(numEvents_ - 1), std::max(int(0), int((index1 - start_) / stride_)));
138 
139  const int strideJustAfterIndex2 = std::max(
140  int(0), std::min(int(numEvents_ - 1), int((index2 - start_) / stride_)));
141 
142  for (int i = strideJustBeforeIndex1; i <= strideJustAfterIndex2; i++) {
143  const int indexEvent = start_ + i * stride_;
144  if (index1 < indexEvent && indexEvent <= index2) return true;
145  }
146 
147  return false;
148 }
149 
150 template <class Scalar>
152  Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
153 {
154  auto l_out = Teuchos::fancyOStream(out.getOStream());
155  Teuchos::OSTab ostab(*l_out, 2, "TimeEventRangeIndex");
156  l_out->setOutputToRootOnly(0);
157 
158  *l_out << "TimeEventRangeIndex:"
159  << "\n"
160  << " name = " << this->getName() << "\n"
161  << " Type = " << this->getType() << "\n"
162  << " start_ = " << start_ << "\n"
163  << " stop_ = " << stop_ << "\n"
164  << " stride_ = " << stride_ << "\n"
165  << " numEvents_ = " << numEvents_ << std::endl;
166 }
167 
168 template <class Scalar>
171 {
173  Teuchos::parameterList("Time Event Range Index");
174 
175  pl->setName(this->getName());
176  pl->set("Name", this->getName());
177  pl->set("Type", "Range Index");
178 
179  pl->set("Start Index", getIndexStart(), "Start of Index range");
180  pl->set("Stop Index", getIndexStop(), "Stop of Index range");
181  pl->set("Stride Index", getIndexStride(), "Stride of Index range");
182 
183  return pl;
184 }
185 
186 // Nonmember constructors.
187 // ------------------------------------------------------------------------
188 
189 template <class Scalar>
192 {
193  auto teri = Teuchos::rcp(new TimeEventRangeIndex<Scalar>());
194  if (pl == Teuchos::null) return teri; // Return default TimeEventRangeIndex.
195 
197  pl->get<std::string>("Type", "Range Index") != "Range Index",
198  std::logic_error,
199  "Error - Time Event Type != 'Range Index'. (='" +
200  pl->get<std::string>("Type") + "')\n");
201 
202  pl->validateParametersAndSetDefaults(*teri->getValidParameters());
203 
204  teri->setName(pl->get("Name", "From createTimeEventRangeIndex"));
205  teri->setIndexStart(pl->get("Start Index", teri->getIndexStart()));
206  teri->setIndexStop(pl->get("Stop Index", teri->getIndexStop()));
207  teri->setIndexStride(pl->get("Stride Index", teri->getIndexStride()));
208 
209  return teri;
210 }
211 
212 } // namespace Tempus
213 #endif // Tempus_TimeEventRangeIndex_impl_hpp
virtual void setIndexStart(int start)
Set the start of the index range.
TimeEventRangeIndex specifies a start, stop and stride index.
virtual void setType(std::string s)
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Describe member data.
virtual void setName(std::string name)
Set the name of the TimeEvent.
T & get(const std::string &name, T def_value)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual int indexToNextEvent(int index) const
How many indices until the next event.
void validateParametersAndSetDefaults(ParameterList const &validParamList, int const depth=1000)
virtual void setIndexStride(int stride)
Set the stride of the index range.
virtual void setNumEvents()
Set the number of events from start_, stop_ and stride_.
virtual void setIndexStop(int stop)
Set the stop of the index range.
RCP< std::basic_ostream< char_type, traits_type > > getOStream()
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Return a valid ParameterList with current settings.
ParameterList & setName(const std::string &name)
virtual bool eventInRangeIndex(int index1, int index2) const
Test if an event occurs within the index range.
virtual int indexOfNextEvent(int index) const
Return the index of the next event following the input index.
virtual bool isIndex(int index) const
Test if index is a time event.
Teuchos::RCP< TimeEventRangeIndex< Scalar > > createTimeEventRangeIndex(Teuchos::RCP< Teuchos::ParameterList > pList)
Nonmember Constructor via ParameterList.
virtual void setIndexRange(int start, int stop, int stride)
Set the range of event indices.