9 #ifndef Tempus_StepperImplicit_impl_hpp
10 #define Tempus_StepperImplicit_impl_hpp
13 #include "NOX_Thyra.H"
19 template<
class Scalar>
21 const Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> >& appModel)
27 TEUCHOS_TEST_FOR_EXCEPTION(solver_ == Teuchos::null, std::logic_error,
28 "Error - Solver is not set!\n");
29 solver_->setModel(wrapperModel_);
31 this->isInitialized_ =
false;
35 template<
class Scalar>
41 int numStates = solutionHistory->getNumStates();
43 TEUCHOS_TEST_FOR_EXCEPTION(numStates < 1, std::logic_error,
44 "Error - setInitialConditions() needs at least one SolutionState\n"
45 " to set the initial condition. Number of States = " << numStates);
47 RCP<SolutionState<Scalar> > initialState = solutionHistory->getCurrentState();
48 RCP<Thyra::VectorBase<Scalar> > x = initialState->getX();
50 auto inArgs = this->wrapperModel_->getNominalValues();
52 RCP<Thyra::VectorBase<Scalar> > xDot = initialState->getXDot();
56 TEUCHOS_TEST_FOR_EXCEPTION(
57 !((x != Teuchos::null && xDot != Teuchos::null) ||
58 (inArgs.get_x() != Teuchos::null &&
59 inArgs.get_x_dot() != Teuchos::null)), std::logic_error,
60 "Error - We need to set the initial conditions for x and xDot from\n"
61 " either initialState or appModel_->getNominalValues::InArgs\n"
62 " (but not from a mixture of the two).\n");
67 if (x == Teuchos::null) {
68 TEUCHOS_TEST_FOR_EXCEPTION( (x == Teuchos::null) &&
69 (inArgs.get_x() == Teuchos::null), std::logic_error,
70 "Error - setInitialConditions needs the ICs from the SolutionHistory\n"
71 " or getNominalValues()!\n");
73 x = Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(inArgs.get_x());
74 initialState->setX(x);
79 using Teuchos::rcp_const_cast;
80 RCP<Thyra::VectorBase<Scalar> > xDot = initialState->getXDot();
81 if ( x == Teuchos::null || xDot == Teuchos::null ) {
82 TEUCHOS_TEST_FOR_EXCEPTION( (inArgs.get_x() == Teuchos::null) ||
83 (inArgs.get_x_dot() == Teuchos::null), std::logic_error,
84 "Error - setInitialConditions() needs the ICs from the initialState\n"
85 " or getNominalValues()!\n");
86 x = rcp_const_cast<Thyra::VectorBase<Scalar> >(inArgs.get_x());
87 initialState->setX(x);
88 xDot = rcp_const_cast<Thyra::VectorBase<Scalar> >(inArgs.get_x_dot());
89 initialState->setXDot(xDot);
95 std::string icConsistency = this->getICConsistency();
96 if (icConsistency ==
"None") {
98 if (initialState->getXDot() == Teuchos::null)
99 Thyra::assign(this->getStepperXDot(initialState).ptr(), Scalar(0.0));
102 if (initialState->getXDotDot() == Teuchos::null)
103 Thyra::assign(this->getStepperXDotDot(initialState).ptr(), Scalar(0.0));
106 else if (icConsistency ==
"Zero") {
108 Thyra::assign(this->getStepperXDot(initialState).ptr(), Scalar(0.0));
110 Thyra::assign(this->getStepperXDotDot(initialState).ptr(), Scalar(0.0));
112 else if (icConsistency ==
"App") {
114 auto xDot = Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(
116 TEUCHOS_TEST_FOR_EXCEPTION(xDot == Teuchos::null, std::logic_error,
117 "Error - setInitialConditions() requested 'App' for IC consistency,\n"
118 " but 'App' returned a null pointer for xDot!\n");
119 Thyra::assign(this->getStepperXDot(initialState).ptr(), *xDot);
122 auto xDotDot = Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(
123 inArgs.get_x_dot_dot());
124 TEUCHOS_TEST_FOR_EXCEPTION(xDotDot == Teuchos::null, std::logic_error,
125 "Error - setInitialConditions() requested 'App' for IC consistency,\n"
126 " but 'App' returned a null pointer for xDotDot!\n");
127 Thyra::assign(this->getStepperXDotDot(initialState).ptr(), *xDotDot);
130 else if (icConsistency ==
"Consistent") {
133 const Scalar time = initialState->getTime();
134 const Scalar dt = initialState->getTimeStep();
135 RCP<TimeDerivative<Scalar> > timeDer = Teuchos::null;
136 const Scalar alpha = Scalar(1.0);
137 const Scalar beta = Scalar(0.0);
141 auto xDot = this->getStepperXDot(initialState);
142 const Thyra::SolveStatus<Scalar> sStatus =
143 this->solveImplicitODE(x, xDot, time, p);
145 TEUCHOS_TEST_FOR_EXCEPTION(
146 sStatus.solveStatus != Thyra::SOLVE_STATUS_CONVERGED, std::logic_error,
147 "Error - Solver failed while determining the initial conditions.\n"
152 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
153 "Error - setInitialConditions(): 'Consistent' for second-order ODE\n"
154 " has not been implemented.\n");
158 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
159 "Error - setInitialConditions() invalid IC consistency, "
160 << icConsistency <<
".\n");
165 initialState->setIsSynced(
true);
168 if (this->getICConsistencyCheck()) {
169 auto f = initialState->getX()->clone_v();
170 auto xDot = this->getStepperXDot(initialState);
172 const Scalar time = initialState->getTime();
173 const Scalar dt = initialState->getTimeStep();
174 RCP<TimeDerivative<Scalar> > timeDer = Teuchos::null;
175 const Scalar alpha = Scalar(0.0);
176 const Scalar beta = Scalar(0.0);
180 this->evaluateImplicitODE(f, x, xDot, time, p);
182 Scalar normX = Thyra::norm(*x);
183 Scalar reldiff = Scalar(0.0);
184 if (normX == Scalar(0.0)) reldiff = Thyra::norm(*f);
185 else reldiff = Thyra::norm(*f)/normX;
187 Scalar eps = Scalar(100.0)*std::abs(Teuchos::ScalarTraits<Scalar>::eps());
189 RCP<Teuchos::FancyOStream> out = this->getOStream();
190 Teuchos::OSTab ostab(out,1,
"StepperImplicit::setInitialConditions()");
191 *out <<
"Info -- Failed consistency check but continuing!\n"
192 <<
" ||f(x,xDot,t)||/||x|| > eps" << std::endl
193 <<
" ||f(x,xDot,t)|| = " << Thyra::norm(*f) << std::endl
194 <<
" ||x|| = " << Thyra::norm(*x) << std::endl
195 <<
" ||f(x,xDot,t)||/||x|| = " << reldiff << std::endl
196 <<
" eps = " << eps << std::endl;
202 template<
class Scalar>
205 solver_ = rcp(
new Thyra::NOXNonlinearSolver());
207 auto subPL = sublist(solverPL,
"NOX");
208 solver_->setParameterList(subPL);
210 if (wrapperModel_ != Teuchos::null) solver_->setModel(wrapperModel_);
212 this->isInitialized_ =
false;
216 template<
class Scalar>
218 Teuchos::RCP<Thyra::NonlinearSolverBase<Scalar> > solver)
220 TEUCHOS_TEST_FOR_EXCEPTION(solver == Teuchos::null, std::logic_error,
221 "Error - Can not set the solver to Teuchos::null.\n");
224 if (wrapperModel_ != Teuchos::null) solver_->setModel(wrapperModel_);
226 this->isInitialized_ =
false;
230 template<
class Scalar>
231 const Thyra::SolveStatus<Scalar>
233 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & x)
235 if (getZeroInitialGuess())
236 Thyra::assign(x.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
238 const Thyra::SolveStatus<Scalar> sStatus = (*solver_).solve(&*x);
244 template<
class Scalar>
245 const Thyra::SolveStatus<Scalar>
247 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & x,
248 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & xDot,
252 typedef Thyra::ModelEvaluatorBase MEB;
253 MEB::InArgs<Scalar> inArgs = wrapperModel_->getInArgs();
254 MEB::OutArgs<Scalar> outArgs = wrapperModel_->getOutArgs();
256 if (inArgs.supports(MEB::IN_ARG_x_dot )) inArgs.set_x_dot (xDot);
257 if (inArgs.supports(MEB::IN_ARG_t )) inArgs.set_t (time);
258 if (inArgs.supports(MEB::IN_ARG_step_size))
259 inArgs.set_step_size(p->timeStepSize_);
260 if (inArgs.supports(MEB::IN_ARG_alpha )) inArgs.set_alpha (p->alpha_);
261 if (inArgs.supports(MEB::IN_ARG_beta )) inArgs.set_beta (p->beta_);
262 if (inArgs.supports(MEB::IN_ARG_stage_number))
263 inArgs.set_stage_number(p->stageNumber_);
265 wrapperModel_->setForSolve(p->timeDer_, inArgs, outArgs, p->evaluationType_);
267 Thyra::SolveStatus<Scalar> sStatus;
268 typedef Teuchos::ScalarTraits<Scalar> ST;
269 switch (p->evaluationType_)
272 if (getZeroInitialGuess()) Thyra::assign(x.ptr(), ST::zero());
273 sStatus = (*solver_).solve(&*x);
278 sStatus = (*solver_).solve(&*xDot);
282 TEUCHOS_TEST_FOR_EXCEPT(
"Invalid EVALUATION_TYPE!");
290 template<
class Scalar>
293 Teuchos::RCP<Thyra::VectorBase<Scalar> > & f,
294 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & x,
295 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & xDot,
299 typedef Thyra::ModelEvaluatorBase MEB;
300 MEB::InArgs<Scalar> inArgs = wrapperModel_->getInArgs();
302 if (inArgs.supports(MEB::IN_ARG_x_dot )) inArgs.set_x_dot (xDot);
303 if (inArgs.supports(MEB::IN_ARG_t )) inArgs.set_t (time);
304 if (inArgs.supports(MEB::IN_ARG_step_size)) inArgs.set_step_size(p->timeStepSize_);
305 if (inArgs.supports(MEB::IN_ARG_alpha )) inArgs.set_alpha (Scalar(0.0));
306 if (inArgs.supports(MEB::IN_ARG_beta )) inArgs.set_beta (Scalar(0.0));
308 MEB::OutArgs<Scalar> outArgs = wrapperModel_->getOutArgs();
311 wrapperModel_->setForSolve(Teuchos::null,inArgs,outArgs,p->evaluationType_);
313 wrapperModel_->evalModel(inArgs, outArgs);
317 template<
class Scalar>
319 const Teuchos::EVerbosityLevel verbLevel)
const
321 out <<
"--- StepperImplicit ---\n";
322 out <<
" wrapperModel_ = " << wrapperModel_ << std::endl;
323 out <<
" solver_ = " << solver_ << std::endl;
324 out <<
" initialGuess_ = " << initialGuess_ << std::endl;
325 out <<
" zeroInitialGuess_ = "
330 template<
class Scalar>
333 bool isValidSetup =
true;
335 if (wrapperModel_->getAppModel() == Teuchos::null) {
336 isValidSetup =
false;
337 out <<
"The application ModelEvaluator is not set!\n";
340 if (wrapperModel_ == Teuchos::null) {
341 isValidSetup =
false;
342 out <<
"The wrapper ModelEvaluator is not set!\n";
345 if (solver_ == Teuchos::null) {
346 isValidSetup =
false;
347 out <<
"The solver is not set!\n";
350 if (solver_ != Teuchos::null) {
351 if (solver_->getModel() == Teuchos::null) {
352 isValidSetup =
false;
353 out <<
"The solver's ModelEvaluator is not set!\n";
362 #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)
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).
virtual void setSolver(Teuchos::RCP< Thyra::NonlinearSolverBase< Scalar > > solver)
Set solver.
Stepper integrates second-order ODEs.
virtual void setDefaultSolver()
virtual bool isValidSetup(Teuchos::FancyOStream &out) const
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.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
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.