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 // StepperBDF2 definitions:
26 template<class Scalar>
28  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
29  Teuchos::RCP<Teuchos::ParameterList> pList)
30 {
31  using Teuchos::RCP;
32  using Teuchos::ParameterList;
33 
34  // Set all the input parameters and call initialize
35  this->setParameterList(pList);
36  this->setModel(appModel);
37  this->initialize();
38 }
39 
40 
41 /** \brief Set the startup stepper to a pre-defined stepper in the ParameterList
42  *
43  * The startup stepper is set to stepperName sublist in the Stepper's
44  * ParameterList. The stepperName sublist should already be defined
45  * in the Stepper's ParameterList. Otherwise it will fail.
46  */
47 template<class Scalar>
48 void StepperBDF2<Scalar>::setStartUpStepper(std::string startupStepperName)
49 {
50  using Teuchos::RCP;
51  using Teuchos::ParameterList;
52 
53  RCP<ParameterList> startupStepperPL =
54  Teuchos::sublist(this->stepperPL_, startupStepperName, true);
55  this->stepperPL_->set("Start Up Stepper Name", startupStepperName);
56  RCP<StepperFactory<Scalar> > sf = Teuchos::rcp(new StepperFactory<Scalar>());
57  startUpStepper_ =
58  sf->createStepper(this->wrapperModel_->getAppModel(), startupStepperPL);
59 }
60 
61 
62 /** \brief Set the start up stepper to the supplied Parameter sublist.
63  *
64  * This adds a new start up stepper Parameter sublist to the Stepper's
65  * ParameterList. If the start up stepper sublist is null, it tests if
66  * the stepper sublist is set in the Stepper's ParameterList.
67  */
68 template<class Scalar>
70  Teuchos::RCP<Teuchos::ParameterList> startupStepperPL)
71 {
72  using Teuchos::RCP;
73  using Teuchos::ParameterList;
74 
75  Teuchos::RCP<Teuchos::ParameterList> stepperPL = this->stepperPL_;
76  std::string startupStepperName =
77  stepperPL->get<std::string>("Start Up Stepper Name","None");
78  if (is_null(startupStepperPL)) {
79  // Create startUpStepper, otherwise keep current startUpStepper.
80  if (startUpStepper_ == Teuchos::null) {
81  if (startupStepperName != "None") {
82  // Construct from ParameterList
83  RCP<ParameterList> startupStepperPL =
84  Teuchos::sublist(this->stepperPL_, startupStepperName, true);
85  RCP<StepperFactory<Scalar> > sf =
86  Teuchos::rcp(new StepperFactory<Scalar>());
87  startUpStepper_ =
88  sf->createStepper(this->wrapperModel_->getAppModel(), startupStepperPL);
89  } else {
90  // Construct default start-up Stepper
91  RCP<StepperFactory<Scalar> > sf =
92  Teuchos::rcp(new StepperFactory<Scalar>());
93  startUpStepper_ =
94  sf->createStepper(this->wrapperModel_->getAppModel(),
95  "IRK 1 Stage Theta Method");
96 
97  startupStepperName = startUpStepper_->description();
98  startupStepperPL = startUpStepper_->getNonconstParameterList();
99  this->stepperPL_->set("Start Up Stepper Name", startupStepperName);
100  this->stepperPL_->set(startupStepperName, *startupStepperPL); // Add sublist
101  }
102  }
103  } else {
104  TEUCHOS_TEST_FOR_EXCEPTION( startupStepperName == startupStepperPL->name(),
105  std::logic_error,
106  "Error - Trying to add a startup stepper that is already in "
107  << "ParameterList!\n"
108  << " Stepper Type = "<< stepperPL->get<std::string>("Stepper Type")
109  << "\n" << " Start Up Stepper Name = "<<startupStepperName<<"\n");
110  startupStepperName = startupStepperPL->name();
111  this->stepperPL_->set("Start Up Stepper Name", startupStepperName);
112  this->stepperPL_->set(startupStepperName, *startupStepperPL); // Add sublist
113  RCP<StepperFactory<Scalar> > sf =
114  Teuchos::rcp(new StepperFactory<Scalar>());
115  startUpStepper_ =
116  sf->createStepper(this->wrapperModel_->getAppModel(), startupStepperPL);
117  }
118 }
119 
120 
121 template<class Scalar>
123  Teuchos::RCP<StepperObserver<Scalar> > obs)
124 {
125  if (obs == Teuchos::null) {
126  // Create default observer, otherwise keep current observer.
127  if (stepperObserver_ == Teuchos::null) {
128  stepperBDF2Observer_ =
129  Teuchos::rcp(new StepperBDF2Observer<Scalar>());
130  stepperObserver_ =
131  Teuchos::rcp_dynamic_cast<StepperObserver<Scalar> >
132  (stepperBDF2Observer_);
133  }
134  } else {
135  stepperObserver_ = obs;
136  stepperBDF2Observer_ =
137  Teuchos::rcp_dynamic_cast<StepperBDF2Observer<Scalar> >(stepperObserver_);
138  }
139 }
140 
141 
142 template<class Scalar>
144 {
145  TEUCHOS_TEST_FOR_EXCEPTION( this->wrapperModel_ == Teuchos::null,
146  std::logic_error,
147  "Error - Need to set the model, setModel(), before calling "
148  "StepperBDF2::initialize()\n");
149 
150  this->setParameterList(this->stepperPL_);
151  this->setSolver();
152  this->setStartUpStepper();
153  this->setObserver();
154  order_ = 2.0;
155 }
156 
157 
158 template<class Scalar>
160  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
161 {
162  using Teuchos::RCP;
163 
164  TEMPUS_FUNC_TIME_MONITOR("Tempus::StepperBDF2::takeStep()");
165  {
166  int numStates = solutionHistory->getNumStates();
167 
168  RCP<Thyra::VectorBase<Scalar> > xOld;
169  RCP<Thyra::VectorBase<Scalar> > xOldOld;
170 
171  // If there are less than 3 states (e.g., first time step), call
172  // startup stepper and return.
173  if (numStates < 3) {
174  computeStartUp(solutionHistory);
175  return;
176  }
177  TEUCHOS_TEST_FOR_EXCEPTION( (numStates < 3), std::logic_error,
178  "Error in Tempus::StepperBDF2::takeStep(): numStates after \n"
179  << "startup stepper must be at least 3, whereas numStates = "
180  << numStates <<"!\n" << "If running with Storage Type = Static, "
181  << "make sure Storage Limit > 2.\n");
182 
183  //IKT, FIXME: add error checking regarding states being consecutive and
184  //whether interpolated states are OK to use.
185 
186  stepperObserver_->observeBeginTakeStep(solutionHistory, *this);
187 
188  RCP<SolutionState<Scalar> > workingState=solutionHistory->getWorkingState();
189  RCP<SolutionState<Scalar> > currentState=solutionHistory->getCurrentState();
190 
191  RCP<Thyra::VectorBase<Scalar> > x = workingState->getX();
192  RCP<Thyra::VectorBase<Scalar> > xDot = workingState->getXDot();
193  if (xDot == Teuchos::null) xDot = getXDotTemp(x);
194 
195  //get time, dt and dtOld
196  const Scalar time = workingState->getTime();
197  const Scalar dt = workingState->getTimeStep();
198  const Scalar dtOld = currentState->getTimeStep();
199 
200  xOld = solutionHistory->getStateTimeIndexNM1()->getX();
201  xOldOld = solutionHistory->getStateTimeIndexNM2()->getX();
202  order_ = 2.0;
203 
204  const Scalar alpha = (1.0/(dt + dtOld))*(1.0/dt)*(2.0*dt + dtOld);
205  const Scalar beta = 1.0;
206 
207  // Setup TimeDerivative
208  Teuchos::RCP<TimeDerivative<Scalar> > timeDer =
209  Teuchos::rcp(new StepperBDF2TimeDerivative<Scalar>(dt, dtOld, xOld, xOldOld));
210 
211  // Setup InArgs and OutArgs
212  typedef Thyra::ModelEvaluatorBase MEB;
213  MEB::InArgs<Scalar> inArgs = this->wrapperModel_->getInArgs();
214  MEB::OutArgs<Scalar> outArgs = this->wrapperModel_->getOutArgs();
215  inArgs.set_x(x);
216  if (inArgs.supports(MEB::IN_ARG_x_dot )) inArgs.set_x_dot (xDot);
217  if (inArgs.supports(MEB::IN_ARG_t )) inArgs.set_t (time);
218  if (inArgs.supports(MEB::IN_ARG_step_size)) inArgs.set_step_size(dt);
219  if (inArgs.supports(MEB::IN_ARG_alpha )) inArgs.set_alpha (alpha);
220  if (inArgs.supports(MEB::IN_ARG_beta )) inArgs.set_beta (beta);
221 
222  this->wrapperModel_->setForSolve(timeDer, inArgs, outArgs);
223 
224  if (!Teuchos::is_null(stepperBDF2Observer_))
225  stepperBDF2Observer_->observeBeforeSolve(solutionHistory, *this);
226 
227  const Thyra::SolveStatus<Scalar> sStatus = this->solveImplicitODE(x);
228 
229  if (!Teuchos::is_null(stepperBDF2Observer_))
230  stepperBDF2Observer_->observeAfterSolve(solutionHistory, *this);
231 
232  if (workingState->getXDot() != Teuchos::null)
233  timeDer->compute(x, xDot);
234 
235  if (sStatus.solveStatus == Thyra::SOLVE_STATUS_CONVERGED)
236  workingState->setSolutionStatus(Status::PASSED);
237  else
238  workingState->setSolutionStatus(Status::FAILED);
239  workingState->setOrder(this->getOrder());
240  stepperObserver_->observeEndTakeStep(solutionHistory, *this);
241  }
242  return;
243 }
244 
245 template<class Scalar>
246 Teuchos::RCP<Thyra::VectorBase<Scalar> >
248 getXDotTemp(Teuchos::RCP<Thyra::VectorBase<Scalar> > x)
249 {
250  if (xDotTemp_ == Teuchos::null) {
251  xDotTemp_ = x->clone_v();
252  Thyra::assign(xDotTemp_.ptr(), Scalar(0.0));
253  }
254  return xDotTemp_;
255 }
256 
257 template<class Scalar>
259  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
260 {
261  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
262  Teuchos::OSTab ostab(out,1,"StepperBDF2::computeStartUp()");
263  *out << "Warning -- Taking a startup step for BDF2 using '"
264  << startUpStepper_->description()<<"'!" << std::endl;
265 
266  //Take one step using startUpStepper_
267  startUpStepper_->takeStep(solutionHistory);
268 
269  order_ = startUpStepper_->getOrder();
270 }
271 
272 /** \brief Provide a StepperState to the SolutionState.
273  * This Stepper does not have any special state data,
274  * so just provide the base class StepperState with the
275  * Stepper description. This can be checked to ensure
276  * that the input StepperState can be used by this Stepper.
277  */
278 template<class Scalar>
279 Teuchos::RCP<Tempus::StepperState<Scalar> >
282 {
283  Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
284  rcp(new StepperState<Scalar>(description()));
285  return stepperState;
286 }
287 
288 
289 template<class Scalar>
291 {
292  std::string name = "BDF2";
293  return(name);
294 }
295 
296 
297 template<class Scalar>
299  Teuchos::FancyOStream &out,
300  const Teuchos::EVerbosityLevel verbLevel) const
301 {
302  out << description() << "::describe:" << std::endl
303  << "wrapperModel_ = " << this->wrapperModel_->description() << std::endl;
304 }
305 
306 
307 template <class Scalar>
309  Teuchos::RCP<Teuchos::ParameterList> const& pList)
310 {
311  Teuchos::RCP<Teuchos::ParameterList> stepperPL = this->stepperPL_;
312  if (pList == Teuchos::null) {
313  // Create default parameters if null, otherwise keep current parameters.
314  if (stepperPL == Teuchos::null) stepperPL = this->getDefaultParameters();
315  } else {
316  stepperPL = pList;
317  }
318  if (!(stepperPL->isParameter("Solver Name"))) {
319  stepperPL->set<std::string>("Solver Name", "Default Solver");
320  Teuchos::RCP<Teuchos::ParameterList> solverPL =
321  this->defaultSolverParameters();
322  stepperPL->set("Default Solver", *solverPL);
323  }
324  // Can not validate because of optional Parameters (e.g., Solver Name).
325  //stepperPL->validateParametersAndSetDefaults(*this->getValidParameters());
326 
327  std::string stepperType = stepperPL->get<std::string>("Stepper Type");
328  TEUCHOS_TEST_FOR_EXCEPTION( stepperType != "BDF2", std::logic_error,
329  "Error - Stepper Type is not 'BDF2'!\n"
330  << " Stepper Type = "<<stepperPL->get<std::string>("Stepper Type")<<"\n");
331 
332  this->stepperPL_ = stepperPL;
333 }
334 
335 
336 template<class Scalar>
337 Teuchos::RCP<const Teuchos::ParameterList>
339 {
340  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
341  pl->setName("Default Stepper - " + this->description());
342  pl->set("Stepper Type", this->description());
343  pl->set("Zero Initial Guess", false);
344  pl->set("Solver Name", "",
345  "Name of ParameterList containing the solver specifications.");
346 
347  return pl;
348 }
349 
350 
351 template<class Scalar>
352 Teuchos::RCP<Teuchos::ParameterList>
354 {
355  using Teuchos::RCP;
356  using Teuchos::ParameterList;
357 
358  RCP<ParameterList> pl = Teuchos::parameterList();
359  pl->setName("Default Stepper - " + this->description());
360  pl->set<std::string>("Stepper Type", this->description());
361  pl->set<bool> ("Zero Initial Guess", false);
362  pl->set<std::string>("Solver Name", "Default Solver");
363 
364  RCP<ParameterList> solverPL = this->defaultSolverParameters();
365  pl->set("Default Solver", *solverPL);
366 
367  return pl;
368 }
369 
370 
371 template <class Scalar>
372 Teuchos::RCP<Teuchos::ParameterList>
374 {
375  return(this->stepperPL_);
376 }
377 
378 
379 template <class Scalar>
380 Teuchos::RCP<Teuchos::ParameterList>
382 {
383  Teuchos::RCP<Teuchos::ParameterList> temp_plist = this->stepperPL_;
384  this->stepperPL_ = Teuchos::null;
385  return(temp_plist);
386 }
387 
388 
389 } // namespace Tempus
390 #endif // Tempus_StepperBDF2_impl_hpp
Tempus::StepperBDF2::describe
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Definition: Tempus_StepperBDF2_impl.hpp:298
Tempus::StepperState
StepperState is a simple class to hold state information about the stepper.
Definition: Tempus_StepperState.hpp:36
Tempus::StepperBDF2::getXDotTemp
virtual Teuchos::RCP< Thyra::VectorBase< Scalar > > getXDotTemp(Teuchos::RCP< Thyra::VectorBase< Scalar > > x)
Provide temporary xDot memory for Stepper if SolutionState doesn't.
Definition: Tempus_StepperBDF2_impl.hpp:248
Tempus::StepperBDF2::getNonconstParameterList
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
Definition: Tempus_StepperBDF2_impl.hpp:373
Tempus::StepperBDF2::takeStep
virtual void takeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Take the specified timestep, dt, and return true if successful.
Definition: Tempus_StepperBDF2_impl.hpp:159
Tempus::solutionHistory
Teuchos::RCP< SolutionHistory< Scalar > > solutionHistory(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
Nonmember constructor.
Definition: Tempus_SolutionHistory_impl.hpp:504
Tempus::StepperBDF2TimeDerivative
Time-derivative interface for BDF2.
Definition: Tempus_StepperBDF2_decl.hpp:146
Tempus::StepperBDF2::getDefaultStepperState
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Get a default (initial) StepperState.
Definition: Tempus_StepperBDF2_impl.hpp:281
Tempus::StepperBDF2::setParameterList
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &pl)
Definition: Tempus_StepperBDF2_impl.hpp:308
Tempus
Definition: Tempus_AdjointAuxSensitivityModelEvaluator_decl.hpp:20
Tempus::StepperBDF2::initialize
virtual void initialize()
Initialize during construction and after changing input parameters.
Definition: Tempus_StepperBDF2_impl.hpp:143
Tempus::StepperBDF2::computeStartUp
virtual void computeStartUp(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Compute the first time step given the supplied startup stepper.
Definition: Tempus_StepperBDF2_impl.hpp:258
Tempus::StepperBDF2::getDefaultParameters
Teuchos::RCP< Teuchos::ParameterList > getDefaultParameters() const
Definition: Tempus_StepperBDF2_impl.hpp:353
Tempus::StepperBDF2::setStartUpStepper
void setStartUpStepper(std::string startupStepperName)
Set the stepper to use in first step.
Definition: Tempus_StepperBDF2_impl.hpp:48
Tempus::StepperBDF2::getValidParameters
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Definition: Tempus_StepperBDF2_impl.hpp:338
Tempus::StepperObserver
StepperObserver class for Stepper class.
Definition: Tempus_StepperObserver.hpp:38
Tempus::StepperBDF2::unsetParameterList
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
Definition: Tempus_StepperBDF2_impl.hpp:381
Tempus::PASSED
Definition: Tempus_Types.hpp:17
Tempus::SolutionHistory
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Definition: Tempus_Integrator.hpp:25
Tempus::StepperFactory
Stepper factory.
Definition: Tempus_StepperBackwardEuler_impl.hpp:22
Tempus::FAILED
Definition: Tempus_Types.hpp:18
Tempus::StepperBDF2::description
virtual std::string description() const
Definition: Tempus_StepperBDF2_impl.hpp:290
Tempus::StepperBDF2::setObserver
virtual void setObserver(Teuchos::RCP< StepperObserver< Scalar > > obs=Teuchos::null)
Set Observer.
Definition: Tempus_StepperBDF2_impl.hpp:122
Tempus::StepperBDF2Observer
StepperBDF2Observer class for StepperBDF2.
Definition: Tempus_StepperBDF2Observer.hpp:35
Tempus_StepperFactory.hpp
Tempus::StepperBDF2::StepperBDF2
StepperBDF2()
Default Constructor – not allowed.