Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Tempus_StepperForwardEuler_impl.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_StepperForwardEuler_impl_hpp
10 #define Tempus_StepperForwardEuler_impl_hpp
11 
12 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
13 #include "Thyra_VectorStdOps.hpp"
14 
15 
16 namespace Tempus {
17 
18 template<class Scalar>
20 {
21  this->setParameterList(Teuchos::null);
22  this->modelWarning();
23 }
24 
25 template<class Scalar>
27  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
28  Teuchos::RCP<Teuchos::ParameterList> pList)
29 {
30  this->setParameterList(pList);
31 
32  if (appModel == Teuchos::null) {
33  this->modelWarning();
34  }
35  else {
36  this->setModel(appModel);
37  this->initialize();
38  }
39 }
40 
41 template<class Scalar>
43  Teuchos::RCP<StepperObserver<Scalar> > obs)
44 {
45  if (obs == Teuchos::null) {
46  // Create default observer, otherwise keep current observer.
47  if (this->stepperObserver_ == Teuchos::null) {
48  stepperFEObserver_ =
49  Teuchos::rcp(new StepperForwardEulerObserver<Scalar>());
50  this->stepperObserver_ =
51  Teuchos::rcp_dynamic_cast<StepperObserver<Scalar> >(stepperFEObserver_);
52  }
53  } else {
54  this->stepperObserver_ = obs;
55  stepperFEObserver_ =
56  Teuchos::rcp_dynamic_cast<StepperForwardEulerObserver<Scalar> >
57  (this->stepperObserver_);
58  }
59 }
60 
61 template<class Scalar>
63 {
64  TEUCHOS_TEST_FOR_EXCEPTION(
65  this->appModel_ == Teuchos::null, std::logic_error,
66  "Error - Need to set the model, setModel(), before calling "
67  "StepperForwardEuler::initialize()\n");
68 
69  this->setParameterList(this->stepperPL_);
70  this->setObserver();
71 }
72 
73 template<class Scalar>
75  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
76 {
77  using Teuchos::RCP;
78 
79  RCP<SolutionState<Scalar> > initialState = solutionHistory->getCurrentState();
80 
81  // Check if we need Stepper storage for xDot
82  if (initialState->getXDot() == Teuchos::null)
83  this->setStepperXDot(initialState->getX()->clone_v());
84 
86 }
87 
88 template<class Scalar>
90  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
91 {
92  using Teuchos::RCP;
93 
94  TEMPUS_FUNC_TIME_MONITOR("Tempus::StepperForwardEuler::takeStep()");
95  {
96  TEUCHOS_TEST_FOR_EXCEPTION(solutionHistory->getNumStates() < 2,
97  std::logic_error,
98  "Error - StepperForwardEuler<Scalar>::takeStep(...)\n"
99  "Need at least two SolutionStates for Forward Euler.\n"
100  " Number of States = " << solutionHistory->getNumStates() << "\n"
101  "Try setting in \"Solution History\" \"Storage Type\" = \"Undo\"\n"
102  " or \"Storage Type\" = \"Static\" and \"Storage Limit\" = \"2\"\n");
103 
104  this->stepperObserver_->observeBeginTakeStep(solutionHistory, *this);
105  RCP<SolutionState<Scalar> > currentState=solutionHistory->getCurrentState();
106  RCP<SolutionState<Scalar> > workingState=solutionHistory->getWorkingState();
107 
108  RCP<Thyra::VectorBase<Scalar> > xDot = this->getStepperXDot(currentState);
109 
110  if ( !(this->getUseFSAL()) ) {
111  // Need to compute XDotOld.
112  if (!Teuchos::is_null(stepperFEObserver_))
113  stepperFEObserver_->observeBeforeExplicit(solutionHistory, *this);
114 
115  // Evaluate xDot = f(x,t).
116  this->evaluateExplicitODE(xDot, currentState->getX(),
117  currentState->getTime());
118 
119  // For UseFSAL=false, x and xDot are now sync'ed or consistent
120  // at the same time level for the currentState.
121  currentState->setIsSynced(true);
122  }
123 
124 
125  // Forward Euler update, x^n = x^{n-1} + dt^n * xDot^{n-1}
126  const Scalar dt = workingState->getTimeStep();
127  Thyra::V_VpStV(Teuchos::outArg(*(workingState->getX())),
128  *(currentState->getX()),dt,*(xDot));
129 
130 
131  xDot = this->getStepperXDot(workingState);
132 
133  if (this->getUseFSAL()) {
134  // Get consistent xDot^n.
135  if (!Teuchos::is_null(stepperFEObserver_))
136  stepperFEObserver_->observeBeforeExplicit(solutionHistory, *this);
137 
138  // Evaluate xDot = f(x,t).
139  this->evaluateExplicitODE(xDot, workingState->getX(),
140  workingState->getTime());
141 
142  // For UseFSAL=true, x and xDot are now sync'ed or consistent
143  // for the workingState.
144  workingState->setIsSynced(true);
145  } else {
146  assign(xDot.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
147  workingState->setIsSynced(false);
148  }
149 
150  workingState->setSolutionStatus(Status::PASSED);
151  workingState->setOrder(this->getOrder());
152  this->stepperObserver_->observeEndTakeStep(solutionHistory, *this);
153  }
154  return;
155 }
156 
157 
158 /** \brief Provide a StepperState to the SolutionState.
159  * This Stepper does not have any special state data,
160  * so just provide the base class StepperState with the
161  * Stepper description. This can be checked to ensure
162  * that the input StepperState can be used by this Stepper.
163  */
164 template<class Scalar>
165 Teuchos::RCP<Tempus::StepperState<Scalar> > StepperForwardEuler<Scalar>::
167 {
168  Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
169  rcp(new StepperState<Scalar>(description()));
170  return stepperState;
171 }
172 
173 
174 template<class Scalar>
176 {
177  std::string name = "Forward Euler";
178  return(name);
179 }
180 
181 
182 template<class Scalar>
184  Teuchos::FancyOStream &out,
185  const Teuchos::EVerbosityLevel /* verbLevel */) const
186 {
187  out << description() << "::describe:" << std::endl
188  << "appModel_ = " << this->appModel_->description() << std::endl;
189 }
190 
191 
192 template <class Scalar>
194  const Teuchos::RCP<Teuchos::ParameterList> & pList)
195 {
196  if (pList == Teuchos::null) {
197  // Create default parameters if null, otherwise keep current parameters.
198  if (this->stepperPL_ == Teuchos::null)
199  this->stepperPL_ = this->getDefaultParameters();
200  } else {
201  this->stepperPL_ = pList;
202  }
203  this->stepperPL_->validateParametersAndSetDefaults(*this->getValidParameters());
204 
205  std::string stepperType =
206  this->stepperPL_->template get<std::string>("Stepper Type");
207  TEUCHOS_TEST_FOR_EXCEPTION( stepperType != "Forward Euler",
208  std::logic_error,
209  "Error - Stepper Type is not 'Forward Euler'!\n"
210  << " Stepper Type = "<< pList->get<std::string>("Stepper Type") << "\n");
211 }
212 
213 
214 template<class Scalar>
215 Teuchos::RCP<const Teuchos::ParameterList>
217 {
218  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
219  pl->setName("Default Stepper - " + this->description());
220  pl->set<std::string>("Stepper Type", "Forward Euler",
221  "'Stepper Type' must be 'Forward Euler'.");
222  this->getValidParametersBasic(pl);
223  pl->set<bool>("Use FSAL", true);
224  pl->set<std::string>("Initial Condition Consistency", "Consistent");
225  return pl;
226 }
227 
228 
229 template<class Scalar>
230 Teuchos::RCP<Teuchos::ParameterList>
232 {
233  using Teuchos::RCP;
234  using Teuchos::ParameterList;
235  using Teuchos::rcp_const_cast;
236 
237  RCP<ParameterList> pl =
238  rcp_const_cast<ParameterList>(this->getValidParameters());
239 
240  return pl;
241 }
242 
243 
244 template <class Scalar>
245 Teuchos::RCP<Teuchos::ParameterList>
247 {
248  return(this->stepperPL_);
249 }
250 
251 
252 template <class Scalar>
253 Teuchos::RCP<Teuchos::ParameterList>
255 {
256  Teuchos::RCP<Teuchos::ParameterList> temp_plist = this->stepperPL_;
257  this->stepperPL_ = Teuchos::null;
258  return(temp_plist);
259 }
260 
261 
262 } // namespace Tempus
263 #endif // Tempus_StepperForwardEuler_impl_hpp
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &pl)
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual void setObserver(Teuchos::RCP< StepperObserver< Scalar > > obs=Teuchos::null)
Set Observer.
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions, make them consistent, and set needed memory.
virtual void initialize()
Initialize during construction and after changing input parameters.
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
StepperForwardEulerObserver class for StepperForwardEuler.
StepperState is a simple class to hold state information about the stepper.
Teuchos::RCP< Teuchos::ParameterList > getDefaultParameters() const
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions, make them consistent, and set needed memory.
StepperObserver class for Stepper class.
Teuchos::RCP< SolutionHistory< Scalar > > solutionHistory(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
Nonmember constructor.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Get a default (initial) StepperState.
virtual void takeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Take the specified timestep, dt, and return true if successful.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const