27 const Teuchos::RCP<const Teuchos::ParameterList>& pList,
28 const Teuchos::RCP<MultiVector>& dxdp_init,
29 const Teuchos::RCP<MultiVector>& dx_dotdp_init,
30 const Teuchos::RCP<MultiVector>& dx_dotdotdp_init) :
48 typedef Thyra::ModelEvaluatorBase MEB;
51 Teuchos::RCP<Teuchos::ParameterList> pl =
52 Teuchos::rcp(
new Teuchos::ParameterList);
53 if (pList != Teuchos::null)
58 p_index_ = pl->get<
int>(
"Sensitivity Parameter Index");
59 g_index_ = pl->get<
int>(
"Response Function Index");
79 Thyra::multiVectorProductVectorSpace(
model_->get_g_space(
g_index_),
83 MEB::InArgs<Scalar> me_inArgs =
model_->createInArgs();
87 MEB::InArgsSetup<Scalar> inArgs;
88 inArgs.setModelEvalDescription(this->description());
89 inArgs.setSupports(MEB::IN_ARG_x);
90 if (me_inArgs.supports(MEB::IN_ARG_x_dot))
91 inArgs.setSupports(MEB::IN_ARG_x_dot);
92 if (me_inArgs.supports(MEB::IN_ARG_t))
93 inArgs.setSupports(MEB::IN_ARG_t);
94 if (me_inArgs.supports(MEB::IN_ARG_alpha))
95 inArgs.setSupports(MEB::IN_ARG_alpha);
96 if (me_inArgs.supports(MEB::IN_ARG_beta))
97 inArgs.setSupports(MEB::IN_ARG_beta);
98 if (me_inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff))
99 inArgs.setSupports(MEB::IN_ARG_W_x_dot_dot_coeff);
102 inArgs.set_Np(me_inArgs.Np());
105 MEB::OutArgs<Scalar> me_outArgs =
model_->createOutArgs();
108 MEB::OutArgsSetup<Scalar> outArgs;
109 outArgs.setModelEvalDescription(this->description());
110 outArgs.set_Np_Ng(me_outArgs.Np(),me_outArgs.Ng()+
g_offset_);
111 outArgs.setSupports(MEB::OUT_ARG_f);
112 if (sens_mer_outArgs.supports(MEB::OUT_ARG_W_op) ||
113 sens_mes_outArgs.supports(MEB::OUT_ARG_W_op))
114 outArgs.setSupports(MEB::OUT_ARG_W_op);
118 for (
int j=0; j<me_outArgs.Ng(); ++j) {
119 outArgs.setSupports(MEB::OUT_ARG_DgDx_dot, j+
g_offset_,
120 me_outArgs.supports(MEB::OUT_ARG_DgDx_dot, j));
121 outArgs.setSupports(MEB::OUT_ARG_DgDx, j+
g_offset_,
122 me_outArgs.supports(MEB::OUT_ARG_DgDx, j));
123 for (
int l=0; l<me_outArgs.Np(); ++l) {
124 outArgs.setSupports(MEB::OUT_ARG_DgDp, j+
g_offset_, l,
125 me_outArgs.supports(MEB::OUT_ARG_DgDp, j, l));
132 TEUCHOS_ASSERT(me_inArgs.supports(MEB::IN_ARG_x));
134 TEUCHOS_ASSERT(sens_mer_outArgs.supports(MEB::OUT_ARG_W_op));
135 if (me_inArgs.supports(MEB::IN_ARG_x_dot)) {
136 TEUCHOS_ASSERT(me_inArgs.supports(MEB::IN_ARG_alpha));
137 TEUCHOS_ASSERT(me_inArgs.supports(MEB::IN_ARG_beta));
139 TEUCHOS_ASSERT(me_outArgs.supports(MEB::OUT_ARG_DfDp,
p_index_).supports(MEB::DERIV_MV_JACOBIAN_FORM));
268 typedef Thyra::ModelEvaluatorBase MEB;
269 typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
271 using Teuchos::rcp_dynamic_cast;
272 using Teuchos::Range1D;
274 MEB::InArgs<Scalar> me_nominal =
model_->getNominalValues();
278 const Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
281 RCP< const Thyra::VectorBase<Scalar> > me_x = me_nominal.get_x();
282 if (me_x != Teuchos::null) {
283 RCP< Thyra::VectorBase<Scalar> > x = Thyra::createMember(*
x_dxdp_space_);
284 RCP<DMVPV> x_dxdp = rcp_dynamic_cast<DMVPV>(x,
true);
285 Thyra::assign(x_dxdp->getNonconstMultiVector()->col(0).ptr(), *me_x);
287 Thyra::assign(x_dxdp->getNonconstMultiVector()->subView(rng).ptr(),
290 Thyra::assign(x_dxdp->getNonconstMultiVector()->subView(rng).ptr(),
296 RCP< const Thyra::VectorBase<Scalar> > me_xdot;
297 if (me_nominal.supports(MEB::IN_ARG_x_dot))
298 me_xdot = me_nominal.get_x_dot();
299 if (me_xdot != Teuchos::null) {
300 RCP< Thyra::VectorBase<Scalar> > xdot = Thyra::createMember(*
x_dxdp_space_);
301 RCP<DMVPV> xdot_dxdp = rcp_dynamic_cast<DMVPV>(xdot,
true);
302 Thyra::assign(xdot_dxdp->getNonconstMultiVector()->col(0).ptr(), *me_xdot);
304 Thyra::assign(xdot_dxdp->getNonconstMultiVector()->subView(rng).ptr(),
307 Thyra::assign(xdot_dxdp->getNonconstMultiVector()->subView(rng).ptr(),
309 nominal.set_x_dot(xdot);
313 RCP< const Thyra::VectorBase<Scalar> > me_xdotdot;
314 if (me_nominal.supports(MEB::IN_ARG_x_dot_dot))
315 me_xdotdot = me_nominal.get_x_dot_dot();
316 if (me_xdotdot != Teuchos::null) {
317 RCP< Thyra::VectorBase<Scalar> > xdotdot =
319 RCP<DMVPV> xdotdot_dxdp = rcp_dynamic_cast<DMVPV>(xdotdot,
true);
320 Thyra::assign(xdotdot_dxdp->getNonconstMultiVector()->col(0).ptr(), *me_xdotdot);
322 Thyra::assign(xdotdot_dxdp->getNonconstMultiVector()->subView(rng).ptr(),
325 Thyra::assign(xdotdot_dxdp->getNonconstMultiVector()->subView(rng).ptr(),
327 nominal.set_x_dot_dot(xdotdot);
330 const int np =
model_->Np();
331 for (
int i=0; i<np; ++i)
332 nominal.set_p(i, me_nominal.get_p(i));
348evalModelImpl(
const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
349 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs)
const
351 typedef Thyra::ModelEvaluatorBase MEB;
352 typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
354 using Teuchos::rcp_dynamic_cast;
355 using Teuchos::Range1D;
360 RCP< const Thyra::VectorBase<Scalar> > x, xdot, xdotdot;
361 RCP< const Thyra::MultiVectorBase<Scalar> > dxdp, dxdotdp, dxdotdotdp;
362 RCP< const Thyra::VectorBase<Scalar> > dxdp_vec, dxdotdp_vec, dxdotdotdp_vec;
363 MEB::InArgs<Scalar> me_inArgs =
model_->getNominalValues();
364 RCP<const DMVPV> x_dxdp = rcp_dynamic_cast<const DMVPV>(inArgs.get_x(),
true);
365 x = x_dxdp->getMultiVector()->col(0);
366 dxdp = x_dxdp->getMultiVector()->subView(Range1D(1,
num_param_));
369 dxdp_vec = Thyra::multiVectorProductVector(
dxdp_space_, dxdp);
373 if (me_inArgs.supports(MEB::IN_ARG_x_dot)) {
374 if (inArgs.get_x_dot() != Teuchos::null) {
375 RCP<const DMVPV> xdot_dxdotdp =
376 rcp_dynamic_cast<const DMVPV>(inArgs.get_x_dot(),
true);
377 xdot = xdot_dxdotdp->getMultiVector()->col(0);
378 dxdotdp = xdot_dxdotdp->getMultiVector()->subView(Range1D(1,
num_param_));
379 me_inArgs.set_x_dot(xdot);
381 dxdotdp_vec = Thyra::multiVectorProductVector(
dxdp_space_, dxdotdp);
387 me_inArgs.set_x_dot(Teuchos::null);
389 if (me_inArgs.supports(MEB::IN_ARG_x_dot_dot)) {
390 if (inArgs.get_x_dot_dot() != Teuchos::null) {
391 RCP<const DMVPV> xdotdot_dxdotdotdp =
392 rcp_dynamic_cast<const DMVPV>(inArgs.get_x_dot_dot(),
true);
393 xdotdot = xdotdot_dxdotdotdp->getMultiVector()->col(0);
394 dxdotdotdp = xdotdot_dxdotdotdp->getMultiVector()->subView(Range1D(1,
num_param_));
395 me_inArgs.set_x_dot_dot(xdotdot);
398 Thyra::multiVectorProductVector(
dxdp_space_, dxdotdotdp);
404 me_inArgs.set_x_dot_dot(Teuchos::null);
406 if (me_inArgs.supports(MEB::IN_ARG_t))
407 me_inArgs.set_t(inArgs.get_t());
408 if (me_inArgs.supports(MEB::IN_ARG_alpha))
409 me_inArgs.set_alpha(inArgs.get_alpha());
410 if (me_inArgs.supports(MEB::IN_ARG_beta))
411 me_inArgs.set_beta(inArgs.get_beta());
412 if (me_inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff))
413 me_inArgs.set_W_x_dot_dot_coeff(inArgs.get_W_x_dot_dot_coeff());
418 const int np = me_inArgs.Np();
419 for (
int i=0; i<np; ++i) {
420 if (inArgs.get_p(i) != Teuchos::null)
425 me_inArgs.set_p(i, inArgs.get_p(i));
429 RCP< Thyra::VectorBase<Scalar> > f;
430 RCP< Thyra::MultiVectorBase<Scalar> > dfdp;
431 MEB::OutArgs<Scalar> me_outArgs =
model_->createOutArgs();
432 if (outArgs.get_f() != Teuchos::null) {
433 RCP<DMVPV> f_dfdp = rcp_dynamic_cast<DMVPV>(outArgs.get_f(),
true);
434 f = f_dfdp->getNonconstMultiVector()->col(0);
435 dfdp = f_dfdp->getNonconstMultiVector()->subView(Range1D(1,
num_param_));
437 me_outArgs.set_DfDp(
p_index_, dfdp);
439 if (outArgs.supports(MEB::OUT_ARG_W_op) &&
440 outArgs.get_W_op() != Teuchos::null &&
442 RCP< Thyra::LinearOpBase<Scalar> > op = outArgs.get_W_op();
443 RCP< Thyra::MultiVectorLinearOp<Scalar> > mv_op =
444 rcp_dynamic_cast< Thyra::MultiVectorLinearOp<Scalar> >(op,
true);
445 me_outArgs.set_W_op(mv_op->getNonconstLinearOp());
447 for (
int j=
g_offset_; j<outArgs.Ng(); ++j) {
448 if (!me_outArgs.supports(MEB::OUT_ARG_DgDx_dot,j-
g_offset_).none())
449 me_outArgs.set_DgDx_dot(j-
g_offset_, outArgs.get_DgDx_dot(j));
450 if (!me_outArgs.supports(MEB::OUT_ARG_DgDx,j-
g_offset_).none())
451 me_outArgs.set_DgDx(j-
g_offset_, outArgs.get_DgDx(j));
452 for (
int l=0; l<outArgs.Np(); ++l)
453 if (!me_outArgs.supports(MEB::OUT_ARG_DgDp,j-
g_offset_,l).none())
454 me_outArgs.set_DgDp(j-
g_offset_, l, outArgs.get_DgDp(j,l));
456 if (
g_index_ >= 0 && outArgs.get_g(1) != Teuchos::null)
457 me_outArgs.set_g(
g_index_, outArgs.get_g(1));
460 model_->evalModel(me_inArgs, me_outArgs);
463 if (outArgs.supports(MEB::OUT_ARG_W_op) &&
464 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 sens_me_outArgs.set_W_op(mv_op->getNonconstLinearOp());
478 if (dxdp != Teuchos::null && dfdp != Teuchos::null) {
483 if (me_inArgs.supports(MEB::IN_ARG_alpha))
484 me_inArgs.set_alpha(0.0);
485 if (me_inArgs.supports(MEB::IN_ARG_beta))
486 me_inArgs.set_beta(1.0);
487 if (me_inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff))
488 me_inArgs.set_W_x_dot_dot_coeff(0.0);
490 my_dfdx_->apply(Thyra::NOTRANS, *dxdp, dfdp.ptr(), Scalar(1.0), Scalar(1.0));
492 if (dxdotdp != Teuchos::null && dfdp != Teuchos::null) {
497 if (me_inArgs.supports(MEB::IN_ARG_alpha))
498 me_inArgs.set_alpha(1.0);
499 if (me_inArgs.supports(MEB::IN_ARG_beta))
500 me_inArgs.set_beta(0.0);
501 if (me_inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff))
502 me_inArgs.set_W_x_dot_dot_coeff(0.0);
504 my_dfdxdot_->apply(Thyra::NOTRANS, *dxdotdp, dfdp.ptr(), Scalar(1.0), Scalar(1.0));
506 if (dxdotdotdp != Teuchos::null && dfdp != Teuchos::null) {
511 if (me_inArgs.supports(MEB::IN_ARG_alpha))
512 me_inArgs.set_alpha(0.0);
513 if (me_inArgs.supports(MEB::IN_ARG_beta))
514 me_inArgs.set_beta(0.0);
515 if (me_inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff))
516 me_inArgs.set_W_x_dot_dot_coeff(1.0);
518 my_dfdxdotdot_->apply(Thyra::NOTRANS, *dxdotdotdp, dfdp.ptr(), Scalar(1.0), Scalar(1.0));
523 if (
g_index_ >= 0 && outArgs.get_g(0) != Teuchos::null) {
524 MEB::OutArgs<Scalar> meo =
model_->createOutArgs();
525 RCP<Thyra::MultiVectorBase<Scalar> > dgdp =
526 rcp_dynamic_cast<DMVPV>(outArgs.get_g(0),
true)->getNonconstMultiVector();
527 RCP<Thyra::MultiVectorBase<Scalar> > dgdp_trans;
528 MEB::DerivativeSupport dgdp_support =
530 if (dgdp_support.supports(MEB::DERIV_MV_JACOBIAN_FORM))
532 MEB::Derivative<Scalar>(dgdp, MEB::DERIV_MV_JACOBIAN_FORM));
533 else if (dgdp_support.supports(MEB::DERIV_MV_GRADIENT_FORM)) {
537 MEB::Derivative<Scalar>(dgdp_trans, MEB::DERIV_MV_GRADIENT_FORM));
540 TEUCHOS_TEST_FOR_EXCEPTION(
541 true, std::logic_error,
542 "Operator form of dg/dp not supported for reduced sensitivity");
545 MEB::DerivativeSupport dgdx_support =
546 meo.supports(MEB::OUT_ARG_DgDx,
g_index_);
547 if (dgdx_support.supports(MEB::DERIV_LINEAR_OP)) {
552 else if (dgdx_support.supports(MEB::DERIV_MV_GRADIENT_FORM)) {
557 MEB::DERIV_MV_GRADIENT_FORM));
560 TEUCHOS_TEST_FOR_EXCEPTION(
561 true, std::logic_error,
562 "Jacobian form of dg/dx not supported for reduced sensitivity");
568 dxdp_vec != Teuchos::null)
571 dxdotdp_vec != Teuchos::null)
574 dxdotdotdp_vec != Teuchos::null)
579 dxdp_vec != Teuchos::null)
582 dxdotdp_vec != Teuchos::null)
585 dxdotdotdp_vec != Teuchos::null)
588 model_->evalModel(me_inArgs, meo);
591 if (dgdp_trans != Teuchos::null) {
592 Thyra::DetachedMultiVectorView<Scalar> dgdp_view(*dgdp);
593 Thyra::DetachedMultiVectorView<Scalar> dgdp_trans_view(*dgdp_trans);
596 dgdp_view(j,i) = dgdp_trans_view(i,j);
602 MEB::DerivativeSupport dgdx_support =
603 meo.supports(MEB::OUT_ARG_DgDx,
g_index_);
604 if (dgdx_support.supports(MEB::DERIV_LINEAR_OP))
605 my_dgdx_->apply(Thyra::NOTRANS, *dxdp, dgdp.ptr(), Scalar(1.0), Scalar(1.0));
606 else if (dgdx_support.supports(MEB::DERIV_MV_GRADIENT_FORM))
607 my_dgdx_mv_->apply(Thyra::TRANS, *dxdp, dgdp.ptr(), Scalar(1.0), Scalar(1.0));
609 TEUCHOS_TEST_FOR_EXCEPTION(
610 true, std::logic_error,
611 "Jacobian form of dg/dx not supported for reduced sensitivity");