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_FORWARD_SENSITIVITY_STEPPER_HPP
00030 #define RYTHMOS_FORWARD_SENSITIVITY_STEPPER_HPP
00031
00032
00033 #include "Rythmos_StepperBase.hpp"
00034 #include "Rythmos_ForwardSensitivityModelEvaluator.hpp"
00035 #include "Rythmos_StateAndForwardSensitivityModelEvaluator.hpp"
00036 #include "Rythmos_SolverAcceptingStepperBase.hpp"
00037 #include "Rythmos_IntegratorBase.hpp"
00038 #include "Rythmos_SingleResidualModelEvaluatorBase.hpp"
00039 #include "Thyra_ModelEvaluatorHelpers.hpp"
00040 #include "Thyra_LinearNonlinearSolver.hpp"
00041 #include "Thyra_AssertOp.hpp"
00042 #include "Teuchos_ParameterListAcceptorDefaultBase.hpp"
00043 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
00044 #include "Teuchos_Assert.hpp"
00045 #include "Teuchos_as.hpp"
00046
00047
00048 namespace Rythmos {
00049
00050
00199 template<class Scalar>
00200 class ForwardSensitivityStepper
00201 : virtual public StepperBase<Scalar>,
00202 virtual public Teuchos::ParameterListAcceptorDefaultBase
00203 {
00204 public:
00205
00207 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType ScalarMag;
00208
00211
00213 ForwardSensitivityStepper();
00214
00268 void initializeSyncedSteppers(
00269 const RCP<const Thyra::ModelEvaluator<Scalar> > &stateModel,
00270 const int p_index,
00271 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stateBasePoint,
00272 const RCP<StepperBase<Scalar> > &stateStepper,
00273 const RCP<Thyra::NonlinearSolverBase<Scalar> > &stateTimeStepSolver,
00274 const RCP<StepperBase<Scalar> > &sensStepper = Teuchos::null,
00275 const RCP<Thyra::NonlinearSolverBase<Scalar> > &sensTimeStepSolver = Teuchos::null
00276 );
00277
00313 void initializeDecoupledSteppers(
00314 const RCP<const Thyra::ModelEvaluator<Scalar> > &stateModel,
00315 const int p_index,
00316 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stateBasePoint,
00317 const RCP<StepperBase<Scalar> > &stateStepper,
00318 const RCP<Thyra::NonlinearSolverBase<Scalar> > &stateTimeStepSolver,
00319 const RCP<IntegratorBase<Scalar> > &stateIntegrator,
00320 const Scalar &finalTime,
00321 const RCP<StepperBase<Scalar> > &sensStepper = Teuchos::null,
00322 const RCP<Thyra::NonlinearSolverBase<Scalar> > &sensTimeStepSolver = Teuchos::null
00323 );
00324
00328 RCP<const Thyra::ModelEvaluator<Scalar> >
00329 getStateModel() const;
00330
00334 RCP<const ForwardSensitivityModelEvaluator<Scalar> >
00335 getFwdSensModel() const;
00336
00343 RCP<const StateAndForwardSensitivityModelEvaluator<Scalar> >
00344 getStateAndFwdSensModel() const;
00345
00347
00350
00352 void setParameterList(RCP<Teuchos::ParameterList> const& paramList);
00354 RCP<const Teuchos::ParameterList> getValidParameters() const;
00355
00357
00360
00362 bool acceptsModel() const;
00363
00365 void setModel(
00366 const RCP<const Thyra::ModelEvaluator<Scalar> > &model
00367 );
00368
00375 RCP<const Thyra::ModelEvaluator<Scalar> >
00376 getModel() const;
00377
00378
00379
00380
00381
00382
00383
00384
00385
00399 void setInitialCondition(
00400 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &state_and_sens_ic
00401 );
00402
00404 Scalar takeStep( Scalar dt, StepSizeType stepType );
00405
00407 const StepStatus<Scalar> getStepStatus() const;
00408
00410
00413
00420 RCP<const Thyra::VectorSpaceBase<Scalar> >
00421 get_x_space() const;
00422
00424 void addPoints(
00425 const Array<Scalar>& time_vec,
00426 const Array<Teuchos::RCP<const Thyra::VectorBase<Scalar> > >& x_vec,
00427 const Array<Teuchos::RCP<const Thyra::VectorBase<Scalar> > >& xdot_vec
00428 );
00429
00431 TimeRange<Scalar> getTimeRange() const;
00432
00434 void getPoints(
00435 const Array<Scalar>& time_vec,
00436 Array<RCP<const Thyra::VectorBase<Scalar> > >* x_vec,
00437 Array<RCP<const Thyra::VectorBase<Scalar> > >* xdot_vec,
00438 Array<ScalarMag>* accuracy_vec
00439 ) const;
00440
00442 void getNodes(Array<Scalar>* time_vec) const;
00443
00445 void removeNodes(Array<Scalar>& time_vec);
00446
00448 int getOrder() const;
00449
00451
00454
00456 void initialize(
00457 const RCP<const Thyra::ModelEvaluator<Scalar> > &stateModel,
00458 const int p_index,
00459 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stateBasePoint,
00460 const RCP<StepperBase<Scalar> > &stateStepper,
00461 const RCP<Thyra::NonlinearSolverBase<Scalar> > &stateTimeStepSolver,
00462 const RCP<StepperBase<Scalar> > &sensStepper = Teuchos::null,
00463 const RCP<Thyra::NonlinearSolverBase<Scalar> > &sensTimeStepSolver = Teuchos::null
00464 )
00465 {
00466 initializeSyncedSteppers(
00467 stateModel, p_index, stateBasePoint, stateStepper, stateTimeStepSolver,
00468 sensStepper, sensTimeStepSolver
00469 );
00470 }
00471
00473
00474 private:
00475
00476
00477
00478
00479 bool forceUpToDateW_;
00480 RCP<const Thyra::ModelEvaluator<Scalar> > stateModel_;
00481 Thyra::ModelEvaluatorBase::InArgs<Scalar> stateBasePoint_;
00482 RCP<StepperBase<Scalar> > stateStepper_;
00483 RCP<Thyra::NonlinearSolverBase<Scalar> > stateTimeStepSolver_;
00484 RCP<IntegratorBase<Scalar> > stateIntegrator_;
00485 Scalar finalTime_;
00486 RCP<StepperBase<Scalar> > sensStepper_;
00487 RCP<Thyra::NonlinearSolverBase<Scalar> > sensTimeStepSolver_;
00488
00489 bool isSingleResidualStepper_;
00490 RCP<ForwardSensitivityModelEvaluator<Scalar> > sensModel_;
00491 RCP<StateAndForwardSensitivityModelEvaluator<Scalar> > stateAndSensModel_;
00492 Thyra::ModelEvaluatorBase::InArgs<Scalar> stateBasePoint_t_;
00493
00494 static const std::string forceUpToDateW_name_;
00495 static const bool forceUpToDateW_default_;
00496
00497
00498
00499
00500 void initializeCommon(
00501 const RCP<const Thyra::ModelEvaluator<Scalar> > &stateModel,
00502 const int p_index,
00503 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stateBasePoint,
00504 const RCP<StepperBase<Scalar> > &stateStepper,
00505 const RCP<Thyra::NonlinearSolverBase<Scalar> > &stateTimeStepSolver,
00506 const RCP<StepperBase<Scalar> > &sensStepper,
00507 const RCP<Thyra::NonlinearSolverBase<Scalar> > &sensTimeStepSolver
00508 );
00509
00510 Scalar takeSyncedStep( Scalar dt, StepSizeType stepType );
00511
00512 Scalar takeDecoupledStep( Scalar dt, StepSizeType stepType );
00513
00514 };
00515
00516
00521 template<class Scalar>
00522 inline
00523 RCP<ForwardSensitivityStepper<Scalar> >
00524 forwardSensitivityStepper()
00525 {
00526 return Teuchos::rcp(new ForwardSensitivityStepper<Scalar>());
00527 }
00528
00529
00534 template<class Scalar>
00535 inline
00536 RCP<ForwardSensitivityStepper<Scalar> >
00537 forwardSensitivityStepper(
00538 const RCP<const Thyra::ModelEvaluator<Scalar> > &stateModel,
00539 const int p_index,
00540 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stateBasePoint,
00541 const RCP<StepperBase<Scalar> > &stateStepper,
00542 const RCP<Thyra::NonlinearSolverBase<Scalar> > &stateTimeStepSolver,
00543 const RCP<StepperBase<Scalar> > &sensStepper = Teuchos::null,
00544 const RCP<Thyra::NonlinearSolverBase<Scalar> > &sensTimeStepSolver = Teuchos::null
00545 )
00546 {
00547 RCP<ForwardSensitivityStepper<Scalar> >
00548 fwdSensStepper = Teuchos::rcp(new ForwardSensitivityStepper<Scalar>());
00549 fwdSensStepper->initialize(
00550 stateModel, p_index, stateBasePoint, stateStepper, stateTimeStepSolver );
00551 return fwdSensStepper;
00552 }
00553
00554
00560 template<class Scalar>
00561 int getParameterIndex(
00562 const ForwardSensitivityStepper<Scalar> &fwdSensStepper
00563 )
00564 {
00565 return fwdSensStepper.getFwdSensModel()->get_p_index();
00566 }
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577 template<class Scalar>
00578 const std::string ForwardSensitivityStepper<Scalar>::forceUpToDateW_name_
00579 = "Force Up-To-Date Jacobian";
00580
00581 template<class Scalar>
00582 const bool ForwardSensitivityStepper<Scalar>::forceUpToDateW_default_
00583 = true;
00584
00585
00586
00587
00588
00589 template<class Scalar>
00590 ForwardSensitivityStepper<Scalar>::ForwardSensitivityStepper()
00591 :forceUpToDateW_(false),
00592 isSingleResidualStepper_(false)
00593 {}
00594
00595
00596 template<class Scalar>
00597 void ForwardSensitivityStepper<Scalar>::initializeSyncedSteppers(
00598 const RCP<const Thyra::ModelEvaluator<Scalar> > &stateModel,
00599 const int p_index,
00600 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stateBasePoint,
00601 const RCP<StepperBase<Scalar> > &stateStepper,
00602 const RCP<Thyra::NonlinearSolverBase<Scalar> > &stateTimeStepSolver,
00603 const RCP<StepperBase<Scalar> > &sensStepper,
00604 const RCP<Thyra::NonlinearSolverBase<Scalar> > &sensTimeStepSolver
00605 )
00606
00607 {
00608 initializeCommon(stateModel, p_index, stateBasePoint, stateStepper,
00609 stateTimeStepSolver, sensStepper, sensTimeStepSolver );
00610 }
00611
00612
00613 template<class Scalar>
00614 void ForwardSensitivityStepper<Scalar>::initializeDecoupledSteppers(
00615 const RCP<const Thyra::ModelEvaluator<Scalar> > &stateModel,
00616 const int p_index,
00617 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stateBasePoint,
00618 const RCP<StepperBase<Scalar> > &stateStepper,
00619 const RCP<Thyra::NonlinearSolverBase<Scalar> > &stateTimeStepSolver,
00620 const RCP<IntegratorBase<Scalar> > &stateIntegrator,
00621 const Scalar &finalTime,
00622 const RCP<StepperBase<Scalar> > &sensStepper,
00623 const RCP<Thyra::NonlinearSolverBase<Scalar> > &sensTimeStepSolver
00624 )
00625 {
00626 TEST_FOR_EXCEPT(is_null(stateIntegrator));
00627 initializeCommon(stateModel, p_index, stateBasePoint, stateStepper,
00628 stateTimeStepSolver, sensStepper, sensTimeStepSolver );
00629 stateIntegrator_ = stateIntegrator;
00630 finalTime_ = finalTime;
00631 }
00632
00633
00634 template<class Scalar>
00635 RCP<const Thyra::ModelEvaluator<Scalar> >
00636 ForwardSensitivityStepper<Scalar>::getStateModel() const
00637 {
00638 return stateModel_;
00639 }
00640
00641
00642 template<class Scalar>
00643 RCP<const ForwardSensitivityModelEvaluator<Scalar> >
00644 ForwardSensitivityStepper<Scalar>::getFwdSensModel() const
00645 {
00646 return sensModel_;
00647 }
00648
00649
00650 template<class Scalar>
00651 RCP<const StateAndForwardSensitivityModelEvaluator<Scalar> >
00652 ForwardSensitivityStepper<Scalar>::getStateAndFwdSensModel() const
00653 {
00654 return stateAndSensModel_;
00655 }
00656
00657
00658
00659
00660
00661 template<class Scalar>
00662 void ForwardSensitivityStepper<Scalar>::setParameterList(
00663 RCP<Teuchos::ParameterList> const& paramList
00664 )
00665 {
00666 TEST_FOR_EXCEPT(is_null(paramList));
00667 paramList->validateParameters(*getValidParameters());
00668 this->setMyParamList(paramList);
00669 forceUpToDateW_ = paramList->get(forceUpToDateW_name_,forceUpToDateW_default_);
00670 Teuchos::readVerboseObjectSublist(&*paramList,this);
00671 }
00672
00673
00674 template<class Scalar>
00675 RCP<const Teuchos::ParameterList>
00676 ForwardSensitivityStepper<Scalar>::getValidParameters() const
00677 {
00678 static RCP<const ParameterList> validPL;
00679 if (is_null(validPL) ) {
00680 RCP<ParameterList> pl = Teuchos::parameterList();
00681 pl->set( forceUpToDateW_name_, forceUpToDateW_default_,
00682 "If set to true, then the Jacobian matrix W used in the\n"
00683 "state timestep equation will be forced to be up to date\n"
00684 "with the final value for x for the nonlinear solve. If\n"
00685 "you are willing to live with slightly less accurate sensitivities\n"
00686 "then set this to false."
00687 );
00688 Teuchos::setupVerboseObjectSublist(&*pl);
00689 validPL = pl;
00690 }
00691 return validPL;
00692 }
00693
00694
00695
00696
00697 template<class Scalar>
00698 bool ForwardSensitivityStepper<Scalar>::acceptsModel() const
00699 {
00700 return false;
00701 }
00702
00703 template<class Scalar>
00704 void ForwardSensitivityStepper<Scalar>::setModel(
00705 const RCP<const Thyra::ModelEvaluator<Scalar> > &model
00706 )
00707 {
00708 TEST_FOR_EXCEPT_MSG( true,
00709 "Error, this stepper subclass does not accept a model"
00710 " as defined by the StepperBase interface!");
00711 }
00712
00713
00714 template<class Scalar>
00715 RCP<const Thyra::ModelEvaluator<Scalar> >
00716 ForwardSensitivityStepper<Scalar>::getModel() const
00717 {
00718 return stateAndSensModel_;
00719 }
00720
00721
00722 template<class Scalar>
00723 void ForwardSensitivityStepper<Scalar>::setInitialCondition(
00724 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &state_and_sens_ic
00725 )
00726 {
00727
00728 typedef Thyra::ModelEvaluatorBase MEB;
00729
00730
00731
00732 TEST_FOR_EXCEPTION(
00733 is_null(state_and_sens_ic.get_x()), std::logic_error,
00734 "Error, the initial condition for x_bar = [ x; s_bar ] can not be null!" );
00735
00736 const RCP<const Thyra::ProductVectorBase<Scalar> >
00737 x_bar_init = Thyra::productVectorBase<Scalar>(
00738 state_and_sens_ic.get_x()
00739 );
00740
00741 const RCP<const Thyra::ProductVectorBase<Scalar> >
00742 x_bar_dot_init = Thyra::productVectorBase<Scalar>(
00743 state_and_sens_ic.get_x_dot()
00744 );
00745
00746
00747
00748 Thyra::ModelEvaluatorBase::InArgs<Scalar>
00749 state_and_sens_ic_no_x = state_and_sens_ic;
00750 state_and_sens_ic_no_x.set_x(Teuchos::null);
00751 state_and_sens_ic_no_x.set_x_dot(Teuchos::null);
00752
00753
00754
00755 MEB::InArgs<Scalar> state_ic = stateModel_->createInArgs();
00756 state_ic.setArgs(state_and_sens_ic_no_x,true,true);
00757 state_ic.set_x(x_bar_init->getVectorBlock(0)->clone_v());
00758 state_ic.set_x_dot(
00759 !is_null(x_bar_dot_init)
00760 ? x_bar_dot_init->getVectorBlock(0)->clone_v()
00761 : Teuchos::null
00762 );
00763 stateStepper_->setInitialCondition(state_ic);
00764
00765
00766 if (!is_null(stateIntegrator_)) {
00767 stateIntegrator_->setStepper( stateStepper_, finalTime_ );
00768 sensModel_->setStateIntegrator( stateIntegrator_, state_ic );
00769 }
00770
00771
00772
00773 MEB::InArgs<Scalar> sens_ic = sensModel_->createInArgs();
00774 sens_ic.setArgs(state_and_sens_ic_no_x,true,true);
00775 sens_ic.set_x(x_bar_init->getVectorBlock(1)->clone_v());
00776 sens_ic.set_x_dot(
00777 !is_null(x_bar_dot_init)
00778 ? x_bar_dot_init->getVectorBlock(1)->clone_v()
00779 : Teuchos::null
00780 );
00781 sensStepper_->setInitialCondition(sens_ic);
00782
00783 }
00784
00785
00786 template<class Scalar>
00787 Scalar
00788 ForwardSensitivityStepper<Scalar>::takeStep(
00789 Scalar dt, StepSizeType stepType
00790 )
00791 {
00792
00793 #ifdef ENABLE_RYTHMOS_TIMERS
00794 TEUCHOS_FUNC_TIME_MONITOR("Rythmos:ForwardSensitivityStepper::takeStep");
00795 #endif
00796
00797 if (!is_null(stateIntegrator_)) {
00798 return takeDecoupledStep(dt,stepType);
00799 }
00800
00801 return takeSyncedStep(dt,stepType);
00802
00803 }
00804
00805
00806 template<class Scalar>
00807 const StepStatus<Scalar>
00808 ForwardSensitivityStepper<Scalar>::getStepStatus() const
00809 {
00810
00811 const StepStatus<Scalar> sensStepStatus = sensStepper_->getStepStatus();
00812 StepStatus<Scalar> stepStatus;
00813
00814 stepStatus.message = sensStepStatus.message;
00815 stepStatus.stepStatus = sensStepStatus.stepStatus;
00816 stepStatus.stepLETStatus = sensStepStatus.stepLETStatus;
00817 stepStatus.stepSize = sensStepStatus.stepSize;
00818 stepStatus.order = sensStepStatus.order;
00819 stepStatus.time = sensStepStatus.time;
00820 stepStatus.stepLETValue = sensStepStatus.stepLETValue;
00821 stepStatus.extraParameters = sensStepStatus.extraParameters;
00822
00823 if (is_null(stateIntegrator_)) {
00824 const StepStatus<Scalar>
00825 stateStepStatus = stateStepper_->getStepStatus();
00826 if (!is_null(stateStepStatus.solution) && !is_null(sensStepStatus.solution))
00827 stepStatus.solution = stateAndSensModel_->create_x_bar_vec(
00828 stateStepStatus.solution, sensStepStatus.solution
00829 );
00830 if (!is_null(stateStepStatus.solutionDot) && !is_null(sensStepStatus.solutionDot))
00831 stepStatus.solutionDot = stateAndSensModel_->create_x_bar_vec(
00832 stateStepStatus.solutionDot, sensStepStatus.solutionDot
00833 );
00834 }
00835
00836 return stepStatus;
00837
00838 }
00839
00840
00841
00842
00843
00844 template<class Scalar>
00845 RCP<const Thyra::VectorSpaceBase<Scalar> >
00846 ForwardSensitivityStepper<Scalar>::get_x_space() const
00847 {
00848 return stateAndSensModel_->get_x_space();
00849 }
00850
00851
00852 template<class Scalar>
00853 void ForwardSensitivityStepper<Scalar>::addPoints(
00854 const Array<Scalar>& time_vec,
00855 const Array<Teuchos::RCP<const Thyra::VectorBase<Scalar> > >& x_vec,
00856 const Array<Teuchos::RCP<const Thyra::VectorBase<Scalar> > >& xdot_vec
00857 )
00858 {
00859 TEST_FOR_EXCEPT("Not implemented addPoints(...) yet but we could if we wanted!");
00860 }
00861
00862
00863 template<class Scalar>
00864 TimeRange<Scalar>
00865 ForwardSensitivityStepper<Scalar>::getTimeRange() const
00866 {
00867 return sensStepper_->getTimeRange();
00868 }
00869
00870
00871 template<class Scalar>
00872 void ForwardSensitivityStepper<Scalar>::getPoints(
00873 const Array<Scalar>& time_vec,
00874 Array<RCP<const Thyra::VectorBase<Scalar> > >* x_bar_vec,
00875 Array<RCP<const Thyra::VectorBase<Scalar> > >* x_bar_dot_vec,
00876 Array<ScalarMag>* accuracy_vec
00877 ) const
00878 {
00879
00880 using Teuchos::as;
00881
00882 #ifdef TEUCHOS_DEBUG
00883 TEST_FOR_EXCEPT( as<int>(time_vec.size()) == 0 );
00884 #endif
00885
00886 const int numTimePoints = time_vec.size();
00887
00888 if (x_bar_vec)
00889 x_bar_vec->clear();
00890
00891 if (x_bar_dot_vec)
00892 x_bar_dot_vec->clear();
00893
00894 Array<RCP<const Thyra::VectorBase<Scalar> > >
00895 x_vec, x_dot_vec;
00896
00897 if (!is_null(stateIntegrator_)) {
00898 stateIntegrator_->getPoints(
00899 time_vec,
00900 x_bar_vec ? &x_vec: 0,
00901 x_bar_dot_vec ? &x_dot_vec: 0,
00902 0
00903 );
00904 }
00905 else {
00906 stateStepper_->getPoints(
00907 time_vec,
00908 x_bar_vec ? &x_vec: 0,
00909 x_bar_dot_vec ? &x_dot_vec: 0,
00910 0
00911 );
00912 }
00913
00914 Array<RCP<const Thyra::VectorBase<Scalar> > >
00915 s_bar_vec, s_bar_dot_vec;
00916
00917 sensStepper_->getPoints(
00918 time_vec,
00919 x_bar_vec ? &s_bar_vec: 0,
00920 x_bar_dot_vec ? &s_bar_dot_vec: 0,
00921 accuracy_vec
00922 );
00923
00924 if ( x_bar_vec ) {
00925 for ( int i = 0; i < numTimePoints; ++i ) {
00926 x_bar_vec->push_back(
00927 stateAndSensModel_->create_x_bar_vec(x_vec[i],s_bar_vec[i])
00928 );
00929 }
00930 }
00931
00932 if ( x_bar_dot_vec ) {
00933 for ( int i = 0; i < numTimePoints; ++i ) {
00934 x_bar_dot_vec->push_back(
00935 stateAndSensModel_->create_x_bar_vec(x_dot_vec[i],s_bar_dot_vec[i])
00936 );
00937 }
00938 }
00939
00940 }
00941
00942
00943 template<class Scalar>
00944 void ForwardSensitivityStepper<Scalar>::getNodes(
00945 Array<Scalar>* time_vec
00946 ) const
00947 {
00948 TEST_FOR_EXCEPT("Not implemented yet but we can!");
00949 }
00950
00951
00952 template<class Scalar>
00953 void ForwardSensitivityStepper<Scalar>::removeNodes(
00954 Array<Scalar>& time_vec
00955 )
00956 {
00957 TEST_FOR_EXCEPT("Not implemented yet but we can!");
00958 }
00959
00960
00961 template<class Scalar>
00962 int ForwardSensitivityStepper<Scalar>::getOrder() const
00963 {
00964 return sensStepper_->getOrder();
00965
00966 }
00967
00968
00969
00970
00971
00972 template<class Scalar>
00973 void ForwardSensitivityStepper<Scalar>::initializeCommon(
00974 const RCP<const Thyra::ModelEvaluator<Scalar> > &stateModel,
00975 const int p_index,
00976 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stateBasePoint,
00977 const RCP<StepperBase<Scalar> > &stateStepper,
00978 const RCP<Thyra::NonlinearSolverBase<Scalar> > &stateTimeStepSolver,
00979 const RCP<StepperBase<Scalar> > &sensStepper,
00980 const RCP<Thyra::NonlinearSolverBase<Scalar> > &sensTimeStepSolver
00981 )
00982 {
00983
00984 using Teuchos::rcp_dynamic_cast;
00985
00986 typedef Thyra::ModelEvaluatorBase MEB;
00987
00988
00989
00990
00991
00992 TEST_FOR_EXCEPT( is_null(stateModel) );
00993 TEST_FOR_EXCEPT( is_null(stateStepper) );
00994 TEST_FOR_EXCEPT( is_null(stateTimeStepSolver) );
00995
00996
00997
00998
00999
01000
01001 RCP<ForwardSensitivityModelEvaluator<Scalar> >
01002 sensModel = Teuchos::rcp(new ForwardSensitivityModelEvaluator<Scalar>);
01003 sensModel->initializeStructure(stateModel,p_index);
01004
01005
01006
01007
01008
01009 stateModel_ = stateModel;
01010
01011 stateBasePoint_ = stateBasePoint;
01012
01013 stateStepper_ = stateStepper;
01014
01015 stateTimeStepSolver_ = stateTimeStepSolver;
01016
01017 sensModel_ = sensModel;
01018
01019 stateAndSensModel_ = Teuchos::rcp(new StateAndForwardSensitivityModelEvaluator<Scalar>);
01020 stateAndSensModel_->initializeStructure(sensModel_);
01021
01022 if (!is_null(sensStepper)) {
01023 sensStepper_ = sensStepper;
01024 }
01025 else {
01026 sensStepper_ = stateStepper_->cloneStepperAlgorithm();
01027 TEST_FOR_EXCEPTION(
01028 is_null(sensStepper_), std::logic_error,
01029 "Error, if the client does not pass in a stepper for the senitivity\n"
01030 "equations then the stateStepper object must support cloning to create\n"
01031 "the sensitivity stepper!"
01032 );
01033 }
01034
01035 if (!is_null(sensTimeStepSolver)) {
01036 sensTimeStepSolver_ = sensTimeStepSolver;
01037 }
01038 else {
01039 RCP<Thyra::LinearNonlinearSolver<Scalar> >
01040 linearNonlinearSolver(new Thyra::LinearNonlinearSolver<Scalar>);
01041
01042 sensTimeStepSolver_ = linearNonlinearSolver;
01043 }
01044
01045
01046
01047
01048
01049 isSingleResidualStepper_ = true;
01050
01051
01052 stateStepper_->setModel(stateModel_);
01053 rcp_dynamic_cast<SolverAcceptingStepperBase<Scalar> >(
01054 stateStepper_,true)->setSolver(stateTimeStepSolver_);
01055 sensStepper_->setModel(sensModel_);
01056 rcp_dynamic_cast<SolverAcceptingStepperBase<Scalar> >(
01057 sensStepper_,true)->setSolver(sensTimeStepSolver_);
01058
01059 stateBasePoint_t_ = stateModel_->createInArgs();
01060
01061
01062
01063
01064 }
01065
01066
01067 template<class Scalar>
01068 Scalar ForwardSensitivityStepper<Scalar>::takeSyncedStep(
01069 Scalar dt, StepSizeType stepType
01070 )
01071 {
01072
01073 #ifdef ENABLE_RYTHMOS_TIMERS
01074 TEUCHOS_FUNC_TIME_MONITOR("Rythmos:ForwardSensitivityStepper::takeStep: synced");
01075 #endif
01076
01077 using Teuchos::as;
01078 typedef Teuchos::ScalarTraits<Scalar> ST;
01079 typedef Teuchos::VerboseObjectTempState<InterpolationBufferBase<Scalar> > VOTSIBB;
01080 typedef Thyra::ModelEvaluatorBase MEB;
01081
01082 RCP<Teuchos::FancyOStream> out = this->getOStream();
01083 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
01084 const bool lowTrace =
01085 ( !is_null(out) && as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW) );
01086 const bool mediumTrace =
01087 ( !is_null(out) && as<int>(verbLevel) >= as<int>(Teuchos::VERB_MEDIUM) );
01088 Teuchos::OSTab tab(out);
01089
01090 if (lowTrace) {
01091 *out
01092 << "\nEntering " << TypeNameTraits<ForwardSensitivityStepper<Scalar> >::name()
01093 << "::takeSyncedStep("<<dt<<","<<toString(stepType)<<") ...\n";
01094 }
01095
01096
01097
01098
01099
01100 if (lowTrace) {
01101 *out
01102 << "\nTaking state step using stepper : "
01103 << stateStepper_->description() << "\n";
01104 }
01105
01106 Scalar state_dt = -1.0;
01107 {
01108 #ifdef ENABLE_RYTHMOS_TIMERS
01109 TEUCHOS_FUNC_TIME_MONITOR("Rythmos:ForwardSensitivityStepper::takeStep: stateStep");
01110 #endif
01111 VOTSIBB stateStepper_outputTempState(stateStepper_,out,verbLevel);
01112 state_dt = stateStepper_->takeStep(dt,stepType);
01113 }
01114
01115 if (state_dt < Scalar(-ST::one())) {
01116 if (lowTrace)
01117 *out << "\nThe state stepper has failed so return a failed timestep!\n";
01118 return state_dt;
01119 }
01120
01121 const StepStatus<Scalar> stateStepStatus = stateStepper_->getStepStatus();
01122 if (mediumTrace)
01123 *out << "\nState step status:\n" << stateStepStatus;
01124
01125
01126
01127
01128
01129 {
01130
01131 #ifdef ENABLE_RYTHMOS_TIMERS
01132 TEUCHOS_FUNC_TIME_MONITOR("Rythmos:ForwardSensitivityStepper::takeStep: updateSensModel");
01133 #endif
01134
01135 TEST_FOR_EXCEPTION(
01136 stateStepStatus.stepStatus != STEP_STATUS_CONVERGED, std::logic_error,
01137 "Error, the status should be converged since a positive step size was returned!"
01138 );
01139
01140 const Scalar curr_t = stateStepStatus.time;
01141
01142
01143
01144
01145 RCP<const Thyra::VectorBase<Scalar> > x, x_dot;
01146 get_x_and_x_dot(*stateStepper_,curr_t,&x,&x_dot);
01147
01148 stateBasePoint_t_ = stateBasePoint_;
01149 stateBasePoint_t_.set_x_dot( x_dot );
01150 stateBasePoint_t_.set_x( x );
01151 stateBasePoint_t_.set_t( curr_t );
01152
01153
01154
01155 RCP<const Rythmos::SingleResidualModelEvaluatorBase<Scalar> >
01156 singleResidualModel
01157 = Teuchos::rcp_dynamic_cast<const Rythmos::SingleResidualModelEvaluatorBase<Scalar> >(
01158 stateTimeStepSolver_->getModel(), true
01159 );
01160 const Scalar
01161 coeff_x_dot = singleResidualModel->get_coeff_x_dot(),
01162 coeff_x = singleResidualModel->get_coeff_x();
01163
01164
01165
01166 if (mediumTrace && forceUpToDateW_)
01167 *out << "\nForcing an update of W at the converged state timestep ...\n";
01168
01169 RCP<Thyra::LinearOpWithSolveBase<Scalar> >
01170 W_tilde = stateTimeStepSolver_->get_nonconst_W(forceUpToDateW_);
01171
01172 TEST_FOR_EXCEPTION(
01173 is_null(W_tilde), std::logic_error,
01174 "Error, the W from the state time step be non-null!"
01175 );
01176
01177 sensModel_->initializeState( stateBasePoint_t_, W_tilde, coeff_x_dot, coeff_x );
01178
01179 }
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190 if (lowTrace) {
01191 *out
01192 << "\nTaking sensitivity step using stepper : "
01193 << sensStepper_->description() << "\n";
01194 }
01195
01196 Scalar sens_dt = -1.0;
01197 {
01198 #ifdef ENABLE_RYTHMOS_TIMERS
01199 TEUCHOS_FUNC_TIME_MONITOR("Rythmos:ForwardSensitivityStepper::takeStep: sensStep");
01200 #endif
01201
01202
01203
01204 sensStepper_->setStepControlData(*stateStepper_);
01205 VOTSIBB sensStepper_outputTempState(sensStepper_,out,verbLevel);
01206 sens_dt = sensStepper_->takeStep(state_dt,STEP_TYPE_FIXED);
01207 }
01208
01209 if (mediumTrace) {
01210 const StepStatus<Scalar> sensStepStatus = sensStepper_->getStepStatus();
01211 *out << "\nSensitivity step status:\n" << sensStepStatus;
01212 }
01213
01214 TEST_FOR_EXCEPTION(
01215 sens_dt != state_dt, std::logic_error,
01216 "Error, the sensitivity step failed for some reason. We should\n"
01217 "just return a negative step size and reject the step but currently\n"
01218 "there is no way to roll back the state timestep it for back to\n"
01219 "the status before this function was called!"
01220 );
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230 if (lowTrace) {
01231 *out
01232 << "\nLeaving " << TypeNameTraits<ForwardSensitivityStepper<Scalar> >::name()
01233 << "::takeSyncedStep("<<dt<<","<<toString(stepType)<<") ...\n";
01234 }
01235
01236 return state_dt;
01237
01238 }
01239
01240
01241 template<class Scalar>
01242 Scalar ForwardSensitivityStepper<Scalar>::takeDecoupledStep(
01243 Scalar dt, StepSizeType stepType
01244 )
01245 {
01246
01247 #ifdef ENABLE_RYTHMOS_TIMERS
01248 TEUCHOS_FUNC_TIME_MONITOR("Rythmos:ForwardSensitivityStepper::takeStep: decoupled");
01249 #endif
01250
01251 using Teuchos::as;
01252 typedef Teuchos::ScalarTraits<Scalar> ST;
01253 typedef Teuchos::VerboseObjectTempState<InterpolationBufferBase<Scalar> > VOTSIBB;
01254 typedef Thyra::ModelEvaluatorBase MEB;
01255
01256 RCP<Teuchos::FancyOStream> out = this->getOStream();
01257 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
01258 const bool lowTrace =
01259 ( !is_null(out) && as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW) );
01260 const bool mediumTrace =
01261 ( !is_null(out) && as<int>(verbLevel) >= as<int>(Teuchos::VERB_MEDIUM) );
01262 Teuchos::OSTab tab(out);
01263
01264 if (lowTrace) {
01265 *out
01266 << "\nEntering " << TypeNameTraits<ForwardSensitivityStepper<Scalar> >::name()
01267 << "::takeDecoupledStep("<<dt<<","<<toString(stepType)<<") ...\n";
01268 }
01269
01270
01271
01272
01273
01274 if (lowTrace) {
01275 *out
01276 << "\nTaking sensitivity step using stepper : "
01277 << sensStepper_->description() << "\n";
01278 }
01279
01280 Scalar sens_dt = -1.0;
01281 VOTSIBB sensStepper_outputTempState(sensStepper_,out,verbLevel);
01282 sens_dt = sensStepper_->takeStep(dt,stepType);
01283
01284 if (mediumTrace) {
01285 const StepStatus<Scalar> sensStepStatus = sensStepper_->getStepStatus();
01286 *out << "\nSensitivity step status:\n" << sensStepStatus;
01287 }
01288
01289
01290
01291
01292
01293
01294
01295 if (lowTrace) {
01296 *out
01297 << "\nLeaving " << TypeNameTraits<ForwardSensitivityStepper<Scalar> >::name()
01298 << "::takeDecoupledStep("<<dt<<","<<toString(stepType)<<") ...\n";
01299 }
01300
01301 return sens_dt;
01302
01303 }
01304
01305
01306 }
01307
01308
01309 #endif //RYTHMOS_FORWARD_SENSITIVITY_STEPPER_HPP