Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Tempus_StepperBDF2_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_StepperBDF2_impl_hpp
10 #define Tempus_StepperBDF2_impl_hpp
11 
12 #include "Tempus_WrapperModelEvaluatorBasic.hpp"
14 #include "Tempus_StepperFactory.hpp"
15 
16 namespace Tempus {
17 
18 template <class Scalar>
20 {
21  this->setStepperName("BDF2");
22  this->setStepperType("BDF2");
23  this->setUseFSAL(false);
24  this->setICConsistency("None");
25  this->setICConsistencyCheck(false);
26  this->setZeroInitialGuess(false);
27 
28  this->setAppAction(Teuchos::null);
29  this->setDefaultSolver();
30  this->setStartUpStepper("DIRK 1 Stage Theta Method");
31 }
32 
33 template <class Scalar>
35  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
37  const Teuchos::RCP<Stepper<Scalar> >& startUpStepper, bool useFSAL,
38  std::string ICConsistency, bool ICConsistencyCheck, bool zeroInitialGuess,
39  const Teuchos::RCP<StepperBDF2AppAction<Scalar> >& stepperBDF2AppAction)
40 {
41  this->setStepperName("BDF2");
42  this->setStepperType("BDF2");
43  this->setUseFSAL(useFSAL);
44  this->setICConsistency(ICConsistency);
45  this->setICConsistencyCheck(ICConsistencyCheck);
46  this->setZeroInitialGuess(zeroInitialGuess);
47 
48  this->setAppAction(stepperBDF2AppAction);
49  this->setSolver(solver);
50  this->setStartUpStepper(startUpStepper);
51 
52  if (appModel != Teuchos::null) {
53  this->setModel(appModel);
54  this->initialize();
55  }
56 }
57 
58 template <class Scalar>
60  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel)
61 {
63  // If the startUpStepper's model is not set, set it to the stepper model.
64  if (startUpStepper_->getModel() == Teuchos::null) {
65  startUpStepper_->setModel(appModel);
66  startUpStepper_->initialize();
67  }
68 
69  this->isInitialized_ = false;
70 }
71 
72 template <class Scalar>
73 void StepperBDF2<Scalar>::setStartUpStepper(std::string startupStepperType)
74 {
75  auto sf = Teuchos::rcp(new StepperFactory<Scalar>());
76  if (this->wrapperModel_ != Teuchos::null &&
77  this->wrapperModel_->getAppModel() != Teuchos::null) {
78  startUpStepper_ = sf->createStepper(startupStepperType,
79  this->wrapperModel_->getAppModel());
80  }
81  else {
82  startUpStepper_ = sf->createStepper(startupStepperType);
83  }
84 
85  this->isInitialized_ = false;
86 }
87 
88 template <class Scalar>
90  Teuchos::RCP<Stepper<Scalar> > startUpStepper)
91 {
92  startUpStepper_ = startUpStepper;
93 
94  if (this->wrapperModel_ != Teuchos::null) {
96  this->wrapperModel_->getAppModel() == Teuchos::null, std::logic_error,
97  "Error - Can not set the startUpStepper to Teuchos::null.\n");
98 
99  if (startUpStepper->getModel() == Teuchos::null &&
100  this->wrapperModel_->getAppModel() != Teuchos::null) {
101  startUpStepper_->setModel(this->wrapperModel_->getAppModel());
102  startUpStepper_->initialize();
103  }
104  }
105 
106  this->isInitialized_ = false;
107 }
108 
109 template <class Scalar>
112 {
113  if (appAction == Teuchos::null) {
114  // Create default appAction
115  stepperBDF2AppAction_ =
117  }
118  else {
119  stepperBDF2AppAction_ = appAction;
120  }
121 }
122 
123 template <class Scalar>
125 {
127 }
128 
129 template <class Scalar>
131  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
132 {
133  using Teuchos::RCP;
134 
135  RCP<SolutionState<Scalar> > initialState = solutionHistory->getCurrentState();
136 
137  // Check if we need Stepper storage for xDot
138  if (initialState->getXDot() == Teuchos::null)
139  this->setStepperXDot(initialState->getX()->clone_v());
140  else
141  this->setStepperXDot(initialState->getXDot());
142 
144 }
145 
146 template <class Scalar>
148  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
149 {
150  this->checkInitialized();
151 
152  using Teuchos::RCP;
153 
154  TEMPUS_FUNC_TIME_MONITOR("Tempus::StepperBDF2::takeStep()");
155  {
156  int numStates = solutionHistory->getNumStates();
157 
158  RCP<Thyra::VectorBase<Scalar> > xOld;
159  RCP<Thyra::VectorBase<Scalar> > xOldOld;
160 
161  // If there are less than 3 states (e.g., first time step), call
162  // startup stepper and return.
163  if (numStates < 3) {
164  computeStartUp(solutionHistory);
165  return;
166  }
168  (numStates < 3), std::logic_error,
169  "Error in Tempus::StepperBDF2::takeStep(): numStates after \n"
170  << "startup stepper must be at least 3, whereas numStates = "
171  << numStates << "!\n"
172  << "If running with Storage Type = Static, "
173  << "make sure Storage Limit > 2.\n");
174 
175  // IKT, FIXME: add error checking regarding states being consecutive and
176  // whether interpolated states are OK to use.
177 
178  RCP<StepperBDF2<Scalar> > thisStepper = Teuchos::rcpFromRef(*this);
179  stepperBDF2AppAction_->execute(
180  solutionHistory, thisStepper,
182 
183  RCP<SolutionState<Scalar> > workingState =
184  solutionHistory->getWorkingState();
185  RCP<SolutionState<Scalar> > currentState =
186  solutionHistory->getCurrentState();
187 
188  RCP<Thyra::VectorBase<Scalar> > x = workingState->getX();
189  if (workingState->getXDot() != Teuchos::null)
190  this->setStepperXDot(workingState->getXDot());
191  RCP<Thyra::VectorBase<Scalar> > xDot = this->getStepperXDot();
192 
193  // get time, dt and dtOld
194  const Scalar time = workingState->getTime();
195  const Scalar dt = workingState->getTimeStep();
196  const Scalar dtOld = currentState->getTimeStep();
197 
198  xOld = solutionHistory->getStateTimeIndexNM1()->getX();
199  xOldOld = solutionHistory->getStateTimeIndexNM2()->getX();
200  order_ = Scalar(2.0);
201 
202  // Setup TimeDerivative
204  new StepperBDF2TimeDerivative<Scalar>(dt, dtOld, xOld, xOldOld));
205 
206  const Scalar alpha = getAlpha(dt, dtOld);
207  const Scalar beta = getBeta(dt);
208 
209  auto p = Teuchos::rcp(
210  new ImplicitODEParameters<Scalar>(timeDer, dt, alpha, beta));
211  stepperBDF2AppAction_->execute(
212  solutionHistory, thisStepper,
214 
215  const Thyra::SolveStatus<Scalar> sStatus =
216  this->solveImplicitODE(x, xDot, time, p);
217 
218  stepperBDF2AppAction_->execute(
219  solutionHistory, thisStepper,
221 
222  if (workingState->getXDot() != Teuchos::null) timeDer->compute(x, xDot);
223 
224  workingState->setSolutionStatus(sStatus); // Converged --> pass.
225  workingState->setOrder(getOrder());
226  workingState->computeNorms(currentState);
227  stepperBDF2AppAction_->execute(
228  solutionHistory, thisStepper,
230  }
231  return;
232 }
233 
234 template <class Scalar>
236  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
237 {
238  auto out = Teuchos::fancyOStream(this->getOStream());
239  out->setOutputToRootOnly(0);
240  Teuchos::OSTab ostab(out, 1, "StepperBDF2::computeStartUp()");
241  *out << "Warning -- Taking a startup step for BDF2 using '"
242  << startUpStepper_->getStepperType() << "'!" << std::endl;
243 
244  // Take one step using startUpStepper_
245  startUpStepper_->takeStep(solutionHistory);
246 
247  order_ = startUpStepper_->getOrder();
248 }
249 
256 template <class Scalar>
259 {
261  rcp(new StepperState<Scalar>(this->getStepperType()));
262  return stepperState;
263 }
264 
265 template <class Scalar>
267  Teuchos::FancyOStream& out, const Teuchos::EVerbosityLevel verbLevel) const
268 {
269  auto l_out = Teuchos::fancyOStream(out.getOStream());
270  Teuchos::OSTab ostab(*l_out, 2, this->description());
271  l_out->setOutputToRootOnly(0);
272  *l_out << std::endl;
273  Stepper<Scalar>::describe(out, verbLevel);
274  StepperImplicit<Scalar>::describe(out, verbLevel);
275 
276  *l_out << "--- StepperBDF2 ---\n";
277  if (startUpStepper_ != Teuchos::null) {
278  *l_out << " startup stepper type = "
279  << startUpStepper_->description() << std::endl;
280  }
281  *l_out << " startUpStepper_ = " << startUpStepper_
282  << std::endl;
283  *l_out << " startUpStepper_->isInitialized() = "
284  << Teuchos::toString(startUpStepper_->isInitialized()) << std::endl;
285  *l_out << " stepperBDF2AppAction_ = " << stepperBDF2AppAction_
286  << std::endl;
287  *l_out << "----------------------------" << std::endl;
288  *l_out << " order_ = " << order_ << std::endl;
289  *l_out << "-------------------" << std::endl;
290 }
291 
292 template <class Scalar>
294 {
295  bool isValidSetup = true;
296  auto l_out = Teuchos::fancyOStream(out.getOStream());
297  l_out->setOutputToRootOnly(0);
298 
299  if (!Stepper<Scalar>::isValidSetup(out)) isValidSetup = false;
300  if (!StepperImplicit<Scalar>::isValidSetup(out)) isValidSetup = false;
301 
302  if (!this->startUpStepper_->isInitialized()) {
303  isValidSetup = false;
304  *l_out << "The startup stepper is not initialized!\n";
305  }
306  if (stepperBDF2AppAction_ == Teuchos::null) {
307  isValidSetup = false;
308  *l_out << "The BDF2 AppAction is not set!\n";
309  }
310  return isValidSetup;
311 }
312 
313 template <class Scalar>
316 {
317  auto pl = this->getValidParametersBasicImplicit();
318  pl->set("Start Up Stepper Type", startUpStepper_->getStepperType());
319  return pl;
320 }
321 
322 // Nonmember constructor - ModelEvaluator and ParameterList
323 // ------------------------------------------------------------------------
324 template <class Scalar>
326  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& model,
328 {
329  auto stepper = Teuchos::rcp(new StepperBDF2<Scalar>());
330  stepper->setStepperImplicitValues(pl);
331 
332  std::string startUpStepperName = "DIRK 1 Stage Theta Method";
333  if (pl != Teuchos::null)
334  startUpStepperName =
335  pl->get<std::string>("Start Up Stepper Type", startUpStepperName);
336  stepper->setStartUpStepper(startUpStepperName);
337 
338  if (model != Teuchos::null) {
339  stepper->setModel(model);
340  stepper->initialize();
341  }
342 
343  return stepper;
344 }
345 
346 } // namespace Tempus
347 #endif // Tempus_StepperBDF2_impl_hpp
BDF2 (Backward-Difference-Formula-2) time stepper.
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions and make them consistent.
Time-derivative interface for BDF2.
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Get a default (initial) StepperState.
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel)
Set the model.
T & get(const std::string &name, T def_value)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual void initialize()
Initialize after construction and changing input parameters.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const override
virtual void computeStartUp(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Compute the first time step given the supplied startup stepper.
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel) override
Set the model.
Thyra Base interface for time steppers.
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory) override
Set the initial conditions and make them consistent.
StepperState is a simple class to hold state information about the stepper.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Thyra Base interface for implicit time steppers.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual void setAppAction(Teuchos::RCP< StepperBDF2AppAction< Scalar > > appAction)
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
virtual bool isValidSetup(Teuchos::FancyOStream &out) const
RCP< std::basic_ostream< char_type, traits_type > > getOStream()
Teuchos::RCP< StepperBDF2< Scalar > > createStepperBDF2(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, Teuchos::RCP< Teuchos::ParameterList > pl)
Nonmember constructor - ModelEvaluator and ParameterList.
Application Action for StepperBDF2.
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.
void setStartUpStepper(std::string startupStepperType)
Set the stepper to use in first step.
virtual void initialize()
Initialize during construction and after changing input parameters.
StepperBDF2()
Default constructor.
std::string toString(const T &t)