Tempus  Version of the Day
Time Integration
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 template<class Scalar>
21  std::vector<Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> > > appModels,
22  Teuchos::RCP<Teuchos::ParameterList> pList)
23  : stepperPL_(Teuchos::null), OpSpSolnHistory_(Teuchos::null),
24  stepperOSObserver_(Teuchos::null)
25 {
26  this->setParameterList(pList);
27  this->createSubSteppers(appModels);
28  this->initialize();
29 }
30 
31 template<class Scalar>
33  : stepperPL_(Teuchos::null), OpSpSolnHistory_(Teuchos::null),
34  stepperOSObserver_(Teuchos::null)
35 {
36  this->setParameterList(Teuchos::null);
37  // Still require
38  // * Setting models and steppers, i.e., addStepper()
39  // * Calling initialize()
40 }
41 
42 template<class Scalar>
44  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel)
45 {
46  if (appModel != Teuchos::null) {
47  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
48  Teuchos::OSTab ostab(out,1,"StepperOperatorSplit::setModel()");
49  *out << "Warning -- No ModelEvaluator to set for StepperOperatorSplit, "
50  << "because it is a Stepper of Steppers.\n" << std::endl;
51  }
52  return;
53 }
54 
55 template<class Scalar>
57  const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& appModel)
58 {
59  if (appModel != Teuchos::null) {
60  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
61  Teuchos::OSTab ostab(out,1,"StepperOperatorSplit::setModel()");
62  *out << "Warning -- No ModelEvaluator to set for StepperOperatorSplit, "
63  << "because it is a Stepper of Steppers.\n" << std::endl;
64  }
65  return;
66 }
67 
68 template<class Scalar>
69 Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >
71 {
72  Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> > model;
73  typename std::vector<Teuchos::RCP<Stepper<Scalar> > >::const_iterator
74  subStepperIter = subStepperList_.begin();
75  for (; subStepperIter < subStepperList_.end(); subStepperIter++) {
76  model = (*subStepperIter)->getModel();
77  if (model != Teuchos::null) break;
78  }
79  if ( model == Teuchos::null ) {
80  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
81  Teuchos::OSTab ostab(out,1,"StepperOperatorSplit::getModel()");
82  *out << "Warning -- StepperOperatorSplit::getModel() "
83  << "Could not find a valid model! Returning null!" << std::endl;
84  }
85 
86  return model;
87 }
88 
89 template<class Scalar>
90 void StepperOperatorSplit<Scalar>::setSolver(std::string solverName)
91 {
92  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
93  Teuchos::OSTab ostab(out,1,"StepperOperatorSplit::setSolver()");
94  *out << "Warning -- No solver to set for StepperOperatorSplit, "
95  << "because it is a Stepper of Steppers.\n" << std::endl;
96  return;
97 }
98 
99 template<class Scalar>
101  Teuchos::RCP<Teuchos::ParameterList> solverPL)
102 {
103  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
104  Teuchos::OSTab ostab(out,1,"StepperOperatorSplit::setSolver()");
105  *out << "Warning -- No solver to set for StepperOperatorSplit "
106  << "because it is a Stepper of Steppers.\n" << std::endl;
107  return;
108 }
109 
110 template<class Scalar>
112  Teuchos::RCP<Thyra::NonlinearSolverBase<Scalar> > solver)
113 {
114  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
115  Teuchos::OSTab ostab(out,1,"StepperOperatorSplit::setSolver()");
116  *out << "Warning -- No solver to set for StepperOperatorSplit "
117  << "because it is a Stepper of Steppers.\n" << std::endl;
118  return;
119 }
120 
121 template<class Scalar>
123  Teuchos::RCP<StepperObserver<Scalar> > obs)
124 {
125  if (obs == Teuchos::null) {
126  // Create default observer, otherwise keep current observer.
127  if (stepperOSObserver_ == Teuchos::null) {
128  stepperOSObserver_ =
129  Teuchos::rcp(new StepperOperatorSplitObserver<Scalar>());
130  }
131  } else {
132  stepperOSObserver_ =
133  Teuchos::rcp_dynamic_cast<StepperOperatorSplitObserver<Scalar> > (obs);
134  }
135 }
136 
137 template<class Scalar>
139  std::vector<Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> > > appModels)
140 {
141  using Teuchos::RCP;
142  using Teuchos::ParameterList;
143 
144  // Parse Stepper List String
145  std::vector<std::string> stepperListStr;
146  stepperListStr.clear();
147  std::string str = stepperPL_->get<std::string>("Stepper List");
148  std::string delimiters(",");
149  // Skip delimiters at the beginning
150  std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
151  // Find the first delimiter
152  std::string::size_type pos = str.find_first_of(delimiters, lastPos);
153  while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
154  std::string token = str.substr(lastPos,pos-lastPos);
155  // Strip single quotes
156  std::string::size_type beg = token.find_first_of("'") + 1;
157  std::string::size_type end = token.find_last_of ("'");
158  stepperListStr.push_back(token.substr(beg,end-beg));
159 
160  lastPos = str.find_first_not_of(delimiters, pos); // Skip delimiters
161  pos = str.find_first_of(delimiters, lastPos); // Find next delimiter
162  }
163 
164  TEUCHOS_TEST_FOR_EXCEPTION(stepperListStr.size() != appModels.size(),
165  std::logic_error, "Error - Number of models and Steppers do not match!\n"
166  << " There are " << appModels.size() << " models.\n"
167  << " There are " << stepperListStr.size() << " steppers.\n"
168  << " " << str << "\n");
169 
170  RCP<StepperFactory<Scalar> > sf = Teuchos::rcp(new StepperFactory<Scalar>());
171  typename
172  std::vector<RCP<const Thyra::ModelEvaluator<Scalar> > >::iterator
173  aMI = appModels.begin();
174  typename std::vector<std::string>::iterator sLSI = stepperListStr.begin();
175 
176  for (; aMI<appModels.end() || sLSI<stepperListStr.end(); aMI++, sLSI++) {
177  RCP<ParameterList> subStepperPL = Teuchos::sublist(stepperPL_,*sLSI,true);
178  subStepperList_.push_back(sf->createStepper(*aMI, subStepperPL));
179  }
180 }
181 
182 template<class Scalar>
184 {
185  TEUCHOS_TEST_FOR_EXCEPTION( subStepperList_.size() == 0, std::logic_error,
186  "Error - Need to set the subSteppers, createSubSteppers(), before calling "
187  "StepperOperatorSplit::initialize()\n");
188 
189  OpSpSolnHistory_ = rcp(new SolutionHistory<Scalar>());
190  OpSpSolnHistory_->setStorageLimit(2);
191  OpSpSolnHistory_->setStorageType(Tempus::STORAGE_TYPE_STATIC);
192 
193  if (tempState_ == Teuchos::null) {
194  Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >model = this->getModel();
195  TEUCHOS_TEST_FOR_EXCEPTION( model == Teuchos::null, std::logic_error,
196  "Error - StepperOperatorSplit::initialize() Could not find "
197  "a valid model!\n");
198  tempState_ = rcp(new SolutionState<Scalar>(
199  model, this->getDefaultStepperState()));
200  }
201  this->setParameterList(this->stepperPL_);
202  this->setObserver();
203 
204  if (!isOneStepMethod() ) {
205  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
206  Teuchos::OSTab ostab(out,1,"StepperOperatorSplit::initialize()");
207  typename std::vector<Teuchos::RCP<Stepper<Scalar> > >::const_iterator
208  subStepperIter = subStepperList_.begin();
209  for (; subStepperIter < subStepperList_.end(); subStepperIter++) {
210  *out << "SubStepper, " << (*subStepperIter)->description()
211  << ", isOneStepMethod = " << (*subStepperIter)->isOneStepMethod()
212  << std::endl;
213  }
214  TEUCHOS_TEST_FOR_EXCEPTION(!isOneStepMethod(), std::logic_error,
215  "Error - OperatorSplit only works for one-step methods!\n");
216  }
217 }
218 
219 template<class Scalar>
221  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
222 {
223  using Teuchos::RCP;
224 
225  TEMPUS_FUNC_TIME_MONITOR("Tempus::StepperOperatorSplit::takeStep()");
226  {
227  TEUCHOS_TEST_FOR_EXCEPTION(solutionHistory->getNumStates() < 2,
228  std::logic_error,
229  "Error - StepperOperatorSplit<Scalar>::takeStep(...)\n"
230  "Need at least two SolutionStates for OperatorSplit.\n"
231  " Number of States = " << solutionHistory->getNumStates() << "\n"
232  "Try setting in \"Solution History\" \"Storage Type\" = \"Undo\"\n"
233  " or \"Storage Type\" = \"Static\" and \"Storage Limit\" = \"2\"\n");
234 
235  stepperOSObserver_->observeBeginTakeStep(solutionHistory, *this);
236 
237  RCP<SolutionState<Scalar> > workingState=solutionHistory->getWorkingState();
238 
239  // Create OperatorSplit SolutionHistory to pass to subSteppers.
240  tempState_->copy(solutionHistory->getCurrentState());
241  OpSpSolnHistory_->clear();
242  OpSpSolnHistory_->addState(tempState_);
243  OpSpSolnHistory_->addWorkingState(workingState, false);
244 
245  RCP<SolutionState<Scalar> > currentSubState =
246  OpSpSolnHistory_->getCurrentState();
247  RCP<SolutionState<Scalar> > workingSubState =
248  OpSpSolnHistory_->getWorkingState();
249 
250  bool pass = true;
251  typename std::vector<Teuchos::RCP<Stepper<Scalar> > >::iterator
252  subStepperIter = subStepperList_.begin();
253  for (; subStepperIter < subStepperList_.end() and pass; subStepperIter++) {
254  int index = subStepperIter - subStepperList_.begin();
255 
256  stepperOSObserver_->observeBeforeStepper(index, solutionHistory, *this);
257 
258  (*subStepperIter)->takeStep(OpSpSolnHistory_);
259 
260  stepperOSObserver_->observeAfterStepper(index, solutionHistory, *this);
261 
262  if (workingSubState->getSolutionStatus() == Status::FAILED) {
263  pass = false;
264  Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
265  Teuchos::OSTab ostab(out,1,"StepperOperatorSplit::takeStep()");
266  *out << "SubStepper, " << (*subStepperIter)->description()
267  << ", failed!" << std::endl;
268  break;
269  }
270 
271  // "promote" workingSubState
272  currentSubState = OpSpSolnHistory_->getCurrentState();
273  currentSubState->copySolutionData(workingSubState);
274  }
275 
276  if (pass == true) workingState->setSolutionStatus(Status::PASSED);
277  else workingState->setSolutionStatus(Status::FAILED);
278  workingState->setOrder(this->getOrder());
279  OpSpSolnHistory_->clear();
280  stepperOSObserver_->observeEndTakeStep(solutionHistory, *this);
281  }
282  return;
283 }
284 
285 
286 /** \brief Provide a StepperState to the SolutionState.
287  * This Stepper does not have any special state data,
288  * so just provide the base class StepperState with the
289  * Stepper description. This can be checked to ensure
290  * that the input StepperState can be used by this Stepper.
291  */
292 template<class Scalar>
293 Teuchos::RCP<Tempus::StepperState<Scalar> > StepperOperatorSplit<Scalar>::
295 {
296  Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
297  rcp(new StepperState<Scalar>(description()));
298  return stepperState;
299 }
300 
301 
302 template<class Scalar>
304 {
305  std::string name = "Operator Split";
306  return(name);
307 }
308 
309 
310 template<class Scalar>
312  Teuchos::FancyOStream &out,
313  const Teuchos::EVerbosityLevel verbLevel) const
314 {
315  out << description() << "::describe:" << std::endl;
316 }
317 
318 
319 template <class Scalar>
321  const Teuchos::RCP<Teuchos::ParameterList> & pList)
322 {
323  Teuchos::RCP<Teuchos::ParameterList> stepperPL = this->stepperPL_;
324  if (pList == Teuchos::null) {
325  // Create default parameters if null, otherwise keep current parameters.
326  if (stepperPL == Teuchos::null) stepperPL = this->getDefaultParameters();
327  } else {
328  stepperPL = pList;
329  }
330  // Can not validate because of optional Parameters, e.g. operators.
331  //stepperPL->validateParametersAndSetDefaults(*this->getValidParameters());
332 
333  std::string stepperType = stepperPL->get<std::string>("Stepper Type");
334  TEUCHOS_TEST_FOR_EXCEPTION( stepperType != "Operator Split", std::logic_error,
335  "Error - Stepper Type is not 'Operator Split'!\n"
336  << " Stepper Type = "<< pList->get<std::string>("Stepper Type") << "\n");
337 
338  this->stepperPL_ = stepperPL;
339 }
340 
341 
342 template<class Scalar>
343 Teuchos::RCP<const Teuchos::ParameterList>
345 {
346  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
347  pl->setName("Default Stepper - " + this->description());
348  pl->set<std::string>("Stepper Type", "Operator Split",
349  "'Stepper Type' must be 'Operator Split'.");
350  pl->set<int> ("Minimum Order", 1,
351  "Minimum Operator-split order. (default = 1)\n");
352  pl->set<int> ("Order", 1,
353  "Operator-split order. (default = 1)\n");
354  pl->set<int> ("Maximum Order", 1,
355  "Maximum Operator-split order. (default = 1)\n");
356 
357  pl->set<std::string>("Stepper List", "",
358  "Comma deliminated list of single quoted Steppers, e.g., \"'Operator 1', 'Operator 2'\".");
359 
360  return pl;
361 }
362 
363 
364 template<class Scalar>
365 Teuchos::RCP<Teuchos::ParameterList>
367 {
368  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
369  *pl = *(this->getValidParameters());
370  return pl;
371 }
372 
373 
374 template <class Scalar>
375 Teuchos::RCP<Teuchos::ParameterList>
377 {
378  return(stepperPL_);
379 }
380 
381 
382 template <class Scalar>
383 Teuchos::RCP<Teuchos::ParameterList>
385 {
386  Teuchos::RCP<Teuchos::ParameterList> temp_plist = stepperPL_;
387  stepperPL_ = Teuchos::null;
388  return(temp_plist);
389 }
390 
391 
392 } // namespace Tempus
393 #endif // Tempus_StepperOperatorSplit_impl_hpp
Tempus::StepperState
StepperState is a simple class to hold state information about the stepper.
Definition: Tempus_StepperState.hpp:36
Tempus::StepperOperatorSplitObserver
StepperOperatorSplitObserver class for StepperOperatorSplit.
Definition: Tempus_StepperOperatorSplitObserver.hpp:35
Tempus::StepperOperatorSplit::getDefaultParameters
Teuchos::RCP< Teuchos::ParameterList > getDefaultParameters() const
Definition: Tempus_StepperOperatorSplit_impl.hpp:366
Tempus::solutionHistory
Teuchos::RCP< SolutionHistory< Scalar > > solutionHistory(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
Nonmember constructor.
Definition: Tempus_SolutionHistory_impl.hpp:504
Tempus::STORAGE_TYPE_STATIC
Keep a fix number of states.
Definition: Tempus_SolutionHistory_decl.hpp:30
Tempus
Definition: Tempus_AdjointAuxSensitivityModelEvaluator_decl.hpp:20
Tempus::StepperOperatorSplit::setSolver
virtual void setSolver(std::string solverName)
Set solver via ParameterList solver name.
Definition: Tempus_StepperOperatorSplit_impl.hpp:90
Tempus::StepperOperatorSplit::getModel
virtual Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > getModel()
Definition: Tempus_StepperOperatorSplit_impl.hpp:70
Tempus::StepperOperatorSplit::describe
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Definition: Tempus_StepperOperatorSplit_impl.hpp:311
Tempus::StepperOperatorSplit::setModel
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel)
Definition: Tempus_StepperOperatorSplit_impl.hpp:43
Tempus::StepperOperatorSplit::initialize
virtual void initialize()
Initialize during construction and after changing input parameters.
Definition: Tempus_StepperOperatorSplit_impl.hpp:183
Tempus::StepperOperatorSplit::setNonConstModel
virtual void setNonConstModel(const Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > &appModel)
Definition: Tempus_StepperOperatorSplit_impl.hpp:56
Tempus::StepperObserver
StepperObserver class for Stepper class.
Definition: Tempus_StepperObserver.hpp:38
Tempus::StepperOperatorSplit::createSubSteppers
virtual void createSubSteppers(std::vector< Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > > appModels)
Take models and ParameterList and create subSteppers.
Definition: Tempus_StepperOperatorSplit_impl.hpp:138
Tempus::SolutionState
Solution state for integrators and steppers. SolutionState contains the metadata for solutions and th...
Definition: Tempus_SolutionState_decl.hpp:56
Tempus::StepperOperatorSplit::getNonconstParameterList
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
Definition: Tempus_StepperOperatorSplit_impl.hpp:376
Tempus::StepperOperatorSplit::StepperOperatorSplit
StepperOperatorSplit()
Constructor which is setup except for models and steppers (i.e., addStepper()), and an initialize() b...
Definition: Tempus_StepperOperatorSplit_impl.hpp:32
Tempus::StepperOperatorSplit::setObserver
virtual void setObserver(Teuchos::RCP< StepperObserver< Scalar > > obs=Teuchos::null)
Set Observer.
Definition: Tempus_StepperOperatorSplit_impl.hpp:122
Tempus::StepperOperatorSplit::getValidParameters
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Definition: Tempus_StepperOperatorSplit_impl.hpp:344
Tempus::StepperOperatorSplit::unsetParameterList
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
Definition: Tempus_StepperOperatorSplit_impl.hpp:384
Tempus::PASSED
Definition: Tempus_Types.hpp:17
Tempus::SolutionHistory
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Definition: Tempus_Integrator.hpp:25
Tempus::StepperOperatorSplit::getDefaultStepperState
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Get a default (initial) StepperState.
Definition: Tempus_StepperOperatorSplit_impl.hpp:294
Tempus::StepperFactory
Stepper factory.
Definition: Tempus_StepperBackwardEuler_impl.hpp:22
Tempus::StepperOperatorSplit::takeStep
virtual void takeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Take the specified timestep, dt, and return true if successful.
Definition: Tempus_StepperOperatorSplit_impl.hpp:220
Tempus::FAILED
Definition: Tempus_Types.hpp:18
Tempus::StepperOperatorSplit::setParameterList
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &pl)
Definition: Tempus_StepperOperatorSplit_impl.hpp:320
Tempus_StepperFactory.hpp
Teuchos
Definition: Tempus_Integrator.hpp:19
Tempus::StepperOperatorSplit::description
virtual std::string description() const
Definition: Tempus_StepperOperatorSplit_impl.hpp:303