29 #ifndef RYTHMOS_ADJOINT_MODEL_EVALUATOR_HPP 
   30 #define RYTHMOS_ADJOINT_MODEL_EVALUATOR_HPP 
   33 #include "Rythmos_IntegratorBase.hpp" 
   34 #include "Thyra_ModelEvaluator.hpp"  
   35 #include "Thyra_StateFuncModelEvaluatorBase.hpp"  
   36 #include "Thyra_ModelEvaluatorDelegatorBase.hpp" 
   37 #include "Thyra_DefaultScaledAdjointLinearOp.hpp" 
   38 #include "Thyra_DefaultAdjointLinearOpWithSolve.hpp" 
   39 #include "Thyra_VectorStdOps.hpp" 
   40 #include "Thyra_MultiVectorStdOps.hpp" 
   41 #include "Teuchos_implicit_cast.hpp" 
   42 #include "Teuchos_Assert.hpp" 
  172 template<
class Scalar>
 
  174   : 
virtual public Thyra::StateFuncModelEvaluatorBase<Scalar>
 
  186     const RCP<
const Thyra::ModelEvaluator<Scalar> > &fwdStateModel,
 
  187     const Thyra::ModelEvaluatorBase::InArgs<Scalar> &basePoint );
 
  215   RCP<const Thyra::VectorSpaceBase<Scalar> > 
get_x_space() 
const;
 
  217   RCP<const Thyra::VectorSpaceBase<Scalar> > 
get_f_space() 
const;
 
  221   RCP<Thyra::LinearOpWithSolveBase<Scalar> > 
create_W() 
const;
 
  223   RCP<Thyra::LinearOpBase<Scalar> > 
create_W_op() 
const;
 
  225   Thyra::ModelEvaluatorBase::InArgs<Scalar> 
createInArgs() 
const;
 
  235   Thyra::ModelEvaluatorBase::OutArgs<Scalar> createOutArgsImpl() 
const;
 
  238     const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs_bar,
 
  239     const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs_bar
 
  249   RCP<const Thyra::ModelEvaluator<Scalar> > fwdStateModel_;
 
  250   Thyra::ModelEvaluatorBase::InArgs<Scalar> basePoint_;
 
  252   RCP<const InterpolationBufferBase<Scalar> > fwdStateSolutionBuffer_;
 
  254   mutable bool isInitialized_;
 
  255   mutable Thyra::ModelEvaluatorBase::InArgs<Scalar> prototypeInArgs_bar_;
 
  256   mutable Thyra::ModelEvaluatorBase::OutArgs<Scalar> prototypeOutArgs_bar_;
 
  257   mutable Thyra::ModelEvaluatorBase::InArgs<Scalar> adjointNominalValues_;
 
  258   mutable RCP<Thyra::LinearOpBase<Scalar> > my_W_bar_adj_op_;
 
  259   mutable RCP<Thyra::LinearOpBase<Scalar> > my_d_f_d_x_dot_op_;
 
  265   void initialize() 
const;
 
  274 template<
class Scalar>
 
  275 RCP<AdjointModelEvaluator<Scalar> >
 
  277   const RCP<
const Thyra::ModelEvaluator<Scalar> > &fwdStateModel,
 
  281   RCP<AdjointModelEvaluator<Scalar> >
 
  283   adjointModel->setFwdStateModel(fwdStateModel, fwdStateModel->getNominalValues());
 
  284   adjointModel->setFwdTimeRange(fwdTimeRange);
 
  296 template<
class Scalar>
 
  298   :isInitialized_(false)
 
  302 template<
class Scalar>
 
  304   const RCP<
const Thyra::ModelEvaluator<Scalar> > &fwdStateModel,
 
  305   const Thyra::ModelEvaluatorBase::InArgs<Scalar> &basePoint
 
  308   TEUCHOS_TEST_FOR_EXCEPT(is_null(fwdStateModel));
 
  309   fwdStateModel_ = fwdStateModel;
 
  310   basePoint_ = basePoint;
 
  311   isInitialized_ = 
false;
 
  315 template<
class Scalar>
 
  319   fwdTimeRange_ = fwdTimeRange;
 
  323 template<
class Scalar>
 
  327   TEUCHOS_TEST_FOR_EXCEPT(is_null(fwdStateSolutionBuffer));
 
  328   fwdStateSolutionBuffer_ = fwdStateSolutionBuffer;
 
  335 template<
class Scalar>
 
  336 RCP<const Thyra::VectorSpaceBase<Scalar> >
 
  340   return fwdStateModel_->get_f_space();
 
  344 template<
class Scalar>
 
  345 RCP<const Thyra::VectorSpaceBase<Scalar> >
 
  349   return fwdStateModel_->get_x_space();
 
  353 template<
