Thyra Package Browser (Single Doxygen Collection) Version of the Day
DefaultProductVectorSpace_UnitTests.cpp
Go to the documentation of this file.
00001 
00002 #include "Thyra_DefaultSpmdVectorSpace.hpp"
00003 #include "Thyra_DefaultProductVectorSpace.hpp"
00004 #include "Thyra_DefaultProductVector.hpp"
00005 #include "Thyra_DefaultProductMultiVector.hpp"
00006 #include "Thyra_DetachedSpmdVectorView.hpp"
00007 #include "Thyra_DetachedVectorView.hpp"
00008 #include "Thyra_VectorStdOps.hpp"
00009 #include "Thyra_MultiVectorStdOps.hpp"
00010 #include "Thyra_TestingTools.hpp"
00011 #include "Teuchos_DefaultComm.hpp"
00012 
00013 #include "Teuchos_UnitTestHarness.hpp"
00014 #include "Thyra_UnitTestHelpers.hpp"
00015 
00016 
00017 namespace Thyra {
00018 
00019 
00020 //
00021 // Helper code and declarations
00022 //
00023 
00024 
00025 using Teuchos::as;
00026 using Teuchos::null;
00027 
00028 
00029 const int g_localDim = 4; // ToDo: Make variable!
00030 
00031 
00032 template<class Scalar>
00033 RCP<VectorSpaceBase<Scalar> > 
00034 createSpmdVectorSpace(const Ordinal localDim)
00035 {
00036   return defaultSpmdVectorSpace<Scalar>(
00037     Teuchos::DefaultComm<Ordinal>::getComm(),
00038     localDim, -1 );
00039 }
00040 
00041 
00042 template<class Scalar>
00043 RCP<VectorSpaceBase<Scalar> > 
00044 createProductVectorSpace(const Ordinal localDim, const int numBlocks)
00045 {
00046   return productVectorSpace<Scalar>(
00047     createSpmdVectorSpace<Scalar>(localDim),
00048     numBlocks);
00049 }
00050 
00051 
00052 //
00053 // Unit Tests
00054 //
00055 
00056 
00057 //
00058 // Test the default product vector space constructor
00059 //
00060 
00061 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DefaultProductVectorSpace, defaultConstruct,
00062   Scalar )
00063 {
00064 
00065   RCP<const DefaultProductVectorSpace<Scalar> > vs = productVectorSpace<Scalar>();
00066   TEST_EQUALITY(vs->numBlocks(), -1);
00067   TEST_EQUALITY(vs->dim(), as<Ordinal>(-1));
00068   out << "vs = " << *vs;
00069 }
00070 THYRA_UNIT_TEST_TEMPLATE_1_INSTANT_SCALAR_TYPES( DefaultProductVectorSpace,
00071   defaultConstruct )
00072 
00073 
00074 //
00075 // Test dynamic casting using the inline double helper functions. In this
00076 // case, we don't need to employ a using declaration or explicit template
00077 // arguments.
00078 //
00079 
00080 TEUCHOS_UNIT_TEST( DefaultProductVectorSpace, dynamicCast_double)
00081 {
00082 
00083   const RCP<DefaultProductVectorSpace<double> > dpvs =  productVectorSpace<double>();
00084   const RCP<const DefaultProductVectorSpace<double> > cdpvs = dpvs;
00085   const RCP<VectorSpaceBase<double> > vs =  dpvs;
00086   const RCP<const VectorSpaceBase<double> > cvs =  vs;
00087     
00088   // VS -> PVSB
00089   RCP<ProductVectorSpaceBase<double> > pvs1 = nonconstProductVectorSpaceBase(vs);
00090   TEST_INEQUALITY(pvs1, null);
00091   out << "pvs1 = " << *pvs1;
00092 
00093   // DPVS -> PVSB
00094   RCP<ProductVectorSpaceBase<double> > pvs2 = nonconstProductVectorSpaceBase(dpvs);
00095   TEST_INEQUALITY(pvs2, null);
00096   out << "pvs2 = " << *pvs2;
00097   
00098   // VS -> const PVSB
00099   RCP<const ProductVectorSpaceBase<double> > pvs3 = productVectorSpaceBase(vs);
00100   TEST_INEQUALITY(pvs3, null);
00101   out << "pvs3 = " << *pvs3;
00102 
00103   // DPVS -> const PVSB
00104   RCP<const ProductVectorSpaceBase<double> > pvs4 = productVectorSpaceBase(dpvs);
00105   TEST_INEQUALITY(pvs4, null);
00106   out << "pvs4 = " << *pvs4;
00107   
00108   // const VS -> const PVSB
00109   RCP<const ProductVectorSpaceBase<double> > cpvs5 = productVectorSpaceBase(cvs);
00110   TEST_INEQUALITY(cpvs5, null);
00111   out << "cpvs5 = " << *cpvs5;
00112 
00113   // const DPVS -> const PVSB
00114   RCP<const ProductVectorSpaceBase<double> > cpvs6 = productVectorSpaceBase(cdpvs);
00115   TEST_INEQUALITY(cpvs6, null);
00116   out << "cpvs6 = " << *cpvs6;
00117 
00118 }
00119 
00120 
00121 //
00122 // Test dynmaic cast from a VectorSpaceBase object to a ProductVectorSpaceBase
00123 // object using the templated function.  In this case, we have to inject the
00124 // names of the non-member conversion functions into the local namespace and
00125 // we have to use the explicit template argument so that the templated
00126 // function will be selected over the non-templated double version of the
00127 // function.
00128 //
00129   
00130 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DefaultProductVectorSpace, dynamicCast,
00131   Scalar )
00132 {
00133 
00134   using Thyra::nonconstProductVectorSpaceBase;
00135   using Thyra::productVectorSpaceBase;
00136 
00137   const RCP<DefaultProductVectorSpace<Scalar> > dpvs =  productVectorSpace<Scalar>();
00138   const RCP<const DefaultProductVectorSpace<Scalar> > cdpvs = dpvs;
00139   const RCP<VectorSpaceBase<Scalar> > vs =  dpvs;
00140   const RCP<const VectorSpaceBase<Scalar> > cvs =  vs;
00141   
00142   // VS -> PVSB (exact match so template arg is *not* needed)
00143   RCP<ProductVectorSpaceBase<Scalar> > 
00144     pvs1 = nonconstProductVectorSpaceBase(vs);
00145   TEST_INEQUALITY(pvs1, null);
00146   out << "pvs1 = " << *pvs1;
00147 
00148   // DPVS -> PVSB (base conversion so template arg is needed)
00149   RCP<ProductVectorSpaceBase<Scalar> >
00150     pvs2 = nonconstProductVectorSpaceBase<Scalar>(dpvs);
00151   TEST_INEQUALITY(pvs2, null);
00152   out << "pvs2 = " << *pvs2;
00153   
00154   // VS -> const PVSB (const conversion so template arg is needed) 
00155   RCP<const ProductVectorSpaceBase<Scalar> >
00156     pvs3 = productVectorSpaceBase<Scalar>(vs);
00157   TEST_INEQUALITY(pvs3, null);
00158   out << "pvs3 = " << *pvs3;
00159 
00160   // DPVS -> const PVSB (base & const conversion so template arg is needed)
00161   RCP<const ProductVectorSpaceBase<Scalar> >
00162     pvs4 = productVectorSpaceBase<Scalar>(dpvs);
00163   TEST_INEQUALITY(pvs4, null);
00164   out << "pvs4 = " << *pvs4;
00165   
00166   // const VS -> const PVSB (exact match so template arg is *not* needed)
00167   RCP<const ProductVectorSpaceBase<Scalar> >
00168     cpvs5 = productVectorSpaceBase(cvs);
00169   TEST_INEQUALITY(cpvs5, null);
00170   out << "cpvs5 = " << *cpvs5;
00171 
00172   // const DPVS -> const PVSB (base conversion so template arg is needed)
00173   RCP<const ProductVectorSpaceBase<Scalar> >
00174     cpvs6 = productVectorSpaceBase<Scalar>(cdpvs);
00175   TEST_INEQUALITY(cpvs6, null);
00176   out << "cpvs6 = " << *cpvs6;
00177 
00178 }
00179 THYRA_UNIT_TEST_TEMPLATE_1_INSTANT_SCALAR_TYPES( DefaultProductVectorSpace,
00180   dynamicCast )
00181 
00182 
00183 //
00184 // Make sure that invalid dynamic casts fail and throw exceptions
00185 //
00186 
00187 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DefaultProductVectorSpace, dynamicCast_fail,
00188   Scalar )
00189 {
00190   using Thyra::nonconstProductVectorSpaceBase;
00191   using Thyra::productVectorSpaceBase;
00192   RCP<VectorSpaceBase<Scalar> > vs = defaultSpmdVectorSpace<Scalar>(g_localDim);
00193   TEST_THROW(productVectorSpaceBase<Scalar>(vs), Teuchos::m_bad_cast);
00194   TEST_THROW(nonconstProductVectorSpaceBase<Scalar>(vs), Teuchos::m_bad_cast);
00195 }
00196 THYRA_UNIT_TEST_TEMPLATE_1_INSTANT_SCALAR_TYPES( DefaultProductVectorSpace,
00197   dynamicCast_fail )
00198 
00199 
00200 //
00201 // Make sure that DefaultProductVectorSpace::createMember() returns a
00202 // DefaultProductVector object.
00203 //
00204 
00205 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DefaultProductVectorSpace, DefaultProductVector,
00206   Scalar )
00207 {
00208   using Teuchos::rcp_dynamic_cast;
00209   const RCP<const VectorSpaceBase<Scalar> >
00210     vs = defaultSpmdVectorSpace<Scalar>(g_localDim),
00211     pvs = productVectorSpace<Scalar>(tuple(vs)());
00212   const RCP<VectorBase<Scalar> > v1 = createMember(pvs);
00213   const RCP<DefaultProductVector<Scalar> > pv1 =
00214     rcp_dynamic_cast<DefaultProductVector<Scalar> >(v1, true);
00215   TEST_EQUALITY(pvs.get(), pv1->space().get());
00216 }
00217 THYRA_UNIT_TEST_TEMPLATE_1_INSTANT_SCALAR_TYPES( DefaultProductVectorSpace,
00218   DefaultProductVector )
00219 
00220 
00221 //
00222 // Make sure that DefaultProductVectorSpace::createMembers() returns a
00223 // DefaultProductMultiVector object.
00224 //
00225 
00226 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DefaultProductVectorSpace, DefaultProductMultiVector,
00227   Scalar )
00228 {
00229   using Teuchos::as;
00230   using Teuchos::rcp_dynamic_cast;
00231   const RCP<const VectorSpaceBase<Scalar> >
00232     vs = defaultSpmdVectorSpace<Scalar>(g_localDim),
00233     pvs = productVectorSpace<Scalar>(tuple(vs)());
00234   const int numCols = 2;
00235   const RCP<MultiVectorBase<Scalar> > mv1 = createMembers(pvs, numCols);
00236   const RCP<DefaultProductMultiVector<Scalar> > pmv1 =
00237     rcp_dynamic_cast<DefaultProductMultiVector<Scalar> >(mv1, true);
00238   TEST_EQUALITY(pvs.get(), pmv1->range().get());
00239   TEST_EQUALITY(as<int>(pmv1->domain()->dim()), numCols);
00240 }
00241 THYRA_UNIT_TEST_TEMPLATE_1_INSTANT_SCALAR_TYPES( DefaultProductVectorSpace,
00242   DefaultProductMultiVector )
00243 
00244 
00245 //
00246 // Test that a product vector space with one embedded space is compatiable
00247 // with that single space and visa versa.
00248 //
00249 
00250 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DefaultProductVectorSpace, singleBlockCompatibility,
00251   Scalar )
00252 {
00253 
00254   using Teuchos::describe;
00255 
00256   typedef Teuchos::ScalarTraits<Scalar> ST;
00257   typedef typename ST::magnitudeType ScalarMag;
00258   typedef Teuchos::ScalarTraits<ScalarMag> SMT;
00259 
00260   const RCP<const VectorSpaceBase<Scalar> >
00261     vs = defaultSpmdVectorSpace<Scalar>(g_localDim),
00262     pvs = productVectorSpace<Scalar>(tuple(vs)());
00263 
00264   out << "vs=" << describe(*vs);
00265   out << "pvs=" << describe(*pvs);
00266 
00267   TEST_ASSERT(pvs->isCompatible(*vs));
00268   TEST_ASSERT(vs->isCompatible(*pvs));
00269 
00270   const ScalarMag dim_scalar = vs->dim();
00271 
00272   const RCP<VectorBase<Scalar> >
00273     v1 = createMember(vs),
00274     pv1 = createMember(pvs);
00275 
00276   out << "Test that you can copy from single vector to product vector (1) ...\n";
00277   const Scalar val1 = 2.0;
00278   V_S(v1.ptr(), val1);
00279   V_V(pv1.ptr(), *v1);
00280   TEST_FLOATING_EQUALITY( sum(*pv1), as<Scalar>(dim_scalar * val1),
00281     as<ScalarMag>(SMT::eps() / dim_scalar * 1e+2) );
00282 
00283   out << "Test that you can copy from product vector (1) to single vector ...\n";
00284   const Scalar val2 = 3.0;
00285   V_S(pv1.ptr(), val2);
00286   V_V(v1.ptr(), *pv1);
00287   TEST_FLOATING_EQUALITY( sum(*v1), as<Scalar>(dim_scalar * val2),
00288     as<ScalarMag>(SMT::eps() / dim_scalar * 1e+2) );
00289 
00290   const RCP<MultiVectorBase<Scalar> >
00291     mv1 = createMembers(vs, 1),
00292     pmv1 = createMembers(pvs, 1);
00293 
00294   out << "Test that you can copy from single multi-vector to product multi-vector (1) ...\n";
00295   assign(mv1.ptr(), val1);
00296   assign(pmv1.ptr(), *mv1);
00297   TEST_FLOATING_EQUALITY( sum(*pmv1->col(0)), as<Scalar>(dim_scalar * val1),
00298     as<ScalarMag>(SMT::eps() / dim_scalar * 1e+2) );
00299 
00300   out << "Test that you can copy from product multi-vector (1) to single multi-vector ...\n";
00301   assign(pmv1.ptr(), val2);
00302   assign(mv1.ptr(), *pmv1);
00303   TEST_FLOATING_EQUALITY( sum(*mv1->col(0)), as<Scalar>(dim_scalar * val2),
00304     as<ScalarMag>(SMT::eps() / dim_scalar * 1e+2) );
00305 
00306 }
00307 THYRA_UNIT_TEST_TEMPLATE_1_INSTANT_SCALAR_TYPES( DefaultProductVectorSpace,
00308   singleBlockCompatibility )
00309 
00310 
00311 //
00312 // DefaultProductVector
00313 //
00314 
00315 
00316 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DefaultProductVector,
00317   castOrCreateNonconstProductVectorBase_cast, Scalar )
00318 {
00319 
00320   const int numBlocks = 3;
00321 
00322   const RCP<const VectorSpaceBase<Scalar> > vs =
00323     createProductVectorSpace<Scalar>(g_localDim, numBlocks);
00324 
00325   const RCP<VectorBase<Scalar> > v = createMember(vs);
00326 
00327   const RCP<ProductVectorBase<Scalar> > prod_v =
00328     castOrCreateNonconstProductVectorBase(v);
00329 
00330   out << "prod_v = " << *prod_v;
00331 
00332   TEST_EQUALITY_CONST(prod_v->productSpace()->numBlocks(), numBlocks);
00333 
00334   TEST_EQUALITY(
00335     dynamic_cast<void*>(v.getRawPtr()),
00336     dynamic_cast<void*>(prod_v.getRawPtr()));
00337 
00338 }
00339 THYRA_UNIT_TEST_TEMPLATE_1_INSTANT_SCALAR_TYPES( DefaultProductVector,
00340   castOrCreateNonconstProductVectorBase_cast )
00341 
00342 
00343 
00344 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DefaultProductVector,
00345   castOrCreateNonconstProductVectorBase_create, Scalar )
00346 {
00347 
00348   const RCP<const VectorSpaceBase<Scalar> > vs =
00349     createSpmdVectorSpace<Scalar>(g_localDim);
00350 
00351   const RCP<VectorBase<Scalar> > v = createMember(vs);
00352 
00353   const RCP<ProductVectorBase<Scalar> > prod_v =
00354     castOrCreateNonconstProductVectorBase(v);
00355 
00356   out << "prod_v = " << *prod_v;
00357 
00358   TEST_EQUALITY_CONST(prod_v->productSpace()->numBlocks(), 1);
00359 
00360 }
00361 THYRA_UNIT_TEST_TEMPLATE_1_INSTANT_SCALAR_TYPES( DefaultProductVector,
00362   castOrCreateNonconstProductVectorBase_create )
00363 
00364 
00365 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DefaultProductVector,
00366   castOrCreateProductVectorBase_cast, Scalar )
00367 {
00368 
00369   const int numBlocks = 3;
00370 
00371   const RCP<const VectorSpaceBase<Scalar> > vs =
00372     createProductVectorSpace<Scalar>(g_localDim, numBlocks);
00373 
00374   const RCP<const VectorBase<Scalar> > v = createMember(vs);
00375 
00376   const RCP<const ProductVectorBase<Scalar> > prod_v =
00377     castOrCreateProductVectorBase(v);
00378 
00379   out << "prod_v = " << *prod_v;
00380 
00381   TEST_EQUALITY_CONST(prod_v->productSpace()->numBlocks(), numBlocks);
00382 
00383   TEST_EQUALITY(
00384     dynamic_cast<const void*>(v.getRawPtr()),
00385     dynamic_cast<const void*>(prod_v.getRawPtr()));
00386 
00387 }
00388 THYRA_UNIT_TEST_TEMPLATE_1_INSTANT_SCALAR_TYPES( DefaultProductVector,
00389   castOrCreateProductVectorBase_cast )
00390 
00391 
00392 
00393 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DefaultProductVector,
00394   castOrCreateProductVectorBase_create, Scalar )
00395 {
00396 
00397   const RCP<const VectorSpaceBase<Scalar> > vs =
00398     createSpmdVectorSpace<Scalar>(g_localDim);
00399 
00400   const RCP<const VectorBase<Scalar> > v = createMember(vs);
00401 
00402   const RCP<const ProductVectorBase<Scalar> > prod_v =
00403     castOrCreateProductVectorBase(v);
00404 
00405   out << "prod_v = " << *prod_v;
00406 
00407   TEST_EQUALITY_CONST(prod_v->productSpace()->numBlocks(), 1);
00408 
00409 }
00410 THYRA_UNIT_TEST_TEMPLATE_1_INSTANT_SCALAR_TYPES( DefaultProductVector,
00411   castOrCreateProductVectorBase_create )
00412 
00413 
00414 
00415 
00416 } // namespace Thyra
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines