9 #ifndef Tempus_IntegratorBasic_impl_hpp
10 #define Tempus_IntegratorBasic_impl_hpp
12 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
13 #include "Teuchos_TimeMonitor.hpp"
15 #include "Tempus_TimeStepControl.hpp"
21 template<
class Scalar>
23 Teuchos::RCP<Teuchos::ParameterList> inputPL,
24 const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& model)
25 : integratorObserver_(Teuchos::null),
26 integratorStatus_(
WORKING), isInitialized_(false)
34 template<
class Scalar>
36 const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& model,
37 std::string stepperType)
38 : integratorObserver_(Teuchos::null),
39 integratorStatus_(
WORKING), isInitialized_(false)
43 RCP<Stepper<Scalar> > stepper = sf->createStepper(stepperType, model);
51 template<
class Scalar>
53 : integratorObserver_(Teuchos::null),
54 integratorStatus_(
WORKING), isInitialized_(false)
60 template<
class Scalar>
62 Teuchos::RCP<Teuchos::ParameterList> inputPL,
63 std::vector<Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> > > models)
64 : integratorObserver_(Teuchos::null),
65 integratorStatus_(
WORKING), isInitialized_(false)
73 template<
class Scalar>
75 Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> > model)
78 using Teuchos::ParameterList;
80 if (stepper_ == Teuchos::null) {
83 std::string stepperName = integratorPL_->get<std::string>(
"Stepper Name");
85 RCP<ParameterList> stepperPL = Teuchos::sublist(tempusPL_,stepperName,
true);
86 stepper_ = sf->createStepper(stepperPL, model);
88 stepper_->setModel(model);
93 template<
class Scalar>
95 std::vector<Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> > > models)
98 using Teuchos::ParameterList;
100 if (stepper_ == Teuchos::null) {
103 std::string stepperName = integratorPL_->get<std::string>(
"Stepper Name");
105 RCP<ParameterList> stepperPL = Teuchos::sublist(tempusPL_,stepperName,
true);
106 stepper_ = sf->createStepper(stepperPL, models);
108 stepper_->createSubSteppers(models);
113 template<
class Scalar>
117 stepper_ = newStepper;
121 template<
class Scalar>
126 using Teuchos::ParameterList;
129 RCP<ParameterList> shPL =
130 Teuchos::sublist(integratorPL_,
"Solution History",
true);
133 if (state == Teuchos::null) {
136 stepper_->getModel(), stepper_->getDefaultStepperState(), Teuchos::null));
139 newState->setTime (timeStepControl_->getInitTime());
140 newState->setIndex (timeStepControl_->getInitIndex());
141 newState->setTimeStep(timeStepControl_->getInitTimeStep());
142 newState->getMetaData()->setTolRel(timeStepControl_->getMaxRelError());
143 newState->getMetaData()->setTolAbs(timeStepControl_->getMaxAbsError());
144 int order = timeStepControl_->getInitOrder();
145 if (order == 0) order = stepper_->getOrder();
146 if (order < stepper_->getOrderMin()) order = stepper_->getOrderMin();
147 if (order > stepper_->getOrderMax()) order = stepper_->getOrderMax();
148 newState->setOrder(order);
151 solutionHistory_->addState(newState);
155 solutionHistory_->addState(state);
159 stepper_->setInitialConditions(solutionHistory_);
163 template<
class Scalar>
166 Teuchos::RCP<
const Thyra::VectorBase<Scalar> > x0,
167 Teuchos::RCP<
const Thyra::VectorBase<Scalar> > xdot0,
168 Teuchos::RCP<
const Thyra::VectorBase<Scalar> > xdotdot0)
171 using Teuchos::ParameterList;
174 RCP<ParameterList> shPL =
175 Teuchos::sublist(integratorPL_,
"Solution History",
true);
179 RCP<Thyra::VectorBase<Scalar> > xdot = x0->clone_v();
180 RCP<Thyra::VectorBase<Scalar> > xdotdot = x0->clone_v();
181 if (xdot0 == Teuchos::null)
182 Thyra::assign(xdot.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
184 Thyra::assign(xdot.ptr(), *(xdot0));
185 if (xdotdot0 == Teuchos::null)
186 Thyra::assign(xdotdot.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
188 Thyra::assign(xdotdot.ptr(), *(xdotdot0));
191 x0->clone_v(), xdot, xdotdot, stepper_->getDefaultStepperState()));
195 newState->setTime (t0);
196 newState->setIndex (timeStepControl_->getInitIndex());
197 newState->setTimeStep(timeStepControl_->getInitTimeStep());
198 int order = timeStepControl_->getInitOrder();
199 if (order == 0) order = stepper_->getOrder();
200 if (order < stepper_->getOrderMin()) order = stepper_->getOrderMin();
201 if (order > stepper_->getOrderMax()) order = stepper_->getOrderMax();
202 newState->setOrder(order);
206 solutionHistory_->addState(newState);
209 stepper_->setInitialConditions(solutionHistory_);
213 template<
class Scalar>
218 using Teuchos::ParameterList;
220 if (sh == Teuchos::null) {
222 if (solutionHistory_ == Teuchos::null) initializeSolutionHistory();
225 TEUCHOS_TEST_FOR_EXCEPTION( sh->getNumStates() < 1,
227 "Error - setSolutionHistory requires at least one SolutionState.\n"
228 <<
" Supplied SolutionHistory has only " << sh->getNumStates()
229 <<
" SolutionStates.\n");
232 RCP<ParameterList> shPL = sh->getNonconstParameterList();
233 integratorPL_->set(
"Solution History", shPL->name());
234 integratorPL_->set(shPL->name(), *shPL);
236 solutionHistory_ = sh;
241 template<
class Scalar>
246 using Teuchos::ParameterList;
248 if (tsc == Teuchos::null) {
250 if (timeStepControl_ == Teuchos::null) {
251 if (integratorPL_->isSublist(
"Time Step Control")) {
253 RCP<ParameterList> tscPL =
254 Teuchos::sublist(integratorPL_,
"Time Step Control",
true);
259 RCP<ParameterList> tscPL = timeStepControl_->getNonconstParameterList();
260 integratorPL_->set(
"Time Step Control", tscPL->name());
261 integratorPL_->set(tscPL->name(), *tscPL);
267 RCP<ParameterList> tscPL = tsc->getNonconstParameterList();
268 integratorPL_->set(
"Time Step Control", tscPL->name());
269 integratorPL_->set(tscPL->name(), *tscPL);
270 timeStepControl_ = tsc;
276 template<
class Scalar>
281 if (obs == Teuchos::null) {
283 if (integratorObserver_ == Teuchos::null) {
284 integratorObserver_ =
287 Teuchos::RCP<IntegratorObserverBasic<Scalar> > basicObs =
289 integratorObserver_->addObserver(basicObs);
292 if (integratorObserver_ == Teuchos::null) {
293 integratorObserver_ =
296 integratorObserver_->addObserver(obs);
302 template<
class Scalar>
305 TEUCHOS_TEST_FOR_EXCEPTION( stepper_ == Teuchos::null, std::logic_error,
306 "Error - Need to set the Stepper, setStepper(), before calling "
307 "IntegratorBasic::initialize()\n");
309 this->setTimeStepControl();
310 this->parseScreenOutput();
311 this->setSolutionHistory();
315 stepper_->setInitialConditions(solutionHistory_);
318 if (timeStepControl_->getMinOrder() < stepper_->getOrderMin())
319 timeStepControl_->setMinOrder(stepper_->getOrderMin());
320 if (timeStepControl_->getMinOrder() > stepper_->getOrderMax())
321 timeStepControl_->setMinOrder(stepper_->getOrderMax());
323 if (timeStepControl_->getMaxOrder() == 0 ||
324 timeStepControl_->getMaxOrder() > stepper_->getOrderMax())
325 timeStepControl_->setMaxOrder(stepper_->getOrderMax());
326 if (timeStepControl_->getMaxOrder() < timeStepControl_->getMinOrder())
327 timeStepControl_->setMaxOrder(timeStepControl_->getMinOrder());
329 if (timeStepControl_->getInitOrder() < timeStepControl_->getMinOrder())
330 timeStepControl_->setInitOrder(timeStepControl_->getMinOrder());
331 if (timeStepControl_->getInitOrder() > timeStepControl_->getMaxOrder())
332 timeStepControl_->setInitOrder(timeStepControl_->getMaxOrder());
334 TEUCHOS_TEST_FOR_EXCEPTION(
335 timeStepControl_->getMinOrder() > timeStepControl_->getMaxOrder(),
337 "Error - Invalid TimeStepControl min order greater than max order.\n"
338 <<
" Min order = " << timeStepControl_->getMinOrder() <<
"\n"
339 <<
" Max order = " << timeStepControl_->getMaxOrder() <<
"\n");
341 TEUCHOS_TEST_FOR_EXCEPTION(
342 timeStepControl_->getInitOrder() < timeStepControl_->getMinOrder() ||
343 timeStepControl_->getInitOrder() > timeStepControl_->getMaxOrder(),
345 "Error - Initial TimeStepControl order is out of min/max range.\n"
346 <<
" Initial order = " << timeStepControl_->getInitOrder() <<
"\n"
347 <<
" Min order = " << timeStepControl_->getMinOrder() <<
"\n"
348 <<
" Max order = " << timeStepControl_->getMaxOrder() <<
"\n");
350 if (integratorTimer_ == Teuchos::null)
351 integratorTimer_ = rcp(
new Teuchos::Time(
"Integrator Timer"));
352 if (stepperTimer_ == Teuchos::null)
353 stepperTimer_ = rcp(
new Teuchos::Time(
"Stepper Timer"));
355 if (Teuchos::as<int>(this->getVerbLevel()) >=
356 Teuchos::as<int>(Teuchos::VERB_HIGH)) {
357 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
358 Teuchos::OSTab ostab(out,1,
"IntegratorBasic::IntegratorBasic");
359 *out << this->description() << std::endl;
362 isInitialized_ =
true;
366 template<
class Scalar>
369 std::string name =
"Tempus::IntegratorBasic";
374 template<
class Scalar>
376 Teuchos::FancyOStream &out,
377 const Teuchos::EVerbosityLevel verbLevel)
const
379 out << description() <<
"::describe" << std::endl;
380 out <<
"solutionHistory= " << solutionHistory_->description()<<std::endl;
381 out <<
"timeStepControl= " << timeStepControl_->description()<<std::endl;
382 out <<
"stepper = " << stepper_ ->description()<<std::endl;
384 if (Teuchos::as<int>(verbLevel) >=
385 Teuchos::as<int>(Teuchos::VERB_HIGH)) {
386 out <<
"solutionHistory= " << std::endl;
387 solutionHistory_->describe(out,verbLevel);
388 out <<
"timeStepControl= " << std::endl;
389 timeStepControl_->describe(out,verbLevel);
390 out <<
"stepper = " << std::endl;
391 stepper_ ->describe(out,verbLevel);
396 template <
class Scalar>
399 if (timeStepControl_->timeInRange(timeFinal))
400 timeStepControl_->setFinalTime(timeFinal);
401 bool itgrStatus = advanceTime();
406 template <
class Scalar>
409 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
410 if (isInitialized_ ==
false) {
411 Teuchos::OSTab ostab(out,1,
"StartIntegrator");
412 *out <<
"Failure - IntegratorBasic is not initialized." << std::endl;
416 integratorTimer_->start();
418 const Scalar initDt =
419 std::min(timeStepControl_->getInitTimeStep(),
420 stepper_->getInitTimeStep(solutionHistory_));
422 timeStepControl_->setInitTimeStep(initDt);
427 template <
class Scalar>
430 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::IntegratorBasic::advanceTime()");
433 integratorObserver_->observeStartIntegrator(*
this);
435 while (integratorStatus_ ==
WORKING and
436 timeStepControl_->timeInRange (solutionHistory_->getCurrentTime()) and
437 timeStepControl_->indexInRange(solutionHistory_->getCurrentIndex())){
439 stepperTimer_->reset();
440 stepperTimer_->start();
441 solutionHistory_->initWorkingState();
444 integratorObserver_->observeStartTimeStep(*
this);
446 timeStepControl_->getNextTimeStep(solutionHistory_, integratorStatus_);
447 integratorObserver_->observeNextTimeStep(*
this);
450 solutionHistory_->getWorkingState()->getMetaData()->
453 integratorObserver_->observeBeforeTakeStep(*
this);
455 stepper_->takeStep(solutionHistory_);
457 integratorObserver_->observeAfterTakeStep(*
this);
459 stepperTimer_->stop();
461 integratorObserver_->observeAfterCheckTimeStep(*
this);
463 solutionHistory_->promoteWorkingState();
464 integratorObserver_->observeEndTimeStep(*
this);
468 integratorObserver_->observeEndIntegrator(*
this);
475 template <
class Scalar>
478 Teuchos::RCP<SolutionStateMetaData<Scalar> > wsmd =
479 solutionHistory_->getWorkingState()->getMetaData();
482 wsmd->setTolRel(timeStepControl_->getMaxRelError());
483 wsmd->setTolAbs(timeStepControl_->getMaxAbsError());
486 std::vector<int>::const_iterator it =
487 std::find(outputScreenIndices_.begin(),
488 outputScreenIndices_.end(),
490 if (it == outputScreenIndices_.end())
491 wsmd->setOutputScreen(
false);
493 wsmd->setOutputScreen(
true);
495 const int initial = timeStepControl_->getInitIndex();
496 const int interval = integratorPL_->get<
int>(
"Screen Output Index Interval");
497 if ( (wsmd->getIStep() - initial) % interval == 0)
498 wsmd->setOutputScreen(
true);
502 template <
class Scalar>
506 RCP<SolutionStateMetaData<Scalar> > wsmd =
507 solutionHistory_->getWorkingState()->getMetaData();
510 if (wsmd->getNFailures() >= timeStepControl_->getMaxFailures()) {
511 RCP<Teuchos::FancyOStream> out = this->getOStream();
512 Teuchos::OSTab ostab(out,2,
"checkTimeStep");
513 *out <<
"Failure - Stepper has failed more than the maximum allowed.\n"
514 <<
" (nFailures = "<<wsmd->getNFailures()<<
") >= (nFailuresMax = "
515 << timeStepControl_->getMaxFailures()<<
")" << std::endl;
519 if (wsmd->getNConsecutiveFailures()
520 >= timeStepControl_->getMaxConsecFailures()){
521 RCP<Teuchos::FancyOStream> out = this->getOStream();
522 Teuchos::OSTab ostab(out,1,
"checkTimeStep");
523 *out <<
"Failure - Stepper has failed more than the maximum "
524 <<
"consecutive allowed.\n"
525 <<
" (nConsecutiveFailures = "<<wsmd->getNConsecutiveFailures()
526 <<
") >= (nConsecutiveFailuresMax = "
527 << timeStepControl_->getMaxConsecFailures()
536 ((timeStepControl_->getStepType() ==
"Constant") and
537 (wsmd->getDt() != timeStepControl_->getInitTimeStep()) and
538 (wsmd->getOutput() !=
true) and
539 (wsmd->getTime() != timeStepControl_->getFinalTime())
543 RCP<Teuchos::FancyOStream> out = this->getOStream();
544 Teuchos::OSTab ostab(out,0,
"checkTimeStep");
545 *out <<std::scientific
546 <<std::setw( 6)<<std::setprecision(3)<<wsmd->getIStep()
547 <<std::setw(11)<<std::setprecision(3)<<wsmd->getTime()
548 <<std::setw(11)<<std::setprecision(3)<<wsmd->getDt()
549 <<
" STEP FAILURE!! - ";
551 *out <<
"Solution Status = " <<
toString(wsmd->getSolutionStatus())
553 }
else if ((timeStepControl_->getStepType() ==
"Constant") and
554 (wsmd->getDt() != timeStepControl_->getInitTimeStep())) {
555 *out <<
"dt != Constant dt (="<<timeStepControl_->getInitTimeStep()<<
")"
559 wsmd->setNFailures(wsmd->getNFailures()+1);
560 wsmd->setNRunningFailures(wsmd->getNRunningFailures()+1);
561 wsmd->setNConsecutiveFailures(wsmd->getNConsecutiveFailures()+1);
572 template <
class Scalar>
575 std::string exitStatus;
576 if (solutionHistory_->getCurrentState()->getSolutionStatus() ==
578 exitStatus =
"Time integration FAILURE!";
581 exitStatus =
"Time integration complete.";
584 integratorTimer_->stop();
585 runtime_ = integratorTimer_->totalElapsedTime();
589 template <
class Scalar>
595 outputScreenIndices_.clear();
597 integratorPL_->get<std::string>(
"Screen Output Index List",
"");
598 std::string delimiters(
",");
599 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
600 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
601 while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
602 std::string token = str.substr(lastPos,pos-lastPos);
603 outputScreenIndices_.push_back(
int(std::stoi(token)));
604 if(pos==std::string::npos)
607 lastPos = str.find_first_not_of(delimiters, pos);
608 pos = str.find_first_of(delimiters, lastPos);
612 std::sort(outputScreenIndices_.begin(),outputScreenIndices_.end());
613 outputScreenIndices_.erase(std::unique(outputScreenIndices_.begin(),
614 outputScreenIndices_.end() ),
615 outputScreenIndices_.end() );
620 template <
class Scalar>
622 const Teuchos::RCP<Teuchos::ParameterList> & inputPL)
624 if (inputPL == Teuchos::null) {
625 if (tempusPL_->isParameter(
"Integrator Name")) {
627 std::string integratorName_ =
628 tempusPL_->get<std::string>(
"Integrator Name");
629 integratorPL_ = Teuchos::sublist(tempusPL_, integratorName_,
true);
632 integratorPL_ = Teuchos::parameterList();
633 integratorPL_->setName(
"Default Integrator");
634 *integratorPL_ = *(this->getValidParameters());
635 tempusPL_->set(
"Integrator Name",
"Default Integrator");
636 tempusPL_->set(
"Default Integrator", *integratorPL_);
639 *integratorPL_ = *inputPL;
640 tempusPL_->set(
"Integrator Name", integratorPL_->name());
641 tempusPL_->set(integratorPL_->name(), *integratorPL_);
644 integratorPL_->validateParametersAndSetDefaults(*this->getValidParameters());
646 std::string integratorType =
647 integratorPL_->get<std::string>(
"Integrator Type");
648 TEUCHOS_TEST_FOR_EXCEPTION( integratorType !=
"Integrator Basic",
650 "Error - Inconsistent Integrator Type for IntegratorBasic\n"
651 <<
" Integrator Type = " << integratorType <<
"\n");
659 template<
class Scalar>
660 Teuchos::RCP<const Teuchos::ParameterList>
663 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
665 std::ostringstream tmp;
666 tmp <<
"'Integrator Type' must be 'Integrator Basic'.";
667 pl->set(
"Integrator Type",
"Integrator Basic", tmp.str());
670 tmp <<
"Screen Output Index List. Required to be in TimeStepControl range "
671 <<
"['Minimum Time Step Index', 'Maximum Time Step Index']";
672 pl->set(
"Screen Output Index List",
"", tmp.str());
673 pl->set(
"Screen Output Index Interval", 1000000,
674 "Screen Output Index Interval (e.g., every 100 time steps)");
676 pl->set(
"Stepper Name",
"",
677 "'Stepper Name' selects the Stepper block to construct (Required).");
680 pl->sublist(
"Solution History",
false,
"solutionHistory_docs")
681 .disableRecursiveValidation();
684 pl->sublist(
"Time Step Control",
false,
"solutionHistory_docs")
685 .disableRecursiveValidation();
691 template <
class Scalar>
692 Teuchos::RCP<Teuchos::ParameterList>
695 return(integratorPL_);
699 template <
class Scalar>
700 Teuchos::RCP<Teuchos::ParameterList>
703 Teuchos::RCP<Teuchos::ParameterList> temp_param_list = integratorPL_;
704 integratorPL_ = Teuchos::null;
705 return(temp_param_list);
709 template<
class Scalar>
711 Teuchos::RCP<Teuchos::ParameterList> pList,
712 const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& model)
714 Teuchos::RCP<Tempus::IntegratorBasic<Scalar> > integrator =
720 template<
class Scalar>
722 const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& model,
723 std::string stepperType)
725 Teuchos::RCP<Tempus::IntegratorBasic<Scalar> > integrator =
731 template<
class Scalar>
734 Teuchos::RCP<Tempus::IntegratorBasic<Scalar> > integrator =
740 template<
class Scalar>
742 Teuchos::RCP<Teuchos::ParameterList> pList,
743 std::vector<Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> > > models)
745 Teuchos::RCP<Tempus::IntegratorBasic<Scalar> > integrator =
751 #endif // Tempus_IntegratorBasic_impl_hpp
virtual bool advanceTime()
Advance the solution to timeMax, and return true if successful.
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList() override
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const override
Create valid IntegratorBasic ParameterList.
const std::string toString(const Status status)
Convert Status to string.
std::string description() const override
virtual void setTimeStepControl(Teuchos::RCP< TimeStepControl< Scalar > > tsc=Teuchos::null)
Set the TimeStepControl.
virtual void setObserver(Teuchos::RCP< IntegratorObserver< Scalar > > obs=Teuchos::null)
Set the Observer.
IntegratorObserverBasic class for time integrators. This basic class has simple no-op functions...
IntegratorBasic()
Constructor that requires a subsequent setParameterList, setStepper, and initialize calls...
Thyra Base interface for time steppers.
virtual void checkTimeStep()
Check if time step has passed or failed.
Teuchos::RCP< Tempus::IntegratorBasic< Scalar > > integratorBasic(Teuchos::RCP< Teuchos::ParameterList > pList, const Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > &model)
Non-member constructor.
void parseScreenOutput()
Parse when screen output should be executed.
virtual void setSolutionHistory(Teuchos::RCP< SolutionHistory< Scalar > > sh=Teuchos::null)
Set the SolutionHistory.
IntegratorObserver class for time integrators.
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList() override
virtual void setStepperWStepper(Teuchos::RCP< Stepper< Scalar > > stepper)
Set the Stepper.
virtual void setTempusParameterList(Teuchos::RCP< Teuchos::ParameterList > pl) override
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &pl) override
TimeStepControl manages the time step size. There several mechanicisms that effect the time step size...
virtual void initializeSolutionHistory(Teuchos::RCP< SolutionState< Scalar > > state=Teuchos::null)
Set the initial state which has the initial conditions.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
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.
virtual void setStepper(Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > model)
Set the Stepper.
virtual void startTimeStep()
Start time step.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const override
This observer is a composite observer,.
Solution state for integrators and steppers. SolutionState contains the metadata for solutions and th...