9 #ifndef Tempus_TimeEventList_impl_hpp
10 #define Tempus_TimeEventList_impl_hpp
16 template <
class Scalar>
19 relTol_(this->getDefaultTol()),
20 absTol_(this->getDefaultTol()),
30 template <
class Scalar>
32 std::string name,
bool landOnExactly,
35 relTol_(this->getDefaultTol()),
36 absTol_(this->getDefaultTol()),
47 template <
class Scalar>
50 if (timeList_.size() == 0) {
52 absTol_ = relTol_ * timeScale_;
57 std::max(std::abs(timeList_.front()), std::abs(timeList_.back()));
58 absTol_ = relTol_ * timeScale_;
63 absTol_ = relTol_ * timeScale_;
67 template <
class Scalar>
72 std::sort(timeList_.begin(), timeList_.end());
73 timeList_.erase(std::unique(timeList_.begin(), timeList_.end()),
78 template <
class Scalar>
81 if (timeList_.size() == 0) {
82 timeList_.push_back(time);
87 auto it = std::upper_bound(timeList_.begin(), timeList_.end(), time);
88 if (timeList_.size() == 1) {
90 if (std::abs(timeList_.front() - time) >= absTol_)
91 timeList_.insert(it, time);
97 if (it == timeList_.begin()) {
98 if (std::abs(timeList_.front() - time) >= absTol_)
99 timeList_.insert(it, time);
101 else if (it == timeList_.end()) {
102 if (std::abs(timeList_.back() - time) >= absTol_)
103 timeList_.insert(it, time);
105 else if (std::abs(*(it - 1) - time) >= absTol_ &&
106 std::abs(*(it)-time) >= absTol_) {
107 timeList_.insert(it, time);
112 template <
class Scalar>
115 relTol_ = std::abs(relTol);
119 template <
class Scalar>
122 for (
auto it = timeList_.begin(); it != timeList_.end(); ++it)
128 template <
class Scalar>
131 return timeOfNextEvent(time) - time;
134 template <
class Scalar>
137 if (timeList_.size() == 0)
return this->getDefaultTime();
140 if (time < timeList_.front() - absTol_)
return timeList_.front();
143 if (time > timeList_.back() - absTol_)
144 return std::numeric_limits<Scalar>::max();
146 typename std::vector<Scalar>::const_iterator it =
147 std::upper_bound(timeList_.begin(), timeList_.end(), time);
148 const Scalar timeEvent = *it;
156 template <
class Scalar>
165 if (timeList_.size() == 0)
return false;
167 for (
auto it = timeList_.begin(); it != timeList_.end(); ++it)
168 if (time1 + absTol_ < *it && *it < time2 + absTol_)
return true;
173 template <
class Scalar>
177 auto l_out = Teuchos::fancyOStream(out.
getOStream());
179 l_out->setOutputToRootOnly(0);
181 *l_out <<
"TimeEventList:"
183 <<
" name = " << this->getName() <<
"\n"
184 <<
" Type = " << this->getType() <<
"\n"
185 <<
" timeScale_ = " << timeScale_ <<
"\n"
186 <<
" relTol_ = " << relTol_ <<
"\n"
187 <<
" absTol_ = " << absTol_ <<
"\n"
188 <<
" landOnExactly_ = " << landOnExactly_ <<
"\n"
190 if (!timeList_.empty()) {
191 for (
auto it = timeList_.begin(); it != timeList_.end() - 1; ++it)
192 *l_out << *it <<
", ";
193 *l_out << *(timeList_.end() - 1) << std::endl;
196 *l_out <<
"<empty>" << std::endl;
200 template <
class Scalar>
205 Teuchos::parameterList(
"Time Event List");
208 pl->
set(
"Name", this->getName());
209 pl->
set(
"Type", this->getType());
211 pl->
set(
"Relative Tolerance", this->getRelTol(),
212 "Relative time tolerance for matching time events.");
214 pl->
set(
"Land On Exactly", this->getLandOnExactly(),
215 "Should these time events be landed on exactly, i.e, adjust the "
216 "timestep to hit time event, versus stepping over and keeping the "
217 "time step unchanged.");
219 std::vector<Scalar> times = this->getTimeList();
220 std::ostringstream list;
221 if (!times.empty()) {
222 for (std::size_t i = 0; i < times.size() - 1; ++i) list << times[i] <<
", ";
223 list << times[times.size() - 1];
225 pl->
set<std::string>(
"Time List", list.str(),
226 "Comma deliminated list of times");
234 template <
class Scalar>
239 if (pl == Teuchos::null)
return tel;
243 "Error - Time Event Type != 'List'. (='" +
244 pl->
get<std::string>(
"Type") +
"')\n");
248 tel->setName(pl->
get(
"Name",
"From createTimeEventList"));
249 tel->setRelTol(pl->
get(
"Relative Tolerance", tel->getRelTol()));
250 tel->setLandOnExactly(pl->
get(
"Land On Exactly", tel->getLandOnExactly()));
252 std::vector<Scalar> timeList;
253 std::string str = pl->
get<std::string>(
"Time List");
254 std::string delimiters(
",");
256 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
258 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
259 while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
261 std::string token = str.substr(lastPos, pos - lastPos);
262 timeList.push_back(Scalar(std::stod(token)));
263 if (pos == std::string::npos)
break;
265 lastPos = str.find_first_not_of(delimiters, pos);
266 pos = str.find_first_of(delimiters, lastPos);
268 tel->setTimeList(timeList);
274 #endif // Tempus_TimeEventList_impl_hpp
virtual bool isTime(Scalar time) const
Test if time is near an event (within tolerance).
virtual void setType(std::string s)
virtual void setName(std::string name)
Set the name of the TimeEvent.
T & get(const std::string &name, T def_value)
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Return a valid ParameterList with current settings.
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)
virtual void addTime(Scalar time)
Add the time to event vector.
virtual Scalar timeOfNextEvent(Scalar time) const
Return the time of the next event following the input time.
virtual bool eventInRange(Scalar time1, Scalar time2) const
Test if an event occurs within the time range.
virtual Scalar getDefaultTol() const
Return the default tolerance used by TimeEvents.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual void setTimeScale()
Set the time scale for the time events.
void validateParametersAndSetDefaults(ParameterList const &validParamList, int const depth=1000)
virtual void setRelTol(Scalar relTol)
Set the relative tolerance.
virtual void setTimeList(std::vector< Scalar > timeList, bool sort=true)
Set the list of time events.
TimeEventList()
Default constructor.
RCP< std::basic_ostream< char_type, traits_type > > getOStream()
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Describe member data.
bool approxEqualAbsTol(Scalar a, Scalar b, Scalar absTol)
Test if values are approximately equal within the absolute tolerance.
bool approxZero(Scalar value, Scalar tol=Teuchos::ScalarTraits< Scalar >::sfmin())
Test if value is approximately zero within tolerance.
virtual Scalar timeToNextEvent(Scalar time) const
How much time until the next event.
ParameterList & setName(const std::string &name)
virtual void setLandOnExactly(bool LOE)
Set if the time event should be landed on exactly.
TimeEventList specifies a list of time events.
Teuchos::RCP< TimeEventList< Scalar > > createTimeEventList(Teuchos::RCP< Teuchos::ParameterList > pList)
Nonmember Constructor via ParameterList.