|
Thyra Package Browser (Single Doxygen Collection) Version of the Day
|
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
1.7.4