9 #ifndef Tempus_IntegratorBasic_impl_hpp
10 #define Tempus_IntegratorBasic_impl_hpp
12 #include "Thyra_VectorStdOps.hpp"
14 #include "Tempus_StepperFactory.hpp"
15 #include "Tempus_StepperForwardEuler.hpp"
20 template<
class Scalar>
22 : outputScreenIndices_(std::vector<int>()),
23 outputScreenInterval_(1000000),
40 template<
class Scalar>
46 std::vector<int> outputScreenIndices,
47 int outputScreenInterval)
48 : outputScreenIndices_(outputScreenIndices),
49 outputScreenInterval_(outputScreenInterval),
66 template<
class Scalar>
70 "Error - Integrator Type should be 'Integrator Basic'\n");
72 this->integratorType_ = i;
76 template<
class Scalar>
81 "Error - setModel(), need to set stepper first!\n");
83 stepper_->setModel(model);
87 template<
class Scalar>
91 if (stepper == Teuchos::null)
98 template<
class Scalar>
104 if (solutionHistory_ == Teuchos::null) {
107 solutionHistory_->clear();
111 "Error - initializeSolutionHistory(), need to set stepper first!\n");
113 if (state == Teuchos::null) {
116 "Error - initializeSolutionHistory(), need to set stepper's model first!\n");
119 stepper_->getDefaultStepperState());
121 if (timeStepControl_ != Teuchos::null) {
123 state->setTime (timeStepControl_->getInitTime());
124 state->setIndex (timeStepControl_->getInitIndex());
125 state->setTimeStep(timeStepControl_->getInitTimeStep());
126 state->setTolRel (timeStepControl_->getMaxRelError());
127 state->setTolAbs (timeStepControl_->getMaxAbsError());
129 state->setOrder (stepper_->getOrder());
133 solutionHistory_->addState(state);
135 stepper_->setInitialConditions(solutionHistory_);
139 template<
class Scalar>
149 RCP<Thyra::VectorBase<Scalar> > xdot = x0->clone_v();
150 RCP<Thyra::VectorBase<Scalar> > xdotdot = x0->clone_v();
151 if (xdot0 == Teuchos::null)
154 Thyra::assign(xdot.ptr(), *(xdot0));
155 if (xdotdot0 == Teuchos::null)
158 Thyra::assign(xdotdot.ptr(), *(xdotdot0));
161 "Error - initializeSolutionHistory(), need to set stepper first!\n");
164 state->setStepperState(stepper_->getDefaultStepperState());
167 if (timeStepControl_ != Teuchos::null) {
169 state->setIndex (timeStepControl_->getInitIndex());
170 state->setTimeStep(timeStepControl_->getInitTimeStep());
171 state->setTolRel (timeStepControl_->getMaxRelError());
172 state->setTolAbs (timeStepControl_->getMaxAbsError());
174 state->setOrder (stepper_->getOrder());
177 initializeSolutionHistory(state);
181 template<
class Scalar>
185 if (sh == Teuchos::null) {
187 if (solutionHistory_ == Teuchos::null)
190 solutionHistory_ = sh;
195 template<
class Scalar>
199 if (tsc == Teuchos::null) {
201 if (timeStepControl_ == Teuchos::null) {
206 timeStepControl_ = tsc;
211 template<
class Scalar>
215 if (obs == Teuchos::null)
218 integratorObserver_ = obs;
222 template<
class Scalar>
226 "Error - Need to set the Stepper, setStepper(), before calling "
227 "IntegratorBasic::initialize()\n");
231 "Error - SolutionHistory requires at least one SolutionState.\n"
232 <<
" Supplied SolutionHistory has only "
233 << solutionHistory_->getNumStates() <<
" SolutionStates.\n");
235 stepper_->initialize();
236 solutionHistory_->initialize();
237 timeStepControl_->initialize();
239 isInitialized_ =
true;
243 template<
class Scalar>
246 std::string name =
"Tempus::IntegratorBasic";
251 template<
class Scalar>
256 auto out = Teuchos::fancyOStream( in_out.
getOStream() );
257 out->setOutputToRootOnly(0);
258 *out << description() <<
"::describe" << std::endl;
259 *out <<
"solutionHistory= " << solutionHistory_->description()<<std::endl;
260 *out <<
"timeStepControl= " << timeStepControl_->description()<<std::endl;
261 *out <<
"stepper = " << stepper_ ->description()<<std::endl;
263 if (Teuchos::as<int>(verbLevel) >=
265 *out <<
"solutionHistory= " << std::endl;
266 solutionHistory_->describe(in_out,verbLevel);
267 *out <<
"timeStepControl= " << std::endl;
268 timeStepControl_->describe(in_out,verbLevel);
269 *out <<
"stepper = " << std::endl;
270 stepper_ ->describe(in_out,verbLevel);
275 template <
class Scalar>
278 if (timeStepControl_->timeInRange(timeFinal))
279 timeStepControl_->setFinalTime(timeFinal);
280 bool itgrStatus = advanceTime();
285 template <
class Scalar>
290 if (isInitialized_ ==
false) {
292 *out <<
"Failure - IntegratorBasic is not initialized." << std::endl;
298 auto cs = solutionHistory_->getCurrentState();
299 cs->setTolRel(timeStepControl_->getMaxRelError());
300 cs->setTolAbs(timeStepControl_->getMaxAbsError());
302 integratorTimer_->start();
304 const Scalar initDt =
305 std::min(timeStepControl_->getInitTimeStep(),
306 stepper_->getInitTimeStep(solutionHistory_));
308 timeStepControl_->setInitTimeStep(initDt);
309 timeStepControl_->initialize();
314 template <
class Scalar>
317 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::IntegratorBasic::advanceTime()");
320 integratorObserver_->observeStartIntegrator(*
this);
322 while (integratorStatus_ ==
WORKING &&
323 timeStepControl_->timeInRange (solutionHistory_->getCurrentTime()) &&
324 timeStepControl_->indexInRange(solutionHistory_->getCurrentIndex())){
326 stepperTimer_->reset();
327 stepperTimer_->start();
328 solutionHistory_->initWorkingState();
331 integratorObserver_->observeStartTimeStep(*
this);
333 timeStepControl_->setNextTimeStep(solutionHistory_, integratorStatus_);
334 integratorObserver_->observeNextTimeStep(*
this);
337 solutionHistory_->getWorkingState()->setSolutionStatus(
WORKING);
339 integratorObserver_->observeBeforeTakeStep(*
this);
341 stepper_->takeStep(solutionHistory_);
343 integratorObserver_->observeAfterTakeStep(*
this);
345 stepperTimer_->stop();
347 integratorObserver_->observeAfterCheckTimeStep(*
this);
349 solutionHistory_->promoteWorkingState();
350 integratorObserver_->observeEndTimeStep(*
this);
354 integratorObserver_->observeEndIntegrator(*
this);
361 template <
class Scalar>
364 auto ws = solutionHistory_->getWorkingState();
367 ws->setTolRel(timeStepControl_->getMaxRelError());
368 ws->setTolAbs(timeStepControl_->getMaxAbsError());
371 std::vector<int>::const_iterator it =
372 std::find(outputScreenIndices_.begin(),
373 outputScreenIndices_.end(),
375 if (it == outputScreenIndices_.end())
376 ws->setOutputScreen(
false);
378 ws->setOutputScreen(
true);
380 const int initial = timeStepControl_->getInitIndex();
381 if ( (ws->getIndex() - initial) % outputScreenInterval_ == 0)
382 ws->setOutputScreen(
true);
386 template <
class Scalar>
390 auto ws = solutionHistory_->getWorkingState();
393 if (ws->getNFailures() >= timeStepControl_->getMaxFailures()) {
394 RCP<Teuchos::FancyOStream> out = this->getOStream();
395 out->setOutputToRootOnly(0);
397 *out <<
"Failure - Stepper has failed more than the maximum allowed.\n"
398 <<
" (nFailures = "<<ws->getNFailures()<<
") >= (nFailuresMax = "
399 << timeStepControl_->getMaxFailures()<<
")" << std::endl;
403 if (ws->getNConsecutiveFailures()
404 >= timeStepControl_->getMaxConsecFailures()){
405 RCP<Teuchos::FancyOStream> out = this->getOStream();
406 out->setOutputToRootOnly(0);
408 *out <<
"Failure - Stepper has failed more than the maximum "
409 <<
"consecutive allowed.\n"
410 <<
" (nConsecutiveFailures = "<<ws->getNConsecutiveFailures()
411 <<
") >= (nConsecutiveFailuresMax = "
412 << timeStepControl_->getMaxConsecFailures()
421 ((timeStepControl_->getStepType() ==
"Constant") &&
422 (ws->getTimeStep() != timeStepControl_->getInitTimeStep()) &&
423 (ws->getOutput() !=
true) &&
424 (ws->getTime() != timeStepControl_->getFinalTime())
428 RCP<Teuchos::FancyOStream> out = this->getOStream();
429 out->setOutputToRootOnly(0);
431 *out <<std::scientific
432 <<std::setw( 6)<<std::setprecision(3)<<ws->getIndex()
433 <<std::setw(11)<<std::setprecision(3)<<ws->getTime()
434 <<std::setw(11)<<std::setprecision(3)<<ws->getTimeStep()
435 <<
" STEP FAILURE!! - ";
437 *out <<
"Solution Status = " <<
toString(ws->getSolutionStatus())
439 }
else if ((timeStepControl_->getStepType() ==
"Constant") &&
440 (ws->getTimeStep() != timeStepControl_->getInitTimeStep())) {
441 *out <<
"dt != Constant dt (="<<timeStepControl_->getInitTimeStep()<<
")"
445 ws->setNFailures(ws->getNFailures()+1);
446 ws->setNRunningFailures(ws->getNRunningFailures()+1);
447 ws->setNConsecutiveFailures(ws->getNConsecutiveFailures()+1);
458 template <
class Scalar>
461 std::string exitStatus;
462 if (solutionHistory_->getCurrentState()->getSolutionStatus() ==
464 exitStatus =
"Time integration FAILURE!";
467 exitStatus =
"Time integration complete.";
470 integratorTimer_->stop();
474 template <
class Scalar>
478 std::string delimiters(
",");
479 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
480 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
481 while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
482 std::string token = str.substr(lastPos,pos-lastPos);
483 outputScreenIndices_.push_back(
int(std::stoi(token)));
484 if(pos==std::string::npos)
487 lastPos = str.find_first_not_of(delimiters, pos);
488 pos = str.find_first_of(delimiters, lastPos);
492 std::sort(outputScreenIndices_.begin(),outputScreenIndices_.end());
493 outputScreenIndices_.erase(std::unique(outputScreenIndices_.begin(),
494 outputScreenIndices_.end() ),
495 outputScreenIndices_.end() );
500 template <
class Scalar>
503 std::stringstream ss;
504 for(
size_t i = 0; i < outputScreenIndices_.size(); ++i) {
505 if(i != 0) ss <<
", ";
506 ss << outputScreenIndices_[i];
514 template<
class Scalar>
519 Teuchos::parameterList(getIntegratorName());
521 pl->
set(
"Integrator Type", getIntegratorType(),
522 "'Integrator Type' must be 'Integrator Basic'.");
524 pl->
set(
"Screen Output Index List", getScreenOutputIndexListString(),
525 "Screen Output Index List. Required to be in TimeStepControl range "
526 "['Minimum Time Step Index', 'Maximum Time Step Index']");
528 pl->
set(
"Screen Output Index Interval", getScreenOutputIndexInterval(),
529 "Screen Output Index Interval (e.g., every 100 time steps)");
531 pl->
set(
"Stepper Name", stepper_->getStepperName(),
532 "'Stepper Name' selects the Stepper block to construct (Required).");
534 pl->
set(
"Solution History", *solutionHistory_->getValidParameters());
535 pl->
set(
"Time Step Control", *timeStepControl_->getValidParameters());
539 Teuchos::parameterList(
"Tempus");
541 tempusPL->
set(
"Integrator Name", pl->
name());
542 tempusPL->
set(pl->
name(), *pl);
543 tempusPL->
set(stepper_->getStepperName(), *stepper_->getValidParameters());
551 template<
class Scalar>
556 auto integratorName = tempusPL->
get<std::string>(
"Integrator Name");
557 auto integratorPL = Teuchos::sublist(tempusPL, integratorName,
true);
559 std::string integratorType = integratorPL->get<std::string>(
"Integrator Type");
562 "Error - For IntegratorBasic, 'Integrator Type' should be "
563 <<
"'Integrator Basic'.\n"
564 <<
" Integrator Type = " << integratorType <<
"\n");
567 integrator->setIntegratorName(integratorName);
570 if (integratorPL->isParameter(
"Stepper Name")) {
572 auto stepperName = integratorPL->get<std::string>(
"Stepper Name");
573 auto stepperPL = Teuchos::sublist(tempusPL, stepperName,
true);
574 stepperPL->setName(stepperName);
576 integrator->setStepper(sf->createStepper(stepperPL, model));
580 integrator->setStepper(
585 if (integratorPL->isSublist(
"Time Step Control")) {
587 auto tscPL = Teuchos::sublist(integratorPL,
"Time Step Control",
true);
588 integrator->setTimeStepControl(createTimeStepControl<Scalar>(tscPL));
596 integrator->getStepper()->getDefaultStepperState());
597 newState->setTime (integrator->getTimeStepControl()->getInitTime());
598 newState->setIndex (integrator->getTimeStepControl()->getInitIndex());
599 newState->setTimeStep(integrator->getTimeStepControl()->getInitTimeStep());
600 newState->setTolRel (integrator->getTimeStepControl()->getMaxRelError());
601 newState->setTolAbs (integrator->getTimeStepControl()->getMaxAbsError());
602 newState->setOrder (integrator->getStepper()->getOrder());
606 auto shPL = Teuchos::sublist(integratorPL,
"Solution History",
true);
607 auto sh = createSolutionHistoryPL<Scalar>(shPL);
608 sh->addState(newState);
609 integrator->getStepper()->setInitialConditions(sh);
610 integrator->setSolutionHistory(sh);
613 integrator->setObserver(Teuchos::null);
616 integrator->setScreenOutputIndexInterval(
617 integratorPL->get<
int>(
"Screen Output Index Interval",
618 integrator->getScreenOutputIndexInterval()));
621 auto str = integratorPL->get<std::string>(
"Screen Output Index List",
"");
622 integrator->setScreenOutputIndexList(str);
627 auto vIntegratorName = validPL->template get<std::string>(
"Integrator Name");
628 auto vIntegratorPL = Teuchos::sublist(validPL, vIntegratorName,
true);
629 integratorPL->validateParametersAndSetDefaults(*vIntegratorPL);
632 auto stepperName = integratorPL->get<std::string>(
"Stepper Name");
633 auto stepperPL = Teuchos::sublist(tempusPL, stepperName,
true);
634 auto vStepperName = vIntegratorPL->template get<std::string>(
"Stepper Name");
635 auto vStepperPL = Teuchos::sublist(validPL, vStepperName,
true);
636 stepperPL->validateParametersAndSetDefaults(*vStepperPL);
638 integrator->initialize();
645 template<
class Scalar>
648 std::string stepperType)
654 auto stepper = sf->createStepper(stepperType, model);
655 integrator->setStepper(stepper);
656 integrator->initializeSolutionHistory();
657 integrator->initialize();
664 template<
class Scalar>
672 template<
class Scalar>
677 auto integratorName = tempusPL->
get<std::string>(
"Integrator Name");
678 auto integratorPL = Teuchos::sublist(tempusPL, integratorName,
true);
680 std::string integratorType = integratorPL->get<std::string>(
"Integrator Type");
683 "Error - For IntegratorBasic, 'Integrator Type' should be "
684 <<
"'Integrator Basic'.\n"
685 <<
" Integrator Type = " << integratorType <<
"\n");
688 integrator->setIntegratorName(integratorName);
690 TEUCHOS_TEST_FOR_EXCEPTION( !integratorPL->isParameter(
"Stepper Name"),
692 "Error - Need to set the 'Stepper Name' in 'Integrator Basic'.\n");
694 auto stepperName = integratorPL->get<std::string>(
"Stepper Name");
695 TEUCHOS_TEST_FOR_EXCEPTION( stepperName ==
"Operator Split",
697 "Error - 'Stepper Name' should be 'Operator Split'.\n");
700 auto stepperPL = Teuchos::sublist(tempusPL, stepperName,
true);
701 stepperPL->setName(stepperName);
703 integrator->setStepper(sf->createStepper(stepperPL, models));
706 if (integratorPL->isSublist(
"Time Step Control")) {
708 auto tscPL = Teuchos::sublist(integratorPL,
"Time Step Control",
true);
709 integrator->setTimeStepControl(createTimeStepControl<Scalar>(tscPL));
717 integrator->getStepper()->getDefaultStepperState());
718 newState->setTime (integrator->getTimeStepControl()->getInitTime());
719 newState->setIndex (integrator->getTimeStepControl()->getInitIndex());
720 newState->setTimeStep(integrator->getTimeStepControl()->getInitTimeStep());
721 newState->setTolRel (integrator->getTimeStepControl()->getMaxRelError());
722 newState->setTolAbs (integrator->getTimeStepControl()->getMaxAbsError());
723 newState->setOrder (integrator->getStepper()->getOrder());
727 auto shPL = Teuchos::sublist(integratorPL,
"Solution History",
true);
728 auto sh = createSolutionHistoryPL<Scalar>(shPL);
729 sh->addState(newState);
730 integrator->getStepper()->setInitialConditions(sh);
731 integrator->setSolutionHistory(sh);
734 integrator->setObserver(Teuchos::null);
737 integrator->setScreenOutputIndexInterval(
738 integratorPL->get<
int>(
"Screen Output Index Interval",
739 integrator->getScreenOutputIndexInterval()));
742 auto str = integratorPL->get<std::string>(
"Screen Output Index List",
"");
743 integrator->setScreenOutputIndexList(str);
748 auto vIntegratorName = validPL->template get<std::string>(
"Integrator Name");
749 auto vIntegratorPL = Teuchos::sublist(validPL, vIntegratorName,
true);
750 integratorPL->validateParametersAndSetDefaults(*vIntegratorPL);
753 auto vStepperName = vIntegratorPL->template get<std::string>(
"Stepper Name");
754 auto vStepperPL = Teuchos::sublist(validPL, vStepperName,
true);
755 stepperPL->validateParametersAndSetDefaults(*vStepperPL);
757 integrator->initialize();
764 #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
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
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.
IntegratorBasic()
Default constructor that requires a subsequent, ??? , setStepper, and initialize calls.
virtual void setStepper(Teuchos::RCP< Stepper< Scalar > > stepper)
Set the Stepper.
Thyra Base interface for time steppers.
Teuchos::RCP< StepperForwardEuler< Scalar > > createStepperForwardEuler(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, Teuchos::RCP< Teuchos::ParameterList > pl)
Nonmember constructor - ModelEvaluator and ParameterList.
virtual void checkTimeStep()
Check if time step has passed or failed.
virtual void setSolutionHistory(Teuchos::RCP< SolutionHistory< Scalar > > sh=Teuchos::null)
Set the SolutionHistory.
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.
Teuchos::RCP< IntegratorBasic< Scalar > > createIntegratorBasic(Teuchos::RCP< Teuchos::ParameterList > pList, const Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > &model)
Nonmember constructor.
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 startTimeStep()
Start time step.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const override
Solution state for integrators and steppers. SolutionState contains the metadata for solutions and th...