Thyra Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
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 "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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines