9 #ifndef Tempus_IntegratorAdjointSensitivity_impl_hpp
10 #define Tempus_IntegratorAdjointSensitivity_impl_hpp
12 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
13 #include "Thyra_DefaultMultiVectorProductVectorSpace.hpp"
14 #include "Thyra_DefaultMultiVectorProductVector.hpp"
15 #include "Thyra_DefaultProductVectorSpace.hpp"
16 #include "Thyra_DefaultProductVector.hpp"
17 #include "Thyra_VectorStdOps.hpp"
18 #include "Thyra_MultiVectorStdOps.hpp"
19 #include "NOX_Thyra.H"
23 template<
class Scalar>
26 Teuchos::RCP<Teuchos::ParameterList> inputPL,
27 const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& model)
30 setParameterList(inputPL);
31 state_integrator_ = integratorBasic<Scalar>(inputPL, model_);
33 TEUCHOS_TEST_FOR_EXCEPTION( getStepper()->getUseFSAL(), std::logic_error,
34 "Error - IntegratorAdjointSensitivity(): Cannot use FSAL with\n"
35 " IntegratorAdjointSensitivity, because the state and adjoint\n"
36 " integrators require ModelEvaluator evaluation in the\n"
37 " constructor to make the initial conditions consistent.\n"
38 " For the adjoint integrator, this requires special construction\n"
39 " which has not been implemented yet.\n");
41 adjoint_model_ = createAdjointModel(model_, inputPL);
42 adjoint_integrator_ = integratorBasic<Scalar>(inputPL, adjoint_model_);
45 template<
class Scalar>
49 state_integrator_ = integratorBasic<Scalar>();
50 adjoint_integrator_ = integratorBasic<Scalar>();
53 template<
class Scalar>
59 state_integrator_->getTimeStepControl()->getFinalTime();
60 return advanceTime(tfinal);
63 template<
class Scalar>
69 using Teuchos::rcp_dynamic_cast;
70 using Thyra::VectorBase;
71 using Thyra::VectorSpaceBase;
72 using Thyra::MultiVectorBase;
73 using Thyra::LinearOpBase;
74 using Thyra::LinearOpWithSolveBase;
75 using Thyra::createMember;
76 using Thyra::createMembers;
78 typedef Thyra::ModelEvaluatorBase MEB;
79 typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
80 typedef Thyra::DefaultProductVector<Scalar> DPV;
83 RCP<const SolutionHistory<Scalar> > state_solution_history =
84 state_integrator_->getSolutionHistory();
85 RCP<const SolutionState<Scalar> > initial_state =
86 (*state_solution_history)[0];
89 bool state_status = state_integrator_->advanceTime(timeFinal);
92 adjoint_model_->setForwardSolutionHistory(state_solution_history);
95 RCP<const VectorSpaceBase<Scalar> > g_space = model_->get_g_space(g_index_);
96 RCP<const VectorSpaceBase<Scalar> > x_space = model_->get_x_space();
97 const int num_g = g_space->dim();
98 RCP<MultiVectorBase<Scalar> > dgdx = createMembers(x_space, num_g);
99 MEB::InArgs<Scalar> inargs = model_->getNominalValues();
100 RCP<const SolutionState<Scalar> > state =
101 state_solution_history->getCurrentState();
102 inargs.set_t(state->getTime());
103 inargs.set_x(state->getX());
104 inargs.set_x_dot(state->getXDot());
105 MEB::OutArgs<Scalar> outargs = model_->createOutArgs();
106 outargs.set_DgDx(g_index_,
107 MEB::Derivative<Scalar>(dgdx, MEB::DERIV_MV_GRADIENT_FORM));
108 model_->evalModel(inargs, outargs);
109 outargs.set_DgDx(g_index_, MEB::Derivative<Scalar>());
115 RCP<DPV> adjoint_init =
116 rcp_dynamic_cast<DPV>(Thyra::createMember(adjoint_model_->get_x_space()));
117 RCP<MultiVectorBase<Scalar> > adjoint_init_mv =
118 rcp_dynamic_cast<DMVPV>(adjoint_init->getNonconstVectorBlock(0))->getNonconstMultiVector();
119 assign(adjoint_init->getNonconstVectorBlock(1).ptr(),
120 Teuchos::ScalarTraits<Scalar>::zero());
121 if (mass_matrix_is_identity_)
122 assign(adjoint_init_mv.ptr(), *dgdx);
124 inargs.set_alpha(1.0);
125 inargs.set_beta(0.0);
126 RCP<LinearOpWithSolveBase<Scalar> > W = model_->create_W();
128 model_->evalModel(inargs, outargs);
129 W->solve(Thyra::CONJTRANS, *dgdx, adjoint_init_mv.ptr());
130 outargs.set_W(Teuchos::null);
134 adjoint_integrator_->initializeSolutionHistory(Scalar(0.0), adjoint_init);
135 bool sens_status = adjoint_integrator_->advanceTime(timeFinal);
136 RCP<const SolutionHistory<Scalar> > adjoint_solution_history =
137 adjoint_integrator_->getSolutionHistory();
140 RCP<const VectorSpaceBase<Scalar> > p_space = model_->get_p_space(p_index_);
141 dgdp_ = createMembers(p_space, num_g);
142 if (g_depends_on_p_) {
143 MEB::DerivativeSupport dgdp_support =
144 outargs.supports(MEB::OUT_ARG_DgDp, g_index_, p_index_);
145 if (dgdp_support.supports(MEB::DERIV_MV_GRADIENT_FORM)) {
146 outargs.set_DgDp(g_index_, p_index_,
147 MEB::Derivative<Scalar>(dgdp_,
148 MEB::DERIV_MV_GRADIENT_FORM));
149 model_->evalModel(inargs, outargs);
151 else if (dgdp_support.supports(MEB::DERIV_MV_JACOBIAN_FORM)) {
152 const int num_p = p_space->dim();
153 RCP<MultiVectorBase<Scalar> > dgdp_trans =
154 createMembers(g_space, num_p);
155 outargs.set_DgDp(g_index_, p_index_,
156 MEB::Derivative<Scalar>(dgdp_trans,
157 MEB::DERIV_MV_JACOBIAN_FORM));
158 model_->evalModel(inargs, outargs);
159 Thyra::DetachedMultiVectorView<Scalar> dgdp_view(*dgdp_);
160 Thyra::DetachedMultiVectorView<Scalar> dgdp_trans_view(*dgdp_trans);
161 for (
int i=0; i<num_p; ++i)
162 for (
int j=0; j<num_g; ++j)
163 dgdp_view(i,j) = dgdp_trans_view(j,i);
166 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
167 "Invalid dg/dp support");
168 outargs.set_DgDp(g_index_, p_index_, MEB::Derivative<Scalar>());
171 assign(dgdp_.ptr(), Scalar(0.0));
175 if (ic_depends_on_p_ && dxdp_init_ != Teuchos::null) {
176 RCP<const SolutionState<Scalar> > adjoint_state =
177 adjoint_solution_history->getCurrentState();
178 RCP<const VectorBase<Scalar> > adjoint_x =
179 rcp_dynamic_cast<const DPV>(adjoint_state->getX())->getVectorBlock(0);
180 RCP<const MultiVectorBase<Scalar> > adjoint_mv =
181 rcp_dynamic_cast<const DMVPV>(adjoint_x)->getMultiVector();
182 if (mass_matrix_is_identity_)
183 dxdp_init_->apply(Thyra::CONJTRANS, *adjoint_mv, dgdp_.ptr(), Scalar(1.0),
186 inargs.set_t(initial_state->getTime());
187 inargs.set_x(initial_state->getX());
188 inargs.set_x_dot(initial_state->getXDot());
189 inargs.set_alpha(1.0);
190 inargs.set_beta(0.0);
191 RCP<LinearOpBase<Scalar> > W_op = model_->create_W_op();
192 outargs.set_W_op(W_op);
193 model_->evalModel(inargs, outargs);
194 outargs.set_W_op(Teuchos::null);
195 RCP<MultiVectorBase<Scalar> > tmp = createMembers(x_space, num_g);
196 W_op->apply(Thyra::CONJTRANS, *adjoint_mv, tmp.ptr(), Scalar(1.0),
198 dxdp_init_->apply(Thyra::CONJTRANS, *tmp, dgdp_.ptr(), Scalar(1.0),
206 if (f_depends_on_p_) {
207 RCP<const SolutionState<Scalar> > adjoint_state =
208 adjoint_solution_history->getCurrentState();
209 RCP<const VectorBase<Scalar> > z =
210 rcp_dynamic_cast<const DPV>(adjoint_state->getX())->getVectorBlock(1);
211 RCP<const MultiVectorBase<Scalar> > z_mv =
212 rcp_dynamic_cast<const DMVPV>(z)->getMultiVector();
213 Thyra::V_VmV(dgdp_.ptr(), *dgdp_, *z_mv);
216 buildSolutionHistory(state_solution_history, adjoint_solution_history);
218 return state_status && sens_status;
221 template<
class Scalar>
226 return solutionHistory_->getCurrentTime();
229 template<
class Scalar>
234 return solutionHistory_->getCurrentIndex();
237 template<
class Scalar>
242 Status state_status = state_integrator_->getStatus();
243 Status sens_status = adjoint_integrator_->getStatus();
251 template<
class Scalar>
252 Teuchos::RCP<Stepper<Scalar> >
256 return state_integrator_->getStepper();
259 template<
class Scalar>
260 Teuchos::RCP<Teuchos::ParameterList>
264 return state_integrator_->getTempusParameterList();
267 template<
class Scalar>
272 state_integrator_->setTempusParameterList(pl);
273 adjoint_integrator_->setTempusParameterList(pl);
276 template<
class Scalar>
277 Teuchos::RCP<const SolutionHistory<Scalar> >
281 return solutionHistory_;
284 template<
class Scalar>
285 Teuchos::RCP<const TimeStepControl<Scalar> >
289 return state_integrator_->getTimeStepControl();
292 template<
class Scalar>
293 Teuchos::RCP<TimeStepControl<Scalar> >
297 return state_integrator_->getNonConstTimeStepControl();
300 template<
class Scalar>
303 Teuchos::RCP<
const Thyra::VectorBase<Scalar> > x0,
304 Teuchos::RCP<
const Thyra::VectorBase<Scalar> > xdot0,
305 Teuchos::RCP<
const Thyra::VectorBase<Scalar> > xdotdot0,
306 Teuchos::RCP<
const Thyra::MultiVectorBase<Scalar> > DxDp0,
307 Teuchos::RCP<
const Thyra::MultiVectorBase<Scalar> > ,
308 Teuchos::RCP<
const Thyra::MultiVectorBase<Scalar> > )
310 state_integrator_->initializeSolutionHistory(t0, x0, xdot0, xdotdot0);
314 template<
class Scalar>
318 state_integrator_->setObserver(obs);
324 template<
class Scalar>
328 state_integrator_->initialize();
329 adjoint_integrator_->initialize();
332 template<
class Scalar>
333 Teuchos::RCP<const Thyra::VectorBase<Scalar> >
337 return state_integrator_->getX();
340 template<
class Scalar>
341 Teuchos::RCP<const Thyra::VectorBase<Scalar> >
345 return state_integrator_->getXdot();
348 template<
class Scalar>
349 Teuchos::RCP<const Thyra::VectorBase<Scalar> >
353 return state_integrator_->getXdotdot();
356 template<
class Scalar>
357 Teuchos::RCP<const Thyra::MultiVectorBase<Scalar> >
364 template<
class Scalar>
369 std::string name =
"Tempus::IntegratorAdjointSensitivity";
373 template<
class Scalar>
377 Teuchos::FancyOStream &out,
378 const Teuchos::EVerbosityLevel verbLevel)
const
380 out << description() <<
"::describe" << std::endl;
381 state_integrator_->describe(out, verbLevel);
382 adjoint_integrator_->describe(out, verbLevel);
385 template<
class Scalar>
390 if (state_integrator_ != Teuchos::null)
391 state_integrator_->setParameterList(inputPL);
392 if (adjoint_integrator_ != Teuchos::null)
393 adjoint_integrator_->setParameterList(inputPL);
394 Teuchos::ParameterList& spl = inputPL->sublist(
"Sensitivities");
395 p_index_ = spl.get<
int>(
"Sensitivity Parameter Index", 0);
396 g_index_ = spl.get<
int>(
"Response Function Index", 0);
397 g_depends_on_p_ = spl.get<
bool>(
"Response Depends on Parameters",
true);
398 f_depends_on_p_ = spl.get<
bool>(
"Residual Depends on Parameters",
true);
399 ic_depends_on_p_ = spl.get<
bool>(
"IC Depends on Parameters",
true);
400 mass_matrix_is_identity_ = spl.get<
bool>(
"Mass Matrix Is Identity",
false);
403 template<
class Scalar>
404 Teuchos::RCP<Teuchos::ParameterList>
408 state_integrator_->unsetParameterList();
409 return adjoint_integrator_->unsetParameterList();
412 template<
class Scalar>
413 Teuchos::RCP<const Teuchos::ParameterList>
418 using Teuchos::ParameterList;
419 using Teuchos::parameterList;
421 RCP<ParameterList> pl = parameterList();
422 RCP<const ParameterList> integrator_pl =
423 state_integrator_->getValidParameters();
424 RCP<const ParameterList> sensitivity_pl =
426 pl->setParameters(*integrator_pl);
427 ParameterList& spl = pl->sublist(
"Sensitivities");
428 spl.setParameters(*sensitivity_pl);
429 spl.set<
bool>(
"Response Depends on Parameters",
true);
430 spl.set<
bool>(
"Residual Depends on Parameters",
true);
431 spl.set<
bool>(
"IC Depends on Parameters",
true);
436 template<
class Scalar>
437 Teuchos::RCP<Teuchos::ParameterList>
441 return state_integrator_->getNonconstParameterList();
444 template <
class Scalar>
445 Teuchos::RCP<AdjointAuxSensitivityModelEvaluator<Scalar> >
448 const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& model,
449 const Teuchos::RCP<Teuchos::ParameterList>& inputPL)
453 using Teuchos::ParameterList;
455 RCP<ParameterList> spl = Teuchos::parameterList();
456 if (inputPL != Teuchos::null) {
457 *spl = inputPL->sublist(
"Sensitivities");
459 spl->remove(
"Response Depends on Parameters");
460 spl->remove(
"Residual Depends on Parameters");
461 spl->remove(
"IC Depends on Parameters");
462 const Scalar tfinal = state_integrator_->getTimeStepControl()->getFinalTime();
464 model, tfinal, spl));
467 template<
class Scalar>
476 using Teuchos::rcp_dynamic_cast;
477 using Teuchos::ParameterList;
478 using Thyra::VectorBase;
479 using Thyra::MultiVectorBase;
480 using Thyra::VectorSpaceBase;
481 using Thyra::createMembers;
482 using Thyra::multiVectorProductVector;
484 typedef Thyra::DefaultProductVectorSpace<Scalar> DPVS;
485 typedef Thyra::DefaultProductVector<Scalar> DPV;
489 RCP<ParameterList> shPL =
490 Teuchos::sublist(state_integrator_->getIntegratorParameterList(),
491 "Solution History",
true);
494 RCP<const VectorSpaceBase<Scalar> > x_space = model_->get_x_space();
495 RCP<const VectorSpaceBase<Scalar> > adjoint_space =
496 rcp_dynamic_cast<const DPVS>(adjoint_model_->get_x_space())->getBlock(0);
497 Teuchos::Array< RCP<const VectorSpaceBase<Scalar> > > spaces(2);
499 spaces[1] = adjoint_space;
500 RCP<const DPVS > prod_space = Thyra::productVectorSpace(spaces());
502 int num_states = state_solution_history->getNumStates();
503 const Scalar t_final = state_integrator_->getTime();
504 for (
int i=0; i<num_states; ++i) {
505 RCP<const SolutionState<Scalar> > forward_state =
506 (*state_solution_history)[i];
507 RCP<const SolutionState<Scalar> > adjoint_state =
508 adjoint_solution_history->findState(t_final-forward_state->getTime());
511 RCP<DPV> x = Thyra::defaultProductVector(prod_space);
512 RCP<const VectorBase<Scalar> > adjoint_x =
513 rcp_dynamic_cast<const DPV>(adjoint_state->getX())->getVectorBlock(0);
514 assign(x->getNonconstVectorBlock(0).ptr(), *(forward_state->getX()));
515 assign(x->getNonconstVectorBlock(1).ptr(), *(adjoint_x));
516 RCP<VectorBase<Scalar> > x_b = x;
519 RCP<DPV> x_dot = Thyra::defaultProductVector(prod_space);
520 RCP<const VectorBase<Scalar> > adjoint_x_dot =
521 rcp_dynamic_cast<const DPV>(adjoint_state->getXDot())->getVectorBlock(0);
522 assign(x_dot->getNonconstVectorBlock(0).ptr(), *(forward_state->getXDot()));
523 assign(x_dot->getNonconstVectorBlock(1).ptr(), *(adjoint_x_dot));
524 RCP<VectorBase<Scalar> > x_dot_b = x_dot;
528 if (forward_state->getXDotDot() != Teuchos::null) {
529 x_dot_dot = Thyra::defaultProductVector(prod_space);
530 RCP<const VectorBase<Scalar> > adjoint_x_dot_dot =
531 rcp_dynamic_cast<const DPV>(
532 adjoint_state->getXDotDot())->getVectorBlock(0);
533 assign(x_dot_dot->getNonconstVectorBlock(0).ptr(),
534 *(forward_state->getXDotDot()));
535 assign(x_dot_dot->getNonconstVectorBlock(1).ptr(),
536 *(adjoint_x_dot_dot));
538 RCP<VectorBase<Scalar> > x_dot_dot_b = x_dot_dot;
540 RCP<SolutionState<Scalar> > prod_state = forward_state->clone();
541 prod_state->setX(x_b);
542 prod_state->setXDot(x_dot_b);
543 prod_state->setXDotDot(x_dot_dot_b);
544 prod_state->setPhysicsState(Teuchos::null);
545 solutionHistory_->addState(prod_state);
550 template<
class Scalar>
551 Teuchos::RCP<IntegratorAdjointSensitivity<Scalar> >
553 Teuchos::RCP<Teuchos::ParameterList> pList,
554 const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& model)
556 Teuchos::RCP<IntegratorAdjointSensitivity<Scalar> > integrator =
562 template<
class Scalar>
563 Teuchos::RCP<IntegratorAdjointSensitivity<Scalar> >
566 Teuchos::RCP<IntegratorAdjointSensitivity<Scalar> > integrator =
ModelEvaluator for forming adjoint sensitivity equations.
static Teuchos::RCP< const Teuchos::ParameterList > getValidParameters()
Time integrator suitable for adjoint sensitivity analysis.
virtual void setObserver(Teuchos::RCP< IntegratorObserver< Scalar > > obs=Teuchos::null)
Set the Observer.
virtual Scalar getTime() const override
Get current time.
virtual int getIndex() const override
Get current index.
virtual Status getStatus() const override
Get Status.
virtual Teuchos::RCP< const SolutionHistory< Scalar > > getSolutionHistory() const override
Get the SolutionHistory.
virtual Teuchos::RCP< const Thyra::VectorBase< Scalar > > getXdotdot() const
Get current the second time derivative of the solution, xdotdot.
void buildSolutionHistory(const Teuchos::RCP< const SolutionHistory< Scalar > > &state_solution_history, const Teuchos::RCP< const SolutionHistory< Scalar > > &adjoint_solution_history)
virtual Teuchos::RCP< Teuchos::ParameterList > getTempusParameterList() override
Return a copy of the Tempus ParameterList.
virtual void initialize()
Initializes the Integrator after set* function calls.
IntegratorAdjointSensitivity()
Destructor.
virtual Teuchos::RCP< const Thyra::VectorBase< Scalar > > getXdot() const
Get current the time derivative of the solution, xdot.
std::string description() const override
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &pl) override
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const override
virtual Teuchos::RCP< const Thyra::VectorBase< Scalar > > getX() const
Get current the solution, x.
virtual bool advanceTime()
Advance the solution to timeMax, and return true if successful.
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList() override
Teuchos::RCP< AdjointAuxSensitivityModelEvaluator< Scalar > > createAdjointModel(const Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > &model, const Teuchos::RCP< Teuchos::ParameterList > &inputPL)
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const override
virtual Teuchos::RCP< const TimeStepControl< Scalar > > getTimeStepControl() const override
Get the TimeStepControl.
virtual Teuchos::RCP< TimeStepControl< Scalar > > getNonConstTimeStepControl() override
virtual void initializeSolutionHistory(Scalar t0, Teuchos::RCP< const Thyra::VectorBase< Scalar > > x0, Teuchos::RCP< const Thyra::VectorBase< Scalar > > xdot0=Teuchos::null, Teuchos::RCP< const Thyra::VectorBase< Scalar > > xdotdot0=Teuchos::null, Teuchos::RCP< const Thyra::MultiVectorBase< Scalar > > DxDp0=Teuchos::null, Teuchos::RCP< const Thyra::MultiVectorBase< Scalar > > DxdotDp0=Teuchos::null, Teuchos::RCP< const Thyra::MultiVectorBase< Scalar > > DxdotdotDp0=Teuchos::null)
Set the initial state from Thyra::VectorBase(s)
virtual Teuchos::RCP< Stepper< Scalar > > getStepper() const override
Get the Stepper.
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList() override
virtual void setTempusParameterList(Teuchos::RCP< Teuchos::ParameterList > pl) override
virtual Teuchos::RCP< const Thyra::MultiVectorBase< Scalar > > getDgDp() const
Return adjoint sensitivity stored in gradient format.
IntegratorObserver class for time integrators.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Status
Status for the Integrator, the Stepper and the SolutionState.
Teuchos::RCP< IntegratorAdjointSensitivity< Scalar > > integratorAdjointSensitivity(Teuchos::RCP< Teuchos::ParameterList > pList, const Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > &model)
Non-member constructor.