9#ifndef Tempus_SolutionHistory_impl_hpp
10#define Tempus_SolutionHistory_impl_hpp
12#include "Teuchos_StandardParameterEntryValidators.hpp"
13#include "Teuchos_TimeMonitor.hpp"
15#include "Thyra_VectorStdOps.hpp"
25 :
name_(
"Solution History"),
64 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
65 "Error - Storage type is STORAGE_TYPE_INVALID.\n");
71 if (state->getTime() >=
history_->front()->getTime()) {
77 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
78 Teuchos::OSTab ostab(out,1,
"SolutionHistory::addState");
79 *out <<
"Warning, state is older than oldest state in history. "
80 <<
"State not added!" << std::endl;
88 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
89 "Error - unknown storage type.\n");
97 typename std::vector<Teuchos::RCP<SolutionState<Scalar> > >::iterator
100 const Scalar newTime = state->getTime();
101 for (; state_it <
history_->end(); state_it++) {
102 const Scalar shTime = (*state_it)->getTime();
104 const Scalar denom = std::max(std::fabs(shTime), std::fabs(newTime));
105 if ( std::fabs(newTime - shTime) < 1.0e-14*denom ) {
107 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
108 Teuchos::OSTab ostab(out,1,
"SolutionHistory::addState");
109 *out <<
"Warning, state to be added matches state in history. "
110 <<
"State not added!" << std::endl;
112 *out <<
"===============" << std::endl;
113 *out <<
"Added SolutionState -- ";
114 (*state_it)->describe(*out, Teuchos::VERB_MEDIUM);
115 *out <<
"===============" << std::endl;
116 this->
describe(*out, Teuchos::VERB_MEDIUM);
122 if (newTime < shTime)
break;
124 if (!equal)
history_->insert(state_it, state);
127 TEUCHOS_TEST_FOR_EXCEPTION(
getNumStates() <= 0, std::logic_error,
128 "Error - SolutionHistory::addState() Invalid history size!\n");
134template<
class Scalar>
142 state->setIndex(cs->getIndex()+1);
144 state->setTime(cs->getTime() + cs->getTimeStep());
145 state->setTimeStep(cs->getTimeStep());
152template<
class Scalar>
158 for ( ; state_it <
history_->rend(); state_it++) {
159 if (state->getTime() == (*state_it)->getTime())
break;
162 TEUCHOS_TEST_FOR_EXCEPTION(
163 state_it ==
history_->rend(), std::logic_error,
164 "Error - removeState() Could not remove state = "
165 << (*state_it)->description());
168 history_->erase(std::next(state_it).base());
174template<
class Scalar>
177 Teuchos::RCP<SolutionState<Scalar> > tmpState =
findState(time);
182template<
class Scalar>
183Teuchos::RCP<SolutionState<Scalar> >
188 if (
history_->size() > 0) scale = (*history_)[
history_->size()-1]->getTime();
192 TEUCHOS_TEST_FOR_EXCEPTION(
193 !(
minTime()-absTol <= time && time <=
maxTime()+absTol), std::logic_error,
194 "Error - SolutionHistory::findState() Requested time out of range!\n"
196 " time = "<< time <<
"\n");
200 for ( ; state_it <
history_->end(); ++state_it) {
205 TEUCHOS_TEST_FOR_EXCEPTION(state_it ==
history_->end(), std::logic_error,
206 "Error - SolutionHistory::findState()!\n"
207 " Did not find a SolutionState with time = " <<time<< std::endl);
213template<
class Scalar>
214Teuchos::RCP<SolutionState<Scalar> >
217 Teuchos::RCP<SolutionState<Scalar> > state_out =
getCurrentState()->clone();
223template<
class Scalar>
233template<
class Scalar>
236 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::SolutionHistory::initWorkingState()");
240 "Error - SolutionHistory::initWorkingState()\n"
241 "Can not initialize working state without a current state!\n");
247 Teuchos::RCP<SolutionState<Scalar> > newState;
253 newState = (*history_)[0];
267template<
class Scalar>
273 ws->setNFailures(std::max(0,ws->getNFailures()-1));
274 ws->setNConsecutiveFailures(0);
277 ws->setIsInterpolated(
false);
280 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
281 Teuchos::OSTab ostab(out,1,
"SolutionHistory::promoteWorkingState()");
282 *out <<
"Warning - WorkingState is not passing, so not promoted!\n"
288template<
class Scalar>
294 auto sh_history = sh->getHistory();
295 typename std::vector<Teuchos::RCP<SolutionState<Scalar> > >::iterator
296 state_it = sh_history->begin();
297 for (; state_it < sh_history->end(); state_it++)
300 auto interpolator = Teuchos::rcp_const_cast<Interpolator<Scalar> >(sh->getInterpolator());
308template<
class Scalar>
315 if (storage_limit != 1) {
316 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
317 Teuchos::OSTab ostab(out,1,
"SolutionHistory::setStorageLimit");
318 *out <<
"Warning - 'Storage Limit' for 'Keep Newest' is 1.\n"
319 <<
" (Storage Limit = "<<storage_limit<<
"). Resetting to 1."
324 if (storage_limit != 2) {
325 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
326 Teuchos::OSTab ostab(out,1,
"SolutionHistory::setStorageLimit");
327 *out <<
"Warning - 'Storage Limit' for 'Undo' is 2.\n"
328 <<
" (Storage Limit = "<<storage_limit<<
"). Resetting to 2."
338 TEUCHOS_TEST_FOR_EXCEPTION(
341 <<
" is smaller than the current number of states stored = "
348template<
class Scalar>
360template<
class Scalar>
363 if ( s ==
"Keep Newest" ) {
366 }
else if ( s ==
"Undo" ) {
369 }
else if ( s ==
"Static" ) {
371 }
else if ( s ==
"Unlimited" ) {
374 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
375 "Error - Unknown 'Storage Type' = '" << s <<
"'\n");
381template<
class Scalar>
384 std::string s =
"Invalid";
393template<
class Scalar>
394Teuchos::RCP<SolutionState<Scalar> >
397 Teuchos::RCP<SolutionState<Scalar> > state = Teuchos::null;
401 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
402 Teuchos::OSTab ostab(out,1,
"SolutionHistory::getStateTimeIndexN");
403 *out <<
"Warning - getStateTimeIndexN() No states in SolutionHistory!"
407 state = (*history_)[m-1];
413template<
class Scalar>
414Teuchos::RCP<SolutionState<Scalar> >
417 Teuchos::RCP<SolutionState<Scalar> > state = Teuchos::null;
421 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
422 Teuchos::OSTab ostab(out,1,
"SolutionHistory::getStateTimeIndexNM1");
423 *out <<
"Warning - getStateTimeIndexNM1() Not enough states in "
424 <<
"SolutionHistory! Size of history = " <<
getNumStates()
428 const int n = (*history_)[m-1]->getIndex();
429 const int nm1 = (*history_)[m-2]->getIndex();
435 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
436 Teuchos::OSTab ostab(out,1,
"SolutionHistory::getStateTimeIndexNM1");
437 *out <<
"Warning - getStateTimeIndexNM1() Timestep index n-1 is not in "
438 <<
"SolutionHistory!\n"
439 <<
" (n)th index = " << n <<
"\n"
440 <<
" (n-1)th index = " << nm1 << std::endl;
443 state = (*history_)[m-2];
451template<
class Scalar>
452Teuchos::RCP<SolutionState<Scalar> >
455 Teuchos::RCP<SolutionState<Scalar> > state = Teuchos::null;
459 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
460 Teuchos::OSTab ostab(out,1,
"SolutionHistory::getStateTimeIndexNM2");
461 *out <<
"Warning - getStateTimeIndexNM2() Not enough states in "
462 <<
"SolutionHistory! Size of history = " <<
getNumStates()
466 const int n = (*history_)[m-1]->getIndex();
467 const int nm2 = (*history_)[m-3]->getIndex();
472 const int nm1 = (*history_)[m-2]->getIndex();
474 state = (*history_)[m-2];
476 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
477 Teuchos::OSTab ostab(out,1,
"SolutionHistory::getStateTimeIndexNM2");
478 *out <<
"Warning - getStateTimeIndexNM2() Timestep index n-2 is not in "
479 <<
"SolutionHistory!\n"
480 <<
" (n)th index = " << n <<
"\n"
481 <<
" (n-2)th index = " << nm2 << std::endl;
484 state = (*history_)[m-3];
492template<
class Scalar>
493Teuchos::RCP<SolutionState<Scalar> >
496 typename std::vector<Teuchos::RCP<SolutionState<Scalar> > >::iterator
498 for (; state_it <
history_->end(); state_it++) {
499 if ((*state_it)->getIndex() == index)
break;
502 Teuchos::RCP<SolutionState<Scalar> > state = Teuchos::null;
503 if ( state_it ==
history_->end() ) {
505 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
506 Teuchos::OSTab ostab(out,1,
"SolutionHistory::getStateTimeIndex");
507 *out <<
"Warning - getStateTimeIndex() Timestep index is not in "
508 <<
"SolutionHistory!\n"
509 <<
" index = " << index << std::endl;
518template<
class Scalar>
521 return (
"Tempus::SolutionHistory - '" +
name_ +
"'");
525template<
class Scalar>
527 Teuchos::FancyOStream &out,
528 const Teuchos::EVerbosityLevel verbLevel)
const
530 auto l_out = Teuchos::fancyOStream( out.getOStream() );
531 Teuchos::OSTab ostab(*l_out, 2, this->
description());
532 l_out->setOutputToRootOnly(0);
534 *l_out <<
"\n--- " << this->
description() <<
" ---" << std::endl;
536 if ((Teuchos::as<int>(verbLevel)==Teuchos::as<int>(Teuchos::VERB_DEFAULT)) ||
537 (Teuchos::as<int>(verbLevel)>=Teuchos::as<int>(Teuchos::VERB_LOW) ) ){
541 *l_out <<
" number of states = " <<
history_->size() << std::endl;
543 *l_out<<
" time range = (" <<
history_->front()->getTime() <<
", "
544 <<
history_->back()->getTime() <<
")"
549 if (Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_MEDIUM)) {
550 for (
int i=0; i<(int)
history_->size() ; ++i)
551 (*
history_)[i]->describe(*l_out, verbLevel);
553 *l_out << std::string(this->
description().length()+8,
'-') << std::endl;
557template<
class Scalar>
558Teuchos::RCP<const Teuchos::ParameterList>
561 Teuchos::RCP<Teuchos::ParameterList> pl =
562 Teuchos::parameterList(
"Solution History");
567 "'Storage Type' sets the memory storage. "
568 "'Keep Newest' - will retain the single newest solution state. "
569 "'Undo' - will retain two solution states in order to do a single undo. "
570 "'Static' - will retain 'Storage Limit' number of solution states. "
571 "'Unlimited' - will not remove any solution states!");
574 "Limit on the number of SolutionStates that SolutionHistory can have.");
576 pl->set(
"Interpolator", *
interpolator_->getNonconstParameterList());
582template <
class Scalar>
583Teuchos::RCP<Teuchos::ParameterList>
590template<
class Scalar>
594 if (interpolator == Teuchos::null) {
602template<
class Scalar>
603Teuchos::RCP<Interpolator<Scalar> >
609template<
class Scalar>
610Teuchos::RCP<const Interpolator<Scalar> >
616template<
class Scalar>
617Teuchos::RCP<Interpolator<Scalar> >
620 Teuchos::RCP<Interpolator<Scalar> > old_interpolator =
interpolator_;
622 return old_interpolator;
626template<
class Scalar>
629 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
630 Teuchos::OSTab ostab(out,1,
"SolutionHistory::printHistory");
632 <<
" (w - working; c - current; i - interpolated)" << std::endl;
633 for (
int i=0; i<(int)
history_->size() ; ++i) {
634 auto state = (*history_)[i];
638 else if (state->getIsInterpolated() ==
true) *out<<
"i - ";
640 *out <<
"[" << i <<
"] = " << state << std::endl;
641 if (verb ==
"medium" || verb ==
"high") {
642 if (state != Teuchos::null) {
643 auto x = state->getX();
644 *out <<
" x = " << x << std::endl
645 <<
" norm(x) = " << Thyra::norm(*x) << std::endl;
648 if (verb ==
"high") {
649 (*history_)[i]->describe(*out,this->getVerbLevel());
655template<
class Scalar>
658 TEUCHOS_TEST_FOR_EXCEPTION(
getNumStates() <= 0, std::logic_error,
659 "Error - SolutionHistory::initialize() Invalid history size!\n");
661 TEUCHOS_TEST_FOR_EXCEPTION(
interpolator_ == Teuchos::null, std::logic_error,
662 "Error - SolutionHistory::initialize() Interpolator is not set!\n");
664 TEUCHOS_TEST_FOR_EXCEPTION(
storageLimit_ < 1, std::logic_error,
665 "Error - SolutionHistory::initialize() Storage Limit needs to a positive integer!\n"
668 TEUCHOS_TEST_FOR_EXCEPTION(
670 "Error - SolutionHistory::initialize() Storage Type is invalid!\n");
672 TEUCHOS_TEST_FOR_EXCEPTION(
675 "Error - SolutionHistory::initialize() \n"
677 <<
"', Storage Limit needs to be one.\n"
680 TEUCHOS_TEST_FOR_EXCEPTION(
683 "Error - SolutionHistory::initialize() \n"
685 <<
"', Storage Limit needs to be two.\n"
695template<
class Scalar>
699 sh->setName(
"From createSolutionHistory");
705template<
class Scalar>
707 Teuchos::RCP<Teuchos::ParameterList> pl)
710 sh->setName(
"From createSolutionHistoryPL");
712 if (pl == Teuchos::null || pl->numParams() == 0)
return sh;
714 pl->validateParametersAndSetDefaults(*sh->getValidParameters());
716 sh->setName(pl->name());
717 sh->setStorageTypeString(pl->get(
"Storage Type",
"Undo"));
718 sh->setStorageLimit(pl->get(
"Storage Limit", 2));
721 Teuchos::sublist(pl,
"Interpolator")));
727template<
class Scalar>
728Teuchos::RCP<SolutionHistory<Scalar> >
732 sh->setName(
"From createSolutionHistoryState");
738template<
class Scalar>
739Teuchos::RCP<SolutionHistory<Scalar> >
745 state->setTime (0.0);
747 state->setTimeStep(0.0);
752 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)
Make a shallow copy of SolutionHistory (i.e., only RCPs to states and interpolator).
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).