Xpetra_StridedMap.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // Xpetra: A linear algebra interface package
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact
39 // Jonathan Hu (jhu@sandia.gov)
40 // Andrey Prokopenko (aprokop@sandia.gov)
41 // Ray Tuminaro (rstumin@sandia.gov)
42 //
43 // ***********************************************************************
44 //
45 // @HEADER
46 
47 // WARNING: This code is experimental. Backwards compatibility should not be expected.
48 
49 #ifndef XPETRA_STRIDEDMAP_HPP
50 #define XPETRA_STRIDEDMAP_HPP
51 
52 /* this file is automatically generated - do not edit (see script/interfaces.py) */
53 
54 #include <Kokkos_DefaultNode.hpp>
55 
56 #include <Teuchos_Describable.hpp>
58 
59 #include "Xpetra_ConfigDefs.hpp"
60 #include "Xpetra_Exceptions.hpp"
61 
62 #include "Xpetra_Map.hpp"
63 #include "Xpetra_MapFactory.hpp"
64 
65 namespace Xpetra {
66 
95  template <class LocalOrdinal = Map<>::local_ordinal_type,
96  class GlobalOrdinal = typename Map<LocalOrdinal>::global_ordinal_type,
97  class Node = typename Map<LocalOrdinal, GlobalOrdinal>::node_type>
98  class StridedMap : public virtual Map<LocalOrdinal, GlobalOrdinal, Node> {
99  public:
100  typedef LocalOrdinal local_ordinal_type;
101  typedef GlobalOrdinal global_ordinal_type;
102  typedef Node node_type;
103 
105  // Workaround function for a deferred visual studio bug
106  // http://connect.microsoft.com/VisualStudio/feedback/details/719847/erroneous-error-c2783-could-not-deduce-template-argument
107  // Use this function for default arguments rather than calling
108  // what is the return value below. Also helps in reducing
109  // duplication in various constructors.
110  return KokkosClassic::Details::getNode<Node>();
111  }
112 
113  private:
114 
116 #undef XPETRA_STRIDEDMAP_SHORT
118 
119  public:
120 
122 
123 
144  global_size_t numGlobalElements,
145  GlobalOrdinal indexBase,
146  std::vector<size_t>& stridingInfo,
147  const Teuchos::RCP< const Teuchos::Comm< int > >& comm,
148  LocalOrdinal stridedBlockId = -1, // FIXME (mfh 03 Sep 2014) This breaks for unsigned LocalOrdinal
149  GlobalOrdinal offset = 0,
151  const Teuchos::RCP< Node >& node = defaultArgNode())
152  : stridingInfo_ (stridingInfo),
153  stridedBlockId_ (stridedBlockId),
154  offset_ (offset),
155  indexBase_ (indexBase)
156  {
157  size_t blkSize = getFixedBlockSize ();
159  stridingInfo.size() == 0, Exceptions::RuntimeError,
160  "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?");
162  numGlobalElements == Teuchos::OrdinalTraits<global_size_t>::invalid (),
163  std::invalid_argument,
164  "StridedMap::StridedMap: numGlobalElements is invalid");
165  TEUCHOS_TEST_FOR_EXCEPTION(
166  numGlobalElements % blkSize != 0, Exceptions::RuntimeError,
167  "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize "
168  "is not an integer multiple of numGlobalElements.");
169  if (stridedBlockId != -1)
170  TEUCHOS_TEST_FOR_EXCEPTION(
171  stridingInfo.size() < static_cast<size_t> (stridedBlockId),
172  Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: "
173  "stridedBlockId > stridingInfo.size()");
174 
175  // Try to create a shortcut
176  if (blkSize != 1 || offset_ != 0) {
177  // check input data and reorganize map
178  global_size_t numGlobalNodes = numGlobalElements / blkSize;
179 
180  // build an equally distributed node map
181  RCP<Map> nodeMap = MapFactory_t::Build(xlib, numGlobalNodes, indexBase, comm, lg, node);
182  global_size_t numLocalNodes = nodeMap->getNodeNumElements();
183 
184  // translate local node ids to local dofs
185  size_t nStridedOffset = 0;
186  size_t nDofsPerNode = blkSize; // dofs per node for local striding block
187  if (stridedBlockId > -1) {
188  for (int j = 0; j < stridedBlockId; j++)
189  nStridedOffset += stridingInfo_[j];
190 
191  nDofsPerNode = stridingInfo_[stridedBlockId];
192  numGlobalElements = numGlobalNodes * Teuchos::as<global_size_t>(nDofsPerNode);
193  }
194  size_t numLocalElements = numLocalNodes * Teuchos::as<size_t>(nDofsPerNode);
195 
196  std::vector<GlobalOrdinal> dofgids(numLocalElements);
197  for (LocalOrdinal i = 0; i < Teuchos::as<LocalOrdinal>(numLocalNodes); i++) {
198  GlobalOrdinal nodeGID = nodeMap->getGlobalElement(i);
199 
200  for (size_t j = 0; j < nDofsPerNode; j++)
201  dofgids[i*nDofsPerNode + j] = indexBase_ + offset_ + (nodeGID - indexBase_)*Teuchos::as<GlobalOrdinal>(blkSize) + Teuchos::as<GlobalOrdinal>(nStridedOffset + j);
202  }
203 
204  map_ = MapFactory_t::Build(xlib, numGlobalElements, dofgids, indexBase, comm, node);
205 
206  if (stridedBlockId == -1) {
207  TEUCHOS_TEST_FOR_EXCEPTION(getNodeNumElements() != Teuchos::as<size_t>(nodeMap->getNodeNumElements()*nDofsPerNode), Exceptions::RuntimeError,
208  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
209  TEUCHOS_TEST_FOR_EXCEPTION(getGlobalNumElements() != Teuchos::as<size_t>(nodeMap->getGlobalNumElements()*nDofsPerNode), Exceptions::RuntimeError,
210  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
211 
212  } else {
213  size_t nDofsInStridedBlock = stridingInfo[stridedBlockId];
214  TEUCHOS_TEST_FOR_EXCEPTION(getNodeNumElements() != Teuchos::as<size_t>(nodeMap->getNodeNumElements()*nDofsInStridedBlock), Exceptions::RuntimeError,
215  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
216  TEUCHOS_TEST_FOR_EXCEPTION(getGlobalNumElements() != Teuchos::as<size_t>(nodeMap->getGlobalNumElements()*nDofsInStridedBlock), Exceptions::RuntimeError,
217  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
218  }
219  } else {
220  map_ = MapFactory_t::Build(xlib, numGlobalElements, indexBase, comm, lg, node);
221  }
222 
223  TEUCHOS_TEST_FOR_EXCEPTION(CheckConsistency() == false, Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: CheckConsistency() == false");
224  }
225 
227 
247  StridedMap(UnderlyingLib xlib, global_size_t numGlobalElements, size_t numLocalElements, GlobalOrdinal indexBase, std::vector<size_t>& stridingInfo,
248  const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalOrdinal stridedBlockId = -1, GlobalOrdinal offset = 0,
249  const Teuchos::RCP< Node > &node = defaultArgNode())
250  : stridingInfo_(stridingInfo), stridedBlockId_(stridedBlockId), offset_(offset), indexBase_(indexBase)
251  {
252  size_t blkSize = getFixedBlockSize();
253  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() == 0, Exceptions::RuntimeError,
254  "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?");
255  if (numGlobalElements != Teuchos::OrdinalTraits<global_size_t>::invalid()) {
256  TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % blkSize != 0, Exceptions::RuntimeError,
257  "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of numGlobalElements.");
258 #ifdef HAVE_TPETRA_DEBUG
259  // We have to do this check ourselves, as we don't necessarily construct the full Tpetra map
260  global_size_t sumLocalElements;
261  Teuchos::reduceAll(*comm, Teuchos::REDUCE_SUM, Teuchos::as<global_size_t>(numLocalElements), Teuchos::outArg(sumLocalElements));
262  TEUCHOS_TEST_FOR_EXCEPTION(sumLocalElements != numGlobalElements, std::invalid_argument,
263  "StridedMap::StridedMap: sum of numbers of local elements is different from the provided number of global elements.");
264 #endif
265  }
266  TEUCHOS_TEST_FOR_EXCEPTION(numLocalElements % blkSize != 0, Exceptions::RuntimeError,
267  "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of numLocalElements.");
268  if (stridedBlockId != -1)
269  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() < Teuchos::as<size_t>(stridedBlockId), Exceptions::RuntimeError,
270  "StridedTpetraMap::StridedTpetraMap: stridedBlockId > stridingInfo.size()");
271 
272  // Try to create a shortcut
273  if (blkSize != 1 || offset_ != 0) {
274  // check input data and reorganize map
276  if (numGlobalElements != Teuchos::OrdinalTraits<global_size_t>::invalid())
277  numGlobalNodes = numGlobalElements / blkSize;
278  global_size_t numLocalNodes = numLocalElements / blkSize;
279 
280  // build an equally distributed node map
281  RCP<Map> nodeMap = MapFactory_t::Build(xlib, numGlobalNodes, numLocalNodes, indexBase, comm, node);
282 
283  // translate local node ids to local dofs
284  size_t nStridedOffset = 0;
285  size_t nDofsPerNode = blkSize; // dofs per node for local striding block
286  if (stridedBlockId > -1) {
287  for (int j = 0; j < stridedBlockId; j++)
288  nStridedOffset += stridingInfo_[j];
289 
290  nDofsPerNode = stridingInfo_[stridedBlockId];
291  numGlobalElements = nodeMap->getGlobalNumElements() * Teuchos::as<global_size_t>(nDofsPerNode);
292  }
293  numLocalElements = numLocalNodes * Teuchos::as<size_t>(nDofsPerNode);
294 
295  std::vector<GlobalOrdinal> dofgids(numLocalElements);
296  for (LocalOrdinal i = 0; i < Teuchos::as<LocalOrdinal>(numLocalNodes); i++) {
297  GlobalOrdinal nodeGID = nodeMap->getGlobalElement(i);
298 
299  for (size_t j = 0; j < nDofsPerNode; j++)
300  dofgids[i*nDofsPerNode + j] = indexBase_ + offset_ + (nodeGID - indexBase_)*Teuchos::as<GlobalOrdinal>(blkSize) + Teuchos::as<GlobalOrdinal>(nStridedOffset + j);
301  }
302 
303  map_ = MapFactory_t::Build(xlib, numGlobalElements, dofgids, indexBase, comm, node);
304 
305  if (stridedBlockId == -1) {
306  TEUCHOS_TEST_FOR_EXCEPTION(getNodeNumElements() != Teuchos::as<size_t>(nodeMap->getNodeNumElements()*nDofsPerNode), Exceptions::RuntimeError,
307  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
308  TEUCHOS_TEST_FOR_EXCEPTION(getGlobalNumElements() != Teuchos::as<size_t>(nodeMap->getGlobalNumElements()*nDofsPerNode), Exceptions::RuntimeError,
309  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
310 
311  } else {
312  int nDofsInStridedBlock = stridingInfo[stridedBlockId];
313  TEUCHOS_TEST_FOR_EXCEPTION(getNodeNumElements() != Teuchos::as<size_t>(nodeMap->getNodeNumElements()*nDofsInStridedBlock), Exceptions::RuntimeError,
314  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
315  TEUCHOS_TEST_FOR_EXCEPTION(getGlobalNumElements() != Teuchos::as<size_t>(nodeMap->getGlobalNumElements()*nDofsInStridedBlock), Exceptions::RuntimeError,
316  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
317  }
318 
319  } else {
320  map_ = MapFactory_t::Build(xlib, numGlobalElements, numLocalElements, indexBase, comm, node);
321  }
322 
323  TEUCHOS_TEST_FOR_EXCEPTION(CheckConsistency() == false, Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: CheckConsistency() == false");
324  }
325 
336  StridedMap(UnderlyingLib xlib, global_size_t numGlobalElements, const Teuchos::ArrayView< const GlobalOrdinal > &elementList, GlobalOrdinal indexBase,
337  std::vector<size_t>& stridingInfo, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalOrdinal stridedBlockId = -1,
338  const Teuchos::RCP< Node > &node = defaultArgNode())
339  : stridingInfo_(stridingInfo), stridedBlockId_(stridedBlockId), indexBase_(indexBase)
340  {
341  size_t blkSize = getFixedBlockSize();
342 
343  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() == 0, Exceptions::RuntimeError,
344  "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?");
345  if (stridedBlockId != -1)
346  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() < Teuchos::as<size_t>(stridedBlockId), Exceptions::RuntimeError,
347  "StridedTpetraMap::StridedTpetraMap: stridedBlockId > stridingInfo.size()");
348  if (numGlobalElements != Teuchos::OrdinalTraits<global_size_t>::invalid()) {
349  TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % blkSize != 0, Exceptions::RuntimeError,
350  "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of numGlobalElements.");
351 #ifdef HAVE_TPETRA_DEBUG
352  // We have to do this check ourselves, as we don't necessarily construct the full Tpetra map
353  global_size_t sumLocalElements, numLocalElements = elementList.size();
354  Teuchos::reduceAll(*comm, Teuchos::REDUCE_SUM, numLocalElements, Teuchos::outArg(sumLocalElements));
355  TEUCHOS_TEST_FOR_EXCEPTION(sumLocalElements != numGlobalElements, std::invalid_argument,
356  "StridedMap::StridedMap: sum of numbers of local elements is different from the provided number of global elements.");
357 #endif
358  }
359 
360  if (stridedBlockId == -1) {
361  // numGlobalElements can be -1! FIXME
362  // TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % blkSize != 0, Exceptions::RuntimeError,
363  // "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of numGlobalElements.");
364  TEUCHOS_TEST_FOR_EXCEPTION(elementList.size() % blkSize != 0, Exceptions::RuntimeError,
365  "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of elementList.size().");
366 
367  } else {
368  // numGlobalElements can be -1! FIXME
369  // TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % stridingInfo[stridedBlockId] != 0, Exceptions::RuntimeError,
370  // "StridedMap::StridedMap: stridingInfo not valid: stridingBlockInfo[stridedBlockId] is not an integer multiple of numGlobalElements.");
371  TEUCHOS_TEST_FOR_EXCEPTION(elementList.size() % stridingInfo[stridedBlockId] != 0, Exceptions::RuntimeError,
372  "StridedMap::StridedMap: stridingInfo not valid: stridingBlockInfo[stridedBlockId] is not an integer multiple of elementList.size().");
373  }
374 
375  map_ = MapFactory_t::Build(xlib, numGlobalElements, elementList, indexBase, comm, node);
376 
377  // calculate offset_
378 
379  // find minimum GID over all procs
380  GlobalOrdinal minGidOnCurProc = Teuchos::OrdinalTraits<GlobalOrdinal>::max();
381  for (Teuchos_Ordinal k = 0; k < elementList.size(); k++) // TODO fix occurence of Teuchos_Ordinal
382  if (elementList[k] < minGidOnCurProc)
383  minGidOnCurProc = elementList[k];
384 
385  Teuchos::reduceAll(*comm, Teuchos::REDUCE_MIN, minGidOnCurProc, Teuchos::outArg(offset_));
386 
387  // calculate striding index
388  size_t nStridedOffset = 0;
389  for (int j = 0; j < stridedBlockId; j++)
390  nStridedOffset += stridingInfo[j];
391  const GlobalOrdinal goStridedOffset = Teuchos::as<GlobalOrdinal>(nStridedOffset);
392 
393  // adapt offset_
394  offset_ -= goStridedOffset + indexBase_;
395 
396  TEUCHOS_TEST_FOR_EXCEPTION(CheckConsistency() == false, Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: CheckConsistency() == false");
397  }
398 
399  StridedMap(const RCP<const Map>& map, std::vector<size_t>& stridingInfo, GlobalOrdinal indexBase, LocalOrdinal stridedBlockId = -1, GlobalOrdinal offset = 0)
400  : stridingInfo_(stridingInfo), stridedBlockId_(stridedBlockId), offset_(offset), indexBase_(map->getIndexBase())
401  {
402  map_ = map;
403  }
404 
405 
407  virtual ~StridedMap() { }
408 
410 
412 
413 
414  std::vector<size_t> getStridingData() const { return stridingInfo_; }
415 
416  void setStridingData(std::vector<size_t> stridingInfo) { stridingInfo_ = stridingInfo; }
417 
418  size_t getFixedBlockSize() const {
419  size_t blkSize = 0;
420  for (std::vector<size_t>::const_iterator it = stridingInfo_.begin(); it != stridingInfo_.end(); ++it)
421  blkSize += *it;
422  return blkSize;
423  }
424 
427  LocalOrdinal getStridedBlockId() const { return stridedBlockId_; }
428 
430  bool isStrided() { return stridingInfo_.size() > 1 ? true : false; }
431 
434  bool isBlocked() { return getFixedBlockSize() > 1 ? true : false; }
435 
436  GlobalOrdinal getOffset() const { return offset_; }
437 
438  void setOffset(GlobalOrdinal offset) { offset_ = offset; }
439 
440  // returns number of strided block id which gid belongs to.
441  size_t GID2StridingBlockId(GlobalOrdinal gid) const {
442  GlobalOrdinal tgid = gid - offset_ - indexBase_;
443  tgid = tgid % getFixedBlockSize();
444 
445  size_t nStridedOffset = 0;
446  size_t stridedBlockId = 0;
447  for (size_t j = 0; j < stridingInfo_.size(); j++) {
448  nStridedOffset += stridingInfo_[j];
449  if (Teuchos::as<size_t>(tgid) < nStridedOffset) {
450  stridedBlockId = j;
451  break;
452  }
453  }
454  return stridedBlockId;
455  }
456 
458 
459 
460  RCP<const Map> getMap() const { return map_; }
461 
463 
464  /* // function currently not needed but maybe useful
465  std::vector<GlobalOrdinal> NodeId2GlobalDofIds(GlobalOrdinal nodeId) const {
466  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo_.size() == 0, Exceptions::RuntimeError, "StridedMap::NodeId2GlobalDofIds: stridingInfo not valid: stridingInfo.size() = 0?");
467  std::vector<GlobalOrdinal> dofs;
468  if(stridedBlockId_ > -1) {
469  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo_[stridedBlockId_] == 0, Exceptions::RuntimeError, "StridedMap::NodeId2GlobalDofIds: stridingInfo not valid: stridingInfo[stridedBlockId] = 0?");
470 
471  // determine nStridedOffset
472  size_t nStridedOffset = 0;
473  for(int j=0; j<stridedBlockId_; j++) {
474  nStridedOffset += stridingInfo_[j];
475  }
476 
477  for(size_t i = 0; i<stridingInfo_[stridedBlockId_]; i++) {
478  GlobalOrdinal gid =
479  nodeId * Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) +
480  offset_ +
481  Teuchos::as<GlobalOrdinal>(nStridedOffset) +
482  Teuchos::as<GlobalOrdinal>(i);
483  dofs.push_back(gid);
484  }
485  } else {
486  for(size_t i = 0; i<getFixedBlockSize(); i++) {
487  GlobalOrdinal gid =
488  nodeId * Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) +
489  offset_ +
490  Teuchos::as<GlobalOrdinal>(i);
491  dofs.push_back(gid);
492  }
493  }
494  return dofs;
495  }*/
497 
498  private:
499  virtual bool CheckConsistency() {
500 #ifndef HAVE_XPETRA_DEBUG
501  return true;
502 #else
503  if (getStridedBlockId() == -1) {
504  // Strided map contains the full map
505  if (getNodeNumElements() % getFixedBlockSize() != 0 || // number of local elements is not a multiple of block size
506  getGlobalNumElements() % getFixedBlockSize() != 0) // number of global -//-
507  return false;
508 
509  } else {
510  // Strided map contains only the partial map
512  // std::sort(dofGids.begin(), dofGids.end());
513 
514  if (dofGids.size() == 0) // special treatment for empty processors
515  return true;
516 
517  if (dofGids.size() % stridingInfo_[stridedBlockId_] != 0)
518  return false;
519 
520 
521  // Calculate nStridedOffset
522  size_t nStridedOffset = 0;
523  for (int j = 0; j < stridedBlockId_; j++)
524  nStridedOffset += stridingInfo_[j];
525 
526  const GlobalOrdinal goStridedOffset = Teuchos::as<GlobalOrdinal>(nStridedOffset);
527  const GlobalOrdinal goZeroOffset = (dofGids[0] - nStridedOffset - offset_ - indexBase_) / Teuchos::as<GlobalOrdinal>(getFixedBlockSize());
528 
529  GlobalOrdinal cnt = 0;
530  for (size_t i = 0; i < Teuchos::as<size_t>(dofGids.size())/stridingInfo_[stridedBlockId_]; i += stridingInfo_[stridedBlockId_]) {
531  const GlobalOrdinal first_gid = dofGids[i];
532 
533  // We expect this to be the same for all DOFs of the same node
534  cnt = (first_gid - goStridedOffset - offset_ - indexBase_) / Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) - goZeroOffset;
535 
536  // Loop over all DOFs that belong to current node
537  for (size_t j = 0; j < stridingInfo_[stridedBlockId_]; j++) {
538  const GlobalOrdinal gid = dofGids[i+j];
539  const GlobalOrdinal r = (gid - Teuchos::as<GlobalOrdinal>(j) - goStridedOffset - offset_ - indexBase_) /
540  Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) - goZeroOffset - cnt;
542  std::cout << "goZeroOffset : " << goZeroOffset << std::endl
543  << "dofGids[0] : " << dofGids[0] << std::endl
544  << "stridedOffset : " << nStridedOffset << std::endl
545  << "offset_ : " << offset_ << std::endl
546  << "goStridedOffset: " << goStridedOffset << std::endl
547  << "getFixedBlkSize: " << getFixedBlockSize() << std::endl
548  << "gid: " << gid << " GID: " << r << std::endl;
549 
550  return false;
551  }
552  }
553  }
554  }
555 
556  return true;
557 #endif
558  }
559 
560  private:
562 
563  std::vector<size_t> stridingInfo_;
564  LocalOrdinal stridedBlockId_;
565  // stridedBlock == -1: the full map (with all strided block dofs)
566  // stridedBlock > -1: only dofs of strided block with index "stridedBlockId" are stored in this map
567  GlobalOrdinal offset_;
568  GlobalOrdinal indexBase_;
569 
570  public:
571 
573 
574 
576  global_size_t getGlobalNumElements() const { return map_->getGlobalNumElements(); }
577 
579  size_t getNodeNumElements() const { return map_->getNodeNumElements(); }
580 
582  GlobalOrdinal getIndexBase() const { return map_->getIndexBase(); }
583 
585  LocalOrdinal getMinLocalIndex() const { return map_->getMinLocalIndex(); }
586 
588  LocalOrdinal getMaxLocalIndex() const { return map_->getMaxLocalIndex(); }
589 
591  GlobalOrdinal getMinGlobalIndex() const { return map_->getMinGlobalIndex(); }
592 
594  GlobalOrdinal getMaxGlobalIndex() const { return map_->getMaxGlobalIndex(); }
595 
597  GlobalOrdinal getMinAllGlobalIndex() const { return map_->getMinAllGlobalIndex(); }
598 
600  GlobalOrdinal getMaxAllGlobalIndex() const { return map_->getMaxAllGlobalIndex(); }
601 
603  LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const { return map_->getLocalElement(globalIndex); }
604 
606  GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const { return map_->getGlobalElement(localIndex); }
607 
610  return map_->getRemoteIndexList(GIDList, nodeIDList, LIDList);
611  }
612 
615  return map_->getRemoteIndexList(GIDList, nodeIDList);
616  }
617 
619  Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const { return map_->getNodeElementList(); }
620 
622  bool isNodeLocalElement(LocalOrdinal localIndex) const { return map_->isNodeLocalElement(localIndex); }
623 
625  bool isNodeGlobalElement(GlobalOrdinal globalIndex) const { return map_->isNodeGlobalElement(globalIndex); }
626 
628  bool isContiguous() const { return map_->isContiguous(); }
629 
631  bool isDistributed() const { return map_->isDistributed(); }
632 
634 
636  bool isCompatible(const Map& map) const { return map_->isCompatible(map); }
637 
639  bool isSameAs(const Map& map) const { return map_->isSameAs(map); }
640 
642  Teuchos::RCP< const Teuchos::Comm< int > > getComm() const { return map_->getComm(); }
643 
645  Teuchos::RCP<Node> getNode() const { return map_->getNode(); }
646 
647  RCP<const Map> removeEmptyProcesses () const { return map_->removeEmptyProcesses(); }
648  RCP<const Map> replaceCommWithSubset (const Teuchos::RCP<const Teuchos::Comm<int> >& newComm) const { return map_->replaceCommWithSubset(newComm); }
649 
651  std::string description() const { return map_->description(); }
652 
654  void describe(Teuchos::FancyOStream& out, const Teuchos::EVerbosityLevel verbLevel = Teuchos::Describable::verbLevel_default) const { map_->describe(out, verbLevel); }
655 
657  UnderlyingLib lib() const { return map_->lib(); }
658 
659  }; // StridedMap class
660 
661 } // Xpetra namespace
662 
663 #define XPETRA_STRIDEDMAP_SHORT
664 #endif // XPETRA_STRIDEDMAP_HPP
LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList, const Teuchos::ArrayView< LocalOrdinal > &LIDList) const
Returns the node IDs and corresponding local indices for a given list of global indices.
LocalOrdinal getStridedBlockId() const
GlobalOrdinal getMaxGlobalIndex() const
Returns maximum global index owned by this node.
GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const
Return the global index for a given local index.
Xpetra::MapFactory< LocalOrdinal, GlobalOrdinal, Node > MapFactory_t
size_t GID2StridingBlockId(GlobalOrdinal gid) const
static Teuchos::RCP< Map< LocalOrdinal, GlobalOrdinal, Node > > Build(UnderlyingLib lib, global_size_t numGlobalElements, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalGlobal lg=Xpetra::GloballyDistributed, const Teuchos::RCP< Node > &node=defaultArgNode())
Map constructor with Xpetra-defined contiguous uniform distribution.
static Teuchos::RCP< Node > defaultArgNode()
RCP< const Map > removeEmptyProcesses() const
Return a new Map with processes with zero elements removed.
LocalOrdinal local_ordinal_type
GlobalOrdinal global_ordinal_type
Definition: Xpetra_Map.hpp:71
GlobalOrdinal global_ordinal_type
bool isContiguous() const
Returns true if this Map is distributed contiguously; returns false otherwise.
void setStridingData(std::vector< size_t > stridingInfo)
Node node_type
Definition: Xpetra_Map.hpp:72
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const
Return a list of the global indices owned by this node.
GlobalOrdinal indexBase_
index base for the strided map (default = 0)
Xpetra namespace
size_type size() const
GlobalOrdinal getOffset() const
Exception throws to report errors in the internal logical of the program.
LocalOrdinal getMaxLocalIndex() const
Returns maximum local index.
LocalOrdinal stridedBlockId_
member variable denoting which dofs are stored in map
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Get the Comm object for this Map.
bool isCompatible(const Map &map) const
Returns true if map is compatible with this Map.
std::string description() const
Return a simple one-line description of this object.
GlobalOrdinal getMaxAllGlobalIndex() const
Return the maximum global index over all nodes.
Teuchos::RCP< Node > getNode() const
Get the Node object for this Map.
bool isNodeGlobalElement(GlobalOrdinal globalIndex) const
Returns true if the global index is found in this Map on this node; returns false if it isn&#39;t...
bool isNodeLocalElement(LocalOrdinal localIndex) const
Returns true if the local index is valid for this Map on this node; returns false if it isn&#39;t...
StridedMap(const RCP< const Map > &map, std::vector< size_t > &stridingInfo, GlobalOrdinal indexBase, LocalOrdinal stridedBlockId=-1, GlobalOrdinal offset=0)
StridedMap(UnderlyingLib xlib, 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=defaultArgNode())
Map constructor with contiguous uniform distribution.
bool isSameAs(const Map &map) const
Returns true if map is identical to this Map.
std::vector< size_t > stridingInfo_
vector with size of strided blocks (dofs)
virtual ~StridedMap()
Destructor.
RCP< const Map > getMap() const
bool isDistributed() const
Returns true if this Map is distributed across more than one node; returns false otherwise.
size_t getFixedBlockSize() const
GlobalOrdinal offset_
offset for gids in map (default = 0)
TEUCHOS_DEPRECATED void reduceAll(const Comm< Ordinal > &comm, const EReductionType reductType, const Packet &send, Packet *globalReduct)
std::vector< size_t > getStridingData() const
StridedMap(UnderlyingLib xlib, 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=defaultArgNode())
Map constructor with a user-defined contiguous distribution.
GlobalOrdinal getMinGlobalIndex() const
Returns minimum global index owned by this node.
size_t getNodeNumElements() const
Returns the number of elements belonging to the calling node.
size_t global_size_t
Global size_t object.
GlobalOrdinal getIndexBase() const
Returns the index base for this Map.
static const EVerbosityLevel verbLevel_default
global_size_t getGlobalNumElements() const
Returns the number of elements in this Map.
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
Return the local index for a given global index.
RCP< const Map > map_
LocalOrdinal getMinLocalIndex() const
Returns minimum local index.
UnderlyingLib lib() const
Get the library used by this object (Tpetra or Epetra?)
bool isStrided()
returns true, if this is a strided map (i.e. more than 1 strided blocks)
GlobalOrdinal getMinAllGlobalIndex() const
Return the minimum global index over all nodes.
virtual bool CheckConsistency()
LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList) const
Returns the node IDs for a given list of global indices.
Create an Xpetra::Map instance.
StridedMap(UnderlyingLib xlib, 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=defaultArgNode())
Map constructor with user-defined non-contiguous (arbitrary) distribution.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object with some verbosity level to a FancyOStream object.
RCP< const Map > replaceCommWithSubset(const Teuchos::RCP< const Teuchos::Comm< int > > &newComm) const
Replace this Map&#39;s communicator with a subset communicator.
void setOffset(GlobalOrdinal offset)