All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
Xpetra_StridedMap.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 //
00003 // ***********************************************************************
00004 //
00005 //             Xpetra: A linear algebra interface package
00006 //                  Copyright 2012 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
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
00039 //                    Jonathan Hu       (jhu@sandia.gov)
00040 //                    Andrey Prokopenko (aprokop@sandia.gov)
00041 //                    Ray Tuminaro      (rstumin@sandia.gov)
00042 //
00043 // ***********************************************************************
00044 //
00045 // @HEADER
00046 
00047 // WARNING: This code is experimental. Backwards compatibility should not be expected.
00048 
00049 #ifndef XPETRA_STRIDEDMAP_HPP
00050 #define XPETRA_STRIDEDMAP_HPP
00051 
00052 /* this file is automatically generated - do not edit (see script/interfaces.py) */
00053 
00054 #include <Kokkos_DefaultNode.hpp>
00055 
00056 #include <Teuchos_Describable.hpp>
00057 #include <Teuchos_OrdinalTraits.hpp>
00058 
00059 #include "Xpetra_ConfigDefs.hpp"
00060 #include "Xpetra_Exceptions.hpp"
00061 
00062 #include "Xpetra_Map.hpp"
00063 #include "Xpetra_MapFactory.hpp"
00064 
00065 namespace Xpetra {
00066 
00095   template <class LocalOrdinal = Map<>::local_ordinal_type,
00096             class GlobalOrdinal = typename Map<LocalOrdinal>::global_ordinal_type,
00097             class Node = typename Map<LocalOrdinal, GlobalOrdinal>::node_type>
00098   class StridedMap : public virtual Map<LocalOrdinal, GlobalOrdinal, Node> {
00099   public:
00100     typedef LocalOrdinal local_ordinal_type;
00101     typedef GlobalOrdinal global_ordinal_type;
00102     typedef Node node_type;
00103 
00104     static Teuchos::RCP<Node> defaultArgNode() {
00105         // Workaround function for a deferred visual studio bug
00106         // http://connect.microsoft.com/VisualStudio/feedback/details/719847/erroneous-error-c2783-could-not-deduce-template-argument
00107         // Use this function for default arguments rather than calling
00108         // what is the return value below.  Also helps in reducing
00109         // duplication in various constructors.
00110         return KokkosClassic::Details::getNode<Node>();
00111     }
00112 
00113   private:
00114 
00115   typedef Xpetra::MapFactory<LocalOrdinal, GlobalOrdinal, Node> MapFactory_t;
00116 #undef XPETRA_STRIDEDMAP_SHORT
00117 #include "Xpetra_UseShortNamesOrdinal.hpp"
00118 
00119   public:
00120 
00122 
00123 
00143     StridedMap (UnderlyingLib xlib,
00144                 global_size_t numGlobalElements,
00145                 GlobalOrdinal indexBase,
00146                 std::vector<size_t>& stridingInfo,
00147                 const Teuchos::RCP< const Teuchos::Comm< int > >& comm,
00148                 LocalOrdinal stridedBlockId = -1,  // FIXME (mfh 03 Sep 2014) This breaks for unsigned LocalOrdinal
00149                 GlobalOrdinal offset = 0,
00150                 LocalGlobal lg = GloballyDistributed,
00151                 const Teuchos::RCP< Node >& node = defaultArgNode())
00152       : stridingInfo_ (stridingInfo),
00153         stridedBlockId_ (stridedBlockId),
00154         offset_ (offset),
00155         indexBase_ (indexBase)
00156     {
00157       size_t blkSize = getFixedBlockSize ();
00158       TEUCHOS_TEST_FOR_EXCEPTION(
00159         stridingInfo.size() == 0, Exceptions::RuntimeError,
00160         "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?");
00161       TEUCHOS_TEST_FOR_EXCEPTION(
00162         numGlobalElements == Teuchos::OrdinalTraits<global_size_t>::invalid (),
00163         std::invalid_argument,
00164         "StridedMap::StridedMap: numGlobalElements is invalid");
00165       TEUCHOS_TEST_FOR_EXCEPTION(
00166         numGlobalElements % blkSize != 0, Exceptions::RuntimeError,
00167         "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize "
00168         "is not an integer multiple of numGlobalElements.");
00169       if (stridedBlockId != -1)
00170         TEUCHOS_TEST_FOR_EXCEPTION(
00171           stridingInfo.size() < static_cast<size_t> (stridedBlockId),
00172           Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: "
00173           "stridedBlockId > stridingInfo.size()");
00174 
00175       // Try to create a shortcut
00176       if (blkSize != 1 || offset_ != 0) {
00177         // check input data and reorganize map
00178         global_size_t numGlobalNodes = numGlobalElements / blkSize;
00179 
00180         // build an equally distributed node map
00181         RCP<Map> nodeMap = MapFactory_t::Build(xlib, numGlobalNodes, indexBase, comm, lg, node);
00182         global_size_t numLocalNodes = nodeMap->getNodeNumElements();
00183 
00184         // translate local node ids to local dofs
00185         size_t nStridedOffset = 0;
00186         size_t nDofsPerNode = blkSize; // dofs per node for local striding block
00187         if (stridedBlockId > -1) {
00188           for (int j = 0; j < stridedBlockId; j++)
00189             nStridedOffset += stridingInfo_[j];
00190 
00191           nDofsPerNode = stridingInfo_[stridedBlockId];
00192           numGlobalElements = numGlobalNodes * Teuchos::as<global_size_t>(nDofsPerNode);
00193         }
00194         size_t numLocalElements = numLocalNodes * Teuchos::as<size_t>(nDofsPerNode);
00195 
00196         std::vector<GlobalOrdinal> dofgids(numLocalElements);
00197         for (LocalOrdinal i = 0; i < Teuchos::as<LocalOrdinal>(numLocalNodes); i++) {
00198           GlobalOrdinal nodeGID = nodeMap->getGlobalElement(i);
00199 
00200           for (size_t j = 0; j < nDofsPerNode; j++)
00201             dofgids[i*nDofsPerNode + j] = indexBase_ + offset_ + (nodeGID - indexBase_)*Teuchos::as<GlobalOrdinal>(blkSize) + Teuchos::as<GlobalOrdinal>(nStridedOffset + j);
00202         }
00203 
00204         map_ = MapFactory_t::Build(xlib, numGlobalElements, dofgids, indexBase, comm, node);
00205 
00206         if (stridedBlockId == -1) {
00207           TEUCHOS_TEST_FOR_EXCEPTION(getNodeNumElements() != Teuchos::as<size_t>(nodeMap->getNodeNumElements()*nDofsPerNode), Exceptions::RuntimeError,
00208                                      "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
00209           TEUCHOS_TEST_FOR_EXCEPTION(getGlobalNumElements() != Teuchos::as<size_t>(nodeMap->getGlobalNumElements()*nDofsPerNode), Exceptions::RuntimeError,
00210                                      "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
00211 
00212         } else {
00213           size_t nDofsInStridedBlock = stridingInfo[stridedBlockId];
00214           TEUCHOS_TEST_FOR_EXCEPTION(getNodeNumElements() != Teuchos::as<size_t>(nodeMap->getNodeNumElements()*nDofsInStridedBlock), Exceptions::RuntimeError,
00215                                      "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
00216           TEUCHOS_TEST_FOR_EXCEPTION(getGlobalNumElements() != Teuchos::as<size_t>(nodeMap->getGlobalNumElements()*nDofsInStridedBlock), Exceptions::RuntimeError,
00217                                      "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
00218         }
00219       } else {
00220         map_ = MapFactory_t::Build(xlib, numGlobalElements, indexBase, comm, lg, node);
00221       }
00222 
00223       TEUCHOS_TEST_FOR_EXCEPTION(CheckConsistency() == false, Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: CheckConsistency() == false");
00224     }
00225 
00227 
00247     StridedMap(UnderlyingLib xlib, global_size_t numGlobalElements, size_t numLocalElements, GlobalOrdinal indexBase, std::vector<size_t>& stridingInfo,
00248                const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalOrdinal stridedBlockId = -1, GlobalOrdinal offset = 0,
00249                const Teuchos::RCP< Node > &node = defaultArgNode())
00250     : stridingInfo_(stridingInfo), stridedBlockId_(stridedBlockId), offset_(offset), indexBase_(indexBase)
00251     {
00252       size_t blkSize = getFixedBlockSize();
00253       TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() == 0, Exceptions::RuntimeError,
00254                                  "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?");
00255       if (numGlobalElements != Teuchos::OrdinalTraits<global_size_t>::invalid()) {
00256         TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % blkSize != 0, Exceptions::RuntimeError,
00257                                    "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of numGlobalElements.");
00258 #ifdef HAVE_TPETRA_DEBUG
00259         // We have to do this check ourselves, as we don't necessarily construct the full Tpetra map
00260         global_size_t sumLocalElements;
00261         Teuchos::reduceAll(*comm, Teuchos::REDUCE_SUM, Teuchos::as<global_size_t>(numLocalElements), Teuchos::outArg(sumLocalElements));
00262         TEUCHOS_TEST_FOR_EXCEPTION(sumLocalElements != numGlobalElements, std::invalid_argument,
00263                                    "StridedMap::StridedMap: sum of numbers of local elements is different from the provided number of global elements.");
00264 #endif
00265       }
00266       TEUCHOS_TEST_FOR_EXCEPTION(numLocalElements % blkSize != 0, Exceptions::RuntimeError,
00267                                  "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of numLocalElements.");
00268       if (stridedBlockId != -1)
00269         TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() < Teuchos::as<size_t>(stridedBlockId), Exceptions::RuntimeError,
00270                                    "StridedTpetraMap::StridedTpetraMap: stridedBlockId > stridingInfo.size()");
00271 
00272       // Try to create a shortcut
00273       if (blkSize != 1 || offset_ != 0) {
00274         // check input data and reorganize map
00275         global_size_t numGlobalNodes = Teuchos::OrdinalTraits<global_size_t>::invalid();
00276         if (numGlobalElements != Teuchos::OrdinalTraits<global_size_t>::invalid())
00277           numGlobalNodes = numGlobalElements / blkSize;
00278         global_size_t numLocalNodes = numLocalElements / blkSize;
00279 
00280         // build an equally distributed node map
00281         RCP<Map> nodeMap = MapFactory_t::Build(xlib, numGlobalNodes, numLocalNodes, indexBase, comm, node);
00282 
00283         // translate local node ids to local dofs
00284         size_t nStridedOffset = 0;
00285         size_t nDofsPerNode = blkSize; // dofs per node for local striding block
00286         if (stridedBlockId > -1) {
00287           for (int j = 0; j < stridedBlockId; j++)
00288             nStridedOffset += stridingInfo_[j];
00289 
00290           nDofsPerNode = stridingInfo_[stridedBlockId];
00291           numGlobalElements = nodeMap->getGlobalNumElements() * Teuchos::as<global_size_t>(nDofsPerNode);
00292         }
00293         numLocalElements = numLocalNodes * Teuchos::as<size_t>(nDofsPerNode);
00294 
00295         std::vector<GlobalOrdinal> dofgids(numLocalElements);
00296         for (LocalOrdinal i = 0; i < Teuchos::as<LocalOrdinal>(numLocalNodes); i++) {
00297           GlobalOrdinal nodeGID = nodeMap->getGlobalElement(i);
00298 
00299           for (size_t j = 0; j < nDofsPerNode; j++)
00300             dofgids[i*nDofsPerNode + j] = indexBase_ + offset_ + (nodeGID - indexBase_)*Teuchos::as<GlobalOrdinal>(blkSize) + Teuchos::as<GlobalOrdinal>(nStridedOffset + j);
00301         }
00302 
00303         map_ = MapFactory_t::Build(xlib, numGlobalElements, dofgids, indexBase, comm, node);
00304 
00305         if (stridedBlockId == -1) {
00306           TEUCHOS_TEST_FOR_EXCEPTION(getNodeNumElements() != Teuchos::as<size_t>(nodeMap->getNodeNumElements()*nDofsPerNode), Exceptions::RuntimeError,
00307                                      "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
00308           TEUCHOS_TEST_FOR_EXCEPTION(getGlobalNumElements() != Teuchos::as<size_t>(nodeMap->getGlobalNumElements()*nDofsPerNode), Exceptions::RuntimeError,
00309                                      "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
00310 
00311         } else {
00312           int nDofsInStridedBlock = stridingInfo[stridedBlockId];
00313           TEUCHOS_TEST_FOR_EXCEPTION(getNodeNumElements() != Teuchos::as<size_t>(nodeMap->getNodeNumElements()*nDofsInStridedBlock), Exceptions::RuntimeError,
00314                                      "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
00315           TEUCHOS_TEST_FOR_EXCEPTION(getGlobalNumElements() != Teuchos::as<size_t>(nodeMap->getGlobalNumElements()*nDofsInStridedBlock), Exceptions::RuntimeError,
00316                                      "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
00317         }
00318 
00319       } else {
00320         map_ = MapFactory_t::Build(xlib, numGlobalElements, numLocalElements, indexBase, comm, node);
00321       }
00322 
00323       TEUCHOS_TEST_FOR_EXCEPTION(CheckConsistency() == false, Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: CheckConsistency() == false");
00324     }
00325 
00336     StridedMap(UnderlyingLib xlib, global_size_t numGlobalElements, const Teuchos::ArrayView< const GlobalOrdinal > &elementList, GlobalOrdinal indexBase,
00337                std::vector<size_t>& stridingInfo, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalOrdinal stridedBlockId = -1,
00338                const Teuchos::RCP< Node > &node = defaultArgNode())
00339     : stridingInfo_(stridingInfo), stridedBlockId_(stridedBlockId), indexBase_(indexBase)
00340     {
00341       size_t blkSize = getFixedBlockSize();
00342 
00343       TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() == 0, Exceptions::RuntimeError,
00344                                  "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?");
00345       if (stridedBlockId != -1)
00346         TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() < Teuchos::as<size_t>(stridedBlockId), Exceptions::RuntimeError,
00347                                    "StridedTpetraMap::StridedTpetraMap: stridedBlockId > stridingInfo.size()");
00348       if (numGlobalElements != Teuchos::OrdinalTraits<global_size_t>::invalid()) {
00349         TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % blkSize != 0, Exceptions::RuntimeError,
00350                                    "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of numGlobalElements.");
00351 #ifdef HAVE_TPETRA_DEBUG
00352         // We have to do this check ourselves, as we don't necessarily construct the full Tpetra map
00353         global_size_t sumLocalElements, numLocalElements = elementList.size();
00354         Teuchos::reduceAll(*comm, Teuchos::REDUCE_SUM, numLocalElements, Teuchos::outArg(sumLocalElements));
00355         TEUCHOS_TEST_FOR_EXCEPTION(sumLocalElements != numGlobalElements, std::invalid_argument,
00356                                    "StridedMap::StridedMap: sum of numbers of local elements is different from the provided number of global elements.");
00357 #endif
00358       }
00359 
00360       if (stridedBlockId == -1) {
00361         // numGlobalElements can be -1! FIXME
00362         // TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements  % blkSize != 0, Exceptions::RuntimeError,
00363                                    // "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of numGlobalElements.");
00364         TEUCHOS_TEST_FOR_EXCEPTION(elementList.size() % blkSize != 0, Exceptions::RuntimeError,
00365                                    "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of elementList.size().");
00366 
00367       } else {
00368         // numGlobalElements can be -1! FIXME
00369         // TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements  % stridingInfo[stridedBlockId] != 0, Exceptions::RuntimeError,
00370                                    // "StridedMap::StridedMap: stridingInfo not valid: stridingBlockInfo[stridedBlockId] is not an integer multiple of numGlobalElements.");
00371         TEUCHOS_TEST_FOR_EXCEPTION(elementList.size() % stridingInfo[stridedBlockId] != 0, Exceptions::RuntimeError,
00372                                    "StridedMap::StridedMap: stridingInfo not valid: stridingBlockInfo[stridedBlockId] is not an integer multiple of elementList.size().");
00373       }
00374 
00375       map_ = MapFactory_t::Build(xlib, numGlobalElements, elementList, indexBase, comm, node);
00376 
00377       // calculate offset_
00378 
00379       // find minimum GID over all procs
00380       GlobalOrdinal minGidOnCurProc = Teuchos::OrdinalTraits<GlobalOrdinal>::max();
00381       for (Teuchos_Ordinal k = 0; k < elementList.size(); k++) // TODO fix occurence of Teuchos_Ordinal
00382         if (elementList[k] < minGidOnCurProc)
00383           minGidOnCurProc = elementList[k];
00384 
00385       Teuchos::reduceAll(*comm, Teuchos::REDUCE_MIN, minGidOnCurProc, Teuchos::outArg(offset_));
00386 
00387       // calculate striding index
00388       size_t nStridedOffset = 0;
00389       for (int j = 0; j < stridedBlockId; j++)
00390         nStridedOffset += stridingInfo[j];
00391       const GlobalOrdinal goStridedOffset = Teuchos::as<GlobalOrdinal>(nStridedOffset);
00392 
00393       // adapt offset_
00394       offset_ -= goStridedOffset + indexBase_;
00395 
00396       TEUCHOS_TEST_FOR_EXCEPTION(CheckConsistency() == false, Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: CheckConsistency() == false");
00397     }
00398 
00399     StridedMap(const RCP<const Map>& map, std::vector<size_t>& stridingInfo, GlobalOrdinal indexBase, LocalOrdinal stridedBlockId = -1, GlobalOrdinal offset = 0)
00400     : stridingInfo_(stridingInfo), stridedBlockId_(stridedBlockId), offset_(offset), indexBase_(map->getIndexBase())
00401     {
00402       map_ = map;
00403     }
00404 
00405 
00407     virtual ~StridedMap() { }
00408 
00410 
00412 
00413 
00414     std::vector<size_t> getStridingData() const             { return stridingInfo_; }
00415 
00416     void setStridingData(std::vector<size_t> stridingInfo)  { stridingInfo_ = stridingInfo; }
00417 
00418     size_t getFixedBlockSize() const {
00419       size_t blkSize = 0;
00420       for (std::vector<size_t>::const_iterator it = stridingInfo_.begin(); it != stridingInfo_.end(); ++it)
00421         blkSize += *it;
00422       return blkSize;
00423     }
00424 
00427     LocalOrdinal getStridedBlockId() const                  { return stridedBlockId_; }
00428 
00430     bool isStrided()                                        { return stridingInfo_.size() > 1 ? true : false; }
00431 
00434     bool isBlocked()                                        { return getFixedBlockSize() > 1 ? true : false; }
00435 
00436     GlobalOrdinal getOffset() const                         { return offset_; }
00437 
00438     void setOffset(GlobalOrdinal offset)                    { offset_ = offset; }
00439 
00440     // returns number of strided block id which gid belongs to.
00441     size_t GID2StridingBlockId(GlobalOrdinal gid) const {
00442       GlobalOrdinal tgid = gid - offset_ - indexBase_;
00443       tgid = tgid % getFixedBlockSize();
00444 
00445       size_t nStridedOffset = 0;
00446       size_t stridedBlockId = 0;
00447       for (size_t j = 0; j < stridingInfo_.size(); j++) {
00448         nStridedOffset += stridingInfo_[j];
00449         if (Teuchos::as<size_t>(tgid) < nStridedOffset) {
00450           stridedBlockId = j;
00451           break;
00452         }
00453       }
00454       return stridedBlockId;
00455     }
00456 
00458 
00459 
00460     RCP<const Map> getMap() const { return map_; }
00461 
00463 
00464     /* // function currently not needed but maybe useful
00465     std::vector<GlobalOrdinal> NodeId2GlobalDofIds(GlobalOrdinal nodeId) const {
00466       TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo_.size() == 0, Exceptions::RuntimeError, "StridedMap::NodeId2GlobalDofIds: stridingInfo not valid: stridingInfo.size() = 0?");
00467       std::vector<GlobalOrdinal> dofs;
00468       if(stridedBlockId_ > -1) {
00469           TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo_[stridedBlockId_] == 0, Exceptions::RuntimeError, "StridedMap::NodeId2GlobalDofIds: stridingInfo not valid: stridingInfo[stridedBlockId] = 0?");
00470 
00471           // determine nStridedOffset
00472           size_t nStridedOffset = 0;
00473           for(int j=0; j<stridedBlockId_; j++) {
00474             nStridedOffset += stridingInfo_[j];
00475           }
00476 
00477           for(size_t i = 0; i<stridingInfo_[stridedBlockId_]; i++) {
00478             GlobalOrdinal gid =
00479                 nodeId * Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) +
00480                 offset_ +
00481                 Teuchos::as<GlobalOrdinal>(nStridedOffset) +
00482                 Teuchos::as<GlobalOrdinal>(i);
00483             dofs.push_back(gid);
00484           }
00485       } else {
00486         for(size_t i = 0; i<getFixedBlockSize(); i++) {
00487           GlobalOrdinal gid =
00488               nodeId * Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) +
00489               offset_ +
00490               Teuchos::as<GlobalOrdinal>(i);
00491           dofs.push_back(gid);
00492         }
00493       }
00494       return dofs;
00495     }*/
00497 
00498   private:
00499     virtual bool CheckConsistency() {
00500 #ifndef HAVE_XPETRA_DEBUG
00501       return true;
00502 #else
00503       if (getStridedBlockId() == -1) {
00504         // Strided map contains the full map
00505         if (getNodeNumElements()   % getFixedBlockSize() != 0 ||    // number of local  elements is not a multiple of block size
00506             getGlobalNumElements() % getFixedBlockSize() != 0)      // number of global    -//-
00507           return false;
00508 
00509       } else {
00510         // Strided map contains only the partial map
00511         Teuchos::ArrayView<const GlobalOrdinal> dofGids = getNodeElementList();
00512         // std::sort(dofGids.begin(), dofGids.end());
00513 
00514         if (dofGids.size() == 0)  // special treatment for empty processors
00515           return true;
00516 
00517         if (dofGids.size() % stridingInfo_[stridedBlockId_] != 0)
00518           return false;
00519 
00520 
00521         // Calculate nStridedOffset
00522         size_t nStridedOffset = 0;
00523         for (int j = 0; j < stridedBlockId_; j++)
00524           nStridedOffset += stridingInfo_[j];
00525 
00526         const GlobalOrdinal goStridedOffset = Teuchos::as<GlobalOrdinal>(nStridedOffset);
00527         const GlobalOrdinal goZeroOffset    = (dofGids[0] - nStridedOffset - offset_ - indexBase_) / Teuchos::as<GlobalOrdinal>(getFixedBlockSize());
00528 
00529         GlobalOrdinal cnt = 0;
00530         for (size_t i = 0; i < Teuchos::as<size_t>(dofGids.size())/stridingInfo_[stridedBlockId_]; i += stridingInfo_[stridedBlockId_]) {
00531           const GlobalOrdinal first_gid = dofGids[i];
00532 
00533           // We expect this to be the same for all DOFs of the same node
00534           cnt = (first_gid - goStridedOffset - offset_ - indexBase_) / Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) - goZeroOffset;
00535 
00536           // Loop over all DOFs that belong to current node
00537           for (size_t j = 0; j < stridingInfo_[stridedBlockId_]; j++) {
00538             const GlobalOrdinal gid = dofGids[i+j];
00539             const GlobalOrdinal r   = (gid - Teuchos::as<GlobalOrdinal>(j) - goStridedOffset - offset_ - indexBase_) /
00540                                       Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) - goZeroOffset - cnt;
00541             if (r != Teuchos::OrdinalTraits<GlobalOrdinal>::zero() ) {
00542               std::cout << "goZeroOffset   : " <<  goZeroOffset << std::endl
00543                         << "dofGids[0]     : " <<  dofGids[0] << std::endl
00544                         << "stridedOffset  : " <<  nStridedOffset << std::endl
00545                         << "offset_        : " <<  offset_ << std::endl
00546                         << "goStridedOffset: " <<  goStridedOffset << std::endl
00547                         << "getFixedBlkSize: " <<  getFixedBlockSize() << std::endl
00548                         << "gid: " << gid << " GID: " << r << std::endl;
00549 
00550               return false;
00551             }
00552           }
00553         }
00554       }
00555 
00556       return true;
00557 #endif
00558     }
00559 
00560   private:
00561     RCP<const Map>      map_;
00562 
00563     std::vector<size_t> stridingInfo_;      
00564     LocalOrdinal        stridedBlockId_;    
00565                                             //     stridedBlock == -1: the full map (with all strided block dofs)
00566                                             //     stridedBlock  > -1: only dofs of strided block with index "stridedBlockId" are stored in this map
00567     GlobalOrdinal       offset_;                    
00568     GlobalOrdinal       indexBase_;         
00569 
00570   public:
00571 
00573 
00574 
00576     global_size_t getGlobalNumElements() const { return map_->getGlobalNumElements(); }
00577 
00579     size_t getNodeNumElements() const { return map_->getNodeNumElements(); }
00580 
00582     GlobalOrdinal getIndexBase() const { return map_->getIndexBase(); }
00583 
00585     LocalOrdinal getMinLocalIndex() const { return map_->getMinLocalIndex(); }
00586 
00588     LocalOrdinal getMaxLocalIndex() const { return map_->getMaxLocalIndex(); }
00589 
00591     GlobalOrdinal getMinGlobalIndex() const { return map_->getMinGlobalIndex(); }
00592 
00594     GlobalOrdinal getMaxGlobalIndex() const { return map_->getMaxGlobalIndex(); }
00595 
00597     GlobalOrdinal getMinAllGlobalIndex() const { return map_->getMinAllGlobalIndex(); }
00598 
00600     GlobalOrdinal getMaxAllGlobalIndex() const { return map_->getMaxAllGlobalIndex(); }
00601 
00603     LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const { return map_->getLocalElement(globalIndex); }
00604 
00606     GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const { return map_->getGlobalElement(localIndex); }
00607 
00609     LookupStatus getRemoteIndexList(const Teuchos::ArrayView<const GlobalOrdinal> &GIDList, const Teuchos::ArrayView<int> &nodeIDList, const Teuchos::ArrayView<LocalOrdinal> &LIDList) const {
00610       return map_->getRemoteIndexList(GIDList, nodeIDList, LIDList);
00611     }
00612 
00614     LookupStatus getRemoteIndexList(const Teuchos::ArrayView<const GlobalOrdinal> &GIDList, const Teuchos::ArrayView< int > &nodeIDList) const {
00615       return map_->getRemoteIndexList(GIDList, nodeIDList);
00616     }
00617 
00619     Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const { return map_->getNodeElementList(); }
00620 
00622     bool isNodeLocalElement(LocalOrdinal localIndex) const { return map_->isNodeLocalElement(localIndex); }
00623 
00625     bool isNodeGlobalElement(GlobalOrdinal globalIndex) const { return map_->isNodeGlobalElement(globalIndex); }
00626 
00628     bool isContiguous() const { return map_->isContiguous(); }
00629 
00631     bool isDistributed() const { return map_->isDistributed(); }
00632 
00634 
00636     bool isCompatible(const Map& map) const { return map_->isCompatible(map); }
00637 
00639     bool isSameAs(const Map& map) const { return map_->isSameAs(map); }
00640 
00642     Teuchos::RCP< const Teuchos::Comm< int > > getComm() const { return map_->getComm(); }
00643 
00645     Teuchos::RCP<Node>  getNode() const { return map_->getNode(); }
00646 
00647     RCP<const Map> removeEmptyProcesses  () const { return map_->removeEmptyProcesses(); }
00648     RCP<const Map> replaceCommWithSubset (const Teuchos::RCP<const Teuchos::Comm<int> >& newComm) const { return map_->replaceCommWithSubset(newComm); }
00649 
00651     std::string description() const { return map_->description(); }
00652 
00654     void describe(Teuchos::FancyOStream& out, const Teuchos::EVerbosityLevel verbLevel = Teuchos::Describable::verbLevel_default) const { map_->describe(out, verbLevel); }
00655 
00657     UnderlyingLib lib() const { return map_->lib(); }
00658 
00659   }; // StridedMap class
00660 
00661 } // Xpetra namespace
00662 
00663 #define XPETRA_STRIDEDMAP_SHORT
00664 #endif // XPETRA_STRIDEDMAP_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines