Tempus  Version of the Day
Time Integration
Tempus_Stepper.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_Stepper_hpp
10 #define Tempus_Stepper_hpp
11 
12 //Teuchos
13 #include "Teuchos_VerboseObject.hpp"
14 #include "Teuchos_Describable.hpp"
15 #include "Teuchos_ParameterList.hpp"
16 #include "Teuchos_StandardParameterEntryValidators.hpp"
17 #include "Teuchos_TimeMonitor.hpp"
18 
19 // Thyra
20 #include "Thyra_ModelEvaluator.hpp"
21 #include "Thyra_NonlinearSolverBase.hpp"
22 
23 // Tempus
24 #include "Tempus_config.hpp"
25 #include "Tempus_SolutionHistory.hpp"
27 
28 
29 namespace Tempus {
30 
31 
32 /** \brief Thyra Base interface for time steppers.
33  *
34  * <b>Design Considerations</b>
35  * - Time steppers are designed to take a single time step.
36  * - a single implicit solve for a time step
37  * - a single solve for a IMEX time step
38  * - Multiple time steps should be managed by Integrators.
39  * - Steppers can be built from other Sub-Steppers.
40  * - An operator-split Stepper is possible with interoperable Steppers.
41  * - For explicit steppers, only one ModelEvaluator and one solution
42  * vector are required.
43  * - For implicit steppers, only one ModelEvaluator, one solution
44  * vector, and one solver are required.
45  * - Steppers will PASS/FAIL the time step based on Solver, error and
46  * order requirements, and not adjust the time step size.
47  * - Steppers can provide a suggested time step size for the next time step.
48  * - For more complex steppers, multiple ModelEvaluators, solution
49  * vectors, and solvers are possible when a common single time-integration
50  * method is desired for all solutions. Examples:
51  * - Solution A with ModelEvaluator A and Solution B with ModelEvaluator B
52  * using the same solver
53  * - Solution A with ModelEvaluator A using Solver A and Solution B with
54  * ModelEvaluator B using Solver B
55  * - Solution A with ModelEvaluator A using Solver A and Solutions A and B
56  * with ModelEvaluator C using Solver B
57  * - Steppers may maintain their own time history of the solution, e.g.,
58  * BDF steppers.
59  *
60  * <b> CS Design Considerations</b>
61  * - All input parameters (i.e., ParameterList) can be set by public methods.
62  * - The Stepper ParameterList must be consistent.
63  * - The "set" methods which update parameters in the ParameterList
64  * must update the Stepper ParameterList.
65  */
66 template<class Scalar>
67 class Stepper
68  : virtual public Teuchos::Describable,
69  virtual public Teuchos::VerboseObject<Stepper<Scalar> >,
70  virtual public Teuchos::ParameterListAcceptor
71 {
72 public:
73 
74  /// \name Basic stepper methods
75  //@{
76  virtual void setModel(
77  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel) = 0;
78  virtual void setNonConstModel(
79  const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& appModel) = 0;
80  virtual Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> > getModel() = 0;
81 
82  /// Set solver via ParameterList solver name.
83  virtual void setSolver(std::string solverName) = 0;
84  /// Set solver via solver ParameterList.
85  virtual void setSolver(
86  Teuchos::RCP<Teuchos::ParameterList> solverPL=Teuchos::null) = 0;
87  /// Set solver.
88  virtual void setSolver(
89  Teuchos::RCP<Thyra::NonlinearSolverBase<Scalar> > solver) = 0;
90  /// Get solver
91  virtual Teuchos::RCP<Thyra::NonlinearSolverBase<Scalar> >
92  getSolver() const = 0;
93 
94  /// Set Observer
95  virtual void setObserver(
96  Teuchos::RCP<StepperObserver<Scalar> > obs = Teuchos::null) = 0;
97 
98  /// Initialize during construction and after changing input parameters.
99  virtual void initialize() = 0;
100 
101  /// Take the specified timestep, dt, and return true if successful.
102  virtual void takeStep(
103  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory) = 0;
104 
105  /// Pass initial guess to Newton solver (for implicit schemes)
106  virtual void setInitialGuess(
107  Teuchos::RCP<const Thyra::VectorBase<Scalar> > initial_guess = Teuchos::null) = 0;
108 
109  virtual std::string getStepperType() const = 0;
110 
111  virtual Teuchos::RCP<Tempus::StepperState<Scalar> >
113  virtual Scalar getOrder() const = 0;
114  virtual Scalar getOrderMin() const = 0;
115  virtual Scalar getOrderMax() const = 0;
116  virtual Scalar getInitTimeStep(
117  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory) const = 0;
118  virtual Teuchos::RCP<Teuchos::ParameterList> getDefaultParameters() const=0;
119 
120  virtual bool isExplicit() const = 0;
121  virtual bool isImplicit() const = 0;
122  virtual bool isExplicitImplicit() const = 0;
123 
124  virtual bool isOneStepMethod() const = 0;
125  virtual bool isMultiStepMethod() const = 0;
126  //@}
127 
128  /// \name Functions for Steppers with subSteppers (e.g., OperatorSplit)
129  //@{
130  virtual void createSubSteppers(
131  std::vector<Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> > > models){}
132  //@}
133 
134  /// \name Helper functions
135  //@{
136  /// Validate that the model supports explicit ODE evaluation, f(x,t) [=xdot]
137  /** Currently the convention to evaluate f(x,t) is to set xdot=null!
138  * There is no InArgs support to test if xdot is null, so we set
139  * xdot=null and hopefully the ModelEvaluator can handle it.
140  */
142  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& model) const
143  {
144  TEUCHOS_TEST_FOR_EXCEPT( is_null(model) );
145  typedef Thyra::ModelEvaluatorBase MEB;
146  const MEB::InArgs<Scalar> inArgs = model->createInArgs();
147  const MEB::OutArgs<Scalar> outArgs = model->createOutArgs();
148  const bool supports = inArgs.supports(MEB::IN_ARG_x) and
149  outArgs.supports(MEB::OUT_ARG_f);
150 
151  TEUCHOS_TEST_FOR_EXCEPTION( supports == false, std::logic_error,
152  model->description() << "can not support an explicit ODE with\n"
153  << " IN_ARG_x = " << inArgs.supports(MEB::IN_ARG_x) << "\n"
154  << " OUT_ARG_f = " << outArgs.supports(MEB::OUT_ARG_f) << "\n"
155  << "Explicit ODE requires:\n"
156  << " IN_ARG_x = true\n"
157  << " OUT_ARG_f = true\n"
158  << "\n"
159  << "NOTE: Currently the convention to evaluate f(x,t) is to set\n"
160  << "xdot=null! There is no InArgs support to test if xdot is null,\n"
161  << "so we set xdot=null and hope the ModelEvaluator can handle it.\n");
162 
163  return;
164  }
165 
166  /// Validate that the model supports explicit second order ODE evaluation, f(x,xdot,t) [=xdotdot]
167  /** Currently the convention to evaluate f(x,xdot,t) is to set xdotdot=null!
168  * There is no InArgs support to test if xdotdot is null, so we set
169  * xdotdot=null and hopefully the ModelEvaluator can handle it.
170  */
172  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& model) const
173  {
174  TEUCHOS_TEST_FOR_EXCEPT( is_null(model) );
175  typedef Thyra::ModelEvaluatorBase MEB;
176  const MEB::InArgs<Scalar> inArgs = model->createInArgs();
177  const MEB::OutArgs<Scalar> outArgs = model->createOutArgs();
178  const bool supports = inArgs.supports(MEB::IN_ARG_x) and
179  inArgs.supports(MEB::IN_ARG_x_dot) and
180  outArgs.supports(MEB::OUT_ARG_f);
181 
182  TEUCHOS_TEST_FOR_EXCEPTION( supports == false, std::logic_error,
183  model->description() << "can not support an explicit ODE with\n"
184  << " IN_ARG_x = " << inArgs.supports(MEB::IN_ARG_x) << "\n"
185  << " IN_ARG_x_dot = " << inArgs.supports(MEB::IN_ARG_x_dot) << "\n"
186  << " OUT_ARG_f = " << outArgs.supports(MEB::OUT_ARG_f) << "\n"
187  << "Explicit ODE requires:\n"
188  << " IN_ARG_x = true\n"
189  << " IN_ARG_x_dot = true\n"
190  << " OUT_ARG_f = true\n"
191  << "\n"
192  << "NOTE: Currently the convention to evaluate f(x, xdot, t) is to\n"
193  << "set xdotdot=null! There is no InArgs support to test if xdotdot\n"
194  << "is null, so we set xdotdot=null and hope the ModelEvaluator can\n"
195  << "handle it.\n");
196 
197  return;
198  }
199 
200 
201  /// Validate ME supports implicit ODE/DAE evaluation, f(xdot,x,t) [= 0]
203  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& model) const
204  {
205  TEUCHOS_TEST_FOR_EXCEPT( is_null(model) );
206  typedef Thyra::ModelEvaluatorBase MEB;
207  const MEB::InArgs<Scalar> inArgs = model->createInArgs();
208  const MEB::OutArgs<Scalar> outArgs = model->createOutArgs();
209  const bool supports = inArgs.supports(MEB::IN_ARG_x) and
210  inArgs.supports(MEB::IN_ARG_x_dot) and
211  inArgs.supports(MEB::IN_ARG_alpha) and
212  inArgs.supports(MEB::IN_ARG_beta) and
213  !inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff) and
214  outArgs.supports(MEB::OUT_ARG_f) and
215  outArgs.supports(MEB::OUT_ARG_W);
216 
217  TEUCHOS_TEST_FOR_EXCEPTION( supports == false, std::logic_error,
218  model->description() << " can not support an implicit ODE with\n"
219  << " IN_ARG_x = "
220  << inArgs.supports(MEB::IN_ARG_x) << "\n"
221  << " IN_ARG_x_dot = "
222  << inArgs.supports(MEB::IN_ARG_x_dot) << "\n"
223  << " IN_ARG_alpha = "
224  << inArgs.supports(MEB::IN_ARG_alpha) << "\n"
225  << " IN_ARG_beta = "
226  << inArgs.supports(MEB::IN_ARG_beta) << "\n"
227  << " IN_ARG_W_x_dot_dot_coeff = "
228  << inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff) << "\n"
229  << " OUT_ARG_f = "
230  << outArgs.supports(MEB::OUT_ARG_f) << "\n"
231  << " OUT_ARG_W = "
232  << outArgs.supports(MEB::OUT_ARG_W) << "\n"
233  << "Implicit ODE requires:\n"
234  << " IN_ARG_x = true\n"
235  << " IN_ARG_x_dot = true\n"
236  << " IN_ARG_alpha = true\n"
237  << " IN_ARG_beta = true\n"
238  << " IN_ARG_W_x_dot_dot_coeff = false\n"
239  << " OUT_ARG_f = true\n"
240  << " OUT_ARG_W = true\n");
241 
242  return;
243  }
244 
245  /// Validate ME supports 2nd order implicit ODE/DAE evaluation, f(xdotdot,xdot,x,t) [= 0]
247  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& model) const
248  {
249  TEUCHOS_TEST_FOR_EXCEPT( is_null(model) );
250  typedef Thyra::ModelEvaluatorBase MEB;
251  const MEB::InArgs<Scalar> inArgs = model->createInArgs();
252  const MEB::OutArgs<Scalar> outArgs = model->createOutArgs();
253  const bool supports = inArgs.supports(MEB::IN_ARG_x) and
254  inArgs.supports(MEB::IN_ARG_x_dot) and
255  inArgs.supports(MEB::IN_ARG_x_dot_dot) and
256  inArgs.supports(MEB::IN_ARG_alpha) and
257  inArgs.supports(MEB::IN_ARG_beta) and
258  inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff) and
259  outArgs.supports(MEB::OUT_ARG_f) and
260  outArgs.supports(MEB::OUT_ARG_W);
261 
262  TEUCHOS_TEST_FOR_EXCEPTION( supports == false, std::logic_error,
263  model->description() << " can not support an implicit ODE with\n"
264  << " IN_ARG_x = "
265  << inArgs.supports(MEB::IN_ARG_x) << "\n"
266  << " IN_ARG_x_dot = "
267  << inArgs.supports(MEB::IN_ARG_x_dot) << "\n"
268  << " IN_ARG_x_dot_dot = "
269  << inArgs.supports(MEB::IN_ARG_x_dot_dot) << "\n"
270  << " IN_ARG_alpha = "
271  << inArgs.supports(MEB::IN_ARG_alpha) << "\n"
272  << " IN_ARG_beta = "
273  << inArgs.supports(MEB::IN_ARG_beta) << "\n"
274  << " IN_ARG_W_x_dot_dot_coeff = "
275  << inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff) << "\n"
276  << " OUT_ARG_f = "
277  << outArgs.supports(MEB::OUT_ARG_f) << "\n"
278  << " OUT_ARG_W = "
279  << outArgs.supports(MEB::OUT_ARG_W) << "\n"
280  << "Implicit Second Order ODE requires:\n"
281  << " IN_ARG_x = true\n"
282  << " IN_ARG_x_dot = true\n"
283  << " IN_ARG_x_dot_dot = true\n"
284  << " IN_ARG_alpha = true\n"
285  << " IN_ARG_beta = true\n"
286  << " IN_ARG_W_x_dot_dot_coeff = true\n"
287  << " OUT_ARG_f = true\n"
288  << " OUT_ARG_W = true\n");
289 
290  return;
291  }
292 
293  Teuchos::RCP<Teuchos::ParameterList> defaultSolverParameters() const
294  {
295  using Teuchos::RCP;
296  using Teuchos::ParameterList;
297 
298  // NOX Solver ParameterList
299  RCP<ParameterList> noxPL = Teuchos::parameterList();
300 
301  // Direction ParameterList
302  RCP<ParameterList> directionPL = Teuchos::parameterList();
303  directionPL->set<std::string>("Method", "Newton");
304  RCP<ParameterList> newtonPL = Teuchos::parameterList();
305  newtonPL->set<std::string>("Forcing Term Method", "Constant");
306  newtonPL->set<bool> ("Rescue Bad Newton Solve", 1);
307  directionPL->set("Newton", *newtonPL);
308  noxPL->set("Direction", *directionPL);
309 
310  // Line Search ParameterList
311  RCP<ParameterList> lineSearchPL = Teuchos::parameterList();
312  lineSearchPL->set<std::string>("Method", "Full Step");
313  RCP<ParameterList> fullStepPL = Teuchos::parameterList();
314  fullStepPL->set<double>("Full Step", 1);
315  lineSearchPL->set("Full Step", *fullStepPL);
316  noxPL->set("Line Search", *lineSearchPL);
317 
318  noxPL->set<std::string>("Nonlinear Solver", "Line Search Based");
319 
320  // Printing ParameterList
321  RCP<ParameterList> printingPL = Teuchos::parameterList();
322  printingPL->set<int>("Output Precision", 3);
323  printingPL->set<int>("Output Processor", 0);
324  RCP<ParameterList> outputPL = Teuchos::parameterList();
325  outputPL->set<bool>("Error", 1);
326  outputPL->set<bool>("Warning", 1);
327  outputPL->set<bool>("Outer Iteration", 0);
328  outputPL->set<bool>("Parameters", 0);
329  outputPL->set<bool>("Details", 0);
330  outputPL->set<bool>("Linear Solver Details", 1);
331  outputPL->set<bool>("Stepper Iteration", 1);
332  outputPL->set<bool>("Stepper Details", 1);
333  outputPL->set<bool>("Stepper Parameters", 1);
334  printingPL->set("Output Information", *outputPL);
335  noxPL->set("Printing", *printingPL);
336 
337  // Solver Options ParameterList
338  RCP<ParameterList> solverOptionsPL = Teuchos::parameterList();
339  solverOptionsPL->set<std::string>("Status Test Check Type", "Minimal");
340  noxPL->set("Solver Options", *solverOptionsPL);
341 
342  // Status Tests ParameterList
343  RCP<ParameterList> statusTestsPL = Teuchos::parameterList();
344  statusTestsPL->set<std::string>("Test Type", "Combo");
345  statusTestsPL->set<std::string>("Combo Type", "OR");
346  statusTestsPL->set<int>("Number of Tests", 2);
347  RCP<ParameterList> test0PL = Teuchos::parameterList();
348  test0PL->set<std::string>("Test Type", "NormF");
349  test0PL->set<double>("Tolerance", 1e-08);
350  statusTestsPL->set("Test 0", *test0PL);
351  RCP<ParameterList> test1PL = Teuchos::parameterList();
352  test1PL->set<std::string>("Test Type", "MaxIters");
353  test1PL->set<int>("Maximum Iterations", 10);
354  statusTestsPL->set("Test 1", *test1PL);
355  noxPL->set("Status Tests", *statusTestsPL);
356 
357  // Solver ParameterList
358  RCP<ParameterList> solverPL = Teuchos::parameterList();
359  solverPL->set("NOX", *noxPL);
360 
361  return solverPL;
362  }
363  //@}
364 
365 };
366 } // namespace Tempus
367 #endif // Tempus_Stepper_hpp
Tempus::Stepper::setObserver
virtual void setObserver(Teuchos::RCP< StepperObserver< Scalar > > obs=Teuchos::null)=0
Set Observer.
Tempus::Stepper::takeStep
virtual void takeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)=0
Take the specified timestep, dt, and return true if successful.
Tempus::Stepper::getModel
virtual Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > getModel()=0
Tempus::solutionHistory
Teuchos::RCP< SolutionHistory< Scalar > > solutionHistory(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
Nonmember constructor.
Definition: Tempus_SolutionHistory_impl.hpp:504
Tempus::Stepper::getOrder
virtual Scalar getOrder() const =0
Tempus::Stepper::getStepperType
virtual std::string getStepperType() const =0
Tempus_StepperObserver.hpp
Tempus
Definition: Tempus_AdjointAuxSensitivityModelEvaluator_decl.hpp:20
Tempus::Stepper::getOrderMin
virtual Scalar getOrderMin() const =0
Tempus::Stepper::setModel
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel)=0
Tempus::Stepper::defaultSolverParameters
Teuchos::RCP< Teuchos::ParameterList > defaultSolverParameters() const
Definition: Tempus_Stepper.hpp:293
Tempus::Stepper::validSecondOrderODE_DAE
void validSecondOrderODE_DAE(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model) const
Validate ME supports 2nd order implicit ODE/DAE evaluation, f(xdotdot,xdot,x,t) [= 0].
Definition: Tempus_Stepper.hpp:246
Tempus::Stepper::validExplicitODE
void validExplicitODE(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model) const
Validate that the model supports explicit ODE evaluation, f(x,t) [=xdot].
Definition: Tempus_Stepper.hpp:141
Tempus::Stepper::isExplicit
virtual bool isExplicit() const =0
Tempus::Stepper::initialize
virtual void initialize()=0
Initialize during construction and after changing input parameters.
Tempus::Stepper::isOneStepMethod
virtual bool isOneStepMethod() const =0
Tempus::Stepper::setInitialGuess
virtual void setInitialGuess(Teuchos::RCP< const Thyra::VectorBase< Scalar > > initial_guess=Teuchos::null)=0
Pass initial guess to Newton solver (for implicit schemes)
Tempus::Stepper::setSolver
virtual void setSolver(std::string solverName)=0
Set solver via ParameterList solver name.
Tempus::Stepper::getInitTimeStep
virtual Scalar getInitTimeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory) const =0
Tempus::Stepper::setNonConstModel
virtual void setNonConstModel(const Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > &appModel)=0
Tempus::Stepper::isMultiStepMethod
virtual bool isMultiStepMethod() const =0
Tempus::Stepper::getDefaultStepperState
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()=0
Tempus::Stepper::validImplicitODE_DAE
void validImplicitODE_DAE(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model) const
Validate ME supports implicit ODE/DAE evaluation, f(xdot,x,t) [= 0].
Definition: Tempus_Stepper.hpp:202
Tempus::Stepper::getSolver
virtual Teuchos::RCP< Thyra::NonlinearSolverBase< Scalar > > getSolver() const =0
Get solver.
Tempus::Stepper::isExplicitImplicit
virtual bool isExplicitImplicit() const =0
Tempus::Stepper::getDefaultParameters
virtual Teuchos::RCP< Teuchos::ParameterList > getDefaultParameters() const =0
Tempus::Stepper::validSecondOrderExplicitODE
void validSecondOrderExplicitODE(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model) const
Validate that the model supports explicit second order ODE evaluation, f(x,xdot,t) [=xdotdot].
Definition: Tempus_Stepper.hpp:171
Tempus::Stepper::createSubSteppers
virtual void createSubSteppers(std::vector< Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > > models)
Definition: Tempus_Stepper.hpp:130
Tempus::Stepper::getOrderMax
virtual Scalar getOrderMax() const =0
Tempus::Stepper::isImplicit
virtual bool isImplicit() const =0