29 #ifndef Rythmos_IMPLICITBDF_STEPPER_STEP_CONTROL_DEF_H
30 #define Rythmos_IMPLICITBDF_STEPPER_STEP_CONTROL_DEF_H
34 #pragma clang system_header
37 #include "Rythmos_ImplicitBDFStepperStepControl_decl.hpp"
38 #include "Rythmos_ImplicitBDFStepper.hpp"
39 #include "Rythmos_ImplicitBDFStepperErrWtVecCalc.hpp"
43 template<
class Scalar>
44 void ImplicitBDFStepperStepControl<Scalar>::setStepControlState_(StepControlStrategyState newState)
46 if (stepControlState_ == UNINITIALIZED) {
47 TEUCHOS_TEST_FOR_EXCEPT(newState != BEFORE_FIRST_STEP);
48 }
else if (stepControlState_ == BEFORE_FIRST_STEP) {
49 TEUCHOS_TEST_FOR_EXCEPT(newState != MID_STEP);
50 }
else if (stepControlState_ == MID_STEP) {
51 TEUCHOS_TEST_FOR_EXCEPT(newState != AFTER_CORRECTION);
52 }
else if (stepControlState_ == AFTER_CORRECTION) {
53 TEUCHOS_TEST_FOR_EXCEPT(newState != READY_FOR_NEXT_STEP);
54 checkReduceOrderCalled_ =
false;
55 }
else if (stepControlState_ == READY_FOR_NEXT_STEP) {
56 TEUCHOS_TEST_FOR_EXCEPT(newState != MID_STEP);
58 stepControlState_ = newState;
61 template<
class Scalar>
62 StepControlStrategyState ImplicitBDFStepperStepControl<Scalar>::getCurrentState()
64 return(stepControlState_);
67 template<
class Scalar>
68 void ImplicitBDFStepperStepControl<Scalar>::updateCoeffs_()
70 TEUCHOS_TEST_FOR_EXCEPT(!((stepControlState_ == BEFORE_FIRST_STEP) || (stepControlState_ == READY_FOR_NEXT_STEP)));
72 typedef Teuchos::ScalarTraits<Scalar> ST;
79 if ((hh_ != usedStep_) || (currentOrder_ != usedOrder_)) {
82 nscsco_ = std::min(nscsco_+1,usedOrder_+2);
83 if (currentOrder_+1 >= nscsco_) {
84 alpha_[0] = ST::one();
86 sigma_[0] = ST::one();
87 gamma_[0] = ST::zero();
88 for (
int i=1;i<=currentOrder_;++i) {
89 Scalar temp2 = psi_[i-1];
92 alpha_[i] = hh_/temp1;
93 sigma_[i] = Scalar(i+1)*sigma_[i-1]*alpha_[i];
94 gamma_[i] = gamma_[i-1]+alpha_[i-1]/hh_;
96 psi_[currentOrder_] = temp1;
97 alpha_s_ = ST::zero();
98 alpha_0_ = ST::zero();
99 for (
int i=0;i<currentOrder_;++i) {
100 alpha_s_ = alpha_s_ - Scalar(ST::one()/(i+ST::one()));
101 alpha_0_ = alpha_0_ - alpha_[i];
104 ck_ = std::abs(alpha_[currentOrder_]+alpha_s_-alpha_0_);
105 ck_ = std::max(ck_,alpha_[currentOrder_]);
107 RCP<Teuchos::FancyOStream> out = this->getOStream();
108 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
109 Teuchos::OSTab ostab(out,1,
"updateCoeffs_");
110 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
111 for (
int i=0;i<=maxOrder_;++i) {
112 *out <<
"alpha_[" << i <<
"] = " << alpha_[i] << std::endl;
113 *out <<
"sigma_[" << i <<
"] = " << sigma_[i] << std::endl;
114 *out <<
"gamma_[" << i <<
"] = " << gamma_[i] << std::endl;
115 *out <<
"psi_[" << i <<
"] = " << psi_[i] << std::endl;
116 *out <<
"alpha_s_ = " << alpha_s_ << std::endl;
117 *out <<
"alpha_0_ = " << alpha_0_ << std::endl;
118 *out <<
"cj_ = " << cj_ << std::endl;
119 *out <<
"ck_ = " << ck_ << std::endl;
124 template<
class Scalar>
125 ImplicitBDFStepperStepControl<Scalar>::ImplicitBDFStepperStepControl()
127 defaultInitializeAllData_();
130 template<
class Scalar>
131 void ImplicitBDFStepperStepControl<Scalar>::initialize(
const StepperBase<Scalar>& stepper)
134 typedef Teuchos::ScalarTraits<Scalar> ST;
135 using Thyra::createMember;
137 RCP<Teuchos::FancyOStream> out = this->getOStream();
138 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
139 const bool doTrace = (as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH));
140 Teuchos::OSTab ostab(out,1,
"initialize");
144 <<
"\nEntering " << this->Teuchos::Describable::description()
145 <<
"::initialize()...\n";
149 TimeRange<Scalar> stepperRange = stepper.getTimeRange();
150 TEUCHOS_TEST_FOR_EXCEPTION(
151 !stepperRange.isValid(),
153 "Error, Stepper does not have valid time range for initialization of ImplicitBDFStepperStepControl!\n"
155 time_ = stepperRange.upper();
157 if (parameterList_ == Teuchos::null) {
158 RCP<Teuchos::ParameterList> emptyParameterList = Teuchos::rcp(
new Teuchos::ParameterList);
159 this->setParameterList(emptyParameterList);
162 if (is_null(errWtVecCalc_)) {
163 RCP<ImplicitBDFStepperErrWtVecCalc<Scalar> > IBDFErrWtVecCalc = rcp(
new ImplicitBDFStepperErrWtVecCalc<Scalar>());
164 errWtVecCalc_ = IBDFErrWtVecCalc;
168 checkReduceOrderCalled_ =
false;
169 stepControlState_ = UNINITIALIZED;
174 alpha_s_=Scalar(-ST::one());
180 Scalar zero = ST::zero();
181 for (
int i=0 ; i<=maxOrder_ ; ++i) {
182 alpha_.push_back(zero);
183 gamma_.push_back(zero);
184 psi_.push_back(zero);
185 sigma_.push_back(zero);
204 newOrder_=currentOrder_;
207 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
208 *out <<
"currentOrder_ = " << currentOrder_ << std::endl;
209 *out <<
"oldOrder_ = " << oldOrder_ << std::endl;
210 *out <<
"usedOrder_ = " << usedOrder_ << std::endl;
211 *out <<
"alpha_s_ = " << alpha_s_ << std::endl;
212 for (
int i=0 ; i<=maxOrder_ ; ++i) {
213 *out <<
"alpha_[" << i <<
"] = " << alpha_[i] << std::endl;
214 *out <<
"gamma_[" << i <<
"] = " << gamma_[i] << std::endl;
215 *out <<
"psi_[" << i <<
"] = " << psi_[i] << std::endl;
216 *out <<
"sigma_[" << i <<
"] = " << sigma_[i] << std::endl;
218 *out <<
"alpha_0_ = " << alpha_0_ << std::endl;
219 *out <<
"cj_ = " << cj_ << std::endl;
220 *out <<
"ck_ = " << ck_ << std::endl;
221 *out <<
"numberOfSteps_ = " << numberOfSteps_ << std::endl;
222 *out <<
"nef_ = " << nef_ << std::endl;
223 *out <<
"usedStep_ = " << usedStep_ << std::endl;
224 *out <<
"nscsco_ = " << nscsco_ << std::endl;
225 *out <<
"Ek_ = " << Ek_ << std::endl;
226 *out <<
"Ekm1_ = " << Ekm1_ << std::endl;
227 *out <<
"Ekm2_ = " << Ekm2_ << std::endl;
228 *out <<
"Ekp1_ = " << Ekp1_ << std::endl;
229 *out <<
"Est_ = " << Est_ << std::endl;
230 *out <<
"Tk_ = " << Tk_ << std::endl;
231 *out <<
"Tkm1_ = " << Tkm1_ << std::endl;
232 *out <<
"Tkm2_ = " << Tkm2_ << std::endl;
233 *out <<
"Tkp1_ = " << Tkp1_ << std::endl;
234 *out <<
"newOrder_ = " << newOrder_ << std::endl;
235 *out <<
"initialPhase_ = " << initialPhase_ << std::endl;
239 if (is_null(delta_)) {
240 delta_ = createMember(stepper.get_x_space());
242 if (is_null(errWtVec_)) {
243 errWtVec_ = createMember(stepper.get_x_space());
245 V_S(delta_.ptr(),zero);
247 setStepControlState_(BEFORE_FIRST_STEP);
251 <<
"\nLeaving " << this->Teuchos::Describable::description()
252 <<
"::initialize()...\n";
256 template<
class Scalar>
257 void ImplicitBDFStepperStepControl<Scalar>::getFirstTimeStep_(
const StepperBase<Scalar>& stepper)
260 TEUCHOS_TEST_FOR_EXCEPT(!(stepControlState_ == BEFORE_FIRST_STEP));
263 typedef Teuchos::ScalarTraits<Scalar> ST;
264 Scalar zero = ST::zero();
266 RCP<Teuchos::FancyOStream> out = this->getOStream();
267 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
268 const bool doTrace = (as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH));
269 Teuchos::OSTab ostab(out,1,
"getFirstTimeStep_");
271 const ImplicitBDFStepper<Scalar>& implicitBDFStepper
272 = Teuchos::dyn_cast<
const ImplicitBDFStepper<Scalar> >(stepper);
273 const Thyra::VectorBase<Scalar>& xHistory0
274 = implicitBDFStepper.getxHistory(0);
275 errWtVecCalc_->errWtVecSet(&*errWtVec_,xHistory0,relErrTol_,absErrTol_);
278 Scalar time_to_stop = stopTime_ - time_;
279 Scalar currentTimeStep = ST::nan();
280 if (stepSizeType_ == STEP_TYPE_FIXED) {
281 currentTimeStep = hh_;
287 const Thyra::VectorBase<Scalar>& xHistory1
288 = implicitBDFStepper.getxHistory(1);
289 Scalar ypnorm = wRMSNorm_(*errWtVec_,xHistory1);
291 currentTimeStep = std::min( h0_max_factor_*std::abs(time_to_stop),
292 std::sqrt(2.0)/(h0_safety_*ypnorm) );
294 currentTimeStep = h0_max_factor_*std::abs(time_to_stop);
298 currentTimeStep = std::min(hh_, currentTimeStep);
301 #ifdef HAVE_RYTHMOS_DEBUG
302 TEUCHOS_TEST_FOR_EXCEPT(ST::isnaninf(currentTimeStep));
303 #endif // HAVE_RYTHMOS_DEBUG
304 Scalar rh = std::abs(currentTimeStep)*h_max_inv_;
306 currentTimeStep = currentTimeStep/rh;
309 hh_ = currentTimeStep;
316 *out <<
"\nhh_ = " << hh_ << std::endl;
317 *out <<
"psi_[0] = " << psi_[0] << std::endl;
318 *out <<
"cj_ = " << cj_ << std::endl;
323 template<
class Scalar>
324 void ImplicitBDFStepperStepControl<Scalar>::setRequestedStepSize(
325 const StepperBase<Scalar>& stepper
326 ,
const Scalar& stepSize
327 ,
const StepSizeType& stepSizeType
330 typedef Teuchos::ScalarTraits<Scalar> ST;
331 TEUCHOS_TEST_FOR_EXCEPT(!((stepControlState_ == UNINITIALIZED) ||
332 (stepControlState_ == BEFORE_FIRST_STEP) ||
333 (stepControlState_ == READY_FOR_NEXT_STEP) ||
334 (stepControlState_ == MID_STEP)));
335 TEUCHOS_TEST_FOR_EXCEPTION(
336 ((stepSizeType == STEP_TYPE_FIXED) && (stepSize == ST::zero())),
338 "Error, step size type == STEP_TYPE_FIXED, but requested step size == 0!\n"
340 bool didInitialization =
false;
341 if (stepControlState_ == UNINITIALIZED) {
343 didInitialization =
true;
347 if (!didInitialization) {
348 const ImplicitBDFStepper<Scalar>& implicitBDFStepper = Teuchos::dyn_cast<
const ImplicitBDFStepper<Scalar> >(stepper);
349 const Thyra::VectorBase<Scalar>& xHistory = implicitBDFStepper.getxHistory(0);
350 errWtVecCalc_->errWtVecSet(&*errWtVec_,xHistory,relErrTol_,absErrTol_);
353 stepSizeType_ = stepSizeType;
354 if (stepSizeType_ == STEP_TYPE_FIXED) {
356 if (numberOfSteps_ == 0) {
361 if (stepSize != ST::zero()) {
362 maxTimeStep_ = stepSize;
363 h_max_inv_ = Scalar(ST::one()/maxTimeStep_);
368 template<
class Scalar>
369 void ImplicitBDFStepperStepControl<Scalar>::nextStepSize(
const StepperBase<Scalar>& stepper, Scalar* stepSize, StepSizeType* stepSizeType,
int* order)
371 TEUCHOS_TEST_FOR_EXCEPT(!((stepControlState_ == BEFORE_FIRST_STEP) ||
372 (stepControlState_ == MID_STEP) ||
373 (stepControlState_ == READY_FOR_NEXT_STEP) )
375 if (stepControlState_ == BEFORE_FIRST_STEP) {
376 getFirstTimeStep_(stepper);
378 if (stepControlState_ != MID_STEP) {
379 this->updateCoeffs_();
381 if (stepSizeType_ == STEP_TYPE_VARIABLE) {
382 if (hh_ > maxTimeStep_) {
387 *stepSizeType = stepSizeType_;
388 *order = currentOrder_;
389 if (stepControlState_ != MID_STEP) {
390 setStepControlState_(MID_STEP);
394 template<
class Scalar>
395 void ImplicitBDFStepperStepControl<Scalar>::setCorrection(
396 const StepperBase<Scalar>&
397 ,
const RCP<
const Thyra::VectorBase<Scalar> >&
398 ,
const RCP<
const Thyra::VectorBase<Scalar> >& ee
401 TEUCHOS_TEST_FOR_EXCEPT(stepControlState_ != MID_STEP);
402 TEUCHOS_TEST_FOR_EXCEPTION(is_null(ee), std::logic_error,
"Error, ee == Teuchos::null!\n");
404 newtonConvergenceStatus_ = solveStatus;
405 setStepControlState_(AFTER_CORRECTION);
408 template<
class Scalar>
409 void ImplicitBDFStepperStepControl<Scalar>::completeStep(
const StepperBase<Scalar>& stepper)
411 TEUCHOS_TEST_FOR_EXCEPT(stepControlState_ != AFTER_CORRECTION);
413 typedef Teuchos::ScalarTraits<Scalar> ST;
418 RCP<Teuchos::FancyOStream> out = this->getOStream();
419 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
420 Teuchos::OSTab ostab(out,1,
"completeStep_");
422 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
423 *out <<
"numberOfSteps_ = " << numberOfSteps_ << std::endl;
424 *out <<
"nef_ = " << nef_ << std::endl;
425 *out <<
"time_ = " << time_ << std::endl;
429 bool adjustStep = (stepSizeType_ == STEP_TYPE_VARIABLE);
431 Scalar newTimeStep = hh_;
432 Scalar rr = ST::one();
435 int orderDiff = currentOrder_ - usedOrder_;
436 usedOrder_ = currentOrder_;
438 if ((newOrder_ == currentOrder_-1) || (currentOrder_ == maxOrder_)) {
442 initialPhase_ =
false;
444 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
445 *out <<
"initialPhase_ = " << initialPhase_ << std::endl;
449 newTimeStep = h_phase0_incr_ * hh_;
450 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
451 *out <<
"currentOrder_ = " << currentOrder_ << std::endl;
452 *out <<
"newTimeStep = " << newTimeStep << std::endl;
455 BDFactionFlag action = ACTION_UNSET;
456 if (newOrder_ == currentOrder_-1) {
457 action = ACTION_LOWER;
458 }
else if (newOrder_ == maxOrder_) {
459 action = ACTION_MAINTAIN;
460 }
else if ((currentOrder_+1>=nscsco_) || (orderDiff == 1)) {
463 action = ACTION_MAINTAIN;
465 const ImplicitBDFStepper<Scalar>& implicitBDFStepper = Teuchos::dyn_cast<
const ImplicitBDFStepper<Scalar> >(stepper);
466 const Thyra::VectorBase<Scalar>& xHistory = implicitBDFStepper.getxHistory(currentOrder_+1);
467 V_StVpStV(delta_.ptr(),ST::one(),*ee_,Scalar(-ST::one()),xHistory);
468 Tkp1_ = wRMSNorm_(*errWtVec_,*delta_);
469 Ekp1_ = Tkp1_/(currentOrder_+2);
470 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
471 *out <<
"delta_ = " << std::endl;
472 delta_->describe(*out,verbLevel);
473 *out <<
"Tkp1_ = ||delta_||_WRMS = " << Tkp1_ << std::endl;
474 *out <<
"Ekp1_ = " << Ekp1_ << std::endl;
476 if (currentOrder_ == 1) {
477 if (Tkp1_ >= Tkp1_Tk_safety_ * Tk_) {
478 action = ACTION_MAINTAIN;
480 action = ACTION_RAISE;
483 if (Tkm1_ <= std::min(Tk_,Tkp1_)) {
484 action = ACTION_LOWER;
485 }
else if (Tkp1_ >= Tk_) {
486 action = ACTION_MAINTAIN;
488 action = ACTION_RAISE;
492 if (currentOrder_ < minOrder_) {
493 action = ACTION_RAISE;
494 }
else if ( (currentOrder_ == minOrder_) && (action == ACTION_LOWER) ) {
495 action = ACTION_MAINTAIN;
497 if (action == ACTION_RAISE) {
500 }
else if (action == ACTION_LOWER) {
505 rr = pow(r_safety_*Est_+r_fudge_,-1.0/(currentOrder_+1.0));
506 if (rr >= r_hincr_test_) {
508 newTimeStep = rr*hh_;
509 }
else if (rr <= 1) {
510 rr = std::max(r_min_,std::min(r_max_,rr));
511 newTimeStep = rr*hh_;
513 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
514 *out <<
"Est_ = " << Est_ << std::endl;
515 *out <<
"rr = " << rr << std::endl;
516 *out <<
"newTimeStep = " << newTimeStep << std::endl;
520 if (time_ < stopTime_) {
523 newTimeStep = std::max(newTimeStep, minTimeStep_);
524 newTimeStep = std::min(newTimeStep, maxTimeStep_);
526 Scalar nextTimePt = time_ + newTimeStep;
528 if (nextTimePt > stopTime_) {
529 nextTimePt = stopTime_;
530 newTimeStep = stopTime_ - time_;
536 Scalar nextTimePt = time_ + hh_;
538 if (nextTimePt > stopTime_) {
539 nextTimePt = stopTime_;
540 hh_ = stopTime_ - time_;
544 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
545 *out <<
"hh_ = " << hh_ << std::endl;
546 *out <<
"currentOrder_ = " << currentOrder_ << std::endl;
548 setStepControlState_(READY_FOR_NEXT_STEP);
551 template<
class Scalar>
552 AttemptedStepStatusFlag ImplicitBDFStepperStepControl<Scalar>::rejectStep(
const StepperBase<Scalar>& )
554 TEUCHOS_TEST_FOR_EXCEPT(stepControlState_ != AFTER_CORRECTION);
571 bool adjustStep = (stepSizeType_ == STEP_TYPE_VARIABLE);
573 Scalar newTimeStep = hh_;
576 RCP<Teuchos::FancyOStream> out = this->getOStream();
577 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
578 Teuchos::OSTab ostab(out,1,
"rejectStep_");
579 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
580 *out <<
"adjustStep = " << adjustStep << std::endl;
581 *out <<
"nef_ = " << nef_ << std::endl;
583 if (nef_ >= max_LET_fail_) {
584 TEUCHOS_TEST_FOR_EXCEPTION(nef_ >= max_LET_fail_, std::logic_error,
"Error, maximum number of local error test failures.\n");
586 initialPhase_ =
false;
588 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
589 *out <<
"initialPhase_ = " << initialPhase_ << std::endl;
591 for (
int i=1;i<=currentOrder_;++i) {
592 psi_[i-1] = psi_[i] - hh_;
595 if ((newtonConvergenceStatus_ < 0)) {
599 newTimeStep = rr * hh_;
609 rr = r_factor_*pow(r_safety_*Est_+r_fudge_,-1.0/(newOrder_+1.0));
610 rr = std::max(r_min_,std::min(r_max_,rr));
611 newTimeStep = rr * hh_;
612 }
else if (nef_ == 2) {
614 newTimeStep = rr * hh_;
615 }
else if (nef_ > 2) {
618 newTimeStep = rr * hh_;
621 if (newOrder_ >= minOrder_) {
622 currentOrder_ = newOrder_;
624 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
625 *out <<
"newTimeStep = " << newTimeStep << std::endl;
626 *out <<
"rr = " << rr << std::endl;
627 *out <<
"newOrder_ = " << newOrder_ << std::endl;
628 *out <<
"currentOrder_ = " << currentOrder_ << std::endl;
630 if (numberOfSteps_ == 0) {
631 psi_[0] = newTimeStep;
632 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
633 *out <<
"numberOfSteps_ == 0:" << std::endl;
634 *out <<
"psi_[0] = " << psi_[0] << std::endl;
637 }
else if (!adjustStep) {
638 if ( as<int>(verbLevel) != as<int>(Teuchos::VERB_NONE) ) {
639 *out <<
"Rythmos_ImplicitBDFStepperStepControl::rejectStep(...): "
640 <<
"Warning: Local error test failed with constant step-size."
645 AttemptedStepStatusFlag return_status = PREDICT_AGAIN;
649 newTimeStep = std::max(newTimeStep, minTimeStep_);
650 newTimeStep = std::min(newTimeStep, maxTimeStep_);
652 Scalar nextTimePt = time_ + newTimeStep;
654 if (nextTimePt > stopTime_) {
655 nextTimePt = stopTime_;
656 newTimeStep = stopTime_ - time_;
662 Scalar nextTimePt = time_ + hh_;
664 if (nextTimePt > stopTime_) {
665 nextTimePt = stopTime_;
666 hh_ = stopTime_ - time_;
668 return_status = CONTINUE_ANYWAY;
670 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
671 *out <<
"hh_ = " << hh_ << std::endl;
674 if (return_status == PREDICT_AGAIN) {
675 setStepControlState_(READY_FOR_NEXT_STEP);
676 }
else if (return_status == CONTINUE_ANYWAY) {
680 return(return_status);
683 template<
class Scalar>
684 Scalar ImplicitBDFStepperStepControl<Scalar>::checkReduceOrder_(
685 const StepperBase<Scalar>& stepper)
687 TEUCHOS_TEST_FOR_EXCEPT(stepControlState_ != AFTER_CORRECTION);
688 TEUCHOS_TEST_FOR_EXCEPT(checkReduceOrderCalled_ ==
true);
692 const ImplicitBDFStepper<Scalar>& implicitBDFStepper =
693 Teuchos::dyn_cast<
const ImplicitBDFStepper<Scalar> >(stepper);
697 RCP<Teuchos::FancyOStream> out = this->getOStream();
698 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
699 Teuchos::OSTab ostab(out,1,
"checkReduceOrder_");
700 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
701 *out <<
"sigma_[" << currentOrder_ <<
"] = "
702 << sigma_[currentOrder_] << std::endl;
703 *out <<
"ee_ = " << std::endl;
704 ee_->describe(*out,verbLevel);
705 *out <<
"errWtVec_ = " << std::endl;
706 errWtVec_->describe(*out,verbLevel);
709 Scalar enorm = wRMSNorm_(*errWtVec_,*ee_);
710 Ek_ = sigma_[currentOrder_]*enorm;
711 Tk_ = Scalar(currentOrder_+1)*Ek_;
713 newOrder_ = currentOrder_;
714 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
715 *out <<
"currentOrder_ = " << currentOrder_ << std::endl;
716 *out <<
"Ek_ = " << Ek_ << std::endl;
717 *out <<
"Tk_ = " << Tk_ << std::endl;
718 *out <<
"enorm = " << enorm << std::endl;
720 if (currentOrder_>1) {
721 const Thyra::VectorBase<Scalar>& xHistoryCur =
722 implicitBDFStepper.getxHistory(currentOrder_);
723 V_VpV(delta_.ptr(),xHistoryCur,*ee_);
724 Ekm1_ = sigma_[currentOrder_-1]*wRMSNorm_(*errWtVec_,*delta_);
725 Tkm1_ = currentOrder_*Ekm1_;
726 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
727 *out <<
"Ekm1_ = " << Ekm1_ << std::endl;
728 *out <<
"Tkm1_ = " << Tkm1_ << std::endl;
730 if (currentOrder_>2) {
731 const Thyra::VectorBase<Scalar>& xHistoryPrev =
732 implicitBDFStepper.getxHistory(currentOrder_-1);
733 Vp_V(delta_.ptr(),xHistoryPrev);
734 Ekm2_ = sigma_[currentOrder_-2]*wRMSNorm_(*errWtVec_,*delta_);
735 Tkm2_ = (currentOrder_-1)*Ekm2_;
736 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
737 *out <<
"Ekm2_ = " << Ekm2_ << std::endl;
738 *out <<
"Tkm2_ = " << Tkm2_ << std::endl;
740 if (std::max(Tkm1_,Tkm2_)<=Tk_) {
745 else if (Tkm1_ <= Tkm1_Tk_safety_ * Tk_) {
750 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
751 *out <<
"Est_ = " << Est_ << std::endl;
752 *out <<
"newOrder_= " << newOrder_ << std::endl;
754 checkReduceOrderCalled_ =
true;
758 template<
class Scalar>
759 bool ImplicitBDFStepperStepControl<Scalar>::acceptStep(
const StepperBase<Scalar>& stepper, Scalar* LETValue)
761 TEUCHOS_TEST_FOR_EXCEPT(stepControlState_ != AFTER_CORRECTION);
762 typedef Teuchos::ScalarTraits<Scalar> ST;
763 RCP<Teuchos::FancyOStream> out = this->getOStream();
764 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
765 Teuchos::OSTab ostab(out,1,
"acceptStep");
767 bool return_status =
false;
768 Scalar enorm = checkReduceOrder_(stepper);
769 Scalar LET = ck_*enorm;
771 if (failStepIfNonlinearSolveFails_ && (newtonConvergenceStatus_ < 0) )
777 if (LET < ST::one()) {
778 return_status =
true;
780 if ( Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
781 *out <<
"ck_ = " << ck_ << std::endl;
782 *out <<
"enorm = " << enorm << std::endl;
783 *out <<
"Local Truncation Error Check: (ck*enorm) < 1: (" << LET <<
") <?= 1" << std::endl;
785 return(return_status);
788 template<
class Scalar>
789 void ImplicitBDFStepperStepControl<Scalar>::describe(
790 Teuchos::FancyOStream &out,
791 const Teuchos::EVerbosityLevel verbLevel
797 if ( (as<int>(verbLevel) == as<int>(Teuchos::VERB_DEFAULT) ) ||
798 (as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW) )
800 out << this->description() <<
"::describe" << std::endl;
802 else if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW)) {
803 out <<
"time_ = " << time_ << std::endl;
804 out <<
"hh_ = " << hh_ << std::endl;
805 out <<
"currentOrder_ = " << currentOrder_ << std::endl;
807 else if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_MEDIUM)) {
809 else if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH)) {
811 if (ee_ == Teuchos::null) {
812 out <<
"Teuchos::null" << std::endl;
814 ee_->describe(out,verbLevel);
817 if (delta_ == Teuchos::null) {
818 out <<
"Teuchos::null" << std::endl;
820 delta_->describe(out,verbLevel);
822 out <<
"errWtVec_ = ";
823 if (errWtVec_ == Teuchos::null) {
824 out <<
"Teuchos::null" << std::endl;
826 errWtVec_->describe(out,verbLevel);
831 template<
class Scalar>
832 void ImplicitBDFStepperStepControl<Scalar>::setParameterList(
833 RCP<Teuchos::ParameterList>
const& paramList)
839 TEUCHOS_TEST_FOR_EXCEPT(paramList == Teuchos::null);
840 paramList->validateParameters(*this->getValidParameters(),0);
841 parameterList_ = paramList;
842 Teuchos::readVerboseObjectSublist(&*parameterList_,
this);
844 minOrder_ = parameterList_->get(
"minOrder",
int(1));
845 TEUCHOS_TEST_FOR_EXCEPTION(
846 !((1 <= minOrder_) && (minOrder_ <= 5)), std::logic_error,
847 "Error, minOrder_ = " << minOrder_ <<
" is not in range [1,5]!\n"
849 maxOrder_ = parameterList_->get(
"maxOrder",
int(5));
850 TEUCHOS_TEST_FOR_EXCEPTION(
851 !((1 <= maxOrder_) && (maxOrder_ <= 5)), std::logic_error,
852 "Error, maxOrder_ = " << maxOrder_ <<
" is not in range [1,5]!\n"
855 relErrTol_ = parameterList_->get(
"relErrTol", Scalar(1.0e-4) );
856 absErrTol_ = parameterList_->get(
"absErrTol", Scalar(1.0e-6) );
857 bool constantStepSize = parameterList_->get(
"constantStepSize",
false );
858 stopTime_ = parameterList_->get(
"stopTime", Scalar(1.0) );
860 if (constantStepSize ==
true) {
861 stepSizeType_ = STEP_TYPE_FIXED;
863 stepSizeType_ = STEP_TYPE_VARIABLE;
866 failStepIfNonlinearSolveFails_ =
867 parameterList_->get(
"failStepIfNonlinearSolveFails",
false );
869 RCP<Teuchos::FancyOStream> out = this->getOStream();
870 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
871 Teuchos::OSTab ostab(out,1,
"setParameterList");
874 setDefaultMagicNumbers_(parameterList_->sublist(
"magicNumbers"));
876 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
877 *out <<
"minOrder_ = " << minOrder_ << std::endl;
878 *out <<
"maxOrder_ = " << maxOrder_ << std::endl;
879 *out <<
"relErrTol = " << relErrTol_ << std::endl;
880 *out <<
"absErrTol = " << absErrTol_ << std::endl;
881 *out <<
"stepSizeType = " << stepSizeType_ << std::endl;
882 *out <<
"stopTime_ = " << stopTime_ << std::endl;
883 *out <<
"failStepIfNonlinearSolveFails_ = "
884 << failStepIfNonlinearSolveFails_ << std::endl;
889 template<
class Scalar>
890 void ImplicitBDFStepperStepControl<Scalar>::setDefaultMagicNumbers_(
891 Teuchos::ParameterList &magicNumberList)
897 h0_safety_ = magicNumberList.get(
"h0_safety", Scalar(2.0) );
898 h0_max_factor_ = magicNumberList.get(
"h0_max_factor", Scalar(0.001) );
899 h_phase0_incr_ = magicNumberList.get(
"h_phase0_incr", Scalar(2.0) );
900 h_max_inv_ = magicNumberList.get(
"h_max_inv", Scalar(0.0) );
901 Tkm1_Tk_safety_ = magicNumberList.get(
"Tkm1_Tk_safety", Scalar(2.0) );
902 Tkp1_Tk_safety_ = magicNumberList.get(
"Tkp1_Tk_safety", Scalar(0.5) );
903 r_factor_ = magicNumberList.get(
"r_factor", Scalar(0.9) );
904 r_safety_ = magicNumberList.get(
"r_safety", Scalar(2.0) );
905 r_fudge_ = magicNumberList.get(
"r_fudge", Scalar(0.0001) );
906 r_min_ = magicNumberList.get(
"r_min", Scalar(0.125) );
907 r_max_ = magicNumberList.get(
"r_max", Scalar(0.9) );
908 r_hincr_test_ = magicNumberList.get(
"r_hincr_test", Scalar(2.0) );
909 r_hincr_ = magicNumberList.get(
"r_hincr", Scalar(2.0) );
910 max_LET_fail_ = magicNumberList.get(
"max_LET_fail",
int(15) );
911 minTimeStep_ = magicNumberList.get(
"minTimeStep", Scalar(0.0) );
912 maxTimeStep_ = magicNumberList.get(
"maxTimeStep", Scalar(10.0) );
914 RCP<Teuchos::FancyOStream> out = this->getOStream();
915 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
916 Teuchos::OSTab ostab(out,1,
"setDefaultMagicNumbers_");
917 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
918 *out <<
"h0_safety_ = " << h0_safety_ << std::endl;
919 *out <<
"h0_max_factor_ = " << h0_max_factor_ << std::endl;
920 *out <<
"h_phase0_incr_ = " << h_phase0_incr_ << std::endl;
921 *out <<
"h_max_inv_ = " << h_max_inv_ << std::endl;
922 *out <<
"Tkm1_Tk_safety_ = " << Tkm1_Tk_safety_ << std::endl;
923 *out <<
"Tkp1_Tk_safety_ = " << Tkp1_Tk_safety_ << std::endl;
924 *out <<
"r_factor_ = " << r_factor_ << std::endl;
925 *out <<
"r_safety_ = " << r_safety_ << std::endl;
926 *out <<
"r_fudge_ = " << r_fudge_ << std::endl;
927 *out <<
"r_min_ = " << r_min_ << std::endl;
928 *out <<
"r_max_ = " << r_max_ << std::endl;
929 *out <<
"r_hincr_test_ = " << r_hincr_test_ << std::endl;
930 *out <<
"r_hincr_ = " << r_hincr_ << std::endl;
931 *out <<
"max_LET_fail_ = " << max_LET_fail_ << std::endl;
932 *out <<
"minTimeStep_ = " << minTimeStep_ << std::endl;
933 *out <<
"maxTimeStep_ = " << maxTimeStep_ << std::endl;
938 template<
class Scalar>
939 RCP<const Teuchos::ParameterList>
940 ImplicitBDFStepperStepControl<Scalar>::getValidParameters()
const
943 static RCP<Teuchos::ParameterList> validPL;
945 if (is_null(validPL)) {
947 RCP<Teuchos::ParameterList>
948 pl = Teuchos::parameterList();
950 pl->set<
int> (
"minOrder", 1,
951 "lower limit of order selection, guaranteed");
952 pl->set<
int> (
"maxOrder", 5,
953 "upper limit of order selection, does not guarantee this order");
954 pl->set<Scalar>(
"relErrTol", Scalar(1.0e-4),
955 "Relative tolerance value used in WRMS calculation.");
956 pl->set<Scalar>(
"absErrTol", Scalar(1.0e-6),
957 "Absolute tolerance value used in WRMS calculation.");
958 pl->set<
bool> (
"constantStepSize",
false,
959 "Use constant (=0) or variable (=1) step sizes during BDF steps.");
960 pl->set<Scalar>(
"stopTime", Scalar(10.0),
961 "The final time for time integration. This may be in conflict with "
962 "the Integrator's final time.");
963 pl->set<
bool>(
"failStepIfNonlinearSolveFails",
false,
964 "Power user command. Will force the function acceptStep() to return "
965 "false even if the LET is acceptable. Used to run with loose "
966 "tolerances but enforce a correct nonlinear solution to the step.");
968 Teuchos::ParameterList
969 &magicNumberList = pl->sublist(
"magicNumbers",
false,
970 "These are knobs in the algorithm that have been set to reasonable "
971 "values using lots of testing and heuristics and some theory.");
972 magicNumberList.set<Scalar>(
"h0_safety", Scalar(2.0),
973 "Safety factor on the initial step size for time-dependent DAEs. "
974 "Larger values will tend to reduce the initial step size.");
975 magicNumberList.set<Scalar>(
"h0_max_factor", Scalar(0.001),
976 "Factor multipler for the initial step size for non-time-dependent "
978 magicNumberList.set<Scalar>(
"h_phase0_incr", Scalar(2.0),
979 "Initial ramp-up in variable mode (stepSize multiplier).");
980 magicNumberList.set<Scalar>(
"h_max_inv", Scalar(0.0),
981 "The inverse of the maximum time step (maxTimeStep). (Not used?)");
982 magicNumberList.set<Scalar>(
"Tkm1_Tk_safety", Scalar(2.0),
983 "Used to help control the decrement of the order when the order is "
984 "less than or equal to 2. Larger values will tend to reduce the "
985 "order from one step to the next.");
986 magicNumberList.set<Scalar>(
"Tkp1_Tk_safety", Scalar(0.5),
987 "Used to control the increment of the order when the order is one. "
988 "Larger values tend to increase the order for the next step.");
989 magicNumberList.set<Scalar>(
"r_factor", Scalar(0.9),
990 "Used in rejectStep: time step ratio multiplier.");
991 magicNumberList.set<Scalar>(
"r_safety", Scalar(2.0),
992 "Local error multiplier as part of time step ratio calculation.");
993 magicNumberList.set<Scalar>(
"r_fudge", Scalar(0.0001),
994 "Local error addition as part of time step ratio calculation.");
995 magicNumberList.set<Scalar>(
"r_min", Scalar(0.125),
996 "Used in rejectStep: How much to cut step and lower bound for time "
998 magicNumberList.set<Scalar>(
"r_max", Scalar(0.9),
999 "Upper bound for time step ratio.");
1000 magicNumberList.set<Scalar>(
"r_hincr_test", Scalar(2.0),
1001 "Used in completeStep: If time step ratio > this then set time step "
1002 "ratio to r_hincr.");
1003 magicNumberList.set<Scalar>(
"r_hincr", Scalar(2.0),
1004 "Used in completeStep: Limit on time step ratio increases, not "
1005 "checked by r_max.");
1006 magicNumberList.set<
int> (
"max_LET_fail", int(15),
1007 "Max number of rejected steps");
1008 magicNumberList.set<Scalar>(
"minTimeStep", Scalar(0.0),
1009 "Bound on smallest time step in variable mode.");
1010 magicNumberList.set<Scalar>(
"maxTimeStep", Scalar(10.0),
1011 "bound on largest time step in variable mode.");
1013 Teuchos::setupVerboseObjectSublist(&*pl);
1023 template<
class Scalar>
1024 RCP<Teuchos::ParameterList>
1025 ImplicitBDFStepperStepControl<Scalar>::unsetParameterList()
1027 RCP<Teuchos::ParameterList> temp_param_list = parameterList_;
1028 parameterList_ = Teuchos::null;
1029 return(temp_param_list);
1032 template<
class Scalar>
1033 RCP<Teuchos::ParameterList>
1034 ImplicitBDFStepperStepControl<Scalar>::getNonconstParameterList()
1036 return(parameterList_);
1039 template<
class Scalar>
1040 void ImplicitBDFStepperStepControl<Scalar>::setStepControlData(
const StepperBase<Scalar>& stepper)
1042 if (stepControlState_ == UNINITIALIZED) {
1043 initialize(stepper);
1045 const ImplicitBDFStepper<Scalar>& bdfstepper = Teuchos::dyn_cast<
const ImplicitBDFStepper<Scalar> >(stepper);
1046 int desiredOrder = bdfstepper.getOrder();
1047 TEUCHOS_TEST_FOR_EXCEPT(!((1 <= desiredOrder) && (desiredOrder <= maxOrder_)));
1048 if (stepControlState_ == BEFORE_FIRST_STEP) {
1049 TEUCHOS_TEST_FOR_EXCEPTION(
1052 "Error, this ImplicitBDF stepper has not taken a step yet, so it cannot take a step of order " << desiredOrder <<
" > 1!\n"
1055 TEUCHOS_TEST_FOR_EXCEPT(!(desiredOrder <= currentOrder_+1));
1056 currentOrder_ = desiredOrder;
1059 RCP<Teuchos::FancyOStream> out = this->getOStream();
1060 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
1061 Teuchos::OSTab ostab(out,1,
"setStepControlData");
1063 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_EXTREME) ) {
1064 *out <<
"currentOrder_ = " << currentOrder_ << std::endl;
1068 template<
class Scalar>
1069 bool ImplicitBDFStepperStepControl<Scalar>::supportsCloning()
const
1075 template<
class Scalar>
1076 RCP<StepControlStrategyBase<Scalar> >
1077 ImplicitBDFStepperStepControl<Scalar>::cloneStepControlStrategyAlgorithm()
const
1080 RCP<ImplicitBDFStepperStepControl<Scalar> > stepControl = rcp(
new ImplicitBDFStepperStepControl<Scalar>());
1082 if (!is_null(parameterList_)) {
1083 stepControl->setParameterList(parameterList_);
1089 template<
class Scalar>
1090 void ImplicitBDFStepperStepControl<Scalar>::setErrWtVecCalc(
const RCP<ErrWtVecCalcBase<Scalar> >& errWtVecCalc)
1092 TEUCHOS_TEST_FOR_EXCEPT(is_null(errWtVecCalc));
1093 errWtVecCalc_ = errWtVecCalc;
1096 template<
class Scalar>
1097 RCP<const ErrWtVecCalcBase<Scalar> > ImplicitBDFStepperStepControl<Scalar>::getErrWtVecCalc()
const
1099 return(errWtVecCalc_);
1102 template<
class Scalar>
1103 Scalar ImplicitBDFStepperStepControl<Scalar>::wRMSNorm_(
1104 const Thyra::VectorBase<Scalar>& weight,
1105 const Thyra::VectorBase<Scalar>& vector)
const
1107 return(norm_2(weight,vector));
1110 template<
class Scalar>
1111 void ImplicitBDFStepperStepControl<Scalar>::defaultInitializeAllData_()
1113 typedef Teuchos::ScalarTraits<Scalar> ST;
1114 Scalar zero = ST::zero();
1115 Scalar mone = Scalar(-ST::one());
1117 stepControlState_ = UNINITIALIZED;
1120 stepSizeType_ = STEP_TYPE_VARIABLE;
1126 checkReduceOrderCalled_ =
false;
1127 time_ = -std::numeric_limits<Scalar>::max();
1139 constantStepSize_ =
false;
1151 initialPhase_ =
false;
1154 h0_max_factor_ = mone;
1155 h_phase0_incr_ = mone;
1157 Tkm1_Tk_safety_ = mone;
1158 Tkp1_Tk_safety_ = mone;
1164 r_hincr_test_ = mone;
1167 minTimeStep_ = mone;
1168 maxTimeStep_ = mone;
1169 newtonConvergenceStatus_ = -1;
1172 template<
class Scalar>
1173 int ImplicitBDFStepperStepControl<Scalar>::getMinOrder()
const
1175 TEUCHOS_TEST_FOR_EXCEPTION(
1176 stepControlState_ == UNINITIALIZED, std::logic_error,
1177 "Error, attempting to call getMinOrder before intiialization!\n"
1182 template<
class Scalar>
1183 int ImplicitBDFStepperStepControl<Scalar>::getMaxOrder()
const
1185 TEUCHOS_TEST_FOR_EXCEPTION(
1186 stepControlState_ == UNINITIALIZED, std::logic_error,
1187 "Error, attempting to call getMaxOrder before initialization!\n"
1198 #define RYTHMOS_IMPLICITBDF_STEPPER_STEPCONTROL_INSTANT(SCALAR) \
1199 template class ImplicitBDFStepperStepControl< SCALAR >;
1203 #endif // Rythmos_IMPLICITBDF_STEPPER_STEP_CONTROL_DEF_H