|
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., 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_DEF_H 00030 #define Rythmos_IMPLICITBDF_STEPPER_DEF_H 00031 00032 #include "Rythmos_ImplicitBDFStepper_decl.hpp" 00033 #include "Rythmos_StepperHelpers.hpp" 00034 #include "Rythmos_ImplicitBDFStepperStepControl.hpp" 00035 00036 namespace Rythmos { 00037 00038 // //////////////////////////// 00039 // Defintions 00040 00041 // Nonmember constructor 00042 template<class Scalar> 00043 RCP<ImplicitBDFStepper<Scalar> > implicitBDFStepper() { 00044 RCP<ImplicitBDFStepper<Scalar> > stepper = rcp(new ImplicitBDFStepper<Scalar>() ); 00045 return stepper; 00046 } 00047 00048 template<class Scalar> 00049 RCP<ImplicitBDFStepper<Scalar> > implicitBDFStepper( 00050 const RCP<Thyra::ModelEvaluator<Scalar> >& model, 00051 const RCP<Thyra::NonlinearSolverBase<Scalar> >& solver, 00052 const RCP<Teuchos::ParameterList>& parameterList 00053 ) 00054 { 00055 RCP<ImplicitBDFStepper<Scalar> > stepper = Teuchos::rcp(new ImplicitBDFStepper<Scalar>(model,solver,parameterList)); 00056 return stepper; 00057 } 00058 00059 // Constructors, intializers, Misc. 00060 00061 00062 template<class Scalar> 00063 ImplicitBDFStepper<Scalar>::ImplicitBDFStepper() 00064 { 00065 this->defaultInitializeAll_(); 00066 haveInitialCondition_ = false; 00067 isInitialized_=false; 00068 } 00069 00070 00071 template<class Scalar> 00072 ImplicitBDFStepper<Scalar>::ImplicitBDFStepper( 00073 const RCP<Thyra::ModelEvaluator<Scalar> >& model 00074 ,const RCP<Thyra::NonlinearSolverBase<Scalar> >& solver 00075 ,const RCP<Teuchos::ParameterList>& parameterList 00076 ) 00077 { 00078 this->defaultInitializeAll_(); 00079 this->setParameterList(parameterList); 00080 // Now we instantiate the model and the solver 00081 setModel(model); 00082 setSolver(solver); 00083 haveInitialCondition_ = false; 00084 isInitialized_=false; 00085 } 00086 00087 00088 template<class Scalar> 00089 ImplicitBDFStepper<Scalar>::ImplicitBDFStepper( 00090 const RCP<Thyra::ModelEvaluator<Scalar> >& model 00091 ,const RCP<Thyra::NonlinearSolverBase<Scalar> >& solver 00092 ) 00093 { 00094 this->defaultInitializeAll_(); 00095 // Now we instantiate the model and the solver 00096 setModel(model); 00097 setSolver(solver); 00098 haveInitialCondition_ = false; 00099 isInitialized_=false; 00100 } 00101 00102 template<class Scalar> 00103 const Thyra::VectorBase<Scalar>& 00104 ImplicitBDFStepper<Scalar>::getxHistory(int index) const 00105 { 00106 TEST_FOR_EXCEPTION(!isInitialized_,std::logic_error, 00107 "Error, attempting to call getxHistory before initialization!\n"); 00108 TEST_FOR_EXCEPT( !(( 0 <= index ) && ( index <= maxOrder_ )) ); 00109 TEST_FOR_EXCEPT( !( index <= usedOrder_+1 ) ); 00110 return(*(xHistory_[index])); 00111 } 00112 00113 template<class Scalar> 00114 void ImplicitBDFStepper<Scalar>::setStepControlStrategy(const RCP<StepControlStrategyBase<Scalar> >& stepControl) 00115 { 00116 TEST_FOR_EXCEPTION(stepControl == Teuchos::null,std::logic_error,"Error, stepControl == Teuchos::null!\n"); 00117 stepControl_ = stepControl; 00118 } 00119 00120 template<class Scalar> 00121 RCP<StepControlStrategyBase<Scalar> > ImplicitBDFStepper<Scalar>::getNonconstStepControlStrategy() 00122 { 00123 return(stepControl_); 00124 } 00125 00126 template<class Scalar> 00127 RCP<const StepControlStrategyBase<Scalar> > ImplicitBDFStepper<Scalar>::getStepControlStrategy() const 00128 { 00129 return(stepControl_); 00130 } 00131 00132 00133 // Overridden from SolverAcceptingStepperBase 00134 00135 00136 template<class Scalar> 00137 void ImplicitBDFStepper<Scalar>::setSolver(const RCP<Thyra::NonlinearSolverBase<Scalar> > &solver) 00138 { 00139 TEST_FOR_EXCEPT(solver == Teuchos::null) 00140 solver_ = solver; 00141 } 00142 00143 00144 template<class Scalar> 00145 RCP<Thyra::NonlinearSolverBase<Scalar> > 00146 ImplicitBDFStepper<Scalar>::getNonconstSolver() 00147 { 00148 return (solver_); 00149 } 00150 00151 00152 template<class Scalar> 00153 RCP<const Thyra::NonlinearSolverBase<Scalar> > 00154 ImplicitBDFStepper<Scalar>::getSolver() const 00155 { 00156 return (solver_); 00157 } 00158 00159 00160 // Overridden from StepperBase 00161 00162 00163 template<class Scalar> 00164 bool ImplicitBDFStepper<Scalar>::isImplicit() const 00165 { 00166 return true; 00167 } 00168 00169 template<class Scalar> 00170 bool ImplicitBDFStepper<Scalar>::supportsCloning() const 00171 { 00172 return true; 00173 } 00174 00175 00176 template<class Scalar> 00177 RCP<StepperBase<Scalar> > 00178 ImplicitBDFStepper<Scalar>::cloneStepperAlgorithm() const 00179 { 00180 00181 // Just use the interface to clone the algorithm in an basically 00182 // uninitialized state 00183 00184 RCP<ImplicitBDFStepper<Scalar> > 00185 stepper = Teuchos::rcp(new ImplicitBDFStepper<Scalar>()); 00186 00187 if (!is_null(model_)) 00188 stepper->setModel(model_); // Shallow copy is okay! 00189 00190 if (!is_null(solver_)) 00191 stepper->setSolver(solver_->cloneNonlinearSolver().assert_not_null()); 00192 00193 if (!is_null(parameterList_)) 00194 stepper->setParameterList(Teuchos::parameterList(*parameterList_)); 00195 00196 if (!is_null(stepControl_)) { 00197 if (stepControl_->supportsCloning()) 00198 stepper->setStepControlStrategy( 00199 stepControl_->cloneStepControlStrategyAlgorithm().assert_not_null()); 00200 } 00201 00202 // At this point, we should have a valid algorithm state. What might be 00203 // missing is the initial condition if it was not given in *model_ but was 00204 // set explicitly. However, the specification for this function does not 00205 // guarantee that the full state will be copied in any case! 00206 00207 return stepper; 00208 00209 } 00210 00211 00212 template<class Scalar> 00213 void ImplicitBDFStepper<Scalar>::setModel( 00214 const RCP<const Thyra::ModelEvaluator<Scalar> >& model 00215 ) 00216 { 00217 typedef Teuchos::ScalarTraits<Scalar> ST; 00218 TEST_FOR_EXCEPT( is_null(model) ); 00219 assertValidModel( *this, *model ); 00220 model_ = model; 00221 } 00222 00223 template<class Scalar> 00224 void ImplicitBDFStepper<Scalar>::setNonconstModel( 00225 const RCP<Thyra::ModelEvaluator<Scalar> >& model 00226 ) 00227 { 00228 this->setModel(model); // TODO 09/09/09 tscoffe: use ConstNonconstObjectContainer! 00229 } 00230 00231 00232 template<class Scalar> 00233 RCP<const Thyra::ModelEvaluator<Scalar> > 00234 ImplicitBDFStepper<Scalar>::getModel() const 00235 { 00236 return model_; 00237 } 00238 00239 00240 template<class Scalar> 00241 RCP<Thyra::ModelEvaluator<Scalar> > 00242 ImplicitBDFStepper<Scalar>::getNonconstModel() 00243 { 00244 return Teuchos::null; 00245 } 00246 00247 00248 template<class Scalar> 00249 void ImplicitBDFStepper<Scalar>::setInitialCondition( 00250 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &initialCondition 00251 ) 00252 { 00253 typedef Teuchos::ScalarTraits<Scalar> ST; 00254 typedef Thyra::ModelEvaluatorBase MEB; 00255 TEST_FOR_EXCEPT(is_null(initialCondition.get_x())); 00256 TEST_FOR_EXCEPT(is_null(initialCondition.get_x_dot())); 00257 basePoint_ = initialCondition; 00258 xn0_ = initialCondition.get_x()->clone_v(); 00259 xpn0_ = initialCondition.get_x_dot()->clone_v(); 00260 time_ = initialCondition.get_t(); 00261 // Generate vectors for use in calculations 00262 x_dot_base_ = createMember(xpn0_->space()); 00263 V_S(x_dot_base_.ptr(),ST::zero()); 00264 ee_ = createMember(xn0_->space()); 00265 V_S(ee_.ptr(),ST::zero()); 00266 // x history 00267 xHistory_.clear(); 00268 xHistory_.push_back(xn0_->clone_v()); 00269 xHistory_.push_back(xpn0_->clone_v()); 00270 00271 haveInitialCondition_ = true; 00272 if (isInitialized_) { 00273 initialize_(); 00274 } 00275 } 00276 00277 00278 template<class Scalar> 00279 Thyra::ModelEvaluatorBase::InArgs<Scalar> 00280 ImplicitBDFStepper<Scalar>::getInitialCondition() const 00281 { 00282 return basePoint_; 00283 } 00284 00285 00286 template<class Scalar> 00287 Scalar ImplicitBDFStepper<Scalar>::takeStep(Scalar dt, StepSizeType stepType) 00288 { 00289 00290 #ifdef ENABLE_RYTHMOS_TIMERS 00291 TEUCHOS_FUNC_TIME_MONITOR("Rythmos::ImplicitBDFStepper::takeStep"); 00292 #endif 00293 00294 using Teuchos::as; 00295 using Teuchos::incrVerbLevel; 00296 typedef Teuchos::ScalarTraits<Scalar> ST; 00297 typedef typename Thyra::ModelEvaluatorBase::InArgs<Scalar>::ScalarMag TScalarMag; 00298 typedef Thyra::NonlinearSolverBase<Scalar> NSB; 00299 typedef Teuchos::VerboseObjectTempState<NSB> VOTSNSB; 00300 00301 RCP<Teuchos::FancyOStream> out = this->getOStream(); 00302 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel(); 00303 Teuchos::OSTab ostab(out,1,"takeStep"); 00304 VOTSNSB solver_outputTempState(solver_,out,incrVerbLevel(verbLevel,-1)); 00305 00306 if ( !is_null(out) && as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW) ) { 00307 *out 00308 << "\nEntering " << this->Teuchos::Describable::description() 00309 << "::takeStep("<<dt<<","<<toString(stepType)<<") ...\n"; 00310 } 00311 00312 if (!isInitialized_) { 00313 initialize_(); 00314 } 00315 00316 stepControl_->setOStream(out); 00317 stepControl_->setVerbLevel(verbLevel); 00318 stepControl_->setRequestedStepSize(*this,dt,stepType); 00319 00320 AttemptedStepStatusFlag status; 00321 while (1) { 00322 // Set up problem coefficients (and handle first step) 00323 Scalar hh_old = hh_; 00324 int desiredOrder; 00325 stepControl_->nextStepSize(*this,&hh_,&stepType,&desiredOrder); 00326 TEST_FOR_EXCEPT(!((1 <= desiredOrder) && (desiredOrder <= maxOrder_))); 00327 TEST_FOR_EXCEPT(!(desiredOrder <= usedOrder_+1)); 00328 currentOrder_ = desiredOrder; 00329 if (numberOfSteps_ == 0) { 00330 psi_[0] = hh_; 00331 if (nef_ == 0) { 00332 Vt_S(xHistory_[1].ptr(),hh_); 00333 } else { 00334 Vt_S(xHistory_[1].ptr(),hh_/hh_old); 00335 } 00336 } 00337 this->updateCoeffs_(); 00338 // compute predictor 00339 obtainPredictor_(); 00340 // solve nonlinear problem (as follows) 00341 00342 // 00343 // Setup the nonlinear equations: 00344 // 00345 // f_bar( x_dot_coeff * x_bar + x_dot_base, x_coeff * x_bar + x_base, t_base ) = 0 00346 // x_dot_coeff = -alpha_s/dt 00347 // x_dot_base = x_prime_pred + (alpha_s/dt) * x_pred 00348 // x_coeff = 1 00349 // x_base = 0 00350 // t_base = tn+dt 00351 // 00352 Scalar coeff_x_dot = Scalar(-ST::one())*alpha_s_/hh_; 00353 V_StVpStV( x_dot_base_.ptr(), ST::one(), *xpn0_, alpha_s_/hh_, *xn0_ ); 00354 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_EXTREME) ) { 00355 *out << "model_ = " << std::endl; 00356 model_->describe(*out,verbLevel); 00357 *out << "basePoint_ = " << std::endl; 00358 basePoint_.describe(*out,verbLevel); 00359 *out << "coeff_x_dot = " << coeff_x_dot << std::endl; 00360 *out << "x_dot_base_ = " << std::endl; 00361 x_dot_base_->describe(*out,verbLevel); 00362 *out << "time_+hh_ = " << time_+hh_ << std::endl; 00363 *out << "xn0_ = " << std::endl; 00364 xn0_->describe(*out,verbLevel); 00365 } 00366 neModel_.initializeSingleResidualModel( 00367 model_, basePoint_, 00368 coeff_x_dot, x_dot_base_, 00369 ST::one(), Teuchos::null, 00370 time_+hh_, 00371 xn0_ 00372 ); 00373 // 00374 // Solve the implicit nonlinear system to a tolerance of ??? 00375 // 00376 if(solver_->getModel().get()!=&neModel_) { 00377 solver_->setModel( Teuchos::rcp(&neModel_,false) ); 00378 } 00379 /* // Rythmos::TimeStepNonlinearSolver uses a built in solveCriteria, so you can't pass one in. 00380 // I believe this is the correct solveCriteria for IDA though. 00381 Thyra::SolveMeasureType nonlinear_solve_measure_type(Thyra::SOLVE_MEASURE_NORM_RESIDUAL,Thyra::SOLVE_MEASURE_ONE); 00382 TScalarMag tolerance = relErrTol_/TScalarMag(10.0); // This should be changed to match the condition in IDA 00383 Thyra::SolveCriteria<Scalar> nonlinearSolveCriteria(nonlinear_solve_measure_type, tolerance); 00384 Thyra::SolveStatus<Scalar> nonlinearSolveStatus = solver_->solve( &*xn0_, &nonlinearSolveCriteria, &*delta_ ); 00385 */ 00386 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_EXTREME) ) { 00387 *out << "xn0 = " << std::endl; 00388 xn0_->describe(*out,verbLevel); 00389 *out << "ee = " << std::endl; 00390 ee_->describe(*out,verbLevel); 00391 } 00392 Thyra::SolveStatus<Scalar> nonlinearSolveStatus = solver_->solve( &*xn0_, NULL, &*ee_ ); 00393 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_EXTREME) ) { 00394 *out << "xn0 = " << std::endl; 00395 xn0_->describe(*out,verbLevel); 00396 *out << "ee = " << std::endl; 00397 ee_->describe(*out,verbLevel); 00398 } 00399 // In the above solve, on input *xn0_ is the initial guess that comes from 00400 // the predictor. On output, *xn0_ is the solved for solution and *ee_ is 00401 // the difference computed from the intial guess in *xn0_ to the final 00402 // solved value of *xn0_. This is needed for basic numerical stability. 00403 if (nonlinearSolveStatus.solveStatus == Thyra::SOLVE_STATUS_CONVERGED) { 00404 newtonConvergenceStatus_ = 0; 00405 } 00406 else { 00407 newtonConvergenceStatus_ = -1; 00408 } 00409 00410 // check error and evaluate LTE 00411 stepControl_->setCorrection(*this,xn0_,ee_,newtonConvergenceStatus_); 00412 bool stepPass = stepControl_->acceptStep(*this,&LETvalue_); 00413 00414 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) { 00415 *out << "xn0_ = " << std::endl; 00416 xn0_->describe(*out,verbLevel); 00417 *out << "xpn0_ = " << std::endl; 00418 xpn0_->describe(*out,verbLevel); 00419 *out << "ee_ = " << std::endl; 00420 ee_->describe(*out,verbLevel); 00421 for (int i=0; i<std::max(2,maxOrder_); ++i) { 00422 *out << "xHistory_[" << i << "] = " << std::endl; 00423 xHistory_[i]->describe(*out,verbLevel); 00424 } 00425 } 00426 00427 // Check LTE here: 00428 if (!stepPass) { // stepPass = false 00429 stepLETStatus_ = STEP_LET_STATUS_FAILED; 00430 status = stepControl_->rejectStep(*this); 00431 nef_++; 00432 if (status == CONTINUE_ANYWAY) { 00433 break; 00434 } else { 00435 restoreHistory_(); 00436 } 00437 } else { // stepPass = true 00438 stepLETStatus_ = STEP_LET_STATUS_PASSED; 00439 break; 00440 } 00441 } 00442 00443 // 08/22/07 the history array must be updated before stepControl_->completeStep. 00444 completeStep_(); 00445 stepControl_->completeStep(*this); 00446 00447 if ( !is_null(out) && as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW) ) { 00448 *out 00449 << "\nLeaving " << this->Teuchos::Describable::description() 00450 << "::takeStep("<<dt<<","<<toString(stepType)<<") ...\n"; 00451 } 00452 00453 return(usedStep_); 00454 00455 } 00456 00457 00458 template<class Scalar> 00459 const StepStatus<Scalar> ImplicitBDFStepper<Scalar>::getStepStatus() const 00460 { 00461 00462 // 2007/08/24: rabartl: We agreed that getStepStatus() would be free 00463 // so I have commented out removed all code that is not free 00464 00465 typedef Teuchos::ScalarTraits<Scalar> ST; 00466 StepStatus<Scalar> stepStatus; 00467 if (!isInitialized_) { 00468 stepStatus.message = "This stepper is uninitialized."; 00469 stepStatus.stepStatus = STEP_STATUS_UNINITIALIZED; 00470 stepStatus.stepSize = Scalar(-ST::one()); 00471 stepStatus.order = -1; 00472 stepStatus.time = Scalar(-ST::one()); 00473 return(stepStatus); 00474 } 00475 00476 if (numberOfSteps_ > 0) { 00477 stepStatus.stepStatus = STEP_STATUS_CONVERGED; 00478 } else { 00479 stepStatus.stepStatus = STEP_STATUS_UNKNOWN; 00480 } 00481 stepStatus.stepLETStatus = stepLETStatus_; 00482 stepStatus.stepSize = usedStep_; 00483 stepStatus.order = usedOrder_; 00484 stepStatus.time = time_; 00485 stepStatus.stepLETValue = LETvalue_; 00486 stepStatus.solution = xHistory_[0]; 00487 stepStatus.solutionDot = Teuchos::null; // This is *not* free! 00488 stepStatus.residual = Teuchos::null; // This is *not* free! 00489 00490 return(stepStatus); 00491 00492 } 00493 00494 00495 // Overridden from InterpolationBufferBase 00496 00497 00498 template<class Scalar> 00499 RCP<const Thyra::VectorSpaceBase<Scalar> > 00500 ImplicitBDFStepper<Scalar>::get_x_space() const 00501 { 00502 //TEST_FOR_EXCEPTION(!isInitialized_,std::logic_error,"Error, attempting to call get_x_space before initialization!\n"); 00503 return ( !is_null(model_) ? model_->get_x_space() : Teuchos::null ); 00504 } 00505 00506 00507 template<class Scalar> 00508 void ImplicitBDFStepper<Scalar>::addPoints( 00509 const Array<Scalar>& time_vec, 00510 const Array<RCP<const Thyra::VectorBase<Scalar> > >& x_vec, 00511 const Array<RCP<const Thyra::VectorBase<Scalar> > >& xdot_vec 00512 ) 00513 { 00514 TEST_FOR_EXCEPTION(true,std::logic_error, 00515 "Error, addPoints is not implemented for ImplicitBDFStepper.\n"); 00516 } 00517 00518 00519 template<class Scalar> 00520 TimeRange<Scalar> ImplicitBDFStepper<Scalar>::getTimeRange() const 00521 { 00522 if ( !isInitialized_ && haveInitialCondition_ ) 00523 return timeRange<Scalar>(time_,time_); 00524 if ( !isInitialized_ && !haveInitialCondition_ ) 00525 return invalidTimeRange<Scalar>(); 00526 return timeRange<Scalar>(time_-usedStep_,time_); 00527 } 00528 00529 00530 template<class Scalar> 00531 void ImplicitBDFStepper<Scalar>::getPoints( 00532 const Array<Scalar>& time_vec 00533 ,Array<RCP<const Thyra::VectorBase<Scalar> > >* x_vec 00534 ,Array<RCP<const Thyra::VectorBase<Scalar> > >* xdot_vec 00535 ,Array<ScalarMag>* accuracy_vec) const 00536 { 00537 using Teuchos::as; 00538 using Teuchos::constOptInArg; 00539 using Teuchos::null; 00540 using Teuchos::ptr; 00541 typedef Teuchos::ScalarTraits<Scalar> ST; 00542 typedef typename ST::magnitudeType mScalarMag; 00543 00544 TEUCHOS_ASSERT(haveInitialCondition_); 00545 // Only do this if we're being called pre-initialization to get the IC. 00546 if ( (numberOfSteps_ == -1) && 00547 (time_vec.length() == 1) && 00548 (compareTimeValues<Scalar>(time_vec[0],time_)==0) ) { 00549 defaultGetPoints<Scalar>( 00550 time_, constOptInArg(*xn0_), constOptInArg(*xpn0_), 00551 time_, constOptInArg(*xn0_), constOptInArg(*xpn0_), 00552 time_vec, ptr(x_vec), ptr(xdot_vec), ptr(accuracy_vec), 00553 Ptr<InterpolatorBase<Scalar> >(null) 00554 ); 00555 return; 00556 } 00557 TEUCHOS_ASSERT(isInitialized_); 00558 #ifdef ENABLE_RYTHMOS_TIMERS 00559 TEUCHOS_FUNC_TIME_MONITOR("Rythmos::ImplicitBDFStepper::getPoints"); 00560 #endif 00561 if (x_vec) 00562 x_vec->clear(); 00563 if (xdot_vec) 00564 xdot_vec->clear(); 00565 for (Teuchos::Ordinal i=0 ; i<time_vec.size() ; ++i) { 00566 RCP<Thyra::VectorBase<Scalar> > 00567 x_temp = createMember(xn0_->space()); 00568 RCP<Thyra::VectorBase<Scalar> > 00569 xdot_temp = createMember(xn0_->space()); 00570 mScalarMag accuracy = -ST::zero(); 00571 interpolateSolution_( 00572 time_vec[i], &*x_temp, &*xdot_temp, 00573 accuracy_vec ? &accuracy : 0 00574 ); 00575 if (x_vec) 00576 x_vec->push_back(x_temp); 00577 if (xdot_vec) 00578 xdot_vec->push_back(xdot_temp); 00579 if (accuracy_vec) 00580 accuracy_vec->push_back(accuracy); 00581 } 00582 if ( as<int>(this->getVerbLevel()) >= as<int>(Teuchos::VERB_HIGH) ) { 00583 RCP<Teuchos::FancyOStream> out = this->getOStream(); 00584 Teuchos::OSTab ostab(out,1,"getPoints"); 00585 *out << "Passing out the interpolated values:" << std::endl; 00586 for (Teuchos::Ordinal i=0; i<time_vec.size() ; ++i) { 00587 *out << "time_[" << i << "] = " << time_vec[i] << std::endl; 00588 if (x_vec) { 00589 *out << "x_vec[" << i << "] = " << std::endl; 00590 (*x_vec)[i]->describe(*out,this->getVerbLevel()); 00591 } 00592 if (xdot_vec) { 00593 *out << "xdot_vec[" << i << "] = "; 00594 if ( (*xdot_vec)[i] == Teuchos::null) { 00595 *out << "Teuchos::null" << std::endl; 00596 } 00597 else { 00598 *out << std::endl << Teuchos::describe(*(*xdot_vec)[i],this->getVerbLevel()); 00599 } 00600 } 00601 if (accuracy_vec) 00602 *out << "accuracy[" << i << "] = " << (*accuracy_vec)[i] << std::endl; 00603 } 00604 } 00605 } 00606 00607 00608 template<class Scalar> 00609 void ImplicitBDFStepper<Scalar>::getNodes(Array<Scalar>* time_vec) const 00610 { 00611 TEUCHOS_ASSERT( time_vec != NULL ); 00612 time_vec->clear(); 00613 if (!haveInitialCondition_) { 00614 return; 00615 } 00616 if (numberOfSteps_ > 0) { 00617 time_vec->push_back(time_-usedStep_); 00618 } 00619 time_vec->push_back(time_); 00620 } 00621 00622 00623 template<class Scalar> 00624 void ImplicitBDFStepper<Scalar>::removeNodes(Array<Scalar>& time_vec) 00625 { 00626 TEST_FOR_EXCEPTION(true,std::logic_error, 00627 "Error, removeNodes is not implemented for ImplicitBDFStepper.\n"); 00628 } 00629 00630 00631 template<class Scalar> 00632 int ImplicitBDFStepper<Scalar>::getOrder() const 00633 { 00634 if (!isInitialized_) { 00635 return(-1); 00636 } 00637 return(usedOrder_); 00638 } 00639 00640 00641 // Overridden from Teuchos::ParameterListAcceptor 00642 00643 00644 template<class Scalar> 00645 void ImplicitBDFStepper<Scalar>::setParameterList( 00646 RCP<Teuchos::ParameterList> const& paramList 00647 ) 00648 { 00649 TEST_FOR_EXCEPT(paramList == Teuchos::null); 00650 paramList->validateParameters(*this->getValidParameters(),0); 00651 parameterList_ = paramList; 00652 Teuchos::readVerboseObjectSublist(&*parameterList_,this); 00653 } 00654 00655 00656 template<class Scalar> 00657 RCP<Teuchos::ParameterList> ImplicitBDFStepper<Scalar>::getNonconstParameterList() 00658 { 00659 return(parameterList_); 00660 } 00661 00662 00663 template<class Scalar> 00664 RCP<Teuchos::ParameterList> 00665 ImplicitBDFStepper<Scalar>::unsetParameterList() 00666 { 00667 RCP<Teuchos::ParameterList> temp_param_list = parameterList_; 00668 parameterList_ = Teuchos::null; 00669 return(temp_param_list); 00670 } 00671 00672 00673 template<class Scalar> 00674 RCP<const Teuchos::ParameterList> 00675 ImplicitBDFStepper<Scalar>::getValidParameters() const 00676 { 00677 00678 static RCP<Teuchos::ParameterList> validPL; 00679 00680 if (is_null(validPL)) { 00681 00682 RCP<Teuchos::ParameterList> 00683 pl = Teuchos::parameterList(); 00684 00685 pl->sublist(RythmosStepControlSettings_name); 00686 00687 Teuchos::setupVerboseObjectSublist(&*pl); 00688 00689 validPL = pl; 00690 00691 } 00692 00693 RCP<Teuchos::FancyOStream> out = this->getOStream(); 00694 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel(); 00695 Teuchos::OSTab ostab(out,1,"getValidParameters"); 00696 if (Teuchos::as<int>(verbLevel) == Teuchos::VERB_HIGH) { 00697 *out << "Setting up valid parameterlist." << std::endl; 00698 validPL->print(*out); 00699 } 00700 00701 return (validPL); 00702 00703 } 00704 00705 00706 // Overridden from Teuchos::Describable 00707 00708 00709 template<class Scalar> 00710 std::string ImplicitBDFStepper<Scalar>::description() const 00711 { 00712 std::ostringstream out; 00713 out << this->Teuchos::Describable::description(); 00714 const TimeRange<Scalar> timeRange = this->getTimeRange(); 00715 if (timeRange.isValid()) 00716 out << " (timeRange="<<timeRange<<")"; 00717 else 00718 out << " (This stepper is not initialized yet)"; 00719 out << std::endl; 00720 return out.str(); 00721 } 00722 00723 00724 template<class Scalar> 00725 void ImplicitBDFStepper<Scalar>::describe( 00726 Teuchos::FancyOStream &out, 00727 const Teuchos::EVerbosityLevel verbLevel 00728 ) const 00729 { 00730 00731 using Teuchos::as; 00732 00733 if (!isInitialized_) { 00734 out << this->description(); 00735 return; 00736 } 00737 00738 if ( (as<int>(verbLevel) == as<int>(Teuchos::VERB_DEFAULT) ) || 00739 (as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW) ) 00740 ) 00741 { 00742 out << this->description() << std::endl; 00743 out << "model_ = " << Teuchos::describe(*model_,verbLevel); 00744 out << "solver_ = " << Teuchos::describe(*solver_,verbLevel); 00745 out << "neModel_ = " << Teuchos::describe(neModel_,verbLevel); 00746 } 00747 if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW)) { 00748 out << "time_ = " << time_ << std::endl; 00749 out << "hh_ = " << hh_ << std::endl; 00750 out << "currentOrder_ = " << currentOrder_ << std::endl; 00751 } 00752 if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH)) { 00753 out << "xn0_ = " << Teuchos::describe(*xn0_,verbLevel); 00754 out << "xpn0_ = " << Teuchos::describe(*xpn0_,verbLevel); 00755 out << "x_dot_base_ = " << Teuchos::describe(*x_dot_base_,verbLevel); 00756 for (int i=0 ; i < std::max(2,maxOrder_) ; ++i) { 00757 out << "xHistory_[" << i << "] = " 00758 << Teuchos::describe(*xHistory_[i],verbLevel); 00759 } 00760 out << "ee_ = " << Teuchos::describe(*ee_,verbLevel); 00761 } 00762 } 00763 00764 00765 // private 00766 00767 00768 // 2007/08/24: rabartl: Belos: We really should initialize all of this data in 00769 // a member initialization list but since there are like three constructors 00770 // this would mean that we would have to duplicate code (which is error prone) 00771 // or use a macro (which is not easy to debug). We really should remove all 00772 // but the default constructor which then would set this data once in the 00773 // initialization list. 00774 00775 template<class Scalar> 00776 void ImplicitBDFStepper<Scalar>::defaultInitializeAll_() 00777 { 00778 typedef Teuchos::ScalarTraits<Scalar> ST; 00779 const Scalar nan = ST::nan(), one = ST::one(), zero = ST::zero(); 00780 // Initialize some data members to their rightful default values 00781 haveInitialCondition_ = false; 00782 isInitialized_ = false; 00783 currentOrder_ = 1; 00784 usedOrder_ = 1; 00785 usedStep_ = zero; 00786 // Initialize the rest of the private data members to invalid values to 00787 // avoid uninitialed memory 00788 time_ = nan; 00789 hh_ = nan; 00790 maxOrder_ = -1; 00791 LETvalue_ = -one; 00792 stepLETStatus_ = STEP_LET_STATUS_UNKNOWN; 00793 alpha_s_ = -one; 00794 numberOfSteps_ = -1; 00795 nef_ = -1; 00796 nscsco_ = -1; 00797 newtonConvergenceStatus_ = -1; 00798 } 00799 00800 00801 template<class Scalar> 00802 void ImplicitBDFStepper<Scalar>::obtainPredictor_() 00803 { 00804 00805 using Teuchos::as; 00806 typedef Teuchos::ScalarTraits<Scalar> ST; 00807 00808 if (!isInitialized_) { 00809 return; 00810 } 00811 00812 RCP<Teuchos::FancyOStream> out = this->getOStream(); 00813 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel(); 00814 Teuchos::OSTab ostab(out,1,"obtainPredictor_"); 00815 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) { 00816 *out << "currentOrder_ = " << currentOrder_ << std::endl; 00817 } 00818 00819 // prepare history array for prediction 00820 for (int i=nscsco_;i<=currentOrder_;++i) { 00821 Vt_S(xHistory_[i].ptr(),beta_[i]); 00822 } 00823 00824 // evaluate predictor 00825 V_V(xn0_.ptr(),*xHistory_[0]); 00826 V_S(xpn0_.ptr(),ST::zero()); 00827 for (int i=1;i<=currentOrder_;++i) { 00828 Vp_V(xn0_.ptr(),*xHistory_[i]); 00829 Vp_StV(xpn0_.ptr(),gamma_[i],*xHistory_[i]); 00830 } 00831 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) { 00832 *out << "xn0_ = " << std::endl; 00833 xn0_->describe(*out,verbLevel); 00834 *out << "xpn0_ = " << std::endl; 00835 xpn0_->describe(*out,verbLevel); 00836 } 00837 } 00838 00839 00840 template<class Scalar> 00841 void ImplicitBDFStepper<Scalar>::interpolateSolution_( 00842 const Scalar& timepoint, 00843 Thyra::VectorBase<Scalar>* x_ptr, 00844 Thyra::VectorBase<Scalar>* xdot_ptr, 00845 ScalarMag* accuracy_ptr 00846 ) const 00847 { 00848 00849 typedef std::numeric_limits<Scalar> NL; 00850 typedef Teuchos::ScalarTraits<Scalar> ST; 00851 00852 #ifdef RYTHMOS_DEBUG 00853 TEST_FOR_EXCEPTION( 00854 !isInitialized_,std::logic_error, 00855 "Error, attempting to call interpolateSolution before initialization!\n"); 00856 const TimeRange<Scalar> currTimeRange = this->getTimeRange(); 00857 TEST_FOR_EXCEPTION( 00858 !currTimeRange.isInRange(timepoint), std::logic_error, 00859 "Error, timepoint = " << timepoint << " is not in the time range " 00860 << currTimeRange << "!" ); 00861 #endif 00862 00863 const Scalar tn = time_; 00864 const int kused = usedOrder_; 00865 00866 // order of interpolation 00867 int kord = kused; 00868 if ( (kused == 0) || (timepoint == tn) ) { 00869 kord = 1; 00870 } 00871 00872 // Initialize interploation 00873 Thyra::V_V(ptr(x_ptr),*xHistory_[0]); 00874 Thyra::V_S(ptr(xdot_ptr),ST::zero()); 00875 00876 // Add history array contributions 00877 const Scalar delt = timepoint - tn; 00878 Scalar c = ST::one(); // coefficient for interpolation of x 00879 Scalar d = ST::zero(); // coefficient for interpolation of xdot 00880 Scalar gam = delt/psi_[0]; // coefficient for interpolation 00881 for (int j=1 ; j <= kord ; ++j) { 00882 d = d*gam + c/psi_[j-1]; 00883 c = c*gam; 00884 gam = (delt + psi_[j-1])/psi_[j]; 00885 Thyra::Vp_StV(ptr(x_ptr),c,*xHistory_[j]); 00886 Thyra::Vp_StV(ptr(xdot_ptr),d,*xHistory_[j]); 00887 } 00888 00889 // Set approximate accuracy 00890 if (accuracy_ptr) { 00891 *accuracy_ptr = pow(usedStep_,kord); 00892 } 00893 00894 } 00895 00896 00897 template<class Scalar> 00898 void ImplicitBDFStepper<Scalar>::updateHistory_() 00899 { 00900 00901 using Teuchos::as; 00902 00903 // Save Newton correction for potential order increase on next step. 00904 if (usedOrder_ < maxOrder_) { 00905 assign( xHistory_[usedOrder_+1].ptr(), *ee_ ); 00906 } 00907 // Update history arrays 00908 Vp_V( xHistory_[usedOrder_].ptr(), *ee_ ); 00909 for (int j=usedOrder_-1;j>=0;j--) { 00910 Vp_V( xHistory_[j].ptr(), *xHistory_[j+1] ); 00911 } 00912 RCP<Teuchos::FancyOStream> out = this->getOStream(); 00913 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel(); 00914 Teuchos::OSTab ostab(out,1,"updateHistory_"); 00915 if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) { 00916 for (int i=0;i<std::max(2,maxOrder_);++i) { 00917 *out << "xHistory_[" << i << "] = " << std::endl; 00918 xHistory_[i]->describe(*out,verbLevel); 00919 } 00920 } 00921 00922 } 00923 00924 00925 template<class Scalar> 00926 void ImplicitBDFStepper<Scalar>::restoreHistory_() 00927 { 00928 00929 using Teuchos::as; 00930 typedef Teuchos::ScalarTraits<Scalar> ST; 00931 00932 // undo preparation of history array for prediction 00933 for (int i=nscsco_;i<=currentOrder_;++i) { 00934 Vt_S( xHistory_[i].ptr(), ST::one()/beta_[i] ); 00935 } 00936 for (int i=1;i<=currentOrder_;++i) { 00937 psi_[i-1] = psi_[i] - hh_; 00938 } 00939 RCP<Teuchos::FancyOStream> out = this->getOStream(); 00940 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel(); 00941 Teuchos::OSTab ostab(out,1,"restoreHistory_"); 00942 if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) { 00943 for (int i=0;i<maxOrder_;++i) { 00944 *out << "psi_[" << i << "] = " << psi_[i] << std::endl; 00945 } 00946 for (int i=0;i<maxOrder_;++i) { 00947 *out << "xHistory_[" << i << "] = " << std::endl; 00948 xHistory_[i]->describe(*out,verbLevel); 00949 } 00950 } 00951 00952 } 00953 00954 00955 template<class Scalar> 00956 void ImplicitBDFStepper<Scalar>::updateCoeffs_() 00957 { 00958 00959 using Teuchos::as; 00960 typedef Teuchos::ScalarTraits<Scalar> ST; 00961 00962 // If the number of steps taken with constant order and constant stepsize is 00963 // more than the current order + 1 then we don't bother to update the 00964 // coefficients because we've reached a constant step-size formula. When 00965 // this is is not true, then we update the coefficients for the variable 00966 // step-sizes. 00967 if ((hh_ != usedStep_) || (currentOrder_ != usedOrder_)) { 00968 nscsco_ = 0; 00969 } 00970 nscsco_ = std::min(nscsco_+1,usedOrder_+2); 00971 if (currentOrder_+1 >= nscsco_) { 00972 beta_[0] = ST::one(); 00973 alpha_[0] = ST::one(); 00974 Scalar temp1 = hh_; 00975 gamma_[0] = ST::zero(); 00976 for (int i=1;i<=currentOrder_;++i) { 00977 Scalar temp2 = psi_[i-1]; 00978 psi_[i-1] = temp1; 00979 beta_[i] = beta_[i-1]*psi_[i-1]/temp2; 00980 temp1 = temp2 + hh_; 00981 alpha_[i] = hh_/temp1; 00982 gamma_[i] = gamma_[i-1]+alpha_[i-1]/hh_; 00983 } 00984 psi_[currentOrder_] = temp1; 00985 } 00986 alpha_s_ = ST::zero(); 00987 for (int i=0;i<currentOrder_;++i) { 00988 alpha_s_ = alpha_s_ - Scalar(ST::one()/(i+ST::one())); 00989 } 00990 RCP<Teuchos::FancyOStream> out = this->getOStream(); 00991 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel(); 00992 Teuchos::OSTab ostab(out,1,"updateCoeffs_"); 00993 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) { 00994 for (int i=0;i<=maxOrder_;++i) { 00995 *out << "alpha_[" << i << "] = " << alpha_[i] << std::endl; 00996 *out << "beta_[" << i << "] = " << beta_[i] << std::endl; 00997 *out << "gamma_[" << i << "] = " << gamma_[i] << std::endl; 00998 *out << "psi_[" << i << "] = " << psi_[i] << std::endl; 00999 *out << "alpha_s_ = " << alpha_s_ << std::endl; 01000 } 01001 } 01002 } 01003 01004 01005 template<class Scalar> 01006 void ImplicitBDFStepper<Scalar>::initialize_() 01007 { 01008 01009 using Teuchos::as; 01010 typedef Teuchos::ScalarTraits<Scalar> ST; 01011 using Thyra::createMember; 01012 01013 RCP<Teuchos::FancyOStream> out = this->getOStream(); 01014 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel(); 01015 const bool doTrace = (as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH)); 01016 Teuchos::OSTab ostab(out,1,"initialize_"); 01017 01018 if (doTrace) { 01019 *out 01020 << "\nEntering " << this->Teuchos::Describable::description() 01021 << "::initialize_()...\n"; 01022 } 01023 01024 TEST_FOR_EXCEPT(model_ == Teuchos::null); 01025 TEST_FOR_EXCEPT(solver_ == Teuchos::null); 01026 TEUCHOS_ASSERT(haveInitialCondition_); 01027 01028 // Initialize Parameter List if none provided. 01029 if (parameterList_ == Teuchos::null) { 01030 RCP<Teuchos::ParameterList> emptyParameterList = Teuchos::rcp(new Teuchos::ParameterList); 01031 this->setParameterList(emptyParameterList); 01032 } 01033 01034 // Initialize StepControl 01035 if (stepControl_ == Teuchos::null) { 01036 RCP<ImplicitBDFStepperStepControl<Scalar> > implicitBDFStepperStepControl = 01037 Teuchos::rcp(new ImplicitBDFStepperStepControl<Scalar>()); 01038 RCP<Teuchos::ParameterList> stepControlPL = 01039 Teuchos::sublist(parameterList_, RythmosStepControlSettings_name); 01040 implicitBDFStepperStepControl->setParameterList(stepControlPL); 01041 this->setStepControlStrategy(implicitBDFStepperStepControl); 01042 } 01043 stepControl_->initialize(*this); 01044 01045 maxOrder_ = stepControl_->getMaxOrder(); // maximum order 01046 TEST_FOR_EXCEPTION( 01047 !((1 <= maxOrder_) && (maxOrder_ <= 5)), std::logic_error, 01048 "Error, maxOrder returned from stepControl_->getMaxOrder() = " << maxOrder_ << " is outside range of [1,5]!\n" 01049 ); 01050 01051 Scalar zero = ST::zero(); 01052 01053 currentOrder_ = 1; // Current order of integration 01054 usedOrder_ = 1; // order used in current step (used after currentOrder_ is updated) 01055 usedStep_ = zero; 01056 nscsco_ = 0; 01057 LETvalue_ = zero; 01058 01059 alpha_.clear(); // $\alpha_j(n)=h_n/\psi_j(n)$ coefficient used in local error test 01060 // note: $h_n$ = current step size, n = current time step 01061 gamma_.clear(); // calculate time derivative of history array for predictor 01062 beta_.clear(); // coefficients used to evaluate predictor from history array 01063 psi_.clear(); // $\psi_j(n) = t_n-t_{n-j}$ intermediary variable used to 01064 // compute $\beta_j(n):$ 01065 for (int i=0 ; i<=maxOrder_ ; ++i) { 01066 alpha_.push_back(zero); 01067 beta_.push_back(zero); 01068 gamma_.push_back(zero); 01069 psi_.push_back(zero); 01070 } 01071 alpha_s_=Scalar(-ST::one()); // $\alpha_s$ fixed-leading coefficient of this BDF method 01072 hh_=zero; 01073 numberOfSteps_=0; // number of total time integration steps taken 01074 nef_ = 0; 01075 01076 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) { 01077 *out << "alpha_s_ = " << alpha_s_ << std::endl; 01078 for (int i=0 ; i<=maxOrder_ ; ++i) { 01079 *out << "alpha_[" << i << "] = " << alpha_[i] << std::endl; 01080 *out << "beta_[" << i << "] = " << beta_[i] << std::endl; 01081 *out << "gamma_[" << i << "] = " << gamma_[i] << std::endl; 01082 *out << "psi_[" << i << "] = " << psi_[i] << std::endl; 01083 } 01084 *out << "numberOfSteps_ = " << numberOfSteps_ << std::endl; 01085 } 01086 01087 // setInitialCondition initialized xHistory with xn0, xpn0. Now we add the rest of the vectors. 01088 // Store maxOrder_+1 vectors 01089 for (int i=2 ; i<=maxOrder_ ; ++i) { 01090 xHistory_.push_back(createMember(xn0_->space())); 01091 V_S(xHistory_[i].ptr(),zero); 01092 } 01093 01094 isInitialized_ = true; 01095 01096 if (doTrace) { 01097 *out 01098 << "\nLeaving " << this->Teuchos::Describable::description() 01099 << "::initialize_()...\n"; 01100 } 01101 01102 } 01103 01104 01105 template<class Scalar> 01106 void ImplicitBDFStepper<Scalar>::completeStep_() 01107 { 01108 01109 using Teuchos::as; 01110 typedef Teuchos::ScalarTraits<Scalar> ST; 01111 01112 #ifdef RYTHMOS_DEBUG 01113 TEST_FOR_EXCEPT(ST::isnaninf(hh_)); 01114 #endif 01115 01116 numberOfSteps_ ++; 01117 nef_ = 0; 01118 usedStep_ = hh_; 01119 usedOrder_ = currentOrder_; 01120 time_ += hh_; 01121 RCP<Teuchos::FancyOStream> out = this->getOStream(); 01122 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel(); 01123 Teuchos::OSTab ostab(out,1,"completeStep_"); 01124 01125 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) { 01126 *out << "numberOfSteps_ = " << numberOfSteps_ << std::endl; 01127 *out << "time_ = " << time_ << std::endl; 01128 } 01129 01130 // 03/22/04 tscoffe: Note that updating the history has nothing to do with 01131 // the step-size and everything to do with the newton correction vectors. 01132 updateHistory_(); 01133 01134 } 01135 01136 template<class Scalar> 01137 void ImplicitBDFStepper<Scalar>::setStepControlData(const StepperBase<Scalar> & stepper) 01138 { 01139 if (!isInitialized_) { 01140 initialize_(); 01141 } 01142 stepControl_->setStepControlData(stepper); 01143 } 01144 01145 // 01146 // Explicit Instantiation macro 01147 // 01148 // Must be expanded from within the Rythmos namespace! 01149 // 01150 01151 #define RYTHMOS_IMPLICITBDF_STEPPER_INSTANT(SCALAR) \ 01152 \ 01153 template class ImplicitBDFStepper< SCALAR >; \ 01154 \ 01155 template RCP< ImplicitBDFStepper< SCALAR > > \ 01156 implicitBDFStepper(); \ 01157 \ 01158 template RCP< ImplicitBDFStepper< SCALAR > > \ 01159 implicitBDFStepper( \ 01160 const RCP<Thyra::ModelEvaluator< SCALAR > >& model, \ 01161 const RCP<Thyra::NonlinearSolverBase< SCALAR > >& solver, \ 01162 const RCP<Teuchos::ParameterList>& parameterList \ 01163 ); \ 01164 01165 01166 } // namespace Rythmos 01167 01168 01169 #endif //Rythmos_IMPLICITBDF_STEPPER_DEF_H
1.7.4