10#ifndef Tempus_SolutionHistory_impl_hpp
11#define Tempus_SolutionHistory_impl_hpp
13#include "Teuchos_StandardParameterEntryValidators.hpp"
14#include "Teuchos_TimeMonitor.hpp"
16#include "Thyra_VectorStdOps.hpp"
23template <
class Scalar>
34template <
class Scalar>
51template <
class Scalar>
59 TEUCHOS_TEST_FOR_EXCEPTION(
60 true, std::logic_error,
61 "Error - Storage type is STORAGE_TYPE_INVALID.\n");
67 if (state->getTime() >=
history_->front()->getTime()) {
74 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
75 Teuchos::OSTab ostab(out, 1,
"SolutionHistory::addState");
76 *out <<
"Warning, state is older than oldest state in history. "
77 <<
"State not added!" << std::endl;
84 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
85 "Error - unknown storage type.\n");
94 typename std::vector<Teuchos::RCP<SolutionState<Scalar> > >::iterator
97 const Scalar newTime = state->getTime();
98 for (; state_it <
history_->end(); state_it++) {
99 const Scalar shTime = (*state_it)->getTime();
101 const Scalar denom = std::max(std::fabs(shTime), std::fabs(newTime));
102 if (std::fabs(newTime - shTime) < 1.0e-14 * denom) {
104 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
105 Teuchos::OSTab ostab(out, 1,
"SolutionHistory::addState");
106 *out <<
"Warning, state to be added matches state in history. "
107 <<
"State not added!" << std::endl;
109 *out <<
"===============" << std::endl;
110 *out <<
"Added SolutionState -- ";
111 (*state_it)->describe(*out, Teuchos::VERB_MEDIUM);
112 *out <<
"===============" << std::endl;
113 this->
describe(*out, Teuchos::VERB_MEDIUM);
119 if (newTime < shTime)
break;
121 if (!equal)
history_->insert(state_it, state);
124 TEUCHOS_TEST_FOR_EXCEPTION(
126 "Error - SolutionHistory::addState() Invalid history size!\n");
131template <
class Scalar>
139 state->setIndex(cs->getIndex() + 1);
141 state->setTime(cs->getTime() + cs->getTimeStep());
142 state->setTimeStep(cs->getTimeStep());
149template <
class Scalar>
155 for (; state_it <
history_->rend(); state_it++) {
156 if (state->getTime() == (*state_it)->getTime())
break;
159 TEUCHOS_TEST_FOR_EXCEPTION(state_it ==
history_->rend(), std::logic_error,
160 "Error - removeState() Could not remove state = "
161 << (*state_it)->description());
164 history_->erase(std::next(state_it).base());
169template <
class Scalar>
172 Teuchos::RCP<SolutionState<Scalar> > tmpState =
findState(time);
176template <
class Scalar>
178 const Scalar time)
const
183 scale = (*history_)[
history_->size() - 1]->getTime();
187 TEUCHOS_TEST_FOR_EXCEPTION(
190 "Error - SolutionHistory::findState() Requested time out of range!\n"
198 for (; state_it <
history_->end(); ++state_it) {
202 TEUCHOS_TEST_FOR_EXCEPTION(state_it ==
history_->end(), std::logic_error,
203 "Error - SolutionHistory::findState()!\n"
204 " Did not find a SolutionState with time = "
205 << time << std::endl);
210template <
class Scalar>
212 const Scalar time)
const
214 Teuchos::RCP<SolutionState<Scalar> > state_out =
getCurrentState()->clone();
219template <
class Scalar>
227template <
class Scalar>
230 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::SolutionHistory::initWorkingState()");
232 TEUCHOS_TEST_FOR_EXCEPTION(
234 "Error - SolutionHistory::initWorkingState()\n"
235 "Can not initialize working state without a current state!\n");
249 Teuchos::RCP<SolutionState<Scalar> > newState;
256 newState = (*history_)[0];
268template <
class Scalar>
274 ws->setNFailures(std::max(0, ws->getNFailures() - 1));
275 ws->setNConsecutiveFailures(0);
278 ws->setIsInterpolated(
false);
282 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
283 Teuchos::OSTab ostab(out, 1,
"SolutionHistory::promoteWorkingState()");
284 *out <<
"Warning - WorkingState is not passing, so not promoted!\n"
289template <
class Scalar>
296 auto sh_history = sh->getHistory();
297 typename std::vector<Teuchos::RCP<SolutionState<Scalar> > >::iterator
298 state_it = sh_history->begin();
299 for (; state_it < sh_history->end(); state_it++) this->
addState(*state_it);
302 Teuchos::rcp_const_cast<Interpolator<Scalar> >(sh->getInterpolator());
309template <
class Scalar>
316 if (storage_limit != 1) {
317 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
318 Teuchos::OSTab ostab(out, 1,
"SolutionHistory::setStorageLimit");
319 *out <<
"Warning - 'Storage Limit' for 'Keep Newest' is 1.\n"
320 <<
" (Storage Limit = " << storage_limit <<
"). Resetting to 1."
326 if (storage_limit != 2) {
327 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
328 Teuchos::OSTab ostab(out, 1,
"SolutionHistory::setStorageLimit");
329 *out <<
"Warning - 'Storage Limit' for 'Undo' is 2.\n"
330 <<
" (Storage Limit = " << storage_limit <<
"). Resetting to 2."
342 TEUCHOS_TEST_FOR_EXCEPTION(
344 "Error - requested storage limit = "
346 <<
" is smaller than the current number of states stored = "
352template <
class Scalar>
365template <
class Scalar>
368 if (s ==
"Keep Newest") {
372 else if (s ==
"Undo") {
376 else if (s ==
"Static") {
379 else if (s ==
"Unlimited") {
383 TEUCHOS_TEST_FOR_EXCEPTION(
384 true, std::logic_error,
385 "Error - Unknown 'Storage Type' = '" << s <<
"'\n");
390template <
class Scalar>
393 std::string s =
"Invalid";
405template <
class Scalar>
406Teuchos::RCP<SolutionState<Scalar> >
409 Teuchos::RCP<SolutionState<Scalar> > state = Teuchos::null;
413 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
414 Teuchos::OSTab ostab(out, 1,
"SolutionHistory::getStateTimeIndexN");
415 *out <<
"Warning - getStateTimeIndexN() No states in SolutionHistory!"
420 state = (*history_)[m - 1];
425template <
class Scalar>
426Teuchos::RCP<SolutionState<Scalar> >
429 Teuchos::RCP<SolutionState<Scalar> > state = Teuchos::null;
433 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
434 Teuchos::OSTab ostab(out, 1,
"SolutionHistory::getStateTimeIndexNM1");
435 *out <<
"Warning - getStateTimeIndexNM1() Not enough states in "
436 <<
"SolutionHistory! Size of history = " <<
getNumStates()
441 const int n = (*history_)[m - 1]->getIndex();
442 const int nm1 = (*history_)[m - 2]->getIndex();
448 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
449 Teuchos::OSTab ostab(out, 1,
"SolutionHistory::getStateTimeIndexNM1");
450 *out <<
"Warning - getStateTimeIndexNM1() Timestep index n-1 is not in "
451 <<
"SolutionHistory!\n"
452 <<
" (n)th index = " << n <<
"\n"
453 <<
" (n-1)th index = " << nm1 << std::endl;
457 state = (*history_)[m - 2];
464template <
class Scalar>
465Teuchos::RCP<SolutionState<Scalar> >
468 Teuchos::RCP<SolutionState<Scalar> > state = Teuchos::null;
472 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
473 Teuchos::OSTab ostab(out, 1,
"SolutionHistory::getStateTimeIndexNM2");
474 *out <<
"Warning - getStateTimeIndexNM2() Not enough states in "
475 <<
"SolutionHistory! Size of history = " <<
getNumStates()
480 const int n = (*history_)[m - 1]->getIndex();
481 const int nm2 = (*history_)[m - 3]->getIndex();
486 const int nm1 = (*history_)[m - 2]->getIndex();
488 state = (*history_)[m - 2];
491 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
492 Teuchos::OSTab ostab(out, 1,
"SolutionHistory::getStateTimeIndexNM2");
493 *out <<
"Warning - getStateTimeIndexNM2() Timestep index n-2 is not in "
494 <<
"SolutionHistory!\n"
495 <<
" (n)th index = " << n <<
"\n"
496 <<
" (n-2)th index = " << nm2 << std::endl;
500 state = (*history_)[m - 3];
507template <
class Scalar>
509 int index,
bool warn)
const
511 typename std::vector<Teuchos::RCP<SolutionState<Scalar> > >::iterator
513 for (; state_it <
history_->end(); state_it++) {
514 if ((*state_it)->getIndex() == index)
break;
517 Teuchos::RCP<SolutionState<Scalar> > state = Teuchos::null;
520 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
521 Teuchos::OSTab ostab(out, 1,
"SolutionHistory::getStateTimeIndex");
522 *out <<
"Warning - getStateTimeIndex() Timestep index is not in "
523 <<
"SolutionHistory!\n"
524 <<
" index = " << index << std::endl;
533template <
class Scalar>
536 return (
"Tempus::SolutionHistory - '" +
name_ +
"'");
539template <
class Scalar>
541 Teuchos::FancyOStream& out,
const Teuchos::EVerbosityLevel verbLevel)
const
543 auto l_out = Teuchos::fancyOStream(out.getOStream());
544 Teuchos::OSTab ostab(*l_out, 2, this->
description());
545 l_out->setOutputToRootOnly(0);
547 *l_out <<
"\n--- " << this->
description() <<
" ---" << std::endl;
549 if ((Teuchos::as<int>(verbLevel) ==
550 Teuchos::as<int>(Teuchos::VERB_DEFAULT)) ||
551 (Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_LOW))) {
556 *l_out <<
" number of states = " <<
history_->size() << std::endl;
558 *l_out <<
" time range = (" <<
history_->front()->getTime() <<
", "
559 <<
history_->back()->getTime() <<
")" << std::endl;
563 if (Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_MEDIUM)) {
564 for (
int i = 0; i < (int)
history_->size(); ++i)
565 (*
history_)[i]->describe(*l_out, verbLevel);
567 *l_out << std::string(this->
description().length() + 8,
'-') << std::endl;
570template <
class Scalar>
571Teuchos::RCP<const Teuchos::ParameterList>
574 Teuchos::RCP<Teuchos::ParameterList> pl =
575 Teuchos::parameterList(
"Solution History");
581 "'Storage Type' sets the memory storage. "
582 "'Keep Newest' - will retain the single newest solution state. "
583 "'Undo' - will retain two solution states in order to do a single undo. "
584 "'Static' - will retain 'Storage Limit' number of solution states. "
585 "'Unlimited' - will not remove any solution states!");
589 "Limit on the number of SolutionStates that SolutionHistory can have.");
591 pl->set(
"Interpolator", *
interpolator_->getNonconstParameterList());
596template <
class Scalar>
597Teuchos::RCP<Teuchos::ParameterList>
603template <
class Scalar>
607 if (interpolator == Teuchos::null) {
616template <
class Scalar>
617Teuchos::RCP<Interpolator<Scalar> >
623template <
class Scalar>
624Teuchos::RCP<const Interpolator<Scalar> >
630template <
class Scalar>
633 Teuchos::RCP<Interpolator<Scalar> > old_interpolator =
interpolator_;
635 return old_interpolator;
638template <
class Scalar>
641 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
642 Teuchos::OSTab ostab(out, 1,
"SolutionHistory::printHistory");
644 <<
" (w - working; c - current; i - interpolated)" << std::endl;
645 for (
int i = 0; i < (int)
history_->size(); ++i) {
646 auto state = (*history_)[i];
652 else if (state->getIsInterpolated() ==
true)
656 *out <<
"[" << i <<
"] = " << state << std::endl;
657 if (verb ==
"medium" || verb ==
"high") {
658 if (state != Teuchos::null) {
659 auto x = state->getX();
660 *out <<
" x = " << x << std::endl
661 <<
" norm(x) = " << Thyra::norm(*x) << std::endl;
664 if (verb ==
"high") {
665 (*history_)[i]->describe(*out, this->getVerbLevel());
670template <
class Scalar>
673 TEUCHOS_TEST_FOR_EXCEPTION(
675 "Error - SolutionHistory::initialize() Invalid history size!\n");
677 TEUCHOS_TEST_FOR_EXCEPTION(
679 "Error - SolutionHistory::initialize() Interpolator is not set!\n");
681 TEUCHOS_TEST_FOR_EXCEPTION(
storageLimit_ < 1, std::logic_error,
682 "Error - SolutionHistory::initialize() Storage "
683 "Limit needs to a positive integer!\n"
687 TEUCHOS_TEST_FOR_EXCEPTION(
689 "Error - SolutionHistory::initialize() Storage Type is invalid!\n");
691 TEUCHOS_TEST_FOR_EXCEPTION(
694 "Error - SolutionHistory::initialize() \n"
696 <<
"', Storage Limit needs to be one.\n"
699 TEUCHOS_TEST_FOR_EXCEPTION(
702 "Error - SolutionHistory::initialize() \n"
704 <<
"', Storage Limit needs to be two.\n"
713template <
class Scalar>
717 sh->setName(
"From createSolutionHistory");
722template <
class Scalar>
724 Teuchos::RCP<Teuchos::ParameterList> pl)
727 sh->setName(
"From createSolutionHistoryPL");
729 if (pl == Teuchos::null || pl->numParams() == 0)
return sh;
731 pl->validateParametersAndSetDefaults(*sh->getValidParameters());
733 sh->setName(pl->name());
734 sh->setStorageTypeString(pl->get(
"Storage Type",
"Undo"));
735 sh->setStorageLimit(pl->get(
"Storage Limit", 2));
738 Teuchos::sublist(pl,
"Interpolator")));
743template <
class Scalar>
748 sh->setName(
"From createSolutionHistoryState");
753template <
class Scalar>
761 state->setTimeStep(0.0);
766 sh->setName(
"From createSolutionHistoryME");
static Teuchos::RCP< Interpolator< Scalar > > createInterpolator(std::string interpolatorType="")
Create default interpolator from interpolator type (e.g., "Linear").
Base strategy class for interpolation functionality.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
std::string getName() const
Get this SolutionHistory's name.
Teuchos::RCP< SolutionState< Scalar > > getStateTimeIndex(int index, bool warn=true) const
Get the state with timestep index equal to "index".
void setName(std::string name)
Set this SolutionHistory's name.
Teuchos::RCP< SolutionState< Scalar > > getStateTimeIndexNM1(bool warn=true) const
Get the state with timestep index equal to n-1.
void initWorkingState()
Initialize the working state.
Teuchos::RCP< SolutionState< Scalar > > workingState_
The state being worked on.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Return a valid ParameterList with current settings.
Scalar minTime() const
Return the current minimum time of the SolutionStates.
Teuchos::RCP< const Interpolator< Scalar > > getInterpolator() const
virtual std::string description() const
void addState(const Teuchos::RCP< SolutionState< Scalar > > &state, bool doChecks=true)
Add solution state to history.
Teuchos::RCP< SolutionState< Scalar > > getStateTimeIndexNM2(bool warn=true) const
Get the state with timestep index equal to n-2.
void setStorageType(StorageType st)
Set the storage type via enum.
bool isInitialized_
Bool if SolutionHistory is initialized.
void setHistory(Teuchos::RCP< std::vector< Teuchos::RCP< SolutionState< Scalar > > > > h)
Set underlining history.
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
Return a valid non-const ParameterList with current settings.
std::string getStorageTypeString() const
Set the string storage type.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
void copy(Teuchos::RCP< const SolutionHistory< Scalar > > sh)
Teuchos::RCP< Interpolator< Scalar > > unSetInterpolator()
Unset the interpolator for this history.
int getNumStates() const
Get the number of states.
void initialize() const
Initialize SolutionHistory.
void setStorageLimit(int storage_limit)
Set the maximum storage of this history.
int getStorageLimit() const
Get the maximum storage of this history.
Teuchos::RCP< SolutionState< Scalar > > getWorkingState(bool warn=true) const
Return the working state.
Teuchos::RCP< Interpolator< Scalar > > getNonconstInterpolator()
void setStorageTypeString(std::string st)
Set the storage type via string.
Teuchos::RCP< SolutionState< Scalar > > findState(const Scalar time) const
Find solution state at requested time (no interpolation).
void printHistory(std::string verb="low") const
Print information on States in the SolutionHistory.
Teuchos::RCP< SolutionState< Scalar > > getCurrentState() const
Return the current state, i.e., the last accepted state.
Teuchos::RCP< SolutionState< Scalar > > interpolateState(const Scalar time) const
Generate and interpolate a new solution state at requested time.
void removeState(const Teuchos::RCP< SolutionState< Scalar > > &state)
Remove solution state.
void addWorkingState(const Teuchos::RCP< SolutionState< Scalar > > &state, const bool updateTime=true)
Add a working solution state to history.
Teuchos::RCP< SolutionState< Scalar > > getStateTimeIndexN(bool warn=true) const
Get the state with timestep index equal to n.
Teuchos::RCP< std::vector< Teuchos::RCP< SolutionState< Scalar > > > > history_
void setInterpolator(const Teuchos::RCP< Interpolator< Scalar > > &interpolator)
Set the interpolator for this history.
Teuchos::RCP< Interpolator< Scalar > > interpolator_
SolutionHistory()
Default Contructor.
void clear()
Clear the history.
Scalar maxTime() const
Return the current maximum time of the SolutionStates.
void promoteWorkingState()
Promote the working state to current state.
Solution state for integrators and steppers.
@ STORAGE_TYPE_STATIC
Keep a fix number of states.
@ STORAGE_TYPE_UNLIMITED
Grow the history as needed.
@ STORAGE_TYPE_INVALID
Invalid storage type.
@ STORAGE_TYPE_UNDO
Keep the 2 newest states for undo.
@ STORAGE_TYPE_KEEP_NEWEST
Keep the single newest state.
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.
Teuchos::RCP< SolutionHistory< Scalar > > createSolutionHistoryPL(Teuchos::RCP< Teuchos::ParameterList > pList)
Nonmember constructor from a ParameterList.
bool approxZero(Scalar value, Scalar tol=Teuchos::ScalarTraits< Scalar >::sfmin())
Test if value is approximately zero within tolerance.
Teuchos::RCP< SolutionHistory< Scalar > > createSolutionHistoryState(const Teuchos::RCP< SolutionState< Scalar > > &state)
Nonmember contructor from a SolutionState.
void interpolate(const Interpolator< Scalar > &interpolator, const Scalar &t, SolutionState< Scalar > *state_out)
Nonmember functions.
bool approxEqualAbsTol(Scalar a, Scalar b, Scalar absTol)
Test if values are approximately equal within the absolute tolerance.
Teuchos::RCP< SolutionHistory< Scalar > > createSolutionHistory()
Nonmember constructor.
Teuchos::RCP< InterpolatorLagrange< Scalar > > lagrangeInterpolator()
Teuchos::RCP< SolutionHistory< Scalar > > createSolutionHistoryME(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
Nonmember contructor from a Thyra ModelEvaluator.
const Scalar numericalTol()
Numerical Tolerance (approx. max. significant digits minus two).