Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Tempus_StepperTrapezoidal_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_StepperTrapezoidal_impl_hpp
10 #define Tempus_StepperTrapezoidal_impl_hpp
11 
12 #include "Tempus_config.hpp"
14 #include "Tempus_WrapperModelEvaluatorBasic.hpp"
15 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
16 #include "NOX_Thyra.H"
17 
18 
19 namespace Tempus {
20 
21 // Forward Declaration for recursive includes (this Stepper <--> StepperFactory)
22 template<class Scalar> class StepperFactory;
23 
24 
25 template<class Scalar>
27 {
28  this->setParameterList(Teuchos::null);
29  this->modelWarning();
30 }
31 
32 
33 template<class Scalar>
35  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
36  Teuchos::RCP<Teuchos::ParameterList> pList)
37 {
38  this->setParameterList(pList);
39 
40  if (appModel == Teuchos::null) {
41  this->modelWarning();
42  }
43  else {
44  this->setModel(appModel);
45  this->initialize();
46  }
47 }
48 
49 
50 template<class Scalar>
52  Teuchos::RCP<StepperObserver<Scalar> > obs)
53 {
54  if (obs == Teuchos::null) {
55  // Create default observer, otherwise keep current observer.
56  if (this->stepperObserver_ == Teuchos::null) {
57  stepperTrapObserver_ =
58  Teuchos::rcp(new StepperTrapezoidalObserver<Scalar>());
59  this->stepperObserver_ =
60  Teuchos::rcp_dynamic_cast<StepperObserver<Scalar> >
61  (stepperTrapObserver_);
62  }
63  } else {
64  this->stepperObserver_ = obs;
65  stepperTrapObserver_ =
66  Teuchos::rcp_dynamic_cast<StepperTrapezoidalObserver<Scalar> >
67  (this->stepperObserver_);
68  }
69 }
70 
71 
72 template<class Scalar>
74 {
75  TEUCHOS_TEST_FOR_EXCEPTION(
76  this->wrapperModel_ == Teuchos::null, std::logic_error,
77  "Error - Need to set the model, setModel(), before calling "
78  "StepperTrapezoidal::initialize()\n");
79 
80  this->setParameterList(this->stepperPL_);
81  this->setSolver();
82  this->setObserver();
83 }
84 
85 
86 template<class Scalar>
88  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
89 {
90  using Teuchos::RCP;
91 
92  RCP<SolutionState<Scalar> > initialState = solutionHistory->getCurrentState();
93 
94  // Check if we need Stepper storage for xDot
95  if (initialState->getXDot() == Teuchos::null)
96  this->setStepperXDot(initialState->getX()->clone_v());
97 
99 
100  TEUCHOS_TEST_FOR_EXCEPTION( !(this->getUseFSAL()), std::logic_error,
101  "Error - The First-Step-As-Last (FSAL) principle is required\n"
102  " for the Trapezoidal Stepper (i.e., useFSAL=true)!\n");
103 // There are at least two ways around this, but are not implemented.
104 // - Do a solve for xDotOld, xDot_{n-1}, at each time step as for the
105 // initial conditions. This is expensive since you would be doing
106 // two solves every time step.
107 // - Use evaluateExplicitODE to get xDot_{n-1} if the application
108 // provides it. Explicit evaluations are cheaper but requires the
109 // application to implement xDot = f(x,t).
110 }
111 
112 
113 template<class Scalar>
115  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
116 {
117  using Teuchos::RCP;
118 
119  TEMPUS_FUNC_TIME_MONITOR("Tempus::StepperTrapezoidal::takeStep()");
120  {
121  TEUCHOS_TEST_FOR_EXCEPTION(solutionHistory->getNumStates() < 2,
122  std::logic_error,
123  "Error - StepperTrapezoidal<Scalar>::takeStep(...)\n"
124  "Need at least two SolutionStates for Trapezoidal.\n"
125  " Number of States = " << solutionHistory->getNumStates() << "\n"
126  "Try setting in \"Solution History\" \"Storage Type\" = \"Undo\"\n"
127  " or \"Storage Type\" = \"Static\" and \"Storage Limit\" = \"2\"\n");
128 
129  this->stepperObserver_->observeBeginTakeStep(solutionHistory, *this);
130  RCP<SolutionState<Scalar> > workingState=solutionHistory->getWorkingState();
131  RCP<SolutionState<Scalar> > currentState=solutionHistory->getCurrentState();
132 
133  RCP<const Thyra::VectorBase<Scalar> > xOld = currentState->getX();
134  RCP<const Thyra::VectorBase<Scalar> > xDotOld = currentState->getXDot();
135  RCP<Thyra::VectorBase<Scalar> > x = workingState->getX();
136  RCP<Thyra::VectorBase<Scalar> > xDot = workingState->getXDot();
137 
138  const Scalar time = workingState->getTime();
139  const Scalar dt = workingState->getTimeStep();
140  const Scalar alpha = getAlpha(dt);
141  const Scalar beta = getBeta (dt);
142 
143 
144  // Setup TimeDerivative
145  Teuchos::RCP<TimeDerivative<Scalar> > timeDer =
147  alpha, xOld, xDotOld));
148 
149  // Setup InArgs and OutArgs
150  typedef Thyra::ModelEvaluatorBase MEB;
151  MEB::InArgs<Scalar> inArgs = this->wrapperModel_->getInArgs();
152  MEB::OutArgs<Scalar> outArgs = this->wrapperModel_->getOutArgs();
153  inArgs.set_x(x);
154  if (inArgs.supports(MEB::IN_ARG_x_dot )) inArgs.set_x_dot (xDot);
155  if (inArgs.supports(MEB::IN_ARG_t )) inArgs.set_t (time);
156  if (inArgs.supports(MEB::IN_ARG_step_size)) inArgs.set_step_size(dt);
157  if (inArgs.supports(MEB::IN_ARG_alpha )) inArgs.set_alpha (alpha);
158  if (inArgs.supports(MEB::IN_ARG_beta )) inArgs.set_beta (beta);
159 
160  this->wrapperModel_->setForSolve(timeDer, inArgs, outArgs);
161 
162  stepperTrapObserver_->observeBeforeSolve(solutionHistory, *this);
163 
164  const Thyra::SolveStatus<Scalar> sStatus = this->solveImplicitODE(x);
165 
166  stepperTrapObserver_->observeAfterSolve(solutionHistory, *this);
167 
168  if (workingState->getXDot() != Teuchos::null)
169  timeDer->compute(x, xDot);
170 
171  workingState->setSolutionStatus(sStatus); // Converged --> pass.
172  workingState->setOrder(this->getOrder());
173  this->stepperObserver_->observeEndTakeStep(solutionHistory, *this);
174  }
175  return;
176 }
177 
178 
179 /** \brief Provide a StepperState to the SolutionState.
180  * This Stepper does not have any special state data,
181  * so just provide the base class StepperState with the
182  * Stepper description. This can be checked to ensure
183  * that the input StepperState can be used by this Stepper.
184  */
185 template<class Scalar>
186 Teuchos::RCP<Tempus::StepperState<Scalar> >
189 {
190  Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
191  rcp(new StepperState<Scalar>(description()));
192  return stepperState;
193 }
194 
195 
196 template<class Scalar>
198 {
199  std::string name = "Trapezoidal Method";
200  return(name);
201 }
202 
203 
204 template<class Scalar>
206  Teuchos::FancyOStream &out,
207  const Teuchos::EVerbosityLevel /* verbLevel */) const
208 {
209  out << description() << "::describe:" << std::endl
210  << "wrapperModel_ = " << this->wrapperModel_->description() << std::endl;
211 }
212 
213 
214 template <class Scalar>
216  Teuchos::RCP<Teuchos::ParameterList> const& pList)
217 {
218  Teuchos::RCP<Teuchos::ParameterList> stepperPL = this->stepperPL_;
219  if (pList == Teuchos::null) {
220  // Create default parameters if null, otherwise keep current parameters.
221  if (stepperPL == Teuchos::null) stepperPL = this->getDefaultParameters();
222  } else {
223  stepperPL = pList;
224  }
225  if (!(stepperPL->isParameter("Solver Name"))) {
226  stepperPL->set<std::string>("Solver Name", "Default Solver");
227  Teuchos::RCP<Teuchos::ParameterList> solverPL =
228  this->defaultSolverParameters();
229  stepperPL->set("Default Solver", *solverPL);
230  }
231  // Can not validate because of optional Parameters (e.g., Solver Name).
232  // stepperPL->validateParametersAndSetDefaults(*this->getValidParameters());
233 
234  std::string stepperType = stepperPL->get<std::string>("Stepper Type");
235  TEUCHOS_TEST_FOR_EXCEPTION( stepperType != "Trapezoidal Method",
236  std::logic_error,
237  "Error - Stepper Type is not 'Trapezoidal Method'!\n"
238  << " Stepper Type = "<<stepperPL->get<std::string>("Stepper Type")<<"\n");
239 
240  this->stepperPL_ = stepperPL;
241 }
242 
243 
244 template<class Scalar>
245 Teuchos::RCP<const Teuchos::ParameterList>
247 {
248  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
249  pl->setName("Default Stepper - " + this->description());
250  pl->set<std::string>("Stepper Type", this->description());
251  this->getValidParametersBasic(pl);
252  pl->set<bool> ("Use FSAL", true);
253  pl->set<std::string>("Initial Condition Consistency", "Consistent");
254  pl->set<bool> ("Zero Initial Guess", false);
255  pl->set<std::string>("Solver Name", "",
256  "Name of ParameterList containing the solver specifications.");
257 
258  return pl;
259 }
260 
261 
262 template<class Scalar>
263 Teuchos::RCP<Teuchos::ParameterList>
265 {
266  using Teuchos::RCP;
267  using Teuchos::ParameterList;
268  using Teuchos::rcp_const_cast;
269 
270  RCP<ParameterList> pl =
271  rcp_const_cast<ParameterList>(this->getValidParameters());
272 
273  pl->set<std::string>("Solver Name", "Default Solver");
274  RCP<ParameterList> solverPL = this->defaultSolverParameters();
275  pl->set("Default Solver", *solverPL);
276 
277  return pl;
278 }
279 
280 
281 template <class Scalar>
282 Teuchos::RCP<Teuchos::ParameterList>
284 {
285  return(this->stepperPL_);
286 }
287 
288 
289 template <class Scalar>
290 Teuchos::RCP<Teuchos::ParameterList>
292 {
293  Teuchos::RCP<Teuchos::ParameterList> temp_plist = this->stepperPL_;
294  this->stepperPL_ = Teuchos::null;
295  return(temp_plist);
296 }
297 
298 
299 } // namespace Tempus
300 #endif // Tempus_StepperTrapezoidal_impl_hpp
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions and make them consistent.
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Get a default (initial) StepperState.
virtual std::string description() const
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
Teuchos::RCP< Teuchos::ParameterList > getDefaultParameters() const
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.
StepperTrapezoidalObserver class for StepperTrapezoidal.
virtual void initialize()
Initialize during construction and after changing input parameters.
StepperObserver class for Stepper class.
Teuchos::RCP< SolutionHistory< Scalar > > solutionHistory(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
Nonmember constructor.
Time-derivative interface for Trapezoidal method.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &pl)
virtual void setObserver(Teuchos::RCP< StepperObserver< Scalar > > obs=Teuchos::null)
Set Observer.
virtual void takeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Take the specified timestep, dt, and return true if successful.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()