Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
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
17namespace Tempus {
18
19template <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
34template <class Scalar>
36 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
37 const Teuchos::RCP<Thyra::NonlinearSolverBase<Scalar> >& solver,
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
59template <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
73template <class Scalar>
74void 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
89template <class Scalar>
91 Teuchos::RCP<Stepper<Scalar> > startUpStepper)
92{
93 startUpStepper_ = startUpStepper;
94
95 if (this->wrapperModel_ != Teuchos::null) {
96 TEUCHOS_TEST_FOR_EXCEPTION(
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
110template <class Scalar>
112 Teuchos::RCP<StepperBDF2AppAction<Scalar> > appAction)
113{
114 if (appAction == Teuchos::null) {
115 // Create default appAction
116 stepperBDF2AppAction_ =
117 Teuchos::rcp(new StepperBDF2ModifierDefault<Scalar>());
118 }
119 else {
120 stepperBDF2AppAction_ = appAction;
121 }
122}
123
124template <class Scalar>
129
130template <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
147template <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 }
168 TEUCHOS_TEST_FOR_EXCEPTION(
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
204 Teuchos::RCP<TimeDerivative<Scalar> > timeDer = Teuchos::rcp(
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
235template <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
257template <class Scalar>
258Teuchos::RCP<Tempus::StepperState<Scalar> >
260{
261 Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
262 rcp(new StepperState<Scalar>(this->getStepperType()));
263 return stepperState;
264}
265
266template <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
293template <class Scalar>
294bool StepperBDF2<Scalar>::isValidSetup(Teuchos::FancyOStream& out) const
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
314template <class Scalar>
315Teuchos::RCP<const Teuchos::ParameterList>
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// ------------------------------------------------------------------------
325template <class Scalar>
326Teuchos::RCP<StepperBDF2<Scalar> > createStepperBDF2(
327 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& model,
328 Teuchos::RCP<Teuchos::ParameterList> pl)
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
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Application Action for StepperBDF2.
Time-derivative interface for BDF2.
BDF2 (Backward-Difference-Formula-2) time stepper.
void setStartUpStepper(std::string startupStepperType)
Set the stepper to use in first step.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual void takeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Take the specified timestep, dt, and return true if successful.
virtual bool isValidSetup(Teuchos::FancyOStream &out) const
virtual void setAppAction(Teuchos::RCP< StepperBDF2AppAction< Scalar > > appAction)
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel)
Set the model.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions and make them consistent.
StepperBDF2()
Default constructor.
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Get a default (initial) StepperState.
virtual void computeStartUp(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Compute the first time step given the supplied startup stepper.
virtual void initialize()
Initialize during construction and after changing input parameters.
Thyra Base interface for implicit time steppers.
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory) override
Set the initial conditions and make them consistent.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const override
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel) override
Set the model.
StepperState is a simple class to hold state information about the stepper.
Thyra Base interface for time steppers.
virtual void initialize()
Initialize after construction and changing input parameters.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Teuchos::RCP< StepperBDF2< Scalar > > createStepperBDF2(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, Teuchos::RCP< Teuchos::ParameterList > pl)
Nonmember constructor - ModelEvaluator and ParameterList.