30 #ifndef RYTHMOS_FORWARD_SENSITIVITY_INTEGRATOR_AS_MODEL_EVALUATOR_HPP
31 #define RYTHMOS_FORWARD_SENSITIVITY_INTEGRATOR_AS_MODEL_EVALUATOR_HPP
34 #include "Thyra_ResponseOnlyModelEvaluatorBase.hpp"
36 #include "Rythmos_StepperBase.hpp"
37 #include "Rythmos_IntegratorBase.hpp"
38 #include "Rythmos_InterpolationBufferHelpers.hpp"
39 #include "Rythmos_ForwardSensitivityStepper.hpp"
40 #include "Rythmos_ForwardResponseSensitivityComputer.hpp"
41 #include "Rythmos_extractStateAndSens.hpp"
42 #include "Thyra_ModelEvaluatorDelegatorBase.hpp"
43 #include "Thyra_DefaultMultiVectorProductVectorSpace.hpp"
44 #include "Thyra_DefaultProductVectorSpace.hpp"
45 #include "Teuchos_ParameterListAcceptor.hpp"
46 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
47 #include "Teuchos_Assert.hpp"
53 namespace ForwardSensitivityIntegratorAsModelEvaluatorTypes {
138 template<
class Scalar>
140 :
virtual public Thyra::ResponseOnlyModelEvaluatorBase<Scalar>
141 ,
virtual public Teuchos::ParameterListAcceptor
211 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stateAndSensInitCond,
212 const Array<Scalar> &responseTimes,
213 const Array<RCP<
const Thyra::ModelEvaluator<Scalar> > > &responseFuncs,
214 const Array<Thyra::ModelEvaluatorBase::InArgs<Scalar> > &responseFuncBasePoints,
215 const ForwardSensitivityIntegratorAsModelEvaluatorTypes::EResponseType responseType
261 RCP<const Thyra::VectorSpaceBase<Scalar> >
get_p_space(
int l)
const;
263 RCP<const Thyra::VectorSpaceBase<Scalar> >
get_g_space(
int j)
const;
265 Thyra::ModelEvaluatorBase::InArgs<Scalar>
createInArgs()
const;
275 Thyra::ModelEvaluatorBase::OutArgs<Scalar> createOutArgsImpl()
const;
278 const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs,
279 const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs
289 typedef Teuchos::Array<RCP<const Thyra::VectorSpaceBase<Scalar> > > SpaceArray_t;
295 RCP<Teuchos::ParameterList> paramList_;
296 bool dumpSensitivities_;
298 RCP<StepperBase<Scalar> > stateStepper_;
299 RCP<IntegratorBase<Scalar> > stateIntegrator_;
300 mutable Thyra::ModelEvaluatorBase::InArgs<Scalar> stateInitCond_;
302 RCP<ForwardSensitivityStepper<Scalar> > stateAndSensStepper_;
303 RCP<IntegratorBase<Scalar> > stateAndSensIntegrator_;
304 mutable Thyra::ModelEvaluatorBase::InArgs<Scalar> stateAndSensInitCond_;
306 Array<Scalar> responseTimes_;
307 Array<RCP<const Thyra::ModelEvaluator<Scalar> > > responseFuncs_;
308 mutable Array<Thyra::ModelEvaluatorBase::InArgs<Scalar> > responseFuncInArgs_;
309 ForwardSensitivityIntegratorAsModelEvaluatorTypes::EResponseType responseType_;
310 bool response_func_supports_x_dot_;
311 bool response_func_supports_D_x_dot_;
312 bool response_func_supports_D_p_;
321 SpaceArray_t g_space_;
322 SpaceArray_t p_space_;
324 static const std::string dumpSensitivities_name_;
325 static const bool dumpSensitivities_default_;
331 template<
class Scalar>
332 RCP<ForwardSensitivityIntegratorAsModelEvaluator<Scalar> >
333 forwardSensitivityIntegratorAsModelEvaluator(
338 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stateAndSensInitCond,
339 const Array<Scalar> &responseTimes,
340 const Array<RCP<
const Thyra::ModelEvaluator<Scalar> > > &responseFuncs,
341 const Array<Thyra::ModelEvaluatorBase::InArgs<Scalar> > &responseFuncBasePoints,
342 const ForwardSensitivityIntegratorAsModelEvaluatorTypes::EResponseType responseType
346 RCP<ForwardSensitivityIntegratorAsModelEvaluator<Scalar> >
348 sensIntegratorAsModelEvaluator->initialize(
349 stateStepper, stateIntegrator,
350 stateAndSensStepper, stateAndSensIntegrator,
351 stateAndSensInitCond,
352 responseTimes, responseFuncs,
353 responseFuncBasePoints, responseType
355 return sensIntegratorAsModelEvaluator;
366 template<
class Scalar>
368 ForwardSensitivityIntegratorAsModelEvaluator<Scalar>::dumpSensitivities_name_
369 =
"Dump Sensitivities";
371 template<
class Scalar>
373 ForwardSensitivityIntegratorAsModelEvaluator<Scalar>::dumpSensitivities_default_
380 template<
class Scalar>
382 :dumpSensitivities_(dumpSensitivities_default_),
383 responseType_(ForwardSensitivityIntegratorAsModelEvaluatorTypes::RESPONSE_TYPE_SUM),
384 response_func_supports_x_dot_(false),
385 response_func_supports_D_x_dot_(false),
386 response_func_supports_D_p_(false),
389 finalTime_(-std::numeric_limits<Scalar>::max()),
395 template<
class Scalar>
401 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stateAndSensInitCond,
402 const Array<Scalar> &responseTimes,
403 const Array<RCP<
const Thyra::ModelEvaluator<Scalar> > > &responseFuncs,
404 const Array<Thyra::ModelEvaluatorBase::InArgs<Scalar> > &responseFuncBasePoints,
405 const ForwardSensitivityIntegratorAsModelEvaluatorTypes::EResponseType responseType
410 typedef Thyra::ModelEvaluatorBase MEB;
411 namespace FSIAMET = ForwardSensitivityIntegratorAsModelEvaluatorTypes;
417 #ifdef HAVE_RYTHMOS_DEBUG
418 const int numResponseTimes = responseTimes.size();
420 TEUCHOS_TEST_FOR_EXCEPT(is_null(stateStepper));
421 TEUCHOS_TEST_FOR_EXCEPT(is_null(stateIntegrator));
422 TEUCHOS_TEST_FOR_EXCEPT(is_null(stateAndSensStepper));
423 TEUCHOS_TEST_FOR_EXCEPT(is_null(stateAndSensInitCond.get_x()));
424 TEUCHOS_TEST_FOR_EXCEPT(is_null(stateAndSensInitCond.get_x_dot()));
425 TEUCHOS_TEST_FOR_EXCEPT( !( numResponseTimes > 0 ) );
426 assertTimePointsAreSorted(responseTimes);
427 TEUCHOS_TEST_FOR_EXCEPT( as<int>(responseFuncs.size()) != numResponseTimes );
428 TEUCHOS_TEST_FOR_EXCEPT( as<int>(responseFuncBasePoints.size()) != numResponseTimes );
431 #endif // HAVE_RYTHMOS_DEBUG
433 stateStepper_ = stateStepper;
434 stateAndSensStepper_ = stateAndSensStepper;
435 stateAndSensInitCond_ = stateAndSensInitCond;
436 stateIntegrator_ = stateIntegrator;
437 if (!is_null(stateAndSensIntegrator))
438 stateAndSensIntegrator_ = stateAndSensIntegrator;
440 stateAndSensIntegrator_ = stateIntegrator_->cloneIntegrator().assert_not_null();
441 responseTimes_ = responseTimes;
442 responseFuncs_ = responseFuncs;
443 responseFuncInArgs_ = responseFuncBasePoints;
444 responseType_ = responseType;
446 finalTime_ = responseTimes_.back();
452 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >
453 stateModel = stateStepper_->getModel();
457 basePoint_no_x = stateAndSensInitCond_;
458 basePoint_no_x.set_x(Teuchos::null);
459 basePoint_no_x.set_x_dot(Teuchos::null);
462 stateInitCond_ = stateModel->createInArgs();
465 stateInitCond_.setArgs(basePoint_no_x);
468 const RCP<const Thyra::ProductVectorBase<Scalar> >
469 x_bar_init = Thyra::productVectorBase<Scalar>(
470 stateAndSensInitCond_.get_x()
472 x_bar_dot_init = Thyra::productVectorBase<Scalar>(
473 stateAndSensInitCond_.get_x_dot()
475 stateInitCond_.set_x(x_bar_init->getVectorBlock(0));
476 stateInitCond_.set_x_dot(x_bar_dot_init->getVectorBlock(0));
483 p_index_ = getParameterIndex(*stateAndSensStepper_);
485 p_space_.push_back(stateModel->get_p_space(p_index_));
491 if (responseType_ == FSIAMET::RESPONSE_TYPE_SUM) {
492 g_space_.push_back(responseFuncs[0]->get_g_space(0));
494 else if (responseType_ == FSIAMET::RESPONSE_TYPE_BLOCK) {
496 Thyra::productVectorSpace(
497 responseFuncs[0]->get_g_space(g_index_), responseFuncs.size()
503 responseInArgs = responseFuncs[0]->createInArgs();
504 response_func_supports_x_dot_ =
505 responseInArgs.supports(MEB::IN_ARG_x_dot);
507 responseOutArgs = responseFuncs[0]->createOutArgs();
508 response_func_supports_D_x_dot_ =
509 !responseOutArgs.supports(MEB::OUT_ARG_DgDx_dot,g_index_).none();
510 response_func_supports_D_p_ =
511 !responseOutArgs.supports(MEB::OUT_ARG_DgDp,g_index_,p_index_).none();
516 template<
class Scalar>
520 return responseTimes_;
527 template<
class Scalar>
529 RCP<Teuchos::ParameterList>
const& paramList
532 TEUCHOS_TEST_FOR_EXCEPT(0==paramList.get());
533 paramList->validateParameters(*getValidParameters());
534 paramList_ = paramList;
535 dumpSensitivities_ = paramList_->get(
536 dumpSensitivities_name_, dumpSensitivities_default_);
537 Teuchos::readVerboseObjectSublist(&*paramList_,
this);
538 #ifdef HAVE_RYTHMOS_DEBUG
539 paramList_->validateParameters(*getValidParameters());
540 #endif // HAVE_RYTHMOS_DEBUG
545 template<
class Scalar>
546 RCP<Teuchos::ParameterList>
553 template<
class Scalar>
554 RCP<Teuchos::ParameterList>
557 RCP<Teuchos::ParameterList> _paramList = paramList_;
558 paramList_ = Teuchos::null;
563 template<
class Scalar>
564 RCP<const Teuchos::ParameterList>
571 template<
class Scalar>
572 RCP<const Teuchos::ParameterList>
575 static RCP<ParameterList> validPL;
576 if (is_null(validPL)) {
577 RCP<ParameterList> pl = Teuchos::parameterList();
578 pl->set(dumpSensitivities_name_, dumpSensitivities_default_,
579 "Set to true to have the individual sensitivities printed to\n"
582 Teuchos::setupVerboseObjectSublist(&*pl);
592 template<
class Scalar>
599 template<
class Scalar>
606 template<
class Scalar>
607 RCP<const Thyra::VectorSpaceBase<Scalar> >
610 #ifdef HAVE_RYTHMOS_DEBUG
611 TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE( l, 0, Np_ );
617 template<
class Scalar>
618 RCP<const Thyra::VectorSpaceBase<Scalar> >
621 #ifdef HAVE_RYTHMOS_DEBUG
622 TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE( j, 0, Ng_ );
628 template<
class Scalar>
629 Thyra::ModelEvaluatorBase::InArgs<Scalar>
632 typedef Thyra::ModelEvaluatorBase MEB;
633 MEB::InArgsSetup<Scalar> inArgs;
634 inArgs.setModelEvalDescription(this->description());
643 template<
class Scalar>
644 Thyra::ModelEvaluatorBase::OutArgs<Scalar>
647 typedef Thyra::ModelEvaluatorBase MEB;
648 typedef MEB::DerivativeSupport DS;
649 namespace FSIAMET = ForwardSensitivityIntegratorAsModelEvaluatorTypes;
650 MEB::OutArgsSetup<Scalar> outArgs;
651 outArgs.setModelEvalDescription(this->description());
652 outArgs.set_Np_Ng(Np_,Ng_);
653 outArgs.setSupports(MEB::OUT_ARG_DgDp, 0 ,0, MEB::DERIV_MV_BY_COL);
658 template<
class Scalar>
659 void ForwardSensitivityIntegratorAsModelEvaluator<Scalar>::evalModelImpl(
660 const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs,
661 const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs
667 using Teuchos::describe;
668 using Teuchos::OSTab;
669 using Teuchos::rcp_dynamic_cast;
670 typedef Teuchos::ScalarTraits<Scalar> ST;
671 typedef Teuchos::VerboseObjectTempState<InterpolationBufferBase<Scalar> > VOTSSB;
672 typedef Thyra::ModelEvaluatorBase MEB;
673 namespace FSIAMET = ForwardSensitivityIntegratorAsModelEvaluatorTypes;
679 THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_GEN_BEGIN(
680 "Rythmos::ForwardSensitivityIntegratorAsModelEvaluator", inArgs, outArgs, null
682 VOTSSB stateIntegrator_outputTempState(
683 stateIntegrator_,out,incrVerbLevel(verbLevel,-1));
684 VOTSSB stateAndSensIntegrator_outputTempState(
685 stateAndSensIntegrator_,out,incrVerbLevel(verbLevel,-1));
688 out.get() && includesVerbLevel(localVerbLevel,Teuchos::VERB_LOW);
689 const bool print_norms =
690 out.get() && includesVerbLevel(localVerbLevel,Teuchos::VERB_MEDIUM);
692 out.get() && includesVerbLevel(localVerbLevel,Teuchos::VERB_EXTREME);
694 const RCP<const Thyra::ModelEvaluator<Scalar> >
695 stateModel = stateStepper_->getModel();
701 RCP<Thyra::VectorBase<Scalar> >
702 d_hat = outArgs.get_g(0);
704 MEB::Derivative<Scalar>
705 D_d_hat_D_p = outArgs.get_DgDp(0,p_index_);
708 const bool integrateStateAndSens = !D_d_hat_D_p.isEmpty();
711 if ( is_null(d_hat) && D_d_hat_D_p.isEmpty() ) {
713 *out <<
"\nSkipping evaluation since no outputs were requested!\n";
722 const RCP<const Thyra::VectorBase<Scalar> >
723 p = inArgs.get_p(0).assert_not_null();
725 if (integrateStateAndSens) {
727 *out <<
"\nComputing D_d_hat_d_p by integrating state+sens ...\n";
728 stateAndSensInitCond_.set_p(p_index_,p);
732 *out <<
"\nComputing just d_hat by integrating the state ...\n";
733 stateInitCond_.set_p(p_index_,p);
740 RCP<IntegratorBase<Scalar> > integrator;
741 if (integrateStateAndSens) {
742 stateAndSensStepper_->setInitialCondition(stateAndSensInitCond_);
743 stateAndSensIntegrator_->setStepper(stateAndSensStepper_,finalTime_);
744 integrator = stateAndSensIntegrator_;
747 stateStepper_->setInitialCondition(stateInitCond_);
748 stateIntegrator_->setStepper(stateStepper_,finalTime_);
749 integrator = stateIntegrator_;
756 ForwardResponseSensitivityComputer<Scalar>
757 forwardResponseSensitivityComputer;
758 forwardResponseSensitivityComputer.setOStream(out);
759 forwardResponseSensitivityComputer.setVerbLevel(localVerbLevel);
760 forwardResponseSensitivityComputer.dumpSensitivities(dumpSensitivities_);
761 forwardResponseSensitivityComputer.setResponseFunction(
763 responseFuncs_[0]->createInArgs(),
770 RCP<Thyra::VectorBase<Scalar> > g_k;
771 RCP<Thyra::MultiVectorBase<Scalar> > D_g_hat_D_p_k;
773 if (!is_null(d_hat)) {
774 g_k = forwardResponseSensitivityComputer.create_g_hat();
776 if (!D_d_hat_D_p.isEmpty()) {
777 D_g_hat_D_p_k = forwardResponseSensitivityComputer.create_D_g_hat_D_p();
782 if (responseType_ == FSIAMET::RESPONSE_TYPE_SUM) {
783 if (!is_null(d_hat)) {
784 assign( d_hat.ptr(), ST::zero() );
786 if (!D_d_hat_D_p.isEmpty()) {
787 assign( D_d_hat_D_p.getMultiVector().ptr(), ST::zero() );
793 RCP<Thyra::ProductVectorBase<Scalar> > prod_d_hat;
794 RCP<Thyra::ProductMultiVectorBase<Scalar> > prod_D_d_hat_D_p_trans;
795 if (responseType_ == FSIAMET::RESPONSE_TYPE_BLOCK) {
796 prod_d_hat = rcp_dynamic_cast<Thyra::ProductVectorBase<Scalar> >(
798 prod_D_d_hat_D_p_trans = rcp_dynamic_cast<Thyra::ProductMultiVectorBase<Scalar> >(
799 D_d_hat_D_p.getMultiVector(),
true);
808 if (trace) *out <<
"\nStarting integration and assembly loop ...\n";
810 const int numResponseFunctions = responseTimes_.size();
812 for (
int k = 0; k < numResponseFunctions; ++k ) {
816 const Scalar t = responseTimes_[k];
824 *out <<
"\nIntegrating state (or state+sens) for response k = "
825 << k <<
" for t = " << t <<
" ...\n";
827 RCP<const Thyra::VectorBase<Scalar> > x_bar, x_bar_dot;
830 RYTHMOS_FUNC_TIME_MONITOR(
831 "Rythmos:ForwardSensitivityIntegratorAsModelEvaluator::evalModel: integrate"
833 get_fwd_x_and_x_dot( *integrator, t, &x_bar, &x_bar_dot );
837 *out <<
"\n||x_bar||inf = " << norms_inf(*x_bar) << std::endl;
838 *out <<
"\n||x_bar_dot||inf = " << norms_inf(*x_bar_dot) << std::endl;
841 *out <<
"\nx_bar = " << *x_bar << std::endl;
842 *out <<
"\nx_bar_dot = " << *x_bar_dot << std::endl;
846 RCP<const Thyra::VectorBase<Scalar> > x, x_dot;
847 RCP<const Thyra::MultiVectorBase<Scalar> > S, S_dot;
848 if (integrateStateAndSens) {
849 extractStateAndSens( x_bar, x_bar_dot, &x, &S, &x_dot, &S_dot );
862 *out <<
"\nEvaluating response function k = " << k <<
" at time t = " << t <<
" ...\n";
864 RCP<const Thyra::ModelEvaluator<Scalar> > responseFunc = responseFuncs_[k];
866 MEB::InArgs<Scalar> responseInArgs = responseFunc->createInArgs();
867 responseInArgs.setArgs(responseFuncInArgs_[k]);
868 responseInArgs.set_p(p_index_,p);
870 forwardResponseSensitivityComputer.resetResponseFunction(
871 responseFunc, responseInArgs
874 if (!is_null(D_g_hat_D_p_k)) {
875 forwardResponseSensitivityComputer.computeResponseAndSensitivity(
876 x_dot.get(), S_dot.get(), *x, *S, t, g_k.get(), &*D_g_hat_D_p_k
880 forwardResponseSensitivityComputer.computeResponse(
881 x_dot.get(), *x, t, g_k.get()
890 if (!is_null(d_hat)) {
891 if (responseType_ == FSIAMET::RESPONSE_TYPE_SUM) {
892 if (trace) *out <<
"\nd_hat += g_k ...\n";
893 Vp_V( d_hat.ptr(), *g_k );
895 else if (responseType_ == FSIAMET::RESPONSE_TYPE_BLOCK) {
896 if (trace) *out <<
"\nd_hat["<<k<<
"] = g_k ...\n";
897 assign( prod_d_hat->getNonconstVectorBlock(k).ptr(), *g_k );
902 if (!D_d_hat_D_p.isEmpty()) {
903 if (responseType_ == FSIAMET::RESPONSE_TYPE_SUM) {
904 if (trace) *out <<
"\nD_d_hat_D_p += D_g_hat_D_p_k ...\n";
905 Vp_V( D_d_hat_D_p.getMultiVector().ptr(), *D_g_hat_D_p_k );
906 if (dumpSensitivities_ || print_x)
907 *out <<
"\nD_d_hat_D_p = "
908 << Teuchos::describe(*D_d_hat_D_p.getMultiVector(),Teuchos::VERB_EXTREME);
910 else if (responseType_ == FSIAMET::RESPONSE_TYPE_BLOCK) {
911 if (trace) *out <<
"\nD_d_hat_D_p["<<k<<
"] = D_g_hat_D_p_k ...\n";
913 prod_D_d_hat_D_p_trans->getNonconstMultiVectorBlock(k).ptr(),
921 THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END();
929 #endif // RYTHMOS_FORWARD_SENSITIVITY_INTEGRATOR_AS_MODEL_EVALUATOR_HPP
RCP< Teuchos::ParameterList > unsetParameterList()
Base class for defining stepper functionality.
Abstract interface for time integrators.
void initialize(const RCP< StepperBase< Scalar > > &stateStepper, const RCP< IntegratorBase< Scalar > > &stateIntegrator, const RCP< ForwardSensitivityStepper< Scalar > > &stateAndSensStepper, const RCP< IntegratorBase< Scalar > > &stateAndSensIntegrator, const Thyra::ModelEvaluatorBase::InArgs< Scalar > &stateAndSensInitCond, const Array< Scalar > &responseTimes, const Array< RCP< const Thyra::ModelEvaluator< Scalar > > > &responseFuncs, const Array< Thyra::ModelEvaluatorBase::InArgs< Scalar > > &responseFuncBasePoints, const ForwardSensitivityIntegratorAsModelEvaluatorTypes::EResponseType responseType)
Initalized with all objects needed to define evaluation.
Foward sensitivity stepper concrete subclass.
const Array< Scalar > & getResponseTimes() const
RCP< Teuchos::ParameterList > getNonconstParameterList()
RCP< const Teuchos::ParameterList > getParameterList() const
Concrete Thyra::ModelEvaluator subclass that turns a forward ODE/DAE with an observation into a param...
RCP< const Teuchos::ParameterList > getValidParameters() const
ForwardSensitivityIntegratorAsModelEvaluator()
Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const
void setParameterList(RCP< Teuchos::ParameterList > const ¶mList)
RCP< const Thyra::VectorSpaceBase< Scalar > > get_g_space(int j) const
RCP< const Thyra::VectorSpaceBase< Scalar > > get_p_space(int l) const