Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
Tempus_StepperNewmarkExplicitAForm_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_StepperNewmarkExplicitAForm_impl_hpp
11#define Tempus_StepperNewmarkExplicitAForm_impl_hpp
12
13#include "Thyra_VectorStdOps.hpp"
14
16
17//#define DEBUG_OUTPUT
18
19namespace Tempus {
20
21template <class Scalar>
24 const Thyra::VectorBase<Scalar>& a, const Scalar dt) const
25{
26 // vPred = v + dt*(1.0-gamma_)*a
27 Thyra::V_StVpStV(Teuchos::ptrFromRef(vPred), 1.0, v, dt * (1.0 - gamma_), a);
28}
29
30template <class Scalar>
34 const Scalar dt) const
35{
36 Teuchos::RCP<const Thyra::VectorBase<Scalar> > tmp =
37 Thyra::createMember<Scalar>(dPred.space());
38 // dPred = dt*v + dt*dt/2.0*a
39 Scalar aConst = dt * dt / 2.0;
40 Thyra::V_StVpStV(Teuchos::ptrFromRef(dPred), dt, v, aConst, a);
41 // dPred += d;
42 Thyra::Vp_V(Teuchos::ptrFromRef(dPred), d, 1.0);
43}
44
45template <class Scalar>
48 const Thyra::VectorBase<Scalar>& a, const Scalar dt) const
49{
50 // v = vPred + dt*gamma_*a
51 Thyra::V_StVpStV(Teuchos::ptrFromRef(v), 1.0, vPred, dt * gamma_, a);
52}
53
54template <class Scalar>
56 : gammaDefault_(Scalar(0.5)), gamma_(Scalar(0.5))
57{
58 this->setStepperName("Newmark Explicit a-Form");
59 this->setStepperType("Newmark Explicit a-Form");
60 this->setUseFSAL(true);
61 this->setICConsistency("Consistent");
62 this->setICConsistencyCheck(false);
63 this->setAppAction(Teuchos::null);
64}
65
66template <class Scalar>
68 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
69 bool useFSAL, std::string ICConsistency, bool ICConsistencyCheck,
70 Scalar gamma,
72 stepperAppAction)
73 : gammaDefault_(Scalar(0.5)), gamma_(Scalar(0.5))
74{
75 this->setStepperName("Newmark Explicit a-Form");
76 this->setStepperType("Newmark Explicit a-Form");
77 this->setUseFSAL(useFSAL);
78 this->setICConsistency(ICConsistency);
79 this->setICConsistencyCheck(ICConsistencyCheck);
80
81 this->setAppAction(stepperAppAction);
82 setGamma(gamma);
83
84 if (appModel != Teuchos::null) {
85 this->setModel(appModel);
86 this->initialize();
87 }
88}
89
90template <class Scalar>
92 const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
93{
94 using Teuchos::RCP;
95
96 int numStates = solutionHistory->getNumStates();
97
98 TEUCHOS_TEST_FOR_EXCEPTION(
99 numStates < 1, std::logic_error,
100 "Error - setInitialConditions() needs at least one SolutionState\n"
101 " to set the initial condition. Number of States = "
102 << numStates);
103
104 if (numStates > 1) {
105 RCP<Teuchos::FancyOStream> out = this->getOStream();
106 Teuchos::OSTab ostab(out, 1,
107 "StepperNewmarkExplicitAForm::setInitialConditions()");
108 *out << "Warning -- SolutionHistory has more than one state!\n"
109 << "Setting the initial conditions on the currentState.\n"
110 << std::endl;
111 }
112
113 RCP<SolutionState<Scalar> > initialState = solutionHistory->getCurrentState();
114 RCP<Thyra::VectorBase<Scalar> > x = initialState->getX();
115 RCP<Thyra::VectorBase<Scalar> > xDot = initialState->getXDot();
116
117 // If initialState has x and xDot set, treat them as the initial conditions.
118 // Otherwise use the x and xDot from getNominalValues() as the ICs.
119 TEUCHOS_TEST_FOR_EXCEPTION(
120 !((initialState->getX() != Teuchos::null &&
121 initialState->getXDot() != Teuchos::null) ||
122 (this->inArgs_.get_x() != Teuchos::null &&
123 this->inArgs_.get_x_dot() != Teuchos::null)),
124 std::logic_error,
125 "Error - We need to set the initial conditions for x and xDot from\n"
126 " either initialState or appModel_->getNominalValues::InArgs\n"
127 " (but not from a mixture of the two).\n");
128
129 this->inArgs_ = this->appModel_->getNominalValues();
130 using Teuchos::rcp_const_cast;
131 // Use the x and xDot from getNominalValues() as the ICs.
132 if (initialState->getX() == Teuchos::null ||
133 initialState->getXDot() == Teuchos::null) {
134 TEUCHOS_TEST_FOR_EXCEPTION((this->inArgs_.get_x() == Teuchos::null) ||
135 (this->inArgs_.get_x_dot() == Teuchos::null),
136 std::logic_error,
137 "Error - setInitialConditions() needs the ICs "
138 "from the SolutionHistory\n"
139 " or getNominalValues()!\n");
140 x = rcp_const_cast<Thyra::VectorBase<Scalar> >(this->inArgs_.get_x());
141 initialState->setX(x);
142 xDot =
143 rcp_const_cast<Thyra::VectorBase<Scalar> >(this->inArgs_.get_x_dot());
144 initialState->setXDot(xDot);
145 }
146 else {
147 this->inArgs_.set_x(x);
148 this->inArgs_.set_x_dot(xDot);
149 }
150
151 // Check if we need Stepper storage for xDotDot
152 if (initialState->getXDotDot() == Teuchos::null)
153 initialState->setXDotDot(initialState->getX()->clone_v());
154 else
155 this->setStepperXDotDot(initialState->getXDotDot());
156
157 // Perform IC Consistency
158 std::string icConsistency = this->getICConsistency();
159 if (icConsistency == "None") {
160 if (initialState->getXDotDot() == Teuchos::null) {
161 RCP<Teuchos::FancyOStream> out = this->getOStream();
162 Teuchos::OSTab ostab(out, 1,
163 "StepperForwardEuler::setInitialConditions()");
164 *out << "Warning -- Requested IC consistency of 'None' but\n"
165 << " initialState does not have an xDotDot.\n"
166 << " Setting a 'Consistent' xDotDot!\n"
167 << std::endl;
168 auto p = Teuchos::rcp(new ExplicitODEParameters<Scalar>(0.0));
169 this->evaluateExplicitODE(initialState->getXDotDot(), x, xDot,
170 initialState->getTime(), p);
171
172 initialState->setIsSynced(true);
173 }
174 }
175 else if (icConsistency == "Zero")
176 Thyra::assign(initialState->getXDotDot().ptr(), Scalar(0.0));
177 else if (icConsistency == "App") {
178 auto xDotDot = Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(
179 this->inArgs_.get_x_dot_dot());
180 TEUCHOS_TEST_FOR_EXCEPTION(
181 xDotDot == Teuchos::null, std::logic_error,
182 "Error - setInitialConditions() requested 'App' for IC consistency,\n"
183 " but 'App' returned a null pointer for xDotDot!\n");
184 Thyra::assign(initialState->getXDotDot().ptr(), *xDotDot);
185 }
186 else if (icConsistency == "Consistent") {
187 // Evaluate xDotDot = f(x,t).
188 auto p = Teuchos::rcp(new ExplicitODEParameters<Scalar>(0.0));
189 this->evaluateExplicitODE(initialState->getXDotDot(), x, xDot,
190 initialState->getTime(), p);
191
192 // At this point, x, xDot and xDotDot are sync'ed or consistent
193 // at the same time level for the initialState.
194 initialState->setIsSynced(true);
195 }
196 else {
197 TEUCHOS_TEST_FOR_EXCEPTION(
198 true, std::logic_error,
199 "Error - setInitialConditions() invalid IC consistency, "
200 << icConsistency << ".\n");
201 }
202
203 // Test for consistency.
204 if (this->getICConsistencyCheck()) {
205 auto xDotDot = initialState->getXDotDot();
206 auto f = initialState->getX()->clone_v();
207 auto p = Teuchos::rcp(new ExplicitODEParameters<Scalar>(0.0));
208 this->evaluateExplicitODE(f, x, xDot, initialState->getTime(), p);
209 Thyra::Vp_StV(f.ptr(), Scalar(-1.0), *(xDotDot));
210 Scalar reldiff = Thyra::norm(*f);
211 Scalar normxDotDot = Thyra::norm(*xDotDot);
212 // The following logic is to prevent FPEs
213 Scalar eps = Scalar(100.0) * std::abs(Teuchos::ScalarTraits<Scalar>::eps());
214 if (normxDotDot > eps * reldiff) reldiff /= normxDotDot;
215
216 RCP<Teuchos::FancyOStream> out = this->getOStream();
217 Teuchos::OSTab ostab(out, 1,
218 "StepperNewmarkExplicitAForm::setInitialConditions()");
219 if (reldiff > eps) {
220 *out << "\n---------------------------------------------------\n"
221 << "Info -- Stepper = " << this->getStepperType() << "\n"
222 << " Initial condition PASSED consistency check!\n"
223 << " (||xDotDot-f(x,xDot,t)||/||x|| = " << reldiff << ") > "
224 << "(eps = " << eps << ")" << std::endl
225 << "---------------------------------------------------\n"
226 << std::endl;
227 }
228 else {
229 *out << "\n---------------------------------------------------\n"
230 << "Info -- Stepper = " << this->getStepperType() << "\n"
231 << "Initial condition FAILED consistency check but continuing!\n"
232 << " (||xDotDot-f(x,xDot,t)||/||x|| = " << reldiff << ") > "
233 << "(eps = " << eps << ")" << std::endl
234 << " ||xDotDot-f(x,xDot,t)|| = " << Thyra::norm(*f) << std::endl
235 << " ||x|| = " << Thyra::norm(*x) << std::endl
236 << "---------------------------------------------------\n"
237 << std::endl;
238 }
239 }
240}
241
242template <class Scalar>
244 const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
245{
246 this->checkInitialized();
247
248 using Teuchos::RCP;
249
250 TEMPUS_FUNC_TIME_MONITOR("Tempus::StepperNewmarkExplicitAForm::takeStep()");
251 {
252 TEUCHOS_TEST_FOR_EXCEPTION(
253 solutionHistory->getNumStates() < 2, std::logic_error,
254 "Error - StepperNewmarkExplicitAForm<Scalar>::takeStep(...)\n"
255 << "Need at least two SolutionStates for NewmarkExplicitAForm.\n"
256 << " Number of States = " << solutionHistory->getNumStates()
257 << "\nTry setting in \"Solution History\" \"Storage Type\" = "
258 << "\"Undo\"\n"
259 << " or \"Storage Type\" = \"Static\" and \"Storage Limit\" = "
260 << "\"2\"\n");
261
262 auto thisStepper = Teuchos::rcpFromRef(*this);
263 stepperNewmarkExpAppAction_->execute(
264 solutionHistory, thisStepper,
266 Scalar>::ACTION_LOCATION::BEGIN_STEP);
267
268 RCP<SolutionState<Scalar> > currentState =
269 solutionHistory->getCurrentState();
270 RCP<SolutionState<Scalar> > workingState =
271 solutionHistory->getWorkingState();
272
273 // Get values of d, v and a from previous step
274 RCP<const Thyra::VectorBase<Scalar> > d_old = currentState->getX();
275 RCP<const Thyra::VectorBase<Scalar> > v_old = currentState->getXDot();
276 RCP<Thyra::VectorBase<Scalar> > a_old = currentState->getXDotDot();
277
278 // Get dt and time
279 const Scalar dt = workingState->getTimeStep();
280 const Scalar time_old = currentState->getTime();
281
282 auto p = Teuchos::rcp(new ExplicitODEParameters<Scalar>(dt));
283 if (!(this->getUseFSAL()) || workingState->getNConsecutiveFailures() != 0) {
284 // Evaluate xDotDot = f(x, xDot, t).
285 this->evaluateExplicitODE(a_old, d_old, v_old, time_old, p);
286
287 // For UseFSAL=false, x and xDot sync'ed or consistent
288 // at the same time level for the currentState.
289 currentState->setIsSynced(true);
290 }
291
292 // New d, v and a to be computed here
293 RCP<Thyra::VectorBase<Scalar> > d_new = workingState->getX();
294 RCP<Thyra::VectorBase<Scalar> > v_new = workingState->getXDot();
295 RCP<Thyra::VectorBase<Scalar> > a_new = workingState->getXDotDot();
296
297 // compute displacement and velocity predictors
298 predictDisplacement(*d_new, *d_old, *v_old, *a_old, dt);
299 predictVelocity(*v_new, *v_old, *a_old, dt);
300
301 stepperNewmarkExpAppAction_->execute(
302 solutionHistory, thisStepper,
304 Scalar>::ACTION_LOCATION::BEFORE_EXPLICIT_EVAL);
305
306 // Evaluate xDotDot = f(x, xDot, t).
307 this->evaluateExplicitODE(a_new, d_new, v_new, time_old, p);
308
309 stepperNewmarkExpAppAction_->execute(
310 solutionHistory, thisStepper,
312 Scalar>::ACTION_LOCATION::AFTER_EXPLICIT_EVAL);
313
314 // Set xDot in workingState to velocity corrector
315 correctVelocity(*v_new, *v_new, *a_new, dt);
316
317 if (this->getUseFSAL()) {
318 // Evaluate xDotDot = f(x, xDot, t).
319 const Scalar time_new = workingState->getTime();
320 this->evaluateExplicitODE(a_new, d_new, v_new, time_new, p);
321
322 // For UseFSAL=true, x, xDot and xDotxDot are now sync'ed or consistent
323 // for the workingState.
324 workingState->setIsSynced(true);
325 }
326 else {
327 assign(a_new.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
328 workingState->setIsSynced(false);
329 }
330
331 workingState->setSolutionStatus(Status::PASSED);
332 workingState->setOrder(this->getOrder());
333 workingState->computeNorms(currentState);
334
335 stepperNewmarkExpAppAction_->execute(
336 solutionHistory, thisStepper,
338 Scalar>::ACTION_LOCATION::END_STEP);
339 }
340 return;
341}
342
349template <class Scalar>
350Teuchos::RCP<Tempus::StepperState<Scalar> >
352{
353 Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
354 rcp(new StepperState<Scalar>(this->getStepperType()));
355 return stepperState;
356}
357
358template <class Scalar>
360 Teuchos::FancyOStream& out, const Teuchos::EVerbosityLevel verbLevel) const
361{
362 out.setOutputToRootOnly(0);
363 out << std::endl;
364 Stepper<Scalar>::describe(out, verbLevel);
365 StepperExplicit<Scalar>::describe(out, verbLevel);
366
367 out << "--- StepperNewmarkExplicitAForm ---\n";
368 out << " gamma_ = " << gamma_ << std::endl;
369 out << "-----------------------------------" << std::endl;
370}
371
372template <class Scalar>
374 Teuchos::FancyOStream& out) const
375{
376 out.setOutputToRootOnly(0);
377 bool isValidSetup = true;
378
379 if (!Stepper<Scalar>::isValidSetup(out)) isValidSetup = false;
380 if (!StepperExplicit<Scalar>::isValidSetup(out)) isValidSetup = false;
381
382 return isValidSetup;
383}
384
385template <class Scalar>
386Teuchos::RCP<const Teuchos::ParameterList>
388{
389 auto pl = this->getValidParametersBasic();
390 pl->sublist("Newmark Explicit Parameters", false, "");
391 pl->sublist("Newmark Explicit Parameters", false, "")
392 .set("Gamma", gamma_, "Newmark Explicit parameter");
393 return pl;
394}
395
396template <class Scalar>
398 Teuchos::RCP<StepperNewmarkExplicitAFormAppAction<Scalar> > appAction)
399{
400 if (appAction == Teuchos::null) {
401 // Create default appAction
402 stepperNewmarkExpAppAction_ =
404 }
405 else {
406 stepperNewmarkExpAppAction_ = appAction;
407 }
408
409 this->isInitialized_ = false;
410}
411
412// Nonmember constructor - ModelEvaluator and ParameterList
413// ------------------------------------------------------------------------
414template <class Scalar>
415Teuchos::RCP<StepperNewmarkExplicitAForm<Scalar> >
417 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& model,
418 Teuchos::RCP<Teuchos::ParameterList> pl)
419{
420 auto stepper = Teuchos::rcp(new StepperNewmarkExplicitAForm<Scalar>());
421 stepper->setStepperExplicitValues(pl);
422
423 if (pl != Teuchos::null) {
424 Scalar gamma = pl->sublist("Newmark Explicit Parameters")
425 .template get<double>("Gamma", 0.5);
426 stepper->setGamma(gamma);
427 }
428
429 if (model != Teuchos::null) {
430 stepper->setModel(model);
431 stepper->initialize();
432 }
433
434 return stepper;
435}
436
437} // namespace Tempus
438#endif // Tempus_StepperNewmarkExplicitAForm_impl_hpp
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Thyra Base interface for implicit time steppers.
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel)
Set model.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual void takeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Take the specified timestep, dt, and return true if successful.
void correctVelocity(Thyra::VectorBase< Scalar > &v, const Thyra::VectorBase< Scalar > &vPred, const Thyra::VectorBase< Scalar > &a, const Scalar dt) const
virtual bool isValidSetup(Teuchos::FancyOStream &out) const
void predictVelocity(Thyra::VectorBase< Scalar > &vPred, const Thyra::VectorBase< Scalar > &v, const Thyra::VectorBase< Scalar > &a, const Scalar dt) const
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Get a default (initial) StepperState.
virtual void setAppAction(Teuchos::RCP< StepperNewmarkExplicitAFormAppAction< Scalar > > appAction)
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions and make them consistent.
void predictDisplacement(Thyra::VectorBase< Scalar > &dPred, const Thyra::VectorBase< Scalar > &d, const Thyra::VectorBase< Scalar > &v, const Thyra::VectorBase< Scalar > &a, const Scalar dt) const
StepperState is a simple class to hold state information about the stepper.
Thyra Base interface for time steppers.
void setICConsistencyCheck(bool c)
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.
void setICConsistency(std::string s)
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Teuchos::RCP< StepperNewmarkExplicitAForm< Scalar > > createStepperNewmarkExplicitAForm(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, Teuchos::RCP< Teuchos::ParameterList > pl)
Nonmember constructor - ModelEvaluator and ParameterList.