Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Tempus_IntegratorBasic_impl.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ****************************************************************************
3 // Tempus: Copyright (2017) Sandia Corporation
4 //
5 // Distributed under BSD 3-clause license (See accompanying file Copyright.txt)
6 // ****************************************************************************
7 // @HEADER
8 
9 #ifndef Tempus_IntegratorBasic_impl_hpp
10 #define Tempus_IntegratorBasic_impl_hpp
11 
12 #include "Thyra_VectorStdOps.hpp"
13 
15 #include "Tempus_StepperFactory.hpp"
16 #include "Tempus_StepperForwardEuler.hpp"
17 
18 namespace Tempus {
19 
20 template <class Scalar>
22  : outputScreenIndices_(std::vector<int>()),
23  outputScreenInterval_(1000000),
24  integratorStatus_(WORKING),
25  isInitialized_(false)
26 {
27  setIntegratorName("Integrator Basic");
28  setIntegratorType("Integrator Basic");
29  setStepper(Teuchos::null);
30  setSolutionHistory(Teuchos::null);
31  setTimeStepControl(Teuchos::null);
32  setObserver(Teuchos::null);
33 
34  integratorTimer_ = rcp(new Teuchos::Time("Integrator Timer"));
35  stepperTimer_ = rcp(new Teuchos::Time("Stepper Timer"));
36 
37  // integrator is not initialized. Still requires calls to setModel
38  // and setSolutionHistory for initial conditions before calling
39  // initialize() to be fully constructed.
40 }
41 
42 template <class Scalar>
44  Teuchos::RCP<Stepper<Scalar> > stepper,
45  Teuchos::RCP<SolutionHistory<Scalar> > solutionHistory,
46  Teuchos::RCP<TimeStepControl<Scalar> > timeStepControl,
47  Teuchos::RCP<IntegratorObserver<Scalar> > integratorObserver,
48  std::vector<int> outputScreenIndices, int outputScreenInterval)
49  : outputScreenIndices_(outputScreenIndices),
50  outputScreenInterval_(outputScreenInterval),
51  integratorStatus_(WORKING),
52  isInitialized_(false)
53 {
54  setIntegratorName("Integrator Basic");
55  setIntegratorType("Integrator Basic");
56  setStepper(stepper);
57  setSolutionHistory(solutionHistory);
58  setTimeStepControl(timeStepControl);
59  setObserver(integratorObserver);
60 
61  integratorTimer_ = rcp(new Teuchos::Time("Integrator Timer"));
62  stepperTimer_ = rcp(new Teuchos::Time("Stepper Timer"));
63 
64  initialize();
65 }
66 
67 template <class Scalar>
69 {
70  this->setIntegratorType(iB->getIntegratorType());
71  this->setIntegratorName(iB->getIntegratorName());
72  this->setStepper(iB->getStepper());
73  this->setSolutionHistory(iB->getNonConstSolutionHistory());
74  this->setTimeStepControl(iB->getNonConstTimeStepControl());
75  this->setObserver(iB->getObserver());
76  this->setScreenOutputIndexList(iB->getScreenOutputIndexList());
77  this->setScreenOutputIndexInterval(iB->getScreenOutputIndexInterval());
78  this->setStatus(iB->getStatus());
79  integratorTimer_ = iB->getIntegratorTimer();
80  stepperTimer_ = iB->getStepperTimer();
81 }
82 
83 template <class Scalar>
85 {
87  i != "Integrator Basic", std::logic_error,
88  "Error - Integrator Type should be 'Integrator Basic'\n");
89 
90  this->integratorType_ = i;
91 }
92 
93 template <class Scalar>
96 {
98  stepper_ == Teuchos::null, std::logic_error,
99  "Error - setModel(), need to set stepper first!\n");
100 
101  stepper_->setModel(model);
102 }
103 
104 template <class Scalar>
106 {
107  if (stepper == Teuchos::null)
108  stepper_ = Teuchos::rcp(new StepperForwardEuler<Scalar>());
109  else
110  stepper_ = stepper;
111 }
112 
114 template <class Scalar>
117 {
118  using Teuchos::RCP;
119 
120  if (solutionHistory_ == Teuchos::null) {
121  solutionHistory_ = rcp(new SolutionHistory<Scalar>());
122  }
123  else {
124  solutionHistory_->clear();
125  }
126 
128  stepper_ == Teuchos::null, std::logic_error,
129  "Error - initializeSolutionHistory(), need to set stepper first!\n");
130 
131  if (state == Teuchos::null) {
132  TEUCHOS_TEST_FOR_EXCEPTION(stepper_->getModel() == Teuchos::null,
133  std::logic_error,
134  "Error - initializeSolutionHistory(), need to "
135  "set stepper's model first!\n");
136  // Construct default IC from the application model
137  state = createSolutionStateME(stepper_->getModel(),
138  stepper_->getDefaultStepperState());
139 
140  if (timeStepControl_ != Teuchos::null) {
141  // Set SolutionState from TimeStepControl
142  state->setTime(timeStepControl_->getInitTime());
143  state->setIndex(timeStepControl_->getInitIndex());
144  state->setTimeStep(timeStepControl_->getInitTimeStep());
145  state->setTolRel(timeStepControl_->getMaxRelError());
146  state->setTolAbs(timeStepControl_->getMaxAbsError());
147  }
148  state->setOrder(stepper_->getOrder());
149  state->setSolutionStatus(Status::PASSED); // ICs are considered passing.
150  }
151 
152  solutionHistory_->addState(state);
153 
154  stepper_->setInitialConditions(solutionHistory_);
155 }
156 
157 template <class Scalar>
159  Scalar t0, Teuchos::RCP<const Thyra::VectorBase<Scalar> > x0,
161  Teuchos::RCP<const Thyra::VectorBase<Scalar> > xdotdot0)
162 {
163  using Teuchos::RCP;
164 
165  // Create and set xdot and xdotdot.
166  RCP<Thyra::VectorBase<Scalar> > xdot = x0->clone_v();
167  RCP<Thyra::VectorBase<Scalar> > xdotdot = x0->clone_v();
168  if (xdot0 == Teuchos::null)
169  Thyra::assign(xdot.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
170  else
171  Thyra::assign(xdot.ptr(), *(xdot0));
172  if (xdotdot0 == Teuchos::null)
173  Thyra::assign(xdotdot.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
174  else
175  Thyra::assign(xdotdot.ptr(), *(xdotdot0));
176 
178  stepper_ == Teuchos::null, std::logic_error,
179  "Error - initializeSolutionHistory(), need to set stepper first!\n");
180 
181  auto state = createSolutionStateX(x0->clone_v(), xdot, xdotdot);
182  state->setStepperState(stepper_->getDefaultStepperState());
183 
184  state->setTime(t0);
185  if (timeStepControl_ != Teuchos::null) {
186  // Set SolutionState from TimeStepControl
187  state->setIndex(timeStepControl_->getInitIndex());
188  state->setTimeStep(timeStepControl_->getInitTimeStep());
189  state->setTolRel(timeStepControl_->getMaxRelError());
190  state->setTolAbs(timeStepControl_->getMaxAbsError());
191  }
192  state->setOrder(stepper_->getOrder());
193  state->setSolutionStatus(Status::PASSED); // ICs are considered passing.
194 
195  initializeSolutionHistory(state);
196 }
197 
198 template <class Scalar>
201 {
202  if (sh == Teuchos::null) {
203  // Create default SolutionHistory, otherwise keep current history.
204  if (solutionHistory_ == Teuchos::null)
205  solutionHistory_ = rcp(new SolutionHistory<Scalar>());
206  }
207  else {
208  solutionHistory_ = sh;
209  }
210 }
211 
212 template <class Scalar>
215 {
216  if (tsc == Teuchos::null) {
217  // Create timeStepControl_ if null, otherwise keep current parameters.
218  if (timeStepControl_ == Teuchos::null) {
219  // Construct default TimeStepControl
220  timeStepControl_ = rcp(new TimeStepControl<Scalar>());
221  }
222  }
223  else {
224  timeStepControl_ = tsc;
225  }
226 }
227 
228 template <class Scalar>
231 {
232  if (obs == Teuchos::null)
233  integratorObserver_ = Teuchos::rcp(new IntegratorObserverBasic<Scalar>());
234  else
235  integratorObserver_ = obs;
236 }
237 
238 template <class Scalar>
240 {
242  stepper_ == Teuchos::null, std::logic_error,
243  "Error - Need to set the Stepper, setStepper(), before calling "
244  "IntegratorBasic::initialize()\n");
245 
247  solutionHistory_->getNumStates() < 1, std::out_of_range,
248  "Error - SolutionHistory requires at least one SolutionState.\n"
249  << " Supplied SolutionHistory has only "
250  << solutionHistory_->getNumStates() << " SolutionStates.\n");
251 
252  stepper_->initialize();
253  solutionHistory_->initialize();
254  timeStepControl_->initialize();
255 
256  isInitialized_ = true;
257 }
258 
259 template <class Scalar>
261 {
262  std::string name = "Tempus::IntegratorBasic";
263  return (name);
264 }
265 
266 template <class Scalar>
268  Teuchos::FancyOStream& out, const Teuchos::EVerbosityLevel verbLevel) const
269 {
270  auto l_out = Teuchos::fancyOStream(out.getOStream());
271  Teuchos::OSTab ostab(*l_out, 2, this->description());
272  l_out->setOutputToRootOnly(0);
273 
274  *l_out << "\n--- " << this->description() << " ---" << std::endl;
275 
276  if (solutionHistory_ != Teuchos::null) {
277  solutionHistory_->describe(*l_out, verbLevel);
278  }
279  else {
280  *l_out << "solutionHistory = " << solutionHistory_ << std::endl;
281  }
282 
283  if (timeStepControl_ != Teuchos::null) {
284  timeStepControl_->describe(out, verbLevel);
285  }
286  else {
287  *l_out << "timeStepControl = " << timeStepControl_ << std::endl;
288  }
289 
290  if (stepper_ != Teuchos::null) {
291  stepper_->describe(out, verbLevel);
292  }
293  else {
294  *l_out << "stepper = " << stepper_ << std::endl;
295  }
296  *l_out << std::string(this->description().length() + 8, '-') << std::endl;
297 }
298 
299 template <class Scalar>
300 bool IntegratorBasic<Scalar>::advanceTime(const Scalar timeFinal)
301 {
302  if (timeStepControl_->timeInRange(timeFinal))
303  timeStepControl_->setFinalTime(timeFinal);
304  bool itgrStatus = advanceTime();
305  return itgrStatus;
306 }
307 
308 template <class Scalar>
310 {
311  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
312  out->setOutputToRootOnly(0);
313  if (isInitialized_ == false) {
314  Teuchos::OSTab ostab(out, 1, "StartIntegrator");
315  *out << "Failure - IntegratorBasic is not initialized." << std::endl;
316  setStatus(Status::FAILED);
317  return;
318  }
319 
320  // set the Abs/Rel tolerance
321  auto cs = solutionHistory_->getCurrentState();
322  cs->setTolRel(timeStepControl_->getMaxRelError());
323  cs->setTolAbs(timeStepControl_->getMaxAbsError());
324 
325  integratorTimer_->start();
326  // get optimal initial time step
327  const Scalar initDt = std::min(timeStepControl_->getInitTimeStep(),
328  stepper_->getInitTimeStep(solutionHistory_));
329  // update initial time step
330  timeStepControl_->setInitTimeStep(initDt);
331  timeStepControl_->initialize();
332  setStatus(WORKING);
333 }
334 
335 template <class Scalar>
337 {
338  TEMPUS_FUNC_TIME_MONITOR("Tempus::IntegratorBasic::advanceTime()");
339  {
340  startIntegrator();
341  integratorObserver_->observeStartIntegrator(*this);
342 
343  while (
344  integratorStatus_ == WORKING &&
345  timeStepControl_->timeInRange(solutionHistory_->getCurrentTime()) &&
346  timeStepControl_->indexInRange(solutionHistory_->getCurrentIndex())) {
347  stepperTimer_->reset();
348  stepperTimer_->start();
349  solutionHistory_->initWorkingState();
350 
351  startTimeStep();
352  integratorObserver_->observeStartTimeStep(*this);
353 
354  timeStepControl_->setNextTimeStep(solutionHistory_, integratorStatus_);
355  integratorObserver_->observeNextTimeStep(*this);
356 
357  if (integratorStatus_ == Status::FAILED) break;
358  solutionHistory_->getWorkingState()->setSolutionStatus(WORKING);
359 
360  integratorObserver_->observeBeforeTakeStep(*this);
361 
362  stepper_->takeStep(solutionHistory_);
363 
364  integratorObserver_->observeAfterTakeStep(*this);
365 
366  stepperTimer_->stop();
367  checkTimeStep();
368  integratorObserver_->observeAfterCheckTimeStep(*this);
369 
370  solutionHistory_->promoteWorkingState();
371  integratorObserver_->observeEndTimeStep(*this);
372  }
373 
374  endIntegrator();
375  integratorObserver_->observeEndIntegrator(*this);
376  }
377 
378  return (integratorStatus_ == Status::PASSED);
379 }
380 
381 template <class Scalar>
383 {
384  auto ws = solutionHistory_->getWorkingState();
385 
386  // set the Abs/Rel tolerance
387  ws->setTolRel(timeStepControl_->getMaxRelError());
388  ws->setTolAbs(timeStepControl_->getMaxAbsError());
389 
390  // Check if we need to dump screen output this step
391  std::vector<int>::const_iterator it = std::find(
392  outputScreenIndices_.begin(), outputScreenIndices_.end(), ws->getIndex());
393  if (it == outputScreenIndices_.end())
394  ws->setOutputScreen(false);
395  else
396  ws->setOutputScreen(true);
397 
398  const int initial = timeStepControl_->getInitIndex();
399  if ((ws->getIndex() - initial) % outputScreenInterval_ == 0)
400  ws->setOutputScreen(true);
401 }
402 
403 template <class Scalar>
405 {
406  using Teuchos::RCP;
407  auto ws = solutionHistory_->getWorkingState();
408 
409  // Too many TimeStep failures, Integrator fails.
410  if (ws->getNFailures() >= timeStepControl_->getMaxFailures()) {
411  RCP<Teuchos::FancyOStream> out = this->getOStream();
412  out->setOutputToRootOnly(0);
413  Teuchos::OSTab ostab(out, 2, "checkTimeStep");
414  *out << "Failure - Stepper has failed more than the maximum allowed.\n"
415  << " (nFailures = " << ws->getNFailures()
416  << ") >= (nFailuresMax = " << timeStepControl_->getMaxFailures() << ")"
417  << std::endl;
418  setStatus(Status::FAILED);
419  return;
420  }
421  if (ws->getNConsecutiveFailures() >=
422  timeStepControl_->getMaxConsecFailures()) {
423  RCP<Teuchos::FancyOStream> out = this->getOStream();
424  out->setOutputToRootOnly(0);
425  Teuchos::OSTab ostab(out, 1, "checkTimeStep");
426  *out << "Failure - Stepper has failed more than the maximum "
427  << "consecutive allowed.\n"
428  << " (nConsecutiveFailures = " << ws->getNConsecutiveFailures()
429  << ") >= (nConsecutiveFailuresMax = "
430  << timeStepControl_->getMaxConsecFailures() << ")" << std::endl;
431  setStatus(Status::FAILED);
432  return;
433  }
434 
435  // Timestep size is at the minimum timestep size and the step failed.
436  if (ws->getTimeStep() <= timeStepControl_->getMinTimeStep() &&
437  ws->getSolutionStatus() == Status::FAILED) {
438  RCP<Teuchos::FancyOStream> out = this->getOStream();
439  out->setOutputToRootOnly(0);
440  Teuchos::OSTab ostab(out, 1, "checkTimeStep");
441  *out << "Failure - Stepper has failed and the time step size is "
442  << "at the minimum.\n"
443  << " Solution Status = " << toString(ws->getSolutionStatus())
444  << std::endl
445  << " (TimeStep = " << ws->getTimeStep()
446  << ") <= (Minimum TimeStep = " << timeStepControl_->getMinTimeStep()
447  << ")" << std::endl;
448  setStatus(Status::FAILED);
449  return;
450  }
451 
452  // Check Stepper failure.
453  if (ws->getSolutionStatus() == Status::FAILED ||
454  // Constant time step failure
455  ((timeStepControl_->getStepType() == "Constant") &&
456  !approxEqual(ws->getTimeStep(), timeStepControl_->getInitTimeStep()))) {
457  RCP<Teuchos::FancyOStream> out = this->getOStream();
458  out->setOutputToRootOnly(0);
459  Teuchos::OSTab ostab(out, 0, "checkTimeStep");
460  *out << std::scientific << std::setw(6) << std::setprecision(3)
461  << ws->getIndex() << std::setw(11) << std::setprecision(3)
462  << ws->getTime() << std::setw(11) << std::setprecision(3)
463  << ws->getTimeStep() << " STEP FAILURE!! - ";
464  if (ws->getSolutionStatus() == Status::FAILED) {
465  *out << "Solution Status = " << toString(ws->getSolutionStatus())
466  << std::endl;
467  }
468  else if ((timeStepControl_->getStepType() == "Constant") &&
469  (ws->getTimeStep() != timeStepControl_->getInitTimeStep())) {
470  *out << "dt != Constant dt (=" << timeStepControl_->getInitTimeStep()
471  << ")" << std::endl;
472  }
473 
474  ws->setNFailures(ws->getNFailures() + 1);
475  ws->setNRunningFailures(ws->getNRunningFailures() + 1);
476  ws->setNConsecutiveFailures(ws->getNConsecutiveFailures() + 1);
477  ws->setSolutionStatus(Status::FAILED);
478  return;
479  }
480 
481  // TIME STEP PASSED basic tests! Ensure it is set as such.
482  ws->setSolutionStatus(Status::PASSED);
483 }
484 
485 template <class Scalar>
487 {
488  std::string exitStatus;
489  if (solutionHistory_->getCurrentState()->getSolutionStatus() ==
490  Status::FAILED ||
491  integratorStatus_ == Status::FAILED) {
492  exitStatus = "Time integration FAILURE!";
493  }
494  else {
495  setStatus(Status::PASSED);
496  exitStatus = "Time integration complete.";
497  }
498 
499  integratorTimer_->stop();
500 }
501 
502 template <class Scalar>
504 {
505  // Parse output indices
506  std::string delimiters(",");
507  std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
508  std::string::size_type pos = str.find_first_of(delimiters, lastPos);
509  while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
510  std::string token = str.substr(lastPos, pos - lastPos);
511  outputScreenIndices_.push_back(int(std::stoi(token)));
512  if (pos == std::string::npos) break;
513 
514  lastPos = str.find_first_not_of(delimiters, pos);
515  pos = str.find_first_of(delimiters, lastPos);
516  }
517 
518  // order output indices and remove duplicates.
519  std::sort(outputScreenIndices_.begin(), outputScreenIndices_.end());
520  outputScreenIndices_.erase(
521  std::unique(outputScreenIndices_.begin(), outputScreenIndices_.end()),
522  outputScreenIndices_.end());
523  return;
524 }
525 
526 template <class Scalar>
528 {
529  std::stringstream ss;
530  for (size_t i = 0; i < outputScreenIndices_.size(); ++i) {
531  if (i != 0) ss << ", ";
532  ss << outputScreenIndices_[i];
533  }
534  return ss.str();
535 }
536 
539 template <class Scalar>
542 {
544  Teuchos::parameterList(getIntegratorName());
545 
546  pl->set("Integrator Type", getIntegratorType(),
547  "'Integrator Type' must be 'Integrator Basic'.");
548 
549  pl->set("Screen Output Index List", getScreenOutputIndexListString(),
550  "Screen Output Index List. Required to be in TimeStepControl range "
551  "['Minimum Time Step Index', 'Maximum Time Step Index']");
552 
553  pl->set("Screen Output Index Interval", getScreenOutputIndexInterval(),
554  "Screen Output Index Interval (e.g., every 100 time steps)");
555 
556  pl->set("Stepper Name", stepper_->getStepperName(),
557  "'Stepper Name' selects the Stepper block to construct (Required).");
558 
559  pl->set("Solution History", *solutionHistory_->getValidParameters());
560  pl->set("Time Step Control", *timeStepControl_->getValidParameters());
561 
563  Teuchos::parameterList("Tempus");
564 
565  tempusPL->set("Integrator Name", pl->name());
566  tempusPL->set(pl->name(), *pl);
567  tempusPL->set(stepper_->getStepperName(), *stepper_->getValidParameters());
568 
569  return tempusPL;
570 }
571 
572 // Nonmember constructor
573 // ------------------------------------------------------------------------
574 template <class Scalar>
576  Teuchos::RCP<Teuchos::ParameterList> tempusPL, bool runInitialize)
577 {
578  auto integrator = Teuchos::rcp(new IntegratorBasic<Scalar>());
579  if (tempusPL == Teuchos::null || tempusPL->numParams() == 0)
580  return integrator; // integrator is not initialized (missing model and IC).
581 
582  auto integratorName = tempusPL->get<std::string>("Integrator Name");
583  auto integratorPL = Teuchos::sublist(tempusPL, integratorName, true);
584 
585  std::string integratorType =
586  integratorPL->get<std::string>("Integrator Type");
588  integratorType != "Integrator Basic", std::logic_error,
589  "Error - For IntegratorBasic, 'Integrator Type' should be "
590  << "'Integrator Basic'.\n"
591  << " Integrator Type = " << integratorType << "\n");
592 
593  integrator->setIntegratorName(integratorName);
594 
595  // Validate the Integrator ParameterList
596  auto validPL = Teuchos::rcp_const_cast<Teuchos::ParameterList>(
597  integrator->getValidParameters());
598  auto vIntegratorName = validPL->template get<std::string>("Integrator Name");
599  auto vIntegratorPL = Teuchos::sublist(validPL, vIntegratorName, true);
600  integratorPL->validateParametersAndSetDefaults(*vIntegratorPL, 1);
601 
602  // Set Stepper
603  if (integratorPL->isParameter("Stepper Name")) {
604  // Construct from Integrator ParameterList
605  auto stepperName = integratorPL->get<std::string>("Stepper Name");
606  auto stepperPL = Teuchos::sublist(tempusPL, stepperName, true);
607  stepperPL->setName(stepperName);
608  auto sf = Teuchos::rcp(new StepperFactory<Scalar>());
609  integrator->setStepper(sf->createStepper(stepperPL));
610  }
611  else {
612  // Construct default Stepper
613  auto stepper = Teuchos::rcp(new StepperForwardEuler<Scalar>());
614  integrator->setStepper(stepper);
615  }
616 
617  // Set TimeStepControl
618  if (integratorPL->isSublist("Time Step Control")) {
619  // Construct from Integrator ParameterList
620  auto tscPL = Teuchos::sublist(integratorPL, "Time Step Control", true);
621  integrator->setTimeStepControl(
622  createTimeStepControl<Scalar>(tscPL, runInitialize));
623  }
624  else {
625  // Construct default TimeStepControl
626  integrator->setTimeStepControl(rcp(new TimeStepControl<Scalar>()));
627  }
628 
629  // Set SolutionHistory
630  if (integratorPL->isSublist("Solution History")) {
631  // Construct from Integrator ParameterList
632  auto shPL = Teuchos::sublist(integratorPL, "Solution History", true);
633  auto sh = createSolutionHistoryPL<Scalar>(shPL);
634  integrator->setSolutionHistory(sh);
635  }
636  else {
637  // Construct default SolutionHistory
638  integrator->setSolutionHistory(createSolutionHistory<Scalar>());
639  }
640 
641  // Set Observer to default.
642  integrator->setObserver(Teuchos::null);
643 
644  // Set screen output interval.
645  integrator->setScreenOutputIndexInterval(
646  integratorPL->get<int>("Screen Output Index Interval",
647  integrator->getScreenOutputIndexInterval()));
648 
649  // Parse screen output indices
650  auto str = integratorPL->get<std::string>("Screen Output Index List", "");
651  integrator->setScreenOutputIndexList(str);
652 
653  return integrator; // integrator is not initialized (missing model and IC).
654 }
655 
656 // Nonmember constructor
657 // ------------------------------------------------------------------------
658 template <class Scalar>
662  bool runInitialize)
663 {
664  auto integrator = createIntegratorBasic<Scalar>(tempusPL, runInitialize);
665  if (model == Teuchos::null) return integrator;
666 
668  integrator->setModel(constModel);
669 
670  // Construct default IC state from the application model and TimeStepControl
671  auto newState =
672  createSolutionStateME(integrator->getStepper()->getModel(),
673  integrator->getStepper()->getDefaultStepperState());
674  newState->setTime(integrator->getTimeStepControl()->getInitTime());
675  newState->setIndex(integrator->getTimeStepControl()->getInitIndex());
676  newState->setTimeStep(integrator->getTimeStepControl()->getInitTimeStep());
677  newState->setTolRel(integrator->getTimeStepControl()->getMaxRelError());
678  newState->setTolAbs(integrator->getTimeStepControl()->getMaxAbsError());
679  newState->setOrder(integrator->getStepper()->getOrder());
680  newState->setSolutionStatus(Status::PASSED); // ICs are considered passing.
681 
682  // Set SolutionHistory IC
683  auto sh = integrator->getNonConstSolutionHistory();
684  sh->addState(newState);
685  integrator->getStepper()->setInitialConditions(sh);
686 
687  if (runInitialize) integrator->initialize();
688 
689  return integrator;
690 }
691 
693 template <class Scalar>
696  std::string stepperType)
697 {
698  auto integrator = Teuchos::rcp(new IntegratorBasic<Scalar>());
699 
700  auto sf = Teuchos::rcp(new StepperFactory<Scalar>());
701  auto stepper = sf->createStepper(stepperType, model);
702  integrator->setStepper(stepper);
703  integrator->initializeSolutionHistory();
704  integrator->initialize();
705 
706  return integrator;
707 }
708 
710 template <class Scalar>
712 {
714 }
715 
717 template <class Scalar>
720  std::vector<Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> > > models,
721  bool runInitialize)
722 {
723  auto integratorName = tempusPL->get<std::string>("Integrator Name");
724  auto integratorPL = Teuchos::sublist(tempusPL, integratorName, true);
725 
726  std::string integratorType =
727  integratorPL->get<std::string>("Integrator Type");
729  integratorType != "Integrator Basic", std::logic_error,
730  "Error - For IntegratorBasic, 'Integrator Type' should be "
731  << "'Integrator Basic'.\n"
732  << " Integrator Type = " << integratorType << "\n");
733 
734  auto integrator = Teuchos::rcp(new IntegratorBasic<Scalar>());
735  integrator->setIntegratorName(integratorName);
736 
737  TEUCHOS_TEST_FOR_EXCEPTION(
738  !integratorPL->isParameter("Stepper Name"), std::logic_error,
739  "Error - Need to set the 'Stepper Name' in 'Integrator Basic'.\n");
740 
741  auto stepperName = integratorPL->get<std::string>("Stepper Name");
742  TEUCHOS_TEST_FOR_EXCEPTION(
743  stepperName == "Operator Split", std::logic_error,
744  "Error - 'Stepper Name' should be 'Operator Split'.\n");
745 
746  // Construct Steppers from Integrator ParameterList
747  auto stepperPL = Teuchos::sublist(tempusPL, stepperName, true);
748  stepperPL->setName(stepperName);
749  auto sf = Teuchos::rcp(new StepperFactory<Scalar>());
750  integrator->setStepper(sf->createStepper(stepperPL, models));
751 
752  // Set TimeStepControl
753  if (integratorPL->isSublist("Time Step Control")) {
754  // Construct from Integrator ParameterList
755  auto tscPL = Teuchos::sublist(integratorPL, "Time Step Control", true);
756  integrator->setTimeStepControl(
757  createTimeStepControl<Scalar>(tscPL, runInitialize));
758  }
759  else {
760  // Construct default TimeStepControl
761  integrator->setTimeStepControl(rcp(new TimeStepControl<Scalar>()));
762  }
763 
764  // Construct default IC state from the application model and TimeStepControl
765  auto newState =
766  createSolutionStateME(integrator->getStepper()->getModel(),
767  integrator->getStepper()->getDefaultStepperState());
768  newState->setTime(integrator->getTimeStepControl()->getInitTime());
769  newState->setIndex(integrator->getTimeStepControl()->getInitIndex());
770  newState->setTimeStep(integrator->getTimeStepControl()->getInitTimeStep());
771  newState->setTolRel(integrator->getTimeStepControl()->getMaxRelError());
772  newState->setTolAbs(integrator->getTimeStepControl()->getMaxAbsError());
773  newState->setOrder(integrator->getStepper()->getOrder());
774  newState->setSolutionStatus(Status::PASSED); // ICs are considered passing.
775 
776  // Set SolutionHistory
777  auto shPL = Teuchos::sublist(integratorPL, "Solution History", true);
778  auto sh = createSolutionHistoryPL<Scalar>(shPL);
779  sh->addState(newState);
780  integrator->getStepper()->setInitialConditions(sh);
781  integrator->setSolutionHistory(sh);
782 
783  // Set Observer to default.
784  integrator->setObserver(Teuchos::null);
785 
786  // Set screen output interval.
787  integrator->setScreenOutputIndexInterval(
788  integratorPL->get<int>("Screen Output Index Interval",
789  integrator->getScreenOutputIndexInterval()));
790 
791  // Parse screen output indices
792  auto str = integratorPL->get<std::string>("Screen Output Index List", "");
793  integrator->setScreenOutputIndexList(str);
794 
795  auto validPL = Teuchos::rcp_const_cast<Teuchos::ParameterList>(
796  integrator->getValidParameters());
797 
798  // Validate the Integrator ParameterList
799  auto vIntegratorName = validPL->template get<std::string>("Integrator Name");
800  auto vIntegratorPL = Teuchos::sublist(validPL, vIntegratorName, true);
801  integratorPL->validateParametersAndSetDefaults(*vIntegratorPL);
802 
803  // Validate the Stepper ParameterList
804  auto vStepperName = vIntegratorPL->template get<std::string>("Stepper Name");
805  auto vStepperPL = Teuchos::sublist(validPL, vStepperName, true);
806  stepperPL->validateParametersAndSetDefaults(*vStepperPL);
807 
808  integrator->initialize();
809 
810  return integrator;
811 }
812 
813 } // namespace Tempus
814 #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.
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
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.