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 
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  this->setName(oss.str());
23  setNumEvents();
24 }
25 
26 
27 template<class Scalar>
29  int start, int stop, 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  this->setName(oss.str());
37  } else {
38  this->setName(name);
39  }
40 
41  this->setIndexRange(start, stop, stride);
42 }
43 
44 
45 template<class Scalar>
47 {
48  start_ = start;
49  if (stop_ < start_) {
50  stop_ = start_;
51  }
52  setNumEvents();
53 }
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 
68 template<class Scalar>
70 {
71  stride_ = stride;
72  if (stride_ < 1) {
73  stride_ = 1;
74  } else if (stride_ > (stop_ - start_)) {
75  stride_ = stop_ - start_;
76  }
77  setNumEvents();
78 }
79 
80 
81 template<class Scalar>
83 {
84  if (stride_ == 0 || start_ == stop_)
85  numEvents_ = 1;
86  else
87  numEvents_ = int((stop_ - start_) / stride_) + 1;
88 }
89 
90 
91 template<class Scalar>
93 {
94  const int indexOfLast = start_ + (numEvents_-1) * stride_;
95  if (index < start_ || index > indexOfLast) return false;
96  if ((index - start_) % stride_ == 0) return true;
97 
98  return false;
99 }
100 
101 
102 template<class Scalar>
104 {
105  return indexOfNextEvent(index) - index;
106 }
107 
108 
109 template<class Scalar>
111 {
112  // Check if before the first index.
113  if (index < start_) return start_;
114 
115  const int indexOfLast = start_ + (numEvents_-1) * stride_;
116  // Check if after or equal to last index.
117  if (index >= indexOfLast) return this->getDefaultIndex();
118 
119  // Check if index is an event. If so, return next event.
120  if (isIndex(index)) return index+stride_;
121 
122  const int numStrides = (index - start_) / stride_ + 1;
123  const Scalar indexOfNext = start_ + numStrides * stride_;
124  return indexOfNext;
125 }
126 
127 
128 template<class Scalar>
129 bool TimeEventRangeIndex<Scalar>::eventInRangeIndex(int index1, int index2) const
130 {
131  if (index1 > index2) {
132  int tmp = index1;
133  index1 = index2;
134  index2 = tmp;
135  }
136 
137  // Check if range is completely outside index events.
138  const Scalar indexOfLast = start_ + (numEvents_-1) * stride_;
139  if (index2 < start_ || indexOfLast < index1) return false;
140 
141  const int strideJustBeforeIndex1 = std::min(int(numEvents_-1),
142  std::max(int(0), int((index1 - start_) / stride_)));
143 
144  const int strideJustAfterIndex2 = std::max(int(0), std::min(int(numEvents_-1),
145  int((index2 - start_) / stride_)));
146 
147  for ( int i = strideJustBeforeIndex1; i <= strideJustAfterIndex2; i++ ) {
148  const int indexEvent = start_ + i * stride_;
149  if (index1 < indexEvent && indexEvent <= index2) return true;
150  }
151 
152  return false;
153 }
154 
155 
156 template<class Scalar>
158  const Teuchos::EVerbosityLevel verbLevel) const
159 {
160  auto l_out = Teuchos::fancyOStream( out.getOStream() );
161  Teuchos::OSTab ostab(*l_out, 2, "TimeEventRangeIndex");
162  l_out->setOutputToRootOnly(0);
163 
164  *l_out << "TimeEventRangeIndex:" << "\n"
165  << " name = " << this->getName() << "\n"
166  << " Type = " << this->getType() << "\n"
167  << " start_ = " << start_ << "\n"
168  << " stop_ = " << stop_ << "\n"
169  << " stride_ = " << stride_ << "\n"
170  << " numEvents_ = " << numEvents_ << std::endl;
171 }
172 
173 
174 template<class Scalar>
177 {
179  Teuchos::parameterList("Time Event Range Index");
180 
181  pl->setName(this->getName());
182  pl->set("Name", this->getName());
183  pl->set("Type", "Range Index");
184 
185  pl->set("Start Index", getIndexStart(), "Start of Index range");
186  pl->set("Stop Index", getIndexStop(), "Stop of Index range");
187  pl->set("Stride Index", getIndexStride(), "Stride of Index range");
188 
189  return pl;
190 }
191 
192 
193 // Nonmember constructors.
194 // ------------------------------------------------------------------------
195 
196 template<class Scalar>
199 {
200  auto teri = Teuchos::rcp(new TimeEventRangeIndex<Scalar>());
201  if (pl == Teuchos::null) return teri; // Return default TimeEventRangeIndex.
202 
204  pl->get<std::string>("Type", "Range Index") != "Range Index",
205  std::logic_error,
206  "Error - Time Event Type != 'Range Index'. (='"
207  + pl->get<std::string>("Type")+"')\n");
208 
209  pl->validateParametersAndSetDefaults(*teri->getValidParameters());
210 
211  teri->setName (pl->get("Name", "From createTimeEventRangeIndex"));
212  teri->setIndexStart (pl->get("Start Index", teri->getIndexStart()));
213  teri->setIndexStop (pl->get("Stop Index", teri->getIndexStop()));
214  teri->setIndexStride (pl->get("Stride Index", teri->getIndexStride()));
215 
216  return teri;
217 }
218 
219 
220 } // namespace Tempus
221 #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.