9 #ifndef Tempus_SolutionHistory_impl_hpp
10 #define Tempus_SolutionHistory_impl_hpp
13 #include "Teuchos_StandardParameterEntryValidators.hpp"
14 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
15 #include "Teuchos_TimeMonitor.hpp"
18 #include "Tempus_SolutionStateMetaData.hpp"
26 static std::string Invalid_name =
"Invalid";
27 static std::string KeepNewest_name =
"Keep Newest";
28 static std::string Undo_name =
"Undo";
29 static std::string Static_name =
"Static";
30 static std::string Unlimited_name =
"Unlimited";
31 static std::string Storage_name =
"Storage Type";
32 static std::string Storage_default = Undo_name;
34 static std::string StorageLimit_name =
"Storage Limit";
35 static int StorageLimit_default = 2;
37 std::vector<std::string> HistoryPolicies =
38 {Invalid_name, KeepNewest_name, Undo_name, Static_name, Unlimited_name};
40 const Teuchos::RCP<Teuchos::StringToIntegralParameterEntryValidator<Tempus::StorageType> >
41 StorageTypeValidator = Teuchos::rcp(
42 new Teuchos::StringToIntegralParameterEntryValidator<Tempus::StorageType>(
44 Teuchos::tuple<Tempus::StorageType>(
57 template<
class Scalar>
59 Teuchos::RCP<Teuchos::ParameterList> pList)
65 this->setParameterList(pList);
67 if (Teuchos::as<int>(this->getVerbLevel()) >=
68 Teuchos::as<int>(Teuchos::VERB_HIGH)) {
69 RCP<Teuchos::FancyOStream> out = this->getOStream();
70 Teuchos::OSTab ostab(out,1,
"SolutionHistory::SolutionHistory");
71 *out << this->description() << std::endl;
76 template<
class Scalar>
81 if (Teuchos::as<int>(history_->size()+1) > storageLimit_) {
82 switch (storageType_) {
84 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
85 "Error - Storage type is STORAGE_TYPE_INVALID.\n");
91 if (state->getTime() >= history_->front()->getTime()) {
94 history_->erase(history_->begin());
97 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
98 Teuchos::OSTab ostab(out,1,
"SolutionHistory::addState");
99 *out <<
"Warning, state is younger than youngest state in history. "
100 <<
"State not added!" << std::endl;
108 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
109 "Error - unknown storage type.\n");
114 if (history_->size() == 0) {
115 history_->push_back(state);
117 typename std::vector<Teuchos::RCP<SolutionState<Scalar> > >::iterator
118 state_it = history_->begin();
119 for (; state_it < history_->end(); state_it++) {
120 if (state->getTime() < (*state_it)->getTime())
break;
122 history_->insert(state_it, state);
125 TEUCHOS_TEST_FOR_EXCEPTION(getNumStates() <= 0, std::logic_error,
126 "Error - SolutionHistory::addState() Invalid history size!\n");
131 template<
class Scalar>
138 workingState_ = (*history_)[getNumStates()-1];
139 RCP<SolutionStateMetaData<Scalar> > csmd = getCurrentState()->getMetaData();
140 RCP<SolutionStateMetaData<Scalar> > wsmd = workingState_ ->getMetaData();
142 wsmd->setIStep(csmd->getIStep()+1);
144 wsmd->setTime(csmd->getTime() + csmd->getDt());
145 wsmd->setDt(csmd->getDt());
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;
159 TEUCHOS_TEST_FOR_EXCEPTION(state_it == history_->rend(), std::logic_error,
160 "Error - removeState() Could not remove state = "
165 history_->erase(std::next(state_it).base());
171 template<
class Scalar>
174 Teuchos::RCP<SolutionState<Scalar> > tmpState = findState(time);
175 removeState(tmpState);
179 template<
class Scalar>
180 Teuchos::RCP<SolutionState<Scalar> >
183 TEUCHOS_TEST_FOR_EXCEPTION(
184 !(minTime() <= time and time <= maxTime()), std::logic_error,
185 "Error - SolutionHistory::findState() Requested time out of range!\n"
186 " [Min, Max] = [" << minTime() <<
", " << maxTime() <<
"]\n"
187 " time = "<< time <<
"\n");
191 history_->size() > 0 ? (*history_)[history_->size()-1]->getTime() : Scalar(1.0);
193 auto state_it = history_->begin();
194 for ( ; state_it < history_->end(); ++state_it) {
199 TEUCHOS_TEST_FOR_EXCEPTION(state_it == history_->end(), std::logic_error,
200 "Error - SolutionHistory::findState()!\n"
201 " Did not find a SolutionState with time = " <<time<< std::endl);
207 template<
class Scalar>
208 Teuchos::RCP<SolutionState<Scalar> >
211 Teuchos::RCP<SolutionState<Scalar> > state_out = getCurrentState()->clone();
212 interpolate<Scalar>(*interpolator_, history_, time, state_out.get());
217 template<
class Scalar>
222 interpolate<Scalar>(*interpolator_, history_, time, state_out);
227 template<
class Scalar>
230 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::SolutionHistory::initWorkingState()");
232 TEUCHOS_TEST_FOR_EXCEPTION(getCurrentState() == Teuchos::null,
234 "Error - SolutionHistory::initWorkingState()\n"
235 "Can not initialize working state without a current state!\n");
239 if (getWorkingState(
false) != Teuchos::null)
return;
241 Teuchos::RCP<SolutionState<Scalar> > newState;
242 if (getNumStates() < storageLimit_) {
244 newState = getCurrentState()->clone();
247 newState = (*history_)[0];
248 history_->erase(history_->begin());
249 if (getNumStates() > 0) newState->copy(getCurrentState());
254 addWorkingState(newState);
261 template<
class Scalar>
264 Teuchos::RCP<SolutionStateMetaData<Scalar> > md =
265 getWorkingState()->getMetaData();
268 md->setNFailures(std::max(0,md->getNFailures()-1));
269 md->setNConsecutiveFailures(0);
272 md->setIsInterpolated(
false);
273 workingState_ = Teuchos::null;
275 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
276 Teuchos::OSTab ostab(out,1,
"SolutionHistory::promoteWorkingState()");
277 *out <<
"Warning - WorkingState is not passing, so not promoted!\n"
283 template<
class Scalar>
286 storageLimit_ = std::max(1,storage_limit);
288 TEUCHOS_TEST_FOR_EXCEPTION(
289 (Teuchos::as<int>(history_->size()) > storageLimit_), std::logic_error,
290 "Error - requested storage limit = " << storageLimit_
291 <<
" is smaller than the current number of states stored = "
292 << history_->size() <<
"!\n");
296 template<
class Scalar>
297 Teuchos::RCP<SolutionState<Scalar> >
300 const int m = history_->size();
301 TEUCHOS_TEST_FOR_EXCEPTION( (m < 1), std::out_of_range,
302 "Error - getStateTimeIndexN() No states in SolutionHistory!\n");
303 return (*history_)[m-1];
307 template<
class Scalar>
308 Teuchos::RCP<SolutionState<Scalar> >
311 const int m = history_->size();
312 TEUCHOS_TEST_FOR_EXCEPTION( (m < 2), std::out_of_range,
313 "Error - getStateTimeIndexNM1() Not enough states in "
314 <<
"SolutionHistory!\n");
315 const int n = (*history_)[m-1]->getIndex();
316 const int nm1 = (*history_)[m-2]->getIndex();
320 TEUCHOS_TEST_FOR_EXCEPTION( (nm1 != n-1), std::out_of_range,
321 "Error - getStateTimeIndexNM1() Timestep index n-1 is not in "
322 <<
"SolutionHistory!\n"
323 <<
" (n)th index = " << n <<
"\n"
324 <<
" (n-1)th index = " << nm1 <<
"\n");
326 return (*history_)[m-2];
330 template<
class Scalar>
331 Teuchos::RCP<SolutionState<Scalar> >
334 const int m = history_->size();
335 TEUCHOS_TEST_FOR_EXCEPTION( (m < 3), std::out_of_range,
336 "Error - getStateTimeIndexNM1() Not enough states in "
337 <<
"SolutionHistory!\n");
338 const int n = (*history_)[m-1]->getIndex();
339 const int nm2 = (*history_)[m-3]->getIndex();
343 TEUCHOS_TEST_FOR_EXCEPTION( (nm2 != n-2), std::out_of_range,
344 "Error - getStateTimeIndexNM1() Timestep index n-2 is not in "
345 <<
"SolutionHistory!\n"
346 <<
" (n)th index = " << n <<
"\n"
347 <<
" (n-2)th index = " << nm2 <<
"\n");
349 return (*history_)[m-3];
353 template<
class Scalar>
354 Teuchos::RCP<SolutionState<Scalar> >
357 typename std::vector<Teuchos::RCP<SolutionState<Scalar> > >::iterator
358 state_it = history_->begin();
359 for (; state_it < history_->end(); state_it++) {
360 if ((*state_it)->getIndex() == index)
break;
362 TEUCHOS_TEST_FOR_EXCEPTION( state_it==history_->end(), std::out_of_range,
363 "Error - getStateTimeIndex() Timestep index is not in "
364 <<
"SolutionHistory!\n"
365 <<
" index = " << index <<
"\n");
370 template<
class Scalar>
373 return (
"Tempus::SolutionHistory - name = '" + name_ +
"'");
377 template<
class Scalar>
379 Teuchos::FancyOStream &out,
380 const Teuchos::EVerbosityLevel verbLevel)
const
382 if ((Teuchos::as<int>(verbLevel)==Teuchos::as<int>(Teuchos::VERB_DEFAULT)) ||
383 (Teuchos::as<int>(verbLevel)>=Teuchos::as<int>(Teuchos::VERB_LOW) ) ){
384 out << description() <<
"::describe" << std::endl;
386 out <<
"storageLimit = " << storageLimit_ << std::endl;
387 out <<
"storageType = " << storageType_ << std::endl;
388 out <<
"number of states = " << history_->size() << std::endl;
389 out <<
"time range = (" << history_->front()->getTime() <<
", "
390 << history_->back()->getTime() <<
")"
392 }
else if (Teuchos::as<int>(verbLevel) >=
393 Teuchos::as<int>(Teuchos::VERB_HIGH)) {
394 out <<
"SolutionStates: " << std::endl;
395 for (
int i=0; i<(int)history_->size() ; ++i) {
396 out <<
"SolutionState[" << i <<
"] = " << std::endl;
397 (*history_)[i]->describe(out,this->getVerbLevel());
403 template <
class Scalar>
405 Teuchos::RCP<Teuchos::ParameterList>
const& pList)
407 if (pList == Teuchos::null) {
409 if (shPL_ == Teuchos::null) {
410 shPL_ = Teuchos::parameterList(
"Solution History");
411 *shPL_ = *(this->getValidParameters());
416 shPL_->validateParametersAndSetDefaults(*this->getValidParameters());
418 name_ = shPL_->name();
420 storageType_ = StorageTypeValidator->getIntegralValue(
421 *shPL_, Storage_name, Storage_default);
423 int storage_limit = shPL_->get(StorageLimit_name, StorageLimit_default);
425 switch (storageType_) {
429 if (storage_limit != 1) {
430 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
431 Teuchos::OSTab ostab(out,1,
"SolutionHistory::setParameterList");
432 *out <<
"Warning - 'Storage Limit' for 'Keep Newest' is 1.\n"
433 <<
" (Storage Limit = "<<storage_limit<<
"). Resetting to 1."
437 setStorageLimit(storage_limit);
441 if (storage_limit != 2) {
442 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
443 Teuchos::OSTab ostab(out,1,
"SolutionHistory::setParameterList");
444 *out <<
"Warning - 'Storage Limit' for 'Undo' is 2.\n"
445 <<
" (Storage Limit = "<<storage_limit<<
"). Resetting to 2."
449 setStorageLimit(storage_limit);
456 storage_limit = 1000000000;
460 setStorageLimit(storage_limit);
463 Teuchos::sublist(shPL_,
"Interpolator"));
467 template<
class Scalar>
468 Teuchos::RCP<const Teuchos::ParameterList>
471 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
473 pl->setName(
"Valid ParameterList");
475 pl->set(Storage_name, Storage_default,
476 "'Storage Type' sets the memory storage. "
477 "'Keep Newest' - will retain the single newest solution state. "
478 "'Undo' - will retain two solution states in order to do a single undo. "
479 "'Static' - will retain 'Storage Limit' number of solution states. "
480 "'Unlimited' - will not remove any solution states!",
481 StorageTypeValidator);
483 pl->set(StorageLimit_name, StorageLimit_default,
484 "Storage limit for the solution history.");
487 pl->sublist(
"Interpolator",
false,
"").disableRecursiveValidation();
493 template <
class Scalar>
494 Teuchos::RCP<Teuchos::ParameterList>
501 template <
class Scalar>
502 Teuchos::RCP<Teuchos::ParameterList>
505 Teuchos::RCP<Teuchos::ParameterList> temp_plist = shPL_;
506 shPL_ = Teuchos::null;
511 template<
class Scalar>
513 Teuchos::RCP<Teuchos::ParameterList> pList)
519 template<
class Scalar>
523 if (interpolator == Teuchos::null) {
526 interpolator_ = interpolator;
528 if (Teuchos::as<int>(this->getVerbLevel()) >=
529 Teuchos::as<int>(Teuchos::VERB_HIGH)) {
530 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
531 Teuchos::OSTab ostab(out,1,
"SolutionHistory::setInterpolator");
532 *out <<
"interpolator = " << interpolator_->description() << std::endl;
536 template<
class Scalar>
537 Teuchos::RCP<Interpolator<Scalar> >
540 return interpolator_;
543 template<
class Scalar>
544 Teuchos::RCP<const Interpolator<Scalar> >
547 return interpolator_;
550 template<
class Scalar>
551 Teuchos::RCP<Interpolator<Scalar> >
554 Teuchos::RCP<Interpolator<Scalar> > old_interpolator = interpolator_;
555 interpolator_ = lagrangeInterpolator<Scalar>();
556 return old_interpolator;
561 #endif // Tempus_SolutionHistory_impl_hpp
Teuchos::RCP< SolutionState< Scalar > > getStateTimeIndexNM2() const
Get the state with timestep index equal to n-2.
Teuchos::RCP< Interpolator< Scalar > > unSetInterpolator()
Unset the interpolator for this history.
Keep the 2 newest states for undo.
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
void initWorkingState()
Initialize the working state.
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()
Teuchos::RCP< Interpolator< Scalar > > getNonconstInterpolator()
void setStorageLimit(int storage_limit)
Set the maximum storage of this history.
static Teuchos::RCP< Interpolator< Scalar > > createInterpolator(std::string interpolatorType="")
Create default interpolator from interpolator type (e.g., "Linear").
Teuchos::RCP< SolutionState< Scalar > > getStateTimeIndexNM1() const
Get the state with timestep index equal to n-1.
void promoteWorkingState()
Promote the working state to current state.
void removeState(const Teuchos::RCP< SolutionState< Scalar > > &state)
Remove solution state.
Base strategy class for interpolation functionality.
virtual std::string description() const
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &pl)
Teuchos::RCP< SolutionHistory< Scalar > > solutionHistory(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
Nonmember constructor.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
void addState(const Teuchos::RCP< SolutionState< Scalar > > &state)
Add solution state to history.
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< SolutionState< Scalar > > getStateTimeIndex(int index) const
Get the state with timestep index equal to "index".
SolutionHistory(Teuchos::RCP< Teuchos::ParameterList > shPL=Teuchos::null)
Contructor.
Teuchos::RCP< SolutionState< Scalar > > getStateTimeIndexN() const
Get the state with timestep index equal to n.
Teuchos::RCP< const Interpolator< Scalar > > getInterpolator() const
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.
Teuchos::RCP< SolutionState< Scalar > > findState(const Scalar time) const
Find solution state at requested time (no interpolation)
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Grow the history as needed.
Solution state for integrators and steppers. SolutionState contains the metadata for solutions and th...