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  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
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.
const std::string toString(const Status status)
Convert Status to string.
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel)
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel)
Teuchos::RCP< Teuchos::ParameterList > defaultSolverParameters()
Returns the default solver ParameterList for implicit Steppers.
virtual void initialize()
Initialize after construction and changing input parameters.
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.
Thyra Base interface for implicit time steppers.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
StepperObserver class for Stepper class.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
virtual bool isValidSetup(Teuchos::FancyOStream &out) const
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
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.
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.