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