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: Time Integration and Sensitivity Analysis Package
4 //
5 // Copyright 2017 NTESS and the Tempus contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 //@HEADER
9 
10 #ifndef Tempus_StepperBDF2_impl_hpp
11 #define Tempus_StepperBDF2_impl_hpp
12 
13 #include "Tempus_WrapperModelEvaluatorBasic.hpp"
15 #include "Tempus_StepperFactory.hpp"
16 
17 namespace Tempus {
18 
19 template <class Scalar>
21 {
22  this->setStepperName("BDF2");
23  this->setStepperType("BDF2");
24  this->setUseFSAL(false);
25  this->setICConsistency("None");
26  this->setICConsistencyCheck(false);
27  this->setZeroInitialGuess(false);
28 
29  this->setAppAction(Teuchos::null);
30  this->setDefaultSolver();
31  this->setStartUpStepper("DIRK 1 Stage Theta Method");
32 }
33 
34 template <class Scalar>
36  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
38  const Teuchos::RCP<Stepper<Scalar> >& startUpStepper, bool useFSAL,
39  std::string ICConsistency, bool ICConsistencyCheck, bool zeroInitialGuess,
40  const Teuchos::RCP<StepperBDF2AppAction<Scalar> >& stepperBDF2AppAction)
41 {
42  this->setStepperName("BDF2");
43  this->setStepperType("BDF2");
44  this->setUseFSAL(useFSAL);
45  this->setICConsistency(ICConsistency);
46  this->setICConsistencyCheck(ICConsistencyCheck);
47  this->setZeroInitialGuess(zeroInitialGuess);
48 
49  this->setAppAction(stepperBDF2AppAction);
50  this->setSolver(solver);
51  this->setStartUpStepper(startUpStepper);
52 
53  if (appModel != Teuchos::null) {
54  this->setModel(appModel);
55  this->initialize();
56  }
57 }
58 
59 template <class Scalar>
61  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel)
62 {
64  // If the startUpStepper's model is not set, set it to the stepper model.
65  if (startUpStepper_->getModel() == Teuchos::null) {
66  startUpStepper_->setModel(appModel);
67  startUpStepper_->initialize();
68  }
69 
70  this->isInitialized_ = false;
71 }
72 
73 template <class Scalar>
74 void StepperBDF2<Scalar>::setStartUpStepper(std::string startupStepperType)
75 {
76  auto sf = Teuchos::rcp(new StepperFactory<Scalar>());
77  if (this->wrapperModel_ != Teuchos::null &&
78  this->wrapperModel_->getAppModel() != Teuchos::null) {
79  startUpStepper_ = sf->createStepper(startupStepperType,
80  this->wrapperModel_->getAppModel());
81  }
82  else {
83  startUpStepper_ = sf->createStepper(startupStepperType);
84  }
85 
86  this->isInitialized_ = false;
87 }
88 
89 template <class Scalar>
91  Teuchos::RCP<Stepper<Scalar> > startUpStepper)
92 {
93  startUpStepper_ = startUpStepper;
94 
95  if (this->wrapperModel_ != Teuchos::null) {
97  this->wrapperModel_->getAppModel() == Teuchos::null, std::logic_error,
98  "Error - Can not set the startUpStepper to Teuchos::null.\n");
99 
100  if (startUpStepper->getModel() == Teuchos::null &&
101  this->wrapperModel_->getAppModel() != Teuchos::null) {
102  startUpStepper_->setModel(this->wrapperModel_->getAppModel());
103  startUpStepper_->initialize();
104  }
105  }
106 
107  this->isInitialized_ = false;
108 }
109 
110 template <class Scalar>
113 {
114  if (appAction == Teuchos::null) {
115  // Create default appAction
116  stepperBDF2AppAction_ =
118  }
119  else {
120  stepperBDF2AppAction_ = appAction;
121  }
122 }
123 
124 template <class Scalar>
126 {
128 }
129 
130 template <class Scalar>
132  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
133 {
134  using Teuchos::RCP;
135 
136  RCP<SolutionState<Scalar> > initialState = solutionHistory->getCurrentState();
137 
138  // Check if we need Stepper storage for xDot
139  if (initialState->getXDot() == Teuchos::null)
140  this->setStepperXDot(initialState->getX()->clone_v());
141  else
142  this->setStepperXDot(initialState->getXDot());
143 
145 }
146 
147 template <class Scalar>
149  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
150 {
151  this->checkInitialized();
152 
153  using Teuchos::RCP;
154 
155  TEMPUS_FUNC_TIME_MONITOR("Tempus::StepperBDF2::takeStep()");
156  {
157  int numStates = solutionHistory->getNumStates();
158 
159  RCP<Thyra::VectorBase<Scalar> > xOld;
160  RCP<Thyra::VectorBase<Scalar> > xOldOld;
161 
162  // If there are less than 3 states (e.g., first time step), call
163  // startup stepper and return.
164  if (numStates < 3) {
165  computeStartUp(solutionHistory);
166  return;
167  }
169  (numStates < 3), std::logic_error,
170  "Error in Tempus::StepperBDF2::takeStep(): numStates after \n"
171  << "startup stepper must be at least 3, whereas numStates = "
172  << numStates << "!\n"
173  << "If running with Storage Type = Static, "
174  << "make sure Storage Limit > 2.\n");
175 
176  // IKT, FIXME: add error checking regarding states being consecutive and
177  // whether interpolated states are OK to use.
178 
179  RCP<StepperBDF2<Scalar> > thisStepper = Teuchos::rcpFromRef(*this);
180  stepperBDF2AppAction_->execute(
181  solutionHistory, thisStepper,
183 
184  RCP<SolutionState<Scalar> > workingState =
185  solutionHistory->getWorkingState();
186  RCP<SolutionState<Scalar> > currentState =
187  solutionHistory->getCurrentState();
188 
189  RCP<Thyra::VectorBase<Scalar> > x = workingState->getX();
190  if (workingState->getXDot() != Teuchos::null)
191  this->setStepperXDot(workingState->getXDot());
192  RCP<Thyra::VectorBase<Scalar> > xDot = this->getStepperXDot();
193 
194  // get time, dt and dtOld
195  const Scalar time = workingState->getTime();
196  const Scalar dt = workingState->getTimeStep();
197  const Scalar dtOld = currentState->getTimeStep();
198 
199  xOld = solutionHistory->getStateTimeIndexNM1()->getX();
200  xOldOld = solutionHistory->getStateTimeIndexNM2()->getX();
201  order_ = Scalar(2.0);
202 
203  // Setup TimeDerivative
205  new StepperBDF2TimeDerivative<Scalar>(dt, dtOld, xOld, xOldOld));
206 
207  const Scalar alpha = getAlpha(dt, dtOld);
208  const Scalar beta = getBeta(dt);
209 
210  auto p = Teuchos::rcp(
211  new ImplicitODEParameters<Scalar>(timeDer, dt, alpha, beta));
212  stepperBDF2AppAction_->execute(
213  solutionHistory, thisStepper,
215 
216  const Thyra::SolveStatus<Scalar> sStatus =
217  this->solveImplicitODE(x, xDot, time, p);
218 
219  stepperBDF2AppAction_->execute(
220  solutionHistory, thisStepper,
222 
223  if (workingState->getXDot() != Teuchos::null) timeDer->compute(x, xDot);
224 
225  workingState->setSolutionStatus(sStatus); // Converged --> pass.
226  workingState->setOrder(getOrder());
227  workingState->computeNorms(currentState);
228  stepperBDF2AppAction_->execute(
229  solutionHistory, thisStepper,
231  }
232  return;
233 }
234 
235 template <class Scalar>
237  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
238 {
239  auto out = Teuchos::fancyOStream(this->getOStream());
240  out->setOutputToRootOnly(0);
241  Teuchos::OSTab ostab(out, 1, "StepperBDF2::computeStartUp()");
242  *out << "Warning -- Taking a startup step for BDF2 using '"
243  << startUpStepper_->getStepperType() << "'!" << std::endl;
244 
245  // Take one step using startUpStepper_
246  startUpStepper_->takeStep(solutionHistory);
247 
248  order_ = startUpStepper_->getOrder();
249 }
250 
257 template <class Scalar>
260 {
262  rcp(new StepperState<Scalar>(this->getStepperType()));
263  return stepperState;
264 }
265 
266 template <class Scalar>
268  Teuchos::FancyOStream& out, const Teuchos::EVerbosityLevel verbLevel) const
269 {
270  auto l_out = Teuchos::fancyOStream(out.getOStream());
271  Teuchos::OSTab ostab(*l_out, 2, this->description());
272  l_out->setOutputToRootOnly(0);
273  *l_out << std::endl;
274  Stepper<Scalar>::describe(out, verbLevel);
275  StepperImplicit<Scalar>::describe(out, verbLevel);
276 
277  *l_out << "--- StepperBDF2 ---\n";
278  if (startUpStepper_ != Teuchos::null) {
279  *l_out << " startup stepper type = "
280  << startUpStepper_->description() << std::endl;
281  }
282  *l_out << " startUpStepper_ = " << startUpStepper_
283  << std::endl;
284  *l_out << " startUpStepper_->isInitialized() = "
285  << Teuchos::toString(startUpStepper_->isInitialized()) << std::endl;
286  *l_out << " stepperBDF2AppAction_ = " << stepperBDF2AppAction_
287  << std::endl;
288  *l_out << "----------------------------" << std::endl;
289  *l_out << " order_ = " << order_ << std::endl;
290  *l_out << "-------------------" << std::endl;
291 }
292 
293 template <class Scalar>
295 {
296  bool isValidSetup = true;
297  auto l_out = Teuchos::fancyOStream(out.getOStream());
298  l_out->setOutputToRootOnly(0);
299 
300  if (!Stepper<Scalar>::isValidSetup(out)) isValidSetup = false;
301  if (!StepperImplicit<Scalar>::isValidSetup(out)) isValidSetup = false;
302 
303  if (!this->startUpStepper_->isInitialized()) {
304  isValidSetup = false;
305  *l_out << "The startup stepper is not initialized!\n";
306  }
307  if (stepperBDF2AppAction_ == Teuchos::null) {
308  isValidSetup = false;
309  *l_out << "The BDF2 AppAction is not set!\n";
310  }
311  return isValidSetup;
312 }
313 
314 template <class Scalar>
317 {
318  auto pl = this->getValidParametersBasicImplicit();
319  pl->set("Start Up Stepper Type", startUpStepper_->getStepperType());
320  return pl;
321 }
322 
323 // Nonmember constructor - ModelEvaluator and ParameterList
324 // ------------------------------------------------------------------------
325 template <class Scalar>
327  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& model,
329 {
330  auto stepper = Teuchos::rcp(new StepperBDF2<Scalar>());
331  stepper->setStepperImplicitValues(pl);
332 
333  std::string startUpStepperName = "DIRK 1 Stage Theta Method";
334  if (pl != Teuchos::null)
335  startUpStepperName =
336  pl->get<std::string>("Start Up Stepper Type", startUpStepperName);
337  stepper->setStartUpStepper(startUpStepperName);
338 
339  if (model != Teuchos::null) {
340  stepper->setModel(model);
341  stepper->initialize();
342  }
343 
344  return stepper;
345 }
346 
347 } // namespace Tempus
348 #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)