Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
19 namespace Tempus {
20 
21 template <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 
30 template <class Scalar>
34  const Scalar dt) const
35 {
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 
45 template <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 
54 template <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 
66 template <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 
90 template <class Scalar>
92  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
93 {
94  using Teuchos::RCP;
95 
96  int numStates = solutionHistory->getNumStates();
97 
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.
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());
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 {
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 
242 template <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  {
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 
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 
349 template <class Scalar>
352 {
354  rcp(new StepperState<Scalar>(this->getStepperType()));
355  return stepperState;
356 }
357 
358 template <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 
372 template <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 
385 template <class Scalar>
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 
396 template <class Scalar>
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 // ------------------------------------------------------------------------
414 template <class Scalar>
417  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& model,
419 {
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
virtual RCP< const VectorSpaceBase< Scalar > > space() const =0
Application Action for StepperNewmarkExplicitAForm.
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
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Get a default (initial) StepperState.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void setStepperName(std::string s)
Set the stepper name.
virtual void initialize()
Initialize after construction and changing input parameters.
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions and make them consistent.
Thyra Base interface for time steppers.
virtual void takeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Take the specified timestep, dt, and return true if successful.
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< const Teuchos::ParameterList > getValidParameters() const
void setICConsistencyCheck(bool c)
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel)
Set model.
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
void predictVelocity(Thyra::VectorBase< Scalar > &vPred, const Thyra::VectorBase< Scalar > &v, const Thyra::VectorBase< Scalar > &a, const Scalar dt) const
Teuchos::RCP< StepperNewmarkExplicitAForm< Scalar > > createStepperNewmarkExplicitAForm(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, Teuchos::RCP< Teuchos::ParameterList > pl)
Nonmember constructor - ModelEvaluator and ParameterList.
virtual bool isValidSetup(Teuchos::FancyOStream &out) const
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
void correctVelocity(Thyra::VectorBase< Scalar > &v, const Thyra::VectorBase< Scalar > &vPred, const Thyra::VectorBase< Scalar > &a, const Scalar dt) const
Thyra Base interface for implicit time steppers.
void setStepperType(std::string s)
Set the stepper type.
virtual void setAppAction(Teuchos::RCP< StepperNewmarkExplicitAFormAppAction< Scalar > > appAction)
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
void setICConsistency(std::string s)