Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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 "Thyra_VectorStdOps.hpp"
13 #include "Thyra_MultiVectorStdOps.hpp"
14 #include "Thyra_DefaultMultiVectorProductVectorSpace.hpp"
15 #include "Thyra_DefaultMultiVectorProductVector.hpp"
16 
17 #include "Tempus_StepperFactory.hpp"
20 
21 namespace Tempus {
22 
23 template <class Scalar>
25  : stepMode_(SensitivityStepMode::Forward)
26 {
27  this->setStepperName("StaggeredForwardSensitivity");
28  this->setStepperType("StaggeredForwardSensitivity");
29  this->setParams(Teuchos::null, Teuchos::null);
30 }
31 
32 template <class Scalar>
34  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
36  sens_residual_model,
37  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& sens_solve_model,
39  const Teuchos::RCP<Teuchos::ParameterList>& sens_pList)
40  : stepMode_(SensitivityStepMode::Forward)
41 {
42  // Set all the input parameters and call initialize
43  this->setStepperName("StaggeredForwardSensitivity");
44  this->setStepperType("StaggeredForwardSensitivity");
45  this->setParams(pList, sens_pList);
46  this->setModel(appModel, sens_residual_model, sens_solve_model);
47  this->initialize();
48 }
49 
50 template <class Scalar>
52  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
54  sens_residual_model,
55  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& sens_solve_model)
56 {
58  using Teuchos::RCP;
59  using Teuchos::rcp;
60 
61  // Create forward sensitivity model evaluator wrapper
62  Teuchos::RCP<Teuchos::ParameterList> spl = Teuchos::parameterList();
63  *spl = *sensPL_;
64  spl->remove("Reuse State Linear Solver");
65  spl->remove("Force W Update");
66  fsa_model_ = wrapStaggeredFSAModelEvaluator(appModel, sens_residual_model,
67  sens_solve_model, false, spl);
68 
69  // Create combined FSA ME which serves as "the" ME for this stepper,
70  // so that getModel() has a ME consistent the FSA problem (including both
71  // state and sensitivity components), e.g., the integrator may call
72  // getModel()->getNominalValues(), which needs to be consistent.
73  combined_fsa_model_ = wrapCombinedFSAModelEvaluator(
74  appModel, sens_residual_model, sens_solve_model, spl);
75 
76  // Create state and sensitivity steppers
77  RCP<StepperFactory<Scalar> > sf = Teuchos::rcp(new StepperFactory<Scalar>());
78  if (stateStepper_ == Teuchos::null)
79  stateStepper_ = sf->createStepper(stepperPL_, appModel);
80  else
81  stateStepper_->setModel(appModel);
82 
83  if (sensitivityStepper_ == Teuchos::null)
84  sensitivityStepper_ = sf->createStepper(stepperPL_, fsa_model_);
85  else
86  sensitivityStepper_->setModel(fsa_model_);
87 
88  this->isInitialized_ = false;
89 }
90 
91 template <class Scalar>
94 {
95  return combined_fsa_model_;
96 }
97 
98 template <class Scalar>
101 {
102  stateStepper_->setSolver(solver);
103  sensitivityStepper_->setSolver(solver);
104 
105  this->isInitialized_ = false;
106 }
107 
108 template <class Scalar>
110  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
111 {
112  this->checkInitialized();
113 
114  using Teuchos::RCP;
115  using Teuchos::rcp;
116  using Teuchos::rcp_dynamic_cast;
117  using Thyra::assign;
118  using Thyra::createMember;
120  using Thyra::multiVectorProductVector;
121  using Thyra::multiVectorProductVectorSpace;
122  using Thyra::VectorBase;
125 
126  // Initialize state, sensitivity solution histories if necessary.
127  // We only need to split the solution history into state and sensitivity
128  // components for the first step, otherwise the state and sensitivity
129  // histories are updated from the previous step.
130  if (stateSolutionHistory_ == Teuchos::null) {
131  RCP<Teuchos::ParameterList> shPL =
132  solutionHistory->getNonconstParameterList();
133 
134  // Get product X, XDot, XDotDot
135  RCP<SolutionState<Scalar> > state = solutionHistory->getCurrentState();
136  RCP<DMVPV> X, XDot, XDotDot;
137  X = rcp_dynamic_cast<DMVPV>(state->getX(), true);
138 
139  XDot = rcp_dynamic_cast<DMVPV>(state->getXDot(), true);
140  if (state->getXDotDot() != Teuchos::null)
141  XDotDot = rcp_dynamic_cast<DMVPV>(state->getXDotDot(), true);
142 
143  // Pull out state components (has to be non-const because of SolutionState
144  // constructor)
145  RCP<VectorBase<Scalar> > x, xdot, xdotdot;
146  x = X->getNonconstMultiVector()->col(0);
147  xdot = XDot->getNonconstMultiVector()->col(0);
148  if (XDotDot != Teuchos::null)
149  xdotdot = XDotDot->getNonconstMultiVector()->col(0);
150 
151  // Create state solution history
152  RCP<SolutionState<Scalar> > state_state = state->clone();
153  state_state->setX(x);
154  state_state->setXDot(xdot);
155  state_state->setXDotDot(xdotdot);
156  stateSolutionHistory_ = createSolutionHistoryPL<Scalar>(shPL);
157  stateSolutionHistory_->addState(state_state);
158 
159  const int num_param = X->getMultiVector()->domain()->dim() - 1;
160  TEUCHOS_ASSERT(num_param > 0);
161  const Teuchos::Range1D rng(1, num_param);
162 
163  // Pull out sensitivity components
164  RCP<MultiVectorBase<Scalar> > dxdp, dxdotdp, dxdotdotdp;
165  dxdp = X->getNonconstMultiVector()->subView(rng);
166  dxdotdp = XDot->getNonconstMultiVector()->subView(rng);
167  if (XDotDot != Teuchos::null)
168  dxdotdotdp = XDotDot->getNonconstMultiVector()->subView(rng);
169 
170  // Create sensitivity product vectors
171  RCP<VectorBase<Scalar> > dxdp_vec, dxdotdp_vec, dxdotdotdp_vec;
172  RCP<const DMVPVS> prod_space =
173  multiVectorProductVectorSpace(X->getMultiVector()->range(), num_param);
174  dxdp_vec = multiVectorProductVector(prod_space, dxdp);
175  dxdotdp_vec = multiVectorProductVector(prod_space, dxdotdp);
176  if (XDotDot != Teuchos::null)
177  dxdotdotdp_vec = multiVectorProductVector(prod_space, dxdotdotdp);
178 
179  // Create sensitivity solution history
180  RCP<SolutionState<Scalar> > sens_state = state->clone();
181  sens_state->setX(dxdp_vec);
182  sens_state->setXDot(dxdotdp_vec);
183  sens_state->setXDotDot(dxdotdotdp_vec);
184  sensSolutionHistory_ = createSolutionHistoryPL<Scalar>(shPL);
185  sensSolutionHistory_->addState(sens_state);
186  }
187 
188  // Get our working state
189  RCP<SolutionState<Scalar> > prod_state = solutionHistory->getWorkingState();
190  RCP<DMVPV> X, XDot, XDotDot;
191  X = rcp_dynamic_cast<DMVPV>(prod_state->getX(), true);
192  XDot = rcp_dynamic_cast<DMVPV>(prod_state->getXDot(), true);
193  if (prod_state->getXDotDot() != Teuchos::null)
194  XDotDot = rcp_dynamic_cast<DMVPV>(prod_state->getXDotDot(), true);
195 
196  // Take step for state equations
197  stepMode_ = SensitivityStepMode::Forward;
198  stateSolutionHistory_->initWorkingState();
199  RCP<SolutionState<Scalar> > state = stateSolutionHistory_->getWorkingState();
200  state->getMetaData()->copy(prod_state->getMetaData());
201  stateStepper_->takeStep(stateSolutionHistory_);
202 
203  // Set state components of product state
204  assign(X->getNonconstMultiVector()->col(0).ptr(), *(state->getX()));
205  assign(XDot->getNonconstMultiVector()->col(0).ptr(), *(state->getXDot()));
206  if (XDotDot != Teuchos::null)
207  assign(XDotDot->getNonconstMultiVector()->col(0).ptr(),
208  *(state->getXDotDot()));
209  prod_state->setOrder(state->getOrder());
210 
211  // If step passed promote the state, otherwise fail and stop
212  if (state->getSolutionStatus() == Status::FAILED) {
213  prod_state->setSolutionStatus(Status::FAILED);
214  return;
215  }
216  stateSolutionHistory_->promoteWorkingState();
217 
218  // Get forward state in sensitivity model evaluator
219  fsa_model_->setForwardSolutionHistory(stateSolutionHistory_);
220  if (reuse_solver_ && stateStepper_->getSolver() != Teuchos::null)
221  fsa_model_->setSolver(stateStepper_->getSolver(), force_W_update_);
222 
223  // 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)
239  ->getMultiVector();
240  assign(XDot->getNonconstMultiVector()->subView(rng).ptr(), *dxdotdp);
241  if (sens_state->getXDotDot() != Teuchos::null) {
242  RCP<const MultiVectorBase<Scalar> > dxdotdotdp =
243  rcp_dynamic_cast<const DMVPV>(sens_state->getXDotDot(), true)
244  ->getMultiVector();
245  assign(XDotDot->getNonconstMultiVector()->subView(rng).ptr(), *dxdotdotdp);
246  }
247  prod_state->setOrder(std::min(state->getOrder(), sens_state->getOrder()));
248 
249  // If step passed promote the state, otherwise fail and stop
250  if (sens_state->getSolutionStatus() == Status::FAILED) {
251  prod_state->setSolutionStatus(Status::FAILED);
252  }
253  else {
254  sensSolutionHistory_->promoteWorkingState();
255  prod_state->setSolutionStatus(Status::PASSED);
256  }
257 }
258 
259 template <class Scalar>
262 {
263  // ETP: Note, maybe this should be a special stepper state that combines
264  // states from both state and sensitivity steppers?
266  rcp(new StepperState<Scalar>(description()));
267  return stepperState;
268 }
269 
270 template <class Scalar>
272  Teuchos::FancyOStream& out, const Teuchos::EVerbosityLevel verbLevel) const
273 {
274  out.setOutputToRootOnly(0);
275  out << std::endl;
276  Stepper<Scalar>::describe(out, verbLevel);
277 
278  out << "--- StepperStaggeredForwardSensitivity ---\n";
279  out << " stateStepper_ = " << stateStepper_ << std::endl;
280  out << " sensitivityStepper_ = " << sensitivityStepper_ << std::endl;
281  out << " combined_fsa_model_ = " << combined_fsa_model_ << std::endl;
282  out << " fsa_model_ = " << fsa_model_ << std::endl;
283  out << " stateSolutionHistory_ = " << stateSolutionHistory_ << std::endl;
284  out << " sensSolutionHistory_ = " << sensSolutionHistory_ << std::endl;
285  out << "------------------------------------------" << std::endl;
286 
287  out << description() << "::describe:" << std::endl;
288  stateStepper_->describe(out, verbLevel);
289  out << std::endl;
290  sensitivityStepper_->describe(out, verbLevel);
291 }
292 
293 template <class Scalar>
295  Teuchos::FancyOStream& out) const
296 {
297  out.setOutputToRootOnly(0);
298  bool isValidSetup = true;
299 
300  if (!Stepper<Scalar>::isValidSetup(out)) isValidSetup = false;
301 
302  if (stateStepper_ == Teuchos::null) {
303  isValidSetup = false;
304  out << "The state stepper is not set!\n";
305  }
306 
307  if (sensitivityStepper_ == Teuchos::null) {
308  isValidSetup = false;
309  out << "The sensitivity stepper is not set!\n";
310  }
311 
312  if (combined_fsa_model_ == Teuchos::null) {
313  isValidSetup = false;
314  out << "The combined FSA model is not set!\n";
315  }
316 
317  if (fsa_model_ == Teuchos::null) {
318  isValidSetup = false;
319  out << "The FSA model is not set!\n";
320  }
321 
322  return isValidSetup;
323 }
324 
325 template <class Scalar>
328 {
329  if (pList == Teuchos::null) {
330  // Create default parameters if null, otherwise keep current parameters.
331  if (this->stepperPL_ == Teuchos::null)
332  this->stepperPL_ = Teuchos::rcp_const_cast<Teuchos::ParameterList>(
333  this->getValidParameters());
334  }
335  else {
336  this->stepperPL_ = pList;
337  }
338  // Can not validate because of optional Parameters (e.g., Solver Name).
339  // stepperPL_->validateParametersAndSetDefaults(*this->getValidParameters());
340 }
341 
342 template <class Scalar>
345 {
346  return stateStepper_->getValidParameters();
347 }
348 
349 template <class Scalar>
352 {
353  return stepperPL_;
354 }
355 
356 template <class Scalar>
359 {
360  Teuchos::RCP<Teuchos::ParameterList> temp_plist = stepperPL_;
361  stepperPL_ = Teuchos::null;
362  return temp_plist;
363 }
364 
365 template <class Scalar>
369 {
370  if (pList == Teuchos::null)
371  stepperPL_ = Teuchos::rcp_const_cast<Teuchos::ParameterList>(
372  this->getValidParameters());
373  else
374  stepperPL_ = pList;
375 
376  if (spList == Teuchos::null)
377  sensPL_ = Teuchos::parameterList();
378  else
379  sensPL_ = spList;
380 
381  reuse_solver_ = sensPL_->get("Reuse State Linear Solver", false);
382  force_W_update_ = sensPL_->get("Force W Update", true);
383 
384  // Can not validate because of optional Parameters (e.g., Solver Name).
385  // stepperPL_->validateParametersAndSetDefaults(*this->getValidParameters());
386 }
387 
388 template <class Scalar>
391 {
392  using Teuchos::RCP;
393  using Teuchos::rcp_dynamic_cast;
395 
396  RCP<const Thyra::VectorSpaceBase<Scalar> > x_space =
397  stateStepper_->getModel()->get_x_space();
398  RCP<const DMVPVS> dxdp_space = rcp_dynamic_cast<const DMVPVS>(
399  sensitivityStepper_->getModel()->get_x_space(), true);
400  const int num_param = dxdp_space->numBlocks();
401  RCP<const Thyra::VectorSpaceBase<Scalar> > prod_space =
402  multiVectorProductVectorSpace(x_space, num_param + 1);
403  return prod_space;
404 }
405 
406 } // namespace Tempus
407 
408 #endif // Tempus_StepperStaggeredForwardSensitivity_impl_hpp
RCP< const VectorSpaceBase< Scalar > > clone() const
T & get(const std::string &name, T def_value)
Teuchos::RCP< SensitivityModelEvaluatorBase< Scalar > > wrapStaggeredFSAModelEvaluator(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 bool is_pseudotransient, const Teuchos::RCP< const Teuchos::ParameterList > &pList=Teuchos::null)
void setStepperName(std::string s)
Set the stepper name.
virtual void takeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Take the specified timestep, dt, and return true if successful.
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const
virtual void initialize()
Initialize after construction and changing input parameters.
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)
bool remove(std::string const &name, bool throwIfNotExists=true)
StepperState is a simple class to hold state information about the stepper.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
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)
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
#define TEUCHOS_ASSERT(assertion_test)
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 setStepperType(std::string s)
Set the stepper type.
virtual Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > getModel() const
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &pl)
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const