|
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 "Thyra_ScaledLinearOpBase.hpp" 00052 #include "Thyra_RowStatLinearOpBase.hpp" 00053 #include "Thyra_VectorStdOps.hpp" 00054 #include "Tpetra_CrsMatrix.hpp" 00055 #include "Teuchos_UnitTestHarness.hpp" 00056 #include "Teuchos_DefaultComm.hpp" 00057 00058 00059 namespace { 00060 00061 00062 // 00063 // Helper code and declarations 00064 // 00065 00066 00067 using Teuchos::as; 00068 using Teuchos::null; 00069 using Teuchos::RCP; 00070 using Teuchos::rcp; 00071 using Teuchos::ArrayView; 00072 using Teuchos::rcp_dynamic_cast; 00073 using Teuchos::inOutArg; 00074 using Teuchos::Comm; 00075 using Teuchos::tuple; 00076 typedef Thyra::Ordinal Ordinal; 00077 using Thyra::VectorSpaceBase; 00078 using Thyra::SpmdVectorSpaceBase; 00079 using Thyra::MultiVectorBase; 00080 using Thyra::VectorBase; 00081 using Thyra::LinearOpBase; 00082 using Thyra::createMember; 00083 00084 00085 const int g_localDim = 4; // ToDo: Make variable! 00086 00087 00088 typedef Tpetra::Map<int> TpetraMap_t; 00089 00090 00091 RCP<const TpetraMap_t> 00092 createTpetraMap(const int localDim) 00093 { 00094 typedef Teuchos::OrdinalTraits<Tpetra::global_size_t> OT; 00095 return Teuchos::rcp(new TpetraMap_t(OT::invalid(), localDim, 0, 00096 Teuchos::DefaultComm<int>::getComm())); 00097 // ToDo: Pass in the comm? 00098 } 00099 00100 // ToDo: Above: Vary the LocalOrdinal and GlobalOrdinal types? 00101 00102 00103 template<class Scalar> 00104 RCP<const VectorSpaceBase<Scalar> > 00105 createTpetraVectorSpace(const int localDim) 00106 { 00107 return Thyra::createVectorSpace<Scalar>(createTpetraMap(g_localDim)); 00108 } 00109 00110 00111 template<class Scalar> 00112 RCP<Tpetra::Operator<Scalar,int> > 00113 createTriDiagonalTpetraOperator(const int numLocalRows) 00114 { 00115 typedef Tpetra::global_size_t global_size_t; 00116 00117 RCP<const Tpetra::Map<int> > map = createTpetraMap(numLocalRows); 00118 00119 const size_t numMyElements = map->getNodeNumElements(); 00120 const global_size_t numGlobalElements = map->getGlobalNumElements(); 00121 00122 ArrayView<const int> myGlobalElements = map->getNodeElementList(); 00123 00124 // Create an OTeger vector numNz that is used to build the Petra Matrix. 00125 // numNz[i] is the Number of OFF-DIAGONAL term for the ith global equation 00126 // on this processor 00127 00128 Teuchos::ArrayRCP<size_t> numNz = Teuchos::arcp<size_t>(numMyElements); 00129 00130 // We are building a tridiagonal matrix where each row has (-1 2 -1) 00131 // So we need 2 off-diagonal terms (except for the first and last equation) 00132 00133 for (size_t i=0; i < numMyElements; ++i) { 00134 if (myGlobalElements[i] == 0 || static_cast<global_size_t>(myGlobalElements[i]) == numGlobalElements-1) { 00135 // boundary 00136 numNz[i] = 2; 00137 } 00138 else { 00139 numNz[i] = 3; 00140 } 00141 } 00142 00143 // Create a Tpetra::Matrix using the Map, with a static allocation dictated by numNz 00144 RCP< Tpetra::CrsMatrix<Scalar,int> > A = 00145 Teuchos::rcp( new Tpetra::CrsMatrix<Scalar,int>(map, numNz, Tpetra::StaticProfile) ); 00146 00147 // We are done with NumNZ 00148 numNz = Teuchos::null; 00149 00150 // Add rows one-at-a-time 00151 // Off diagonal values will always be -1 00152 const Scalar two = static_cast<Scalar>( 2.0); 00153 const Scalar posOne = static_cast<Scalar>(+1.0); 00154 const Scalar negOne = static_cast<Scalar>(-1.0); 00155 for (size_t i = 0; i < numMyElements; i++) { 00156 if (myGlobalElements[i] == 0) { 00157 A->insertGlobalValues( myGlobalElements[i], 00158 tuple<int>(myGlobalElements[i], myGlobalElements[i]+1)(), 00159 tuple<Scalar> (two, posOne)() 00160 ); 00161 } 00162 else if (static_cast<global_size_t>(myGlobalElements[i]) == numGlobalElements-1) { 00163 A->insertGlobalValues( myGlobalElements[i], 00164 tuple<int>(myGlobalElements[i]-1, myGlobalElements[i])(), 00165 tuple<Scalar> (negOne, two)() 00166 ); 00167 } 00168 else { 00169 A->insertGlobalValues( myGlobalElements[i], 00170 tuple<int>(myGlobalElements[i]-1, myGlobalElements[i], myGlobalElements[i]+1)(), 00171 tuple<Scalar> (negOne, two, posOne)() 00172 ); 00173 } 00174 } 00175 00176 // Finish up 00177 A->fillComplete(); 00178 00179 return A; 00180 00181 } 00182 00183 00184 bool showAllTests = false; 00185 bool dumpAll = false; 00186 bool runLinearOpTester = true; 00187 00188 00189 TEUCHOS_STATIC_SETUP() 00190 { 00191 Teuchos::UnitTestRepository::getCLP().setOption( 00192 "show-all-tests", "no-show-all-tests", &showAllTests, "Show all tests or not" ); 00193 Teuchos::UnitTestRepository::getCLP().setOption( 00194 "dump-all", "no-dump-all", &dumpAll, "Dump all objects being tested" ); 00195 Teuchos::UnitTestRepository::getCLP().setOption( 00196 "run-linear-op-tester", "no-run-linear-op-tester", &runLinearOpTester, "..." ); 00197 } 00198 00199 00200 // 00201 // Unit Tests 00202 // 00203 00204 00205 // 00206 // convertTpetraToThyraComm 00207 // 00208 00209 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, convertTpetraToThyraComm, 00210 Scalar ) 00211 { 00212 RCP<const Comm<int> > tpetraComm = Teuchos::DefaultComm<int>::getComm(); 00213 RCP<const Comm<Ordinal> > thyraComm = Thyra::convertTpetraToThyraComm(tpetraComm); 00214 TEST_ASSERT(nonnull(thyraComm)); 00215 } 00216 00217 00218 // 00219 // createVectorSpace 00220 // 00221 00222 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createVectorSpace, 00223 Scalar ) 00224 { 00225 const RCP<const TpetraMap_t> tpetraMap = createTpetraMap(g_localDim); 00226 const RCP<const VectorSpaceBase<Scalar> > vs = 00227 Thyra::createVectorSpace<Scalar>(tpetraMap); 00228 TEST_ASSERT(nonnull(vs)); 00229 out << "vs = " << *vs; 00230 const RCP<const SpmdVectorSpaceBase<Scalar> > vs_spmd = 00231 rcp_dynamic_cast<const SpmdVectorSpaceBase<Scalar> >(vs, true); 00232 TEST_EQUALITY(vs_spmd->localSubDim(), g_localDim); 00233 TEST_EQUALITY(vs->dim(), as<Ordinal>(tpetraMap->getGlobalNumElements())); 00234 } 00235 00236 00237 // 00238 // createVector 00239 // 00240 00241 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createVector, 00242 Scalar ) 00243 { 00244 00245 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT; 00246 00247 const RCP<const TpetraMap_t> tpetraMap = createTpetraMap(g_localDim); 00248 const RCP<const VectorSpaceBase<Scalar> > vs = 00249 Thyra::createVectorSpace<Scalar>(tpetraMap); 00250 00251 const RCP<Tpetra::Vector<Scalar,int> > tpetraVector = 00252 rcp(new Tpetra::Vector<Scalar,int>(tpetraMap)); 00253 00254 { 00255 const RCP<VectorBase<Scalar> > thyraVector = createVector(tpetraVector, vs); 00256 TEST_EQUALITY(thyraVector->space(), vs); 00257 const RCP<Tpetra::Vector<Scalar,int> > tpetraVector2 = 00258 ConverterT::getTpetraVector(thyraVector); 00259 TEST_EQUALITY(tpetraVector2, tpetraVector); 00260 } 00261 00262 { 00263 const RCP<VectorBase<Scalar> > thyraVector = Thyra::createVector(tpetraVector); 00264 TEST_INEQUALITY(thyraVector->space(), vs); 00265 TEST_ASSERT(thyraVector->space()->isCompatible(*vs)); 00266 const RCP<Tpetra::Vector<Scalar,int> > tpetraVector2 = 00267 ConverterT::getTpetraVector(thyraVector); 00268 TEST_EQUALITY(tpetraVector2, tpetraVector); 00269 } 00270 00271 } 00272 00273 00274 // 00275 // createConstVector 00276 // 00277 00278 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createConstVector, 00279 Scalar ) 00280 { 00281 00282 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT; 00283 00284 const RCP<const TpetraMap_t> tpetraMap = createTpetraMap(g_localDim); 00285 const RCP<const VectorSpaceBase<Scalar> > vs = 00286 Thyra::createVectorSpace<Scalar>(tpetraMap); 00287 00288 const RCP<const Tpetra::Vector<Scalar,int> > tpetraVector = 00289 rcp(new Tpetra::Vector<Scalar,int>(tpetraMap)); 00290 00291 { 00292 const RCP<const VectorBase<Scalar> > thyraVector = 00293 createConstVector(tpetraVector, vs); 00294 TEST_EQUALITY(thyraVector->space(), vs); 00295 const RCP<const Tpetra::Vector<Scalar,int> > tpetraVector2 = 00296 ConverterT::getConstTpetraVector(thyraVector); 00297 TEST_EQUALITY(tpetraVector2, tpetraVector); 00298 } 00299 00300 { 00301 const RCP<const VectorBase<Scalar> > thyraVector = 00302 Thyra::createConstVector(tpetraVector); 00303 TEST_INEQUALITY(thyraVector->space(), vs); 00304 TEST_ASSERT(thyraVector->space()->isCompatible(*vs)); 00305 const RCP<const Tpetra::Vector<Scalar,int> > tpetraVector2 = 00306 ConverterT::getConstTpetraVector(thyraVector); 00307 TEST_EQUALITY(tpetraVector2, tpetraVector); 00308 } 00309 00310 } 00311 00312 00313 // 00314 // createMultiVector 00315 // 00316 00317 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createMultiVector, 00318 Scalar ) 00319 { 00320 00321 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT; 00322 00323 const int numCols = 3; 00324 00325 const RCP<const TpetraMap_t> tpetraMap = createTpetraMap(g_localDim); 00326 const RCP<const VectorSpaceBase<Scalar> > rangeVs = 00327 Thyra::createVectorSpace<Scalar>(tpetraMap); 00328 00329 const RCP<const TpetraMap_t> tpetraLocRepMap = 00330 Tpetra::createLocalMapWithNode<int,int>( 00331 numCols, tpetraMap->getComm(), tpetraMap->getNode()); 00332 const RCP<const VectorSpaceBase<Scalar> > domainVs = 00333 Thyra::createVectorSpace<Scalar>(tpetraLocRepMap); 00334 00335 const RCP<Tpetra::MultiVector<Scalar,int> > tpetraMultiVector = 00336 rcp(new Tpetra::MultiVector<Scalar,int>(tpetraMap, numCols)); 00337 00338 { 00339 const RCP<MultiVectorBase<Scalar> > thyraMultiVector = 00340 createMultiVector(tpetraMultiVector, rangeVs, domainVs); 00341 TEST_EQUALITY(thyraMultiVector->range(), rangeVs); 00342 TEST_EQUALITY(thyraMultiVector->domain(), domainVs); 00343 const RCP<Tpetra::MultiVector<Scalar,int> > tpetraMultiVector2 = 00344 ConverterT::getTpetraMultiVector(thyraMultiVector); 00345 TEST_EQUALITY(tpetraMultiVector2, tpetraMultiVector); 00346 } 00347 00348 { 00349 const RCP<MultiVectorBase<Scalar> > thyraMultiVector = 00350 Thyra::createMultiVector(tpetraMultiVector); 00351 TEST_INEQUALITY(thyraMultiVector->range(), rangeVs); 00352 TEST_INEQUALITY(thyraMultiVector->domain(), domainVs); 00353 TEST_ASSERT(thyraMultiVector->range()->isCompatible(*rangeVs)); 00354 TEST_ASSERT(thyraMultiVector->domain()->isCompatible(*domainVs)); 00355 const RCP<Tpetra::MultiVector<Scalar,int> > tpetraMultiVector2 = 00356 ConverterT::getTpetraMultiVector(thyraMultiVector); 00357 TEST_EQUALITY(tpetraMultiVector2, tpetraMultiVector); 00358 } 00359 00360 } 00361 00362 00363 // 00364 // createConstMultiVector 00365 // 00366 00367 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createConstMultiVector, 00368 Scalar ) 00369 { 00370 00371 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT; 00372 00373 const int numCols = 3; 00374 00375 const RCP<const TpetraMap_t> tpetraMap = createTpetraMap(g_localDim); 00376 const RCP<const VectorSpaceBase<Scalar> > rangeVs = 00377 Thyra::createVectorSpace<Scalar>(tpetraMap); 00378 00379 const RCP<const TpetraMap_t> tpetraLocRepMap = 00380 Tpetra::createLocalMapWithNode<int,int>( 00381 numCols, tpetraMap->getComm(), tpetraMap->getNode()); 00382 const RCP<const VectorSpaceBase<Scalar> > domainVs = 00383 Thyra::createVectorSpace<Scalar>(tpetraLocRepMap); 00384 00385 const RCP<const Tpetra::MultiVector<Scalar,int> > tpetraMultiVector = 00386 rcp(new Tpetra::MultiVector<Scalar,int>(tpetraMap, numCols)); 00387 00388 { 00389 const RCP<const MultiVectorBase<Scalar> > thyraMultiVector = 00390 createConstMultiVector(tpetraMultiVector, rangeVs, domainVs); 00391 TEST_EQUALITY(thyraMultiVector->range(), rangeVs); 00392 TEST_EQUALITY(thyraMultiVector->domain(), domainVs); 00393 const RCP<const Tpetra::MultiVector<Scalar,int> > tpetraMultiVector2 = 00394 ConverterT::getConstTpetraMultiVector(thyraMultiVector); 00395 TEST_EQUALITY(tpetraMultiVector2, tpetraMultiVector); 00396 } 00397 00398 { 00399 const RCP<const MultiVectorBase<Scalar> > thyraMultiVector = 00400 Thyra::createConstMultiVector(tpetraMultiVector); 00401 TEST_INEQUALITY(thyraMultiVector->range(), rangeVs); 00402 TEST_INEQUALITY(thyraMultiVector->domain(), domainVs); 00403 TEST_ASSERT(thyraMultiVector->range()->isCompatible(*rangeVs)); 00404 TEST_ASSERT(thyraMultiVector->domain()->isCompatible(*domainVs)); 00405 const RCP<const Tpetra::MultiVector<Scalar,int> > tpetraMultiVector2 = 00406 ConverterT::getConstTpetraMultiVector(thyraMultiVector); 00407 TEST_EQUALITY(tpetraMultiVector2, tpetraMultiVector); 00408 } 00409 00410 } 00411 00412 00413 // 00414 // TeptraVectorSpace 00415 // 00416 00417 00418 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, TeptraVectorSpace, 00419 Scalar ) 00420 { 00421 const RCP<const VectorSpaceBase<Scalar> > vs = 00422 Thyra::createVectorSpace<Scalar>(createTpetraMap(g_localDim)); 00423 const RCP<VectorBase<Scalar> > v = createMember(vs); 00424 TEST_ASSERT(nonnull(v)); 00425 TEST_EQUALITY(v->space(), vs); 00426 } 00427 00428 00429 // 00430 // vectorSpaceTester 00431 // 00432 00433 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, vectorSpaceTester, 00434 Scalar ) 00435 { 00436 const RCP<const VectorSpaceBase<Scalar> > vs 00437 = createTpetraVectorSpace<Scalar>(g_localDim); 00438 Thyra::VectorSpaceTester<Scalar> vectorSpaceTester; 00439 vectorSpaceTester.show_all_tests(showAllTests); 00440 vectorSpaceTester.dump_all(dumpAll); 00441 TEST_ASSERT(vectorSpaceTester.check(*vs, &out)); 00442 } 00443 00444 00445 // ToDo: Fix the default tolerances for below 00446 00447 /* 00448 00449 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraVectorSpace, vectorStdOpsTester, 00450 Scalar ) 00451 { 00452 const RCP<const VectorSpaceBase<Scalar> > vs = 00453 Thyra::createVectorSpace<Scalar>(createTpetraMap(g_localDim)); 00454 Thyra::VectorStdOpsTester<Scalar> vectorStdOpsTester; 00455 //vectorStdOpsTester.show_all_tests(showAllTests); 00456 //vectorStdOpsTester.dump_all(dumpAll); 00457 TEST_ASSERT(vectorStdOpsTester.checkStdOps(*vs, &out)); 00458 } 00459 00460 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT_SCALAR_TYPES( TpetraVectorSpace, 00461 vectorStdOpsTester ) 00462 00463 */ 00464 00465 00466 // 00467 // getTpetraMultiVector 00468 // 00469 00470 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, getTpetraMultiVector, 00471 Scalar ) 00472 { 00473 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT; 00474 00475 const int numCols = 3; 00476 const RCP<const VectorSpaceBase<Scalar> > vs 00477 = createTpetraVectorSpace<Scalar>(g_localDim); 00478 00479 { 00480 const RCP<MultiVectorBase<Scalar> > mv = createMembers(vs, numCols); 00481 const RCP<Tpetra::MultiVector<Scalar,int> > tmv = 00482 ConverterT::getTpetraMultiVector(mv); 00483 TEST_ASSERT(nonnull(tmv)); 00484 TEST_EQUALITY(as<Ordinal>(tmv->getMap()->getGlobalNumElements()), vs->dim()); 00485 } 00486 00487 { 00488 const RCP<VectorBase<Scalar> > v = createMember(vs); 00489 const RCP<Tpetra::MultiVector<Scalar,int> > tmv = 00490 ConverterT::getTpetraMultiVector(v); 00491 TEST_ASSERT(nonnull(tmv)); 00492 TEST_EQUALITY(as<Ordinal>(tmv->getMap()->getGlobalNumElements()), vs->dim()); 00493 } 00494 00495 #ifdef THYRA_DEBUG 00496 const RCP<VectorBase<Scalar> > pv = Thyra::defaultProductVector<Scalar>(); 00497 TEST_THROW(ConverterT::getTpetraMultiVector(pv), std::logic_error); 00498 #endif 00499 00500 } 00501 00502 00503 // 00504 // getConstTpetraMultiVector 00505 // 00506 00507 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, getConstTpetraMultiVector, 00508 Scalar ) 00509 { 00510 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT; 00511 00512 const int numCols = 3; 00513 const RCP<const VectorSpaceBase<Scalar> > vs 00514 = createTpetraVectorSpace<Scalar>(g_localDim); 00515 00516 { 00517 const RCP<const MultiVectorBase<Scalar> > mv = createMembers(vs, numCols); 00518 const RCP<const Tpetra::MultiVector<Scalar,int> > tmv = 00519 ConverterT::getConstTpetraMultiVector(mv); 00520 TEST_ASSERT(nonnull(tmv)); 00521 TEST_EQUALITY(as<Ordinal>(tmv->getMap()->getGlobalNumElements()), vs->dim()); 00522 } 00523 00524 { 00525 const RCP<const VectorBase<Scalar> > v = createMember(vs); 00526 const RCP<const Tpetra::MultiVector<Scalar,int> > tmv = 00527 ConverterT::getConstTpetraMultiVector(v); 00528 TEST_ASSERT(nonnull(tmv)); 00529 TEST_EQUALITY(as<Ordinal>(tmv->getMap()->getGlobalNumElements()), vs->dim()); 00530 } 00531 00532 #ifdef THYRA_DEBUG 00533 const RCP<const VectorBase<Scalar> > pv = Thyra::defaultProductVector<Scalar>(); 00534 TEST_THROW(ConverterT::getConstTpetraMultiVector(pv), std::logic_error); 00535 #endif 00536 00537 } 00538 00539 00540 // 00541 // TpetraLinearOp 00542 // 00543 00544 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, TpetraLinearOp, 00545 Scalar ) 00546 { 00547 00548 typedef Teuchos::ScalarTraits<Scalar> ST; 00549 using Teuchos::as; 00550 00551 const RCP<Tpetra::Operator<Scalar,int> > tpetraOp = 00552 createTriDiagonalTpetraOperator<Scalar>(g_localDim); 00553 out << "tpetraOp = " << Teuchos::describe(*tpetraOp, Teuchos::VERB_HIGH) << std::endl; 00554 TEST_ASSERT(nonnull(tpetraOp)); 00555 00556 const RCP<const VectorSpaceBase<Scalar> > rangeSpace = 00557 Thyra::createVectorSpace<Scalar>(tpetraOp->getRangeMap()); 00558 const RCP<const VectorSpaceBase<Scalar> > domainSpace = 00559 Thyra::createVectorSpace<Scalar>(tpetraOp->getDomainMap()); 00560 const RCP<const LinearOpBase<Scalar> > thyraLinearOp = 00561 Thyra::tpetraLinearOp(rangeSpace, domainSpace, tpetraOp); 00562 TEST_ASSERT(nonnull(thyraLinearOp)); 00563 00564 out << "\nCheck that operator returns the right thing ...\n"; 00565 const RCP<VectorBase<Scalar> > x = createMember(thyraLinearOp->domain()); 00566 Thyra::V_S(x.ptr(), ST::one()); 00567 const RCP<VectorBase<Scalar> > y = createMember(thyraLinearOp->range()); 00568 Thyra::apply<Scalar>(*thyraLinearOp, Thyra::NOTRANS, *x, y.ptr()); 00569 const Scalar sum_y = sum(*y); 00570 TEST_FLOATING_EQUALITY( sum_y, as<Scalar>(3+1+2*(y->space()->dim()-2)), 00571 100.0 * ST::eps() ); 00572 00573 out << "\nCheck the general LinearOp interface ...\n"; 00574 Thyra::LinearOpTester<Scalar> linearOpTester; 00575 linearOpTester.show_all_tests(showAllTests); 00576 linearOpTester.dump_all(dumpAll); 00577 if (runLinearOpTester) { 00578 TEST_ASSERT(linearOpTester.check(*thyraLinearOp, Teuchos::inOutArg(out))); 00579 } 00580 00581 } 00582 00583 00584 // 00585 // createLinearOp 00586 // 00587 00588 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createLinearOp, 00589 Scalar ) 00590 { 00591 00592 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT; 00593 00594 const RCP<Tpetra::Operator<Scalar,int> > tpetraOp = 00595 createTriDiagonalTpetraOperator<Scalar>(g_localDim); 00596 out << "tpetraOp = " << Teuchos::describe(*tpetraOp, Teuchos::VERB_HIGH) << std::endl; 00597 00598 const RCP<const VectorSpaceBase<Scalar> > rangeSpace = 00599 Thyra::createVectorSpace<Scalar>(tpetraOp->getRangeMap()); 00600 00601 const RCP<const VectorSpaceBase<Scalar> > domainSpace = 00602 Thyra::createVectorSpace<Scalar>(tpetraOp->getDomainMap()); 00603 00604 { 00605 const RCP<LinearOpBase<Scalar> > thyraOp = 00606 createLinearOp(tpetraOp, rangeSpace, domainSpace); 00607 TEST_EQUALITY(thyraOp->range(), rangeSpace); 00608 TEST_EQUALITY(thyraOp->domain(), domainSpace); 00609 const RCP<Tpetra::Operator<Scalar,int> > tpetraOp2 = 00610 ConverterT::getTpetraOperator(thyraOp); 00611 TEST_EQUALITY(tpetraOp2, tpetraOp); 00612 } 00613 00614 { 00615 const RCP<LinearOpBase<Scalar> > thyraOp = 00616 Thyra::createLinearOp(tpetraOp); 00617 TEST_INEQUALITY(thyraOp->range(), rangeSpace); 00618 TEST_INEQUALITY(thyraOp->domain(), domainSpace); 00619 TEST_ASSERT(thyraOp->range()->isCompatible(*rangeSpace)); 00620 TEST_ASSERT(thyraOp->domain()->isCompatible(*domainSpace)); 00621 const RCP<Tpetra::Operator<Scalar,int> > tpetraOp2 = 00622 ConverterT::getTpetraOperator(thyraOp); 00623 TEST_EQUALITY(tpetraOp2, tpetraOp); 00624 } 00625 00626 } 00627 00628 00629 // 00630 // createConstLinearOp 00631 // 00632 00633 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createConstLinearOp, 00634 Scalar ) 00635 { 00636 00637 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT; 00638 00639 const RCP<const Tpetra::Operator<Scalar,int> > tpetraOp = 00640 createTriDiagonalTpetraOperator<Scalar>(g_localDim); 00641 out << "tpetraOp = " << Teuchos::describe(*tpetraOp, Teuchos::VERB_HIGH) << std::endl; 00642 00643 const RCP<const VectorSpaceBase<Scalar> > rangeSpace = 00644 Thyra::createVectorSpace<Scalar>(tpetraOp->getRangeMap()); 00645 00646 const RCP<const VectorSpaceBase<Scalar> > domainSpace = 00647 Thyra::createVectorSpace<Scalar>(tpetraOp->getDomainMap()); 00648 00649 { 00650 const RCP<const LinearOpBase<Scalar> > thyraOp = 00651 createConstLinearOp(tpetraOp, rangeSpace, domainSpace); 00652 TEST_EQUALITY(thyraOp->range(), rangeSpace); 00653 TEST_EQUALITY(thyraOp->domain(), domainSpace); 00654 const RCP<const Tpetra::Operator<Scalar,int> > tpetraOp2 = 00655 ConverterT::getConstTpetraOperator(thyraOp); 00656 TEST_EQUALITY(tpetraOp2, tpetraOp); 00657 } 00658 00659 { 00660 const RCP<const LinearOpBase<Scalar> > thyraOp = 00661 Thyra::createConstLinearOp(tpetraOp); 00662 TEST_INEQUALITY(thyraOp->range(), rangeSpace); 00663 TEST_INEQUALITY(thyraOp->domain(), domainSpace); 00664 TEST_ASSERT(thyraOp->range()->isCompatible(*rangeSpace)); 00665 TEST_ASSERT(thyraOp->domain()->isCompatible(*domainSpace)); 00666 const RCP<const Tpetra::Operator<Scalar,int> > tpetraOp2 = 00667 ConverterT::getConstTpetraOperator(thyraOp); 00668 TEST_EQUALITY(tpetraOp2, tpetraOp); 00669 } 00670 00671 } 00672 00673 00674 // 00675 // TpetraLinearOp_EpetraRowMatrix 00676 // 00677 00678 00679 #ifdef HAVE_THYRA_TPETRA_EPETRA 00680 00681 00682 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, TpetraLinearOp_EpetraRowMatrix, 00683 Scalar ) 00684 { 00685 00686 using Teuchos::as; 00687 using Teuchos::outArg; 00688 using Teuchos::rcp_dynamic_cast; 00689 using Teuchos::Array; 00690 typedef Teuchos::ScalarTraits<Scalar> ST; 00691 00692 const RCP<Tpetra::Operator<Scalar,int> > tpetraOp = 00693 createTriDiagonalTpetraOperator<Scalar>(g_localDim); 00694 00695 const RCP<LinearOpBase<Scalar> > thyraOp = 00696 Thyra::createLinearOp(tpetraOp); 00697 00698 const RCP<Thyra::TpetraLinearOp<Scalar, int> > thyraTpetraOp = 00699 Teuchos::rcp_dynamic_cast<Thyra::TpetraLinearOp<Scalar, int> >(thyraOp); 00700 00701 RCP<const Epetra_Operator> epetraOp; 00702 Thyra::EOpTransp epetraOpTransp; 00703 Thyra::EApplyEpetraOpAs epetraOpApplyAs; 00704 Thyra::EAdjointEpetraOp epetraOpAdjointSupport; 00705 00706 thyraTpetraOp->getEpetraOpView( outArg(epetraOp), outArg(epetraOpTransp), 00707 outArg(epetraOpApplyAs), outArg(epetraOpAdjointSupport) ); 00708 00709 if (typeid(Scalar) == typeid(double)) { 00710 TEST_ASSERT(nonnull(epetraOp)); 00711 const RCP<const Epetra_RowMatrix> epetraRowMatrix = 00712 rcp_dynamic_cast<const Epetra_RowMatrix>(epetraOp, true); 00713 int numRowEntries = -1; 00714 epetraRowMatrix->NumMyRowEntries(1, numRowEntries); 00715 TEST_EQUALITY_CONST(numRowEntries, 3); 00716 Array<double> row_values(numRowEntries); 00717 Array<int> row_indices(numRowEntries); 00718 epetraRowMatrix->ExtractMyRowCopy(1, numRowEntries, numRowEntries, 00719 row_values.getRawPtr(), row_indices.getRawPtr()); 00720 TEST_EQUALITY_CONST(row_values[0], -1.0); 00721 TEST_EQUALITY_CONST(row_values[1], 2.0); 00722 TEST_EQUALITY_CONST(row_values[2], 1.0); 00723 // ToDo: Test column indices! 00724 } 00725 else { 00726 TEST_ASSERT(is_null(epetraOp)); 00727 } 00728 00729 } 00730 00731 #else 00732 00733 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, TpetraLinearOp_EpetraRowMatrix, 00734 Scalar ) 00735 { 00736 } 00737 00738 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, TpetraLinearOp_RowStatLinearOpBase, 00739 Scalar ) 00740 { 00741 using Teuchos::as; 00742 00743 const RCP<Tpetra::Operator<Scalar,int> > tpetraOp = 00744 createTriDiagonalTpetraOperator<Scalar>(g_localDim); 00745 out << "tpetraOp = " << Teuchos::describe(*tpetraOp, Teuchos::VERB_HIGH) << std::endl; 00746 TEST_ASSERT(nonnull(tpetraOp)); 00747 00748 const RCP<Tpetra::CrsMatrix<Scalar,int> > tpetraCrsMatrix = 00749 Teuchos::rcp_dynamic_cast<Tpetra::CrsMatrix<Scalar,int> >(tpetraOp,true); 00750 00751 const RCP<const VectorSpaceBase<Scalar> > rangeSpace = 00752 Thyra::createVectorSpace<Scalar>(tpetraOp->getRangeMap()); 00753 const RCP<const VectorSpaceBase<Scalar> > domainSpace = 00754 Thyra::createVectorSpace<Scalar>(tpetraOp->getDomainMap()); 00755 const RCP<LinearOpBase<Scalar> > thyraLinearOp = 00756 Thyra::tpetraLinearOp(rangeSpace, domainSpace, tpetraOp); 00757 TEST_ASSERT(nonnull(thyraLinearOp)); 00758 00759 const Teuchos::RCP<Thyra::RowStatLinearOpBase<Scalar> > rowStatOp = 00760 Teuchos::rcp_dynamic_cast<Thyra::RowStatLinearOpBase<Scalar> >(thyraLinearOp, true); 00761 00762 // Get the inverse row sums 00763 00764 const RCP<VectorBase<Scalar> > inv_row_sums = 00765 createMember<Scalar>(thyraLinearOp->range()); 00766 const RCP<VectorBase<Scalar> > row_sums = 00767 createMember<Scalar>(thyraLinearOp->range()); 00768 00769 rowStatOp->getRowStat(Thyra::RowStatLinearOpBaseUtils::ROW_STAT_INV_ROW_SUM, 00770 inv_row_sums.ptr()); 00771 rowStatOp->getRowStat(Thyra::RowStatLinearOpBaseUtils::ROW_STAT_ROW_SUM, 00772 row_sums.ptr()); 00773 00774 out << "inv_row_sums = " << *inv_row_sums; 00775 out << "row_sums = " << *row_sums; 00776 00777 TEST_FLOATING_EQUALITY( 00778 Thyra::sum<Scalar>(*row_sums), 00779 Teuchos::as<Scalar>(4.0 * thyraLinearOp->domain()->dim() - 2.0), 00780 Teuchos::as<Scalar>(10.0 * Teuchos::ScalarTraits<Scalar>::eps()) 00781 ); 00782 00783 TEST_FLOATING_EQUALITY( 00784 Thyra::sum<Scalar>(*inv_row_sums), 00785 Teuchos::as<Scalar>( 1.0 / 4.0 * (thyraLinearOp->domain()->dim() - 2) + 2.0 / 3.0 ), 00786 Teuchos::as<Scalar>(10.0 * Teuchos::ScalarTraits<Scalar>::eps()) 00787 ); 00788 } 00789 00790 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, TpetraLinearOp_ScaledLinearOpBase, 00791 Scalar ) 00792 { 00793 const RCP<Tpetra::Operator<Scalar,int> > tpetraOp = 00794 createTriDiagonalTpetraOperator<Scalar>(g_localDim); 00795 out << "tpetraOp = " << Teuchos::describe(*tpetraOp, Teuchos::VERB_HIGH) << std::endl; 00796 TEST_ASSERT(nonnull(tpetraOp)); 00797 00798 const RCP<Tpetra::CrsMatrix<Scalar,int> > tpetraCrsMatrix = 00799 Teuchos::rcp_dynamic_cast<Tpetra::CrsMatrix<Scalar,int> >(tpetraOp,true); 00800 00801 const RCP<const VectorSpaceBase<Scalar> > rangeSpace = 00802 Thyra::createVectorSpace<Scalar>(tpetraOp->getRangeMap()); 00803 const RCP<const VectorSpaceBase<Scalar> > domainSpace = 00804 Thyra::createVectorSpace<Scalar>(tpetraOp->getDomainMap()); 00805 const RCP<LinearOpBase<Scalar> > thyraLinearOp = 00806 Thyra::tpetraLinearOp(rangeSpace, domainSpace, tpetraOp); 00807 TEST_ASSERT(nonnull(thyraLinearOp)); 00808 00809 const Teuchos::RCP<Thyra::RowStatLinearOpBase<Scalar> > rowStatOp = 00810 Teuchos::rcp_dynamic_cast<Thyra::RowStatLinearOpBase<Scalar> >(thyraLinearOp, true); 00811 00812 // Get the inverse row sums 00813 00814 const RCP<VectorBase<Scalar> > inv_row_sums = 00815 createMember<Scalar>(thyraLinearOp->range()); 00816 const RCP<VectorBase<Scalar> > row_sums = 00817 createMember<Scalar>(thyraLinearOp->range()); 00818 00819 rowStatOp->getRowStat(Thyra::RowStatLinearOpBaseUtils::ROW_STAT_INV_ROW_SUM, 00820 inv_row_sums.ptr()); 00821 rowStatOp->getRowStat(Thyra::RowStatLinearOpBaseUtils::ROW_STAT_ROW_SUM, 00822 row_sums.ptr()); 00823 00824 out << "inv_row_sums = " << *inv_row_sums; 00825 out << "row_sums = " << *row_sums; 00826 00827 const Teuchos::RCP<Thyra::ScaledLinearOpBase<Scalar> > scaledOp = 00828 Teuchos::rcp_dynamic_cast<Thyra::ScaledLinearOpBase<Scalar> >(thyraLinearOp, true); 00829 00830 TEUCHOS_ASSERT(scaledOp->supportsScaleLeft()); 00831 00832 scaledOp->scaleLeft(*inv_row_sums); 00833 00834 rowStatOp->getRowStat(Thyra::RowStatLinearOpBaseUtils::ROW_STAT_ROW_SUM, 00835 row_sums.ptr()); 00836 00837 out << "row_sums after left scaling by inv_row_sum = " << *row_sums; 00838 00839 // scaled row sums should be one for each entry 00840 TEST_FLOATING_EQUALITY( 00841 Scalar(row_sums->space()->dim()), 00842 Thyra::sum<Scalar>(*row_sums), 00843 as<Scalar>(10.0 * Teuchos::ScalarTraits<Scalar>::eps()) 00844 ); 00845 00846 // Don't currently check the results of right scaling. Tpetra tests 00847 // already check this. Once column sums are supported in tpetra 00848 // adapters, this can be checked easily. 00849 TEUCHOS_ASSERT(scaledOp->supportsScaleRight()); 00850 scaledOp->scaleRight(*inv_row_sums); 00851 rowStatOp->getRowStat(Thyra::RowStatLinearOpBaseUtils::ROW_STAT_ROW_SUM,row_sums.ptr()); 00852 out << "row_sums after right scaling by inv_row_sum = " << *row_sums; 00853 } 00854 00855 #endif // HAVE_THYRA_TPETRA_EPETRA 00856 00857 00858 // 00859 // Unit test instantiations 00860 // 00861 00862 #define THYRA_TPETRA_THYRA_WRAPPERS_INSTANT(SCALAR) \ 00863 \ 00864 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00865 convertTpetraToThyraComm, SCALAR ) \ 00866 \ 00867 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00868 createVectorSpace, SCALAR ) \ 00869 \ 00870 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00871 createVector, SCALAR ) \ 00872 \ 00873 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00874 createConstVector, SCALAR ) \ 00875 \ 00876 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00877 createMultiVector, SCALAR ) \ 00878 \ 00879 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00880 createConstMultiVector, SCALAR ) \ 00881 \ 00882 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00883 TeptraVectorSpace, SCALAR ) \ 00884 \ 00885 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00886 vectorSpaceTester, SCALAR ) \ 00887 \ 00888 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00889 getTpetraMultiVector, SCALAR ) \ 00890 \ 00891 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00892 getConstTpetraMultiVector, SCALAR ) \ 00893 \ 00894 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00895 TpetraLinearOp, SCALAR ) \ 00896 \ 00897 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00898 createLinearOp, SCALAR ) \ 00899 \ 00900 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00901 createConstLinearOp, SCALAR ) \ 00902 \ 00903 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00904 TpetraLinearOp_EpetraRowMatrix, SCALAR ) \ 00905 \ 00906 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00907 TpetraLinearOp_RowStatLinearOpBase, SCALAR ) \ 00908 \ 00909 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \ 00910 TpetraLinearOp_ScaledLinearOpBase, SCALAR ) \ 00911 00912 00913 // We can currently only explicitly instantiate with double support because 00914 // Tpetra only supports explicit instantaition with double. As for implicit 00915 // instantation, g++ 3.4.6 on my Linux machine was taking more than 30 minutes 00916 // to compile this file when all of the types double, float, complex<double>, 00917 // and complex<float> where enabled. Therefore, we will only test double for 00918 // now until explicit instantation with other types are supported by Tpetra. 00919 00920 THYRA_TPETRA_THYRA_WRAPPERS_INSTANT(double) 00921 00922 00923 } // namespace
1.7.6.1