00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #ifndef XPETRA_STRIDEDTPETRAMAP_HPP
00050 #define XPETRA_STRIDEDTPETRAMAP_HPP
00051
00052 #include "Xpetra_TpetraConfigDefs.hpp"
00053
00054 #include <Tpetra_Map_decl.hpp>
00055
00056 #include "Xpetra_StridedMap.hpp"
00057 #include "Xpetra_TpetraMap.hpp"
00058
00059
00060
00061 namespace Xpetra {
00062
00063 template <class LocalOrdinal, class GlobalOrdinal = LocalOrdinal, class Node = Kokkos::DefaultNode::DefaultNodeType>
00064 class StridedTpetraMap
00065 : public virtual TpetraMap<LocalOrdinal,GlobalOrdinal,Node>, public virtual StridedMap<LocalOrdinal,GlobalOrdinal,Node> {
00066
00067 public:
00068
00070
00071
00091 StridedTpetraMap(global_size_t numGlobalElements, GlobalOrdinal indexBase, std::vector<size_t>& stridingInfo, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalOrdinal stridedBlockId=-1, GlobalOrdinal offset = 0, LocalGlobal lg=GloballyDistributed, const Teuchos::RCP< Node > &node=Kokkos::DefaultNode::getDefaultNode())
00092 : Xpetra::TpetraMap<LocalOrdinal,GlobalOrdinal,Node>(numGlobalElements, indexBase, comm, lg, node), Xpetra::StridedMap<LocalOrdinal,GlobalOrdinal,Node>(numGlobalElements, indexBase, stridingInfo, comm, stridedBlockId, offset)
00093 {
00094 typedef Xpetra::StridedMap<LocalOrdinal,GlobalOrdinal,Node> StridedMapClass;
00095
00096
00097 global_size_t numGlobalNodes = Teuchos::OrdinalTraits<global_size_t>::invalid();
00098 if(numGlobalElements != Teuchos::OrdinalTraits<global_size_t>::invalid())
00099 numGlobalNodes = numGlobalElements / StridedMapClass::getFixedBlockSize();
00100
00101
00102 RCP<Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > nodeMap = Teuchos::rcp(new Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node >(numGlobalNodes, indexBase, comm, toTpetra(lg), node));
00103
00104
00105 size_t nStridedOffset = 0;
00106 size_t nDofsPerNode = StridedMapClass::getFixedBlockSize();
00107 if(stridedBlockId > -1) {
00108
00109 for(int j=0; j<stridedBlockId; j++) {
00110 nStridedOffset += stridingInfo[j];
00111 }
00112 nDofsPerNode = stridingInfo[stridedBlockId];
00113
00114 numGlobalElements = nodeMap->getGlobalNumElements()*Teuchos::as<global_size_t>(nDofsPerNode);
00115 }
00116 std::vector<GlobalOrdinal> dofgids;
00117 for(LocalOrdinal i = 0; i<Teuchos::as<LocalOrdinal>(nodeMap->getNodeNumElements()); i++) {
00118 GlobalOrdinal gid = nodeMap->getGlobalElement(i);
00119 for(size_t dof = 0; dof < nDofsPerNode; ++dof) {
00120
00121
00122 dofgids.push_back(StridedMapClass::offset_ + gid*Teuchos::as<GlobalOrdinal>(StridedMapClass::getFixedBlockSize()) + Teuchos::as<GlobalOrdinal>(nStridedOffset + dof));
00123 }
00124 }
00125
00126 const Teuchos::ArrayView<const GlobalOrdinal> dofgidsview = Teuchos::ArrayView<const GlobalOrdinal>(dofgids);
00127 TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::map_ = Teuchos::rcp(new Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node >(numGlobalElements, dofgidsview, indexBase, comm, node));
00128
00129
00130 if(stridedBlockId == -1) {
00131 TEUCHOS_TEST_FOR_EXCEPTION(getNodeNumElements() != Teuchos::as<size_t>(nodeMap->getNodeNumElements()*nDofsPerNode), Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
00132 TEUCHOS_TEST_FOR_EXCEPTION(getGlobalNumElements() != Teuchos::as<size_t>(nodeMap->getGlobalNumElements()*nDofsPerNode), Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
00133 } else {
00134 TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() < Teuchos::as<size_t>(stridedBlockId), Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: stridedBlockId > stridingInfo.size()");
00135 int nDofsInStridedBlock = stridingInfo[stridedBlockId];
00136 TEUCHOS_TEST_FOR_EXCEPTION(getNodeNumElements() != Teuchos::as<size_t>(nodeMap->getNodeNumElements()*nDofsInStridedBlock), Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
00137 TEUCHOS_TEST_FOR_EXCEPTION(getGlobalNumElements() != Teuchos::as<size_t>(nodeMap->getGlobalNumElements()*nDofsInStridedBlock), Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
00138 }
00139
00140 TEUCHOS_TEST_FOR_EXCEPTION(CheckConsistency() == false, Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: CheckConsistency() == false");
00141 }
00142
00144
00164 StridedTpetraMap(global_size_t numGlobalElements, size_t numLocalElements, GlobalOrdinal indexBase, std::vector<size_t>& stridingInfo, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalOrdinal stridedBlockId=-1, GlobalOrdinal offset = 0, const Teuchos::RCP< Node > &node=Kokkos::DefaultNode::getDefaultNode())
00165 : Xpetra::TpetraMap<LocalOrdinal,GlobalOrdinal,Node>(numGlobalElements, numLocalElements, indexBase, comm, node), Xpetra::StridedMap<LocalOrdinal,GlobalOrdinal,Node>(numGlobalElements, numLocalElements, indexBase, stridingInfo, comm, stridedBlockId, offset)
00166 {
00167 typedef Xpetra::StridedMap<LocalOrdinal,GlobalOrdinal,Node> StridedMapClass;
00168
00169
00170 global_size_t numGlobalNodes = Teuchos::OrdinalTraits<global_size_t>::invalid();
00171 if(numGlobalElements != Teuchos::OrdinalTraits<global_size_t>::invalid())
00172 numGlobalNodes = numGlobalElements / StridedMapClass::getFixedBlockSize();
00173 global_size_t numLocalNodes = numLocalElements / StridedMapClass::getFixedBlockSize();
00174
00175
00176 RCP<Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > nodeMap = Teuchos::rcp(new Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node >(numGlobalNodes, numLocalNodes, indexBase, comm, node));
00177
00178
00179 size_t nStridedOffset = 0;
00180 size_t nDofsPerNode = StridedMapClass::getFixedBlockSize();
00181 if(stridedBlockId > -1) {
00182
00183 for(int j=0; j<stridedBlockId; j++) {
00184 nStridedOffset += stridingInfo[j];
00185 }
00186 nDofsPerNode = stridingInfo[stridedBlockId];
00187
00188 numGlobalElements = nodeMap->getGlobalNumElements()*Teuchos::as<global_size_t>(nDofsPerNode);
00189 }
00190 std::vector<GlobalOrdinal> dofgids;
00191 for(LocalOrdinal i = 0; i<Teuchos::as<LocalOrdinal>(nodeMap->getNodeNumElements()); i++) {
00192 GlobalOrdinal gid = nodeMap->getGlobalElement(i);
00193 for(size_t dof = 0; dof < nDofsPerNode; ++dof) {
00194
00195
00196 dofgids.push_back(StridedMapClass::offset_ + gid*Teuchos::as<GlobalOrdinal>(StridedMapClass::getFixedBlockSize()) + Teuchos::as<GlobalOrdinal>(nStridedOffset + dof));
00197 }
00198 }
00199
00200 const Teuchos::ArrayView<const GlobalOrdinal> dofgidsview = Teuchos::ArrayView<const GlobalOrdinal>(dofgids);
00201 TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::map_ = Teuchos::rcp(new Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node >(numGlobalElements, dofgidsview, indexBase, comm, node));
00202
00203
00204 if(stridedBlockId == -1) {
00205 TEUCHOS_TEST_FOR_EXCEPTION(getNodeNumElements() != Teuchos::as<size_t>(nodeMap->getNodeNumElements()*nDofsPerNode), Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
00206 TEUCHOS_TEST_FOR_EXCEPTION(getGlobalNumElements() != Teuchos::as<size_t>(nodeMap->getGlobalNumElements()*nDofsPerNode), Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
00207 } else {
00208 TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() < Teuchos::as<size_t>(stridedBlockId), Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: stridedBlockId > stridingInfo.size()");
00209 int nDofsInStridedBlock = stridingInfo[stridedBlockId];
00210 TEUCHOS_TEST_FOR_EXCEPTION(getNodeNumElements() != Teuchos::as<size_t>(nodeMap->getNodeNumElements()*nDofsInStridedBlock), Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
00211 TEUCHOS_TEST_FOR_EXCEPTION(getGlobalNumElements() != Teuchos::as<size_t>(nodeMap->getGlobalNumElements()*nDofsInStridedBlock), Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
00212 }
00213
00214 TEUCHOS_TEST_FOR_EXCEPTION(CheckConsistency() == false, Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: CheckConsistency() == false");
00215
00216 }
00217
00228 StridedTpetraMap(global_size_t numGlobalElements, const Teuchos::ArrayView< const GlobalOrdinal > &elementList, GlobalOrdinal indexBase, std::vector<size_t>& stridingInfo, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalOrdinal stridedBlockId=-1, const Teuchos::RCP< Node > &node=Kokkos::DefaultNode::getDefaultNode())
00229 : Xpetra::TpetraMap<LocalOrdinal,GlobalOrdinal,Node>(numGlobalElements, elementList, indexBase, comm, node), Xpetra::StridedMap<LocalOrdinal,GlobalOrdinal,Node>(numGlobalElements, elementList, indexBase, stridingInfo, comm, stridedBlockId)
00230 {
00231 typedef Xpetra::StridedMap<LocalOrdinal,GlobalOrdinal,Node> StridedMapClass;
00232
00233 if(stridedBlockId != -1) {
00234 TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() < Teuchos::as<size_t>(stridedBlockId), Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: stridedBlockId > stridingInfo.size()");
00235 }
00236
00237
00238 TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::map_ = Teuchos::rcp(new Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node >(numGlobalElements, elementList, indexBase, comm, node));
00239
00240
00241 TEUCHOS_TEST_FOR_EXCEPTION(CheckConsistency() == false, Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: CheckConsistency() == false");
00242 }
00243
00245 ~StridedTpetraMap() { }
00246
00248
00250
00251
00253 global_size_t getGlobalNumElements() const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::getGlobalNumElements(); }
00254
00256 size_t getNodeNumElements() const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::getNodeNumElements(); }
00257
00259 GlobalOrdinal getIndexBase() const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::getIndexBase(); }
00260
00262 LocalOrdinal getMinLocalIndex() const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::getMinLocalIndex(); }
00263
00265 LocalOrdinal getMaxLocalIndex() const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::getMaxLocalIndex(); }
00266
00268 GlobalOrdinal getMinGlobalIndex() const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::getMinGlobalIndex(); }
00269
00271 GlobalOrdinal getMaxGlobalIndex() const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::getMaxGlobalIndex(); }
00272
00274 GlobalOrdinal getMinAllGlobalIndex() const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::getMinAllGlobalIndex(); }
00275
00277 GlobalOrdinal getMaxAllGlobalIndex() const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::getMaxAllGlobalIndex(); }
00278
00280 LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::getLocalElement(globalIndex); }
00281
00283 GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::getGlobalElement(localIndex); }
00284
00286 LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList, const Teuchos::ArrayView< LocalOrdinal > &LIDList) const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::getRemoteIndexList(GIDList, nodeIDList, LIDList); }
00287
00289 LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList) const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::getRemoteIndexList(GIDList, nodeIDList); }
00290
00292 Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::getNodeElementList(); }
00293
00295 bool isNodeLocalElement(LocalOrdinal localIndex) const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::isNodeLocalElement(localIndex); }
00296
00298 bool isNodeGlobalElement(GlobalOrdinal globalIndex) const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::isNodeGlobalElement(globalIndex); }
00299
00301 bool isContiguous() const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::isContiguous(); }
00302
00304 bool isDistributed() const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::isDistributed(); }
00305
00307
00309
00310
00312 bool isCompatible(const Map< LocalOrdinal, GlobalOrdinal, Node > &map) const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::isCompatible(map); }
00313
00315 bool isSameAs(const Map< LocalOrdinal, GlobalOrdinal, Node > &map) const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::isSameAs(map); }
00316
00318
00320
00321
00323 const Teuchos::RCP< const Teuchos::Comm< int > > getComm() const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::getComm(); }
00324
00326 const Teuchos::RCP< Node > getNode() const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::getNode(); }
00327
00329
00331
00332
00334 std::string description() const { return TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::description(); }
00335
00337 void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const { TpetraMap<LocalOrdinal,GlobalOrdinal,Node>::describe(out, verbLevel); }
00338
00340
00342
00343
00345 StridedTpetraMap(const Teuchos::RCP<const Tpetra::Map<LocalOrdinal, GlobalOrdinal, Node > > &map, std::vector<size_t>& stridingInfo, LocalOrdinal stridedBlockId=-1, GlobalOrdinal offset = 0)
00346 : Xpetra::TpetraMap<LocalOrdinal,GlobalOrdinal,Node>(map), Xpetra::StridedMap<LocalOrdinal,GlobalOrdinal,Node>(stridingInfo, stridedBlockId, offset) {
00347 typedef Xpetra::StridedMap<LocalOrdinal,GlobalOrdinal,Node> StridedMapClass;
00348
00349
00350 TEUCHOS_TEST_FOR_EXCEPTION(CheckConsistency() == false, Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: CheckConsistency() == false");
00351 }
00352
00354 UnderlyingLib lib() const { return Xpetra::UseTpetra; }
00355
00356
00357
00358
00360
00361 private:
00362 bool CheckConsistency() {
00363 typedef Xpetra::StridedMap<LocalOrdinal,GlobalOrdinal,Node> StridedMapClass;
00364
00365 if(StridedMapClass::getStridedBlockId() == -1) {
00366
00367 if(getNodeNumElements() % StridedMapClass::getFixedBlockSize() != 0) return false;
00368 if(getGlobalNumElements() % StridedMapClass::getFixedBlockSize() != 0) return false;
00369 }
00370 else {
00371 Teuchos::ArrayView< const GlobalOrdinal > dofGids = getNodeElementList();
00372
00373
00374
00375 size_t nStridedOffset = 0;
00376 for(int j=0; j<StridedMapClass::stridedBlockId_; j++) {
00377 nStridedOffset += StridedMapClass::stridingInfo_[j];
00378 }
00379
00380
00381 const GlobalOrdinal goStridedOffset = Teuchos::as<GlobalOrdinal>(nStridedOffset);
00382 const GlobalOrdinal goZeroOffset = (dofGids[0] - nStridedOffset - StridedMapClass::offset_) / Teuchos::as<GlobalOrdinal>(StridedMapClass::getFixedBlockSize());
00383
00384 GlobalOrdinal cnt = 0;
00385 for(size_t i = 0; i<Teuchos::as<size_t>(dofGids.size())/StridedMapClass::stridingInfo_[StridedMapClass::stridedBlockId_]; i+=StridedMapClass::stridingInfo_[StridedMapClass::stridedBlockId_]) {
00386
00387 for(size_t j=0; j<StridedMapClass::stridingInfo_[StridedMapClass::stridedBlockId_]; j++) {
00388 const GlobalOrdinal gid = dofGids[i+j];
00389 if((gid - Teuchos::as<GlobalOrdinal>(j) - goStridedOffset - StridedMapClass::offset_) / Teuchos::as<GlobalOrdinal>(StridedMapClass::getFixedBlockSize()) - goZeroOffset - cnt != 0) {
00390
00391 return false;
00392 }
00393 }
00394 cnt++;
00395 }
00396 }
00397
00398 return true;
00399 }
00400
00401 };
00402
00403
00404 }
00405
00406 #define XPETRA_STRIDEDTPETRAMAP_SHORT
00407 #endif // XPETRA_STRIDEDTPETRAMAP_HPP