10 #ifndef Tempus_TimeEventList_impl_hpp
11 #define Tempus_TimeEventList_impl_hpp
17 template <
class Scalar>
20 relTol_(this->getDefaultTol()),
21 absTol_(this->getDefaultTol()),
31 template <
class Scalar>
33 std::string name,
bool landOnExactly,
36 relTol_(this->getDefaultTol()),
37 absTol_(this->getDefaultTol()),
48 template <
class Scalar>
51 if (timeList_.size() == 0) {
53 absTol_ = relTol_ * timeScale_;
58 std::max(std::abs(timeList_.front()), std::abs(timeList_.back()));
59 absTol_ = relTol_ * timeScale_;
64 absTol_ = relTol_ * timeScale_;
68 template <
class Scalar>
73 std::sort(timeList_.begin(), timeList_.end());
74 timeList_.erase(std::unique(timeList_.begin(), timeList_.end()),
79 template <
class Scalar>
82 if (timeList_.size() == 0) {
83 timeList_.push_back(time);
88 auto it = std::upper_bound(timeList_.begin(), timeList_.end(), time);
89 if (timeList_.size() == 1) {
91 if (std::abs(timeList_.front() - time) >= absTol_)
92 timeList_.insert(it, time);
98 if (it == timeList_.begin()) {
99 if (std::abs(timeList_.front() - time) >= absTol_)
100 timeList_.insert(it, time);
102 else if (it == timeList_.end()) {
103 if (std::abs(timeList_.back() - time) >= absTol_)
104 timeList_.insert(it, time);
106 else if (std::abs(*(it - 1) - time) >= absTol_ &&
107 std::abs(*(it)-time) >= absTol_) {
108 timeList_.insert(it, time);
113 template <
class Scalar>
116 relTol_ = std::abs(relTol);
120 template <
class Scalar>
123 for (
auto it = timeList_.begin(); it != timeList_.end(); ++it)
129 template <
class Scalar>
132 return timeOfNextEvent(time) - time;
135 template <
class Scalar>
138 if (timeList_.size() == 0)
return this->getDefaultTime();
141 if (time < timeList_.front() - absTol_)
return timeList_.front();
144 if (time > timeList_.back() - absTol_)
145 return std::numeric_limits<Scalar>::max();
147 typename std::vector<Scalar>::const_iterator it =
148 std::upper_bound(timeList_.begin(), timeList_.end(), time);
149 const Scalar timeEvent = *it;
157 template <
class Scalar>
166 if (timeList_.size() == 0)
return false;
168 for (
auto it = timeList_.begin(); it != timeList_.end(); ++it)
169 if (time1 + absTol_ < *it && *it < time2 + absTol_)
return true;
174 template <
class Scalar>
178 auto l_out = Teuchos::fancyOStream(out.
getOStream());
180 l_out->setOutputToRootOnly(0);
182 *l_out <<
"TimeEventList:"
184 <<
" name = " << this->getName() <<
"\n"
185 <<
" Type = " << this->getType() <<
"\n"
186 <<
" timeScale_ = " << timeScale_ <<
"\n"
187 <<
" relTol_ = " << relTol_ <<
"\n"
188 <<
" absTol_ = " << absTol_ <<
"\n"
189 <<
" landOnExactly_ = " << landOnExactly_ <<
"\n"
191 if (!timeList_.empty()) {
192 for (
auto it = timeList_.begin(); it != timeList_.end() - 1; ++it)
193 *l_out << *it <<
", ";
194 *l_out << *(timeList_.end() - 1) << std::endl;
197 *l_out <<
"<empty>" << std::endl;
201 template <
class Scalar>
206 Teuchos::parameterList(
"Time Event List");
209 pl->
set(
"Name", this->getName());
210 pl->
set(
"Type", this->getType());
212 pl->
set(
"Relative Tolerance", this->getRelTol(),
213 "Relative time tolerance for matching time events.");
215 pl->
set(
"Land On Exactly", this->getLandOnExactly(),
216 "Should these time events be landed on exactly, i.e, adjust the "
217 "timestep to hit time event, versus stepping over and keeping the "
218 "time step unchanged.");
220 std::vector<Scalar> times = this->getTimeList();
221 std::ostringstream list;
222 if (!times.empty()) {
223 for (std::size_t i = 0; i < times.size() - 1; ++i) list << times[i] <<
", ";
224 list << times[times.size() - 1];
226 pl->
set<std::string>(
"Time List", list.str(),
227 "Comma deliminated list of times");
235 template <
class Scalar>
240 if (pl == Teuchos::null)
return tel;
244 "Error - Time Event Type != 'List'. (='" +
245 pl->
get<std::string>(
"Type") +
"')\n");
249 tel->setName(pl->
get(
"Name",
"From createTimeEventList"));
250 tel->setRelTol(pl->
get(
"Relative Tolerance", tel->getRelTol()));
251 tel->setLandOnExactly(pl->
get(
"Land On Exactly", tel->getLandOnExactly()));
253 std::vector<Scalar> timeList;
254 std::string str = pl->
get<std::string>(
"Time List");
255 std::string delimiters(
",");
257 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
259 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
260 while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
262 std::string token = str.substr(lastPos, pos - lastPos);
263 timeList.push_back(Scalar(std::stod(token)));
264 if (pos == std::string::npos)
break;
266 lastPos = str.find_first_not_of(delimiters, pos);
267 pos = str.find_first_of(delimiters, lastPos);
269 tel->setTimeList(timeList);
275 #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.
#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)
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.