9#ifndef Tempus_TimeEventList_impl_hpp
10#define Tempus_TimeEventList_impl_hpp
19 : timeScale_(1.0), relTol_(this->getDefaultTol()),
20 absTol_(this->getDefaultTol()), landOnExactly_(true)
32 std::vector<Scalar> timeList, std::string name,
33 bool landOnExactly, Scalar relTol)
34 : timeScale_(1.0), relTol_(this->getDefaultTol()),
35 absTol_(this->getDefaultTol()), landOnExactly_(true)
49 if (timeList_.size() == 0) {
51 absTol_ = relTol_*timeScale_;
55 timeScale_ = std::max(std::abs(timeList_.front()),
56 std::abs(timeList_.back()));
57 absTol_ = relTol_*timeScale_;
62 absTol_ = relTol_*timeScale_;
72 std::sort(timeList_.begin(),timeList_.end());
73 timeList_.erase(std::unique(timeList_.begin(),
83 if (timeList_.size() == 0) {
84 timeList_.push_back(time);
89 auto it = std::upper_bound(timeList_.begin(), timeList_.end(), time);
90 if (timeList_.size() == 1) {
92 if (std::abs(timeList_.front()-time) >= absTol_)
93 timeList_.insert(it, time);
99 if (it == timeList_.begin()) {
100 if (std::abs(timeList_.front()-time) >= absTol_)
101 timeList_.insert(it, time);
102 }
else if (it == timeList_.end()) {
103 if (std::abs(timeList_.back()-time) >= absTol_)
104 timeList_.insert(it, time);
105 }
else if (std::abs(*(it-1) - time) >= absTol_ &&
106 std::abs(*(it ) - time) >= absTol_) {
107 timeList_.insert(it, time);
113template<
class Scalar>
116 relTol_ = std::abs(relTol);
121template<
class Scalar>
124 for (
auto it = timeList_.begin(); it != timeList_.end(); ++it)
131template<
class Scalar>
134 return timeOfNextEvent(time) - time;
138template<
class Scalar>
141 if (timeList_.size() == 0)
return this->getDefaultTime();
144 if (time < timeList_.front()-absTol_)
return timeList_.front();
147 if (time > timeList_.back()-absTol_)
148 return std::numeric_limits<Scalar>::max();
150 typename std::vector<Scalar>::const_iterator it =
151 std::upper_bound(timeList_.begin(), timeList_.end(), time);
152 const Scalar timeEvent = *it;
162template<
class Scalar>
164 Scalar time1, Scalar time2)
const
172 if (timeList_.size() == 0)
return false;
174 for (
auto it = timeList_.begin(); it != timeList_.end(); ++it)
175 if (time1+absTol_ < *it && *it < time2+absTol_)
return true;
181template<
class Scalar>
183 const Teuchos::EVerbosityLevel verbLevel)
const
185 auto l_out = Teuchos::fancyOStream( out.getOStream() );
186 Teuchos::OSTab ostab(*l_out, 2,
"TimeEventList");
187 l_out->setOutputToRootOnly(0);
189 *l_out <<
"TimeEventList:" <<
"\n"
190 <<
" name = " << this->getName() <<
"\n"
191 <<
" Type = " << this->getType() <<
"\n"
192 <<
" timeScale_ = " << timeScale_ <<
"\n"
193 <<
" relTol_ = " << relTol_ <<
"\n"
194 <<
" absTol_ = " << absTol_ <<
"\n"
195 <<
" landOnExactly_ = " << landOnExactly_ <<
"\n"
197 if (!timeList_.empty()) {
198 for (
auto it = timeList_.begin(); it != timeList_.end()-1; ++it)
199 *l_out << *it <<
", ";
200 *l_out << *(timeList_.end()-1) << std::endl;
202 *l_out <<
"<empty>" << std::endl;
207template<
class Scalar>
208Teuchos::RCP<const Teuchos::ParameterList>
211 Teuchos::RCP<Teuchos::ParameterList> pl =
212 Teuchos::parameterList(
"Time Event List");
214 pl->setName(this->getName());
215 pl->set(
"Name", this->getName());
216 pl->set(
"Type", this->getType());
218 pl->set(
"Relative Tolerance", this->getRelTol(),
219 "Relative time tolerance for matching time events.");
221 pl->set(
"Land On Exactly", this->getLandOnExactly(),
222 "Should these time events be landed on exactly, i.e, adjust the timestep to hit time event, versus stepping over and keeping the time step unchanged.");
224 std::vector<Scalar> times = this->getTimeList();
225 std::ostringstream list;
226 if (!times.empty()) {
227 for(std::size_t i = 0; i < times.size()-1; ++i) list << times[i] <<
", ";
228 list << times[times.size()-1];
230 pl->set<std::string>(
"Time List", list.str(),
231 "Comma deliminated list of times");
240template<
class Scalar>
242 Teuchos::RCP<Teuchos::ParameterList> pl)
244 auto tel = Teuchos::rcp(
new TimeEventList<Scalar>());
245 if (pl == Teuchos::null)
return tel;
247 TEUCHOS_TEST_FOR_EXCEPTION(
248 pl->get<std::string>(
"Type",
"List") !=
"List",
250 "Error - Time Event Type != 'List'. (='"
251 + pl->get<std::string>(
"Type")+
"')\n");
253 pl->validateParametersAndSetDefaults(*tel->getValidParameters());
255 tel->setName (pl->get(
"Name",
"From createTimeEventList"));
256 tel->setRelTol (pl->get(
"Relative Tolerance", tel->getRelTol()));
257 tel->setLandOnExactly (pl->get(
"Land On Exactly", tel->getLandOnExactly()));
259 std::vector<Scalar> timeList;
260 std::string str = pl->get<std::string>(
"Time List");
261 std::string delimiters(
",");
263 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
265 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
266 while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
268 std::string token = str.substr(lastPos,pos-lastPos);
269 timeList.push_back(Scalar(std::stod(token)));
270 if(pos==std::string::npos)
break;
272 lastPos = str.find_first_not_of(delimiters, pos);
273 pos = str.find_first_of(delimiters, lastPos);
275 tel->setTimeList(timeList);
virtual void setType(std::string s)
virtual void setName(std::string name)
Set the name of the TimeEvent.
virtual Scalar getDefaultTol() const
Return the default tolerance used by TimeEvents.
virtual Scalar timeToNextEvent(Scalar time) const
How much time until the next event.
virtual Scalar timeOfNextEvent(Scalar time) const
Return the time of the next event following the input time.
virtual bool isTime(Scalar time) const
Test if time is near an event (within tolerance).
TimeEventList()
Default constructor.
virtual void setTimeScale()
Set the time scale for the time events.
virtual void addTime(Scalar time)
Add the time to event vector.
virtual bool eventInRange(Scalar time1, Scalar time2) const
Test if an event occurs within the time range.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Return a valid ParameterList with current settings.
virtual void setRelTol(Scalar relTol)
Set the relative tolerance.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Describe member data.
virtual void setLandOnExactly(bool LOE)
Set if the time event should be landed on exactly.
virtual void setTimeList(std::vector< Scalar > timeList, bool sort=true)
Set the list of time events.
bool approxZero(Scalar value, Scalar tol=Teuchos::ScalarTraits< Scalar >::sfmin())
Test if value is approximately zero within tolerance.
bool approxEqualAbsTol(Scalar a, Scalar b, Scalar absTol)
Test if values are approximately equal within the absolute tolerance.
Teuchos::RCP< TimeEventList< Scalar > > createTimeEventList(Teuchos::RCP< Teuchos::ParameterList > pList)
Nonmember Constructor via ParameterList.