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<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>
118 using Teuchos::ParameterList;
121 RCP<ParameterList> newStepperPL = newStepper->getNonconstParameterList();
122 integratorPL_->set(
"Stepper Name", newStepperPL->name());
123 tempusPL_->set(newStepperPL->name(), *newStepperPL);
124 stepper_ = newStepper;
128 template<
class Scalar>
133 using Teuchos::ParameterList;
136 RCP<ParameterList> shPL =
137 Teuchos::sublist(integratorPL_,
"Solution History",
true);
140 if (state == Teuchos::null) {
143 stepper_->getModel(), stepper_->getDefaultStepperState(), Teuchos::null));
146 newState->setTime (timeStepControl_->getInitTime());
147 newState->setIndex (timeStepControl_->getInitIndex());
148 newState->setTimeStep(timeStepControl_->getInitTimeStep());
149 newState->getMetaData()->setTolRel(timeStepControl_->getMaxRelError());
150 newState->getMetaData()->setTolAbs(timeStepControl_->getMaxAbsError());
151 int order = timeStepControl_->getInitOrder();
152 if (order == 0) order = stepper_->getOrder();
153 if (order < stepper_->getOrderMin()) order = stepper_->getOrderMin();
154 if (order > stepper_->getOrderMax()) order = stepper_->getOrderMax();
155 newState->setOrder(order);
158 solutionHistory_->addState(newState);
162 solutionHistory_->addState(state);
166 stepper_->setInitialConditions(solutionHistory_);
170 template<
class Scalar>
173 Teuchos::RCP<
const Thyra::VectorBase<Scalar> > x0,
174 Teuchos::RCP<
const Thyra::VectorBase<Scalar> > xdot0,
175 Teuchos::RCP<
const Thyra::VectorBase<Scalar> > xdotdot0)
178 using Teuchos::ParameterList;
181 RCP<ParameterList> shPL =
182 Teuchos::sublist(integratorPL_,
"Solution History",
true);
186 RCP<Thyra::VectorBase<Scalar> > xdot = x0->clone_v();
187 RCP<Thyra::VectorBase<Scalar> > xdotdot = x0->clone_v();
188 if (xdot0 == Teuchos::null)
189 Thyra::assign(xdot.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
191 Thyra::assign(xdot.ptr(), *(xdot0));
192 if (xdotdot0 == Teuchos::null)
193 Thyra::assign(xdotdot.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
195 Thyra::assign(xdotdot.ptr(), *(xdotdot0));
198 x0->clone_v(), xdot, xdotdot, stepper_->getDefaultStepperState()));
202 newState->setTime (t0);
203 newState->setIndex (timeStepControl_->getInitIndex());
204 newState->setTimeStep(timeStepControl_->getInitTimeStep());
205 int order = timeStepControl_->getInitOrder();
206 if (order == 0) order = stepper_->getOrder();
207 if (order < stepper_->getOrderMin()) order = stepper_->getOrderMin();
208 if (order > stepper_->getOrderMax()) order = stepper_->getOrderMax();
209 newState->setOrder(order);
213 solutionHistory_->addState(newState);
216 stepper_->setInitialConditions(solutionHistory_);
220 template<
class Scalar>
225 using Teuchos::ParameterList;
227 if (sh == Teuchos::null) {
229 if (solutionHistory_ == Teuchos::null) initializeSolutionHistory();
232 TEUCHOS_TEST_FOR_EXCEPTION( sh->getNumStates() < 1,
234 "Error - setSolutionHistory requires at least one SolutionState.\n"
235 <<
" Supplied SolutionHistory has only " << sh->getNumStates()
236 <<
" SolutionStates.\n");
239 RCP<ParameterList> shPL = sh->getNonconstParameterList();
240 integratorPL_->set(
"Solution History", shPL->name());
241 integratorPL_->set(shPL->name(), *shPL);
243 solutionHistory_ = sh;
248 template<
class Scalar>
253 using Teuchos::ParameterList;
255 if (tsc == Teuchos::null) {
257 if (timeStepControl_ == Teuchos::null) {
258 if (integratorPL_->isSublist(
"Time Step Control")) {
260 RCP<ParameterList> tscPL =
261 Teuchos::sublist(integratorPL_,
"Time Step Control",
true);
266 RCP<ParameterList> tscPL = timeStepControl_->getNonconstParameterList();
267 integratorPL_->set(
"Time Step Control", tscPL->name());
268 integratorPL_->set(tscPL->name(), *tscPL);
274 RCP<ParameterList> tscPL = tsc->getNonconstParameterList();
275 integratorPL_->set(
"Time Step Control", tscPL->name());
276 integratorPL_->set(tscPL->name(), *tscPL);
277 timeStepControl_ = tsc;
283 template<
class Scalar>
288 if (obs == Teuchos::null) {
290 if (integratorObserver_ == Teuchos::null) {
291 integratorObserver_ =
294 Teuchos::RCP<IntegratorObserverBasic<Scalar> > basicObs =
296 integratorObserver_->addObserver(basicObs);
299 if (integratorObserver_ == Teuchos::null) {
300 integratorObserver_ =
303 integratorObserver_->addObserver(obs);
309 template<
class Scalar>
312 TEUCHOS_TEST_FOR_EXCEPTION( stepper_ == Teuchos::null, std::logic_error,
313 "Error - Need to set the Stepper, setStepper(), before calling "
314 "IntegratorBasic::initialize()\n");
316 this->setTimeStepControl();
317 this->parseScreenOutput();
318 this->setSolutionHistory();
322 stepper_->setInitialConditions(solutionHistory_);
325 if (timeStepControl_->getMinOrder() < stepper_->getOrderMin())
326 timeStepControl_->setMinOrder(stepper_->getOrderMin());
327 if (timeStepControl_->getMinOrder() > stepper_->getOrderMax())
328 timeStepControl_->setMinOrder(stepper_->getOrderMax());
330 if (timeStepControl_->getMaxOrder() == 0 ||
331 timeStepControl_->getMaxOrder() > stepper_->getOrderMax())
332 timeStepControl_->setMaxOrder(stepper_->getOrderMax());
333 if (timeStepControl_->getMaxOrder() < timeStepControl_->getMinOrder())
334 timeStepControl_->setMaxOrder(timeStepControl_->getMinOrder());
336 if (timeStepControl_->getInitOrder() < timeStepControl_->getMinOrder())
337 timeStepControl_->setInitOrder(timeStepControl_->getMinOrder());
338 if (timeStepControl_->getInitOrder() > timeStepControl_->getMaxOrder())
339 timeStepControl_->setInitOrder(timeStepControl_->getMaxOrder());
341 TEUCHOS_TEST_FOR_EXCEPTION(
342 timeStepControl_->getMinOrder() > timeStepControl_->getMaxOrder(),
344 "Error - Invalid TimeStepControl min order greater than max order.\n"
345 <<
" Min order = " << timeStepControl_->getMinOrder() <<
"\n"
346 <<
" Max order = " << timeStepControl_->getMaxOrder() <<
"\n");
348 TEUCHOS_TEST_FOR_EXCEPTION(
349 timeStepControl_->getInitOrder() < timeStepControl_->getMinOrder() ||
350 timeStepControl_->getInitOrder() > timeStepControl_->getMaxOrder(),
352 "Error - Initial TimeStepControl order is out of min/max range.\n"
353 <<
" Initial order = " << timeStepControl_->getInitOrder() <<
"\n"
354 <<
" Min order = " << timeStepControl_->getMinOrder() <<
"\n"
355 <<
" Max order = " << timeStepControl_->getMaxOrder() <<
"\n");
357 if (integratorTimer_ == Teuchos::null)
358 integratorTimer_ = rcp(
new Teuchos::Time(
"Integrator Timer"));
359 if (stepperTimer_ == Teuchos::null)
360 stepperTimer_ = rcp(
new Teuchos::Time(
"Stepper Timer"));
362 if (Teuchos::as<int>(this->getVerbLevel()) >=
363 Teuchos::as<int>(Teuchos::VERB_HIGH)) {
364 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
365 Teuchos::OSTab ostab(out,1,
"IntegratorBasic::IntegratorBasic");
366 *out << this->description() << std::endl;
369 isInitialized_ =
true;
373 template<
class Scalar>
376 std::string name =
"Tempus::IntegratorBasic";
381 template<
class Scalar>
383 Teuchos::FancyOStream &out,
384 const Teuchos::EVerbosityLevel verbLevel)
const
386 out << description() <<
"::describe" << std::endl;
387 out <<
"solutionHistory= " << solutionHistory_->description()<<std::endl;
388 out <<
"timeStepControl= " << timeStepControl_->description()<<std::endl;
389 out <<
"stepper = " << stepper_ ->description()<<std::endl;
391 if (Teuchos::as<int>(verbLevel) >=
392 Teuchos::as<int>(Teuchos::VERB_HIGH)) {
393 out <<
"solutionHistory= " << std::endl;
394 solutionHistory_->describe(out,verbLevel);
395 out <<
"timeStepControl= " << std::endl;
396 timeStepControl_->describe(out,verbLevel);
397 out <<
"stepper = " << std::endl;
398 stepper_ ->describe(out,verbLevel);
403 template <
class Scalar>
406 if (timeStepControl_->timeInRange(timeFinal))
407 timeStepControl_->setFinalTime(timeFinal);
408 bool itgrStatus = advanceTime();
413 template <
class Scalar>
416 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
417 if (isInitialized_ ==
false) {
418 Teuchos::OSTab ostab(out,1,
"StartIntegrator");
419 *out <<
"Failure - IntegratorBasic is not initialized." << std::endl;
423 integratorTimer_->start();
425 const Scalar initDt =
426 std::min(timeStepControl_->getInitTimeStep(),
427 stepper_->getInitTimeStep(solutionHistory_));
429 timeStepControl_->setInitTimeStep(initDt);
434 template <
class Scalar>
437 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::IntegratorBasic::advanceTime()");
440 integratorObserver_->observeStartIntegrator(*
this);
442 while (integratorStatus_ ==
WORKING and
443 timeStepControl_->timeInRange (solutionHistory_->getCurrentTime()) and
444 timeStepControl_->indexInRange(solutionHistory_->getCurrentIndex())){
446 stepperTimer_->reset();
447 stepperTimer_->start();
448 solutionHistory_->initWorkingState();
451 integratorObserver_->observeStartTimeStep(*
this);
453 timeStepControl_->getNextTimeStep(solutionHistory_, integratorStatus_);
454 integratorObserver_->observeNextTimeStep(*
this);
457 solutionHistory_->getWorkingState()->getMetaData()->
460 integratorObserver_->observeBeforeTakeStep(*
this);
462 stepper_->takeStep(solutionHistory_);
464 integratorObserver_->observeAfterTakeStep(*
this);
466 stepperTimer_->stop();
468 integratorObserver_->observeAfterCheckTimeStep(*
this);
470 solutionHistory_->promoteWorkingState();
471 integratorObserver_->observeEndTimeStep(*
this);
475 integratorObserver_->observeEndIntegrator(*
this);
482 template <
class Scalar>
485 Teuchos::RCP<SolutionStateMetaData<Scalar> > wsmd =
486 solutionHistory_->getWorkingState()->getMetaData();
489 wsmd->setTolRel(timeStepControl_->getMaxRelError());
490 wsmd->setTolAbs(timeStepControl_->getMaxAbsError());
493 std::vector<int>::const_iterator it =
494 std::find(outputScreenIndices_.begin(),
495 outputScreenIndices_.end(),
497 if (it == outputScreenIndices_.end())
498 wsmd->setOutputScreen(
false);
500 wsmd->setOutputScreen(
true);
502 const int initial = timeStepControl_->getInitIndex();
503 const int interval = integratorPL_->get<
int>(
"Screen Output Index Interval");
504 if ( (wsmd->getIStep() - initial) % interval == 0)
505 wsmd->setOutputScreen(
true);
509 template <
class Scalar>
513 RCP<SolutionStateMetaData<Scalar> > wsmd =
514 solutionHistory_->getWorkingState()->getMetaData();
517 if (wsmd->getNFailures() >= timeStepControl_->getMaxFailures()) {
518 RCP<Teuchos::FancyOStream> out = this->getOStream();
519 Teuchos::OSTab ostab(out,2,
"checkTimeStep");
520 *out <<
"Failure - Stepper has failed more than the maximum allowed.\n"
521 <<
" (nFailures = "<<wsmd->getNFailures()<<
") >= (nFailuresMax = "
522 << timeStepControl_->getMaxFailures()<<
")" << std::endl;
526 if (wsmd->getNConsecutiveFailures()
527 >= timeStepControl_->getMaxConsecFailures()){
528 RCP<Teuchos::FancyOStream> out = this->getOStream();
529 Teuchos::OSTab ostab(out,1,
"checkTimeStep");
530 *out <<
"Failure - Stepper has failed more than the maximum "
531 <<
"consecutive allowed.\n"
532 <<
" (nConsecutiveFailures = "<<wsmd->getNConsecutiveFailures()
533 <<
") >= (nConsecutiveFailuresMax = "
534 << timeStepControl_->getMaxConsecFailures()
543 ((timeStepControl_->getStepType() ==
"Constant") and
544 (wsmd->getDt() != timeStepControl_->getInitTimeStep()) and
545 (wsmd->getOutput() !=
true) and
546 (wsmd->getTime() != timeStepControl_->getFinalTime())
550 RCP<Teuchos::FancyOStream> out = this->getOStream();
551 Teuchos::OSTab ostab(out,0,
"checkTimeStep");
552 *out <<std::scientific
553 <<std::setw( 6)<<std::setprecision(3)<<wsmd->getIStep()
554 <<std::setw(11)<<std::setprecision(3)<<wsmd->getTime()
555 <<std::setw(11)<<std::setprecision(3)<<wsmd->getDt()
556 <<
" STEP FAILURE!! - ";
558 *out <<
"Solution Status = " <<
toString(wsmd->getSolutionStatus())
560 }
else if ((timeStepControl_->getStepType() ==
"Constant") and
561 (wsmd->getDt() != timeStepControl_->getInitTimeStep())) {
562 *out <<
"dt != Constant dt (="<<timeStepControl_->getInitTimeStep()<<
")"
566 wsmd->setNFailures(wsmd->getNFailures()+1);
567 wsmd->setNRunningFailures(wsmd->getNRunningFailures()+1);
568 wsmd->setNConsecutiveFailures(wsmd->getNConsecutiveFailures()+1);
579 template <
class Scalar>
582 std::string exitStatus;
583 if (solutionHistory_->getCurrentState()->getSolutionStatus() ==
585 exitStatus =
"Time integration FAILURE!";
588 exitStatus =
"Time integration complete.";
591 integratorTimer_->stop();
592 runtime_ = integratorTimer_->totalElapsedTime();
596 template <
class Scalar>
602 outputScreenIndices_.clear();
604 integratorPL_->get<std::string>(
"Screen Output Index List",
"");
605 std::string delimiters(
",");
606 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
607 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
608 while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
609 std::string token = str.substr(lastPos,pos-lastPos);
610 outputScreenIndices_.push_back(
int(std::stoi(token)));
611 if(pos==std::string::npos)
614 lastPos = str.find_first_not_of(delimiters, pos);
615 pos = str.find_first_of(delimiters, lastPos);
619 std::sort(outputScreenIndices_.begin(),outputScreenIndices_.end());
620 outputScreenIndices_.erase(std::unique(outputScreenIndices_.begin(),
621 outputScreenIndices_.end() ),
622 outputScreenIndices_.end() );
627 template <
class Scalar>
629 const Teuchos::RCP<Teuchos::ParameterList> & inputPL)
631 if (inputPL == Teuchos::null) {
632 if (tempusPL_->isParameter(
"Integrator Name")) {
634 std::string integratorName_ =
635 tempusPL_->get<std::string>(
"Integrator Name");
636 integratorPL_ = Teuchos::sublist(tempusPL_, integratorName_,
true);
639 integratorPL_ = Teuchos::parameterList();
640 integratorPL_->setName(
"Default Integrator");
641 *integratorPL_ = *(this->getValidParameters());
642 tempusPL_->set(
"Integrator Name",
"Default Integrator");
643 tempusPL_->set(
"Default Integrator", *integratorPL_);
646 *integratorPL_ = *inputPL;
647 tempusPL_->set(
"Integrator Name", integratorPL_->name());
648 tempusPL_->set(integratorPL_->name(), *integratorPL_);
651 integratorPL_->validateParametersAndSetDefaults(*this->getValidParameters());
653 std::string integratorType =
654 integratorPL_->get<std::string>(
"Integrator Type");
655 TEUCHOS_TEST_FOR_EXCEPTION( integratorType !=
"Integrator Basic",
657 "Error - Inconsistent Integrator Type for IntegratorBasic\n"
658 <<
" Integrator Type = " << integratorType <<
"\n");
666 template<
class Scalar>
667 Teuchos::RCP<const Teuchos::ParameterList>
670 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
672 std::ostringstream tmp;
673 tmp <<
"'Integrator Type' must be 'Integrator Basic'.";
674 pl->set(
"Integrator Type",
"Integrator Basic", tmp.str());
677 tmp <<
"Screen Output Index List. Required to be in TimeStepControl range "
678 <<
"['Minimum Time Step Index', 'Maximum Time Step Index']";
679 pl->set(
"Screen Output Index List",
"", tmp.str());
680 pl->set(
"Screen Output Index Interval", 1000000,
681 "Screen Output Index Interval (e.g., every 100 time steps)");
683 pl->set(
"Stepper Name",
"",
684 "'Stepper Name' selects the Stepper block to construct (Required).");
687 pl->sublist(
"Solution History",
false,
"solutionHistory_docs")
688 .disableRecursiveValidation();
691 pl->sublist(
"Time Step Control",
false,
"solutionHistory_docs")
692 .disableRecursiveValidation();
698 template <
class Scalar>
699 Teuchos::RCP<Teuchos::ParameterList>
702 return(integratorPL_);
706 template <
class Scalar>
707 Teuchos::RCP<Teuchos::ParameterList>
710 Teuchos::RCP<Teuchos::ParameterList> temp_param_list = integratorPL_;
711 integratorPL_ = Teuchos::null;
712 return(temp_param_list);
716 template<
class Scalar>
718 Teuchos::RCP<Teuchos::ParameterList> pList,
719 const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& model)
721 Teuchos::RCP<Tempus::IntegratorBasic<Scalar> > integrator =
727 template<
class Scalar>
729 const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& model,
730 std::string stepperType)
732 Teuchos::RCP<Tempus::IntegratorBasic<Scalar> > integrator =
738 template<
class Scalar>
741 Teuchos::RCP<Tempus::IntegratorBasic<Scalar> > integrator =
747 template<
class Scalar>
749 Teuchos::RCP<Teuchos::ParameterList> pList,
750 std::vector<Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> > > models)
752 Teuchos::RCP<Tempus::IntegratorBasic<Scalar> > integrator =
758 #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 startTimeStep()
Start time step.
virtual void setStepper(Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > model)
Set the Stepper.
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...