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(model, stepperType);
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(model, stepperPL);
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(models, stepperPL);
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);
167 template<
class Scalar>
170 Teuchos::RCP<
const Thyra::VectorBase<Scalar> > x0,
171 Teuchos::RCP<
const Thyra::VectorBase<Scalar> > xdot0,
172 Teuchos::RCP<
const Thyra::VectorBase<Scalar> > xdotdot0)
175 using Teuchos::ParameterList;
178 RCP<ParameterList> shPL =
179 Teuchos::sublist(integratorPL_,
"Solution History",
true);
183 RCP<Thyra::VectorBase<Scalar> > xdot = x0->clone_v();
184 RCP<Thyra::VectorBase<Scalar> > xdotdot = x0->clone_v();
185 if (xdot0 == Teuchos::null)
186 Thyra::assign(xdot.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
188 Thyra::assign(xdot.ptr(), *(xdot0));
189 if (xdotdot0 == Teuchos::null)
190 Thyra::assign(xdotdot.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
192 Thyra::assign(xdotdot.ptr(), *(xdotdot0));
195 x0->clone_v(), xdot, xdotdot, stepper_->getDefaultStepperState()));
198 newState->setTime (timeStepControl_->getInitTime());
199 newState->setIndex (timeStepControl_->getInitIndex());
200 newState->setTimeStep(timeStepControl_->getInitTimeStep());
201 int order = timeStepControl_->getInitOrder();
202 if (order == 0) order = stepper_->getOrder();
203 if (order < stepper_->getOrderMin()) order = stepper_->getOrderMin();
204 if (order > stepper_->getOrderMax()) order = stepper_->getOrderMax();
205 newState->setOrder(order);
209 solutionHistory_->addState(newState);
213 template<
class Scalar>
218 using Teuchos::ParameterList;
220 if (sh == Teuchos::null) {
222 if (solutionHistory_ == Teuchos::null) setInitialState();
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 if (timeStepControl_->getMinOrder() < stepper_->getOrderMin())
316 timeStepControl_->setMinOrder(stepper_->getOrderMin());
317 if (timeStepControl_->getMinOrder() > stepper_->getOrderMax())
318 timeStepControl_->setMinOrder(stepper_->getOrderMax());
320 if (timeStepControl_->getMaxOrder() == 0 ||
321 timeStepControl_->getMaxOrder() > stepper_->getOrderMax())
322 timeStepControl_->setMaxOrder(stepper_->getOrderMax());
323 if (timeStepControl_->getMaxOrder() < timeStepControl_->getMinOrder())
324 timeStepControl_->setMaxOrder(timeStepControl_->getMinOrder());
326 if (timeStepControl_->getInitOrder() < timeStepControl_->getMinOrder())
327 timeStepControl_->setInitOrder(timeStepControl_->getMinOrder());
328 if (timeStepControl_->getInitOrder() > timeStepControl_->getMaxOrder())
329 timeStepControl_->setInitOrder(timeStepControl_->getMaxOrder());
331 TEUCHOS_TEST_FOR_EXCEPTION(
332 timeStepControl_->getMinOrder() > timeStepControl_->getMaxOrder(),
334 "Error - Invalid TimeStepControl min order greater than max order.\n"
335 <<
" Min order = " << timeStepControl_->getMinOrder() <<
"\n"
336 <<
" Max order = " << timeStepControl_->getMaxOrder() <<
"\n");
338 TEUCHOS_TEST_FOR_EXCEPTION(
339 timeStepControl_->getInitOrder() < timeStepControl_->getMinOrder() ||
340 timeStepControl_->getInitOrder() > timeStepControl_->getMaxOrder(),
342 "Error - Initial TimeStepControl order is out of min/max range.\n"
343 <<
" Initial order = " << timeStepControl_->getInitOrder() <<
"\n"
344 <<
" Min order = " << timeStepControl_->getMinOrder() <<
"\n"
345 <<
" Max order = " << timeStepControl_->getMaxOrder() <<
"\n");
347 if (integratorTimer_ == Teuchos::null)
348 integratorTimer_ = rcp(
new Teuchos::Time(
"Integrator Timer"));
349 if (stepperTimer_ == Teuchos::null)
350 stepperTimer_ = rcp(
new Teuchos::Time(
"Stepper Timer"));
352 if (Teuchos::as<int>(this->getVerbLevel()) >=
353 Teuchos::as<int>(Teuchos::VERB_HIGH)) {
354 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
355 Teuchos::OSTab ostab(out,1,
"IntegratorBasic::IntegratorBasic");
356 *out << this->description() << std::endl;
359 isInitialized_ =
true;
363 template<
class Scalar>
366 std::string name =
"Tempus::IntegratorBasic";
371 template<
class Scalar>
373 Teuchos::FancyOStream &out,
374 const Teuchos::EVerbosityLevel verbLevel)
const
376 out << description() <<
"::describe" << std::endl;
377 out <<
"solutionHistory= " << solutionHistory_->description()<<std::endl;
378 out <<
"timeStepControl= " << timeStepControl_->description()<<std::endl;
379 out <<
"stepper = " << stepper_ ->description()<<std::endl;
381 if (Teuchos::as<int>(verbLevel) >=
382 Teuchos::as<int>(Teuchos::VERB_HIGH)) {
383 out <<
"solutionHistory= " << std::endl;
384 solutionHistory_->describe(out,verbLevel);
385 out <<
"timeStepControl= " << std::endl;
386 timeStepControl_->describe(out,verbLevel);
387 out <<
"stepper = " << std::endl;
388 stepper_ ->describe(out,verbLevel);
393 template <
class Scalar>
396 if (timeStepControl_->timeInRange(timeFinal))
397 timeStepControl_->setFinalTime(timeFinal);
398 bool itgrStatus = advanceTime();
403 template <
class Scalar>
406 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
407 if (isInitialized_ ==
false) {
408 Teuchos::OSTab ostab(out,1,
"StartIntegrator");
409 *out <<
"Failure - IntegratorBasic is not initialized." << std::endl;
410 integratorStatus_ =
FAILED;
413 integratorTimer_->start();
415 const Scalar initDt =
416 std::min(timeStepControl_->getInitTimeStep(),
417 stepper_->getInitTimeStep(solutionHistory_));
419 timeStepControl_->setInitTimeStep(initDt);
424 template <
class Scalar>
427 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::IntegratorBasic::advanceTime()");
430 integratorObserver_->observeStartIntegrator(*
this);
432 while (integratorStatus_ ==
WORKING and
433 timeStepControl_->timeInRange (solutionHistory_->getCurrentTime()) and
434 timeStepControl_->indexInRange(solutionHistory_->getCurrentIndex())){
436 stepperTimer_->reset();
437 stepperTimer_->start();
438 solutionHistory_->initWorkingState();
441 integratorObserver_->observeStartTimeStep(*
this);
443 timeStepControl_->getNextTimeStep(solutionHistory_, integratorStatus_);
444 integratorObserver_->observeNextTimeStep(*
this);
446 if (integratorStatus_ ==
FAILED)
break;
447 solutionHistory_->getWorkingState()->getMetaData()->
450 integratorObserver_->observeBeforeTakeStep(*
this);
452 stepper_->takeStep(solutionHistory_);
454 integratorObserver_->observeAfterTakeStep(*
this);
456 stepperTimer_->stop();
458 integratorObserver_->observeAcceptedTimeStep(*
this);
462 integratorObserver_->observeEndIntegrator(*
this);
469 template <
class Scalar>
472 Teuchos::RCP<SolutionStateMetaData<Scalar> > wsmd =
473 solutionHistory_->getWorkingState()->getMetaData();
476 wsmd->setTolRel(timeStepControl_->getMaxRelError());
477 wsmd->setTolAbs(timeStepControl_->getMaxAbsError());
480 std::vector<int>::const_iterator it =
481 std::find(outputScreenIndices_.begin(),
482 outputScreenIndices_.end(),
484 if (it == outputScreenIndices_.end())
485 wsmd->setOutputScreen(
false);
487 wsmd->setOutputScreen(
true);
491 template <
class Scalar>
495 RCP<SolutionStateMetaData<Scalar> > wsmd =
496 solutionHistory_->getWorkingState()->getMetaData();
499 if (wsmd->getNFailures() >= timeStepControl_->getMaxFailures()) {
500 RCP<Teuchos::FancyOStream> out = this->getOStream();
501 Teuchos::OSTab ostab(out,2,
"acceptTimeStep");
502 *out <<
"Failure - Stepper has failed more than the maximum allowed.\n"
503 <<
" (nFailures = "<<wsmd->getNFailures()<<
") >= (nFailuresMax = "
504 << timeStepControl_->getMaxFailures()<<
")" << std::endl;
505 integratorStatus_ =
FAILED;
508 if (wsmd->getNConsecutiveFailures()
509 >= timeStepControl_->getMaxConsecFailures()){
510 RCP<Teuchos::FancyOStream> out = this->getOStream();
511 Teuchos::OSTab ostab(out,1,
"acceptTimeStep");
512 *out <<
"Failure - Stepper has failed more than the maximum "
513 <<
"consecutive allowed.\n"
514 <<
" (nConsecutiveFailures = "<<wsmd->getNConsecutiveFailures()
515 <<
") >= (nConsecutiveFailuresMax = "
516 << timeStepControl_->getMaxConsecFailures()
518 integratorStatus_ =
FAILED;
523 if ( solutionHistory_->getWorkingState()->getSolutionStatus() ==
FAILED or
525 ((timeStepControl_->getStepType() ==
"Constant") and
526 (wsmd->getDt() != timeStepControl_->getInitTimeStep()) and
527 (wsmd->getOutput() !=
true) and
528 (wsmd->getTime() != timeStepControl_->getFinalTime())
532 RCP<Teuchos::FancyOStream> out = this->getOStream();
533 Teuchos::OSTab ostab(out,0,
"acceptTimeStep");
534 *out <<std::scientific
535 <<std::setw( 6)<<std::setprecision(3)<<wsmd->getIStep()
536 <<std::setw(11)<<std::setprecision(3)<<wsmd->getTime()
537 <<std::setw(11)<<std::setprecision(3)<<wsmd->getDt()
538 <<
" STEP FAILURE!! - ";
539 if ( solutionHistory_->getWorkingState()->getSolutionStatus() ==
FAILED) {
540 *out <<
"Solution Status = "
541 <<
toString(solutionHistory_->getWorkingState()->getSolutionStatus())
543 }
else if ((timeStepControl_->getStepType() ==
"Constant") and
544 (wsmd->getDt() != timeStepControl_->getInitTimeStep())) {
545 *out <<
"dt != Constant dt (="<<timeStepControl_->getInitTimeStep()<<
")"
549 wsmd->setNFailures(wsmd->getNFailures()+1);
550 wsmd->setNRunningFailures(wsmd->getNRunningFailures()+1);
551 wsmd->setNConsecutiveFailures(wsmd->getNConsecutiveFailures()+1);
552 wsmd->setSolutionStatus(
FAILED);
559 solutionHistory_->promoteWorkingState();
561 RCP<SolutionStateMetaData<Scalar> > csmd =
562 solutionHistory_->getCurrentState()->getMetaData();
565 if (csmd->getOutput() ==
true) {
571 template <
class Scalar>
574 std::string exitStatus;
575 if (solutionHistory_->getCurrentState()->getSolutionStatus() ==
577 exitStatus =
"Time integration FAILURE!";
580 exitStatus =
"Time integration complete.";
583 integratorTimer_->stop();
584 runtime_ = integratorTimer_->totalElapsedTime();
588 template <
class Scalar>
594 outputScreenIndices_.clear();
596 integratorPL_->get<std::string>(
"Screen Output Index List",
"");
597 std::string delimiters(
",");
598 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
599 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
600 while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
601 std::string token = str.substr(lastPos,pos-lastPos);
602 outputScreenIndices_.push_back(
int(std::stoi(token)));
603 if(pos==std::string::npos)
606 lastPos = str.find_first_not_of(delimiters, pos);
607 pos = str.find_first_of(delimiters, lastPos);
610 int outputScreenIndexInterval =
611 integratorPL_->get<
int>(
"Screen Output Index Interval", 1000000);
612 int outputScreen_i = timeStepControl_->getInitIndex();
613 const int finalIStep = timeStepControl_->getFinalIndex();
614 while (outputScreen_i <= finalIStep) {
615 outputScreenIndices_.push_back(outputScreen_i);
616 outputScreen_i += outputScreenIndexInterval;
620 std::sort(outputScreenIndices_.begin(),outputScreenIndices_.end());
626 template <
class Scalar>
628 const Teuchos::RCP<Teuchos::ParameterList> & inputPL)
630 if (inputPL == Teuchos::null) {
631 if (tempusPL_->isParameter(
"Integrator Name")) {
633 std::string integratorName_ =
634 tempusPL_->get<std::string>(
"Integrator Name");
635 integratorPL_ = Teuchos::sublist(tempusPL_, integratorName_,
true);
638 integratorPL_ = Teuchos::parameterList();
639 integratorPL_->setName(
"Default Integrator");
640 *integratorPL_ = *(this->getValidParameters());
641 tempusPL_->set(
"Integrator Name",
"Default Integrator");
642 tempusPL_->set(
"Default Integrator", *integratorPL_);
645 *integratorPL_ = *inputPL;
646 tempusPL_->set(
"Integrator Name", integratorPL_->name());
647 tempusPL_->set(integratorPL_->name(), *integratorPL_);
650 integratorPL_->validateParametersAndSetDefaults(*this->getValidParameters());
652 std::string integratorType =
653 integratorPL_->get<std::string>(
"Integrator Type");
654 TEUCHOS_TEST_FOR_EXCEPTION( integratorType !=
"Integrator Basic",
656 "Error - Inconsistent Integrator Type for IntegratorBasic\n"
657 <<
" Integrator Type = " << integratorType <<
"\n");
665 template<
class Scalar>
666 Teuchos::RCP<const Teuchos::ParameterList>
669 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
671 std::ostringstream tmp;
672 tmp <<
"'Integrator Type' must be 'Integrator Basic'.";
673 pl->set(
"Integrator Type",
"Integrator Basic", tmp.str());
676 tmp <<
"Screen Output Index List. Required to be in TimeStepControl range "
677 <<
"['Minimum Time Step Index', 'Maximum Time Step Index']";
678 pl->set(
"Screen Output Index List",
"", tmp.str());
679 pl->set(
"Screen Output Index Interval", 1000000,
680 "Screen Output Index Interval (e.g., every 100 time steps)");
682 pl->set(
"Stepper Name",
"",
683 "'Stepper Name' selects the Stepper block to construct (Required).");
686 pl->sublist(
"Solution History",
false,
"solutionHistory_docs")
687 .disableRecursiveValidation();
690 pl->sublist(
"Time Step Control",
false,
"solutionHistory_docs")
691 .disableRecursiveValidation();
697 template <
class Scalar>
698 Teuchos::RCP<Teuchos::ParameterList>
701 return(integratorPL_);
705 template <
class Scalar>
706 Teuchos::RCP<Teuchos::ParameterList>
709 Teuchos::RCP<Teuchos::ParameterList> temp_param_list = integratorPL_;
710 integratorPL_ = Teuchos::null;
711 return(temp_param_list);
715 template<
class Scalar>
717 Teuchos::RCP<Teuchos::ParameterList> pList,
718 const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& model)
720 Teuchos::RCP<Tempus::IntegratorBasic<Scalar> > integrator =
726 template<
class Scalar>
728 const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& model,
729 std::string stepperType)
731 Teuchos::RCP<Tempus::IntegratorBasic<Scalar> > integrator =
737 template<
class Scalar>
740 Teuchos::RCP<Tempus::IntegratorBasic<Scalar> > integrator =
746 template<
class Scalar>
748 Teuchos::RCP<Teuchos::ParameterList> pList,
749 std::vector<Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> > > models)
751 Teuchos::RCP<Tempus::IntegratorBasic<Scalar> > integrator =
757 #endif // Tempus_IntegratorBasic_impl_hpp