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"
26 template<
class Scalar>
28 : isInitialized_ (false),
32 initTimeStep_ (1.0e+99),
33 maxTimeStep_ (1.0e+99),
35 finalIndex_ (1000000),
36 maxAbsError_ (1.0e-08),
37 maxRelError_ (1.0e-08),
39 maxConsecFailures_ (5),
41 printDtChanges_ (true),
42 teAdjustedDt_ (false),
43 dtAfterTimeEvent_ (0.0)
51 template<
class Scalar>
63 int maxConsecFailures,
67 std::vector<int> outputIndices,
68 std::vector<Scalar> outputTimes,
69 int outputIndexInterval,
70 Scalar outputTimeInterval,
73 : isInitialized_ (false ),
74 initTime_ (initTime ),
75 finalTime_ (finalTime ),
76 minTimeStep_ (minTimeStep ),
77 initTimeStep_ (initTimeStep ),
78 maxTimeStep_ (maxTimeStep ),
79 initIndex_ (initIndex ),
80 finalIndex_ (finalIndex ),
81 maxAbsError_ (maxAbsError ),
82 maxRelError_ (maxRelError ),
83 maxFailures_ (maxFailures ),
84 maxConsecFailures_ (maxConsecFailures ),
85 printDtChanges_ (printDtChanges ),
86 teAdjustedDt_ (false ),
87 dtAfterTimeEvent_ (0.0 )
95 tec->setName(
"Time Step Control Events");
96 auto tes = timeEvent->getTimeEvents();
97 for(
auto& e : tes) tec->add(e);
101 initTime, finalTime, outputTimeInterval,
"Output Time Interval", outputExactly));
105 if (!outputTimes.empty())
107 outputTimes,
"Output Time List", outputExactly)));
111 initIndex, finalIndex, outputIndexInterval,
"Output Index Interval")));
114 if (!outputTimes.empty())
116 outputIndices,
"Output Index List")));
124 template<
class Scalar>
128 (getInitTime() > getFinalTime() ), std::logic_error,
129 "Error - Inconsistent time range.\n"
130 " (timeMin = "<<getInitTime()<<
") > (timeMax = "<<getFinalTime()<<
")\n");
135 "Error - Negative minimum time step. dtMin = "<<getMinTimeStep()<<
")\n");
139 "Error - Negative maximum time step. dtMax = "<<getMaxTimeStep()<<
")\n");
141 (getMinTimeStep() > getMaxTimeStep() ), std::logic_error,
142 "Error - Inconsistent time step range.\n"
143 " (dtMin = "<<getMinTimeStep()<<
") > (dtMax = "<<getMaxTimeStep()<<
")\n");
147 "Error - Negative initial time step. dtInit = "<<getInitTimeStep()<<
")\n");
149 (getInitTimeStep() < getMinTimeStep() ||
150 getInitTimeStep() > getMaxTimeStep() ),
152 "Error - Initial time step is out of range.\n"
153 <<
" [dtMin, dtMax] = [" << getMinTimeStep() <<
", "
154 << getMaxTimeStep() <<
"]\n"
155 <<
" dtInit = " << getInitTimeStep() <<
"\n");
158 (getInitIndex() > getFinalIndex() ), std::logic_error,
159 "Error - Inconsistent time index range.\n"
160 " (iStepMin = "<<getInitIndex()<<
") > (iStepMax = "
161 <<getFinalIndex()<<
")\n");
166 "Error - Negative maximum time step. errorMaxAbs = "
167 <<getMaxAbsError()<<
")\n");
171 "Error - Negative maximum time step. errorMaxRel = "
172 <<getMaxRelError()<<
")\n");
175 (stepControlStrategy_ == Teuchos::null), std::logic_error,
176 "Error - Strategy is unset!\n");
178 stepControlStrategy_->initialize();
181 (getStepType() !=
"Constant" && getStepType() !=
"Variable"),
183 "Error - 'Step Type' does not equal one of these:\n"
184 <<
" 'Constant' - Integrator will take constant time step sizes.\n"
185 <<
" 'Variable' - Integrator will allow changes to the time step size.\n"
186 <<
" stepType = " << getStepType() <<
"\n");
188 isInitialized_ =
true;
192 template<
class Scalar>
194 printDtChanges(
int istep, Scalar dt_old, Scalar dt_new, std::string reason)
const
196 if (!getPrintDtChanges())
return;
202 std::stringstream message;
203 message << std::scientific
204 <<std::setw(6)<<std::setprecision(3)<<istep
205 <<
" * (dt = "<<std::setw(9)<<std::setprecision(3)<<dt_old
206 <<
", new = "<<std::setw(9)<<std::setprecision(3)<<dt_new
207 <<
") " << reason << std::endl;
208 *out << message.str();
212 template<
class Scalar>
215 if ( !isInitialized_ ) {
218 "Error - " << this->description() <<
" is not initialized!");
223 template<
class Scalar>
226 Status & integratorStatus)
232 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::TimeStepControl::setNextTimeStep()");
234 RCP<SolutionState<Scalar> > workingState=solutionHistory->getWorkingState();
235 const Scalar lastTime = solutionHistory->getCurrentState()->getTime();
236 const int iStep = workingState->getIndex();
237 Scalar dt = workingState->getTimeStep();
238 Scalar time = workingState->getTime();
240 RCP<StepperState<Scalar> > stepperState = workingState->getStepperState();
243 if (getStepType() ==
"Variable") {
244 if (teAdjustedDt_ ==
true) {
245 printDtChanges(iStep, dt, dtAfterTimeEvent_,
"Reset dt after time event.");
246 dt = dtAfterTimeEvent_;
247 time = lastTime + dt;
248 teAdjustedDt_ =
false;
249 dtAfterTimeEvent_ = 0.0;
253 printDtChanges(iStep, dt, getInitTimeStep(),
"Reset dt to initial dt.");
254 dt = getInitTimeStep();
255 time = lastTime + dt;
258 if (dt < getMinTimeStep()) {
259 printDtChanges(iStep, dt, getMinTimeStep(),
"Reset dt to minimum dt.");
260 dt = getMinTimeStep();
261 time = lastTime + dt;
266 workingState->setTimeStep(dt);
267 workingState->setTime(time);
270 stepControlStrategy_->setNextTimeStep(*
this, solutionHistory,
274 dt = workingState->getTimeStep();
275 time = workingState->getTime();
277 if (getStepType() ==
"Variable") {
278 if (dt < getMinTimeStep()) {
279 printDtChanges(iStep, dt, getMinTimeStep(),
280 "dt is too small. Resetting to minimum dt.");
281 dt = getMinTimeStep();
282 time = lastTime + dt;
284 if (dt > getMaxTimeStep()) {
285 printDtChanges(iStep, dt, getMaxTimeStep(),
286 "dt is too large. Resetting to maximum dt.");
287 dt = getMaxTimeStep();
288 time = lastTime + dt;
294 bool outputDueToIndex =
false;
295 std::vector<Teuchos::RCP<TimeEventBase<Scalar> > > constrainingTEs;
296 if (timeEvent_->isIndex(iStep, constrainingTEs)) {
297 for(
auto& e : constrainingTEs) {
298 if (e->getName() ==
"Output Index Interval" ||
299 e->getName() ==
"Output Index List" )
300 { outputDueToIndex =
true; }
305 Scalar endTime = lastTime+dt;
308 if (getStepType() ==
"Variable") endTime = lastTime+dt+getMinTimeStep();
310 bool teThisStep = timeEvent_->eventInRange(lastTime, endTime, constrainingTEs);
312 bool outputDueToTime =
false;
313 Scalar tone = endTime;
314 bool landOnExactly =
false;
316 for (
auto& e : constrainingTEs) {
317 if (e->getName() ==
"Output Time Interval" ||
318 e->getName() ==
"Output Time List" )
319 { outputDueToTime =
true; }
321 if (e->getLandOnExactly() ==
true) {
322 landOnExactly =
true;
323 tone = e->timeOfNextEvent(lastTime);
329 Scalar reltol = 1.0e-6;
330 if (teThisStep && getStepType() ==
"Variable") {
331 if (landOnExactly ==
true) {
336 printDtChanges(iStep, dt, tone - lastTime,
337 "Adjusting dt to hit the next TimeEvent.");
338 teAdjustedDt_ =
true;
339 dtAfterTimeEvent_ = dt;
340 dt = tone - lastTime;
341 time = lastTime + dt;
342 }
else if (std::fabs(time-tone) < reltol*std::fabs(time)) {
345 printDtChanges(iStep, dt, tone - lastTime,
346 "Adjusting dt for numerical roundoff to hit the next TimeEvent.");
347 teAdjustedDt_ =
true;
348 dtAfterTimeEvent_ = dt;
349 dt = tone - lastTime;
350 time = lastTime + dt;
351 }
else if (std::fabs(time + getMinTimeStep() - tone)
352 < reltol*std::fabs(tone)) {
356 printDtChanges(iStep, dt, (tone - lastTime)/2.0,
357 "The next TimeEvent is within the minimum dt of the next time. "
358 "Adjusting dt to take two steps.");
359 dt = (tone - lastTime)/2.0;
360 time = lastTime + dt;
362 outputDueToTime =
false;
369 if (getStepType() ==
"Variable") {
370 if ( (lastTime+dt > getFinalTime()) ||
371 (std::fabs((lastTime+dt-getFinalTime()))
372 < reltol*std::fabs(lastTime+dt)) ) {
373 printDtChanges(iStep, dt, getFinalTime() - lastTime,
374 "Adjusting dt to hit final time.");
375 dt = getFinalTime() - lastTime;
376 time = lastTime + dt;
382 "Error - Time step is not positive. dt = " << dt <<
"\n");
386 (lastTime + dt < getInitTime()), std::out_of_range,
387 "Error - Time step does not move time INTO time range.\n"
388 " [timeMin, timeMax] = [" << getInitTime() <<
", "
389 << getFinalTime() <<
"]\n"
390 " T + dt = " << lastTime <<
" + "<< dt <<
" = " << lastTime + dt <<
"\n");
392 if (getStepType() ==
"Variable") {
394 (lastTime + dt > getFinalTime()), std::out_of_range,
395 "Error - Time step move time OUT OF time range.\n"
396 " [timeMin, timeMax] = [" << getInitTime() <<
", "
397 << getFinalTime() <<
"]\n"
398 " T + dt = " << lastTime <<
" + "<< dt <<
" = " << lastTime + dt <<
"\n");
401 workingState->setTimeStep(dt);
402 workingState->setTime(time);
403 workingState->setOutput(outputDueToIndex || outputDueToTime);
410 template<
class Scalar>
414 const int relTol = 14;
416 (getInitTime() == 0) ? 0 : 1 + (
int)std::floor(std::log10(std::fabs(getInitTime()) ) );
417 const Scalar absTolInit = std::pow(10, i-relTol);
419 (getFinalTime() == 0) ? 0 : 1 + (
int)std::floor(std::log10(std::fabs(getFinalTime()) ) );
420 const Scalar absTolFinal = std::pow(10, j-relTol);
422 const bool test1 = getInitTime() - absTolInit <= time;
423 const bool test2 = time < getFinalTime() - absTolFinal;
425 return (test1 && test2);
430 template<
class Scalar>
433 bool iir = (getInitIndex() <= iStep && iStep < getFinalIndex());
438 template<
class Scalar>
442 (stepControlStrategy_ == Teuchos::null), std::logic_error,
443 "Error - getStepType() - Strategy is unset!\n");
444 return stepControlStrategy_->getStepType();
448 template<
class Scalar>
451 auto event = timeEvent_->find(
"Output Time Interval");
452 if (event != Teuchos::null)
return event->getLandOnExactly();
454 event = timeEvent_->find(
"Output Time List");
455 if (event != Teuchos::null)
return event->getLandOnExactly();
461 template<
class Scalar>
464 std::vector<int> indices;
465 if ( timeEvent_->find(
"Output Index List") == Teuchos::null)
468 timeEvent_->find(
"Output Index List"));
473 template<
class Scalar>
476 std::vector<Scalar> times;
477 if ( timeEvent_->find(
"Output Time List") == Teuchos::null)
480 timeEvent_->find(
"Output Time List"));
485 template<
class Scalar>
488 if ( timeEvent_->find(
"Output Index Interval") == Teuchos::null)
491 timeEvent_->find(
"Output Index Interval"));
496 template<
class Scalar>
499 if ( timeEvent_->find(
"Output Time Interval") == Teuchos::null)
502 timeEvent_->find(
"Output Time Interval"));
507 template<
class Scalar>
511 "Error - Can only use setNumTimeSteps() when 'Step Type' == 'Constant'.\n");
513 numTimeSteps_ = numTimeSteps;
514 if (numTimeSteps_ >= 0) {
515 setFinalIndex(getInitIndex() + numTimeSteps_);
517 if (numTimeSteps_ == 0)
518 initTimeStep = Scalar(0.0);
520 initTimeStep = (getFinalTime() - getInitTime())/numTimeSteps_;
521 setInitTimeStep(initTimeStep);
522 setMinTimeStep (initTimeStep);
523 setMaxTimeStep (initTimeStep);
528 *out <<
"Warning - setNumTimeSteps() Setting 'Number of Time Steps' = " << getNumTimeSteps()
529 <<
" Set the following parameters: \n"
530 <<
" 'Final Time Index' = " << getFinalIndex() <<
"\n"
531 <<
" 'Initial Time Step' = " << getInitTimeStep() <<
"\n"
532 <<
" 'Step Type' = " << getStepType() << std::endl;
534 isInitialized_ =
false;
539 template<
class Scalar>
542 auto event = timeEvent_->find(
"Output Time Interval");
543 if (event != Teuchos::null) {
547 event = timeEvent_->find(
"Output Time List");
548 if (event != Teuchos::null) {
555 template<
class Scalar>
559 outputIndices,
"Output Index List")));
560 isInitialized_ =
false;
564 template<
class Scalar>
568 outputTimes,
"Output Time List", getOutputExactly())));
569 isInitialized_ =
false;
573 template<
class Scalar>
577 getInitIndex(), getFinalIndex(), i,
"Output Index Interval")));
578 isInitialized_ =
false;
582 template<
class Scalar>
586 getInitTime(), getFinalTime(), t,
"Output Time Interval", getOutputExactly())));
587 isInitialized_ =
false;
591 template<
class Scalar>
597 if ( timeEvent != Teuchos::null ) {
598 timeEvent_ = timeEvent;
601 tec->setName(
"Time Step Control Events");
603 getInitIndex(), getFinalIndex(), 1000000,
"Output Index Interval")));
605 getInitTime(), getFinalTime(), 1.0e+99,
"Output Time Interval",
true)));
608 isInitialized_ =
false;
612 template<
class Scalar>
618 if ( tscs != Teuchos::null ) {
619 stepControlStrategy_ = tscs;
621 stepControlStrategy_ =
624 isInitialized_ =
false;
628 template<
class Scalar>
631 std::string name =
"Tempus::TimeStepControl";
636 template<
class Scalar>
641 auto l_out = Teuchos::fancyOStream( out.
getOStream() );
643 l_out->setOutputToRootOnly(0);
645 *l_out <<
"\n--- " << this->description() <<
" ---" <<std::endl;
648 std::vector<int> idx = getOutputIndices();
649 std::ostringstream listIdx;
651 for(std::size_t i = 0; i < idx.size()-1; ++i) listIdx << idx[i] <<
", ";
652 listIdx << idx[idx.size()-1];
655 std::vector<Scalar> times = getOutputTimes();
656 std::ostringstream listTimes;
657 if (!times.empty()) {
658 for(std::size_t i = 0; i < times.size()-1; ++i)
659 listTimes << times[i] <<
", ";
660 listTimes << times[times.size()-1];
663 *l_out <<
" stepType = " << getStepType() << std::endl
664 <<
" initTime = " << getInitTime() << std::endl
665 <<
" finalTime = " << getFinalTime() << std::endl
666 <<
" minTimeStep = " << getMinTimeStep() << std::endl
667 <<
" initTimeStep = " << getInitTimeStep() << std::endl
668 <<
" maxTimeStep = " << getMaxTimeStep() << std::endl
669 <<
" initIndex = " << getInitIndex() << std::endl
670 <<
" finalIndex = " << getFinalIndex() << std::endl
671 <<
" maxAbsError = " << getMaxAbsError() << std::endl
672 <<
" maxRelError = " << getMaxRelError() << std::endl
673 <<
" maxFailures = " << getMaxFailures() << std::endl
674 <<
" maxConsecFailures = " << getMaxConsecFailures() << std::endl
675 <<
" numTimeSteps = " << getNumTimeSteps() << std::endl
676 <<
" printDtChanges = " << getPrintDtChanges() << std::endl
677 <<
" outputExactly = " << getOutputExactly() << std::endl
678 <<
" outputIndices = " << listIdx.str() << std::endl
679 <<
" outputTimes = " << listTimes.str() << std::endl
680 <<
" outputIndexInterval= " << getOutputIndexInterval() << std::endl
681 <<
" outputTimeInterval = " << getOutputTimeInterval() << std::endl
682 <<
" outputAdjustedDt = " << teAdjustedDt_ << std::endl
683 <<
" dtAfterOutput = " << dtAfterTimeEvent_ << std::endl;
684 stepControlStrategy_->describe(*l_out, verbLevel);
685 timeEvent_->describe(*l_out, verbLevel);
687 *l_out << std::string(this->description().length()+8,
'-') <<std::endl;
692 template<
class Scalar>
698 pl->
set<
double>(
"Initial Time" , getInitTime() ,
"Initial time");
699 pl->
set<
double>(
"Final Time" , getFinalTime() ,
"Final time");
700 pl->
set<
double>(
"Minimum Time Step" , getMinTimeStep() ,
"Minimum time step size");
701 pl->
set<
double>(
"Initial Time Step" , getInitTimeStep(),
"Initial time step size");
702 pl->
set<
double>(
"Maximum Time Step" , getMaxTimeStep() ,
"Maximum time step size");
703 pl->
set<
int> (
"Initial Time Index" , getInitIndex() ,
"Initial time index");
704 pl->
set<
int> (
"Final Time Index" , getFinalIndex() ,
"Final time index");
705 pl->
set<
int> (
"Number of Time Steps", getNumTimeSteps(),
706 "The number of constant time steps. The actual step size gets computed\n"
707 "on the fly given the size of the time domain. Overides and resets\n"
708 " 'Final Time Index' = 'Initial Time Index' + 'Number of Time Steps'\n"
709 " 'Initial Time Step' = "
710 "('Final Time' - 'Initial Time')/'Number of Time Steps'\n");
711 pl->
set<
double>(
"Maximum Absolute Error", getMaxAbsError() ,
"Maximum absolute error");
712 pl->
set<
double>(
"Maximum Relative Error", getMaxRelError() ,
"Maximum relative error");
714 pl->
set<
bool> (
"Print Time Step Changes", getPrintDtChanges(),
715 "Print timestep size when it changes");
717 auto event = timeEvent_->find(
"Output Index Interval");
718 if (event != Teuchos::null) {
720 pl->
set<
int> (
"Output Index Interval", teri->getIndexStride(),
"Output Index Interval");
723 event = timeEvent_->find(
"Output Time Interval");
724 if (event != Teuchos::null) {
726 pl->
set<
double>(
"Output Time Interval", ter->getTimeStride(),
"Output time interval");
729 pl->
set<
bool>(
"Output Exactly On Output Times", getOutputExactly(),
730 "This determines if the timestep size will be adjusted to exactly land\n"
731 "on the output times for 'Variable' timestepping (default=true).\n"
732 "When set to 'false' or for 'Constant' time stepping, the timestep\n"
733 "following the output time will be flagged for output.\n");
736 event = timeEvent_->find(
"Output Index List");
737 std::ostringstream list;
738 if (event != Teuchos::null) {
742 for(std::size_t i = 0; i < idx.size()-1; ++i) list << idx[i] <<
", ";
743 list << idx[idx.size()-1];
746 pl->
set<std::string>(
"Output Index List", list.str(),
747 "Comma deliminated list of output indices");
751 event = timeEvent_->find(
"Output Time List");
752 std::ostringstream list;
753 if (event != Teuchos::null) {
756 if (!times.empty()) {
757 for(std::size_t i = 0; i < times.size()-1; ++i) list << times[i] <<
", ";
758 list << times[times.size()-1];
761 pl->
set<std::string>(
"Output Time List", list.str(),
762 "Comma deliminated list of output times");
767 tecTmp->setTimeEvents(timeEvent_->getTimeEvents());
768 tecTmp->remove(
"Output Index Interval");
769 tecTmp->remove(
"Output Time Interval");
770 tecTmp->remove(
"Output Index List");
771 tecTmp->remove(
"Output Time List");
772 if (tecTmp->getSize() > 0)
773 pl->
set(
"Time Step Control Events", *tecTmp->getValidParameters());
776 pl->
set<
int> (
"Maximum Number of Stepper Failures", getMaxFailures(),
777 "Maximum number of Stepper failures");
778 pl->
set<
int> (
"Maximum Number of Consecutive Stepper Failures", getMaxConsecFailures(),
779 "Maximum number of consecutive Stepper failures");
781 pl->
set(
"Time Step Control Strategy", *stepControlStrategy_->getValidParameters());
789 template <
class Scalar>
798 if (pList == Teuchos::null || pList->
numParams() == 0)
return tsc;
800 auto tscValidPL = Teuchos::rcp_const_cast<ParameterList>(tsc->getValidParameters());
802 if (pList->
isSublist(
"Time Step Control Events")) {
803 RCP<ParameterList> tsctePL =
804 Teuchos::sublist(pList,
"Time Step Control Events",
true);
805 tscValidPL->set(
"Time Step Control Events", *tsctePL);
810 tsc->setInitTime( pList->
get<
double>(
"Initial Time"));
811 tsc->setFinalTime( pList->
get<
double>(
"Final Time"));
812 tsc->setMinTimeStep( pList->
get<
double>(
"Minimum Time Step"));
813 tsc->setInitTimeStep( pList->
get<
double>(
"Initial Time Step"));
814 tsc->setMaxTimeStep( pList->
get<
double>(
"Maximum Time Step"));
815 tsc->setInitIndex( pList->
get<
int> (
"Initial Time Index"));
816 tsc->setFinalIndex( pList->
get<
int> (
"Final Time Index"));
817 tsc->setMaxAbsError( pList->
get<
double>(
"Maximum Absolute Error"));
818 tsc->setMaxRelError( pList->
get<
double>(
"Maximum Relative Error"));
819 tsc->setMaxFailures( pList->
get<
int> (
"Maximum Number of Stepper Failures"));
820 tsc->setMaxConsecFailures(pList->
get<
int> (
"Maximum Number of Consecutive Stepper Failures"));
821 tsc->setPrintDtChanges( pList->
get<
bool> (
"Print Time Step Changes"));
822 tsc->setNumTimeSteps( pList->
get<
int> (
"Number of Time Steps"));
826 tec->setName(
"Time Step Control Events");
829 std::vector<int> outputIndices;
830 outputIndices.clear();
831 std::string str = pList->
get<std::string>(
"Output Index List");
832 std::string delimiters(
",");
833 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
834 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
835 while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
836 std::string token = str.substr(lastPos,pos-lastPos);
837 outputIndices.push_back(
int(std::stoi(token)));
838 if(pos==std::string::npos)
break;
840 lastPos = str.find_first_not_of(delimiters, pos);
841 pos = str.find_first_of(delimiters, lastPos);
844 if (!outputIndices.empty()) {
846 std::sort(outputIndices.begin(),outputIndices.end());
847 outputIndices.erase(std::unique(outputIndices.begin(),
848 outputIndices.end() ),
849 outputIndices.end() );
852 outputIndices,
"Output Index List")));
858 tsc->getInitIndex(), tsc->getFinalIndex(),
859 pList->
get<
int>(
"Output Index Interval"),
860 "Output Index Interval")));
862 auto outputExactly = pList->
get<
bool>(
"Output Exactly On Output Times",
true);
865 std::vector<Scalar> outputTimes;
867 std::string str = pList->
get<std::string>(
"Output Time List");
868 std::string delimiters(
",");
870 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
872 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
873 while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
875 std::string token = str.substr(lastPos,pos-lastPos);
876 outputTimes.push_back(Scalar(std::stod(token)));
877 if(pos==std::string::npos)
break;
879 lastPos = str.find_first_not_of(delimiters, pos);
880 pos = str.find_first_of(delimiters, lastPos);
883 if (!outputTimes.empty()) {
885 std::sort(outputTimes.begin(),outputTimes.end());
886 outputTimes.erase(std::unique(outputTimes.begin(),
891 outputTimes,
"Output Time List", outputExactly)));
897 tsc->getInitTime(), tsc->getFinalTime(),
898 pList->
get<
double>(
"Output Time Interval"),
899 "Output Time Interval", outputExactly)));
901 if (pList->
isSublist(
"Time Step Control Events")) {
902 RCP<ParameterList> tsctePL =
903 Teuchos::sublist(pList,
"Time Step Control Events",
true);
905 auto timeEventType = tsctePL->get<std::string>(
"Type",
"Unknown");
906 if (timeEventType ==
"Range") {
907 tec->add(createTimeEventRange<Scalar>(tsctePL));
908 }
else if (timeEventType ==
"Range Index") {
909 tec->add(createTimeEventRangeIndex<Scalar>(tsctePL));
910 }
else if (timeEventType ==
"List") {
911 tec->add(createTimeEventList<Scalar>(tsctePL));
912 }
else if (timeEventType ==
"List Index") {
913 tec->add(createTimeEventListIndex<Scalar>(tsctePL));
914 }
else if (timeEventType ==
"Composite") {
915 auto tecTmp = createTimeEventComposite<Scalar>(tsctePL);
916 auto timeEvents = tecTmp->getTimeEvents();
917 for(
auto& e : timeEvents) tec->add(e);
919 RCP<Teuchos::FancyOStream> out =
920 Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
921 out->setOutputToRootOnly(0);
923 *out <<
"Warning -- Unknown Time Event Type!\n"
924 <<
"'Type' = '" << timeEventType <<
"'\n"
925 <<
"Should call add() with this "
926 <<
"(app-specific?) Time Event.\n" << std::endl;
930 tsc->setTimeEvents(tec);
932 if ( !pList->
isParameter(
"Time Step Control Strategy") ) {
934 tsc->setTimeStepControlStrategy();
938 RCP<ParameterList> tscsPL =
939 Teuchos::sublist(pList,
"Time Step Control Strategy",
true);
941 auto strategyType = tscsPL->get<std::string>(
"Strategy Type");
942 if (strategyType ==
"Constant") {
943 tsc->setTimeStepControlStrategy(
944 createTimeStepControlStrategyConstant<Scalar>(tscsPL));
945 }
else if (strategyType ==
"Basic VS") {
946 tsc->setTimeStepControlStrategy(
947 createTimeStepControlStrategyBasicVS<Scalar>(tscsPL));
948 }
else if (strategyType ==
"Integral Controller") {
949 tsc->setTimeStepControlStrategy(
950 createTimeStepControlStrategyIntegralController<Scalar>(tscsPL));
951 }
else if (strategyType ==
"Composite") {
952 tsc->setTimeStepControlStrategy(
953 createTimeStepControlStrategyComposite<Scalar>(tscsPL));
955 RCP<Teuchos::FancyOStream> out =
956 Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
957 out->setOutputToRootOnly(0);
959 *out <<
"Warning -- Did not find a Tempus strategy to create!\n"
960 <<
"'Strategy Type' = '" << strategyType <<
"'\n"
961 <<
"Should call setTimeStepControlStrategy() with this\n"
962 <<
"(app-specific?) strategy, and initialize().\n" << std::endl;
966 if (runInitialize) tsc->initialize();
972 #endif // Tempus_TimeStepControl_impl_hpp
TimeEventRangeIndex specifies a start, stop and stride index.
virtual void checkInitialized()
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 setTimeEvents(Teuchos::RCP< TimeEventComposite< Scalar > > teb=Teuchos::null)
virtual void setOutputTimes(std::vector< Scalar > outputTimes)
virtual void setOutputIndexInterval(int i)
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)
virtual void setTimeStepControlStrategy(Teuchos::RCP< TimeStepControlStrategy< Scalar > > tscs=Teuchos::null)
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)
StepControlStrategy class for TimeStepControl.
RCP< std::basic_ostream< char_type, traits_type > > getOStream()
virtual void setNextTimeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory, Status &integratorStatus)
Determine the time step size.
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.