Xpetra_StridedMap_def.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_DEF_HPP
50 #define XPETRA_STRIDEDMAP_DEF_HPP
51 
53 
55 
56 #include "Xpetra_Exceptions.hpp"
57 #include "Xpetra_MapFactory.hpp"
58 
59 namespace Xpetra {
60 
61 
62 
63 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
64 template<class LocalOrdinal, class GlobalOrdinal, class Node>
65 TPETRA_DEPRECATED
68  global_size_t numGlobalElements,
69  GlobalOrdinal indexBase,
70  std::vector<size_t>& stridingInfo,
71  const Teuchos::RCP<const Teuchos::Comm<int>>& comm,
72  LocalOrdinal stridedBlockId, // FIXME (mfh 03 Sep 2014) This breaks for unsigned LocalOrdinal
73  GlobalOrdinal offset,
74  LocalGlobal lg,
75  const Teuchos::RCP<Node>& /* node */)
76  : StridedMap(xlib, numGlobalElements, indexBase, stridingInfo, comm, stridedBlockId, offset, lg)
77 {
78 }
79 #endif // #ifdef TPETRA_ENABLE_DEPRECATED_CODE
80 
81 
82 template<class LocalOrdinal, class GlobalOrdinal, class Node>
85  global_size_t numGlobalElements,
86  GlobalOrdinal indexBase,
87  std::vector<size_t>& stridingInfo,
88  const Teuchos::RCP<const Teuchos::Comm<int>>& comm,
89  LocalOrdinal stridedBlockId, // FIXME (mfh 03 Sep 2014) This breaks for unsigned LocalOrdinal
90  GlobalOrdinal offset,
91  LocalGlobal lg)
92  : stridingInfo_(stridingInfo), stridedBlockId_(stridedBlockId), offset_(offset), indexBase_(indexBase)
93 {
95 
96  size_t blkSize = getFixedBlockSize();
97 
98  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() == 0,
100  "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?");
101 
103  std::invalid_argument,
104  "StridedMap::StridedMap: numGlobalElements is invalid");
105 
106  TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % blkSize != 0,
108  "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize "
109  "is not an integer multiple of numGlobalElements.");
110 
111  if(stridedBlockId != -1)
112  {
113  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() < static_cast<size_t>(stridedBlockId),
115  "StridedTpetraMap::StridedTpetraMap: "
116  "stridedBlockId > stridingInfo.size()");
117  }
118 
119  // Try to create a shortcut
120  if(blkSize != 1 || offset_ != 0)
121  {
122  // check input data and reorganize map
123  global_size_t numGlobalNodes = numGlobalElements / blkSize;
124 
125  // build an equally distributed node map
126  RCP<Map> nodeMap = MapFactory_t::Build(xlib, numGlobalNodes, indexBase, comm, lg);
127  global_size_t numLocalNodes = nodeMap->getNodeNumElements();
128 
129  // translate local node ids to local dofs
130  size_t nStridedOffset = 0;
131  size_t nDofsPerNode = blkSize; // dofs per node for local striding block
132  if(stridedBlockId > -1)
133  {
134  for(int j = 0; j < stridedBlockId; j++)
135  {
136  nStridedOffset += stridingInfo_[ j ];
137  }
138 
139  nDofsPerNode = stridingInfo_[ stridedBlockId ];
140  numGlobalElements = numGlobalNodes * Teuchos::as<global_size_t>(nDofsPerNode);
141  }
142  size_t numLocalElements = numLocalNodes * Teuchos::as<size_t>(nDofsPerNode);
143 
144  std::vector<GlobalOrdinal> dofgids(numLocalElements);
145  for(LocalOrdinal i = 0; i < Teuchos::as<LocalOrdinal>(numLocalNodes); i++)
146  {
147  GlobalOrdinal nodeGID = nodeMap->getGlobalElement(i);
148 
149  for(size_t j = 0; j < nDofsPerNode; j++)
150  {
151  dofgids[ i * nDofsPerNode + j ] = indexBase_ + offset_
152  + (nodeGID - indexBase_) * Teuchos::as<GlobalOrdinal>(blkSize)
153  + Teuchos::as<GlobalOrdinal>(nStridedOffset + j);
154  }
155  }
156 
157  map_ = MapFactory_t::Build(xlib, numGlobalElements, dofgids, indexBase, comm);
158 
159  if(stridedBlockId == -1)
160  {
161  TEUCHOS_TEST_FOR_EXCEPTION(getNodeNumElements() != Teuchos::as<size_t>(nodeMap->getNodeNumElements() * nDofsPerNode),
163  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
164 
166  != Teuchos::as<size_t>(nodeMap->getGlobalNumElements() * nDofsPerNode),
168  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
169  }
170  else
171  {
172  size_t nDofsInStridedBlock = stridingInfo[ stridedBlockId ];
174  != Teuchos::as<size_t>(nodeMap->getNodeNumElements() * nDofsInStridedBlock),
176  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
177 
179  != Teuchos::as<size_t>(nodeMap->getGlobalNumElements() * nDofsInStridedBlock),
181  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
182  }
183  }
184  else
185  {
186  map_ = MapFactory_t::Build(xlib, numGlobalElements, indexBase, comm, lg);
187  }
188 
189  TEUCHOS_TEST_FOR_EXCEPTION(CheckConsistency() == false, Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: CheckConsistency() == false");
190 }
191 
192 
193 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
194 template<class LocalOrdinal, class GlobalOrdinal, class Node>
195 TPETRA_DEPRECATED
198  global_size_t numGlobalElements,
199  size_t numLocalElements,
200  GlobalOrdinal indexBase,
201  std::vector<size_t>& stridingInfo,
202  const Teuchos::RCP<const Teuchos::Comm<int>>& comm,
203  LocalOrdinal stridedBlockId,
204  GlobalOrdinal offset,
205  const Teuchos::RCP<Node>& /* node */)
206  : StridedMap(xlib, numGlobalElements, numLocalElements, indexBase, stridingInfo, comm, stridedBlockId, offset)
207 {
208 }
209 #endif // TPETRA_ENABLE_DEPRECATED_CODE
210 
211 
212 template<class LocalOrdinal, class GlobalOrdinal, class Node>
215  global_size_t numGlobalElements,
216  size_t numLocalElements,
217  GlobalOrdinal indexBase,
218  std::vector<size_t>& stridingInfo,
219  const Teuchos::RCP<const Teuchos::Comm<int>>& comm,
220  LocalOrdinal stridedBlockId,
221  GlobalOrdinal offset)
222  : stridingInfo_(stridingInfo), stridedBlockId_(stridedBlockId), offset_(offset), indexBase_(indexBase)
223 {
225 
226  size_t blkSize = getFixedBlockSize();
227  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() == 0,
229  "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?");
230  if(numGlobalElements != Teuchos::OrdinalTraits<global_size_t>::invalid())
231  {
232  TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % blkSize != 0,
234  "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer "
235  "multiple of numGlobalElements.");
236 #ifdef HAVE_XPETRA_DEBUG
237  // We have to do this check ourselves, as we don't necessarily construct the full Tpetra map
238  global_size_t sumLocalElements;
239  Teuchos::reduceAll(*comm, Teuchos::REDUCE_SUM, Teuchos::as<global_size_t>(numLocalElements), Teuchos::outArg(sumLocalElements));
240 
241  TEUCHOS_TEST_FOR_EXCEPTION(sumLocalElements != numGlobalElements,
242  std::invalid_argument,
243  "StridedMap::StridedMap: sum of numbers of local elements is different from the provided "
244  "number of global elements.");
245 #endif
246  }
247 
249  numLocalElements % blkSize != 0,
251  "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of numLocalElements.");
252 
253  if(stridedBlockId != -1)
254  {
255  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() < Teuchos::as<size_t>(stridedBlockId),
257  "StridedTpetraMap::StridedTpetraMap: stridedBlockId > stridingInfo.size()");
258  }
259 
260  // Try to create a shortcut
261  if(blkSize != 1 || offset_ != 0)
262  {
263  // check input data and reorganize map
265  if(numGlobalElements != Teuchos::OrdinalTraits<global_size_t>::invalid())
266  {
267  numGlobalNodes = numGlobalElements / blkSize;
268  }
269  global_size_t numLocalNodes = numLocalElements / blkSize;
270 
271  // build an equally distributed node map
272  RCP<Map> nodeMap = MapFactory_t::Build(xlib, numGlobalNodes, numLocalNodes, indexBase, comm);
273 
274  // translate local node ids to local dofs
275  size_t nStridedOffset = 0;
276  size_t nDofsPerNode = blkSize; // dofs per node for local striding block
277  if(stridedBlockId > -1)
278  {
279  for(int j = 0; j < stridedBlockId; j++)
280  {
281  nStridedOffset += stridingInfo_[ j ];
282  }
283 
284  nDofsPerNode = stridingInfo_[ stridedBlockId ];
285  numGlobalElements = nodeMap->getGlobalNumElements() * Teuchos::as<global_size_t>(nDofsPerNode);
286  }
287  numLocalElements = numLocalNodes * Teuchos::as<size_t>(nDofsPerNode);
288 
289  std::vector<GlobalOrdinal> dofgids(numLocalElements);
290  for(LocalOrdinal i = 0; i < Teuchos::as<LocalOrdinal>(numLocalNodes); i++)
291  {
292  GlobalOrdinal nodeGID = nodeMap->getGlobalElement(i);
293 
294  for(size_t j = 0; j < nDofsPerNode; j++)
295  {
296  dofgids[ i * nDofsPerNode + j ] = indexBase_ + offset_
297  + (nodeGID - indexBase_) * Teuchos::as<GlobalOrdinal>(blkSize)
298  + Teuchos::as<GlobalOrdinal>(nStridedOffset + j);
299  }
300  }
301 
302  map_ = MapFactory_t::Build(xlib, numGlobalElements, dofgids, indexBase, comm);
303 
304  if(stridedBlockId == -1)
305  {
306  TEUCHOS_TEST_FOR_EXCEPTION(getNodeNumElements() != Teuchos::as<size_t>(nodeMap->getNodeNumElements() * nDofsPerNode),
308  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
309 
311  != Teuchos::as<size_t>(nodeMap->getGlobalNumElements() * nDofsPerNode),
313  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
314  }
315  else
316  {
317  int nDofsInStridedBlock = stridingInfo[ stridedBlockId ];
318 
320  != Teuchos::as<size_t>(nodeMap->getNodeNumElements() * nDofsInStridedBlock),
322  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
323 
325  != Teuchos::as<size_t>(nodeMap->getGlobalNumElements() * nDofsInStridedBlock),
327  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
328  }
329  }
330  else
331  {
332  map_ = MapFactory_t::Build(xlib, numGlobalElements, numLocalElements, indexBase, comm);
333  }
334 
335  TEUCHOS_TEST_FOR_EXCEPTION(CheckConsistency() == false, Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: CheckConsistency() == false");
336 }
337 
338 
339 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
340 template<class LocalOrdinal, class GlobalOrdinal, class Node>
341 TPETRA_DEPRECATED
344  global_size_t numGlobalElements,
345  const Teuchos::ArrayView<const GlobalOrdinal>& elementList,
346  GlobalOrdinal indexBase,
347  std::vector<size_t>& stridingInfo,
348  const Teuchos::RCP<const Teuchos::Comm<int>>& comm,
349  LocalOrdinal stridedBlockId,
350  const Teuchos::RCP<Node>& /* node */)
351  : StridedMap(xlib, numGlobalElements, elementList, indexBase, stridingInfo, comm, stridedBlockId)
352 {
353 }
354 #endif // TPETRA_ENABLE_DEPRECATED_CODE
355 
356 
357 template<class LocalOrdinal, class GlobalOrdinal, class Node>
360  global_size_t numGlobalElements,
361  const Teuchos::ArrayView<const GlobalOrdinal>& elementList,
362  GlobalOrdinal indexBase,
363  std::vector<size_t>& stridingInfo,
364  const Teuchos::RCP<const Teuchos::Comm<int>>& comm,
365  LocalOrdinal stridedBlockId)
366  : stridingInfo_(stridingInfo), stridedBlockId_(stridedBlockId), indexBase_(indexBase)
367 {
369 
370  size_t blkSize = getFixedBlockSize();
371 
372  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() == 0,
374  "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?");
375  if(stridedBlockId != -1)
376  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() < Teuchos::as<size_t>(stridedBlockId),
378  "StridedTpetraMap::StridedTpetraMap: stridedBlockId > stridingInfo.size()");
379  if(numGlobalElements != Teuchos::OrdinalTraits<global_size_t>::invalid())
380  {
381  TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % blkSize != 0,
383  "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer "
384  "multiple of numGlobalElements.");
385 #ifdef HAVE_XPETRA_DEBUG
386  // We have to do this check ourselves, as we don't necessarily construct the full Tpetra map
387  global_size_t sumLocalElements, numLocalElements = elementList.size();
388  Teuchos::reduceAll(*comm, Teuchos::REDUCE_SUM, numLocalElements, Teuchos::outArg(sumLocalElements));
389  TEUCHOS_TEST_FOR_EXCEPTION(sumLocalElements != numGlobalElements,
390  std::invalid_argument,
391  "StridedMap::StridedMap: sum of numbers of local elements is different from the provided "
392  "number of global elements.");
393 #endif
394  }
395 
396  if(stridedBlockId == -1)
397  {
398  // numGlobalElements can be -1! FIXME
399  // TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % blkSize != 0, Exceptions::RuntimeError,
400  // "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of
401  // numGlobalElements.");
402  TEUCHOS_TEST_FOR_EXCEPTION(elementList.size() % blkSize != 0,
404  "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer "
405  "multiple of elementList.size().");
406  }
407  else
408  {
409  // numGlobalElements can be -1! FIXME
410  // TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % stridingInfo[stridedBlockId] != 0, Exceptions::RuntimeError,
411  // "StridedMap::StridedMap: stridingInfo not valid: stridingBlockInfo[stridedBlockId] is not an integer multiple of
412  // numGlobalElements.");
413  TEUCHOS_TEST_FOR_EXCEPTION(elementList.size() % stridingInfo[ stridedBlockId ] != 0,
415  "StridedMap::StridedMap: stridingInfo not valid: stridingBlockInfo[stridedBlockId] is not "
416  "an integer multiple of elementList.size().");
417  }
418 
419  map_ = MapFactory_t::Build(xlib, numGlobalElements, elementList, indexBase, comm);
420 
421  // calculate offset_
422 
423  // find minimum GID over all procs
424  GlobalOrdinal minGidOnCurProc = Teuchos::OrdinalTraits<GlobalOrdinal>::max();
425  for(Teuchos_Ordinal k = 0; k < elementList.size(); k++) // TODO fix occurence of Teuchos_Ordinal
426  {
427  if(elementList[ k ] < minGidOnCurProc)
428  {
429  minGidOnCurProc = elementList[ k ];
430  }
431  }
432 
433  Teuchos::reduceAll(*comm, Teuchos::REDUCE_MIN, minGidOnCurProc, Teuchos::outArg(offset_));
434 
435  // calculate striding index
436  size_t nStridedOffset = 0;
437  for(int j = 0; j < stridedBlockId; j++)
438  {
439  nStridedOffset += stridingInfo[ j ];
440  }
441  const GlobalOrdinal goStridedOffset = Teuchos::as<GlobalOrdinal>(nStridedOffset);
442 
443  // adapt offset_
444  offset_ -= goStridedOffset + indexBase_;
445 
446  TEUCHOS_TEST_FOR_EXCEPTION(CheckConsistency() == false, Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: CheckConsistency() == false");
447 }
448 
449 
450 template<class LocalOrdinal, class GlobalOrdinal, class Node>
452 StridedMap(const RCP<const Map>& map,
453  std::vector<size_t>& stridingInfo,
454  GlobalOrdinal /* indexBase */,
455  LocalOrdinal stridedBlockId,
456  GlobalOrdinal offset)
457  : stridingInfo_(stridingInfo),
458  stridedBlockId_(stridedBlockId),
459  offset_(offset),
460  indexBase_(map->getIndexBase())
461 {
462  // TAW: 11/24/15
463  // A strided map never can be built from a strided map. getMap always returns the underlying
464  // Xpetra::Map object which contains the data (either in a Xpetra::EpetraMapT or Xpetra::TpetraMap
465  // object)
466  if(Teuchos::rcp_dynamic_cast<const StridedMap>(map) == Teuchos::null)
467  {
468  map_ = map; // if map is not a strided map, just store it (standard case)
469  }
470  else
471  {
472  map_ = map->getMap(); // if map is also a strided map, store the underlying plain Epetra/Tpetra Xpetra map object
473  }
474 }
475 
476 
477 template<class LocalOrdinal, class GlobalOrdinal, class Node>
479 ~StridedMap()
480 {
481 }
482 
483 
484 template<class LocalOrdinal, class GlobalOrdinal, class Node>
485 std::vector<size_t>
487 getStridingData() const
488 {
489  return stridingInfo_;
490 }
491 
492 
493 template<class LocalOrdinal, class GlobalOrdinal, class Node>
494 void
496 setStridingData(std::vector<size_t> stridingInfo)
497 {
498  stridingInfo_ = stridingInfo;
499 }
500 
501 
502 template<class LocalOrdinal, class GlobalOrdinal, class Node>
503 size_t
505 getFixedBlockSize() const
506 {
507  size_t blkSize = 0;
508  for(std::vector<size_t>::const_iterator it = stridingInfo_.begin(); it != stridingInfo_.end(); ++it)
509  {
510  blkSize += *it;
511  }
512  return blkSize;
513 }
514 
515 
516 template<class LocalOrdinal, class GlobalOrdinal, class Node>
517 LocalOrdinal
519 getStridedBlockId() const
520 {
521  return stridedBlockId_;
522 }
523 
524 
525 template<class LocalOrdinal, class GlobalOrdinal, class Node>
526 bool
528 isStrided() const
529 {
530  return stridingInfo_.size() > 1 ? true : false;
531 }
532 
533 
534 template<class LocalOrdinal, class GlobalOrdinal, class Node>
535 bool
537 isBlocked() const
538 {
539  return getFixedBlockSize() > 1 ? true : false;
540 }
541 
542 
543 template<class LocalOrdinal, class GlobalOrdinal, class Node>
544 GlobalOrdinal
546 getOffset() const
547 {
548  return offset_;
549 }
550 
551 
552 template<class LocalOrdinal, class GlobalOrdinal, class Node>
553 void
555 setOffset(GlobalOrdinal offset)
556 {
557  offset_ = offset;
558 }
559 
560 
561 template<class LocalOrdinal, class GlobalOrdinal, class Node>
562 size_t
564 GID2StridingBlockId(GlobalOrdinal gid) const
565 {
566  GlobalOrdinal tgid = gid - offset_ - indexBase_;
567  tgid = tgid % getFixedBlockSize();
568 
569  size_t nStridedOffset = 0;
570  size_t stridedBlockId = 0;
571  for(size_t j = 0; j < stridingInfo_.size(); j++)
572  {
573  nStridedOffset += stridingInfo_[ j ];
574  if(Teuchos::as<size_t>(tgid) < nStridedOffset)
575  {
576  stridedBlockId = j;
577  break;
578  }
579  }
580  return stridedBlockId;
581 }
582 
583 
584 template<class LocalOrdinal, class GlobalOrdinal, class Node>
587 getMap() const
588 {
589  return map_;
590 }
591 
592 
593 template<class LocalOrdinal, class GlobalOrdinal, class Node>
594 bool
597 {
598 #ifndef HAVE_XPETRA_DEBUG
599  return true;
600 #else
601  if(getStridedBlockId() == -1)
602  {
603  // Strided map contains the full map
604  if(getNodeNumElements() % getFixedBlockSize() != 0 || // number of local elements is not a multiple of block size
605  getGlobalNumElements() % getFixedBlockSize() != 0) // number of global -//-
606  return false;
607  }
608  else
609  {
610  // Strided map contains only the partial map
611  Teuchos::ArrayView<const GlobalOrdinal> dofGids = getNodeElementList();
612  // std::sort(dofGids.begin(), dofGids.end());
613 
614  if(dofGids.size() == 0) // special treatment for empty processors
615  {
616  return true;
617  }
618 
619  if(dofGids.size() % stridingInfo_[ stridedBlockId_ ] != 0)
620  {
621  return false;
622  }
623 
624 
625  // Calculate nStridedOffset
626  size_t nStridedOffset = 0;
627  for(int j = 0; j < stridedBlockId_; j++)
628  {
629  nStridedOffset += stridingInfo_[ j ];
630  }
631 
632  const GlobalOrdinal goStridedOffset = Teuchos::as<GlobalOrdinal>(nStridedOffset);
633  const GlobalOrdinal goZeroOffset = (dofGids[ 0 ] - nStridedOffset - offset_ - indexBase_) / Teuchos::as<GlobalOrdinal>(getFixedBlockSize());
634 
635  GlobalOrdinal cnt = 0;
636  for(size_t i = 0;
637  i < Teuchos::as<size_t>(dofGids.size()) / stridingInfo_[ stridedBlockId_ ];
638  i += stridingInfo_[ stridedBlockId_ ])
639  {
640  const GlobalOrdinal first_gid = dofGids[ i ];
641 
642  // We expect this to be the same for all DOFs of the same node
643  cnt = (first_gid - goStridedOffset - offset_ - indexBase_) / Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) - goZeroOffset;
644 
645  // Loop over all DOFs that belong to current node
646  for(size_t j = 0; j < stridingInfo_[ stridedBlockId_ ]; j++)
647  {
648  const GlobalOrdinal gid = dofGids[ i + j ];
649  const GlobalOrdinal r = (gid - Teuchos::as<GlobalOrdinal>(j) - goStridedOffset - offset_ - indexBase_)
650  / Teuchos::as<GlobalOrdinal>(getFixedBlockSize())
651  - goZeroOffset - cnt;
652  // TAW 1/18/2016: We cannot use Teuchos::OrdinalTraits<GlobalOrdinal>::zero() ) here,
653  // If, e.g., GO=long long is disabled, OrdinalTraits<long long> is not available.
654  // But we instantiate stubs on GO=long long which might contain StridedMaps.
655  // These lead to compilation errors, then.
656  if(0 != r)
657  {
658  std::cout << "goZeroOffset : " << goZeroOffset << std::endl
659  << "dofGids[0] : " << dofGids[ 0 ] << std::endl
660  << "stridedOffset : " << nStridedOffset << std::endl
661  << "offset_ : " << offset_ << std::endl
662  << "goStridedOffset: " << goStridedOffset << std::endl
663  << "getFixedBlkSize: " << getFixedBlockSize() << std::endl
664  << "gid: " << gid << " GID: " << r << std::endl;
665 
666  return false;
667  }
668  }
669  }
670  }
671 
672  return true;
673 #endif
674 }
675 
676 
677 template<class LocalOrdinal, class GlobalOrdinal, class Node>
680 getGlobalNumElements() const
681 {
682  return map_->getGlobalNumElements();
683 }
684 
685 
686 template<class LocalOrdinal, class GlobalOrdinal, class Node>
687 size_t
689 getNodeNumElements() const
690 {
691  return map_->getNodeNumElements();
692 }
693 
694 
695 template<class LocalOrdinal, class GlobalOrdinal, class Node>
696 GlobalOrdinal
698 getIndexBase() const
699 {
700  return map_->getIndexBase();
701 }
702 
703 
704 template<class LocalOrdinal, class GlobalOrdinal, class Node>
705 LocalOrdinal
707 getMinLocalIndex() const
708 {
709  return map_->getMinLocalIndex();
710 }
711 
712 
713 template<class LocalOrdinal, class GlobalOrdinal, class Node>
714 LocalOrdinal
716 getMaxLocalIndex() const
717 {
718  return map_->getMaxLocalIndex();
719 }
720 
721 
722 template<class LocalOrdinal, class GlobalOrdinal, class Node>
723 GlobalOrdinal
725 getMinGlobalIndex() const
726 {
727  return map_->getMinGlobalIndex();
728 }
729 
730 
731 template<class LocalOrdinal, class GlobalOrdinal, class Node>
732 GlobalOrdinal
734 getMaxGlobalIndex() const
735 {
736  return map_->getMaxGlobalIndex();
737 }
738 
739 
740 template<class LocalOrdinal, class GlobalOrdinal, class Node>
741 GlobalOrdinal
743 getMinAllGlobalIndex() const
744 {
745  return map_->getMinAllGlobalIndex();
746 }
747 
748 
749 template<class LocalOrdinal, class GlobalOrdinal, class Node>
750 GlobalOrdinal
752 getMaxAllGlobalIndex() const
753 {
754  return map_->getMaxAllGlobalIndex();
755 }
756 
757 
758 template<class LocalOrdinal, class GlobalOrdinal, class Node>
759 LocalOrdinal
761 getLocalElement(GlobalOrdinal globalIndex) const
762 {
763  return map_->getLocalElement(globalIndex);
764 }
765 
766 
767 template<class LocalOrdinal, class GlobalOrdinal, class Node>
768 GlobalOrdinal
770 getGlobalElement(LocalOrdinal localIndex) const
771 {
772  return map_->getGlobalElement(localIndex);
773 }
774 
775 
776 template<class LocalOrdinal, class GlobalOrdinal, class Node>
780  const Teuchos::ArrayView<int>& nodeIDList,
781  const Teuchos::ArrayView<LocalOrdinal>& LIDList) const
782 {
783  return map_->getRemoteIndexList(GIDList, nodeIDList, LIDList);
784 }
785 
786 
787 template<class LocalOrdinal, class GlobalOrdinal, class Node>
791  const Teuchos::ArrayView<int>& nodeIDList) const
792 {
793  return map_->getRemoteIndexList(GIDList, nodeIDList);
794 }
795 
796 
797 template<class LocalOrdinal, class GlobalOrdinal, class Node>
800 getNodeElementList() const
801 {
802  return map_->getNodeElementList();
803 }
804 
805 
806 template<class LocalOrdinal, class GlobalOrdinal, class Node>
807 bool
809 isNodeLocalElement(LocalOrdinal localIndex) const
810 {
811  return map_->isNodeLocalElement(localIndex);
812 }
813 
814 
815 template<class LocalOrdinal, class GlobalOrdinal, class Node>
816 bool
818 isNodeGlobalElement(GlobalOrdinal globalIndex) const
819 {
820  return map_->isNodeGlobalElement(globalIndex);
821 }
822 
823 
824 template<class LocalOrdinal, class GlobalOrdinal, class Node>
825 bool
827 isContiguous() const
828 {
829  return map_->isContiguous();
830 }
831 
832 
833 template<class LocalOrdinal, class GlobalOrdinal, class Node>
834 bool
836 isDistributed() const
837 {
838  return map_->isDistributed();
839 }
840 
841 
842 template<class LocalOrdinal, class GlobalOrdinal, class Node>
843 bool
845 isCompatible(const Map& map) const
846 {
847  return map_->isCompatible(map);
848 }
849 
850 
851 template<class LocalOrdinal, class GlobalOrdinal, class Node>
852 bool
854 isSameAs(const Map& map) const
855 {
856  return map_->isSameAs(map);
857 }
858 
859 
860 template<class LocalOrdinal, class GlobalOrdinal, class Node>
863 getComm() const
864 {
865  return map_->getComm();
866 }
867 
868 
869 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
870 template<class LocalOrdinal, class GlobalOrdinal, class Node>
873 getNode() const
874 {
875  return map_->getNode();
876 }
877 #endif // TPETRA_ENABLE_DEPRECATED_CODE
878 
879 
880 template<class LocalOrdinal, class GlobalOrdinal, class Node>
881 RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node>>
883 removeEmptyProcesses() const
884 {
885  return map_->removeEmptyProcesses();
886 }
887 
888 
889 template<class LocalOrdinal, class GlobalOrdinal, class Node>
892 replaceCommWithSubset(const Teuchos::RCP<const Teuchos::Comm<int>>& newComm) const
893 {
894  return map_->replaceCommWithSubset(newComm);
895 }
896 
897 
898 template<class LocalOrdinal, class GlobalOrdinal, class Node>
899 std::string
901 description() const
902 {
903  return map_->description();
904 }
905 
906 
907 template<class LocalOrdinal, class GlobalOrdinal, class Node>
908 void
910 describe(Teuchos::FancyOStream& out, const Teuchos::EVerbosityLevel verbLevel) const
911 {
912  map_->describe(out, verbLevel);
913 }
914 
915 
916 template<class LocalOrdinal, class GlobalOrdinal, class Node>
919 lib() const
920 {
921  return map_->lib();
922 }
923 
924 
925 
926 } // namespace Xpetra
927 
928 
929 
930 #endif // XPETRA_STRIDEDMAP_DEF_HPP
931 
932 
size_type size() const
Exception throws to report errors in the internal logical of the program.
Create an Xpetra::Map instance.
Class that stores a strided map.
RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const
LocalOrdinal getMaxLocalIndex() const
Returns maximum local index.
std::vector< size_t > stridingInfo_
vector with size of strided blocks (dofs)
GlobalOrdinal getMinAllGlobalIndex() const
Return the minimum global index over all nodes.
virtual ~StridedMap()
Destructor.
RCP< const Map > replaceCommWithSubset(const Teuchos::RCP< const Teuchos::Comm< int >> &newComm) const
bool isSameAs(const Map &map) const
Returns true if map is identical to 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't.
size_t GID2StridingBlockId(GlobalOrdinal gid) const
GlobalOrdinal indexBase_
index base for the strided map (default = 0)
bool isNodeLocalElement(LocalOrdinal localIndex) const
Returns true if the local index is valid for this Map on this node; returns false if it isn't.
Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const
Return a list of the global indices owned by this node.
GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const
Return the global index for a given local index.
UnderlyingLib lib() const
Get the library used by this object (Tpetra or Epetra?)
global_size_t getGlobalNumElements() const
Returns the number of elements in this Map.
bool isDistributed() const
Returns true if this Map is distributed across more than one node; returns false otherwise.
LocalOrdinal getStridedBlockId() const
void setStridingData(std::vector< size_t > stridingInfo)
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.
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)
Map constructor with contiguous uniform distribution.
GlobalOrdinal getOffset() const
bool isContiguous() const
Returns true if this Map is distributed contiguously; returns false otherwise.
GlobalOrdinal getMaxAllGlobalIndex() const
Return the maximum global index over all nodes.
void setOffset(GlobalOrdinal offset)
GlobalOrdinal offset_
offset for gids in map (default = 0)
GlobalOrdinal getMinGlobalIndex() const
Returns minimum global index owned by this node.
std::vector< size_t > getStridingData() const
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.
size_t getFixedBlockSize() const
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
Return the local index for a given global index.
bool isStrided() const
returns true, if this is a strided map (i.e. more than 1 strided blocks)
size_t getNodeNumElements() const
Returns the number of elements belonging to the calling node.
std::string description() const
Return a simple one-line description of this object.
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 Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > map_
LocalOrdinal getMinLocalIndex() const
Returns minimum local index.
GlobalOrdinal getMaxGlobalIndex() const
Returns maximum global index owned by this node.
RCP< const Map > removeEmptyProcesses() const
Return a new Map with processes with zero elements removed.
GlobalOrdinal getIndexBase() const
Returns the index base for this Map.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
TEUCHOS_DEPRECATED void reduceAll(const Comm< Ordinal > &comm, const EReductionType reductType, const Packet &send, Packet *globalReduct)
Xpetra namespace
size_t global_size_t
Global size_t object.