10 #ifndef Tempus_TimeEventRange_impl_hpp
11 #define Tempus_TimeEventRange_impl_hpp
17 template <
class Scalar>
24 relTol_(this->getDefaultTol()),
25 absTol_(this->getDefaultTol()),
31 std::ostringstream oss;
37 template <
class Scalar>
39 std::string name,
bool landOnExactly,
45 timeScale_(std::max(std::abs(start_), std::abs(stop_))),
47 absTol_(relTol_ * timeScale_),
48 landOnExactly_(landOnExactly)
52 std::ostringstream oss;
53 oss <<
"TimeEventRange (" << start <<
"; " << stop <<
"; " << stride <<
")";
64 template <
class Scalar>
66 std::string name,
bool landOnExactly,
71 numEvents_(numEvents),
72 timeScale_(std::max(std::abs(start_), std::abs(stop_))),
74 absTol_(relTol_ * timeScale_),
75 landOnExactly_(landOnExactly)
78 std::ostringstream oss;
79 oss <<
"TimeEventRange (" << start <<
"; " << stop <<
"; " << numEvents
91 template <
class Scalar>
103 setTimeStride(stride);
106 template <
class Scalar>
112 if (stop_ < start_) {
118 setNumEvents(numEvents);
121 template <
class Scalar>
125 if (stop_ < start_) stop_ = start_;
127 setTimeStride(stride_);
130 template <
class Scalar>
134 if (start_ > stop_) start_ = stop_;
136 setTimeStride(stride_);
139 template <
class Scalar>
142 timeScale_ = std::max(std::abs(start_), std::abs(stop_));
143 absTol_ = relTol_ * timeScale_;
148 absTol_ = relTol_ * timeScale_;
152 template <
class Scalar>
162 if ((stride_ > stop_ - start_) || (stride_ < 2 * absTol_)) {
163 stride_ = stop_ - start_;
166 numEvents_ = int((stop_ + absTol_ - start_) / stride_) + 1;
169 template <
class Scalar>
172 numEvents_ = numEvents;
173 if (numEvents_ < 0) {
175 if (stride_ < 2 * absTol_) stride_ = 2 * absTol_;
176 numEvents_ = int((stop_ + absTol_ - start_) / stride_) + 1;
182 stride_ = stop_ - start_;
185 if (numEvents_ < 2) numEvents_ = 2;
186 stride_ = (stop_ - start_) / Scalar(numEvents_ - 1);
191 if (stride_ <= 2 * absTol_) setTimeStride(2 * absTol_);
194 template <
class Scalar>
197 relTol_ = std::abs(relTol);
201 template <
class Scalar>
205 if (time < start_ - absTol_)
return false;
208 const Scalar timeOfLast = start_ + (numEvents_ - 1) * stride_;
209 if (time > timeOfLast + absTol_)
return false;
212 if (!
approxZero(stride_, 2 * absTol_)) numStrides = (time - start_) / stride_;
214 numStrides = std::min(std::max(0, numStrides),
int(numEvents_ - 1));
215 const Scalar leftBracket = start_ + numStrides * stride_;
221 const Scalar rightBracket = leftBracket + stride_;
227 template <
class Scalar>
230 return timeOfNextEvent(time) - time;
233 template <
class Scalar>
237 if (time < start_ - absTol_)
return start_;
239 const Scalar timeOfLast = start_ + (numEvents_ - 1) * stride_;
241 if (time > timeOfLast - absTol_)
return std::numeric_limits<Scalar>::max();
245 numStrides = int((time - start_) / stride_) + 1;
246 const Scalar timeEvent = start_ + numStrides * stride_;
254 template <
class Scalar>
264 const Scalar timeOfLast = start_ + (numEvents_ - 1) * stride_;
265 if (time2 < start_ - absTol_ || timeOfLast + absTol_ < time1)
return false;
268 return (time1 < start_ - absTol_ && start_ - absTol_ <= time2);
270 const int strideJustBeforeTime1 = std::min(
272 std::max(
int(0),
int((time1 - start_ + absTol_) / stride_ - 0.5)));
274 const int strideJustAfterTime2 = std::max(
275 int(0), std::min(
int(numEvents_ - 1),
276 int((time2 - start_ + absTol_) / stride_ + 0.5)));
278 for (
int i = strideJustBeforeTime1; i <= strideJustAfterTime2; i++) {
279 const Scalar timeEvent = start_ + i * stride_;
280 if (time1 < timeEvent - absTol_ && timeEvent - absTol_ <= time2)
287 template <
class Scalar>
291 auto l_out = Teuchos::fancyOStream(out.
getOStream());
293 l_out->setOutputToRootOnly(0);
295 *l_out <<
"TimeEventRange:"
297 <<
" name = " << this->getName() <<
"\n"
298 <<
" Type = " << this->getType() <<
"\n"
299 <<
" start_ = " << start_ <<
"\n"
300 <<
" stop_ = " << stop_ <<
"\n"
301 <<
" stride_ = " << stride_ <<
"\n"
302 <<
" numEvents_ = " << numEvents_ <<
"\n"
303 <<
" timeScale_ = " << timeScale_ <<
"\n"
304 <<
" relTol_ = " << relTol_ <<
"\n"
305 <<
" absTol_ = " << absTol_ <<
"\n"
306 <<
" landOnExactly_ = " << landOnExactly_ << std::endl;
309 template <
class Scalar>
314 Teuchos::parameterList(
"Time Event Range");
317 pl->
set(
"Name", this->getName());
318 pl->
set(
"Type", this->getType());
320 pl->
set(
"Start Time", getTimeStart(),
"Start of time range");
321 pl->
set(
"Stop Time", getTimeStop(),
"Stop of time range");
322 pl->
set(
"Stride Time", getTimeStride(),
"Stride of time range");
324 if (getTimeStride() * Scalar(getNumEvents() - 1) -
325 (getTimeStop() - getTimeStart()) <
327 pl->
set(
"Number of Events", getNumEvents(),
328 "Number of events in time range. If specified, 'Stride Time' is "
331 pl->
set(
"Relative Tolerance", getRelTol(),
332 "Relative time tolerance for matching time events.");
334 pl->
set(
"Land On Exactly", getLandOnExactly(),
335 "Should these time events be landed on exactly, i.e, adjust the "
336 "timestep to hit time event, versus stepping over and keeping the "
337 "time step unchanged.");
345 template <
class Scalar>
350 if (pl == Teuchos::null)
return ter;
354 "Error - Time Event Type != 'Range'. (='" +
355 pl->
get<std::string>(
"Type") +
"')\n");
357 auto validPL = *ter->getValidParameters();
358 bool numEventsFound = pl->
isParameter(
"Number of Events");
359 if (!numEventsFound) validPL.remove(
"Number of Events");
363 ter->setName(pl->
get(
"Name",
"From createTimeEventRange"));
364 ter->setTimeStart(pl->
get(
"Start Time", ter->getTimeStart()));
365 ter->setTimeStop(pl->
get(
"Stop Time", ter->getTimeStop()));
366 ter->setTimeStride(pl->
get(
"Stride Time", ter->getTimeStride()));
368 ter->setNumEvents(pl->
get(
"Number of Events", ter->getNumEvents()));
369 ter->setRelTol(pl->
get(
"Relative Tolerance", ter->getRelTol()));
370 ter->setLandOnExactly(pl->
get(
"Land On Exactly", ter->getLandOnExactly()));
376 #endif // Tempus_TimeEventRange_impl_hpp
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Return a valid ParameterList with current settings.
virtual void setType(std::string s)
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Describe member data.
virtual void setRelTol(Scalar relTol)
Set the relative tolerance.
Scalar stride_
Stride of time range.
virtual void setNumEvents(int numEvents)
Set the number of time events.
virtual void setName(std::string name)
Set the name of the TimeEvent.
T & get(const std::string &name, T def_value)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
virtual void setLandOnExactly(bool LOE)
Set if the time event should be landed on exactly.
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
Scalar start_
Start of time range.
bool isParameter(const std::string &name) const
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.
TimeEventRange specifies a start, stop and stride time.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual Scalar timeToNextEvent(Scalar time) const
How much time until the next event.
Teuchos::RCP< TimeEventRange< Scalar > > createTimeEventRange(Teuchos::RCP< Teuchos::ParameterList > pList)
Nonmember Constructor via ParameterList.
virtual void setTimeStop(Scalar stop)
Set the stop of the time range.
void validateParametersAndSetDefaults(ParameterList const &validParamList, int const depth=1000)
virtual void setTimeScale()
Set the time scale for the time events.
static magnitudeType magnitude(T a)
RCP< std::basic_ostream< char_type, traits_type > > getOStream()
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 void setTimeStart(Scalar start)
Set the start of the time range.
Scalar stop_
Stop of time range.
ParameterList & setName(const std::string &name)
virtual void setTimeStride(Scalar stride)
Set the stride of the time range.
virtual bool isTime(Scalar time) const
Test if time is near an event (within tolerance).
TimeEventRange()
Default constructor.
virtual Scalar timeOfNextEvent(Scalar time) const
Return the time of the next event following the input time.
virtual void setTimeRange(Scalar start, Scalar stop, Scalar stride)
Set the range of time events from start, stop and stride.