9 #ifndef Tempus_TimeStepControl_impl_hpp
10 #define Tempus_TimeStepControl_impl_hpp
18 #include "Tempus_TimeEventRange.hpp"
19 #include "Tempus_TimeEventRangeIndex.hpp"
20 #include "Tempus_TimeEventList.hpp"
21 #include "Tempus_TimeEventListIndex.hpp"
25 template <
class Scalar>
27 : isInitialized_(false),
31 initTimeStep_(1.0e+99),
32 maxTimeStep_(1.0e+99),
35 maxAbsError_(1.0e-08),
36 maxRelError_(1.0e-08),
38 maxConsecFailures_(5),
40 printDtChanges_(true),
42 dtAfterTimeEvent_(0.0)
49 template <
class Scalar>
51 Scalar initTime, Scalar finalTime, Scalar minTimeStep, Scalar initTimeStep,
52 Scalar maxTimeStep,
int initIndex,
int finalIndex, Scalar maxAbsError,
53 Scalar maxRelError,
int maxFailures,
int maxConsecFailures,
54 int numTimeSteps,
bool printDtChanges,
bool outputExactly,
55 std::vector<int> outputIndices, std::vector<Scalar> outputTimes,
56 int outputIndexInterval, Scalar outputTimeInterval,
59 : isInitialized_(false),
61 finalTime_(finalTime),
62 minTimeStep_(minTimeStep),
63 initTimeStep_(initTimeStep),
64 maxTimeStep_(maxTimeStep),
65 initIndex_(initIndex),
66 finalIndex_(finalIndex),
67 maxAbsError_(maxAbsError),
68 maxRelError_(maxRelError),
69 maxFailures_(maxFailures),
70 maxConsecFailures_(maxConsecFailures),
71 printDtChanges_(printDtChanges),
73 dtAfterTimeEvent_(0.0)
81 tec->setName(
"Time Step Control Events");
82 auto tes = timeEvent->getTimeEvents();
83 for (
auto& e : tes) tec->add(e);
88 "Output Time Interval", outputExactly));
92 if (!outputTimes.empty())
98 initIndex, finalIndex, outputIndexInterval,
"Output Index Interval")));
101 if (!outputTimes.empty())
110 template <
class Scalar>
114 (getInitTime() > getFinalTime()), std::logic_error,
115 "Error - Inconsistent time range.\n"
117 << getInitTime() <<
") > (timeMax = " << getFinalTime() <<
")\n");
122 "Error - Negative minimum time step. dtMin = " << getMinTimeStep() <<
")\n");
126 "Error - Negative maximum time step. dtMax = " << getMaxTimeStep() <<
")\n");
128 (getMinTimeStep() > getMaxTimeStep()), std::logic_error,
129 "Error - Inconsistent time step range.\n"
131 << getMinTimeStep() <<
") > (dtMax = " << getMaxTimeStep() <<
")\n");
135 "Error - Negative initial time step. dtInit = " << getInitTimeStep() <<
")\n");
137 getInitTimeStep() > getMaxTimeStep()),
139 "Error - Initial time step is out of range.\n"
140 <<
" [dtMin, dtMax] = [" << getMinTimeStep()
141 <<
", " << getMaxTimeStep() <<
"]\n"
142 <<
" dtInit = " << getInitTimeStep()
146 (getInitIndex() > getFinalIndex()), std::logic_error,
147 "Error - Inconsistent time index range.\n"
149 << getInitIndex() <<
") > (iStepMax = " << getFinalIndex() <<
")\n");
154 "Error - Negative maximum time step. errorMaxAbs = " << getMaxAbsError() <<
")\n");
158 "Error - Negative maximum time step. errorMaxRel = " << getMaxRelError() <<
")\n");
161 std::logic_error,
"Error - Strategy is unset!\n");
163 stepControlStrategy_->initialize();
166 (getStepType() !=
"Constant" && getStepType() !=
"Variable"),
168 "Error - 'Step Type' does not equal one of these:\n"
169 <<
" 'Constant' - Integrator will take constant time step sizes.\n"
170 <<
" 'Variable' - Integrator will allow changes to the time step "
172 <<
" stepType = " << getStepType() <<
"\n");
174 isInitialized_ =
true;
177 template <
class Scalar>
180 std::string reason)
const
182 if (!getPrintDtChanges())
return;
188 std::stringstream message;
189 message << std::scientific << std::setw(6) << std::setprecision(3) << istep
190 <<
" * (dt = " << std::setw(9) << std::setprecision(3) << dt_old
191 <<
", new = " << std::setw(9) << std::setprecision(3) << dt_new
192 <<
") " << reason << std::endl;
193 *out << message.str();
196 template <
class Scalar>
199 if (!isInitialized_) {
202 !isInitialized_, std::logic_error,
203 "Error - " << this->description() <<
" is not initialized!");
207 template <
class Scalar>
216 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::TimeStepControl::setNextTimeStep()");
218 RCP<SolutionState<Scalar>> workingState =
219 solutionHistory->getWorkingState();
220 const Scalar lastTime = solutionHistory->getCurrentState()->getTime();
221 const int iStep = workingState->getIndex();
222 Scalar dt = workingState->getTimeStep();
223 Scalar time = workingState->getTime();
225 RCP<StepperState<Scalar>> stepperState = workingState->getStepperState();
228 if (getStepType() ==
"Variable") {
229 if (teAdjustedDt_ ==
true) {
230 printDtChanges(iStep, dt, dtAfterTimeEvent_,
231 "Reset dt after time event.");
232 dt = dtAfterTimeEvent_;
233 time = lastTime + dt;
234 teAdjustedDt_ =
false;
235 dtAfterTimeEvent_ = 0.0;
239 printDtChanges(iStep, dt, getInitTimeStep(),
"Reset dt to initial dt.");
240 dt = getInitTimeStep();
241 time = lastTime + dt;
244 if (dt < getMinTimeStep()) {
245 printDtChanges(iStep, dt, getMinTimeStep(),
"Reset dt to minimum dt.");
246 dt = getMinTimeStep();
247 time = lastTime + dt;
252 workingState->setTimeStep(dt);
253 workingState->setTime(time);
256 stepControlStrategy_->setNextTimeStep(*
this, solutionHistory,
260 dt = workingState->getTimeStep();
261 time = workingState->getTime();
263 if (getStepType() ==
"Variable") {
264 if (dt < getMinTimeStep()) {
265 printDtChanges(iStep, dt, getMinTimeStep(),
266 "dt is too small. Resetting to minimum dt.");
267 dt = getMinTimeStep();
268 time = lastTime + dt;
270 if (dt > getMaxTimeStep()) {
271 printDtChanges(iStep, dt, getMaxTimeStep(),
272 "dt is too large. Resetting to maximum dt.");
273 dt = getMaxTimeStep();
274 time = lastTime + dt;
279 bool outputDueToIndex =
false;
280 std::vector<Teuchos::RCP<TimeEventBase<Scalar>>> constrainingTEs;
281 if (timeEvent_->isIndex(iStep, constrainingTEs)) {
282 for (
auto& e : constrainingTEs) {
283 if (e->getName() ==
"Output Index Interval" ||
284 e->getName() ==
"Output Index List") {
285 outputDueToIndex =
true;
291 Scalar endTime = lastTime + dt;
294 if (getStepType() ==
"Variable") endTime = lastTime + dt + getMinTimeStep();
297 timeEvent_->eventInRange(lastTime, endTime, constrainingTEs);
299 bool outputDueToTime =
false;
300 Scalar tone = endTime;
301 bool landOnExactly =
false;
303 for (
auto& e : constrainingTEs) {
304 if (e->getName() ==
"Output Time Interval" ||
305 e->getName() ==
"Output Time List") {
306 outputDueToTime =
true;
309 if (e->getLandOnExactly() ==
true) {
310 landOnExactly =
true;
311 tone = e->timeOfNextEvent(lastTime);
317 Scalar reltol = 1.0e-6;
318 if (teThisStep && getStepType() ==
"Variable") {
319 if (landOnExactly ==
true) {
324 printDtChanges(iStep, dt, tone - lastTime,
325 "Adjusting dt to hit the next TimeEvent.");
326 teAdjustedDt_ =
true;
327 dtAfterTimeEvent_ = dt;
328 dt = tone - lastTime;
329 time = lastTime + dt;
331 else if (std::fabs(time - tone) < reltol * std::fabs(time)) {
335 iStep, dt, tone - lastTime,
336 "Adjusting dt for numerical roundoff to hit the next TimeEvent.");
337 teAdjustedDt_ =
true;
338 dtAfterTimeEvent_ = dt;
339 dt = tone - lastTime;
340 time = lastTime + dt;
342 else if (std::fabs(time + getMinTimeStep() - tone) <
343 reltol * std::fabs(tone)) {
348 iStep, dt, (tone - lastTime) / 2.0,
349 "The next TimeEvent is within the minimum dt of the next time. "
350 "Adjusting dt to take two steps.");
351 dt = (tone - lastTime) / 2.0;
352 time = lastTime + dt;
354 outputDueToTime =
false;
361 if (getStepType() ==
"Variable") {
362 if ((lastTime + dt > getFinalTime()) ||
363 (std::fabs((lastTime + dt - getFinalTime())) <
364 reltol * std::fabs(lastTime + dt))) {
365 printDtChanges(iStep, dt, getFinalTime() - lastTime,
366 "Adjusting dt to hit final time.");
367 dt = getFinalTime() - lastTime;
368 time = lastTime + dt;
374 dt <= Scalar(0.0), std::out_of_range,
375 "Error - Time step is not positive. dt = " << dt <<
"\n");
379 (lastTime + dt < getInitTime()), std::out_of_range,
380 "Error - Time step does not move time INTO time range.\n"
381 <<
" [timeMin, timeMax] = ["
382 << getInitTime() <<
", " << getFinalTime()
384 << lastTime <<
" + " << dt <<
" = " << lastTime + dt <<
"\n");
386 if (getStepType() ==
"Variable") {
388 (lastTime + dt > getFinalTime()), std::out_of_range,
389 "Error - Time step move time OUT OF time range.\n"
390 <<
" [timeMin, timeMax] = ["
391 << getInitTime() <<
", " << getFinalTime()
393 << lastTime <<
" + " << dt <<
" = " << lastTime + dt <<
"\n");
396 workingState->setTimeStep(dt);
397 workingState->setTime(time);
398 workingState->setOutput(outputDueToIndex || outputDueToTime);
404 template <
class Scalar>
408 const int relTol = 14;
409 const int i = (getInitTime() == 0)
411 : 1 + (
int)std::floor(std::log10(std::fabs(getInitTime())));
412 const Scalar absTolInit = std::pow(10, i - relTol);
414 (getFinalTime() == 0)
416 : 1 + (
int)std::floor(std::log10(std::fabs(getFinalTime())));
417 const Scalar absTolFinal = std::pow(10, j - relTol);
419 const bool test1 = getInitTime() - absTolInit <= time;
420 const bool test2 = time < getFinalTime() - absTolFinal;
422 return (test1 && test2);
426 template <
class Scalar>
429 bool iir = (getInitIndex() <= iStep && iStep < getFinalIndex());
433 template <
class Scalar>
438 "Error - getStepType() - Strategy is unset!\n");
439 return stepControlStrategy_->getStepType();
442 template <
class Scalar>
445 auto event = timeEvent_->find(
"Output Time Interval");
446 if (event != Teuchos::null)
return event->getLandOnExactly();
448 event = timeEvent_->find(
"Output Time List");
449 if (event != Teuchos::null)
return event->getLandOnExactly();
454 template <
class Scalar>
457 std::vector<int> indices;
458 if (timeEvent_->find(
"Output Index List") == Teuchos::null)
return indices;
460 timeEvent_->find(
"Output Index List"));
464 template <
class Scalar>
467 std::vector<Scalar> times;
468 if (timeEvent_->find(
"Output Time List") == Teuchos::null)
return times;
470 timeEvent_->find(
"Output Time List"));
474 template <
class Scalar>
477 if (timeEvent_->find(
"Output Index Interval") == Teuchos::null)
480 timeEvent_->find(
"Output Index Interval"));
484 template <
class Scalar>
487 if (timeEvent_->find(
"Output Time Interval") == Teuchos::null)
return 1.0e+99;
489 timeEvent_->find(
"Output Time Interval"));
493 template <
class Scalar>
497 "Error - Can only use setNumTimeSteps() when "
498 "'Step Type' == 'Constant'.\n");
500 numTimeSteps_ = numTimeSteps;
501 if (numTimeSteps_ >= 0) {
502 setFinalIndex(getInitIndex() + numTimeSteps_);
504 if (numTimeSteps_ == 0)
505 initTimeStep = Scalar(0.0);
507 initTimeStep = (getFinalTime() - getInitTime()) / numTimeSteps_;
508 setInitTimeStep(initTimeStep);
509 setMinTimeStep(initTimeStep);
510 setMaxTimeStep(initTimeStep);
515 *out <<
"Warning - setNumTimeSteps() Setting 'Number of Time Steps' = "
516 << getNumTimeSteps() <<
" Set the following parameters: \n"
517 <<
" 'Final Time Index' = " << getFinalIndex() <<
"\n"
518 <<
" 'Initial Time Step' = " << getInitTimeStep() <<
"\n"
519 <<
" 'Step Type' = " << getStepType() << std::endl;
521 isInitialized_ =
false;
525 template <
class Scalar>
528 auto event = timeEvent_->find(
"Output Time Interval");
529 if (event != Teuchos::null) {
533 event = timeEvent_->find(
"Output Time List");
534 if (event != Teuchos::null) {
540 template <
class Scalar>
544 outputIndices,
"Output Index List")));
545 isInitialized_ =
false;
548 template <
class Scalar>
552 outputTimes,
"Output Time List", getOutputExactly())));
553 isInitialized_ =
false;
556 template <
class Scalar>
560 getInitIndex(), getFinalIndex(), i,
"Output Index Interval")));
561 isInitialized_ =
false;
564 template <
class Scalar>
569 "Output Time Interval", getOutputExactly())));
570 isInitialized_ =
false;
573 template <
class Scalar>
579 if (timeEvent != Teuchos::null) {
580 timeEvent_ = timeEvent;
584 tec->setName(
"Time Step Control Events");
586 getInitIndex(), getFinalIndex(), 1000000,
"Output Index Interval")));
588 getInitTime(), getFinalTime(), 1.0e+99,
"Output Time Interval",
true)));
591 isInitialized_ =
false;
594 template <
class Scalar>
600 if (tscs != Teuchos::null) {
601 stepControlStrategy_ = tscs;
604 stepControlStrategy_ =
607 isInitialized_ =
false;
610 template <
class Scalar>
613 std::string name =
"Tempus::TimeStepControl";
617 template <
class Scalar>
621 auto l_out = Teuchos::fancyOStream(out.
getOStream());
623 l_out->setOutputToRootOnly(0);
625 *l_out <<
"\n--- " << this->description() <<
" ---" << std::endl;
628 std::vector<int> idx = getOutputIndices();
629 std::ostringstream listIdx;
631 for (std::size_t i = 0; i < idx.size() - 1; ++i)
632 listIdx << idx[i] <<
", ";
633 listIdx << idx[idx.size() - 1];
636 std::vector<Scalar> times = getOutputTimes();
637 std::ostringstream listTimes;
638 if (!times.empty()) {
639 for (std::size_t i = 0; i < times.size() - 1; ++i)
640 listTimes << times[i] <<
", ";
641 listTimes << times[times.size() - 1];
644 *l_out <<
" stepType = " << getStepType() << std::endl
645 <<
" initTime = " << getInitTime() << std::endl
646 <<
" finalTime = " << getFinalTime() << std::endl
647 <<
" minTimeStep = " << getMinTimeStep() << std::endl
648 <<
" initTimeStep = " << getInitTimeStep() << std::endl
649 <<
" maxTimeStep = " << getMaxTimeStep() << std::endl
650 <<
" initIndex = " << getInitIndex() << std::endl
651 <<
" finalIndex = " << getFinalIndex() << std::endl
652 <<
" maxAbsError = " << getMaxAbsError() << std::endl
653 <<
" maxRelError = " << getMaxRelError() << std::endl
654 <<
" maxFailures = " << getMaxFailures() << std::endl
655 <<
" maxConsecFailures = " << getMaxConsecFailures() << std::endl
656 <<
" numTimeSteps = " << getNumTimeSteps() << std::endl
657 <<
" printDtChanges = " << getPrintDtChanges() << std::endl
658 <<
" outputExactly = " << getOutputExactly() << std::endl
659 <<
" outputIndices = " << listIdx.str() << std::endl
660 <<
" outputTimes = " << listTimes.str() << std::endl
661 <<
" outputIndexInterval= " << getOutputIndexInterval() << std::endl
662 <<
" outputTimeInterval = " << getOutputTimeInterval() << std::endl
663 <<
" outputAdjustedDt = " << teAdjustedDt_ << std::endl
664 <<
" dtAfterOutput = " << dtAfterTimeEvent_ << std::endl;
665 stepControlStrategy_->describe(*l_out, verbLevel);
666 timeEvent_->describe(*l_out, verbLevel);
668 *l_out << std::string(this->description().length() + 8,
'-') << std::endl;
671 template <
class Scalar>
676 Teuchos::parameterList(
"Time Step Control");
678 pl->
set<
double>(
"Initial Time", getInitTime(),
"Initial time");
679 pl->
set<
double>(
"Final Time", getFinalTime(),
"Final time");
680 pl->
set<
double>(
"Minimum Time Step", getMinTimeStep(),
681 "Minimum time step size");
682 pl->
set<
double>(
"Initial Time Step", getInitTimeStep(),
683 "Initial time step size");
684 pl->
set<
double>(
"Maximum Time Step", getMaxTimeStep(),
685 "Maximum time step size");
686 pl->
set<
int>(
"Initial Time Index", getInitIndex(),
"Initial time index");
687 pl->
set<
int>(
"Final Time Index", getFinalIndex(),
"Final time index");
689 "Number of Time Steps", getNumTimeSteps(),
690 "The number of constant time steps. The actual step size gets computed\n"
691 "on the fly given the size of the time domain. Overides and resets\n"
692 " 'Final Time Index' = 'Initial Time Index' + 'Number of Time "
694 " 'Initial Time Step' = "
695 "('Final Time' - 'Initial Time')/'Number of Time Steps'\n");
696 pl->
set<
double>(
"Maximum Absolute Error", getMaxAbsError(),
697 "Maximum absolute error");
698 pl->
set<
double>(
"Maximum Relative Error", getMaxRelError(),
699 "Maximum relative error");
701 pl->
set<
bool>(
"Print Time Step Changes", getPrintDtChanges(),
702 "Print timestep size when it changes");
704 auto event = timeEvent_->find(
"Output Index Interval");
705 if (event != Teuchos::null) {
707 pl->
set<
int>(
"Output Index Interval", teri->getIndexStride(),
708 "Output Index Interval");
711 event = timeEvent_->find(
"Output Time Interval");
712 if (event != Teuchos::null) {
714 pl->
set<
double>(
"Output Time Interval", ter->getTimeStride(),
715 "Output time interval");
719 "Output Exactly On Output Times", getOutputExactly(),
720 "This determines if the timestep size will be adjusted to exactly land\n"
721 "on the output times for 'Variable' timestepping (default=true).\n"
722 "When set to 'false' or for 'Constant' time stepping, the timestep\n"
723 "following the output time will be flagged for output.\n");
726 event = timeEvent_->find(
"Output Index List");
727 std::ostringstream list;
728 if (event != Teuchos::null) {
732 for (std::size_t i = 0; i < idx.size() - 1; ++i) list << idx[i] <<
", ";
733 list << idx[idx.size() - 1];
736 pl->
set<std::string>(
"Output Index List", list.str(),
737 "Comma deliminated list of output indices");
741 event = timeEvent_->find(
"Output Time List");
742 std::ostringstream list;
743 if (event != Teuchos::null) {
746 if (!times.empty()) {
747 for (std::size_t i = 0; i < times.size() - 1; ++i)
748 list << times[i] <<
", ";
749 list << times[times.size() - 1];
752 pl->
set<std::string>(
"Output Time List", list.str(),
753 "Comma deliminated list of output times");
759 tecTmp->setTimeEvents(timeEvent_->getTimeEvents());
760 tecTmp->remove(
"Output Index Interval");
761 tecTmp->remove(
"Output Time Interval");
762 tecTmp->remove(
"Output Index List");
763 tecTmp->remove(
"Output Time List");
764 if (tecTmp->getSize() > 0)
765 pl->
set(
"Time Step Control Events", *tecTmp->getValidParameters());
768 pl->
set<
int>(
"Maximum Number of Stepper Failures", getMaxFailures(),
769 "Maximum number of Stepper failures");
770 pl->
set<
int>(
"Maximum Number of Consecutive Stepper Failures",
771 getMaxConsecFailures(),
772 "Maximum number of consecutive Stepper failures");
774 pl->
set(
"Time Step Control Strategy",
775 *stepControlStrategy_->getValidParameters());
782 template <
class Scalar>
791 if (pList == Teuchos::null || pList->
numParams() == 0)
return tsc;
794 Teuchos::rcp_const_cast<ParameterList>(tsc->getValidParameters());
796 if (pList->
isSublist(
"Time Step Control Events")) {
797 RCP<ParameterList> tsctePL =
798 Teuchos::sublist(pList,
"Time Step Control Events",
true);
799 tscValidPL->set(
"Time Step Control Events", *tsctePL);
804 tsc->setInitTime(pList->
get<
double>(
"Initial Time"));
805 tsc->setFinalTime(pList->
get<
double>(
"Final Time"));
806 tsc->setMinTimeStep(pList->
get<
double>(
"Minimum Time Step"));
807 tsc->setInitTimeStep(pList->
get<
double>(
"Initial Time Step"));
808 tsc->setMaxTimeStep(pList->
get<
double>(
"Maximum Time Step"));
809 tsc->setInitIndex(pList->
get<
int>(
"Initial Time Index"));
810 tsc->setFinalIndex(pList->
get<
int>(
"Final Time Index"));
811 tsc->setMaxAbsError(pList->
get<
double>(
"Maximum Absolute Error"));
812 tsc->setMaxRelError(pList->
get<
double>(
"Maximum Relative Error"));
813 tsc->setMaxFailures(pList->
get<
int>(
"Maximum Number of Stepper Failures"));
814 tsc->setMaxConsecFailures(
815 pList->
get<
int>(
"Maximum Number of Consecutive Stepper Failures"));
816 tsc->setPrintDtChanges(pList->
get<
bool>(
"Print Time Step Changes"));
817 tsc->setNumTimeSteps(pList->
get<
int>(
"Number of Time Steps"));
820 tec->setName(
"Time Step Control Events");
823 std::vector<int> outputIndices;
824 outputIndices.clear();
825 std::string str = pList->
get<std::string>(
"Output Index List");
826 std::string delimiters(
",");
827 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
828 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
829 while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
830 std::string token = str.substr(lastPos, pos - lastPos);
831 outputIndices.push_back(
int(std::stoi(token)));
832 if (pos == std::string::npos)
break;
834 lastPos = str.find_first_not_of(delimiters, pos);
835 pos = str.find_first_of(delimiters, lastPos);
838 if (!outputIndices.empty()) {
840 std::sort(outputIndices.begin(), outputIndices.end());
842 std::unique(outputIndices.begin(), outputIndices.end()),
843 outputIndices.end());
846 outputIndices,
"Output Index List")));
852 tsc->getInitIndex(), tsc->getFinalIndex(),
853 pList->
get<
int>(
"Output Index Interval"),
"Output Index Interval")));
855 auto outputExactly = pList->
get<
bool>(
"Output Exactly On Output Times",
true);
858 std::vector<Scalar> outputTimes;
860 std::string str = pList->
get<std::string>(
"Output Time List");
861 std::string delimiters(
",");
863 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
865 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
866 while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
868 std::string token = str.substr(lastPos, pos - lastPos);
869 outputTimes.push_back(Scalar(std::stod(token)));
870 if (pos == std::string::npos)
break;
872 lastPos = str.find_first_not_of(delimiters, pos);
873 pos = str.find_first_of(delimiters, lastPos);
876 if (!outputTimes.empty()) {
878 std::sort(outputTimes.begin(), outputTimes.end());
879 outputTimes.erase(std::unique(outputTimes.begin(), outputTimes.end()),
883 outputTimes,
"Output Time List", outputExactly)));
890 pList->
get<
double>(
"Output Time Interval"),
891 "Output Time Interval", outputExactly)));
893 if (pList->
isSublist(
"Time Step Control Events")) {
894 RCP<ParameterList> tsctePL =
895 Teuchos::sublist(pList,
"Time Step Control Events",
true);
897 auto timeEventType = tsctePL->get<std::string>(
"Type",
"Unknown");
898 if (timeEventType ==
"Range") {
899 tec->add(createTimeEventRange<Scalar>(tsctePL));
901 else if (timeEventType ==
"Range Index") {
902 tec->add(createTimeEventRangeIndex<Scalar>(tsctePL));
904 else if (timeEventType ==
"List") {
905 tec->add(createTimeEventList<Scalar>(tsctePL));
907 else if (timeEventType ==
"List Index") {
908 tec->add(createTimeEventListIndex<Scalar>(tsctePL));
910 else if (timeEventType ==
"Composite") {
911 auto tecTmp = createTimeEventComposite<Scalar>(tsctePL);
912 auto timeEvents = tecTmp->getTimeEvents();
913 for (
auto& e : timeEvents) tec->add(e);
916 RCP<Teuchos::FancyOStream> out =
917 Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
918 out->setOutputToRootOnly(0);
920 *out <<
"Warning -- Unknown Time Event Type!\n"
921 <<
"'Type' = '" << timeEventType <<
"'\n"
922 <<
"Should call add() with this "
923 <<
"(app-specific?) Time Event.\n"
928 tsc->setTimeEvents(tec);
930 if (!pList->
isParameter(
"Time Step Control Strategy")) {
931 tsc->setTimeStepControlStrategy();
935 RCP<ParameterList> tscsPL =
936 Teuchos::sublist(pList,
"Time Step Control Strategy",
true);
938 auto strategyType = tscsPL->get<std::string>(
"Strategy Type");
939 if (strategyType ==
"Constant") {
940 tsc->setTimeStepControlStrategy(
941 createTimeStepControlStrategyConstant<Scalar>(tscsPL));
943 else if (strategyType ==
"Basic VS") {
944 tsc->setTimeStepControlStrategy(
945 createTimeStepControlStrategyBasicVS<Scalar>(tscsPL));
947 else if (strategyType ==
"Integral Controller") {
948 tsc->setTimeStepControlStrategy(
949 createTimeStepControlStrategyIntegralController<Scalar>(tscsPL));
951 else if (strategyType ==
"Composite") {
952 tsc->setTimeStepControlStrategy(
953 createTimeStepControlStrategyComposite<Scalar>(tscsPL));
956 RCP<Teuchos::FancyOStream> out =
957 Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
958 out->setOutputToRootOnly(0);
960 *out <<
"Warning -- Did not find a Tempus strategy to create!\n"
961 <<
"'Strategy Type' = '" << strategyType <<
"'\n"
962 <<
"Should call setTimeStepControlStrategy() with this\n"
963 <<
"(app-specific?) strategy, and initialize().\n"
968 if (runInitialize) tsc->initialize();
973 #endif // Tempus_TimeStepControl_impl_hpp
TimeEventRangeIndex specifies a start, stop and stride index.
virtual void checkInitialized()
virtual void setTimeEvents(Teuchos::RCP< TimeEventComposite< Scalar >> teb=Teuchos::null)
Teuchos::RCP< TimeStepControl< Scalar > > createTimeStepControl(Teuchos::RCP< Teuchos::ParameterList > const &pList, bool runInitialize=true)
Nonmember constructor from ParameterList.
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)
virtual void setNumTimeSteps(int numTimeSteps)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
TimeEventListIndex specifies a list of index events.
virtual void setLandOnExactly(bool LOE)
Set if the time event should be landed on exactly.
std::string description() const
Ordinal numParams() const
virtual void printDtChanges(int istep, Scalar dt_old, Scalar dt_new, std::string reason) const
virtual void setOutputTimes(std::vector< Scalar > outputTimes)
virtual void setOutputIndexInterval(int i)
virtual void setTimeStepControlStrategy(Teuchos::RCP< TimeStepControlStrategy< Scalar >> tscs=Teuchos::null)
bool isParameter(const std::string &name) const
virtual std::string getStepType() const
virtual int getIndexStride() const
Return the stride of the index range.
TimeEventRange specifies a start, stop and stride time.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Status
Status for the Integrator, the Stepper and the SolutionState.
bool isSublist(const std::string &name) const
virtual Scalar getTimeStride() const
Return the stride of the time range.
This composite TimeEvent loops over added TimeEvents.
virtual bool indexInRange(const int iStep) const
Check if time step index is within minimum and maximum index.
TimeStepControl manages the time step size. There several mechanisms that effect the time step size a...
TimeStepControl()
Default Constructor.
void validateParametersAndSetDefaults(ParameterList const &validParamList, int const depth=1000)
virtual std::vector< int > getIndexList() const
Return a vector of event indices.
virtual void setOutputTimeInterval(Scalar t)
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
virtual void setOutputExactly(bool b)
virtual void setNextTimeStep(const Teuchos::RCP< SolutionHistory< Scalar >> &solutionHistory, Status &integratorStatus)
Determine the time step size.
StepControlStrategy class for TimeStepControl.
RCP< std::basic_ostream< char_type, traits_type > > getOStream()
virtual bool timeInRange(const Scalar time) const
Check if time is within minimum and maximum time.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual int getOutputIndexInterval() const
virtual Scalar getOutputTimeInterval() const
virtual bool getOutputExactly() const
Return if the output needs to exactly happen on output time.
virtual void setLandOnExactly(bool LOE)
Set if the time event should be landed on exactly.
TimeEventList specifies a list of time events.
TimeStepControlStrategy class for TimeStepControl.
virtual void initialize() const
virtual void setOutputIndices(std::vector< int > v)
virtual std::vector< Scalar > getOutputTimes() const
virtual Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Return ParameterList with current values.
virtual std::vector< int > getOutputIndices() const
virtual std::vector< Scalar > getTimeList() const
Return the list of time events.