9 #ifndef Tempus_StepperBackwardEuler_impl_hpp
10 #define Tempus_StepperBackwardEuler_impl_hpp
12 #include "Tempus_config.hpp"
14 #include "Tempus_WrapperModelEvaluatorBasic.hpp"
15 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
16 #include "NOX_Thyra.H"
26 template<
class Scalar>
28 const Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> >& appModel,
29 Teuchos::RCP<Teuchos::ParameterList> pList)
32 using Teuchos::ParameterList;
35 this->setParameterList(pList);
36 this->setModel(appModel);
46 template<
class Scalar>
50 using Teuchos::ParameterList;
52 RCP<ParameterList> predPL =
53 Teuchos::sublist(this->stepperPL_, predictorName,
true);
54 this->stepperPL_->set(
"Predictor Name", predictorName);
55 if (predictorStepper_ != Teuchos::null) predictorStepper_ = Teuchos::null;
65 template<
class Scalar>
67 Teuchos::RCP<Teuchos::ParameterList> predPL)
70 using Teuchos::ParameterList;
72 Teuchos::RCP<Teuchos::ParameterList> stepperPL = this->stepperPL_;
73 std::string predictorName =
74 stepperPL->get<std::string>(
"Predictor Name",
"None");
75 if (is_null(predPL)) {
76 if (predictorName !=
"None") {
77 RCP<ParameterList> predPL =
78 Teuchos::sublist(stepperPL, predictorName,
true);
79 RCP<StepperFactory<Scalar> > sf =
82 sf->createStepper(this->wrapperModel_->getAppModel(), predPL);
85 TEUCHOS_TEST_FOR_EXCEPTION( predictorName == predPL->name(),
87 "Error - Trying to add a predictor that is already in ParameterList!\n"
88 <<
" Stepper Type = " << stepperPL->get<std::string>(
"Stepper Type")
89 <<
"\n" <<
" Predictor Name = "<<predictorName<<
"\n");
90 predictorName = predPL->name();
91 stepperPL->set(
"Predictor Name", predictorName);
92 stepperPL->set(predictorName, *predPL);
93 if (predictorStepper_ != Teuchos::null) predictorStepper_ = Teuchos::null;
94 RCP<StepperFactory<Scalar> > sf =
97 sf->createStepper(this->wrapperModel_->getAppModel(), predPL);
102 template<
class Scalar>
106 if (obs == Teuchos::null) {
108 if (stepperObserver_ == Teuchos::null) {
115 stepperObserver_ = obs;
123 template<
class Scalar>
126 TEUCHOS_TEST_FOR_EXCEPTION(
127 this->wrapperModel_ == Teuchos::null, std::logic_error,
128 "Error - Need to set the model, setModel(), before calling "
129 "StepperBackwardEuler::initialize()\n");
131 this->setParameterList(this->stepperPL_);
133 this->setPredictor();
138 template<
class Scalar>
144 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::StepperBackwardEuler::takeStep()");
148 "Error - StepperBackwardEuler<Scalar>::takeStep(...)\n"
149 "Need at least two SolutionStates for Backward Euler.\n"
151 "Try setting in \"Solution History\" \"Storage Type\" = \"Undo\"\n"
152 " or \"Storage Type\" = \"Static\" and \"Storage Limit\" = \"2\"\n");
155 RCP<SolutionState<Scalar> > workingState=
solutionHistory->getWorkingState();
156 RCP<SolutionState<Scalar> > currentState=
solutionHistory->getCurrentState();
158 RCP<const Thyra::VectorBase<Scalar> > xOld = currentState->getX();
159 RCP<Thyra::VectorBase<Scalar> > x = workingState->getX();
160 RCP<Thyra::VectorBase<Scalar> > xDot = workingState->getXDot();
161 if (xDot == Teuchos::null) xDot = getXDotTemp(x);
167 const Scalar time = workingState->getTime();
168 const Scalar dt = workingState->getTimeStep();
171 Teuchos::RCP<TimeDerivative<Scalar> > timeDer =
175 typedef Thyra::ModelEvaluatorBase MEB;
176 MEB::InArgs<Scalar> inArgs = this->wrapperModel_->getInArgs();
177 MEB::OutArgs<Scalar> outArgs = this->wrapperModel_->getOutArgs();
179 if (inArgs.supports(MEB::IN_ARG_x_dot )) inArgs.set_x_dot (xDot);
180 if (inArgs.supports(MEB::IN_ARG_t )) inArgs.set_t (time);
181 if (inArgs.supports(MEB::IN_ARG_step_size)) inArgs.set_step_size(dt);
182 if (inArgs.supports(MEB::IN_ARG_alpha )) inArgs.set_alpha (1.0/dt);
183 if (inArgs.supports(MEB::IN_ARG_beta )) inArgs.set_beta (1.0);
185 this->wrapperModel_->setForSolve(timeDer, inArgs, outArgs);
187 if (!Teuchos::is_null(stepperBEObserver_))
190 const Thyra::SolveStatus<Scalar> sStatus = this->solveImplicitODE(x);
192 if (!Teuchos::is_null(stepperBEObserver_))
195 if (workingState->getXDot() != Teuchos::null)
196 timeDer->compute(x, xDot);
198 if (sStatus.solveStatus == Thyra::SOLVE_STATUS_CONVERGED)
202 workingState->setOrder(this->getOrder());
208 template<
class Scalar>
209 Teuchos::RCP<Thyra::VectorBase<Scalar> >
211 getXDotTemp(Teuchos::RCP<
const Thyra::VectorBase<Scalar> > x)
const
213 if (xDotTemp_ == Teuchos::null) {
214 xDotTemp_ = x->clone_v();
215 Thyra::assign(xDotTemp_.ptr(), Scalar(0.0));
220 template<
class Scalar>
224 if (predictorStepper_ == Teuchos::null)
return;
228 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
229 Teuchos::OSTab ostab(out,1,
"StepperBackwardEuler::computePredictor");
230 *out <<
"Warning - predictorStepper has failed." << std::endl;
244 template<
class Scalar>
245 Teuchos::RCP<Tempus::StepperState<Scalar> >
249 Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
255 template<
class Scalar>
258 std::string name =
"Backward Euler";
263 template<
class Scalar>
265 Teuchos::FancyOStream &out,
266 const Teuchos::EVerbosityLevel verbLevel)
const
268 out << description() <<
"::describe:" << std::endl
269 <<
"wrapperModel_ = " << this->wrapperModel_->description() << std::endl;
273 template <
class Scalar>
275 Teuchos::RCP<Teuchos::ParameterList>
const& pList)
277 Teuchos::RCP<Teuchos::ParameterList> stepperPL = this->stepperPL_;
278 if (pList == Teuchos::null) {
280 if (stepperPL == Teuchos::null) stepperPL = this->getDefaultParameters();
284 if (!(stepperPL->isParameter(
"Solver Name"))) {
285 stepperPL->set<std::string>(
"Solver Name",
"Default Solver");
286 Teuchos::RCP<Teuchos::ParameterList> solverPL =
287 this->defaultSolverParameters();
288 stepperPL->set(
"Default Solver", *solverPL);
293 std::string stepperType = stepperPL->get<std::string>(
"Stepper Type");
294 TEUCHOS_TEST_FOR_EXCEPTION( stepperType !=
"Backward Euler",
296 "Error - Stepper Type is not 'Backward Euler'!\n"
297 <<
" Stepper Type = "<<stepperPL->get<std::string>(
"Stepper Type")<<
"\n");
299 this->stepperPL_ = stepperPL;
303 template<
class Scalar>
304 Teuchos::RCP<const Teuchos::ParameterList>
307 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
308 pl->setName(
"Default Stepper - " + this->description());
309 pl->set(
"Stepper Type", this->description());
310 pl->set(
"Zero Initial Guess",
false);
311 pl->set(
"Solver Name",
"",
312 "Name of ParameterList containing the solver specifications.");
318 template<
class Scalar>
319 Teuchos::RCP<Teuchos::ParameterList>
323 using Teuchos::ParameterList;
325 RCP<ParameterList> pl = Teuchos::parameterList();
326 pl->setName(
"Default Stepper - " + this->description());
327 pl->set<std::string>(
"Stepper Type", this->description());
328 pl->set<
bool> (
"Zero Initial Guess",
false);
329 pl->set<std::string>(
"Solver Name",
"Default Solver");
331 RCP<ParameterList> solverPL = this->defaultSolverParameters();
332 pl->set(
"Default Solver", *solverPL);
338 template <
class Scalar>
339 Teuchos::RCP<Teuchos::ParameterList>
342 return(this->stepperPL_);
346 template <
class Scalar>
347 Teuchos::RCP<Teuchos::ParameterList>
350 Teuchos::RCP<Teuchos::ParameterList> temp_plist = this->stepperPL_;
351 this->stepperPL_ = Teuchos::null;
356 template <
class Scalar>
364 template <
class Scalar>
367 Thyra::VectorBase<Scalar>& residual,
368 const Teuchos::Array< Teuchos::RCP<
const Thyra::VectorBase<Scalar> > >& x,
369 const Teuchos::Array<Scalar>& t,
370 const Thyra::VectorBase<Scalar>& p,
371 const int param_index)
const
373 typedef Thyra::ModelEvaluatorBase MEB;
374 MEB::OutArgs<Scalar> outArgs = this->wrapperModel_->getOutArgs();
375 outArgs.set_f(Teuchos::rcpFromRef(residual));
376 computeStepResidDerivImpl(outArgs, x, t, p, param_index);
379 template <
class Scalar>
382 Thyra::LinearOpBase<Scalar>& jacobian,
383 const Teuchos::Array< Teuchos::RCP<
const Thyra::VectorBase<Scalar> > >& x,
384 const Teuchos::Array<Scalar>& t,
385 const Thyra::VectorBase<Scalar>& p,
386 const int param_index,
387 const int deriv_index)
const
389 typedef Thyra::ModelEvaluatorBase MEB;
390 MEB::OutArgs<Scalar> outArgs = this->wrapperModel_->getOutArgs();
391 TEUCHOS_ASSERT(outArgs.supports(MEB::OUT_ARG_W_op));
392 outArgs.set_W_op(Teuchos::rcpFromRef(jacobian));
393 computeStepResidDerivImpl(outArgs, x, t, p, param_index, deriv_index);
396 template <
class Scalar>
399 Thyra::LinearOpBase<Scalar>& deriv,
400 const Teuchos::Array< Teuchos::RCP<
const Thyra::VectorBase<Scalar> > >& x,
401 const Teuchos::Array<Scalar>& t,
402 const Thyra::VectorBase<Scalar>& p,
403 const int param_index)
const
405 typedef Thyra::ModelEvaluatorBase MEB;
406 MEB::OutArgs<Scalar> outArgs = this->wrapperModel_->getOutArgs();
407 TEUCHOS_ASSERT(outArgs.supports(MEB::OUT_ARG_DfDp, param_index).supports(MEB::DERIV_LINEAR_OP));
408 outArgs.set_DfDp(param_index,
409 MEB::Derivative<Scalar>(Teuchos::rcpFromRef(deriv)));
410 computeStepResidDerivImpl(outArgs, x, t, p, param_index);
413 template <
class Scalar>
416 Thyra::LinearOpWithSolveBase<Scalar>& jacobian_solver,
417 const Teuchos::Array< Teuchos::RCP<
const Thyra::VectorBase<Scalar> > >& x,
418 const Teuchos::Array<Scalar>& t,
419 const Thyra::VectorBase<Scalar>& p,
420 const int param_index)
const
422 typedef Thyra::ModelEvaluatorBase MEB;
423 MEB::OutArgs<Scalar> outArgs = this->wrapperModel_->getOutArgs();
424 TEUCHOS_ASSERT(outArgs.supports(MEB::OUT_ARG_W));
425 outArgs.set_W(Teuchos::rcpFromRef(jacobian_solver));
426 computeStepResidDerivImpl(outArgs, x, t, p, param_index, 0);
429 template <
class Scalar>
432 const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs,
433 const Teuchos::Array< Teuchos::RCP<
const Thyra::VectorBase<Scalar> > >& x,
434 const Teuchos::Array<Scalar>& t,
435 const Thyra::VectorBase<Scalar>& p,
436 const int param_index,
437 const int deriv_index)
const
440 typedef Thyra::ModelEvaluatorBase MEB;
442 TEUCHOS_ASSERT(x.size() == 2);
443 TEUCHOS_ASSERT(t.size() == 2);
444 RCP<const Thyra::VectorBase<Scalar> > xn = x[0];
445 RCP<const Thyra::VectorBase<Scalar> > xo = x[1];
446 const Scalar tn = t[0];
447 const Scalar to = t[1];
448 const Scalar dt = tn-to;
451 RCP<Thyra::VectorBase<Scalar> > x_dot = getXDotTemp(xn);
452 Teuchos::RCP<TimeDerivative<Scalar> > timeDer =
454 timeDer->compute(xn, x_dot);
457 MEB::InArgs<Scalar> inArgs = this->wrapperModel_->getInArgs();
459 if (inArgs.supports(MEB::IN_ARG_x_dot )) inArgs.set_x_dot (x_dot);
460 if (inArgs.supports(MEB::IN_ARG_t )) inArgs.set_t (tn);
461 if (inArgs.supports(MEB::IN_ARG_step_size )) inArgs.set_step_size(dt);
462 inArgs.set_p(param_index, Teuchos::rcpFromRef(p));
463 TEUCHOS_ASSERT(inArgs.supports(MEB::IN_ARG_alpha));
464 TEUCHOS_ASSERT(inArgs.supports(MEB::IN_ARG_beta));
465 if (deriv_index == 0) {
467 inArgs.set_alpha(1.0/dt);
468 inArgs.set_beta(1.0);
470 else if (deriv_index == 1) {
472 inArgs.set_alpha(-1.0/dt);
473 inArgs.set_beta(0.0);
475 this->wrapperModel_->getAppModel()->evalModel(inArgs, outArgs);
479 #endif // Tempus_StepperBackwardEuler_impl_hpp