42 #ifndef THYRA_ASSERT_OP_HPP 
   43 #define THYRA_ASSERT_OP_HPP 
   46 #include "Thyra_OperatorVectorTypes.hpp" 
   47 #include "Thyra_VectorSpaceBase.hpp" 
   48 #include "Thyra_VectorBase.hpp" 
   49 #include "Thyra_LinearOpBase.hpp" 
   50 #include "Teuchos_Assert.hpp" 
   58 template<
class Scalar>
 
   59 struct dump_vec_spaces_t {
 
   63     const std::string &_vec_space1_name,
 
   65     const std::string &_vec_space2_name
 
   67     :vec_space1(_vec_space1),vec_space1_name(_vec_space1_name)
 
   68     ,vec_space2(_vec_space2),vec_space2_name(_vec_space2_name)
 
   71   const std::string                    vec_space1_name;
 
   73   const std::string                    vec_space2_name;
 
   79 template<
class Scalar>
 
   80 inline dump_vec_spaces_t<Scalar> dump_vec_spaces(
 
   82   const std::string &vec_space1_name,
 
   84   const std::string &vec_space2_name
 
   87   return dump_vec_spaces_t<Scalar>(
 
   88     vec_space1,vec_space1_name,vec_space2,vec_space2_name);
 
   98 template<
class Scalar>
 
   99 std::ostream& operator<<( std::ostream& o, const dump_vec_spaces_t<Scalar>& d )
 
  104   o << 
"Error, the following vector spaces are not compatible:\n\n";
 
  106     << d.vec_space1_name << 
" : " 
  107     << Teuchos::describe(d.vec_space1,verbLevel);
 
  110     << d.vec_space2_name << 
" : " 
  111     << Teuchos::describe(d.vec_space2,verbLevel);
 
  118 enum EM_VS { VS_RANGE, VS_DOMAIN };
 
  125 template<
class Scalar>
 
  150 #define THYRA_ASSERT_LHS_ARG(FUNC_NAME,LHS_ARG) \ 
  151   TEUCHOS_TEST_FOR_EXCEPTION( \ 
  152     (&*LHS_ARG) == NULL, std::invalid_argument, \ 
  153     FUNC_NAME << " : Error!" \ 
  166 #define THYRA_ASSERT_VEC_SPACES_NAMES(FUNC_NAME,VS1,VS1_NAME,VS2,VS2_NAME) \ 
  168   const bool l_isCompatible = (VS1).isCompatible(VS2); \ 
  169   TEUCHOS_TEST_FOR_EXCEPTION( \ 
  170     !l_isCompatible, ::Thyra::Exceptions::IncompatibleVectorSpaces, \ 
  171     FUNC_NAME << "\n\n" \ 
  172     << ::Thyra::dump_vec_spaces(VS1,VS1_NAME,VS2,VS2_NAME) \ 
  188 #define THYRA_ASSERT_VEC_SPACES(FUNC_NAME,VS1,VS2)\ 
  189 THYRA_ASSERT_VEC_SPACES_NAMES(FUNC_NAME,VS1,#VS1,VS2,#VS2) 
  199 #define THYRA_ASSERT_MAT_VEC_SPACES(FUNC_NAME,M,M_T,M_VS,VS) \ 
  201   std::ostringstream M_VS_name; \ 
  202   M_VS_name << "(" #M << ( (M_T) == Thyra::NOTRANS ? "" : "^T" ) << ")" \ 
  203             << "." << ( (M_VS) == Thyra::VS_RANGE ? "range()" : "domain()" ); \ 
  204   THYRA_ASSERT_VEC_SPACES_NAMES( \ 
  206     ::Thyra::linear_op_op(M,M_T,M_VS),M_VS_name.str().c_str(), \ 
  224 #define THYRA_ASSERT_LINEAR_OP_VEC_APPLY_SPACES(FUNC_NAME,M,M_T,X,Y) \ 
  226     std::ostringstream headeross; \ 
  228       << FUNC_NAME << ":\n" \ 
  229       << "Spaces check failed for " \ 
  230       << #M << ( (M_T) == Thyra::NOTRANS ? "" : "^T" ) << " * " \ 
  231       << #X << " and " << #Y; \ 
  232     const std::string &header = headeross.str(); \ 
  233     THYRA_ASSERT_MAT_VEC_SPACES(header,M,M_T,::Thyra::VS_RANGE,*(Y)->space()); \ 
  234     THYRA_ASSERT_MAT_VEC_SPACES(header,M,M_T,::Thyra::VS_DOMAIN,*(X).space()); \ 
  250 #define THYRA_ASSERT_LINEAR_OP_MULTIVEC_APPLY_SPACES(FUNC_NAME,M,M_T,X,Y) \ 
  252     std::ostringstream headeross; \ 
  254       << FUNC_NAME << ":\n\n" \ 
  255       << "Spaces check failed for " \ 
  256       << #M << ( (M_T) == Thyra::NOTRANS ? "" : "^T" ) << " * " \ 
  257       << #X << " and " << #Y << ":\n\n"; \ 
  258     const std::string &header = headeross.str(); \ 
  259     THYRA_ASSERT_VEC_SPACES(header,*(X).domain(),*(Y)->domain()); \ 
  260     THYRA_ASSERT_MAT_VEC_SPACES(header,M,M_T,::Thyra::VS_RANGE,*(Y)->range()); \ 
  261     THYRA_ASSERT_MAT_VEC_SPACES(header,M,M_T,::Thyra::VS_DOMAIN,*(X).range()); \ 
  268 template<
class Scalar>
 
  269 void assertLinearOpPlusLinearOpNames(
 
  270   const std::string &funcName,
 
  271   const LinearOpBase<Scalar> &M1, 
const EOpTransp M1_trans_in, 
const std::string &M1_name,
 
  272   const LinearOpBase<Scalar> &M2, 
const EOpTransp M2_trans_in, 
const std::string &M2_name
 
  277   std::ostringstream headeross;
 
  279     << funcName << 
":\n\n" 
  280     << 
"Spaces check failed for " 
  281     << 
"(" << M1_name << 
")" << ( M1_trans == 
NOTRANS ? 
"" : 
"^T" )
 
  283     << 
"(" << M2_name << 
")" << ( M2_trans == 
NOTRANS ? 
"" : 
"^T" )
 
  285     << 
"  " << M1_name << 
": " << M1.description() << 
"\n\n" 
  286     << 
"  " << M2_name << 
": " << M2.description();
 
  287   const std::string &header = headeross.str();
 
  288   if ( M1_trans == M2_trans ) {
 
  290       *M1.range(), M1_name + 
".range()",
 
  291       *M2.range(), M2_name + 
".range()" );
 
  293       *M1.domain(), M1_name + 
".domain()",
 
  294       *M2.domain(), M2_name + 
".domain()" );
 
  298       *M1.domain(), M1_name + 
".domain()",
 
  299       *M2.range(), M2_name + 
".range()" );
 
  301       *M1.range(), M1_name + 
".range()",
 
  302       *M2.domain(), M2_name + 
".domain()" );
 
  307 template<
class Scalar>
 
  308 void assertLinearOpTimesLinearOpNames(
 
  309   const std::string &funcName,
 
  310   const LinearOpBase<Scalar> &M1, 
const EOpTransp M1_trans_in, 
const std::string &M1_name,
 
  311   const LinearOpBase<Scalar> &M2, 
const EOpTransp M2_trans_in, 
const std::string &M2_name
 
  316   std::ostringstream headeross;
 
  318     << funcName << 
":\n\n" 
  319     << 
"Spaces check failed for " 
  320     << 
"(" << M1_name << 
")" << ( M1_trans == 
NOTRANS ? 
"" : 
"^T" )
 
  322     << 
"(" << M2_name << 
")" << ( M2_trans == 
NOTRANS ? 
"" : 
"^T" )
 
  324     << 
"  " << M1_name << 
": " << M1.description() << 
"\n\n" 
  325     << 
"  " << M2_name << 
": " << M2.description();
 
  326   const std::string &header = headeross.str();
 
  329       *M1.domain(), M1_name + 
".domain()",
 
  330       *M2.range(), M2_name + 
".range()" );
 
  334       *M1.domain(), M1_name + 
".domain()",
 
  335       *M2.domain(), M2_name + 
".domain()" );
 
  339       *M1.domain(), M1_name + 
".range()",
 
  340       *M2.range(), M2_name + 
".range()" );
 
  342   else if ( M1_trans == 
TRANS &&  M2_trans == 
TRANS ) {
 
  344       *M1.domain(), M1_name + 
".range()",
 
  345       *M2.range(), M2_name + 
".domain()" );
 
  349       header << 
"\n\n" << 
"Error, invalid value for trasponse enums!" );
 
  361 #define THYRA_ASSERT_LINEAR_OP_PLUS_LINEAR_OP_SPACES_NAMES(FUNC_NAME,M1,M1_T,M1_N,M2,M2_T,M2_N) \ 
  362   ::Thyra::assertLinearOpPlusLinearOpNames(FUNC_NAME,M1,M1_T,M1_N,M2,M2_T,M2_N) 
  369 #define THYRA_ASSERT_LINEAR_OP_TIMES_LINEAR_OP_SPACES_NAMES(FUNC_NAME,M1,M1_T,M1_N,M2,M2_T,M2_N) \ 
  370   ::Thyra::assertLinearOpTimesLinearOpNames(FUNC_NAME,M1,M1_T,M1_N,M2,M2_T,M2_N) 
  379 #define THYRA_ASSERT_MAT_MAT_SPACES(FUNC_NAME,M1,M1_T,M1_VS,M2,M2_T,M2_VS) \ 
  381     std::ostringstream headeross; \ 
  383       << FUNC_NAME << "\n" \ 
  384       << "Spaces check failed for " \ 
  385       << #M1 << ( (M1_T) == Thyra::NOTRANS ? "" : "^T" ) << " and " \ 
  386       << #M2 << ( (M2_T) == Thyra::NOTRANS ? "" : "^T" ); \ 
  387     const std::string &header = headeross.str(); \ 
  388     std::ostringstream M1_VS_name, M2_VS_name; \ 
  389     M1_VS_name << "(" #M1 << ( M1_T == ::Thyra::NOTRANS ? "" : "^T" ) << ")" \ 
  390                << "." << ( M1_VS == ::Thyra::VS_RANGE ? "range()" : "domain()" ); \ 
  391     M2_VS_name << "(" #M2 << ( M2_T == ::Thyra::NOTRANS ? "" : "^T" ) << ")" \ 
  392                << "." << ( M2_VS == ::Thyra::VS_RANGE ? "range()" : "domain()" ); \ 
  393     THYRA_ASSERT_VEC_SPACES_NAMES( \ 
  395       ::Thyra::linear_op_op(M1,M1_T,M1_VS),M1_VS_name.str().c_str() \ 
  396       ::Thyra::linear_op_op(M2,M2_T,M2_VS),M2_VS_name.str().c_str() \ 
  401 #endif // THYRA_ASSERT_OP_HPP 
virtual RCP< const VectorSpaceBase< Scalar > > range() const =0
Return a smart pointer for the range space for this operator. 
EOpTransp
Enumeration for determining how a linear operator is applied. `*. 
basic_OSTab< char > OSTab
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Use the non-transposed operator. 
EOpTransp real_trans(EOpTransp transp)
Return NOTRANS or TRANS for real scalar valued operators and this also is used for determining struct...
Abstract interface for objects that represent a space for vectors. 
Use the transposed operator. 
const Thyra::VectorSpaceBase< Scalar > & linear_op_op(const Thyra::LinearOpBase< Scalar > &M, Thyra::EOpTransp M_trans, EM_VS M_VS)
Utility function for selecting domain or range spaces. 
Base class for all linear operators. 
virtual RCP< const VectorSpaceBase< Scalar > > domain() const =0
Return a smart pointer for the domain space for this operator. 
#define THYRA_ASSERT_VEC_SPACES_NAMES(FUNC_NAME, VS1, VS1_NAME, VS2, VS2_NAME)
Helper assertion macro.