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