Xpetra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 
52 #include "Xpetra_StridedMap.hpp"
53 
54 #include <Teuchos_OrdinalTraits.hpp>
55 
56 #include "Xpetra_Exceptions.hpp"
57 #include "Xpetra_MapFactory.hpp"
58 
59 namespace Xpetra {
60 
61 
62 
63 
64 
65 template<class LocalOrdinal, class GlobalOrdinal, class Node>
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  : stridingInfo_(stridingInfo), stridedBlockId_(stridedBlockId), offset_(offset), indexBase_(indexBase)
76 {
78 
79  size_t blkSize = getFixedBlockSize();
80 
81  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() == 0,
83  "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?");
84 
85  TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements == Teuchos::OrdinalTraits<global_size_t>::invalid(),
86  std::invalid_argument,
87  "StridedMap::StridedMap: numGlobalElements is invalid");
88 
89  TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % blkSize != 0,
91  "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize "
92  "is not an integer multiple of numGlobalElements.");
93 
94  if(stridedBlockId != -1)
95  {
96  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() < static_cast<size_t>(stridedBlockId),
98  "StridedTpetraMap::StridedTpetraMap: "
99  "stridedBlockId > stridingInfo.size()");
100  }
101 
102  // Try to create a shortcut
103  if(blkSize != 1 || offset_ != 0)
104  {
105  // check input data and reorganize map
106  global_size_t numGlobalNodes = numGlobalElements / blkSize;
107 
108  // build an equally distributed node map
109  RCP<Map> nodeMap = MapFactory_t::Build(xlib, numGlobalNodes, indexBase, comm, lg);
110  global_size_t numLocalNodes = nodeMap->getNodeNumElements();
111 
112  // translate local node ids to local dofs
113  size_t nStridedOffset = 0;
114  size_t nDofsPerNode = blkSize; // dofs per node for local striding block
115  if(stridedBlockId > -1)
116  {
117  for(int j = 0; j < stridedBlockId; j++)
118  {
119  nStridedOffset += stridingInfo_[ j ];
120  }
121 
122  nDofsPerNode = stridingInfo_[ stridedBlockId ];
123  numGlobalElements = numGlobalNodes * Teuchos::as<global_size_t>(nDofsPerNode);
124  }
125  size_t numLocalElements = numLocalNodes * Teuchos::as<size_t>(nDofsPerNode);
126 
127  std::vector<GlobalOrdinal> dofgids(numLocalElements);
128  for(LocalOrdinal i = 0; i < Teuchos::as<LocalOrdinal>(numLocalNodes); i++)
129  {
130  GlobalOrdinal nodeGID = nodeMap->getGlobalElement(i);
131 
132  for(size_t j = 0; j < nDofsPerNode; j++)
133  {
134  dofgids[ i * nDofsPerNode + j ] = indexBase_ + offset_
135  + (nodeGID - indexBase_) * Teuchos::as<GlobalOrdinal>(blkSize)
136  + Teuchos::as<GlobalOrdinal>(nStridedOffset + j);
137  }
138  }
139 
140  map_ = MapFactory_t::Build(xlib, numGlobalElements, dofgids, indexBase, comm);
141 
142  if(stridedBlockId == -1)
143  {
144  TEUCHOS_TEST_FOR_EXCEPTION(getNodeNumElements() != Teuchos::as<size_t>(nodeMap->getNodeNumElements() * nDofsPerNode),
146  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
147 
148  TEUCHOS_TEST_FOR_EXCEPTION(getGlobalNumElements()
149  != Teuchos::as<size_t>(nodeMap->getGlobalNumElements() * nDofsPerNode),
151  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
152  }
153  else
154  {
155  size_t nDofsInStridedBlock = stridingInfo[ stridedBlockId ];
156  TEUCHOS_TEST_FOR_EXCEPTION(getNodeNumElements()
157  != Teuchos::as<size_t>(nodeMap->getNodeNumElements() * nDofsInStridedBlock),
159  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
160 
161  TEUCHOS_TEST_FOR_EXCEPTION(getGlobalNumElements()
162  != Teuchos::as<size_t>(nodeMap->getGlobalNumElements() * nDofsInStridedBlock),
164  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
165  }
166  }
167  else
168  {
169  map_ = MapFactory_t::Build(xlib, numGlobalElements, indexBase, comm, lg);
170  }
171 
172  TEUCHOS_TEST_FOR_EXCEPTION(CheckConsistency() == false, Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: CheckConsistency() == false");
173 }
174 
175 
176 
177 
178 template<class LocalOrdinal, class GlobalOrdinal, class Node>
181  global_size_t numGlobalElements,
182  size_t numLocalElements,
183  GlobalOrdinal indexBase,
184  std::vector<size_t>& stridingInfo,
185  const Teuchos::RCP<const Teuchos::Comm<int>>& comm,
186  LocalOrdinal stridedBlockId,
187  GlobalOrdinal offset)
188  : stridingInfo_(stridingInfo), stridedBlockId_(stridedBlockId), offset_(offset), indexBase_(indexBase)
189 {
191 
192  size_t blkSize = getFixedBlockSize();
193  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() == 0,
195  "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?");
196  if(numGlobalElements != Teuchos::OrdinalTraits<global_size_t>::invalid())
197  {
198  TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % blkSize != 0,
200  "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer "
201  "multiple of numGlobalElements.");
202 #ifdef HAVE_XPETRA_DEBUG
203  // We have to do this check ourselves, as we don't necessarily construct the full Tpetra map
204  global_size_t sumLocalElements;
205  Teuchos::reduceAll(*comm, Teuchos::REDUCE_SUM, Teuchos::as<global_size_t>(numLocalElements), Teuchos::outArg(sumLocalElements));
206 
207  TEUCHOS_TEST_FOR_EXCEPTION(sumLocalElements != numGlobalElements,
208  std::invalid_argument,
209  "StridedMap::StridedMap: sum of numbers of local elements is different from the provided "
210  "number of global elements.");
211 #endif
212  }
213 
214  TEUCHOS_TEST_FOR_EXCEPTION(
215  numLocalElements % blkSize != 0,
217  "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of numLocalElements.");
218 
219  if(stridedBlockId != -1)
220  {
221  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() < Teuchos::as<size_t>(stridedBlockId),
223  "StridedTpetraMap::StridedTpetraMap: stridedBlockId > stridingInfo.size()");
224  }
225 
226  // Try to create a shortcut
227  if(blkSize != 1 || offset_ != 0)
228  {
229  // check input data and reorganize map
230  global_size_t numGlobalNodes = Teuchos::OrdinalTraits<global_size_t>::invalid();
231  if(numGlobalElements != Teuchos::OrdinalTraits<global_size_t>::invalid())
232  {
233  numGlobalNodes = numGlobalElements / blkSize;
234  }
235  global_size_t numLocalNodes = numLocalElements / blkSize;
236 
237  // build an equally distributed node map
238  RCP<Map> nodeMap = MapFactory_t::Build(xlib, numGlobalNodes, numLocalNodes, indexBase, comm);
239 
240  // translate local node ids to local dofs
241  size_t nStridedOffset = 0;
242  size_t nDofsPerNode = blkSize; // dofs per node for local striding block
243  if(stridedBlockId > -1)
244  {
245  for(int j = 0; j < stridedBlockId; j++)
246  {
247  nStridedOffset += stridingInfo_[ j ];
248  }
249 
250  nDofsPerNode = stridingInfo_[ stridedBlockId ];
251  numGlobalElements = nodeMap->getGlobalNumElements() * Teuchos::as<global_size_t>(nDofsPerNode);
252  }
253  numLocalElements = numLocalNodes * Teuchos::as<size_t>(nDofsPerNode);
254 
255  std::vector<GlobalOrdinal> dofgids(numLocalElements);
256  for(LocalOrdinal i = 0; i < Teuchos::as<LocalOrdinal>(numLocalNodes); i++)
257  {
258  GlobalOrdinal nodeGID = nodeMap->getGlobalElement(i);
259 
260  for(size_t j = 0; j < nDofsPerNode; j++)
261  {
262  dofgids[ i * nDofsPerNode + j ] = indexBase_ + offset_
263  + (nodeGID - indexBase_) * Teuchos::as<GlobalOrdinal>(blkSize)
264  + Teuchos::as<GlobalOrdinal>(nStridedOffset + j);
265  }
266  }
267 
268  map_ = MapFactory_t::Build(xlib, numGlobalElements, dofgids, indexBase, comm);
269 
270  if(stridedBlockId == -1)
271  {
272  TEUCHOS_TEST_FOR_EXCEPTION(getNodeNumElements() != Teuchos::as<size_t>(nodeMap->getNodeNumElements() * nDofsPerNode),
274  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
275 
276  TEUCHOS_TEST_FOR_EXCEPTION(getGlobalNumElements()
277  != Teuchos::as<size_t>(nodeMap->getGlobalNumElements() * nDofsPerNode),
279  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
280  }
281  else
282  {
283  int nDofsInStridedBlock = stridingInfo[ stridedBlockId ];
284 
285  TEUCHOS_TEST_FOR_EXCEPTION(getNodeNumElements()
286  != Teuchos::as<size_t>(nodeMap->getNodeNumElements() * nDofsInStridedBlock),
288  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
289 
290  TEUCHOS_TEST_FOR_EXCEPTION(getGlobalNumElements()
291  != Teuchos::as<size_t>(nodeMap->getGlobalNumElements() * nDofsInStridedBlock),
293  "StridedTpetraMap::StridedTpetraMap: wrong distribution of dofs among processors.");
294  }
295  }
296  else
297  {
298  map_ = MapFactory_t::Build(xlib, numGlobalElements, numLocalElements, indexBase, comm);
299  }
300 
301  TEUCHOS_TEST_FOR_EXCEPTION(CheckConsistency() == false, Exceptions::RuntimeError, "StridedTpetraMap::StridedTpetraMap: CheckConsistency() == false");
302 }
303 
304 
305 
306 
307 template<class LocalOrdinal, class GlobalOrdinal, class Node>
310  global_size_t numGlobalElements,
311  const Teuchos::ArrayView<const GlobalOrdinal>& elementList,
312  GlobalOrdinal indexBase,
313  std::vector<size_t>& stridingInfo,
314  const Teuchos::RCP<const Teuchos::Comm<int>>& comm,
315  LocalOrdinal stridedBlockId)
316  : stridingInfo_(stridingInfo), stridedBlockId_(stridedBlockId), indexBase_(indexBase)
317 {
319 
320  size_t blkSize = getFixedBlockSize();
321 
322  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() == 0,
324  "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?");
325  if(stridedBlockId != -1)
326  TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() < Teuchos::as<size_t>(stridedBlockId),
328  "StridedTpetraMap::StridedTpetraMap: stridedBlockId > stridingInfo.size()");
329  if(numGlobalElements != Teuchos::OrdinalTraits<global_size_t>::invalid())
330  {
331  TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % blkSize != 0,
333  "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer "
334  "multiple of numGlobalElements.");
335 #ifdef HAVE_XPETRA_DEBUG
336  // We have to do this check ourselves, as we don't necessarily construct the full Tpetra map
337  global_size_t sumLocalElements, numLocalElements = elementList.size();
338  Teuchos::reduceAll(*comm, Teuchos::REDUCE_SUM, numLocalElements, Teuchos::outArg(sumLocalElements));
339  TEUCHOS_TEST_FOR_EXCEPTION(sumLocalElements != numGlobalElements,
340  std::invalid_argument,
341  "StridedMap::StridedMap: sum of numbers of local elements is different from the provided "
342  "number of global elements.");
343 #endif
344  }
345 
346  if(stridedBlockId == -1)
347  {
348  // numGlobalElements can be -1! FIXME
349  // TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % blkSize != 0, Exceptions::RuntimeError,
350  // "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of
351  // numGlobalElements.");
352  TEUCHOS_TEST_FOR_EXCEPTION(elementList.size() % blkSize != 0,
354  "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer "
355  "multiple of elementList.size().");
356  }
357  else
358  {
359  // numGlobalElements can be -1! FIXME
360  // TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % stridingInfo[stridedBlockId] != 0, Exceptions::RuntimeError,
361  // "StridedMap::StridedMap: stridingInfo not valid: stridingBlockInfo[stridedBlockId] is not an integer multiple of
362  // numGlobalElements.");
363  TEUCHOS_TEST_FOR_EXCEPTION(elementList.size() % stridingInfo[ stridedBlockId ] != 0,
365  "StridedMap::StridedMap: stridingInfo not valid: stridingBlockInfo[stridedBlockId] is not "
366  "an integer multiple of elementList.size().");
367  }
368 
369  map_ = MapFactory_t::Build(xlib, numGlobalElements, elementList, indexBase, comm);
370 
371  // calculate offset_
372 
373  // find minimum GID over all procs
374  GlobalOrdinal minGidOnCurProc = Teuchos::OrdinalTraits<GlobalOrdinal>::max();
375  for(Teuchos_Ordinal k = 0; k < elementList.size(); k++) // TODO fix occurence of Teuchos_Ordinal
376  {
377  if(elementList[ k ] < minGidOnCurProc)
378  {
379  minGidOnCurProc = elementList[ k ];
380  }
381  }
382 
383  Teuchos::reduceAll(*comm, Teuchos::REDUCE_MIN, minGidOnCurProc, Teuchos::outArg(offset_));
384 
385  // calculate striding index
386  size_t nStridedOffset = 0;
387  for(int j = 0; j < stridedBlockId; j++)
388  {
389  nStridedOffset += stridingInfo[ j ];
390  }
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 
400 template<class LocalOrdinal, class GlobalOrdinal, class Node>
402 StridedMap(const RCP<const Map>& map,
403  std::vector<size_t>& stridingInfo,
404  GlobalOrdinal /* indexBase */,
405  LocalOrdinal stridedBlockId,
406  GlobalOrdinal offset)
407  : stridingInfo_(stridingInfo),
408  stridedBlockId_(stridedBlockId),
409  offset_(offset),
410  indexBase_(map->getIndexBase())
411 {
412  // TAW: 11/24/15
413  // A strided map never can be built from a strided map. getMap always returns the underlying
414  // Xpetra::Map object which contains the data (either in a Xpetra::EpetraMapT or Xpetra::TpetraMap
415  // object)
416  if(Teuchos::rcp_dynamic_cast<const StridedMap>(map) == Teuchos::null)
417  {
418  map_ = map; // if map is not a strided map, just store it (standard case)
419  }
420  else
421  {
422  map_ = map->getMap(); // if map is also a strided map, store the underlying plain Epetra/Tpetra Xpetra map object
423  }
424 }
425 
426 
427 template<class LocalOrdinal, class GlobalOrdinal, class Node>
430 {
431 }
432 
433 
434 template<class LocalOrdinal, class GlobalOrdinal, class Node>
435 std::vector<size_t>
438 {
439  return stridingInfo_;
440 }
441 
442 
443 template<class LocalOrdinal, class GlobalOrdinal, class Node>
444 void
446 setStridingData(std::vector<size_t> stridingInfo)
447 {
448  stridingInfo_ = stridingInfo;
449 }
450 
451 
452 template<class LocalOrdinal, class GlobalOrdinal, class Node>
453 size_t
456 {
457  size_t blkSize = 0;
458  for(std::vector<size_t>::const_iterator it = stridingInfo_.begin(); it != stridingInfo_.end(); ++it)
459  {
460  blkSize += *it;
461  }
462  return blkSize;
463 }
464 
465 
466 template<class LocalOrdinal, class GlobalOrdinal, class Node>
467 LocalOrdinal
470 {
471  return stridedBlockId_;
472 }
473 
474 
475 template<class LocalOrdinal, class GlobalOrdinal, class Node>
476 bool
478 isStrided() const
479 {
480  return stridingInfo_.size() > 1 ? true : false;
481 }
482 
483 
484 template<class LocalOrdinal, class GlobalOrdinal, class Node>
485 bool
487 isBlocked() const
488 {
489  return getFixedBlockSize() > 1 ? true : false;
490 }
491 
492 
493 template<class LocalOrdinal, class GlobalOrdinal, class Node>
494 GlobalOrdinal
496 getOffset() const
497 {
498  return offset_;
499 }
500 
501 
502 template<class LocalOrdinal, class GlobalOrdinal, class Node>
503 void
505 setOffset(GlobalOrdinal offset)
506 {
507  offset_ = offset;
508 }
509 
510 
511 template<class LocalOrdinal, class GlobalOrdinal, class Node>
512 size_t
514 GID2StridingBlockId(GlobalOrdinal gid) const
515 {
516  GlobalOrdinal tgid = gid - offset_ - indexBase_;
517  tgid = tgid % getFixedBlockSize();
518 
519  size_t nStridedOffset = 0;
520  size_t stridedBlockId = 0;
521  for(size_t j = 0; j < stridingInfo_.size(); j++)
522  {
523  nStridedOffset += stridingInfo_[ j ];
524  if(Teuchos::as<size_t>(tgid) < nStridedOffset)
525  {
526  stridedBlockId = j;
527  break;
528  }
529  }
530  return stridedBlockId;
531 }
532 
533 
534 template<class LocalOrdinal, class GlobalOrdinal, class Node>
535 RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
537 getMap() const
538 {
539  return map_;
540 }
541 
542 
543 template<class LocalOrdinal, class GlobalOrdinal, class Node>
544 bool
547 {
548 #ifndef HAVE_XPETRA_DEBUG
549  return true;
550 #else
551  if(getStridedBlockId() == -1)
552  {
553  // Strided map contains the full map
554  if(getNodeNumElements() % getFixedBlockSize() != 0 || // number of local elements is not a multiple of block size
555  getGlobalNumElements() % getFixedBlockSize() != 0) // number of global -//-
556  return false;
557  }
558  else
559  {
560  // Strided map contains only the partial map
561  Teuchos::ArrayView<const GlobalOrdinal> dofGids = getNodeElementList();
562  // std::sort(dofGids.begin(), dofGids.end());
563 
564  if(dofGids.size() == 0) // special treatment for empty processors
565  {
566  return true;
567  }
568 
569  if(dofGids.size() % stridingInfo_[ stridedBlockId_ ] != 0)
570  {
571  return false;
572  }
573 
574 
575  // Calculate nStridedOffset
576  size_t nStridedOffset = 0;
577  for(int j = 0; j < stridedBlockId_; j++)
578  {
579  nStridedOffset += stridingInfo_[ j ];
580  }
581 
582  const GlobalOrdinal goStridedOffset = Teuchos::as<GlobalOrdinal>(nStridedOffset);
583  const GlobalOrdinal goZeroOffset = (dofGids[ 0 ] - nStridedOffset - offset_ - indexBase_) / Teuchos::as<GlobalOrdinal>(getFixedBlockSize());
584 
585  GlobalOrdinal cnt = 0;
586  for(size_t i = 0;
587  i < Teuchos::as<size_t>(dofGids.size()) / stridingInfo_[ stridedBlockId_ ];
588  i += stridingInfo_[ stridedBlockId_ ])
589  {
590  const GlobalOrdinal first_gid = dofGids[ i ];
591 
592  // We expect this to be the same for all DOFs of the same node
593  cnt = (first_gid - goStridedOffset - offset_ - indexBase_) / Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) - goZeroOffset;
594 
595  // Loop over all DOFs that belong to current node
596  for(size_t j = 0; j < stridingInfo_[ stridedBlockId_ ]; j++)
597  {
598  const GlobalOrdinal gid = dofGids[ i + j ];
599  const GlobalOrdinal r = (gid - Teuchos::as<GlobalOrdinal>(j) - goStridedOffset - offset_ - indexBase_)
600  / Teuchos::as<GlobalOrdinal>(getFixedBlockSize())
601  - goZeroOffset - cnt;
602  // TAW 1/18/2016: We cannot use Teuchos::OrdinalTraits<GlobalOrdinal>::zero() ) here,
603  // If, e.g., GO=long long is disabled, OrdinalTraits<long long> is not available.
604  // But we instantiate stubs on GO=long long which might contain StridedMaps.
605  // These lead to compilation errors, then.
606  if(0 != r)
607  {
608  std::cout << "goZeroOffset : " << goZeroOffset << std::endl
609  << "dofGids[0] : " << dofGids[ 0 ] << std::endl
610  << "stridedOffset : " << nStridedOffset << std::endl
611  << "offset_ : " << offset_ << std::endl
612  << "goStridedOffset: " << goStridedOffset << std::endl
613  << "getFixedBlkSize: " << getFixedBlockSize() << std::endl
614  << "gid: " << gid << " GID: " << r << std::endl;
615 
616  return false;
617  }
618  }
619  }
620  }
621 
622  return true;
623 #endif
624 }
625 
626 
627 template<class LocalOrdinal, class GlobalOrdinal, class Node>
631 {
632  return map_->getGlobalNumElements();
633 }
634 
635 
636 template<class LocalOrdinal, class GlobalOrdinal, class Node>
637 size_t
640 {
641  return map_->getNodeNumElements();
642 }
643 
644 
645 template<class LocalOrdinal, class GlobalOrdinal, class Node>
646 GlobalOrdinal
649 {
650  return map_->getIndexBase();
651 }
652 
653 
654 template<class LocalOrdinal, class GlobalOrdinal, class Node>
655 LocalOrdinal
658 {
659  return map_->getMinLocalIndex();
660 }
661 
662 
663 template<class LocalOrdinal, class GlobalOrdinal, class Node>
664 LocalOrdinal
667 {
668  return map_->getMaxLocalIndex();
669 }
670 
671 
672 template<class LocalOrdinal, class GlobalOrdinal, class Node>
673 GlobalOrdinal
676 {
677  return map_->getMinGlobalIndex();
678 }
679 
680 
681 template<class LocalOrdinal, class GlobalOrdinal, class Node>
682 GlobalOrdinal
685 {
686  return map_->getMaxGlobalIndex();
687 }
688 
689 
690 template<class LocalOrdinal, class GlobalOrdinal, class Node>
691 GlobalOrdinal
694 {
695  return map_->getMinAllGlobalIndex();
696 }
697 
698 
699 template<class LocalOrdinal, class GlobalOrdinal, class Node>
700 GlobalOrdinal
703 {
704  return map_->getMaxAllGlobalIndex();
705 }
706 
707 
708 template<class LocalOrdinal, class GlobalOrdinal, class Node>
709 LocalOrdinal
711 getLocalElement(GlobalOrdinal globalIndex) const
712 {
713  return map_->getLocalElement(globalIndex);
714 }
715 
716 
717 template<class LocalOrdinal, class GlobalOrdinal, class Node>
718 GlobalOrdinal
720 getGlobalElement(LocalOrdinal localIndex) const
721 {
722  return map_->getGlobalElement(localIndex);
723 }
724 
725 
726 template<class LocalOrdinal, class GlobalOrdinal, class Node>
729 getRemoteIndexList(const Teuchos::ArrayView<const GlobalOrdinal>& GIDList,
730  const Teuchos::ArrayView<int>& nodeIDList,
731  const Teuchos::ArrayView<LocalOrdinal>& LIDList) const
732 {
733  return map_->getRemoteIndexList(GIDList, nodeIDList, LIDList);
734 }
735 
736 
737 template<class LocalOrdinal, class GlobalOrdinal, class Node>
740 getRemoteIndexList(const Teuchos::ArrayView<const GlobalOrdinal>& GIDList,
741  const Teuchos::ArrayView<int>& nodeIDList) const
742 {
743  return map_->getRemoteIndexList(GIDList, nodeIDList);
744 }
745 
746 
747 template<class LocalOrdinal, class GlobalOrdinal, class Node>
748 Teuchos::ArrayView<const GlobalOrdinal>
751 {
752  return map_->getNodeElementList();
753 }
754 
755 
756 template<class LocalOrdinal, class GlobalOrdinal, class Node>
757 bool
759 isNodeLocalElement(LocalOrdinal localIndex) const
760 {
761  return map_->isNodeLocalElement(localIndex);
762 }
763 
764 
765 template<class LocalOrdinal, class GlobalOrdinal, class Node>
766 bool
768 isNodeGlobalElement(GlobalOrdinal globalIndex) const
769 {
770  return map_->isNodeGlobalElement(globalIndex);
771 }
772 
773 
774 template<class LocalOrdinal, class GlobalOrdinal, class Node>
775 bool
778 {
779  return map_->isContiguous();
780 }
781 
782 
783 template<class LocalOrdinal, class GlobalOrdinal, class Node>
784 bool
787 {
788  return map_->isDistributed();
789 }
790 
791 
792 template<class LocalOrdinal, class GlobalOrdinal, class Node>
793 bool
795 isCompatible(const Map& map) const
796 {
797  return map_->isCompatible(map);
798 }
799 
800 
801 template<class LocalOrdinal, class GlobalOrdinal, class Node>
802 bool
804 isSameAs(const Map& map) const
805 {
806  return map_->isSameAs(map);
807 }
808 
809 
810 template<class LocalOrdinal, class GlobalOrdinal, class Node>
811 Teuchos::RCP<const Teuchos::Comm<int>>
813 getComm() const
814 {
815  return map_->getComm();
816 }
817 
818 
819 
820 
821 template<class LocalOrdinal, class GlobalOrdinal, class Node>
822 RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node>>
825 {
826  return map_->removeEmptyProcesses();
827 }
828 
829 
830 template<class LocalOrdinal, class GlobalOrdinal, class Node>
831 RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node>>
833 replaceCommWithSubset(const Teuchos::RCP<const Teuchos::Comm<int>>& newComm) const
834 {
835  return map_->replaceCommWithSubset(newComm);
836 }
837 
838 
839 template<class LocalOrdinal, class GlobalOrdinal, class Node>
840 std::string
842 description() const
843 {
844  return map_->description();
845 }
846 
847 
848 template<class LocalOrdinal, class GlobalOrdinal, class Node>
849 void
851 describe(Teuchos::FancyOStream& out, const Teuchos::EVerbosityLevel verbLevel) const
852 {
853  map_->describe(out, verbLevel);
854 }
855 
856 
857 template<class LocalOrdinal, class GlobalOrdinal, class Node>
860 lib() const
861 {
862  return map_->lib();
863 }
864 
865 
866 
867 } // namespace Xpetra
868 
869 
870 
871 #endif // XPETRA_STRIDEDMAP_DEF_HPP
872 
873 
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.
size_t GID2StridingBlockId(GlobalOrdinal gid) const
bool isContiguous() const
Returns true if this Map is distributed contiguously; returns false otherwise.
void setStridingData(std::vector< size_t > stridingInfo)
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)
GlobalOrdinal getOffset() const
Exception throws to report errors in the internal logical of the program.
LocalOrdinal getMaxLocalIndex() const
Returns maximum local index.
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.
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...
bool isStrided() const
returns true, if this is a strided map (i.e. more than 1 strided blocks)
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)
RCP< const Map > removeEmptyProcesses() const
Return a new Map with processes with zero elements removed.
RCP< const Map > replaceCommWithSubset(const Teuchos::RCP< const Teuchos::Comm< int >> &newComm) 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)
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.
RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const
global_size_t getGlobalNumElements() const
Returns the number of elements in this Map.
std::vector< size_t > getStridingData() const
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
Return the local index for a given global index.
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.
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.
Create an Xpetra::Map instance.
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.
virtual ~StridedMap()
Destructor.
void setOffset(GlobalOrdinal offset)
RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > map_