Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Tempus_Stepper_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_Stepper_impl_hpp
10 #define Tempus_Stepper_impl_hpp
11 
12 #include "NOX_Thyra.H"
13 
14 namespace Tempus {
15 
16 template <class Scalar>
18 {
19  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
20  out->setOutputToRootOnly(0);
21 
22  bool isValidSetup = this->isValidSetup(*out);
23 
24  if (isValidSetup)
25  this->isInitialized_ = true; // Only place it is set to true.
26  else
27  this->describe(*out, Teuchos::VERB_MEDIUM);
28 }
29 
30 template <class Scalar>
32 {
33  if (!this->isInitialized()) {
34  this->describe(*(this->getOStream()), Teuchos::VERB_MEDIUM);
36  !this->isInitialized(), std::logic_error,
37  "Error - " << this->description() << " is not initialized!");
38  }
39 }
40 
41 template <class Scalar>
43 {
44  if (a == false) {
45  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
46  out->setOutputToRootOnly(0);
47  Teuchos::OSTab ostab(out, 1, "Stepper::setUseFSALTrueOnly()");
48  *out << "Warning -- useFSAL for '" << this->getStepperType() << "'\n"
49  << "can only be set to true. Leaving set to true." << std::endl;
50  }
51  useFSAL_ = true;
52 }
53 
54 template <class Scalar>
56 {
57  if (a == true) {
58  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
59  out->setOutputToRootOnly(0);
60  Teuchos::OSTab ostab(out, 1, "Stepper::setUseFSALFalseOnly()");
61  *out << "Warning -- useFSAL for '" << this->getStepperType() << "'\n"
62  << "can only be set to false. Leaving set to false." << std::endl;
63  }
64  useFSAL_ = false;
65 }
66 
67 template <class Scalar>
69 {
71  stepperX_ == Teuchos::null, std::logic_error,
72  "Error - stepperX_ has not been set in setInitialConditions() or\n"
73  " can not be set from the state!\n");
74 
75  return stepperX_;
76 }
77 
78 template <class Scalar>
80 {
82  stepperXDot_ == Teuchos::null, std::logic_error,
83  "Error - stepperXDot_ has not been set in setInitialConditions() or\n"
84  " can not be set from the state!\n");
85 
86  return stepperXDot_;
87 }
88 
89 template <class Scalar>
91 {
93  stepperXDotDot_ == Teuchos::null, std::logic_error,
94  "Error - stepperXDotDot_ has not been set in setInitialConditions() or\n"
95  " can not be set from the state!\n");
96 
97  return stepperXDotDot_;
98 }
99 
100 template <class Scalar>
103 {
104  if (state->getXDotDot() != Teuchos::null)
105  stepperXDotDot_ = state->getXDotDot();
106  // Else use temporary storage stepperXDotDot_ which should have been set in
107  // setInitialConditions().
108 
110  stepperXDotDot_ == Teuchos::null, std::logic_error,
111  "Error - stepperXDotDot_ has not been set in setInitialConditions() or\n"
112  " can not be set from the state!\n");
113 
114  return stepperXDotDot_;
115 }
116 
117 template <class Scalar>
119  const Teuchos::EVerbosityLevel verbLevel) const
120 {
121  auto l_out = Teuchos::fancyOStream(out.getOStream());
122  Teuchos::OSTab ostab(*l_out, 2, this->description());
123  l_out->setOutputToRootOnly(0);
124 
125  *l_out << "--- Stepper ---\n"
126  << " isInitialized_ = " << Teuchos::toString(isInitialized_)
127  << std::endl
128  << " stepperType_ = " << stepperType_ << std::endl
129  << " useFSAL_ = " << Teuchos::toString(useFSAL_)
130  << std::endl
131  << " ICConsistency_ = " << ICConsistency_ << std::endl
132  << " ICConsistencyCheck_ = " << Teuchos::toString(ICConsistencyCheck_)
133  << std::endl
134  << " stepperX_ = " << stepperX_ << std::endl
135  << " stepperXDot_ = " << stepperXDot_ << std::endl
136  << " stepperXDotDot_ = " << stepperXDotDot_ << std::endl;
137 }
138 
139 template <class Scalar>
141 {
142  out.setOutputToRootOnly(0);
143  bool isValidSetup = true;
144 
145  if (!(ICConsistency_ == "None" || ICConsistency_ == "Zero" ||
146  ICConsistency_ == "App" || ICConsistency_ == "Consistent")) {
147  isValidSetup = false;
148  auto l_out = Teuchos::fancyOStream(out.getOStream());
149  l_out->setOutputToRootOnly(0);
150  *l_out << "The IC consistency does not have a valid value!\n"
151  << "('None', 'Zero', 'App' or 'Consistent')\n"
152  << " ICConsistency = " << ICConsistency_ << "\n";
153  }
154 
155  return isValidSetup;
156 }
157 
158 template <class Scalar>
160 {
161  if (pl != Teuchos::null) {
162  this->setStepperName(pl->name());
163  auto stepperType =
164  pl->get<std::string>("Stepper Type", this->getStepperType());
166  stepperType != this->getStepperType(), std::runtime_error,
167  " ParameterList 'Stepper Type' (='"
168  << stepperType
169  << "')\n does not match type for this Stepper (='"
170  << this->getStepperType() << "').");
171  this->setStepperType(stepperType);
172 
173  this->setUseFSAL(pl->get<bool>("Use FSAL", this->getUseFSAL()));
174  this->setICConsistency(pl->get<std::string>("Initial Condition Consistency",
175  this->getICConsistency()));
176  this->setICConsistencyCheck(pl->get<bool>(
177  "Initial Condition Consistency Check", this->getICConsistencyCheck()));
178  }
179 }
180 
181 template <class Scalar>
183  const
184 {
185  return this->getValidParametersBasic();
186 }
187 
188 template <class Scalar>
190  const
191 {
192  auto pl = Teuchos::parameterList(this->getStepperName());
193  pl->template set<std::string>("Stepper Type", this->getStepperType());
194 
195  pl->template set<bool>(
196  "Use FSAL", this->getUseFSAL(),
197  "The First-Same-As-Last (FSAL) principle is the situation where the\n"
198  "last function evaluation, f(x^{n-1},t^{n-1}) [a.k.a. xDot^{n-1}],\n"
199  "can be used for the first function evaluation, f(x^n,t^n)\n"
200  "[a.k.a. xDot^n]. For RK methods, this applies to the stages.\n"
201  "\n"
202  "Often the FSAL priniciple can be used to save an evaluation.\n"
203  "However there are cases when it cannot be used, e.g., operator\n"
204  "splitting where other steppers/operators have modified the solution,\n"
205  "x^*, and thus require the function evaluation, f(x^*, t^{n-1}).\n"
206  "\n"
207  "It should be noted that when the FSAL priniciple can be used\n"
208  "(can set useFSAL=true), setting useFSAL=false will give the\n"
209  "same solution but at additional expense. However, the reverse\n"
210  "is not true. When the FSAL priniciple can not be used\n"
211  "(need to set useFSAL=false), setting useFSAL=true will produce\n"
212  "incorrect solutions.\n"
213  "\n"
214  "Default in general for explicit and implicit steppers is false,\n"
215  "but individual steppers can override this default.");
216 
217  pl->template set<std::string>(
218  "Initial Condition Consistency", this->getICConsistency(),
219  "This indicates which type of consistency should be applied to\n"
220  "the initial conditions (ICs):\n"
221  "\n"
222  " 'None' - Do nothing to the ICs provided in the SolutionHistory.\n"
223  " 'Zero' - Set the derivative of the SolutionState to zero in the\n"
224  " SolutionHistory provided, e.g., xDot^0 = 0, or \n"
225  " xDotDot^0 = 0.\n"
226  " 'App' - Use the application's ICs, e.g., getNominalValues().\n"
227  " 'Consistent' - Make the initial conditions for x and xDot\n"
228  " consistent with the governing equations, e.g.,\n"
229  " xDot = f(x,t), and f(x, xDot, t) = 0. For implicit\n"
230  " ODEs, this requires a solve of f(x, xDot, t) = 0 for\n"
231  " xDot, and another Jacobian and residual may be\n"
232  " needed, e.g., boundary conditions on xDot may need\n"
233  " to replace boundary conditions on x.\n"
234  "\n"
235  "In general for explicit steppers, the default is 'Consistent',\n"
236  "because it is fairly cheap with just one residual evaluation.\n"
237  "In general for implicit steppers, the default is 'None', because\n"
238  "the application often knows its IC and can set it the initial\n"
239  "SolutionState. Also, as noted above, 'Consistent' may require\n"
240  "another Jacobian from the application. Individual steppers may\n"
241  "override these defaults.");
242 
243  pl->template set<bool>(
244  "Initial Condition Consistency Check", this->getICConsistencyCheck(),
245  "Check if the initial condition, x and xDot, is consistent with the\n"
246  "governing equations, xDot = f(x,t), or f(x, xDot, t) = 0.\n"
247  "\n"
248  "In general for explicit and implicit steppers, the default is true,\n"
249  "because it is fairly cheap with just one residual evaluation.\n"
250  "Individual steppers may override this default.");
251 
252  return pl;
253 }
254 
255 // Nonmember Helper Functions.
256 // ------------------------------------------------------------------------
257 
258 template <class Scalar>
260  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& model)
261 {
263  typedef Thyra::ModelEvaluatorBase MEB;
264  const MEB::InArgs<Scalar> inArgs = model->createInArgs();
265  const MEB::OutArgs<Scalar> outArgs = model->createOutArgs();
266  const bool supports =
267  inArgs.supports(MEB::IN_ARG_x) && outArgs.supports(MEB::OUT_ARG_f);
268 
270  supports == false, std::logic_error,
271  model->description()
272  << " can not support an explicit ODE with\n"
273  << " IN_ARG_x = " << inArgs.supports(MEB::IN_ARG_x) << "\n"
274  << " OUT_ARG_f = " << outArgs.supports(MEB::OUT_ARG_f) << "\n"
275  << "Explicit ODE requires:\n"
276  << " IN_ARG_x = true\n"
277  << " OUT_ARG_f = true\n"
278  << "\n"
279  << "NOTE: Currently the convention to evaluate f(x,t) is to set\n"
280  << "xdot=null! There is no InArgs support to test if xdot is null,\n"
281  << "so we set xdot=null and hope the ModelEvaluator can handle "
282  "it.\n");
283 
284  return;
285 }
286 
287 template <class Scalar>
289  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& model)
290 {
292  typedef Thyra::ModelEvaluatorBase MEB;
293  const MEB::InArgs<Scalar> inArgs = model->createInArgs();
294  const MEB::OutArgs<Scalar> outArgs = model->createOutArgs();
295  const bool supports = inArgs.supports(MEB::IN_ARG_x) &&
296  inArgs.supports(MEB::IN_ARG_x_dot) &&
297  outArgs.supports(MEB::OUT_ARG_f);
298 
300  supports == false, std::logic_error,
301  model->description()
302  << "can not support an explicit ODE with\n"
303  << " IN_ARG_x = " << inArgs.supports(MEB::IN_ARG_x) << "\n"
304  << " IN_ARG_x_dot = " << inArgs.supports(MEB::IN_ARG_x_dot) << "\n"
305  << " OUT_ARG_f = " << outArgs.supports(MEB::OUT_ARG_f) << "\n"
306  << "Explicit ODE requires:\n"
307  << " IN_ARG_x = true\n"
308  << " IN_ARG_x_dot = true\n"
309  << " OUT_ARG_f = true\n"
310  << "\n"
311  << "NOTE: Currently the convention to evaluate f(x, xdot, t) is to\n"
312  << "set xdotdot=null! There is no InArgs support to test if "
313  "xdotdot\n"
314  << "is null, so we set xdotdot=null and hope the ModelEvaluator can\n"
315  << "handle it.\n");
316 
317  return;
318 }
319 
320 template <class Scalar>
322  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& model)
323 {
325  typedef Thyra::ModelEvaluatorBase MEB;
326  const MEB::InArgs<Scalar> inArgs = model->createInArgs();
327  const MEB::OutArgs<Scalar> outArgs = model->createOutArgs();
328  const bool supports =
329  inArgs.supports(MEB::IN_ARG_x) && inArgs.supports(MEB::IN_ARG_x_dot) &&
330  inArgs.supports(MEB::IN_ARG_alpha) && inArgs.supports(MEB::IN_ARG_beta) &&
331  !inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff) &&
332  outArgs.supports(MEB::OUT_ARG_f) && outArgs.supports(MEB::OUT_ARG_W);
333 
335  supports == false, std::logic_error,
336  model->description() << " can not support an implicit ODE with\n"
337  << " IN_ARG_x = "
338  << inArgs.supports(MEB::IN_ARG_x) << "\n"
339  << " IN_ARG_x_dot = "
340  << inArgs.supports(MEB::IN_ARG_x_dot) << "\n"
341  << " IN_ARG_alpha = "
342  << inArgs.supports(MEB::IN_ARG_alpha) << "\n"
343  << " IN_ARG_beta = "
344  << inArgs.supports(MEB::IN_ARG_beta) << "\n"
345  << " IN_ARG_W_x_dot_dot_coeff = "
346  << inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff)
347  << "\n"
348  << " OUT_ARG_f = "
349  << outArgs.supports(MEB::OUT_ARG_f) << "\n"
350  << " OUT_ARG_W = "
351  << outArgs.supports(MEB::OUT_ARG_W) << "\n"
352  << "Implicit ODE requires:\n"
353  << " IN_ARG_x = true\n"
354  << " IN_ARG_x_dot = true\n"
355  << " IN_ARG_alpha = true\n"
356  << " IN_ARG_beta = true\n"
357  << " IN_ARG_W_x_dot_dot_coeff = false\n"
358  << " OUT_ARG_f = true\n"
359  << " OUT_ARG_W = true\n");
360 
361  return;
362 }
363 
364 template <class Scalar>
366  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& model)
367 {
369  typedef Thyra::ModelEvaluatorBase MEB;
370  const MEB::InArgs<Scalar> inArgs = model->createInArgs();
371  const MEB::OutArgs<Scalar> outArgs = model->createOutArgs();
372  const bool supports =
373  inArgs.supports(MEB::IN_ARG_x) && inArgs.supports(MEB::IN_ARG_x_dot) &&
374  inArgs.supports(MEB::IN_ARG_x_dot_dot) &&
375  inArgs.supports(MEB::IN_ARG_alpha) && inArgs.supports(MEB::IN_ARG_beta) &&
376  inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff) &&
377  outArgs.supports(MEB::OUT_ARG_f) && outArgs.supports(MEB::OUT_ARG_W);
378 
380  supports == false, std::logic_error,
381  model->description() << " can not support an implicit ODE with\n"
382  << " IN_ARG_x = "
383  << inArgs.supports(MEB::IN_ARG_x) << "\n"
384  << " IN_ARG_x_dot = "
385  << inArgs.supports(MEB::IN_ARG_x_dot) << "\n"
386  << " IN_ARG_x_dot_dot = "
387  << inArgs.supports(MEB::IN_ARG_x_dot_dot) << "\n"
388  << " IN_ARG_alpha = "
389  << inArgs.supports(MEB::IN_ARG_alpha) << "\n"
390  << " IN_ARG_beta = "
391  << inArgs.supports(MEB::IN_ARG_beta) << "\n"
392  << " IN_ARG_W_x_dot_dot_coeff = "
393  << inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff)
394  << "\n"
395  << " OUT_ARG_f = "
396  << outArgs.supports(MEB::OUT_ARG_f) << "\n"
397  << " OUT_ARG_W = "
398  << outArgs.supports(MEB::OUT_ARG_W) << "\n"
399  << "Implicit Second Order ODE requires:\n"
400  << " IN_ARG_x = true\n"
401  << " IN_ARG_x_dot = true\n"
402  << " IN_ARG_x_dot_dot = true\n"
403  << " IN_ARG_alpha = true\n"
404  << " IN_ARG_beta = true\n"
405  << " IN_ARG_W_x_dot_dot_coeff = true\n"
406  << " OUT_ARG_f = true\n"
407  << " OUT_ARG_W = true\n");
408 
409  return;
410 }
411 
413 {
415  using Teuchos::RCP;
416 
417  // NOX Solver ParameterList
418  RCP<ParameterList> noxPL = Teuchos::parameterList();
419 
420  // Direction ParameterList
421  RCP<ParameterList> directionPL = Teuchos::parameterList();
422  directionPL->set<std::string>("Method", "Newton");
423  RCP<ParameterList> newtonPL = Teuchos::parameterList();
424  newtonPL->set<std::string>("Forcing Term Method", "Constant");
425  newtonPL->set<bool>("Rescue Bad Newton Solve", 1);
426  directionPL->set("Newton", *newtonPL);
427  noxPL->set("Direction", *directionPL);
428 
429  // Line Search ParameterList
430  RCP<ParameterList> lineSearchPL = Teuchos::parameterList();
431  lineSearchPL->set<std::string>("Method", "Full Step");
432  RCP<ParameterList> fullStepPL = Teuchos::parameterList();
433  fullStepPL->set<double>("Full Step", 1);
434  lineSearchPL->set("Full Step", *fullStepPL);
435  noxPL->set("Line Search", *lineSearchPL);
436 
437  noxPL->set<std::string>("Nonlinear Solver", "Line Search Based");
438 
439  // Printing ParameterList
440  RCP<ParameterList> printingPL = Teuchos::parameterList();
441  printingPL->set<int>("Output Precision", 3);
442  printingPL->set<int>("Output Processor", 0);
443  RCP<ParameterList> outputPL = Teuchos::parameterList();
444  outputPL->set<bool>("Error", 1);
445  outputPL->set<bool>("Warning", 1);
446  outputPL->set<bool>("Outer Iteration", 0);
447  outputPL->set<bool>("Parameters", 0);
448  outputPL->set<bool>("Details", 0);
449  outputPL->set<bool>("Linear Solver Details", 1);
450  outputPL->set<bool>("Stepper Iteration", 1);
451  outputPL->set<bool>("Stepper Details", 1);
452  outputPL->set<bool>("Stepper Parameters", 1);
453  printingPL->set("Output Information", *outputPL);
454  noxPL->set("Printing", *printingPL);
455 
456  // Solver Options ParameterList
457  RCP<ParameterList> solverOptionsPL = Teuchos::parameterList();
458  solverOptionsPL->set<std::string>("Status Test Check Type", "Minimal");
459  noxPL->set("Solver Options", *solverOptionsPL);
460 
461  // Status Tests ParameterList
462  RCP<ParameterList> statusTestsPL = Teuchos::parameterList();
463  statusTestsPL->set<std::string>("Test Type", "Combo");
464  statusTestsPL->set<std::string>("Combo Type", "OR");
465  statusTestsPL->set<int>("Number of Tests", 2);
466  RCP<ParameterList> test0PL = Teuchos::parameterList();
467  test0PL->set<std::string>("Test Type", "NormF");
468  test0PL->set<double>("Tolerance", 1e-08);
469  statusTestsPL->set("Test 0", *test0PL);
470  RCP<ParameterList> test1PL = Teuchos::parameterList();
471  test1PL->set<std::string>("Test Type", "MaxIters");
472  test1PL->set<int>("Maximum Iterations", 10);
473  statusTestsPL->set("Test 1", *test1PL);
474  noxPL->set("Status Tests", *statusTestsPL);
475 
476  // Solver ParameterList
477  RCP<ParameterList> solverPL = Teuchos::parameterList("Default Solver");
478  solverPL->set("NOX", *noxPL);
479 
480  return solverPL;
481 }
482 
483 } // namespace Tempus
484 #endif // Tempus_Stepper_impl_hpp
const std::string & name() const
virtual bool isValidSetup(Teuchos::FancyOStream &out) const
bool is_null(const boost::shared_ptr< T > &p)
T & get(const std::string &name, T def_value)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Teuchos::RCP< Teuchos::ParameterList > defaultSolverParameters()
Returns the default solver ParameterList for implicit Steppers.
void validExplicitODE(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
Validate that the model supports explicit ODE evaluation, f(x,t) [=xdot].
virtual void initialize()
Initialize after construction and changing input parameters.
Teuchos::RCP< Teuchos::ParameterList > getValidParametersBasic() const
Add basic parameters to Steppers ParameterList.
void setUseFSALFalseOnly(bool a)
virtual void checkInitialized()
Check initialization, and error out on failure.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
void setUseFSALTrueOnly(bool a)
virtual Teuchos::RCP< Thyra::VectorBase< Scalar > > getStepperX()
Get Stepper x.
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
void setStepperValues(const Teuchos::RCP< Teuchos::ParameterList > pl)
Set Stepper member data from ParameterList.
void validSecondOrderExplicitODE(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
void validSecondOrderODE_DAE(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
RCP< std::basic_ostream< char_type, traits_type > > getOStream()
virtual Teuchos::RCP< Thyra::VectorBase< Scalar > > getStepperXDotDot()
Get Stepper xDotDot.
void validImplicitODE_DAE(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
Validate ME supports implicit ODE/DAE evaluation, f(xdot,x,t) [= 0].
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
Solution state for integrators and steppers.
std::string toString(const T &t)
virtual Teuchos::RCP< Thyra::VectorBase< Scalar > > getStepperXDot()
Get Stepper xDot.
virtual Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const