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