Rythmos - Transient Integration for Differential Equations Version of the Day
Rythmos_ImplicitBDFStepperRampingStepControl_def.hpp
00001 //@HEADER
00002 // ***********************************************************************
00003 //
00004 //                           Rythmos Package
00005 //                 Copyright (2006) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Todd S. Coffey (tscoffe@sandia.gov)
00025 //
00026 // ***********************************************************************
00027 //@HEADER
00028 
00029 #ifndef Rythmos_IMPLICITBDF_STEPPER_RAMPING_STEP_CONTROL_DEF_H
00030 #define Rythmos_IMPLICITBDF_STEPPER_RAMPING_STEP_CONTROL_DEF_H
00031 
00032 #include "Rythmos_ImplicitBDFStepper.hpp"
00033 #include "Rythmos_ImplicitBDFStepperErrWtVecCalc.hpp"
00034 #include "Teuchos_StandardParameterEntryValidators.hpp"
00035 
00036 namespace Rythmos {
00037 
00038 template<class Scalar>
00039 ImplicitBDFStepperRampingStepControl<Scalar>::
00040 ImplicitBDFStepperRampingStepControl() :
00041   stepControlState_(UNINITIALIZED)
00042 {
00043 
00044 }
00045 
00046 template<class Scalar>
00047 void ImplicitBDFStepperRampingStepControl<Scalar>::setStepControlState_(
00048   StepControlStrategyState newState)
00049 {
00050   if (stepControlState_ == UNINITIALIZED) {
00051     TEUCHOS_TEST_FOR_EXCEPT(newState != BEFORE_FIRST_STEP);
00052   } else if (stepControlState_ == BEFORE_FIRST_STEP) {
00053     TEUCHOS_TEST_FOR_EXCEPT(newState != MID_STEP);
00054   } else if (stepControlState_ == MID_STEP) {
00055     TEUCHOS_TEST_FOR_EXCEPT(newState != AFTER_CORRECTION);
00056   } else if (stepControlState_ == AFTER_CORRECTION) {
00057     TEUCHOS_TEST_FOR_EXCEPT(newState != READY_FOR_NEXT_STEP);
00058   } else if (stepControlState_ == READY_FOR_NEXT_STEP) {
00059     TEUCHOS_TEST_FOR_EXCEPT(newState != MID_STEP);
00060   }
00061   stepControlState_ = newState;
00062 }
00063 
00064 template<class Scalar>
00065 StepControlStrategyState
00066 ImplicitBDFStepperRampingStepControl<Scalar>::getCurrentState()
00067 {
00068   return(stepControlState_);
00069 }
00070 
00071 template<class Scalar>
00072 void ImplicitBDFStepperRampingStepControl<Scalar>::updateCoeffs_()
00073 {
00074   TEUCHOS_TEST_FOR_EXCEPT(!((stepControlState_ == BEFORE_FIRST_STEP) ||
00075                             (stepControlState_ == READY_FOR_NEXT_STEP)));
00076 
00077   TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
00078     "updateCoeffs_() is not implemented!");
00079 }
00080 
00081 template<class Scalar>
00082 void ImplicitBDFStepperRampingStepControl<Scalar>::initialize(
00083   const StepperBase<Scalar>& stepper)
00084 {
00085   // Initialize can be called from the stepper when setInitialCondition
00086   // is called.
00087   using Teuchos::as;
00088   typedef Teuchos::ScalarTraits<Scalar> ST;
00089   using Thyra::createMember;
00090 
00091   // Set initial time:
00092   TimeRange<Scalar> stepperRange = stepper.getTimeRange();
00093   TEUCHOS_TEST_FOR_EXCEPTION(
00094       !stepperRange.isValid(),
00095       std::logic_error,
00096       "Error, Stepper does not have valid time range for initialization "
00097       "of ImplicitBDFStepperRampingStepControl!\n");
00098 
00099   if (is_null(parameterList_)) {
00100     RCP<Teuchos::ParameterList> emptyParameterList =
00101       Teuchos::rcp(new Teuchos::ParameterList);
00102     this->setParameterList(emptyParameterList);
00103   }
00104 
00105   if (is_null(errWtVecCalc_)) {
00106     RCP<ImplicitBDFStepperErrWtVecCalc<Scalar> > IBDFErrWtVecCalc =
00107       rcp(new ImplicitBDFStepperErrWtVecCalc<Scalar>());
00108     errWtVecCalc_ = IBDFErrWtVecCalc;
00109   }
00110 
00111   stepControlState_ = UNINITIALIZED;
00112 
00113   requestedStepSize_ = Scalar(-1.0);
00114   currentStepSize_ = initialStepSize_;
00115   currentOrder_ = 1;
00116   nextStepSize_ = initialStepSize_;
00117   nextOrder_ = 1;
00118   numberOfSteps_ = 0;
00119   totalNumberOfFailedSteps_ = 0;
00120   countOfConstantStepsAfterFailure_ = 0;
00121 
00122   if (is_null(delta_)) {
00123     delta_ = createMember(stepper.get_x_space());
00124   }
00125   if (is_null(errWtVec_)) {
00126     errWtVec_ = createMember(stepper.get_x_space());
00127   }
00128   V_S(delta_.ptr(),ST::zero());
00129 
00130   if ( doOutput_(Teuchos::VERB_HIGH) ) {
00131     RCP<Teuchos::FancyOStream> out = this->getOStream();
00132     Teuchos::OSTab ostab(out,1,"initialize");
00133     *out << "currentOrder_ = " << currentOrder_ << std::endl;
00134     *out << "numberOfSteps_ = " << numberOfSteps_ << std::endl;
00135   }
00136 
00137   setStepControlState_(BEFORE_FIRST_STEP);
00138 
00139 }
00140 
00141 template<class Scalar>
00142 void ImplicitBDFStepperRampingStepControl<Scalar>::setRequestedStepSize(
00143     const StepperBase<Scalar>& stepper,
00144     const Scalar& stepSize,
00145     const StepSizeType& stepSizeType)
00146 {
00147   typedef Teuchos::ScalarTraits<Scalar> ST;
00148 
00149   TEUCHOS_TEST_FOR_EXCEPT(!((stepControlState_ == UNINITIALIZED) ||
00150                             (stepControlState_ == BEFORE_FIRST_STEP) ||
00151                             (stepControlState_ == READY_FOR_NEXT_STEP) ||
00152                             (stepControlState_ == MID_STEP)));
00153 
00154   TEUCHOS_TEST_FOR_EXCEPTION(
00155       ((stepSizeType == STEP_TYPE_FIXED) && (stepSize == ST::zero())),
00156       std::logic_error,
00157       "Error, step size type == STEP_TYPE_FIXED, "
00158       "but requested step size == 0!\n");
00159 
00160   bool didInitialization = false;
00161   if (stepControlState_ == UNINITIALIZED) {
00162     initialize(stepper);
00163     didInitialization = true;
00164   }
00165 
00166   // errWtVecSet_ is called during initialize
00167   if (!didInitialization) {
00168     const ImplicitBDFStepper<Scalar>& implicitBDFStepper =
00169       Teuchos::dyn_cast<const ImplicitBDFStepper<Scalar> >(stepper);
00170     const Thyra::VectorBase<Scalar>& xHistory =
00171       implicitBDFStepper.getxHistory(0);
00172     errWtVecCalc_->errWtVecSet(&*errWtVec_,xHistory,relErrTol_,absErrTol_);
00173   }
00174 
00175   requestedStepSize_ = stepSize;
00176   stepSizeType_ = stepSizeType;
00177 }
00178 
00179 template<class Scalar>
00180 void ImplicitBDFStepperRampingStepControl<Scalar>::nextStepSize(
00181   const StepperBase<Scalar>& stepper, Scalar* stepSize,
00182   StepSizeType* stepSizeType, int* order)
00183 {
00184   TEUCHOS_TEST_FOR_EXCEPT(!((stepControlState_ == BEFORE_FIRST_STEP) ||
00185          (stepControlState_ == MID_STEP) ||
00186          (stepControlState_ == READY_FOR_NEXT_STEP) )
00187         );
00188 
00189   if (stepControlState_ == BEFORE_FIRST_STEP) {
00190     nextStepSize_ = initialStepSize_;
00191     nextOrder_ = 1;
00192   }
00193 
00194   // Now starting a step - rotate next values into current values
00195   if (stepSizeType_ == STEP_TYPE_FIXED)
00196     currentStepSize_ = requestedStepSize_;
00197   else
00198     currentStepSize_ = nextStepSize_;
00199 
00200   currentOrder_ = nextOrder_;
00201 
00202   // Limit the step size to the requested step size
00203   currentStepSize_ = std::min(requestedStepSize_, currentStepSize_);
00204 
00205   *stepSize = currentStepSize_;
00206   *stepSizeType = stepSizeType_;
00207   *order = currentOrder_;
00208 
00209   if (stepControlState_ != MID_STEP) {
00210     setStepControlState_(MID_STEP);
00211   }
00212 
00213   // Output
00214   if (doOutput_(Teuchos::VERB_MEDIUM)){
00215     Teuchos::FancyOStream& out = *this->getOStream();
00216     Teuchos::OSTab ostab1(out,2,"** nextStepSize_ **");
00217     out << "Values returned to stepper:" << std::endl;
00218     Teuchos::OSTab ostab2(out,2,"** nextStepSize_ **");
00219     out << "currentStepSize_ = " << currentStepSize_ << std::endl;
00220     out << "currentOrder_ = " << currentOrder_ << std::endl;
00221     out << "requestedStepSize_ = " << requestedStepSize_ << std::endl;
00222   }
00223 
00224 }
00225 
00226 template<class Scalar>
00227 void ImplicitBDFStepperRampingStepControl<Scalar>::setCorrection(
00228      const StepperBase<Scalar>& stepper
00229     ,const RCP<const Thyra::VectorBase<Scalar> >& soln
00230     ,const RCP<const Thyra::VectorBase<Scalar> >& ee
00231     ,int solveStatus)
00232 {
00233   TEUCHOS_TEST_FOR_EXCEPT(stepControlState_ != MID_STEP);
00234 
00235   TEUCHOS_TEST_FOR_EXCEPTION(is_null(ee), std::logic_error,
00236     "Error, ee == Teuchos::null!\n");
00237 
00238   ee_ = ee;
00239 
00240   newtonConvergenceStatus_ = solveStatus;
00241 
00242   if ( doOutput_(Teuchos::VERB_MEDIUM)  && newtonConvergenceStatus_ < 0) {
00243     RCP<Teuchos::FancyOStream> out = this->getOStream();
00244     Teuchos::OSTab ostab(out,1,"setCorrection");
00245     *out << "\nImplicitBDFStepperRampingStepControl::setCorrection(): "
00246          << "Nonlinear Solver Failed!\n";
00247   }
00248 
00249   setStepControlState_(AFTER_CORRECTION);
00250 }
00251 
00252 template<class Scalar>
00253 bool ImplicitBDFStepperRampingStepControl<Scalar>::acceptStep(
00254   const StepperBase<Scalar>& stepper, Scalar* LETValue)
00255 {
00256   using Teuchos::as;
00257   typedef Teuchos::ScalarTraits<Scalar> ST;
00258 
00259   TEUCHOS_TEST_FOR_EXCEPT(stepControlState_ != AFTER_CORRECTION);
00260 
00261 
00262   if ( doOutput_(Teuchos::VERB_HIGH) ) {
00263     RCP<Teuchos::FancyOStream> out = this->getOStream();
00264     Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
00265     Teuchos::OSTab ostab(out,1,"acceptStep");
00266     *out << "ee_ = " << std::endl;
00267     ee_->describe(*out,verbLevel);
00268     *out << "errWtVec_ = " << std::endl;
00269     errWtVec_->describe(*out,verbLevel);
00270   }
00271 
00272   Scalar enorm = wRMSNorm_(*errWtVec_,*ee_);
00273 
00274   Scalar LET = ck_ * enorm;
00275 
00276   if (LETValue) {
00277     *LETValue = LET;
00278     *LETValue = Scalar(0.0);
00279   }
00280 
00281   if (newtonConvergenceStatus_ < 0)
00282     return false;
00283 
00284   bool return_status = false;
00285 
00286   if (LET < ST::one() || !useLETToDetermineConvergence_)
00287     return_status = true;
00288 
00289   if ( doOutput_(Teuchos::VERB_HIGH) ) {
00290     RCP<Teuchos::FancyOStream> out = this->getOStream();
00291     Teuchos::OSTab ostab(out,1,"acceptStep");
00292     *out << "return_status = " << return_status << std::endl;
00293     *out << "Local Truncation Error Check: (ck*enorm) < 1:  (" << LET
00294          << ") <?= 1" << std::endl;
00295     if ( doOutput_(Teuchos::VERB_EXTREME) ) {
00296       *out << "ck_ = " << ck_ << std::endl;
00297       *out << "enorm = " << enorm << std::endl;
00298     }
00299   }
00300 
00301   return(return_status);
00302 }
00303 
00304 template<class Scalar>
00305 void ImplicitBDFStepperRampingStepControl<Scalar>::completeStep(
00306   const StepperBase<Scalar>& stepper)
00307 {
00308   TEUCHOS_TEST_FOR_EXCEPT(stepControlState_ != AFTER_CORRECTION);
00309   using Teuchos::as;
00310   typedef Teuchos::ScalarTraits<Scalar> ST;
00311 
00312   if ( doOutput_(Teuchos::VERB_HIGH) ) {
00313     RCP<Teuchos::FancyOStream> out = this->getOStream();
00314 
00315     Teuchos::OSTab ostab1(out,2,"completeStep_");
00316     *out << "\n** Begin completeStep() **" << std::endl;
00317     Teuchos::OSTab ostab2(out,2,"** Begin completeStep_ **");
00318     *out << "numberOfSteps_ = " << numberOfSteps_ << std::endl;
00319     *out << "numConstantSteps_ = " << numConstantSteps_ << std::endl;
00320     *out << "currentStepSize_ = " << currentStepSize_ << std::endl;
00321     *out << "nextStepSize_ = " << nextStepSize_ << std::endl;
00322     *out << "currentOrder_ = " << currentOrder_ << std::endl;
00323     *out << "nextOrder_ = " << nextOrder_ << std::endl;
00324     *out << "stepSizeIncreaseFactor_ = " << stepSizeIncreaseFactor_ <<std::endl;
00325     *out << "countOfConstantStepsAfterFailure_ = "
00326          << countOfConstantStepsAfterFailure_ << std::endl;
00327   }
00328 
00329   numberOfSteps_ ++;
00330 
00331   if (countOfConstantStepsAfterFailure_ > 0) {
00332     // We track the number of consecutive time step failures so that
00333     // if we have a bunch of nonlinear failures, lets keep the time
00334     // step constant for a while before we start to ramp again.  This
00335     // keeps us from oscillating between ramping and cutting step
00336     // sizes and wasting resources.
00337 
00338     nextStepSize_ = currentStepSize_;
00339     nextOrder_ = currentOrder_;
00340 
00341     // Decrement failure counter
00342     countOfConstantStepsAfterFailure_ =
00343       std::max( (countOfConstantStepsAfterFailure_ - 1), 0);
00344 
00345     if ( doOutput_(Teuchos::VERB_HIGH) ) {
00346       RCP<Teuchos::FancyOStream> out = this->getOStream();
00347       Teuchos::OSTab ostab(out,1,"completeStep_");
00348       *out << "\nNext Step Size held constant due to previous failed steps!\n";
00349       *out << "countOfConstantStepsAfterFailure_ = "
00350            << countOfConstantStepsAfterFailure_ << std::endl;
00351     }
00352   }
00353   else {
00354 
00355     // Phase 1: Constant step size at 1st order
00356     if (numberOfSteps_ < numConstantSteps_) {
00357       if (currentStepSize_ <  initialStepSize_)
00358         nextStepSize_ = std::min(initialStepSize_,
00359                                  currentStepSize_ * stepSizeIncreaseFactor_);
00360       nextOrder_ = 1;
00361     }
00362     // Phase 2: Constant step size, ramping the order
00363     else if (currentOrder_ < maxOrder_) {
00364       if (currentStepSize_ <  initialStepSize_)
00365         nextStepSize_ = std::min(initialStepSize_,
00366                                  currentStepSize_ * stepSizeIncreaseFactor_);
00367       else
00368         nextStepSize_ = currentStepSize_;
00369 
00370       nextOrder_ = currentOrder_ + 1;
00371     }
00372     // Phase 3: Ramping dt to max step size, highest order
00373     else if ( (numberOfSteps_ >= numConstantSteps_) &&
00374               (currentOrder_ == maxOrder_)             ) {
00375       nextStepSize_ = std::min(maxStepSize_,
00376                                currentStepSize_ * stepSizeIncreaseFactor_);
00377       nextOrder_ = maxOrder_;
00378     }
00379     else {
00380       TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
00381         "RampingStepControlStrategy logic is broken. Please contact "
00382         "developers. Aborting run!");
00383     }
00384 
00385     if (restrictStepSizeByNumberOfNonlinearIterations_) {
00386       const Rythmos::ImplicitBDFStepper<Scalar>* ibdfStepper =
00387   dynamic_cast<const Rythmos::ImplicitBDFStepper<Scalar>* >(&stepper);
00388       TEUCHOS_ASSERT(ibdfStepper != NULL);
00389       TEUCHOS_ASSERT(nonnull(ibdfStepper->getNonlinearSolveStatus().extraParameters));
00390       int numberOfNonlinearIterations = ibdfStepper->getNonlinearSolveStatus().extraParameters->template get<int>("Number of Iterations");
00391       if (numberOfNonlinearIterations >= numberOfNonlinearIterationsForStepSizeRestriction_) {
00392   nextStepSize_ = currentStepSize_;
00393       }
00394     }
00395 
00396 
00397   } // if (countOfConstantStepsAfterFailure_ > 0)
00398 
00399   setStepControlState_(READY_FOR_NEXT_STEP);
00400 
00401   if ( doOutput_(Teuchos::VERB_HIGH) ) {
00402     RCP<Teuchos::FancyOStream> out = this->getOStream();
00403     Teuchos::OSTab ostab1(out,2,"** completeStep_ **");
00404     *out << "** End of completeStep() **" << std::endl;
00405     Teuchos::OSTab ostab2(out,2,"** End completeStep_ **");
00406     *out << "numberOfSteps_ = " << numberOfSteps_ << std::endl;
00407     *out << "numConstantSteps_ = " << numConstantSteps_ << std::endl;
00408     *out << "currentStepSize_ = " << currentStepSize_ << std::endl;
00409     *out << "nextStepSize_ = " << nextStepSize_ << std::endl;
00410     *out << "currentOrder_ = " << currentOrder_ << std::endl;
00411     *out << "nextOrder_ = " << nextOrder_ << std::endl;
00412     *out << "stepSizeIncreaseFactor_ = " << stepSizeIncreaseFactor_ <<std::endl;
00413     *out << "countOfConstantStepsAfterFailure_ = "
00414          << countOfConstantStepsAfterFailure_ << std::endl;
00415   }
00416 }
00417 
00418 template<class Scalar>
00419 AttemptedStepStatusFlag
00420 ImplicitBDFStepperRampingStepControl<Scalar>::rejectStep(
00421   const StepperBase<Scalar>& stepper)
00422 {
00423   TEUCHOS_TEST_FOR_EXCEPT(stepControlState_ != AFTER_CORRECTION);
00424 
00425   using Teuchos::as;
00426 
00427   ++totalNumberOfFailedSteps_;
00428   ++countOfConstantStepsAfterFailure_;
00429 
00430   // If time step size is already at the min time step, then quit
00431   if (currentStepSize_ <= minStepSize_)
00432     return (REP_ERR_FAIL);
00433 
00434   // Otherwise, cut the time step and keep order the same
00435   nextStepSize_ = std::max(minStepSize_,
00436                            (currentStepSize_ * stepSizeDecreaseFactor_) );
00437 
00438   setStepControlState_(READY_FOR_NEXT_STEP);
00439 
00440   return(PREDICT_AGAIN);
00441 }
00442 
00443 template<class Scalar>
00444 void ImplicitBDFStepperRampingStepControl<Scalar>::describe(
00445   Teuchos::FancyOStream &out,
00446   const Teuchos::EVerbosityLevel verbLevel
00447   ) const
00448 {
00449 
00450   using Teuchos::as;
00451 
00452   if ( (as<int>(verbLevel) == as<int>(Teuchos::VERB_DEFAULT) ) ||
00453     (as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW)     )
00454     ) {
00455     out << this->description() << "::describe" << std::endl;
00456   }
00457   else if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW)) {
00458     out << "currentStepSize_ = " << currentStepSize_ << std::endl;
00459     out << "currentOrder_ = " << currentOrder_ << std::endl;
00460   }
00461   else if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_MEDIUM)) {
00462   }
00463   else if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH)) {
00464     out << "ee_ = ";
00465     if (ee_ == Teuchos::null) {
00466       out << "Teuchos::null" << std::endl;
00467     } else {
00468       ee_->describe(out,verbLevel);
00469     }
00470     out << "delta_ = ";
00471     if (delta_ == Teuchos::null) {
00472       out << "Teuchos::null" << std::endl;
00473     } else {
00474       delta_->describe(out,verbLevel);
00475     }
00476     out << "errWtVec_ = ";
00477     if (errWtVec_ == Teuchos::null) {
00478       out << "Teuchos::null" << std::endl;
00479     } else {
00480       errWtVec_->describe(out,verbLevel);
00481     }
00482   }
00483 }
00484 
00485 template<class Scalar>
00486 void ImplicitBDFStepperRampingStepControl<Scalar>::setParameterList(
00487   RCP<Teuchos::ParameterList> const& paramList
00488   )
00489 {
00490 
00491   using Teuchos::as;
00492   typedef Teuchos::ScalarTraits<Scalar> ST;
00493 
00494   TEUCHOS_TEST_FOR_EXCEPT(paramList == Teuchos::null);
00495 
00496   parameterList_ = Teuchos::parameterList(*paramList);
00497 
00498   parameterList_->validateParametersAndSetDefaults(*this->getValidParameters());
00499 
00500   Teuchos::ParameterList& p = *parameterList_;
00501 
00502   numConstantSteps_ = p.get<int>("Number of Constant First Order Steps");
00503   initialStepSize_ = p.get<Scalar>("Initial Step Size");
00504   minStepSize_ = p.get<Scalar>("Min Step Size");
00505   maxStepSize_ = p.get<Scalar>("Max Step Size");
00506   stepSizeIncreaseFactor_ = p.get<Scalar>("Step Size Increase Factor");
00507   stepSizeDecreaseFactor_ = p.get<Scalar>("Step Size Decrease Factor");
00508 
00509   minOrder_ = p.get<int>("Min Order");
00510   TEUCHOS_TEST_FOR_EXCEPTION(
00511       !((1 <= minOrder_) && (minOrder_ <= 5)), std::logic_error,
00512       "Error, minOrder_ = " << minOrder_ << " is not in range [1,5]!\n"
00513       );
00514   maxOrder_ = p.get<int>("Max Order");
00515   TEUCHOS_TEST_FOR_EXCEPTION(
00516       !((1 <= maxOrder_) && (maxOrder_ <= 5)), std::logic_error,
00517       "Error, maxOrder_ = " << maxOrder_ << " is not in range [1,5]!\n"
00518       );
00519 
00520   absErrTol_ = p.get<Scalar>("Absolute Error Tolerance");
00521   relErrTol_ = p.get<Scalar>("Relative Error Tolerance");
00522 
00523   {
00524     std::string let_acceptance =
00525       p.get<std::string>("Use LET To Determine Step Acceptance");
00526     useLETToDetermineConvergence_ = (let_acceptance == "TRUE");
00527 
00528     // Currently the using LET for step acceptance is not supported
00529     // since we can't calculate the LETValue. Once this is
00530     // implemented, delete the line below.
00531     TEUCHOS_TEST_FOR_EXCEPTION(useLETToDetermineConvergence_, std::logic_error,
00532       "Error - the flag \"Use LET To Determine Step Acceptance\" is set to "
00533       "\"TRUE\" but the local error computation is currently not supported.  "
00534       "Please set this flag to \"FALSE\" for now.");
00535   }
00536 
00537   if (p.get<std::string>("Restrict Step Size Increase by Number of Nonlinear Iterations") == "TRUE")
00538     restrictStepSizeByNumberOfNonlinearIterations_ = true;
00539   else if (p.get<std::string>("Restrict Step Size Increase by Number of Nonlinear Iterations") == "FALSE") 
00540     restrictStepSizeByNumberOfNonlinearIterations_ = false;
00541     
00542   numberOfNonlinearIterationsForStepSizeRestriction_ = 
00543     p.get<int>("Number of Nonlinear Iterations for Step Size Restriction");
00544 
00545   if ( doOutput_(Teuchos::VERB_HIGH) ) {
00546     RCP<Teuchos::FancyOStream> out = this->getOStream();
00547     Teuchos::OSTab ostab(out,1,"setParameterList");
00548     out->precision(15);
00549     *out << "minOrder_ = " << minOrder_ << std::endl;
00550     *out << "maxOrder_ = " << maxOrder_ << std::endl;
00551     *out << "relErrTol_  = " << relErrTol_  << std::endl;
00552     *out << "absErrTol_  = " << absErrTol_  << std::endl;
00553     *out << "stepSizeType = " << stepSizeType_  << std::endl;
00554     *out << "stopTime_  = " << stopTime_  << std::endl;
00555   }
00556 
00557 }
00558 
00559 template<class Scalar>
00560 RCP<const Teuchos::ParameterList>
00561 ImplicitBDFStepperRampingStepControl<Scalar>::getValidParameters() const
00562 {
00563   using Teuchos::RCP;
00564   using Teuchos::rcp;
00565   using Teuchos::ParameterList;
00566 
00567   static RCP<ParameterList> p;
00568 
00569   if (is_null(p)) {
00570 
00571     p = rcp(new ParameterList);
00572 
00573     p->set<int>("Number of Constant First Order Steps", 10,
00574       "Number of constant steps to take before handing control to "
00575       "variable stepper.");
00576     p->set<Scalar>("Initial Step Size", Scalar(1.0e-3),
00577       "Initial time step size and target step size to take during the "
00578       "initial constant step phase (could be reduced due to step failures).");
00579     p->set<Scalar>("Min Step Size", Scalar(1.0e-7), "Minimum time step size.");
00580     p->set<Scalar>("Max Step Size", Scalar(1.0), "Maximum time step size.");
00581     p->set<Scalar>("Step Size Increase Factor", Scalar(1.2),
00582       "Time step growth factor used after a successful time step. dt_{n+1} = "
00583       "(increase factor) * dt_n");
00584     p->set<Scalar>("Step Size Decrease Factor", Scalar(0.5),
00585       "Time step reduction factor used for a failed time step. dt_{n+1} = "
00586       "(decrease factor) * dt_n");
00587     p->set<int>("Min Order", 1, "Minimum order to run at.");
00588     p->set<int>("Max Order", 5, "Maximum order to run at.");
00589     p->set<Scalar>("Absolute Error Tolerance", Scalar(1.0e-5),
00590       "abstol value used in WRMS calculation.");
00591     p->set<Scalar>("Relative Error Tolerance", Scalar(1.0e-3),
00592       "reltol value used in WRMS calculation.");
00593     Teuchos::setStringToIntegralParameter<int>(
00594       "Use LET To Determine Step Acceptance",
00595       "FALSE",
00596       "If set to TRUE, then acceptance of step dependes on LET in addition "
00597       "to Nonlinear solver converging.",
00598       Teuchos::tuple<std::string>("TRUE","FALSE"),
00599       p.get());
00600     Teuchos::setStringToIntegralParameter<int>(
00601       "Restrict Step Size Increase by Number of Nonlinear Iterations",
00602       "FALSE",
00603       "If set to TRUE, then the step size will not be allowed to increase "
00604       "if the number of nonlinear iterations was greater than or equal to the "
00605       "specified value.",
00606       Teuchos::tuple<std::string>("TRUE","FALSE"),
00607       p.get());
00608     p->set<int>("Number of Nonlinear Iterations for Step Size Restriction",
00609     2,
00610     "If \" Restrct Step Size Increase by Number of Nonlinear Iterations\" is "
00611                 "true, the step size will not be allowed to increase if the number of nonlinear "
00612     "iterations was greater than or equal to the specified value.");
00613   }
00614 
00615   return (p);
00616 }
00617 
00618 template<class Scalar>
00619 RCP<Teuchos::ParameterList>
00620 ImplicitBDFStepperRampingStepControl<Scalar>::unsetParameterList()
00621 {
00622   RCP<Teuchos::ParameterList> temp_param_list = parameterList_;
00623   parameterList_ = Teuchos::null;
00624   return(temp_param_list);
00625 }
00626 
00627 template<class Scalar>
00628 RCP<Teuchos::ParameterList>
00629 ImplicitBDFStepperRampingStepControl<Scalar>::getNonconstParameterList()
00630 {
00631   return(parameterList_);
00632 }
00633 
00634 template<class Scalar>
00635 void ImplicitBDFStepperRampingStepControl<Scalar>::setStepControlData(
00636   const StepperBase<Scalar>& stepper)
00637 {
00638   if (stepControlState_ == UNINITIALIZED) {
00639     initialize(stepper);
00640   }
00641   const ImplicitBDFStepper<Scalar>& bdfstepper =
00642     Teuchos::dyn_cast<const ImplicitBDFStepper<Scalar> >(stepper);
00643   int desiredOrder = bdfstepper.getOrder();
00644   TEUCHOS_TEST_FOR_EXCEPT(!((1 <= desiredOrder) &&
00645                             (desiredOrder <= maxOrder_)));
00646   if (stepControlState_ == BEFORE_FIRST_STEP) {
00647     TEUCHOS_TEST_FOR_EXCEPTION(
00648         desiredOrder > 1,
00649         std::logic_error,
00650         "Error, this ImplicitBDF stepper has not taken a step yet, so it "
00651         "cannot take a step of order " << desiredOrder << " > 1!\n");
00652   }
00653   TEUCHOS_TEST_FOR_EXCEPT(!(desiredOrder <= currentOrder_+1));
00654   currentOrder_ = desiredOrder;
00655 
00656   if ( doOutput_(Teuchos::VERB_EXTREME) ) {
00657     RCP<Teuchos::FancyOStream> out = this->getOStream();
00658     Teuchos::OSTab ostab(out,1,"setStepControlData");
00659     *out << "currentOrder_ = " << currentOrder_ << std::endl;
00660   }
00661 }
00662 
00663 template<class Scalar>
00664 bool ImplicitBDFStepperRampingStepControl<Scalar>::supportsCloning() const
00665 {
00666   return true;
00667 }
00668 
00669 
00670 template<class Scalar>
00671 RCP<StepControlStrategyBase<Scalar> >
00672 ImplicitBDFStepperRampingStepControl<Scalar>::cloneStepControlStrategyAlgorithm() const
00673 {
00674 
00675   RCP<ImplicitBDFStepperRampingStepControl<Scalar> > stepControl =
00676     rcp(new ImplicitBDFStepperRampingStepControl<Scalar>());
00677 
00678   if (!is_null(parameterList_)) {
00679     stepControl->setParameterList(parameterList_);
00680   }
00681 
00682   return stepControl;
00683 }
00684 
00685 template<class Scalar>
00686 void ImplicitBDFStepperRampingStepControl<Scalar>::setErrWtVecCalc(
00687   const RCP<ErrWtVecCalcBase<Scalar> >& errWtVecCalc)
00688 {
00689   TEUCHOS_TEST_FOR_EXCEPT(is_null(errWtVecCalc));
00690   errWtVecCalc_ = errWtVecCalc;
00691 }
00692 
00693 template<class Scalar>
00694 RCP<const ErrWtVecCalcBase<Scalar> >
00695 ImplicitBDFStepperRampingStepControl<Scalar>::getErrWtVecCalc() const
00696 {
00697   return(errWtVecCalc_);
00698 }
00699 
00700 template<class Scalar>
00701 Scalar ImplicitBDFStepperRampingStepControl<Scalar>::wRMSNorm_(
00702     const Thyra::VectorBase<Scalar>& weight,
00703     const Thyra::VectorBase<Scalar>& vector) const
00704 {
00705   return(norm_2(weight,vector));
00706 }
00707 
00708 template<class Scalar>
00709 int ImplicitBDFStepperRampingStepControl<Scalar>::getMinOrder() const
00710 {
00711   TEUCHOS_TEST_FOR_EXCEPTION(
00712       stepControlState_ == UNINITIALIZED, std::logic_error,
00713       "Error, attempting to call getMinOrder before intiialization!\n"
00714       );
00715   return(minOrder_);
00716 }
00717 
00718 template<class Scalar>
00719 int ImplicitBDFStepperRampingStepControl<Scalar>::getMaxOrder() const
00720 {
00721   TEUCHOS_TEST_FOR_EXCEPTION(
00722       stepControlState_ == UNINITIALIZED, std::logic_error,
00723       "Error, attempting to call getMaxOrder before initialization!\n"
00724       );
00725   return(maxOrder_);
00726 }
00727 
00728 template<class Scalar>
00729 bool ImplicitBDFStepperRampingStepControl<Scalar>::doOutput_(
00730   Teuchos::EVerbosityLevel verbLevel)
00731 {
00732   Teuchos::EVerbosityLevel currentObjectVerbLevel = this->getVerbLevel();
00733 
00734   if ( Teuchos::as<int>(currentObjectVerbLevel) >= Teuchos::as<int>(verbLevel) )
00735     return true;
00736 
00737   return false;
00738 }
00739 
00740 template<class Scalar>
00741 int ImplicitBDFStepperRampingStepControl<Scalar>::numberOfSteps() const
00742 {
00743   return numberOfSteps_;
00744 }
00745 
00746 template<class Scalar>
00747 int ImplicitBDFStepperRampingStepControl<Scalar>::numberOfFailedSteps() const
00748 {
00749   return totalNumberOfFailedSteps_;
00750 }
00751 
00752 template<class Scalar>
00753 Scalar ImplicitBDFStepperRampingStepControl<Scalar>::currentStepSize() const
00754 {
00755   return currentStepSize_;
00756 }
00757 
00758 template<class Scalar>
00759 int ImplicitBDFStepperRampingStepControl<Scalar>::currentOrder() const
00760 {
00761   return currentOrder_;
00762 }
00763 
00764 
00765 //
00766 // Explicit Instantiation macro
00767 //
00768 // Must be expanded from within the Rythmos namespace!
00769 //
00770 
00771 #define RYTHMOS_IMPLICITBDF_STEPPER_RAMPING_STEPCONTROL_INSTANT(SCALAR) \
00772   template class ImplicitBDFStepperRampingStepControl< SCALAR >;
00773 
00774 
00775 } // namespace Rythmos
00776 #endif // Rythmos_IMPLICITBDF_STEPPER_RAMPING_STEP_CONTROL_DEF_H
00777 
 All Classes Functions Variables Typedefs Friends