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: Time Integration and Sensitivity Analysis Package
4 //
5 // Copyright 2017 NTESS and the Tempus contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 //@HEADER
9 
10 #ifndef Tempus_TimeEventRangeIndex_impl_hpp
11 #define Tempus_TimeEventRangeIndex_impl_hpp
12 
13 namespace Tempus {
14 
15 template <class Scalar>
17  : start_(0), stop_(0), stride_(1), numEvents_(1)
18 {
19  this->setType("Range Index");
20  std::ostringstream oss;
21  oss << "TimeEventRangeIndex (" << start_ << "; " << stop_ << "; " << stride_
22  << ")";
23  this->setName(oss.str());
24  setNumEvents();
25 }
26 
27 template <class Scalar>
29  int stride, std::string name)
30  : start_(0), stop_(0), stride_(1), numEvents_(1)
31 {
32  this->setType("Range Index");
33  if (name == "") {
34  std::ostringstream oss;
35  oss << "TimeEventRangeIndex (" << start << "; " << stop << "; " << stride
36  << ")";
37  this->setName(oss.str());
38  }
39  else {
40  this->setName(name);
41  }
42 
43  this->setIndexRange(start, stop, stride);
44 }
45 
46 template <class Scalar>
48 {
49  start_ = start;
50  if (stop_ < start_) {
51  stop_ = start_;
52  }
53  setNumEvents();
54 }
55 
56 template <class Scalar>
58 {
59  stop_ = stop;
60  if (start_ > stop_) {
61  start_ = stop_;
62  setIndexStride(1);
63  }
64  setNumEvents();
65 }
66 
67 template <class Scalar>
69 {
70  stride_ = stride;
71  if (stride_ < 1) {
72  stride_ = 1;
73  }
74  else if (stride_ > (stop_ - start_)) {
75  stride_ = stop_ - start_;
76  }
77  setNumEvents();
78 }
79 
80 template <class Scalar>
82 {
83  if (stride_ == 0 || start_ == stop_)
84  numEvents_ = 1;
85  else
86  numEvents_ = int((stop_ - start_) / stride_) + 1;
87 }
88 
89 template <class Scalar>
91 {
92  const int indexOfLast = start_ + (numEvents_ - 1) * stride_;
93  if (index < start_ || index > indexOfLast) return false;
94  if ((index - start_) % stride_ == 0) return true;
95 
96  return false;
97 }
98 
99 template <class Scalar>
101 {
102  return indexOfNextEvent(index) - index;
103 }
104 
105 template <class Scalar>
107 {
108  // Check if before the first index.
109  if (index < start_) return start_;
110 
111  const int indexOfLast = start_ + (numEvents_ - 1) * stride_;
112  // Check if after or equal to last index.
113  if (index >= indexOfLast) return this->getDefaultIndex();
114 
115  // Check if index is an event. If so, return next event.
116  if (isIndex(index)) return index + stride_;
117 
118  const int numStrides = (index - start_) / stride_ + 1;
119  const Scalar indexOfNext = start_ + numStrides * stride_;
120  return indexOfNext;
121 }
122 
123 template <class Scalar>
125  int index2) const
126 {
127  if (index1 > index2) {
128  int tmp = index1;
129  index1 = index2;
130  index2 = tmp;
131  }
132 
133  // Check if range is completely outside index events.
134  const Scalar indexOfLast = start_ + (numEvents_ - 1) * stride_;
135  if (index2 < start_ || indexOfLast < index1) return false;
136 
137  const int strideJustBeforeIndex1 = std::min(
138  int(numEvents_ - 1), std::max(int(0), int((index1 - start_) / stride_)));
139 
140  const int strideJustAfterIndex2 = std::max(
141  int(0), std::min(int(numEvents_ - 1), int((index2 - start_) / stride_)));
142 
143  for (int i = strideJustBeforeIndex1; i <= strideJustAfterIndex2; i++) {
144  const int indexEvent = start_ + i * stride_;
145  if (index1 < indexEvent && indexEvent <= index2) return true;
146  }
147 
148  return false;
149 }
150 
151 template <class Scalar>
153  Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
154 {
155  auto l_out = Teuchos::fancyOStream(out.getOStream());
156  Teuchos::OSTab ostab(*l_out, 2, "TimeEventRangeIndex");
157  l_out->setOutputToRootOnly(0);
158 
159  *l_out << "TimeEventRangeIndex:"
160  << "\n"
161  << " name = " << this->getName() << "\n"
162  << " Type = " << this->getType() << "\n"
163  << " start_ = " << start_ << "\n"
164  << " stop_ = " << stop_ << "\n"
165  << " stride_ = " << stride_ << "\n"
166  << " numEvents_ = " << numEvents_ << std::endl;
167 }
168 
169 template <class Scalar>
172 {
174  Teuchos::parameterList("Time Event Range Index");
175 
176  pl->setName(this->getName());
177  pl->set("Name", this->getName());
178  pl->set("Type", "Range Index");
179 
180  pl->set("Start Index", getIndexStart(), "Start of Index range");
181  pl->set("Stop Index", getIndexStop(), "Stop of Index range");
182  pl->set("Stride Index", getIndexStride(), "Stride of Index range");
183 
184  return pl;
185 }
186 
187 // Nonmember constructors.
188 // ------------------------------------------------------------------------
189 
190 template <class Scalar>
193 {
194  auto teri = Teuchos::rcp(new TimeEventRangeIndex<Scalar>());
195  if (pl == Teuchos::null) return teri; // Return default TimeEventRangeIndex.
196 
198  pl->get<std::string>("Type", "Range Index") != "Range Index",
199  std::logic_error,
200  "Error - Time Event Type != 'Range Index'. (='" +
201  pl->get<std::string>("Type") + "')\n");
202 
203  pl->validateParametersAndSetDefaults(*teri->getValidParameters());
204 
205  teri->setName(pl->get("Name", "From createTimeEventRangeIndex"));
206  teri->setIndexStart(pl->get("Start Index", teri->getIndexStart()));
207  teri->setIndexStop(pl->get("Stop Index", teri->getIndexStop()));
208  teri->setIndexStride(pl->get("Stride Index", teri->getIndexStride()));
209 
210  return teri;
211 }
212 
213 } // namespace Tempus
214 #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)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
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.