10 #ifndef Tempus_TimeStepControl_impl_hpp
11 #define Tempus_TimeStepControl_impl_hpp
19 #include "Tempus_TimeEventRange.hpp"
20 #include "Tempus_TimeEventRangeIndex.hpp"
21 #include "Tempus_TimeEventList.hpp"
22 #include "Tempus_TimeEventListIndex.hpp"
26 template <
class Scalar>
28 : isInitialized_(false),
32 initTimeStep_(1.0e+99),
33 maxTimeStep_(1.0e+99),
36 maxAbsError_(1.0e-08),
37 maxRelError_(1.0e-08),
39 maxConsecFailures_(5),
41 printDtChanges_(true),
43 dtAfterTimeEvent_(0.0)
50 template <
class Scalar>
52 Scalar initTime, Scalar finalTime, Scalar minTimeStep, Scalar initTimeStep,
53 Scalar maxTimeStep,
int initIndex,
int finalIndex, Scalar maxAbsError,
54 Scalar maxRelError,
int maxFailures,
int maxConsecFailures,
55 int numTimeSteps,
bool printDtChanges,
bool outputExactly,
56 std::vector<int> outputIndices, std::vector<Scalar> outputTimes,
57 int outputIndexInterval, Scalar outputTimeInterval,
60 : isInitialized_(false),
62 finalTime_(finalTime),
63 minTimeStep_(minTimeStep),
64 initTimeStep_(initTimeStep),
65 maxTimeStep_(maxTimeStep),
66 initIndex_(initIndex),
67 finalIndex_(finalIndex),
68 maxAbsError_(maxAbsError),
69 maxRelError_(maxRelError),
70 maxFailures_(maxFailures),
71 maxConsecFailures_(maxConsecFailures),
72 printDtChanges_(printDtChanges),
74 dtAfterTimeEvent_(0.0)
82 tec->setName(
"Time Step Control Events");
83 auto tes = timeEvent->getTimeEvents();
84 for (
auto& e : tes) tec->add(e);
89 "Output Time Interval", outputExactly));
93 if (!outputTimes.empty())
99 initIndex, finalIndex, outputIndexInterval,
"Output Index Interval")));
102 if (!outputTimes.empty())
111 template <
class Scalar>
115 (getInitTime() > getFinalTime()), std::logic_error,
116 "Error - Inconsistent time range.\n"
118 << getInitTime() <<
") > (timeMax = " << getFinalTime() <<
")\n");
123 "Error - Negative minimum time step. dtMin = " << getMinTimeStep() <<
")\n");
127 "Error - Negative maximum time step. dtMax = " << getMaxTimeStep() <<
")\n");
129 (getMinTimeStep() > getMaxTimeStep()), std::logic_error,
130 "Error - Inconsistent time step range.\n"
132 << getMinTimeStep() <<
") > (dtMax = " << getMaxTimeStep() <<
")\n");
136 "Error - Negative initial time step. dtInit = " << getInitTimeStep() <<
")\n");
138 getInitTimeStep() > getMaxTimeStep()),
140 "Error - Initial time step is out of range.\n"
141 <<
" [dtMin, dtMax] = [" << getMinTimeStep()
142 <<
", " << getMaxTimeStep() <<
"]\n"
143 <<
" dtInit = " << getInitTimeStep()
147 (getInitIndex() > getFinalIndex()), std::logic_error,
148 "Error - Inconsistent time index range.\n"
150 << getInitIndex() <<
") > (iStepMax = " << getFinalIndex() <<
")\n");
155 "Error - Negative maximum time step. errorMaxAbs = " << getMaxAbsError() <<
")\n");
159 "Error - Negative maximum time step. errorMaxRel = " << getMaxRelError() <<
")\n");
162 std::logic_error,
"Error - Strategy is unset!\n");
164 stepControlStrategy_->initialize();
167 (getStepType() !=
"Constant" && getStepType() !=
"Variable"),
169 "Error - 'Step Type' does not equal one of these:\n"
170 <<
" 'Constant' - Integrator will take constant time step sizes.\n"
171 <<
" 'Variable' - Integrator will allow changes to the time step "
173 <<
" stepType = " << getStepType() <<
"\n");
175 isInitialized_ =
true;
178 template <
class Scalar>
181 std::string reason)
const
183 if (!getPrintDtChanges())
return;
189 std::stringstream message;
190 message << std::scientific << std::setw(6) << std::setprecision(3) << istep
191 <<
" * (dt = " << std::setw(9) << std::setprecision(3) << dt_old
192 <<
", new = " << std::setw(9) << std::setprecision(3) << dt_new
193 <<
") " << reason << std::endl;
194 *out << message.str();
197 template <
class Scalar>
200 if (!isInitialized_) {
203 !isInitialized_, std::logic_error,
204 "Error - " << this->description() <<
" is not initialized!");
208 template <
class Scalar>
217 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::TimeStepControl::setNextTimeStep()");
219 RCP<SolutionState<Scalar>> workingState =
220 solutionHistory->getWorkingState();
221 const Scalar lastTime = solutionHistory->getCurrentState()->getTime();
222 const int iStep = workingState->getIndex();
223 Scalar dt = workingState->getTimeStep();
224 Scalar time = workingState->getTime();
226 RCP<StepperState<Scalar>> stepperState = workingState->getStepperState();
229 if (getStepType() ==
"Variable") {
230 if (teAdjustedDt_ ==
true) {
231 printDtChanges(iStep, dt, dtAfterTimeEvent_,
232 "Reset dt after time event.");
233 dt = dtAfterTimeEvent_;
234 time = lastTime + dt;
235 teAdjustedDt_ =
false;
236 dtAfterTimeEvent_ = 0.0;
240 printDtChanges(iStep, dt, getInitTimeStep(),
"Reset dt to initial dt.");
241 dt = getInitTimeStep();
242 time = lastTime + dt;
245 if (dt < getMinTimeStep()) {
246 printDtChanges(iStep, dt, getMinTimeStep(),
"Reset dt to minimum dt.");
247 dt = getMinTimeStep();
248 time = lastTime + dt;
253 workingState->setTimeStep(dt);
254 workingState->setTime(time);
257 stepControlStrategy_->setNextTimeStep(*
this, solutionHistory,
261 dt = workingState->getTimeStep();
262 time = workingState->getTime();
264 if (getStepType() ==
"Variable") {
265 if (dt < getMinTimeStep()) {
266 printDtChanges(iStep, dt, getMinTimeStep(),
267 "dt is too small. Resetting to minimum dt.");
268 dt = getMinTimeStep();
269 time = lastTime + dt;
271 if (dt > getMaxTimeStep()) {
272 printDtChanges(iStep, dt, getMaxTimeStep(),
273 "dt is too large. Resetting to maximum dt.");
274 dt = getMaxTimeStep();
275 time = lastTime + dt;
280 bool outputDueToIndex =
false;
281 std::vector<Teuchos::RCP<TimeEventBase<Scalar>>> constrainingTEs;
282 if (timeEvent_->isIndex(iStep, constrainingTEs)) {
283 for (
auto& e : constrainingTEs) {
284 if (e->getName() ==
"Output Index Interval" ||
285 e->getName() ==
"Output Index List") {
286 outputDueToIndex =
true;
292 Scalar endTime = lastTime + dt;
295 if (getStepType() ==
"Variable") endTime = lastTime + dt + getMinTimeStep();
298 timeEvent_->eventInRange(lastTime, endTime, constrainingTEs);
300 bool outputDueToTime =
false;
301 Scalar tone = endTime;
302 bool landOnExactly =
false;
304 for (
auto& e : constrainingTEs) {
305 if (e->getName() ==
"Output Time Interval" ||
306 e->getName() ==
"Output Time List") {
307 outputDueToTime =
true;
310 if (e->getLandOnExactly() ==
true) {
311 landOnExactly =
true;
312 tone = e->timeOfNextEvent(lastTime);
318 Scalar reltol = 1.0e-6;
319 if (teThisStep && getStepType() ==
"Variable") {
320 if (landOnExactly ==
true) {
325 printDtChanges(iStep, dt, tone - lastTime,
326 "Adjusting dt to hit the next TimeEvent.");
327 teAdjustedDt_ =
true;
328 dtAfterTimeEvent_ = dt;
329 dt = tone - lastTime;
330 time = lastTime + dt;
332 else if (std::fabs(time - tone) < reltol * std::fabs(time)) {
336 iStep, dt, tone - lastTime,
337 "Adjusting dt for numerical roundoff to hit the next TimeEvent.");
338 teAdjustedDt_ =
true;
339 dtAfterTimeEvent_ = dt;
340 dt = tone - lastTime;
341 time = lastTime + dt;
343 else if (std::fabs(time + getMinTimeStep() - tone) <
344 reltol * std::fabs(tone)) {
349 iStep, dt, (tone - lastTime) / 2.0,
350 "The next TimeEvent is within the minimum dt of the next time. "
351 "Adjusting dt to take two steps.");
352 dt = (tone - lastTime) / 2.0;
353 time = lastTime + dt;
355 outputDueToTime =
false;
362 if (getStepType() ==
"Variable") {
363 if ((lastTime + dt > getFinalTime()) ||
364 (std::fabs((lastTime + dt - getFinalTime())) <
365 reltol * std::fabs(lastTime + dt))) {
366 printDtChanges(iStep, dt, getFinalTime() - lastTime,
367 "Adjusting dt to hit final time.");
368 dt = getFinalTime() - lastTime;
369 time = lastTime + dt;
375 dt <= Scalar(0.0), std::out_of_range,
376 "Error - Time step is not positive. dt = " << dt <<
"\n");
380 (lastTime + dt < getInitTime()), std::out_of_range,
381 "Error - Time step does not move time INTO time range.\n"
382 <<
" [timeMin, timeMax] = ["
383 << getInitTime() <<
", " << getFinalTime()
385 << lastTime <<
" + " << dt <<
" = " << lastTime + dt <<
"\n");
387 if (getStepType() ==
"Variable") {
389 (lastTime + dt > getFinalTime()), std::out_of_range,
390 "Error - Time step move time OUT OF time range.\n"
391 <<
" [timeMin, timeMax] = ["
392 << getInitTime() <<
", " << getFinalTime()
394 << lastTime <<
" + " << dt <<
" = " << lastTime + dt <<
"\n");
397 workingState->setTimeStep(dt);
398 workingState->setTime(time);
399 workingState->setOutput(outputDueToIndex || outputDueToTime);
405 template <
class Scalar>
409 const int relTol = 14;
410 const int i = (getInitTime() == 0)
412 : 1 + (
int)std::floor(std::log10(std::fabs(getInitTime())));
413 const Scalar absTolInit = std::pow(10, i - relTol);
415 (getFinalTime() == 0)
417 : 1 + (
int)std::floor(std::log10(std::fabs(getFinalTime())));
418 const Scalar absTolFinal = std::pow(10, j - relTol);
420 const bool test1 = getInitTime() - absTolInit <= time;
421 const bool test2 = time < getFinalTime() - absTolFinal;
423 return (test1 && test2);
427 template <
class Scalar>
430 bool iir = (getInitIndex() <= iStep && iStep < getFinalIndex());
434 template <
class Scalar>
439 "Error - getStepType() - Strategy is unset!\n");
440 return stepControlStrategy_->getStepType();
443 template <
class Scalar>
446 auto event = timeEvent_->find(
"Output Time Interval");
447 if (event != Teuchos::null)
return event->getLandOnExactly();
449 event = timeEvent_->find(
"Output Time List");
450 if (event != Teuchos::null)
return event->getLandOnExactly();
455 template <
class Scalar>
458 std::vector<int> indices;
459 if (timeEvent_->find(
"Output Index List") == Teuchos::null)
return indices;
461 timeEvent_->find(
"Output Index List"));
465 template <
class Scalar>
468 std::vector<Scalar> times;
469 if (timeEvent_->find(
"Output Time List") == Teuchos::null)
return times;
471 timeEvent_->find(
"Output Time List"));
475 template <
class Scalar>
478 if (timeEvent_->find(
"Output Index Interval") == Teuchos::null)
481 timeEvent_->find(
"Output Index Interval"));
485 template <
class Scalar>
488 if (timeEvent_->find(
"Output Time Interval") == Teuchos::null)
return 1.0e+99;
490 timeEvent_->find(
"Output Time Interval"));
494 template <
class Scalar>
498 "Error - Can only use setNumTimeSteps() when "
499 "'Step Type' == 'Constant'.\n");
501 numTimeSteps_ = numTimeSteps;
502 if (numTimeSteps_ >= 0) {
503 setFinalIndex(getInitIndex() + numTimeSteps_);
505 if (numTimeSteps_ == 0)
506 initTimeStep = Scalar(0.0);
508 initTimeStep = (getFinalTime() - getInitTime()) / numTimeSteps_;
509 setInitTimeStep(initTimeStep);
510 setMinTimeStep(initTimeStep);
511 setMaxTimeStep(initTimeStep);
516 *out <<
"Warning - setNumTimeSteps() Setting 'Number of Time Steps' = "
517 << getNumTimeSteps() <<
" Set the following parameters: \n"
518 <<
" 'Final Time Index' = " << getFinalIndex() <<
"\n"
519 <<
" 'Initial Time Step' = " << getInitTimeStep() <<
"\n"
520 <<
" 'Step Type' = " << getStepType() << std::endl;
522 isInitialized_ =
false;
526 template <
class Scalar>
529 auto event = timeEvent_->find(
"Output Time Interval");
530 if (event != Teuchos::null) {
534 event = timeEvent_->find(
"Output Time List");
535 if (event != Teuchos::null) {
541 template <
class Scalar>
545 outputIndices,
"Output Index List")));
546 isInitialized_ =
false;
549 template <
class Scalar>
553 outputTimes,
"Output Time List", getOutputExactly())));
554 isInitialized_ =
false;
557 template <
class Scalar>
561 getInitIndex(), getFinalIndex(), i,
"Output Index Interval")));
562 isInitialized_ =
false;
565 template <
class Scalar>
570 "Output Time Interval", getOutputExactly())));
571 isInitialized_ =
false;
574 template <
class Scalar>
580 if (timeEvent != Teuchos::null) {
581 timeEvent_ = timeEvent;
585 tec->setName(
"Time Step Control Events");
587 getInitIndex(), getFinalIndex(), 1000000,
"Output Index Interval")));
589 getInitTime(), getFinalTime(), 1.0e+99,
"Output Time Interval",
true)));
592 isInitialized_ =
false;
595 template <
class Scalar>
601 if (tscs != Teuchos::null) {
602 stepControlStrategy_ = tscs;
605 stepControlStrategy_ =
608 isInitialized_ =
false;
611 template <
class Scalar>
614 std::string name =
"Tempus::TimeStepControl";
618 template <
class Scalar>
622 auto l_out = Teuchos::fancyOStream(out.
getOStream());
624 l_out->setOutputToRootOnly(0);
626 *l_out <<
"\n--- " << this->description() <<
" ---" << std::endl;
629 std::vector<int> idx = getOutputIndices();
630 std::ostringstream listIdx;
632 for (std::size_t i = 0; i < idx.size() - 1; ++i)
633 listIdx << idx[i] <<
", ";
634 listIdx << idx[idx.size() - 1];
637 std::vector<Scalar> times = getOutputTimes();
638 std::ostringstream listTimes;
639 if (!times.empty()) {
640 for (std::size_t i = 0; i < times.size() - 1; ++i)
641 listTimes << times[i] <<
", ";
642 listTimes << times[times.size() - 1];
645 *l_out <<
" stepType = " << getStepType() << std::endl
646 <<
" initTime = " << getInitTime() << std::endl
647 <<
" finalTime = " << getFinalTime() << std::endl
648 <<
" minTimeStep = " << getMinTimeStep() << std::endl
649 <<
" initTimeStep = " << getInitTimeStep() << std::endl
650 <<
" maxTimeStep = " << getMaxTimeStep() << std::endl
651 <<
" initIndex = " << getInitIndex() << std::endl
652 <<
" finalIndex = " << getFinalIndex() << std::endl
653 <<
" maxAbsError = " << getMaxAbsError() << std::endl
654 <<
" maxRelError = " << getMaxRelError() << std::endl
655 <<
" maxFailures = " << getMaxFailures() << std::endl
656 <<
" maxConsecFailures = " << getMaxConsecFailures() << std::endl
657 <<
" numTimeSteps = " << getNumTimeSteps() << std::endl
658 <<
" printDtChanges = " << getPrintDtChanges() << std::endl
659 <<
" outputExactly = " << getOutputExactly() << std::endl
660 <<
" outputIndices = " << listIdx.str() << std::endl
661 <<
" outputTimes = " << listTimes.str() << std::endl
662 <<
" outputIndexInterval= " << getOutputIndexInterval() << std::endl
663 <<
" outputTimeInterval = " << getOutputTimeInterval() << std::endl
664 <<
" outputAdjustedDt = " << teAdjustedDt_ << std::endl
665 <<
" dtAfterOutput = " << dtAfterTimeEvent_ << std::endl;
666 stepControlStrategy_->describe(*l_out, verbLevel);
667 timeEvent_->describe(*l_out, verbLevel);
669 *l_out << std::string(this->description().length() + 8,
'-') << std::endl;
672 template <
class Scalar>
677 Teuchos::parameterList(
"Time Step Control");
679 pl->
set<
double>(
"Initial Time", getInitTime(),
"Initial time");
680 pl->
set<
double>(
"Final Time", getFinalTime(),
"Final time");
681 pl->
set<
double>(
"Minimum Time Step", getMinTimeStep(),
682 "Minimum time step size");
683 pl->
set<
double>(
"Initial Time Step", getInitTimeStep(),
684 "Initial time step size");
685 pl->
set<
double>(
"Maximum Time Step", getMaxTimeStep(),
686 "Maximum time step size");
687 pl->
set<
int>(
"Initial Time Index", getInitIndex(),
"Initial time index");
688 pl->
set<
int>(
"Final Time Index", getFinalIndex(),
"Final time index");
690 "Number of Time Steps", getNumTimeSteps(),
691 "The number of constant time steps. The actual step size gets computed\n"
692 "on the fly given the size of the time domain. Overides and resets\n"
693 " 'Final Time Index' = 'Initial Time Index' + 'Number of Time "
695 " 'Initial Time Step' = "
696 "('Final Time' - 'Initial Time')/'Number of Time Steps'\n");
697 pl->
set<
double>(
"Maximum Absolute Error", getMaxAbsError(),
698 "Maximum absolute error");
699 pl->
set<
double>(
"Maximum Relative Error", getMaxRelError(),
700 "Maximum relative error");
702 pl->
set<
bool>(
"Print Time Step Changes", getPrintDtChanges(),
703 "Print timestep size when it changes");
705 auto event = timeEvent_->find(
"Output Index Interval");
706 if (event != Teuchos::null) {
708 pl->
set<
int>(
"Output Index Interval", teri->getIndexStride(),
709 "Output Index Interval");
712 event = timeEvent_->find(
"Output Time Interval");
713 if (event != Teuchos::null) {
715 pl->
set<
double>(
"Output Time Interval", ter->getTimeStride(),
716 "Output time interval");
720 "Output Exactly On Output Times", getOutputExactly(),
721 "This determines if the timestep size will be adjusted to exactly land\n"
722 "on the output times for 'Variable' timestepping (default=true).\n"
723 "When set to 'false' or for 'Constant' time stepping, the timestep\n"
724 "following the output time will be flagged for output.\n");
727 event = timeEvent_->find(
"Output Index List");
728 std::ostringstream list;
729 if (event != Teuchos::null) {
733 for (std::size_t i = 0; i < idx.size() - 1; ++i) list << idx[i] <<
", ";
734 list << idx[idx.size() - 1];
737 pl->
set<std::string>(
"Output Index List", list.str(),
738 "Comma deliminated list of output indices");
742 event = timeEvent_->find(
"Output Time List");
743 std::ostringstream list;
744 if (event != Teuchos::null) {
747 if (!times.empty()) {
748 for (std::size_t i = 0; i < times.size() - 1; ++i)
749 list << times[i] <<
", ";
750 list << times[times.size() - 1];
753 pl->
set<std::string>(
"Output Time List", list.str(),
754 "Comma deliminated list of output times");
760 tecTmp->setTimeEvents(timeEvent_->getTimeEvents());
761 tecTmp->remove(
"Output Index Interval");
762 tecTmp->remove(
"Output Time Interval");
763 tecTmp->remove(
"Output Index List");
764 tecTmp->remove(
"Output Time List");
765 if (tecTmp->getSize() > 0)
766 pl->
set(
"Time Step Control Events", *tecTmp->getValidParameters());
769 pl->
set<
int>(
"Maximum Number of Stepper Failures", getMaxFailures(),
770 "Maximum number of Stepper failures");
771 pl->
set<
int>(
"Maximum Number of Consecutive Stepper Failures",
772 getMaxConsecFailures(),
773 "Maximum number of consecutive Stepper failures");
775 pl->
set(
"Time Step Control Strategy",
776 *stepControlStrategy_->getValidParameters());
783 template <
class Scalar>
792 if (pList == Teuchos::null || pList->
numParams() == 0)
return tsc;
795 Teuchos::rcp_const_cast<ParameterList>(tsc->getValidParameters());
797 if (pList->
isSublist(
"Time Step Control Events")) {
798 RCP<ParameterList> tsctePL =
799 Teuchos::sublist(pList,
"Time Step Control Events",
true);
800 tscValidPL->set(
"Time Step Control Events", *tsctePL);
805 tsc->setInitTime(pList->
get<
double>(
"Initial Time"));
806 tsc->setFinalTime(pList->
get<
double>(
"Final Time"));
807 tsc->setMinTimeStep(pList->
get<
double>(
"Minimum Time Step"));
808 tsc->setInitTimeStep(pList->
get<
double>(
"Initial Time Step"));
809 tsc->setMaxTimeStep(pList->
get<
double>(
"Maximum Time Step"));
810 tsc->setInitIndex(pList->
get<
int>(
"Initial Time Index"));
811 tsc->setFinalIndex(pList->
get<
int>(
"Final Time Index"));
812 tsc->setMaxAbsError(pList->
get<
double>(
"Maximum Absolute Error"));
813 tsc->setMaxRelError(pList->
get<
double>(
"Maximum Relative Error"));
814 tsc->setMaxFailures(pList->
get<
int>(
"Maximum Number of Stepper Failures"));
815 tsc->setMaxConsecFailures(
816 pList->
get<
int>(
"Maximum Number of Consecutive Stepper Failures"));
817 tsc->setPrintDtChanges(pList->
get<
bool>(
"Print Time Step Changes"));
818 tsc->setNumTimeSteps(pList->
get<
int>(
"Number of Time Steps"));
821 tec->setName(
"Time Step Control Events");
824 std::vector<int> outputIndices;
825 outputIndices.clear();
826 std::string str = pList->
get<std::string>(
"Output Index List");
827 std::string delimiters(
",");
828 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
829 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
830 while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
831 std::string token = str.substr(lastPos, pos - lastPos);
832 outputIndices.push_back(
int(std::stoi(token)));
833 if (pos == std::string::npos)
break;
835 lastPos = str.find_first_not_of(delimiters, pos);
836 pos = str.find_first_of(delimiters, lastPos);
839 if (!outputIndices.empty()) {
841 std::sort(outputIndices.begin(), outputIndices.end());
843 std::unique(outputIndices.begin(), outputIndices.end()),
844 outputIndices.end());
847 outputIndices,
"Output Index List")));
853 tsc->getInitIndex(), tsc->getFinalIndex(),
854 pList->
get<
int>(
"Output Index Interval"),
"Output Index Interval")));
856 auto outputExactly = pList->
get<
bool>(
"Output Exactly On Output Times",
true);
859 std::vector<Scalar> outputTimes;
861 std::string str = pList->
get<std::string>(
"Output Time List");
862 std::string delimiters(
",");
864 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
866 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
867 while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
869 std::string token = str.substr(lastPos, pos - lastPos);
870 outputTimes.push_back(Scalar(std::stod(token)));
871 if (pos == std::string::npos)
break;
873 lastPos = str.find_first_not_of(delimiters, pos);
874 pos = str.find_first_of(delimiters, lastPos);
877 if (!outputTimes.empty()) {
879 std::sort(outputTimes.begin(), outputTimes.end());
880 outputTimes.erase(std::unique(outputTimes.begin(), outputTimes.end()),
884 outputTimes,
"Output Time List", outputExactly)));
891 pList->
get<
double>(
"Output Time Interval"),
892 "Output Time Interval", outputExactly)));
894 if (pList->
isSublist(
"Time Step Control Events")) {
895 RCP<ParameterList> tsctePL =
896 Teuchos::sublist(pList,
"Time Step Control Events",
true);
898 auto timeEventType = tsctePL->get<std::string>(
"Type",
"Unknown");
899 if (timeEventType ==
"Range") {
900 tec->add(createTimeEventRange<Scalar>(tsctePL));
902 else if (timeEventType ==
"Range Index") {
903 tec->add(createTimeEventRangeIndex<Scalar>(tsctePL));
905 else if (timeEventType ==
"List") {
906 tec->add(createTimeEventList<Scalar>(tsctePL));
908 else if (timeEventType ==
"List Index") {
909 tec->add(createTimeEventListIndex<Scalar>(tsctePL));
911 else if (timeEventType ==
"Composite") {
912 auto tecTmp = createTimeEventComposite<Scalar>(tsctePL);
913 auto timeEvents = tecTmp->getTimeEvents();
914 for (
auto& e : timeEvents) tec->add(e);
917 RCP<Teuchos::FancyOStream> out =
918 Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
919 out->setOutputToRootOnly(0);
921 *out <<
"Warning -- Unknown Time Event Type!\n"
922 <<
"'Type' = '" << timeEventType <<
"'\n"
923 <<
"Should call add() with this "
924 <<
"(app-specific?) Time Event.\n"
929 tsc->setTimeEvents(tec);
931 if (!pList->
isParameter(
"Time Step Control Strategy")) {
932 tsc->setTimeStepControlStrategy();
936 RCP<ParameterList> tscsPL =
937 Teuchos::sublist(pList,
"Time Step Control Strategy",
true);
939 auto strategyType = tscsPL->get<std::string>(
"Strategy Type");
940 if (strategyType ==
"Constant") {
941 tsc->setTimeStepControlStrategy(
942 createTimeStepControlStrategyConstant<Scalar>(tscsPL));
944 else if (strategyType ==
"Basic VS") {
945 tsc->setTimeStepControlStrategy(
946 createTimeStepControlStrategyBasicVS<Scalar>(tscsPL));
948 else if (strategyType ==
"Integral Controller") {
949 tsc->setTimeStepControlStrategy(
950 createTimeStepControlStrategyIntegralController<Scalar>(tscsPL));
952 else if (strategyType ==
"Composite") {
953 tsc->setTimeStepControlStrategy(
954 createTimeStepControlStrategyComposite<Scalar>(tscsPL));
957 RCP<Teuchos::FancyOStream> out =
958 Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
959 out->setOutputToRootOnly(0);
961 *out <<
"Warning -- Did not find a Tempus strategy to create!\n"
962 <<
"'Strategy Type' = '" << strategyType <<
"'\n"
963 <<
"Should call setTimeStepControlStrategy() with this\n"
964 <<
"(app-specific?) strategy, and initialize().\n"
969 if (runInitialize) tsc->initialize();
974 #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)
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
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
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.