Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Tempus_StepperSubcycling_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_StepperSubcycling_impl_hpp
10 #define Tempus_StepperSubcycling_impl_hpp
11 
15 #include "Tempus_IntegratorObserverSubcycling.hpp"
16 
17 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
18 #include "Thyra_VectorStdOps.hpp"
19 
20 
21 namespace Tempus {
22 
23 
24 template<class Scalar>
26 {
27  using Teuchos::RCP;
28  using Teuchos::ParameterList;
29 
30  this->setStepperType( "Subcycling");
31  this->setUseFSAL( this->getUseFSALDefault());
32  this->setICConsistency( this->getICConsistencyDefault());
33  this->setICConsistencyCheck( this->getICConsistencyCheckDefault());
34 
35  this->setObserver(Teuchos::rcp(new StepperSubcyclingObserver<Scalar>()));
36  scIntegrator_ = Teuchos::rcp(new IntegratorBasic<Scalar>());
37  scIntegrator_->setTimeStepControl();
38  scIntegrator_->setObserver(
39  Teuchos::rcp(new IntegratorObserverSubcycling<Scalar>()));
40 
41  RCP<ParameterList> tempusPL = scIntegrator_->getTempusParameterList();
42 
43  { // Set default subcycling Stepper to Forward Euler.
44  tempusPL->sublist("Default Integrator")
45  .set("Stepper Name", "Default Subcycling Stepper");
46  RCP<ParameterList> stepperPL = Teuchos::parameterList();
47  stepperPL->set("Stepper Type", "Forward Euler");
48  tempusPL->set("Default Subcycling Stepper", *stepperPL);
49 
50  auto sf = Teuchos::rcp(new Tempus::StepperFactory<double>());
51  auto stepperFE = sf->createStepperForwardEuler(Teuchos::null,Teuchos::null);
52  setSubcyclingStepper(stepperFE);
53  }
54 
55  // Keep the default SolutionHistory settings:
56  // * 'Storage Type' = "Undo"
57  // * 'Storage Limit' = 2
58  // Also
59  // * No checkpointing within the subcycling, but can restart from
60  // failed subcycle step.
61 
62  // Keep the default TimeStepControl settings for subcycling:
63  // * Finish exactly on the full timestep.
64  // * No solution output during the subcycling.
65  // * Variable time step size.
66  // Set the default initial time step size.
67  {
68  tempusPL->sublist("Default Integrator")
69  .sublist("Time Step Control")
70  .set("Initial Time Step", std::numeric_limits<Scalar>::max());
71  }
72 }
73 
74 
75 template<class Scalar>
77  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
78  const Teuchos::RCP<StepperSubcyclingObserver<Scalar> >& obs,
79  const Teuchos::RCP<IntegratorBasic<Scalar> >& scIntegrator,
80  bool useFSAL,
81  std::string ICConsistency,
82  bool ICConsistencyCheck)
83 {
84  this->setStepperType( "Subcycling");
85  this->setUseFSAL( useFSAL);
86  this->setICConsistency( ICConsistency);
87  this->setICConsistencyCheck( ICConsistencyCheck);
88 
89  this->setObserver(obs);
90  scIntegrator_ = scIntegrator;
91 
92  if (appModel != Teuchos::null) {
93  this->setModel(appModel);
94  this->initialize();
95  }
96 }
97 
98 
99 template<class Scalar>
101  Teuchos::RCP<Stepper<Scalar> > stepper)
102 {
103  scIntegrator_->setStepperWStepper(stepper);
104  this->isInitialized_ = false;
105 }
106 
107 
108 template<class Scalar>
110 {
111  scIntegrator_->getNonConstTimeStepControl()->setMinTimeStep(MinTimeStep);
112  this->isInitialized_ = false;
113 }
114 
115 
116 template<class Scalar>
118 {
119  scIntegrator_->getNonConstTimeStepControl()->setInitTimeStep(InitTimeStep);
120  this->isInitialized_ = false;
121 }
122 
123 
124 template<class Scalar>
126 {
127  scIntegrator_->getNonConstTimeStepControl()->setMaxTimeStep(MaxTimeStep);
128  this->isInitialized_ = false;
129 }
130 
131 
132 template<class Scalar>
134 {
135  scIntegrator_->getNonConstTimeStepControl()->setStepType(stepType);
136 
137  auto tsc = scIntegrator_->getNonConstTimeStepControl();
138  auto tscStrategy = tsc->getTimeStepControlStrategy();
139  tscStrategy->clearObservers();
140 
141  Teuchos::RCP<TimeStepControlStrategy<Scalar> > strategy =
142  Teuchos::rcp(new TimeStepControlStrategyConstant<Scalar>());
143  if (stepType == "Variable")
144  strategy = Teuchos::rcp(new TimeStepControlStrategyBasicVS<Scalar>());
145 
146  tscStrategy->addStrategy(strategy);
147 
148  this->isInitialized_ = false;
149 }
150 
151 
152 template<class Scalar>
154 {
155  scIntegrator_->getNonConstTimeStepControl()->setMaxFailures(MaxFailures);
156  this->isInitialized_ = false;
157 }
158 
159 
160 template<class Scalar>
162 setSubcyclingMaxConsecFailures(int MaxConsecFailures)
163 {
164  scIntegrator_->getNonConstTimeStepControl()->setMaxConsecFailures(MaxConsecFailures);
165  this->isInitialized_ = false;
166 }
167 
168 
169 template<class Scalar>
172 {
173  scIntegrator_->setScreenOutputIndexInterval(i);
174  this->isInitialized_ = false;
175 }
176 
177 
178 template<class Scalar>
181  Teuchos::RCP<TimeStepControlStrategy<Scalar> > tscs)
182 {
183  scIntegrator_->getNonConstTimeStepControl()->getTimeStepControlStrategy()->clearObservers();
184  scIntegrator_->getNonConstTimeStepControl()->setTimeStepControlStrategy(tscs);
185  this->isInitialized_ = false;
186 }
187 
188 
189 template<class Scalar>
191  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel)
192 {
193  scIntegrator_->setStepper(appModel);
194  this->isInitialized_ = false;
195 }
196 
197 
198 template<class Scalar>
200  const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& appModel)
201 {
202  setModel(appModel);
203  this->isInitialized_ = false;
204 }
205 
206 
207 template<class Scalar>
209  Teuchos::RCP<StepperObserver<Scalar> > obs)
210 {
211  if (obs != Teuchos::null) stepperSCObserver_ =
212  Teuchos::rcp_dynamic_cast<StepperSubcyclingObserver<Scalar> > (obs, true);
213 
214  if (stepperSCObserver_ == Teuchos::null)
215  stepperSCObserver_ = Teuchos::rcp(new StepperSubcyclingObserver<Scalar>());
216 
217  this->isInitialized_ = false;
218 }
219 
220 
221 template<class Scalar>
222 Teuchos::RCP<StepperObserver<Scalar> >
224 { return stepperSCObserver_; }
225 
226 
227 template<class Scalar>
229 {
230  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
231  bool isValidSetup = true;
232 
233  if ( !(this->getICConsistency() == "None" ||
234  this->getICConsistency() == "Zero" ||
235  this->getICConsistency() == "App" ||
236  this->getICConsistency() == "Consistent") ) {
237  isValidSetup = false;
238  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
239  *out << "The IC consistency does not have a valid value!\n"
240  << "('None', 'Zero', 'App' or 'Consistent')\n"
241  << " ICConsistency = " << this->getICConsistency() << "\n";
242  }
243  scIntegrator_->initialize();
244 
245 
246  if (stepperSCObserver_ == Teuchos::null) {
247  isValidSetup = false;
248  *out << "The Subcycling observer is not set!\n";
249  }
250 
251  if (isValidSetup)
252  this->isInitialized_ = true; // Only place it is set to true.
253  else
254  this->describe(*out, Teuchos::VERB_MEDIUM);
255 }
256 
257 
258 template<class Scalar>
260 { return scIntegrator_->getStepper()->isExplicit(); }
261 
262 
263 template<class Scalar>
265 { return scIntegrator_->getStepper()->isImplicit(); }
266 
267 
268 template<class Scalar>
270 { return scIntegrator_->getStepper()->isExplicitImplicit(); }
271 
272 
273 template<class Scalar>
275 { return scIntegrator_->getStepper()->isOneStepMethod(); }
276 
277 
278 template<class Scalar>
280 { return scIntegrator_->getStepper()->isMultiStepMethod(); }
281 
282 
283 template<class Scalar>
285 { return scIntegrator_->getStepper()->getOrder(); }
286 
287 
288 template<class Scalar>
290 { return scIntegrator_->getStepper()->getOrderMin(); }
291 
292 
293 template<class Scalar>
295 { return scIntegrator_->getStepper()->getOrderMax(); }
296 
297 
298 template<class Scalar>
300 { return scIntegrator_->getStepper()->getOrderODE(); }
301 
302 
303 template<class Scalar>
305  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory) const
306 { return scIntegrator_->getStepper()->getInitTimeStep(solutionHistory); }
307 
308 
309 template<class Scalar>
311  Teuchos::RCP<const Thyra::VectorBase<Scalar> > initialGuess)
312 {
313  scIntegrator_->getStepper()->setInitialGuess(initialGuess);
314  this->isInitialized_ = false;
315 }
316 
317 
318 template<class Scalar>
320  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
321 { scIntegrator_->getStepper()->setInitialConditions(solutionHistory); }
322 
323 
324 template<class Scalar>
326  Teuchos::RCP<Thyra::NonlinearSolverBase<Scalar> > solver)
327 {
328  scIntegrator_->getStepper()->setSolver(solver);
329  this->isInitialized_ = false;
330 }
331 
332 
333 template<class Scalar>
334 Teuchos::RCP<Thyra::NonlinearSolverBase<Scalar> >
336 { return scIntegrator_->getStepper()->getSolver(); }
337 
338 
339 template<class Scalar>
341  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
342 {
343  using Teuchos::RCP;
344 
345  TEMPUS_FUNC_TIME_MONITOR("Tempus::StepperSubcycling::takeStep()");
346  {
347  TEUCHOS_TEST_FOR_EXCEPTION(solutionHistory->getNumStates() < 2,
348  std::logic_error,
349  "Error - StepperSubcycling<Scalar>::takeStep(...)\n"
350  "Need at least two SolutionStates for Subcycling.\n"
351  " Number of States = " << solutionHistory->getNumStates() << "\n"
352  "Try setting in \"Solution History\" \"Storage Type\" = \"Undo\"\n"
353  " or \"Storage Type\" = \"Static\" and \"Storage Limit\" = \"2\"\n");
354 
355  stepperSCObserver_->observeBeginTakeStep(solutionHistory, *this);
356  RCP<SolutionState<Scalar> > currentState=solutionHistory->getCurrentState();
357  RCP<SolutionState<Scalar> > workingState=solutionHistory->getWorkingState();
358 
359  auto scTSC = scIntegrator_->getNonConstTimeStepControl();
360  scTSC->setInitTime (currentState->getTime());
361  scTSC->setInitIndex (0);
362  scTSC->setFinalTime (workingState->getTime());
363  scTSC->setMaxTimeStep(workingState->getTimeStep());
364 
365 
366  Teuchos::RCP<SolutionStateMetaData<Scalar> > scMD =
368  scMD->copy(currentState->getMetaData());
369  scMD->setDt(scTSC->getInitTimeStep());
370  scMD->setOrder(scIntegrator_->getStepper()->getOrder());
371  scMD->setIStep(0);
372  scMD->setNFailures(0);
373  scMD->setNRunningFailures(0);
374  scMD->setNConsecutiveFailures(0);
375  scMD->setOutput(false);
376  scMD->setOutputScreen(false);
377 
378  TEUCHOS_TEST_FOR_EXCEPTION(!scMD->getIsSynced(), std::logic_error,
379  "Error - StepperSubcycling<Scalar>::takeStep(...)\n"
380  " Subcycling requires the the solution is synced!\n"
381  " (i.e., x, xDot, and xDotDot at the same time level.\n");
382 
383  auto subcyclingState = rcp(new SolutionState<Scalar>( scMD,
384  currentState->getX(),
385  currentState->getXDot(),
386  currentState->getXDotDot(),
387  currentState->getStepperState(),
388  currentState->getPhysicsState()));
389 
390  auto scSH = rcp(new Tempus::SolutionHistory<double>());
391  scSH->setName("Subcycling States");
392  scSH->setStorageType(Tempus::STORAGE_TYPE_STATIC);
393  scSH->setStorageLimit(3);
394  scSH->addState(subcyclingState);
395 
396  scIntegrator_->setSolutionHistory(scSH);
397 
398  bool pass = scIntegrator_->advanceTime();
399 
400  RCP<SolutionState<Scalar> > scCS = scSH->getCurrentState();
401 
402  RCP<Thyra::VectorBase<Scalar> > x = workingState->getX();
403  RCP<Thyra::VectorBase<Scalar> > scX = scCS->getX();
404  Thyra::V_V(x.ptr(), *(scX));
405 
406  RCP<Thyra::VectorBase<Scalar> > xDot = workingState->getXDot();
407  if (xDot != Teuchos::null) {
408  RCP<Thyra::VectorBase<Scalar> > scXDot = scCS->getXDot();
409  Thyra::V_V(xDot.ptr(), *(scXDot));
410  }
411 
412  RCP<Thyra::VectorBase<Scalar> > xDotDot = workingState->getXDotDot();
413  if (xDotDot != Teuchos::null) {
414  RCP<Thyra::VectorBase<Scalar> > scXDotDot = scCS->getXDotDot();
415  Thyra::V_V(xDotDot.ptr(), *(scXDotDot));
416  }
417 
418  if (pass == true) workingState->setSolutionStatus(Status::PASSED);
419  else workingState->setSolutionStatus(Status::FAILED);
420  workingState->setOrder(scCS->getOrder());
421  scSH->clear();
422  stepperSCObserver_->observeEndTakeStep(solutionHistory, *this);
423  }
424  return;
425 }
426 
427 
428 /** \brief Provide a StepperState to the SolutionState.
429  * This Stepper does not have any special state data,
430  * so just provide the base class StepperState with the
431  * Stepper description. This can be checked to ensure
432  * that the input StepperState can be used by this Stepper.
433  */
434 template<class Scalar>
435 Teuchos::RCP<Tempus::StepperState<Scalar> > StepperSubcycling<Scalar>::
437 {
438  Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
439  rcp(new StepperState<Scalar>(this->getStepperType()));
440  return stepperState;
441 }
442 
443 
444 template<class Scalar>
446  Teuchos::FancyOStream &out,
447  const Teuchos::EVerbosityLevel verbLevel) const
448 {
449  out << std::endl;
450  Stepper<Scalar>::describe(out, verbLevel);
451 
452  out << "--- StepperSubcycling ---\n";
453  out << " stepperSCObserver = " << stepperSCObserver_ << std::endl;
454  out << " scIntegrator = " << scIntegrator_ << std::endl;
455  out << "-------------------------" << std::endl;
456  scIntegrator_->getStepper()->describe(out, verbLevel);
457 }
458 
459 
460 template<class Scalar>
461 Teuchos::RCP<const Teuchos::ParameterList>
463 {
464  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
465  "Error - StepperSubcycling<Scalar>::getValidParameters()\n"
466  " is not implemented yet.\n");
467 
468  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
469  getValidParametersBasic(pl, this->getStepperType());
470  pl->set<bool>("Use FSAL", true);
471  pl->set<std::string>("Initial Condition Consistency", "Consistent");
472  return pl;
473 }
474 
475 
476 } // namespace Tempus
477 #endif // Tempus_StepperSubcycling_impl_hpp
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
virtual void setSubcyclingStepper(Teuchos::RCP< Stepper< Scalar > > stepper)
virtual void initialize()
Initialize during construction and after changing input parameters.
virtual void setSubcyclingMinTimeStep(Scalar MinTimeStep)
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual void setSubcyclingScreenOutputIndexInterval(int i)
virtual void setSubcyclingMaxTimeStep(Scalar MaxTimeStep)
StepControlStrategy class for TimeStepControl.
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Get a default (initial) StepperState.
virtual void takeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Take the specified timestep, dt, and return true if successful.
virtual void setSolver(Teuchos::RCP< Thyra::NonlinearSolverBase< Scalar > > solver=Teuchos::null)
Set solver.
virtual void setSubcyclingMaxConsecFailures(int MaxConsecFailures)
virtual void setSubcyclingTimeStepControlStrategy(Teuchos::RCP< TimeStepControlStrategy< Scalar > > tscs)
Thyra Base interface for time steppers.
StepperState is a simple class to hold state information about the stepper.
virtual void setObserver(Teuchos::RCP< StepperObserver< Scalar > > obs=Teuchos::null)
Set Observer.
virtual Teuchos::RCP< Thyra::NonlinearSolverBase< Scalar > > getSolver() const
Get solver.
virtual void setSubcyclingStepType(std::string StepType)
StepperObserver class for Stepper class.
Teuchos::RCP< SolutionHistory< Scalar > > solutionHistory(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
Nonmember constructor.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
virtual Scalar getInitTimeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory) const
Keep a fix number of states.
StepControlStrategy class for TimeStepControl.
virtual void setSubcyclingInitTimeStep(Scalar InitTimeStep)
virtual void setInitialGuess(Teuchos::RCP< const Thyra::VectorBase< Scalar > > initial_guess)
Pass initial guess to Newton solver (only relevant for implicit solvers)
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel)
IntegratorObserverSubcycling class for time integrators. This basic class has simple no-op functions...
StepperSubcyclingObserver class for StepperSubcycling.
StepControlStrategy class for TimeStepControl.
void getValidParametersBasic(Teuchos::RCP< Teuchos::ParameterList > pl, std::string stepperType)
Provide basic parameters to Steppers.
Solution state for integrators and steppers. SolutionState contains the metadata for solutions and th...
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions, make them consistent, and set needed memory.
virtual void setNonConstModel(const Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > &appModel)
virtual Teuchos::RCP< StepperObserver< Scalar > > getObserver() const
Get Observer.
virtual void setSubcyclingMaxFailures(int MaxFailures)