27 const bool is_pseudotransient,
28 const Teuchos::RCP<const Teuchos::ParameterList>& pList,
29 const Teuchos::RCP<MultiVector>& dxdp_init,
30 const Teuchos::RCP<MultiVector>& dx_dotdp_init,
31 const Teuchos::RCP<MultiVector>& dx_dotdotdp_init) :
55 typedef Thyra::ModelEvaluatorBase MEB;
58 Teuchos::RCP<Teuchos::ParameterList> pl =
59 Teuchos::rcp(
new Teuchos::ParameterList);
60 if (pList != Teuchos::null)
65 p_index_ = pl->get<
int>(
"Sensitivity Parameter Index");
66 g_index_ = pl->get<
int>(
"Response Function Index", -1);
82 Thyra::multiVectorProductVectorSpace(
model_->get_g_space(
g_index_),
86 MEB::InArgs<Scalar> me_inArgs =
model_->createInArgs();
90 MEB::InArgsSetup<Scalar> inArgs;
91 inArgs.setModelEvalDescription(this->description());
92 inArgs.setSupports(MEB::IN_ARG_x);
93 if (me_inArgs.supports(MEB::IN_ARG_x_dot))
94 inArgs.setSupports(MEB::IN_ARG_x_dot);
95 if (me_inArgs.supports(MEB::IN_ARG_t))
96 inArgs.setSupports(MEB::IN_ARG_t);
97 if (me_inArgs.supports(MEB::IN_ARG_alpha))
98 inArgs.setSupports(MEB::IN_ARG_alpha);
99 if (me_inArgs.supports(MEB::IN_ARG_beta))
100 inArgs.setSupports(MEB::IN_ARG_beta);
101 if (me_inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff))
102 inArgs.setSupports(MEB::IN_ARG_W_x_dot_dot_coeff);
105 inArgs.set_Np(me_inArgs.Np());
108 MEB::OutArgs<Scalar> me_outArgs =
model_->createOutArgs();
111 MEB::OutArgsSetup<Scalar> outArgs;
112 outArgs.setModelEvalDescription(this->description());
113 outArgs.set_Np_Ng(me_inArgs.Np(),me_outArgs.Ng()+
g_offset_);
114 outArgs.setSupports(MEB::OUT_ARG_f);
115 if (sens_mer_outArgs.supports(MEB::OUT_ARG_W_op) ||
116 sens_mes_outArgs.supports(MEB::OUT_ARG_W_op))
117 outArgs.setSupports(MEB::OUT_ARG_W_op);
121 for (
int j=0; j<me_outArgs.Ng(); ++j) {
122 outArgs.setSupports(MEB::OUT_ARG_DgDx_dot, j+
g_offset_,
123 me_outArgs.supports(MEB::OUT_ARG_DgDx_dot, j));
124 outArgs.setSupports(MEB::OUT_ARG_DgDx, j+
g_offset_,
125 me_outArgs.supports(MEB::OUT_ARG_DgDx, j));
126 for (
int l=0; l<me_outArgs.Np(); ++l) {
127 outArgs.setSupports(MEB::OUT_ARG_DgDp, j+
g_offset_, l,
128 me_outArgs.supports(MEB::OUT_ARG_DgDp, j, l));
135 TEUCHOS_ASSERT(me_inArgs.supports(MEB::IN_ARG_x));
137 TEUCHOS_ASSERT(sens_mer_outArgs.supports(MEB::OUT_ARG_W_op));
138 if (me_inArgs.supports(MEB::IN_ARG_x_dot)) {
139 TEUCHOS_ASSERT(me_inArgs.supports(MEB::IN_ARG_alpha));
140 TEUCHOS_ASSERT(me_inArgs.supports(MEB::IN_ARG_beta));
142 TEUCHOS_ASSERT(me_outArgs.supports(MEB::OUT_ARG_DfDp,
p_index_).supports(MEB::DERIV_MV_JACOBIAN_FORM));
305 typedef Thyra::ModelEvaluatorBase MEB;
306 typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
308 using Teuchos::rcp_dynamic_cast;
310 MEB::InArgs<Scalar> me_nominal =
model_->getNominalValues();
313 const Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
316 RCP< Thyra::VectorBase<Scalar> > x = Thyra::createMember(*
dxdp_space_);
317 RCP<DMVPV> dxdp = rcp_dynamic_cast<DMVPV>(x,
true);
319 Thyra::assign(dxdp->getNonconstMultiVector().ptr(), zero);
321 Thyra::assign(dxdp->getNonconstMultiVector().ptr(), *
dxdp_init_);
325 if (me_nominal.supports(MEB::IN_ARG_x_dot)) {
326 RCP< Thyra::VectorBase<Scalar> > xdot = Thyra::createMember(*
dxdp_space_);
327 RCP<DMVPV> dxdotdp = rcp_dynamic_cast<DMVPV>(xdot,
true);
329 Thyra::assign(dxdotdp->getNonconstMultiVector().ptr(), zero);
331 Thyra::assign(dxdotdp->getNonconstMultiVector().ptr(), *
dx_dotdp_init_);
332 nominal.set_x_dot(xdot);
336 if (me_nominal.supports(MEB::IN_ARG_x_dot_dot)) {
337 RCP< Thyra::VectorBase<Scalar> > xdotdot =
339 RCP<DMVPV> dxdotdotdp = rcp_dynamic_cast<DMVPV>(xdotdot,
true);
341 Thyra::assign(dxdotdotdp->getNonconstMultiVector().ptr(), zero);
343 Thyra::assign(dxdotdotdp->getNonconstMultiVector().ptr(),
345 nominal.set_x_dot_dot(xdotdot);
348 const int np =
model_->Np();
349 for (
int i=0; i<np; ++i)
350 nominal.set_p(i, me_nominal.get_p(i));
365evalModelImpl(
const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
366 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs)
const
368 typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
369 typedef Thyra::ModelEvaluatorBase MEB;
371 using Teuchos::rcp_dynamic_cast;
376 if (
sh_ != Teuchos::null) {
377 forward_t = inArgs.get_t();
395 RCP< const Thyra::MultiVectorBase<Scalar> > dxdp, dxdotdp, dxdotdotdp;
396 MEB::InArgs<Scalar> me_inArgs =
model_->getNominalValues();
397 dxdp = rcp_dynamic_cast<const DMVPV>(inArgs.get_x(),
true)->getMultiVector();
401 if (me_inArgs.supports(MEB::IN_ARG_x_dot)) {
402 if (inArgs.get_x_dot() != Teuchos::null) {
404 rcp_dynamic_cast<const DMVPV>(inArgs.get_x_dot(),
true)->getMultiVector();
412 me_inArgs.set_x_dot(Teuchos::null);
415 if (me_inArgs.supports(MEB::IN_ARG_x_dot_dot)) {
416 if (inArgs.get_x_dot_dot() != Teuchos::null) {
418 rcp_dynamic_cast<const DMVPV>(inArgs.get_x_dot_dot(),
true)->getMultiVector();
424 me_inArgs.set_x_dot_dot(Teuchos::null);
426 if (me_inArgs.supports(MEB::IN_ARG_t))
427 me_inArgs.set_t(forward_t);
428 if (me_inArgs.supports(MEB::IN_ARG_alpha))
429 me_inArgs.set_alpha(inArgs.get_alpha());
430 if (me_inArgs.supports(MEB::IN_ARG_beta))
431 me_inArgs.set_beta(inArgs.get_beta());
432 if (me_inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff))
433 me_inArgs.set_W_x_dot_dot_coeff(inArgs.get_W_x_dot_dot_coeff());
438 const int np = me_inArgs.Np();
439 for (
int i=0; i<np; ++i) {
440 if (inArgs.get_p(i) != Teuchos::null)
445 me_inArgs.set_p(i, inArgs.get_p(i));
449 RCP< Thyra::MultiVectorBase<Scalar> > dfdp;
450 MEB::OutArgs<Scalar> me_outArgs =
model_->createOutArgs();
451 if (outArgs.get_f() != Teuchos::null) {
452 dfdp = rcp_dynamic_cast<DMVPV>(outArgs.get_f(),
true)->getNonconstMultiVector();
461 me_outArgs.set_DfDp(
p_index_, dfdp);
464 if (outArgs.supports(MEB::OUT_ARG_W_op) &&
lo_ == Teuchos::null &&
465 outArgs.get_W_op() != Teuchos::null &&
467 RCP<Thyra::LinearOpBase<Scalar> > op = outArgs.get_W_op();
468 RCP<Thyra::MultiVectorLinearOp<Scalar> > mv_op =
469 rcp_dynamic_cast<Thyra::MultiVectorLinearOp<Scalar> >(op,
true);
470 me_outArgs.set_W_op(mv_op->getNonconstLinearOp());
472 for (
int j=
g_offset_; j<outArgs.Ng(); ++j) {
473 me_outArgs.set_g(j-
g_offset_, outArgs.get_g(j));
474 if (!me_outArgs.supports(MEB::OUT_ARG_DgDx_dot,j-
g_offset_).none())
475 me_outArgs.set_DgDx_dot(j-
g_offset_, outArgs.get_DgDx_dot(j));
476 if (!me_outArgs.supports(MEB::OUT_ARG_DgDx,j-
g_offset_).none())
477 me_outArgs.set_DgDx(j-
g_offset_, outArgs.get_DgDx(j));
478 for (
int l=0; l<outArgs.Np(); ++l)
479 if (!me_outArgs.supports(MEB::OUT_ARG_DgDp,j-
g_offset_,l).none())
480 me_outArgs.set_DgDp(j-
g_offset_, l, outArgs.get_DgDp(j,l));
482 if (
g_index_ >= 0 && outArgs.get_g(1) != Teuchos::null)
483 me_outArgs.set_g(
g_index_, outArgs.get_g(1));
486 model_->evalModel(me_inArgs, me_outArgs);
489 if (outArgs.supports(MEB::OUT_ARG_W_op) &&
lo_ == Teuchos::null &&
490 outArgs.get_W_op() != Teuchos::null &&
493 RCP<Thyra::LinearOpBase<Scalar> > op = outArgs.get_W_op();
494 RCP<Thyra::MultiVectorLinearOp<Scalar> > mv_op =
495 rcp_dynamic_cast<Thyra::MultiVectorLinearOp<Scalar> >(op,
true);
496 sens_me_outArgs.set_W_op(mv_op->getNonconstLinearOp());
508 Thyra::assign(dfdp.ptr(), *
my_dfdp_);
510 if (dxdp != Teuchos::null && dfdp != Teuchos::null) {
516 if (me_inArgs.supports(MEB::IN_ARG_alpha))
517 me_inArgs.set_alpha(0.0);
518 if (me_inArgs.supports(MEB::IN_ARG_beta))
519 me_inArgs.set_beta(1.0);
520 if (me_inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff))
521 me_inArgs.set_W_x_dot_dot_coeff(0.0);
526 my_dfdx_->apply(Thyra::NOTRANS, *dxdp, dfdp.ptr(), Scalar(1.0), Scalar(1.0));
528 if (dxdotdp != Teuchos::null && dfdp != Teuchos::null) {
534 if (me_inArgs.supports(MEB::IN_ARG_alpha))
535 me_inArgs.set_alpha(1.0);
536 if (me_inArgs.supports(MEB::IN_ARG_beta))
537 me_inArgs.set_beta(0.0);
538 if (me_inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff))
539 me_inArgs.set_W_x_dot_dot_coeff(0.0);
544 my_dfdxdot_->apply(Thyra::NOTRANS, *dxdotdp, dfdp.ptr(), Scalar(1.0), Scalar(1.0));
546 if (dxdotdotdp != Teuchos::null && dfdp != Teuchos::null) {
552 if (me_inArgs.supports(MEB::IN_ARG_alpha))
553 me_inArgs.set_alpha(0.0);
554 if (me_inArgs.supports(MEB::IN_ARG_beta))
555 me_inArgs.set_beta(0.0);
556 if (me_inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff))
557 me_inArgs.set_W_x_dot_dot_coeff(1.0);
562 my_dfdxdotdot_->apply(Thyra::NOTRANS, *dxdotdotdp, dfdp.ptr(), Scalar(1.0), Scalar(1.0));
566 if (
g_index_ >= 0 && outArgs.get_g(0) != Teuchos::null) {
567 MEB::OutArgs<Scalar> meo =
model_->createOutArgs();
568 RCP<Thyra::MultiVectorBase<Scalar> > dgdp =
569 rcp_dynamic_cast<DMVPV>(outArgs.get_g(0),
true)->getNonconstMultiVector();
570 RCP<Thyra::MultiVectorBase<Scalar> > dgdp_trans;
571 MEB::DerivativeSupport dgdp_support =
573 if (dgdp_support.supports(MEB::DERIV_MV_JACOBIAN_FORM))
575 MEB::Derivative<Scalar>(dgdp, MEB::DERIV_MV_JACOBIAN_FORM));
576 else if (dgdp_support.supports(MEB::DERIV_MV_GRADIENT_FORM)) {
580 MEB::Derivative<Scalar>(dgdp_trans, MEB::DERIV_MV_GRADIENT_FORM));
583 TEUCHOS_TEST_FOR_EXCEPTION(
584 true, std::logic_error,
585 "Operator form of dg/dp not supported for reduced sensitivity");
588 MEB::DerivativeSupport dgdx_support =
589 meo.supports(MEB::OUT_ARG_DgDx,
g_index_);
590 if (dgdx_support.supports(MEB::DERIV_LINEAR_OP)) {
595 else if (dgdx_support.supports(MEB::DERIV_MV_GRADIENT_FORM)) {
600 MEB::DERIV_MV_GRADIENT_FORM));
603 TEUCHOS_TEST_FOR_EXCEPTION(
604 true, std::logic_error,
605 "Jacobian form of dg/dx not supported for reduced sensitivity");
613 dxdp != Teuchos::null)
616 dxdotdp != Teuchos::null)
619 dxdotdotdp != Teuchos::null)
624 dxdp != Teuchos::null)
627 dxdotdp != Teuchos::null)
630 dxdotdotdp != Teuchos::null)
633 model_->evalModel(me_inArgs, meo);
636 if (dgdp_trans != Teuchos::null) {
637 Thyra::DetachedMultiVectorView<Scalar> dgdp_view(*dgdp);
638 Thyra::DetachedMultiVectorView<Scalar> dgdp_trans_view(*dgdp_trans);
641 dgdp_view(j,i) = dgdp_trans_view(i,j);
647 MEB::DerivativeSupport dgdx_support =
648 me_outArgs.supports(MEB::OUT_ARG_DgDx,
g_index_);
649 if (dgdx_support.supports(MEB::DERIV_LINEAR_OP)) {
650 my_dgdx_->apply(Thyra::NOTRANS, *dxdp, dgdp.ptr(), Scalar(1.0), Scalar(1.0));
652 else if (dgdx_support.supports(MEB::DERIV_MV_GRADIENT_FORM)) {
653 my_dgdx_mv_->apply(Thyra::TRANS, *dxdp, dgdp.ptr(), Scalar(1.0), Scalar(1.0));
656 TEUCHOS_TEST_FOR_EXCEPTION(
657 true, std::logic_error,
658 "Jacobian form of dg/dx not supported for reduced sensitivity");