Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Tempus_SolutionHistory_decl.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ****************************************************************************
3 // Tempus: Copyright (2017) Sandia Corporation
4 //
5 // Distributed under BSD 3-clause license (See accompanying file Copyright.txt)
6 // ****************************************************************************
7 // @HEADER
8 
9 #ifndef Tempus_SolutionHistory_decl_hpp
10 #define Tempus_SolutionHistory_decl_hpp
11 
12 
13 #include "Teuchos_VerboseObject.hpp"
14 #include "Teuchos_Describable.hpp"
15 #include "Teuchos_ParameterListAcceptorDefaultBase.hpp"
16 
17 #include "Thyra_VectorStdOps.hpp"
18 
19 #include "Tempus_config.hpp"
20 #include "Tempus_SolutionState.hpp"
21 #include "Tempus_Interpolator.hpp"
22 
23 
24 namespace Tempus {
25 
27  STORAGE_TYPE_INVALID = 0, ///< Invalid storage type
28  STORAGE_TYPE_KEEP_NEWEST = 1, ///< Keep the single newest state
29  STORAGE_TYPE_UNDO = 2, ///< Keep the 2 newest states for undo
30  STORAGE_TYPE_STATIC = 3, ///< Keep a fix number of states
31  STORAGE_TYPE_UNLIMITED = 4, ///< Grow the history as needed
32 };
33 
34 
35 /** \brief SolutionHistory is basically a container of SolutionStates.
36  * SolutionHistory maintains a collection of SolutionStates for later
37  * retrival and reuse, such as checkpointing, restart, and undo
38  * operations.
39  *
40  * The actual storage of the SolutionStates may take several forms:
41  * - in memory
42  * - on disk
43  * - combination
44  * - use ATDM DataWareHouse
45  * but the interface should be unchanged and very similar to other
46  * containers.
47  *
48  * SolutionHistory can fill in SolutionStates between other SolutionStates
49  * by either
50  * - Integrating from one SolutionState to the desired time
51  * - This might include methods like Griewank's algorithm.
52  * - Interpolating between SolutionStates
53  * - Interpolated SolutionStates may not be suitable for adjoint
54  * solutions, restart, or undo operations (see SolutionState).
55  *
56  * There are two sets of indices associated with SolutionHistory:
57  * timestep index and the SolutionHistory index. Users are interested
58  * in the timestep index as it indicates the solution increment, e.g.,
59  * \f$[x^0, ... , x^{n-2}, x^{n-1}, x^{n}]\f$, where \f$n\f$ is the timestep
60  * index. While developers can also be interested in the SolutionHistory
61  * index to access the correct SolutionState in the SolutionHistory, e.g.,
62  * \f$[S^0, ... , S^{M-1}]\f$, where \f$M\f$ is the number of SolutionStates
63  * in the SolutionHistory (1 \f$\le M \le\f$ StorageLimit_).
64  *
65  * SolutionHistory will hold upto the StorageLimit_ number of states.
66  * Rules of thumb for the <b>minimum</b> storage limit:
67  * - Explicit one-step methods can update the solution state in-place
68  * --> StorageLimit_ = 1.
69  * - Implicit one-step methods need two solution states --> StorageLimit_ = 2.
70  * - MultiStep methods require k past solution states --> StorageLimit_ = k+1.
71  *
72  * The states contained in the SolutionHistory will often be the last
73  * \f$M\f$ states for forward time integration, e.g.,
74  * \f$[S^0(x^{n-M+1}), ... , S^{M-3}(x^{n-2}), S^{M-2}(x^{n-1}),
75  * S^{M-1}(x^{n})]\f$, but this is not guaranteed.
76  * For example, during transient adjoint sensitivity calculations, not
77  * all the forward states can be stored and therefore will be recalculated.
78  * Thus intermediate states are kept to reduce recomputation costs, i.e.,
79  * so one does not recalculate from the initial conditions to the desired time.
80  * This means the states in the SolutionHistory may not have consecutive
81  * timestep indices, e.g., \f$[..., S^{M-4}(x^{n-200}), S^{M-3}(x^{n-100}),
82  * S^{M-2}(x^{n-1}), S^{M-1}(x^{n})]\f$.
83  *
84  * The SolutionHistory is kept in chronological order, starting with the
85  * oldest state and ending with the latest.
86  *
87  * The "current" state is the latest solution that has been successfully
88  * solved. The solution from the last successful time step or the initial
89  * conditions.
90  *
91  * The "working" state is the state which is being worked on. It is valid
92  * from initialization (e.g., copied from the "current" state), during the
93  * the timestep, and until it is accepted and promoted to the new "current"
94  * state. Between the promotion and the initialization, the workingState_
95  * is invalid (i.e., Teuchos::null). If the timestep fails, the
96  * workingState_ is maintained, and the timestep is retried until the
97  * Integrator declares a successful timestep or the time integration is a
98  * failure. The SolutionHistory indices associated with the currentState_
99  * and the workingState_ vary during the time step loop, and are
100  * <table>
101  * <tr><th> Loop Portion <th> currentState_ <th> workingState_
102  * <tr><td> Before initializing working state
103  * <td> PASS -> \f$M\f$-1 <br>
104  * FAIL -> \f$M\f$-2
105  * <td> PASS -> Invalid <br>
106  * FAIL -> \f$M\f$-1
107  * <tr><td> After initializing working state <br>
108  * During timestep <br>
109  * Before accepting timestep
110  * <td> \f$M\f$-2
111  * <td> \f$M\f$-1
112  * <tr><td> After accepting timestep
113  * <td> PASS -> \f$M\f$-1 <br>
114  * FAIL -> \f$M\f$-2
115  * <td> PASS -> Invalid <br>
116  * FAIL -> \f$M\f$-1
117  * </table>
118  * Initial conditions are considered PASSing, which sets up the loop.
119  * The difference between the currentState_ timestep index and the
120  * workingState_ timestep index is guaranteed to be one (except for when
121  * StorageLimit_ = 1, i.e., explicit one-step methods that can update
122  * the solution in-place).
123  */
124 template<class Scalar>
125 class SolutionHistory
126  : virtual public Teuchos::Describable,
127  virtual public Teuchos::VerboseObject<SolutionHistory<Scalar> >,
128  virtual public Teuchos::ParameterListAcceptor
129 //, virtual public InterpolatorAcceptingObjectBase<Scalar>
130 {
131 public:
132 
133  /// Contructor
134  SolutionHistory(Teuchos::RCP<Teuchos::ParameterList> shPL = Teuchos::null);
135 
136  /// Destructor
138 
139  /// \name Basic SolutionHistory Methods
140  //@{
141  /// Add solution state to history
142  void addState(const Teuchos::RCP<SolutionState<Scalar> >& state);
143 
144  /// Add a working solution state to history
145  void addWorkingState(const Teuchos::RCP<SolutionState<Scalar> >& state,
146  const bool updateTime = true);
147 
148  /// Remove solution state
149  void removeState(const Teuchos::RCP<SolutionState<Scalar> >& state);
150 
151  /// Remove solution state based on time
152  void removeState(const Scalar time);
153 
154  /// Find solution state at requested time (no interpolation)
155  Teuchos::RCP<SolutionState<Scalar> > findState(const Scalar time) const;
156 
157  /// Generate and interpolate a new solution state at requested time
158  Teuchos::RCP<SolutionState<Scalar> > interpolateState(const Scalar time) const;
159 
160  /// Interpolate solution state at requested time and store in supplied state
161  void interpolateState(const Scalar time,
162  SolutionState<Scalar>* state_out) const;
163 
164  /// Initialize the working state
165  void initWorkingState();
166 
167  /// Promote the working state to current state
168  void promoteWorkingState();
169 
170  void clear() {history_->clear();}
171  //@}
172 
173  /// \name Accessor methods
174  //@{
175  /// Get this SolutionHistory's name
176  std::string getName() const {return name_;}
177 
178  /// Set this SolutionHistory's name
179  void setName(std::string name) {name_ = name;}
180 
181  /// Get underlining history
182  Teuchos::RCP<std::vector<Teuchos::RCP<SolutionState<Scalar> > > >
183  getHistory() const {return history_;}
184 
185  /// Subscript operator
186  Teuchos::RCP<SolutionState<Scalar> > operator[](const int i) {
187  TEUCHOS_TEST_FOR_EXCEPTION(
188  !((0 <= i) and (i < (int)history_->size())), std::out_of_range,
189  "Error - SolutionHistory index is out of range.\n"
190  << " [Min, Max] = [ 0, " << history_->size()<< "]\n"
191  << " index = " << i << "\n");
192  return (*history_)[i];
193  }
194 
195  /// Subscript operator (const version)
196  Teuchos::RCP<const SolutionState<Scalar> > operator[](const int i) const {
197  TEUCHOS_TEST_FOR_EXCEPTION(
198  !((0 <= i) and (i < (int)history_->size())), std::out_of_range,
199  "Error - SolutionHistory index is out of range.\n"
200  << " [Min, Max] = [ 0, " << history_->size()<< "]\n"
201  << " index = " << i << "\n");
202  return (*history_)[i];
203  }
204 
205  /// Return the current state, i.e., the last accepted state
206  Teuchos::RCP<SolutionState<Scalar> > getCurrentState() const
207  {
208  const int m = history_->size();
209  Teuchos::RCP<SolutionState<Scalar> > state;
210  if (m == 0) state=Teuchos::null;
211  else if (m == 1 or workingState_ == Teuchos::null) state=(*history_)[m-1];
212  else if (m > 1) state=(*history_)[m-2];
213  return state;
214  }
215 
216  /// Return the working state
217  Teuchos::RCP<SolutionState<Scalar> > getWorkingState(bool warn=true) const
218  {
219  if (workingState_ == Teuchos::null && warn) {
220  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
221  Teuchos::OSTab ostab(out,1,"SolutionHistory::getWorkingState()");
222  *out << "Warning - WorkingState is null and likely has been promoted. "
223  << "You might want to call getCurrentState() instead.\n"
224  << std::endl;
225  }
226  return workingState_;
227  }
228 
229  /// Get the number of states
230  int getNumStates() const {return history_->size();}
231 
232  /// Get the current time
233  Scalar getCurrentTime() const {return getCurrentState()->getTime();}
234 
235  /// Get the current timestep index
236  int getCurrentIndex() const {return getCurrentState()->getIndex();}
237 
238  /// Set the maximum storage of this history
239  void setStorageLimit(int storage_limit);
240 
241  /// Get the maximum storage of this history
242  int getStorageLimit() const {return storageLimit_;}
243 
246 
247  /// Return the current minimum time of the SolutionStates
248  Scalar minTime() const {return (history_->front())->getTime();}
249 
250  /// Return the current maximum time of the SolutionStates
251  Scalar maxTime() const {return (history_->back())->getTime();}
252 
253  /// Get the state with timestep index equal to n
254  Teuchos::RCP<SolutionState<Scalar> > getStateTimeIndexN() const;
255 
256  /// Get the state with timestep index equal to n-1
257  Teuchos::RCP<SolutionState<Scalar> > getStateTimeIndexNM1() const;
258 
259  /// Get the state with timestep index equal to n-2
260  Teuchos::RCP<SolutionState<Scalar> > getStateTimeIndexNM2() const;
261 
262  /// Get the state with timestep index equal to "index"
263  Teuchos::RCP<SolutionState<Scalar> > getStateTimeIndex(int index) const;
264  //@}
265 
266  /// \name Overridden from Teuchos::ParameterListAcceptor
267  //@{
268  void setParameterList(const Teuchos::RCP<Teuchos::ParameterList> & pl);
269  Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const;
270  Teuchos::RCP<Teuchos::ParameterList> getNonconstParameterList();
271  Teuchos::RCP<Teuchos::ParameterList> unsetParameterList();
272  //@}
273 
274  /// \name Overridden from Teuchos::Describable
275  //@{
276  virtual std::string description() const;
277  virtual void describe(Teuchos::FancyOStream & out,
278  const Teuchos::EVerbosityLevel verbLevel) const;
279  //@}
280 
281  /// \name Interpolation Methods
282  //@{
283  /// Set the interpolator for this history
284  void setInterpolator(const Teuchos::RCP<Interpolator<Scalar> >& interpolator);
285  Teuchos::RCP<Interpolator<Scalar> > getNonconstInterpolator();
286  Teuchos::RCP<const Interpolator<Scalar> > getInterpolator() const;
287  /// Unset the interpolator for this history
288  Teuchos::RCP<Interpolator<Scalar> > unSetInterpolator();
289  //@}
290 
291  void printHistory(std::string verb="low") const
292  {
293  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
294  Teuchos::OSTab ostab(out,1,"SolutionHistory::printHistory");
295  *out << name_ << " (size=" << history_->size() << ")"
296  << " (w - working; c - current; i - interpolated)" << std::endl;
297  for (int i=0; i<(int)history_->size() ; ++i) {
298  auto state = (*history_)[i];
299  *out << " ";
300  if (state == getWorkingState()) *out << "w - ";
301  else if (state == getCurrentState()) *out << "c - ";
302  else if (state->getMetaData()->getIsInterpolated() == true) *out<<"i - ";
303  else *out << " ";
304  *out << "[" << i << "] = " << state << std::endl;
305  if (verb == "medium" or verb == "high") {
306  if (state != Teuchos::null) {
307  auto x = state->getX();
308  *out << " x = " << x << std::endl
309  << " norm(x) = " << Thyra::norm(*x) << std::endl;
310  }
311  }
312  if (verb == "high") {
313  (*history_)[i]->describe(*out,this->getVerbLevel());
314  }
315  }
316  }
317 
318 protected:
319 
320  std::string name_;
321  Teuchos::RCP<Teuchos::ParameterList> shPL_;
322  Teuchos::RCP<std::vector<Teuchos::RCP<SolutionState<Scalar> > > > history_;
323  Teuchos::RCP<Interpolator<Scalar> > interpolator_;
326 
327  Teuchos::RCP<SolutionState<Scalar> > workingState_; ///< The state being worked on
328 };
329 
330 /// Nonmember constructor
331 template<class Scalar>
332 Teuchos::RCP<SolutionHistory<Scalar> >
333 solutionHistory(Teuchos::RCP<Teuchos::ParameterList> pList = Teuchos::null);
334 
335 
336 } // namespace Tempus
337 
338 #endif // Tempus_SolutionHistory_decl_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.
Scalar minTime() const
Return the current minimum time of the SolutionStates.
std::string getName() const
Get this SolutionHistory&#39;s name.
Keep the 2 newest states for undo.
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
int getCurrentIndex() const
Get the current timestep index.
Teuchos::RCP< Interpolator< Scalar > > interpolator_
void initWorkingState()
Initialize the working state.
void printHistory(std::string verb="low") const
Teuchos::RCP< SolutionState< Scalar > > interpolateState(const Scalar time) const
Generate and interpolate a new solution state at requested time.
int getNumStates() const
Get the number of states.
Teuchos::RCP< const SolutionState< Scalar > > operator[](const int i) const
Subscript operator (const version)
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
Teuchos::RCP< Interpolator< Scalar > > getNonconstInterpolator()
Scalar getCurrentTime() const
Get the current time.
void setStorageLimit(int storage_limit)
Set the maximum storage of this history.
Teuchos::RCP< SolutionState< Scalar > > getWorkingState(bool warn=true) const
Return the working state.
Teuchos::RCP< SolutionState< Scalar > > workingState_
The state being worked on.
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.
Teuchos::RCP< SolutionState< Scalar > > getCurrentState() const
Return the current state, i.e., the last accepted state.
Teuchos::RCP< std::vector< Teuchos::RCP< SolutionState< Scalar > > > > getHistory() const
Get underlining history.
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
void addState(const Teuchos::RCP< SolutionState< Scalar > > &state)
Add solution state to history.
Teuchos::RCP< Teuchos::ParameterList > shPL_
void setName(std::string name)
Set this SolutionHistory&#39;s name.
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 &quot;index&quot;.
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
Scalar maxTime() const
Return the current maximum time of the SolutionStates.
void setInterpolator(const Teuchos::RCP< Interpolator< Scalar > > &interpolator)
Set the interpolator for this history.
int getStorageLimit() const
Get the maximum storage of this history.
Teuchos::RCP< SolutionState< Scalar > > findState(const Scalar time) const
Find solution state at requested time (no interpolation)
Teuchos::RCP< SolutionState< Scalar > > operator[](const int i)
Subscript operator.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Solution state for integrators and steppers. SolutionState contains the metadata for solutions and th...
Teuchos::RCP< std::vector< Teuchos::RCP< SolutionState< Scalar > > > > history_