29 #ifndef RYTHMOS_FORWARD_SENSITIVITY_IMPLICIT_MODEL_EVALUATOR_HPP
30 #define RYTHMOS_FORWARD_SENSITIVITY_IMPLICIT_MODEL_EVALUATOR_HPP
33 #include "Rythmos_IntegratorBase.hpp"
34 #include "Rythmos_ForwardSensitivityModelEvaluatorBase.hpp"
35 #include "Rythmos_SolverAcceptingStepperBase.hpp"
36 #include "Rythmos_SingleResidualModelEvaluator.hpp"
37 #include "Thyra_ModelEvaluator.hpp"
38 #include "Thyra_StateFuncModelEvaluatorBase.hpp"
39 #include "Thyra_DefaultProductVectorSpace.hpp"
40 #include "Thyra_PhysicallyBlockedLinearOpWithSolveBase.hpp"
41 #include "Thyra_DefaultBlockedTriangularLinearOpWithSolve.hpp"
42 #include "Thyra_ModelEvaluatorDelegatorBase.hpp"
43 #include "Thyra_ModelEvaluatorHelpers.hpp"
44 #include "Thyra_DefaultMultiVectorProductVectorSpace.hpp"
45 #include "Thyra_DefaultMultiVectorProductVector.hpp"
46 #include "Thyra_DefaultMultiVectorLinearOpWithSolve.hpp"
47 #include "Thyra_MultiVectorStdOps.hpp"
48 #include "Teuchos_implicit_cast.hpp"
49 #include "Teuchos_Assert.hpp"
301 template<
class Scalar>
329 const RCP<
const Thyra::ModelEvaluator<Scalar> > &stateModel,
334 RCP<const Thyra::ModelEvaluator<Scalar> >
338 RCP<Thyra::ModelEvaluator<Scalar> >
361 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stateBasePoint
470 const RCP<
const Thyra::ModelEvaluator<Scalar> >& stateModel,
471 const RCP<
const Thyra::VectorSpaceBase<Scalar> >& p_space
475 RCP<const Thyra::DefaultMultiVectorProductVectorSpace<Scalar> >
487 RCP<const Thyra::VectorSpaceBase<Scalar> >
get_x_space()
const;
489 RCP<const Thyra::VectorSpaceBase<Scalar> >
get_f_space()
const;
493 RCP<Thyra::LinearOpWithSolveBase<Scalar> >
create_W()
const;
495 Thyra::ModelEvaluatorBase::InArgs<Scalar>
createInArgs()
const;
504 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stateBasePoint,
505 const RCP<
const Thyra::LinearOpWithSolveBase<Scalar> > &W_tilde,
506 const Scalar &coeff_x_dot,
507 const Scalar &coeff_x,
508 const RCP<
const Thyra::LinearOpBase<Scalar> > &DfDx_dot = Teuchos::null,
509 const RCP<
const Thyra::MultiVectorBase<Scalar> > &DfDp = Teuchos::null
520 Thyra::ModelEvaluatorBase::OutArgs<Scalar> createOutArgsImpl()
const;
523 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
524 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs
534 RCP<const Thyra::ModelEvaluator<Scalar> > stateModel_;
536 RCP<const Thyra::VectorSpaceBase<Scalar> > p_space_;
539 RCP<IntegratorBase<Scalar> > stateIntegrator_;
541 RCP<const Thyra::DefaultMultiVectorProductVectorSpace<Scalar> > s_bar_space_;
542 RCP<const Thyra::DefaultMultiVectorProductVectorSpace<Scalar> > f_sens_space_;
544 Thyra::ModelEvaluatorBase::InArgs<Scalar> nominalValues_;
546 mutable Thyra::ModelEvaluatorBase::InArgs<Scalar> stateBasePoint_;
548 mutable RCP<const Thyra::LinearOpWithSolveBase<Scalar> > W_tilde_;
549 mutable Scalar coeff_x_dot_;
550 mutable Scalar coeff_x_;
551 mutable RCP<const Thyra::LinearOpBase<Scalar> > DfDx_dot_;
552 mutable RCP<const Thyra::MultiVectorBase<Scalar> > DfDp_;
554 mutable RCP<Thyra::LinearOpWithSolveBase<Scalar> > W_tilde_compute_;
555 mutable RCP<Thyra::LinearOpBase<Scalar> > DfDx_dot_compute_;
556 mutable RCP<Thyra::MultiVectorBase<Scalar> > DfDp_compute_;
561 bool hasStateFuncParams()
const {
return p_index_ >= 0; }
563 void initializeStructureCommon(
564 const RCP<
const Thyra::ModelEvaluator<Scalar> > &stateModel,
566 const RCP<
const Thyra::VectorSpaceBase<Scalar> > &p_space
569 void wrapNominalValuesAndBounds();
571 void computeDerivativeMatrices(
572 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &point
584 template<
class Scalar>
585 RCP<ForwardSensitivityImplicitModelEvaluator<Scalar> > forwardSensitivityImplicitModelEvaluator()
590 template<
class Scalar>
592 : p_index_(0), np_(-1)
596 template<
class Scalar>
597 RCP<const Thyra::ModelEvaluator<Scalar> >
604 template<
class Scalar>
605 RCP<Thyra::ModelEvaluator<Scalar> >
608 return Teuchos::null;
612 template<
class Scalar>
619 template<
class Scalar>
622 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stateBasePoint
625 stateIntegrator_ = stateIntegrator.assert_not_null();
626 stateBasePoint_ = stateBasePoint;
629 template<
class Scalar>
635 TEUCHOS_ASSERT( Teuchos::nonnull(stateStepper) );
636 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
637 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
640 TEUCHOS_TEST_FOR_EXCEPTION(
641 stateStepStatus.
stepStatus != STEP_STATUS_CONVERGED, std::logic_error,
642 "Error, the status should be converged since a positive step size was returned!"
644 Scalar curr_t = stateStepStatus.
time;
648 RCP<const Thyra::VectorBase<Scalar> > x, x_dot;
649 get_x_and_x_dot(*stateStepper,curr_t,&x,&x_dot);
651 stateBasePoint_ = stateStepper->getInitialCondition();
652 stateBasePoint_.set_x_dot( x_dot );
653 stateBasePoint_.set_x( x );
654 stateBasePoint_.set_t( curr_t );
658 RCP<SolverAcceptingStepperBase<Scalar> >
660 Teuchos::rcpFromRef(*stateStepper),true
662 RCP<Thyra::NonlinearSolverBase<Scalar> >
664 RCP<const SingleResidualModelEvaluatorBase<Scalar> >
667 stateTimeStepSolver->getModel(), true
671 coeff_x = singleResidualModel->get_coeff_x();
676 if ((as<int>(verbLevel) >= as<int>(Teuchos::VERB_MEDIUM)) && forceUpToDateW) {
677 *out <<
"\nForcing an update of W at the converged state timestep ...\n";
680 RCP<Thyra::LinearOpWithSolveBase<Scalar> >
681 W_tilde = stateTimeStepSolver->get_nonconst_W(forceUpToDateW);
683 TEUCHOS_TEST_FOR_EXCEPTION(
684 is_null(W_tilde), std::logic_error,
685 "Error, the W from the state time step must be non-null!"
688 #ifdef HAVE_RYTHMOS_DEBUG
689 TEUCHOS_TEST_FOR_EXCEPTION(
690 is_null(stateModel_), std::logic_error,
691 "Error, you must call intializeStructure(...) before you call initializeState(...)"
693 TEUCHOS_TEST_FOR_EXCEPT( is_null(stateBasePoint_.get_x()) );
694 TEUCHOS_TEST_FOR_EXCEPT( is_null(stateBasePoint_.get_x_dot()) );
695 TEUCHOS_TEST_FOR_EXCEPT( is_null(stateBasePoint_.get_p(p_index_)) );
698 if (!is_null(W_tilde)) {
699 THYRA_ASSERT_VEC_SPACES(
"",*W_tilde->domain(),*stateModel_->get_x_space());
700 THYRA_ASSERT_VEC_SPACES(
"",*W_tilde->range(),*stateModel_->get_f_space());
705 coeff_x_dot_ = coeff_x_dot;
707 DfDx_dot_ = Teuchos::null;
708 DfDp_ = Teuchos::null;
710 wrapNominalValuesAndBounds();
715 template<
class Scalar>
717 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stateBasePoint,
718 const RCP<
const Thyra::LinearOpWithSolveBase<Scalar> > &W_tilde,
719 const Scalar &coeff_x_dot,
720 const Scalar &coeff_x,
721 const RCP<
const Thyra::LinearOpBase<Scalar> > &DfDx_dot,
722 const RCP<
const Thyra::MultiVectorBase<Scalar> > &DfDp
728 #ifdef HAVE_RYTHMOS_DEBUG
729 TEUCHOS_TEST_FOR_EXCEPTION(
730 is_null(stateModel_), std::logic_error,
731 "Error, you must call intializeStructure(...) before you call initializeState(...)"
733 TEUCHOS_TEST_FOR_EXCEPT( is_null(stateBasePoint.get_x()) );
734 TEUCHOS_TEST_FOR_EXCEPT( is_null(stateBasePoint.get_x_dot()) );
735 if (hasStateFuncParams()) {
736 TEUCHOS_TEST_FOR_EXCEPT( is_null(stateBasePoint.get_p(p_index_)) );
740 if (nonnull(W_tilde)) {
741 THYRA_ASSERT_VEC_SPACES(
"", *W_tilde->domain(), *stateModel_->get_x_space());
742 THYRA_ASSERT_VEC_SPACES(
"", *W_tilde->range(), *stateModel_->get_f_space());
744 if (nonnull(DfDx_dot)) {
745 THYRA_ASSERT_VEC_SPACES(
"", *DfDx_dot->domain(), *stateModel_->get_x_space());
746 THYRA_ASSERT_VEC_SPACES(
"", *DfDx_dot->range(), *stateModel_->get_f_space());
749 TEUCHOS_ASSERT(hasStateFuncParams());
750 THYRA_ASSERT_VEC_SPACES(
"", *DfDp->domain(), *p_space_);
751 THYRA_ASSERT_VEC_SPACES(
"", *DfDp->range(), *stateModel_->get_f_space());
755 stateBasePoint_ = stateBasePoint;
762 coeff_x_dot_ = coeff_x_dot;
764 DfDx_dot_ = DfDx_dot;
767 wrapNominalValuesAndBounds();
775 template<
class Scalar>
777 const RCP<
const Thyra::ModelEvaluator<Scalar> >& stateModel,
781 initializeStructureCommon(stateModel, p_index, Teuchos::null);
785 template<
class Scalar>
787 const RCP<
const Thyra::ModelEvaluator<Scalar> >& stateModel,
788 const RCP<
const Thyra::VectorSpaceBase<Scalar> >& p_space
791 initializeStructureCommon(stateModel, -1, p_space);
795 template<
class Scalar>
796 RCP<const Thyra::DefaultMultiVectorProductVectorSpace<Scalar> >
803 template<
class Scalar>
804 RCP<const Thyra::VectorSpaceBase<Scalar> >
814 template<
class Scalar>
815 RCP<const Thyra::VectorSpaceBase<Scalar> >
822 template<
class Scalar>
823 RCP<const Thyra::VectorSpaceBase<Scalar> >
826 return f_sens_space_;
830 template<
class Scalar>
831 Thyra::ModelEvaluatorBase::InArgs<Scalar>
834 return nominalValues_;
838 template<
class Scalar>
839 RCP<Thyra::LinearOpWithSolveBase<Scalar> >
842 return Thyra::multiVectorLinearOpWithSolve<Scalar>();
846 template<
class Scalar>
847 Thyra::ModelEvaluatorBase::InArgs<Scalar>
850 typedef Thyra::ModelEvaluatorBase MEB;
851 MEB::InArgs<Scalar> stateModelInArgs = stateModel_->createInArgs();
852 MEB::InArgsSetup<Scalar> inArgs;
853 inArgs.setModelEvalDescription(this->description());
854 inArgs.setSupports( MEB::IN_ARG_x_dot,
855 stateModelInArgs.supports(MEB::IN_ARG_x_dot) );
856 inArgs.setSupports( MEB::IN_ARG_x );
857 inArgs.setSupports( MEB::IN_ARG_t );
858 inArgs.setSupports( MEB::IN_ARG_alpha,
859 stateModelInArgs.supports(MEB::IN_ARG_alpha) );
860 inArgs.setSupports( MEB::IN_ARG_beta,
861 stateModelInArgs.supports(MEB::IN_ARG_beta) );
869 template<
class Scalar>
870 Thyra::ModelEvaluatorBase::OutArgs<Scalar>
874 typedef Thyra::ModelEvaluatorBase MEB;
876 MEB::OutArgs<Scalar> stateModelOutArgs = stateModel_->createOutArgs();
877 MEB::OutArgsSetup<Scalar> outArgs;
879 outArgs.setModelEvalDescription(this->description());
881 outArgs.setSupports(MEB::OUT_ARG_f);
883 if (stateModelOutArgs.supports(MEB::OUT_ARG_W) ) {
884 outArgs.setSupports(MEB::OUT_ARG_W);
885 outArgs.set_W_properties(stateModelOutArgs.get_W_properties());
893 template<
class Scalar>
894 void ForwardSensitivityImplicitModelEvaluator<Scalar>::evalModelImpl(
895 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
896 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs
901 using Teuchos::rcp_dynamic_cast;
902 typedef Teuchos::ScalarTraits<Scalar> ST;
904 typedef Teuchos::VerboseObjectTempState<Thyra::ModelEvaluatorBase> VOTSME;
906 THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_GEN_BEGIN(
907 "ForwardSensitivityImplicitModelEvaluator", inArgs, outArgs, Teuchos::null );
915 RYTHMOS_FUNC_TIME_MONITOR_DIFF(
916 "Rythmos:ForwardSensitivityImplicitModelEvaluator::evalModel: computeMatrices",
919 computeDerivativeMatrices(inArgs);
926 RCP<const Thyra::DefaultMultiVectorProductVector<Scalar> >
927 s_bar = rcp_dynamic_cast<
const Thyra::DefaultMultiVectorProductVector<Scalar> >(
928 inArgs.get_x().assert_not_null(), true
930 RCP<const Thyra::DefaultMultiVectorProductVector<Scalar> >
931 s_bar_dot = rcp_dynamic_cast<
const Thyra::DefaultMultiVectorProductVector<Scalar> >(
932 inArgs.get_x_dot().assert_not_null(), true
935 alpha = inArgs.get_alpha();
937 beta = inArgs.get_beta();
939 RCP<const Thyra::MultiVectorBase<Scalar> >
940 S = s_bar->getMultiVector();
941 RCP<const Thyra::MultiVectorBase<Scalar> >
942 S_dot = s_bar_dot->getMultiVector();
948 RCP<Thyra::DefaultMultiVectorProductVector<Scalar> >
949 f_sens = rcp_dynamic_cast<Thyra::DefaultMultiVectorProductVector<Scalar> >(
950 outArgs.get_f(), true
952 RCP<Thyra::DefaultMultiVectorLinearOpWithSolve<Scalar> >
953 W_sens = rcp_dynamic_cast<Thyra::DefaultMultiVectorLinearOpWithSolve<Scalar> >(
954 outArgs.get_W(), true
957 RCP<Thyra::MultiVectorBase<Scalar> >
958 F_sens = f_sens->getNonconstMultiVector().assert_not_null();
964 if(nonnull(F_sens)) {
966 RYTHMOS_FUNC_TIME_MONITOR_DIFF(
967 "Rythmos:ForwardSensitivityImplicitModelEvaluator::evalModel: computeSens",
971 RCP<Thyra::MultiVectorBase<Scalar> >
972 S_diff = createMembers( stateModel_->get_x_space(), np_ );
973 V_StVpV( S_diff.ptr(), as<Scalar>(-coeff_x_dot_/coeff_x_), *S, *S_dot );
976 *W_tilde_, Thyra::NOTRANS,
978 as<Scalar>(1.0/coeff_x_), ST::zero()
982 *DfDx_dot_, Thyra::NOTRANS,
983 *S_diff, F_sens.ptr(),
987 if (hasStateFuncParams())
988 Vp_V( F_sens.ptr(), *DfDp_ );
991 if(nonnull(W_sens)) {
992 TEUCHOS_TEST_FOR_EXCEPTION(
993 alpha != coeff_x_dot_, std::logic_error,
994 "Error, alpha="<<alpha<<
" != coeff_x_dot="<<coeff_x_dot_
995 <<
" with difference = "<<(alpha-coeff_x_dot_)<<
"!" );
996 TEUCHOS_TEST_FOR_EXCEPTION(
997 beta != coeff_x_, std::logic_error,
998 "Error, beta="<<beta<<
" != coeff_x="<<coeff_x_
999 <<
" with difference = "<<(beta-coeff_x_)<<
"!" );
1000 W_sens->initialize( W_tilde_, s_bar_space_, f_sens_space_ );
1004 THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END();
1012 template<
class Scalar>
1013 void ForwardSensitivityImplicitModelEvaluator<Scalar>::initializeStructureCommon(
1014 const RCP<
const Thyra::ModelEvaluator<Scalar> >& stateModel,
1016 const RCP<
const Thyra::VectorSpaceBase<Scalar> >& p_space
1020 typedef Thyra::ModelEvaluatorBase MEB;
1026 TEUCHOS_ASSERT(nonnull(stateModel));
1027 TEUCHOS_ASSERT(p_index >= 0 || nonnull(p_space));
1029 TEUCHOS_TEST_FOR_EXCEPTION(
1030 !( 0 <= p_index && p_index < stateModel->Np() ), std::logic_error,
1031 "Error, p_index does not fall in the range [0,"<<(stateModel->Np()-1)<<
"]!" );
1035 TEUCHOS_ASSERT_EQUALITY(p_index, -1);
1042 stateModel_ = stateModel;
1046 p_space_ = stateModel_->get_p_space(p_index);
1053 np_ = p_space_->dim();
1059 s_bar_space_ = Thyra::multiVectorProductVectorSpace(
1060 stateModel_->get_x_space(), np_
1063 f_sens_space_ = Thyra::multiVectorProductVectorSpace(
1064 stateModel_->get_f_space(), np_
1067 nominalValues_ = this->createInArgs();
1073 stateBasePoint_ = MEB::InArgs<Scalar>();
1074 W_tilde_ = Teuchos::null;
1077 DfDx_dot_ = Teuchos::null;
1078 DfDp_ = Teuchos::null;
1079 W_tilde_compute_ = Teuchos::null;
1080 DfDx_dot_compute_ = Teuchos::null;
1081 DfDp_compute_ = Teuchos::null;
1086 template<
class Scalar>
1087 void ForwardSensitivityImplicitModelEvaluator<Scalar>::wrapNominalValuesAndBounds()
1095 nominalValues_.set_t(stateModel_->getNominalValues().get_t());
1106 template<
class Scalar>
1107 void ForwardSensitivityImplicitModelEvaluator<Scalar>::computeDerivativeMatrices(
1108 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &point
1112 typedef Thyra::ModelEvaluatorBase MEB;
1113 typedef Teuchos::VerboseObjectTempState<MEB> VOTSME;
1115 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
1116 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
1119 t_base = stateBasePoint_.get_t(),
1122 TEUCHOS_ASSERT_EQUALITY( t , t_base );
1124 if (is_null(W_tilde_)) {
1125 TEUCHOS_TEST_FOR_EXCEPT_MSG(
true,
"ToDo: compute W_tilde from scratch!");
1128 if ( is_null(DfDx_dot_) || is_null(DfDp_) ) {
1130 MEB::InArgs<Scalar> inArgs = stateBasePoint_;
1131 MEB::OutArgs<Scalar> outArgs = stateModel_->createOutArgs();
1133 Teuchos::RCP<Thyra::LinearOpBase<Scalar> > DfDx_dot_compute;
1134 if (is_null(DfDx_dot_)) {
1135 DfDx_dot_compute = stateModel_->create_W_op();
1136 inArgs.set_alpha(1.0);
1137 inArgs.set_beta(0.0);
1138 outArgs.set_W_op(DfDx_dot_compute);
1141 Teuchos::RCP<Thyra::MultiVectorBase<Scalar> > DfDp_compute;
1142 if (is_null(DfDp_) && hasStateFuncParams()) {
1143 DfDp_compute = Thyra::create_DfDp_mv(
1144 *stateModel_, p_index_,
1145 MEB::DERIV_MV_BY_COL
1149 MEB::Derivative<Scalar>(DfDp_compute,MEB::DERIV_MV_BY_COL)
1153 VOTSME stateModel_outputTempState(stateModel_,out,verbLevel);
1154 stateModel_->evalModel(inArgs,outArgs);
1155 if (nonnull(DfDx_dot_compute))
1156 DfDx_dot_ = DfDx_dot_compute;
1157 if (nonnull(DfDp_compute))
1158 DfDp_ = DfDp_compute;
1162 TEUCHOS_TEST_FOR_EXCEPT_MSG( nonnull(stateIntegrator_),
1163 "ToDo: Update for using the stateIntegrator!" );
1319 #endif // RYTHMOS_FORWARD_SENSITIVITY_IMPLICIT_MODEL_EVALUATOR_HPP
void initializeStructureInitCondOnly(const RCP< const Thyra::ModelEvaluator< Scalar > > &stateModel, const RCP< const Thyra::VectorSpaceBase< Scalar > > &p_space)
virtual Teuchos::RCP< Thyra::NonlinearSolverBase< Scalar > > getNonconstSolver()=0
RCP< const Thyra::DefaultMultiVectorProductVectorSpace< Scalar > > get_s_bar_space() const
void initializeStructure(const RCP< const Thyra::ModelEvaluator< Scalar > > &stateModel, const int p_index)
Intialize the with the model structure.
void initializeState(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &stateBasePoint, const RCP< const Thyra::LinearOpWithSolveBase< Scalar > > &W_tilde, const Scalar &coeff_x_dot, const Scalar &coeff_x, const RCP< const Thyra::LinearOpBase< Scalar > > &DfDx_dot=Teuchos::null, const RCP< const Thyra::MultiVectorBase< Scalar > > &DfDp=Teuchos::null)
Deprecated.
Base class for defining stepper functionality.
Abstract interface for time integrators.
RCP< const Thyra::ModelEvaluator< Scalar > > getStateModel() const
Thyra::ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const
RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const
ForwardSensitivityImplicitModelEvaluator()
Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const
void setStateIntegrator(const RCP< IntegratorBase< Scalar > > &stateIntegrator, const Thyra::ModelEvaluatorBase::InArgs< Scalar > &stateBasePoint)
Set the state integrator that will be used to get x and x_dot at various time points.
Base class mix-in interface for single-residual model evaluators.
RCP< const Thyra::VectorSpaceBase< Scalar > > get_p_sens_space() const
void initializePointState(Ptr< StepperBase< Scalar > > stateStepper, bool forceUpToDateW)
Initialize full state for a single point in time.
Mix-in interface all implicit stepper objects that accept a nonlinear solver to be used to compute th...
Forward sensitivity transient ModelEvaluator subclass.
Forward sensitivity transient ModelEvaluator node interface class.
RCP< Thyra::LinearOpWithSolveBase< Scalar > > create_W() const
RCP< Thyra::ModelEvaluator< Scalar > > getNonconstStateModel() const
virtual Scalar get_coeff_x_dot() const =0
RCP< const Thyra::VectorSpaceBase< Scalar > > get_f_space() const