9 #ifndef Tempus_StepperOperatorSplit_impl_hpp
10 #define Tempus_StepperOperatorSplit_impl_hpp
12 #include "Tempus_StepperFactory.hpp"
17 template <
class Scalar>
20 this->setStepperName(
"Operator Split");
21 this->setStepperType(
"Operator Split");
22 this->setUseFSAL(
false);
23 this->setICConsistency(
"None");
24 this->setICConsistencyCheck(
false);
29 this->setAppAction(Teuchos::null);
32 OpSpSolnHistory_->setStorageLimit(2);
36 template <
class Scalar>
40 std::string ICConsistency,
bool ICConsistencyCheck,
int order,
int orderMin,
45 this->setStepperName(
"Operator Split");
46 this->setStepperType(
"Operator Split");
47 this->setUseFSAL(useFSAL);
48 this->setICConsistency(ICConsistency);
49 this->setICConsistencyCheck(ICConsistencyCheck);
51 this->setSubStepperList(subStepperList);
52 this->setOrder(order);
53 this->setOrderMin(orderMin);
54 this->setOrderMax(orderMax);
56 this->setAppAction(stepperOSAppAction);
58 OpSpSolnHistory_->setStorageLimit(2);
61 if (!(appModels.empty())) {
62 this->setModels(appModels);
67 template <
class Scalar>
71 if (appModel != Teuchos::null) {
74 *out <<
"Warning -- No ModelEvaluator to set for StepperOperatorSplit, "
75 <<
"because it is a Stepper of Steppers.\n"
80 template <
class Scalar>
85 typename std::vector<Teuchos::RCP<Stepper<Scalar> > >::const_iterator
86 subStepperIter = subStepperList_.begin();
87 for (; subStepperIter < subStepperList_.end(); subStepperIter++) {
88 model = (*subStepperIter)->getModel();
89 if (model != Teuchos::null)
break;
91 if (model == Teuchos::null) {
94 *out <<
"Warning -- StepperOperatorSplit::getModel() "
95 <<
"Could not find a valid model! Returning null!" << std::endl;
101 template <
class Scalar>
106 Teuchos::OSTab ostab(out, 1,
"StepperOperatorSplit::setSolver()");
107 *out <<
"Warning -- No solver to set for StepperOperatorSplit "
108 <<
"because it is a Stepper of Steppers.\n"
111 this->isInitialized_ =
false;
114 template <
class Scalar>
118 if (appAction == Teuchos::null) {
120 if (stepperOSAppAction_ == Teuchos::null) {
121 stepperOSAppAction_ =
126 stepperOSAppAction_ =
130 this->isInitialized_ =
false;
133 template <
class Scalar>
137 stepper->setUseFSAL(useFSAL);
138 subStepperList_.push_back(stepper);
141 template <
class Scalar>
148 subStepperList_ = subStepperList;
150 typename std::vector<Teuchos::RCP<Stepper<Scalar> > >::iterator
151 subStepperIter = subStepperList_.begin();
153 for (; subStepperIter < subStepperList_.end(); subStepperIter++) {
154 auto subStepper = *(subStepperIter);
155 bool useFSAL = subStepper->getUseFSAL();
158 Teuchos::OSTab ostab(out, 1,
"StepperOperatorSplit::setSubStepperList()");
159 *out <<
"Warning -- subStepper = '" << subStepper->getStepperType()
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"
168 this->isInitialized_ =
false;
171 template <
class Scalar>
179 subStepperList_.size() != appModels.size(), std::logic_error,
180 "Error - Number of models and Steppers do not match!\n"
181 <<
" There are " << appModels.size() <<
" models.\n"
182 <<
" There are " << subStepperList_.size() <<
" steppers.\n");
184 typename std::vector<RCP<const Thyra::ModelEvaluator<Scalar> > >::iterator
185 appModelIter = appModels.begin();
187 typename std::vector<Teuchos::RCP<Stepper<Scalar> > >::iterator
188 subStepperIter = subStepperList_.begin();
191 appModelIter < appModels.end() || subStepperIter < subStepperList_.end();
192 appModelIter++, subStepperIter++) {
193 auto appModel = *(appModelIter);
194 auto subStepper = *(subStepperIter);
195 subStepper->setModel(appModel);
198 this->isInitialized_ =
false;
201 template <
class Scalar>
204 if (tempState_ == Teuchos::null) {
207 model == Teuchos::null, std::logic_error,
208 "Error - StepperOperatorSplit::initialize() Could not find "
213 if (!isOneStepMethod()) {
215 Teuchos::OSTab ostab(out, 1,
"StepperOperatorSplit::initialize()");
216 typename std::vector<Teuchos::RCP<Stepper<Scalar> > >::const_iterator
217 subStepperIter = subStepperList_.begin();
218 for (; subStepperIter < subStepperList_.end(); subStepperIter++) {
219 *out <<
"SubStepper, " << (*subStepperIter)->getStepperType()
220 <<
", isOneStepMethod = " << (*subStepperIter)->isOneStepMethod()
224 !isOneStepMethod(), std::logic_error,
225 "Error - OperatorSplit only works for one-step methods!\n");
229 typename std::vector<Teuchos::RCP<Stepper<Scalar> > >::const_iterator
230 subStepperIter = subStepperList_.begin();
231 for (; subStepperIter < subStepperList_.end(); subStepperIter++)
232 (*subStepperIter)->initialize();
237 template <
class Scalar>
241 typename std::vector<Teuchos::RCP<Stepper<Scalar> > >::iterator
242 subStepperIter = subStepperList_.begin();
243 for (; subStepperIter < subStepperList_.end(); subStepperIter++)
244 (*subStepperIter)->setInitialConditions(solutionHistory);
247 solutionHistory->getCurrentState();
250 this->setStepperXDot(initialState->getXDot());
251 if (initialState->getXDot() == Teuchos::null)
252 this->setStepperXDot(initialState->getX()->clone_v());
255 template <
class Scalar>
259 this->checkInitialized();
263 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::StepperOperatorSplit::takeStep()");
266 solutionHistory->getNumStates() < 2, std::logic_error,
267 "Error - StepperOperatorSplit<Scalar>::takeStep(...)\n"
268 <<
"Need at least two SolutionStates for OperatorSplit.\n"
269 <<
" Number of States = " << solutionHistory->getNumStates()
270 <<
"\nTry setting in \"Solution History\" \"Storage Type\" = "
272 <<
" or \"Storage Type\" = \"Static\" and \"Storage Limit\" = "
274 RCP<StepperOperatorSplit<Scalar> > thisStepper = Teuchos::rcpFromRef(*
this);
275 stepperOSAppAction_->execute(
276 solutionHistory, thisStepper,
279 RCP<SolutionState<Scalar> > workingState =
280 solutionHistory->getWorkingState();
283 tempState_->copy(solutionHistory->getCurrentState());
284 OpSpSolnHistory_->clear();
285 OpSpSolnHistory_->addState(tempState_);
286 OpSpSolnHistory_->addWorkingState(workingState,
false);
288 RCP<SolutionState<Scalar> > currentSubState =
289 OpSpSolnHistory_->getCurrentState();
290 RCP<SolutionState<Scalar> > workingSubState =
291 OpSpSolnHistory_->getWorkingState();
294 typename std::vector<Teuchos::RCP<Stepper<Scalar> > >::iterator
295 subStepperIter = subStepperList_.begin();
296 for (; subStepperIter < subStepperList_.end() && pass; subStepperIter++) {
297 stepperOSAppAction_->execute(
298 solutionHistory, thisStepper,
300 Scalar>::ACTION_LOCATION::BEFORE_STEPPER);
302 (*subStepperIter)->takeStep(OpSpSolnHistory_);
304 stepperOSAppAction_->execute(solutionHistory, thisStepper,
306 Scalar>::ACTION_LOCATION::AFTER_STEPPER);
312 *out <<
"SubStepper, " << (*subStepperIter)->getStepperType()
313 <<
", failed!" << std::endl;
318 currentSubState = OpSpSolnHistory_->getCurrentState();
319 currentSubState->copySolutionData(workingSubState);
326 workingState->setOrder(this->getOrder());
327 workingState->computeNorms(solutionHistory->getCurrentState());
328 OpSpSolnHistory_->clear();
330 stepperOSAppAction_->execute(
331 solutionHistory, thisStepper,
343 template <
class Scalar>
352 template <
class Scalar>
360 out <<
"--- StepperOperatorSplit ---\n";
361 out <<
" subStepperList_.size() = " << subStepperList_.size() << std::endl;
362 typename std::vector<Teuchos::RCP<Stepper<Scalar> > >::const_iterator
363 subStepperIter = subStepperList_.begin();
364 for (; subStepperIter < subStepperList_.end(); subStepperIter++) {
365 out <<
" SubStepper = " << (*subStepperIter)->getStepperType()
367 out <<
" = " << (*subStepperIter)->isInitialized()
369 out <<
" = " << (*subStepperIter) << std::endl;
371 out <<
" OpSpSolnHistory_ = " << OpSpSolnHistory_ << std::endl;
372 out <<
" tempState_ = " << tempState_ << std::endl;
373 out <<
" stepperOSAppAction_ = " << stepperOSAppAction_ << std::endl;
374 out <<
" order_ = " << order_ << std::endl;
375 out <<
" orderMin_ = " << orderMin_ << std::endl;
376 out <<
" orderMax_ = " << orderMax_ << std::endl;
377 out <<
"----------------------------" << std::endl;
380 template <
class Scalar>
385 bool isValidSetup =
true;
389 if (subStepperList_.size() == 0) {
390 isValidSetup =
false;
391 out <<
"The substepper list is empty!\n";
394 typename std::vector<Teuchos::RCP<Stepper<Scalar> > >::const_iterator
395 subStepperIter = subStepperList_.begin();
397 for (; subStepperIter < subStepperList_.end(); subStepperIter++) {
398 auto subStepper = *(subStepperIter);
399 if (!subStepper->isInitialized()) {
400 isValidSetup =
false;
401 out <<
"The subStepper, " << subStepper->description()
402 <<
", is not initialized!\n";
405 if (stepperOSAppAction_ == Teuchos::null) {
406 isValidSetup =
false;
407 out <<
"The Operator-Split AppAction is not set!\n";
413 template <
class Scalar>
417 auto pl = this->getValidParametersBasic();
418 pl->template set<int>(
"Minimum Order", orderMin_,
419 "Minimum Operator-split order. (default = 1)\n");
420 pl->template set<int>(
"Order", order_,
421 "Operator-split order. (default = 1)\n");
422 pl->template set<int>(
"Maximum Order", orderMax_,
423 "Maximum Operator-split order. (default = 1)\n");
425 std::ostringstream list;
426 size_t size = subStepperList_.size();
427 for (std::size_t i = 0; i < size - 1; ++i) {
428 list <<
"'" << subStepperList_[i]->getStepperName() <<
"', ";
430 list <<
"'" << subStepperList_[size - 1]->getStepperName() <<
"'";
431 pl->template set<std::string>(
432 "Stepper List", list.str(),
433 "Comma deliminated list of single quoted Steppers, e.g., \"'Operator 1', "
436 for (std::size_t i = 0; i < size; ++i) {
437 pl->set(subStepperList_[i]->getStepperName(),
438 *(subStepperList_[i]->getValidParameters()));
444 template <
class Scalar>
449 if (stepperPL != Teuchos::null) {
454 std::vector<std::string> stepperListStr;
455 stepperListStr.clear();
456 std::string str = stepperPL->
get<std::string>(
"Stepper List");
457 std::string delimiters(
",");
459 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
461 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
462 while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
463 std::string token = str.substr(lastPos, pos - lastPos);
465 std::string::size_type beg = token.find_first_of(
"'") + 1;
466 std::string::size_type end = token.find_last_of(
"'");
467 stepperListStr.push_back(token.substr(beg, end - beg));
469 lastPos = str.find_first_not_of(delimiters, pos);
470 pos = str.find_first_of(delimiters, lastPos);
474 stepperListStr.size() != appModels.size(), std::logic_error,
475 "Error - Number of models and Steppers do not match!\n"
476 <<
" There are " << appModels.size() <<
" models.\n"
477 <<
" There are " << stepperListStr.size() <<
" steppers.\n"
478 <<
" " << str <<
"\n");
480 typename std::vector<RCP<const Thyra::ModelEvaluator<Scalar> > >::iterator
481 aMI = appModels.begin();
482 typename std::vector<std::string>::iterator sLSI = stepperListStr.begin();
484 for (; aMI < appModels.end() || sLSI < stepperListStr.end();
486 RCP<ParameterList> subStepperPL =
487 Teuchos::sublist(stepperPL, *sLSI,
true);
488 auto name = subStepperPL->name();
489 lastPos = name.rfind(
"->");
490 std::string newName = name.substr(lastPos + 2, name.length());
491 subStepperPL->setName(newName);
492 bool useFSAL = subStepperPL->template get<bool>(
"Use FSAL",
false);
494 auto subStepper = sf->createStepper(subStepperPL, *aMI);
498 Teuchos::OSTab ostab(out, 1,
"StepperFactory::createSubSteppers()");
499 *out <<
"Warning -- subStepper = '" << subStepper->getStepperType()
501 <<
" subStepper->getUseFSAL() = " << useFSAL <<
".\n"
502 <<
" subSteppers usually can not use the FSAL priniciple with\n"
503 <<
" operator splitting. Proceeding with it set to true.\n"
506 this->addStepper(subStepper, useFSAL);
513 template <
class Scalar>
520 if (pl != Teuchos::null) {
521 stepper->setStepperValues(pl);
522 stepper->setOrderMin(pl->
get<
int>(
"Minimum Order", 1));
523 stepper->setOrder(pl->
get<
int>(
"Order", 1));
524 stepper->setOrderMax(pl->
get<
int>(
"Maximum Order", 1));
527 if (!(appModels.empty())) {
528 stepper->createSubSteppers(appModels, pl);
529 stepper->initialize();
536 #endif // Tempus_StepperOperatorSplit_impl_hpp
virtual void setAppAction(Teuchos::RCP< StepperOperatorSplitAppAction< Scalar >> appAction)
T & get(const std::string &name, T def_value)
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
virtual void setSubStepperList(std::vector< Teuchos::RCP< Stepper< Scalar >>> subStepperList)
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Get a default (initial) StepperState.
virtual void initialize()
Initialize after construction and changing input parameters.
OperatorSplit stepper loops through the Stepper list.
Thyra Base interface for time steppers.
virtual void setModels(std::vector< Teuchos::RCP< const Thyra::ModelEvaluator< Scalar >>> appModels)
StepperOperatorSplit()
Default constructor.
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)
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
static RCP< FancyOStream > getDefaultOStream()
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar >> &solutionHistory)
Set the initial conditions and make them consistent.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
void createSubSteppers(std::vector< Teuchos::RCP< const Thyra::ModelEvaluator< Scalar >>> appModels, Teuchos::RCP< Teuchos::ParameterList > pl)
virtual Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > getModel() const
Default modifier for StepperOperatorSplit.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
Teuchos::RCP< SolutionState< Scalar > > createSolutionStateME(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, const Teuchos::RCP< StepperState< Scalar > > &stepperState=Teuchos::null, const Teuchos::RCP< PhysicsState< Scalar > > &physicsState=Teuchos::null)
Nonmember constructor from Thyra ModelEvaluator.
Keep a fix number of states.
Teuchos::RCP< StepperOperatorSplit< Scalar > > createStepperOperatorSplit(std::vector< Teuchos::RCP< const Thyra::ModelEvaluator< Scalar >>> appModels, Teuchos::RCP< Teuchos::ParameterList > pl)
Nonmember constructor - ModelEvaluator and ParameterList.
virtual void takeStep(const Teuchos::RCP< SolutionHistory< Scalar >> &solutionHistory)
Take the specified timestep, dt, and return true if successful.
StepperOperatorSplitAppAction class for StepperOperatorSplit.
virtual bool isValidSetup(Teuchos::FancyOStream &out) const
virtual void setSolver(Teuchos::RCP< Thyra::NonlinearSolverBase< Scalar >> solver)
virtual void initialize()
Initialize during construction and after changing input parameters.
virtual void addStepper(Teuchos::RCP< Stepper< Scalar >> stepper, bool useFSAL=false)
Add Stepper to subStepper list. In most cases, subSteppers cannot use xDotOld (thus the default)...
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar >> &appModel)