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.