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>
315 Teuchos::RCP<const Thyra::VectorBase<Scalar> >
319 return state_integrator_->getX();
322 template<
class Scalar>
323 Teuchos::RCP<const Thyra::VectorBase<Scalar> >
327 return state_integrator_->getXdot();
330 template<
class Scalar>
331 Teuchos::RCP<const Thyra::VectorBase<Scalar> >
335 return state_integrator_->getXdotdot();
338 template<
class Scalar>
339 Teuchos::RCP<const Thyra::MultiVectorBase<Scalar> >
346 template<
class Scalar>
351 std::string name =
"Tempus::IntegratorAdjointSensitivity";
355 template<
class Scalar>
359 Teuchos::FancyOStream &out,
360 const Teuchos::EVerbosityLevel verbLevel)
const
362 out << description() <<
"::describe" << std::endl;
363 state_integrator_->describe(out, verbLevel);
364 adjoint_integrator_->describe(out, verbLevel);
367 template<
class Scalar>
372 if (state_integrator_ != Teuchos::null)
373 state_integrator_->setParameterList(inputPL);
374 if (adjoint_integrator_ != Teuchos::null)
375 adjoint_integrator_->setParameterList(inputPL);
376 Teuchos::ParameterList& spl = inputPL->sublist(
"Sensitivities");
377 p_index_ = spl.get<
int>(
"Sensitivity Parameter Index", 0);
378 g_index_ = spl.get<
int>(
"Response Function Index", 0);
379 g_depends_on_p_ = spl.get<
bool>(
"Response Depends on Parameters",
true);
380 f_depends_on_p_ = spl.get<
bool>(
"Residual Depends on Parameters",
true);
381 ic_depends_on_p_ = spl.get<
bool>(
"IC Depends on Parameters",
true);
382 mass_matrix_is_identity_ = spl.get<
bool>(
"Mass Matrix Is Identity",
false);
385 template<
class Scalar>
386 Teuchos::RCP<Teuchos::ParameterList>
390 state_integrator_->unsetParameterList();
391 return adjoint_integrator_->unsetParameterList();
394 template<
class Scalar>
395 Teuchos::RCP<const Teuchos::ParameterList>
400 using Teuchos::ParameterList;
401 using Teuchos::parameterList;
403 RCP<ParameterList> pl = parameterList();
404 RCP<const ParameterList> integrator_pl =
405 state_integrator_->getValidParameters();
406 RCP<const ParameterList> sensitivity_pl =
408 pl->setParameters(*integrator_pl);
409 ParameterList& spl = pl->sublist(
"Sensitivities");
410 spl.setParameters(*sensitivity_pl);
411 spl.set<
bool>(
"Response Depends on Parameters",
true);
412 spl.set<
bool>(
"Residual Depends on Parameters",
true);
413 spl.set<
bool>(
"IC Depends on Parameters",
true);
418 template<
class Scalar>
419 Teuchos::RCP<Teuchos::ParameterList>
423 return state_integrator_->getNonconstParameterList();
426 template <
class Scalar>
427 Teuchos::RCP<Tempus::AdjointAuxSensitivityModelEvaluator<Scalar> >
430 const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& model,
431 const Teuchos::RCP<Teuchos::ParameterList>& inputPL)
435 using Teuchos::ParameterList;
437 RCP<ParameterList> spl = Teuchos::parameterList();
438 if (inputPL != Teuchos::null) {
439 *spl = inputPL->sublist(
"Sensitivities");
441 spl->remove(
"Response Depends on Parameters");
442 spl->remove(
"Residual Depends on Parameters");
443 spl->remove(
"IC Depends on Parameters");
444 const Scalar tfinal = state_integrator_->getTimeStepControl()->getFinalTime();
446 model, tfinal, spl));
449 template<
class Scalar>
458 using Teuchos::rcp_dynamic_cast;
459 using Teuchos::ParameterList;
460 using Thyra::VectorBase;
461 using Thyra::MultiVectorBase;
462 using Thyra::VectorSpaceBase;
463 using Thyra::createMembers;
464 using Thyra::multiVectorProductVector;
466 typedef Thyra::DefaultProductVectorSpace<Scalar> DPVS;
467 typedef Thyra::DefaultProductVector<Scalar> DPV;
471 RCP<ParameterList> shPL =
472 Teuchos::sublist(state_integrator_->getIntegratorParameterList(),
473 "Solution History",
true);
476 RCP<const VectorSpaceBase<Scalar> > x_space = model_->get_x_space();
477 RCP<const VectorSpaceBase<Scalar> > adjoint_space =
478 rcp_dynamic_cast<
const DPVS>(adjoint_model_->get_x_space())->getBlock(0);
479 Teuchos::Array< RCP<const VectorSpaceBase<Scalar> > > spaces(2);
481 spaces[1] = adjoint_space;
482 RCP<const DPVS > prod_space = Thyra::productVectorSpace(spaces());
484 int num_states = state_solution_history->getNumStates();
485 const Scalar t_final = state_integrator_->getTime();
486 for (
int i=0; i<num_states; ++i) {
487 RCP<const SolutionState<Scalar> > forward_state =
488 (*state_solution_history)[i];
489 RCP<const SolutionState<Scalar> > adjoint_state =
490 adjoint_solution_history->findState(t_final-forward_state->getTime());
493 RCP<DPV> x = Thyra::defaultProductVector(prod_space);
494 RCP<const VectorBase<Scalar> > adjoint_x =
495 rcp_dynamic_cast<
const DPV>(adjoint_state->getX())->getVectorBlock(0);
496 assign(x->getNonconstVectorBlock(0).ptr(), *(forward_state->getX()));
497 assign(x->getNonconstVectorBlock(1).ptr(), *(adjoint_x));
498 RCP<VectorBase<Scalar> > x_b = x;
501 RCP<DPV> x_dot = Thyra::defaultProductVector(prod_space);
502 RCP<const VectorBase<Scalar> > adjoint_x_dot =
503 rcp_dynamic_cast<
const DPV>(adjoint_state->getXDot())->getVectorBlock(0);
504 assign(x_dot->getNonconstVectorBlock(0).ptr(), *(forward_state->getXDot()));
505 assign(x_dot->getNonconstVectorBlock(1).ptr(), *(adjoint_x_dot));
506 RCP<VectorBase<Scalar> > x_dot_b = x_dot;
510 if (forward_state->getXDotDot() != Teuchos::null) {
511 x_dot_dot = Thyra::defaultProductVector(prod_space);
512 RCP<const VectorBase<Scalar> > adjoint_x_dot_dot =
513 rcp_dynamic_cast<
const DPV>(
514 adjoint_state->getXDotDot())->getVectorBlock(0);
515 assign(x_dot_dot->getNonconstVectorBlock(0).ptr(),
516 *(forward_state->getXDotDot()));
517 assign(x_dot_dot->getNonconstVectorBlock(1).ptr(),
518 *(adjoint_x_dot_dot));
520 RCP<VectorBase<Scalar> > x_dot_dot_b = x_dot_dot;
522 RCP<SolutionState<Scalar> > prod_state =
524 x_b, x_dot_b, x_dot_dot_b,
525 forward_state->getStepperState()->clone(),
527 solutionHistory_->addState(prod_state);
532 template<
class Scalar>
533 Teuchos::RCP<Tempus::IntegratorAdjointSensitivity<Scalar> >
535 Teuchos::RCP<Teuchos::ParameterList> pList,
536 const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& model)
538 Teuchos::RCP<Tempus::IntegratorAdjointSensitivity<Scalar> > integrator =
544 template<
class Scalar>
545 Teuchos::RCP<Tempus::IntegratorAdjointSensitivity<Scalar> >
548 Teuchos::RCP<Tempus::IntegratorAdjointSensitivity<Scalar> > integrator =
554 #endif // Tempus_IntegratorAdjointSensitivity_impl_hpp
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const override
Teuchos::RCP< Tempus::IntegratorAdjointSensitivity< Scalar > > integratorAdjointSensitivity(Teuchos::RCP< Teuchos::ParameterList > pList, const Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > &model)
Non-member constructor.
Teuchos::RCP< Tempus::AdjointAuxSensitivityModelEvaluator< Scalar > > createAdjointModel(const Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > &model, const Teuchos::RCP< Teuchos::ParameterList > &inputPL)
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
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.
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.
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &pl) override
Time integrator suitable for adjoint sensitivity analysis.
virtual int getIndex() const override
Get current index.
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.
Solution state for integrators and steppers. SolutionState contains the metadata for solutions and th...
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.