9 #ifndef Tempus_Stepper_impl_hpp
10 #define Tempus_Stepper_impl_hpp
12 #include "NOX_Thyra.H"
16 template <
class Scalar>
22 bool isValidSetup = this->isValidSetup(*out);
25 this->isInitialized_ =
true;
30 template <
class Scalar>
33 if (!this->isInitialized()) {
36 !this->isInitialized(), std::logic_error,
37 "Error - " << this->description() <<
" is not initialized!");
41 template <
class Scalar>
48 *out <<
"Warning -- useFSAL for '" << this->getStepperType() <<
"'\n"
49 <<
"can only be set to true. Leaving set to true." << std::endl;
54 template <
class Scalar>
61 *out <<
"Warning -- useFSAL for '" << this->getStepperType() <<
"'\n"
62 <<
"can only be set to false. Leaving set to false." << std::endl;
67 template <
class Scalar>
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");
78 template <
class Scalar>
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");
89 template <
class Scalar>
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");
97 return stepperXDotDot_;
100 template <
class Scalar>
104 if (state->getXDotDot() != Teuchos::null)
105 stepperXDotDot_ = state->getXDotDot();
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");
114 return stepperXDotDot_;
117 template <
class Scalar>
121 auto l_out = Teuchos::fancyOStream(out.
getOStream());
123 l_out->setOutputToRootOnly(0);
125 *l_out <<
"--- Stepper ---\n"
128 <<
" stepperType_ = " << stepperType_ << std::endl
131 <<
" ICConsistency_ = " << ICConsistency_ << std::endl
134 <<
" stepperX_ = " << stepperX_ << std::endl
135 <<
" stepperXDot_ = " << stepperXDot_ << std::endl
136 <<
" stepperXDotDot_ = " << stepperXDotDot_ << std::endl;
139 template <
class Scalar>
143 bool isValidSetup =
true;
145 if (!(ICConsistency_ ==
"None" || ICConsistency_ ==
"Zero" ||
146 ICConsistency_ ==
"App" || ICConsistency_ ==
"Consistent")) {
147 isValidSetup =
false;
148 auto l_out = Teuchos::fancyOStream(out.
getOStream());
150 *l_out <<
"The IC consistency does not have a valid value!\n"
151 <<
"('None', 'Zero', 'App' or 'Consistent')\n"
152 <<
" ICConsistency = " << ICConsistency_ <<
"\n";
158 template <
class Scalar>
161 if (pl != Teuchos::null) {
162 this->setStepperName(pl->
name());
164 pl->
get<std::string>(
"Stepper Type", this->getStepperType());
166 stepperType != this->getStepperType(), std::runtime_error,
167 " ParameterList 'Stepper Type' (='"
169 <<
"')\n does not match type for this Stepper (='"
170 << this->getStepperType() <<
"').");
171 this->setStepperType(stepperType);
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()));
181 template <
class Scalar>
185 return this->getValidParametersBasic();
188 template <
class Scalar>
192 auto pl = Teuchos::parameterList(this->getStepperName());
193 pl->template set<std::string>(
"Stepper Type", this->getStepperType());
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"
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"
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"
214 "Default in general for explicit and implicit steppers is false,\n"
215 "but individual steppers can override this default.");
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"
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"
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"
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.");
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"
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.");
258 template <
class Scalar>
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);
270 supports ==
false, std::logic_error,
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"
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 "
287 template <
class Scalar>
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);
300 supports ==
false, std::logic_error,
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"
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 "
314 <<
"is null, so we set xdotdot=null and hope the ModelEvaluator can\n"
320 template <
class Scalar>
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);
335 supports ==
false, std::logic_error,
336 model->description() <<
" can not support an implicit ODE with\n"
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"
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)
349 << outArgs.supports(MEB::OUT_ARG_f) <<
"\n"
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");
364 template <
class Scalar>
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);
380 supports ==
false, std::logic_error,
381 model->description() <<
" can not support an implicit ODE with\n"
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"
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)
396 << outArgs.supports(MEB::OUT_ARG_f) <<
"\n"
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");
418 RCP<ParameterList> noxPL = Teuchos::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);
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);
437 noxPL->set<std::string>(
"Nonlinear Solver",
"Line Search Based");
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);
457 RCP<ParameterList> solverOptionsPL = Teuchos::parameterList();
458 solverOptionsPL->set<std::string>(
"Status Test Check Type",
"Minimal");
459 noxPL->set(
"Solver Options", *solverOptionsPL);
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);
477 RCP<ParameterList> solverPL = Teuchos::parameterList(
"Default Solver");
478 solverPL->set(
"NOX", *noxPL);
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