9 #ifndef Tempus_TimeEventRange_impl_hpp
10 #define Tempus_TimeEventRange_impl_hpp
16 template<
class Scalar>
23 relTol_(this->getDefaultTol()),
24 absTol_(this->getDefaultTol()),
31 std::ostringstream oss;
37 template<
class Scalar>
39 Scalar start, Scalar stop, Scalar stride,
40 std::string name,
bool landOnExactly, Scalar relTol)
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 Scalar start, Scalar stop,
int numEvents,
67 std::string name,
bool landOnExactly, Scalar relTol)
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 <<
")";
90 template<
class Scalar>
92 Scalar start, Scalar stop, Scalar stride)
102 setTimeStride(stride);
106 template<
class Scalar>
108 Scalar start, Scalar stop,
int numEvents)
112 if (stop_ < start_) {
118 setNumEvents(numEvents);
122 template<
class Scalar>
126 if (stop_ < start_) stop_ = start_;
128 setTimeStride(stride_);
132 template<
class Scalar>
136 if (start_ > stop_) start_ = stop_;
138 setTimeStride(stride_);
142 template<
class Scalar>
145 timeScale_ = std::max(std::abs(start_), std::abs(stop_));
146 absTol_ = relTol_*timeScale_;
151 absTol_ = relTol_*timeScale_;
156 template<
class Scalar>
166 if ((stride_ > stop_ - start_) || (stride_ < 2*absTol_)) {
167 stride_ = stop_ - start_;
170 numEvents_ = int((stop_+absTol_ - start_) / stride_) + 1;
174 template<
class Scalar>
177 numEvents_ = numEvents;
178 if (numEvents_ < 0) {
179 if (stride_ < 2 * absTol_) stride_ = 2*absTol_;
180 numEvents_ = int((stop_+absTol_ - start_) / stride_) + 1;
185 stride_ = stop_ - start_;
187 if (numEvents_ < 2) numEvents_ = 2;
188 stride_ = (stop_ - start_)/Scalar(numEvents_-1);
193 if (stride_ <= 2 * absTol_) setTimeStride(2*absTol_);
197 template<
class Scalar>
200 relTol_ = std::abs(relTol);
205 template<
class Scalar>
209 if (time < start_-absTol_)
return false;
212 const Scalar timeOfLast = start_ + (numEvents_-1) * stride_;
213 if (time > timeOfLast+absTol_)
return false;
217 numStrides = (time - start_) / stride_;
219 numStrides = std::min(std::max(0, numStrides),
int(numEvents_-1));
220 const Scalar leftBracket = start_ + numStrides * stride_;
227 const Scalar rightBracket = leftBracket + stride_;
235 template<
class Scalar>
238 return timeOfNextEvent(time) - time;
242 template<
class Scalar>
246 if (time < start_-absTol_)
return start_;
248 const Scalar timeOfLast = start_ + (numEvents_-1) * stride_;
250 if (time > timeOfLast-absTol_)
return std::numeric_limits<Scalar>::max();
254 numStrides = int((time - start_) / stride_) + 1;
255 const Scalar timeEvent = start_ + numStrides*stride_;
259 return timeEvent + stride_;
265 template<
class Scalar>
275 const Scalar timeOfLast = start_ + (numEvents_-1) * stride_;
276 if (time2 < start_-absTol_ || timeOfLast+absTol_ < time1)
return false;
279 return (time1 < start_-absTol_ && start_-absTol_ <= time2);
281 const int strideJustBeforeTime1 = std::min(
int(numEvents_-1),
282 std::max(
int(0),
int((time1 - start_ + absTol_) / stride_ - 0.5)));
284 const int strideJustAfterTime2 = std::max(
int(0), std::min(
int(numEvents_-1),
285 int((time2 - start_ + absTol_) / stride_ + 0.5)));
287 for (
int i = strideJustBeforeTime1; i <= strideJustAfterTime2; i++ ) {
288 const Scalar timeEvent = start_ + i * stride_;
289 if (time1 < timeEvent-absTol_ && timeEvent-absTol_ <= time2)
return true;
296 template<
class Scalar>
300 auto l_out = Teuchos::fancyOStream( out.
getOStream() );
302 l_out->setOutputToRootOnly(0);
304 *l_out <<
"TimeEventRange:" <<
"\n"
305 <<
" name = " << this->getName() <<
"\n"
306 <<
" Type = " << this->getType() <<
"\n"
307 <<
" start_ = " << start_ <<
"\n"
308 <<
" stop_ = " << stop_ <<
"\n"
309 <<
" stride_ = " << stride_ <<
"\n"
310 <<
" numEvents_ = " << numEvents_ <<
"\n"
311 <<
" timeScale_ = " << timeScale_ <<
"\n"
312 <<
" relTol_ = " << relTol_ <<
"\n"
313 <<
" absTol_ = " << absTol_ <<
"\n"
314 <<
" landOnExactly_ = " << landOnExactly_ << std::endl;
318 template<
class Scalar>
323 Teuchos::parameterList(
"Time Event Range");
326 pl->
set(
"Name", this->getName());
327 pl->
set(
"Type", this->getType());
329 pl->
set(
"Start Time", getTimeStart(),
"Start of time range");
330 pl->
set(
"Stop Time", getTimeStop(),
"Stop of time range");
331 pl->
set(
"Stride Time", getTimeStride(),
"Stride of time range");
333 if ( getTimeStride()*Scalar(getNumEvents()-1) - (getTimeStop()-getTimeStart()) < getAbsTol() )
334 pl->
set(
"Number of Events", getNumEvents(),
335 "Number of events in time range. If specified, 'Stride Time' is reset.");
337 pl->
set(
"Relative Tolerance", getRelTol(),
338 "Relative time tolerance for matching time events.");
340 pl->
set(
"Land On Exactly", getLandOnExactly(),
341 "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.");
350 template<
class Scalar>
355 if (pl == Teuchos::null)
return ter;
358 pl->
get<std::string>(
"Type",
"Range") !=
"Range",
360 "Error - Time Event Type != 'Range'. (='"
361 + pl->
get<std::string>(
"Type")+
"')\n");
363 auto validPL = *ter->getValidParameters();
364 bool numEventsFound = pl->
isParameter(
"Number of Events");
365 if (!numEventsFound) validPL.remove(
"Number of Events");
369 ter->setName (pl->
get(
"Name",
"From createTimeEventRange"));
370 ter->setTimeStart (pl->
get(
"Start Time", ter->getTimeStart()));
371 ter->setTimeStop (pl->
get(
"Stop Time", ter->getTimeStop()));
372 ter->setTimeStride (pl->
get(
"Stride Time", ter->getTimeStride()));
374 ter->setNumEvents (pl->
get(
"Number of Events", ter->getNumEvents()));
375 ter->setRelTol (pl->
get(
"Relative Tolerance", ter->getRelTol()));
376 ter->setLandOnExactly (pl->
get(
"Land On Exactly", ter->getLandOnExactly()));
383 #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)
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 setLandOnExactly(bool LOE)
Set if the time event should be landed on exactly.
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.