9 #ifndef Tempus_Stepper_impl_hpp
10 #define Tempus_Stepper_impl_hpp
12 #include "NOX_Thyra.H"
18 template<
class Scalar>
24 bool isValidSetup = this->isValidSetup(*out);
27 this->isInitialized_ =
true;
33 template<
class Scalar>
36 if ( !this->isInitialized() ) {
39 "Error - " << this->description() <<
" is not initialized!");
44 template<
class Scalar>
51 *out <<
"Warning -- useFSAL for '" << this->getStepperType() <<
"'\n"
52 <<
"can only be set to true. Leaving set to true." << std::endl;
58 template<
class Scalar>
65 *out <<
"Warning -- useFSAL for '" << this->getStepperType() <<
"'\n"
66 <<
"can only be set to false. Leaving set to false." << std::endl;
72 template<
class Scalar>
77 "Error - stepperX_ has not been set in setInitialConditions() or\n"
78 " can not be set from the state!\n");
83 template<
class Scalar>
88 "Error - stepperXDot_ has not been set in setInitialConditions() or\n"
89 " can not be set from the state!\n");
94 template<
class Scalar>
99 "Error - stepperXDotDot_ has not been set in setInitialConditions() or\n"
100 " can not be set from the state!\n");
102 return stepperXDotDot_;
106 template<
class Scalar>
110 if (state->getXDotDot() != Teuchos::null) stepperXDotDot_=state->getXDotDot();
115 "Error - stepperXDotDot_ has not been set in setInitialConditions() or\n"
116 " can not be set from the state!\n");
118 return stepperXDotDot_;
122 template<
class Scalar>
126 auto out = Teuchos::fancyOStream( in_out.
getOStream() );
127 out->setOutputToRootOnly(0);
128 *out <<
"--- Stepper ---\n"
130 <<
" stepperType_ = " << stepperType_ << 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;
140 template<
class Scalar>
144 bool isValidSetup =
true;
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";
160 template<
class Scalar>
164 if (pl != Teuchos::null) {
165 this->setStepperName(pl->
name());
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);
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()));
186 template<
class Scalar>
190 return this->getValidParametersBasic();
194 template<
class Scalar>
198 auto pl = Teuchos::parameterList(this->getStepperName());
199 pl->template set<std::string>(
"Stepper Type", this->getStepperType());
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"
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"
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"
219 "Default in general for explicit and implicit steppers is false,\n"
220 "but individual steppers can override this default.");
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"
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"
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"
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.");
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"
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.");
262 template<
class Scalar>
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);
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"
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");
289 template<
class Scalar>
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);
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"
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"
320 template<
class Scalar>
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);
337 model->description() <<
" can not support an implicit ODE with\n"
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"
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"
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");
365 template<
class Scalar>
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);
383 model->description() <<
" can not support an implicit ODE with\n"
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"
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"
397 << outArgs.supports(MEB::OUT_ARG_f) <<
"\n"
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");
420 RCP<ParameterList> noxPL = Teuchos::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);
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);
439 noxPL->set<std::string>(
"Nonlinear Solver",
"Line Search Based");
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);
459 RCP<ParameterList> solverOptionsPL = Teuchos::parameterList();
460 solverOptionsPL->set<std::string>(
"Status Test Check Type",
"Minimal");
461 noxPL->set(
"Solver Options", *solverOptionsPL);
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);
479 RCP<ParameterList> solverPL = Teuchos::parameterList(
"Default Solver");
480 solverPL->set(
"NOX", *noxPL);
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