9 #ifndef Tempus_StaggeredForwardSensitivityModelEvaluator_impl_hpp
10 #define Tempus_StaggeredForwardSensitivityModelEvaluator_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),
38 t_interp_(Teuchos::ScalarTraits<Scalar>::rmax())
40 typedef Thyra::ModelEvaluatorBase MEB;
43 Teuchos::RCP<Teuchos::ParameterList> pl =
44 Teuchos::rcp(
new Teuchos::ParameterList);
45 if (pList != Teuchos::null)
49 p_index_ = pl->get<
int>(
"Sensitivity Parameter Index");
60 MEB::InArgs<Scalar> me_inArgs =
model_->createInArgs();
61 MEB::InArgsSetup<Scalar> inArgs;
62 inArgs.setModelEvalDescription(this->description());
63 inArgs.setSupports(MEB::IN_ARG_x);
64 if (me_inArgs.supports(MEB::IN_ARG_x_dot))
65 inArgs.setSupports(MEB::IN_ARG_x_dot);
66 if (me_inArgs.supports(MEB::IN_ARG_t))
67 inArgs.setSupports(MEB::IN_ARG_t);
68 if (me_inArgs.supports(MEB::IN_ARG_alpha))
69 inArgs.setSupports(MEB::IN_ARG_alpha);
70 if (me_inArgs.supports(MEB::IN_ARG_beta))
71 inArgs.setSupports(MEB::IN_ARG_beta);
72 if (me_inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff))
73 inArgs.setSupports(MEB::IN_ARG_W_x_dot_dot_coeff);
76 inArgs.set_Np(me_inArgs.Np());
79 MEB::OutArgs<Scalar> me_outArgs =
model_->createOutArgs();
80 MEB::OutArgsSetup<Scalar> outArgs;
81 outArgs.setModelEvalDescription(this->description());
82 outArgs.set_Np_Ng(me_inArgs.Np(),me_outArgs.Ng());
83 outArgs.setSupports(MEB::OUT_ARG_f);
84 outArgs.setSupports(MEB::OUT_ARG_W_op);
85 for (
int j=0; j<me_outArgs.Ng(); ++j) {
86 outArgs.setSupports(MEB::OUT_ARG_DgDx_dot, j,
87 me_outArgs.supports(MEB::OUT_ARG_DgDx_dot, j));
88 outArgs.setSupports(MEB::OUT_ARG_DgDx, j,
89 me_outArgs.supports(MEB::OUT_ARG_DgDx, j));
90 for (
int l=0; l<me_outArgs.Np(); ++l) {
91 outArgs.setSupports(MEB::OUT_ARG_DgDp, j, l,
92 me_outArgs.supports(MEB::OUT_ARG_DgDp, j, l));
97 TEUCHOS_ASSERT(me_outArgs.supports(MEB::OUT_ARG_DfDp, p_index_).supports(MEB::DERIV_MV_JACOBIAN_FORM));
99 TEUCHOS_ASSERT(me_outArgs.supports(MEB::OUT_ARG_W_op));
102 template <
typename Scalar>
109 t_interp_ = Teuchos::ScalarTraits<Scalar>::rmax();
112 template <
typename Scalar>
122 template <
typename Scalar>
123 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
127 TEUCHOS_ASSERT(p < model_->Np());
128 return model_->get_p_space(p);
131 template <
typename Scalar>
132 Teuchos::RCP<const Teuchos::Array<std::string> >
136 TEUCHOS_ASSERT(p < model_->Np());
137 return model_->get_p_names(p);
140 template <
typename Scalar>
141 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
148 template <
typename Scalar>
149 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
156 template <
typename Scalar>
157 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
161 return model_->get_g_space(j);
164 template <
typename Scalar>
165 Teuchos::ArrayView<const std::string>
169 return model_->get_g_names(j);
172 template <
typename Scalar>
173 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
177 Teuchos::RCP<Thyra::LinearOpBase<Scalar> > op;
178 if (lo_ != Teuchos::null)
181 op = model_->create_W_op();
182 return Thyra::nonconstMultiVectorLinearOp(op, num_param_);
185 template <
typename Scalar>
186 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
190 return model_->create_DgDx_dot_op(j);
193 template <
typename Scalar>
194 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
198 return model_->create_DgDx_op(j);
201 template <
typename Scalar>
202 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
206 return model_->create_DgDp_op(j,l);
209 template <
typename Scalar>
210 Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> >
215 using Teuchos::rcp_dynamic_cast;
217 Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> > factory;
218 Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> > model_factory
219 = model_->get_W_factory();
220 if (model_factory == Teuchos::null)
221 return Teuchos::null;
222 if (po_ != Teuchos::null) {
224 Thyra::reuseLinearOpWithSolveFactory<Scalar>(model_factory, po_);
227 factory = model_factory;
228 return Thyra::multiVectorLinearOpWithSolveFactory(factory,
233 template <
typename Scalar>
234 Thyra::ModelEvaluatorBase::InArgs<Scalar>
238 return prototypeInArgs_;
241 template <
typename Scalar>
242 Thyra::ModelEvaluatorBase::InArgs<Scalar>
246 typedef Thyra::ModelEvaluatorBase MEB;
247 typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
249 using Teuchos::rcp_dynamic_cast;
251 MEB::InArgs<Scalar> me_nominal = model_->getNominalValues();
252 MEB::InArgs<Scalar> nominal = this->createInArgs();
254 const Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
257 RCP< Thyra::VectorBase<Scalar> > x = Thyra::createMember(*dxdp_space_);
258 RCP<DMVPV> dxdp = rcp_dynamic_cast<DMVPV>(x,
true);
259 if (dxdp_init_ == Teuchos::null)
260 Thyra::assign(dxdp->getNonconstMultiVector().ptr(), zero);
262 Thyra::assign(dxdp->getNonconstMultiVector().ptr(), *dxdp_init_);
266 if (me_nominal.supports(MEB::IN_ARG_x_dot)) {
267 RCP< Thyra::VectorBase<Scalar> > xdot = Thyra::createMember(*dxdp_space_);
268 RCP<DMVPV> dxdotdp = rcp_dynamic_cast<DMVPV>(xdot,
true);
269 if (dx_dotdp_init_ == Teuchos::null)
270 Thyra::assign(dxdotdp->getNonconstMultiVector().ptr(), zero);
272 Thyra::assign(dxdotdp->getNonconstMultiVector().ptr(), *dx_dotdp_init_);
273 nominal.set_x_dot(xdot);
277 if (me_nominal.supports(MEB::IN_ARG_x_dot_dot)) {
278 RCP< Thyra::VectorBase<Scalar> > xdotdot =
279 Thyra::createMember(*dxdp_space_);
280 RCP<DMVPV> dxdotdotdp = rcp_dynamic_cast<DMVPV>(xdotdot,
true);
281 if (dx_dotdotdp_init_ == Teuchos::null)
282 Thyra::assign(dxdotdotdp->getNonconstMultiVector().ptr(), zero);
284 Thyra::assign(dxdotdotdp->getNonconstMultiVector().ptr(),
286 nominal.set_x_dot_dot(xdotdot);
289 const int np = model_->Np();
290 for (
int i=0; i<np; ++i)
291 nominal.set_p(i, me_nominal.get_p(i));
295 template <
typename Scalar>
296 Thyra::ModelEvaluatorBase::OutArgs<Scalar>
300 return prototypeOutArgs_;
303 template <
typename Scalar>
307 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs)
const
309 typedef Thyra::ModelEvaluatorBase MEB;
310 typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
312 using Teuchos::rcp_dynamic_cast;
317 if (sh_ != Teuchos::null) {
318 forward_t = inArgs.get_t();
319 if (t_interp_ != forward_t) {
320 if (nc_forward_state_ == Teuchos::null)
321 nc_forward_state_ = sh_->interpolateState(forward_t);
323 sh_->interpolateState(forward_t, nc_forward_state_.get());
324 forward_state_ = nc_forward_state_;
325 t_interp_ = forward_t;
329 TEUCHOS_ASSERT(forward_state_ != Teuchos::null);
330 forward_t = forward_state_->getTime();
334 RCP< const Thyra::MultiVectorBase<Scalar> > dxdp, dxdotdp, dxdotdotdp;
335 MEB::InArgs<Scalar> me_inArgs = model_->getNominalValues();
336 dxdp = rcp_dynamic_cast<
const DMVPV>(inArgs.get_x(),
true)->getMultiVector();
337 me_inArgs.set_x(forward_state_->getX());
338 if (use_dfdp_as_tangent_)
339 me_inArgs.set_p(x_tangent_index_, inArgs.get_x());
340 if (me_inArgs.supports(MEB::IN_ARG_x_dot)) {
341 if (inArgs.get_x_dot() != Teuchos::null) {
343 rcp_dynamic_cast<
const DMVPV>(inArgs.get_x_dot(),
true)->getMultiVector();
344 me_inArgs.set_x_dot(forward_state_->getXDot());
345 if (use_dfdp_as_tangent_)
346 me_inArgs.set_p(xdot_tangent_index_, inArgs.get_x_dot());
351 me_inArgs.set_x_dot(Teuchos::null);
354 if (me_inArgs.supports(MEB::IN_ARG_x_dot_dot)) {
355 if (inArgs.get_x_dot_dot() != Teuchos::null) {
357 rcp_dynamic_cast<
const DMVPV>(inArgs.get_x_dot_dot(),
true)->getMultiVector();
358 me_inArgs.set_x_dot_dot(forward_state_->getXDotDot());
359 if (use_dfdp_as_tangent_)
360 me_inArgs.set_p(xdotdot_tangent_index_, inArgs.get_x_dot_dot());
363 me_inArgs.set_x_dot_dot(Teuchos::null);
365 if (me_inArgs.supports(MEB::IN_ARG_t))
366 me_inArgs.set_t(forward_t);
367 if (me_inArgs.supports(MEB::IN_ARG_alpha))
368 me_inArgs.set_alpha(inArgs.get_alpha());
369 if (me_inArgs.supports(MEB::IN_ARG_beta))
370 me_inArgs.set_beta(inArgs.get_beta());
371 if (me_inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff))
372 me_inArgs.set_W_x_dot_dot_coeff(inArgs.get_W_x_dot_dot_coeff());
377 const int np = me_inArgs.Np();
378 for (
int i=0; i<np; ++i) {
379 if (inArgs.get_p(i) != Teuchos::null)
380 if (!use_dfdp_as_tangent_ ||
381 (use_dfdp_as_tangent_ && i != x_tangent_index_ &&
382 i != xdot_tangent_index_ &&
383 i != xdotdot_tangent_index_ ))
384 me_inArgs.set_p(i, inArgs.get_p(i));
388 RCP< Thyra::MultiVectorBase<Scalar> > dfdp;
389 MEB::OutArgs<Scalar> me_outArgs = model_->createOutArgs();
390 if (outArgs.get_f() != Teuchos::null) {
391 dfdp = rcp_dynamic_cast<DMVPV>(outArgs.get_f(),
true)->getNonconstMultiVector();
392 me_outArgs.set_DfDp(p_index_, dfdp);
394 if (lo_ == Teuchos::null && outArgs.get_W_op() != Teuchos::null) {
395 RCP<Thyra::LinearOpBase<Scalar> > op = outArgs.get_W_op();
396 RCP<Thyra::MultiVectorLinearOp<Scalar> > mv_op =
398 me_outArgs.set_W_op(mv_op->getNonconstLinearOp());
400 for (
int j=0; j<outArgs.Ng(); ++j) {
401 if (!me_outArgs.supports(MEB::OUT_ARG_DgDx_dot,j).none())
402 me_outArgs.set_DgDx_dot(j, outArgs.get_DgDx_dot(j));
403 if (!me_outArgs.supports(MEB::OUT_ARG_DgDx,j).none())
404 me_outArgs.set_DgDx(j, outArgs.get_DgDx(j));
405 for (
int l=0; l<outArgs.Np(); ++l)
406 if (!me_outArgs.supports(MEB::OUT_ARG_DgDp,j,l).none())
407 me_outArgs.set_DgDp(j, l, outArgs.get_DgDp(j,l));
411 model_->evalModel(me_inArgs, me_outArgs);
418 if (!use_dfdp_as_tangent_) {
419 if (dxdp != Teuchos::null && dfdp != Teuchos::null) {
420 if (my_dfdx_ == Teuchos::null)
421 my_dfdx_ = model_->create_W_op();
422 MEB::OutArgs<Scalar> meo = model_->createOutArgs();
423 meo.set_W_op(my_dfdx_);
424 if (me_inArgs.supports(MEB::IN_ARG_alpha))
425 me_inArgs.set_alpha(0.0);
426 if (me_inArgs.supports(MEB::IN_ARG_beta))
427 me_inArgs.set_beta(1.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_dfdx_->apply(Thyra::NOTRANS, *dxdp, dfdp.ptr(), Scalar(1.0), Scalar(1.0));
433 if (dxdotdp != Teuchos::null && dfdp != Teuchos::null) {
434 if (my_dfdxdot_ == Teuchos::null)
435 my_dfdxdot_ = model_->create_W_op();
436 MEB::OutArgs<Scalar> meo = model_->createOutArgs();
437 meo.set_W_op(my_dfdxdot_);
438 if (me_inArgs.supports(MEB::IN_ARG_alpha))
439 me_inArgs.set_alpha(1.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(0.0);
444 model_->evalModel(me_inArgs, meo);
445 my_dfdxdot_->apply(Thyra::NOTRANS, *dxdotdp, dfdp.ptr(), Scalar(1.0), Scalar(1.0));
447 if (dxdotdotdp != Teuchos::null && dfdp != Teuchos::null) {
448 if (my_dfdxdotdot_ == Teuchos::null)
449 my_dfdxdotdot_ = model_->create_W_op();
450 MEB::OutArgs<Scalar> meo = model_->createOutArgs();
451 meo.set_W_op(my_dfdxdotdot_);
452 if (me_inArgs.supports(MEB::IN_ARG_alpha))
453 me_inArgs.set_alpha(0.0);
454 if (me_inArgs.supports(MEB::IN_ARG_beta))
455 me_inArgs.set_beta(0.0);
456 if (me_inArgs.supports(MEB::IN_ARG_W_x_dot_dot_coeff))
457 me_inArgs.set_W_x_dot_dot_coeff(1.0);
458 model_->evalModel(me_inArgs, meo);
459 my_dfdxdotdot_->apply(Thyra::NOTRANS, *dxdotdotdp, dfdp.ptr(), Scalar(1.0), Scalar(1.0));
464 template<
class Scalar>
465 Teuchos::RCP<const Teuchos::ParameterList>
469 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
470 pl->set<
bool>(
"Use DfDp as Tangent",
false);
471 pl->set<
int>(
"Sensitivity Parameter Index", 0);
472 pl->set<
int>(
"Sensitivity X Tangent Index", 1);
473 pl->set<
int>(
"Sensitivity X-Dot Tangent Index", 2);
474 pl->set<
int>(
"Sensitivity X-Dot-Dot Tangent Index", 3);
Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const
void setForwardSolutionHistory(const Teuchos::RCP< const Tempus::SolutionHistory< Scalar > > &sh)
Set solution history from forward state evaluation (for interpolation)
virtual void setForwardSolutionState(const Teuchos::RCP< const Tempus::SolutionState< Scalar > > &s)
Set solution state from forward state evaluation (for frozen state)
Teuchos::RCP< const Teuchos::Array< std::string > > get_p_names(int p) const
Teuchos::RCP< const Thyra::DefaultMultiVectorProductVectorSpace< Scalar > > dxdp_space_
static Teuchos::RCP< const Teuchos::ParameterList > getValidParameters()
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_p_space(int p) const
StaggeredForwardSensitivityModelEvaluator(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_DgDx_dot_op(int j) const
Teuchos::RCP< const Thyra::DefaultMultiVectorProductVectorSpace< Scalar > > dfdp_space_
int xdotdot_tangent_index_
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_DgDp_op(int j, int l) const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const
Implicit concrete LinearOpBase subclass that takes a flattended out multi-vector and performs a multi...
Thyra::ModelEvaluatorBase::InArgs< Scalar > prototypeInArgs_
Teuchos::RCP< const Thyra::LinearOpWithSolveFactoryBase< Scalar > > get_W_factory() const
Teuchos::ArrayView< const std::string > get_g_names(int j) const
bool use_dfdp_as_tangent_
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_W_op() const
Thyra::ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const
Thyra::ModelEvaluatorBase::OutArgs< Scalar > prototypeOutArgs_
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_DgDx_op(int j) const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_f_space() const
Solution state for integrators and steppers. SolutionState contains the metadata for solutions and th...
Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > model_
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_g_space(int j) const
void evalModelImpl(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const
Thyra::ModelEvaluatorBase::OutArgs< Scalar > createOutArgsImpl() const