Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
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
22namespace Tempus {
23
24template <class Scalar>
26 : stepMode_(SensitivityStepMode::Forward)
27{
28 this->setStepperName("StaggeredForwardSensitivity");
29 this->setStepperType("StaggeredForwardSensitivity");
30 this->setParams(Teuchos::null, Teuchos::null);
31}
32
33template <class Scalar>
35 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
36 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >&
37 sens_residual_model,
38 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& sens_solve_model,
39 const Teuchos::RCP<Teuchos::ParameterList>& pList,
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
51template <class Scalar>
53 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
54 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >&
55 sens_residual_model,
56 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& sens_solve_model)
57{
58 using Teuchos::ParameterList;
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
92template <class Scalar>
93Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >
95{
96 return combined_fsa_model_;
97}
98
99template <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
109template <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;
124 typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
125 typedef Thyra::DefaultMultiVectorProductVectorSpace<Scalar> DMVPVS;
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
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
260template <class Scalar>
261Teuchos::RCP<Tempus::StepperState<Scalar> >
263{
264 // ETP: Note, maybe this should be a special stepper state that combines
265 // states from both state and sensitivity steppers?
266 Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
267 rcp(new StepperState<Scalar>(description()));
268 return stepperState;
269}
270
271template <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
294template <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
326template <class Scalar>
328 Teuchos::RCP<Teuchos::ParameterList> const& pList)
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
343template <class Scalar>
344Teuchos::RCP<const Teuchos::ParameterList>
346{
347 return stateStepper_->getValidParameters();
348}
349
350template <class Scalar>
351Teuchos::RCP<Teuchos::ParameterList>
356
357template <class Scalar>
358Teuchos::RCP<Teuchos::ParameterList>
360{
361 Teuchos::RCP<Teuchos::ParameterList> temp_plist = stepperPL_;
362 stepperPL_ = Teuchos::null;
363 return temp_plist;
364}
365
366template <class Scalar>
368 Teuchos::RCP<Teuchos::ParameterList> const& pList,
369 Teuchos::RCP<Teuchos::ParameterList> const& spList)
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
389template <class Scalar>
390Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
392{
393 using Teuchos::RCP;
394 using Teuchos::rcp_dynamic_cast;
395 typedef Thyra::DefaultMultiVectorProductVectorSpace<Scalar> DMVPVS;
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
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
virtual Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > getModel() const
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Get a default (initial) StepperState.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
void setParams(const Teuchos::RCP< Teuchos::ParameterList > &pl, const Teuchos::RCP< Teuchos::ParameterList > &spl)
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &pl)
virtual void takeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Take the specified timestep, dt, and return true if successful.
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel)
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const
virtual void setSolver(Teuchos::RCP< Thyra::NonlinearSolverBase< Scalar > > solver=Teuchos::null)
Set solver.
StepperState is a simple class to hold state information about the stepper.
Thyra Base interface for time steppers.
void setStepperName(std::string s)
Set the stepper name.
virtual void initialize()
Initialize after construction and changing input parameters.
void setStepperType(std::string s)
Set the stepper type.
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)
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)