00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef Rythmos_BACKWARD_EULER_STEPPER_H
00030 #define Rythmos_BACKWARD_EULER_STEPPER_H
00031
00032 #include "Rythmos_StepperBase.hpp"
00033 #include "Rythmos_DataStore.hpp"
00034 #include "Rythmos_LinearInterpolator.hpp"
00035 #include "Rythmos_SingleResidualModelEvaluator.hpp"
00036 #include "Rythmos_SolverAcceptingStepperBase.hpp"
00037 #include "Rythmos_StepperHelpers.hpp"
00038
00039 #include "Thyra_VectorBase.hpp"
00040 #include "Thyra_ModelEvaluator.hpp"
00041 #include "Thyra_ModelEvaluatorHelpers.hpp"
00042 #include "Thyra_AssertOp.hpp"
00043 #include "Thyra_NonlinearSolverBase.hpp"
00044 #include "Thyra_TestingTools.hpp"
00045
00046 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
00047 #include "Teuchos_as.hpp"
00048
00049
00050 namespace Rythmos {
00051
00052
00063 template<class Scalar>
00064 class BackwardEulerStepper : virtual public SolverAcceptingStepperBase<Scalar>
00065 {
00066 public:
00067
00069 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType ScalarMag;
00070
00073
00075 BackwardEulerStepper();
00076
00078 BackwardEulerStepper(
00079 const RCP<const Thyra::ModelEvaluator<Scalar> > &model,
00080 const RCP<Thyra::NonlinearSolverBase<Scalar> > &solver
00081 );
00082
00084 void setInterpolator(RCP<InterpolatorBase<Scalar> > interpolator);
00085
00087 RCP<InterpolatorBase<Scalar> > unsetInterpolator();
00088
00090
00093
00095 void setSolver(
00096 const RCP<Thyra::NonlinearSolverBase<Scalar> > &solver
00097 );
00098
00100 RCP<Thyra::NonlinearSolverBase<Scalar> >
00101 getNonconstSolver();
00102
00104 RCP<const Thyra::NonlinearSolverBase<Scalar> >
00105 getSolver() const;
00106
00108
00111
00113 bool supportsCloning() const;
00114
00122 RCP<StepperBase<Scalar> > cloneStepperAlgorithm() const;
00123
00125 void setModel(const RCP<const Thyra::ModelEvaluator<Scalar> > &model);
00126
00128 RCP<const Thyra::ModelEvaluator<Scalar> >
00129 getModel() const;
00130
00132 void setInitialCondition(
00133 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &initialCondition
00134 );
00135
00137 Scalar takeStep(Scalar dt, StepSizeType flag);
00138
00140 const StepStatus<Scalar> getStepStatus() const;
00141
00143
00146
00148 RCP<const Thyra::VectorSpaceBase<Scalar> >
00149 get_x_space() const;
00150
00152 void addPoints(
00153 const Array<Scalar>& time_vec,
00154 const Array<RCP<const Thyra::VectorBase<Scalar> > >& x_vec,
00155 const Array<RCP<const Thyra::VectorBase<Scalar> > >& xdot_vec
00156 );
00157
00159 TimeRange<Scalar> getTimeRange() const;
00160
00162 void getPoints(
00163 const Array<Scalar>& time_vec,
00164 Array<RCP<const Thyra::VectorBase<Scalar> > >* x_vec,
00165 Array<RCP<const Thyra::VectorBase<Scalar> > >* xdot_vec,
00166 Array<ScalarMag>* accuracy_vec
00167 ) const;
00168
00170 void getNodes(Array<Scalar>* time_vec) const;
00171
00173 void removeNodes(Array<Scalar>& time_vec);
00174
00176 int getOrder() const;
00177
00179
00182
00184 void setParameterList(RCP<Teuchos::ParameterList> const& paramList);
00185
00187 RCP<Teuchos::ParameterList> getNonconstParameterList();
00188
00190 RCP<Teuchos::ParameterList> unsetParameterList();
00191
00193 RCP<const Teuchos::ParameterList> getValidParameters() const;
00194
00196
00199
00201 void describe(
00202 Teuchos::FancyOStream &out,
00203 const Teuchos::EVerbosityLevel verbLevel
00204 ) const;
00205
00207
00208 private:
00209
00210
00211
00212
00213 bool isInitialized_;
00214 bool haveInitialCondition_;
00215 RCP<const Thyra::ModelEvaluator<Scalar> > model_;
00216 RCP<Thyra::NonlinearSolverBase<Scalar> > solver_;
00217 RCP<Thyra::VectorBase<Scalar> > scaled_x_old_;
00218 RCP<Thyra::VectorBase<Scalar> > x_dot_old_;
00219
00220 Thyra::ModelEvaluatorBase::InArgs<Scalar> basePoint_;
00221 RCP<Thyra::VectorBase<Scalar> > x_;
00222 RCP<Thyra::VectorBase<Scalar> > x_dot_;
00223 Scalar t_;
00224 Scalar t_old_;
00225
00226 Scalar dt_;
00227 int numSteps_;
00228
00229 RCP<Rythmos::SingleResidualModelEvaluator<Scalar> > neModel_;
00230
00231 RCP<Teuchos::ParameterList> parameterList_;
00232
00233 RCP<InterpolatorBase<Scalar> > interpolator_;
00234
00235
00236
00237
00238
00239 void initialize();
00240
00241 };
00242
00243
00248 template<class Scalar>
00249 RCP<BackwardEulerStepper<Scalar> >
00250 backwardEulerStepper(
00251 const RCP<const Thyra::ModelEvaluator<Scalar> > &model,
00252 const RCP<Thyra::NonlinearSolverBase<Scalar> > &solver
00253 )
00254 {
00255 return Teuchos::rcp(new BackwardEulerStepper<Scalar>(model, solver));
00256 }
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 template<class Scalar>
00267 BackwardEulerStepper<Scalar>::BackwardEulerStepper()
00268 :isInitialized_(false),
00269 haveInitialCondition_(false),
00270 t_(-1.0),
00271 t_old_(0.0),
00272 dt_(0.0),
00273 numSteps_(0)
00274 {}
00275
00276
00277 template<class Scalar>
00278 BackwardEulerStepper<Scalar>::BackwardEulerStepper(
00279 const RCP<const Thyra::ModelEvaluator<Scalar> > &model,
00280 const RCP<Thyra::NonlinearSolverBase<Scalar> > &solver
00281 )
00282 :isInitialized_(false),
00283 haveInitialCondition_(false),
00284 t_(-1.0),
00285 t_old_(0.0),
00286 dt_(0.0),
00287 numSteps_(0)
00288 {
00289 setModel(model);
00290 setSolver(solver);
00291 }
00292
00293
00294 template<class Scalar>
00295 void BackwardEulerStepper<Scalar>::setInterpolator(
00296 RCP<InterpolatorBase<Scalar> > interpolator
00297 )
00298 {
00299 #ifdef TEUCHOS_DEBUG
00300 TEST_FOR_EXCEPT(is_null(interpolator));
00301 #endif
00302 interpolator_ = interpolator;
00303 isInitialized_ = false;
00304 }
00305
00306
00307 template<class Scalar>
00308 RCP<InterpolatorBase<Scalar> >
00309 BackwardEulerStepper<Scalar>::unsetInterpolator()
00310 {
00311 RCP<InterpolatorBase<Scalar> > temp_interpolator = interpolator_;
00312 interpolator_ = Teuchos::null;
00313 return(temp_interpolator);
00314 isInitialized_ = false;
00315 }
00316
00317
00318
00319
00320
00321 template<class Scalar>
00322 void BackwardEulerStepper<Scalar>::setSolver(
00323 const RCP<Thyra::NonlinearSolverBase<Scalar> > &solver
00324 )
00325 {
00326 using Teuchos::as;
00327
00328 TEST_FOR_EXCEPT(solver == Teuchos::null)
00329
00330 RCP<Teuchos::FancyOStream> out = this->getOStream();
00331 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
00332 Teuchos::OSTab ostab(out,1,"BES::setSolver");
00333 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
00334 *out << "solver = " << solver->description() << std::endl;
00335 }
00336
00337 solver_ = solver;
00338
00339 isInitialized_ = false;
00340
00341 }
00342
00343
00344 template<class Scalar>
00345 RCP<Thyra::NonlinearSolverBase<Scalar> >
00346 BackwardEulerStepper<Scalar>::getNonconstSolver()
00347 {
00348 return solver_;
00349 }
00350
00351
00352 template<class Scalar>
00353 RCP<const Thyra::NonlinearSolverBase<Scalar> >
00354 BackwardEulerStepper<Scalar>::getSolver() const
00355 {
00356 return solver_;
00357 }
00358
00359
00360
00361
00362
00363 template<class Scalar>
00364 bool BackwardEulerStepper<Scalar>::supportsCloning() const
00365 {
00366 return true;
00367 }
00368
00369
00370 template<class Scalar>
00371 RCP<StepperBase<Scalar> >
00372 BackwardEulerStepper<Scalar>::cloneStepperAlgorithm() const
00373 {
00374 RCP<BackwardEulerStepper<Scalar> >
00375 stepper = Teuchos::rcp(new BackwardEulerStepper<Scalar>);
00376 stepper->isInitialized_ = isInitialized_;
00377 stepper->model_ = model_;
00378 if (!is_null(solver_))
00379 stepper->solver_ = solver_->cloneNonlinearSolver().assert_not_null();
00380 if (!is_null(x_))
00381 stepper->x_ = x_->clone_v().assert_not_null();
00382 if (!is_null(scaled_x_old_))
00383 stepper->scaled_x_old_ = scaled_x_old_->clone_v().assert_not_null();
00384 stepper->t_ = t_;
00385 stepper->t_old_ = t_old_;
00386 stepper->dt_ = dt_;
00387 stepper->numSteps_ = numSteps_;
00388 if (!is_null(neModel_))
00389 stepper->neModel_
00390 = Teuchos::rcp(new Rythmos::SingleResidualModelEvaluator<Scalar>);
00391 if (!is_null(parameterList_))
00392 stepper->parameterList_ = parameterList(*parameterList_);
00393 if (!is_null(interpolator_))
00394 stepper->interpolator_
00395 = interpolator_->cloneInterpolator().assert_not_null();
00396 return stepper;
00397 }
00398
00399
00400 template<class Scalar>
00401 void BackwardEulerStepper<Scalar>::setModel(
00402 const RCP<const Thyra::ModelEvaluator<Scalar> > &model
00403 )
00404 {
00405
00406 using Teuchos::as;
00407
00408 TEST_FOR_EXCEPT( is_null(model) );
00409 assertValidModel( *this, *model );
00410
00411 RCP<Teuchos::FancyOStream> out = this->getOStream();
00412 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
00413 Teuchos::OSTab ostab(out,1,"BES::setModel");
00414 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
00415 *out << "model = " << model->description() << std::endl;
00416 }
00417 model_ = model;
00418
00419
00420
00421 x_ = Teuchos::null;
00422 scaled_x_old_ = Teuchos::null;
00423 x_dot_ = Teuchos::null;
00424 x_dot_old_ = Teuchos::null;
00425
00426 isInitialized_ = false;
00427 haveInitialCondition_ = setDefaultInitialConditionFromNominalValues<Scalar>(
00428 *model_, Teuchos::ptr(this) );
00429
00430 }
00431
00432
00433 template<class Scalar>
00434 RCP<const Thyra::ModelEvaluator<Scalar> >
00435 BackwardEulerStepper<Scalar>::getModel() const
00436 {
00437 return model_;
00438 }
00439
00440
00441 template<class Scalar>
00442 void BackwardEulerStepper<Scalar>::setInitialCondition(
00443 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &initialCondition
00444 )
00445 {
00446
00447 typedef Teuchos::ScalarTraits<Scalar> ST;
00448 typedef Thyra::ModelEvaluatorBase MEB;
00449
00450 TEST_FOR_EXCEPT( is_null(model_) );
00451
00452 basePoint_ = initialCondition;
00453
00454
00455
00456 RCP<const Thyra::VectorBase<Scalar> >
00457 x_init = initialCondition.get_x();
00458
00459 #ifdef TEUCHOS_DEBUG
00460 TEST_FOR_EXCEPTION(
00461 is_null(x_init), std::logic_error,
00462 "Error, if the client passes in an intial condition to setInitialCondition(...),\n"
00463 "then x can not be null!" );
00464 THYRA_ASSERT_VEC_SPACES(
00465 "Rythmos::BackwardEulerStepper::setInitialCondition(...)",
00466 *x_init->space(), *model_->get_x_space() );
00467 #endif
00468
00469 x_ = x_init->clone_v();
00470
00471
00472
00473 x_dot_ = createMember(model_->get_x_space());
00474
00475 RCP<const Thyra::VectorBase<Scalar> >
00476 x_dot_init = initialCondition.get_x_dot();
00477
00478 if (!is_null(x_dot_init))
00479 assign(&*x_dot_,*x_dot_init);
00480 else
00481 assign(&*x_dot_,ST::zero());
00482
00483
00484
00485 t_ = initialCondition.get_t();
00486
00487 t_old_ = t_;
00488
00489 haveInitialCondition_ = true;
00490
00491 }
00492
00493
00494 template<class Scalar>
00495 Scalar BackwardEulerStepper<Scalar>::takeStep(Scalar dt, StepSizeType stepSizeType)
00496 {
00497
00498 using Teuchos::as;
00499 using Teuchos::incrVerbLevel;
00500 typedef Teuchos::ScalarTraits<Scalar> ST;
00501 typedef Thyra::NonlinearSolverBase<Scalar> NSB;
00502 typedef Teuchos::VerboseObjectTempState<NSB> VOTSNSB;
00503
00504 initialize();
00505
00506 RCP<Teuchos::FancyOStream> out = this->getOStream();
00507 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
00508 Teuchos::OSTab ostab(out,1,"BES::takeStep");
00509 VOTSNSB solver_outputTempState(solver_,out,incrVerbLevel(verbLevel,-1));
00510
00511 if ( !is_null(out) && as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW) ) {
00512 *out
00513 << "\nEntering " << Teuchos::TypeNameTraits<BackwardEulerStepper<Scalar> >::name()
00514 << "::takeStep("<<dt<<","<<toString(stepSizeType)<<") ...\n";
00515 }
00516
00517 dt_ = dt;
00518
00519 if ((stepSizeType == STEP_TYPE_VARIABLE) || (dt == ST::zero())) {
00520 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW) )
00521 *out << "\nThe arguments to takeStep are not valid for BackwardEulerStepper at this time." << std::endl;
00522
00523 return(Scalar(-ST::one()));
00524 }
00525 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
00526 *out << "\ndt = " << dt << std::endl;
00527 }
00528
00529
00530
00531
00532
00533
00534
00535
00536 V_StV( &*scaled_x_old_, Scalar(-ST::one()/dt), *x_ );
00537 t_old_ = t_;
00538 if(!neModel_.get()) {
00539 neModel_ = Teuchos::rcp(new Rythmos::SingleResidualModelEvaluator<Scalar>());
00540 }
00541 neModel_->initializeSingleResidualModel(
00542 model_, basePoint_,
00543 Scalar(ST::one()/dt), scaled_x_old_,
00544 ST::one(), Teuchos::null,
00545 t_old_+dt,
00546 Teuchos::null
00547 );
00548 if( solver_->getModel().get() != neModel_.get() ) {
00549 solver_->setModel(neModel_);
00550 }
00551
00552
00553
00554
00555
00556
00557
00558 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW) ) {
00559 *out << "\nSolving the implicit backward-Euler timestep equation ...\n";
00560 }
00561
00562 Thyra::SolveStatus<Scalar>
00563 neSolveStatus = solver_->solve(&*x_);
00564
00565
00566
00567
00568
00569 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW) ) {
00570 *out << "\nOutput status of nonlinear solve:\n" << neSolveStatus;
00571 }
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582 assign( &*x_dot_old_, *x_dot_ );
00583
00584
00585 V_StV( &*x_dot_, Scalar(ST::one()/dt), *x_ );
00586 Vp_StV( &*x_dot_, Scalar(ST::one()), *scaled_x_old_ );
00587
00588 t_ += dt;
00589
00590 numSteps_++;
00591
00592 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
00593 *out << "\nt_old_ = " << t_old_ << std::endl;
00594 *out << "\nt_ = " << t_ << std::endl;
00595 }
00596
00597 #ifdef TEUCHOS_DEBUG
00598
00599 if ( includesVerbLevel(verbLevel,Teuchos::VERB_LOW) )
00600 *out << "\nChecking to make sure that solution and the interpolated solution are the same! ...\n";
00601
00602 {
00603
00604 typedef ScalarTraits<Scalar> ST;
00605 typedef typename ST::magnitudeType ScalarMag;
00606 typedef ScalarTraits<ScalarMag> SMT;
00607
00608 Teuchos::OSTab tab(out);
00609
00610 const StepStatus<Scalar> stepStatus = this->getStepStatus();
00611
00612 RCP<const Thyra::VectorBase<Scalar> >
00613 x = stepStatus.solution,
00614 xdot = stepStatus.solutionDot;
00615
00616 Array<Scalar> time_vec = Teuchos::tuple(stepStatus.time);
00617 Array<RCP<const Thyra::VectorBase<Scalar> > > x_vec, xdot_vec;
00618 this->getPoints(time_vec,&x_vec,&xdot_vec,0);
00619
00620 RCP<const Thyra::VectorBase<Scalar> >
00621 x_interp = x_vec[0],
00622 xdot_interp = xdot_vec[0];
00623
00624 TEST_FOR_EXCEPT(
00625 !Thyra::testRelNormDiffErr(
00626 "x", *x, "x_interp", *x_interp,
00627 "2*epsilon", ScalarMag(100.0*SMT::eps()),
00628 "2*epsilon", ScalarMag(100.0*SMT::eps()),
00629 includesVerbLevel(verbLevel,Teuchos::VERB_HIGH) ? out.get() : 0
00630 )
00631 );
00632
00633 TEST_FOR_EXCEPT(
00634 !Thyra::testRelNormDiffErr(
00635 "xdot", *xdot, "xdot_interp", *xdot_interp,
00636 "2*epsilon", ScalarMag(100.0*SMT::eps()),
00637 "2*epsilon", ScalarMag(100.0*SMT::eps()),
00638 includesVerbLevel(verbLevel,Teuchos::VERB_HIGH) ? out.get() : 0
00639 )
00640 );
00641
00642 }
00643
00644
00645
00646
00647 #endif
00648
00649 if ( !is_null(out) && as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW) ) {
00650 *out
00651 << "\nLeaving " << Teuchos::TypeNameTraits<BackwardEulerStepper<Scalar> >::name()
00652 << "::takeStep(...) ...\n";
00653 }
00654
00655 return(dt);
00656
00657 }
00658
00659
00660 template<class Scalar>
00661 const StepStatus<Scalar> BackwardEulerStepper<Scalar>::getStepStatus() const
00662 {
00663
00664 typedef Teuchos::ScalarTraits<Scalar> ST;
00665
00666 StepStatus<Scalar> stepStatus;
00667
00668 if (!isInitialized_) {
00669 stepStatus.stepStatus = STEP_STATUS_UNINITIALIZED;
00670 }
00671 else if (numSteps_ > 0) {
00672 stepStatus.stepStatus = STEP_STATUS_CONVERGED;
00673 }
00674
00675
00676 stepStatus.stepSize = dt_;
00677 stepStatus.order = 1;
00678 stepStatus.time = t_;
00679 stepStatus.solution = x_;
00680 stepStatus.solutionDot = x_dot_;
00681
00682 return(stepStatus);
00683
00684 }
00685
00686
00687
00688
00689
00690 template<class Scalar>
00691 RCP<const Thyra::VectorSpaceBase<Scalar> >
00692 BackwardEulerStepper<Scalar>::get_x_space() const
00693 {
00694 return ( !is_null(model_) ? model_->get_x_space() : Teuchos::null );
00695 }
00696
00697
00698 template<class Scalar>
00699 void BackwardEulerStepper<Scalar>::addPoints(
00700 const Array<Scalar>& time_vec,
00701 const Array<RCP<const Thyra::VectorBase<Scalar> > >& x_vec,
00702 const Array<RCP<const Thyra::VectorBase<Scalar> > >& xdot_vec
00703 )
00704 {
00705
00706 typedef Teuchos::ScalarTraits<Scalar> ST;
00707 using Teuchos::as;
00708
00709 initialize();
00710
00711 #ifdef TEUCHOS_DEBUG
00712 TEST_FOR_EXCEPTION(
00713 time_vec.size() == 0, std::logic_error,
00714 "Error, addPoints called with an empty time_vec array!\n");
00715 #endif // TEUCHOS_DEBUG
00716
00717 RCP<Teuchos::FancyOStream> out = this->getOStream();
00718 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
00719 Teuchos::OSTab ostab(out,1,"BES::setPoints");
00720
00721 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
00722 *out << "time_vec = " << std::endl;
00723 for (int i=0 ; i<Teuchos::as<int>(time_vec.size()) ; ++i) {
00724 *out << "time_vec[" << i << "] = " << time_vec[i] << std::endl;
00725 }
00726 }
00727 else if (time_vec.size() == 1) {
00728 int n = 0;
00729 t_ = time_vec[n];
00730 t_old_ = t_;
00731 Thyra::V_V(&*x_,*x_vec[n]);
00732 Thyra::V_V(&*scaled_x_old_,*x_);
00733 }
00734 else {
00735 int n = time_vec.size()-1;
00736 int nm1 = time_vec.size()-2;
00737 t_ = time_vec[n];
00738 t_old_ = time_vec[nm1];
00739 Thyra::V_V(&*x_,*x_vec[n]);
00740 Scalar dt = t_ - t_old_;
00741 Thyra::V_StV(&*scaled_x_old_,Scalar(-ST::one()/dt),*x_vec[nm1]);
00742 }
00743 }
00744
00745
00746 template<class Scalar>
00747 TimeRange<Scalar> BackwardEulerStepper<Scalar>::getTimeRange() const
00748 {
00749 if ( !isInitialized_ && haveInitialCondition_ )
00750 return timeRange<Scalar>(t_,t_);
00751 if ( !isInitialized_ && !haveInitialCondition_ )
00752 return invalidTimeRange<Scalar>();
00753 return timeRange<Scalar>(t_old_,t_);
00754 }
00755
00756
00757 template<class Scalar>
00758 void BackwardEulerStepper<Scalar>::getPoints(
00759 const Array<Scalar>& time_vec,
00760 Array<RCP<const Thyra::VectorBase<Scalar> > >* x_vec,
00761 Array<RCP<const Thyra::VectorBase<Scalar> > >* xdot_vec,
00762 Array<ScalarMag>* accuracy_vec
00763 ) const
00764 {
00765
00766 using Teuchos::as;
00767 typedef Teuchos::ScalarTraits<Scalar> ST;
00768 typedef typename ST::magnitudeType ScalarMag;
00769 typedef Teuchos::ScalarTraits<ScalarMag> SMT;
00770 typename DataStore<Scalar>::DataStoreVector_t ds_nodes;
00771 typename DataStore<Scalar>::DataStoreVector_t ds_out;
00772
00773 #ifdef TEUCHOS_DEBUG
00774 TEST_FOR_EXCEPT(!haveInitialCondition_);
00775 TEST_FOR_EXCEPT( 0 == x_vec );
00776 #endif
00777
00778 RCP<Teuchos::FancyOStream> out = this->getOStream();
00779 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
00780 Teuchos::OSTab ostab(out,1,"BES::getPoints");
00781 if ( !is_null(out) && as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW) ) {
00782 *out
00783 << "\nEntering " << Teuchos::TypeNameTraits<BackwardEulerStepper<Scalar> >::name()
00784 << "::getPoints(...) ...\n";
00785 }
00786 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
00787 for (int i=0 ; i<Teuchos::as<int>(time_vec.size()) ; ++i) {
00788 *out << "time_vec[" << i << "] = " << time_vec[i] << std::endl;
00789 }
00790 *out << "I can interpolate in the interval [" << t_old_ << "," << t_ << "]." << std::endl;
00791 }
00792 if (t_old_ != t_) {
00793 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
00794 *out << "Passing two points to interpolator: " << t_old_ << " and " << t_ << std::endl;
00795 }
00796 DataStore<Scalar> ds_temp;
00797 Scalar dt = t_ - t_old_;
00798 #ifdef TEUCHOS_DEBUG
00799 TEST_FOR_EXCEPT(
00800 !Thyra::testRelErr(
00801 "dt", dt, "dt_", dt_,
00802 "1e+4*epsilon", ScalarMag(1e+4*SMT::eps()),
00803 "1e+2*epsilon", ScalarMag(1e+2*SMT::eps()),
00804 as<int>(verbLevel) >= as<int>(Teuchos::VERB_MEDIUM) ? out.get() : 0
00805 )
00806 );
00807 #endif
00808 RCP<Thyra::VectorBase<Scalar> >
00809 x_temp = scaled_x_old_->clone_v();
00810 Thyra::Vt_S(&*x_temp,Scalar(-ST::one()*dt));
00811 ds_temp.time = t_old_;
00812 ds_temp.x = x_temp;
00813 ds_temp.xdot = x_dot_old_;
00814 ds_temp.accuracy = ScalarMag(dt);
00815 ds_nodes.push_back(ds_temp);
00816 ds_temp.time = t_;
00817 ds_temp.x = x_;
00818 ds_temp.xdot = x_dot_;
00819 ds_temp.accuracy = ScalarMag(dt);
00820 ds_nodes.push_back(ds_temp);
00821 }
00822 else {
00823 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
00824 *out << "Passing one point to interpolator: " << t_ << std::endl;
00825 }
00826 DataStore<Scalar> ds_temp;
00827 ds_temp.time = t_;
00828 ds_temp.x = x_;
00829 ds_temp.xdot = x_dot_;
00830 ds_temp.accuracy = ScalarMag(ST::zero());
00831 ds_nodes.push_back(ds_temp);
00832 }
00833 interpolator_->interpolate(ds_nodes,time_vec,&ds_out);
00834 Array<Scalar> time_out;
00835 dataStoreVectorToVector(ds_out,&time_out,x_vec,xdot_vec,accuracy_vec);
00836 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
00837 *out << "Passing out the interpolated values:" << std::endl;
00838 for (int i=0; i<Teuchos::as<int>(time_out.size()) ; ++i) {
00839 *out << "time[" << i << "] = " << time_out[i] << std::endl;
00840 *out << "x_vec[" << i << "] = " << std::endl;
00841 (*x_vec)[i]->describe(*out,Teuchos::VERB_EXTREME);
00842 if (xdot_vec) {
00843 if ( (*xdot_vec)[i] == Teuchos::null) {
00844 *out << "xdot_vec[" << i << "] = Teuchos::null" << std::endl;
00845 }
00846 else {
00847 *out << "xdot_vec[" << i << "] = " << std::endl;
00848 (*xdot_vec)[i]->describe(*out,Teuchos::VERB_EXTREME);
00849 }
00850 }
00851 if(accuracy_vec) {
00852 *out << "accuracy[" << i << "] = " << (*accuracy_vec)[i] << std::endl;
00853 }
00854 }
00855 }
00856 if ( !is_null(out) && as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW) ) {
00857 *out
00858 << "Leaving " << Teuchos::TypeNameTraits<BackwardEulerStepper<Scalar> >::name()
00859 << "::getPoints(...) ...\n";
00860 }
00861
00862 }
00863
00864
00865 template<class Scalar>
00866 void BackwardEulerStepper<Scalar>::getNodes(Array<Scalar>* time_vec) const
00867 {
00868 using Teuchos::as;
00869
00870
00871 #ifdef TEUCHOS_DEBUG
00872 TEST_FOR_EXCEPT(!haveInitialCondition_);
00873 #endif
00874
00875 time_vec->clear();
00876 time_vec->push_back(t_old_);
00877 if (numSteps_ > 0) {
00878 time_vec->push_back(t_);
00879 }
00880 RCP<Teuchos::FancyOStream> out = this->getOStream();
00881 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
00882 Teuchos::OSTab ostab(out,1,"BES::getNodes");
00883 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
00884 *out << this->description() << std::endl;
00885 for (int i=0 ; i<Teuchos::as<int>(time_vec->size()) ; ++i) {
00886 *out << "time_vec[" << i << "] = " << (*time_vec)[i] << std::endl;
00887 }
00888 }
00889 }
00890
00891
00892 template<class Scalar>
00893 void BackwardEulerStepper<Scalar>::removeNodes(Array<Scalar>& time_vec)
00894 {
00895 initialize();
00896 using Teuchos::as;
00897 RCP<Teuchos::FancyOStream> out = this->getOStream();
00898 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
00899 Teuchos::OSTab ostab(out,1,"BES::removeNodes");
00900 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
00901 *out << "time_vec = " << std::endl;
00902 for (int i=0 ; i<Teuchos::as<int>(time_vec.size()) ; ++i) {
00903 *out << "time_vec[" << i << "] = " << time_vec[i] << std::endl;
00904 }
00905 }
00906 TEST_FOR_EXCEPTION(true,std::logic_error,"Error, removeNodes is not implemented for BackwardEulerStepper at this time.\n");
00907
00908
00909
00910
00911 }
00912
00913
00914 template<class Scalar>
00915 int BackwardEulerStepper<Scalar>::getOrder() const
00916 {
00917 return(1);
00918 }
00919
00920
00921
00922
00923
00924 template <class Scalar>
00925 void BackwardEulerStepper<Scalar>::setParameterList(
00926 RCP<Teuchos::ParameterList> const& paramList
00927 )
00928 {
00929 TEST_FOR_EXCEPT(is_null(paramList));
00930 paramList->validateParametersAndSetDefaults(*this->getValidParameters());
00931 parameterList_ = paramList;
00932 Teuchos::readVerboseObjectSublist(&*parameterList_,this);
00933 }
00934
00935
00936 template <class Scalar>
00937 RCP<Teuchos::ParameterList>
00938 BackwardEulerStepper<Scalar>::getNonconstParameterList()
00939 {
00940 return(parameterList_);
00941 }
00942
00943
00944 template <class Scalar>
00945 RCP<Teuchos::ParameterList>
00946 BackwardEulerStepper<Scalar>::unsetParameterList()
00947 {
00948 RCP<Teuchos::ParameterList>
00949 temp_param_list = parameterList_;
00950 parameterList_ = Teuchos::null;
00951 return(temp_param_list);
00952 }
00953
00954
00955 template<class Scalar>
00956 RCP<const Teuchos::ParameterList>
00957 BackwardEulerStepper<Scalar>::getValidParameters() const
00958 {
00959 using Teuchos::ParameterList;
00960 static RCP<const ParameterList> validPL;
00961 if (is_null(validPL)) {
00962 RCP<ParameterList> pl = Teuchos::parameterList();
00963 Teuchos::setupVerboseObjectSublist(&*pl);
00964 validPL = pl;
00965 }
00966 return validPL;
00967 }
00968
00969
00970
00971
00972
00973 template<class Scalar>
00974 void BackwardEulerStepper<Scalar>::describe(
00975 Teuchos::FancyOStream &out,
00976 const Teuchos::EVerbosityLevel verbLevel
00977 ) const
00978 {
00979 using Teuchos::as;
00980 Teuchos::OSTab tab(out);
00981 if (!isInitialized_) {
00982 out << this->description() << " : This stepper is not initialized yet" << std::endl;
00983 return;
00984 }
00985 if (
00986 as<int>(verbLevel) == as<int>(Teuchos::VERB_DEFAULT)
00987 ||
00988 as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW)
00989 )
00990 {
00991 out << this->description() << "::describe:" << std::endl;
00992 out << "model = " << model_->description() << std::endl;
00993 out << "solver = " << solver_->description() << std::endl;
00994 if (neModel_ == Teuchos::null) {
00995 out << "neModel = Teuchos::null" << std::endl;
00996 } else {
00997 out << "neModel = " << neModel_->description() << std::endl;
00998 }
00999 }
01000 else if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW)) {
01001 out << "t_ = " << t_ << std::endl;
01002 out << "t_old_ = " << t_old_ << std::endl;
01003 }
01004 else if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_MEDIUM)) {
01005 }
01006 else if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH)) {
01007 out << "model_ = " << std::endl;
01008 model_->describe(out,verbLevel);
01009 out << "solver_ = " << std::endl;
01010 solver_->describe(out,verbLevel);
01011 if (neModel_ == Teuchos::null) {
01012 out << "neModel = Teuchos::null" << std::endl;
01013 } else {
01014 out << "neModel = " << std::endl;
01015 neModel_->describe(out,verbLevel);
01016 }
01017 out << "x_ = " << std::endl;
01018 x_->describe(out,verbLevel);
01019 out << "scaled_x_old_ = " << std::endl;
01020 scaled_x_old_->describe(out,verbLevel);
01021 }
01022 }
01023
01024
01025
01026
01027
01028 template <class Scalar>
01029 void BackwardEulerStepper<Scalar>::initialize()
01030 {
01031
01032 if (isInitialized_)
01033 return;
01034
01035 TEST_FOR_EXCEPT(is_null(model_));
01036 TEST_FOR_EXCEPT(is_null(solver_));
01037 TEST_FOR_EXCEPT(!haveInitialCondition_);
01038
01039 if ( is_null(interpolator_) ) {
01040
01041
01042 interpolator_ = Teuchos::rcp(new LinearInterpolator<Scalar> );
01043
01044
01045 }
01046
01047 if (is_null(scaled_x_old_))
01048 scaled_x_old_ = createMember(model_->get_x_space());
01049
01050 if (is_null(x_dot_))
01051 x_dot_ = createMember(model_->get_x_space());
01052
01053 if (is_null(x_dot_old_))
01054 x_dot_old_ = createMember(model_->get_x_space());
01055
01056
01057
01058
01059 isInitialized_ = true;
01060
01061 }
01062
01063
01064 }
01065
01066 #endif //Rythmos_BACKWARD_EULER_STEPPER_H