29 #ifndef RYTHMOS_ADJOINT_MODEL_EVALUATOR_HPP
30 #define RYTHMOS_ADJOINT_MODEL_EVALUATOR_HPP
33 #include "Rythmos_IntegratorBase.hpp"
34 #include "Thyra_ModelEvaluator.hpp"
35 #include "Thyra_StateFuncModelEvaluatorBase.hpp"
36 #include "Thyra_ModelEvaluatorDelegatorBase.hpp"
37 #include "Thyra_DefaultScaledAdjointLinearOp.hpp"
38 #include "Thyra_DefaultAdjointLinearOpWithSolve.hpp"
39 #include "Thyra_VectorStdOps.hpp"
40 #include "Thyra_MultiVectorStdOps.hpp"
41 #include "Teuchos_implicit_cast.hpp"
42 #include "Teuchos_Assert.hpp"
172 template<
class Scalar>
174 :
virtual public Thyra::StateFuncModelEvaluatorBase<Scalar>
186 const RCP<
const Thyra::ModelEvaluator<Scalar> > &fwdStateModel,
187 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &basePoint );
215 RCP<const Thyra::VectorSpaceBase<Scalar> >
get_x_space()
const;
217 RCP<const Thyra::VectorSpaceBase<Scalar> >
get_f_space()
const;
221 RCP<Thyra::LinearOpWithSolveBase<Scalar> >
create_W()
const;
223 RCP<Thyra::LinearOpBase<Scalar> >
create_W_op()
const;
225 Thyra::ModelEvaluatorBase::InArgs<Scalar>
createInArgs()
const;
235 Thyra::ModelEvaluatorBase::OutArgs<Scalar> createOutArgsImpl()
const;
238 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs_bar,
239 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs_bar
249 RCP<const Thyra::ModelEvaluator<Scalar> > fwdStateModel_;
250 Thyra::ModelEvaluatorBase::InArgs<Scalar> basePoint_;
252 RCP<const InterpolationBufferBase<Scalar> > fwdStateSolutionBuffer_;
254 mutable bool isInitialized_;
255 mutable Thyra::ModelEvaluatorBase::InArgs<Scalar> prototypeInArgs_bar_;
256 mutable Thyra::ModelEvaluatorBase::OutArgs<Scalar> prototypeOutArgs_bar_;
257 mutable Thyra::ModelEvaluatorBase::InArgs<Scalar> adjointNominalValues_;
258 mutable RCP<Thyra::LinearOpBase<Scalar> > my_W_bar_adj_op_;
259 mutable RCP<Thyra::LinearOpBase<Scalar> > my_d_f_d_x_dot_op_;
265 void initialize()
const;
274 template<
class Scalar>
275 RCP<AdjointModelEvaluator<Scalar> >
277 const RCP<
const Thyra::ModelEvaluator<Scalar> > &fwdStateModel,
281 RCP<AdjointModelEvaluator<Scalar> >
283 adjointModel->setFwdStateModel(fwdStateModel, fwdStateModel->getNominalValues());
284 adjointModel->setFwdTimeRange(fwdTimeRange);
296 template<
class Scalar>
298 :isInitialized_(false)
302 template<
class Scalar>
304 const RCP<
const Thyra::ModelEvaluator<Scalar> > &fwdStateModel,
305 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &basePoint
308 TEUCHOS_TEST_FOR_EXCEPT(is_null(fwdStateModel));
309 fwdStateModel_ = fwdStateModel;
310 basePoint_ = basePoint;
311 isInitialized_ =
false;
315 template<
class Scalar>
319 fwdTimeRange_ = fwdTimeRange;
323 template<
class Scalar>
327 TEUCHOS_TEST_FOR_EXCEPT(is_null(fwdStateSolutionBuffer));
328 fwdStateSolutionBuffer_ = fwdStateSolutionBuffer;
335 template<
class Scalar>
336 RCP<const Thyra::VectorSpaceBase<Scalar> >
340 return fwdStateModel_->get_f_space();
344 template<
class Scalar>
345 RCP<const Thyra::VectorSpaceBase<Scalar> >
349 return fwdStateModel_->get_x_space();
353 template<
class Scalar>
354 Thyra::ModelEvaluatorBase::InArgs<Scalar>
358 return adjointNominalValues_;
362 template<
class Scalar>
363 RCP<Thyra::LinearOpWithSolveBase<Scalar> >
367 return Thyra::nonconstAdjointLows<Scalar>(fwdStateModel_->create_W());
371 template<
class Scalar>
372 RCP<Thyra::LinearOpBase<Scalar> >
376 return Thyra::nonconstAdjoint<Scalar>(fwdStateModel_->create_W_op());
380 template<
class Scalar>
381 Thyra::ModelEvaluatorBase::InArgs<Scalar>
385 return prototypeInArgs_bar_;
392 template<
class Scalar>
393 Thyra::ModelEvaluatorBase::OutArgs<Scalar>
397 return prototypeOutArgs_bar_;
401 template<
class Scalar>
402 void AdjointModelEvaluator<Scalar>::evalModelImpl(
403 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs_bar,
404 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs_bar
408 using Teuchos::rcp_dynamic_cast;
409 using Teuchos::describe;
410 typedef Teuchos::ScalarTraits<Scalar> ST;
411 typedef Thyra::ModelEvaluatorBase MEB;
412 typedef Thyra::DefaultScaledAdjointLinearOp<Scalar> DSALO;
413 typedef Thyra::DefaultAdjointLinearOpWithSolve<Scalar> DALOWS;
414 typedef Teuchos::VerboseObjectTempState<Thyra::ModelEvaluatorBase> VOTSME;
420 THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_GEN_BEGIN(
421 "AdjointModelEvaluator", inArgs_bar, outArgs_bar, Teuchos::null );
425 VOTSME fwdStateModel_outputTempState(fwdStateModel_,out,verbLevel);
428 const bool dumpAll = includesVerbLevel(localVerbLevel, Teuchos::VERB_EXTREME);
436 const Scalar t_bar = inArgs_bar.get_t();
437 const RCP<const Thyra::VectorBase<Scalar> >
438 lambda_rev_dot = inArgs_bar.get_x_dot().assert_not_null(),
439 lambda = inArgs_bar.get_x().assert_not_null();
440 const Scalar alpha_bar = inArgs_bar.get_alpha();
441 const Scalar beta_bar = inArgs_bar.get_beta();
444 *out <<
"\nlambda_rev_dot = " << describe(*lambda_rev_dot, Teuchos::VERB_EXTREME);
445 *out <<
"\nlambda = " << describe(*lambda, Teuchos::VERB_EXTREME);
446 *out <<
"\nalpha_bar = " << alpha_bar <<
"\n";
447 *out <<
"\nbeta_bar = " << beta_bar <<
"\n";
452 const RCP<Thyra::VectorBase<Scalar> > f_bar = outArgs_bar.get_f();
455 if (outArgs_bar.supports(MEB::OUT_ARG_W))
456 W_bar = rcp_dynamic_cast<DALOWS>(outArgs_bar.get_W(),
true);
459 if (outArgs_bar.supports(MEB::OUT_ARG_W_op))
460 W_bar_op = rcp_dynamic_cast<DSALO>(outArgs_bar.get_W_op(),
true);
463 if (!is_null(W_bar)) {
464 *out <<
"\nW_bar = " << describe(*W_bar, Teuchos::VERB_EXTREME);
466 if (!is_null(W_bar_op)) {
467 *out <<
"\nW_bar_op = " << describe(*W_bar_op, Teuchos::VERB_EXTREME);
475 MEB::InArgs<Scalar> fwdInArgs = fwdStateModel_->createInArgs();
479 fwdInArgs = basePoint_;
481 if (!is_null(fwdStateSolutionBuffer_)) {
482 const Scalar t = fwdTimeRange_.length() - t_bar;
483 RCP<const Thyra::VectorBase<Scalar> > x, x_dot;
484 get_x_and_x_dot<Scalar>( *fwdStateSolutionBuffer_, t,
485 outArg(x), outArg(x_dot) );
487 fwdInArgs.set_x_dot(x);
504 RCP<Thyra::LinearOpWithSolveBase<Scalar> > W_bar_adj;
505 RCP<Thyra::LinearOpBase<Scalar> > W_bar_adj_op;
508 MEB::OutArgs<Scalar> fwdOutArgs = fwdStateModel_->createOutArgs();
511 if (!is_null(W_bar)) {
514 W_bar_adj = W_bar->getNonconstOp();
515 W_bar_adj_op = W_bar_adj;
517 else if (!is_null(W_bar_op)) {
520 W_bar_adj_op = W_bar_op->getNonconstOp();
522 else if (!is_null(f_bar)) {
523 TEUCHOS_TEST_FOR_EXCEPT_MSG(
true,
"ToDo: Unit test this code!");
527 if (is_null(my_W_bar_adj_op_)) {
528 my_W_bar_adj_op_ = fwdStateModel_->create_W_op();
530 W_bar_adj_op = my_W_bar_adj_op_;
534 if (!is_null(W_bar_adj)) {
535 fwdOutArgs.set_W(W_bar_adj);
537 else if (!is_null(W_bar_adj_op)) {
538 fwdOutArgs.set_W_op(W_bar_adj_op);
542 if (!is_null(W_bar_adj) || !is_null(W_bar_adj_op)) {
543 fwdInArgs.set_alpha(alpha_bar);
544 fwdInArgs.set_beta(beta_bar);
548 if (!is_null(W_bar_adj) || !is_null(W_bar_adj_op)) {
549 fwdStateModel_->evalModel( fwdInArgs, fwdOutArgs );
553 if (!is_null(W_bar_adj) && dumpAll)
554 *out <<
"\nW_bar_adj = " << describe(*W_bar_adj, Teuchos::VERB_EXTREME);
555 if (!is_null(W_bar_adj_op) && dumpAll)
556 *out <<
"\nW_bar_adj_op = " << describe(*W_bar_adj_op, Teuchos::VERB_EXTREME);
562 RCP<Thyra::LinearOpBase<Scalar> > d_f_d_x_dot_op;
563 if (!is_null(f_bar)) {
564 if (is_null(my_d_f_d_x_dot_op_)) {
565 my_d_f_d_x_dot_op_ = fwdStateModel_->create_W_op();
567 d_f_d_x_dot_op = my_d_f_d_x_dot_op_;
568 MEB::OutArgs<Scalar> fwdOutArgs = fwdStateModel_->createOutArgs();
569 fwdOutArgs.set_W_op(d_f_d_x_dot_op);
570 fwdInArgs.set_alpha(ST::one());
571 fwdInArgs.set_beta(ST::zero());
572 fwdStateModel_->evalModel( fwdInArgs, fwdOutArgs );
574 *out <<
"\nd_f_d_x_dot_op = " << describe(*d_f_d_x_dot_op, Teuchos::VERB_EXTREME);
585 if (!is_null(f_bar)) {
588 const RCP<Thyra::VectorBase<Scalar> >
589 lambda_hat = createMember(lambda_rev_dot->space());
590 Thyra::V_VpStV<Scalar>( outArg(*lambda_hat),
591 *lambda_rev_dot, -alpha_bar/beta_bar, *lambda );
593 *out <<
"\nlambda_hat = " << describe(*lambda_hat, Teuchos::VERB_EXTREME);
596 Thyra::apply<Scalar>( *d_f_d_x_dot_op, Thyra::CONJTRANS, *lambda_hat,
600 Thyra::apply<Scalar>( *W_bar_adj_op, Thyra::CONJTRANS, *lambda,
601 outArg(*f_bar), 1.0/beta_bar, ST::one() );
608 *out <<
"\nf_bar = " << describe(*f_bar, Teuchos::VERB_EXTREME);
613 if (!is_null(W_bar)) {
614 *out <<
"\nW_bar = " << describe(*W_bar, Teuchos::VERB_EXTREME);
616 if (!is_null(W_bar_op)) {
617 *out <<
"\nW_bar_op = " << describe(*W_bar_op, Teuchos::VERB_EXTREME);
626 THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END();
634 template<
class Scalar>
635 void AdjointModelEvaluator<Scalar>::initialize()
const
638 typedef Thyra::ModelEvaluatorBase MEB;
647 MEB::InArgs<Scalar> fwdStateModelInArgs = fwdStateModel_->createInArgs();
648 MEB::OutArgs<Scalar> fwdStateModelOutArgs = fwdStateModel_->createOutArgs();
650 #ifdef HAVE_RYTHMOS_DEBUG
651 TEUCHOS_ASSERT( fwdStateModelInArgs.supports(MEB::IN_ARG_x_dot) );
652 TEUCHOS_ASSERT( fwdStateModelInArgs.supports(MEB::IN_ARG_x) );
653 TEUCHOS_ASSERT( fwdStateModelInArgs.supports(MEB::IN_ARG_t) );
654 TEUCHOS_ASSERT( fwdStateModelInArgs.supports(MEB::IN_ARG_alpha) );
655 TEUCHOS_ASSERT( fwdStateModelInArgs.supports(MEB::IN_ARG_beta) );
656 TEUCHOS_ASSERT( fwdStateModelOutArgs.supports(MEB::OUT_ARG_f) );
657 TEUCHOS_ASSERT( fwdStateModelOutArgs.supports(MEB::OUT_ARG_W) );
665 MEB::InArgsSetup<Scalar> inArgs_bar;
666 inArgs_bar.setModelEvalDescription(this->description());
667 inArgs_bar.setSupports( MEB::IN_ARG_x_dot );
668 inArgs_bar.setSupports( MEB::IN_ARG_x );
669 inArgs_bar.setSupports( MEB::IN_ARG_t );
670 inArgs_bar.setSupports( MEB::IN_ARG_alpha );
671 inArgs_bar.setSupports( MEB::IN_ARG_beta );
672 prototypeInArgs_bar_ = inArgs_bar;
676 MEB::OutArgsSetup<Scalar> outArgs_bar;
677 outArgs_bar.setModelEvalDescription(this->description());
678 outArgs_bar.setSupports(MEB::OUT_ARG_f);
679 if (fwdStateModelOutArgs.supports(MEB::OUT_ARG_W) ) {
680 outArgs_bar.setSupports(MEB::OUT_ARG_W);
681 outArgs_bar.set_W_properties(fwdStateModelOutArgs.get_W_properties());
683 if (fwdStateModelOutArgs.supports(MEB::OUT_ARG_W_op) ) {
684 outArgs_bar.setSupports(MEB::OUT_ARG_W_op);
685 outArgs_bar.set_W_properties(fwdStateModelOutArgs.get_W_properties());
687 prototypeOutArgs_bar_ = outArgs_bar;
695 adjointNominalValues_ = prototypeInArgs_bar_;
697 const RCP<Thyra::VectorBase<Scalar> > zero_lambda_vec =
698 createMember(fwdStateModel_->get_f_space());
699 V_S( zero_lambda_vec.ptr(), ScalarTraits<Scalar>::zero() );
700 adjointNominalValues_.set_x_dot(zero_lambda_vec);
701 adjointNominalValues_.set_x(zero_lambda_vec);
707 my_W_bar_adj_op_ = Teuchos::null;
708 my_d_f_d_x_dot_op_ = Teuchos::null;
714 isInitialized_ =
true;
722 #endif // RYTHMOS_ADJOINT_MODEL_EVALUATOR_HPP
RCP< const Thyra::VectorSpaceBase< Scalar > > get_f_space() const
Standard concrete adjoint ModelEvaluator for time-constant mass matrix models.
RCP< Thyra::LinearOpBase< Scalar > > create_W_op() const
Thyra::ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const
RCP< Thyra::LinearOpWithSolveBase< Scalar > > create_W() const
Base class for an interpolation buffer.
RCP< AdjointModelEvaluator< Scalar > > adjointModelEvaluator(const RCP< const Thyra::ModelEvaluator< Scalar > > &fwdStateModel, const TimeRange< Scalar > &fwdTimeRange)
Nonmember constructor.
void setFwdStateSolutionBuffer(const RCP< const InterpolationBufferBase< Scalar > > &fwdStateSolutionBuffer)
Set the interpolation buffer that will return values of the state solution x and x_dot at various poi...
Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const
void setFwdStateModel(const RCP< const Thyra::ModelEvaluator< Scalar > > &fwdStateModel, const Thyra::ModelEvaluatorBase::InArgs< Scalar > &basePoint)
Set the underlying forward model and base point.
void setFwdTimeRange(const TimeRange< Scalar > &fwdTimeRange)
Set the forward time range that this adjoint model will be defined over.
RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const