Tempus  Version of the Day
Time Integration
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>
24  const Teuchos::RCP<Thyra::ModelEvaluator<Scalar>> &model,
25  const Teuchos::RCP<IntegratorBasic<Scalar>> &integrator,
26  const Teuchos::RCP<SensitivityModelEvaluatorBase<Scalar>> &sens_model,
27  const Teuchos::RCP<StepperStaggeredForwardSensitivity<Scalar>> &sens_stepper,
28  bool use_combined_method)
29  : model_(model)
30  , integrator_(integrator)
31  , sens_model_(sens_model)
32  , sens_stepper_(sens_stepper)
33  , use_combined_method_(use_combined_method)
34 {
35  integrator_->initialize();
36 }
37 
38 template<class Scalar>
41 {
42  integrator_ = createIntegratorBasic<Scalar>();
43  integrator_->initialize();
44 }
45 
46 template<class Scalar>
49  Teuchos::RCP<Thyra::ModelEvaluator<Scalar> > model)
50 {
51  if (use_combined_method_)
52  integrator_->setModel(sens_model_);
53  else
54  integrator_->setStepper(sens_stepper_);
55 }
56 
57 template<class Scalar>
60  Teuchos::RCP<const Thyra::VectorBase<Scalar> > x0,
61  Teuchos::RCP<const Thyra::VectorBase<Scalar> > xdot0,
62  Teuchos::RCP<const Thyra::VectorBase<Scalar> > xdotdot0,
63  Teuchos::RCP<const Thyra::MultiVectorBase<Scalar> > DxDp0,
64  Teuchos::RCP<const Thyra::MultiVectorBase<Scalar> > DxdotDp0,
65  Teuchos::RCP<const Thyra::MultiVectorBase<Scalar> > DxdotdotDp0)
66 {
67  using Teuchos::RCP;
68  using Teuchos::rcp_dynamic_cast;
69  using Thyra::VectorSpaceBase;
70  using Thyra::assign;
71  using Thyra::createMember;
72  typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
73 
74  //
75  // Create and initialize product X, Xdot, Xdotdot
76 
77  RCP< const VectorSpaceBase<Scalar> > space;
78  if (use_combined_method_)
79  space = sens_model_->get_x_space();
80  else
81  space = sens_stepper_->get_x_space();
82  RCP<DMVPV> X = rcp_dynamic_cast<DMVPV>(createMember(space));
83  RCP<DMVPV> Xdot = rcp_dynamic_cast<DMVPV>(createMember(space));
84  RCP<DMVPV> Xdotdot = rcp_dynamic_cast<DMVPV>(createMember(space));
85 
86  const int num_param = X->getNonconstMultiVector()->domain()->dim()-1;
87  const Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
88  const Teuchos::Range1D rng(1,num_param);
89 
90  // x
91  assign(X->getNonconstMultiVector()->col(0).ptr(), *x0);
92  if (DxDp0 == Teuchos::null)
93  assign(X->getNonconstMultiVector()->subView(rng).ptr(), zero);
94  else
95  assign(X->getNonconstMultiVector()->subView(rng).ptr(), *DxDp0);
96 
97  // xdot
98  if (xdot0 == Teuchos::null)
99  assign(Xdot->getNonconstMultiVector()->col(0).ptr(), zero);
100  else
101  assign(Xdot->getNonconstMultiVector()->col(0).ptr(), *xdot0);
102  if (DxdotDp0 == Teuchos::null)
103  assign(Xdot->getNonconstMultiVector()->subView(rng).ptr(), zero);
104  else
105  assign(Xdot->getNonconstMultiVector()->subView(rng).ptr(), *DxdotDp0);
106 
107  // xdotdot
108  if (xdotdot0 == Teuchos::null)
109  assign(Xdotdot->getNonconstMultiVector()->col(0).ptr(), zero);
110  else
111  assign(Xdotdot->getNonconstMultiVector()->col(0).ptr(), *xdotdot0);
112  if (DxdotDp0 == Teuchos::null)
113  assign(Xdotdot->getNonconstMultiVector()->subView(rng).ptr(), zero);
114  else
115  assign(Xdotdot->getNonconstMultiVector()->subView(rng).ptr(), *DxdotdotDp0);
116 
117  integrator_->initializeSolutionHistory(t0, X, Xdot, Xdotdot);
118 }
119 
120 template<class Scalar>
121 Teuchos::RCP<const Thyra::VectorBase<Scalar> >
123 getX() const
124 {
125  using Teuchos::RCP;
126  using Teuchos::rcp_dynamic_cast;
127  typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
128 
129  RCP<const DMVPV> X = rcp_dynamic_cast<const DMVPV>(integrator_->getX());
130  return X->getMultiVector()->col(0);
131 }
132 
133 template<class Scalar>
134 Teuchos::RCP<const Thyra::MultiVectorBase<Scalar> >
136 getDxDp() const
137 {
138  using Teuchos::RCP;
139  using Teuchos::rcp_dynamic_cast;
140  typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
141 
142  RCP<const DMVPV> X = rcp_dynamic_cast<const DMVPV>(integrator_->getX());
143  const int num_param = X->getMultiVector()->domain()->dim()-1;
144  const Teuchos::Range1D rng(1,num_param);
145  return X->getMultiVector()->subView(rng);
146 }
147 
148 template<class Scalar>
149 Teuchos::RCP<const Thyra::VectorBase<Scalar> >
151 getXDot() const
152 {
153  using Teuchos::RCP;
154  using Teuchos::rcp_dynamic_cast;
155  typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
156 
157  RCP<const DMVPV> Xdot = rcp_dynamic_cast<const DMVPV>(integrator_->getXDot());
158  return Xdot->getMultiVector()->col(0);
159 }
160 
161 template<class Scalar>
162 Teuchos::RCP<const Thyra::MultiVectorBase<Scalar> >
164 getDXDotDp() const
165 {
166  using Teuchos::RCP;
167  using Teuchos::rcp_dynamic_cast;
168  typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
169 
170  RCP<const DMVPV> Xdot = rcp_dynamic_cast<const DMVPV>(integrator_->getXDot());
171  const int num_param = Xdot->getMultiVector()->domain()->dim()-1;
172  const Teuchos::Range1D rng(1,num_param);
173  return Xdot->getMultiVector()->subView(rng);
174 }
175 
176 template<class Scalar>
177 Teuchos::RCP<const Thyra::VectorBase<Scalar> >
179 getXDotDot() const
180 {
181  using Teuchos::RCP;
182  using Teuchos::rcp_dynamic_cast;
183  typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
184 
185  RCP<const DMVPV> Xdotdot =
186  rcp_dynamic_cast<const DMVPV>(integrator_->getXDotDot());
187  return Xdotdot->getMultiVector()->col(0);
188 }
189 
190 template<class Scalar>
191 Teuchos::RCP<const Thyra::MultiVectorBase<Scalar> >
194 {
195  using Teuchos::RCP;
196  using Teuchos::rcp_dynamic_cast;
197  typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
198 
199  RCP<const DMVPV> Xdotdot =
200  rcp_dynamic_cast<const DMVPV>(integrator_->getXDotDot());
201  const int num_param = Xdotdot->getMultiVector()->domain()->dim()-1;
202  const Teuchos::Range1D rng(1,num_param);
203  return Xdotdot->getMultiVector()->subView(rng);
204 }
205 
206 template<class Scalar>
207 std::string
209 description() const
210 {
211  std::string name = "Tempus::IntegratorForwardSensitivity";
212  return(name);
213 }
214 
215 template<class Scalar>
216 void
219  Teuchos::FancyOStream &out,
220  const Teuchos::EVerbosityLevel verbLevel) const
221 {
222  auto l_out = Teuchos::fancyOStream( out.getOStream() );
223  Teuchos::OSTab ostab(*l_out, 2, this->description());
224  l_out->setOutputToRootOnly(0);
225 
226  *l_out << description() << "::describe" << std::endl;
227  integrator_->describe(*l_out, verbLevel);
228 }
229 
230 
232 template<class Scalar>
233 Teuchos::RCP<IntegratorForwardSensitivity<Scalar> >
235  Teuchos::RCP<Teuchos::ParameterList> pList,
236  const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& model)
237 {
238 
239 
240  Teuchos::RCP<SensitivityModelEvaluatorBase<Scalar> > sens_model;
241  Teuchos::RCP<StepperStaggeredForwardSensitivity<Scalar>> sens_stepper;
242 
243  //1. create integrator
244  auto fwd_integrator = createIntegratorBasic<Scalar>(pList, model);
245 
246  //2. set parameter list
247  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::rcp(new Teuchos::ParameterList);
248  {
249  Teuchos::RCP<const Teuchos::ParameterList> integrator_pl = fwd_integrator->getValidParameters();
250  Teuchos::RCP<const Teuchos::ParameterList> sensitivity_pl =
252  pl->setParameters(*integrator_pl);
253  Teuchos::ParameterList &spl = pl->sublist("Sensitivities");
254  spl.setParameters(*sensitivity_pl);
255  spl.set("Sensitivity Method", "Combined");
256  spl.set("Reuse State Linear Solver", false);
257  }
258  pList->setParametersNotAlreadySet(*pl);
259 
260  auto sens_pl = Teuchos::sublist(pList, "Sensitivities", false);
261  std::string integratorName = pList->get<std::string>("Integrator Name", "Default Integrator");
262  std::string stepperName = pList->sublist(integratorName).get<std::string>("Stepper Name");
263  auto stepper_pl = Teuchos::sublist(pList, stepperName, true);
264  std::string sensitivity_method = sens_pl->get<std::string>("Sensitivity Method");
265  bool use_combined_method = sensitivity_method == "Combined";
266 
267  //3. create sensitivity model and stepper
268  // createSensitivityModelAndStepper
269  {
270  sens_pl->remove("Sensitivity Method");
271 
272  if (use_combined_method)
273  {
274  sens_pl->remove("Reuse State Linear Solver");
275  sens_model = wrapCombinedFSAModelEvaluator(model, sens_pl);
276  fwd_integrator = createIntegratorBasic<Scalar>(pList, sens_model);
277  }
278  else
279  {
280  sens_stepper = Teuchos::rcp(new StepperStaggeredForwardSensitivity<Scalar>(model, stepper_pl, sens_pl));
281  auto fsa_staggered_me = Teuchos::rcp_const_cast<Thyra::ModelEvaluator<Scalar>>(sens_stepper->getModel());
282  fwd_integrator = createIntegratorBasic<Scalar>(pList, fsa_staggered_me);
283  fwd_integrator->setStepper(sens_stepper);
284  }
285  }
286 
287  //4. initialize propoer integrator
288  Teuchos::RCP<IntegratorForwardSensitivity<Scalar>> integrator =
289  Teuchos::rcp(new IntegratorForwardSensitivity<Scalar>(model, fwd_integrator, sens_model, sens_stepper, use_combined_method));
290  return (integrator);
291 }
292 
294 template<class Scalar>
295 Teuchos::RCP<IntegratorForwardSensitivity<Scalar> >
297 {
298 
299  Teuchos::RCP<IntegratorForwardSensitivity<Scalar> > integrator =
300  Teuchos::rcp(new IntegratorForwardSensitivity<Scalar>());
301  return(integrator);
302 }
303 
304 } // namespace Tempus
305 #endif // Tempus_IntegratorForwardSensitivity_impl_hpp
Teuchos::RCP< IntegratorBasic< Scalar > > integrator_
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->getX() which will return a Block MultiVector with the first block containing the current solution, x, and the remaining blocks are the forward sensitivities .
virtual void initializeSolutionHistory(Teuchos::RCP< SolutionState< Scalar > > state=Teuchos::null)
Set the initial state which has the initial conditions.
virtual Teuchos::RCP< const Thyra::MultiVectorBase< Scalar > > getDXDotDotDp() const
virtual Teuchos::RCP< const Thyra::MultiVectorBase< Scalar > > getDxDp() const
Get the forward sensitivities .
Teuchos::RCP< IntegratorForwardSensitivity< Scalar > > createIntegratorForwardSensitivity(Teuchos::RCP< Teuchos::ParameterList > pList, const Teuchos::RCP< Thyra::ModelEvaluator< Scalar >> &model)
Nonmember constructor.
A stepper implementing staggered forward sensitivity analysis.
virtual void setStepper(Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > model)
Set the Stepper.
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...
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...
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const override
Teuchos::RCP< SensitivityModelEvaluatorBase< Scalar > > wrapCombinedFSAModelEvaluator(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, const Teuchos::RCP< const Teuchos::ParameterList > &pList=Teuchos::null)
A ModelEvaluator decorator for sensitivity analysis.
Time integrator implementing forward sensitivity analysis.
virtual Teuchos::RCP< const Thyra::MultiVectorBase< Scalar > > getDXDotDp() const