Tempus  Version of the Day
Time Integration
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_config.hpp"
14 #include "Tempus_WrapperModelEvaluatorBasic.hpp"
15 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
16 #include "NOX_Thyra.H"
17 
18 
19 namespace Tempus {
20 
21 // Forward Declaration for recursive includes (this Stepper <--> StepperFactory)
22 template<class Scalar> class StepperFactory;
23 
24 
25 template<class Scalar>
27 {
28  this->setStepperType( "BDF2");
29  this->setUseFSAL( this->getUseFSALDefault());
30  this->setICConsistency( this->getICConsistencyDefault());
31  this->setICConsistencyCheck( this->getICConsistencyCheckDefault());
32  this->setZeroInitialGuess( false);
33 
34  this->setObserver();
35  this->setDefaultSolver();
36  this->setStartUpStepper("DIRK 1 Stage Theta Method");
37 }
38 
39 
40 template<class Scalar>
42  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
43  const Teuchos::RCP<StepperObserver<Scalar> >& obs,
44  const Teuchos::RCP<Thyra::NonlinearSolverBase<Scalar> >& solver,
45  const Teuchos::RCP<Stepper<Scalar> >& startUpStepper,
46  bool useFSAL,
47  std::string ICConsistency,
48  bool ICConsistencyCheck,
49  bool zeroInitialGuess)
50 
51 {
52  this->setStepperType( "BDF2");
53  this->setUseFSAL( useFSAL);
54  this->setICConsistency( ICConsistency);
55  this->setICConsistencyCheck( ICConsistencyCheck);
56  this->setZeroInitialGuess( zeroInitialGuess);
57 
58  this->setObserver(obs);
59  this->setSolver(solver);
60  this->setStartUpStepper(startUpStepper);
61 
62  if (appModel != Teuchos::null) {
63  this->setModel(appModel);
64  this->initialize();
65  }
66 }
67 
68 
69 template<class Scalar>
71  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel)
72 {
74  if (startUpStepper_->getModel() == Teuchos::null) {
75  startUpStepper_->setModel(appModel);
76  startUpStepper_->initialize();
77  }
78 
79  this->isInitialized_ = false;
80 }
81 
82 
83 /// Set the startup stepper to a default stepper.
84 template<class Scalar>
85 void StepperBDF2<Scalar>::setStartUpStepper(std::string startupStepperType)
86 {
87  using Teuchos::RCP;
88  RCP<StepperFactory<Scalar> > sf = Teuchos::rcp(new StepperFactory<Scalar>());
89  if (this->wrapperModel_ != Teuchos::null &&
90  this->wrapperModel_->getAppModel() != Teuchos::null) {
91  startUpStepper_ =
92  sf->createStepper(startupStepperType, this->wrapperModel_->getAppModel());
93  } else {
94  startUpStepper_ = sf->createStepper(startupStepperType);
95  }
96 
97  this->isInitialized_ = false;
98 }
99 
100 
101 /// Set the start up stepper.
102 template<class Scalar>
104  Teuchos::RCP<Stepper<Scalar> > startUpStepper)
105 {
106  startUpStepper_ = startUpStepper;
107 
108  if (this->wrapperModel_ != Teuchos::null) {
109  TEUCHOS_TEST_FOR_EXCEPTION(
110  this->wrapperModel_->getAppModel() == Teuchos::null, std::logic_error,
111  "Error - Can not set the startUpStepper to Teuchos::null.\n");
112 
113  if (startUpStepper->getModel() == Teuchos::null &&
114  this->wrapperModel_->getAppModel() != Teuchos::null) {
115  startUpStepper_->setModel(this->wrapperModel_->getAppModel());
116  startUpStepper_->initialize();
117  }
118  }
119 
120  this->isInitialized_ = false;
121 }
122 
123 
124 template<class Scalar>
126  Teuchos::RCP<StepperObserver<Scalar> > obs)
127 {
128  if (this->stepperObserver_ == Teuchos::null)
129  this->stepperObserver_ =
130  Teuchos::rcp(new StepperObserverComposite<Scalar>());
131 
132  if (obs == Teuchos::null) {
133  if (stepperBDF2Observer_ == Teuchos::null)
134  stepperBDF2Observer_ = Teuchos::rcp(new StepperBDF2Observer<Scalar>());
135  if (this->stepperObserver_->getSize() == 0)
136  this->stepperObserver_->addObserver(stepperBDF2Observer_);
137  } else {
138  stepperBDF2Observer_ =
139  Teuchos::rcp_dynamic_cast<StepperBDF2Observer<Scalar> >(obs,true);
140  this->stepperObserver_->addObserver(stepperBDF2Observer_);
141  }
142 
143  this->isInitialized_ = false;
144 }
145 
146 
147 template<class Scalar>
149 {
151 }
152 
153 
154 template<class Scalar>
156  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
157 {
158  using Teuchos::RCP;
159 
160  RCP<SolutionState<Scalar> > initialState = solutionHistory->getCurrentState();
161 
162  // Check if we need Stepper storage for xDot
163  if (initialState->getXDot() == Teuchos::null)
164  this->setStepperXDot(initialState->getX()->clone_v());
165 
167 }
168 
169 
170 template<class Scalar>
172  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
173 {
174  this->checkInitialized();
175 
176  using Teuchos::RCP;
177 
178  TEMPUS_FUNC_TIME_MONITOR("Tempus::StepperBDF2::takeStep()");
179  {
180  int numStates = solutionHistory->getNumStates();
181 
182  RCP<Thyra::VectorBase<Scalar> > xOld;
183  RCP<Thyra::VectorBase<Scalar> > xOldOld;
184 
185  // If there are less than 3 states (e.g., first time step), call
186  // startup stepper and return.
187  if (numStates < 3) {
188  computeStartUp(solutionHistory);
189  return;
190  }
191  TEUCHOS_TEST_FOR_EXCEPTION( (numStates < 3), std::logic_error,
192  "Error in Tempus::StepperBDF2::takeStep(): numStates after \n"
193  << "startup stepper must be at least 3, whereas numStates = "
194  << numStates <<"!\n" << "If running with Storage Type = Static, "
195  << "make sure Storage Limit > 2.\n");
196 
197  //IKT, FIXME: add error checking regarding states being consecutive and
198  //whether interpolated states are OK to use.
199 
200  //this->stepperObserver_->observeBeginTakeStep(solutionHistory, *this);
201 
202  RCP<SolutionState<Scalar> > workingState=solutionHistory->getWorkingState();
203  RCP<SolutionState<Scalar> > currentState=solutionHistory->getCurrentState();
204 
205  RCP<Thyra::VectorBase<Scalar> > x = workingState->getX();
206  RCP<Thyra::VectorBase<Scalar> > xDot = this->getStepperXDot(workingState);
207 
208  //get time, dt and dtOld
209  const Scalar time = workingState->getTime();
210  const Scalar dt = workingState->getTimeStep();
211  const Scalar dtOld = currentState->getTimeStep();
212 
213  xOld = solutionHistory->getStateTimeIndexNM1()->getX();
214  xOldOld = solutionHistory->getStateTimeIndexNM2()->getX();
215  order_ = Scalar(2.0);
216 
217  // Setup TimeDerivative
218  Teuchos::RCP<TimeDerivative<Scalar> > timeDer =
219  Teuchos::rcp(new StepperBDF2TimeDerivative<Scalar>(dt, dtOld, xOld, xOldOld));
220 
221  const Scalar alpha = getAlpha(dt, dtOld);
222  const Scalar beta = getBeta (dt);
223 
224  auto p = Teuchos::rcp(new ImplicitODEParameters<Scalar>(
225  timeDer, dt, alpha, beta));
226 
227  if (!Teuchos::is_null(stepperBDF2Observer_))
228  stepperBDF2Observer_->observeBeforeSolve(solutionHistory, *this);
229 
230  const Thyra::SolveStatus<Scalar> sStatus =
231  this->solveImplicitODE(x, xDot, time, p);
232 
233  if (!Teuchos::is_null(stepperBDF2Observer_))
234  stepperBDF2Observer_->observeAfterSolve(solutionHistory, *this);
235 
236  if (workingState->getXDot() != Teuchos::null)
237  timeDer->compute(x, xDot);
238 
239  workingState->setSolutionStatus(sStatus); // Converged --> pass.
240  workingState->setOrder(getOrder());
241  workingState->computeNorms(currentState);
242  //this->stepperObserver_->observeEndTakeStep(solutionHistory, *this);
243  }
244  return;
245 }
246 
247 template<class Scalar>
249  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
250 {
251  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
252  Teuchos::OSTab ostab(out,1,"StepperBDF2::computeStartUp()");
253  *out << "Warning -- Taking a startup step for BDF2 using '"
254  << startUpStepper_->getStepperType()<<"'!" << std::endl;
255 
256  //Take one step using startUpStepper_
257  startUpStepper_->takeStep(solutionHistory);
258 
259  order_ = startUpStepper_->getOrder();
260 }
261 
262 /** \brief Provide a StepperState to the SolutionState.
263  * This Stepper does not have any special state data,
264  * so just provide the base class StepperState with the
265  * Stepper description. This can be checked to ensure
266  * that the input StepperState can be used by this Stepper.
267  */
268 template<class Scalar>
269 Teuchos::RCP<Tempus::StepperState<Scalar> >
272 {
273  Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
274  rcp(new StepperState<Scalar>(this->getStepperType()));
275  return stepperState;
276 }
277 
278 
279 template<class Scalar>
281  Teuchos::FancyOStream &out,
282  const Teuchos::EVerbosityLevel verbLevel ) const
283 {
284  out << std::endl;
285  Stepper<Scalar>::describe(out, verbLevel);
286  StepperImplicit<Scalar>::describe(out, verbLevel);
287 
288  out << "--- StepperBDF2 ---\n";
289  if (startUpStepper_ != Teuchos::null) {
290  out << " startup stepper type = "
291  << startUpStepper_->description() << std::endl;
292  }
293  out << " startUpStepper_ = "
294  << startUpStepper_ << std::endl;
295  out << " startUpStepper_->isInitialized() = "
296  << Teuchos::toString(startUpStepper_->isInitialized()) << std::endl;
297  out << " stepperBDF2Observer_ = "
298  << stepperBDF2Observer_ << std::endl;
299  out << " order_ = " << order_ << std::endl;
300  out << "-------------------" << std::endl;
301 }
302 
303 
304 template<class Scalar>
305 bool StepperBDF2<Scalar>::isValidSetup(Teuchos::FancyOStream & out) const
306 {
307  bool isValidSetup = true;
308 
309  if ( !Stepper<Scalar>::isValidSetup(out) ) isValidSetup = false;
310  if ( !StepperImplicit<Scalar>::isValidSetup(out) ) isValidSetup = false;
311 
312  if ( !this->startUpStepper_->isInitialized() ) {
313  isValidSetup = false;
314  out << "The startup stepper is not initialized!\n";
315  }
316 
317  if (stepperBDF2Observer_ == Teuchos::null) {
318  isValidSetup = false;
319  out << "The BDF2 observer is not set!\n";
320  }
321 
322  return isValidSetup;
323 }
324 
325 
326 template<class Scalar>
327 Teuchos::RCP<const Teuchos::ParameterList>
329 {
330  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
331  getValidParametersBasic(pl, this->getStepperType());
332  pl->set<bool>("Initial Condition Consistency Check",
333  this->getICConsistencyCheckDefault());
334  pl->set<std::string>("Solver Name", "Default Solver");
335  pl->set<bool>("Zero Initial Guess", false);
336  pl->set<std::string>("Start Up Stepper Type", "DIRK 1 Stage Theta Method");
337  Teuchos::RCP<Teuchos::ParameterList> solverPL = defaultSolverParameters();
338  pl->set("Default Solver", *solverPL);
339 
340  return pl;
341 }
342 
343 
344 } // namespace Tempus
345 #endif // Tempus_StepperBDF2_impl_hpp
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
StepperBDF2Observer class for StepperBDF2.
Time-derivative interface for BDF2.
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 setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel)
virtual void setObserver(Teuchos::RCP< StepperObserver< Scalar > > obs=Teuchos::null)
Set Observer.
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 describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel)
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions and make them consistent.
This observer is a composite observer,.
StepperObserver class for Stepper class.
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
const std::string toString(const Status status)
Convert Status to string.
void getValidParametersBasic(Teuchos::RCP< Teuchos::ParameterList > pl, std::string stepperType)
Provide basic parameters to Steppers.
Teuchos::RCP< Teuchos::ParameterList > defaultSolverParameters()
Returns the default solver ParameterList for implicit Steppers.