Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Tempus_StepperLeapfrog_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_StepperLeapfrog_impl_hpp
10 #define Tempus_StepperLeapfrog_impl_hpp
11 
12 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
13 #include "Thyra_VectorStdOps.hpp"
14 
15 
16 namespace Tempus {
17 
18 
19 template<class Scalar>
21 {
22  this->setStepperType( "Leapfrog");
23  this->setUseFSAL( this->getUseFSALDefault());
24  this->setICConsistency( this->getICConsistencyDefault());
25  this->setICConsistencyCheck( this->getICConsistencyCheckDefault());
26 
27  this->setObserver();
28 }
29 
30 
31 template<class Scalar>
33  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
34  const Teuchos::RCP<StepperObserver<Scalar> >& obs,
35  bool useFSAL,
36  std::string ICConsistency,
37  bool ICConsistencyCheck)
38 {
39  this->setStepperType( "Leapfrog");
40  this->setUseFSAL( useFSAL);
41  this->setICConsistency( ICConsistency);
42  this->setICConsistencyCheck( ICConsistencyCheck);
43 
44  this->setObserver(obs);
45 
46  if (appModel != Teuchos::null) {
47 
48  this->setModel(appModel);
49  this->initialize();
50  }
51 }
52 
53 
54 template<class Scalar>
56  Teuchos::RCP<StepperObserver<Scalar> > obs)
57 {
58 
59  if (this->stepperObserver_ == Teuchos::null)
60  this->stepperObserver_ =
61  Teuchos::rcp(new StepperObserverComposite<Scalar>());
62 
63  if (( obs == Teuchos::null ) and (this->stepperObserver_->getSize() == 0) )
64  obs = Teuchos::rcp(new StepperLeapfrogObserver<Scalar>());
65 
66  this->stepperObserver_->addObserver(
67  Teuchos::rcp_dynamic_cast<StepperLeapfrogObserver<Scalar> > (obs, true) );
68 
69 }
70 
71 template<class Scalar>
73 {
74  TEUCHOS_TEST_FOR_EXCEPTION(
75  this->appModel_ == Teuchos::null, std::logic_error,
76  "Error - Need to set the model, setModel(), before calling "
77  "StepperLeapfrog::initialize()\n");
78 
79  this->setObserver();
80 }
81 
82 template<class Scalar>
84  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
85 {
86  using Teuchos::RCP;
87 
88  RCP<SolutionState<Scalar> > initialState = solutionHistory->getCurrentState();
89 
90  // Check if we need Stepper storage for xDotDot
91  if (initialState->getXDotDot() == Teuchos::null)
92  this->setStepperXDotDot(initialState->getX()->clone_v());
93 
95 
96  if (this->getUseFSAL()) {
97  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
98  Teuchos::OSTab ostab(out,1,"StepperLeapfrog::setInitialConditions()");
99  *out << "Warning -- The First-Step-As-Last (FSAL) principle is not "
100  << "used with Leapfrog because of the algorithm's prescribed "
101  << "order of solution update. The default is to set useFSAL=false, "
102  << "however useFSAL=true will also work but have no affect "
103  << "(i.e., no-op).\n" << std::endl;
104  }
105 }
106 
107 template<class Scalar>
109  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
110 {
111  using Teuchos::RCP;
112 
113  TEMPUS_FUNC_TIME_MONITOR("Tempus::StepperLeapfrog::takeStep()");
114  {
115  TEUCHOS_TEST_FOR_EXCEPTION(solutionHistory->getNumStates() < 2,
116  std::logic_error,
117  "Error - StepperLeapfrog<Scalar>::takeStep(...)\n"
118  "Need at least two SolutionStates for Leapfrog.\n"
119  " Number of States = " << solutionHistory->getNumStates() << "\n"
120  "Try setting in \"Solution History\" \"Storage Type\" = \"Undo\"\n"
121  " or \"Storage Type\" = \"Static\" and \"Storage Limit\" = \"2\"\n");
122 
123  //this->stepperObserver_->observeBeginTakeStep(solutionHistory, *this);
124  RCP<SolutionState<Scalar> > currentState=solutionHistory->getCurrentState();
125  RCP<SolutionState<Scalar> > workingState=solutionHistory->getWorkingState();
126  const Scalar time = currentState->getTime();
127  const Scalar dt = workingState->getTimeStep();
128 
129  // Perform half-step startup if working state is synced
130  // (i.e., xDot and x are at the same time level).
131  if (workingState->getIsSynced() == true) {
132  if (!Teuchos::is_null(stepperLFObserver_))
133  stepperLFObserver_->observeBeforeXDotUpdateInitialize(
134  solutionHistory, *this);
135  // Half-step startup: xDot_{n+1/2} = xDot_n + 0.5*dt*xDotDot_n
136  Thyra::V_VpStV(Teuchos::outArg(*(workingState->getXDot())),
137  *(currentState->getXDot()),0.5*dt,*(currentState->getXDotDot()));
138  }
139 
140  if (!Teuchos::is_null(stepperLFObserver_))
141  stepperLFObserver_->observeBeforeXUpdate(solutionHistory, *this);
142  // x_{n+1} = x_n + dt*xDot_{n+1/2}
143  Thyra::V_VpStV(Teuchos::outArg(*(workingState->getX())),
144  *(currentState->getX()),dt,*(workingState->getXDot()));
145 
146  if (!Teuchos::is_null(stepperLFObserver_))
147  stepperLFObserver_->observeBeforeExplicit(solutionHistory, *this);
148 
149  auto p = Teuchos::rcp(new ExplicitODEParameters<Scalar>(dt));
150 
151  // Evaluate xDotDot = f(x,t).
152  this->evaluateExplicitODE(workingState->getXDotDot(),
153  workingState->getX(),
154  Teuchos::null, time+dt, p);
155 
156  if (!Teuchos::is_null(stepperLFObserver_))
157  stepperLFObserver_->observeBeforeXDotUpdate(solutionHistory, *this);
158  if (workingState->getOutput() == true) {
159  // Half-step sync: xDot_{n+1} = xDot_{n+1/2} + 0.5*dt*xDotDot_{n+1}
160  Thyra::V_VpStV(Teuchos::outArg(*(workingState->getXDot())),
161  *(workingState->getXDot()),0.5*dt,*(workingState->getXDotDot()));
162  workingState->setIsSynced(true);
163  } else {
164  // Full leapfrog step: xDot_{n+3/2} = xDot_{n+1/2} + dt*xDotDot_{n+1}
165  Thyra::V_VpStV(Teuchos::outArg(*(workingState->getXDot())),
166  *(workingState->getXDot()),dt,*(workingState->getXDotDot()));
167  workingState->setIsSynced(false);
168  }
169 
170  workingState->setSolutionStatus(Status::PASSED);
171  workingState->setOrder(this->getOrder());
172  //this->stepperObserver_->observeEndTakeStep(solutionHistory, *this);
173  }
174  return;
175 }
176 
177 
178 /** \brief Provide a StepperState to the SolutionState.
179  * This Stepper does not have any special state data,
180  * so just provide the base class StepperState with the
181  * Stepper description. This can be checked to ensure
182  * that the input StepperState can be used by this Stepper.
183  */
184 template<class Scalar>
185 Teuchos::RCP<Tempus::StepperState<Scalar> > StepperLeapfrog<Scalar>::
187 {
188  Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
189  rcp(new StepperState<Scalar>(this->getStepperType()));
190  return stepperState;
191 }
192 
193 
194 template<class Scalar>
196  Teuchos::FancyOStream &out,
197  const Teuchos::EVerbosityLevel /* verbLevel */) const
198 {
199  out << this->getStepperType() << "::describe:" << std::endl
200  << "appModel_ = " << this->appModel_->description() << std::endl;
201 }
202 
203 
204 template<class Scalar>
205 Teuchos::RCP<const Teuchos::ParameterList>
207 {
208  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
209  getValidParametersBasic(pl, this->getStepperType());
210  pl->set<std::string>("Initial Condition Consistency",
211  this->getICConsistencyDefault());
212  return pl;
213 }
214 
215 
216 } // namespace Tempus
217 #endif // Tempus_StepperLeapfrog_impl_hpp
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions and make them consistent.
virtual void setObserver(Teuchos::RCP< StepperObserver< Scalar > > obs=Teuchos::null)
Set Observer.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
virtual void takeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Take the specified timestep, dt, and return true if successful.
This observer is a composite observer,.
StepperState is a simple class to hold state information about the stepper.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) 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.
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Get a default (initial) StepperState.
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...
StepperLeapfrog()
Default constructor.
StepperLeapfrogObserver class for StepperLeapfrog.
void getValidParametersBasic(Teuchos::RCP< Teuchos::ParameterList > pl, std::string stepperType)
Provide basic parameters to Steppers.
virtual void initialize()
Initialize during construction and after changing input parameters.