|
Thyra Package Browser (Single Doxygen Collection)
Version of the Day
|
00001 /* 00002 // @HEADER 00003 // *********************************************************************** 00004 // 00005 // Thyra: Interfaces and Support for Abstract Numerical Algorithms 00006 // Copyright (2004) Sandia Corporation 00007 // 00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00009 // license for use of this work by or on behalf of the U.S. Government. 00010 // 00011 // Redistribution and use in source and binary forms, with or without 00012 // modification, are permitted provided that the following conditions are 00013 // met: 00014 // 00015 // 1. Redistributions of source code must retain the above copyright 00016 // notice, this list of conditions and the following disclaimer. 00017 // 00018 // 2. Redistributions in binary form must reproduce the above copyright 00019 // notice, this list of conditions and the following disclaimer in the 00020 // documentation and/or other materials provided with the distribution. 00021 // 00022 // 3. Neither the name of the Corporation nor the names of the 00023 // contributors may be used to endorse or promote products derived from 00024 // this software without specific prior written permission. 00025 // 00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00037 // 00038 // Questions? Contact Roscoe A. Bartlett (bartlettra@ornl.gov) 00039 // 00040 // *********************************************************************** 00041 // @HEADER 00042 */ 00043 00044 00045 #include "Thyra_TpetraThyraWrappers.hpp" 00046 #include "Thyra_VectorSpaceTester.hpp" 00047 #include "Thyra_VectorStdOpsTester.hpp" 00048 #include "Thyra_LinearOpTester.hpp" 00049 #include "Thyra_DefaultProductVector.hpp" 00050 #include "Thyra_TestingTools.hpp" 00051 #include "Tpetra_CrsMatrix.hpp" 00052 #include "Teuchos_UnitTestHarness.hpp" 00053 #include "Teuchos_DefaultComm.hpp" 00054 00055 00056 namespace { 00057 00058 00059 // 00060 // Helper code and declarations 00061 // 00062 00063 00064 using Teuchos::as; 00065 using Teuchos::null; 00066 using Teuchos::RCP; 00067 using Teuchos::rcp; 00068 using Teuchos::ArrayView; 00069 using Teuchos::rcp_dynamic_cast; 00070 using Teuchos::inOutArg; 00071 using Teuchos::Comm; 00072 using Teuchos::tuple; 00073 typedef Thyra::Ordinal Ordinal; 00074 using Thyra::VectorSpaceBase; 00075 using Thyra::SpmdVectorSpaceBase; 00076 using Thyra::MultiVectorBase; 00077 using Thyra::VectorBase; 00078 using Thyra::LinearOpBase; 00079 using Thyra::createMember; 00080 00081 00082 const int g_localDim = 4; // ToDo: Make variable! 00083 00084 00085 typedef Tpetra::Map<int> TpetraMap_t; 00086 00087 00088 RCP<const TpetraMap_t> 00089 createTpetraMap(const int localDim) 00090 { 00091 typedef Teuchos::OrdinalTraits<Tpetra::global_size_t> OT; 00092 return Teuchos::rcp(new TpetraMap_t(OT::invalid(), localDim, 0, 00093 Teuchos::DefaultComm<int>::getComm())); 00094 // ToDo: Pass in the comm? 00095 } 00096 00097 // ToDo: Above: Vary the LocalOrdinal and GlobalOrdinal types? 00098 00099 00100 template<class Scalar> 00101 RCP<const VectorSpaceBase<Scalar> > 00102 createTpetraVectorSpace(const int localDim) 00103 { 00104 return Thyra::createVectorSpace<Scalar>(createTpetraMap(g_localDim)); 00105 } 00106 00107 00108 template<class Scalar> 00109 RCP<Tpetra::Operator<Scalar,int> > 00110 createTriDiagonalTpetraOperator(const int numLocalRows) 00111 { 00112 typedef Tpetra::global_size_t global_size_t; 00113 00114 RCP<const Tpetra::Map<int> > map = createTpetraMap(numLocalRows); 00115 00116 const size_t numMyElements = map->getNodeNumElements(); 00117 const global_size_t numGlobalElements = map->getGlobalNumElements(); 00118 00119 ArrayView<const int> myGlobalElements = map->getNodeElementList(); 00120 00121 // Create an OTeger vector numNz that is used to build the Petra Matrix. 00122 // numNz[i] is the Number of OFF-DIAGONAL term for the ith global equation 00123 // on this processor 00124 00125 Teuchos::ArrayRCP<size_t> numNz = Teuchos::arcp<size_t>(numMyElements); 00126 00127 // We are building a tridiagonal matrix where each row has (-1 2 -1) 00128 // So we need 2 off-diagonal terms (except for the first and last equation) 00129 00130 for (size_t i=0; i < numMyElements; ++i) { 00131 if (myGlobalElements[i] == 0 || static_cast<global_size_t>(myGlobalElements[i]) == numGlobalElements-1) { 00132 // boundary 00133 numNz[i] = 2; 00134 } 00135 else { 00136 numNz[i] = 3; 00137 } 00138 } 00139 00140 // Create a Tpetra::Matrix using the Map, with a static allocation dictated by numNz 00141 RCP< Tpetra::CrsMatrix<Scalar,int> > A = 00142 Teuchos::rcp( new Tpetra::CrsMatrix<Scalar,int>(map, numNz, Tpetra::StaticProfile) ); 00143 00144 // We are done with NumNZ 00145 numNz = Teuchos::null; 00146 00147 // Add rows one-at-a-time 00148 // Off diagonal values will always be -1 00149 const Scalar two = static_cast<Scalar>( 2.0); 00150 const Scalar posOne = static_cast<Scalar>(+1.0); 00151 const Scalar negOne = static_cast<Scalar>(-1.0); 00152 for (size_t i = 0; i < numMyElements; i++) { 00153 if (myGlobalElements[i] == 0) { 00154 A->insertGlobalValues( myGlobalElements[i], 00155 tuple<int>(myGlobalElements[i], myGlobalElements[i]+1)(), 00156 tuple<Scalar> (two, posOne)() 00157 ); 00158 } 00159 else if (static_cast<global_size_t>(myGlobalElements[i]) == numGlobalElements-1) { 00160 A->insertGlobalValues( myGlobalElements[i], 00161 tuple<int>(myGlobalElements[i]-1, myGlobalElements[i])(), 00162 tuple<Scalar> (negOne, two)() 00163 ); 00164 } 00165 else { 00166 A->insertGlobalValues( myGlobalElements[i], 00167 tuple<int>(myGlobalElements[i]-1, myGlobalElements[i], myGlobalElements[i]+1)(), 00168 tuple<Scalar> (negOne, two, posOne)() 00169 ); 00170 } 00171 } 00172 00173 // Finish up 00174 A->fillComplete(); 00175 00176 return A; 00177 00178 } 00179 00180 00181 bool showAllTests = false; 00182 bool dumpAll = false; 00183 bool runLinearOpTester = true; 00184 00185 00186 TEUCHOS_STATIC_SETUP() 00187 { 00188 Teuchos::UnitTestRepository::getCLP().setOption( 00189 "show-all-tests", "no-show-all-tests", &showAllTests, "Show all tests or not" ); 00190 Teuchos::UnitTestRepository::getCLP().setOption( 00191 "dump-all", "no-dump-all", &dumpAll, "Dump all objects being tested" ); 00192 Teuchos::UnitTestRepository::getCLP().setOption( 00193 "run-linear-op-tester", "no-run-linear-op-tester", &runLinearOpTester, "..." ); 00194 } 00195 00196 00197 // 00198 // Unit Tests 00199 // 00200 00201 00202 // 00203 // convertTpetraToThyraComm 00204 // 00205 00206 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, convertTpetraToThyraComm, 00207 Scalar ) 00208 { 00209 RCP<const Comm<int> > tpetraComm = Teuchos::DefaultComm<int>::getComm(); 00210 RCP<const Comm<Ordinal> > thyraComm = Thyra::convertTpetraToThyraComm(tpetraComm); 00211 TEST_ASSERT(nonnull(thyraComm)); 00212 } 00213 00214 00215 // 00216 // createVectorSpace 00217 // 00218 00219 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createVectorSpace, 00220 Scalar ) 00221 { 00222 const RCP<const TpetraMap_t> tpetraMap = createTpetraMap(g_localDim); 00223 const RCP<const VectorSpaceBase<Scalar> > vs = 00224 Thyra::createVectorSpace<Scalar>(tpetraMap); 00225 TEST_ASSERT(nonnull(vs)); 00226 out << "vs = " << *vs; 00227 const RCP<const SpmdVectorSpaceBase<Scalar> > vs_spmd = 00228 rcp_dynamic_cast<const SpmdVectorSpaceBase<Scalar> >(vs, true); 00229 TEST_EQUALITY(vs_spmd->localSubDim(), g_localDim); 00230 TEST_EQUALITY(vs->dim(), as<Ordinal>(tpetraMap->getGlobalNumElements())); 00231 } 00232 00233 00234 // 00235 // createVector 00236 // 00237 00238 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createVector, 00239 Scalar ) 00240 { 00241 00242 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT; 00243 00244 const RCP<const TpetraMap_t> tpetraMap = createTpetraMap(g_localDim); 00245 const RCP<const VectorSpaceBase<Scalar> > vs = 00246 Thyra::createVectorSpace<Scalar>(tpetraMap); 00247 00248 const RCP<Tpetra::Vector<Scalar,int> > tpetraVector = 00249 rcp(new Tpetra::Vector<Scalar,int>(tpetraMap)); 00250 00251 { 00252 const RCP<VectorBase<Scalar> > thyraVector = createVector(tpetraVector, vs); 00253 TEST_EQUALITY(thyraVector->space(), vs); 00254 const RCP<Tpetra::Vector<Scalar,int> > tpetraVector2 = 00255 ConverterT::getTpetraVector(thyraVector); 00256 TEST_EQUALITY(tpetraVector2, tpetraVector); 00257 } 00258 00259 { 00260 const RCP<VectorBase<Scalar> > thyraVector = Thyra::createVector(tpetraVector); 00261 TEST_INEQUALITY(thyraVector->space(), vs); 00262 TEST_ASSERT(thyraVector->space()->isCompatible(*vs)); 00263 const RCP<Tpetra::Vector<Scalar,int> > tpetraVector2 = 00264 ConverterT::getTpetraVector(thyraVector); 00265 TEST_EQUALITY(tpetraVector2, tpetraVector); 00266 } 00267 00268 } 00269 00270 00271 // 00272 // createConstVector 00273 // 00274 00275 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createConstVector, 00276 Scalar ) 00277 { 00278 00279 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT; 00280 00281 const RCP<const TpetraMap_t> tpetraMap = createTpetraMap(g_localDim); 00282 const RCP<const VectorSpaceBase<Scalar> > vs = 00283 Thyra::createVectorSpace<Scalar>(tpetraMap); 00284 00285 const RCP<const Tpetra::Vector<Scalar,int> > tpetraVector = 00286 rcp(new Tpetra::Vector<Scalar,int>(tpetraMap)); 00287 00288 { 00289 const RCP<const VectorBase<Scalar> > thyraVector = 00290 createConstVector(tpetraVector, vs); 00291 TEST_EQUALITY(thyraVector->space(), vs); 00292 const RCP<const Tpetra::Vector<Scalar,int> > tpetraVector2 = 00293 ConverterT::getConstTpetraVector(thyraVector); 00294 TEST_EQUALITY(tpetraVector2, tpetraVector); 00295 } 00296 00297 { 00298 const RCP<const VectorBase<Scalar> > thyraVector = 00299 Thyra::createConstVector(tpetraVector); 00300 TEST_INEQUALITY(thyraVector->space(), vs); 00301 TEST_ASSERT(thyraVector->space()->isCompatible(*vs)); 00302 const RCP<const Tpetra::Vector<Scalar,int> > tpetraVector2 = 00303 ConverterT::getConstTpetraVector(thyraVector); 00304 TEST_EQUALITY(tpetraVector2, tpetraVector); 00305 } 00306 00307 } 00308 00309 00310 // 00311 // createMultiVector 00312 // 00313 00314 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createMultiVector, 00315 Scalar ) 00316 { 00317 00318 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT; 00319 00320 const int numCols = 3; 00321 00322 const RCP<const TpetraMap_t> tpetraMap = createTpetraMap(g_localDim); 00323 const RCP<const VectorSpaceBase<Scalar> > rangeVs = 00324 Thyra::createVectorSpace<Scalar>(tpetraMap); 00325 00326 const RCP<const TpetraMap_t> tpetraLocRepMap = 00327 Tpetra::createLocalMapWithNode<int,int>( 00328 numCols, tpetraMap->getComm(), tpetraMap->getNode()); 00329 const RCP<const VectorSpaceBase<Scalar> > domainVs = 00330 Thyra::createVectorSpace<Scalar>(tpetraLocRepMap); 00331 00332 const RCP<Tpetra::MultiVector<Scalar,int> > tpetraMultiVector = 00333 rcp(new Tpetra::MultiVector<Scalar,int>(tpetraMap, numCols)); 00334 00335 { 00336 const RCP<MultiVectorBase<Scalar> > thyraMultiVector = 00337 createMultiVector(tpetraMultiVector, rangeVs, domainVs); 00338 TEST_EQUALITY(thyraMultiVector->range(), rangeVs); 00339 TEST_EQUALITY(thyraMultiVector->domain(), domainVs); 00340 const RCP<Tpetra::MultiVector<Scalar,int> > tpetraMultiVector2 = 00341 ConverterT::getTpetraMultiVector(thyraMultiVector); 00342 TEST_EQUALITY(tpetraMultiVector2, tpetraMultiVector); 00343 } 00344 00345 { 00346 const RCP<MultiVectorBase<Scalar> > thyraMultiVector = 00347 Thyra::createMultiVector(tpetraMultiVector); 00348 TEST_INEQUALITY(thyraMultiVector->range(), rangeVs); 00349 TEST_INEQUALITY(thyraMultiVector->domain(), domainVs); 00350 TEST_ASSERT(thyraMultiVector->range()->isCompatible(*rangeVs)); 00351 TEST_ASSERT(thyraMultiVector->domain()->isCompatible(*domainVs)); 00352 const RCP<Tpetra::MultiVector<Scalar,int> > tpetraMultiVector2 = 00353 ConverterT::getTpetraMultiVector(thyraMultiVector); 00354 TEST_EQUALITY(tpetraMultiVector2, tpetraMultiVector); 00355 } 00356 00357 } 00358 00359 00360 // 00361 // createConstMultiVector 00362 // 00363 00364 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createConstMultiVector, 00365 Scalar ) 00366 { 00367 00368 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT; 00369 00370 const int numCols = 3; 00371 00372 const RCP<const TpetraMap_t> tpetraMap = createTpetraMap(g_localDim); 00373 const RCP<const VectorSpaceBase<Scalar> > rangeVs = 00374 Thyra::createVectorSpace<Scalar>(tpetraMap); 00375 00376 const RCP<const TpetraMap_t> tpetraLocRepMap = 00377 Tpetra::createLocalMapWithNode<int,int>( 00378 numCols, tpetraMap->getComm(), tpetraMap->getNode()); 00379 const RCP<const VectorSpaceBase<Scalar> > domainVs = 00380 Thyra::createVectorSpace<Scalar>(tpetraLocRepMap); 00381 00382 const RCP<const Tpetra::MultiVector<Scalar,int> > tpetraMultiVector = 00383 rcp(new Tpetra::MultiVector<Scalar,int>(tpetraMap, numCols)); 00384 00385 { 00386 const RCP<const MultiVectorBase<Scalar> > thyraMultiVector = 00387 createConstMultiVector(tpetraMultiVector, rangeVs, domainVs); 00388 TEST_EQUALITY(thyraMultiVector->range(), rangeVs); 00389 TEST_EQUALITY(thyraMultiVector->domain(), domainVs); 00390 const RCP<const Tpetra::MultiVector<Scalar,int> > tpetraMultiVector2 = 00391 ConverterT::getConstTpetraMultiVector(thyraMultiVector); 00392 TEST_EQUALITY(tpetraMultiVector2, tpetraMultiVector); 00393 } 00394 00395 { 00396 const RCP<const MultiVectorBase<Scalar> > thyraMultiVector = 00397 Thyra::createConstMultiVector(tpetraMultiVector); 00398 TEST_INEQUALITY(thyraMultiVector->range(), rangeVs); 00399 TEST_INEQUALITY(thyraMultiVector->domain(), domainVs); 00400 TEST_ASSERT(thyraMultiVector->range()->isCompatible(*rangeVs)); 00401 TEST_ASSERT(thyraMultiVector->domain()->isCompatible(*domainVs)); 00402 const RCP<const Tpetra::MultiVector<Scalar,int> > tpetraMultiVector2 = 00403 ConverterT::getConstTpetraMultiVector(thyraMultiVector); 00404 TEST_EQUALITY(tpetraMultiVector2, tpetraMultiVector); 00405 } 00406 00407 } 00408 00409 00410 // 00411 // TeptraVectorSpace 00412 // 00413 00414 00415 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, TeptraVectorSpace, 00416 Scalar ) 00417 { 00418 const RCP<const VectorSpaceBase<Scalar> > vs = 00419 Thyra::createVectorSpace<Scalar>(createTpetraMap(g_localDim)); 00420 const RCP<VectorBase<Scalar> > v = createMember(vs); 00421 TEST_ASSERT(nonnull(v)); 00422 TEST_EQUALITY(v->space(), vs); 00423 } 00424 00425 00426 // 00427 // vectorSpaceTester 00428 // 00429 00430 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, vectorSpaceTester, 00431 Scalar ) 00432 { 00433 const RCP<const VectorSpaceBase<Scalar> > vs 00434 = createTpetraVectorSpace<Scalar>(g_localDim); 00435 Thyra::VectorSpaceTester<Scalar> vectorSpaceTester; 00436 vectorSpaceTester.show_all_tests(showAllTests); 00437 vectorSpaceTester.dump_all(dumpAll); 00438 TEST_ASSERT(vectorSpaceTester.check(*vs, &out)); 00439 } 00440 00441 00442 // ToDo: Fix the default tolerances for below 00443 00444 /* 00445 00446 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraVectorSpace, vectorStdOpsTester, 00447 Scalar ) 00448 { 00449 const RCP<const VectorSpaceBase<Scalar> > vs = 00450 Thyra::createVectorSpace<Scalar>(createTpetraMap(g_localDim)); 00451 Thyra::VectorStdOpsTester<Scalar> vectorStdOpsTester; 00452 //vectorStdOpsTester.show_all_tests(showAllTests); 00453 //vectorStdOpsTester.dump_all(dumpAll); 00454 TEST_ASSERT(vectorStdOpsTester.checkStdOps(*vs, &out)); 00455 } 00456 00457 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT_SCALAR_TYPES( TpetraVectorSpace, 00458 vectorStdOpsTester ) 00459 00460 */ 00461 00462 00463 // 00464 // getTpetraMultiVector 00465 // 00466 00467 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, getTpetraMultiVector, 00468 Scalar ) 00469 { 00470 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT; 00471 00472 const int numCols = 3; 00473 const RCP<const VectorSpaceBase<Scalar> > vs 00474 = createTpetraVectorSpace<Scalar>(g_localDim); 00475 00476 { 00477 const RCP<MultiVectorBase<Scalar> > mv = createMembers(vs, numCols); 00478 const RCP<Tpetra::MultiVector<Scalar,int> > tmv = 00479 ConverterT::getTpetraMultiVector(mv); 00480 TEST_ASSERT(nonnull(tmv)); 00481 TEST_EQUALITY(as<Ordinal>(tmv->getMap()->getGlobalNumElements()), vs->dim()); 00482 } 00483 00484 { 00485 const RCP<VectorBase<Scalar> > v = createMember(vs); 00486 const RCP<Tpetra::MultiVector<Scalar,int> > tmv = 00487 ConverterT::getTpetraMultiVector(v); 00488 TEST_ASSERT(nonnull(tmv)); 00489 TEST_EQUALITY(as<Ordinal>(tmv->getMap()->getGlobalNumElements()), vs->dim()); 00490 } 00491 00492 #ifdef THYRA_DEBUG 00493 const RCP<VectorBase<Scalar> > pv = Thyra::defaultProductVector<Scalar>(); 00494 TEST_THROW(ConverterT::getTpetraMultiVector(pv), std::logic_error); 00495 #endif 00496 00497 } 00498 00499 00500 // 00501 // getConstTpetraMultiVector 00502 // 00503 00504 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, getConstTpetraMultiVector, 00505 Scalar ) 00506 { 00507 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT; 00508 00509 const int numCols = 3; 00510 const RCP<const VectorSpaceBase<Scalar> > vs 00511 = createTpetraVectorSpace<Scalar>(g_localDim); 00512 00513 { 00514 const RCP<const MultiVectorBase<Scalar> > mv = createMembers(vs, numCols); 00515 const RCP<const Tpetra::MultiVector<Scalar,int> > tmv = 00516 ConverterT::getConstTpetraMultiVector(mv); 00517 TEST_ASSERT(nonnull(tmv)); 00518 TEST_EQUALITY(as<Ordinal>(tmv->getMap()->getGlobalNumElements()), vs->dim()); 00519 } 00520 00521 { 00522 const RCP<const VectorBase<Scalar> > v = createMember(vs); 00523 const RCP<const Tpetra::MultiVector<Scalar,int> > tmv = 00524 ConverterT::getConstTpetraMultiVector(v); 00525 TEST_ASSERT(nonnull(tmv)); 00526 TEST_EQUALITY(as<Ordinal>(tmv->getMap()->getGlobalNumElements()), vs->dim()); 00527 } 00528 00529 #ifdef THYRA_DEBUG 00530 const RCP<const VectorBase<Scalar> > pv = Thyra::defaultProductVector<Scalar>(); 00531 TEST_THROW(ConverterT::getConstTpetraMultiVector(pv), std::logic_error); 00532 #endif 00533 00534 } 00535 00536 00537 // 00538 // TpetraLinearOp 00539 // 00540 00541 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, TpetraLinearOp, 00542 Scalar ) 00543 { 00544 00545 typedef Teuchos::ScalarTraits<Scalar> ST; 00546 using Teuchos::as; 00547 00548 const RCP<Tpetra::Operator<Scalar,int> > tpetraOp = 00549 createTriDiagonalTpetraOperator<Scalar>(g_localDim); 00550 out << "tpetraOp = " << Teuchos::describe(*tpetraOp, Teuchos::VERB_HIGH) << std::endl; 00551 TEST_ASSERT(nonnull(tpetraOp)); 00552 00553 const RCP<const VectorSpaceBase<Scalar> > rangeSpace = 00554 Thyra::createVectorSpace<Scalar>(tpetraOp->getRangeMap()); 00555 const RCP<const VectorSpaceBase<Scalar> > domainSpace = 00556 Thyra::createVectorSpace<Scalar>(tpetraOp->getDomainMap()); 00557 const RCP<const LinearOpBase<Scalar> > thyraLinearOp = 00558 Thyra::tpetraLinearOp(rangeSpace, domainSpace, tpetraOp); 00559 TEST_ASSERT(nonnull(thyraLinearOp)); 00560 00561 out << "\nCheck that operator returns the right thing ...\n"; 00562 const RCP<VectorBase<Scalar> > x = createMember(thyraLinearOp->domain()); 00563 Thyra::V_S(x.ptr(), ST::one()); 00564 const RCP<VectorBase<Scalar> > y = createMember(thyraLinearOp->range()); 00565 Thyra::apply<Scalar>(*thyraLinearOp, Thyra::NOTRANS, *x, y.ptr()); 00566 const Scalar sum_y = sum(*y); 00567 TEST_FLOATING_EQUALITY( sum_y, as<Scalar>(3+1+2*(y->space()->dim()-2)), 00568 100.0 * ST::eps() ); 00569 00570 out << "\nCheck the general LinearOp interface ...\n"; 00571 Thyra::LinearOpTester<Scalar> linearOpTester; 00572 linearOpTester.show_all_tests(showAllTests); 00573 linearOpTester.dump_all(dumpAll); 00574 if (runLinearOpTester) { 00575 TEST_ASSERT(linearOpTester.check(*thyraLinearOp, Teuchos::inOutArg(out))); 00576 } 00577 00578 } 00579 00580 00581 // 00582 // createLinearOp 00583 // 00584 00585 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createLinearOp, 00586 Scalar ) 00587 { 00588 00589 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT; 00590 00591 const RCP<Tpetra::Operator<Scalar,int> > tpetraOp = 00592 createTriDiagonalTpetraOperator<Scalar>(g_localDim); 00593 out << "tpetraOp = " << Teuchos::describe(*tpetraOp, Teuchos::VERB_HIGH) << std::endl; 00594 00595 const RCP<const VectorSpaceBase<Scalar> > rangeSpace = 00596 Thyra::createVectorSpace<Scalar>(tpetraOp->getRangeMap()); 00597 00598 const RCP<const VectorSpaceBase<Scalar> > domainSpace = 00599 Thyra::createVectorSpace<Scalar>(tpetraOp->getDomainMap()); 00600 00601 { 00602 const RCP<LinearOpBase<Scalar> > thyraOp = 00603 createLinearOp(tpetraOp, rangeSpace, domainSpace); 00604 TEST_EQUALITY(thyraOp->range(), rangeSpace); 00605 TEST_EQUALITY(thyraOp->domain(), domainSpace); 00606 const RCP<Tpetra::Operator<Scalar,int> > tpetraOp2 = 00607 ConverterT::getTpetraOperator(thyraOp); 00608 TEST_EQUALITY(tpetraOp2, tpetraOp); 00609 } 00610 00611 { 00612 const RCP<LinearOpBase<Scalar> > thyraOp = 00613 Thyra::createLinearOp(tpetraOp); 00614 TEST_INEQUALITY(thyraOp->range(), rangeSpace); 00615 TEST_INEQUALITY(thyraOp->domain(), domainSpace); 00616 TEST_ASSERT(thyraOp->range()->isCompatible(*rangeSpace)); 00617 TEST_ASSERT(thyraOp->domain()->isCompatible(*domainSpace)); 00618 const RCP<Tpetra::Operator<Scalar,int> > tpetraOp2 = 00619 ConverterT::getTpetraOperator(thyraOp); 00620 TEST_EQUALITY(tpetraOp2, tpetraOp); 00621 } 00622 00623 } 00624 00625 00626 // 00627 // createConstLinearOp 00628 // 00629 00630 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createConstLinearOp, 00631 Scalar ) 00632 { 00633 00634 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT; 00635 00636 const RCP<const Tpetra::Operator<Scalar,int> > tpetraOp = 00637 createTriDiagonalTpetraOperator<Scalar>(g_localDim); 00638 out << "tpetraOp = " << Teuchos::describe(*tpetraOp, Teuchos::VERB_HIGH) << std::endl; 00639 00640 const RCP<const VectorSpaceBase<Scalar> > rangeSpace = 00641 Thyra::createVectorSpace<Scalar>(tpetraOp->getRangeMap()); 00642 00643 const RCP<const VectorSpaceBase<Scalar> > domainSpace = 00644 Thyra::createVectorSpace<Scalar>(tpetraOp->getDomainMap()); 00645 00646 { 00647 const RCP<const LinearOpBase<Scalar> > thyraOp = 00648 createConstLinearOp(tpetraOp, rangeSpace, domainSpace); 00649 TEST_EQUALITY(thyraOp->range(), rangeSpace); 00650 TEST_EQUALITY(thyraOp->domain(), domainSpace); 00651 const RCP<const Tpetra::Operator<Scalar,int> > tpetraOp2 = 00652 ConverterT::getConstTpetraOperator(thyraOp); 00653 TEST_EQUALITY(tpetraOp2, tpetraOp); 00654 } 00655 00656 { 00657 const RCP<const LinearOpBase<Scalar> > thyraOp = 00658 Thyra::createConstLinearOp(tpetraOp); 00659 TEST_INEQUALITY(thyraOp->range(), rangeSpace); 00660 TEST_INEQUALITY(thyraOp->domain(), domainSpace); 00661 TEST_ASSERT(thyraOp->range()->isCompatible(*rangeSpace)); 00662 TEST_ASSERT(thyraOp->domain()->isCompatible(*domainSpace)); 00663 const RCP<const Tpetra::Operator<Scalar,int> > tpetraOp2 = 00664 ConverterT::getConstTpetraOperator(thyraOp); 00665 TEST_EQUALITY(tpetraOp2, tpetraOp); 00666 } 00667 00668 } 00669 00670 00671 // 00672 // TpetraLinearOp_EpetraRowMatrix 00673 // 00674 00675 00676 #ifdef HAVE_THYRA_TPETRA_EPETRA 00677 00678 00679 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, TpetraLinearOp_EpetraRowMatrix, 00680 Scalar ) 00681 { 00682 00683 using Teuchos::as; 00684 using Teuchos::outArg; 00685 using Teuchos::rcp_dynamic_cast; 00686 using Teuchos::Array; 00687 typedef Teuchos::ScalarTraits<Scalar> ST; 00688 00689 const RCP<Tpetra::Operator<Scalar,int> > tpetraOp = 00690 createTriDiagonalTpetraOperator<Scalar>(g_localDim); 00691 00692 const RCP<LinearOpBase<Scalar> > thyraOp = 00693 Thyra::createLinearOp(tpetraOp); 00694 00695 const RCP<Thyra::TpetraLinearOp<Scalar, int> > thyraTpetraOp = 00696 Teuchos::rcp_dynamic_cast<Thyra::TpetraLinearOp<Scalar, int> >(thyraOp); 00697 00698 RCP<const Epetra_Operator> epetraOp; 00699 Thyra::EOpTransp epetraOpTransp; 00700 Thyra::EApplyEpetraOpAs epetraOpApplyAs; 00701 Thyra::EAdjointEpetraOp epetraOpAdjointSupport; 00702 00703 thyraTpetraOp->getEpetraOpView( outArg(epetraOp), outArg(epetraOpTransp), 00704 outArg(epetraOpApplyAs), outArg(epetraOpAdjointSupport) ); 00705 00706 if (typeid(Scalar) == typeid(double)) { 00707 TEST_ASSERT(nonnull(epetraOp)); 00708 const RCP<const Epetra_RowMatrix> epetraRowMatrix = 00709 rcp_dynamic_cast<const Epetra_RowMatrix>(epetraOp, true); 00710 int numRowEntries = -1; 00711 epetraRowMatrix->NumMyRowEntries(1, numRowEntries); 00712 TEST_EQUALITY_CONST(numRowEntries, 3); 00713 Array<double> row_values(numRowEntries); 00714 Array<int> row_indices(numRowEntries); 00715 epetraRowMatrix->ExtractMyRowCopy(1, numRowEntries, numRowEntries, 00716 row_values.getRawPtr(), row_indices.getRawPtr()); 00717 TEST_EQUALITY_CONST(row_values[0], -1.0); 00718 TEST_EQUALITY_CONST(row_values[1], 2.0); 00719 TEST_EQUALITY_CONST(row_values[2], 1.0); 00720 // ToDo: Test column indices! 00721 } 00722 else { 00723 TEST_ASSERT(is_null(epetraOp)); 00724 } 00725 00726 } 00727 00728 #else 00729 00730 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, TpetraLinearOp_EpetraRowMatrix, 00731 Scalar ) 00732 { 00733 } 00734 00735 #endif // HAVE_THYRA_TPETRA_EPETRA 00736 00737 00738 // 00739 // Unit test instantiations 00740 // 00741 00742 #define THYRA_TPETRA_THYRA_WRAPPERS_INSTANT(SCALAR) \ 00743 \ 00744 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00745 convertTpetraToThyraComm, SCALAR ) \ 00746 \ 00747 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00748 createVectorSpace, SCALAR ) \ 00749 \ 00750 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00751 createVector, SCALAR ) \ 00752 \ 00753 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00754 createConstVector, SCALAR ) \ 00755 \ 00756 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00757 createMultiVector, SCALAR ) \ 00758 \ 00759 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00760 createConstMultiVector, SCALAR ) \ 00761 \ 00762 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00763 TeptraVectorSpace, SCALAR ) \ 00764 \ 00765 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00766 vectorSpaceTester, SCALAR ) \ 00767 \ 00768 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00769 getTpetraMultiVector, SCALAR ) \ 00770 \ 00771 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00772 getConstTpetraMultiVector, SCALAR ) \ 00773 \ 00774 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00775 TpetraLinearOp, SCALAR ) \ 00776 \ 00777 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00778 createLinearOp, SCALAR ) \ 00779 \ 00780 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00781 createConstLinearOp, SCALAR ) \ 00782 \ 00783 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00784 TpetraLinearOp_EpetraRowMatrix, SCALAR ) \ 00785 00786 00787 // We can currently only explicitly instantiate with double support because 00788 // Tpetra only supports explicit instantaition with double. As for implicit 00789 // instantation, g++ 3.4.6 on my Linux machine was taking more than 30 minutes 00790 // to compile this file when all of the types double, float, complex<double>, 00791 // and complex<float> where enabled. Therefore, we will only test double for 00792 // now until explicit instantation with other types are supported by Tpetra. 00793 00794 THYRA_TPETRA_THYRA_WRAPPERS_INSTANT(double) 00795 00796 00797 } // namespace
1.7.6.1