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.