Tempus  Version of the Day
Time Integration
Tempus_IntegratorAdjointSensitivity_impl.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ****************************************************************************
3 // Tempus: Copyright (2017) Sandia Corporation
4 //
5 // Distributed under BSD 3-clause license (See accompanying file Copyright.txt)
6 // ****************************************************************************
7 // @HEADER
8 
9 #ifndef Tempus_IntegratorAdjointSensitivity_impl_hpp
10 #define Tempus_IntegratorAdjointSensitivity_impl_hpp
11 
12 #include "Teuchos_ParameterList.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"
20 #include "Thyra_LinearOpWithSolveFactoryHelpers.hpp"
21 
22 namespace Tempus {
23 
24 template <class Scalar>
26  const Teuchos::RCP<Thyra::ModelEvaluator<Scalar>> &model,
27  const Teuchos::RCP<IntegratorBasic<Scalar>> &state_integrator,
28  const Teuchos::RCP<Thyra::ModelEvaluator<Scalar>> &adjoint_model,
29  const Teuchos::RCP<AdjointAuxSensitivityModelEvaluator<Scalar> > &adjoint_aux_model,
30  const Teuchos::RCP<IntegratorBasic<Scalar>> &adjoint_integrator,
31  const Teuchos::RCP<SolutionHistory<Scalar>> &solutionHistory,
32  const int p_index,
33  const int g_index,
34  const bool g_depends_on_p,
35  const bool f_depends_on_p,
36  const bool ic_depends_on_p,
37  const bool mass_matrix_is_identity)
38  : model_(model)
39  , state_integrator_(state_integrator)
40  , adjoint_model_(adjoint_model)
41  , adjoint_aux_model_(adjoint_aux_model)
42  , adjoint_integrator_(adjoint_integrator)
43  , solutionHistory_(solutionHistory)
44  , p_index_(p_index)
45  , g_index_(g_index)
46  , g_depends_on_p_(g_depends_on_p)
47  , f_depends_on_p_(f_depends_on_p)
48  , ic_depends_on_p_(ic_depends_on_p)
49  , mass_matrix_is_identity_(mass_matrix_is_identity)
50 {
51 
52  TEUCHOS_TEST_FOR_EXCEPTION(
53  getStepper()->getUseFSAL(), std::logic_error,
54  "Error - IntegratorAdjointSensitivity(): Cannot use FSAL with\n"
55  " IntegratorAdjointSensitivity, because the state and adjoint\n"
56  " integrators require ModelEvaluator evaluation in the\n"
57  " constructor to make the initial conditions consistent.\n"
58  " For the adjoint integrator, this requires special construction\n"
59  " which has not been implemented yet.\n");
60 }
61 
62 template<class Scalar>
65 {
66  state_integrator_ = createIntegratorBasic<Scalar>();
67  adjoint_integrator_ = createIntegratorBasic<Scalar>();
68 }
69 
70 template<class Scalar>
71 bool
74 {
75  const Scalar tfinal =
76  state_integrator_->getTimeStepControl()->getFinalTime();
77  return advanceTime(tfinal);
78 }
79 
80 template<class Scalar>
81 bool
83 advanceTime(const Scalar timeFinal)
84 {
85  using Teuchos::RCP;
86  using Teuchos::rcp_dynamic_cast;
87  using Thyra::VectorBase;
88  using Thyra::VectorSpaceBase;
90  using Thyra::LinearOpBase;
95  using Thyra::createMember;
96  using Thyra::createMembers;
97  using Thyra::assign;
98  typedef Thyra::ModelEvaluatorBase MEB;
99  typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
100  typedef Thyra::DefaultProductVector<Scalar> DPV;
101 
102  // Get initial state for later
103  RCP<const SolutionHistory<Scalar> > state_solution_history =
104  state_integrator_->getSolutionHistory();
105  RCP<const SolutionState<Scalar> > initial_state =
106  (*state_solution_history)[0];
107 
108  // Run state integrator and get solution
109  bool state_status = state_integrator_->advanceTime(timeFinal);
110 
111  // Set solution history in adjoint stepper
112  adjoint_aux_model_->setForwardSolutionHistory(state_solution_history);
113 
114  // Compute dg/dx
115  RCP<const VectorSpaceBase<Scalar> > g_space = model_->get_g_space(g_index_);
116  RCP<const VectorSpaceBase<Scalar> > x_space = model_->get_x_space();
117  const int num_g = g_space->dim();
118  RCP<MultiVectorBase<Scalar> > dgdx = createMembers(x_space, num_g);
119  MEB::InArgs<Scalar> inargs = model_->getNominalValues();
120  RCP<const SolutionState<Scalar> > state =
121  state_solution_history->getCurrentState();
122  inargs.set_t(state->getTime());
123  inargs.set_x(state->getX());
124  inargs.set_x_dot(state->getXDot());
125  MEB::OutArgs<Scalar> outargs = model_->createOutArgs();
126  MEB::OutArgs<Scalar> adj_outargs = adjoint_model_->createOutArgs();
127  outargs.set_DgDx(g_index_,
128  MEB::Derivative<Scalar>(dgdx, MEB::DERIV_MV_GRADIENT_FORM));
129  model_->evalModel(inargs, outargs);
130  outargs.set_DgDx(g_index_, MEB::Derivative<Scalar>());
131 
132  // Compute ICs == [ (df/dx_dot)^{-T} (dg/dx)^T; 0 ]
133  // For explicit form, we are relying on the user to inform us the
134  // the mass matrix is the identity. It would be nice to be able to determine
135  // somehow automatically that we are using an explicit stepper.
136  RCP<DPV> adjoint_init =
137  rcp_dynamic_cast<DPV>(Thyra::createMember(adjoint_aux_model_->get_x_space()));
138  RCP<MultiVectorBase<Scalar> > adjoint_init_mv =
139  rcp_dynamic_cast<DMVPV>(adjoint_init->getNonconstVectorBlock(0))->getNonconstMultiVector();
140  assign(adjoint_init->getNonconstVectorBlock(1).ptr(),
141  Teuchos::ScalarTraits<Scalar>::zero());
142  if (mass_matrix_is_identity_)
143  assign(adjoint_init_mv.ptr(), *dgdx);
144  else {
145  inargs.set_alpha(1.0);
146  inargs.set_beta(0.0);
147  RCP<LinearOpWithSolveBase<Scalar> > W;
148  if (adj_outargs.supports(MEB::OUT_ARG_W)) {
149  // Model supports W
150  W = adjoint_model_->create_W();
151  adj_outargs.set_W(W);
152  adjoint_model_->evalModel(inargs, adj_outargs);
153  adj_outargs.set_W(Teuchos::null);
154  }
155  else {
156  // Otherwise model must support a W_op and W factory
157  RCP<const LinearOpWithSolveFactoryBase<Scalar> > lowsfb =
158  adjoint_model_->get_W_factory();
159  TEUCHOS_TEST_FOR_EXCEPTION(
160  lowsfb == Teuchos::null, std::logic_error,
161  "Adjoint ME must support W out-arg or provide a W_factory for non-identity mass matrix");
162 
163  // Compute W_op (and W_prec if supported)
164  RCP<LinearOpBase<Scalar> > W_op = adjoint_model_->create_W_op();
165  adj_outargs.set_W_op(W_op);
166  RCP<PreconditionerFactoryBase<Scalar> > prec_factory =
167  lowsfb->getPreconditionerFactory();
168  RCP<PreconditionerBase<Scalar> > W_prec;
169  if (prec_factory != Teuchos::null)
170  W_prec = prec_factory->createPrec();
171  else if (adj_outargs.supports(MEB::OUT_ARG_W_prec)) {
172  W_prec = adjoint_model_->create_W_prec();
173  adj_outargs.set_W_prec(W_prec);
174  }
175  adjoint_model_->evalModel(inargs, adj_outargs);
176  adj_outargs.set_W_op(Teuchos::null);
177  if (adj_outargs.supports(MEB::OUT_ARG_W_prec))
178  adj_outargs.set_W_prec(Teuchos::null);
179 
180  // Create and initialize W
181  W = lowsfb->createOp();
182  if (W_prec != Teuchos::null) {
183  if (prec_factory != Teuchos::null)
184  prec_factory->initializePrec(
185  Thyra::defaultLinearOpSource<Scalar>(W_op), W_prec.get());
186  Thyra::initializePreconditionedOp<Scalar>(
187  *lowsfb, W_op, W_prec, W.ptr());
188  }
189  else
190  Thyra::initializeOp<Scalar>(*lowsfb, W_op, W.ptr());
191  }
192  W->solve(Thyra::NOTRANS, *dgdx, adjoint_init_mv.ptr());
193  }
194 
195  // Run sensitivity integrator and get solution
196  adjoint_integrator_->initializeSolutionHistory(Scalar(0.0), adjoint_init);
197  bool sens_status = adjoint_integrator_->advanceTime(timeFinal);
198  RCP<const SolutionHistory<Scalar> > adjoint_solution_history =
199  adjoint_integrator_->getSolutionHistory();
200 
201  // Compute dg/dp at final time T
202  RCP<const VectorSpaceBase<Scalar> > p_space = model_->get_p_space(p_index_);
203  dgdp_ = createMembers(p_space, num_g);
204  if (g_depends_on_p_) {
205  MEB::DerivativeSupport dgdp_support =
206  outargs.supports(MEB::OUT_ARG_DgDp, g_index_, p_index_);
207  if (dgdp_support.supports(MEB::DERIV_MV_GRADIENT_FORM)) {
208  outargs.set_DgDp(g_index_, p_index_,
209  MEB::Derivative<Scalar>(dgdp_,
210  MEB::DERIV_MV_GRADIENT_FORM));
211  model_->evalModel(inargs, outargs);
212  }
213  else if (dgdp_support.supports(MEB::DERIV_MV_JACOBIAN_FORM)) {
214  const int num_p = p_space->dim();
215  RCP<MultiVectorBase<Scalar> > dgdp_trans =
216  createMembers(g_space, num_p);
217  outargs.set_DgDp(g_index_, p_index_,
218  MEB::Derivative<Scalar>(dgdp_trans,
219  MEB::DERIV_MV_JACOBIAN_FORM));
220  model_->evalModel(inargs, outargs);
221  Thyra::DetachedMultiVectorView<Scalar> dgdp_view(*dgdp_);
222  Thyra::DetachedMultiVectorView<Scalar> dgdp_trans_view(*dgdp_trans);
223  for (int i=0; i<num_p; ++i)
224  for (int j=0; j<num_g; ++j)
225  dgdp_view(i,j) = dgdp_trans_view(j,i);
226  }
227  else
228  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
229  "Invalid dg/dp support");
230  outargs.set_DgDp(g_index_, p_index_, MEB::Derivative<Scalar>());
231  }
232  else
233  assign(dgdp_.ptr(), Scalar(0.0));
234 
235  // Add in initial condition term = (dx/dp^T(0))*(df/dx_dot^T(0))*y(0)
236  // If dxdp_init_ is null, assume it is zero
237  if (ic_depends_on_p_ && dxdp_init_ != Teuchos::null) {
238  RCP<const SolutionState<Scalar> > adjoint_state =
239  adjoint_solution_history->getCurrentState();
240  RCP<const VectorBase<Scalar> > adjoint_x =
241  rcp_dynamic_cast<const DPV>(adjoint_state->getX())->getVectorBlock(0);
242  RCP<const MultiVectorBase<Scalar> > adjoint_mv =
243  rcp_dynamic_cast<const DMVPV>(adjoint_x)->getMultiVector();
244  if (mass_matrix_is_identity_)
245  dxdp_init_->apply(Thyra::CONJTRANS, *adjoint_mv, dgdp_.ptr(), Scalar(1.0),
246  Scalar(1.0));
247  else {
248  inargs.set_t(initial_state->getTime());
249  inargs.set_x(initial_state->getX());
250  inargs.set_x_dot(initial_state->getXDot());
251  inargs.set_alpha(1.0);
252  inargs.set_beta(0.0);
253  RCP<LinearOpBase<Scalar> > W_op = adjoint_model_->create_W_op();
254  adj_outargs.set_W_op(W_op);
255  adjoint_model_->evalModel(inargs, adj_outargs);
256  adj_outargs.set_W_op(Teuchos::null);
257  RCP<MultiVectorBase<Scalar> > tmp = createMembers(x_space, num_g);
258  W_op->apply(Thyra::NOTRANS, *adjoint_mv, tmp.ptr(), Scalar(1.0),
259  Scalar(0.0));
260  dxdp_init_->apply(Thyra::CONJTRANS, *tmp, dgdp_.ptr(), Scalar(1.0),
261  Scalar(1.0));
262  }
263  }
264 
265  // Add in model parameter term = \int_0^T( (df/dp^T(t)*y(t) )dt which
266  // is computed during the adjoint integration as an auxiliary integral
267  // (2nd block of the solution vector)
268  if (f_depends_on_p_) {
269  RCP<const SolutionState<Scalar> > adjoint_state =
270  adjoint_solution_history->getCurrentState();
271  RCP<const VectorBase<Scalar> > z =
272  rcp_dynamic_cast<const DPV>(adjoint_state->getX())->getVectorBlock(1);
273  RCP<const MultiVectorBase<Scalar> > z_mv =
274  rcp_dynamic_cast<const DMVPV>(z)->getMultiVector();
275  Thyra::V_VmV(dgdp_.ptr(), *dgdp_, *z_mv);
276  }
277 
278  buildSolutionHistory(state_solution_history, adjoint_solution_history);
279 
280  return state_status && sens_status;
281 }
282 
283 template<class Scalar>
284 Scalar
286 getTime() const
287 {
288  return solutionHistory_->getCurrentTime();
289 }
290 
291 template<class Scalar>
292 int
294 getIndex() const
295 {
296  return solutionHistory_->getCurrentIndex();
297 }
298 
299 template<class Scalar>
300 Status
302 getStatus() const
303 {
304  Status state_status = state_integrator_->getStatus();
305  Status sens_status = adjoint_integrator_->getStatus();
306  if (state_status == FAILED || sens_status == FAILED)
307  return FAILED;
308  if (state_status == WORKING || sens_status == WORKING)
309  return WORKING;
310  return PASSED;
311 }
312 
313 template <class Scalar>
315  state_integrator_->setStatus(st);
316  adjoint_integrator_->setStatus(st);
317 }
318 
319 template<class Scalar>
320 Teuchos::RCP<Stepper<Scalar> >
322 getStepper() const
323 {
324  return state_integrator_->getStepper();
325 }
326 
327 template<class Scalar>
328 Teuchos::RCP<Teuchos::ParameterList>
331 {
332  return state_integrator_->getTempusParameterList();
333 }
334 
335 template<class Scalar>
336 void
338 setTempusParameterList(Teuchos::RCP<Teuchos::ParameterList> pl)
339 {
340  state_integrator_->setTempusParameterList(pl);
341  adjoint_integrator_->setTempusParameterList(pl);
342 }
343 
344 template<class Scalar>
345 Teuchos::RCP<const SolutionHistory<Scalar> >
348 {
349  return solutionHistory_;
350 }
351 
352 template<class Scalar>
353 Teuchos::RCP<SolutionHistory<Scalar> >
356 {
357  return solutionHistory_;
358 }
359 
360 template<class Scalar>
361 Teuchos::RCP<const TimeStepControl<Scalar> >
364 {
365  return state_integrator_->getTimeStepControl();
366 }
367 
368 template<class Scalar>
369 Teuchos::RCP<TimeStepControl<Scalar> >
372 {
373  return state_integrator_->getNonConstTimeStepControl();
374 }
375 
376 template<class Scalar>
379  Teuchos::RCP<const Thyra::VectorBase<Scalar> > x0,
380  Teuchos::RCP<const Thyra::VectorBase<Scalar> > xdot0,
381  Teuchos::RCP<const Thyra::VectorBase<Scalar> > xdotdot0,
382  Teuchos::RCP<const Thyra::MultiVectorBase<Scalar> > DxDp0,
383  Teuchos::RCP<const Thyra::MultiVectorBase<Scalar> > /* DxdotDp0 */,
384  Teuchos::RCP<const Thyra::MultiVectorBase<Scalar> > /* DxdotdotDp0 */)
385 {
386  state_integrator_->initializeSolutionHistory(t0, x0, xdot0, xdotdot0);
387  dxdp_init_ = DxDp0;
388 }
389 
390 template<class Scalar>
393 {
394  state_integrator_->setObserver(obs);
395  // Currently not setting observer on adjoint integrator because it isn't
396  // clear what we want to do with it
397  //adjoint_integrator_->setObserver(obs);
398 }
399 
400 template<class Scalar>
403 {
404  state_integrator_->initialize();
405  adjoint_integrator_->initialize();
406 }
407 
408 template<class Scalar>
409 Teuchos::RCP<const Thyra::VectorBase<Scalar> >
411 getX() const
412 {
413  return state_integrator_->getX();
414 }
415 
416 template<class Scalar>
417 Teuchos::RCP<const Thyra::VectorBase<Scalar> >
419 getXDot() const
420 {
421  return state_integrator_->getXDot();
422 }
423 
424 template<class Scalar>
425 Teuchos::RCP<const Thyra::VectorBase<Scalar> >
427 getXDotDot() const
428 {
429  return state_integrator_->getXDotDot();
430 }
431 
432 template<class Scalar>
433 Teuchos::RCP<const Thyra::MultiVectorBase<Scalar> >
435 getDgDp() const
436 {
437  return dgdp_;
438 }
439 
440 template<class Scalar>
441 std::string
443 description() const
444 {
445  std::string name = "Tempus::IntegratorAdjointSensitivity";
446  return(name);
447 }
448 
449 template<class Scalar>
450 void
453  Teuchos::FancyOStream &out,
454  const Teuchos::EVerbosityLevel verbLevel) const
455 {
456  auto l_out = Teuchos::fancyOStream( out.getOStream() );
457  Teuchos::OSTab ostab(*l_out, 2, this->description());
458  l_out->setOutputToRootOnly(0);
459 
460  *l_out << description() << "::describe" << std::endl;
461  state_integrator_->describe(*l_out, verbLevel);
462  adjoint_integrator_->describe(*l_out, verbLevel);
463 }
464 
465 
466 template <class Scalar>
467 Teuchos::RCP<AdjointAuxSensitivityModelEvaluator<Scalar> >
470  const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& model,
471  const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& adjoint_model,
472  const Teuchos::RCP<Teuchos::ParameterList>& inputPL)
473 {
474  using Teuchos::ParameterList;
475  using Teuchos::RCP;
476  using Teuchos::rcp;
477 
478  RCP<ParameterList> spl = Teuchos::parameterList();
479  if (inputPL != Teuchos::null)
480  {
481  *spl = inputPL->sublist("Sensitivities");
482  }
483  if (spl->isParameter("Response Depends on Parameters"))
484  spl->remove("Response Depends on Parameters");
485  if (spl->isParameter("Residual Depends on Parameters"))
486  spl->remove("Residual Depends on Parameters");
487  if (spl->isParameter("IC Depends on Parameters"))
488  spl->remove("IC Depends on Parameters");
489 
490  const Scalar tfinal = state_integrator_->getTimeStepControl()->getFinalTime();
492  model, adjoint_model, tfinal, spl));
493 }
494 
495 template<class Scalar>
496 void
499  const Teuchos::RCP<const SolutionHistory<Scalar> >& state_solution_history,
500  const Teuchos::RCP<const SolutionHistory<Scalar> >& adjoint_solution_history)
501 {
502  using Teuchos::RCP;
503  using Teuchos::rcp;
504  using Teuchos::rcp_dynamic_cast;
505  using Teuchos::ParameterList;
506  using Thyra::VectorBase;
508  using Thyra::VectorSpaceBase;
509  using Thyra::createMembers;
510  using Thyra::multiVectorProductVector;
511  using Thyra::assign;
512  typedef Thyra::DefaultProductVectorSpace<Scalar> DPVS;
513  typedef Thyra::DefaultProductVector<Scalar> DPV;
514 
515  RCP<const VectorSpaceBase<Scalar> > x_space = model_->get_x_space();
516  RCP<const VectorSpaceBase<Scalar> > adjoint_space =
517  rcp_dynamic_cast<const DPVS>(adjoint_aux_model_->get_x_space())->getBlock(0);
518  Teuchos::Array< RCP<const VectorSpaceBase<Scalar> > > spaces(2);
519  spaces[0] = x_space;
520  spaces[1] = adjoint_space;
521  RCP<const DPVS > prod_space = Thyra::productVectorSpace(spaces());
522 
523  int num_states = state_solution_history->getNumStates();
524  const Scalar t_final = state_integrator_->getTime();
525  for (int i=0; i<num_states; ++i) {
526  RCP<const SolutionState<Scalar> > forward_state =
527  (*state_solution_history)[i];
528  RCP<const SolutionState<Scalar> > adjoint_state =
529  adjoint_solution_history->findState(t_final-forward_state->getTime());
530 
531  // X
532  RCP<DPV> x = Thyra::defaultProductVector(prod_space);
533  RCP<const VectorBase<Scalar> > adjoint_x =
534  rcp_dynamic_cast<const DPV>(adjoint_state->getX())->getVectorBlock(0);
535  assign(x->getNonconstVectorBlock(0).ptr(), *(forward_state->getX()));
536  assign(x->getNonconstVectorBlock(1).ptr(), *(adjoint_x));
537  RCP<VectorBase<Scalar> > x_b = x;
538 
539  // X-Dot
540  RCP<DPV> x_dot = Thyra::defaultProductVector(prod_space);
541  RCP<const VectorBase<Scalar> > adjoint_x_dot =
542  rcp_dynamic_cast<const DPV>(adjoint_state->getXDot())->getVectorBlock(0);
543  assign(x_dot->getNonconstVectorBlock(0).ptr(), *(forward_state->getXDot()));
544  assign(x_dot->getNonconstVectorBlock(1).ptr(), *(adjoint_x_dot));
545  RCP<VectorBase<Scalar> > x_dot_b = x_dot;
546 
547  // X-Dot-Dot
548  RCP<DPV> x_dot_dot;
549  if (forward_state->getXDotDot() != Teuchos::null) {
550  x_dot_dot = Thyra::defaultProductVector(prod_space);
551  RCP<const VectorBase<Scalar> > adjoint_x_dot_dot =
552  rcp_dynamic_cast<const DPV>(
553  adjoint_state->getXDotDot())->getVectorBlock(0);
554  assign(x_dot_dot->getNonconstVectorBlock(0).ptr(),
555  *(forward_state->getXDotDot()));
556  assign(x_dot_dot->getNonconstVectorBlock(1).ptr(),
557  *(adjoint_x_dot_dot));
558  }
559  RCP<VectorBase<Scalar> > x_dot_dot_b = x_dot_dot;
560 
561  RCP<SolutionState<Scalar> > prod_state = forward_state->clone();
562  prod_state->setX(x_b);
563  prod_state->setXDot(x_dot_b);
564  prod_state->setXDotDot(x_dot_dot_b);
565  prod_state->setPhysicsState(Teuchos::null);
566  solutionHistory_->addState(prod_state);
567  }
568 }
569 
571 template<class Scalar>
572 Teuchos::RCP<IntegratorAdjointSensitivity<Scalar> >
574  Teuchos::RCP<Teuchos::ParameterList> inputPL,
575  const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& model
576  ,const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& adjoint_model)
577 {
578  // set the parameters
579  Teuchos::RCP<Teuchos::ParameterList> spl = Teuchos::parameterList();
580  if (inputPL != Teuchos::null)
581  *spl = inputPL->sublist("Sensitivities");
582 
583  int p_index = spl->get<int>("Sensitivity Parameter Index", 0);
584  int g_index = spl->get<int>("Response Function Index", 0);
585  bool g_depends_on_p = spl->get<bool>("Response Depends on Parameters", true);
586  bool f_depends_on_p = spl->get<bool>("Residual Depends on Parameters", true);
587  bool ic_depends_on_p = spl->get<bool>("IC Depends on Parameters", true);
588  bool mass_matrix_is_identity = spl->get<bool>("Mass Matrix Is Identity", false);
589 
590  auto state_integrator = createIntegratorBasic<Scalar>(inputPL, model);
591 
592  // createAdjointModel
593  if (spl->isParameter("Response Depends on Parameters"))
594  spl->remove("Response Depends on Parameters");
595  if (spl->isParameter("Residual Depends on Parameters"))
596  spl->remove("Residual Depends on Parameters");
597  if (spl->isParameter("IC Depends on Parameters"))
598  spl->remove("IC Depends on Parameters");
599 
600  const Scalar tfinal = state_integrator->getTimeStepControl()->getFinalTime();
601  //auto adjoint_model = Teuchos::rcp(new AdjointAuxSensitivityModelEvaluator<Scalar>(model, tfinal, spl));
602  //TODO: where is the adjoint ME coming from?
603 
604  Teuchos::RCP<Thyra::ModelEvaluator<Scalar>> adjt_model = adjoint_model;
605  if (adjoint_model == Teuchos::null)
606  adjt_model = Thyra::implicitAdjointModelEvaluator(model);
607 
608  auto adjoint_aux_model = Teuchos::rcp(new AdjointAuxSensitivityModelEvaluator<Scalar>(model, adjt_model, tfinal, spl));
609 
610  // Create combined solution histories combining the forward and adjoint
611  // solutions. We do not include the auxiliary part from the adjoint solution.
612  auto integrator_name = inputPL->get<std::string>("Integrator Name");
613  auto integratorPL = Teuchos::sublist(inputPL, integrator_name, true);
614  auto shPL = Teuchos::sublist(integratorPL, "Solution History", true);
615  auto combined_solution_History = createSolutionHistoryPL<Scalar>(shPL);
616 
617  auto adjoint_integrator = createIntegratorBasic<Scalar>(inputPL, adjoint_aux_model);
618 
619  Teuchos::RCP<IntegratorAdjointSensitivity<Scalar>> integrator = Teuchos::rcp(new IntegratorAdjointSensitivity<Scalar>(
620  model, state_integrator, adjt_model, adjoint_aux_model, adjoint_integrator, combined_solution_History, p_index, g_index, g_depends_on_p,
621  f_depends_on_p, ic_depends_on_p, mass_matrix_is_identity));
622 
623  return (integrator);
624 }
625 
627 template<class Scalar>
628 Teuchos::RCP<IntegratorAdjointSensitivity<Scalar> >
630 {
631  Teuchos::RCP<IntegratorAdjointSensitivity<Scalar> > integrator =
632  Teuchos::rcp(new IntegratorAdjointSensitivity<Scalar>());
633  return(integrator);
634 }
635 
636 } // namespace Tempus
637 #endif // Tempus_IntegratorAdjointSensitivity_impl_hpp
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const override
virtual Teuchos::RCP< TimeStepControl< Scalar > > getNonConstTimeStepControl() override
Teuchos::RCP< IntegratorAdjointSensitivity< Scalar > > createIntegratorAdjointSensitivity(Teuchos::RCP< Teuchos::ParameterList > pList, const Teuchos::RCP< Thyra::ModelEvaluator< Scalar >> &model, const Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > &adjoint_model=Teuchos::null)
Nonmember constructor.
virtual Teuchos::RCP< const Thyra::MultiVectorBase< Scalar > > getDgDp() const
Return adjoint sensitivity stored in gradient format.
virtual void setStatus(const Status st) override
Set Status.
virtual Teuchos::RCP< SolutionHistory< Scalar > > getNonConstSolutionHistory() override
Get the SolutionHistory.
ModelEvaluator for forming adjoint sensitivity equations.
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.
virtual Teuchos::RCP< const Thyra::VectorBase< Scalar > > getXDot() const
Get current the time derivative of the solution, xdot.
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< ImplicitAdjointModelEvaluator< Scalar > > implicitAdjointModelEvaluator(const RCP< const ModelEvaluator< Scalar > > &model)
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< Thyra::ModelEvaluator< Scalar > > &adjoint_model, const Teuchos::RCP< Teuchos::ParameterList > &inputPL)
virtual Scalar getTime() const override
Get current time.
virtual Status getStatus() const override
Get Status.
virtual Teuchos::RCP< const Thyra::VectorBase< Scalar > > getXDotDot() const
Get current the second time derivative of the solution, xdotdot.
virtual void initialize()
Initializes the Integrator after set* function calls.
virtual Teuchos::RCP< Stepper< Scalar > > getStepper() const override
Get the Stepper.
IntegratorAdjointSensitivity()
Constructor that requires a subsequent setParameterList, setStepper, and initialize calls...