29 #ifndef Rythmos_SIMPLE_STEP_CONTROL_STRATEGY_DEF_H
30 #define Rythmos_SIMPLE_STEP_CONTROL_STRATEGY_DEF_H
32 #include "Rythmos_SimpleStepControlStrategy_decl.hpp"
33 #include "Thyra_VectorStdOps.hpp"
34 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
41 template<
class Scalar>
43 SimpleStepControlStrategy<Scalar>::initialStepSizeName_
44 =
"Initial Step Size";
46 template<
class Scalar>
48 SimpleStepControlStrategy<Scalar>::initialStepSizeDefault_
49 = std::numeric_limits<Scalar>::min();
52 template<
class Scalar>
54 SimpleStepControlStrategy<Scalar>::minStepSizeName_
57 template<
class Scalar>
59 SimpleStepControlStrategy<Scalar>::minStepSizeDefault_
60 = std::numeric_limits<Scalar>::min();
63 template<
class Scalar>
65 SimpleStepControlStrategy<Scalar>::maxStepSizeName_
68 template<
class Scalar>
70 SimpleStepControlStrategy<Scalar>::maxStepSizeDefault_
71 = std::numeric_limits<Scalar>::max();
74 template<
class Scalar>
76 SimpleStepControlStrategy<Scalar>::stepSizeDecreaseFactorName_
77 =
"Step Size Decrease Factor";
79 template<
class Scalar>
81 SimpleStepControlStrategy<Scalar>::stepSizeDecreaseFactorDefault_
85 template<
class Scalar>
87 SimpleStepControlStrategy<Scalar>::stepSizeIncreaseFactorName_
88 =
"Step Size Increase Factor";
90 template<
class Scalar>
92 SimpleStepControlStrategy<Scalar>::stepSizeIncreaseFactorDefault_
96 template<
class Scalar>
98 SimpleStepControlStrategy<Scalar>::maxStepFailuresName_
99 =
"Maximum Number of Step Failures";
101 template<
class Scalar>
103 SimpleStepControlStrategy<Scalar>::maxStepFailuresDefault_
107 template<
class Scalar>
109 SimpleStepControlStrategy<Scalar>::dxRelativeToleranceName_
110 =
"Solution Change Relative Tolerance";
112 template<
class Scalar>
114 SimpleStepControlStrategy<Scalar>::dxRelativeToleranceDefault_
118 template<
class Scalar>
120 SimpleStepControlStrategy<Scalar>::dxAbsoluteToleranceName_
121 =
"Solution Change Absolute Tolerance";
123 template<
class Scalar>
125 SimpleStepControlStrategy<Scalar>::dxAbsoluteToleranceDefault_
131 template<
class Scalar>
132 void SimpleStepControlStrategy<Scalar>::setStepControlState_(StepControlStrategyState newState)
134 if (stepControlState_ == UNINITIALIZED) {
135 TEUCHOS_TEST_FOR_EXCEPT(newState != BEFORE_FIRST_STEP);
136 }
else if (stepControlState_ == BEFORE_FIRST_STEP) {
137 TEUCHOS_TEST_FOR_EXCEPT(newState != MID_STEP);
138 }
else if (stepControlState_ == MID_STEP) {
139 TEUCHOS_TEST_FOR_EXCEPT(newState != AFTER_CORRECTION);
140 }
else if (stepControlState_ == AFTER_CORRECTION) {
141 TEUCHOS_TEST_FOR_EXCEPT(newState != READY_FOR_NEXT_STEP);
142 }
else if (stepControlState_ == READY_FOR_NEXT_STEP) {
143 TEUCHOS_TEST_FOR_EXCEPT(newState != MID_STEP);
145 stepControlState_ = newState;
148 template<
class Scalar>
149 StepControlStrategyState SimpleStepControlStrategy<Scalar>::getCurrentState()
151 return(stepControlState_);
154 template<
class Scalar>
155 SimpleStepControlStrategy<Scalar>::SimpleStepControlStrategy()
156 : stepControlState_(UNINITIALIZED),
157 initialStepSize_(initialStepSizeDefault_),
158 stepSizeType_(STEP_TYPE_VARIABLE),
159 minStepSize_(minStepSizeDefault_),
160 maxStepSize_(maxStepSizeDefault_),
161 stepSizeIncreaseFactor_(stepSizeIncreaseFactorDefault_),
162 stepSizeDecreaseFactor_(stepSizeDecreaseFactorDefault_),
164 maxStepFailures_(maxStepFailuresDefault_),
166 dxRelativeTolerance_(dxRelativeToleranceDefault_),
167 dxAbsoluteTolerance_(dxAbsoluteToleranceDefault_),
171 template<
class Scalar>
172 void SimpleStepControlStrategy<Scalar>::initialize(
173 const StepperBase<Scalar>& )
179 RCP<Teuchos::FancyOStream> out = this->getOStream();
180 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
181 const bool doTrace = (as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH));
182 Teuchos::OSTab ostab(out,1,
"initialize");
185 *out <<
"\nEntering " << this->Teuchos::Describable::description()
186 <<
"::initialize()...\n";
189 setStepControlState_(BEFORE_FIRST_STEP);
192 *out <<
"\nLeaving " << this->Teuchos::Describable::description()
193 <<
"::initialize()...\n";
197 template<
class Scalar>
198 void SimpleStepControlStrategy<Scalar>::setRequestedStepSize(
199 const StepperBase<Scalar>& stepper,
200 const Scalar& stepSize,
201 const StepSizeType& stepSizeType)
203 typedef Teuchos::ScalarTraits<Scalar> ST;
204 TEUCHOS_TEST_FOR_EXCEPTION(
205 !((stepControlState_ == UNINITIALIZED) ||
206 (stepControlState_ == BEFORE_FIRST_STEP) ||
207 (stepControlState_ == READY_FOR_NEXT_STEP) ||
208 (stepControlState_ == MID_STEP)), std::logic_error,
209 "Error: Invalid state (stepControlState_=" << toString(stepControlState_)
210 <<
") for SimpleStepControlStrategy<Scalar>::setRequestedStepSize()\n");
212 TEUCHOS_TEST_FOR_EXCEPTION(
213 ((stepSizeType == STEP_TYPE_FIXED) && (stepSize == ST::zero())),
214 std::logic_error,
"Error, step size type == STEP_TYPE_FIXED, "
215 "but requested step size == 0!\n");
217 TEUCHOS_TEST_FOR_EXCEPTION(
218 ((stepSizeType == STEP_TYPE_FIXED) && (stepSize < minStepSize_)),
219 std::logic_error,
"Error, step size type == STEP_TYPE_FIXED, "
220 "and (stepSize="<<stepSize<<
") < (minStepSize="<<minStepSize_<<
")!\n");
222 TEUCHOS_TEST_FOR_EXCEPTION(
223 ((stepSizeType == STEP_TYPE_FIXED) && (stepSize > maxStepSize_)),
224 std::logic_error,
"Error, step size type == STEP_TYPE_FIXED, "
225 "and (stepSize="<<stepSize<<
") > (maxStepSize="<<maxStepSize_<<
")!\n");
227 if (stepControlState_ == UNINITIALIZED) initialize(stepper);
228 requestedStepSize_ = stepSize;
229 stepSizeType_ = stepSizeType;
232 template<
class Scalar>
233 void SimpleStepControlStrategy<Scalar>::nextStepSize(
234 const StepperBase<Scalar>& , Scalar* stepSize,
235 StepSizeType* stepSizeType,
int* )
237 TEUCHOS_TEST_FOR_EXCEPTION(!((stepControlState_ == BEFORE_FIRST_STEP) ||
238 (stepControlState_ == MID_STEP) ||
239 (stepControlState_ == READY_FOR_NEXT_STEP) ),
241 "Error: Invalid state (stepControlState_=" << toString(stepControlState_)
242 <<
") for SimpleStepControlStrategy<Scalar>::nextStepSize()\n");
244 if (stepControlState_ == BEFORE_FIRST_STEP) {
245 if (initialStepSize_ == initialStepSizeDefault_)
246 initialStepSize_ = requestedStepSize_;
247 nextStepSize_ = initialStepSize_;
250 stepSizeType_ = *stepSizeType;
251 if (stepSizeType_ == STEP_TYPE_FIXED)
252 currentStepSize_ = requestedStepSize_;
254 currentStepSize_ = nextStepSize_;
257 currentStepSize_ = std::min(requestedStepSize_, currentStepSize_);
259 *stepSize = currentStepSize_;
260 setStepControlState_(MID_STEP);
263 template<
class Scalar>
264 void SimpleStepControlStrategy<Scalar>::setCorrection(
265 const StepperBase<Scalar>&
266 ,
const RCP<
const Thyra::VectorBase<Scalar> >& soln
267 ,
const RCP<
const Thyra::VectorBase<Scalar> >& dx
270 TEUCHOS_TEST_FOR_EXCEPTION(stepControlState_ != MID_STEP, std::logic_error,
271 "Error: Invalid state (stepControlState_=" << toString(stepControlState_)
272 <<
") for SimpleStepControlStrategy<Scalar>::setCorrection()\n");
275 solveStatus_ = solveStatus;
276 setStepControlState_(AFTER_CORRECTION);
279 template<
class Scalar>
280 bool SimpleStepControlStrategy<Scalar>::acceptStep(
281 const StepperBase<Scalar>& , Scalar* )
283 TEUCHOS_TEST_FOR_EXCEPTION(stepControlState_ != AFTER_CORRECTION,
285 "Error: Invalid state (stepControlState_=" << toString(stepControlState_)
286 <<
") for SimpleStepControlStrategy<Scalar>::completeStep()\n");
288 if (solveStatus_ < 0 )
291 bool return_status =
true;
292 Scalar maxAbs_x = std::max(Thyra::max(*x_),-Thyra::min(*x_));
293 Scalar maxAbs_dx = std::max(Thyra::max(*dx_),-Thyra::min(*dx_));
294 Scalar dx_tolerance = dxRelativeTolerance_ * maxAbs_x + dxAbsoluteTolerance_;
295 if (maxAbs_dx > dx_tolerance) return_status =
false;
297 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
298 if ( Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
299 RCP<Teuchos::FancyOStream> out = this->getOStream();
300 Teuchos::OSTab ostab(out,1,
"acceptStep");
301 *out <<
" max |*x_| = " << maxAbs_x <<
"\n"
302 <<
" dx_tolerance = " << dx_tolerance <<
"\n"
303 <<
" max |*dx_| = " << maxAbs_dx <<
"\n";
306 return(return_status);
309 template<
class Scalar>
310 AttemptedStepStatusFlag SimpleStepControlStrategy<Scalar>::rejectStep(
311 const StepperBase<Scalar>& )
313 TEUCHOS_TEST_FOR_EXCEPTION(stepControlState_ != AFTER_CORRECTION,
315 "Error: Invalid state (stepControlState_=" << toString(stepControlState_)
316 <<
") for SimpleStepControlStrategy<Scalar>::completeStep()\n");
318 setStepControlState_(READY_FOR_NEXT_STEP);
322 RCP<Teuchos::FancyOStream> out = this->getOStream();
323 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
324 Teuchos::OSTab ostab(out,1,
"rejectStep");
327 if ( as<int>(verbLevel) != as<int>(Teuchos::VERB_NONE) )
328 *out <<
"numStepFailures_ = " << numStepFailures_ <<
"\n";
329 if (numStepFailures_ > maxStepFailures_) {
330 *out <<
"Rythmos_SimpleStepControlStrategy::rejectStep(...): "
331 <<
"Error: Too many step failures "
332 <<
"(numStepFailures="<<numStepFailures_
333 <<
") > (maxStepFailures="<<maxStepFailures_<<
")\n";
334 return (REP_ERR_FAIL);
338 if (stepSizeType_ == STEP_TYPE_VARIABLE) {
339 nextStepSize_ *= stepSizeDecreaseFactor_;
340 if ( as<int>(verbLevel) != as<int>(Teuchos::VERB_NONE) ) {
341 *out <<
"Rythmos_SimpleStepControl::rejectStep(...): "
342 <<
" Step failure. Reducing step size to "<< nextStepSize_ <<
".\n";
345 if ( as<int>(verbLevel) != as<int>(Teuchos::VERB_NONE) ) {
346 *out <<
"Rythmos_SimpleStepControl::rejectStep(...): "
347 <<
"Error: Step failure with fixed step size.\n";
349 return (REP_ERR_FAIL);
352 nextStepSize_ = std::max(nextStepSize_, minStepSize_);
353 nextStepSize_ = std::min(nextStepSize_, maxStepSize_);
355 AttemptedStepStatusFlag return_status = PREDICT_AGAIN;
357 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
358 *out <<
"nextStepSize_ = " << nextStepSize_ <<
"\n";
361 return(return_status);
364 template<
class Scalar>
365 void SimpleStepControlStrategy<Scalar>::completeStep(
366 const StepperBase<Scalar>& )
368 TEUCHOS_TEST_FOR_EXCEPTION(stepControlState_ != AFTER_CORRECTION,
370 "Error: Invalid state (stepControlState_=" << toString(stepControlState_)
371 <<
") for SimpleStepControlStrategy<Scalar>::completeStep()\n");
374 if (stepSizeType_ == STEP_TYPE_VARIABLE) {
376 if (numStepFailures_ == 0) {
377 nextStepSize_ *= stepSizeIncreaseFactor_;
380 nextStepSize_ = currentStepSize_;
381 numStepFailures_ = std::max(numStepFailures_-1,0);
384 nextStepSize_ = std::max(nextStepSize_, minStepSize_);
385 nextStepSize_ = std::min(nextStepSize_, maxStepSize_);
387 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
388 if ( Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
389 RCP<Teuchos::FancyOStream> out = this->getOStream();
390 Teuchos::OSTab ostab(out,1,
"completeStep_");
391 *out <<
"nextStepSize_ = " << nextStepSize_ <<
"\n";
392 *out <<
"numStepFailures_ = " << numStepFailures_ <<
"\n";
394 setStepControlState_(READY_FOR_NEXT_STEP);
397 template<
class Scalar>
398 void SimpleStepControlStrategy<Scalar>::describe(
399 Teuchos::FancyOStream &out,
400 const Teuchos::EVerbosityLevel verbLevel
406 if ( (as<int>(verbLevel) == as<int>(Teuchos::VERB_DEFAULT) ) ||
407 (as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW) ) ) {
408 out << this->description() <<
"::describe" <<
"\n";
410 if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW)) {
411 out <<
"requestedStepSize_ = " << requestedStepSize_ <<
"\n";
412 out <<
"currentStepSize_ = " << currentStepSize_ <<
"\n";
413 out <<
"nextStepSize_ = " << nextStepSize_ <<
"\n";
414 out <<
"stepSizeType_ = " << stepSizeType_ <<
"\n";
415 out <<
"numStepFailures_ = " << numStepFailures_ <<
"\n";
419 template<
class Scalar>
420 void SimpleStepControlStrategy<Scalar>::setParameterList(
421 RCP<Teuchos::ParameterList>
const& paramList)
426 TEUCHOS_TEST_FOR_EXCEPT(paramList == Teuchos::null);
427 paramList->validateParameters(*this->getValidParameters(),0);
428 parameterList_ = paramList;
429 Teuchos::readVerboseObjectSublist(&*parameterList_,
this);
431 initialStepSize_ = parameterList_->get(initialStepSizeName_,
432 initialStepSizeDefault_);
433 minStepSize_ = parameterList_->get(minStepSizeName_, minStepSizeDefault_);
434 maxStepSize_ = parameterList_->get(maxStepSizeName_, maxStepSizeDefault_);
435 TEUCHOS_TEST_FOR_EXCEPTION(
436 !(minStepSize_ <= maxStepSize_), std::logic_error,
437 "Error: (minStepSize="<<minStepSize_
438 <<
") > (maxStepSize="<<maxStepSize_<<
")\n");
439 TEUCHOS_TEST_FOR_EXCEPTION(
440 !((minStepSize_ <= initialStepSize_) && (initialStepSize_ <= maxStepSize_)),
442 "Error: Initial Step Size is not within min/max range.\n"
443 <<
" (minStepSize="<<minStepSize_
444 <<
") > (initialStepSize="<<initialStepSize_<<
") or \n"
445 <<
" (maxStepSize="<<maxStepSize_
446 <<
") < (initialStepSize="<<initialStepSize_<<
")\n");
448 stepSizeIncreaseFactor_ = parameterList_->get(stepSizeIncreaseFactorName_,
449 stepSizeIncreaseFactorDefault_);
450 TEUCHOS_TEST_FOR_EXCEPTION(
451 !(stepSizeIncreaseFactor_ > 0.0), std::logic_error,
452 "Error: (stepSizeIncreaseFactor="<<stepSizeIncreaseFactor_<<
") <= 0.0\n");
454 stepSizeDecreaseFactor_ = parameterList_->get(stepSizeDecreaseFactorName_,
455 stepSizeDecreaseFactorDefault_);
456 TEUCHOS_TEST_FOR_EXCEPTION(
457 !(stepSizeDecreaseFactor_ > 0.0), std::logic_error,
458 "Error: (stepSizeDecreaseFactor="<<stepSizeDecreaseFactor_<<
") <= 0.0\n");
460 maxStepFailures_ = parameterList_->get(maxStepFailuresName_,
461 maxStepFailuresDefault_);
462 TEUCHOS_TEST_FOR_EXCEPTION(
463 !(maxStepFailures_ >= 0), std::logic_error,
464 "Error: (maxStepFailures="<<maxStepFailures_<<
") < 0\n");
466 dxRelativeTolerance_ = parameterList_->get(dxRelativeToleranceName_,
467 dxRelativeToleranceDefault_);
468 TEUCHOS_TEST_FOR_EXCEPTION(
469 !(dxRelativeTolerance_ >= 0.0), std::logic_error,
470 "Error: (dxRelativeTolerance="<<dxRelativeTolerance_<<
") < 0.0\n");
472 dxAbsoluteTolerance_ = parameterList_->get(dxAbsoluteToleranceName_,
473 dxAbsoluteToleranceDefault_);
474 TEUCHOS_TEST_FOR_EXCEPTION(
475 !(dxAbsoluteTolerance_ >= 0.0), std::logic_error,
476 "Error: (dxAbsoluteTolerance="<<dxAbsoluteTolerance_<<
") < 0.0\n");
478 RCP<Teuchos::FancyOStream> out = this->getOStream();
479 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
480 Teuchos::OSTab ostab(out,1,
"setParameterList");
483 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
484 *out <<
"minStepSize_ = " << minStepSize_ <<
"\n";
485 *out <<
"maxStepSize_ = " << maxStepSize_ <<
"\n";
486 *out <<
"stepSizeIncreaseFactor_ = " << stepSizeIncreaseFactor_<<
"\n";
487 *out <<
"stepSizeDecreaseFactor_ = " << stepSizeDecreaseFactor_<<
"\n";
488 *out <<
"maxStepFailures_ = " << maxStepFailures_ <<
"\n";
489 *out <<
"dxRelativeTolerance_ = " << dxRelativeTolerance_ <<
"\n";
490 *out <<
"dxAbsoluteTolerance_ = " << dxAbsoluteTolerance_ <<
"\n";
494 template<
class Scalar>
495 RCP<const Teuchos::ParameterList>
496 SimpleStepControlStrategy<Scalar>::getValidParameters()
const
498 static RCP<Teuchos::ParameterList> validPL;
499 if (is_null(validPL)) {
500 RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
502 pl->set(initialStepSizeName_,initialStepSizeDefault_,
"Initial step size.");
503 pl->set(minStepSizeName_, minStepSizeDefault_,
"Minimum step size.");
504 pl->set(maxStepSizeName_, maxStepSizeDefault_,
"Maximum step size.");
505 pl->set(stepSizeIncreaseFactorName_, stepSizeIncreaseFactorDefault_,
506 "Factor used to increase the step size after a successful step.");
507 pl->set(stepSizeDecreaseFactorName_, stepSizeDecreaseFactorDefault_,
508 "Factor used to decrease the step size after a step failure.");
509 pl->set(maxStepFailuresName_, maxStepFailuresDefault_,
510 "The maximum number of step failures before exiting with an error. "
511 "The number of failure steps are carried between successful steps.");
512 pl->set(dxRelativeToleranceName_, dxRelativeToleranceDefault_,
513 "The allowable relative change in the solution for each step to "
514 "pass. The stepper solution status is also used to determine "
516 pl->set(dxAbsoluteToleranceName_, dxAbsoluteToleranceDefault_,
517 "The allowable absolute change in the solution for each step to "
518 "pass. The stepper solution status is also used to determine "
521 Teuchos::setupVerboseObjectSublist(&*pl);
527 template<
class Scalar>
528 RCP<Teuchos::ParameterList>
529 SimpleStepControlStrategy<Scalar>::unsetParameterList()
531 RCP<Teuchos::ParameterList> temp_param_list = parameterList_;
532 parameterList_ = Teuchos::null;
533 return(temp_param_list);
536 template<
class Scalar>
537 RCP<Teuchos::ParameterList>
538 SimpleStepControlStrategy<Scalar>::getNonconstParameterList()
540 return(parameterList_);
543 template<
class Scalar>
544 void SimpleStepControlStrategy<Scalar>::setStepControlData(
const StepperBase<Scalar>& stepper)
546 if (stepControlState_ == UNINITIALIZED) initialize(stepper);
549 template<
class Scalar>
550 bool SimpleStepControlStrategy<Scalar>::supportsCloning()
const
556 template<
class Scalar>
557 RCP<StepControlStrategyBase<Scalar> >
558 SimpleStepControlStrategy<Scalar>::cloneStepControlStrategyAlgorithm()
const
561 RCP<SimpleStepControlStrategy<Scalar> >
562 stepControl = rcp(
new SimpleStepControlStrategy<Scalar>());
564 if (!is_null(parameterList_)) {
565 stepControl->setParameterList(parameterList_);
571 template<
class Scalar>
572 int SimpleStepControlStrategy<Scalar>::getMaxOrder()
const
574 TEUCHOS_TEST_FOR_EXCEPTION(
575 stepControlState_ == UNINITIALIZED, std::logic_error,
576 "Error, attempting to call getMaxOrder before initialization!\n"
587 #define RYTHMOS_SIMPLE_STEP_CONTROL_STRATEGY_INSTANT(SCALAR) \
588 template class SimpleStepControlStrategy< SCALAR >;
592 #endif // Rythmos_SIMPLE_STEP_CONTROL_STRATEGY_DEF_H