class Scalar>
 
  354 Thyra::ModelEvaluatorBase::InArgs<Scalar>
 
  358   return adjointNominalValues_;
 
  362 template<
class Scalar>
 
  363 RCP<Thyra::LinearOpWithSolveBase<Scalar> >
 
  367   return Thyra::nonconstAdjointLows<Scalar>(fwdStateModel_->create_W());
 
  371 template<
class Scalar>
 
  372 RCP<Thyra::LinearOpBase<Scalar> >
 
  376   return Thyra::nonconstAdjoint<Scalar>(fwdStateModel_->create_W_op());
 
  380 template<
class Scalar>
 
  381 Thyra::ModelEvaluatorBase::InArgs<Scalar>
 
  385   return prototypeInArgs_bar_;
 
  392 template<
class Scalar>
 
  393 Thyra::ModelEvaluatorBase::OutArgs<Scalar>
 
  397   return prototypeOutArgs_bar_;
 
  401 template<
class Scalar>
 
  402 void AdjointModelEvaluator<Scalar>::evalModelImpl(
 
  403   const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs_bar,
 
  404   const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs_bar
 
  408   using Teuchos::rcp_dynamic_cast;
 
  409   using Teuchos::describe;
 
  410   typedef Teuchos::ScalarTraits<Scalar> ST;
 
  411   typedef Thyra::ModelEvaluatorBase MEB;
 
  412   typedef Thyra::DefaultScaledAdjointLinearOp<Scalar> DSALO;
 
  413   typedef Thyra::DefaultAdjointLinearOpWithSolve<Scalar> DALOWS;
 
  414   typedef Teuchos::VerboseObjectTempState<Thyra::ModelEvaluatorBase> VOTSME;
 
  420   THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_GEN_BEGIN(
 
  421     "AdjointModelEvaluator", inArgs_bar, outArgs_bar, Teuchos::null );
 
  425   VOTSME fwdStateModel_outputTempState(fwdStateModel_,out,verbLevel);
 
  428   const bool dumpAll = includesVerbLevel(localVerbLevel, Teuchos::VERB_EXTREME);
 
  436   const Scalar t_bar = inArgs_bar.get_t();
 
  437   const RCP<const Thyra::VectorBase<Scalar> >
 
  438     lambda_rev_dot = inArgs_bar.get_x_dot().assert_not_null(), 
 
  439     lambda = inArgs_bar.get_x().assert_not_null(); 
 
  440   const Scalar alpha_bar = inArgs_bar.get_alpha();
 
  441   const Scalar beta_bar = inArgs_bar.get_beta();
 
  444     *out << 
"\nlambda_rev_dot = " << describe(*lambda_rev_dot, Teuchos::VERB_EXTREME);
 
  445     *out << 
"\nlambda = " << describe(*lambda, Teuchos::VERB_EXTREME);
 
  446     *out << 
"\nalpha_bar = " << alpha_bar << 
"\n";
 
  447     *out << 
"\nbeta_bar = " << beta_bar << 
"\n";
 
  452   const RCP<Thyra::VectorBase<Scalar> > f_bar = outArgs_bar.get_f();
 
  455   if (outArgs_bar.supports(MEB::OUT_ARG_W))
 
  456     W_bar = rcp_dynamic_cast<DALOWS>(outArgs_bar.get_W(), 
true);
 
  459   if (outArgs_bar.supports(MEB::OUT_ARG_W_op))
 
  460     W_bar_op = rcp_dynamic_cast<DSALO>(outArgs_bar.get_W_op(), 
true);
 
  463     if (!is_null(W_bar)) {
 
  464       *out << 
"\nW_bar = " << describe(*W_bar, Teuchos::VERB_EXTREME);
 
  466     if (!is_null(W_bar_op)) {
 
  467       *out << 
"\nW_bar_op = " << describe(*W_bar_op, Teuchos::VERB_EXTREME);
 
  475   MEB::InArgs<Scalar> fwdInArgs = fwdStateModel_->createInArgs();
 
  479   fwdInArgs = basePoint_;
 
  481   if (!is_null(fwdStateSolutionBuffer_)) {
 
  482     const Scalar t = fwdTimeRange_.length() - t_bar;
 
  483     RCP<const Thyra::VectorBase<Scalar> > x, x_dot;
 
  484     get_x_and_x_dot<Scalar>( *fwdStateSolutionBuffer_, t,
 
  485       outArg(x), outArg(x_dot) );
 
  487     fwdInArgs.set_x_dot(x);
 
  504   RCP<Thyra::LinearOpWithSolveBase<Scalar> > W_bar_adj;
 
  505   RCP<Thyra::LinearOpBase<Scalar> > W_bar_adj_op;
 
  508     MEB::OutArgs<Scalar> fwdOutArgs = fwdStateModel_->createOutArgs();
 
  511     if (!is_null(W_bar)) {
 
  514       W_bar_adj = W_bar->getNonconstOp();
 
  515       W_bar_adj_op = W_bar_adj;
 
  517     else if (!is_null(W_bar_op)) {
 
  520       W_bar_adj_op = W_bar_op->getNonconstOp();
 
  522     else if (!is_null(f_bar)) {
 
  523       TEUCHOS_TEST_FOR_EXCEPT_MSG(
true, 
"ToDo: Unit test this code!");
 
  527       if (is_null(my_W_bar_adj_op_)) {
 
  528         my_W_bar_adj_op_ = fwdStateModel_->create_W_op();
 
  530       W_bar_adj_op = my_W_bar_adj_op_;
 
  534     if (!is_null(W_bar_adj)) {
 
  535       fwdOutArgs.set_W(W_bar_adj);
 
  537     else if (!is_null(W_bar_adj_op)) {
 
  538       fwdOutArgs.set_W_op(W_bar_adj_op);
 
  542     if (!is_null(W_bar_adj) || !is_null(W_bar_adj_op)) {
 
  543       fwdInArgs.set_alpha(alpha_bar);
 
  544       fwdInArgs.set_beta(beta_bar);
 
  548     if (!is_null(W_bar_adj) || !is_null(W_bar_adj_op)) {
 
  549       fwdStateModel_->evalModel( fwdInArgs, fwdOutArgs );
 
  553     if (!is_null(W_bar_adj) && dumpAll)
 
  554       *out << 
"\nW_bar_adj = " << describe(*W_bar_adj, Teuchos::VERB_EXTREME);
 
  555     if (!is_null(W_bar_adj_op) && dumpAll)
 
  556       *out << 
"\nW_bar_adj_op = " << describe(*W_bar_adj_op, Teuchos::VERB_EXTREME);
 
  562   RCP<Thyra::LinearOpBase<Scalar> > d_f_d_x_dot_op;
 
  563   if (!is_null(f_bar)) {
 
  564     if (is_null(my_d_f_d_x_dot_op_)) {
 
  565       my_d_f_d_x_dot_op_ = fwdStateModel_->create_W_op();
 
  567     d_f_d_x_dot_op = my_d_f_d_x_dot_op_;
 
  568     MEB::OutArgs<Scalar> fwdOutArgs = fwdStateModel_->createOutArgs();
 
  569     fwdOutArgs.set_W_op(d_f_d_x_dot_op);
 
  570     fwdInArgs.set_alpha(ST::one());
 
  571     fwdInArgs.set_beta(ST::zero());
 
  572     fwdStateModel_->evalModel( fwdInArgs, fwdOutArgs );
 
  574       *out << 
"\nd_f_d_x_dot_op = " << describe(*d_f_d_x_dot_op, Teuchos::VERB_EXTREME);
 
  585   if (!is_null(f_bar)) {
 
  588     const RCP<Thyra::VectorBase<Scalar> >
 
  589       lambda_hat = createMember(lambda_rev_dot->space());
 
  590     Thyra::V_VpStV<Scalar>( outArg(*lambda_hat),
 
  591       *lambda_rev_dot, -alpha_bar/beta_bar, *lambda );
 
  593       *out << 
"\nlambda_hat = " << describe(*lambda_hat, Teuchos::VERB_EXTREME);
 
  596     Thyra::apply<Scalar>( *d_f_d_x_dot_op, Thyra::CONJTRANS, *lambda_hat,
 
  600     Thyra::apply<Scalar>( *W_bar_adj_op, Thyra::CONJTRANS, *lambda,
 
  601       outArg(*f_bar), 1.0/beta_bar, ST::one() );
 
  608       *out << 
"\nf_bar = " << describe(*f_bar, Teuchos::VERB_EXTREME);
 
  613     if (!is_null(W_bar)) {
 
  614       *out << 
"\nW_bar = " << describe(*W_bar, Teuchos::VERB_EXTREME);
 
  616     if (!is_null(W_bar_op)) {
 
  617       *out << 
"\nW_bar_op = " << describe(*W_bar_op, Teuchos::VERB_EXTREME);
 
  626   THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END();
 
  634 template<
class Scalar>
 
  635 void AdjointModelEvaluator<Scalar>::initialize()
 const 
  638   typedef Thyra::ModelEvaluatorBase MEB;
 
  647   MEB::InArgs<Scalar> fwdStateModelInArgs = fwdStateModel_->createInArgs();
 
  648   MEB::OutArgs<Scalar> fwdStateModelOutArgs = fwdStateModel_->createOutArgs();
 
  650 #ifdef HAVE_RYTHMOS_DEBUG 
  651   TEUCHOS_ASSERT( fwdStateModelInArgs.supports(MEB::IN_ARG_x_dot) );
 
  652   TEUCHOS_ASSERT( fwdStateModelInArgs.supports(MEB::IN_ARG_x) );
 
  653   TEUCHOS_ASSERT( fwdStateModelInArgs.supports(MEB::IN_ARG_t) );
 
  654   TEUCHOS_ASSERT( fwdStateModelInArgs.supports(MEB::IN_ARG_alpha) );
 
  655   TEUCHOS_ASSERT( fwdStateModelInArgs.supports(MEB::IN_ARG_beta) );
 
  656   TEUCHOS_ASSERT( fwdStateModelOutArgs.supports(MEB::OUT_ARG_f) );
 
  657   TEUCHOS_ASSERT( fwdStateModelOutArgs.supports(MEB::OUT_ARG_W) );
 
  665     MEB::InArgsSetup<Scalar> inArgs_bar;
 
  666     inArgs_bar.setModelEvalDescription(this->description());
 
  667     inArgs_bar.setSupports( MEB::IN_ARG_x_dot );
 
  668     inArgs_bar.setSupports( MEB::IN_ARG_x );
 
  669     inArgs_bar.setSupports( MEB::IN_ARG_t );
 
  670     inArgs_bar.setSupports( MEB::IN_ARG_alpha );
 
  671     inArgs_bar.setSupports( MEB::IN_ARG_beta );
 
  672     prototypeInArgs_bar_ = inArgs_bar;
 
  676     MEB::OutArgsSetup<Scalar> outArgs_bar;
 
  677     outArgs_bar.setModelEvalDescription(this->description());
 
  678     outArgs_bar.setSupports(MEB::OUT_ARG_f);
 
  679     if (fwdStateModelOutArgs.supports(MEB::OUT_ARG_W) ) {
 
  680       outArgs_bar.setSupports(MEB::OUT_ARG_W);
 
  681       outArgs_bar.set_W_properties(fwdStateModelOutArgs.get_W_properties());
 
  683     if (fwdStateModelOutArgs.supports(MEB::OUT_ARG_W_op) ) {
 
  684       outArgs_bar.setSupports(MEB::OUT_ARG_W_op);
 
  685       outArgs_bar.set_W_properties(fwdStateModelOutArgs.get_W_properties());
 
  687     prototypeOutArgs_bar_ = outArgs_bar;
 
  695   adjointNominalValues_ = prototypeInArgs_bar_;
 
  697   const RCP<Thyra::VectorBase<Scalar> > zero_lambda_vec =
 
  698     createMember(fwdStateModel_->get_f_space());
 
  699   V_S( zero_lambda_vec.ptr(), ScalarTraits<Scalar>::zero() );
 
  700   adjointNominalValues_.set_x_dot(zero_lambda_vec);
 
  701   adjointNominalValues_.set_x(zero_lambda_vec);
 
  707   my_W_bar_adj_op_ = Teuchos::null;
 
  708   my_d_f_d_x_dot_op_ = Teuchos::null;
 
  714   isInitialized_ = 
true;
 
  722 #endif // RYTHMOS_ADJOINT_MODEL_EVALUATOR_HPP 
RCP< const Thyra::VectorSpaceBase< Scalar > > get_f_space() const 
 
Standard concrete adjoint ModelEvaluator for time-constant mass matrix models. 
 
RCP< Thyra::LinearOpBase< Scalar > > create_W_op() const 
 
Thyra::ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const 
 
RCP< Thyra::LinearOpWithSolveBase< Scalar > > create_W() const 
 
Base class for an interpolation buffer. 
 
RCP< AdjointModelEvaluator< Scalar > > adjointModelEvaluator(const RCP< const Thyra::ModelEvaluator< Scalar > > &fwdStateModel, const TimeRange< Scalar > &fwdTimeRange)
Nonmember constructor. 
 
void setFwdStateSolutionBuffer(const RCP< const InterpolationBufferBase< Scalar > > &fwdStateSolutionBuffer)
Set the interpolation buffer that will return values of the state solution x and x_dot at various poi...
 
Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const 
 
void setFwdStateModel(const RCP< const Thyra::ModelEvaluator< Scalar > > &fwdStateModel, const Thyra::ModelEvaluatorBase::InArgs< Scalar > &basePoint)
Set the underlying forward model and base point. 
 
void setFwdTimeRange(const TimeRange< Scalar > &fwdTimeRange)
Set the forward time range that this adjoint model will be defined over. 
 
RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const