10 #ifndef Tempus_IntegratorBasic_impl_hpp
11 #define Tempus_IntegratorBasic_impl_hpp
13 #include "Thyra_VectorStdOps.hpp"
16 #include "Tempus_StepperFactory.hpp"
17 #include "Tempus_StepperForwardEuler.hpp"
21 template <
class Scalar>
23 : outputScreenIndices_(std::vector<int>()),
24 outputScreenInterval_(1000000),
43 template <
class Scalar>
49 std::vector<int> outputScreenIndices,
int outputScreenInterval)
50 : outputScreenIndices_(outputScreenIndices),
51 outputScreenInterval_(outputScreenInterval),
68 template <
class Scalar>
71 this->setIntegratorType(iB->getIntegratorType());
72 this->setIntegratorName(iB->getIntegratorName());
73 this->setStepper(iB->getStepper());
74 this->setSolutionHistory(iB->getNonConstSolutionHistory());
75 this->setTimeStepControl(iB->getNonConstTimeStepControl());
76 this->setObserver(iB->getObserver());
77 this->setScreenOutputIndexList(iB->getScreenOutputIndexList());
78 this->setScreenOutputIndexInterval(iB->getScreenOutputIndexInterval());
79 this->setStatus(iB->getStatus());
80 integratorTimer_ = iB->getIntegratorTimer();
81 stepperTimer_ = iB->getStepperTimer();
84 template <
class Scalar>
88 i !=
"Integrator Basic", std::logic_error,
89 "Error - Integrator Type should be 'Integrator Basic'\n");
91 this->integratorType_ = i;
94 template <
class Scalar>
99 stepper_ == Teuchos::null, std::logic_error,
100 "Error - setModel(), need to set stepper first!\n");
102 stepper_->setModel(model);
105 template <
class Scalar>
108 if (stepper == Teuchos::null)
115 template <
class Scalar>
121 if (solutionHistory_ == Teuchos::null) {
125 solutionHistory_->clear();
129 stepper_ == Teuchos::null, std::logic_error,
130 "Error - initializeSolutionHistory(), need to set stepper first!\n");
132 if (state == Teuchos::null) {
135 "Error - initializeSolutionHistory(), need to "
136 "set stepper's model first!\n");
139 stepper_->getDefaultStepperState());
141 if (timeStepControl_ != Teuchos::null) {
143 state->setTime(timeStepControl_->getInitTime());
144 state->setIndex(timeStepControl_->getInitIndex());
145 state->setTimeStep(timeStepControl_->getInitTimeStep());
146 state->setTolRel(timeStepControl_->getMaxRelError());
147 state->setTolAbs(timeStepControl_->getMaxAbsError());
149 state->setOrder(stepper_->getOrder());
153 solutionHistory_->addState(state);
155 stepper_->setInitialConditions(solutionHistory_);
158 template <
class Scalar>
167 RCP<Thyra::VectorBase<Scalar> > xdot = x0->clone_v();
168 RCP<Thyra::VectorBase<Scalar> > xdotdot = x0->clone_v();
169 if (xdot0 == Teuchos::null)
172 Thyra::assign(xdot.ptr(), *(xdot0));
173 if (xdotdot0 == Teuchos::null)
176 Thyra::assign(xdotdot.ptr(), *(xdotdot0));
179 stepper_ == Teuchos::null, std::logic_error,
180 "Error - initializeSolutionHistory(), need to set stepper first!\n");
183 state->setStepperState(stepper_->getDefaultStepperState());
186 if (timeStepControl_ != Teuchos::null) {
188 state->setIndex(timeStepControl_->getInitIndex());
189 state->setTimeStep(timeStepControl_->getInitTimeStep());
190 state->setTolRel(timeStepControl_->getMaxRelError());
191 state->setTolAbs(timeStepControl_->getMaxAbsError());
193 state->setOrder(stepper_->getOrder());
196 initializeSolutionHistory(state);
199 template <
class Scalar>
203 if (sh == Teuchos::null) {
205 if (solutionHistory_ == Teuchos::null)
209 solutionHistory_ = sh;
213 template <
class Scalar>
217 if (tsc == Teuchos::null) {
219 if (timeStepControl_ == Teuchos::null) {
225 timeStepControl_ = tsc;
229 template <
class Scalar>
233 if (obs == Teuchos::null)
236 integratorObserver_ = obs;
239 template <
class Scalar>
243 stepper_ == Teuchos::null, std::logic_error,
244 "Error - Need to set the Stepper, setStepper(), before calling "
245 "IntegratorBasic::initialize()\n");
248 solutionHistory_->getNumStates() < 1, std::out_of_range,
249 "Error - SolutionHistory requires at least one SolutionState.\n"
250 <<
" Supplied SolutionHistory has only "
251 << solutionHistory_->getNumStates() <<
" SolutionStates.\n");
253 stepper_->initialize();
254 solutionHistory_->initialize();
255 timeStepControl_->initialize();
257 isInitialized_ =
true;
260 template <
class Scalar>
263 std::string name =
"Tempus::IntegratorBasic";
267 template <
class Scalar>
271 auto l_out = Teuchos::fancyOStream(out.
getOStream());
273 l_out->setOutputToRootOnly(0);
275 *l_out <<
"\n--- " << this->description() <<
" ---" << std::endl;
277 if (solutionHistory_ != Teuchos::null) {
278 solutionHistory_->describe(*l_out, verbLevel);
281 *l_out <<
"solutionHistory = " << solutionHistory_ << std::endl;
284 if (timeStepControl_ != Teuchos::null) {
285 timeStepControl_->describe(out, verbLevel);
288 *l_out <<
"timeStepControl = " << timeStepControl_ << std::endl;
291 if (stepper_ != Teuchos::null) {
292 stepper_->describe(out, verbLevel);
295 *l_out <<
"stepper = " << stepper_ << std::endl;
297 *l_out << std::string(this->description().length() + 8,
'-') << std::endl;
300 template <
class Scalar>
303 if (timeStepControl_->timeInRange(timeFinal))
304 timeStepControl_->setFinalTime(timeFinal);
305 bool itgrStatus = advanceTime();
309 template <
class Scalar>
314 if (isInitialized_ ==
false) {
316 *out <<
"Failure - IntegratorBasic is not initialized." << std::endl;
322 auto cs = solutionHistory_->getCurrentState();
323 cs->setTolRel(timeStepControl_->getMaxRelError());
324 cs->setTolAbs(timeStepControl_->getMaxAbsError());
326 integratorTimer_->start();
328 const Scalar initDt = std::min(timeStepControl_->getInitTimeStep(),
329 stepper_->getInitTimeStep(solutionHistory_));
331 timeStepControl_->setInitTimeStep(initDt);
332 timeStepControl_->initialize();
336 template <
class Scalar>
339 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::IntegratorBasic::advanceTime()");
342 integratorObserver_->observeStartIntegrator(*
this);
345 integratorStatus_ ==
WORKING &&
346 timeStepControl_->timeInRange(solutionHistory_->getCurrentTime()) &&
347 timeStepControl_->indexInRange(solutionHistory_->getCurrentIndex())) {
348 stepperTimer_->reset();
349 stepperTimer_->start();
350 solutionHistory_->initWorkingState();
353 integratorObserver_->observeStartTimeStep(*
this);
355 timeStepControl_->setNextTimeStep(solutionHistory_, integratorStatus_);
356 integratorObserver_->observeNextTimeStep(*
this);
359 solutionHistory_->getWorkingState()->setSolutionStatus(
WORKING);
361 integratorObserver_->observeBeforeTakeStep(*
this);
363 stepper_->takeStep(solutionHistory_);
365 integratorObserver_->observeAfterTakeStep(*
this);
367 stepperTimer_->stop();
369 integratorObserver_->observeAfterCheckTimeStep(*
this);
371 solutionHistory_->promoteWorkingState();
372 integratorObserver_->observeEndTimeStep(*
this);
376 integratorObserver_->observeEndIntegrator(*
this);
382 template <
class Scalar>
385 auto ws = solutionHistory_->getWorkingState();
388 ws->setTolRel(timeStepControl_->getMaxRelError());
389 ws->setTolAbs(timeStepControl_->getMaxAbsError());
392 std::vector<int>::const_iterator it = std::find(
393 outputScreenIndices_.begin(), outputScreenIndices_.end(), ws->getIndex());
394 if (it == outputScreenIndices_.end())
395 ws->setOutputScreen(
false);
397 ws->setOutputScreen(
true);
399 const int initial = timeStepControl_->getInitIndex();
400 if ((ws->getIndex() - initial) % outputScreenInterval_ == 0)
401 ws->setOutputScreen(
true);
404 template <
class Scalar>
408 auto ws = solutionHistory_->getWorkingState();
411 if (ws->getNFailures() >= timeStepControl_->getMaxFailures()) {
412 RCP<Teuchos::FancyOStream> out = this->getOStream();
413 out->setOutputToRootOnly(0);
415 *out <<
"Failure - Stepper has failed more than the maximum allowed.\n"
416 <<
" (nFailures = " << ws->getNFailures()
417 <<
") >= (nFailuresMax = " << timeStepControl_->getMaxFailures() <<
")"
422 if (ws->getNConsecutiveFailures() >=
423 timeStepControl_->getMaxConsecFailures()) {
424 RCP<Teuchos::FancyOStream> out = this->getOStream();
425 out->setOutputToRootOnly(0);
427 *out <<
"Failure - Stepper has failed more than the maximum "
428 <<
"consecutive allowed.\n"
429 <<
" (nConsecutiveFailures = " << ws->getNConsecutiveFailures()
430 <<
") >= (nConsecutiveFailuresMax = "
431 << timeStepControl_->getMaxConsecFailures() <<
")" << std::endl;
437 if (ws->getTimeStep() <= timeStepControl_->getMinTimeStep() &&
439 RCP<Teuchos::FancyOStream> out = this->getOStream();
440 out->setOutputToRootOnly(0);
442 *out <<
"Failure - Stepper has failed and the time step size is "
443 <<
"at the minimum.\n"
444 <<
" Solution Status = " <<
toString(ws->getSolutionStatus())
446 <<
" (TimeStep = " << ws->getTimeStep()
447 <<
") <= (Minimum TimeStep = " << timeStepControl_->getMinTimeStep()
456 ((timeStepControl_->getStepType() ==
"Constant") &&
457 !
approxEqual(ws->getTimeStep(), timeStepControl_->getInitTimeStep()))) {
458 RCP<Teuchos::FancyOStream> out = this->getOStream();
459 out->setOutputToRootOnly(0);
461 *out << std::scientific << std::setw(6) << std::setprecision(3)
462 << ws->getIndex() << std::setw(11) << std::setprecision(3)
463 << ws->getTime() << std::setw(11) << std::setprecision(3)
464 << ws->getTimeStep() <<
" STEP FAILURE!! - ";
466 *out <<
"Solution Status = " <<
toString(ws->getSolutionStatus())
469 else if ((timeStepControl_->getStepType() ==
"Constant") &&
470 (ws->getTimeStep() != timeStepControl_->getInitTimeStep())) {
471 *out <<
"dt != Constant dt (=" << timeStepControl_->getInitTimeStep()
475 ws->setNFailures(ws->getNFailures() + 1);
476 ws->setNRunningFailures(ws->getNRunningFailures() + 1);
477 ws->setNConsecutiveFailures(ws->getNConsecutiveFailures() + 1);
486 template <
class Scalar>
489 std::string exitStatus;
490 if (solutionHistory_->getCurrentState()->getSolutionStatus() ==
493 exitStatus =
"Time integration FAILURE!";
497 exitStatus =
"Time integration complete.";
500 integratorTimer_->stop();
503 template <
class Scalar>
507 std::string delimiters(
",");
508 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
509 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
510 while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
511 std::string token = str.substr(lastPos, pos - lastPos);
512 outputScreenIndices_.push_back(
int(std::stoi(token)));
513 if (pos == std::string::npos)
break;
515 lastPos = str.find_first_not_of(delimiters, pos);
516 pos = str.find_first_of(delimiters, lastPos);
520 std::sort(outputScreenIndices_.begin(), outputScreenIndices_.end());
521 outputScreenIndices_.erase(
522 std::unique(outputScreenIndices_.begin(), outputScreenIndices_.end()),
523 outputScreenIndices_.end());
527 template <
class Scalar>
530 std::stringstream ss;
531 for (
size_t i = 0; i < outputScreenIndices_.size(); ++i) {
532 if (i != 0) ss <<
", ";
533 ss << outputScreenIndices_[i];
540 template <
class Scalar>
545 Teuchos::parameterList(getIntegratorName());
547 pl->
set(
"Integrator Type", getIntegratorType(),
548 "'Integrator Type' must be 'Integrator Basic'.");
550 pl->
set(
"Screen Output Index List", getScreenOutputIndexListString(),
551 "Screen Output Index List. Required to be in TimeStepControl range "
552 "['Minimum Time Step Index', 'Maximum Time Step Index']");
554 pl->
set(
"Screen Output Index Interval", getScreenOutputIndexInterval(),
555 "Screen Output Index Interval (e.g., every 100 time steps)");
557 pl->
set(
"Stepper Name", stepper_->getStepperName(),
558 "'Stepper Name' selects the Stepper block to construct (Required).");
560 pl->
set(
"Solution History", *solutionHistory_->getValidParameters());
561 pl->
set(
"Time Step Control", *timeStepControl_->getValidParameters());
564 Teuchos::parameterList(
"Tempus");
566 tempusPL->
set(
"Integrator Name", pl->
name());
567 tempusPL->
set(pl->
name(), *pl);
568 tempusPL->
set(stepper_->getStepperName(), *stepper_->getValidParameters());
575 template <
class Scalar>
580 if (tempusPL == Teuchos::null || tempusPL->
numParams() == 0)
583 auto integratorName = tempusPL->
get<std::string>(
"Integrator Name");
584 auto integratorPL = Teuchos::sublist(tempusPL, integratorName,
true);
586 std::string integratorType =
587 integratorPL->get<std::string>(
"Integrator Type");
589 integratorType !=
"Integrator Basic", std::logic_error,
590 "Error - For IntegratorBasic, 'Integrator Type' should be "
591 <<
"'Integrator Basic'.\n"
592 <<
" Integrator Type = " << integratorType <<
"\n");
594 integrator->setIntegratorName(integratorName);
598 integrator->getValidParameters());
599 auto vIntegratorName = validPL->template get<std::string>(
"Integrator Name");
600 auto vIntegratorPL = Teuchos::sublist(validPL, vIntegratorName,
true);
601 integratorPL->validateParametersAndSetDefaults(*vIntegratorPL, 1);
604 if (integratorPL->isParameter(
"Stepper Name")) {
606 auto stepperName = integratorPL->get<std::string>(
"Stepper Name");
607 auto stepperPL = Teuchos::sublist(tempusPL, stepperName,
true);
608 stepperPL->setName(stepperName);
610 integrator->setStepper(sf->createStepper(stepperPL));
615 integrator->setStepper(stepper);
619 if (integratorPL->isSublist(
"Time Step Control")) {
621 auto tscPL = Teuchos::sublist(integratorPL,
"Time Step Control",
true);
622 integrator->setTimeStepControl(
623 createTimeStepControl<Scalar>(tscPL, runInitialize));
631 if (integratorPL->isSublist(
"Solution History")) {
633 auto shPL = Teuchos::sublist(integratorPL,
"Solution History",
true);
634 auto sh = createSolutionHistoryPL<Scalar>(shPL);
635 integrator->setSolutionHistory(sh);
639 integrator->setSolutionHistory(createSolutionHistory<Scalar>());
643 integrator->setObserver(Teuchos::null);
646 integrator->setScreenOutputIndexInterval(
647 integratorPL->get<
int>(
"Screen Output Index Interval",
648 integrator->getScreenOutputIndexInterval()));
651 auto str = integratorPL->get<std::string>(
"Screen Output Index List",
"");
652 integrator->setScreenOutputIndexList(str);
659 template <
class Scalar>
665 auto integrator = createIntegratorBasic<Scalar>(tempusPL, runInitialize);
666 if (model == Teuchos::null)
return integrator;
669 integrator->setModel(constModel);
674 integrator->getStepper()->getDefaultStepperState());
675 newState->setTime(integrator->getTimeStepControl()->getInitTime());
676 newState->setIndex(integrator->getTimeStepControl()->getInitIndex());
677 newState->setTimeStep(integrator->getTimeStepControl()->getInitTimeStep());
678 newState->setTolRel(integrator->getTimeStepControl()->getMaxRelError());
679 newState->setTolAbs(integrator->getTimeStepControl()->getMaxAbsError());
680 newState->setOrder(integrator->getStepper()->getOrder());
684 auto sh = integrator->getNonConstSolutionHistory();
685 sh->addState(newState);
686 integrator->getStepper()->setInitialConditions(sh);
688 if (runInitialize) integrator->initialize();
694 template <
class Scalar>
697 std::string stepperType)
702 auto stepper = sf->createStepper(stepperType, model);
703 integrator->setStepper(stepper);
704 integrator->initializeSolutionHistory();
705 integrator->initialize();
711 template <
class Scalar>
718 template <
class Scalar>
724 auto integratorName = tempusPL->
get<std::string>(
"Integrator Name");
725 auto integratorPL = Teuchos::sublist(tempusPL, integratorName,
true);
727 std::string integratorType =
728 integratorPL->get<std::string>(
"Integrator Type");
730 integratorType !=
"Integrator Basic", std::logic_error,
731 "Error - For IntegratorBasic, 'Integrator Type' should be "
732 <<
"'Integrator Basic'.\n"
733 <<
" Integrator Type = " << integratorType <<
"\n");
736 integrator->setIntegratorName(integratorName);
738 TEUCHOS_TEST_FOR_EXCEPTION(
739 !integratorPL->isParameter(
"Stepper Name"), std::logic_error,
740 "Error - Need to set the 'Stepper Name' in 'Integrator Basic'.\n");
742 auto stepperName = integratorPL->get<std::string>(
"Stepper Name");
743 TEUCHOS_TEST_FOR_EXCEPTION(
744 stepperName ==
"Operator Split", std::logic_error,
745 "Error - 'Stepper Name' should be 'Operator Split'.\n");
748 auto stepperPL = Teuchos::sublist(tempusPL, stepperName,
true);
749 stepperPL->setName(stepperName);
751 integrator->setStepper(sf->createStepper(stepperPL, models));
754 if (integratorPL->isSublist(
"Time Step Control")) {
756 auto tscPL = Teuchos::sublist(integratorPL,
"Time Step Control",
true);
757 integrator->setTimeStepControl(
758 createTimeStepControl<Scalar>(tscPL, runInitialize));
768 integrator->getStepper()->getDefaultStepperState());
769 newState->setTime(integrator->getTimeStepControl()->getInitTime());
770 newState->setIndex(integrator->getTimeStepControl()->getInitIndex());
771 newState->setTimeStep(integrator->getTimeStepControl()->getInitTimeStep());
772 newState->setTolRel(integrator->getTimeStepControl()->getMaxRelError());
773 newState->setTolAbs(integrator->getTimeStepControl()->getMaxAbsError());
774 newState->setOrder(integrator->getStepper()->getOrder());
778 auto shPL = Teuchos::sublist(integratorPL,
"Solution History",
true);
779 auto sh = createSolutionHistoryPL<Scalar>(shPL);
780 sh->addState(newState);
781 integrator->getStepper()->setInitialConditions(sh);
782 integrator->setSolutionHistory(sh);
785 integrator->setObserver(Teuchos::null);
788 integrator->setScreenOutputIndexInterval(
789 integratorPL->get<
int>(
"Screen Output Index Interval",
790 integrator->getScreenOutputIndexInterval()));
793 auto str = integratorPL->get<std::string>(
"Screen Output Index List",
"");
794 integrator->setScreenOutputIndexList(str);
797 integrator->getValidParameters());
800 auto vIntegratorName = validPL->template get<std::string>(
"Integrator Name");
801 auto vIntegratorPL = Teuchos::sublist(validPL, vIntegratorName,
true);
802 integratorPL->validateParametersAndSetDefaults(*vIntegratorPL);
805 auto vStepperName = vIntegratorPL->template get<std::string>(
"Stepper Name");
806 auto vStepperPL = Teuchos::sublist(validPL, vStepperName,
true);
807 stepperPL->validateParametersAndSetDefaults(*vStepperPL);
809 integrator->initialize();
815 #endif // Tempus_IntegratorBasic_impl_hpp
virtual bool advanceTime()
Advance the solution to timeMax, and return true if successful.
Teuchos::RCP< SolutionState< Scalar > > createSolutionStateX(const Teuchos::RCP< Thyra::VectorBase< Scalar > > &x, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &xdot=Teuchos::null, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &xdotdot=Teuchos::null)
Nonmember constructor from non-const solution vectors, x.
const std::string & name() const
virtual void setModel(Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > model)
Set the model on the stepper.
const std::string toString(const Status status)
Convert Status to string.
Teuchos::RCP< Teuchos::Time > integratorTimer_
T & get(const std::string &name, T def_value)
std::string description() const override
virtual void setTimeStepControl(Teuchos::RCP< TimeStepControl< Scalar > > tsc=Teuchos::null)
Set the TimeStepControl.
Forward Euler time stepper.
virtual void setObserver(Teuchos::RCP< IntegratorObserver< Scalar > > obs=Teuchos::null)
Set the Observer.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Teuchos::RCP< Teuchos::Time > stepperTimer_
virtual std::string getScreenOutputIndexListString() const
IntegratorObserverBasic class for time integrators. This basic class has simple no-op functions...
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Create valid IntegratorBasic ParameterList.
Ordinal numParams() const
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
virtual void setStepper(Teuchos::RCP< Stepper< Scalar > > stepper)
Set the Stepper.
Thyra Base interface for time steppers.
virtual void checkTimeStep()
Check if time step has passed or failed.
virtual void setSolutionHistory(Teuchos::RCP< SolutionHistory< Scalar > > sh=Teuchos::null)
Set the SolutionHistory.
bool approxEqual(Scalar a, Scalar b, Scalar relTol=numericalTol< Scalar >())
Test if values are approximately equal within the relative tolerance.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
IntegratorObserver class for time integrators.
TimeStepControl manages the time step size. There several mechanisms that effect the time step size a...
virtual void initializeSolutionHistory(Teuchos::RCP< SolutionState< Scalar > > state=Teuchos::null)
Set the initial state which has the initial conditions.
virtual void setScreenOutputIndexList(std::vector< int > indices)
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
void setIntegratorName(std::string i)
Set the Integrator Name.
Teuchos::RCP< SolutionState< Scalar > > createSolutionStateME(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, const Teuchos::RCP< StepperState< Scalar > > &stepperState=Teuchos::null, const Teuchos::RCP< PhysicsState< Scalar > > &physicsState=Teuchos::null)
Nonmember constructor from Thyra ModelEvaluator.
virtual void initialize()
Initializes the Integrator after set* function calls.
virtual void endIntegrator()
Perform tasks after end of integrator.
virtual void startIntegrator()
Perform tasks before start of integrator.
void setIntegratorType(std::string i)
Set the Integrator Type.
RCP< std::basic_ostream< char_type, traits_type > > getOStream()
virtual void copy(Teuchos::RCP< IntegratorBasic< Scalar > > iB)
Copy (a shallow copy)
virtual void startTimeStep()
Start time step.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const override
Teuchos::RCP< IntegratorBasic< Scalar > > createIntegratorBasic(Teuchos::RCP< Teuchos::ParameterList > pList, bool runInitialize=true)
Nonmember constructor.
Solution state for integrators and steppers.