Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Tempus_StepperTrapezoidal_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_StepperTrapezoidal_impl_hpp
11 #define Tempus_StepperTrapezoidal_impl_hpp
12 
14 #include "Tempus_WrapperModelEvaluatorBasic.hpp"
15 
16 namespace Tempus {
17 
18 template <class Scalar>
20 {
21  this->setStepperName("Trapezoidal Method");
22  this->setStepperType("Trapezoidal Method");
23  this->setUseFSAL(true);
24  this->setICConsistency("Consistent");
25  this->setICConsistencyCheck(false);
26  this->setZeroInitialGuess(false);
27 
28  this->setAppAction(Teuchos::null);
29  this->setDefaultSolver();
30 }
31 
32 template <class Scalar>
34  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
36  bool useFSAL, std::string ICConsistency, bool ICConsistencyCheck,
37  bool zeroInitialGuess,
39  stepperTrapAppAction)
40 {
41  this->setStepperName("Trapezoidal Method");
42  this->setStepperType("Trapezoidal Method");
43  this->setUseFSAL(useFSAL);
44  this->setICConsistency(ICConsistency);
45  this->setICConsistencyCheck(ICConsistencyCheck);
46  this->setZeroInitialGuess(zeroInitialGuess);
47 
48  this->setAppAction(stepperTrapAppAction);
49  this->setSolver(solver);
50 
51  if (appModel != Teuchos::null) {
52  this->setModel(appModel);
53  this->initialize();
54  }
55 }
56 
57 template <class Scalar>
60 {
61  if (appAction == Teuchos::null) {
62  // Create default appAction
63  stepperTrapAppAction_ =
65  }
66  else {
67  stepperTrapAppAction_ = appAction;
68  }
69  this->isInitialized_ = false;
70 }
71 
72 template <class Scalar>
74  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
75 {
76  using Teuchos::RCP;
77 
78  RCP<SolutionState<Scalar> > initialState = solutionHistory->getCurrentState();
79 
80  // Check if we need Stepper storage for xDot
81  if (initialState->getXDot() == Teuchos::null)
82  this->setStepperXDot(initialState->getX()->clone_v());
83  else
84  this->setStepperXDot(initialState->getXDot());
85 
87 
89  !(this->getUseFSAL()), std::logic_error,
90  "Error - The First-Same-As-Last (FSAL) principle is required\n"
91  " for the Trapezoidal Stepper (i.e., useFSAL=true)!\n");
92  // There are at least two ways around this, but are not implemented.
93  // - Do a solve for xDotOld, xDot_{n-1}, at each time step as for the
94  // initial conditions. This is expensive since you would be doing
95  // two solves every time step.
96  // - Use evaluateExplicitODE to get xDot_{n-1} if the application
97  // provides it. Explicit evaluations are cheaper but requires the
98  // application to implement xDot = f(x,t).
99 }
100 
101 template <class Scalar>
103  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
104 {
105  this->checkInitialized();
106 
107  using Teuchos::RCP;
108 
109  TEMPUS_FUNC_TIME_MONITOR("Tempus::StepperTrapezoidal::takeStep()");
110  {
112  solutionHistory->getNumStates() < 2, std::logic_error,
113  "Error - StepperTrapezoidal<Scalar>::takeStep(...)\n"
114  << "Need at least two SolutionStates for Trapezoidal.\n"
115  << " Number of States = " << solutionHistory->getNumStates()
116  << "\nTry setting in \"Solution History\" \"Storage Type\" = "
117  << "\"Undo\"\n"
118  << " or \"Storage Type\" = \"Static\" and \"Storage Limit\" = "
119  << "\"2\"\n");
120  RCP<StepperTrapezoidal<Scalar> > thisStepper = Teuchos::rcpFromRef(*this);
121  stepperTrapAppAction_->execute(
122  solutionHistory, thisStepper,
124 
125  RCP<SolutionState<Scalar> > workingState =
126  solutionHistory->getWorkingState();
127  RCP<SolutionState<Scalar> > currentState =
128  solutionHistory->getCurrentState();
129 
130  RCP<const Thyra::VectorBase<Scalar> > xOld = currentState->getX();
131  RCP<const Thyra::VectorBase<Scalar> > xDotOld = currentState->getXDot();
132  RCP<Thyra::VectorBase<Scalar> > x = workingState->getX();
133  if (workingState->getXDot() != Teuchos::null)
134  this->setStepperXDot(workingState->getXDot());
135  RCP<Thyra::VectorBase<Scalar> > xDot = this->getStepperXDot();
136 
137  const Scalar time = workingState->getTime();
138  const Scalar dt = workingState->getTimeStep();
139  const Scalar alpha = getAlpha(dt);
140  const Scalar beta = getBeta(dt);
141 
142  // Setup TimeDerivative
144  new StepperTrapezoidalTimeDerivative<Scalar>(alpha, xOld, xDotOld));
145 
146  auto p = Teuchos::rcp(
147  new ImplicitODEParameters<Scalar>(timeDer, dt, alpha, beta));
148  stepperTrapAppAction_->execute(
149  solutionHistory, thisStepper,
151 
152  const Thyra::SolveStatus<Scalar> sStatus =
153  this->solveImplicitODE(x, xDot, time, p);
154  stepperTrapAppAction_->execute(
155  solutionHistory, thisStepper,
157 
158  if (workingState->getXDot() != Teuchos::null) timeDer->compute(x, xDot);
159 
160  workingState->setSolutionStatus(sStatus); // Converged --> pass.
161  workingState->setOrder(this->getOrder());
162  workingState->computeNorms(currentState);
163  stepperTrapAppAction_->execute(
164  solutionHistory, thisStepper,
166  }
167  return;
168 }
169 
176 template <class Scalar>
179 {
181  rcp(new StepperState<Scalar>(this->getStepperType()));
182  return stepperState;
183 }
184 
185 template <class Scalar>
187  Teuchos::FancyOStream& out, const Teuchos::EVerbosityLevel verbLevel) const
188 {
189  out.setOutputToRootOnly(0);
190  out << std::endl;
191  Stepper<Scalar>::describe(out, verbLevel);
192  StepperImplicit<Scalar>::describe(out, verbLevel);
193 
194  out << "--- StepperTrapezoidal ---\n";
195  out << " stepperTrapAppAction_ = " << stepperTrapAppAction_ << std::endl;
196  out << "--------------------------" << std::endl;
197 }
198 
199 template <class Scalar>
201 {
202  out.setOutputToRootOnly(0);
203  bool isValidSetup = true;
204 
205  if (!Stepper<Scalar>::isValidSetup(out)) isValidSetup = false;
206  if (!StepperImplicit<Scalar>::isValidSetup(out)) isValidSetup = false;
207 
208  if (stepperTrapAppAction_ == Teuchos::null) {
209  isValidSetup = false;
210  out << "The Trapezoidal AppAction is not set!\n";
211  }
212 
213  return isValidSetup;
214 }
215 
216 // Nonmember constructor - ModelEvaluator and ParameterList
217 // ------------------------------------------------------------------------
218 template <class Scalar>
220  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& model,
222 {
223  auto stepper = Teuchos::rcp(new StepperTrapezoidal<Scalar>());
224  stepper->setStepperImplicitValues(pl);
225 
226  if (model != Teuchos::null) {
227  stepper->setModel(model);
228  stepper->initialize();
229  }
230 
231  return stepper;
232 }
233 
234 } // namespace Tempus
235 #endif // Tempus_StepperTrapezoidal_impl_hpp
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Get a default (initial) StepperState.
Trapezoidal method time stepper.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const override
Thyra Base interface for time steppers.
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory) override
Set the initial conditions and make them consistent.
Teuchos::RCP< StepperTrapezoidal< Scalar > > createStepperTrapezoidal(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, Teuchos::RCP< Teuchos::ParameterList > pl)
Nonmember constructor - ModelEvaluator and ParameterList.
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions and make them consistent.
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)
Thyra Base interface for implicit time steppers.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Application Action for StepperTrapezoidal.
virtual void setAppAction(Teuchos::RCP< StepperTrapezoidalAppAction< Scalar > > appAction)
Time-derivative interface for Trapezoidal method.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
virtual bool isValidSetup(Teuchos::FancyOStream &out) 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.