9 #ifndef Tempus_StepperImplicit_impl_hpp 10 #define Tempus_StepperImplicit_impl_hpp 13 #include "NOX_Thyra.H" 19 template<
class Scalar>
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();
49 RCP<Thyra::VectorBase<Scalar> > xDot = initialState->getXDot();
50 if (xDot() == Teuchos::null) xDot = this->getStepperXDot();
53 auto inArgs = this->wrapperModel_->getNominalValues();
55 RCP<Thyra::VectorBase<Scalar> > initialXDot = initialState->getXDot();
58 TEUCHOS_TEST_FOR_EXCEPTION(
59 !((x != Teuchos::null && initialXDot != Teuchos::null) ||
60 (inArgs.get_x() != Teuchos::null &&
61 inArgs.get_x_dot() != Teuchos::null)), std::logic_error,
62 "Error - We need to set the initial conditions for x and xDot from\n" 63 " either initialState or appModel_->getNominalValues::InArgs\n" 64 " (but not from a mixture of the two).\n");
69 if (x == Teuchos::null) {
70 TEUCHOS_TEST_FOR_EXCEPTION( (x == Teuchos::null) &&
71 (inArgs.get_x() == Teuchos::null), std::logic_error,
72 "Error - setInitialConditions needs the ICs from the SolutionHistory\n" 73 " or getNominalValues()!\n");
76 initialState->setX(x);
81 using Teuchos::rcp_const_cast;
82 if ( x == Teuchos::null || xDot == Teuchos::null ) {
83 TEUCHOS_TEST_FOR_EXCEPTION( (inArgs.get_x() == Teuchos::null) ||
84 (inArgs.get_x_dot() == Teuchos::null), std::logic_error,
85 "Error - setInitialConditions() needs the ICs from the initialState\n" 86 " or getNominalValues()!\n");
88 initialState->setX(x);
89 RCP<Thyra::VectorBase<Scalar> > x_dot =
91 initialState->setXDot(x_dot);
97 std::string icConsistency = this->getICConsistency();
98 if (icConsistency ==
"None") {
100 if (initialState->getXDot() == Teuchos::null)
101 Thyra::assign(xDot.ptr(), Scalar(0.0));
104 if (initialState->getXDotDot() == Teuchos::null)
105 Thyra::assign(this->getStepperXDotDot(initialState).ptr(), Scalar(0.0));
108 else if (icConsistency ==
"Zero") {
110 Thyra::assign(xDot.ptr(), Scalar(0.0));
112 Thyra::assign(this->getStepperXDotDot(initialState).ptr(), Scalar(0.0));
114 else if (icConsistency ==
"App") {
118 TEUCHOS_TEST_FOR_EXCEPTION(x_dot == Teuchos::null, std::logic_error,
119 "Error - setInitialConditions() requested 'App' for IC consistency,\n" 120 " but 'App' returned a null pointer for xDot!\n");
121 Thyra::assign(xDot.ptr(), *x_dot);
125 inArgs.get_x_dot_dot());
126 TEUCHOS_TEST_FOR_EXCEPTION(xDotDot == Teuchos::null, std::logic_error,
127 "Error - setInitialConditions() requested 'App' for IC consistency,\n" 128 " but 'App' returned a null pointer for xDotDot!\n");
129 Thyra::assign(this->getStepperXDotDot(initialState).ptr(), *xDotDot);
132 else if (icConsistency ==
"Consistent") {
135 const Scalar time = initialState->getTime();
136 const Scalar dt = initialState->getTimeStep();
137 RCP<TimeDerivative<Scalar> > timeDer = Teuchos::null;
138 const Scalar alpha = Scalar(1.0);
139 const Scalar beta = Scalar(0.0);
143 const Thyra::SolveStatus<Scalar> sStatus =
144 this->solveImplicitODE(x, xDot, time, p);
146 TEUCHOS_TEST_FOR_EXCEPTION(
147 sStatus.solveStatus != Thyra::SOLVE_STATUS_CONVERGED, std::logic_error,
148 "Error - Solver failed while determining the initial conditions.\n" 153 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
154 "Error - setInitialConditions(): 'Consistent' for second-order ODE\n" 155 " has not been implemented.\n");
159 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
160 "Error - setInitialConditions() invalid IC consistency, " 161 << icConsistency <<
".\n");
166 initialState->setIsSynced(
true);
169 if (this->getICConsistencyCheck()) {
170 auto f = initialState->getX()->clone_v();
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());
188 RCP<Teuchos::FancyOStream> out = this->getOStream();
189 Teuchos::OSTab ostab(out,1,
"StepperImplicit::setInitialConditions()");
191 *out <<
"\n---------------------------------------------------\n" 192 <<
"Info -- Stepper = " << this->getStepperType() <<
"\n" 193 <<
" Initial condition PASSED consistency check!\n" 194 <<
" (||f(x,xDot,t)||/||x|| = " << reldiff <<
") < " 195 <<
"(eps = " << eps <<
")" << std::endl
196 <<
"---------------------------------------------------\n"<<std::endl;
198 *out <<
"\n---------------------------------------------------\n" 199 <<
"Info -- Stepper = " << this->getStepperType() <<
"\n" 200 <<
" Initial condition FAILED consistency check but continuing!\n" 201 <<
" (||f(x,xDot,t)||/||x|| = " << reldiff <<
") > " 202 <<
"(eps = " << eps <<
")" << std::endl
203 <<
" ||f(x,xDot,t)|| = " << Thyra::norm(*f) << std::endl
204 <<
" ||x|| = " << Thyra::norm(*x) << std::endl
205 <<
"---------------------------------------------------\n"<<std::endl;
211 template<
class Scalar>
216 this->setSolverName(
"Default Solver");
217 auto subPL = sublist(solverPL,
"NOX");
218 solver_->setParameterList(subPL);
220 if (wrapperModel_ != Teuchos::null) solver_->setModel(wrapperModel_);
222 this->isInitialized_ =
false;
226 template<
class Scalar>
228 Teuchos::RCP<Thyra::NonlinearSolverBase<Scalar> > solver)
230 TEUCHOS_TEST_FOR_EXCEPTION(solver == Teuchos::null, std::logic_error,
231 "Error - Can not set the solver to Teuchos::null.\n");
234 if (wrapperModel_ != Teuchos::null) solver_->setModel(wrapperModel_);
236 this->isInitialized_ =
false;
240 template<
class Scalar>
241 const Thyra::SolveStatus<Scalar>
245 if (getZeroInitialGuess())
246 Thyra::assign(x.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
248 const Thyra::SolveStatus<Scalar> sStatus = (*solver_).solve(&*x);
254 template<
class Scalar>
255 const Thyra::SolveStatus<Scalar>
262 typedef Thyra::ModelEvaluatorBase MEB;
263 MEB::InArgs<Scalar> inArgs = wrapperModel_->getInArgs();
264 MEB::OutArgs<Scalar> outArgs = wrapperModel_->getOutArgs();
266 if (inArgs.supports(MEB::IN_ARG_x_dot )) inArgs.set_x_dot (xDot);
267 if (inArgs.supports(MEB::IN_ARG_t )) inArgs.set_t (time);
268 if (inArgs.supports(MEB::IN_ARG_step_size))
269 inArgs.set_step_size(p->timeStepSize_);
270 if (inArgs.supports(MEB::IN_ARG_alpha )) inArgs.set_alpha (p->alpha_);
271 if (inArgs.supports(MEB::IN_ARG_beta )) inArgs.set_beta (p->beta_);
272 if (inArgs.supports(MEB::IN_ARG_stage_number))
273 inArgs.set_stage_number(p->stageNumber_);
275 wrapperModel_->setForSolve(p->timeDer_, inArgs, outArgs, p->evaluationType_);
277 Thyra::SolveStatus<Scalar> sStatus;
278 typedef Teuchos::ScalarTraits<Scalar> ST;
279 switch (p->evaluationType_)
282 if (getZeroInitialGuess()) Thyra::assign(x.ptr(), ST::zero());
283 sStatus = (*solver_).solve(&*x);
288 sStatus = (*solver_).solve(&*xDot);
292 TEUCHOS_TEST_FOR_EXCEPT(
"Invalid EVALUATION_TYPE!");
300 template<
class Scalar>
309 typedef Thyra::ModelEvaluatorBase MEB;
310 MEB::InArgs<Scalar> inArgs = wrapperModel_->getInArgs();
312 if (inArgs.supports(MEB::IN_ARG_x_dot )) inArgs.set_x_dot (xDot);
313 if (inArgs.supports(MEB::IN_ARG_t )) inArgs.set_t (time);
314 if (inArgs.supports(MEB::IN_ARG_step_size)) inArgs.set_step_size(p->timeStepSize_);
315 if (inArgs.supports(MEB::IN_ARG_alpha )) inArgs.set_alpha (Scalar(0.0));
316 if (inArgs.supports(MEB::IN_ARG_beta )) inArgs.set_beta (Scalar(0.0));
318 MEB::OutArgs<Scalar> outArgs = wrapperModel_->getOutArgs();
321 wrapperModel_->setForSolve(Teuchos::null,inArgs,outArgs,p->evaluationType_);
323 wrapperModel_->evalModel(inArgs, outArgs);
327 template<
class Scalar>
329 const Teuchos::EVerbosityLevel verbLevel)
const 331 out.setOutputToRootOnly(0);
332 out <<
"--- StepperImplicit ---\n";
333 out <<
" wrapperModel_ = " << wrapperModel_ << std::endl;
334 out <<
" solver_ = " << solver_ << std::endl;
335 out <<
" initialGuess_ = " << initialGuess_ << std::endl;
336 out <<
" zeroInitialGuess_ = " 341 template<
class Scalar>
344 out.setOutputToRootOnly(0);
345 bool isValidSetup =
true;
347 if (wrapperModel_->getAppModel() == Teuchos::null) {
348 isValidSetup =
false;
349 out <<
"The application ModelEvaluator is not set!\n";
352 if (wrapperModel_ == Teuchos::null) {
353 isValidSetup =
false;
354 out <<
"The wrapper ModelEvaluator is not set!\n";
357 if (solver_ == Teuchos::null) {
358 isValidSetup =
false;
359 out <<
"The solver is not set!\n";
362 if (solver_ != Teuchos::null) {
363 if (solver_->getModel() == Teuchos::null) {
364 isValidSetup =
false;
365 out <<
"The solver's ModelEvaluator is not set!\n";
373 template<
class Scalar>
374 Teuchos::RCP<const Teuchos::ParameterList>
377 return this->getValidParametersBasicImplicit();
381 template<
class Scalar>
382 Teuchos::RCP<Teuchos::ParameterList>
385 auto pl = this->getValidParametersBasic();
386 pl->template set<std::string>(
"Solver Name", this->getSolverName());
387 pl->template set<bool>(
"Zero Initial Guess", this->getZeroInitialGuess());
388 auto noxSolverPL = this->getSolver()->getParameterList();
389 auto solverPL = Teuchos::parameterList(this->getSolverName());
390 solverPL->set(
"NOX", *noxSolverPL);
391 pl->set(this->getSolverName(), *solverPL);
397 template<
class Scalar>
400 Teuchos::RCP<Teuchos::ParameterList> pl)
402 if (pl != Teuchos::null) {
405 this->setStepperValues(pl);
406 this->setZeroInitialGuess(pl->get<
bool>(
"Zero Initial Guess",
false));
408 this->setStepperSolverValues(pl);
412 template<
class Scalar>
416 if (pl != Teuchos::null) {
418 std::string solverName = pl->get<std::string>(
"Solver Name");
419 if ( pl->isSublist(solverName) ) {
420 auto solverPL = Teuchos::parameterList();
421 solverPL = Teuchos::sublist(pl, solverName);
422 this->setSolverName(solverName);
423 Teuchos::RCP<Teuchos::ParameterList> noxPL =
424 Teuchos::sublist(solverPL,
"NOX",
true);
425 getSolver()->setParameterList(noxPL);
432 #endif // Tempus_StepperImplicit_impl_hpp virtual Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const override
virtual void setSolver(Teuchos::RCP< Thyra::NonlinearSolverBase< Scalar > > solver) override
Set solver.
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.
virtual bool isValidSetup(Teuchos::FancyOStream &out) const override
Teuchos::RCP< Teuchos::ParameterList > getValidParametersBasicImplicit() const
const std::string toString(const Status status)
Convert Status to string.
void setStepperImplicitValues(Teuchos::RCP< Teuchos::ParameterList > pl)
Set StepperImplicit member data from the ParameterList.
Teuchos::RCP< Teuchos::ParameterList > defaultSolverParameters()
Returns the default solver ParameterList for implicit Steppers.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const override
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel) override
Set the model.
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory) override
Set the initial conditions and make them consistent.
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 setDefaultSolver()
void setStepperSolverValues(Teuchos::RCP< Teuchos::ParameterList > pl)
Set solver from ParameterList.
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.