9 #ifndef Tempus_AdjointAuxSensitivityModelEvaluator_impl_hpp 
   10 #define Tempus_AdjointAuxSensitivityModelEvaluator_impl_hpp 
   14 #include "Thyra_DefaultScaledAdjointLinearOp.hpp" 
   15 #include "Thyra_DefaultAdjointLinearOpWithSolve.hpp" 
   19 #include "Thyra_DefaultBlockedLinearOp.hpp" 
   21 #include "Thyra_VectorStdOps.hpp" 
   22 #include "Thyra_MultiVectorStdOps.hpp" 
   26 template <
typename Scalar>
 
   30   const Scalar& t_final,
 
   34   mass_matrix_is_computed_(false),
 
   35   t_interp_(Teuchos::ScalarTraits<Scalar>::rmax())
 
   45   if (pList != Teuchos::null)
 
   50   p_index_ = pl->
get<
int>(
"Sensitivity Parameter Index", 0);
 
   51   g_index_ = pl->
get<
int>(
"Response Function Index", 0);
 
   57     "AdjointAuxSensitivityModelEvaluator currently does not support " <<
 
   58     "non-constant mass matrix df/dx_dot!");
 
   65     Thyra::multiVectorProductVectorSpace(
model_->get_p_space(p_index_),
 
   67   Array< RCP<const VectorSpaceBase<Scalar> > > x_spaces(2);
 
   68   Array< RCP<const VectorSpaceBase<Scalar> > > f_spaces(2);
 
   76   MEB::InArgs<Scalar> me_inArgs = 
model_->createInArgs();
 
   77   MEB::InArgsSetup<Scalar> inArgs;
 
   78   inArgs.setModelEvalDescription(this->
description());
 
   79   inArgs.setSupports(MEB::IN_ARG_x);
 
   80   inArgs.setSupports(MEB::IN_ARG_t);
 
   81   if (me_inArgs.supports(MEB::IN_ARG_x_dot))
 
   82     inArgs.setSupports(MEB::IN_ARG_x_dot);
 
   83   inArgs.setSupports(MEB::IN_ARG_alpha);
 
   84   inArgs.setSupports(MEB::IN_ARG_beta);
 
   87   inArgs.set_Np(me_inArgs.Np());
 
   90   MEB::OutArgs<Scalar> me_outArgs = 
model_->createOutArgs();
 
   91   MEB::OutArgsSetup<Scalar> outArgs;
 
   92   outArgs.setModelEvalDescription(this->
description());
 
   93   outArgs.set_Np_Ng(me_inArgs.Np(),0);
 
   94   outArgs.setSupports(MEB::OUT_ARG_f);
 
   95   outArgs.setSupports(MEB::OUT_ARG_W_op);
 
  102   if (me_inArgs.supports(MEB::IN_ARG_x_dot)) {
 
  108 template <
typename Scalar>
 
  116   forward_state_ = Teuchos::null;
 
  119 template <
typename Scalar>
 
  125   return model_->get_p_space(p);
 
  128 template <
typename Scalar>
 
  134   return model_->get_p_names(p);
 
  137 template <
typename Scalar>
 
  142   return x_prod_space_;
 
  145 template <
typename Scalar>
 
  150   return f_prod_space_;
 
  153 template <
typename Scalar>
 
  161   RCP<LinearOpBase<Scalar> > op = model_->create_W_op();
 
  162   RCP<LinearOpBase<Scalar> > mv_adjoint_op =
 
  163     Thyra::nonconstMultiVectorLinearOp(Thyra::nonconstAdjoint(op),
 
  165   RCP<const Thyra::VectorSpaceBase<Scalar> > g_space = response_space_;
 
  166   RCP<LinearOpBase<Scalar> > g_op =
 
  167     Thyra::scaledIdentity(g_space, Scalar(1.0));
 
  168   RCP<LinearOpBase<Scalar> > null_op;
 
  169   return nonconstBlock2x2(mv_adjoint_op, null_op, null_op, g_op);
 
  172 template <
typename Scalar>
 
  178   using Teuchos::rcp_dynamic_cast;
 
  181   RCP<const LOWSFB > factory = model_->get_W_factory();
 
  182   if (factory == Teuchos::null)
 
  183     return Teuchos::null; 
 
  185   RCP<const LOWSFB > alowsfb = Thyra::adjointLinearOpWithSolveFactory(factory);
 
  186   RCP<const LOWSFB > mv_alowsfb =
 
  187     Thyra::multiVectorLinearOpWithSolveFactory(alowsfb, residual_space_,
 
  190   RCP<const Thyra::VectorSpaceBase<Scalar> > g_space = response_space_;
 
  191   RCP<const LOWSFB > g_lowsfb =
 
  192     Thyra::scaledIdentitySolveFactory(g_space, Scalar(1.0));
 
  195   lowsfbs[0] = mv_alowsfb;
 
  196   lowsfbs[1] = g_lowsfb;
 
  197   return Thyra::blockedTriangularLinearOpWithSolveFactory(lowsfbs);
 
  200 template <
typename Scalar>
 
  205   return prototypeInArgs_;
 
  208 template <
typename Scalar>
 
  215   using Teuchos::rcp_dynamic_cast;
 
  217   MEB::InArgs<Scalar> me_nominal = model_->getNominalValues();
 
  218   MEB::InArgs<Scalar> nominal = this->createInArgs();
 
  223   RCP< Thyra::VectorBase<Scalar> > x = Thyra::createMember(*x_prod_space_);
 
  224   Thyra::assign(x.ptr(), zero);
 
  227   if (me_nominal.supports(MEB::IN_ARG_x_dot)) {
 
  228     RCP< Thyra::VectorBase<Scalar> > x_dot =
 
  229       Thyra::createMember(*x_prod_space_);
 
  230     Thyra::assign(x_dot.ptr(), zero);
 
  231     nominal.set_x_dot(x_dot);
 
  234   const int np = model_->Np();
 
  235   for (
int i=0; i<np; ++i)
 
  236     nominal.set_p(i, me_nominal.get_p(i));
 
  241 template <
typename Scalar>
 
  246   return prototypeOutArgs_;
 
  249 template <
typename Scalar>
 
  257   using Teuchos::rcp_dynamic_cast;
 
  262   const Scalar t = inArgs.
get_t();
 
  263   const Scalar forward_t = t_final_ - t;
 
  264   if (forward_state_ == Teuchos::null || t_interp_ != t) {
 
  265     if (forward_state_ == Teuchos::null)
 
  266       forward_state_ = sh_->interpolateState(forward_t);
 
  268       sh_->interpolateState(forward_t, forward_state_.get());
 
  273   MEB::InArgs<Scalar> me_inArgs = model_->getNominalValues();
 
  274   me_inArgs.set_x(forward_state_->getX());
 
  275   if (me_inArgs.supports(MEB::IN_ARG_x_dot) &&
 
  277     me_inArgs.set_x_dot(forward_state_->getXDot());
 
  278   if (me_inArgs.supports(MEB::IN_ARG_t))
 
  279     me_inArgs.set_t(forward_t);
 
  280   const int np = me_inArgs.Np();
 
  281   for (
int i=0; i<np; ++i)
 
  282     me_inArgs.set_p(i, inArgs.
get_p(i));
 
  285   RCP<Thyra::LinearOpBase<Scalar> > op = outArgs.
get_W_op();
 
  286   if (op != Teuchos::null) {
 
  287     if (me_inArgs.supports(MEB::IN_ARG_alpha))
 
  289     if (me_inArgs.supports(MEB::IN_ARG_beta))
 
  290       me_inArgs.set_beta(inArgs.
get_beta());
 
  293     RCP<Thyra::DefaultBlockedLinearOp<Scalar> > block_op =
 
  295     RCP<Thyra::MultiVectorLinearOp<Scalar> > mv_adjoint_op =
 
  297         block_op->getNonconstBlock(0,0),
true);
 
  298     RCP<Thyra::DefaultScaledAdjointLinearOp<Scalar> > adjoint_op =
 
  300         mv_adjoint_op->getNonconstLinearOp(),
true);
 
  301     MEB::OutArgs<Scalar> me_outArgs = model_->createOutArgs();
 
  302     me_outArgs.set_W_op(adjoint_op->getNonconstOp());
 
  303     model_->evalModel(me_inArgs, me_outArgs);
 
  306     RCP<Thyra::ScaledIdentityLinearOpWithSolve<Scalar> > si_op =
 
  308         block_op->getNonconstBlock(1,1),
true);
 
  317   RCP<Thyra::VectorBase<Scalar> > f = outArgs.
get_f();
 
  318   if (f != Teuchos::null) {
 
  319     RCP<const Thyra::VectorBase<Scalar> > x = inArgs.
get_x().assert_not_null();
 
  320     RCP<const DPV> prod_x = rcp_dynamic_cast<
const DPV>(x,
true);
 
  321     RCP<const Thyra::VectorBase<Scalar> > adjoint_x = prod_x->
getVectorBlock(0);
 
  322     RCP<const Thyra::MultiVectorBase<Scalar> >adjoint_x_mv =
 
  323       rcp_dynamic_cast<
const DMVPV>(adjoint_x,
true)->getMultiVector();
 
  325     RCP<DPV> prod_f = rcp_dynamic_cast<
DPV>(f,
true);
 
  326     RCP<Thyra::VectorBase<Scalar> > adjoint_f =
 
  328     RCP<Thyra::MultiVectorBase<Scalar> > adjoint_f_mv =
 
  329       rcp_dynamic_cast<DMVPV>(adjoint_f,
true)->getNonconstMultiVector();
 
  331     MEB::OutArgs<Scalar> me_outArgs = model_->createOutArgs();
 
  333     if (my_dfdx_ == Teuchos::null)
 
  334       my_dfdx_ = model_->create_W_op();
 
  335     me_outArgs.set_W_op(my_dfdx_);
 
  336     if (me_inArgs.supports(MEB::IN_ARG_alpha))
 
  337       me_inArgs.set_alpha(0.0);
 
  338     if (me_inArgs.supports(MEB::IN_ARG_beta))
 
  339       me_inArgs.set_beta(1.0);
 
  340     model_->evalModel(me_inArgs, me_outArgs);
 
  344                     Scalar(-1.0), Scalar(0.0));
 
  348     RCP<const DPV> prod_x_dot;
 
  349     if (me_inArgs.supports(MEB::IN_ARG_x_dot)) {
 
  350       RCP<const Thyra::VectorBase<Scalar> > x_dot = inArgs.
get_x_dot();
 
  351       if (x_dot != Teuchos::null) {
 
  352         prod_x_dot = rcp_dynamic_cast<
const DPV>(x_dot,
true);
 
  353         RCP<const Thyra::VectorBase<Scalar> > adjoint_x_dot =
 
  355         RCP<const Thyra::MultiVectorBase<Scalar> > adjoint_x_dot_mv =
 
  356           rcp_dynamic_cast<
const DMVPV>(adjoint_x_dot,
true)->getMultiVector();
 
  357         if (mass_matrix_is_identity_) {
 
  359           Thyra::V_StVpV(adjoint_f_mv.ptr(), Scalar(-1.0), *adjoint_f_mv,
 
  363           if (my_dfdxdot_ == Teuchos::null)
 
  364             my_dfdxdot_ = model_->create_W_op();
 
  365           if (!mass_matrix_is_constant_ || !mass_matrix_is_computed_) {
 
  366             me_outArgs.set_W_op(my_dfdxdot_);
 
  367             me_inArgs.set_alpha(1.0);
 
  368             me_inArgs.set_beta(0.0);
 
  369             model_->evalModel(me_inArgs, me_outArgs);
 
  371             mass_matrix_is_computed_ = 
true;
 
  374                              adjoint_f_mv.ptr(), Scalar(1.0), Scalar(-1.0));
 
  381     RCP<Thyra::VectorBase<Scalar> > adjoint_g =
 
  382       prod_f->getNonconstVectorBlock(1);
 
  383     RCP<Thyra::MultiVectorBase<Scalar> > adjoint_g_mv =
 
  384       rcp_dynamic_cast<DMVPV>(adjoint_g,
true)->getNonconstMultiVector();
 
  386     MEB::OutArgs<Scalar> me_outArgs2 = model_->createOutArgs();
 
  387     MEB::DerivativeSupport dfdp_support =
 
  388       me_outArgs2.supports(MEB::OUT_ARG_DfDp, p_index_);
 
  390     if (dfdp_support.supports(MEB::DERIV_LINEAR_OP)) {
 
  391       if (my_dfdp_op_ == Teuchos::null)
 
  392         my_dfdp_op_ = model_->create_DfDp_op(p_index_);
 
  393       me_outArgs2.set_DfDp(p_index_, MEB::Derivative<Scalar>(my_dfdp_op_));
 
  396     else if (dfdp_support.supports(MEB::DERIV_MV_JACOBIAN_FORM)) {
 
  397       if (my_dfdp_mv_ == Teuchos::null)
 
  398         my_dfdp_mv_ = createMembers(model_->get_f_space(),
 
  399                                     model_->get_p_space(p_index_)->dim());
 
  400       me_outArgs2.set_DfDp(p_index_,
 
  401                            MEB::Derivative<Scalar>(my_dfdp_mv_,
 
  402                                                    MEB::DERIV_MV_JACOBIAN_FORM));
 
  403       my_dfdp_op_ = my_dfdp_mv_;
 
  406     else if (dfdp_support.supports(MEB::DERIV_MV_GRADIENT_FORM)) {
 
  407       if (my_dfdp_mv_ == Teuchos::null)
 
  408         my_dfdp_mv_ = createMembers(model_->get_p_space(p_index_),
 
  409                                     model_->get_f_space()->dim());
 
  410       me_outArgs2.set_DfDp(p_index_,
 
  411                            MEB::Derivative<Scalar>(my_dfdp_mv_,
 
  412                                                    MEB::DERIV_MV_GRADIENT_FORM));
 
  413       my_dfdp_op_ = my_dfdp_mv_;
 
  418         true, std::logic_error, 
"Invalid df/dp support");
 
  419     model_->evalModel(me_inArgs, me_outArgs2);
 
  420     my_dfdp_op_->apply(trans, *adjoint_x_mv, adjoint_g_mv.ptr(),
 
  421                        Scalar(1.0), Scalar(0.0));
 
  423     if (prod_x_dot != Teuchos::null) {
 
  424      RCP<const Thyra::VectorBase<Scalar> > z_dot =
 
  425        prod_x_dot->getVectorBlock(1);
 
  426      RCP<const Thyra::MultiVectorBase<Scalar> > z_dot_mv =
 
  427        rcp_dynamic_cast<
const DMVPV>(z_dot,
true)->getMultiVector();
 
  428      Thyra::V_VmV(adjoint_g_mv.ptr(), *z_dot_mv, *adjoint_g_mv);
 
  433 template<
class Scalar>
 
  439   pl->
set<
int>(
"Sensitivity Parameter Index", 0);
 
  440   pl->
set<
int>(
"Response Function Index", 0);
 
  441   pl->
set<
bool>(
"Mass Matrix Is Constant", 
true);
 
  442   pl->
set<
bool>(
"Mass Matrix Is Identity", 
false);
 
Teuchos::RCP< const Thyra::LinearOpWithSolveFactoryBase< Scalar > > get_W_factory() const 
 
Implicit concrete LinearOpBase subclass that takes a flattended out multi-vector and performs a multi...
 
void setScale(const Scalar &s)
 
RCP< const VectorBase< Scalar > > get_x_dot() const 
 
void evalModelImpl(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const 
 
static Teuchos::RCP< const Teuchos::ParameterList > getValidParameters()
 
T & get(const std::string &name, T def_value)
 
RCP< const VectorBase< Scalar > > getVectorBlock(const int k) const 
 
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
 
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
 
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_W_op() const 
 
bool mass_matrix_is_constant_
 
Evaluation< VectorBase< Scalar > > get_f() const 
 
Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const 
 
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const 
 
static magnitudeType rmax()
 
bool mass_matrix_is_identity_
 
Teuchos::RCP< const DPVS > f_prod_space_
 
Teuchos::RCP< const Teuchos::Array< std::string > > get_p_names(int p) const 
 
Thyra::ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const 
 
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
 
Thyra::ModelEvaluatorBase::OutArgs< Scalar > createOutArgsImpl() const 
 
virtual std::string description() const 
 
void validateParametersAndSetDefaults(ParameterList const &validParamList, int const depth=1000)
 
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_f_space() const 
 
Thyra::ModelEvaluatorBase::InArgs< Scalar > prototypeInArgs_
 
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
 
void setForwardSolutionHistory(const Teuchos::RCP< const Tempus::SolutionHistory< Scalar > > &sh)
Set solution history from forward evaluation. 
 
RCP< VectorBase< Scalar > > getNonconstVectorBlock(const int k)
 
Implicit concrete LinearOpBase subclass that takes a flattended out multi-vector and performs a multi...
 
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_p_space(int p) const 
 
Teuchos::RCP< const DPVS > x_prod_space_
 
Teuchos::RCP< const DMVPVS > residual_space_
 
Teuchos::RCP< const DMVPVS > response_space_
 
Thyra::ModelEvaluatorBase::OutArgs< Scalar > prototypeOutArgs_
 
AdjointAuxSensitivityModelEvaluator(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, const Scalar &t_final, const Teuchos::RCP< const Teuchos::ParameterList > &pList=Teuchos::null)
Constructor. 
 
Teuchos::RCP< const DMVPVS > adjoint_space_
 
#define TEUCHOS_ASSERT(assertion_test)
 
Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > model_
 
RCP< LinearOpBase< Scalar > > get_W_op() const 
 
RCP< const VectorBase< Scalar > > get_x() const 
 
RCP< const VectorBase< Scalar > > get_p(int l) const