Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros 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_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 }
36 
37 
38 template<class Scalar>
40  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
41  const Teuchos::RCP<StepperObserver<Scalar> >& obs,
42  const Teuchos::RCP<Thyra::NonlinearSolverBase<Scalar> >& solver,
43  const Teuchos::RCP<Stepper<Scalar> >& startUpStepper,
44  bool useFSAL,
45  std::string ICConsistency,
46  bool ICConsistencyCheck,
47  bool zeroInitialGuess)
48 
49 {
50  this->setStepperType( "BDF2");
51  this->setUseFSAL( useFSAL);
52  this->setICConsistency( ICConsistency);
53  this->setICConsistencyCheck( ICConsistencyCheck);
54  this->setZeroInitialGuess( zeroInitialGuess);
55 
56  this->setObserver(obs);
57 
58  if (appModel != Teuchos::null) {
59 
60  this->setModel(appModel);
61  this->setSolver(solver);
62  this->setStartUpStepper(startUpStepper);
63  this->initialize();
64  }
65 }
66 
67 
68 /// Set the startup stepper to a default stepper.
69 template<class Scalar>
70 void StepperBDF2<Scalar>::setStartUpStepper(std::string startupStepperType)
71 {
72  TEUCHOS_TEST_FOR_EXCEPTION(
73  this->wrapperModel_->getAppModel() == Teuchos::null, std::logic_error,
74  "Error - Need to set the model, setModel(), before calling "
75  "StepperBDF2::setStartUpStepper()\n");
76 
77  using Teuchos::RCP;
78  RCP<StepperFactory<Scalar> > sf = Teuchos::rcp(new StepperFactory<Scalar>());
79  startUpStepper_ =
80  sf->createStepper(startupStepperType, this->wrapperModel_->getAppModel());
81 }
82 
83 
84 /// Set the start up stepper.
85 template<class Scalar>
87  Teuchos::RCP<Stepper<Scalar> > startUpStepper)
88 {
89  TEUCHOS_TEST_FOR_EXCEPTION(
90  this->wrapperModel_->getAppModel() == Teuchos::null, std::logic_error,
91  "Error - Need to set the model, setModel(), before calling "
92  "StepperBDF2::setStartUpStepper()\n");
93 
94  startUpStepper_ = startUpStepper;
95  startUpStepper_->setModel(this->wrapperModel_->getAppModel());
96  startUpStepper_->initialize();
97 }
98 
99 
100 template<class Scalar>
102  Teuchos::RCP<StepperObserver<Scalar> > obs)
103 {
104 
105  if (this->stepperObserver_ == Teuchos::null)
106  this->stepperObserver_ =
107  Teuchos::rcp(new StepperObserverComposite<Scalar>());
108 
109  if (( obs == Teuchos::null ) and (this->stepperObserver_->getSize() == 0) )
110  obs = Teuchos::rcp(new StepperBDF2Observer<Scalar>());
111 
112  this->stepperObserver_->addObserver(
113  Teuchos::rcp_dynamic_cast<StepperObserver<Scalar> > (obs, true) );
114 
115 }
116 
117 
118 template<class Scalar>
120 {
121  TEUCHOS_TEST_FOR_EXCEPTION( this->wrapperModel_ == Teuchos::null,
122  std::logic_error,
123  "Error - Need to set the model, setModel(), before calling "
124  "StepperBDF2::initialize()\n");
125 
126  this->setObserver();
127  order_ = Scalar(2.0);
128 }
129 
130 
131 template<class Scalar>
133  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
134 {
135  using Teuchos::RCP;
136 
137  RCP<SolutionState<Scalar> > initialState = solutionHistory->getCurrentState();
138 
139  // Check if we need Stepper storage for xDot
140  if (initialState->getXDot() == Teuchos::null)
141  this->setStepperXDot(initialState->getX()->clone_v());
142 
144 
145  if (this->getUseFSAL()) {
146  RCP<Teuchos::FancyOStream> out = this->getOStream();
147  Teuchos::OSTab ostab(out,1,"StepperBDF2::setInitialConditions()");
148  *out << "\nWarning -- The First-Step-As-Last (FSAL) principle is not "
149  << "needed with Backward Euler. The default is to set useFSAL=false, "
150  << "however useFSAL=true will also work but have no affect "
151  << "(i.e., no-op).\n" << std::endl;
152  }
153 }
154 
155 
156 template<class Scalar>
158  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
159 {
160  using Teuchos::RCP;
161 
162  TEMPUS_FUNC_TIME_MONITOR("Tempus::StepperBDF2::takeStep()");
163  {
164  int numStates = solutionHistory->getNumStates();
165 
166  RCP<Thyra::VectorBase<Scalar> > xOld;
167  RCP<Thyra::VectorBase<Scalar> > xOldOld;
168 
169  // If there are less than 3 states (e.g., first time step), call
170  // startup stepper and return.
171  if (numStates < 3) {
172  computeStartUp(solutionHistory);
173  return;
174  }
175  TEUCHOS_TEST_FOR_EXCEPTION( (numStates < 3), std::logic_error,
176  "Error in Tempus::StepperBDF2::takeStep(): numStates after \n"
177  << "startup stepper must be at least 3, whereas numStates = "
178  << numStates <<"!\n" << "If running with Storage Type = Static, "
179  << "make sure Storage Limit > 2.\n");
180 
181  //IKT, FIXME: add error checking regarding states being consecutive and
182  //whether interpolated states are OK to use.
183 
184  //this->stepperObserver_->observeBeginTakeStep(solutionHistory, *this);
185 
186  RCP<SolutionState<Scalar> > workingState=solutionHistory->getWorkingState();
187  RCP<SolutionState<Scalar> > currentState=solutionHistory->getCurrentState();
188 
189  RCP<Thyra::VectorBase<Scalar> > x = workingState->getX();
190  RCP<Thyra::VectorBase<Scalar> > xDot = this->getStepperXDot(workingState);
191 
192  //get time, dt and dtOld
193  const Scalar time = workingState->getTime();
194  const Scalar dt = workingState->getTimeStep();
195  const Scalar dtOld = currentState->getTimeStep();
196 
197  xOld = solutionHistory->getStateTimeIndexNM1()->getX();
198  xOldOld = solutionHistory->getStateTimeIndexNM2()->getX();
199  order_ = Scalar(2.0);
200 
201  // Setup TimeDerivative
202  Teuchos::RCP<TimeDerivative<Scalar> > timeDer =
203  Teuchos::rcp(new StepperBDF2TimeDerivative<Scalar>(dt, dtOld, xOld, xOldOld));
204 
205  const Scalar alpha = getAlpha(dt, dtOld);
206  const Scalar beta = getBeta (dt);
207 
208  auto p = Teuchos::rcp(new ImplicitODEParameters<Scalar>(
209  timeDer, dt, alpha, beta));
210 
211  if (!Teuchos::is_null(stepperBDF2Observer_))
212  stepperBDF2Observer_->observeBeforeSolve(solutionHistory, *this);
213 
214  const Thyra::SolveStatus<Scalar> sStatus =
215  this->solveImplicitODE(x, xDot, time, p);
216 
217  if (!Teuchos::is_null(stepperBDF2Observer_))
218  stepperBDF2Observer_->observeAfterSolve(solutionHistory, *this);
219 
220  if (workingState->getXDot() != Teuchos::null)
221  timeDer->compute(x, xDot);
222 
223  workingState->setSolutionStatus(sStatus); // Converged --> pass.
224  workingState->setOrder(getOrder());
225  //this->stepperObserver_->observeEndTakeStep(solutionHistory, *this);
226  }
227  return;
228 }
229 
230 template<class Scalar>
232  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
233 {
234  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
235  Teuchos::OSTab ostab(out,1,"StepperBDF2::computeStartUp()");
236  *out << "Warning -- Taking a startup step for BDF2 using '"
237  << startUpStepper_->getStepperType()<<"'!" << std::endl;
238 
239  //Take one step using startUpStepper_
240  startUpStepper_->takeStep(solutionHistory);
241 
242  order_ = startUpStepper_->getOrder();
243 }
244 
245 /** \brief Provide a StepperState to the SolutionState.
246  * This Stepper does not have any special state data,
247  * so just provide the base class StepperState with the
248  * Stepper description. This can be checked to ensure
249  * that the input StepperState can be used by this Stepper.
250  */
251 template<class Scalar>
252 Teuchos::RCP<Tempus::StepperState<Scalar> >
255 {
256  Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
257  rcp(new StepperState<Scalar>(this->getStepperType()));
258  return stepperState;
259 }
260 
261 
262 template<class Scalar>
264  Teuchos::FancyOStream &out,
265  const Teuchos::EVerbosityLevel /* verbLevel */) const
266 {
267  out << this->getStepperType() << "::describe:" << std::endl
268  << "wrapperModel_ = " << this->wrapperModel_->description() << std::endl;
269 }
270 
271 
272 template<class Scalar>
273 Teuchos::RCP<const Teuchos::ParameterList>
275 {
276  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
277  getValidParametersBasic(pl, this->getStepperType());
278  pl->set<bool>("Initial Condition Consistency Check",
279  this->getICConsistencyCheckDefault());
280  pl->set<std::string>("Solver Name", "Default Solver");
281  pl->set<bool>("Zero Initial Guess", false);
282  pl->set<std::string>("Start Up Stepper Type", "DIRK 1 Stage Theta Method");
283  Teuchos::RCP<Teuchos::ParameterList> solverPL = defaultSolverParameters();
284  pl->set("Default Solver", *solverPL);
285 
286  return pl;
287 }
288 
289 
290 } // namespace Tempus
291 #endif // Tempus_StepperBDF2_impl_hpp
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions and make them consistent.
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 setObserver(Teuchos::RCP< StepperObserver< Scalar > > obs=Teuchos::null)
Set Observer.
void setStartUpStepper(std::string startupStepperType="DIRK 1 Stage Theta Method")
Set the stepper to use in first step.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Teuchos::RCP< Teuchos::ParameterList > defaultSolverParameters()
Returns the default solver ParameterList for implicit Steppers.
virtual void computeStartUp(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Compute the first time step given the supplied startup stepper.
Thyra Base interface for time steppers.
This observer is a composite observer,.
StepperState is a simple class to hold state information about the stepper.
StepperObserver class for Stepper class.
Teuchos::RCP< SolutionHistory< Scalar > > solutionHistory(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
Nonmember constructor.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
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 getValidParametersBasic(Teuchos::RCP< Teuchos::ParameterList > pl, std::string stepperType)
Provide basic parameters to Steppers.
virtual void initialize()
Initialize during construction and after changing input parameters.
StepperBDF2()
Default constructor.
StepperBDF2Observer class for StepperBDF2.