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 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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines