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  // TAW: 11/24/15
403  // A strided map never can be built from a strided map. getMap always returns the underlying
404  // Xpetra::Map object which contains the data (either in a Xpetra::EpetraMapT or Xpetra::TpetraMap
405  // object)
406  if(Teuchos::rcp_dynamic_cast<const StridedMap>(map) == Teuchos::null)
407  map_ = map; // if map is not a strided map, just store it (standard case)
408  else
409  map_ = map->getMap(); // if map is also a strided map, store the underlying plain Epetra/Tpetra Xpetra map object
410  }
411 
412 
414  virtual ~StridedMap() { }
415 
417 
419 
420 
421  std::vector<size_t> getStridingData() const { return stridingInfo_; }
422 
423  void setStridingData(std::vector<size_t> stridingInfo) { stridingInfo_ = stridingInfo; }
424 
425  size_t getFixedBlockSize() const {
426  size_t blkSize = 0;
427  for (std::vector<size_t>::const_iterator it = stridingInfo_.begin(); it != stridingInfo_.end(); ++it)
428  blkSize += *it;
429  return blkSize;
430  }
431 
434  LocalOrdinal getStridedBlockId() const { return stridedBlockId_; }
435 
437  bool isStrided() const { return stridingInfo_.size() > 1 ? true : false; }
438 
441  bool isBlocked() const { return getFixedBlockSize() > 1 ? true : false; }
442 
443  GlobalOrdinal getOffset() const { return offset_; }
444 
445  void setOffset(GlobalOrdinal offset) { offset_ = offset; }
446 
447  // returns number of strided block id which gid belongs to.
448  size_t GID2StridingBlockId(GlobalOrdinal gid) const {
449  GlobalOrdinal tgid = gid - offset_ - indexBase_;
450  tgid = tgid % getFixedBlockSize();
451 
452  size_t nStridedOffset = 0;
453  size_t stridedBlockId = 0;
454  for (size_t j = 0; j < stridingInfo_.size(); j++) {
455  nStridedOffset += stridingInfo_[j];
456  if (Teuchos::as<size_t>(tgid) < nStridedOffset) {
457  stridedBlockId = j;
458  break;
459  }
460  }
461  return stridedBlockId;
462  }
463 
465 
466 
468 
470 
471  /* // function currently not needed but maybe useful
472  std::vector<GlobalOrdinal> NodeId2GlobalDofIds(GlobalOrdinal nodeId) const {
473  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo_.size() == 0, Exceptions::RuntimeError, "StridedMap::NodeId2GlobalDofIds: stridingInfo not valid: stridingInfo.size() = 0?");
474  std::vector<GlobalOrdinal> dofs;
475  if(stridedBlockId_ > -1) {
476  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo_[stridedBlockId_] == 0, Exceptions::RuntimeError, "StridedMap::NodeId2GlobalDofIds: stridingInfo not valid: stridingInfo[stridedBlockId] = 0?");
477 
478  // determine nStridedOffset
479  size_t nStridedOffset = 0;
480  for(int j=0; j<stridedBlockId_; j++) {
481  nStridedOffset += stridingInfo_[j];
482  }
483 
484  for(size_t i = 0; i<stridingInfo_[stridedBlockId_]; i++) {
485  GlobalOrdinal gid =
486  nodeId * Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) +
487  offset_ +
488  Teuchos::as<GlobalOrdinal>(nStridedOffset) +
489  Teuchos::as<GlobalOrdinal>(i);
490  dofs.push_back(gid);
491  }
492  } else {
493  for(size_t i = 0; i<getFixedBlockSize(); i++) {
494  GlobalOrdinal gid =
495  nodeId * Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) +
496  offset_ +
497  Teuchos::as<GlobalOrdinal>(i);
498  dofs.push_back(gid);
499  }
500  }
501  return dofs;
502  }*/
504 
505  private:
506  virtual bool CheckConsistency() {
507 #ifndef HAVE_XPETRA_DEBUG
508  return true;
509 #else
510  if (getStridedBlockId() == -1) {
511  // Strided map contains the full map
512  if (getNodeNumElements() % getFixedBlockSize() != 0 || // number of local elements is not a multiple of block size
513  getGlobalNumElements() % getFixedBlockSize() != 0) // number of global -//-
514  return false;
515 
516  } else {
517  // Strided map contains only the partial map
519  // std::sort(dofGids.begin(), dofGids.end());
520 
521  if (dofGids.size() == 0) // special treatment for empty processors
522  return true;
523 
524  if (dofGids.size() % stridingInfo_[stridedBlockId_] != 0)
525  return false;
526 
527 
528  // Calculate nStridedOffset
529  size_t nStridedOffset = 0;
530  for (int j = 0; j < stridedBlockId_; j++)
531  nStridedOffset += stridingInfo_[j];
532 
533  const GlobalOrdinal goStridedOffset = Teuchos::as<GlobalOrdinal>(nStridedOffset);
534  const GlobalOrdinal goZeroOffset = (dofGids[0] - nStridedOffset - offset_ - indexBase_) / Teuchos::as<GlobalOrdinal>(getFixedBlockSize());
535 
536  GlobalOrdinal cnt = 0;
537  for (size_t i = 0; i < Teuchos::as<size_t>(dofGids.size())/stridingInfo_[stridedBlockId_]; i += stridingInfo_[stridedBlockId_]) {
538  const GlobalOrdinal first_gid = dofGids[i];
539 
540  // We expect this to be the same for all DOFs of the same node
541  cnt = (first_gid - goStridedOffset - offset_ - indexBase_) / Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) - goZeroOffset;
542 
543  // Loop over all DOFs that belong to current node
544  for (size_t j = 0; j < stridingInfo_[stridedBlockId_]; j++) {
545  const GlobalOrdinal gid = dofGids[i+j];
546  const GlobalOrdinal r = (gid - Teuchos::as<GlobalOrdinal>(j) - goStridedOffset - offset_ - indexBase_) /
547  Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) - goZeroOffset - cnt;
549  std::cout << "goZeroOffset : " << goZeroOffset << std::endl
550  << "dofGids[0] : " << dofGids[0] << std::endl
551  << "stridedOffset : " << nStridedOffset << std::endl
552  << "offset_ : " << offset_ << std::endl
553  << "goStridedOffset: " << goStridedOffset << std::endl
554  << "getFixedBlkSize: " << getFixedBlockSize() << std::endl
555  << "gid: " << gid << " GID: " << r << std::endl;
556 
557  return false;
558  }
559  }
560  }
561  }
562 
563  return true;
564 #endif
565  }
566 
567  private:
569 
570  std::vector<size_t> stridingInfo_;
571  LocalOrdinal stridedBlockId_;
572  // stridedBlock == -1: the full map (with all strided block dofs)
573  // stridedBlock > -1: only dofs of strided block with index "stridedBlockId" are stored in this map
574  GlobalOrdinal offset_;
575  GlobalOrdinal indexBase_;
576 
577  public:
578 
580 
581 
583  global_size_t getGlobalNumElements() const { return map_->getGlobalNumElements(); }
584 
586  size_t getNodeNumElements() const { return map_->getNodeNumElements(); }
587 
589  GlobalOrdinal getIndexBase() const { return map_->getIndexBase(); }
590 
592  LocalOrdinal getMinLocalIndex() const { return map_->getMinLocalIndex(); }
593 
595  LocalOrdinal getMaxLocalIndex() const { return map_->getMaxLocalIndex(); }
596 
598  GlobalOrdinal getMinGlobalIndex() const { return map_->getMinGlobalIndex(); }
599 
601  GlobalOrdinal getMaxGlobalIndex() const { return map_->getMaxGlobalIndex(); }
602 
604  GlobalOrdinal getMinAllGlobalIndex() const { return map_->getMinAllGlobalIndex(); }
605 
607  GlobalOrdinal getMaxAllGlobalIndex() const { return map_->getMaxAllGlobalIndex(); }
608 
610  LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const { return map_->getLocalElement(globalIndex); }
611 
613  GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const { return map_->getGlobalElement(localIndex); }
614 
617  return map_->getRemoteIndexList(GIDList, nodeIDList, LIDList);
618  }
619 
622  return map_->getRemoteIndexList(GIDList, nodeIDList);
623  }
624 
626  Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const { return map_->getNodeElementList(); }
627 
629  bool isNodeLocalElement(LocalOrdinal localIndex) const { return map_->isNodeLocalElement(localIndex); }
630 
632  bool isNodeGlobalElement(GlobalOrdinal globalIndex) const { return map_->isNodeGlobalElement(globalIndex); }
633 
635  bool isContiguous() const { return map_->isContiguous(); }
636 
638  bool isDistributed() const { return map_->isDistributed(); }
639 
641 
643  bool isCompatible(const Map& map) const { return map_->isCompatible(map); }
644 
646  bool isSameAs(const Map& map) const { return map_->isSameAs(map); }
647 
649  Teuchos::RCP< const Teuchos::Comm< int > > getComm() const { return map_->getComm(); }
650 
652  Teuchos::RCP<Node> getNode() const { return map_->getNode(); }
653 
654  RCP<const Map> removeEmptyProcesses () const { return map_->removeEmptyProcesses(); }
655  RCP<const Map> replaceCommWithSubset (const Teuchos::RCP<const Teuchos::Comm<int> >& newComm) const { return map_->replaceCommWithSubset(newComm); }
656 
658  std::string description() const { return map_->description(); }
659 
661  void describe(Teuchos::FancyOStream& out, const Teuchos::EVerbosityLevel verbLevel = Teuchos::Describable::verbLevel_default) const { map_->describe(out, verbLevel); }
662 
664  UnderlyingLib lib() const { return map_->lib(); }
665 
666  }; // StridedMap class
667 
668 } // Xpetra namespace
669 
670 #define XPETRA_STRIDEDMAP_SHORT
671 #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:86
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:87
#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)
RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const
bool isStrided() const
returns true, if this is a strided map (i.e. more than 1 strided blocks)
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.
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.
LocalOrdinal getMinLocalIndex() const
Returns minimum local index.
UnderlyingLib lib() const
Get the library used by this object (Tpetra or Epetra?)
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)
RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > map_