9 #ifndef Tempus_IntegratorAdjointSensitivity_impl_hpp
10 #define Tempus_IntegratorAdjointSensitivity_impl_hpp
12 #include "Thyra_DefaultMultiVectorProductVectorSpace.hpp"
13 #include "Thyra_DefaultMultiVectorProductVector.hpp"
14 #include "Thyra_DefaultProductVectorSpace.hpp"
15 #include "Thyra_DefaultProductVector.hpp"
16 #include "Thyra_VectorStdOps.hpp"
17 #include "Thyra_MultiVectorStdOps.hpp"
22 template<
class Scalar>
29 setParameterList(inputPL);
30 state_integrator_ = integratorBasic<Scalar>(inputPL, model_);
33 "Error - IntegratorAdjointSensitivity(): Cannot use FSAL with\n"
34 " IntegratorAdjointSensitivity, because the state and adjoint\n"
35 " integrators require ModelEvaluator evaluation in the\n"
36 " constructor to make the initial conditions consistent.\n"
37 " For the adjoint integrator, this requires special construction\n"
38 " which has not been implemented yet.\n");
40 adjoint_model_ = createAdjointModel(model_, inputPL);
41 adjoint_integrator_ = integratorBasic<Scalar>(inputPL, adjoint_model_);
44 template<
class Scalar>
48 state_integrator_ = integratorBasic<Scalar>();
49 adjoint_integrator_ = integratorBasic<Scalar>();
52 template<
class Scalar>
58 state_integrator_->getTimeStepControl()->getFinalTime();
59 return advanceTime(tfinal);
62 template<
class Scalar>
68 using Teuchos::rcp_dynamic_cast;
74 using Thyra::createMember;
75 using Thyra::createMembers;
82 RCP<const SolutionHistory<Scalar> > state_solution_history =
83 state_integrator_->getSolutionHistory();
84 RCP<const SolutionState<Scalar> > initial_state =
85 (*state_solution_history)[0];
88 bool state_status = state_integrator_->advanceTime(timeFinal);
91 adjoint_model_->setForwardSolutionHistory(state_solution_history);
94 RCP<const VectorSpaceBase<Scalar> > g_space = model_->get_g_space(g_index_);
95 RCP<const VectorSpaceBase<Scalar> > x_space = model_->get_x_space();
96 const int num_g = g_space->dim();
97 RCP<MultiVectorBase<Scalar> > dgdx = createMembers(x_space, num_g);
98 MEB::InArgs<Scalar> inargs = model_->getNominalValues();
99 RCP<const SolutionState<Scalar> > state =
100 state_solution_history->getCurrentState();
101 inargs.set_t(state->getTime());
102 inargs.set_x(state->getX());
103 inargs.set_x_dot(state->getXDot());
104 MEB::OutArgs<Scalar> outargs = model_->createOutArgs();
105 outargs.set_DgDx(g_index_,
106 MEB::Derivative<Scalar>(dgdx, MEB::DERIV_MV_GRADIENT_FORM));
107 model_->evalModel(inargs, outargs);
108 outargs.set_DgDx(g_index_, MEB::Derivative<Scalar>());
114 RCP<DPV> adjoint_init =
115 rcp_dynamic_cast<DPV>(Thyra::createMember(adjoint_model_->get_x_space()));
116 RCP<MultiVectorBase<Scalar> > adjoint_init_mv =
117 rcp_dynamic_cast<DMVPV>(adjoint_init->getNonconstVectorBlock(0))->getNonconstMultiVector();
118 assign(adjoint_init->getNonconstVectorBlock(1).ptr(),
120 if (mass_matrix_is_identity_)
121 assign(adjoint_init_mv.ptr(), *dgdx);
123 inargs.set_alpha(1.0);
124 inargs.set_beta(0.0);
125 RCP<LinearOpWithSolveBase<Scalar> > W = model_->create_W();
127 model_->evalModel(inargs, outargs);
129 outargs.set_W(Teuchos::null);
133 adjoint_integrator_->initializeSolutionHistory(Scalar(0.0), adjoint_init);
134 bool sens_status = adjoint_integrator_->advanceTime(timeFinal);
135 RCP<const SolutionHistory<Scalar> > adjoint_solution_history =
136 adjoint_integrator_->getSolutionHistory();
139 RCP<const VectorSpaceBase<Scalar> > p_space = model_->get_p_space(p_index_);
140 dgdp_ = createMembers(p_space, num_g);
141 if (g_depends_on_p_) {
142 MEB::DerivativeSupport dgdp_support =
143 outargs.supports(MEB::OUT_ARG_DgDp, g_index_, p_index_);
144 if (dgdp_support.supports(MEB::DERIV_MV_GRADIENT_FORM)) {
145 outargs.set_DgDp(g_index_, p_index_,
146 MEB::Derivative<Scalar>(dgdp_,
147 MEB::DERIV_MV_GRADIENT_FORM));
148 model_->evalModel(inargs, outargs);
150 else if (dgdp_support.supports(MEB::DERIV_MV_JACOBIAN_FORM)) {
151 const int num_p = p_space->dim();
152 RCP<MultiVectorBase<Scalar> > dgdp_trans =
153 createMembers(g_space, num_p);
154 outargs.set_DgDp(g_index_, p_index_,
155 MEB::Derivative<Scalar>(dgdp_trans,
156 MEB::DERIV_MV_JACOBIAN_FORM));
157 model_->evalModel(inargs, outargs);
160 for (
int i=0; i<num_p; ++i)
161 for (
int j=0; j<num_g; ++j)
162 dgdp_view(i,j) = dgdp_trans_view(j,i);
166 "Invalid dg/dp support");
167 outargs.set_DgDp(g_index_, p_index_, MEB::Derivative<Scalar>());
170 assign(dgdp_.ptr(), Scalar(0.0));
174 if (ic_depends_on_p_ && dxdp_init_ != Teuchos::null) {
175 RCP<const SolutionState<Scalar> > adjoint_state =
176 adjoint_solution_history->getCurrentState();
177 RCP<const VectorBase<Scalar> > adjoint_x =
178 rcp_dynamic_cast<
const DPV>(adjoint_state->getX())->getVectorBlock(0);
179 RCP<const MultiVectorBase<Scalar> > adjoint_mv =
180 rcp_dynamic_cast<
const DMVPV>(adjoint_x)->getMultiVector();
181 if (mass_matrix_is_identity_)
185 inargs.set_t(initial_state->getTime());
186 inargs.set_x(initial_state->getX());
187 inargs.set_x_dot(initial_state->getXDot());
188 inargs.set_alpha(1.0);
189 inargs.set_beta(0.0);
190 RCP<LinearOpBase<Scalar> > W_op = model_->create_W_op();
191 outargs.set_W_op(W_op);
192 model_->evalModel(inargs, outargs);
193 outargs.set_W_op(Teuchos::null);
194 RCP<MultiVectorBase<Scalar> > tmp = createMembers(x_space, num_g);
205 if (f_depends_on_p_) {
206 RCP<const SolutionState<Scalar> > adjoint_state =
207 adjoint_solution_history->getCurrentState();
208 RCP<const VectorBase<Scalar> > z =
209 rcp_dynamic_cast<
const DPV>(adjoint_state->getX())->getVectorBlock(1);
210 RCP<const MultiVectorBase<Scalar> > z_mv =
211 rcp_dynamic_cast<
const DMVPV>(z)->getMultiVector();
212 Thyra::V_VmV(dgdp_.ptr(), *dgdp_, *z_mv);
215 buildSolutionHistory(state_solution_history, adjoint_solution_history);
217 return state_status && sens_status;
220 template<
class Scalar>
225 return solutionHistory_->getCurrentTime();
228 template<
class Scalar>
233 return solutionHistory_->getCurrentIndex();
236 template<
class Scalar>
241 Status state_status = state_integrator_->getStatus();
242 Status sens_status = adjoint_integrator_->getStatus();
250 template<
class Scalar>
255 return state_integrator_->getStepper();
258 template<
class Scalar>
263 return state_integrator_->getTempusParameterList();
266 template<
class Scalar>
271 state_integrator_->setTempusParameterList(pl);
272 adjoint_integrator_->setTempusParameterList(pl);
275 template<
class Scalar>
280 return solutionHistory_;
283 template<
class Scalar>
288 return state_integrator_->getTimeStepControl();
291 template<
class Scalar>
296 return state_integrator_->getNonConstTimeStepControl();
299 template<
class Scalar>
309 state_integrator_->initializeSolutionHistory(t0, x0, xdot0, xdotdot0);
313 template<
class Scalar>
317 state_integrator_->setObserver(obs);
323 template<
class Scalar>
327 state_integrator_->initialize();
328 adjoint_integrator_->initialize();
331 template<
class Scalar>
336 return state_integrator_->getX();
339 template<
class Scalar>
344 return state_integrator_->getXDot();
347 template<
class Scalar>
352 return state_integrator_->getXDotDot();
355 template<
class Scalar>
363 template<
class Scalar>
368 std::string name =
"Tempus::IntegratorAdjointSensitivity";
372 template<
class Scalar>
380 auto l_out = Teuchos::fancyOStream( out.
getOStream() );
381 l_out->setOutputToRootOnly(0);
382 *l_out << description() <<
"::describe" << std::endl;
383 state_integrator_->describe(out, verbLevel);
384 adjoint_integrator_->describe(out, verbLevel);
387 template<
class Scalar>
392 if (state_integrator_ != Teuchos::null)
393 state_integrator_->setParameterList(inputPL);
394 if (adjoint_integrator_ != Teuchos::null)
395 adjoint_integrator_->setParameterList(inputPL);
397 p_index_ = spl.
get<
int>(
"Sensitivity Parameter Index", 0);
398 g_index_ = spl.
get<
int>(
"Response Function Index", 0);
399 g_depends_on_p_ = spl.
get<
bool>(
"Response Depends on Parameters",
true);
400 f_depends_on_p_ = spl.
get<
bool>(
"Residual Depends on Parameters",
true);
401 ic_depends_on_p_ = spl.
get<
bool>(
"IC Depends on Parameters",
true);
402 mass_matrix_is_identity_ = spl.
get<
bool>(
"Mass Matrix Is Identity",
false);
405 template<
class Scalar>
410 state_integrator_->unsetParameterList();
411 return adjoint_integrator_->unsetParameterList();
414 template<
class Scalar>
421 using Teuchos::parameterList;
423 RCP<ParameterList> pl = parameterList();
424 RCP<const ParameterList> integrator_pl =
425 state_integrator_->getValidParameters();
426 RCP<const ParameterList> sensitivity_pl =
428 pl->setParameters(*integrator_pl);
429 ParameterList& spl = pl->sublist(
"Sensitivities");
430 spl.setParameters(*sensitivity_pl);
431 spl.set<
bool>(
"Response Depends on Parameters",
true);
432 spl.set<
bool>(
"Residual Depends on Parameters",
true);
433 spl.set<
bool>(
"IC Depends on Parameters",
true);
438 template<
class Scalar>
443 return state_integrator_->getNonconstParameterList();
446 template <
class Scalar>
457 RCP<ParameterList> spl = Teuchos::parameterList();
458 if (inputPL != Teuchos::null) {
459 *spl = inputPL->
sublist(
"Sensitivities");
461 spl->
remove(
"Response Depends on Parameters");
462 spl->remove(
"Residual Depends on Parameters");
463 spl->remove(
"IC Depends on Parameters");
464 const Scalar tfinal = state_integrator_->getTimeStepControl()->getFinalTime();
466 model, tfinal, spl));
469 template<
class Scalar>
478 using Teuchos::rcp_dynamic_cast;
483 using Thyra::createMembers;
484 using Thyra::multiVectorProductVector;
491 RCP<ParameterList> shPL =
492 Teuchos::sublist(state_integrator_->getIntegratorParameterList(),
493 "Solution History",
true);
494 solutionHistory_ = createSolutionHistoryPL<Scalar>(shPL);
496 RCP<const VectorSpaceBase<Scalar> > x_space = model_->get_x_space();
497 RCP<const VectorSpaceBase<Scalar> > adjoint_space =
498 rcp_dynamic_cast<
const DPVS>(adjoint_model_->get_x_space())->getBlock(0);
501 spaces[1] = adjoint_space;
502 RCP<const DPVS > prod_space = Thyra::productVectorSpace(spaces());
504 int num_states = state_solution_history->getNumStates();
505 const Scalar t_final = state_integrator_->getTime();
506 for (
int i=0; i<num_states; ++i) {
507 RCP<const SolutionState<Scalar> > forward_state =
508 (*state_solution_history)[i];
509 RCP<const SolutionState<Scalar> > adjoint_state =
510 adjoint_solution_history->findState(t_final-forward_state->getTime());
513 RCP<DPV> x = Thyra::defaultProductVector(prod_space);
514 RCP<const VectorBase<Scalar> > adjoint_x =
515 rcp_dynamic_cast<
const DPV>(adjoint_state->getX())->getVectorBlock(0);
516 assign(x->getNonconstVectorBlock(0).ptr(), *(forward_state->getX()));
517 assign(x->getNonconstVectorBlock(1).ptr(), *(adjoint_x));
518 RCP<VectorBase<Scalar> > x_b = x;
521 RCP<DPV> x_dot = Thyra::defaultProductVector(prod_space);
522 RCP<const VectorBase<Scalar> > adjoint_x_dot =
523 rcp_dynamic_cast<
const DPV>(adjoint_state->getXDot())->getVectorBlock(0);
524 assign(x_dot->getNonconstVectorBlock(0).ptr(), *(forward_state->getXDot()));
525 assign(x_dot->getNonconstVectorBlock(1).ptr(), *(adjoint_x_dot));
526 RCP<VectorBase<Scalar> > x_dot_b = x_dot;
530 if (forward_state->getXDotDot() != Teuchos::null) {
531 x_dot_dot = Thyra::defaultProductVector(prod_space);
532 RCP<const VectorBase<Scalar> > adjoint_x_dot_dot =
533 rcp_dynamic_cast<
const DPV>(
534 adjoint_state->getXDotDot())->getVectorBlock(0);
535 assign(x_dot_dot->getNonconstVectorBlock(0).ptr(),
536 *(forward_state->getXDotDot()));
537 assign(x_dot_dot->getNonconstVectorBlock(1).ptr(),
538 *(adjoint_x_dot_dot));
540 RCP<VectorBase<Scalar> > x_dot_dot_b = x_dot_dot;
542 RCP<SolutionState<Scalar> > prod_state = forward_state->clone();
543 prod_state->setX(x_b);
544 prod_state->setXDot(x_dot_b);
545 prod_state->setXDotDot(x_dot_dot_b);
546 prod_state->setPhysicsState(Teuchos::null);
547 solutionHistory_->addState(prod_state);
552 template<
class Scalar>
564 template<
class Scalar>
574 #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()
T & get(const std::string &name, T def_value)
virtual Teuchos::RCP< const Thyra::VectorBase< Scalar > > getXDotDot() const
Get current the second time derivative of the solution, xdotdot.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
ModelEvaluator for forming adjoint sensitivity equations.
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList() override
virtual Teuchos::RCP< const Thyra::VectorBase< Scalar > > getXDot() const
Get current the time derivative of the solution, xdot.
Teuchos::RCP< IntegratorAdjointSensitivity< Scalar > > integratorAdjointSensitivity(Teuchos::RCP< Teuchos::ParameterList > pList, const Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > &model)
Nonmember 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.
bool remove(std::string const &name, bool throwIfNotExists=true)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
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.
RCP< std::basic_ostream< char_type, traits_type > > getOStream()
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)
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
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.