|
Rythmos - Transient Integration for Differential Equations
Version of the Day
|
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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
1.7.6.1