10 #ifndef Tempus_TimeEventComposite_decl_hpp
11 #define Tempus_TimeEventComposite_decl_hpp
16 #include "Tempus_config.hpp"
19 #include "Tempus_TimeEventRange.hpp"
20 #include "Tempus_TimeEventRangeIndex.hpp"
21 #include "Tempus_TimeEventList.hpp"
22 #include "Tempus_TimeEventListIndex.hpp"
31 template <
class Scalar>
38 this->
setName(
"TimeEventComposite");
43 std::string name =
"TimeEventComposite")
55 virtual std::vector<Teuchos::RCP<TimeEventBase<Scalar> > >
getTimeEvents()
59 std::vector<Teuchos::RCP<TimeEventBase<Scalar> > > te =
timeEvents_;
84 virtual bool isTime(Scalar time)
const
86 std::vector<Teuchos::RCP<TimeEventBase<Scalar> > > timeEvents;
87 return isTime(time, timeEvents);
107 if (e->isTime(time)) timeEvents.push_back(e);
109 return (!timeEvents.empty());
152 std::vector<Teuchos::RCP<TimeEventBase<Scalar> > > timeEvents;
180 typedef std::pair<Scalar, Teuchos::RCP<TimeEventBase<Scalar> > > TEPAIR;
181 std::vector<TEPAIR> timeEventPair;
183 timeEventPair.push_back(std::make_pair(e->timeOfNextEvent(time), e));
187 auto compare = [](TEPAIR a, TEPAIR b) {
return a.first < b.first; };
188 std::stable_sort(timeEventPair.begin(), timeEventPair.end(), compare);
191 Scalar tone = timeEventPair.front().first;
194 for (
auto it = timeEventPair.begin(); it != timeEventPair.end(); ++it) {
195 if ((*it).second->isTime(tone)) timeEvents.push_back((*it).second);
216 std::vector<Teuchos::RCP<TimeEventBase<Scalar> > > timeEvents;
240 Scalar time1, Scalar time2,
243 typedef std::pair<Scalar, Teuchos::RCP<TimeEventBase<Scalar> > > TEPAIR;
244 std::vector<TEPAIR> timeEventPair;
246 if (e->eventInRange(time1, time2))
247 timeEventPair.push_back(std::make_pair(e->timeOfNextEvent(time1), e));
250 auto compare = [](TEPAIR a, TEPAIR b) {
return a.first < b.first; };
251 std::stable_sort(timeEventPair.begin(), timeEventPair.end(), compare);
254 for (
auto& e : timeEventPair) timeEvents.push_back(e.second);
256 return (!timeEvents.empty());
269 std::vector<Teuchos::RCP<TimeEventBase<Scalar> > > timeEvents;
270 return isIndex(index, timeEvents);
289 if (e->isIndex(index)) timeEvents.push_back(e);
291 return (!timeEvents.empty());
330 std::vector<Teuchos::RCP<TimeEventBase<Scalar> > > timeEvents;
352 typedef std::pair<int, Teuchos::RCP<TimeEventBase<Scalar> > > TEPAIR;
353 std::vector<TEPAIR> timeEventPair;
355 timeEventPair.push_back(std::make_pair(e->indexOfNextEvent(index), e));
359 auto compare = [](TEPAIR a, TEPAIR b) {
return a.first < b.first; };
360 std::stable_sort(timeEventPair.begin(), timeEventPair.end(), compare);
363 int ione = timeEventPair.front().first;
366 for (
auto it = timeEventPair.begin(); it != timeEventPair.end(); ++it) {
367 if ((*it).second->isIndex(ione)) timeEvents.push_back((*it).second);
386 std::vector<Teuchos::RCP<TimeEventBase<Scalar> > > timeEvents;
408 int index1,
int index2,
411 typedef std::pair<int, Teuchos::RCP<TimeEventBase<Scalar> > > TEPAIR;
412 std::vector<TEPAIR> timeEventPair;
414 if (e->eventInRangeIndex(index1, index2))
415 timeEventPair.push_back(std::make_pair(e->indexOfNextEvent(index1), e));
418 auto compare = [](TEPAIR a, TEPAIR b) {
return a.first < b.first; };
419 std::stable_sort(timeEventPair.begin(), timeEventPair.end(), compare);
422 for (
auto& e : timeEventPair) timeEvents.push_back(e.second);
424 return (!timeEvents.empty());
433 std::vector<Teuchos::RCP<TimeEventBase<Scalar> > > timeEvents;
450 Scalar largestAbsTol =
timeEvents_.front()->getAbsTol();
453 if (e->getAbsTol() > largestAbsTol) largestAbsTol = e->getAbsTol();
455 for (
auto& e : timeEvents_)
456 if (e->getAbsTol() - largestAbsTol < largestAbsTol * 1.0e-14)
457 timeEvents.push_back(e);
459 return largestAbsTol;
471 std::vector<Teuchos::RCP<TimeEventBase<Scalar> > > timeEvents;
490 if (e->getLandOnExactly()) timeEvents.push_back(e);
492 return (!timeEvents.empty());
507 std::string name = timeEvent->getName();
528 void remove(std::string name)
530 for (std::size_t i = 0; i <
timeEvents_.size(); ++i) {
548 for (std::size_t i = 0; i <
timeEvents_.size(); ++i)
551 return Teuchos::null;
563 std::stringstream tecList;
564 for (std::size_t i = 0; i <
timeEvents_.size(); ++i) {
568 return tecList.str();
575 auto l_out = Teuchos::fancyOStream(out.
getOStream());
577 l_out->setOutputToRootOnly(0);
579 *l_out <<
"TimeEventComposite:"
581 <<
" name = " << this->
getName() <<
"\n"
582 <<
" Type = " << this->
getType() <<
"\n"
583 <<
" Number of TimeEvents = " << this->
getSize() <<
"\n"
586 *l_out <<
"--------------------------------------------" << std::endl;
588 (*e).describe(*l_out, verbLevel);
589 *l_out <<
"--------------------------------------------" << std::endl;
606 Teuchos::parameterList(
"Time Event Composite");
613 for (
auto& s :
timeEvents_) pl->
set(s->getName(), *s->getValidParameters());
639 template <
class Scalar>
647 if (pList == Teuchos::null || pList->
numParams() == 0)
return tec;
650 pList->
get<std::string>(
"Type",
"Composite") !=
"Composite",
652 "Error - Time Event Type != 'Composite'. (='" +
653 pList->
get<std::string>(
"Type") +
"')\n");
655 tec->setName(pList->
get(
"Name",
"From createTimeEventComposite"));
658 std::vector<std::string> teList;
660 std::string str = pList->
get<std::string>(
"Time Events");
661 std::string delimiters(
",");
662 const char* WhiteSpace =
" \t\v\r\n";
664 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
666 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
667 while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
669 std::string token = str.substr(lastPos, pos - lastPos);
671 std::size_t start = token.find_first_not_of(WhiteSpace);
672 std::size_t end = token.find_last_not_of(WhiteSpace);
674 (start == end ? std::string() : token.substr(start, end - start + 1));
676 teList.push_back(token);
677 if (pos == std::string::npos)
break;
679 lastPos = str.find_first_not_of(delimiters, pos);
680 pos = str.find_first_of(delimiters, lastPos);
684 for (
auto teName : teList) {
685 RCP<ParameterList> pl =
688 auto timeEventType = pl->get<std::string>(
"Type",
"Unknown");
689 if (timeEventType ==
"Range") {
690 tec->add(createTimeEventRange<Scalar>(pl));
692 else if (timeEventType ==
"Range Index") {
693 tec->add(createTimeEventRangeIndex<Scalar>(pl));
695 else if (timeEventType ==
"List") {
696 tec->add(createTimeEventList<Scalar>(pl));
698 else if (timeEventType ==
"List Index") {
699 tec->add(createTimeEventListIndex<Scalar>(pl));
702 RCP<Teuchos::FancyOStream> out =
703 Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
704 out->setOutputToRootOnly(0);
706 *out <<
"Warning -- createTimeEventComposite() - Unknown Time Event "
708 <<
"'Type' = '" << timeEventType <<
"'\n"
709 <<
"Should call add() with this "
710 <<
"(app-specific?) Time Event.\n"
715 if (tec->getSize() == 0) {
716 RCP<Teuchos::FancyOStream> out =
717 Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
718 out->setOutputToRootOnly(0);
720 *out <<
"Warning -- createTimeEventComposite() - Did not\n"
721 <<
" find/recognize any TimeEvents to create!\n"
722 <<
" If there is a app-specific TimeEvent,\n"
723 <<
" explicitly add it to this TimeEventComposite.\n"
732 #endif // Tempus_TimeEventComposite_decl_hpp
virtual int indexOfNextEvent(int index, std::vector< Teuchos::RCP< TimeEventBase< Scalar > > > &timeEvents) const
Return the index of the next event following the input index plus the constraining TimeEvent(s)...
virtual std::string getType() const
Return the type of TimeEvent.
virtual Scalar getDefaultTime() const
Return the default time used for TimeEvents.
TimeEventComposite(std::vector< Teuchos::RCP< TimeEventBase< Scalar > > > te, std::string name="TimeEventComposite")
Construct with full argument list of data members.
virtual bool isIndex(int index) const
Test if index is a time event.
virtual void setType(std::string s)
TimeEventComposite()
Default Constructor.
std::string getTimeEventNames() const
Return a string of the names of Time Events (comma separated).
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 bool isIndex(int index, std::vector< Teuchos::RCP< TimeEventBase< Scalar > > > &timeEvents) const
Test if index is a time event plus the constraining TimeEvent(s).
virtual bool getLandOnExactly(std::vector< Teuchos::RCP< TimeEventBase< Scalar > > > &timeEvents) const
Return if the time events need to be landed on exactly plus the constraining TimeEvent(s).
virtual Scalar timeOfNextEvent(Scalar time, std::vector< Teuchos::RCP< TimeEventBase< Scalar > > > &timeEvents) const
Return the time of the next time event and constraining TimeEvent(s).
Ordinal numParams() const
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
virtual bool isTime(Scalar time) const
Test if time is near a TimeEvent (within tolerance).
virtual void setTimeEvents(std::vector< Teuchos::RCP< TimeEventBase< Scalar > > > te)
Set the TimeEvents.
virtual Scalar timeToNextEvent(Scalar time, std::vector< Teuchos::RCP< TimeEventBase< Scalar > > > &timeEvents) const
How much time until the next event plus the constraining TimeEvent(s).
virtual int getDefaultIndex() const
Return the default index used by TimeEvents.
virtual bool isTime(Scalar time, std::vector< Teuchos::RCP< TimeEventBase< Scalar > > > &timeEvents) const
Test if time is near a TimeEvent (within tolerance) plus the constraining TimeEvent(s).
void add(Teuchos::RCP< TimeEventBase< Scalar > > timeEvent)
Add TimeEvent to the TimeEvent vector.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual bool eventInRange(Scalar time1, Scalar time2) const
Test if an event occurs within the time range.
virtual Scalar getAbsTol() const
Return the largest absolute tolerance from all the TimeEvents.
void clear()
Clear the TimeEvent vector.
virtual Scalar timeToNextEvent(Scalar time) const
How much time until the next event.
This composite TimeEvent loops over added TimeEvents.
std::vector< Teuchos::RCP< TimeEventBase< Scalar > > > timeEvents_
std::size_t getSize() const
Return the size of the TimeEvent vector.
virtual bool eventInRangeIndex(int index1, int index2) const
Test if an event occurs within the index range.
virtual bool eventInRangeIndex(int index1, int index2, std::vector< Teuchos::RCP< TimeEventBase< Scalar > > > &timeEvents) const
Test if an event occurs within the index range plus the constraining TimeEvent(s).
virtual int indexToNextEvent(int index) const
How many indices until the next event.
virtual int indexOfNextEvent(int index) const
Return the index of the next event following the input index.
This class defines time events which can be used to "trigger" an action.
virtual std::string getName() const
Return the name of the TimeEvent.
Teuchos::RCP< TimeEventBase< Scalar > > find(std::string name)
Find TimeEvent based on name.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Describe member data.
RCP< std::basic_ostream< char_type, traits_type > > getOStream()
virtual std::vector< Teuchos::RCP< TimeEventBase< Scalar > > > getTimeEvents() const
Get a copy of the current set of TimeEvents.
virtual Scalar timeOfNextEvent(Scalar time) const
Return the time of the next event following the input time.
virtual ~TimeEventComposite()
Destructor.
virtual int indexToNextEvent(int index, std::vector< Teuchos::RCP< TimeEventBase< Scalar > > > &timeEvents) const
How many indices until the next event.
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
ParameterList & setName(const std::string &name)
virtual bool eventInRange(Scalar time1, Scalar time2, std::vector< Teuchos::RCP< TimeEventBase< Scalar > > > &timeEvents) const
Test if an event occurs within the time range plus the constraining TimeEvent(s). ...
Teuchos::RCP< TimeEventComposite< Scalar > > createTimeEventComposite(Teuchos::RCP< Teuchos::ParameterList > const &pList)
TimeEventComposite nonmember constructor via ParameterList.
virtual Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Return a valid ParameterList with current settings.
virtual bool getLandOnExactly() const
Return if the time events need to be landed on exactly.
virtual Scalar getAbsTol(std::vector< Teuchos::RCP< TimeEventBase< Scalar > > > &timeEvents) const
Return the largest absolute tolerance from all the TimeEvents plus the constraining TimeEvent(s)...