Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Tempus_TimeEventListIndex_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_TimeEventListIndex_impl_hpp
10 #define Tempus_TimeEventListIndex_impl_hpp
11 
12 namespace Tempus {
13 
14 template <class Scalar>
16 {
17  this->setType("List Index");
18  this->setName("TimeEventListIndex");
19 }
20 
21 template <class Scalar>
23  std::string name)
24 {
25  this->setType("List Index");
26  if (name == "" && !indexList.empty()) {
27  std::ostringstream oss;
28  oss << "TimeEventListIndex (" << indexList_.front() << ", ... ,"
29  << indexList_.back() << ")";
30  this->setName(oss.str());
31  }
32  else {
33  this->setName(name);
34  }
35 
36  this->setIndexList(indexList);
37 }
38 
39 template <class Scalar>
40 void TimeEventListIndex<Scalar>::setIndexList(std::vector<int> indexList,
41  bool sort)
42 {
43  indexList_ = indexList;
44  if (sort) {
45  std::sort(indexList_.begin(), indexList_.end());
46  indexList_.erase(std::unique(indexList_.begin(), indexList_.end()),
47  indexList_.end());
48  }
49 }
50 
51 template <class Scalar>
53 {
54  if (indexList_.size() == 0) {
55  indexList_.push_back(index);
56  return;
57  }
58 
59  std::vector<int>::iterator it;
60  it = std::find(indexList_.begin(), indexList_.end(), index);
61  // Check if index is already in list.
62  if (it != indexList_.end()) return;
63 
64  it = std::upper_bound(indexList_.begin(), indexList_.end(), index);
65  indexList_.insert(it, index);
66 }
67 
68 template <class Scalar>
70 {
71  return (std::find(indexList_.begin(), indexList_.end(), index) !=
72  indexList_.end());
73 }
74 
75 template <class Scalar>
77 {
78  return indexOfNextEvent(index) - index; // Neg. indicating in the past.
79 }
80 
81 template <class Scalar>
83 {
84  if (indexList_.size() == 0) return this->getDefaultIndex();
85 
86  // Check if before first event.
87  if (index < indexList_.front()) return indexList_.front();
88 
89  // Check if after last event.
90  if (index >= indexList_.back()) return this->getDefaultIndex();
91 
92  std::vector<int>::const_iterator it =
93  std::upper_bound(indexList_.begin(), indexList_.end(), index);
94 
95  return int(*it);
96 }
97 
98 template <class Scalar>
99 bool TimeEventListIndex<Scalar>::eventInRangeIndex(int index1, int index2) const
100 {
101  if (index1 > index2) {
102  int tmp = index1;
103  index1 = index2;
104  index2 = tmp;
105  }
106 
107  if (indexList_.size() == 0) return false;
108 
109  // Check if range is completely outside index events.
110  if (index2 < indexList_.front() || indexList_.back() < index1) return false;
111 
112  Scalar indexEvent1 = indexOfNextEvent(index1);
113  Scalar indexEvent2 = indexOfNextEvent(index2);
114  // Check if the next index event is different for the two indices.
115  if (indexEvent1 != indexEvent2) return true;
116 
117  // Check if indices bracket index event.
118  if (index1 < indexEvent1 && indexEvent1 <= index2) return true;
119 
120  return false;
121 }
122 
123 template <class Scalar>
125  Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
126 {
127  auto l_out = Teuchos::fancyOStream(out.getOStream());
128  Teuchos::OSTab ostab(*l_out, 2, "TimeEventListIndex");
129  l_out->setOutputToRootOnly(0);
130 
131  *l_out << "TimeEventListIndex:"
132  << "\n"
133  << " name = " << this->getName() << "\n"
134  << " Type = " << this->getType() << "\n"
135  << " IndexList_ = ";
136  if (!indexList_.empty()) {
137  for (auto it = indexList_.begin(); it != indexList_.end() - 1; ++it)
138  *l_out << *it << ", ";
139  *l_out << *(indexList_.end() - 1) << std::endl;
140  }
141  else {
142  *l_out << "<empty>" << std::endl;
143  }
144 }
145 
146 template <class Scalar>
149 {
151  Teuchos::parameterList("Time Event List Index");
152 
153  pl->setName(this->getName());
154  pl->set("Name", this->getName());
155  pl->set("Type", this->getType());
156 
157  std::ostringstream list;
158  if (!indexList_.empty()) {
159  for (std::size_t i = 0; i < indexList_.size() - 1; ++i)
160  list << indexList_[i] << ", ";
161  list << indexList_[indexList_.size() - 1];
162  }
163  pl->set<std::string>("Index List", list.str(),
164  "Comma deliminated list of indices");
165 
166  return pl;
167 }
168 
169 // Nonmember constructors.
170 // ------------------------------------------------------------------------
171 
172 template <class Scalar>
175 {
176  auto teli = Teuchos::rcp(new TimeEventListIndex<Scalar>());
177  if (pl == Teuchos::null) return teli; // Return default TimeEventListIndex.
178 
180  pl->get<std::string>("Type", "List Index") != "List Index",
181  std::logic_error,
182  "Error - Time Event Type != 'List Index'. (='" +
183  pl->get<std::string>("Type") + "')\n");
184 
185  pl->validateParametersAndSetDefaults(*teli->getValidParameters());
186 
187  teli->setName(pl->get("Name", "From createTimeEventListIndex"));
188 
189  std::vector<int> indexList;
190  indexList.clear();
191  std::string str = pl->get<std::string>("Index List");
192  std::string delimiters(",");
193  std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
194  std::string::size_type pos = str.find_first_of(delimiters, lastPos);
195  while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
196  std::string token = str.substr(lastPos, pos - lastPos);
197  indexList.push_back(int(std::stoi(token)));
198  if (pos == std::string::npos) break;
199 
200  lastPos = str.find_first_not_of(delimiters, pos);
201  pos = str.find_first_of(delimiters, lastPos);
202  }
203  teli->setIndexList(indexList);
204 
205  return teli;
206 }
207 
208 } // namespace Tempus
209 #endif // Tempus_TimeEventListIndex_impl_hpp
virtual int indexToNextEvent(int index) const
How many indices until the next event.
T & get(const std::string &name, T def_value)
virtual bool isIndex(int index) const
Test if index is a time event.
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
virtual int indexOfNextEvent(int index) const
Return the index of the next event following the input index.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
TimeEventListIndex specifies a list of index events.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Return a valid ParameterList with current settings.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual void addIndex(int index)
Add the index to event vector.
void validateParametersAndSetDefaults(ParameterList const &validParamList, int const depth=1000)
Teuchos::RCP< TimeEventListIndex< Scalar > > createTimeEventListIndex(Teuchos::RCP< Teuchos::ParameterList > pList)
Nonmember Constructor via ParameterList.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Describe member data.
virtual bool eventInRangeIndex(int index1, int index2) const
Test if an event occurs within the index range.
RCP< std::basic_ostream< char_type, traits_type > > getOStream()
virtual void setIndexList(std::vector< int > indexList, bool sort=true)
Set the vector of event indices.
ParameterList & setName(const std::string &name)