Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Tempus_StepperOperatorSplit_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_StepperOperatorSplit_impl_hpp
10 #define Tempus_StepperOperatorSplit_impl_hpp
11 
12 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
13 #include "Thyra_VectorStdOps.hpp"
15 
16 
17 namespace Tempus {
18 
19 
20 template<class Scalar>
22  : OpSpSolnHistory_(Teuchos::null)
23 {
24  this->setStepperType( "Operator Split");
25  this->setUseFSAL( this->getUseFSALDefault());
28 
29  this->setOrder (1);
30  this->setOrderMin(1);
31  this->setOrderMax(1);
32 
33  this->setObserver();
34 }
35 
36 template<class Scalar>
38  std::vector<Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> > > appModels,
39  std::vector<Teuchos::RCP<Stepper<Scalar> > > subStepperList,
40  const Teuchos::RCP<StepperObserver<Scalar> >& obs,
41  bool useFSAL,
42  std::string ICConsistency,
43  bool ICConsistencyCheck,
44  int order,
45  int orderMin,
46  int orderMax)
47  : OpSpSolnHistory_(Teuchos::null)
48 {
49  this->setStepperType( "Operator Split");
50  this->setUseFSAL( useFSAL);
51  this->setICConsistency( ICConsistency);
52  this->setICConsistencyCheck( ICConsistencyCheck);
53 
54  this->setSubStepperList(subStepperList);
55  this->setOrder (order);
56  this->setOrderMin(orderMin);
57  this->setOrderMax(orderMax);
58 
59  this->setObserver(obs);
60 
61  if ( !(appModels.empty()) ) {
62  this->setModels(appModels);
63  this->initialize();
64  }
65 }
66 
67 template<class Scalar>
69  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel)
70 {
71  if (appModel != Teuchos::null) {
72  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
73  Teuchos::OSTab ostab(out,1,"StepperOperatorSplit::setModel()");
74  *out << "Warning -- No ModelEvaluator to set for StepperOperatorSplit, "
75  << "because it is a Stepper of Steppers.\n" << std::endl;
76  }
77  return;
78 }
79 
80 template<class Scalar>
82  const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& appModel)
83 {
84  if (appModel != Teuchos::null) {
85  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
86  Teuchos::OSTab ostab(out,1,"StepperOperatorSplit::setModel()");
87  *out << "Warning -- No ModelEvaluator to set for StepperOperatorSplit, "
88  << "because it is a Stepper of Steppers.\n" << std::endl;
89  }
90  return;
91 }
92 
93 template<class Scalar>
94 Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >
96 {
97  Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> > model;
98  typename std::vector<Teuchos::RCP<Stepper<Scalar> > >::const_iterator
99  subStepperIter = subStepperList_.begin();
100  for (; subStepperIter < subStepperList_.end(); subStepperIter++) {
101  model = (*subStepperIter)->getModel();
102  if (model != Teuchos::null) break;
103  }
104  if ( model == Teuchos::null ) {
105  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
106  Teuchos::OSTab ostab(out,1,"StepperOperatorSplit::getModel()");
107  *out << "Warning -- StepperOperatorSplit::getModel() "
108  << "Could not find a valid model! Returning null!" << std::endl;
109  }
110 
111  return model;
112 }
113 
114 template<class Scalar>
116  Teuchos::RCP<Thyra::NonlinearSolverBase<Scalar> > /* solver */)
117 {
118  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
119  Teuchos::OSTab ostab(out,1,"StepperOperatorSplit::setSolver()");
120  *out << "Warning -- No solver to set for StepperOperatorSplit "
121  << "because it is a Stepper of Steppers.\n" << std::endl;
122  return;
123 }
124 
125 template<class Scalar>
127  Teuchos::RCP<StepperObserver<Scalar> > obs)
128 {
129  if (obs == Teuchos::null) {
130  // Create default observer, otherwise keep current observer.
131  if (stepperOSObserver_ == Teuchos::null) {
132  stepperOSObserver_ =
133  Teuchos::rcp(new StepperOperatorSplitObserver<Scalar>());
134  }
135  } else {
136  stepperOSObserver_ =
137  Teuchos::rcp_dynamic_cast<StepperOperatorSplitObserver<Scalar> > (obs, true);
138  }
139 }
140 
141 template<class Scalar>
143  std::vector<Teuchos::RCP<Stepper<Scalar> > > subStepperList)
144 {
145  using Teuchos::RCP;
146  using Teuchos::ParameterList;
147 
148  subStepperList_ = subStepperList;
149 
150  typename std::vector<Teuchos::RCP<Stepper<Scalar> > >::iterator
151  subStepperIter = subStepperList_.begin();
152 
153  for (; subStepperIter<subStepperList_.end(); subStepperIter++) {
154  auto subStepper = *(subStepperIter);
155  bool useFSAL = subStepper->getUseFSAL();
156  if (useFSAL) {
157  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
158  Teuchos::OSTab ostab(out,1,"StepperOperatorSplit::createSubSteppers()");
159  *out << "Warning -- subStepper = '"
160  << subStepper->getStepperType() << "' has \n"
161  << " subStepper->getUseFSAL() = " << useFSAL << ".\n"
162  << " subSteppers usually can not use the FSAL priniciple with\n"
163  << " operator splitting. Proceeding with it set to true.\n"
164  << std::endl;
165  }
166  }
167 }
168 
169 template<class Scalar>
171  std::vector<Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> > > appModels)
172 {
173  using Teuchos::RCP;
174  using Teuchos::ParameterList;
175 
176  TEUCHOS_TEST_FOR_EXCEPTION(subStepperList_.size() != appModels.size(),
177  std::logic_error, "Error - Number of models and Steppers do not match!\n"
178  << " There are " << appModels.size() << " models.\n"
179  << " There are " << subStepperList_.size() << " steppers.\n");
180 
181  typename std::vector<RCP<const Thyra::ModelEvaluator<Scalar> > >::iterator
182  appModelIter = appModels.begin();
183 
184  typename std::vector<Teuchos::RCP<Stepper<Scalar> > >::iterator
185  subStepperIter = subStepperList_.begin();
186 
187  for (; appModelIter<appModels.end() || subStepperIter<subStepperList_.end();
188  appModelIter++, subStepperIter++)
189  {
190  auto appModel = *(appModelIter);
191  auto subStepper = *(subStepperIter);
192  subStepper->setModel(appModel);
193  subStepper->initialize();
194  }
195 }
196 
197 template<class Scalar>
199 {
200  TEUCHOS_TEST_FOR_EXCEPTION( subStepperList_.size() == 0, std::logic_error,
201  "Error - Need to set the subSteppers, createSubSteppers(), before calling "
202  "StepperOperatorSplit::initialize()\n");
203 
204  OpSpSolnHistory_ = rcp(new SolutionHistory<Scalar>());
205  OpSpSolnHistory_->setStorageLimit(2);
206  OpSpSolnHistory_->setStorageType(Tempus::STORAGE_TYPE_STATIC);
207 
208  if (tempState_ == Teuchos::null) {
209  Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >model = this->getModel();
210  TEUCHOS_TEST_FOR_EXCEPTION( model == Teuchos::null, std::logic_error,
211  "Error - StepperOperatorSplit::initialize() Could not find "
212  "a valid model!\n");
213  //tempState_ = rcp(new SolutionState<Scalar>()); Doesn't seem to work?!
214  tempState_ = rcp(new SolutionState<Scalar>(
215  model, this->getDefaultStepperState()));
216  }
217 
218  if (!isOneStepMethod() ) {
219  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
220  Teuchos::OSTab ostab(out,1,"StepperOperatorSplit::initialize()");
221  typename std::vector<Teuchos::RCP<Stepper<Scalar> > >::const_iterator
222  subStepperIter = subStepperList_.begin();
223  for (; subStepperIter < subStepperList_.end(); subStepperIter++) {
224  *out << "SubStepper, " << (*subStepperIter)->getStepperType()
225  << ", isOneStepMethod = " << (*subStepperIter)->isOneStepMethod()
226  << std::endl;
227  }
228  TEUCHOS_TEST_FOR_EXCEPTION(!isOneStepMethod(), std::logic_error,
229  "Error - OperatorSplit only works for one-step methods!\n");
230  }
231 }
232 
233 template<class Scalar>
235  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
236 {
237  typename std::vector<Teuchos::RCP<Stepper<Scalar> > >::iterator
238  subStepperIter = subStepperList_.begin();
239  for (; subStepperIter < subStepperList_.end(); subStepperIter++)
240  (*subStepperIter)->setInitialConditions(solutionHistory);
241 }
242 
243 template<class Scalar>
245  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
246 {
247  using Teuchos::RCP;
248 
249  TEMPUS_FUNC_TIME_MONITOR("Tempus::StepperOperatorSplit::takeStep()");
250  {
251  TEUCHOS_TEST_FOR_EXCEPTION(solutionHistory->getNumStates() < 2,
252  std::logic_error,
253  "Error - StepperOperatorSplit<Scalar>::takeStep(...)\n"
254  "Need at least two SolutionStates for OperatorSplit.\n"
255  " Number of States = " << solutionHistory->getNumStates() << "\n"
256  "Try setting in \"Solution History\" \"Storage Type\" = \"Undo\"\n"
257  " or \"Storage Type\" = \"Static\" and \"Storage Limit\" = \"2\"\n");
258 
259  stepperOSObserver_->observeBeginTakeStep(solutionHistory, *this);
260 
261  RCP<SolutionState<Scalar> > workingState=solutionHistory->getWorkingState();
262 
263  // Create OperatorSplit SolutionHistory to pass to subSteppers.
264  tempState_->copy(solutionHistory->getCurrentState());
265  OpSpSolnHistory_->clear();
266  OpSpSolnHistory_->addState(tempState_);
267  OpSpSolnHistory_->addWorkingState(workingState, false);
268 
269  RCP<SolutionState<Scalar> > currentSubState =
270  OpSpSolnHistory_->getCurrentState();
271  RCP<SolutionState<Scalar> > workingSubState =
272  OpSpSolnHistory_->getWorkingState();
273 
274  bool pass = true;
275  typename std::vector<Teuchos::RCP<Stepper<Scalar> > >::iterator
276  subStepperIter = subStepperList_.begin();
277  for (; subStepperIter < subStepperList_.end() and pass; subStepperIter++) {
278  int index = subStepperIter - subStepperList_.begin();
279 
280  stepperOSObserver_->observeBeforeStepper(index, solutionHistory, *this);
281 
282  (*subStepperIter)->takeStep(OpSpSolnHistory_);
283 
284  stepperOSObserver_->observeAfterStepper(index, solutionHistory, *this);
285 
286  if (workingSubState->getSolutionStatus() == Status::FAILED) {
287  pass = false;
288  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
289  Teuchos::OSTab ostab(out,1,"StepperOperatorSplit::takeStep()");
290  *out << "SubStepper, " << (*subStepperIter)->getStepperType()
291  << ", failed!" << std::endl;
292  break;
293  }
294 
295  // "promote" workingSubState
296  currentSubState = OpSpSolnHistory_->getCurrentState();
297  currentSubState->copySolutionData(workingSubState);
298  }
299 
300  if (pass == true) workingState->setSolutionStatus(Status::PASSED);
301  else workingState->setSolutionStatus(Status::FAILED);
302  workingState->setOrder(this->getOrder());
303  OpSpSolnHistory_->clear();
304  stepperOSObserver_->observeEndTakeStep(solutionHistory, *this);
305  }
306  return;
307 }
308 
309 
310 /** \brief Provide a StepperState to the SolutionState.
311  * This Stepper does not have any special state data,
312  * so just provide the base class StepperState with the
313  * Stepper description. This can be checked to ensure
314  * that the input StepperState can be used by this Stepper.
315  */
316 template<class Scalar>
317 Teuchos::RCP<Tempus::StepperState<Scalar> > StepperOperatorSplit<Scalar>::
319 {
320  Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
321  rcp(new StepperState<Scalar>(this->getStepperType()));
322  return stepperState;
323 }
324 
325 
326 template<class Scalar>
328  Teuchos::FancyOStream &out,
329  const Teuchos::EVerbosityLevel /* verbLevel */) const
330 {
331  out << this->getStepperType() << "::describe:" << std::endl;
332 }
333 
334 
335 template<class Scalar>
336 Teuchos::RCP<const Teuchos::ParameterList>
338 {
339  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
340  getValidParametersBasic(pl, this->getStepperType());
341  pl->set<int> ("Minimum Order", 1,
342  "Minimum Operator-split order. (default = 1)\n");
343  pl->set<int> ("Order", 1,
344  "Operator-split order. (default = 1)\n");
345  pl->set<int> ("Maximum Order", 1,
346  "Maximum Operator-split order. (default = 1)\n");
347 
348  pl->set<std::string>("Stepper List", "",
349  "Comma deliminated list of single quoted Steppers, e.g., \"'Operator 1', 'Operator 2'\".");
350 
351  return pl;
352 }
353 
354 
355 } // namespace Tempus
356 #endif // Tempus_StepperOperatorSplit_impl_hpp
virtual Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > getModel()
virtual void setObserver(Teuchos::RCP< StepperObserver< Scalar > > obs=Teuchos::null)
Set Observer.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel)
virtual void setNonConstModel(const Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > &appModel)
virtual void setSolver(Teuchos::RCP< Thyra::NonlinearSolverBase< Scalar > > solver)
Set solver.
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Get a default (initial) StepperState.
virtual bool getICConsistencyCheckDefault() const
virtual void setModels(std::vector< Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > > appModels)
virtual std::string getICConsistencyDefault() const
Thyra Base interface for time steppers.
StepperState is a simple class to hold state information about the stepper.
StepperOperatorSplitObserver class for StepperOperatorSplit.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
void setICConsistencyCheck(bool c)
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 void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions and make them consistent.
Keep a fix number of states.
virtual bool getUseFSALDefault() const
virtual void takeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Take the specified timestep, dt, and return true if successful.
void getValidParametersBasic(Teuchos::RCP< Teuchos::ParameterList > pl, std::string stepperType)
Provide basic parameters to Steppers.
void setStepperType(std::string s)
virtual void initialize()
Initialize during construction and after changing input parameters.
Solution state for integrators and steppers. SolutionState contains the metadata for solutions and th...
virtual void setSubStepperList(std::vector< Teuchos::RCP< Stepper< Scalar > > > subStepperList)
void setICConsistency(std::string s)