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  if (this->stepperObserver_ == Teuchos::null)
59  this->stepperObserver_ =
60  Teuchos::rcp(new StepperObserverComposite<Scalar>());
61 
62  if (obs == Teuchos::null) {
63  if (stepperLFObserver_ == Teuchos::null)
64  stepperLFObserver_ = Teuchos::rcp(new StepperLeapfrogObserver<Scalar>());
65  if (this->stepperObserver_->getSize() == 0)
66  this->stepperObserver_->addObserver(stepperLFObserver_);
67  } else {
68  stepperLFObserver_ =
69  Teuchos::rcp_dynamic_cast<StepperLeapfrogObserver<Scalar> >(obs,true);
70  this->stepperObserver_->addObserver(stepperLFObserver_);
71  }
72 
73  this->isInitialized_ = false;
74 }
75 
76 
77 template<class Scalar>
79  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
80 {
81  using Teuchos::RCP;
82 
83  RCP<SolutionState<Scalar> > initialState = solutionHistory->getCurrentState();
84 
85  // Check if we need Stepper storage for xDotDot
86  if (initialState->getXDotDot() == Teuchos::null)
87  this->setStepperXDotDot(initialState->getX()->clone_v());
88 
90 
91  if (this->getUseFSAL()) {
92  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
93  Teuchos::OSTab ostab(out,1,"StepperLeapfrog::setInitialConditions()");
94  *out << "Warning -- The First-Step-As-Last (FSAL) principle is not "
95  << "used with Leapfrog because of the algorithm's prescribed "
96  << "order of solution update. The default is to set useFSAL=false, "
97  << "however useFSAL=true will also work but have no affect "
98  << "(i.e., no-op).\n" << std::endl;
99  }
100 }
101 
102 template<class Scalar>
104  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
105 {
106  this->checkInitialized();
107 
108  using Teuchos::RCP;
109 
110  TEMPUS_FUNC_TIME_MONITOR("Tempus::StepperLeapfrog::takeStep()");
111  {
112  TEUCHOS_TEST_FOR_EXCEPTION(solutionHistory->getNumStates() < 2,
113  std::logic_error,
114  "Error - StepperLeapfrog<Scalar>::takeStep(...)\n"
115  "Need at least two SolutionStates for Leapfrog.\n"
116  " Number of States = " << solutionHistory->getNumStates() << "\n"
117  "Try setting in \"Solution History\" \"Storage Type\" = \"Undo\"\n"
118  " or \"Storage Type\" = \"Static\" and \"Storage Limit\" = \"2\"\n");
119 
120  //this->stepperObserver_->observeBeginTakeStep(solutionHistory, *this);
121  RCP<SolutionState<Scalar> > currentState=solutionHistory->getCurrentState();
122  RCP<SolutionState<Scalar> > workingState=solutionHistory->getWorkingState();
123  const Scalar time = currentState->getTime();
124  const Scalar dt = workingState->getTimeStep();
125 
126  // Perform half-step startup if working state is synced
127  // (i.e., xDot and x are at the same time level).
128  if (workingState->getIsSynced() == true) {
129  if (!Teuchos::is_null(stepperLFObserver_))
130  stepperLFObserver_->observeBeforeXDotUpdateInitialize(
131  solutionHistory, *this);
132  // Half-step startup: xDot_{n+1/2} = xDot_n + 0.5*dt*xDotDot_n
133  Thyra::V_VpStV(Teuchos::outArg(*(workingState->getXDot())),
134  *(currentState->getXDot()),0.5*dt,*(currentState->getXDotDot()));
135  }
136 
137  if (!Teuchos::is_null(stepperLFObserver_))
138  stepperLFObserver_->observeBeforeXUpdate(solutionHistory, *this);
139  // x_{n+1} = x_n + dt*xDot_{n+1/2}
140  Thyra::V_VpStV(Teuchos::outArg(*(workingState->getX())),
141  *(currentState->getX()),dt,*(workingState->getXDot()));
142 
143  if (!Teuchos::is_null(stepperLFObserver_))
144  stepperLFObserver_->observeBeforeExplicit(solutionHistory, *this);
145 
146  auto p = Teuchos::rcp(new ExplicitODEParameters<Scalar>(dt));
147 
148  // Evaluate xDotDot = f(x,t).
149  this->evaluateExplicitODE(workingState->getXDotDot(),
150  workingState->getX(),
151  Teuchos::null, time+dt, p);
152 
153  if (!Teuchos::is_null(stepperLFObserver_))
154  stepperLFObserver_->observeBeforeXDotUpdate(solutionHistory, *this);
155  if (workingState->getOutput() == true) {
156  // Half-step sync: xDot_{n+1} = xDot_{n+1/2} + 0.5*dt*xDotDot_{n+1}
157  Thyra::V_VpStV(Teuchos::outArg(*(workingState->getXDot())),
158  *(workingState->getXDot()),0.5*dt,*(workingState->getXDotDot()));
159  workingState->setIsSynced(true);
160  } else {
161  // Full leapfrog step: xDot_{n+3/2} = xDot_{n+1/2} + dt*xDotDot_{n+1}
162  Thyra::V_VpStV(Teuchos::outArg(*(workingState->getXDot())),
163  *(workingState->getXDot()),dt,*(workingState->getXDotDot()));
164  workingState->setIsSynced(false);
165  }
166 
167  workingState->setSolutionStatus(Status::PASSED);
168  workingState->setOrder(this->getOrder());
169  workingState->computeNorms(currentState);
170  //this->stepperObserver_->observeEndTakeStep(solutionHistory, *this);
171  }
172  return;
173 }
174 
175 
176 /** \brief Provide a StepperState to the SolutionState.
177  * This Stepper does not have any special state data,
178  * so just provide the base class StepperState with the
179  * Stepper description. This can be checked to ensure
180  * that the input StepperState can be used by this Stepper.
181  */
182 template<class Scalar>
183 Teuchos::RCP<Tempus::StepperState<Scalar> > StepperLeapfrog<Scalar>::
185 {
186  Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
187  rcp(new StepperState<Scalar>(this->getStepperType()));
188  return stepperState;
189 }
190 
191 
192 template<class Scalar>
194  Teuchos::FancyOStream &out,
195  const Teuchos::EVerbosityLevel verbLevel) const
196 {
197  out << std::endl;
198  Stepper<Scalar>::describe(out, verbLevel);
199  StepperExplicit<Scalar>::describe(out, verbLevel);
200 
201  out << "--- StepperLeapfrog ---\n";
202  out << " stepperLFObserver_ = " << stepperLFObserver_ << std::endl;
203  out << "-----------------------" << std::endl;
204 }
205 
206 
207 template<class Scalar>
208 bool StepperLeapfrog<Scalar>::isValidSetup(Teuchos::FancyOStream & out) const
209 {
210  bool isValidSetup = true;
211 
212  if ( !Stepper<Scalar>::isValidSetup(out) ) isValidSetup = false;
213  if ( !StepperExplicit<Scalar>::isValidSetup(out) ) isValidSetup = false;
214 
215  if (stepperLFObserver_ == Teuchos::null) {
216  isValidSetup = false;
217  out << "The Leapfrog observer is not set!\n";
218  }
219 
220  return isValidSetup;
221 }
222 
223 
224 template<class Scalar>
225 Teuchos::RCP<const Teuchos::ParameterList>
227 {
228  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
229  getValidParametersBasic(pl, this->getStepperType());
230  pl->set<std::string>("Initial Condition Consistency",
231  this->getICConsistencyDefault());
232  return pl;
233 }
234 
235 
236 } // namespace Tempus
237 #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.
Thyra Base interface for time steppers.
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 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.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
StepperObserver class for Stepper class.
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Get a default (initial) StepperState.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
virtual bool isValidSetup(Teuchos::FancyOStream &out) const
StepperLeapfrog()
Default constructor.
StepperLeapfrogObserver class for StepperLeapfrog.
Thyra Base interface for implicit time steppers.
void getValidParametersBasic(Teuchos::RCP< Teuchos::ParameterList > pl, std::string stepperType)
Provide basic parameters to Steppers.