10#ifndef THYRA_MODEL_EVALUATOR_HELPERS_HPP
11#define THYRA_MODEL_EVALUATOR_HELPERS_HPP
14#include "Thyra_ModelEvaluator.hpp"
86 ,
const std::string &derivName
95 ,
const std::string &derivName
105template<
class Scalar>
107 const std::string &modelEvalDescription,
109 const std::string &deriv_name,
111 const std::string &fnc_space_name,
113 const std::string &var_space_name
121template<
class Scalar>
123 const std::string &modelEvalDescription,
133template<
class Scalar>
144template<
class Scalar>
153template<
class Scalar>
162template<
class Scalar>
172template<
class Scalar>
182template<
class Scalar>
193template<
class Scalar>
205template<
class Scalar>
217template<
class Scalar>
229template<
class Scalar>
242#ifdef HAVE_THYRA_ME_POLYNOMIAL
246template<
class Scalar>
256template<
class Scalar>
277#include "Thyra_AssertOp.hpp"
281template<
class Scalar>
292template<
class Scalar>
294Thyra::derivativeGradient(
295 const RCP<MultiVectorBase<Scalar> > &grad
298 return ModelEvaluatorBase::Derivative<Scalar>(
300 ModelEvaluatorBase::DERIV_MV_GRADIENT_FORM
305template<
class Scalar>
307Thyra::create_DfDp_mv(
308 const ModelEvaluator<Scalar>& model,
310 ModelEvaluatorBase::EDerivativeMultiVectorOrientation orientation
314 return createMembers( model.get_f_space(), model.get_p_space(l)->dim() );
318template<
class Scalar>
320Thyra::create_DgDx_dot_mv(
321 const ModelEvaluator<Scalar>& model,
323 ModelEvaluatorBase::EDerivativeMultiVectorOrientation orientation
326 typedef ModelEvaluatorBase MEB;
327 switch(orientation) {
328 case MEB::DERIV_MV_BY_COL:
330 MEB::DerivativeMultiVector<Scalar>(
331 createMembers( model.get_g_space(j), model.get_x_space()->dim() )
332 ,MEB::DERIV_MV_BY_COL
334 case MEB::DERIV_TRANS_MV_BY_ROW:
336 MEB::DerivativeMultiVector<Scalar>(
337 createMembers( model.get_x_space(), model.get_g_space(j)->dim() )
338 ,MEB::DERIV_TRANS_MV_BY_ROW
347template<
class Scalar>
349Thyra::create_DgDx_mv(
350 const ModelEvaluator<Scalar>& model,
352 ModelEvaluatorBase::EDerivativeMultiVectorOrientation orientation
355 return create_DgDx_dot_mv(model,j,orientation);
359template<
class Scalar>
361Thyra::create_DgDp_mv(
362 const ModelEvaluator<Scalar>& model,
365 ModelEvaluatorBase::EDerivativeMultiVectorOrientation orientation
368 typedef ModelEvaluatorBase MEB;
369 switch(orientation) {
370 case MEB::DERIV_MV_BY_COL:
372 MEB::DerivativeMultiVector<Scalar>(
373 createMembers( model.get_g_space(j), model.get_p_space(l)->dim() )
374 ,MEB::DERIV_MV_BY_COL
376 case MEB::DERIV_TRANS_MV_BY_ROW:
378 MEB::DerivativeMultiVector<Scalar>(
379 createMembers( model.get_p_space(l), model.get_g_space(j)->dim() )
380 ,MEB::DERIV_TRANS_MV_BY_ROW
389template<
class Scalar>
392 const ModelEvaluatorBase::Derivative<Scalar> &deriv
393 ,
const std::string &derivName
397 deriv.getLinearOp().get()!=NULL, std::logic_error
398 ,
"Error, LinearOpBase type not expected for " << derivName <<
"!"
400 return deriv.getDerivativeMultiVector();
404template<
class Scalar>
407 const ModelEvaluatorBase::Derivative<Scalar> &deriv
408 ,
const std::string &derivName
409 ,ModelEvaluatorBase::EDerivativeMultiVectorOrientation orientation
412 typedef ModelEvaluatorBase MEB;
414 deriv.getLinearOp().get()!=NULL, std::logic_error
415 ,
"Error, LinearOpBase type not expected for " << derivName <<
"!"
417 MEB::DerivativeMultiVector<Scalar>
418 dmv = deriv.getDerivativeMultiVector();
419 RCP<MultiVectorBase<Scalar> >
420 mv = dmv.getMultiVector();
423 dmv.getOrientation() != orientation, std::logic_error
424 ,
"Error, the orientation " <<
toString(dmv.getOrientation()) <<
" is not the"
425 " expected orientation of " <<
toString(orientation)
426 <<
" for " << derivName <<
"!"
433template<
class Scalar>
435 const std::string &modelEvalDescription,
437 const std::string &deriv_name,
439 const std::string &fnc_space_name,
441 const std::string &var_space_name
447 if (!is_null(lo->range())) {
449 modelEvalDescription,
450 *lo->range(), deriv_name +
".range()",
451 fnc_space, fnc_space_name
454 modelEvalDescription,
455 *lo->domain(), deriv_name +
".domain()",
456 var_space, var_space_name
463 case MEB::DERIV_MV_BY_COL: {
465 modelEvalDescription,
466 *mv->range(), deriv_name +
".range()",
467 fnc_space, fnc_space_name
470 modelEvalDescription,
471 *mv->domain(), deriv_name +
".domain()",
472 var_space, var_space_name
476 case MEB::DERIV_TRANS_MV_BY_ROW: {
478 modelEvalDescription,
479 *mv->range(), deriv_name +
"^T.range()",
480 var_space, var_space_name
483 modelEvalDescription,
484 *mv->domain(), deriv_name +
"^T.domain()",
485 fnc_space, fnc_space_name
498template<
class Scalar>
500 const std::string &modelEvalDescription,
508 const int Ng = outArgs.
Ng();
509 const int Np = outArgs.
Np();
517 inArgs.
Np() != outArgs.
Np(), std::logic_error,
518 "Error: The underlying model " << modelEvalDescription <<
" incorrectly\n"
519 "set inArgs.Np() = "<<inArgs.
Np()<<
" != outArgs.Np() = "
527 "Error: The underlying model " << modelEvalDescription <<
" supports\n"
528 "x_dot but does not support x!"
535 "Error: The underlying model " << modelEvalDescription <<
" supports\n"
536 "x_dot but does not support t!"
547 "Error: The underlying model " << modelEvalDescription <<
" says that\n"
548 "it supports W and/or W_op but it does not support x!"
556 !( inArgs.
supports(MEB::IN_ARG_alpha) && inArgs.
supports(MEB::IN_ARG_beta) )
559 "Error: The underlying model " << modelEvalDescription <<
" supports W and/or W_op\n"
560 "and x_dot but it does not support alpha and beta as InArgs! \n"
561 "If the model supports W and x_dot, then it can be interpreted as an implicit \n"
562 "ODE/DAE and therefore D(f)/D(x_dot) must be non-zero and therefore alpha must \n"
563 "be supported. If, however, the model can be interpreted as an explicit ODE \n"
564 "then x_dot should not be supported at all."
567 for (
int l = 0; l <
Np; ++l ) {
571 for (
int j = 0; j <
Ng; ++j ) {
575 ( !outArgs.
supports(MEB::OUT_ARG_DgDx_dot,j).none()
576 && !inArgs.
supports(MEB::IN_ARG_x_dot) ),
578 "Error: The underlying model " << modelEvalDescription <<
" says that\n"
579 "it supports DgDx_dot("<<j<<
") but it does not support x_dot!"
584 ( !outArgs.
supports(MEB::OUT_ARG_DgDx,j).none()
585 && !inArgs.
supports(MEB::IN_ARG_x) ),
587 "Error: The underlying model " << modelEvalDescription <<
" says that\n"
588 "it supports DgDx("<<j<<
") but it does not support x!"
600template<
class Scalar>
610 const int Np = inArgs.
Np();
621 if ( inArgs.
supports(MEB::IN_ARG_x) && !is_null(inArgs.
get_x()) ) {
627 for (
int l = 0; l <
Np; ++l ) {
628 if (!is_null(inArgs.
get_p(l))) {
637template<
class Scalar>
650 const int Ng = outArgs.
Ng();
651 const int Np = outArgs.
Np();
660 if ( outArgs.
supports(MEB::OUT_ARG_f) && !is_null(outArgs.
get_f()) ) {
666 if ( outArgs.
supports(MEB::OUT_ARG_W) && !is_null(outArgs.
get_W()) ) {
667 if (!is_null(outArgs.
get_W()->range())) {
676 if ( outArgs.
supports(MEB::OUT_ARG_W_op) && !is_null(outArgs.
get_W_op()) ) {
677 if (!is_null(outArgs.
get_W_op()->range())) {
691 ( outArgs.
supports(MEB::OUT_ARG_W) && !is_null(outArgs.
get_W()) )
697 if ( inArgs->
supports(MEB::IN_ARG_alpha) && inArgs->
supports(MEB::IN_ARG_beta) ) {
705 else if ( inArgs->
supports(MEB::IN_ARG_beta) ) {
711 if (outArgs.
supports(MEB::OUT_ARG_f)) {
712 for (
int l = 0; l <
Np; ++l ) {
713 if (!outArgs.
supports(MEB::OUT_ARG_DfDp,l).none()) {
716 outArgs.
get_DfDp(l),
"DfDp("+TU::toString(l)+
")",
718 *model.
get_p_space(l),
"p_space("+TU::toString(l)+
")"
725 for (
int j = 0; j <
Ng; ++j ) {
726 if (!is_null(outArgs.
get_g(j))) {
733 for (
int j = 0; j <
Ng; ++j ) {
734 if (!outArgs.
supports(MEB::OUT_ARG_DgDx_dot,j).none()) {
737 outArgs.
get_DgDx_dot(j),
"DgDx_dot("+TU::toString(j)+
")",
738 *model.
get_g_space(j),
"g_space("+TU::toString(j)+
")",
745 for (
int j = 0; j <
Ng; ++j ) {
746 if (!outArgs.
supports(MEB::OUT_ARG_DgDx,j).none()) {
749 outArgs.
get_DgDx(j),
"DgDx("+TU::toString(j)+
")",
750 *model.
get_g_space(j),
"g_space("+TU::toString(j)+
")",
757 for (
int j = 0; j <
Ng; ++j ) {
758 for (
int l = 0; l <
Np; ++l ) {
759 if (!outArgs.
supports(MEB::OUT_ARG_DgDp,j,l).none()) {
760 const std::string j_str = TU::toString(j);
761 const std::string l_str = TU::toString(l);
764 outArgs.
get_DgDp(j,l),
"DgDp("+j_str+
","+l_str+
")",
775template<
class Scalar>
791template<
class Scalar>
793 const ModelEvaluator<Scalar> &model
794 ,
const VectorBase<Scalar> &x
795 ,VectorBase<Scalar> *f
796 ,LinearOpWithSolveBase<Scalar> *W
800 typedef ModelEvaluatorBase MEB;
802 MEB::InArgs<Scalar> inArgs = model.createInArgs();
803 MEB::OutArgs<Scalar> outArgs = model.createOutArgs();
810 model.evalModel(inArgs,outArgs);
815template<
class Scalar>
817 const ModelEvaluator<Scalar> &model
818 ,
const VectorBase<Scalar> &x
820 ,VectorBase<Scalar> *f
823 typedef ModelEvaluatorBase MEB;
824 MEB::InArgs<Scalar> inArgs = model.createInArgs();
825 MEB::OutArgs<Scalar> outArgs = model.createOutArgs();
827 if(inArgs.supports(MEB::IN_ARG_t)) inArgs.set_t(t);
829 model.evalModel(inArgs,outArgs);
833template<
class Scalar>
835 const ModelEvaluator<Scalar> &model,
837 const VectorBase<Scalar> &p_l,
839 const Ptr<VectorBase<Scalar> > &g_j
842 typedef ModelEvaluatorBase MEB;
843 MEB::InArgs<Scalar> inArgs = model.createInArgs();
844 MEB::OutArgs<Scalar> outArgs= model.createOutArgs();
845 inArgs.set_p(l, Teuchos::rcpFromRef(p_l));
846 outArgs.set_g(j, Teuchos::rcpFromRef(*g_j));
847 model.evalModel(inArgs,outArgs);
851template<
class Scalar>
853 const ModelEvaluator<Scalar> &model,
855 const VectorBase<Scalar> &p_l,
858 VectorBase<Scalar> *g_j
861 typedef ModelEvaluatorBase MEB;
862 MEB::InArgs<Scalar> inArgs = model.createInArgs();
863 MEB::OutArgs<Scalar> outArgs= model.createOutArgs();
867 model.evalModel(inArgs,outArgs);
871template<
class Scalar>
872void Thyra::eval_g_DgDp(
873 const ModelEvaluator<Scalar> &model,
875 const VectorBase<Scalar> &p_l,
877 const Ptr<VectorBase<Scalar> > &g_j,
878 const ModelEvaluatorBase::Derivative<Scalar> &DgDp_j_l
881 typedef ModelEvaluatorBase MEB;
882 MEB::InArgs<Scalar> inArgs = model.createInArgs();
883 MEB::OutArgs<Scalar> outArgs= model.createOutArgs();
884 inArgs.set_p(l, Teuchos::rcpFromRef(p_l));
886 outArgs.set_g(j, Teuchos::rcpFromPtr(g_j));
888 if (!DgDp_j_l.isEmpty()) {
889 outArgs.set_DgDp(j, l, DgDp_j_l);
891 model.evalModel(inArgs,outArgs);
895template<
class Scalar>
897 const ModelEvaluator<Scalar> &model
898 ,
const VectorBase<Scalar> &x_dot
899 ,
const VectorBase<Scalar> &x
900 ,
const typename ModelEvaluatorBase::InArgs<Scalar>::ScalarMag &t
901 ,VectorBase<Scalar> *f
905 typedef ModelEvaluatorBase MEB;
907 MEB::InArgs<Scalar> inArgs = model.createInArgs();
908 MEB::OutArgs<Scalar> outArgs = model.createOutArgs();
912 if(inArgs.supports(MEB::IN_ARG_t))
917 model.evalModel(inArgs,outArgs);
922template<
class Scalar>
924 const ModelEvaluator<Scalar> &model
925 ,
const VectorBase<Scalar> &x_dot
926 ,
const VectorBase<Scalar> &x
927 ,
const typename ModelEvaluatorBase::InArgs<Scalar>::ScalarMag &t
930 ,VectorBase<Scalar> *f
931 ,LinearOpWithSolveBase<Scalar> *W
935 typedef ModelEvaluatorBase MEB;
937 MEB::InArgs<Scalar> inArgs = model.createInArgs();
938 MEB::OutArgs<Scalar> outArgs = model.createOutArgs();
942 if(inArgs.supports(MEB::IN_ARG_t))
944 inArgs.set_alpha(alpha);
945 inArgs.set_beta(beta);
950 model.evalModel(inArgs,outArgs);
955#ifdef HAVE_THYRA_ME_POLYNOMIAL
958template<
class Scalar>
959void Thyra::eval_f_poly(
960 const ModelEvaluator<Scalar> &model
962 ,
const typename ModelEvaluatorBase::InArgs<Scalar>::ScalarMag &t
967 typedef ModelEvaluatorBase MEB;
969 MEB::InArgs<Scalar> inArgs = model.createInArgs();
970 MEB::OutArgs<Scalar> outArgs = model.createOutArgs();
973 if(inArgs.supports(MEB::IN_ARG_t))
978 model.evalModel(inArgs,outArgs);
983template<
class Scalar>
984void Thyra::eval_f_poly(
985 const ModelEvaluator<Scalar> &model
987 ,
const VectorBase<Scalar> &x_poly
988 ,
const typename ModelEvaluatorBase::InArgs<Scalar>::ScalarMag &t
993 typedef ModelEvaluatorBase MEB;
995 MEB::InArgs<Scalar> inArgs = model.createInArgs();
996 MEB::OutArgs<Scalar> outArgs = model.createOutArgs();
1000 if(inArgs.supports(MEB::IN_ARG_t))
1005 model.evalModel(inArgs,outArgs);
virtual std::string description() const
Base class for all linear operators that can support a high-level solve operation.
Simple aggregate class for a derivative object represented as a column-wise multi-vector or its trans...
Simple aggregate class that stores a derivative object as a general linear operator or as a multi-vec...
RCP< MultiVectorBase< Scalar > > getMultiVector() const
RCP< LinearOpBase< Scalar > > getLinearOp() const
EDerivativeMultiVectorOrientation getMultiVectorOrientation() const
Concrete aggregate class for all input arguments computable by a ModelEvaluator subclass object.
std::string modelEvalDescription() const
RCP< const VectorBase< Scalar > > get_p(int l) const
Get p(l) where 0 <= l && l < this->Np().
Scalar get_beta() const
Precondition: supports(IN_ARG_beta)==true.
RCP< const VectorBase< Scalar > > get_x() const
Precondition: supports(IN_ARG_x)==true.
Teuchos::ScalarTraits< Scalar >::magnitudeType ScalarMag
RCP< const VectorBase< Scalar > > get_x_dot() const
Precondition: supports(IN_ARG_x_dot)==true.
bool supports(EInArgsMembers arg) const
Determines if an input argument is supported or not.
int Np() const
Return the number of parameter subvectors p(l) supported (Np >= 0).
Concrete aggregate class for all output arguments computable by a ModelEvaluator subclass object.
Derivative< Scalar > get_DfDp(int l) const
Precondition: supports(OUT_ARG_DfDp,l)==true.
RCP< LinearOpWithSolveBase< Scalar > > get_W() const
Precondition: supports(OUT_ARG_W)==true.
int Ng() const
Return the number of axillary response functions g(j)(...) supported (Ng >= 0).
std::string modelEvalDescription() const
Derivative< Scalar > get_DgDp(int j, int l) const
Precondition: supports(OUT_ARG_DgDp,j,l)==true.
Evaluation< VectorBase< Scalar > > get_f() const
Precondition: supports(OUT_ARG_f)==true.
RCP< LinearOpBase< Scalar > > get_W_op() const
Precondition: supports(OUT_ARG_W_op)==true.
Derivative< Scalar > get_DgDx_dot(int j) const
Precondition: supports(OUT_ARG_DgDx_dot,j)==true.
Derivative< Scalar > get_DgDx(int j) const
Precondition: supports(OUT_ARG_DgDx,j)==true.
bool supports(EOutArgsMembers arg) const
Determine if an input argument is supported or not.
int Np() const
Return the number of parameter subvectors p(l) supported (Np >= 0).
Evaluation< VectorBase< Scalar > > get_g(int j) const
Precondition: supports(OUT_ARG_g)==true..
Base subclass for ModelEvaluator that defines some basic types.
EDerivativeMultiVectorOrientation
void assertInArgsEvalObjects(const ModelEvaluator< Scalar > &model, const ModelEvaluatorBase::InArgs< Scalar > &inArgs)
Assert that the objects in an InArgs object match a given model.
void assertInArgsOutArgsSetup(const std::string &modelEvalDescription, const ModelEvaluatorBase::InArgs< Scalar > &inArgs, const ModelEvaluatorBase::OutArgs< Scalar > &outArgs)
Assert that an InArgs and OutArgs object are setup consistently.
void assertOutArgsEvalObjects(const ModelEvaluator< Scalar > &model, const ModelEvaluatorBase::OutArgs< Scalar > &outArgs, const ModelEvaluatorBase::InArgs< Scalar > *inArgs=0)
Assert that the objects in an OutArgs object match a given model.
void assertDerivSpaces(const std::string &modelEvalDescription, const ModelEvaluatorBase::Derivative< Scalar > &deriv, const std::string &deriv_name, const VectorSpaceBase< Scalar > &fnc_space, const std::string &fnc_space_name, const VectorSpaceBase< Scalar > &var_space, const std::string &var_space_name)
Assert that that Thyra objects imbedded in a Derivative object matches its function and variable spac...
RCP< ModelEvaluatorBase::InArgs< Scalar > > clone(const ModelEvaluatorBase::InArgs< Scalar > &inArgs)
Create a clone of an InArgs object.
Pure abstract base interface for evaluating a stateless "model" that can be mapped into a number of d...
virtual RCP< const VectorSpaceBase< Scalar > > get_f_space() const =0
Return the vector space for the state function f(...) <: RE^n_x.
virtual ModelEvaluatorBase::OutArgs< Scalar > createOutArgs() const =0
Create an empty output functions/derivatives object that can be set up and passed to evalModel().
virtual RCP< const VectorSpaceBase< Scalar > > get_g_space(int j) const =0
Return the vector space for the auxiliary response functions g(j) <: RE^n_g_j.
virtual ModelEvaluatorBase::InArgs< Scalar > createInArgs() const =0
Create an empty input arguments object that can be set up and passed to evalModel().
virtual RCP< const VectorSpaceBase< Scalar > > get_p_space(int l) const =0
Return the vector space for the auxiliary parameters p(l) <: RE^n_p_l.
virtual RCP< const VectorSpaceBase< Scalar > > get_x_space() const =0
Return the vector space for the state variables x <: RE^n_x.
virtual void evalModel(const ModelEvaluatorBase::InArgs< Scalar > &inArgs, const ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const =0
Compute all of the requested functions/derivatives at the given point.
Interface for a collection of column vectors called a multi-vector.
Abstract interface for finite-dimensional dense vectors.
Abstract interface for objects that represent a space for vectors.
RCP< MultiVectorBase< Scalar > > createMembers(const RCP< const VectorSpaceBase< Scalar > > &vs, int numMembers, const std::string &label="")
Create a set of vector members (a MultiVectorBase) from the vector space.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
bool is_null(const std::shared_ptr< T > &p)
#define THYRA_ASSERT_VEC_SPACES(FUNC_NAME, VS1, VS2)
This is a very useful macro that should be used to validate that two vector spaces are compatible.
#define THYRA_ASSERT_VEC_SPACES_NAMES(FUNC_NAME, VS1, VS1_NAME, VS2, VS2_NAME)
Helper assertion macro.
#define TEUCHOS_UNREACHABLE_RETURN(dummyReturnVal)
std::string toString(const T &t)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)