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  this->modelWarning();
33 }
34 
35 
36 template<class Scalar>
39  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
40  const Teuchos::RCP<Teuchos::ParameterList>& pList,
41  const Teuchos::RCP<Teuchos::ParameterList>& sens_pList)
42 {
43  // Set all the input parameters and call initialize
44  this->setParams(pList, sens_pList);
45  this->setModel(appModel);
46  this->initialize();
47 }
48 
49 
50 template<class Scalar>
53  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel)
54 {
55  using Teuchos::RCP;
56  using Teuchos::rcp;
57  using Teuchos::ParameterList;
58 
59  // Create forward sensitivity model evaluator wrapper
60  Teuchos::RCP<Teuchos::ParameterList> spl = Teuchos::parameterList();
61  *spl = *sensPL_;
62  spl->remove("Reuse State Linear Solver");
63  spl->remove("Force W Update");
64  fsa_model_ = wrapStaggeredFSAModelEvaluator(appModel, spl);
65 
66  // Create combined FSA ME which serves as "the" ME for this stepper,
67  // so that getModel() has a ME consistent the FSA problem (including both
68  // state and sensitivity components), e.g., the integrator may call
69  // getModel()->getNominalValues(), which needs to be consistent.
70  combined_fsa_model_ = wrapCombinedFSAModelEvaluator(appModel, spl);
71 
72  // Create state and sensitivity steppers
73  RCP<StepperFactory<Scalar> > sf =Teuchos::rcp(new StepperFactory<Scalar>());
74  if (stateStepper_ == Teuchos::null)
75  stateStepper_ = sf->createStepper(stepperPL_, appModel);
76  else
77  stateStepper_->setModel(appModel);
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>
96 setSolver(std::string solverName)
97 {
98  stateStepper_->setSolver(solverName);
99  sensitivityStepper_->setSolver(solverName);
100 }
101 
102 template<class Scalar>
103 Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >
106 {
107  return combined_fsa_model_;
108 }
109 
110 
111 template<class Scalar>
114  Teuchos::RCP<Teuchos::ParameterList> solverPL)
115 {
116  stateStepper_->setSolver(solverPL);
117  sensitivityStepper_->setSolver(solverPL);
118 }
119 
120 
121 template<class Scalar>
124  Teuchos::RCP<Thyra::NonlinearSolverBase<Scalar> > solver)
125 {
126  stateStepper_->setSolver(solver);
127  sensitivityStepper_->setSolver(solver);
128 }
129 
130 
131 template<class Scalar>
134 {
135  this->setSolver();
136 }
137 
138 
139 template<class Scalar>
142  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
143 {
144  using Teuchos::RCP;
145  using Teuchos::rcp;
146  using Teuchos::rcp_dynamic_cast;
147  using Thyra::VectorBase;
148  using Thyra::MultiVectorBase;
149  using Thyra::assign;
150  using Thyra::createMember;
151  using Thyra::multiVectorProductVector;
152  using Thyra::multiVectorProductVectorSpace;
153  typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
154  typedef Thyra::DefaultMultiVectorProductVectorSpace<Scalar> DMVPVS;
155 
156  // Initialize state, sensitivity solution histories if necessary.
157  // We only need to split the solution history into state and sensitivity
158  // components for the first step, otherwise the state and sensitivity
159  // histories are updated from the previous step.
160  if (stateSolutionHistory_ == Teuchos::null) {
161  RCP<Teuchos::ParameterList> shPL =
162  solutionHistory->getNonconstParameterList();
163 
164  // Get product X, XDot, XDotDot
165  RCP<SolutionState<Scalar> > state = solutionHistory->getCurrentState();
166  RCP<DMVPV> X, XDot, XDotDot;
167  X = rcp_dynamic_cast<DMVPV>(state->getX(),true);
168  XDot = rcp_dynamic_cast<DMVPV>(state->getXDot(),true);
169  if (state->getXDotDot() != Teuchos::null)
170  XDotDot = rcp_dynamic_cast<DMVPV>(state->getXDotDot(),true);
171 
172  // Pull out state components (has to be non-const because of SolutionState
173  // constructor)
174  RCP<VectorBase<Scalar> > x, xdot, xdotdot;
175  x = X->getNonconstMultiVector()->col(0);
176  xdot = XDot->getNonconstMultiVector()->col(0);
177  if (XDotDot != Teuchos::null)
178  xdotdot = XDotDot->getNonconstMultiVector()->col(0);
179 
180  // Create state solution history
181  RCP<SolutionState<Scalar> > state_state =
182  rcp(new SolutionState<Scalar>(state->getMetaData()->clone(),
183  x, xdot, xdotdot,
184  state->getStepperState()->clone()));
185  stateSolutionHistory_ = rcp(new SolutionHistory<Scalar>(shPL));
186  stateSolutionHistory_->addState(state_state);
187 
188  const int num_param = X->getMultiVector()->domain()->dim()-1;
189  TEUCHOS_ASSERT(num_param > 0);
190  const Teuchos::Range1D rng(1,num_param);
191 
192  // Pull out sensitivity components
193  RCP<MultiVectorBase<Scalar> > dxdp, dxdotdp, dxdotdotdp;
194  dxdp = X->getNonconstMultiVector()->subView(rng);
195  dxdotdp = XDot->getNonconstMultiVector()->subView(rng);
196  if (XDotDot != Teuchos::null)
197  dxdotdotdp = XDotDot->getNonconstMultiVector()->subView(rng);
198 
199  // Create sensitivity product vectors
200  RCP<VectorBase<Scalar> > dxdp_vec, dxdotdp_vec, dxdotdotdp_vec;
201  RCP<const DMVPVS> prod_space =
202  multiVectorProductVectorSpace(X->getMultiVector()->range(), num_param);
203  dxdp_vec = multiVectorProductVector(prod_space, dxdp);
204  dxdotdp_vec = multiVectorProductVector(prod_space, dxdotdp);
205  if (XDotDot != Teuchos::null)
206  dxdotdotdp_vec = multiVectorProductVector(prod_space, dxdotdotdp);
207 
208  // Create sensitivity solution history
209  RCP<SolutionState<Scalar> > sens_state =
210  rcp(new SolutionState<Scalar>(state->getMetaData()->clone(),
211  dxdp_vec, dxdotdp_vec, dxdotdotdp_vec,
212  state->getStepperState()->clone()));
213  sensSolutionHistory_ = rcp(new SolutionHistory<Scalar>(shPL));
214  sensSolutionHistory_->addState(sens_state);
215  }
216 
217  // Get our working state
218  RCP<SolutionState<Scalar> > prod_state = solutionHistory->getWorkingState();
219  RCP<DMVPV> X, XDot, XDotDot;
220  X = rcp_dynamic_cast<DMVPV>(prod_state->getX(),true);
221  XDot = rcp_dynamic_cast<DMVPV>(prod_state->getXDot(),true);
222  if (prod_state->getXDotDot() != Teuchos::null)
223  XDotDot = rcp_dynamic_cast<DMVPV>(prod_state->getXDotDot(),true);
224 
225  // Take step for state equations
226  stateSolutionHistory_->initWorkingState();
227  RCP<SolutionState<Scalar> > state = stateSolutionHistory_->getWorkingState();
228  state->getMetaData()->copy(prod_state->getMetaData());
229  stateStepper_->takeStep(stateSolutionHistory_);
230 
231  // Set state components of product state
232  assign(X->getNonconstMultiVector()->col(0).ptr(), *(state->getX()));
233  assign(XDot->getNonconstMultiVector()->col(0).ptr(), *(state->getXDot()));
234  if (XDotDot != Teuchos::null)
235  assign(XDotDot->getNonconstMultiVector()->col(0).ptr(),
236  *(state->getXDotDot()));
237  prod_state->setOrder(state->getOrder());
238 
239  // If step passed promote the state, otherwise fail and stop
240  if (state->getSolutionStatus() == Status::FAILED) {
241  prod_state->setSolutionStatus(Status::FAILED);
242  return;
243  }
244  stateSolutionHistory_->promoteWorkingState();
245 
246  // Get forward state in sensitivity model evaluator
247  fsa_model_->setForwardSolutionHistory(stateSolutionHistory_);
248  if (reuse_solver_ && stateStepper_->getSolver() != Teuchos::null)
249  fsa_model_->setSolver(stateStepper_->getSolver(), force_W_update_);
250 
251  // Take step in sensitivity equations
252  sensSolutionHistory_->initWorkingState();
253  RCP<SolutionState<Scalar> > sens_state =
254  sensSolutionHistory_->getWorkingState();
255  sens_state->getMetaData()->copy(prod_state->getMetaData());
256  sensitivityStepper_->takeStep(sensSolutionHistory_);
257 
258  // Set sensitivity components of product state
259  RCP<const MultiVectorBase<Scalar> > dxdp =
260  rcp_dynamic_cast<const DMVPV>(sens_state->getX(),true)->getMultiVector();
261  const int num_param = dxdp->domain()->dim();
262  const Teuchos::Range1D rng(1,num_param);
263  assign(X->getNonconstMultiVector()->subView(rng).ptr(), *dxdp);
264  RCP<const MultiVectorBase<Scalar> > dxdotdp =
265  rcp_dynamic_cast<const DMVPV>(sens_state->getXDot(),true)->getMultiVector();
266  assign(XDot->getNonconstMultiVector()->subView(rng).ptr(), *dxdotdp);
267  if (sens_state->getXDotDot() != Teuchos::null) {
268  RCP<const MultiVectorBase<Scalar> > dxdotdotdp =
269  rcp_dynamic_cast<const DMVPV>(sens_state->getXDotDot(),true)->getMultiVector();
270  assign(XDotDot->getNonconstMultiVector()->subView(rng).ptr(), *dxdotdotdp);
271  }
272  prod_state->setOrder(std::min(state->getOrder(), sens_state->getOrder()));
273 
274  // If step passed promote the state, otherwise fail and stop
275  if (sens_state->getSolutionStatus() == Status::FAILED) {
276  prod_state->setSolutionStatus(Status::FAILED);
277  }
278  else {
279  sensSolutionHistory_->promoteWorkingState();
280  prod_state->setSolutionStatus(Status::PASSED);
281  }
282 }
283 
284 
285 template<class Scalar>
286 Teuchos::RCP<Tempus::StepperState<Scalar> >
289 {
290  // ETP: Note, maybe this should be a special stepper state that combines
291  // states from both state and sensitivity steppers?
292  Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
293  rcp(new StepperState<Scalar>(description()));
294  return stepperState;
295 }
296 
297 
298 template<class Scalar>
300 description() const
301 {
302  std::string name = "StepperStaggeredForwardSensitivity";
303  return(name);
304 }
305 
306 
307 template<class Scalar>
310  Teuchos::FancyOStream &out,
311  const Teuchos::EVerbosityLevel verbLevel) const
312 {
313  out << description() << "::describe:" << std::endl;
314  stateStepper_->describe(out, verbLevel);
315  out << std::endl;
316  sensitivityStepper_->describe(out, verbLevel);
317 }
318 
319 
320 template <class Scalar>
323  Teuchos::RCP<Teuchos::ParameterList> const& pList)
324 {
325  if (pList == Teuchos::null) {
326  // Create default parameters if null, otherwise keep current parameters.
327  if (stepperPL_ == Teuchos::null) stepperPL_ = this->getDefaultParameters();
328  } else {
329  stepperPL_ = pList;
330  }
331  // Can not validate because of optional Parameters (e.g., Solver Name).
332  //stepperPL_->validateParametersAndSetDefaults(*this->getValidParameters());
333 }
334 
335 
336 template<class Scalar>
337 Teuchos::RCP<const Teuchos::ParameterList>
340 {
341  return stateStepper_->getValidParameters();
342 }
343 
344 
345 template<class Scalar>
346 Teuchos::RCP<Teuchos::ParameterList>
349 {
350  return stateStepper_->getDefaultParameters();
351 }
352 
353 
354 template <class Scalar>
355 Teuchos::RCP<Teuchos::ParameterList>
358 {
359  return stepperPL_;
360 }
361 
362 
363 template <class Scalar>
364 Teuchos::RCP<Teuchos::ParameterList>
367 {
368  Teuchos::RCP<Teuchos::ParameterList> temp_plist = stepperPL_;
369  stepperPL_ = Teuchos::null;
370  return temp_plist;
371 }
372 
373 
374 template <class Scalar>
377  Teuchos::RCP<Teuchos::ParameterList> const& pList,
378  Teuchos::RCP<Teuchos::ParameterList> const& spList)
379 {
380  if (pList == Teuchos::null)
381  stepperPL_ = this->getDefaultParameters();
382  else
383  stepperPL_ = pList;
384 
385  if (spList == Teuchos::null)
386  sensPL_ = Teuchos::parameterList();
387  else
388  sensPL_ = spList;
389 
390  reuse_solver_ = sensPL_->get("Reuse State Linear Solver", false);
391  force_W_update_ = sensPL_->get("Force W Update", true);
392 
393  // Can not validate because of optional Parameters (e.g., Solver Name).
394  //stepperPL_->validateParametersAndSetDefaults(*this->getValidParameters());
395 }
396 
397 
398 template <class Scalar>
399 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
401 get_x_space() const
402 {
403  using Teuchos::RCP;
404  using Teuchos::rcp_dynamic_cast;
405  typedef Thyra::DefaultMultiVectorProductVectorSpace<Scalar> DMVPVS;
406 
407  RCP<const Thyra::VectorSpaceBase<Scalar> > x_space =
408  stateStepper_->getModel()->get_x_space();
409  RCP<const DMVPVS> dxdp_space =
410  rcp_dynamic_cast<const DMVPVS>(sensitivityStepper_->getModel()->get_x_space(),true);
411  const int num_param = dxdp_space->numBlocks();
412  RCP<const Thyra::VectorSpaceBase<Scalar> > prod_space =
413  multiVectorProductVectorSpace(x_space, num_param+1);
414  return prod_space;
415 }
416 
417 } // namespace Tempus
418 
419 #endif // Tempus_StepperStaggeredForwardSensitivity_impl_hpp
virtual void initialize()
Initialize during construction and after changing input parameters.
virtual void setSolver(std::string solverName)
Set solver via ParameterList solver name.
Teuchos::RCP< Teuchos::ParameterList > getDefaultParameters() const
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)
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