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 =
572 #endif // Tempus_IntegratorAdjointSensitivity_impl_hpp
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const override
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList() override
virtual Teuchos::RCP< TimeStepControl< Scalar > > getNonConstTimeStepControl() override
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const override
static Teuchos::RCP< const Teuchos::ParameterList > getValidParameters()
virtual Teuchos::RCP< const Thyra::VectorBase< Scalar > > getXdot() const
Get current the time derivative of the solution, xdot.
ModelEvaluator for forming adjoint sensitivity equations.
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList() override
Teuchos::RCP< IntegratorAdjointSensitivity< Scalar > > integratorAdjointSensitivity(Teuchos::RCP< Teuchos::ParameterList > pList, const Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > &model)
Non-member constructor.
void buildSolutionHistory(const Teuchos::RCP< const SolutionHistory< Scalar > > &state_solution_history, const Teuchos::RCP< const SolutionHistory< Scalar > > &adjoint_solution_history)
virtual Teuchos::RCP< const Thyra::VectorBase< Scalar > > getX() const
Get current the solution, x.
std::string description() const override
virtual Teuchos::RCP< const SolutionHistory< Scalar > > getSolutionHistory() const override
Get the SolutionHistory.
Status
Status for the Integrator, the Stepper and the SolutionState.
virtual Teuchos::RCP< Teuchos::ParameterList > getTempusParameterList() override
Return a copy of the Tempus ParameterList.
IntegratorObserver class for time integrators.
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< const TimeStepControl< Scalar > > getTimeStepControl() const override
Get the TimeStepControl.
virtual void setTempusParameterList(Teuchos::RCP< Teuchos::ParameterList > pl) override
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
virtual bool advanceTime()
Advance the solution to timeMax, and return true if successful.
virtual void setObserver(Teuchos::RCP< IntegratorObserver< Scalar > > obs=Teuchos::null)
Set the Observer.
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &pl) override
Time integrator suitable for adjoint sensitivity analysis.
virtual int getIndex() const override
Get current index.
Teuchos::RCP< AdjointAuxSensitivityModelEvaluator< Scalar > > createAdjointModel(const Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > &model, const Teuchos::RCP< Teuchos::ParameterList > &inputPL)
virtual Teuchos::RCP< const Thyra::VectorBase< Scalar > > getXdotdot() const
Get current the second time derivative of the solution, xdotdot.
virtual Scalar getTime() const override
Get current time.
virtual Status getStatus() const override
Get Status.
virtual void initialize()
Initializes the Integrator after set* function calls.
virtual Teuchos::RCP< Stepper< Scalar > > getStepper() const override
Get the Stepper.
virtual Teuchos::RCP< const Thyra::MultiVectorBase< Scalar > > getDgDp() const
Return adjoint sensitivity stored in gradient format.
IntegratorAdjointSensitivity()
Destructor.