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: Time Integration and Sensitivity Analysis Package
4 //
5 // Copyright 2017 NTESS and the Tempus contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 //@HEADER
9 
10 #ifndef Tempus_StepperStaggeredForwardSensitivity_impl_hpp
11 #define Tempus_StepperStaggeredForwardSensitivity_impl_hpp
12 
13 #include "Thyra_VectorStdOps.hpp"
14 #include "Thyra_MultiVectorStdOps.hpp"
15 #include "Thyra_DefaultMultiVectorProductVectorSpace.hpp"
16 #include "Thyra_DefaultMultiVectorProductVector.hpp"
17 
18 #include "Tempus_StepperFactory.hpp"
21 
22 namespace Tempus {
23 
24 template <class Scalar>
26  : stepMode_(SensitivityStepMode::Forward)
27 {
28  this->setStepperName("StaggeredForwardSensitivity");
29  this->setStepperType("StaggeredForwardSensitivity");
30  this->setParams(Teuchos::null, Teuchos::null);
31 }
32 
33 template <class Scalar>
35  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
37  sens_residual_model,
38  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& sens_solve_model,
40  const Teuchos::RCP<Teuchos::ParameterList>& sens_pList)
41  : stepMode_(SensitivityStepMode::Forward)
42 {
43  // Set all the input parameters and call initialize
44  this->setStepperName("StaggeredForwardSensitivity");
45  this->setStepperType("StaggeredForwardSensitivity");
46  this->setParams(pList, sens_pList);
47  this->setModel(appModel, sens_residual_model, sens_solve_model);
48  this->initialize();
49 }
50 
51 template <class Scalar>
53  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
55  sens_residual_model,
56  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& sens_solve_model)
57 {
59  using Teuchos::RCP;
60  using Teuchos::rcp;
61 
62  // Create forward sensitivity model evaluator wrapper
63  Teuchos::RCP<Teuchos::ParameterList> spl = Teuchos::parameterList();
64  *spl = *sensPL_;
65  spl->remove("Reuse State Linear Solver");
66  spl->remove("Force W Update");
67  fsa_model_ = wrapStaggeredFSAModelEvaluator(appModel, sens_residual_model,
68  sens_solve_model, false, spl);
69 
70  // Create combined FSA ME which serves as "the" ME for this stepper,
71  // so that getModel() has a ME consistent the FSA problem (including both
72  // state and sensitivity components), e.g., the integrator may call
73  // getModel()->getNominalValues(), which needs to be consistent.
74  combined_fsa_model_ = wrapCombinedFSAModelEvaluator(
75  appModel, sens_residual_model, sens_solve_model, spl);
76 
77  // Create state and sensitivity steppers
78  RCP<StepperFactory<Scalar> > sf = Teuchos::rcp(new StepperFactory<Scalar>());
79  if (stateStepper_ == Teuchos::null)
80  stateStepper_ = sf->createStepper(stepperPL_, appModel);
81  else
82  stateStepper_->setModel(appModel);
83 
84  if (sensitivityStepper_ == Teuchos::null)
85  sensitivityStepper_ = sf->createStepper(stepperPL_, fsa_model_);
86  else
87  sensitivityStepper_->setModel(fsa_model_);
88 
89  this->isInitialized_ = false;
90 }
91 
92 template <class Scalar>
95 {
96  return combined_fsa_model_;
97 }
98 
99 template <class Scalar>
102 {
103  stateStepper_->setSolver(solver);
104  sensitivityStepper_->setSolver(solver);
105 
106  this->isInitialized_ = false;
107 }
108 
109 template <class Scalar>
111  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
112 {
113  this->checkInitialized();
114 
115  using Teuchos::RCP;
116  using Teuchos::rcp;
117  using Teuchos::rcp_dynamic_cast;
118  using Thyra::assign;
119  using Thyra::createMember;
121  using Thyra::multiVectorProductVector;
122  using Thyra::multiVectorProductVectorSpace;
123  using Thyra::VectorBase;
126 
127  // Initialize state, sensitivity solution histories if necessary.
128  // We only need to split the solution history into state and sensitivity
129  // components for the first step, otherwise the state and sensitivity
130  // histories are updated from the previous step.
131  if (stateSolutionHistory_ == Teuchos::null) {
132  RCP<Teuchos::ParameterList> shPL =
133  solutionHistory->getNonconstParameterList();
134 
135  // Get product X, XDot, XDotDot
136  RCP<SolutionState<Scalar> > state = solutionHistory->getCurrentState();
137  RCP<DMVPV> X, XDot, XDotDot;
138  X = rcp_dynamic_cast<DMVPV>(state->getX(), true);
139 
140  XDot = rcp_dynamic_cast<DMVPV>(state->getXDot(), true);
141  if (state->getXDotDot() != Teuchos::null)
142  XDotDot = rcp_dynamic_cast<DMVPV>(state->getXDotDot(), true);
143 
144  // Pull out state components (has to be non-const because of SolutionState
145  // constructor)
146  RCP<VectorBase<Scalar> > x, xdot, xdotdot;
147  x = X->getNonconstMultiVector()->col(0);
148  xdot = XDot->getNonconstMultiVector()->col(0);
149  if (XDotDot != Teuchos::null)
150  xdotdot = XDotDot->getNonconstMultiVector()->col(0);
151 
152  // Create state solution history
153  RCP<SolutionState<Scalar> > state_state = state->clone();
154  state_state->setX(x);
155  state_state->setXDot(xdot);
156  state_state->setXDotDot(xdotdot);
157  stateSolutionHistory_ = createSolutionHistoryPL<Scalar>(shPL);
158  stateSolutionHistory_->addState(state_state);
159 
160  const int num_param = X->getMultiVector()->domain()->dim() - 1;
161  TEUCHOS_ASSERT(num_param > 0);
162  const Teuchos::Range1D rng(1, num_param);
163 
164  // Pull out sensitivity components
165  RCP<MultiVectorBase<Scalar> > dxdp, dxdotdp, dxdotdotdp;
166  dxdp = X->getNonconstMultiVector()->subView(rng);
167  dxdotdp = XDot->getNonconstMultiVector()->subView(rng);
168  if (XDotDot != Teuchos::null)
169  dxdotdotdp = XDotDot->getNonconstMultiVector()->subView(rng);
170 
171  // Create sensitivity product vectors
172  RCP<VectorBase<Scalar> > dxdp_vec, dxdotdp_vec, dxdotdotdp_vec;
173  RCP<const DMVPVS> prod_space =
174  multiVectorProductVectorSpace(X->getMultiVector()->range(), num_param);
175  dxdp_vec = multiVectorProductVector(prod_space, dxdp);
176  dxdotdp_vec = multiVectorProductVector(prod_space, dxdotdp);
177  if (XDotDot != Teuchos::null)
178  dxdotdotdp_vec = multiVectorProductVector(prod_space, dxdotdotdp);
179 
180  // Create sensitivity solution history
181  RCP<SolutionState<Scalar> > sens_state = state->clone();
182  sens_state->setX(dxdp_vec);
183  sens_state->setXDot(dxdotdp_vec);
184  sens_state->setXDotDot(dxdotdotdp_vec);
185  sensSolutionHistory_ = createSolutionHistoryPL<Scalar>(shPL);
186  sensSolutionHistory_->addState(sens_state);
187  }
188 
189  // Get our working state
190  RCP<SolutionState<Scalar> > prod_state = solutionHistory->getWorkingState();
191  RCP<DMVPV> X, XDot, XDotDot;
192  X = rcp_dynamic_cast<DMVPV>(prod_state->getX(), true);
193  XDot = rcp_dynamic_cast<DMVPV>(prod_state->getXDot(), true);
194  if (prod_state->getXDotDot() != Teuchos::null)
195  XDotDot = rcp_dynamic_cast<DMVPV>(prod_state->getXDotDot(), true);
196 
197  // Take step for state equations
198  stepMode_ = SensitivityStepMode::Forward;
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
226  sensSolutionHistory_->initWorkingState();
227  RCP<SolutionState<Scalar> > sens_state =
228  sensSolutionHistory_->getWorkingState();
229  sens_state->getMetaData()->copy(prod_state->getMetaData());
230  sensitivityStepper_->takeStep(sensSolutionHistory_);
231 
232  // Set sensitivity components of product state
233  RCP<const MultiVectorBase<Scalar> > dxdp =
234  rcp_dynamic_cast<const DMVPV>(sens_state->getX(), true)->getMultiVector();
235  const int num_param = dxdp->domain()->dim();
236  const Teuchos::Range1D rng(1, num_param);
237  assign(X->getNonconstMultiVector()->subView(rng).ptr(), *dxdp);
238  RCP<const MultiVectorBase<Scalar> > dxdotdp =
239  rcp_dynamic_cast<const DMVPV>(sens_state->getXDot(), true)
240  ->getMultiVector();
241  assign(XDot->getNonconstMultiVector()->subView(rng).ptr(), *dxdotdp);
242  if (sens_state->getXDotDot() != Teuchos::null) {
243  RCP<const MultiVectorBase<Scalar> > dxdotdotdp =
244  rcp_dynamic_cast<const DMVPV>(sens_state->getXDotDot(), true)
245  ->getMultiVector();
246  assign(XDotDot->getNonconstMultiVector()->subView(rng).ptr(), *dxdotdotdp);
247  }
248  prod_state->setOrder(std::min(state->getOrder(), sens_state->getOrder()));
249 
250  // If step passed promote the state, otherwise fail and stop
251  if (sens_state->getSolutionStatus() == Status::FAILED) {
252  prod_state->setSolutionStatus(Status::FAILED);
253  }
254  else {
255  sensSolutionHistory_->promoteWorkingState();
256  prod_state->setSolutionStatus(Status::PASSED);
257  }
258 }
259 
260 template <class Scalar>
263 {
264  // ETP: Note, maybe this should be a special stepper state that combines
265  // states from both state and sensitivity steppers?
267  rcp(new StepperState<Scalar>(description()));
268  return stepperState;
269 }
270 
271 template <class Scalar>
273  Teuchos::FancyOStream& out, const Teuchos::EVerbosityLevel verbLevel) const
274 {
275  out.setOutputToRootOnly(0);
276  out << std::endl;
277  Stepper<Scalar>::describe(out, verbLevel);
278 
279  out << "--- StepperStaggeredForwardSensitivity ---\n";
280  out << " stateStepper_ = " << stateStepper_ << std::endl;
281  out << " sensitivityStepper_ = " << sensitivityStepper_ << std::endl;
282  out << " combined_fsa_model_ = " << combined_fsa_model_ << std::endl;
283  out << " fsa_model_ = " << fsa_model_ << std::endl;
284  out << " stateSolutionHistory_ = " << stateSolutionHistory_ << std::endl;
285  out << " sensSolutionHistory_ = " << sensSolutionHistory_ << std::endl;
286  out << "------------------------------------------" << std::endl;
287 
288  out << description() << "::describe:" << std::endl;
289  stateStepper_->describe(out, verbLevel);
290  out << std::endl;
291  sensitivityStepper_->describe(out, verbLevel);
292 }
293 
294 template <class Scalar>
296  Teuchos::FancyOStream& out) const
297 {
298  out.setOutputToRootOnly(0);
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 template <class Scalar>
329 {
330  if (pList == Teuchos::null) {
331  // Create default parameters if null, otherwise keep current parameters.
332  if (this->stepperPL_ == Teuchos::null)
333  this->stepperPL_ = Teuchos::rcp_const_cast<Teuchos::ParameterList>(
334  this->getValidParameters());
335  }
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 template <class Scalar>
346 {
347  return stateStepper_->getValidParameters();
348 }
349 
350 template <class Scalar>
353 {
354  return stepperPL_;
355 }
356 
357 template <class Scalar>
360 {
361  Teuchos::RCP<Teuchos::ParameterList> temp_plist = stepperPL_;
362  stepperPL_ = Teuchos::null;
363  return temp_plist;
364 }
365 
366 template <class Scalar>
370 {
371  if (pList == Teuchos::null)
372  stepperPL_ = Teuchos::rcp_const_cast<Teuchos::ParameterList>(
373  this->getValidParameters());
374  else
375  stepperPL_ = pList;
376 
377  if (spList == Teuchos::null)
378  sensPL_ = Teuchos::parameterList();
379  else
380  sensPL_ = spList;
381 
382  reuse_solver_ = sensPL_->get("Reuse State Linear Solver", false);
383  force_W_update_ = sensPL_->get("Force W Update", true);
384 
385  // Can not validate because of optional Parameters (e.g., Solver Name).
386  // stepperPL_->validateParametersAndSetDefaults(*this->getValidParameters());
387 }
388 
389 template <class Scalar>
392 {
393  using Teuchos::RCP;
394  using Teuchos::rcp_dynamic_cast;
396 
397  RCP<const Thyra::VectorSpaceBase<Scalar> > x_space =
398  stateStepper_->getModel()->get_x_space();
399  RCP<const DMVPVS> dxdp_space = rcp_dynamic_cast<const DMVPVS>(
400  sensitivityStepper_->getModel()->get_x_space(), true);
401  const int num_param = dxdp_space->numBlocks();
402  RCP<const Thyra::VectorSpaceBase<Scalar> > prod_space =
403  multiVectorProductVectorSpace(x_space, num_param + 1);
404  return prod_space;
405 }
406 
407 } // namespace Tempus
408 
409 #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