9 #ifndef Tempus_StepperImplicit_impl_hpp
10 #define Tempus_StepperImplicit_impl_hpp
19 #include "NOX_Thyra.H"
25 template<
class Scalar>
27 const Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> >& appModel)
29 this->validImplicitODE_DAE(appModel);
35 template<
class Scalar>
37 const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& appModel)
39 this->setModel(appModel);
43 template<
class Scalar>
51 TEUCHOS_TEST_FOR_EXCEPTION(numStates < 1, std::logic_error,
52 "Error - setInitialConditions() needs at least one SolutionState\n"
53 " to set the initial condition. Number of States = " << numStates);
56 RCP<Teuchos::FancyOStream> out = this->getOStream();
57 Teuchos::OSTab ostab(out,1,
"StepperImplicit::setInitialConditions()");
58 *out <<
"Warning -- SolutionHistory has more than one state!\n"
59 <<
"Setting the initial conditions on the currentState.\n"<<std::endl;
62 RCP<SolutionState<Scalar> > initialState =
solutionHistory->getCurrentState();
63 RCP<Thyra::VectorBase<Scalar> > x = initialState->getX();
65 auto inArgs = this->wrapperModel_->getNominalValues();
67 RCP<Thyra::VectorBase<Scalar> > xDot = initialState->getXDot();
71 TEUCHOS_TEST_FOR_EXCEPTION(
72 !((x != Teuchos::null && xDot != Teuchos::null) ||
73 (inArgs.get_x() != Teuchos::null &&
74 inArgs.get_x_dot() != Teuchos::null)), std::logic_error,
75 "Error - We need to set the initial conditions for x and xDot from\n"
76 " either initialState or appModel_->getNominalValues::InArgs\n"
77 " (but not from a mixture of the two).\n");
82 if (x == Teuchos::null) {
83 TEUCHOS_TEST_FOR_EXCEPTION( (x == Teuchos::null) &&
84 (inArgs.get_x() == Teuchos::null), std::logic_error,
85 "Error - setInitialConditions needs the ICs from the SolutionHistory\n"
86 " or getNominalValues()!\n");
88 x = Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(inArgs.get_x());
89 initialState->setX(x);
94 using Teuchos::rcp_const_cast;
95 RCP<Thyra::VectorBase<Scalar> > xDot = initialState->getXDot();
96 if ( x == Teuchos::null || xDot == Teuchos::null ) {
97 TEUCHOS_TEST_FOR_EXCEPTION( (inArgs.get_x() == Teuchos::null) ||
98 (inArgs.get_x_dot() == Teuchos::null), std::logic_error,
99 "Error - setInitialConditions() needs the ICs from the initialState\n"
100 " or getNominalValues()!\n");
101 x = rcp_const_cast<Thyra::VectorBase<Scalar> >(inArgs.get_x());
102 initialState->setX(x);
103 xDot = rcp_const_cast<Thyra::VectorBase<Scalar> >(inArgs.get_x_dot());
104 initialState->setXDot(xDot);
110 std::string icConsistency = this->getICConsistency();
111 if (icConsistency ==
"None") {
113 if (initialState->getXDot() == Teuchos::null) {
114 RCP<Teuchos::FancyOStream> out = this->getOStream();
115 Teuchos::OSTab ostab(out,1,
116 "StepperImplicit::setInitialConditions()");
117 *out <<
"Warning -- Requested IC consistency of 'None' but\n"
118 <<
" initialState does not have an xDot.\n"
119 <<
" Setting a 'Zero' xDot!\n" << std::endl;
121 Thyra::assign(this->getStepperXDot(initialState).ptr(), Scalar(0.0));
125 if (initialState->getXDotDot() == Teuchos::null) {
126 RCP<Teuchos::FancyOStream> out = this->getOStream();
127 Teuchos::OSTab ostab(out,1,
128 "StepperImplicit::setInitialConditions()");
129 *out <<
"Warning -- Requested IC consistency of 'None' but\n"
130 <<
" initialState does not have an xDotDot.\n"
131 <<
" Setting a 'Zero' xDotDot!\n" << std::endl;
133 Thyra::assign(this->getStepperXDotDot(initialState).ptr(), Scalar(0.0));
137 else if (icConsistency ==
"Zero") {
139 Thyra::assign(this->getStepperXDot(initialState).ptr(), Scalar(0.0));
141 Thyra::assign(this->getStepperXDotDot(initialState).ptr(), Scalar(0.0));
143 else if (icConsistency ==
"App") {
145 auto xDot = Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(
147 TEUCHOS_TEST_FOR_EXCEPTION(xDot == Teuchos::null, std::logic_error,
148 "Error - setInitialConditions() requested 'App' for IC consistency,\n"
149 " but 'App' returned a null pointer for xDot!\n");
150 Thyra::assign(this->getStepperXDot(initialState).ptr(), *xDot);
153 auto xDotDot = Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(
154 inArgs.get_x_dot_dot());
155 TEUCHOS_TEST_FOR_EXCEPTION(xDotDot == Teuchos::null, std::logic_error,
156 "Error - setInitialConditions() requested 'App' for IC consistency,\n"
157 " but 'App' returned a null pointer for xDotDot!\n");
158 Thyra::assign(getStepperXDotDot(initialState).ptr(), *xDotDot);
161 else if (icConsistency ==
"Consistent") {
164 const Scalar time = initialState->getTime();
165 const Scalar dt = initialState->getTimeStep();
166 RCP<TimeDerivative<Scalar> > timeDer = Teuchos::null;
167 const Scalar alpha = Scalar(1.0);
168 const Scalar beta = Scalar(0.0);
169 RCP<ImplicitODEParameters<Scalar> > p =
173 auto xDot = this->getStepperXDot(initialState);
174 const Thyra::SolveStatus<Scalar> sStatus =
175 this->solveImplicitODE(x, xDot, time, p);
177 TEUCHOS_TEST_FOR_EXCEPTION(
178 sStatus.solveStatus != Thyra::SOLVE_STATUS_CONVERGED, std::logic_error,
179 "Error - Solver failed while determining the initial conditions.\n"
184 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
185 "Error - setInitialConditions(): 'Consistent' for second-order ODE\n"
186 " has not been implemented.\n");
190 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
191 "Error - setInitialConditions() invalid IC consistency, "
192 << icConsistency <<
".\n");
197 initialState->setIsSynced(
true);
200 if (this->getICConsistencyCheck()) {
201 auto f = initialState->getX()->clone_v();
202 auto xDot = this->getStepperXDot(initialState);
204 const Scalar time = initialState->getTime();
205 const Scalar dt = initialState->getTimeStep();
206 RCP<TimeDerivative<Scalar> > timeDer = Teuchos::null;
207 const Scalar alpha = Scalar(0.0);
208 const Scalar beta = Scalar(0.0);
209 RCP<ImplicitODEParameters<Scalar> > p =
213 this->evaluateImplicitODE(f, x, xDot, time, p);
215 Scalar normX = Thyra::norm(*x);
216 Scalar reldiff = Scalar(0.0);
217 if (normX == Scalar(0.0)) reldiff = Thyra::norm(*f);
218 else reldiff = Thyra::norm(*f)/normX;
220 Scalar eps = Scalar(100.0)*std::abs(Teuchos::ScalarTraits<Scalar>::eps());
222 RCP<Teuchos::FancyOStream> out = this->getOStream();
223 Teuchos::OSTab ostab(out,1,
"StepperImplicit::setInitialConditions()");
224 *out <<
"Warning -- Failed consistency check but continuing!\n"
225 <<
" ||f(x,xDot,t)||/||x|| > eps" << std::endl
226 <<
" ||f(x,xDot,t)|| = " << Thyra::norm(*f) << std::endl
227 <<
" ||x|| = " << Thyra::norm(*x) << std::endl
228 <<
" ||f(x,xDot,t)||/||x|| = " << reldiff << std::endl
229 <<
" eps = " << eps << std::endl;
241 template<
class Scalar>
244 Teuchos::RCP<Teuchos::ParameterList> solverPL =
245 Teuchos::sublist(stepperPL_, solverName,
true);
246 this->setSolver(solverPL);
256 template<
class Scalar>
258 Teuchos::RCP<Teuchos::ParameterList> solverPL)
261 using Teuchos::ParameterList;
263 std::string solverName = stepperPL_->get<std::string>(
"Solver Name");
264 if (is_null(solverPL)) {
265 if ( stepperPL_->isSublist(solverName) )
266 solverPL = Teuchos::sublist(stepperPL_, solverName,
true);
268 solverPL = this->defaultSolverParameters();
271 solverName = solverPL->name();
272 stepperPL_->set(
"Solver Name", solverName);
273 stepperPL_->set(solverName, *solverPL);
274 RCP<ParameterList> noxPL = Teuchos::sublist(solverPL,
"NOX",
true);
276 solver_ = rcp(
new Thyra::NOXNonlinearSolver());
277 solver_->setParameterList(noxPL);
279 TEUCHOS_TEST_FOR_EXCEPTION(wrapperModel_ == Teuchos::null, std::logic_error,
280 "Error - StepperImplicit<Scalar>::setSolver() wrapperModel_ is unset!\n"
281 <<
" Should call setModel(...) first.\n");
282 solver_->setModel(wrapperModel_);
291 template<
class Scalar>
293 Teuchos::RCP<Thyra::NonlinearSolverBase<Scalar> > solver)
295 Teuchos::RCP<Teuchos::ParameterList> solverPL =
296 solver->getNonconstParameterList();
297 this->setSolver(solverPL);
300 template<
class Scalar>
301 Teuchos::RCP<Thyra::VectorBase<Scalar> >
305 if (state->getXDot() != Teuchos::null) stepperXDot_ = state->getXDot();
309 TEUCHOS_TEST_FOR_EXCEPTION( stepperXDot_ == Teuchos::null, std::logic_error,
310 "Error - stepperXDot_ has not been set in setInitialConditions() or\n"
311 " can not be set from the state!\n");
317 template<
class Scalar>
318 Teuchos::RCP<Thyra::VectorBase<Scalar> >
322 if (state->getXDotDot() != Teuchos::null) stepperXDotDot_=state->getXDotDot();
326 TEUCHOS_TEST_FOR_EXCEPTION( stepperXDotDot_ == Teuchos::null,std::logic_error,
327 "Error - stepperXDotDot_ has not been set in setInitialConditions() or\n"
328 " can not be set from the state!\n");
330 return stepperXDotDot_;
334 template<
class Scalar>
335 const Thyra::SolveStatus<Scalar>
337 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & x)
339 if (getZeroInitialGuess())
340 Thyra::assign(x.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
342 const Thyra::SolveStatus<Scalar> sStatus = (*solver_).solve(&*x);
348 template<
class Scalar>
349 const Thyra::SolveStatus<Scalar>
351 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & x,
352 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & xDot,
356 typedef Thyra::ModelEvaluatorBase MEB;
357 MEB::InArgs<Scalar> inArgs = wrapperModel_->getInArgs();
358 MEB::OutArgs<Scalar> outArgs = wrapperModel_->getOutArgs();
360 if (inArgs.supports(MEB::IN_ARG_x_dot )) inArgs.set_x_dot (xDot);
361 if (inArgs.supports(MEB::IN_ARG_t )) inArgs.set_t (time);
362 if (inArgs.supports(MEB::IN_ARG_step_size))
363 inArgs.set_step_size(p->timeStepSize_);
364 if (inArgs.supports(MEB::IN_ARG_alpha )) inArgs.set_alpha (p->alpha_);
365 if (inArgs.supports(MEB::IN_ARG_beta )) inArgs.set_beta (p->beta_);
366 if (inArgs.supports(MEB::IN_ARG_stage_number))
367 inArgs.set_stage_number(p->stageNumber_);
369 wrapperModel_->setForSolve(p->timeDer_, inArgs, outArgs, p->evaluationType_);
371 Thyra::SolveStatus<Scalar> sStatus;
372 typedef Teuchos::ScalarTraits<Scalar> ST;
373 switch (p->evaluationType_)
376 if (getZeroInitialGuess()) Thyra::assign(x.ptr(), ST::zero());
377 sStatus = (*solver_).solve(&*x);
382 sStatus = (*solver_).solve(&*xDot);
386 TEUCHOS_TEST_FOR_EXCEPT(
"Invalid EVALUATION_TYPE!");
394 template<
class Scalar>
397 Teuchos::RCP<Thyra::VectorBase<Scalar> > & f,
398 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & x,
399 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & xDot,
403 typedef Thyra::ModelEvaluatorBase MEB;
404 MEB::InArgs<Scalar> inArgs = wrapperModel_->getInArgs();
406 if (inArgs.supports(MEB::IN_ARG_x_dot )) inArgs.set_x_dot (xDot);
407 if (inArgs.supports(MEB::IN_ARG_t )) inArgs.set_t (time);
408 if (inArgs.supports(MEB::IN_ARG_step_size)) inArgs.set_step_size(p->timeStepSize_);
409 if (inArgs.supports(MEB::IN_ARG_alpha )) inArgs.set_alpha (Scalar(0.0));
410 if (inArgs.supports(MEB::IN_ARG_beta )) inArgs.set_beta (Scalar(0.0));
412 MEB::OutArgs<Scalar> outArgs = wrapperModel_->getOutArgs();
415 wrapperModel_->setForSolve(Teuchos::null,inArgs,outArgs,p->evaluationType_);
417 wrapperModel_->evalModel(inArgs, outArgs);
422 #endif // Tempus_StepperImplicit_impl_hpp
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions and make them consistent.
const Thyra::SolveStatus< Scalar > solveImplicitODE(const Teuchos::RCP< Thyra::VectorBase< Scalar > > &x)
Solve problem using x in-place. (Needs to be deprecated!)
Evaluate residual for the implicit ODE.
const std::string toString(const Status status)
Convert Status to string.
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel)
void evaluateImplicitODE(Teuchos::RCP< Thyra::VectorBase< Scalar > > &f, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &x, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &xDot, const Scalar time, const Teuchos::RCP< ImplicitODEParameters< Scalar > > &p)
Evaluate implicit ODE, f(x, xDot, t, p), residual.
Stepper integrates second-order ODEs.
virtual void setNonConstModel(const Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > &appModel)
virtual Teuchos::RCP< Thyra::VectorBase< Scalar > > getStepperXDot(Teuchos::RCP< SolutionState< Scalar > > state)
Get xDot from SolutionState or Stepper storage.
virtual void setSolver(std::string solverName)
Set solver via ParameterList solver name.
Teuchos::RCP< SolutionHistory< Scalar > > solutionHistory(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
Nonmember constructor.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Solve for xDot keeping x constant (for ICs).
Stepper integrates first-order ODEs.
A ModelEvaluator for residual evaluations given a state. This ModelEvaluator takes a state...
Solve for x and determine xDot from x.
Solution state for integrators and steppers. SolutionState contains the metadata for solutions and th...
virtual Teuchos::RCP< Thyra::VectorBase< Scalar > > getStepperXDotDot(Teuchos::RCP< SolutionState< Scalar > > state)
Get xDotDot from SolutionState or Stepper storage.