9 #ifndef Tempus_CombinedForwardSensitivityModelEvaluator_impl_hpp
10 #define Tempus_CombinedForwardSensitivityModelEvaluator_impl_hpp
12 #include "Thyra_DefaultMultiVectorProductVector.hpp"
16 #include "Thyra_VectorStdOps.hpp"
17 #include "Thyra_MultiVectorStdOps.hpp"
21 template <
typename Scalar>
24 const Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> > & model,
25 const Teuchos::RCP<const Teuchos::ParameterList>& pList,
26 const Teuchos::RCP<MultiVector>& dxdp_init,
27 const Teuchos::RCP<MultiVector>& dx_dotdp_init,
28 const Teuchos::RCP<MultiVector>& dx_dotdotdp_init) :
30 dxdp_init_(dxdp_init),
31 dx_dotdp_init_(dx_dotdp_init),
32 dx_dotdotdp_init_(dx_dotdotdp_init),
35 xdot_tangent_index_(2),
36 xdotdot_tangent_index_(3),
37 use_dfdp_as_tangent_(false)
39 typedef Thyra::ModelEvaluatorBase MEB;
42 Teuchos::RCP<Teuchos::ParameterList> pl =
43 Teuchos::rcp(
new Teuchos::ParameterList);
44 if (pList != Teuchos::null)
48 p_index_ = pl->get<
int>(
"Sensitivity Parameter Index");
57 Thyra::multiVectorProductVectorSpace(
model_->get_x_space(), num_param_+1);
61 Thyra::multiVectorProductVectorSpace(
model_->get_f_space(), num_param_+1);
63 MEB::InArgs<Scalar> me_inArgs =
model_->createInArgs();
64 MEB::InArgsSetup<Scalar> inArgs;
65 inArgs.setModelEvalDescription(this->description());
66 inArgs.setSupports(MEB::IN_ARG_x);
67 if (me_inArgs.supports(MEB::IN_ARG_x_dot))
68 inArgs.setSupports(MEB::IN_ARG_x_dot);
69 if (me_inArgs.supports(MEB::IN_ARG_t))
70 inArgs.setSupports(MEB::IN_ARG_t);
71 if (me_inArgs.supports(MEB::IN_ARG_alpha))
72 inArgs.setSupports(MEB::IN_ARG_alpha);
73 if (me_inArgs.supports(MEB::IN_ARG_beta))
74 inArgs.setSupports(MEB::IN_ARG_beta);
75 if (me_inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff))
76 inArgs.setSupports(MEB::IN_ARG_W_x_dot_dot_coeff);
79 inArgs.set_Np(me_inArgs.Np());
82 MEB::OutArgs<Scalar> me_outArgs =
model_->createOutArgs();
83 MEB::OutArgsSetup<Scalar> outArgs;
84 outArgs.setModelEvalDescription(this->description());
85 outArgs.set_Np_Ng(me_outArgs.Np(),me_outArgs.Ng());
86 outArgs.setSupports(MEB::OUT_ARG_f);
87 if (me_outArgs.supports(MEB::OUT_ARG_W_op))
88 outArgs.setSupports(MEB::OUT_ARG_W_op);
89 for (
int j=0; j<me_outArgs.Ng(); ++j) {
90 outArgs.setSupports(MEB::OUT_ARG_DgDx_dot, j,
91 me_outArgs.supports(MEB::OUT_ARG_DgDx_dot, j));
92 outArgs.setSupports(MEB::OUT_ARG_DgDx, j,
93 me_outArgs.supports(MEB::OUT_ARG_DgDx, j));
94 for (
int l=0; l<me_outArgs.Np(); ++l) {
95 outArgs.setSupports(MEB::OUT_ARG_DgDp, j, l,
96 me_outArgs.supports(MEB::OUT_ARG_DgDp, j, l));
101 TEUCHOS_ASSERT(me_outArgs.supports(MEB::OUT_ARG_DfDp, p_index_).supports(MEB::DERIV_MV_JACOBIAN_FORM));
103 TEUCHOS_ASSERT(me_outArgs.supports(MEB::OUT_ARG_W_op));
106 template <
typename Scalar>
107 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
111 return model_->get_p_space(p);
114 template <
typename Scalar>
115 Teuchos::RCP<const Teuchos::Array<std::string> >
119 return model_->get_p_names(p);
122 template <
typename Scalar>
123 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
127 return x_dxdp_space_;
130 template <
typename Scalar>
131 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
135 return f_dfdp_space_;
138 template <
typename Scalar>
139 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
143 return model_->get_g_space(j);
146 template <
typename Scalar>
147 Teuchos::ArrayView<const std::string>
151 return model_->get_g_names(j);
154 template <
typename Scalar>
155 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
159 Teuchos::RCP<Thyra::LinearOpBase<Scalar> > op = model_->create_W_op();
160 return Thyra::nonconstMultiVectorLinearOp(op, num_param_+1);
163 template <
typename Scalar>
164 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
168 return model_->create_DgDx_dot_op(j);
171 template <
typename Scalar>
172 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
176 return model_->create_DgDx_op(j);
179 template <
typename Scalar>
180 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
184 return model_->create_DgDp_op(j,l);
187 template <
typename Scalar>
188 Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> >
192 Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> > factory =
193 model_->get_W_factory();
194 if (factory == Teuchos::null)
195 return Teuchos::null;
197 return Thyra::multiVectorLinearOpWithSolveFactory(factory,
202 template <
typename Scalar>
203 Thyra::ModelEvaluatorBase::InArgs<Scalar>
207 return prototypeInArgs_;
210 template <
typename Scalar>
211 Thyra::ModelEvaluatorBase::InArgs<Scalar>
215 typedef Thyra::ModelEvaluatorBase MEB;
216 typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
218 using Teuchos::rcp_dynamic_cast;
219 using Teuchos::Range1D;
221 MEB::InArgs<Scalar> me_nominal = model_->getNominalValues();
222 MEB::InArgs<Scalar> nominal = this->createInArgs();
224 const Teuchos::Range1D rng(1,num_param_);
225 const Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
228 RCP< const Thyra::VectorBase<Scalar> > me_x = me_nominal.get_x();
229 if (me_x != Teuchos::null) {
230 RCP< Thyra::VectorBase<Scalar> > x = Thyra::createMember(*x_dxdp_space_);
231 RCP<DMVPV> x_dxdp = rcp_dynamic_cast<DMVPV>(x,
true);
232 Thyra::assign(x_dxdp->getNonconstMultiVector()->col(0).ptr(), *me_x);
233 if (dxdp_init_ == Teuchos::null)
234 Thyra::assign(x_dxdp->getNonconstMultiVector()->subView(rng).ptr(),
237 Thyra::assign(x_dxdp->getNonconstMultiVector()->subView(rng).ptr(),
243 RCP< const Thyra::VectorBase<Scalar> > me_xdot;
244 if (me_nominal.supports(MEB::IN_ARG_x_dot))
245 me_xdot = me_nominal.get_x_dot();
246 if (me_xdot != Teuchos::null) {
247 RCP< Thyra::VectorBase<Scalar> > xdot = Thyra::createMember(*x_dxdp_space_);
248 RCP<DMVPV> xdot_dxdp = rcp_dynamic_cast<DMVPV>(xdot,
true);
249 Thyra::assign(xdot_dxdp->getNonconstMultiVector()->col(0).ptr(), *me_xdot);
250 if (dx_dotdp_init_ == Teuchos::null)
251 Thyra::assign(xdot_dxdp->getNonconstMultiVector()->subView(rng).ptr(),
254 Thyra::assign(xdot_dxdp->getNonconstMultiVector()->subView(rng).ptr(),
256 nominal.set_x_dot(xdot);
260 RCP< const Thyra::VectorBase<Scalar> > me_xdotdot;
261 if (me_nominal.supports(MEB::IN_ARG_x_dot_dot))
262 me_xdotdot = me_nominal.get_x_dot_dot();
263 if (me_xdotdot != Teuchos::null) {
264 RCP< Thyra::VectorBase<Scalar> > xdotdot =
265 Thyra::createMember(*x_dxdp_space_);
266 RCP<DMVPV> xdotdot_dxdp = rcp_dynamic_cast<DMVPV>(xdotdot,
true);
267 Thyra::assign(xdotdot_dxdp->getNonconstMultiVector()->col(0).ptr(), *me_xdotdot);
268 if (dx_dotdotdp_init_ == Teuchos::null)
269 Thyra::assign(xdotdot_dxdp->getNonconstMultiVector()->subView(rng).ptr(),
272 Thyra::assign(xdotdot_dxdp->getNonconstMultiVector()->subView(rng).ptr(),
274 nominal.set_x_dot_dot(xdotdot);
277 const int np = model_->Np();
278 for (
int i=0; i<np; ++i)
279 nominal.set_p(i, me_nominal.get_p(i));
284 template <
typename Scalar>
285 Thyra::ModelEvaluatorBase::OutArgs<Scalar>
289 return prototypeOutArgs_;
292 template <
typename Scalar>
296 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs)
const
298 typedef Thyra::ModelEvaluatorBase MEB;
299 typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
301 using Teuchos::rcp_dynamic_cast;
302 using Teuchos::Range1D;
305 RCP< const Thyra::VectorBase<Scalar> > x, xdot, xdotdot;
306 RCP< const Thyra::MultiVectorBase<Scalar> > dxdp, dxdotdp, dxdotdotdp;
307 MEB::InArgs<Scalar> me_inArgs = model_->getNominalValues();
308 RCP<const DMVPV> x_dxdp = rcp_dynamic_cast<
const DMVPV>(inArgs.get_x(),
true);
309 x = x_dxdp->getMultiVector()->col(0);
310 dxdp = x_dxdp->getMultiVector()->subView(Range1D(1,num_param_));
312 if (use_dfdp_as_tangent_) {
313 RCP< const Thyra::VectorBase<Scalar> > dxdp_vec =
314 Thyra::multiVectorProductVector(dxdp_space_, dxdp);
315 me_inArgs.set_p(x_tangent_index_, dxdp_vec);
317 if (me_inArgs.supports(MEB::IN_ARG_x_dot)) {
318 if (inArgs.get_x_dot() != Teuchos::null) {
319 RCP<const DMVPV> xdot_dxdotdp =
320 rcp_dynamic_cast<
const DMVPV>(inArgs.get_x_dot(),
true);
321 xdot = xdot_dxdotdp->getMultiVector()->col(0);
322 dxdotdp = xdot_dxdotdp->getMultiVector()->subView(Range1D(1,num_param_));
323 me_inArgs.set_x_dot(xdot);
324 if (use_dfdp_as_tangent_) {
325 RCP< const Thyra::VectorBase<Scalar> > dxdotdp_vec =
326 Thyra::multiVectorProductVector(dxdp_space_, dxdotdp);
327 me_inArgs.set_p(xdot_tangent_index_, dxdotdp_vec);
331 me_inArgs.set_x_dot(Teuchos::null);
333 if (me_inArgs.supports(MEB::IN_ARG_x_dot_dot)) {
334 if (inArgs.get_x_dot_dot() != Teuchos::null) {
335 RCP<const DMVPV> xdotdot_dxdotdotdp =
336 rcp_dynamic_cast<
const DMVPV>(inArgs.get_x_dot_dot(),
true);
337 xdotdot = xdotdot_dxdotdotdp->getMultiVector()->col(0);
338 dxdotdotdp = xdotdot_dxdotdotdp->getMultiVector()->subView(Range1D(1,num_param_));
339 me_inArgs.set_x_dot_dot(xdotdot);
340 if (use_dfdp_as_tangent_) {
341 RCP< const Thyra::VectorBase<Scalar> > dxdotdotdp_vec =
342 Thyra::multiVectorProductVector(dxdp_space_, dxdotdotdp);
343 me_inArgs.set_p(xdotdot_tangent_index_, dxdotdotdp_vec);
347 me_inArgs.set_x_dot_dot(Teuchos::null);
349 if (me_inArgs.supports(MEB::IN_ARG_t))
350 me_inArgs.set_t(inArgs.get_t());
351 if (me_inArgs.supports(MEB::IN_ARG_alpha))
352 me_inArgs.set_alpha(inArgs.get_alpha());
353 if (me_inArgs.supports(MEB::IN_ARG_beta))
354 me_inArgs.set_beta(inArgs.get_beta());
355 if (me_inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff))
356 me_inArgs.set_W_x_dot_dot_coeff(inArgs.get_W_x_dot_dot_coeff());
361 const int np = me_inArgs.Np();
362 for (
int i=0; i<np; ++i) {
363 if (inArgs.get_p(i) != Teuchos::null)
364 if (!use_dfdp_as_tangent_ ||
365 (use_dfdp_as_tangent_ && i != x_tangent_index_ &&
366 i != xdot_tangent_index_ &&
367 i != xdotdot_tangent_index_ ))
368 me_inArgs.set_p(i, inArgs.get_p(i));
372 RCP< Thyra::VectorBase<Scalar> > f;
373 RCP< Thyra::MultiVectorBase<Scalar> > dfdp;
374 MEB::OutArgs<Scalar> me_outArgs = model_->createOutArgs();
375 if (outArgs.get_f() != Teuchos::null) {
376 RCP<DMVPV> f_dfdp = rcp_dynamic_cast<DMVPV>(outArgs.get_f(),
true);
377 f = f_dfdp->getNonconstMultiVector()->col(0);
378 dfdp = f_dfdp->getNonconstMultiVector()->subView(Range1D(1,num_param_));
380 me_outArgs.set_DfDp(p_index_, dfdp);
382 if (outArgs.get_W_op() != Teuchos::null) {
383 RCP< Thyra::LinearOpBase<Scalar> > op = outArgs.get_W_op();
384 RCP< Thyra::MultiVectorLinearOp<Scalar> > mv_op =
386 me_outArgs.set_W_op(mv_op->getNonconstLinearOp());
388 for (
int j=0; j<outArgs.Ng(); ++j) {
389 if (!me_outArgs.supports(MEB::OUT_ARG_DgDx_dot,j).none())
390 me_outArgs.set_DgDx_dot(j, outArgs.get_DgDx_dot(j));
391 if (!me_outArgs.supports(MEB::OUT_ARG_DgDx,j).none())
392 me_outArgs.set_DgDx(j, outArgs.get_DgDx(j));
393 for (
int l=0; l<outArgs.Np(); ++l)
394 if (!me_outArgs.supports(MEB::OUT_ARG_DgDp,j,l).none())
395 me_outArgs.set_DgDp(j, l, outArgs.get_DgDp(j,l));
399 model_->evalModel(me_inArgs, me_outArgs);
404 if (!use_dfdp_as_tangent_) {
405 if (dxdp != Teuchos::null && dfdp != Teuchos::null) {
406 if (my_dfdx_ == Teuchos::null)
407 my_dfdx_ = model_->create_W_op();
408 MEB::OutArgs<Scalar> meo = model_->createOutArgs();
409 meo.set_W_op(my_dfdx_);
410 if (me_inArgs.supports(MEB::IN_ARG_alpha))
411 me_inArgs.set_alpha(0.0);
412 if (me_inArgs.supports(MEB::IN_ARG_beta))
413 me_inArgs.set_beta(1.0);
414 if (me_inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff))
415 me_inArgs.set_W_x_dot_dot_coeff(0.0);
416 model_->evalModel(me_inArgs, meo);
417 my_dfdx_->apply(Thyra::NOTRANS, *dxdp, dfdp.ptr(), Scalar(1.0), Scalar(1.0));
419 if (dxdotdp != Teuchos::null && dfdp != Teuchos::null) {
420 if (my_dfdxdot_ == Teuchos::null)
421 my_dfdxdot_ = model_->create_W_op();
422 MEB::OutArgs<Scalar> meo = model_->createOutArgs();
423 meo.set_W_op(my_dfdxdot_);
424 if (me_inArgs.supports(MEB::IN_ARG_alpha))
425 me_inArgs.set_alpha(1.0);
426 if (me_inArgs.supports(MEB::IN_ARG_beta))
427 me_inArgs.set_beta(0.0);
428 if (me_inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff))
429 me_inArgs.set_W_x_dot_dot_coeff(0.0);
430 model_->evalModel(me_inArgs, meo);
431 my_dfdxdot_->apply(Thyra::NOTRANS, *dxdotdp, dfdp.ptr(), Scalar(1.0), Scalar(1.0));
433 if (dxdotdotdp != Teuchos::null && dfdp != Teuchos::null) {
434 if (my_dfdxdotdot_ == Teuchos::null)
435 my_dfdxdotdot_ = model_->create_W_op();
436 MEB::OutArgs<Scalar> meo = model_->createOutArgs();
437 meo.set_W_op(my_dfdxdotdot_);
438 if (me_inArgs.supports(MEB::IN_ARG_alpha))
439 me_inArgs.set_alpha(0.0);
440 if (me_inArgs.supports(MEB::IN_ARG_beta))
441 me_inArgs.set_beta(0.0);
442 if (me_inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff))
443 me_inArgs.set_W_x_dot_dot_coeff(1.0);
444 model_->evalModel(me_inArgs, meo);
445 my_dfdxdotdot_->apply(Thyra::NOTRANS, *dxdotdotdp, dfdp.ptr(), Scalar(1.0), Scalar(1.0));
450 template<
class Scalar>
451 Teuchos::RCP<const Teuchos::ParameterList>
455 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
456 pl->set<
bool>(
"Use DfDp as Tangent",
false);
457 pl->set<
int>(
"Sensitivity Parameter Index", 0);
458 pl->set<
int>(
"Sensitivity X Tangent Index", 1);
459 pl->set<
int>(
"Sensitivity X-Dot Tangent Index", 2);
460 pl->set<
int>(
"Sensitivity X-Dot-Dot Tangent Index", 3);
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_p_space(int p) const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_g_space(int j) const
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_DgDx_dot_op(int j) const
Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const
Teuchos::RCP< const Thyra::DefaultMultiVectorProductVectorSpace< Scalar > > dxdp_space_
Teuchos::RCP< const Teuchos::Array< std::string > > get_p_names(int p) const
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_DgDp_op(int j, int l) const
Thyra::ModelEvaluatorBase::InArgs< Scalar > prototypeInArgs_
static Teuchos::RCP< const Teuchos::ParameterList > getValidParameters()
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const
Teuchos::RCP< const Thyra::DefaultMultiVectorProductVectorSpace< Scalar > > x_dxdp_space_
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_DgDx_op(int j) const
Teuchos::RCP< const Thyra::DefaultMultiVectorProductVectorSpace< Scalar > > f_dfdp_space_
Thyra::ModelEvaluatorBase::OutArgs< Scalar > createOutArgsImpl() const
Thyra::ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const
Teuchos::ArrayView< const std::string > get_g_names(int j) const
void evalModelImpl(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const
Teuchos::RCP< const Thyra::DefaultMultiVectorProductVectorSpace< Scalar > > dfdp_space_
Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > model_
int xdotdot_tangent_index_
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...
bool use_dfdp_as_tangent_
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_f_space() const
CombinedForwardSensitivityModelEvaluator(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, const Teuchos::RCP< const Teuchos::ParameterList > &pList=Teuchos::null, const Teuchos::RCP< MultiVector > &dxdp_init=Teuchos::null, const Teuchos::RCP< MultiVector > &dx_dotdp_init=Teuchos::null, const Teuchos::RCP< MultiVector > &dx_dotdot_dp_init=Teuchos::null)
Constructor.
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_W_op() const
Thyra::ModelEvaluatorBase::OutArgs< Scalar > prototypeOutArgs_