10 #ifndef THYRA_ASSERT_OP_HPP
11 #define THYRA_ASSERT_OP_HPP
14 #include "Thyra_OperatorVectorTypes.hpp"
15 #include "Thyra_VectorSpaceBase.hpp"
16 #include "Thyra_VectorBase.hpp"
17 #include "Thyra_LinearOpBase.hpp"
18 #include "Teuchos_Assert.hpp"
26 template<
class Scalar>
27 struct dump_vec_spaces_t {
31 const std::string &_vec_space1_name,
33 const std::string &_vec_space2_name
35 :vec_space1(_vec_space1),vec_space1_name(_vec_space1_name)
36 ,vec_space2(_vec_space2),vec_space2_name(_vec_space2_name)
39 const std::string vec_space1_name;
41 const std::string vec_space2_name;
47 template<
class Scalar>
48 inline dump_vec_spaces_t<Scalar> dump_vec_spaces(
50 const std::string &vec_space1_name,
52 const std::string &vec_space2_name
55 return dump_vec_spaces_t<Scalar>(
56 vec_space1,vec_space1_name,vec_space2,vec_space2_name);
66 template<
class Scalar>
67 std::ostream& operator<<( std::ostream& o, const dump_vec_spaces_t<Scalar>& d )
72 o <<
"Error, the following vector spaces are not compatible:\n\n";
74 << d.vec_space1_name <<
" : "
75 << Teuchos::describe(d.vec_space1,verbLevel);
78 << d.vec_space2_name <<
" : "
79 << Teuchos::describe(d.vec_space2,verbLevel);
86 enum EM_VS { VS_RANGE, VS_DOMAIN };
93 template<
class Scalar>
118 #define THYRA_ASSERT_LHS_ARG(FUNC_NAME,LHS_ARG) \
119 TEUCHOS_TEST_FOR_EXCEPTION( \
120 (&*LHS_ARG) == NULL, std::invalid_argument, \
121 FUNC_NAME << " : Error!" \
134 #define THYRA_ASSERT_VEC_SPACES_NAMES(FUNC_NAME,VS1,VS1_NAME,VS2,VS2_NAME) \
136 const bool l_isCompatible = (VS1).isCompatible(VS2); \
137 TEUCHOS_TEST_FOR_EXCEPTION( \
138 !l_isCompatible, ::Thyra::Exceptions::IncompatibleVectorSpaces, \
139 FUNC_NAME << "\n\n" \
140 << ::Thyra::dump_vec_spaces(VS1,VS1_NAME,VS2,VS2_NAME) \
156 #define THYRA_ASSERT_VEC_SPACES(FUNC_NAME,VS1,VS2)\
157 THYRA_ASSERT_VEC_SPACES_NAMES(FUNC_NAME,VS1,#VS1,VS2,#VS2)
167 #define THYRA_ASSERT_MAT_VEC_SPACES(FUNC_NAME,M,M_T,M_VS,VS) \
169 std::ostringstream M_VS_name; \
170 M_VS_name << "(" #M << ( (M_T) == Thyra::NOTRANS ? "" : "^T" ) << ")" \
171 << "." << ( (M_VS) == Thyra::VS_RANGE ? "range()" : "domain()" ); \
172 THYRA_ASSERT_VEC_SPACES_NAMES( \
174 ::Thyra::linear_op_op(M,M_T,M_VS),M_VS_name.str().c_str(), \
192 #define THYRA_ASSERT_LINEAR_OP_VEC_APPLY_SPACES(FUNC_NAME,M,M_T,X,Y) \
194 std::ostringstream headeross; \
196 << FUNC_NAME << ":\n" \
197 << "Spaces check failed for " \
198 << #M << ( (M_T) == Thyra::NOTRANS ? "" : "^T" ) << " * " \
199 << #X << " and " << #Y; \
200 const std::string &header = headeross.str(); \
201 THYRA_ASSERT_MAT_VEC_SPACES(header,M,M_T,::Thyra::VS_RANGE,*(Y)->space()); \
202 THYRA_ASSERT_MAT_VEC_SPACES(header,M,M_T,::Thyra::VS_DOMAIN,*(X).space()); \
218 #define THYRA_ASSERT_LINEAR_OP_MULTIVEC_APPLY_SPACES(FUNC_NAME,M,M_T,X,Y) \
220 std::ostringstream headeross; \
222 << FUNC_NAME << ":\n\n" \
223 << "Spaces check failed for " \
224 << #M << ( (M_T) == Thyra::NOTRANS ? "" : "^T" ) << " * " \
225 << #X << " and " << #Y << ":\n\n"; \
226 const std::string &header = headeross.str(); \
227 THYRA_ASSERT_VEC_SPACES(header,*(X).domain(),*(Y)->domain()); \
228 THYRA_ASSERT_MAT_VEC_SPACES(header,M,M_T,::Thyra::VS_RANGE,*(Y)->range()); \
229 THYRA_ASSERT_MAT_VEC_SPACES(header,M,M_T,::Thyra::VS_DOMAIN,*(X).range()); \
236 template<
class Scalar>
237 void assertLinearOpPlusLinearOpNames(
238 const std::string &funcName,
239 const LinearOpBase<Scalar> &M1,
const EOpTransp M1_trans_in,
const std::string &M1_name,
240 const LinearOpBase<Scalar> &M2,
const EOpTransp M2_trans_in,
const std::string &M2_name
245 std::ostringstream headeross;
247 << funcName <<
":\n\n"
248 <<
"Spaces check failed for "
249 <<
"(" << M1_name <<
")" << ( M1_trans ==
NOTRANS ?
"" :
"^T" )
251 <<
"(" << M2_name <<
")" << ( M2_trans ==
NOTRANS ?
"" :
"^T" )
253 <<
" " << M1_name <<
": " << M1.description() <<
"\n\n"
254 <<
" " << M2_name <<
": " << M2.description();
255 const std::string &header = headeross.str();
256 if ( M1_trans == M2_trans ) {
258 *M1.range(), M1_name +
".range()",
259 *M2.range(), M2_name +
".range()" );
261 *M1.domain(), M1_name +
".domain()",
262 *M2.domain(), M2_name +
".domain()" );
266 *M1.domain(), M1_name +
".domain()",
267 *M2.range(), M2_name +
".range()" );
269 *M1.range(), M1_name +
".range()",
270 *M2.domain(), M2_name +
".domain()" );
275 template<
class Scalar>
276 void assertLinearOpTimesLinearOpNames(
277 const std::string &funcName,
278 const LinearOpBase<Scalar> &M1,
const EOpTransp M1_trans_in,
const std::string &M1_name,
279 const LinearOpBase<Scalar> &M2,
const EOpTransp M2_trans_in,
const std::string &M2_name
284 std::ostringstream headeross;
286 << funcName <<
":\n\n"
287 <<
"Spaces check failed for "
288 <<
"(" << M1_name <<
")" << ( M1_trans ==
NOTRANS ?
"" :
"^T" )
290 <<
"(" << M2_name <<
")" << ( M2_trans ==
NOTRANS ?
"" :
"^T" )
292 <<
" " << M1_name <<
": " << M1.description() <<
"\n\n"
293 <<
" " << M2_name <<
": " << M2.description();
294 const std::string &header = headeross.str();
297 *M1.domain(), M1_name +
".domain()",
298 *M2.range(), M2_name +
".range()" );
302 *M1.domain(), M1_name +
".domain()",
303 *M2.domain(), M2_name +
".domain()" );
307 *M1.domain(), M1_name +
".range()",
308 *M2.range(), M2_name +
".range()" );
310 else if ( M1_trans ==
TRANS && M2_trans ==
TRANS ) {
312 *M1.domain(), M1_name +
".range()",
313 *M2.range(), M2_name +
".domain()" );
317 header <<
"\n\n" <<
"Error, invalid value for trasponse enums!" );
329 #define THYRA_ASSERT_LINEAR_OP_PLUS_LINEAR_OP_SPACES_NAMES(FUNC_NAME,M1,M1_T,M1_N,M2,M2_T,M2_N) \
330 ::Thyra::assertLinearOpPlusLinearOpNames(FUNC_NAME,M1,M1_T,M1_N,M2,M2_T,M2_N)
337 #define THYRA_ASSERT_LINEAR_OP_TIMES_LINEAR_OP_SPACES_NAMES(FUNC_NAME,M1,M1_T,M1_N,M2,M2_T,M2_N) \
338 ::Thyra::assertLinearOpTimesLinearOpNames(FUNC_NAME,M1,M1_T,M1_N,M2,M2_T,M2_N)
347 #define THYRA_ASSERT_MAT_MAT_SPACES(FUNC_NAME,M1,M1_T,M1_VS,M2,M2_T,M2_VS) \
349 std::ostringstream headeross; \
351 << FUNC_NAME << "\n" \
352 << "Spaces check failed for " \
353 << #M1 << ( (M1_T) == Thyra::NOTRANS ? "" : "^T" ) << " and " \
354 << #M2 << ( (M2_T) == Thyra::NOTRANS ? "" : "^T" ); \
355 const std::string &header = headeross.str(); \
356 std::ostringstream M1_VS_name, M2_VS_name; \
357 M1_VS_name << "(" #M1 << ( M1_T == ::Thyra::NOTRANS ? "" : "^T" ) << ")" \
358 << "." << ( M1_VS == ::Thyra::VS_RANGE ? "range()" : "domain()" ); \
359 M2_VS_name << "(" #M2 << ( M2_T == ::Thyra::NOTRANS ? "" : "^T" ) << ")" \
360 << "." << ( M2_VS == ::Thyra::VS_RANGE ? "range()" : "domain()" ); \
361 THYRA_ASSERT_VEC_SPACES_NAMES( \
363 ::Thyra::linear_op_op(M1,M1_T,M1_VS),M1_VS_name.str().c_str() \
364 ::Thyra::linear_op_op(M2,M2_T,M2_VS),M2_VS_name.str().c_str() \
369 #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.