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