Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Tempus_IntegratorForwardSensitivity_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_IntegratorForwardSensitivity_impl_hpp
10 #define Tempus_IntegratorForwardSensitivity_impl_hpp
11 
13 #include "Thyra_DefaultMultiVectorProductVector.hpp"
14 #include "Thyra_VectorStdOps.hpp"
15 #include "Thyra_MultiVectorStdOps.hpp"
16 
17 #include "Tempus_CombinedForwardSensitivityModelEvaluator.hpp"
19 
20 namespace Tempus {
21 
22 template <class Scalar>
25  const Teuchos::RCP<IntegratorBasic<Scalar>> &integrator,
28  &sens_stepper,
29  bool use_combined_method)
30  : model_(model),
31  integrator_(integrator),
32  sens_model_(sens_model),
33  sens_stepper_(sens_stepper),
34  use_combined_method_(use_combined_method)
35 {
36  integrator_->initialize();
37 }
38 
39 template <class Scalar>
41 {
42  integrator_ = createIntegratorBasic<Scalar>();
43  integrator_->initialize();
44 }
45 
46 template <class Scalar>
49 {
50  if (use_combined_method_)
51  integrator_->setModel(sens_model_);
52  else
53  integrator_->setStepper(sens_stepper_);
54 }
55 
56 template <class Scalar>
58  Scalar t0, Teuchos::RCP<const Thyra::VectorBase<Scalar>> x0,
64 {
65  using Teuchos::RCP;
66  using Teuchos::rcp_dynamic_cast;
67  using Thyra::assign;
68  using Thyra::createMember;
71 
72  //
73  // Create and initialize product X, Xdot, Xdotdot
74 
75  RCP<const VectorSpaceBase<Scalar>> space;
76  if (use_combined_method_)
77  space = sens_model_->get_x_space();
78  else
79  space = sens_stepper_->get_x_space();
80  RCP<DMVPV> X = rcp_dynamic_cast<DMVPV>(createMember(space));
81  RCP<DMVPV> Xdot = rcp_dynamic_cast<DMVPV>(createMember(space));
82  RCP<DMVPV> Xdotdot = rcp_dynamic_cast<DMVPV>(createMember(space));
83 
84  const int num_param = X->getNonconstMultiVector()->domain()->dim() - 1;
85  const Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
86  const Teuchos::Range1D rng(1, num_param);
87 
88  // x
89  assign(X->getNonconstMultiVector()->col(0).ptr(), *x0);
90  if (DxDp0 == Teuchos::null)
91  assign(X->getNonconstMultiVector()->subView(rng).ptr(), zero);
92  else
93  assign(X->getNonconstMultiVector()->subView(rng).ptr(), *DxDp0);
94 
95  // xdot
96  if (xdot0 == Teuchos::null)
97  assign(Xdot->getNonconstMultiVector()->col(0).ptr(), zero);
98  else
99  assign(Xdot->getNonconstMultiVector()->col(0).ptr(), *xdot0);
100  if (DxdotDp0 == Teuchos::null)
101  assign(Xdot->getNonconstMultiVector()->subView(rng).ptr(), zero);
102  else
103  assign(Xdot->getNonconstMultiVector()->subView(rng).ptr(), *DxdotDp0);
104 
105  // xdotdot
106  if (xdotdot0 == Teuchos::null)
107  assign(Xdotdot->getNonconstMultiVector()->col(0).ptr(), zero);
108  else
109  assign(Xdotdot->getNonconstMultiVector()->col(0).ptr(), *xdotdot0);
110  if (DxdotDp0 == Teuchos::null)
111  assign(Xdotdot->getNonconstMultiVector()->subView(rng).ptr(), zero);
112  else
113  assign(Xdotdot->getNonconstMultiVector()->subView(rng).ptr(), *DxdotdotDp0);
114 
115  integrator_->initializeSolutionHistory(t0, X, Xdot, Xdotdot);
116 }
117 
118 template <class Scalar>
121 {
122  using Teuchos::RCP;
123  using Teuchos::rcp_dynamic_cast;
125 
126  RCP<const DMVPV> X = rcp_dynamic_cast<const DMVPV>(integrator_->getX());
127  return X->getMultiVector()->col(0);
128 }
129 
130 template <class Scalar>
133 {
134  using Teuchos::RCP;
135  using Teuchos::rcp_dynamic_cast;
137 
138  RCP<const DMVPV> X = rcp_dynamic_cast<const DMVPV>(integrator_->getX());
139  const int num_param = X->getMultiVector()->domain()->dim() - 1;
140  const Teuchos::Range1D rng(1, num_param);
141  return X->getMultiVector()->subView(rng);
142 }
143 
144 template <class Scalar>
147 {
148  using Teuchos::RCP;
149  using Teuchos::rcp_dynamic_cast;
151 
152  RCP<const DMVPV> Xdot = rcp_dynamic_cast<const DMVPV>(integrator_->getXDot());
153  return Xdot->getMultiVector()->col(0);
154 }
155 
156 template <class Scalar>
159 {
160  using Teuchos::RCP;
161  using Teuchos::rcp_dynamic_cast;
163 
164  RCP<const DMVPV> Xdot = rcp_dynamic_cast<const DMVPV>(integrator_->getXDot());
165  const int num_param = Xdot->getMultiVector()->domain()->dim() - 1;
166  const Teuchos::Range1D rng(1, num_param);
167  return Xdot->getMultiVector()->subView(rng);
168 }
169 
170 template <class Scalar>
173 {
174  using Teuchos::RCP;
175  using Teuchos::rcp_dynamic_cast;
177 
178  RCP<const DMVPV> Xdotdot =
179  rcp_dynamic_cast<const DMVPV>(integrator_->getXDotDot());
180  return Xdotdot->getMultiVector()->col(0);
181 }
182 
183 template <class Scalar>
186 {
187  using Teuchos::RCP;
188  using Teuchos::rcp_dynamic_cast;
190 
191  RCP<const DMVPV> Xdotdot =
192  rcp_dynamic_cast<const DMVPV>(integrator_->getXDotDot());
193  const int num_param = Xdotdot->getMultiVector()->domain()->dim() - 1;
194  const Teuchos::Range1D rng(1, num_param);
195  return Xdotdot->getMultiVector()->subView(rng);
196 }
197 
198 template <class Scalar>
201 {
202  typedef Thyra::ModelEvaluatorBase MEB;
203 
204  // Compute g which is computed by response 1 of the
205  // sensitivity model evaluator
207  if (use_combined_method_)
208  smodel = sens_model_;
209  else
210  smodel = sens_stepper_->getModel();
211  MEB::InArgs<Scalar> inargs = smodel->getNominalValues();
212  MEB::OutArgs<Scalar> outargs = smodel->createOutArgs();
213  inargs.set_t(integrator_->getTime());
214  inargs.set_x(integrator_->getX());
215  if (inargs.supports(MEB::IN_ARG_x_dot))
216  inargs.set_x_dot(integrator_->getXDot());
217  if (inargs.supports(MEB::IN_ARG_x_dot_dot))
218  inargs.set_x_dot_dot(integrator_->getXDotDot());
219 
221  Thyra::createMember(smodel->get_g_space(1));
222  outargs.set_g(1, g);
223 
224  smodel->evalModel(inargs, outargs);
225  return g;
226 }
227 
228 template <class Scalar>
231 {
232  typedef Thyra::ModelEvaluatorBase MEB;
234 
235  // Compute final dg/dp which is computed by response 0 of the
236  // sensitivity model evaluator
238  if (use_combined_method_)
239  smodel = sens_model_;
240  else
241  smodel = sens_stepper_->getModel();
242  MEB::InArgs<Scalar> inargs = smodel->getNominalValues();
243  MEB::OutArgs<Scalar> outargs = smodel->createOutArgs();
244  inargs.set_t(integrator_->getTime());
245  inargs.set_x(integrator_->getX());
246  if (inargs.supports(MEB::IN_ARG_x_dot))
247  inargs.set_x_dot(integrator_->getXDot());
248  if (inargs.supports(MEB::IN_ARG_x_dot_dot))
249  inargs.set_x_dot_dot(integrator_->getXDotDot());
250 
252  Thyra::createMember(smodel->get_g_space(0));
253  Teuchos::RCP<DMVPV> dgdp = Teuchos::rcp_dynamic_cast<DMVPV>(G);
254  outargs.set_g(0, G);
255 
256  smodel->evalModel(inargs, outargs);
257  return dgdp->getMultiVector();
258 }
259 
260 template <class Scalar>
262 {
263  std::string name = "Tempus::IntegratorForwardSensitivity";
264  return (name);
265 }
266 
267 template <class Scalar>
269  Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
270 {
271  auto l_out = Teuchos::fancyOStream(out.getOStream());
272  Teuchos::OSTab ostab(*l_out, 2, this->description());
273  l_out->setOutputToRootOnly(0);
274 
275  *l_out << description() << "::describe" << std::endl;
276  integrator_->describe(*l_out, verbLevel);
277 }
278 
279 template <class Scalar>
281 {
282  if (use_combined_method_) return SensitivityStepMode::Combined;
283  return sens_stepper_->getStepMode(); // Staggered case
284 }
285 
287 template <class Scalar>
292  const Teuchos::RCP<Thyra::ModelEvaluator<Scalar>> &sens_residual_model,
293  const Teuchos::RCP<Thyra::ModelEvaluator<Scalar>> &sens_solve_model)
294 {
297 
298  // 1. create integrator
299  auto fwd_integrator = createIntegratorBasic<Scalar>(pList, model);
300 
301  // 2. set parameter list
304  {
306  fwd_integrator->getValidParameters();
309  pl->setParameters(*integrator_pl);
310  Teuchos::ParameterList &spl = pl->sublist("Sensitivities");
311  spl.setParameters(*sensitivity_pl);
312  spl.set("Sensitivity Method", "Combined");
313  spl.set("Reuse State Linear Solver", false);
314  }
315  pList->setParametersNotAlreadySet(*pl);
316 
317  auto sens_pl = Teuchos::sublist(pList, "Sensitivities", false);
318  std::string integratorName =
319  pList->get<std::string>("Integrator Name", "Default Integrator");
320  std::string stepperName =
321  pList->sublist(integratorName).get<std::string>("Stepper Name");
322  auto stepper_pl = Teuchos::sublist(pList, stepperName, true);
323  std::string sensitivity_method =
324  sens_pl->get<std::string>("Sensitivity Method");
325  bool use_combined_method = sensitivity_method == "Combined";
326 
327  // 3. create sensitivity model and stepper
328  // createSensitivityModelAndStepper
329  {
330  sens_pl->remove("Sensitivity Method");
331 
332  if (use_combined_method) {
333  sens_pl->remove("Reuse State Linear Solver");
334  sens_model = wrapCombinedFSAModelEvaluator(model, sens_residual_model,
335  sens_solve_model, sens_pl);
336  fwd_integrator = createIntegratorBasic<Scalar>(pList, sens_model);
337  }
338  else {
339  sens_stepper =
341  model, sens_residual_model, sens_solve_model, stepper_pl,
342  sens_pl));
343  auto fsa_staggered_me =
344  Teuchos::rcp_const_cast<Thyra::ModelEvaluator<Scalar>>(
345  sens_stepper->getModel());
346  fwd_integrator = createIntegratorBasic<Scalar>(pList, fsa_staggered_me);
347  fwd_integrator->setStepper(sens_stepper);
348  }
349  }
350 
351  // 4. initialize propoer integrator
354  model, fwd_integrator, sens_model, sens_stepper,
355  use_combined_method));
356  return (integrator);
357 }
358 
360 template <class Scalar>
363 {
366  return (integrator);
367 }
368 
369 } // namespace Tempus
370 #endif // Tempus_IntegratorForwardSensitivity_impl_hpp
Teuchos::RCP< IntegratorBasic< Scalar > > integrator_
Teuchos::RCP< IntegratorForwardSensitivity< Scalar > > createIntegratorForwardSensitivity(Teuchos::RCP< Teuchos::ParameterList > pList, const Teuchos::RCP< Thyra::ModelEvaluator< Scalar >> &model, const Teuchos::RCP< Thyra::ModelEvaluator< Scalar >> &sens_residual_model, const Teuchos::RCP< Thyra::ModelEvaluator< Scalar >> &sens_solve_model)
Nonmember constructor.
virtual Teuchos::RCP< const Thyra::VectorBase< Scalar > > getXDotDot() const
Get current the second time derivative of the solution, xdotdot, only. This is the first block only a...
virtual void setStepper(Teuchos::RCP< Thyra::ModelEvaluator< Scalar >> model)
Set the Stepper.
SensitivityStepMode getStepMode() const
What mode the current time integration step is in.
virtual Teuchos::RCP< const Thyra::MultiVectorBase< Scalar > > getDXDotDp() const
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
virtual Teuchos::RCP< const Thyra::MultiVectorBase< Scalar > > getDXDotDotDp() const
A stepper implementing staggered forward sensitivity analysis.
virtual Teuchos::RCP< const Thyra::MultiVectorBase< Scalar > > getDgDp() const
Return forward sensitivity stored in Jacobian format.
virtual Teuchos::RCP< const Thyra::MultiVectorBase< Scalar > > getDxDp() const
Get the forward sensitivities .
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::RCP< SensitivityModelEvaluatorBase< Scalar > > wrapCombinedFSAModelEvaluator(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &sens_residual_model, const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &sens_solve_model, const Teuchos::RCP< const Teuchos::ParameterList > &pList=Teuchos::null)
RCP< const MultiVectorBase< Scalar > > getMultiVector() const
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const override
ParameterList & setParameters(const ParameterList &source)
virtual Teuchos::RCP< const Thyra::VectorBase< Scalar > > getG() const
Return response function g.
virtual Teuchos::RCP< const Thyra::VectorBase< Scalar > > getX() const
Get the current solution, x, only. If looking for the solution vector and the sensitivities, use SolutionState-&gt;getX() which will return a Block MultiVector with the first block containing the current solution, x, and the remaining blocks are the forward sensitivities .
RCP< std::basic_ostream< char_type, traits_type > > getOStream()
ParameterList & setParametersNotAlreadySet(const ParameterList &source)
RCP< MultiVectorBase< Scalar > > getNonconstMultiVector()
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
virtual Teuchos::RCP< const Thyra::VectorBase< Scalar > > getXDot() const
Get current the time derivative of the solution, xdot, only. This is the first block only and not the...
A ModelEvaluator decorator for sensitivity analysis.
Time integrator implementing forward sensitivity analysis.
virtual void initializeSolutionHistory(Teuchos::RCP< SolutionState< Scalar >> state=Teuchos::null)
Set the initial state which has the initial conditions.