Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
Tempus_AdjointAuxSensitivityModelEvaluator_impl.hpp
Go to the documentation of this file.
1//@HEADER
2// *****************************************************************************
3// Tempus: Time Integration and Sensitivity Analysis Package
4//
5// Copyright 2017 NTESS and the Tempus contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8//@HEADER
9
10#ifndef Tempus_AdjointAuxSensitivityModelEvaluator_impl_hpp
11#define Tempus_AdjointAuxSensitivityModelEvaluator_impl_hpp
12
17#include "Thyra_DefaultBlockedLinearOp.hpp"
19#include "Thyra_VectorStdOps.hpp"
20#include "Thyra_MultiVectorStdOps.hpp"
21
22namespace Tempus {
23
24template <typename Scalar>
27 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& model,
28 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& adjoint_model,
29 const Scalar& t_init, const Scalar& t_final,
30 const Teuchos::RCP<const Teuchos::ParameterList>& pList)
31 : model_(model),
32 adjoint_model_(adjoint_model),
33 t_init_(t_init),
34 t_final_(t_final),
36 dgdx_dot_checked_(false),
37 t_interp_(Teuchos::ScalarTraits<Scalar>::rmax())
38{
39 using Teuchos::Array;
40 using Teuchos::RCP;
41 using Thyra::VectorSpaceBase;
42 typedef Thyra::ModelEvaluatorBase MEB;
43
44 // Set parameters
45 Teuchos::RCP<Teuchos::ParameterList> pl =
46 Teuchos::rcp(new Teuchos::ParameterList);
47 if (pList != Teuchos::null) *pl = *pList;
48 pl->validateParametersAndSetDefaults(*this->getValidParameters());
49 mass_matrix_is_constant_ = pl->get<bool>("Mass Matrix Is Constant");
50 mass_matrix_is_identity_ = pl->get<bool>("Mass Matrix Is Identity");
51 p_index_ = pl->get<int>("Sensitivity Parameter Index", 0);
52 g_index_ = pl->get<int>("Response Function Index", 0);
53 num_adjoint_ = model_->get_g_space(g_index_)->dim();
55 pl->get<std::string>("Response Type"));
56 g_depends_on_p_ = pl->get<bool>("Response Depends on Parameters");
57 f_depends_on_p_ = pl->get<bool>("Residual Depends on Parameters");
58
59 // We currently do not support a non-constant mass matrix
60 TEUCHOS_TEST_FOR_EXCEPTION(
61 mass_matrix_is_constant_ == false, std::logic_error,
62 "AdjointAuxSensitivityModelEvaluator currently does not support "
63 << "non-constant mass matrix df/dx_dot!");
64
66 Thyra::multiVectorProductVectorSpace(model_->get_f_space(), num_adjoint_);
68 Thyra::multiVectorProductVectorSpace(model_->get_x_space(), num_adjoint_);
69 response_space_ = Thyra::multiVectorProductVectorSpace(
70 model_->get_p_space(p_index_), num_adjoint_);
71 Array<RCP<const VectorSpaceBase<Scalar> > > x_spaces(2);
72 Array<RCP<const VectorSpaceBase<Scalar> > > f_spaces(2);
73 x_spaces[0] = adjoint_space_;
74 x_spaces[1] = response_space_;
75 f_spaces[0] = residual_space_;
76 f_spaces[1] = response_space_;
77 x_prod_space_ = Thyra::productVectorSpace(x_spaces());
78 f_prod_space_ = Thyra::productVectorSpace(f_spaces());
79
80 // forward and adjoint models must support same InArgs
81 MEB::InArgs<Scalar> me_inArgs = model_->createInArgs();
82 me_inArgs.assertSameSupport(adjoint_model_->createInArgs());
83
84 MEB::InArgsSetup<Scalar> inArgs;
85 inArgs.setModelEvalDescription(this->description());
86 inArgs.setSupports(MEB::IN_ARG_x);
87 inArgs.setSupports(MEB::IN_ARG_t);
88 if (me_inArgs.supports(MEB::IN_ARG_x_dot))
89 inArgs.setSupports(MEB::IN_ARG_x_dot);
90 inArgs.setSupports(MEB::IN_ARG_alpha);
91 inArgs.setSupports(MEB::IN_ARG_beta);
92
93 // Support additional parameters for x and xdot
94 inArgs.set_Np(me_inArgs.Np());
95 prototypeInArgs_ = inArgs;
96
97 MEB::OutArgs<Scalar> me_outArgs = model_->createOutArgs();
98 MEB::OutArgs<Scalar> adj_me_outArgs = adjoint_model_->createOutArgs();
99 MEB::OutArgsSetup<Scalar> outArgs;
100 outArgs.setModelEvalDescription(this->description());
101 outArgs.set_Np_Ng(me_inArgs.Np(), 0);
102 outArgs.setSupports(MEB::OUT_ARG_f);
103 outArgs.setSupports(MEB::OUT_ARG_W_op);
104 prototypeOutArgs_ = outArgs;
105
106 // Adjoint ME must support W_op to define adjoint ODE/DAE.
107 // Must support alpha, beta if it suports x_dot
108 TEUCHOS_ASSERT(me_inArgs.supports(MEB::IN_ARG_x));
109 TEUCHOS_ASSERT(adj_me_outArgs.supports(MEB::OUT_ARG_W_op));
110 if (me_inArgs.supports(MEB::IN_ARG_x_dot)) {
111 TEUCHOS_ASSERT(me_inArgs.supports(MEB::IN_ARG_alpha));
112 TEUCHOS_ASSERT(me_inArgs.supports(MEB::IN_ARG_beta));
113 }
114}
115
116template <typename Scalar>
118 const Scalar t_final)
119{
120 t_final_ = t_final;
121}
122
123template <typename Scalar>
125 const Teuchos::RCP<const Tempus::SolutionHistory<Scalar> >& sh)
126{
127 sh_ = sh;
128 t_interp_ = Teuchos::ScalarTraits<Scalar>::rmax();
129 forward_state_ = Teuchos::null;
130 dgdx_dot_checked_ = false;
131}
132
133template <typename Scalar>
134Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
136{
137 TEUCHOS_ASSERT(p < model_->Np());
138 return model_->get_p_space(p);
139}
140
141template <typename Scalar>
142Teuchos::RCP<const Teuchos::Array<std::string> >
144{
145 TEUCHOS_ASSERT(p < model_->Np());
146 return model_->get_p_names(p);
147}
148
149template <typename Scalar>
150Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
155
156template <typename Scalar>
157Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
162
163template <typename Scalar>
164Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
166{
167 using Teuchos::RCP;
169
170 RCP<LinearOpBase<Scalar> > adjoint_op = adjoint_model_->create_W_op();
171 RCP<LinearOpBase<Scalar> > mv_adjoint_op =
173 RCP<const Thyra::VectorSpaceBase<Scalar> > g_space = response_space_;
174 RCP<LinearOpBase<Scalar> > g_op = Thyra::scaledIdentity(g_space, Scalar(1.0));
175 RCP<LinearOpBase<Scalar> > null_op;
176 return nonconstBlock2x2(mv_adjoint_op, null_op, null_op, g_op);
177}
178
179template <typename Scalar>
180Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> >
182{
183 using Teuchos::RCP;
184 using Teuchos::rcp_dynamic_cast;
186
187 RCP<const LOWSFB> alowsfb = adjoint_model_->get_W_factory();
188 if (alowsfb == Teuchos::null)
189 return Teuchos::null; // model_ doesn't support W_factory
190
191 RCP<const LOWSFB> mv_alowsfb = Thyra::multiVectorLinearOpWithSolveFactory(
193
194 RCP<const Thyra::VectorSpaceBase<Scalar> > g_space = response_space_;
195 RCP<const LOWSFB> g_lowsfb =
196 Thyra::scaledIdentitySolveFactory(g_space, Scalar(1.0));
197
198 Teuchos::Array<RCP<const LOWSFB> > lowsfbs(2);
199 lowsfbs[0] = mv_alowsfb;
200 lowsfbs[1] = g_lowsfb;
202}
203
204template <typename Scalar>
205Thyra::ModelEvaluatorBase::InArgs<Scalar>
210
211template <typename Scalar>
212Thyra::ModelEvaluatorBase::InArgs<Scalar>
214{
215 typedef Thyra::ModelEvaluatorBase MEB;
216 using Teuchos::RCP;
217 using Teuchos::rcp_dynamic_cast;
218
219 MEB::InArgs<Scalar> me_nominal = model_->getNominalValues();
220 MEB::InArgs<Scalar> nominal = this->createInArgs();
221
222 const Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
223
224 // Set initial x, x_dot
225 RCP<Thyra::VectorBase<Scalar> > x = Thyra::createMember(*x_prod_space_);
226 Thyra::assign(x.ptr(), zero);
227 nominal.set_x(x);
228
229 if (me_nominal.supports(MEB::IN_ARG_x_dot)) {
230 RCP<Thyra::VectorBase<Scalar> > x_dot = Thyra::createMember(*x_prod_space_);
231 Thyra::assign(x_dot.ptr(), zero);
232 nominal.set_x_dot(x_dot);
233 }
234
235 const int np = model_->Np();
236 for (int i = 0; i < np; ++i) nominal.set_p(i, me_nominal.get_p(i));
237
238 return nominal;
239}
240
241template <typename Scalar>
242Thyra::ModelEvaluatorBase::OutArgs<Scalar>
247
248template <typename Scalar>
250 const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs,
251 const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs) const
252{
253 typedef Thyra::ModelEvaluatorBase MEB;
254 using Teuchos::RCP;
255 using Teuchos::rcp_dynamic_cast;
256
257 // Note: adjoint_model computes the transposed W (either explicitly or
258 // implicitly. Thus we need to always call adjoint_model->evalModel()
259 // whenever computing the adjoint operator, and subsequent calls to apply()
260 // do not transpose it.
261
262 // Interpolate forward solution at supplied time, reusing previous
263 // interpolation if possible
264 TEUCHOS_ASSERT(sh_ != Teuchos::null);
265 const Scalar t = inArgs.get_t();
266 const Scalar forward_t = t_final_ + t_init_ - t;
267 if (forward_state_ == Teuchos::null || t_interp_ != t) {
268 if (forward_state_ == Teuchos::null)
269 forward_state_ = sh_->interpolateState(forward_t);
270 else
271 sh_->interpolateState(forward_t, forward_state_.get());
272 t_interp_ = t;
273 }
274
275 // setup input arguments for model
276 MEB::InArgs<Scalar> me_inArgs = model_->getNominalValues();
277 me_inArgs.set_x(forward_state_->getX());
278 if (me_inArgs.supports(MEB::IN_ARG_x_dot) &&
279 inArgs.get_x_dot() != Teuchos::null)
280 me_inArgs.set_x_dot(forward_state_->getXDot());
281 if (me_inArgs.supports(MEB::IN_ARG_t)) me_inArgs.set_t(forward_t);
282 const int np = me_inArgs.Np();
283 for (int i = 0; i < np; ++i) me_inArgs.set_p(i, inArgs.get_p(i));
284
285 // compute W
286 RCP<Thyra::LinearOpBase<Scalar> > op = outArgs.get_W_op();
287 if (op != Teuchos::null) {
288 if (me_inArgs.supports(MEB::IN_ARG_alpha))
289 me_inArgs.set_alpha(inArgs.get_alpha());
290 if (me_inArgs.supports(MEB::IN_ARG_beta))
291 me_inArgs.set_beta(inArgs.get_beta());
292
293 // Adjoint W
294 RCP<Thyra::DefaultBlockedLinearOp<Scalar> > block_op =
295 rcp_dynamic_cast<Thyra::DefaultBlockedLinearOp<Scalar> >(op, true);
296 RCP<Thyra::MultiVectorLinearOp<Scalar> > mv_adjoint_op =
297 rcp_dynamic_cast<Thyra::MultiVectorLinearOp<Scalar> >(
298 block_op->getNonconstBlock(0, 0), true);
299 RCP<Thyra::LinearOpBase<Scalar> > adjoint_op =
300 mv_adjoint_op->getNonconstLinearOp();
301 MEB::OutArgs<Scalar> adj_me_outArgs = adjoint_model_->createOutArgs();
302 adj_me_outArgs.set_W_op(adjoint_op);
303 adjoint_model_->evalModel(me_inArgs, adj_me_outArgs);
304
305 // g W
306 RCP<Thyra::ScaledIdentityLinearOpWithSolve<Scalar> > si_op =
307 rcp_dynamic_cast<Thyra::ScaledIdentityLinearOpWithSolve<Scalar> >(
308 block_op->getNonconstBlock(1, 1), true);
309 si_op->setScale(inArgs.get_alpha());
310 }
311
312 // Compute adjoint residual F(y):
313 // * For implicit form, F(y) = d/dt( df/dx_dot^T*y ) + df/dx^T*y
314 // * For explict form, F(y) = -df/dx^T*y
315 // For implicit form, we assume df/dx_dot is constant w.r.t. x, x_dot, and t,
316 // so the residual becomes F(y) = df/dx_dot^T*y_dot + df/dx^T*y
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();
324
325 RCP<DPV> prod_f = rcp_dynamic_cast<DPV>(f, true);
326 RCP<Thyra::VectorBase<Scalar> > adjoint_f =
327 prod_f->getNonconstVectorBlock(0);
328 RCP<Thyra::MultiVectorBase<Scalar> > adjoint_f_mv =
329 rcp_dynamic_cast<DMVPV>(adjoint_f, true)->getNonconstMultiVector();
330
331 MEB::OutArgs<Scalar> adj_me_outArgs = adjoint_model_->createOutArgs();
332
333 if (my_dfdx_ == Teuchos::null) my_dfdx_ = adjoint_model_->create_W_op();
334 adj_me_outArgs.set_W_op(my_dfdx_);
335 if (me_inArgs.supports(MEB::IN_ARG_alpha)) me_inArgs.set_alpha(0.0);
336 if (me_inArgs.supports(MEB::IN_ARG_beta)) me_inArgs.set_beta(1.0);
337 adjoint_model_->evalModel(me_inArgs, adj_me_outArgs);
338
339 // Explicit form residual F(y) = -df/dx^T*y
340 my_dfdx_->apply(Thyra::NOTRANS, *adjoint_x_mv, adjoint_f_mv.ptr(),
341 Scalar(-1.0), Scalar(0.0));
342
343 // For a time-integrated response, add the source term:
344 // explicit form residual F(y) = -df/dx^T*y + dg/dx^T
346 if (my_dgdx_mv_ == Teuchos::null)
347 my_dgdx_mv_ = createMembers(model_->get_x_space(), num_adjoint_);
351 "Tempus::AdjointAuxSensitivityModelEvaluator::evalModel");
352 dgdx_dot_checked_ = true;
353 Thyra::update(Scalar(1.0), *my_dgdx_mv_, adjoint_f_mv.ptr());
354 }
355
356 // Implicit form residual df/dx_dot^T*y_dot + df/dx^T*y using the second
357 // scalar argument to apply() to change the explicit term above
358 RCP<const DPV> prod_x_dot;
359 if (me_inArgs.supports(MEB::IN_ARG_x_dot)) {
360 RCP<const Thyra::VectorBase<Scalar> > x_dot = inArgs.get_x_dot();
361 if (x_dot != Teuchos::null) {
362 prod_x_dot = rcp_dynamic_cast<const DPV>(x_dot, true);
363 RCP<const Thyra::VectorBase<Scalar> > adjoint_x_dot =
364 prod_x_dot->getVectorBlock(0);
365 RCP<const Thyra::MultiVectorBase<Scalar> > adjoint_x_dot_mv =
366 rcp_dynamic_cast<const DMVPV>(adjoint_x_dot, true)
367 ->getMultiVector();
369 // F = -F + y_dot
370 Thyra::V_StVpV(adjoint_f_mv.ptr(), Scalar(-1.0), *adjoint_f_mv,
371 *adjoint_x_dot_mv);
372 }
373 else {
374 if (my_dfdxdot_ == Teuchos::null)
375 my_dfdxdot_ = adjoint_model_->create_W_op();
377 adj_me_outArgs.set_W_op(my_dfdxdot_);
378 me_inArgs.set_alpha(1.0);
379 me_inArgs.set_beta(0.0);
380 adjoint_model_->evalModel(me_inArgs, adj_me_outArgs);
381
383 }
384 my_dfdxdot_->apply(Thyra::NOTRANS, *adjoint_x_dot_mv,
385 adjoint_f_mv.ptr(), Scalar(1.0), Scalar(-1.0));
386 }
387 }
388 }
389
390 // Compute g = z_dot - df/dp^T*y for computing the model parameter term
391 // in the adjoint sensitivity formula (g = z_dot - df/dp^T*y + dg/dp^T for
392 // a time-integrated response)
393 RCP<Thyra::VectorBase<Scalar> > adjoint_g =
394 prod_f->getNonconstVectorBlock(1);
395 RCP<Thyra::MultiVectorBase<Scalar> > adjoint_g_mv =
396 rcp_dynamic_cast<DMVPV>(adjoint_g, true)->getNonconstMultiVector();
397
398 if (f_depends_on_p_) {
400 *model_, p_index_, me_inArgs, *adjoint_x_mv, *adjoint_g_mv,
401 Scalar(1.0), Scalar(0.0), my_dfdp_op_, my_dfdp_mv_);
402 }
403 else
404 Thyra::assign(adjoint_g_mv.ptr(), Scalar(0.0));
405
406 // For a time-integrated response, subtract dg/dp^T
408 if (my_dgdp_mv_ == Teuchos::null)
409 my_dgdp_mv_ = createMembers(model_->get_p_space(p_index_), num_adjoint_);
412 Thyra::update(Scalar(-1.0), *my_dgdp_mv_, adjoint_g_mv.ptr());
413 }
414
415 if (prod_x_dot != Teuchos::null) {
416 RCP<const Thyra::VectorBase<Scalar> > z_dot =
417 prod_x_dot->getVectorBlock(1);
418 RCP<const Thyra::MultiVectorBase<Scalar> > z_dot_mv =
419 rcp_dynamic_cast<const DMVPV>(z_dot, true)->getMultiVector();
420 Thyra::V_VmV(adjoint_g_mv.ptr(), *z_dot_mv, *adjoint_g_mv);
421 }
422 }
423}
424
425template <class Scalar>
426Teuchos::RCP<const Teuchos::ParameterList>
428{
429 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
430 pl->set<int>("Sensitivity Parameter Index", 0);
431 pl->set<int>("Response Function Index", 0);
432 pl->set<bool>("Mass Matrix Is Constant", true);
433 pl->set<bool>("Mass Matrix Is Identity", false);
434 pl->set<std::string>("Response Type", "Final Time",
435 "\"Final Time\": g(x(T),p,T), "
436 "\"Time Integral\": int_{t0}^{T} g(x(t),p,t) dt, or "
437 "\"Sum Over Times\": sum_k g(x(t_k),p,t_k)");
438 pl->set<std::string>("Response Time List", "",
439 "Comma-separated times t_k of the \"Sum Over Times\" "
440 "response");
441 pl->set<bool>("Response Depends on Parameters", true);
442 pl->set<bool>("Residual Depends on Parameters", true);
443 return pl;
444}
445
446template <typename Scalar>
447Thyra::ModelEvaluatorBase::InArgs<Scalar>
449 const Thyra::ModelEvaluatorBase::InArgs<Scalar>& me_inArgs) const
450{
451 // The response is evaluated at the forward state, including x_dot when the
452 // model supports it (for explicit steppers x_dot is not set in me_inArgs).
453 typedef Thyra::ModelEvaluatorBase MEB;
454 MEB::InArgs<Scalar> inArgs = me_inArgs;
455 if (inArgs.supports(MEB::IN_ARG_x_dot) && forward_state_->getXDot() != Teuchos::null)
456 inArgs.set_x_dot(forward_state_->getXDot());
457 return inArgs;
458}
459
460} // namespace Tempus
461
462#endif
Thyra::ModelEvaluatorBase::InArgs< Scalar > responseInArgs(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &me_inArgs) const
InArgs for evaluating the response derivatives at the forward state.
void evalModelImpl(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_p_space(int p) const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const
Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > adjoint_model_
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_W_op() const
static Teuchos::RCP< const Teuchos::ParameterList > getValidParameters()
void setFinalTime(const Scalar t_final)
Set the final time from the forward evaluation.
Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const
Thyra::ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const
Teuchos::RCP< const Tempus::SolutionHistory< Scalar > > sh_
Thyra::ModelEvaluatorBase::OutArgs< Scalar > createOutArgsImpl() const
void setForwardSolutionHistory(const Teuchos::RCP< const Tempus::SolutionHistory< Scalar > > &sh)
Set solution history from forward evaluation.
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_f_space() const
Teuchos::RCP< const Thyra::LinearOpWithSolveFactoryBase< Scalar > > get_W_factory() const
Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > model_
Teuchos::RCP< const Teuchos::Array< std::string > > get_p_names(int p) const
AdjointAuxSensitivityModelEvaluator(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &adjoint_model, const Scalar &t_init, const Scalar &t_final, const Teuchos::RCP< const Teuchos::ParameterList > &pList=Teuchos::null)
Constructor.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
RCP< BlockedTriangularLinearOpWithSolveFactory< Scalar > > blockedTriangularLinearOpWithSolveFactory(const Array< RCP< LinearOpWithSolveFactoryBase< Scalar > > > &lowsf)
Nonmember constructor.
RCP< MultiVectorLinearOp< Scalar > > nonconstMultiVectorLinearOp(const RCP< LinearOpBase< Scalar > > &op, const RCP< const DefaultMultiVectorProductVectorSpace< Scalar > > &multiVecRange, const RCP< const DefaultMultiVectorProductVectorSpace< Scalar > > &multiVecDomain)
Nonmember constructor function.
RCP< MultiVectorLinearOpWithSolveFactory< Scalar > > multiVectorLinearOpWithSolveFactory(const RCP< const LinearOpWithSolveFactoryBase< Scalar > > &lowsf, const RCP< const DefaultMultiVectorProductVectorSpace< Scalar > > &multiVecRange, const RCP< const DefaultMultiVectorProductVectorSpace< Scalar > > &multiVecDomain)
Nonmember constructor.
RCP< ScaledIdentityLinearOpWithSolveFactory< Scalar > > scaledIdentitySolveFactory(const RCP< const VectorSpaceBase< Scalar > > &space, const Scalar &s)
Nonmember constructor.
RCP< ScaledIdentityLinearOpWithSolve< Scalar > > scaledIdentity()
Nonmember constructor function.
void evalResponseGradientX(const Thyra::ModelEvaluator< Scalar > &model, const int g_index, const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, Thyra::MultiVectorBase< Scalar > &dgdx, const bool dgdx_dot_check, const std::string &caller)
Evaluate dg/dx^T (gradient form, x_space x num_g) of response g_index at the given inArgs.
AdjointResponseType parseResponseType(const std::string &name)
Convert the "Response Type" parameter value to the enum.
void applyDfDpTranspose(const Thyra::ModelEvaluator< Scalar > &model, const int p_index, const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Thyra::MultiVectorBase< Scalar > &v, Thyra::MultiVectorBase< Scalar > &y, const Scalar alpha, const Scalar beta, Teuchos::RCP< Thyra::LinearOpBase< Scalar > > &dfdp_op, Teuchos::RCP< Thyra::MultiVectorBase< Scalar > > &dfdp_mv)
Compute y = alpha * df/dp^T * v + beta * y.
void evalResponseGradientP(const Thyra::ModelEvaluator< Scalar > &model, const int g_index, const int p_index, const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, Thyra::MultiVectorBase< Scalar > &dgdp)
Evaluate dg/dp^T (gradient form, p_space x num_g) of response g_index with respect to parameter p_ind...