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" 22 template<
class Scalar>
24 : name_(
"Solution History"),
36 template<
class Scalar>
46 setInterpolator(interpolator);
47 setStorageType(storageType);
48 setStorageLimit(storageLimit);
50 isInitialized_ =
false;
51 if (getNumStates() > 0 ) isInitialized_ =
true;
55 template<
class Scalar>
60 if (Teuchos::as<int>(history_->size()+1) > storageLimit_) {
61 switch (storageType_) {
63 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
64 "Error - Storage type is STORAGE_TYPE_INVALID.\n");
70 if (state->getTime() >= history_->front()->getTime()) {
73 history_->erase(history_->begin());
76 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
77 Teuchos::OSTab ostab(out,1,
"SolutionHistory::addState");
78 *out <<
"Warning, state is older than oldest state in history. " 79 <<
"State not added!" << std::endl;
87 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
88 "Error - unknown storage type.\n");
93 if (history_->size() == 0) {
94 history_->push_back(state);
96 typename std::vector<Teuchos::RCP<SolutionState<Scalar> > >::iterator
97 state_it = history_->begin();
99 const Scalar newTime = state->getTime();
100 for (; state_it < history_->end(); state_it++) {
101 const Scalar shTime = (*state_it)->getTime();
103 const Scalar denom = std::max(std::fabs(shTime), std::fabs(newTime));
104 if ( std::fabs(newTime - shTime) < 1.0e-14*denom ) {
106 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
107 Teuchos::OSTab ostab(out,1,
"SolutionHistory::addState");
108 *out <<
"Warning, state to be added matches state in history. " 109 <<
"State not added!" << std::endl;
111 *out <<
"===============" << std::endl;
112 *out <<
"Added SolutionState -- ";
113 (*state_it)->describe(*out, Teuchos::VERB_MEDIUM);
114 *out <<
"===============" << std::endl;
115 this->describe(*out, Teuchos::VERB_MEDIUM);
121 if (newTime < shTime)
break;
123 if (!equal) history_->insert(state_it, state);
126 TEUCHOS_TEST_FOR_EXCEPTION(getNumStates() <= 0, std::logic_error,
127 "Error - SolutionHistory::addState() Invalid history size!\n");
133 template<
class Scalar>
139 auto cs = getCurrentState();
141 state->setIndex(cs->getIndex()+1);
143 state->setTime(cs->getTime() + cs->getTimeStep());
144 state->setTimeStep(cs->getTimeStep());
148 workingState_ = (*history_)[getNumStates()-1];
151 template<
class Scalar>
155 if (history_->size() != 0) {
156 auto state_it = history_->rbegin();
157 for ( ; state_it < history_->rend(); state_it++) {
158 if (state->getTime() == (*state_it)->getTime())
break;
161 TEUCHOS_TEST_FOR_EXCEPTION(
162 state_it == history_->rend(), std::logic_error,
163 "Error - removeState() Could not remove state = " 164 << (*state_it)->description());
167 history_->erase(std::next(state_it).base());
173 template<
class Scalar>
176 Teuchos::RCP<SolutionState<Scalar> > tmpState = findState(time);
177 removeState(tmpState);
181 template<
class Scalar>
182 Teuchos::RCP<SolutionState<Scalar> >
185 TEUCHOS_TEST_FOR_EXCEPTION(
186 !(minTime() <= time && time <= maxTime()), std::logic_error,
187 "Error - SolutionHistory::findState() Requested time out of range!\n" 188 " [Min, Max] = [" << minTime() <<
", " << maxTime() <<
"]\n" 189 " time = "<< time <<
"\n");
193 history_->size() > 0 ? (*history_)[history_->size()-1]->getTime() : Scalar(1.0);
195 auto state_it = history_->begin();
196 for ( ; state_it < history_->end(); ++state_it) {
201 TEUCHOS_TEST_FOR_EXCEPTION(state_it == history_->end(), std::logic_error,
202 "Error - SolutionHistory::findState()!\n" 203 " Did not find a SolutionState with time = " <<time<< std::endl);
209 template<
class Scalar>
210 Teuchos::RCP<SolutionState<Scalar> >
213 Teuchos::RCP<SolutionState<Scalar> > state_out = getCurrentState()->clone();
214 interpolate<Scalar>(*interpolator_, history_, time, state_out.get());
219 template<
class Scalar>
224 interpolate<Scalar>(*interpolator_, history_, time, state_out);
229 template<
class Scalar>
232 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::SolutionHistory::initWorkingState()");
234 TEUCHOS_TEST_FOR_EXCEPTION(getCurrentState() == Teuchos::null,
236 "Error - SolutionHistory::initWorkingState()\n" 237 "Can not initialize working state without a current state!\n");
241 if (getWorkingState(
false) != Teuchos::null)
return;
243 Teuchos::RCP<SolutionState<Scalar> > newState;
244 if (getNumStates() < storageLimit_) {
246 newState = getCurrentState()->clone();
249 newState = (*history_)[0];
250 history_->erase(history_->begin());
251 if (getNumStates() > 0) newState->copy(getCurrentState());
256 addWorkingState(newState);
263 template<
class Scalar>
266 auto ws = getWorkingState();
269 ws->setNFailures(std::max(0,ws->getNFailures()-1));
270 ws->setNConsecutiveFailures(0);
273 ws->setIsInterpolated(
false);
274 workingState_ = Teuchos::null;
276 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
277 Teuchos::OSTab ostab(out,1,
"SolutionHistory::promoteWorkingState()");
278 *out <<
"Warning - WorkingState is not passing, so not promoted!\n" 284 template<
class Scalar>
287 this->setName(sh->getName());
290 auto sh_history = sh->getHistory();
291 typename std::vector<Teuchos::RCP<SolutionState<Scalar> > >::iterator
292 state_it = sh_history->begin();
293 for (; state_it < sh_history->end(); state_it++)
294 this->addState( *state_it );
297 this->setInterpolator(interpolator);
299 this->setStorageType(sh->getStorageType());
300 this->setStorageLimit(sh->getStorageLimit());
304 template<
class Scalar>
307 storageLimit_ = std::max(1,storage_limit);
311 if (storage_limit != 1) {
312 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
313 Teuchos::OSTab ostab(out,1,
"SolutionHistory::setStorageLimit");
314 *out <<
"Warning - 'Storage Limit' for 'Keep Newest' is 1.\n" 315 <<
" (Storage Limit = "<<storage_limit<<
"). Resetting to 1." 320 if (storage_limit != 2) {
321 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
322 Teuchos::OSTab ostab(out,1,
"SolutionHistory::setStorageLimit");
323 *out <<
"Warning - 'Storage Limit' for 'Undo' is 2.\n" 324 <<
" (Storage Limit = "<<storage_limit<<
"). Resetting to 2." 329 storageLimit_ = storage_limit;
331 storageLimit_ = std::numeric_limits<int>::max();
334 TEUCHOS_TEST_FOR_EXCEPTION(
335 (Teuchos::as<int>(history_->size()) > storageLimit_), std::logic_error,
336 "Error - requested storage limit = " << storageLimit_
337 <<
" is smaller than the current number of states stored = " 338 << history_->size() <<
"!\n");
340 isInitialized_ =
false;
344 template<
class Scalar>
351 setStorageLimit(std::numeric_limits<int>::max());
352 isInitialized_ =
false;
356 template<
class Scalar>
359 if ( s ==
"Keep Newest" ) {
362 }
else if ( s ==
"Undo" ) {
365 }
else if ( s ==
"Static" ) {
367 }
else if ( s ==
"Unlimited" ) {
370 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
371 "Error - Unknown 'Storage Type' = '" << s <<
"'\n");
373 isInitialized_ =
false;
377 template<
class Scalar>
380 std::string s =
"Invalid";
389 template<
class Scalar>
390 Teuchos::RCP<SolutionState<Scalar> >
393 Teuchos::RCP<SolutionState<Scalar> > state = Teuchos::null;
394 const int m = history_->size();
397 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
398 Teuchos::OSTab ostab(out,1,
"SolutionHistory::getStateTimeIndexN");
399 *out <<
"Warning - getStateTimeIndexN() No states in SolutionHistory!" 403 state = (*history_)[m-1];
409 template<
class Scalar>
410 Teuchos::RCP<SolutionState<Scalar> >
413 Teuchos::RCP<SolutionState<Scalar> > state = Teuchos::null;
414 const int m = history_->size();
417 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
418 Teuchos::OSTab ostab(out,1,
"SolutionHistory::getStateTimeIndexNM1");
419 *out <<
"Warning - getStateTimeIndexNM1() Not enough states in " 420 <<
"SolutionHistory! Size of history = " << getNumStates()
424 const int n = (*history_)[m-1]->getIndex();
425 const int nm1 = (*history_)[m-2]->getIndex();
431 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
432 Teuchos::OSTab ostab(out,1,
"SolutionHistory::getStateTimeIndexNM1");
433 *out <<
"Warning - getStateTimeIndexNM1() Timestep index n-1 is not in " 434 <<
"SolutionHistory!\n" 435 <<
" (n)th index = " << n <<
"\n" 436 <<
" (n-1)th index = " << nm1 << std::endl;
439 state = (*history_)[m-2];
447 template<
class Scalar>
448 Teuchos::RCP<SolutionState<Scalar> >
451 Teuchos::RCP<SolutionState<Scalar> > state = Teuchos::null;
452 const int m = history_->size();
455 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
456 Teuchos::OSTab ostab(out,1,
"SolutionHistory::getStateTimeIndexNM2");
457 *out <<
"Warning - getStateTimeIndexNM2() Not enough states in " 458 <<
"SolutionHistory! Size of history = " << getNumStates()
462 const int n = (*history_)[m-1]->getIndex();
463 const int nm2 = (*history_)[m-3]->getIndex();
468 const int nm1 = (*history_)[m-2]->getIndex();
470 state = (*history_)[m-2];
472 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
473 Teuchos::OSTab ostab(out,1,
"SolutionHistory::getStateTimeIndexNM2");
474 *out <<
"Warning - getStateTimeIndexNM2() Timestep index n-2 is not in " 475 <<
"SolutionHistory!\n" 476 <<
" (n)th index = " << n <<
"\n" 477 <<
" (n-2)th index = " << nm2 << std::endl;
480 state = (*history_)[m-3];
488 template<
class Scalar>
489 Teuchos::RCP<SolutionState<Scalar> >
492 typename std::vector<Teuchos::RCP<SolutionState<Scalar> > >::iterator
493 state_it = history_->begin();
494 for (; state_it < history_->end(); state_it++) {
495 if ((*state_it)->getIndex() == index)
break;
498 Teuchos::RCP<SolutionState<Scalar> > state = Teuchos::null;
499 if ( state_it == history_->end() ) {
501 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
502 Teuchos::OSTab ostab(out,1,
"SolutionHistory::getStateTimeIndex");
503 *out <<
"Warning - getStateTimeIndex() Timestep index is not in " 504 <<
"SolutionHistory!\n" 505 <<
" index = " << index << std::endl;
514 template<
class Scalar>
517 return (
"Tempus::SolutionHistory - '" + name_ +
"'");
521 template<
class Scalar>
523 Teuchos::FancyOStream &out,
524 const Teuchos::EVerbosityLevel verbLevel)
const 526 auto l_out = Teuchos::fancyOStream( out.getOStream() );
527 Teuchos::OSTab ostab(*l_out, 2, this->description());
528 l_out->setOutputToRootOnly(0);
530 *l_out <<
"\n--- " << this->description() <<
" ---" << std::endl;
532 if ((Teuchos::as<int>(verbLevel)==Teuchos::as<int>(Teuchos::VERB_DEFAULT)) ||
533 (Teuchos::as<int>(verbLevel)>=Teuchos::as<int>(Teuchos::VERB_LOW) ) ){
535 *l_out <<
" storageLimit = " << storageLimit_ << std::endl;
536 *l_out <<
" storageType = " << getStorageTypeString() << std::endl;
537 *l_out <<
" number of states = " << history_->size() << std::endl;
538 if ( history_->size() > 0 ) {
539 *l_out<<
" time range = (" << history_->front()->getTime() <<
", " 540 << history_->back()->getTime() <<
")" 545 if (Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_MEDIUM)) {
546 for (
int i=0; i<(int)history_->size() ; ++i)
547 (*history_)[i]->describe(*l_out, verbLevel);
549 *l_out << std::string(this->description().length()+8,
'-') << std::endl;
553 template<
class Scalar>
554 Teuchos::RCP<const Teuchos::ParameterList>
557 Teuchos::RCP<Teuchos::ParameterList> pl =
558 Teuchos::parameterList(
"Solution History");
560 pl->setName(getName());
562 pl->set(
"Storage Type", getStorageTypeString(),
563 "'Storage Type' sets the memory storage. " 564 "'Keep Newest' - will retain the single newest solution state. " 565 "'Undo' - will retain two solution states in order to do a single undo. " 566 "'Static' - will retain 'Storage Limit' number of solution states. " 567 "'Unlimited' - will not remove any solution states!");
569 pl->set(
"Storage Limit", getStorageLimit(),
570 "Limit on the number of SolutionStates that SolutionHistory can have.");
572 pl->set(
"Interpolator", *interpolator_->getNonconstParameterList());
578 template <
class Scalar>
579 Teuchos::RCP<Teuchos::ParameterList>
582 return Teuchos::rcp_const_cast<Teuchos::ParameterList>(getValidParameters());
586 template<
class Scalar>
590 if (interpolator == Teuchos::null) {
593 interpolator_ = interpolator;
595 isInitialized_ =
false;
598 template<
class Scalar>
599 Teuchos::RCP<Interpolator<Scalar> >
602 return interpolator_;
605 template<
class Scalar>
606 Teuchos::RCP<const Interpolator<Scalar> >
609 return interpolator_;
612 template<
class Scalar>
613 Teuchos::RCP<Interpolator<Scalar> >
616 Teuchos::RCP<Interpolator<Scalar> > old_interpolator = interpolator_;
617 interpolator_ = lagrangeInterpolator<Scalar>();
618 return old_interpolator;
622 template<
class Scalar>
625 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
626 Teuchos::OSTab ostab(out,1,
"SolutionHistory::printHistory");
627 *out << name_ <<
" (size=" << history_->size() <<
")" 628 <<
" (w - working; c - current; i - interpolated)" << std::endl;
629 for (
int i=0; i<(int)history_->size() ; ++i) {
630 auto state = (*history_)[i];
632 if (state == getWorkingState()) *out <<
"w - ";
633 else if (state == getCurrentState()) *out <<
"c - ";
634 else if (state->getIsInterpolated() ==
true) *out<<
"i - ";
636 *out <<
"[" << i <<
"] = " << state << std::endl;
637 if (verb ==
"medium" || verb ==
"high") {
638 if (state != Teuchos::null) {
639 auto x = state->getX();
640 *out <<
" x = " << x << std::endl
641 <<
" norm(x) = " << Thyra::norm(*x) << std::endl;
644 if (verb ==
"high") {
645 (*history_)[i]->describe(*out,this->getVerbLevel());
651 template<
class Scalar>
654 TEUCHOS_TEST_FOR_EXCEPTION(getNumStates() <= 0, std::logic_error,
655 "Error - SolutionHistory::initialize() Invalid history size!\n");
657 TEUCHOS_TEST_FOR_EXCEPTION(interpolator_ == Teuchos::null, std::logic_error,
658 "Error - SolutionHistory::initialize() Interpolator is not set!\n");
660 TEUCHOS_TEST_FOR_EXCEPTION(storageLimit_ < 1, std::logic_error,
661 "Error - SolutionHistory::initialize() Storage Limit needs to a positive integer!\n" 662 <<
" Storage Limit = " << storageLimit_ <<
"\n");
664 TEUCHOS_TEST_FOR_EXCEPTION(
666 "Error - SolutionHistory::initialize() Storage Type is invalid!\n");
668 TEUCHOS_TEST_FOR_EXCEPTION(
671 "Error - SolutionHistory::initialize() \n" 672 <<
" For Storage Type = '" << getStorageTypeString()
673 <<
"', Storage Limit needs to be one.\n" 674 <<
" Storage Limit = " << storageLimit_ <<
"\n");
676 TEUCHOS_TEST_FOR_EXCEPTION(
679 "Error - SolutionHistory::initialize() \n" 680 <<
" For Storage Type = '" << getStorageTypeString()
681 <<
"', Storage Limit needs to be two.\n" 682 <<
" Storage Limit = " << storageLimit_ <<
"\n");
684 isInitialized_ =
true;
691 template<
class Scalar>
695 sh->setName(
"From createSolutionHistory");
701 template<
class Scalar>
703 Teuchos::RCP<Teuchos::ParameterList> pl)
706 sh->setName(
"From createSolutionHistoryPL");
708 if (pl == Teuchos::null)
return sh;
710 pl->validateParametersAndSetDefaults(*sh->getValidParameters());
712 sh->setName(pl->name());
713 sh->setStorageTypeString(pl->get(
"Storage Type",
"Undo"));
714 sh->setStorageLimit(pl->get(
"Storage Limit", 2));
717 Teuchos::sublist(pl,
"Interpolator")));
723 template<
class Scalar>
724 Teuchos::RCP<SolutionHistory<Scalar> >
728 sh->setName(
"From createSolutionHistoryState");
734 template<
class Scalar>
735 Teuchos::RCP<SolutionHistory<Scalar> >
741 state->setTime (0.0);
743 state->setTimeStep(0.0);
748 sh->setName(
"From createSolutionHistoryME");
756 #endif // Tempus_SolutionHistory_impl_hpp Teuchos::RCP< Interpolator< Scalar > > unSetInterpolator()
Unset the interpolator for this history.
SolutionHistory()
Default Contructor.
Teuchos::RCP< SolutionState< Scalar > > getStateTimeIndexNM2(bool warn=true) const
Get the state with timestep index equal to n-2.
Keep the 2 newest states for undo.
Teuchos::RCP< Interpolator< Scalar > > interpolator_
virtual std::string description() const
void initWorkingState()
Initialize the working state.
std::string getStorageTypeString() const
Set the string storage type.
Teuchos::RCP< SolutionHistory< Scalar > > createSolutionHistory()
Nonmember constructor.
Teuchos::RCP< const Interpolator< Scalar > > getInterpolator() const
Teuchos::RCP< SolutionState< Scalar > > findState(const Scalar time) const
Find solution state at requested time (no interpolation)
Teuchos::RCP< SolutionState< Scalar > > interpolateState(const Scalar time) const
Generate and interpolate a new solution state at requested time.
Keep the single newest state.
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
Return a valid non-const ParameterList with current settings.
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< SolutionState< Scalar > > getStateTimeIndexN(bool warn=true) const
Get the state with timestep index equal to n.
Teuchos::RCP< SolutionHistory< Scalar > > createSolutionHistoryME(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
Nonmember contructor from a Thyra ModelEvaluator.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Teuchos::RCP< SolutionState< Scalar > > getStateTimeIndex(int index, bool warn=true) const
Get the state with timestep index equal to "index".
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.
void printHistory(std::string verb="low") const
Print information on States in the SolutionHistory.
bool isInitialized_
Bool if SolutionHistory is initialized.
Base strategy class for interpolation functionality.
void addState(const Teuchos::RCP< SolutionState< Scalar > > &state, bool doChecks=true)
Add solution state to history.
Teuchos::RCP< SolutionState< Scalar > > getStateTimeIndexNM1(bool warn=true) const
Get the state with timestep index equal to n-1.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
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.
bool floating_compare_equals(const Scalar &a, const Scalar &b, const Scalar &scale)
Helper function for comparing times.
void setInterpolator(const Teuchos::RCP< Interpolator< Scalar > > &interpolator)
Set the interpolator for this history.
void copy(Teuchos::RCP< const SolutionHistory< Scalar > > sh)
Make a shallow copy of SolutionHistory (i.e., only RCPs to states and interpolator).
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. SolutionState contains the metadata for solutions and th...
Teuchos::RCP< std::vector< Teuchos::RCP< SolutionState< Scalar > > > > history_
void initialize() const
Initialize SolutionHistory.