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)
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);
172 auto xDot = this->getStepperXDot(initialState);
173 const Thyra::SolveStatus<Scalar> sStatus =
174 this->solveImplicitODE(x, xDot, time, p);
176 TEUCHOS_TEST_FOR_EXCEPTION(
177 sStatus.solveStatus != Thyra::SOLVE_STATUS_CONVERGED, std::logic_error,
178 "Error - Solver failed while determining the initial conditions.\n"
183 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
184 "Error - setInitialConditions(): 'Consistent' for second-order ODE\n"
185 " has not been implemented.\n");
189 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
190 "Error - setInitialConditions() invalid IC consistency, "
191 << icConsistency <<
".\n");
196 initialState->setIsSynced(
true);
199 if (this->getICConsistencyCheck()) {
200 auto f = initialState->getX()->clone_v();
201 auto xDot = this->getStepperXDot(initialState);
203 const Scalar time = initialState->getTime();
204 const Scalar dt = initialState->getTimeStep();
205 RCP<TimeDerivative<Scalar> > timeDer = Teuchos::null;
206 const Scalar alpha = Scalar(0.0);
207 const Scalar beta = Scalar(0.0);
211 this->evaluateImplicitODE(f, x, xDot, time, p);
213 Scalar normX = Thyra::norm(*x);
214 Scalar reldiff = Scalar(0.0);
215 if (normX == Scalar(0.0)) reldiff = Thyra::norm(*f);
216 else reldiff = Thyra::norm(*f)/normX;
218 Scalar eps = Scalar(100.0)*std::abs(Teuchos::ScalarTraits<Scalar>::eps());
220 RCP<Teuchos::FancyOStream> out = this->getOStream();
221 Teuchos::OSTab ostab(out,1,
"StepperImplicit::setInitialConditions()");
222 *out <<
"Warning -- Failed consistency check but continuing!\n"
223 <<
" ||f(x,xDot,t)||/||x|| > eps" << std::endl
224 <<
" ||f(x,xDot,t)|| = " << Thyra::norm(*f) << std::endl
225 <<
" ||x|| = " << Thyra::norm(*x) << std::endl
226 <<
" ||f(x,xDot,t)||/||x|| = " << reldiff << std::endl
227 <<
" eps = " << eps << std::endl;
233 template<
class Scalar>
235 Teuchos::RCP<Thyra::NonlinearSolverBase<Scalar> > solver)
237 if (solver == Teuchos::null) {
238 solver = rcp(
new Thyra::NOXNonlinearSolver());
244 TEUCHOS_TEST_FOR_EXCEPTION(wrapperModel_ == Teuchos::null, std::logic_error,
245 "Error - ModelEvaluator is unset! Should call setModel() first.\n");
247 solver_->setModel(wrapperModel_);
251 template<
class Scalar>
252 Teuchos::RCP<Thyra::VectorBase<Scalar> >
256 if (state->getXDot() != Teuchos::null) stepperXDot_ = state->getXDot();
260 TEUCHOS_TEST_FOR_EXCEPTION( stepperXDot_ == Teuchos::null, std::logic_error,
261 "Error - stepperXDot_ has not been set in setInitialConditions() or\n"
262 " can not be set from the state!\n");
268 template<
class Scalar>
269 Teuchos::RCP<Thyra::VectorBase<Scalar> >
273 if (state->getXDotDot() != Teuchos::null) stepperXDotDot_=state->getXDotDot();
277 TEUCHOS_TEST_FOR_EXCEPTION( stepperXDotDot_ == Teuchos::null,std::logic_error,
278 "Error - stepperXDotDot_ has not been set in setInitialConditions() or\n"
279 " can not be set from the state!\n");
281 return stepperXDotDot_;
285 template<
class Scalar>
286 const Thyra::SolveStatus<Scalar>
288 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & x)
290 if (getZeroInitialGuess())
291 Thyra::assign(x.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
293 const Thyra::SolveStatus<Scalar> sStatus = (*solver_).solve(&*x);
299 template<
class Scalar>
300 const Thyra::SolveStatus<Scalar>
302 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & x,
303 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & xDot,
307 typedef Thyra::ModelEvaluatorBase MEB;
308 MEB::InArgs<Scalar> inArgs = wrapperModel_->getInArgs();
309 MEB::OutArgs<Scalar> outArgs = wrapperModel_->getOutArgs();
311 if (inArgs.supports(MEB::IN_ARG_x_dot )) inArgs.set_x_dot (xDot);
312 if (inArgs.supports(MEB::IN_ARG_t )) inArgs.set_t (time);
313 if (inArgs.supports(MEB::IN_ARG_step_size))
314 inArgs.set_step_size(p->timeStepSize_);
315 if (inArgs.supports(MEB::IN_ARG_alpha )) inArgs.set_alpha (p->alpha_);
316 if (inArgs.supports(MEB::IN_ARG_beta )) inArgs.set_beta (p->beta_);
317 if (inArgs.supports(MEB::IN_ARG_stage_number))
318 inArgs.set_stage_number(p->stageNumber_);
320 wrapperModel_->setForSolve(p->timeDer_, inArgs, outArgs, p->evaluationType_);
322 Thyra::SolveStatus<Scalar> sStatus;
323 typedef Teuchos::ScalarTraits<Scalar> ST;
324 switch (p->evaluationType_)
327 if (getZeroInitialGuess()) Thyra::assign(x.ptr(), ST::zero());
328 sStatus = (*solver_).solve(&*x);
333 sStatus = (*solver_).solve(&*xDot);
337 TEUCHOS_TEST_FOR_EXCEPT(
"Invalid EVALUATION_TYPE!");
345 template<
class Scalar>
348 Teuchos::RCP<Thyra::VectorBase<Scalar> > & f,
349 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & x,
350 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & xDot,
354 typedef Thyra::ModelEvaluatorBase MEB;
355 MEB::InArgs<Scalar> inArgs = wrapperModel_->getInArgs();
357 if (inArgs.supports(MEB::IN_ARG_x_dot )) inArgs.set_x_dot (xDot);
358 if (inArgs.supports(MEB::IN_ARG_t )) inArgs.set_t (time);
359 if (inArgs.supports(MEB::IN_ARG_step_size)) inArgs.set_step_size(p->timeStepSize_);
360 if (inArgs.supports(MEB::IN_ARG_alpha )) inArgs.set_alpha (Scalar(0.0));
361 if (inArgs.supports(MEB::IN_ARG_beta )) inArgs.set_beta (Scalar(0.0));
363 MEB::OutArgs<Scalar> outArgs = wrapperModel_->getOutArgs();
366 wrapperModel_->setForSolve(Teuchos::null,inArgs,outArgs,p->evaluationType_);
368 wrapperModel_->evalModel(inArgs, outArgs);
373 #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)
virtual void setSolver(Teuchos::RCP< Thyra::NonlinearSolverBase< Scalar > > solver=Teuchos::null)
Set solver.
Teuchos::RCP< Teuchos::ParameterList > defaultSolverParameters()
Returns the default solver ParameterList for implicit Steppers.
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 residual, f(x, xDot, t, p).
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.
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.
void validImplicitODE_DAE(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
Validate ME supports implicit ODE/DAE evaluation, f(xdot,x,t) [= 0].
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.