Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Tempus_StepperStaggeredForwardSensitivity_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_StepperStaggeredForwardSensitivity_impl_hpp
10 #define Tempus_StepperStaggeredForwardSensitivity_impl_hpp
11 
12 #include "Tempus_config.hpp"
16 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
17 
18 #include "Thyra_DefaultMultiVectorProductVectorSpace.hpp"
19 #include "Thyra_DefaultMultiVectorProductVector.hpp"
20 
21 namespace Tempus {
22 
23 // Forward Declaration for recursive includes (this Stepper <--> StepperFactory)
24 template<class Scalar> class StepperFactory;
25 
26 
27 template<class Scalar>
30 {
31  this->setParams(Teuchos::null, Teuchos::null);
32 }
33 
34 
35 template<class Scalar>
38  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
39  const Teuchos::RCP<Teuchos::ParameterList>& pList,
40  const Teuchos::RCP<Teuchos::ParameterList>& sens_pList)
41 {
42  // Set all the input parameters and call initialize
43  this->setParams(pList, sens_pList);
44  this->setModel(appModel);
45  this->initialize();
46 }
47 
48 
49 template<class Scalar>
52  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel)
53 {
54  using Teuchos::RCP;
55  using Teuchos::rcp;
56  using Teuchos::ParameterList;
57 
58  // Create forward sensitivity model evaluator wrapper
59  Teuchos::RCP<Teuchos::ParameterList> spl = Teuchos::parameterList();
60  *spl = *sensPL_;
61  spl->remove("Reuse State Linear Solver");
62  spl->remove("Force W Update");
63  fsa_model_ = wrapStaggeredFSAModelEvaluator(appModel, spl);
64 
65  // Create combined FSA ME which serves as "the" ME for this stepper,
66  // so that getModel() has a ME consistent the FSA problem (including both
67  // state and sensitivity components), e.g., the integrator may call
68  // getModel()->getNominalValues(), which needs to be consistent.
69  combined_fsa_model_ = wrapCombinedFSAModelEvaluator(appModel, spl);
70 
71  // Create state and sensitivity steppers
72  RCP<StepperFactory<Scalar> > sf =Teuchos::rcp(new StepperFactory<Scalar>());
73  if (stateStepper_ == Teuchos::null)
74  stateStepper_ = sf->createStepper(stepperPL_, appModel);
75  else
76  stateStepper_->setModel(appModel);
77 
78  if (sensitivityStepper_ == Teuchos::null)
79  sensitivityStepper_ = sf->createStepper(stepperPL_, fsa_model_);
80  else
81  sensitivityStepper_->setModel(fsa_model_);
82 }
83 
84 
85 template<class Scalar>
88  const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& appModel)
89 {
90  this->setModel(appModel);
91 }
92 
93 
94 template<class Scalar>
95 Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >
98 {
99  return combined_fsa_model_;
100 }
101 
102 
103 template<class Scalar>
106  Teuchos::RCP<Thyra::NonlinearSolverBase<Scalar> > solver)
107 {
108  stateStepper_->setSolver(solver);
109  sensitivityStepper_->setSolver(solver);
110 }
111 
112 
113 template<class Scalar>
116 {
117 }
118 
119 
120 template<class Scalar>
123  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
124 {
125  using Teuchos::RCP;
126  using Teuchos::rcp;
127  using Teuchos::rcp_dynamic_cast;
128  using Thyra::VectorBase;
129  using Thyra::MultiVectorBase;
130  using Thyra::assign;
131  using Thyra::createMember;
132  using Thyra::multiVectorProductVector;
133  using Thyra::multiVectorProductVectorSpace;
134  typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
135  typedef Thyra::DefaultMultiVectorProductVectorSpace<Scalar> DMVPVS;
136 
137  // Initialize state, sensitivity solution histories if necessary.
138  // We only need to split the solution history into state and sensitivity
139  // components for the first step, otherwise the state and sensitivity
140  // histories are updated from the previous step.
141  if (stateSolutionHistory_ == Teuchos::null) {
142  RCP<Teuchos::ParameterList> shPL =
143  solutionHistory->getNonconstParameterList();
144 
145  // Get product X, XDot, XDotDot
146  RCP<SolutionState<Scalar> > state = solutionHistory->getCurrentState();
147  RCP<DMVPV> X, XDot, XDotDot;
148  X = rcp_dynamic_cast<DMVPV>(state->getX(),true);
149  XDot = rcp_dynamic_cast<DMVPV>(state->getXDot(),true);
150  if (state->getXDotDot() != Teuchos::null)
151  XDotDot = rcp_dynamic_cast<DMVPV>(state->getXDotDot(),true);
152 
153  // Pull out state components (has to be non-const because of SolutionState
154  // constructor)
155  RCP<VectorBase<Scalar> > x, xdot, xdotdot;
156  x = X->getNonconstMultiVector()->col(0);
157  xdot = XDot->getNonconstMultiVector()->col(0);
158  if (XDotDot != Teuchos::null)
159  xdotdot = XDotDot->getNonconstMultiVector()->col(0);
160 
161  // Create state solution history
162  RCP<SolutionState<Scalar> > state_state =
163  rcp(new SolutionState<Scalar>(state->getMetaData()->clone(),
164  x, xdot, xdotdot,
165  state->getStepperState()->clone()));
166  stateSolutionHistory_ = rcp(new SolutionHistory<Scalar>(shPL));
167  stateSolutionHistory_->addState(state_state);
168 
169  const int num_param = X->getMultiVector()->domain()->dim()-1;
170  TEUCHOS_ASSERT(num_param > 0);
171  const Teuchos::Range1D rng(1,num_param);
172 
173  // Pull out sensitivity components
174  RCP<MultiVectorBase<Scalar> > dxdp, dxdotdp, dxdotdotdp;
175  dxdp = X->getNonconstMultiVector()->subView(rng);
176  dxdotdp = XDot->getNonconstMultiVector()->subView(rng);
177  if (XDotDot != Teuchos::null)
178  dxdotdotdp = XDotDot->getNonconstMultiVector()->subView(rng);
179 
180  // Create sensitivity product vectors
181  RCP<VectorBase<Scalar> > dxdp_vec, dxdotdp_vec, dxdotdotdp_vec;
182  RCP<const DMVPVS> prod_space =
183  multiVectorProductVectorSpace(X->getMultiVector()->range(), num_param);
184  dxdp_vec = multiVectorProductVector(prod_space, dxdp);
185  dxdotdp_vec = multiVectorProductVector(prod_space, dxdotdp);
186  if (XDotDot != Teuchos::null)
187  dxdotdotdp_vec = multiVectorProductVector(prod_space, dxdotdotdp);
188 
189  // Create sensitivity solution history
190  RCP<SolutionState<Scalar> > sens_state =
191  rcp(new SolutionState<Scalar>(state->getMetaData()->clone(),
192  dxdp_vec, dxdotdp_vec, dxdotdotdp_vec,
193  state->getStepperState()->clone()));
194  sensSolutionHistory_ = rcp(new SolutionHistory<Scalar>(shPL));
195  sensSolutionHistory_->addState(sens_state);
196  }
197 
198  // Get our working state
199  RCP<SolutionState<Scalar> > prod_state = solutionHistory->getWorkingState();
200  RCP<DMVPV> X, XDot, XDotDot;
201  X = rcp_dynamic_cast<DMVPV>(prod_state->getX(),true);
202  XDot = rcp_dynamic_cast<DMVPV>(prod_state->getXDot(),true);
203  if (prod_state->getXDotDot() != Teuchos::null)
204  XDotDot = rcp_dynamic_cast<DMVPV>(prod_state->getXDotDot(),true);
205 
206  // Take step for state equations
207  stateSolutionHistory_->initWorkingState();
208  RCP<SolutionState<Scalar> > state = stateSolutionHistory_->getWorkingState();
209  state->getMetaData()->copy(prod_state->getMetaData());
210  stateStepper_->takeStep(stateSolutionHistory_);
211 
212  // Set state components of product state
213  assign(X->getNonconstMultiVector()->col(0).ptr(), *(state->getX()));
214  assign(XDot->getNonconstMultiVector()->col(0).ptr(), *(state->getXDot()));
215  if (XDotDot != Teuchos::null)
216  assign(XDotDot->getNonconstMultiVector()->col(0).ptr(),
217  *(state->getXDotDot()));
218  prod_state->setOrder(state->getOrder());
219 
220  // If step passed promote the state, otherwise fail and stop
221  if (state->getSolutionStatus() == Status::FAILED) {
222  prod_state->setSolutionStatus(Status::FAILED);
223  return;
224  }
225  stateSolutionHistory_->promoteWorkingState();
226 
227  // Get forward state in sensitivity model evaluator
228  fsa_model_->setForwardSolutionHistory(stateSolutionHistory_);
229  if (reuse_solver_ && stateStepper_->getSolver() != Teuchos::null)
230  fsa_model_->setSolver(stateStepper_->getSolver(), force_W_update_);
231 
232  // Take step in sensitivity equations
233  sensSolutionHistory_->initWorkingState();
234  RCP<SolutionState<Scalar> > sens_state =
235  sensSolutionHistory_->getWorkingState();
236  sens_state->getMetaData()->copy(prod_state->getMetaData());
237  sensitivityStepper_->takeStep(sensSolutionHistory_);
238 
239  // Set sensitivity components of product state
240  RCP<const MultiVectorBase<Scalar> > dxdp =
241  rcp_dynamic_cast<const DMVPV>(sens_state->getX(),true)->getMultiVector();
242  const int num_param = dxdp->domain()->dim();
243  const Teuchos::Range1D rng(1,num_param);
244  assign(X->getNonconstMultiVector()->subView(rng).ptr(), *dxdp);
245  RCP<const MultiVectorBase<Scalar> > dxdotdp =
246  rcp_dynamic_cast<const DMVPV>(sens_state->getXDot(),true)->getMultiVector();
247  assign(XDot->getNonconstMultiVector()->subView(rng).ptr(), *dxdotdp);
248  if (sens_state->getXDotDot() != Teuchos::null) {
249  RCP<const MultiVectorBase<Scalar> > dxdotdotdp =
250  rcp_dynamic_cast<const DMVPV>(sens_state->getXDotDot(),true)->getMultiVector();
251  assign(XDotDot->getNonconstMultiVector()->subView(rng).ptr(), *dxdotdotdp);
252  }
253  prod_state->setOrder(std::min(state->getOrder(), sens_state->getOrder()));
254 
255  // If step passed promote the state, otherwise fail and stop
256  if (sens_state->getSolutionStatus() == Status::FAILED) {
257  prod_state->setSolutionStatus(Status::FAILED);
258  }
259  else {
260  sensSolutionHistory_->promoteWorkingState();
261  prod_state->setSolutionStatus(Status::PASSED);
262  }
263 }
264 
265 
266 template<class Scalar>
267 Teuchos::RCP<Tempus::StepperState<Scalar> >
270 {
271  // ETP: Note, maybe this should be a special stepper state that combines
272  // states from both state and sensitivity steppers?
273  Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
274  rcp(new StepperState<Scalar>(description()));
275  return stepperState;
276 }
277 
278 
279 template<class Scalar>
282  Teuchos::FancyOStream &out,
283  const Teuchos::EVerbosityLevel verbLevel) const
284 {
285  out << description() << "::describe:" << std::endl;
286  stateStepper_->describe(out, verbLevel);
287  out << std::endl;
288  sensitivityStepper_->describe(out, verbLevel);
289 }
290 
291 
292 template <class Scalar>
295  Teuchos::RCP<Teuchos::ParameterList> const& pList)
296 {
297  if (pList == Teuchos::null) {
298  // Create default parameters if null, otherwise keep current parameters.
299  if (this->stepperPL_ == Teuchos::null) this->stepperPL_ =
300  Teuchos::rcp_const_cast<Teuchos::ParameterList>(this->getValidParameters());
301  } else {
302  this->stepperPL_ = pList;
303  }
304  // Can not validate because of optional Parameters (e.g., Solver Name).
305  //stepperPL_->validateParametersAndSetDefaults(*this->getValidParameters());
306 }
307 
308 
309 template<class Scalar>
310 Teuchos::RCP<const Teuchos::ParameterList>
313 {
314  return stateStepper_->getValidParameters();
315 }
316 
317 
318 template <class Scalar>
319 Teuchos::RCP<Teuchos::ParameterList>
322 {
323  return stepperPL_;
324 }
325 
326 
327 template <class Scalar>
328 Teuchos::RCP<Teuchos::ParameterList>
331 {
332  Teuchos::RCP<Teuchos::ParameterList> temp_plist = stepperPL_;
333  stepperPL_ = Teuchos::null;
334  return temp_plist;
335 }
336 
337 
338 template <class Scalar>
341  Teuchos::RCP<Teuchos::ParameterList> const& pList,
342  Teuchos::RCP<Teuchos::ParameterList> const& spList)
343 {
344  if (pList == Teuchos::null)
345  stepperPL_ = Teuchos::rcp_const_cast<Teuchos::ParameterList>(this->getValidParameters());
346  else
347  stepperPL_ = pList;
348 
349  if (spList == Teuchos::null)
350  sensPL_ = Teuchos::parameterList();
351  else
352  sensPL_ = spList;
353 
354  reuse_solver_ = sensPL_->get("Reuse State Linear Solver", false);
355  force_W_update_ = sensPL_->get("Force W Update", true);
356 
357  // Can not validate because of optional Parameters (e.g., Solver Name).
358  //stepperPL_->validateParametersAndSetDefaults(*this->getValidParameters());
359 }
360 
361 
362 template <class Scalar>
363 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
365 get_x_space() const
366 {
367  using Teuchos::RCP;
368  using Teuchos::rcp_dynamic_cast;
369  typedef Thyra::DefaultMultiVectorProductVectorSpace<Scalar> DMVPVS;
370 
371  RCP<const Thyra::VectorSpaceBase<Scalar> > x_space =
372  stateStepper_->getModel()->get_x_space();
373  RCP<const DMVPVS> dxdp_space =
374  rcp_dynamic_cast<const DMVPVS>(sensitivityStepper_->getModel()->get_x_space(),true);
375  const int num_param = dxdp_space->numBlocks();
376  RCP<const Thyra::VectorSpaceBase<Scalar> > prod_space =
377  multiVectorProductVectorSpace(x_space, num_param+1);
378  return prod_space;
379 }
380 
381 } // namespace Tempus
382 
383 #endif // Tempus_StepperStaggeredForwardSensitivity_impl_hpp
virtual void initialize()
Initialize during construction and after changing input parameters.
virtual void setNonConstModel(const Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > &appModel)
virtual Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > getModel()
virtual void takeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Take the specified timestep, dt, and return true if successful.
Teuchos::RCP< SensitivityModelEvaluatorBase< Scalar > > wrapStaggeredFSAModelEvaluator(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, const Teuchos::RCP< const Teuchos::ParameterList > &pList=Teuchos::null)
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Get a default (initial) StepperState.
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel)
StepperState is a simple class to hold state information about the stepper.
Teuchos::RCP< SolutionHistory< Scalar > > solutionHistory(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
Nonmember constructor.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Teuchos::RCP< SensitivityModelEvaluatorBase< Scalar > > wrapCombinedFSAModelEvaluator(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, const Teuchos::RCP< const Teuchos::ParameterList > &pList=Teuchos::null)
void setParams(const Teuchos::RCP< Teuchos::ParameterList > &pl, const Teuchos::RCP< Teuchos::ParameterList > &spl)
virtual void setSolver(Teuchos::RCP< Thyra::NonlinearSolverBase< Scalar > > solver=Teuchos::null)
Set solver.
Solution state for integrators and steppers. SolutionState contains the metadata for solutions and th...
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &pl)
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const