10 #ifndef Tempus_SolutionHistory_impl_hpp
11 #define Tempus_SolutionHistory_impl_hpp
13 #include "Teuchos_StandardParameterEntryValidators.hpp"
16 #include "Thyra_VectorStdOps.hpp"
23 template <
class Scalar>
34 template <
class Scalar>
43 setInterpolator(interpolator);
44 setStorageType(storageType);
45 setStorageLimit(storageLimit);
47 isInitialized_ =
false;
48 if (getNumStates() > 0) isInitialized_ =
true;
51 template <
class Scalar>
56 if (Teuchos::as<int>(history_->size() + 1) > storageLimit_) {
57 switch (storageType_) {
60 true, std::logic_error,
61 "Error - Storage type is STORAGE_TYPE_INVALID.\n");
67 if (state->getTime() >= history_->front()->getTime()) {
70 history_->erase(history_->begin());
76 *out <<
"Warning, state is older than oldest state in history. "
77 <<
"State not added!" << std::endl;
85 "Error - unknown storage type.\n");
90 if (history_->size() == 0) {
91 history_->push_back(state);
94 typename std::vector<Teuchos::RCP<SolutionState<Scalar> > >::iterator
95 state_it = history_->begin();
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) {
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 -- ";
112 *out <<
"===============" << std::endl;
119 if (newTime < shTime)
break;
121 if (!equal) history_->insert(state_it, state);
125 getNumStates() <= 0, std::logic_error,
126 "Error - SolutionHistory::addState() Invalid history size!\n");
131 template <
class Scalar>
137 auto cs = getCurrentState();
139 state->setIndex(cs->getIndex() + 1);
141 state->setTime(cs->getTime() + cs->getTimeStep());
142 state->setTimeStep(cs->getTimeStep());
146 workingState_ = (*history_)[getNumStates() - 1];
149 template <
class Scalar>
153 if (history_->size() != 0) {
154 auto state_it = history_->rbegin();
155 for (; state_it < history_->rend(); state_it++) {
156 if (state->getTime() == (*state_it)->getTime())
break;
160 "Error - removeState() Could not remove state = "
161 << (*state_it)->description());
164 history_->erase(std::next(state_it).base());
169 template <
class Scalar>
173 removeState(tmpState);
176 template <
class Scalar>
178 const Scalar time)
const
182 if (history_->size() > 0)
183 scale = (*history_)[history_->size() - 1]->getTime();
186 const Scalar absTol = scale * numericalTol<Scalar>();
188 !(minTime() - absTol <= time && time <= maxTime() + absTol),
190 "Error - SolutionHistory::findState() Requested time out of range!\n"
192 << minTime() <<
", " << maxTime()
197 auto state_it = history_->begin();
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);
210 template <
class Scalar>
212 const Scalar time)
const
215 interpolate<Scalar>(*interpolator_, history_, time, state_out.
get());
219 template <
class Scalar>
223 interpolate<Scalar>(*interpolator_, history_, time, state_out);
227 template <
class Scalar>
230 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::SolutionHistory::initWorkingState()");
233 getCurrentState() == Teuchos::null, std::logic_error,
234 "Error - SolutionHistory::initWorkingState()\n"
235 "Can not initialize working state without a current state!\n");
244 if (getWorkingState(
false) != Teuchos::null) {
245 Thyra::V_V(getWorkingState()->getX().ptr(), *(getCurrentState()->getX()));
250 if (getNumStates() < storageLimit_) {
252 newState = getCurrentState()->clone();
256 newState = (*history_)[0];
257 history_->erase(history_->begin());
258 if (getNumStates() > 0) newState->copy(getCurrentState());
263 addWorkingState(newState);
268 template <
class Scalar>
271 auto ws = getWorkingState();
274 ws->setNFailures(std::max(0, ws->getNFailures() - 1));
275 ws->setNConsecutiveFailures(0);
278 ws->setIsInterpolated(
false);
279 workingState_ = Teuchos::null;
283 Teuchos::OSTab ostab(out, 1,
"SolutionHistory::promoteWorkingState()");
284 *out <<
"Warning - WorkingState is not passing, so not promoted!\n"
289 template <
class Scalar>
293 this->setName(sh->getName());
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);
303 this->setInterpolator(interpolator);
305 this->setStorageType(sh->getStorageType());
306 this->setStorageLimit(sh->getStorageLimit());
309 template <
class Scalar>
312 storageLimit_ = std::max(1, storage_limit);
316 if (storage_limit != 1) {
319 *out <<
"Warning - 'Storage Limit' for 'Keep Newest' is 1.\n"
320 <<
" (Storage Limit = " << storage_limit <<
"). Resetting to 1."
326 if (storage_limit != 2) {
329 *out <<
"Warning - 'Storage Limit' for 'Undo' is 2.\n"
330 <<
" (Storage Limit = " << storage_limit <<
"). Resetting to 2."
336 storageLimit_ = storage_limit;
339 storageLimit_ = std::numeric_limits<int>::max();
343 (Teuchos::as<int>(history_->size()) > storageLimit_), std::logic_error,
344 "Error - requested storage limit = "
346 <<
" is smaller than the current number of states stored = "
347 << history_->size() <<
"!\n");
349 isInitialized_ =
false;
352 template <
class Scalar>
361 setStorageLimit(std::numeric_limits<int>::max());
362 isInitialized_ =
false;
365 template <
class Scalar>
368 if (s ==
"Keep Newest") {
372 else if (s ==
"Undo") {
376 else if (s ==
"Static") {
379 else if (s ==
"Unlimited") {
384 true, std::logic_error,
385 "Error - Unknown 'Storage Type' = '" << s <<
"'\n");
387 isInitialized_ =
false;
390 template <
class Scalar>
393 std::string s =
"Invalid";
405 template <
class Scalar>
410 const int m = history_->size();
414 Teuchos::OSTab ostab(out, 1,
"SolutionHistory::getStateTimeIndexN");
415 *out <<
"Warning - getStateTimeIndexN() No states in SolutionHistory!"
420 state = (*history_)[m - 1];
425 template <
class Scalar>
430 const int m = history_->size();
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();
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];
464 template <
class Scalar>
469 const int m = history_->size();
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];
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];
507 template <
class Scalar>
509 int index,
bool warn)
const
511 typename std::vector<Teuchos::RCP<SolutionState<Scalar> > >::iterator
512 state_it = history_->begin();
513 for (; state_it < history_->end(); state_it++) {
514 if ((*state_it)->getIndex() == index)
break;
518 if (state_it == history_->end()) {
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;
533 template <
class Scalar>
536 return (
"Tempus::SolutionHistory - '" + name_ +
"'");
539 template <
class Scalar>
543 auto l_out = Teuchos::fancyOStream(out.
getOStream());
545 l_out->setOutputToRootOnly(0);
547 *l_out <<
"\n--- " << this->description() <<
" ---" << std::endl;
549 if ((Teuchos::as<int>(verbLevel) ==
554 *l_out <<
" storageLimit = " << storageLimit_ << std::endl;
555 *l_out <<
" storageType = " << getStorageTypeString() << std::endl;
556 *l_out <<
" number of states = " << history_->size() << std::endl;
557 if (history_->size() > 0) {
558 *l_out <<
" time range = (" << history_->front()->getTime() <<
", "
559 << history_->back()->getTime() <<
")" << std::endl;
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;
570 template <
class Scalar>
575 Teuchos::parameterList(
"Solution History");
580 "Storage Type", getStorageTypeString(),
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!");
588 "Storage Limit", getStorageLimit(),
589 "Limit on the number of SolutionStates that SolutionHistory can have.");
591 pl->
set(
"Interpolator", *interpolator_->getNonconstParameterList());
596 template <
class Scalar>
603 template <
class Scalar>
607 if (interpolator == Teuchos::null) {
611 interpolator_ = interpolator;
613 isInitialized_ =
false;
616 template <
class Scalar>
620 return interpolator_;
623 template <
class Scalar>
627 return interpolator_;
630 template <
class Scalar>
634 interpolator_ = lagrangeInterpolator<Scalar>();
635 return old_interpolator;
638 template <
class Scalar>
643 *out << name_ <<
" (size=" << history_->size() <<
")"
644 <<
" (w - working; c - current; i - interpolated)" << std::endl;
645 for (
int i = 0; i < (int)history_->size(); ++i) {
646 auto state = (*history_)[i];
648 if (state == getWorkingState())
650 else if (state == getCurrentState())
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());
670 template <
class Scalar>
674 getNumStates() <= 0, std::logic_error,
675 "Error - SolutionHistory::initialize() Invalid history size!\n");
678 interpolator_ == Teuchos::null, std::logic_error,
679 "Error - SolutionHistory::initialize() Interpolator is not set!\n");
682 "Error - SolutionHistory::initialize() Storage "
683 "Limit needs to a positive integer!\n"
684 <<
" Storage Limit = " << storageLimit_
689 "Error - SolutionHistory::initialize() Storage Type is invalid!\n");
694 "Error - SolutionHistory::initialize() \n"
695 <<
" For Storage Type = '" << getStorageTypeString()
696 <<
"', Storage Limit needs to be one.\n"
697 <<
" Storage Limit = " << storageLimit_ <<
"\n");
702 "Error - SolutionHistory::initialize() \n"
703 <<
" For Storage Type = '" << getStorageTypeString()
704 <<
"', Storage Limit needs to be two.\n"
705 <<
" Storage Limit = " << storageLimit_ <<
"\n");
707 isInitialized_ =
true;
713 template <
class Scalar>
717 sh->setName(
"From createSolutionHistory");
722 template <
class Scalar>
727 sh->setName(
"From createSolutionHistoryPL");
729 if (pl == Teuchos::null || pl->
numParams() == 0)
return sh;
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")));
743 template <
class Scalar>
748 sh->setName(
"From createSolutionHistoryState");
753 template <
class Scalar>
761 state->setTimeStep(0.0);
766 sh->setName(
"From createSolutionHistoryME");
773 #endif // Tempus_SolutionHistory_impl_hpp
Teuchos::RCP< Interpolator< Scalar > > unSetInterpolator()
Unset the interpolator for this history.
SolutionHistory()
Default Contructor.
const std::string & name() const
Keep the 2 newest states for undo.
Teuchos::RCP< Interpolator< Scalar > > interpolator_
void initWorkingState()
Initialize the working state.
Teuchos::RCP< SolutionHistory< Scalar > > createSolutionHistory()
Nonmember constructor.
void printHistory(std::string verb="low") const
Print information on States in the SolutionHistory.
T & get(const std::string &name, T def_value)
Teuchos::RCP< SolutionState< Scalar > > interpolateState(const Scalar time) const
Generate and interpolate a new solution state at requested time.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Keep the single newest state.
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
Return a valid non-const ParameterList with current settings.
Ordinal numParams() const
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
Teuchos::RCP< Interpolator< Scalar > > getNonconstInterpolator()
void setStorageLimit(int storage_limit)
Set the maximum storage of this history.
Teuchos::RCP< SolutionHistory< Scalar > > createSolutionHistoryPL(Teuchos::RCP< Teuchos::ParameterList > pList)
Nonmember constructor from a ParameterList.
Teuchos::RCP< SolutionHistory< Scalar > > createSolutionHistoryME(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
Nonmember contructor from a Thyra ModelEvaluator.
Teuchos::RCP< SolutionState< Scalar > > getStateTimeIndex(int index, bool warn=true) const
Get the state with timestep index equal to "index".
void initialize() const
Initialize SolutionHistory.
static Teuchos::RCP< Interpolator< Scalar > > createInterpolator(std::string interpolatorType="")
Create default interpolator from interpolator type (e.g., "Linear").
void promoteWorkingState()
Promote the working state to current state.
void removeState(const Teuchos::RCP< SolutionState< Scalar > > &state)
Remove solution state.
bool isInitialized_
Bool if SolutionHistory is initialized.
Teuchos::RCP< SolutionState< Scalar > > getStateTimeIndexNM1(bool warn=true) const
Get the state with timestep index equal to n-1.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Base strategy class for interpolation functionality.
virtual std::string description() const
Teuchos::RCP< SolutionState< Scalar > > getStateTimeIndexN(bool warn=true) const
Get the state with timestep index equal to n.
Teuchos::RCP< SolutionState< Scalar > > getStateTimeIndexNM2(bool warn=true) const
Get the state with timestep index equal to n-2.
void addState(const Teuchos::RCP< SolutionState< Scalar > > &state, bool doChecks=true)
Add solution state to history.
void validateParametersAndSetDefaults(ParameterList const &validParamList, int const depth=1000)
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
std::string getStorageTypeString() const
Set the string storage type.
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.
void setStorageType(StorageType st)
Set the storage type via enum.
void addWorkingState(const Teuchos::RCP< SolutionState< Scalar > > &state, const bool updateTime=true)
Add a working solution state to history.
Keep a fix number of states.
Teuchos::RCP< SolutionHistory< Scalar > > createSolutionHistoryState(const Teuchos::RCP< SolutionState< Scalar > > &state)
Nonmember contructor from a SolutionState.
void setStorageTypeString(std::string st)
Set the storage type via string.
RCP< std::basic_ostream< char_type, traits_type > > getOStream()
bool approxEqualAbsTol(Scalar a, Scalar b, Scalar absTol)
Test if values are approximately equal within the absolute tolerance.
bool approxZero(Scalar value, Scalar tol=Teuchos::ScalarTraits< Scalar >::sfmin())
Test if value is approximately zero within tolerance.
Teuchos::RCP< const Interpolator< Scalar > > getInterpolator() const
void setInterpolator(const Teuchos::RCP< Interpolator< Scalar > > &interpolator)
Set the interpolator for this history.
ParameterList & setName(const std::string &name)
void copy(Teuchos::RCP< const SolutionHistory< Scalar > > sh)
Teuchos::RCP< SolutionState< Scalar > > findState(const Scalar time) const
Find solution state at requested time (no interpolation)
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Return a valid ParameterList with current settings.
Grow the history as needed.
Solution state for integrators and steppers.
Teuchos::RCP< std::vector< Teuchos::RCP< SolutionState< Scalar > > > > history_