Thyra Package Browser (Single Doxygen Collection) Version of the Day
TpetraThyraWrappers_UnitTests.cpp
Go to the documentation of this file.
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 int Ordinal;
00113   typedef Tpetra::global_size_t global_size_t;
00114 
00115   RCP<const Tpetra::Map<int> > map = createTpetraMap(numLocalRows);
00116 
00117   const size_t numMyElements = map->getNodeNumElements();
00118   const global_size_t numGlobalElements = map->getGlobalNumElements();
00119 
00120   ArrayView<const Ordinal> myGlobalElements = map->getNodeElementList();
00121 
00122   // Create an OTeger vector numNz that is used to build the Petra Matrix.
00123   // numNz[i] is the Number of OFF-DIAGONAL term for the ith global equation 
00124   // on this processor
00125 
00126   Teuchos::ArrayRCP<size_t> numNz = Teuchos::arcp<size_t>(numMyElements);
00127 
00128   // We are building a tridiagonal matrix where each row has (-1 2 -1)
00129   // So we need 2 off-diagonal terms (except for the first and last equation)
00130 
00131   for (size_t i=0; i < numMyElements; ++i) {
00132     if (myGlobalElements[i] == 0 || static_cast<global_size_t>(myGlobalElements[i]) == numGlobalElements-1) {
00133       // boundary
00134       numNz[i] = 2;
00135     }
00136     else {
00137       numNz[i] = 3;
00138     }
00139   }
00140 
00141   // Create a Tpetra::Matrix using the Map, with a static allocation dictated by numNz
00142   RCP< Tpetra::CrsMatrix<Scalar,Ordinal> > A =
00143     Teuchos::rcp( new Tpetra::CrsMatrix<Scalar,Ordinal>(map, numNz, Tpetra::StaticProfile) );
00144   
00145   // We are done with NumNZ
00146   numNz = Teuchos::null;
00147 
00148   // Add  rows one-at-a-time
00149   // Off diagonal values will always be -1
00150   const Scalar two    = static_cast<Scalar>( 2.0);
00151   const Scalar posOne = static_cast<Scalar>(+1.0);
00152   const Scalar negOne = static_cast<Scalar>(-1.0);
00153   for (size_t i = 0; i < numMyElements; i++) {
00154     if (myGlobalElements[i] == 0) {
00155       A->insertGlobalValues( myGlobalElements[i],
00156         tuple<Ordinal>(myGlobalElements[i], myGlobalElements[i]+1)(),
00157         tuple<Scalar> (two, posOne)()
00158         );
00159     }
00160     else if (static_cast<global_size_t>(myGlobalElements[i]) == numGlobalElements-1) {
00161       A->insertGlobalValues( myGlobalElements[i],
00162         tuple<Ordinal>(myGlobalElements[i]-1, myGlobalElements[i])(),
00163         tuple<Scalar> (negOne, two)()
00164         );
00165     }
00166     else {
00167       A->insertGlobalValues( myGlobalElements[i],
00168         tuple<Ordinal>(myGlobalElements[i]-1, myGlobalElements[i], myGlobalElements[i]+1)(),
00169         tuple<Scalar> (negOne, two, posOne)()
00170         );
00171     }
00172   }
00173 
00174   // Finish up
00175   A->fillComplete(Tpetra::DoOptimizeStorage);
00176 
00177   return A;
00178 
00179 }
00180 
00181 
00182 bool showAllTests = false;
00183 bool dumpAll = false;
00184 bool runLinearOpTester = true;
00185 
00186 
00187 TEUCHOS_STATIC_SETUP()
00188 {
00189   Teuchos::UnitTestRepository::getCLP().setOption(
00190     "show-all-tests", "no-show-all-tests", &showAllTests, "Show all tests or not" );
00191   Teuchos::UnitTestRepository::getCLP().setOption(
00192     "dump-all", "no-dump-all", &dumpAll, "Dump all objects being tested" );
00193   Teuchos::UnitTestRepository::getCLP().setOption(
00194     "run-linear-op-tester", "no-run-linear-op-tester", &runLinearOpTester, "..." );
00195 }
00196 
00197 
00198 //
00199 // Unit Tests
00200 //
00201 
00202 
00203 //
00204 // convertTpetraToThyraComm
00205 //
00206 
00207 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, convertTpetraToThyraComm,
00208   Scalar )
00209 {
00210   RCP<const Comm<int> > tpetraComm = Teuchos::DefaultComm<int>::getComm();
00211   RCP<const Comm<Ordinal> > thyraComm = Thyra::convertTpetraToThyraComm(tpetraComm);
00212   TEST_ASSERT(nonnull(thyraComm));
00213 }
00214 
00215 
00216 //
00217 // createVectorSpace
00218 //
00219 
00220 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createVectorSpace,
00221   Scalar )
00222 {
00223   const RCP<const TpetraMap_t> tpetraMap = createTpetraMap(g_localDim);
00224   const RCP<const VectorSpaceBase<Scalar> > vs =
00225     Thyra::createVectorSpace<Scalar>(tpetraMap);
00226   TEST_ASSERT(nonnull(vs));
00227   out << "vs = " << *vs;
00228   const RCP<const SpmdVectorSpaceBase<Scalar> > vs_spmd = 
00229     rcp_dynamic_cast<const SpmdVectorSpaceBase<Scalar> >(vs, true);
00230   TEST_EQUALITY(vs_spmd->localSubDim(), g_localDim);
00231   TEST_EQUALITY(vs->dim(), as<Ordinal>(tpetraMap->getGlobalNumElements()));
00232 }
00233 
00234 
00235 //
00236 // createVector
00237 //
00238 
00239 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createVector,
00240   Scalar )
00241 {
00242 
00243   typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT;
00244 
00245   const RCP<const TpetraMap_t> tpetraMap = createTpetraMap(g_localDim);
00246   const RCP<const VectorSpaceBase<Scalar> > vs =
00247     Thyra::createVectorSpace<Scalar>(tpetraMap);
00248 
00249   const RCP<Tpetra::Vector<Scalar,int> > tpetraVector =
00250     rcp(new Tpetra::Vector<Scalar,int>(tpetraMap));
00251 
00252   {
00253     const RCP<VectorBase<Scalar> > thyraVector = createVector(tpetraVector, vs);
00254     TEST_EQUALITY(thyraVector->space(), vs);
00255     const RCP<Tpetra::Vector<Scalar,int> > tpetraVector2 = 
00256       ConverterT::getTpetraVector(thyraVector);
00257     TEST_EQUALITY(tpetraVector2, tpetraVector);
00258   }
00259 
00260   {
00261     const RCP<VectorBase<Scalar> > thyraVector = Thyra::createVector(tpetraVector);
00262     TEST_INEQUALITY(thyraVector->space(), vs);
00263     TEST_ASSERT(thyraVector->space()->isCompatible(*vs));
00264     const RCP<Tpetra::Vector<Scalar,int> > tpetraVector2 = 
00265       ConverterT::getTpetraVector(thyraVector);
00266     TEST_EQUALITY(tpetraVector2, tpetraVector);
00267   }
00268 
00269 }
00270 
00271 
00272 //
00273 // createConstVector
00274 //
00275 
00276 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createConstVector,
00277   Scalar )
00278 {
00279 
00280   typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT;
00281 
00282   const RCP<const TpetraMap_t> tpetraMap = createTpetraMap(g_localDim);
00283   const RCP<const VectorSpaceBase<Scalar> > vs =
00284     Thyra::createVectorSpace<Scalar>(tpetraMap);
00285 
00286   const RCP<const Tpetra::Vector<Scalar,int> > tpetraVector =
00287     rcp(new Tpetra::Vector<Scalar,int>(tpetraMap));
00288 
00289   {
00290     const RCP<const VectorBase<Scalar> > thyraVector =
00291       createConstVector(tpetraVector, vs);
00292     TEST_EQUALITY(thyraVector->space(), vs);
00293     const RCP<const Tpetra::Vector<Scalar,int> > tpetraVector2 = 
00294       ConverterT::getConstTpetraVector(thyraVector);
00295     TEST_EQUALITY(tpetraVector2, tpetraVector);
00296   }
00297 
00298   {
00299     const RCP<const VectorBase<Scalar> > thyraVector =
00300       Thyra::createConstVector(tpetraVector);
00301     TEST_INEQUALITY(thyraVector->space(), vs);
00302     TEST_ASSERT(thyraVector->space()->isCompatible(*vs));
00303     const RCP<const Tpetra::Vector<Scalar,int> > tpetraVector2 = 
00304       ConverterT::getConstTpetraVector(thyraVector);
00305     TEST_EQUALITY(tpetraVector2, tpetraVector);
00306   }
00307 
00308 }
00309 
00310 
00311 //
00312 // createMultiVector
00313 //
00314 
00315 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createMultiVector,
00316   Scalar )
00317 {
00318 
00319   typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT;
00320   
00321   const int numCols = 3;
00322 
00323   const RCP<const TpetraMap_t> tpetraMap = createTpetraMap(g_localDim);
00324   const RCP<const VectorSpaceBase<Scalar> > rangeVs =
00325     Thyra::createVectorSpace<Scalar>(tpetraMap);
00326 
00327   const RCP<const TpetraMap_t> tpetraLocRepMap =
00328     Tpetra::createLocalMapWithNode<int,int>(
00329       numCols, tpetraMap->getComm(), tpetraMap->getNode());
00330   const RCP<const VectorSpaceBase<Scalar> > domainVs =
00331     Thyra::createVectorSpace<Scalar>(tpetraLocRepMap);
00332 
00333   const RCP<Tpetra::MultiVector<Scalar,int> > tpetraMultiVector =
00334     rcp(new Tpetra::MultiVector<Scalar,int>(tpetraMap, numCols));
00335 
00336   {
00337     const RCP<MultiVectorBase<Scalar> > thyraMultiVector =
00338       createMultiVector(tpetraMultiVector, rangeVs, domainVs);
00339     TEST_EQUALITY(thyraMultiVector->range(), rangeVs);
00340     TEST_EQUALITY(thyraMultiVector->domain(), domainVs);
00341     const RCP<Tpetra::MultiVector<Scalar,int> > tpetraMultiVector2 = 
00342       ConverterT::getTpetraMultiVector(thyraMultiVector);
00343     TEST_EQUALITY(tpetraMultiVector2, tpetraMultiVector);
00344   }
00345 
00346   {
00347     const RCP<MultiVectorBase<Scalar> > thyraMultiVector =
00348       Thyra::createMultiVector(tpetraMultiVector);
00349     TEST_INEQUALITY(thyraMultiVector->range(), rangeVs);
00350     TEST_INEQUALITY(thyraMultiVector->domain(), domainVs);
00351     TEST_ASSERT(thyraMultiVector->range()->isCompatible(*rangeVs));
00352     TEST_ASSERT(thyraMultiVector->domain()->isCompatible(*domainVs));
00353     const RCP<Tpetra::MultiVector<Scalar,int> > tpetraMultiVector2 = 
00354       ConverterT::getTpetraMultiVector(thyraMultiVector);
00355     TEST_EQUALITY(tpetraMultiVector2, tpetraMultiVector);
00356   }
00357 
00358 }
00359 
00360 
00361 //
00362 // createConstMultiVector
00363 //
00364 
00365 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createConstMultiVector,
00366   Scalar )
00367 {
00368 
00369   typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT;
00370   
00371   const int numCols = 3;
00372 
00373   const RCP<const TpetraMap_t> tpetraMap = createTpetraMap(g_localDim);
00374   const RCP<const VectorSpaceBase<Scalar> > rangeVs =
00375     Thyra::createVectorSpace<Scalar>(tpetraMap);
00376 
00377   const RCP<const TpetraMap_t> tpetraLocRepMap =
00378     Tpetra::createLocalMapWithNode<int,int>(
00379       numCols, tpetraMap->getComm(), tpetraMap->getNode());
00380   const RCP<const VectorSpaceBase<Scalar> > domainVs =
00381     Thyra::createVectorSpace<Scalar>(tpetraLocRepMap);
00382 
00383   const RCP<const Tpetra::MultiVector<Scalar,int> > tpetraMultiVector =
00384     rcp(new Tpetra::MultiVector<Scalar,int>(tpetraMap, numCols));
00385 
00386   {
00387     const RCP<const MultiVectorBase<Scalar> > thyraMultiVector =
00388       createConstMultiVector(tpetraMultiVector, rangeVs, domainVs);
00389     TEST_EQUALITY(thyraMultiVector->range(), rangeVs);
00390     TEST_EQUALITY(thyraMultiVector->domain(), domainVs);
00391     const RCP<const Tpetra::MultiVector<Scalar,int> > tpetraMultiVector2 = 
00392       ConverterT::getConstTpetraMultiVector(thyraMultiVector);
00393     TEST_EQUALITY(tpetraMultiVector2, tpetraMultiVector);
00394   }
00395 
00396   {
00397     const RCP<const MultiVectorBase<Scalar> > thyraMultiVector =
00398       Thyra::createConstMultiVector(tpetraMultiVector);
00399     TEST_INEQUALITY(thyraMultiVector->range(), rangeVs);
00400     TEST_INEQUALITY(thyraMultiVector->domain(), domainVs);
00401     TEST_ASSERT(thyraMultiVector->range()->isCompatible(*rangeVs));
00402     TEST_ASSERT(thyraMultiVector->domain()->isCompatible(*domainVs));
00403     const RCP<const Tpetra::MultiVector<Scalar,int> > tpetraMultiVector2 = 
00404       ConverterT::getConstTpetraMultiVector(thyraMultiVector);
00405     TEST_EQUALITY(tpetraMultiVector2, tpetraMultiVector);
00406   }
00407 
00408 }
00409 
00410 
00411 //
00412 // TeptraVectorSpace
00413 //
00414 
00415 
00416 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, TeptraVectorSpace,
00417   Scalar )
00418 {
00419   const RCP<const VectorSpaceBase<Scalar> > vs =
00420     Thyra::createVectorSpace<Scalar>(createTpetraMap(g_localDim));
00421   const RCP<VectorBase<Scalar> > v = createMember(vs);
00422   TEST_ASSERT(nonnull(v));
00423   TEST_EQUALITY(v->space(), vs);
00424 }
00425 
00426 
00427 //
00428 // vectorSpaceTester
00429 //
00430 
00431 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, vectorSpaceTester,
00432   Scalar )
00433 {
00434   const RCP<const VectorSpaceBase<Scalar> > vs 
00435     = createTpetraVectorSpace<Scalar>(g_localDim);
00436   Thyra::VectorSpaceTester<Scalar> vectorSpaceTester;
00437   vectorSpaceTester.show_all_tests(showAllTests);
00438   vectorSpaceTester.dump_all(dumpAll);
00439   TEST_ASSERT(vectorSpaceTester.check(*vs, &out));
00440 }
00441 
00442 
00443 // ToDo: Fix the default tolerances for below
00444 
00445 /*
00446 
00447 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraVectorSpace, vectorStdOpsTester,
00448   Scalar )
00449 {
00450   const RCP<const VectorSpaceBase<Scalar> > vs =
00451     Thyra::createVectorSpace<Scalar>(createTpetraMap(g_localDim));
00452   Thyra::VectorStdOpsTester<Scalar> vectorStdOpsTester;
00453   //vectorStdOpsTester.show_all_tests(showAllTests);
00454   //vectorStdOpsTester.dump_all(dumpAll);
00455   TEST_ASSERT(vectorStdOpsTester.checkStdOps(*vs, &out));
00456 }
00457 
00458 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT_SCALAR_TYPES( TpetraVectorSpace,
00459   vectorStdOpsTester )
00460 
00461 */
00462 
00463 
00464 //
00465 // getTpetraMultiVector
00466 //
00467 
00468 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, getTpetraMultiVector,
00469   Scalar )
00470 {
00471   typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT;
00472 
00473   const int numCols = 3;
00474   const RCP<const VectorSpaceBase<Scalar> > vs 
00475     = createTpetraVectorSpace<Scalar>(g_localDim);
00476 
00477   {
00478     const RCP<MultiVectorBase<Scalar> > mv = createMembers(vs, numCols);
00479     const RCP<Tpetra::MultiVector<Scalar,int> > tmv =
00480       ConverterT::getTpetraMultiVector(mv);
00481     TEST_ASSERT(nonnull(tmv));
00482     TEST_EQUALITY(as<Ordinal>(tmv->getMap()->getGlobalNumElements()), vs->dim());
00483   }
00484 
00485   {
00486     const RCP<VectorBase<Scalar> > v = createMember(vs);
00487     const RCP<Tpetra::MultiVector<Scalar,int> > tmv =
00488       ConverterT::getTpetraMultiVector(v);
00489     TEST_ASSERT(nonnull(tmv));
00490     TEST_EQUALITY(as<Ordinal>(tmv->getMap()->getGlobalNumElements()), vs->dim());
00491   }
00492 
00493 #ifdef THYRA_DEBUG
00494   const RCP<VectorBase<Scalar> > pv = Thyra::defaultProductVector<Scalar>();
00495   TEST_THROW(ConverterT::getTpetraMultiVector(pv), std::logic_error);
00496 #endif
00497 
00498 }
00499 
00500 
00501 //
00502 // getConstTpetraMultiVector
00503 //
00504 
00505 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, getConstTpetraMultiVector,
00506   Scalar )
00507 {
00508   typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT;
00509 
00510   const int numCols = 3;
00511   const RCP<const VectorSpaceBase<Scalar> > vs 
00512     = createTpetraVectorSpace<Scalar>(g_localDim);
00513 
00514   {
00515     const RCP<const MultiVectorBase<Scalar> > mv = createMembers(vs, numCols);
00516     const RCP<const Tpetra::MultiVector<Scalar,int> > tmv =
00517       ConverterT::getConstTpetraMultiVector(mv);
00518     TEST_ASSERT(nonnull(tmv));
00519     TEST_EQUALITY(as<Ordinal>(tmv->getMap()->getGlobalNumElements()), vs->dim());
00520   }
00521 
00522   {
00523     const RCP<const VectorBase<Scalar> > v = createMember(vs);
00524     const RCP<const Tpetra::MultiVector<Scalar,int> > tmv =
00525       ConverterT::getConstTpetraMultiVector(v);
00526     TEST_ASSERT(nonnull(tmv));
00527     TEST_EQUALITY(as<Ordinal>(tmv->getMap()->getGlobalNumElements()), vs->dim());
00528   }
00529 
00530 #ifdef THYRA_DEBUG
00531   const RCP<const VectorBase<Scalar> > pv = Thyra::defaultProductVector<Scalar>();
00532   TEST_THROW(ConverterT::getConstTpetraMultiVector(pv), std::logic_error);
00533 #endif
00534 
00535 }
00536 
00537 
00538 //
00539 // TpetraLinearOp
00540 //
00541 
00542 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, TpetraLinearOp,
00543   Scalar )
00544 {
00545 
00546   typedef Teuchos::ScalarTraits<Scalar> ST;
00547   using Teuchos::as;
00548 
00549   const RCP<Tpetra::Operator<Scalar,int> > tpetraOp =
00550     createTriDiagonalTpetraOperator<Scalar>(g_localDim);
00551   out << "tpetraOp = " << Teuchos::describe(*tpetraOp, Teuchos::VERB_HIGH) << std::endl;
00552   TEST_ASSERT(nonnull(tpetraOp));
00553 
00554   const RCP<const VectorSpaceBase<Scalar> > rangeSpace =
00555     Thyra::createVectorSpace<Scalar>(tpetraOp->getRangeMap());
00556   const RCP<const VectorSpaceBase<Scalar> > domainSpace =
00557     Thyra::createVectorSpace<Scalar>(tpetraOp->getDomainMap());
00558   const RCP<const LinearOpBase<Scalar> > thyraLinearOp =
00559     Thyra::tpetraLinearOp(rangeSpace, domainSpace, tpetraOp);
00560   TEST_ASSERT(nonnull(thyraLinearOp));
00561 
00562   out << "\nCheck that operator returns the right thing ...\n";
00563   const RCP<VectorBase<Scalar> > x = createMember(thyraLinearOp->domain());
00564   Thyra::V_S(x.ptr(), ST::one());
00565   const RCP<VectorBase<Scalar> > y = createMember(thyraLinearOp->range());
00566   Thyra::apply<Scalar>(*thyraLinearOp, Thyra::NOTRANS, *x, y.ptr());
00567   const Scalar sum_y = sum(*y);
00568   TEST_FLOATING_EQUALITY( sum_y, as<Scalar>(3+1+2*(y->space()->dim()-2)),
00569     100.0 * ST::eps() );
00570 
00571   out << "\nCheck the general LinearOp interface ...\n";
00572   Thyra::LinearOpTester<Scalar> linearOpTester;
00573   linearOpTester.show_all_tests(showAllTests);
00574   linearOpTester.dump_all(dumpAll);
00575   if (runLinearOpTester) {
00576     TEST_ASSERT(linearOpTester.check(*thyraLinearOp, Teuchos::inOutArg(out)));
00577   }
00578 
00579 }
00580 
00581 
00582 //
00583 // createLinearOp
00584 //
00585 
00586 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createLinearOp,
00587   Scalar )
00588 {
00589 
00590   typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT;
00591 
00592   const RCP<Tpetra::Operator<Scalar,int> > tpetraOp =
00593     createTriDiagonalTpetraOperator<Scalar>(g_localDim);
00594   out << "tpetraOp = " << Teuchos::describe(*tpetraOp, Teuchos::VERB_HIGH) << std::endl;
00595 
00596   const RCP<const VectorSpaceBase<Scalar> > rangeSpace =
00597     Thyra::createVectorSpace<Scalar>(tpetraOp->getRangeMap());
00598 
00599   const RCP<const VectorSpaceBase<Scalar> > domainSpace =
00600     Thyra::createVectorSpace<Scalar>(tpetraOp->getDomainMap());
00601 
00602   {
00603     const RCP<LinearOpBase<Scalar> > thyraOp =
00604       createLinearOp(tpetraOp, rangeSpace, domainSpace);
00605     TEST_EQUALITY(thyraOp->range(), rangeSpace);
00606     TEST_EQUALITY(thyraOp->domain(), domainSpace);
00607     const RCP<Tpetra::Operator<Scalar,int> > tpetraOp2 = 
00608       ConverterT::getTpetraOperator(thyraOp);
00609     TEST_EQUALITY(tpetraOp2, tpetraOp);
00610   }
00611 
00612   {
00613     const RCP<LinearOpBase<Scalar> > thyraOp =
00614       Thyra::createLinearOp(tpetraOp);
00615     TEST_INEQUALITY(thyraOp->range(), rangeSpace);
00616     TEST_INEQUALITY(thyraOp->domain(), domainSpace);
00617     TEST_ASSERT(thyraOp->range()->isCompatible(*rangeSpace));
00618     TEST_ASSERT(thyraOp->domain()->isCompatible(*domainSpace));
00619     const RCP<Tpetra::Operator<Scalar,int> > tpetraOp2 = 
00620       ConverterT::getTpetraOperator(thyraOp);
00621     TEST_EQUALITY(tpetraOp2, tpetraOp);
00622   }
00623 
00624 }
00625 
00626 
00627 //
00628 // createConstLinearOp
00629 //
00630 
00631 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, createConstLinearOp,
00632   Scalar )
00633 {
00634 
00635   typedef Thyra::TpetraOperatorVectorExtraction<Scalar,int> ConverterT;
00636 
00637   const RCP<const Tpetra::Operator<Scalar,int> > tpetraOp =
00638     createTriDiagonalTpetraOperator<Scalar>(g_localDim);
00639   out << "tpetraOp = " << Teuchos::describe(*tpetraOp, Teuchos::VERB_HIGH) << std::endl;
00640 
00641   const RCP<const VectorSpaceBase<Scalar> > rangeSpace =
00642     Thyra::createVectorSpace<Scalar>(tpetraOp->getRangeMap());
00643 
00644   const RCP<const VectorSpaceBase<Scalar> > domainSpace =
00645     Thyra::createVectorSpace<Scalar>(tpetraOp->getDomainMap());
00646 
00647   {
00648     const RCP<const LinearOpBase<Scalar> > thyraOp =
00649       createConstLinearOp(tpetraOp, rangeSpace, domainSpace);
00650     TEST_EQUALITY(thyraOp->range(), rangeSpace);
00651     TEST_EQUALITY(thyraOp->domain(), domainSpace);
00652     const RCP<const Tpetra::Operator<Scalar,int> > tpetraOp2 = 
00653       ConverterT::getConstTpetraOperator(thyraOp);
00654     TEST_EQUALITY(tpetraOp2, tpetraOp);
00655   }
00656 
00657   {
00658     const RCP<const LinearOpBase<Scalar> > thyraOp =
00659       Thyra::createConstLinearOp(tpetraOp);
00660     TEST_INEQUALITY(thyraOp->range(), rangeSpace);
00661     TEST_INEQUALITY(thyraOp->domain(), domainSpace);
00662     TEST_ASSERT(thyraOp->range()->isCompatible(*rangeSpace));
00663     TEST_ASSERT(thyraOp->domain()->isCompatible(*domainSpace));
00664     const RCP<const Tpetra::Operator<Scalar,int> > tpetraOp2 = 
00665       ConverterT::getConstTpetraOperator(thyraOp);
00666     TEST_EQUALITY(tpetraOp2, tpetraOp);
00667   }
00668 
00669 }
00670 
00671 
00672 //
00673 // TpetraLinearOp_EpetraRowMatrix
00674 //
00675 
00676 
00677 #ifdef HAVE_THYRA_TPETRA_EPETRA
00678 
00679 
00680 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, TpetraLinearOp_EpetraRowMatrix,
00681   Scalar )
00682 {
00683 
00684   using Teuchos::as;
00685   using Teuchos::outArg;
00686   using Teuchos::rcp_dynamic_cast;
00687   using Teuchos::Array;
00688   typedef Teuchos::ScalarTraits<Scalar> ST;
00689 
00690   const RCP<Tpetra::Operator<Scalar,int> > tpetraOp =
00691     createTriDiagonalTpetraOperator<Scalar>(g_localDim);
00692 
00693   const RCP<LinearOpBase<Scalar> > thyraOp =
00694     Thyra::createLinearOp(tpetraOp);
00695 
00696   const RCP<Thyra::TpetraLinearOp<Scalar, int> > thyraTpetraOp =
00697     Teuchos::rcp_dynamic_cast<Thyra::TpetraLinearOp<Scalar, int> >(thyraOp);
00698 
00699   RCP<const Epetra_Operator> epetraOp;
00700   Thyra::EOpTransp epetraOpTransp;
00701   Thyra::EApplyEpetraOpAs epetraOpApplyAs;
00702   Thyra::EAdjointEpetraOp epetraOpAdjointSupport;
00703 
00704   thyraTpetraOp->getEpetraOpView( outArg(epetraOp), outArg(epetraOpTransp),
00705     outArg(epetraOpApplyAs), outArg(epetraOpAdjointSupport) );
00706 
00707   if (typeid(Scalar) == typeid(double)) {
00708     TEST_ASSERT(nonnull(epetraOp));
00709     const RCP<const Epetra_RowMatrix> epetraRowMatrix =
00710       rcp_dynamic_cast<const Epetra_RowMatrix>(epetraOp, true);
00711     int numRowEntries = -1;
00712     epetraRowMatrix->NumMyRowEntries(1, numRowEntries);
00713     TEST_EQUALITY_CONST(numRowEntries, 3);
00714     Array<double> row_values(numRowEntries);
00715     Array<int> row_indices(numRowEntries);
00716     epetraRowMatrix->ExtractMyRowCopy(1, numRowEntries, numRowEntries,
00717       row_values.getRawPtr(), row_indices.getRawPtr());
00718     TEST_EQUALITY_CONST(row_values[0], -1.0);
00719     TEST_EQUALITY_CONST(row_values[1], 2.0);
00720     TEST_EQUALITY_CONST(row_values[2], 1.0);
00721     // ToDo: Test column indices!
00722   }
00723   else {
00724     TEST_ASSERT(is_null(epetraOp));
00725   }
00726 
00727 }
00728 
00729 #else
00730 
00731 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( TpetraThyraWrappers, TpetraLinearOp_EpetraRowMatrix,
00732   Scalar )
00733 {
00734 }
00735 
00736 #endif // HAVE_THYRA_TPETRA_EPETRA
00737 
00738 
00739 //
00740 // Unit test instantiations
00741 //
00742 
00743 #define THYRA_TPETRA_THYRA_WRAPPERS_INSTANT(SCALAR) \
00744  \
00745   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers,  \
00746     convertTpetraToThyraComm, SCALAR ) \
00747    \
00748   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \
00749     createVectorSpace, SCALAR ) \
00750    \
00751   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \
00752     createVector, SCALAR ) \
00753    \
00754   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \
00755     createConstVector, SCALAR ) \
00756    \
00757   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers,  \
00758     createMultiVector, SCALAR ) \
00759    \
00760   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \
00761     createConstMultiVector, SCALAR ) \
00762    \
00763   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \
00764     TeptraVectorSpace, SCALAR ) \
00765    \
00766   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \
00767     vectorSpaceTester, SCALAR ) \
00768    \
00769   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \
00770     getTpetraMultiVector, SCALAR ) \
00771    \
00772   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \
00773     getConstTpetraMultiVector, SCALAR ) \
00774    \
00775   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \
00776     TpetraLinearOp, SCALAR ) \
00777    \
00778   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \
00779     createLinearOp, SCALAR ) \
00780    \
00781   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \
00782     createConstLinearOp, SCALAR ) \
00783    \
00784   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( TpetraThyraWrappers, \
00785     TpetraLinearOp_EpetraRowMatrix, SCALAR ) \
00786   
00787 
00788 // We can currently only explicitly instantiate with double support because
00789 // Tpetra only supports explicit instantaition with double.  As for implicit
00790 // instantation, g++ 3.4.6 on my Linux machine was taking more than 30 minutes
00791 // to compile this file when all of the types double, float, complex<double>,
00792 // and complex<float> where enabled.  Therefore, we will only test double for
00793 // now until explicit instantation with other types are supported by Tpetra.
00794 
00795 THYRA_TPETRA_THYRA_WRAPPERS_INSTANT(double)
00796 
00797 
00798 } // namespace
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines