Epetra Package Browser (Single Doxygen Collection)  Development
Epetra_BlockMap.cpp
Go to the documentation of this file.
1 
2 //@HEADER
3 // ************************************************************************
4 //
5 // Epetra: Linear Algebra Services Package
6 // Copyright 2011 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 Michael A. Heroux (maherou@sandia.gov)
39 //
40 // ************************************************************************
41 //@HEADER
42 
43 #include "Epetra_ConfigDefs.h"
44 #include "Epetra_BlockMap.h"
45 #include "Epetra_Comm.h"
46 #include "Epetra_Directory.h"
48 #include "Epetra_HashTable.h"
49 #include <limits>
50 
51 #ifdef HAVE_MPI
52 #include "Epetra_MpiComm.h"
53 #endif
54 
55 // Use the new LID hash table approach by default
56 #define EPETRA_BLOCKMAP_NEW_LID
57 
58 //==============================================================================
59 // Epetra_BlockMap constructor function for a Epetra-defined uniform linear distribution of constant size elements.
60 void Epetra_BlockMap::ConstructAutoUniform(long long NumGlobal_Elements, int Element_Size, long long Index_Base, const Epetra_Comm& comm, bool IsLongLong)
61 {
62 
63  // Each processor gets roughly numGlobalPoints/p points
64  // This routine automatically defines a linear partitioning of a
65  // map with numGlobalPoints across the processors
66  // specified in the given Epetra_Comm
67 
68  if (NumGlobal_Elements < 0)
69  throw ReportError("NumGlobal_Elements = " + toString(NumGlobal_Elements) + ". Should be >= 0.", -1);
70  if (Element_Size <= 0)
71  throw ReportError("ElementSize = " + toString(Element_Size) + ". Should be > 0.", -2);
72 
73  BlockMapData_ = new Epetra_BlockMapData(NumGlobal_Elements, Element_Size, Index_Base, comm, IsLongLong);
74  int NumProc = comm.NumProc();
76  BlockMapData_->LinearMap_ = true;
77 
78  int MyPID = comm.MyPID();
79 
80  if(BlockMapData_->NumGlobalElements_ / NumProc > (long long) std::numeric_limits<int>::max())
81  throw ReportError("Epetra_BlockMap::ConstructAutoUniform: Error. Not enough space for elements on each processor", -99);
82 
84  int remainder = (int) (BlockMapData_->NumGlobalElements_ % NumProc); // remainder will fit int
85  long long start_index = ((long long)(MyPID)) * (BlockMapData_->NumMyElements_ + 1);
86 
87  if (MyPID < remainder)
89  else
90  start_index -= (MyPID - remainder);
91 
94 
99 
105 
107 }
108 
109 //==============================================================================
110 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
111 Epetra_BlockMap::Epetra_BlockMap(long long NumGlobal_Elements, int Element_Size, int Index_Base, const Epetra_Comm& comm)
112  : Epetra_Object("Epetra::BlockMap"),
113  BlockMapData_(0)
114 {
115  const bool IsLongLong = true;
116  ConstructAutoUniform(NumGlobal_Elements, Element_Size, static_cast<long long>(Index_Base), comm, IsLongLong);
117 }
118 
119 Epetra_BlockMap::Epetra_BlockMap(long long NumGlobal_Elements, int Element_Size, long long Index_Base, const Epetra_Comm& comm)
120  : Epetra_Object("Epetra::BlockMap"),
121  BlockMapData_(0)
122 {
123  const bool IsLongLong = true;
124  ConstructAutoUniform(NumGlobal_Elements, Element_Size, Index_Base, comm, IsLongLong);
125 }
126 #endif
127 
128 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
129 Epetra_BlockMap::Epetra_BlockMap(int NumGlobal_Elements, int Element_Size, int Index_Base, const Epetra_Comm& comm)
130  : Epetra_Object("Epetra::BlockMap"),
131  BlockMapData_(0)
132 {
133  const bool IsLongLong = false;
134  ConstructAutoUniform((long long)NumGlobal_Elements, Element_Size, Index_Base, comm, IsLongLong);
135 }
136 #endif
137 //==============================================================================
138 
139 // Epetra_BlockMap constructor function for a user-defined linear distribution of constant size elements.
141  long long NumGlobal_Elements, int NumMy_Elements,
142  int Element_Size, long long Index_Base, const Epetra_Comm& comm, bool IsLongLong)
143 {
144  if (NumGlobal_Elements < -1)
145  throw ReportError("NumGlobal_Elements = " + toString(NumGlobal_Elements) + ". Should be >= -1.", -1);
146  if (NumMy_Elements < 0)
147  throw ReportError("NumMy_Elements = " + toString(NumMy_Elements) + ". Should be >= 0.", -2);
148  if (Element_Size <= 0)
149  throw ReportError("ElementSize = " + toString(Element_Size) + ". Should be > 0.", -3);
150 
151  BlockMapData_ = new Epetra_BlockMapData(NumGlobal_Elements, Element_Size, Index_Base, comm, IsLongLong);
152  BlockMapData_->NumMyElements_ = NumMy_Elements;
158  BlockMapData_->LinearMap_ = true;
159 
160  // Each processor gets NumMyElements points
161 
162 
163  // Get processor information
164 
165  int NumProc = comm.NumProc();
166 
167  BlockMapData_->DistributedGlobal_ = IsDistributedGlobal(NumGlobal_Elements, NumMy_Elements);
168 
169  // Local Map and uniprocessor case: Each processor gets a complete copy of all elements
170  if (!BlockMapData_->DistributedGlobal_ || NumProc==1) {
172  CheckValidNGE(NumGlobal_Elements);
173 
176 
177  BlockMapData_-> MinAllGID_ = BlockMapData_->IndexBase_;
181  }
182  else if (NumProc > 1) {
183  // Sum up all local element counts to get global count
184  long long tmp_NumMyElements = BlockMapData_->NumMyElements_;
185  BlockMapData_->Comm_->SumAll(&tmp_NumMyElements, &BlockMapData_->NumGlobalElements_, 1);
186 
187  CheckValidNGE(NumGlobal_Elements);
188 
191 
194 
195  // Use the ScanSum function to compute a prefix sum of the number of points
196  long long tmp2_NumMyElements = BlockMapData_->NumMyElements_;
197  BlockMapData_->Comm_->ScanSum(&tmp2_NumMyElements, &BlockMapData_->MaxMyGID_, 1);
198 
199  long long start_index = BlockMapData_->MaxMyGID_ - BlockMapData_->NumMyElements_;
202  }
203  else
204  throw ReportError("Internal Error. Report to Epetra developer", -99);
205 
206 
208 }
209 
210 //==============================================================================
211 
212 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
213 Epetra_BlockMap::Epetra_BlockMap(long long NumGlobal_Elements, int NumMy_Elements,
214  int Element_Size, int Index_Base, const Epetra_Comm& comm)
215  : Epetra_Object("Epetra::BlockMap"),
216  BlockMapData_(0)
217 {
218  const bool IsLongLong = true;
219  ConstructUserLinear(NumGlobal_Elements, NumMy_Elements, Element_Size,static_cast<long long>(Index_Base), comm, IsLongLong);
220 }
221 
222 Epetra_BlockMap::Epetra_BlockMap(long long NumGlobal_Elements, int NumMy_Elements,
223  int Element_Size, long long Index_Base, const Epetra_Comm& comm)
224  : Epetra_Object("Epetra::BlockMap"),
225  BlockMapData_(0)
226 {
227  const bool IsLongLong = true;
228  ConstructUserLinear(NumGlobal_Elements, NumMy_Elements, Element_Size,Index_Base, comm, IsLongLong);
229 }
230 #endif
231 
232 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
233 Epetra_BlockMap::Epetra_BlockMap(int NumGlobal_Elements, int NumMy_Elements,
234  int Element_Size, int Index_Base, const Epetra_Comm& comm)
235  : Epetra_Object("Epetra::BlockMap"),
236  BlockMapData_(0)
237 {
238  const bool IsLongLong = false;
239  ConstructUserLinear((long long)NumGlobal_Elements, NumMy_Elements, Element_Size,Index_Base, comm, IsLongLong);
240 }
241 #endif
242 
243 // Epetra_BlockMap constructor for a user-defined arbitrary distribution of constant size elements.
244 template<typename int_type>
245 void Epetra_BlockMap::ConstructUserConstant(int_type NumGlobal_Elements, int NumMy_Elements,
246  const int_type * myGlobalElements,
247  int Element_Size, int_type indexBase,
248  const Epetra_Comm& comm, bool IsLongLong)
249 {
250  int i;
251  // Each processor gets NumMyElements points
252 
253  if (NumGlobal_Elements < -1)
254  throw ReportError("NumGlobal_Elements = " + toString(NumGlobal_Elements) + ". Should be >= -1.", -1);
255  if (NumMy_Elements < 0)
256  throw ReportError("NumMy_Elements = " + toString(NumMy_Elements) + ". Should be >= 0.", -2);
257  if (Element_Size <= 0)
258  throw ReportError("ElementSize = " + toString(Element_Size) + ". Should be > 0.", -3);
259 
260  // Allocate storage for global index list information
261 
262  BlockMapData_ = new Epetra_BlockMapData(NumGlobal_Elements, Element_Size, indexBase, comm, IsLongLong);
263  if (NumMy_Elements > 0) {
264  int errorcode = SizeMyGlobalElement<int_type>(NumMy_Elements);
265  if(errorcode != 0)
266  throw ReportError("Error with MyGlobalElements allocation.", -99);
267  }
268 
269  BlockMapData_->NumMyElements_ = NumMy_Elements;
275  BlockMapData_->LinearMap_ = false;
276  // Get processor information
277 
278  int NumProc = comm.NumProc();
279  if (NumMy_Elements > 0) {
280  // Compute min/max GID on this processor
281  BlockMapData_->MinMyGID_ = myGlobalElements[0];
282  BlockMapData_->MaxMyGID_ = myGlobalElements[0];
283  for (i = 0; i < NumMy_Elements; i++) {
284  MyGlobalElementVal<int_type>(i) = myGlobalElements[i];
285  BlockMapData_->MinMyGID_ = EPETRA_MIN(BlockMapData_->MinMyGID_, (long long) myGlobalElements[i]);
286  BlockMapData_->MaxMyGID_ = EPETRA_MAX(BlockMapData_->MaxMyGID_, (long long) myGlobalElements[i]);
287  }
288  }
289  else {
292  }
293 
294  BlockMapData_->DistributedGlobal_ = IsDistributedGlobal(NumGlobal_Elements, NumMy_Elements);
295 
296  // Local Map and uniprocessor case: Each processor gets a complete copy of all elements
297  if (!BlockMapData_->DistributedGlobal_ || NumProc==1) {
299  CheckValidNGE(NumGlobal_Elements);
302 
305  }
306  else if (NumProc > 1) {
307  // Sum up all local element counts to get global count
308  long long tmp_NumMyElements = BlockMapData_->NumMyElements_;
309  BlockMapData_->Comm_->SumAll(&tmp_NumMyElements, &BlockMapData_->NumGlobalElements_, 1);
310  CheckValidNGE(NumGlobal_Elements);
311 
314 
315  // Use the Allreduce function to find min/max GID
316  long long *tmp_send = new long long[2];
317  long long *tmp_recv = new long long[2];
318  if (BlockMapData_->NumMyElements_ > 0 ||
319  BlockMapData_->NumGlobalElements_ == 0) // This test restores behavior for empty map
320  tmp_send[0] = - BlockMapData_->MinMyGID_; // Negative sign lets us do one reduction
321  else
322  tmp_send[0] = -(std::numeric_limits<int_type>::max())-1;
323  tmp_send[1] = BlockMapData_->MaxMyGID_;
324  BlockMapData_->Comm_->MaxAll(tmp_send, tmp_recv, 2);
325  BlockMapData_->MinAllGID_ = - tmp_recv[0];
326  BlockMapData_->MaxAllGID_ = tmp_recv[1];
327  delete [] tmp_send;
328  delete [] tmp_recv;
330  throw ReportError("Minimum global element index = " + toString(BlockMapData_->MinAllGID_) +
331  " is less than index base = " + toString(BlockMapData_->IndexBase_) +".", -5);
332  }
333  else
334  throw ReportError("Internal Error. Report to Epetra developer", -99);
335 
336 
338 }
339 
340 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
341 Epetra_BlockMap::Epetra_BlockMap(long long NumGlobal_Elements, int NumMy_Elements,
342  const long long * myGlobalElements,
343  int Element_Size, int indexBase,
344  const Epetra_Comm& comm)
345  : Epetra_Object("Epetra::BlockMap"),
346  BlockMapData_(0)
347 {
348  const bool IsLongLong = true;
349  ConstructUserConstant(NumGlobal_Elements, NumMy_Elements, myGlobalElements,
350  Element_Size, static_cast<long long>(indexBase), comm, IsLongLong);
351 }
352 
353 Epetra_BlockMap::Epetra_BlockMap(long long NumGlobal_Elements, int NumMy_Elements,
354  const long long * myGlobalElements,
355  int Element_Size, long long indexBase,
356  const Epetra_Comm& comm)
357  : Epetra_Object("Epetra::BlockMap"),
358  BlockMapData_(0)
359 {
360  const bool IsLongLong = true;
361  ConstructUserConstant(NumGlobal_Elements, NumMy_Elements, myGlobalElements,
362  Element_Size, indexBase, comm, IsLongLong);
363 }
364 #endif
365 
366 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
367 Epetra_BlockMap::Epetra_BlockMap(int NumGlobal_Elements, int NumMy_Elements,
368  const int * myGlobalElements,
369  int Element_Size, int indexBase,
370  const Epetra_Comm& comm)
371  : Epetra_Object("Epetra::BlockMap"),
372  BlockMapData_(0)
373 {
374  const bool IsLongLong = false;
375  ConstructUserConstant(NumGlobal_Elements, NumMy_Elements, myGlobalElements,
376  Element_Size, indexBase, comm, IsLongLong);
377 }
378 #endif
379 
380 
381 //==============================================================================
382 // Epetra_BlockMap constructor function for a user-defined arbitrary distribution of variable size elements.
383 template<typename int_type>
384 void Epetra_BlockMap::ConstructUserVariable(int_type NumGlobal_Elements, int NumMy_Elements,
385  const int_type * myGlobalElements,
386  const int *elementSizeList, int_type indexBase,
387  const Epetra_Comm& comm, bool IsLongLong)
388 {
389 
390  int i;
391  // Each processor gets NumMyElements points
392 
393  if (NumGlobal_Elements < -1)
394  throw ReportError("NumGlobal_Elements = " + toString(NumGlobal_Elements) + ". Should be >= -1.", -1);
395  if (NumMy_Elements < 0)
396  throw ReportError("NumMy_Elements = " + toString(NumMy_Elements) + ". Should be >= 0.", -2);
397  for (i = 0; i < NumMy_Elements; i++)
398  if (elementSizeList[i] <= 0)
399  throw ReportError("elementSizeList["+toString(i)+"] = " + toString(elementSizeList[i]) + ". Should be > 0.", -3);
400 
401  BlockMapData_ = new Epetra_BlockMapData(NumGlobal_Elements, 0, indexBase, comm, IsLongLong);
402  BlockMapData_->NumMyElements_ = NumMy_Elements;
404  BlockMapData_->LinearMap_ = false;
405  // Allocate storage for global index list and element size information
406 
407  if (NumMy_Elements > 0) {
408  int errorcode = SizeMyGlobalElement<int_type>(NumMy_Elements);
409  if(errorcode != 0)
410  throw ReportError("Error with MyGlobalElements allocation.", -99);
411  errorcode = BlockMapData_->ElementSizeList_.Size(NumMy_Elements);
412  if(errorcode != 0)
413  throw ReportError("Error with ElementSizeList allocation.", -99);
414  }
415  // Get processor information
416 
417  int NumProc = comm.NumProc();
418 
419  if (NumMy_Elements > 0) {
420  // Compute min/max GID and element size, number of points on this processor
421  BlockMapData_->MinMyGID_ = myGlobalElements[0];
422  BlockMapData_->MaxMyGID_ = myGlobalElements[0];
423  BlockMapData_->MinMyElementSize_ = elementSizeList[0];
424  BlockMapData_->MaxMyElementSize_ = elementSizeList[0];
426  for (i = 0; i < NumMy_Elements; i++) {
427  MyGlobalElementVal<int_type>(i) = myGlobalElements[i];
428  BlockMapData_->ElementSizeList_[i] = elementSizeList[i];
429  BlockMapData_->MinMyGID_ = EPETRA_MIN(BlockMapData_->MinMyGID_,(long long) myGlobalElements[i]);
430  BlockMapData_->MaxMyGID_ = EPETRA_MAX(BlockMapData_->MaxMyGID_,(long long) myGlobalElements[i]);
433  BlockMapData_->NumMyPoints_ += elementSizeList[i];
434  }
435  }
436  else {
442  }
443 
444  BlockMapData_->DistributedGlobal_ = IsDistributedGlobal(NumGlobal_Elements, NumMy_Elements);
445 
446  // Local Map and uniprocessor case: Each processor gets a complete copy of all elements
447  if (!BlockMapData_->DistributedGlobal_ || NumProc == 1) {
449  CheckValidNGE(NumGlobal_Elements);
451 
456  }
457  else if (NumProc > 1) {
458  // Sum up all local element and point counts to get global counts
459  int_type *tmp_send = new int_type[4];
460  int_type *tmp_recv = new int_type[4];
461  tmp_send[0] = BlockMapData_->NumMyElements_;
462  tmp_send[1] = BlockMapData_->NumMyPoints_;
463  BlockMapData_->Comm_->SumAll(tmp_send, tmp_recv, 2);
464  BlockMapData_->NumGlobalElements_ = tmp_recv[0];
465  BlockMapData_->NumGlobalPoints_ = tmp_recv[1];
466 
467  CheckValidNGE(NumGlobal_Elements);
468 
469  // Use the MaxAll function to find min/max GID
470  if (BlockMapData_->NumMyElements_ > 0 ||
471  BlockMapData_->NumGlobalElements_ == 0) // This test restores behavior for empty map
472  tmp_send[0] = - static_cast<int_type>(BlockMapData_->MinMyGID_); // Negative sign lets us do one reduction
473  else
474  tmp_send[0] = -(std::numeric_limits<int_type>::max())-1;
475  tmp_send[1] = static_cast<int_type>(BlockMapData_->MaxMyGID_);
476  tmp_send[2] = - BlockMapData_->MinMyElementSize_;
477  if (BlockMapData_->NumMyElements_ == 0)
478  tmp_send[2] = - static_cast<int_type>(BlockMapData_->NumGlobalPoints_); // This processor has no elements, so should not sizes.
479  tmp_send[3] = BlockMapData_->MaxMyElementSize_;
480 
481  BlockMapData_->Comm_->MaxAll(tmp_send, tmp_recv, 4);
482 
483  BlockMapData_->MinAllGID_ = - tmp_recv[0];
484  BlockMapData_->MaxAllGID_ = tmp_recv[1];
485  BlockMapData_->MinElementSize_ = - (int) tmp_recv[2];
486  BlockMapData_->MaxElementSize_ = (int) tmp_recv[3];
487 
488  delete [] tmp_send;
489  delete [] tmp_recv;
490 
491  // Check for constant element size
495  }
496 
498  throw ReportError("Minimum global element index = " + toString(BlockMapData_->MinAllGID_) +
499  " is less than index base = " + toString(BlockMapData_->IndexBase_) +".", -5);
500  }
501  else
502  throw ReportError("Internal Error. Report to Epetra developer", -99);
503 
504 
506 }
507 
508 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
509 Epetra_BlockMap::Epetra_BlockMap(long long NumGlobal_Elements, int NumMy_Elements,
510  const long long * myGlobalElements,
511  const int *elementSizeList, int indexBase,
512  const Epetra_Comm& comm)
513  : Epetra_Object("Epetra::BlockMap"),
514  BlockMapData_(0)
515 {
516  const bool IsLongLong = true;
517  ConstructUserVariable(NumGlobal_Elements, NumMy_Elements, myGlobalElements,
518  elementSizeList, static_cast<long long>(indexBase), comm, IsLongLong);
519 }
520 
521 Epetra_BlockMap::Epetra_BlockMap(long long NumGlobal_Elements, int NumMy_Elements,
522  const long long * myGlobalElements,
523  const int *elementSizeList, long long indexBase,
524  const Epetra_Comm& comm)
525  : Epetra_Object("Epetra::BlockMap"),
526  BlockMapData_(0)
527 {
528  const bool IsLongLong = true;
529  ConstructUserVariable(NumGlobal_Elements, NumMy_Elements, myGlobalElements,
530  elementSizeList, indexBase, comm, IsLongLong);
531 }
532 #endif
533 
534 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
535 Epetra_BlockMap::Epetra_BlockMap(int NumGlobal_Elements, int NumMy_Elements,
536  const int * myGlobalElements,
537  const int *elementSizeList, int indexBase,
538  const Epetra_Comm& comm)
539  : Epetra_Object("Epetra::BlockMap"),
540  BlockMapData_(0)
541 {
542  const bool IsLongLong = false;
543  ConstructUserVariable(NumGlobal_Elements, NumMy_Elements, myGlobalElements,
544  elementSizeList, indexBase, comm, IsLongLong);
545 }
546 #endif
547 
548 
549 //==============================================================================
550 // Epetra_BlockMap constructor function for a user-defined arbitrary distribution of variable size elements,
551 // with all the information on globals provided by the user.
552 template<typename int_type>
553 void Epetra_BlockMap::ConstructUserConstantNoComm(int_type NumGlobal_Elements, int NumMy_Elements,
554  const int_type * myGlobalElements,
555  int Element_Size, int_type indexBase,
556  const Epetra_Comm& comm, bool IsLongLong,
557  bool UserIsDistributedGlobal,
558  int_type UserMinAllGID, int_type UserMaxAllGID)
559 {
560 
561 
562  int i;
563  // Each processor gets NumMyElements points
564 
565  if (NumGlobal_Elements < -1)
566  throw ReportError("NumGlobal_Elements = " + toString(NumGlobal_Elements) + ". Should be >= -1.", -1);
567  if (NumMy_Elements < 0)
568  throw ReportError("NumMy_Elements = " + toString(NumMy_Elements) + ". Should be >= 0.", -2);
569  if (Element_Size <= 0)
570  throw ReportError("ElementSize = " + toString(Element_Size) + ". Should be > 0.", -3);
571 
572  // Allocate storage for global index list information
573 
574  BlockMapData_ = new Epetra_BlockMapData(NumGlobal_Elements, Element_Size, indexBase, comm, IsLongLong);
575  if (NumMy_Elements > 0) {
576  int errorcode = SizeMyGlobalElement<int_type>(NumMy_Elements);
577  if(errorcode != 0)
578  throw ReportError("Error with MyGlobalElements allocation.", -99);
579  }
580 
581  BlockMapData_->NumMyElements_ = NumMy_Elements;
587  BlockMapData_->LinearMap_ = false;
588  // Get processor information
589 
590  int NumProc = comm.NumProc();
591  if (NumMy_Elements > 0) {
592  // Compute min/max GID on this processor
593  BlockMapData_->MinMyGID_ = myGlobalElements[0];
594  BlockMapData_->MaxMyGID_ = myGlobalElements[0];
595  for (i = 0; i < NumMy_Elements; i++) {
596  MyGlobalElementVal<int_type>(i) = myGlobalElements[i];
597  BlockMapData_->MinMyGID_ = EPETRA_MIN(BlockMapData_->MinMyGID_, (long long) myGlobalElements[i]);
598  BlockMapData_->MaxMyGID_ = EPETRA_MAX(BlockMapData_->MaxMyGID_, (long long) myGlobalElements[i]);
599  }
600  }
601  else {
604  }
605 
606  BlockMapData_->DistributedGlobal_ = UserIsDistributedGlobal;
607 
608  // Local Map and uniprocessor case: Each processor gets a complete copy of all elements
609  if (!BlockMapData_->DistributedGlobal_ || NumProc==1) {
611  CheckValidNGE(NumGlobal_Elements);
614 
617  }
618  else if (NumProc > 1) {
619  if(NumGlobal_Elements==-1) {
620  // Sum up all local element counts to get global count
621  long long tmp_NumMyElements = BlockMapData_->NumMyElements_;
622  BlockMapData_->Comm_->SumAll(&tmp_NumMyElements, &BlockMapData_->NumGlobalElements_, 1);
623  }
624  else {
625  // User provides this information
626  BlockMapData_->NumGlobalElements_ = NumGlobal_Elements;
627  }
629 
632 
633  BlockMapData_->MinAllGID_ = UserMinAllGID;
634  BlockMapData_->MaxAllGID_ = UserMaxAllGID;
636  throw ReportError("Minimum global element index = " + toString(BlockMapData_->MinAllGID_) +
637  " is less than index base = " + toString(BlockMapData_->IndexBase_) +".", -5);
638  }
639  else
640  throw ReportError("Internal Error. Report to Epetra developer", -99);
641 
642 
644 }
645 
646 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
647 Epetra_BlockMap::Epetra_BlockMap(long long NumGlobal_Elements, int NumMy_Elements,
648  const long long * myGlobalElements,
649  int theElementSize, int indexBase,
650  const Epetra_Comm& comm,
651  bool UserIsDistributedGlobal,
652  long long UserMinAllGID, long long UserMaxAllGID)
653  : Epetra_Object("Epetra::BlockMap"),
654  BlockMapData_(0)
655 {
656  const bool IsLongLong = true;
657  ConstructUserConstantNoComm(NumGlobal_Elements, NumMy_Elements, myGlobalElements,
658  theElementSize, (long long) indexBase, comm, IsLongLong,
659  UserIsDistributedGlobal, UserMinAllGID, UserMaxAllGID);
660 }
661 Epetra_BlockMap::Epetra_BlockMap(long long NumGlobal_Elements, int NumMy_Elements,
662  const long long * myGlobalElements,
663  int theElementSize, long long indexBase,
664  const Epetra_Comm& comm,
665  bool UserIsDistributedGlobal,
666  long long UserMinAllGID, long long UserMaxAllGID)
667  : Epetra_Object("Epetra::BlockMap"),
668  BlockMapData_(0)
669 {
670  const bool IsLongLong = true;
671  ConstructUserConstantNoComm(NumGlobal_Elements, NumMy_Elements, myGlobalElements,
672  theElementSize, indexBase, comm, IsLongLong,
673  UserIsDistributedGlobal, UserMinAllGID, UserMaxAllGID);
674 }
675 #endif
676 
677 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
678 Epetra_BlockMap::Epetra_BlockMap(int NumGlobal_Elements, int NumMy_Elements,
679  const int * myGlobalElements,
680  int theElementSize, int indexBase,
681  const Epetra_Comm& comm,
682  bool UserIsDistributedGlobal,
683  int UserMinAllGID, int UserMaxAllGID)
684  : Epetra_Object("Epetra::BlockMap"),
685  BlockMapData_(0)
686 {
687  const bool IsLongLong = false;
688  ConstructUserConstantNoComm(NumGlobal_Elements, NumMy_Elements, myGlobalElements,
689  theElementSize, indexBase, comm, IsLongLong,
690  UserIsDistributedGlobal, UserMinAllGID, UserMaxAllGID);
691 }
692 #endif
693 
694 
695 
696 
697 //==============================================================================
699  : Epetra_Object(map.Label()),
700  BlockMapData_(map.BlockMapData_)
701 {
703 
704  // This call appears to be unnecessary overhead. Removed 10-Aug-2004 maherou.
705  // GlobalToLocalSetup(); // Setup any information for making global index to local index translation fast.
706 }
707 
708 //==============================================================================
710 
711  // Quickest test: See if both maps share an inner data class
712  if (this->BlockMapData_ == Map.BlockMapData_)
713  return(true);
714  return false;
715 }
716 
717 //==============================================================================
718 bool Epetra_BlockMap::SameAs(const Epetra_BlockMap & Map) const {
719 
720  // Quickest test: See if both maps share an inner data class
721  if (this->BlockMapData_ == Map.BlockMapData_)
722  return(true);
723 
724  if(!GlobalIndicesTypeMatch(Map))
725  return(false);
726 
727  // Next check other global properties that are easy global attributes
728  if (BlockMapData_->MinAllGID_ != Map.MinAllGID64() ||
732  return(false);
733 
734  // Last possible global check for constant element sizes
736  return(false);
737 
738  // If we get this far, we need to check local properties and then check across
739  // all processors to see if local properties are all true
740 
741  int numMyElements = BlockMapData_->NumMyElements_;
742 
743  int MySameMap = 1; // Assume not needed
744 
745  // First check if number of element is the same in each map
746  if (numMyElements != Map.NumMyElements()) MySameMap = 0;
747 
748  // If numMyElements is the same, check to see that list of GIDs is the same
749  if (MySameMap==1) {
750  if (LinearMap() && Map.LinearMap() ) {
751  // For linear maps, just need to check whether lower bound is the same
752  if (MinMyGID64() != Map.MinMyGID64() )
753  MySameMap = 0;
754  }
755  else {
756  for (int i = 0; i < numMyElements; i++) {
757  if (GID64(i) != Map.GID64(i)) {
758  MySameMap = 0;
759  break;
760  }
761  }
762  }
763  }
764 // for (int i = 0; i < numMyElements; i++)
765 // if (GID64(i) != Map.GID64(i)) MySameMap = 0;
766 
767  // If GIDs are the same, check to see element sizes are the same
768  if (MySameMap==1 && !BlockMapData_->ConstantElementSize_) {
769  int * sizeList1 = ElementSizeList();
770  int * sizeList2 = Map.ElementSizeList();
771  for (int i = 0; i < numMyElements; i++) if (sizeList1[i] != sizeList2[i]) MySameMap=0;
772  }
773  // Now get min of MySameMap across all processors
774 
775  int GlobalSameMap = 0;
776 #ifdef NDEBUG
777  (void) Comm().MinAll(&MySameMap, &GlobalSameMap, 1);
778 #else
779  // Don't declare 'err' unless we actually use it (in the assert(),
780  // which gets defined away in a release build).
781  int err = Comm().MinAll(&MySameMap, &GlobalSameMap, 1);
782  assert(err==0);
783 #endif // NDEBUG
784  return(GlobalSameMap==1);
785 }
786 
787 //==============================================================================
789 {
790  if (this->BlockMapData_ == Map.BlockMapData_)
791  return(true);
792 
793  if(!GlobalIndicesTypeMatch(Map))
794  return(false);
795 
797  return(false);
798 
799  // If we get this far, we need to check local properties and then check across
800  // all processors to see if local properties are all true
801 
802  int MySameMap = 1; // Assume not needed
803  if (BlockMapData_->NumMyPoints_ != Map.NumMyPoints())
804  MySameMap = 0;
805 
806  int GlobalSameMap = 0;
807 
808 #ifdef NDEBUG
809  (void) Comm().MinAll(&MySameMap, &GlobalSameMap, 1);
810 #else
811  // Don't declare 'err' unless we actually use it (in the assert(),
812  // which gets defined away in a release build).
813  int err = Comm().MinAll(&MySameMap, &GlobalSameMap, 1);
814  assert( err == 0 );
815 #endif // NDEBUG
816 
817  return(GlobalSameMap==1);
818 }
819 
820 //==============================================================================
821 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
822 int Epetra_BlockMap::MyGlobalElements(long long * myGlobalElements) const
823 {
824  // Although one can populate long long data from int data, we don't
825  // allow it to maintain int/long long symmetry.
827  throw ReportError("Epetra_BlockMap::MyGlobalElements(long long *) ERROR, Can't call for non long long* map.",-1);
828 
829  // If the global element list is not create, then do so. This can only happen when
830  // a linear distribution has been specified. Thus we can easily construct the update
831  // list in this case.
832 
833  int i;
834  int numMyElements = BlockMapData_->NumMyElements_;
835 
837  for (i = 0; i < numMyElements; i++)
838  myGlobalElements[i] = BlockMapData_->MinMyGID_ + i;
839  else
840  for (i = 0; i < numMyElements; i++)
841  myGlobalElements[i] = BlockMapData_->MyGlobalElements_LL_[i];
842  return(0);
843 }
844 #endif
845 
846 //==============================================================================
847 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
848 int Epetra_BlockMap::MyGlobalElements(int * myGlobalElements) const
849 {
851  throw ReportError("Epetra_BlockMap::MyGlobalElements(int *) ERROR, Can't call for non int* map.",-1);
852 
853  // If the global element list is not create, then do so. This can only happen when
854  // a linear distribution has been specified. Thus we can easily construct the update
855  // list in this case.
856 
857  int i;
858  int numMyElements = BlockMapData_->NumMyElements_;
859 
861  for (i = 0; i < numMyElements; i++)
862  myGlobalElements[i] = (int) BlockMapData_->MinMyGID_ + i;
863  else
864  for (i = 0; i < numMyElements; i++)
865  myGlobalElements[i] = (int) BlockMapData_->MyGlobalElements_int_[i];
866  return(0);
867 }
868 #endif
869 
870 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
871 int Epetra_BlockMap::MyGlobalElementsPtr(long long *& MyGlobalElementList) const
872 {
873  MyGlobalElementList = MyGlobalElements64();
874  return(0);
875 }
876 #endif
877 
878 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
879 int Epetra_BlockMap::MyGlobalElementsPtr(int *& MyGlobalElementList) const
880 {
881  MyGlobalElementList = MyGlobalElements();
882  return(0);
883 }
884 #endif
885 //==============================================================================
886 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
889  throw ReportError("Epetra_BlockMap::MyGlobalElements() ERROR, Can't call for non int* map.",-1);
890 
891  int numMyElements = BlockMapData_->NumMyElements_;
892 
893  // If ElementSizeList not built, do so
894  if(BlockMapData_->MyGlobalElements_int_.Length() == 0 && numMyElements > 0) {
895  int errorcode = BlockMapData_->MyGlobalElements_int_.Size(numMyElements + 1);
896  if(errorcode != 0)
897  throw ReportError("Error with MyGlobalElements allocation.", -99);
898 
899  // Build the array
900  for (int i = 0; i < numMyElements; i++)
902  }
904 }
905 #endif
906 //==============================================================================
907 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
910  throw ReportError("Epetra_BlockMap::MyGlobalElements64 ERROR, Can't call for non long long* map.",-1);
911 
912  int numMyElements = BlockMapData_->NumMyElements_;
913 
914  // If ElementSizeList not built, do so
915  if(BlockMapData_->MyGlobalElements_LL_.Length() == 0 && numMyElements > 0) {
916  int errorcode = BlockMapData_->MyGlobalElements_LL_.Size(numMyElements + 1);
917  if(errorcode != 0)
918  throw ReportError("Error with MyGlobalElements allocation.", -99);
919 
920  // Build the array
921  for (int i = 0; i < numMyElements; i++)
923  }
925 }
926 #endif
927 //==============================================================================
929 {
930  if (!MyLID(lid))
931  EPETRA_CHK_ERR(-1);
932 
933  int entry;
934 
935  if (ConstantElementSize())
936  entry = MaxElementSize() * lid; // convert to vector entry
937  else {
938  int * entrylist = FirstPointInElementList(); // get entry list
939  entry = entrylist[lid];
940  }
941  return(entry);
942 }
943 
944 //==============================================================================
945 int Epetra_BlockMap::FirstPointInElementList(int * firstPointInElementList) const
946 {
947  // If the first element entry list is not create, then do so.
948 
949  // Note: This array is of length NumMyElement+1
950 
951  int i;
952  int numMyElements = BlockMapData_->NumMyElements_;
953 
955  firstPointInElementList[0] = 0; // First element of first entry is always zero
956 
958  for (i = 0; i < numMyElements; i++)
959  firstPointInElementList[i+1] = firstPointInElementList[i] + BlockMapData_->ElementSize_;
960  else
961  for (i = 0; i < numMyElements; i++)
962  firstPointInElementList[i+1] = firstPointInElementList[i] + BlockMapData_->ElementSizeList_[i];
963  }
964  else
965  for (i = 0; i <= numMyElements; i++)
966  firstPointInElementList[i] = BlockMapData_->FirstPointInElementList_[i];
967  return(0);
968 }
969 
970 //==============================================================================
972  int numMyElements = BlockMapData_->NumMyElements_;
973 
974  // If ElementSizeList not built, do so
975  if ((BlockMapData_->FirstPointInElementList_.Length() == 0) && (numMyElements > 0)) {
977  BlockMapData_->FirstPointInElementList_[0] = 0; // First element of first entry is always zero
979  for (int i = 0; i < numMyElements; i++)
981  else
982  for (int i = 0; i < numMyElements; i++)
984  }
986 }
987 
988 //==============================================================================
989 int Epetra_BlockMap::ElementSizeList(int * elementSizeList) const
990 {
991  // If the element size list is not create, then do so. This can only happen when
992  // a constant element size has been specified. Thus we can easily construct the element size
993  // list in this case.
994 
995  int i;
996  int numMyElements = BlockMapData_->NumMyElements_;
997 
999  for (i = 0; i < numMyElements; i++)
1000  elementSizeList[i] = BlockMapData_->ElementSize_;
1001  else
1002  for (i = 0; i < numMyElements; i++)
1003  elementSizeList[i] = BlockMapData_->ElementSizeList_[i];
1004 
1005  return(0);
1006 }
1007 
1008 //==============================================================================
1010  int numMyElements = BlockMapData_->NumMyElements_;
1011 
1012  // If ElementSizeList not built, do so
1013  if ((BlockMapData_->ElementSizeList_.Length() == 0) && (numMyElements > 0)) {
1014  BlockMapData_->ElementSizeList_.Size(numMyElements);
1015  for (int i = 0; i < numMyElements; i++)
1017  }
1019 }
1020 
1021 //==============================================================================
1022 int Epetra_BlockMap::PointToElementList(int * pointToElementList) const {
1023  // Build an array such that the local element ID is stored for each point
1024 
1025  int i;
1027  int numMyElements = BlockMapData_->NumMyElements_;
1028  int * ptr = pointToElementList;
1029  for (i = 0; i < numMyElements; i++) {
1030  int Size = ElementSize(i);
1031  for (int j = 0; j < Size; j++)
1032  *ptr++ = i;
1033  }
1034  }
1035  else {
1036  int numMyPoints = BlockMapData_->NumMyPoints_;
1037  for (i = 0; i < numMyPoints; i++)
1038  pointToElementList[i] = BlockMapData_->PointToElementList_[i];
1039  }
1040  return(0);
1041 }
1042 
1043 //==============================================================================
1045 
1046  // If PointToElementList not built, do so
1049  int numMyElements = BlockMapData_->NumMyElements_;
1050  int * ptr = BlockMapData_->PointToElementList_.Values();
1051  for (int i = 0; i < numMyElements; i++) {
1052  int Size = ElementSize(i);
1053  for (int j = 0; j < Size; j++)
1054  *ptr++ = i;
1055  }
1056  }
1058 }
1059 
1060 //==============================================================================
1061 int Epetra_BlockMap::ElementSize(int lid) const {
1062 
1063  if (ConstantElementSize())
1064  return(BlockMapData_->ElementSize_);
1065  else
1066  return(BlockMapData_->ElementSizeList_[lid]);
1067 }
1068 
1069 //==============================================================================
1074  }
1075  return(BlockMapData_->OneToOne_);
1076 }
1077 
1078 //==============================================================================
1079 template<typename int_type>
1081 {
1082  int i;
1083  int numMyElements = BlockMapData_->NumMyElements_;
1084 
1085  if (BlockMapData_->NumGlobalElements_ == 0) {
1086  return; // Nothing to do
1087  }
1088 
1089  if (LinearMap() || numMyElements == 0) {
1090  return; // Nothing else to do
1091  }
1092 
1093  // Build LID_ vector to make look up of local index values fast
1094 
1095 #ifdef EPETRA_BLOCKMAP_NEW_LID
1096 
1097  // Here follows an optimization that checks for an initial block of
1098  // contiguous GIDs, and stores the GID->LID mapping for those in a
1099  // more efficient way. This supports a common use case for
1100  // overlapping Maps, in which owned entries of a vector are ordered
1101  // before halo entries.
1102  //
1103  // Epetra defines EPETRA_BLOCKMAP_NEW_LID by default (see the top of
1104  // this file).
1105 
1106  //check for initial contiguous block
1107  int_type val = MyGlobalElementValGet<int_type>(0);
1108  for( i = 0 ; i < numMyElements; ++i ) {
1109  if (val != MyGlobalElementValGet<int_type>(i)) break;
1110  ++val;
1111  }
1114  BlockMapData_->LastContiguousGID_ = MyGlobalElementValGet<int_type>(0);
1115  }
1116  else {
1118  MyGlobalElementValGet<int_type>(BlockMapData_->LastContiguousGIDLoc_);
1119  }
1120 
1121  //Hash everything else
1122  if(i < numMyElements) {
1123  if (BlockMapData_->LIDHash_ != NULL) {
1124  delete BlockMapData_->LIDHash_;
1125  }
1126 
1127  BlockMapData_->LIDHash_ = new Epetra_HashTable<int>(numMyElements - i + 1 );
1128  for(; i < numMyElements; ++i )
1129  BlockMapData_->LIDHash_->Add( MyGlobalElementValGet<int_type>(i), i );
1130  }
1131 
1132 #else
1133 
1134  int SpanGID = BlockMapData_->MaxMyGID_ - BlockMapData_->MinMyGID_ + 1;
1135  BlockMapData_->LID_.Size(SpanGID);
1136 
1137  for (i = 0; i < SpanGID; i++)
1138  BlockMapData_->LID_[i] = -1; // Fill all locations with -1
1139 
1140  for (i = 0; i < numMyElements; i++) {
1141  int tmp = MyGlobalElementValGet<int_type>(i) - BlockMapData_->MinMyGID_;
1142  assert(tmp >= 0);
1143  assert(tmp < SpanGID);
1144  BlockMapData_->LID_[MyGlobalElementValGet<int_type>(i) - BlockMapData_->MinMyGID_] = i; // Spread local indices
1145  }
1146 
1147 #endif
1148 
1149 }
1150 
1152 {
1154  {
1155 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
1156  TGlobalToLocalSetup<int>();
1157 #else
1158  throw ReportError("Epetra_BlockMap::GlobalToLocalSetup ERROR, GlobalIndices int but no API for it.",-1);
1159 #endif
1160  }
1162  {
1163 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
1164  TGlobalToLocalSetup<long long>();
1165 #else
1166  throw ReportError("Epetra_BlockMap::GlobalToLocalSetup ERROR, GlobalIndices long long but no API for it.",-1);
1167 #endif
1168  }
1169  else
1170  {
1171  throw ReportError("Epetra_BlockMap::GlobalToLocalSetup ERROR, GlobalIndices type unknown.",-1);
1172  }
1173 }
1174 
1175 //==============================================================================
1176 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
1177 int Epetra_BlockMap::LID(long long gid) const
1178 {
1179  if ((gid < BlockMapData_->MinMyGID_) ||
1180  (gid > BlockMapData_->MaxMyGID_)) {
1181  return(-1); // Out of range
1182  }
1183 
1184  if (BlockMapData_->LinearMap_) {
1185  return (int) (gid - BlockMapData_->MinMyGID_); // Can compute with an offset
1186  }
1187 
1188 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
1190  if( (int) gid >= BlockMapData_->MyGlobalElements_int_[0] &&
1191  (int) gid <= BlockMapData_->LastContiguousGID_ ) {
1192  return (int) gid - BlockMapData_->MyGlobalElements_int_[0];
1193  }
1194  }
1195  else
1196 #endif
1197 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
1199  if( gid >= BlockMapData_->MyGlobalElements_LL_[0] &&
1200  gid <= BlockMapData_->LastContiguousGID_ ) {
1201  return (int) ( gid - BlockMapData_->MyGlobalElements_LL_[0] );
1202  }
1203  }
1204  else
1205 #endif
1206  throw ReportError("Epetra_BlockMap::LID ERROR, GlobalIndices type unknown.",-1);
1207 
1208 #ifdef EPETRA_BLOCKMAP_NEW_LID
1209  return BlockMapData_->LIDHash_->Get( gid );
1210 #else
1211  return(BlockMapData_->LID_[gid - BlockMapData_->MinMyGID_]); // Find it in LID array
1212 #endif
1213 }
1214 #endif
1215 
1216 //==============================================================================
1217 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
1218 int Epetra_BlockMap::LID(int gid) const
1219 {
1220  if ((gid < (int) BlockMapData_->MinMyGID_) ||
1221  (gid > (int) BlockMapData_->MaxMyGID_)) {
1222  return(-1); // Out of range
1223  }
1224 
1225  if (BlockMapData_->LinearMap_) {
1226  return (int) (gid - (int) BlockMapData_->MinMyGID_); // Can compute with an offset
1227  }
1228 
1230  if( gid >= BlockMapData_->MyGlobalElements_int_[0] &&
1231  gid <= (int) BlockMapData_->LastContiguousGID_ ) {
1232  return (int) ( gid - BlockMapData_->MyGlobalElements_int_[0] );
1233  }
1234  }
1236  throw ReportError("Epetra_BlockMap::LID ERROR, int version called for long long map.",-1);
1237  }
1238  else {
1239  throw ReportError("Epetra_BlockMap::LID ERROR, GlobalIndices type unknown.",-1);
1240  }
1241 
1242 #ifdef EPETRA_BLOCKMAP_NEW_LID
1243  return BlockMapData_->LIDHash_->Get( gid );
1244 #else
1245  return(BlockMapData_->LID_[gid - BlockMapData_->MinMyGID_]); // Find it in LID array
1246 #endif
1247 }
1248 #endif
1249 
1250 //==============================================================================
1251 
1252 long long Epetra_BlockMap::GID64(int lid) const
1253 {
1254  if ((BlockMapData_->NumMyElements_==0) ||
1255  (lid < BlockMapData_->MinLID_) ||
1256  (lid > BlockMapData_->MaxLID_)) {
1257  return(BlockMapData_->IndexBase_ - 1); // Out of range
1258  }
1259 
1260  if (LinearMap()) {
1261  return(lid + BlockMapData_->MinMyGID_); // Can compute with an offset
1262  }
1263 
1264 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
1266  {
1267  return(BlockMapData_->MyGlobalElements_int_[lid]); // Find it in MyGlobalElements array
1268  }
1269  else
1270 #endif
1271 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
1273  {
1274  return(BlockMapData_->MyGlobalElements_LL_[lid]); // Find it in MyGlobalElements array
1275  }
1276  else
1277 #endif
1278  throw ReportError("Epetra_BlockMap::GID64 ERROR, GlobalIndices type unknown.",-1);
1279 }
1280 
1281 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
1282 int Epetra_BlockMap::GID(int lid) const
1283 {
1285  {
1286  if ((BlockMapData_->NumMyElements_==0) ||
1287  (lid < BlockMapData_->MinLID_) ||
1288  (lid > BlockMapData_->MaxLID_)) {
1289  return((int) BlockMapData_->IndexBase_ - 1); // Out of range
1290  }
1291 
1292  if (LinearMap()) {
1293  return(lid + (int) BlockMapData_->MinMyGID_); // Can compute with an offset
1294  }
1295 
1296  return(BlockMapData_->MyGlobalElements_int_[lid]); // Find it in MyGlobalElements array
1297  }
1298 
1299  throw ReportError("Epetra_BlockMap::GID ERROR, GlobalIndices type unknown or long long.",-1);
1300 }
1301 #endif
1302 
1303 //==============================================================================
1304 int Epetra_BlockMap::FindLocalElementID(int PointID, int & ElementID, int & ElementOffset) const {
1305 
1306  if (PointID >= BlockMapData_->NumMyPoints_)
1307  return(-1); // Point is out of range
1308 
1309  if (ConstantElementSize()) {
1310  ElementID = PointID / BlockMapData_->MaxElementSize_;
1311  ElementOffset = PointID % BlockMapData_->MaxElementSize_;
1312  return(0);
1313  }
1314  else {
1315  int * tmpPointToElementList = PointToElementList();
1316  int * tmpFirstPointInElementList = FirstPointInElementList();
1317  ElementID = tmpPointToElementList[PointID];
1318  ElementOffset = PointID - tmpFirstPointInElementList[ElementID];
1319  return(0);
1320  }
1321 }
1322 
1323 //==============================================================================
1324 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
1325 int Epetra_BlockMap::RemoteIDList(int NumIDs, const int * GIDList,
1326  int * PIDList, int * LIDList,
1327  int * SizeList) const
1328 {
1330  throw ReportError("Epetra_BlockMap::RemoteIDList ERROR, Can't call int* version for non int* map.",-1);
1331 
1332  if (BlockMapData_->Directory_ == NULL) {
1334  }
1335 
1337  if (directory == NULL) {
1338  return(-1);
1339  }
1340 
1341  EPETRA_CHK_ERR( directory->GetDirectoryEntries(*this, NumIDs, GIDList,
1342  PIDList, LIDList, SizeList) );
1343 
1344  return(0);
1345 }
1346 #endif
1347 //==============================================================================
1348 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
1349 int Epetra_BlockMap::RemoteIDList(int NumIDs, const long long * GIDList,
1350  int * PIDList, int * LIDList,
1351  int * SizeList) const
1352 {
1354  throw ReportError("Epetra_BlockMap::RemoteIDList ERROR, Can't call long long* version for non long long* map.",-1);
1355 
1356  if (BlockMapData_->Directory_ == NULL) {
1358  }
1359 
1361  if (directory == NULL) {
1362  return(-1);
1363  }
1364 
1365  EPETRA_CHK_ERR( directory->GetDirectoryEntries(*this, NumIDs, GIDList,
1366  PIDList, LIDList, SizeList) );
1367 
1368  return(0);
1369 }
1370 #endif
1371 
1372 //==============================================================================
1374 {
1375  if (Comm().NumProc() < 2) {
1376  return(true);
1377  }
1378 
1379  if (BlockMapData_->Directory_ == NULL) {
1381  }
1382 
1384  if (directory == NULL) {
1385  throw ReportError("Epetra_BlockMap::IsOneToOne ERROR, CreateDirectory failed.",-1);
1386  }
1387 
1388  return(directory->GIDsAllUniquelyOwned());
1389 }
1390 
1391 //==============================================================================
1392 bool Epetra_BlockMap::IsDistributedGlobal(long long numGlobalElements, int numMyElements) const {
1393 
1394  bool isDistributedGlobal = false; // Assume map is not global distributed
1395  if (BlockMapData_->Comm_->NumProc() > 1) {
1396  int LocalReplicated = 0;
1397  int AllLocalReplicated;
1398  if (numGlobalElements == numMyElements)
1399  LocalReplicated=1;
1400  BlockMapData_->Comm_->MinAll(&LocalReplicated, &AllLocalReplicated, 1);
1401 
1402  // If any PE has LocalReplicated=0, then map is distributed global
1403  if (AllLocalReplicated != 1)
1404  isDistributedGlobal = true;
1405  }
1406  return(isDistributedGlobal);
1407 }
1408 
1409 //==============================================================================
1410 void Epetra_BlockMap::CheckValidNGE(long long numGlobalElements) {
1411  // Check to see if user's value for numGlobalElements is either -1
1412  // (in which case we use our computed value) or matches ours.
1413  if ((numGlobalElements != -1) && (numGlobalElements != BlockMapData_->NumGlobalElements_)) {
1414  long long BmdNumGlobalElements = BlockMapData_->NumGlobalElements_;
1415  CleanupData();
1416  throw ReportError("Invalid NumGlobalElements. NumGlobalElements = " + toString(numGlobalElements) +
1417  ". Should equal " + toString(BmdNumGlobalElements) +
1418  ", or be set to -1 to compute automatically", -4);
1419  }
1420 }
1421 
1422 //==============================================================================
1424  BlockMapData_->MinLID_ = 0;
1426 
1427  GlobalToLocalSetup(); // Setup any information for making global index to local index translation fast.
1428 }
1429 
1430 //==============================================================================
1431 void Epetra_BlockMap::Print(std::ostream & os) const
1432 {
1433  int * FirstPointInElementList1 = 0;
1434  int * ElementSizeList1 = 0;
1435  if (!ConstantElementSize()) {
1436  FirstPointInElementList1 = FirstPointInElementList();
1437  ElementSizeList1 = ElementSizeList();
1438  }
1439  int MyPID = Comm().MyPID();
1440  int NumProc = Comm().NumProc();
1441 
1442  for (int iproc = 0; iproc < NumProc; iproc++) {
1443  if (MyPID == iproc) {
1444  if (MyPID == 0) {
1445  os << "\nNumber of Global Elements = "; os << NumGlobalElements64(); os << std::endl;
1446  os << "Number of Global Points = "; os << NumGlobalPoints64(); os << std::endl;
1447  os << "Maximum of all GIDs = "; os << MaxAllGID64(); os << std::endl;
1448  os << "Minimum of all GIDs = "; os << MinAllGID64(); os << std::endl;
1449  os << "Index Base = "; os << IndexBase64(); os << std::endl;
1450  if (ConstantElementSize()) {
1451  os << "Constant Element Size = "; os << ElementSize(); os << std::endl;
1452  }
1453  }
1454  os << std::endl;
1455 
1456  os << "Number of Local Elements = "; os << NumMyElements(); os << std::endl;
1457  os << "Number of Local Points = "; os << NumMyPoints(); os << std::endl;
1458  os << "Maximum of my GIDs = "; os << MaxMyGID64(); os << std::endl;
1459  os << "Minimum of my GIDs = "; os << MinMyGID64(); os << std::endl;
1460  os << std::endl;
1461 
1462  os.width(14);
1463  os << " MyPID"; os << " ";
1464  os.width(14);
1465  os << " Local Index "; os << " ";
1466  os.width(14);
1467  os << " Global Index "; os << " ";
1468  if (!ConstantElementSize()) {
1469  os.width(14);
1470  os <<" FirstPointInElement "; os << " ";
1471  os.width(14);
1472  os <<" ElementSize "; os << " ";
1473  }
1474  os << std::endl;
1475 
1476  for (int i = 0; i < NumMyElements(); i++) {
1477  os.width(14);
1478  os << MyPID; os << " ";
1479  os.width(14);
1480  os << i; os << " ";
1481  os.width(14);
1482 
1484  {
1485 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
1486  long long * MyGlobalElements1 = MyGlobalElements64();
1487  os << MyGlobalElements1[i]; os << " ";
1488 #else
1489  throw ReportError("Epetra_BlockMap::Print: ERROR, GlobalIndicesLongLong but no API for it.",-1);
1490 #endif
1491  }
1493  {
1494 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
1495  int * MyGlobalElements1 = MyGlobalElements();
1496  os << MyGlobalElements1[i]; os << " ";
1497 #else
1498  throw ReportError("Epetra_BlockMap::Print: ERROR, no GlobalIndicesLongLong but no API for it.",-1);
1499 #endif
1500  }
1501 
1502  if (!ConstantElementSize()) {
1503  os.width(14);
1504  os << FirstPointInElementList1[i]; os << " ";
1505  os.width(14);
1506  os << ElementSizeList1[i]; os << " ";
1507  }
1508  os << std::endl;
1509  }
1510 
1511  os << std::flush;
1512 
1513  }
1514  // Do a few global ops to give I/O a chance to complete
1515  Comm().Barrier();
1516  Comm().Barrier();
1517  Comm().Barrier();
1518  }
1519  return;
1520 }
1521 
1522 //==============================================================================
1524  CleanupData();
1525 }
1526 
1527 //==============================================================================
1529 {
1530  if(BlockMapData_ != 0) {
1531 
1533  if(BlockMapData_->ReferenceCount() == 0) {
1534  delete BlockMapData_;
1535  BlockMapData_ = 0;
1536  }
1537  }
1538 }
1539 
1540 //=============================================================================
1542 {
1543  if((this != &map) && (BlockMapData_ != map.BlockMapData_)) {
1544  CleanupData();
1547  }
1548 
1549  return(*this);
1550 }
1551 
1552 //=============================================================================
1554 {
1555 #ifdef HAVE_MPI
1556  const Epetra_MpiComm * MpiComm = dynamic_cast<const Epetra_MpiComm*>(&Comm());
1557 
1558  // If the Comm isn't MPI, just treat this as a copy constructor
1559  if(!MpiComm) return new Epetra_BlockMap(*this);
1560 
1561  MPI_Comm NewComm,MyMPIComm = MpiComm->Comm();
1562 
1563  // Create the new communicator. MPI_Comm_split returns a valid
1564  // communicator on all processes. On processes where color == MPI_UNDEFINED,
1565  // ignore the result. Passing key == 0 tells MPI to order the
1566  // processes in the new communicator by their rank in the old
1567  // communicator.
1568  const int color = (NumMyElements() == 0) ? MPI_UNDEFINED : 1;
1569 
1570  // MPI_Comm_split must be called collectively over the original
1571  // communicator. We can't just call it on processes with color
1572  // one, even though we will ignore its result on processes with
1573  // color zero.
1574  int rv = MPI_Comm_split(MyMPIComm,color,0,&NewComm);
1575  if(rv!=MPI_SUCCESS) throw ReportError("Epetra_BlockMap::RemoveEmptyProcesses: MPI_Comm_split failed.",-1);
1576 
1577  if(color == MPI_UNDEFINED)
1578  return 0; // We're not in the new map
1579  else {
1580  Epetra_MpiComm * NewEpetraComm = new Epetra_MpiComm(NewComm);
1581 
1582  // Use the copy constructor for a new map, but basically because it does nothing useful
1583  Epetra_BlockMap * NewMap = new Epetra_BlockMap(*this);
1584 
1585  // Get rid of the old BlockMapData, now make a new one from scratch...
1586  NewMap->CleanupData();
1587  if(GlobalIndicesInt()) {
1588 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
1589  NewMap->BlockMapData_ = new Epetra_BlockMapData(NumGlobalElements(),0,IndexBase(),*NewEpetraComm,false);
1590 #endif
1591  }
1592  else {
1593 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
1594  NewMap->BlockMapData_ = new Epetra_BlockMapData(NumGlobalElements64(),0,IndexBase64(),*NewEpetraComm,true);
1595 #endif
1596  }
1597  // Now copy all of the relevent bits of BlockMapData...
1598  // NewMap->BlockMapData_->Comm_ = NewEpetraComm;
1599  NewMap->BlockMapData_->LID_ = BlockMapData_->LID_;
1600 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
1602 #endif
1603 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
1605 #endif
1609 
1628  NewMap->BlockMapData_->DistributedGlobal_ = NewEpetraComm->NumProc()==1 ? false : BlockMapData_->DistributedGlobal_;
1636 
1637  // Delay directory construction
1638  NewMap->BlockMapData_->Directory_ = 0;
1639 
1640  // Cleanup
1641  delete NewEpetraComm;
1642 
1643  return NewMap;
1644  }
1645 #else
1646  // MPI isn't compiled, so just treat this as a copy constructor
1647  return new Epetra_BlockMap(*this);
1648 #endif
1649 }
1650 
1651 //=============================================================================
1653 {
1654  // mfh 26 Mar 2013: The lazy way to do this is simply to recreate
1655  // the Map by calling its ordinary public constructor, using the
1656  // original Map's data. This only involves O(1) all-reduces over
1657  // the new communicator, which in the common case only includes a
1658  // small number of processes.
1659  Epetra_BlockMap * NewMap=0;
1660 
1661  // Create the Map to return (unless theComm is zero, in which case we return zero).
1662  if (theComm) {
1663  // Map requires that the index base equal the global min GID.
1664  // Figuring out the global min GID requires a reduction over all
1665  // processes in the new communicator. It could be that some (or
1666  // even all) of these processes contain zero entries. (Recall
1667  // that this method, unlike removeEmptyProcesses(), may remove
1668  // an arbitrary subset of processes.) We deal with this by
1669  // doing a min over the min GID on each process if the process
1670  // has more than zero entries, or the global max GID, if that
1671  // process has zero entries. If no processes have any entries,
1672  // then the index base doesn't matter anyway.
1673 
1674 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
1675  if(GlobalIndicesInt()) {
1676  int MyMin, theIndexBase;
1677  MyMin = NumMyElements() > 0 ? MinMyGID() : MaxAllGID();
1678  theComm->MinAll(&MyMin,&theIndexBase,1);
1679  NewMap = new Epetra_BlockMap(-1,NumMyElements(),MyGlobalElements(),ElementSizeList(),theIndexBase,*theComm);
1680  }
1681  else
1682 #endif
1683 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
1684  if(GlobalIndicesLongLong()) {
1685  long long MyMin, theIndexBase;
1686  MyMin = NumMyElements() > 0 ? MinMyGID64() : MaxAllGID64();
1687  theComm->MinAll(&MyMin,&theIndexBase,1);
1688  NewMap = new Epetra_BlockMap(-1,NumMyElements(),MyGlobalElements64(),ElementSizeList(),theIndexBase,*theComm);
1689  }
1690  else
1691 #endif
1692  throw ReportError("Epetra_BlockMap::ReplaceCommWithSubset ERROR, GlobalIndices type unknown.",-1);
1693  }
1694  return NewMap;
1695 }
Epetra_Object
Epetra_Object: The base Epetra class.
Definition: Epetra_Object.h:57
Epetra_BlockMapData::MyGlobalElements_LL_
Epetra_LongLongSerialDenseVector MyGlobalElements_LL_
Definition: Epetra_BlockMapData.h:90
Epetra_BlockMap::Comm
const Epetra_Comm & Comm() const
Access function for Epetra_Comm communicator.
Definition: Epetra_BlockMap.h:770
Epetra_IntSerialDenseVector.h
Epetra_Data::DecrementReferenceCount
void DecrementReferenceCount()
Decrement reference count.
Definition: Epetra_Data.cpp:66
Epetra_BlockMap::Print
virtual void Print(std::ostream &os) const
Print object to an output stream.
Definition: Epetra_BlockMap.cpp:1431
Epetra_BlockMap::NumMyElements
int NumMyElements() const
Number of elements on the calling processor.
Definition: Epetra_BlockMap.h:555
Epetra_HashTable::Get
value_type Get(const long long key)
Definition: Epetra_HashTable.h:126
Epetra_Comm::NumProc
virtual int NumProc() const =0
Returns total number of processes.
Epetra_BlockMapData::LinearMap_
bool LinearMap_
Definition: Epetra_BlockMapData.h:114
Epetra_BlockMap::GlobalIndicesInt
bool GlobalIndicesInt() const
Returns true if map create with int NumGlobalElements.
Definition: Epetra_BlockMap.h:653
Epetra_HashTable::Add
void Add(const long long key, const value_type value)
Definition: Epetra_HashTable.h:119
EPETRA_MIN
#define EPETRA_MIN(x, y)
Definition: Epetra_ConfigDefs.h:63
Epetra_BlockMapData::MinLID_
int MinLID_
Definition: Epetra_BlockMapData.h:108
Epetra_BlockMapData::DistributedGlobal_
bool DistributedGlobal_
Definition: Epetra_BlockMapData.h:115
Epetra_BlockMap::ElementSize
int ElementSize() const
Returns the size of elements in the map; only valid if map has constant element size.
Definition: Epetra_BlockMap.h:573
Epetra_BlockMapData::Comm_
const Epetra_Comm * Comm_
Definition: Epetra_BlockMapData.h:81
Epetra_Directory.h
Epetra_BlockMapData::LastContiguousGIDLoc_
int LastContiguousGIDLoc_
Definition: Epetra_BlockMapData.h:122
Epetra_BlockMap::SameBlockMapDataAs
bool SameBlockMapDataAs(const Epetra_BlockMap &Map) const
Returns true if maps share same block map data underneath.
Definition: Epetra_BlockMap.cpp:709
Epetra_BlockMap::operator=
Epetra_BlockMap & operator=(const Epetra_BlockMap &map)
Assignment Operator.
Definition: Epetra_BlockMap.cpp:1541
Epetra_BlockMap::ConstructUserLinear
void ConstructUserLinear(long long NumGlobal_Elements, int NumMy_Elements, int Element_Size, long long Index_Base, const Epetra_Comm &comm, bool IsLongLong)
Definition: Epetra_BlockMap.cpp:140
Epetra_BlockMapData::NumMyPoints_
int NumMyPoints_
Definition: Epetra_BlockMapData.h:111
Epetra_MpiComm::NumProc
int NumProc() const
Returns total number of processes.
Definition: Epetra_MpiComm.h:469
Epetra_BlockMap::MinAllGID64
long long MinAllGID64() const
Definition: Epetra_BlockMap.h:503
Epetra_BlockMap::RemoteIDList
int RemoteIDList(int NumIDs, const int *GIDList, int *PIDList, int *LIDList) const
Returns the processor IDs and corresponding local index value for a given list of global indices.
Definition: Epetra_BlockMap.h:430
Epetra_LongLongSerialDenseVector::Size
int Size(int Length_in)
Set length of a Epetra_LongLongSerialDenseVector object; init values to zero.
Definition: Epetra_LongLongSerialDenseVector.h:142
EPETRA_CHK_ERR
#define EPETRA_CHK_ERR(a)
Definition: Epetra_ConfigDefs.h:307
Epetra_BlockMap::Epetra_BlockMap
Epetra_BlockMap(int NumGlobalElements, int ElementSize, int IndexBase, const Epetra_Comm &Comm)
Epetra_BlockMap constructor for a Epetra-defined uniform linear distribution of constant size element...
Definition: Epetra_BlockMap.cpp:129
Epetra_HashTable< int >
Epetra_BlockMapData::ConstantElementSize_
bool ConstantElementSize_
Definition: Epetra_BlockMapData.h:113
Epetra_BlockMap::ConstructUserVariable
void ConstructUserVariable(int_type NumGlobal_Elements, int NumMy_Elements, const int_type *myGlobalElements, const int *elementSizeList, int_type indexBase, const Epetra_Comm &comm, bool IsLongLong)
Definition: Epetra_BlockMap.cpp:384
Epetra_BlockMap::MinMyGID
int MinMyGID() const
Returns the minimum global ID owned by this processor.
Definition: Epetra_BlockMap.h:517
Epetra_Comm::MinAll
virtual int MinAll(double *PartialMins, double *GlobalMins, int Count) const =0
Epetra_Comm Global Min function.
Epetra_BlockMap::LID
int LID(int GID) const
Returns local ID of global ID, return -1 if not found on this processor.
Definition: Epetra_BlockMap.cpp:1218
Epetra_HashTable.h
Epetra_Comm::Barrier
virtual void Barrier() const =0
Epetra_Comm Barrier function.
Epetra_BlockMapData::MinMyElementSize_
int MinMyElementSize_
Definition: Epetra_BlockMapData.h:100
Epetra_BlockMap::IndexBase64
long long IndexBase64() const
Definition: Epetra_BlockMap.h:592
Epetra_BlockMap::MaxElementSize
int MaxElementSize() const
Maximum element size across all processors.
Definition: Epetra_BlockMap.h:617
Epetra_BlockMapData::GlobalIndicesInt_
bool GlobalIndicesInt_
Definition: Epetra_BlockMapData.h:118
Epetra_BlockMapData::Directory_
Epetra_Directory * Directory_
Definition: Epetra_BlockMapData.h:83
Epetra_BlockMap::GlobalIndicesTypeMatch
bool GlobalIndicesTypeMatch(const Epetra_BlockMap &other) const
Definition: Epetra_BlockMap.h:662
Epetra_BlockMap::MaxMyGID64
long long MaxMyGID64() const
Definition: Epetra_BlockMap.h:533
Epetra_BlockMap::~Epetra_BlockMap
virtual ~Epetra_BlockMap(void)
Epetra_BlockMap destructor.
Definition: Epetra_BlockMap.cpp:1523
Epetra_BlockMapData::MinMyGID_
long long MinMyGID_
Definition: Epetra_BlockMapData.h:106
Epetra_Data::IncrementReferenceCount
void IncrementReferenceCount()
Increment reference count.
Definition: Epetra_Data.cpp:61
Epetra_Data::ReferenceCount
int ReferenceCount() const
Get reference count.
Definition: Epetra_Data.cpp:71
Epetra_IntSerialDenseVector::Values
int * Values()
Returns pointer to the values in vector.
Definition: Epetra_IntSerialDenseVector.h:211
Epetra_BlockMap::LinearMap
bool LinearMap() const
Returns true if the global ID space is contiguously divided (but not necessarily uniformly) across al...
Definition: Epetra_BlockMap.h:691
Epetra_BlockMap::ConstructAutoUniform
void ConstructAutoUniform(long long NumGlobal_Elements, int Element_Size, long long Index_Base, const Epetra_Comm &comm, bool IsLongLong)
Definition: Epetra_BlockMap.cpp:60
Epetra_BlockMapData::NumGlobalPoints_
long long NumGlobalPoints_
Definition: Epetra_BlockMapData.h:110
Epetra_BlockMap::NumGlobalElements
int NumGlobalElements() const
Number of elements across all processors.
Definition: Epetra_BlockMap.h:546
Epetra_Comm
Epetra_Comm: The Epetra Communication Abstract Base Class.
Definition: Epetra_Comm.h:73
Epetra_BlockMap::GlobalToLocalSetup
void GlobalToLocalSetup()
Definition: Epetra_BlockMap.cpp:1151
Epetra_BlockMap::MyGlobalElementsPtr
int MyGlobalElementsPtr(int *&MyGlobalElementList) const
Definition: Epetra_BlockMap.cpp:879
Epetra_BlockMap::GlobalIndicesLongLong
bool GlobalIndicesLongLong() const
Returns true if map create with long long NumGlobalElements.
Definition: Epetra_BlockMap.h:655
Epetra_BlockMapData::NumGlobalElements_
long long NumGlobalElements_
Definition: Epetra_BlockMapData.h:96
Epetra_BlockMapData::FirstPointInElementList_
Epetra_IntSerialDenseVector FirstPointInElementList_
Definition: Epetra_BlockMapData.h:92
Epetra_BlockMapData::ElementSizeList_
Epetra_IntSerialDenseVector ElementSizeList_
Definition: Epetra_BlockMapData.h:93
Epetra_MpiComm.h
Epetra_BlockMap::PointSameAs
bool PointSameAs(const Epetra_BlockMap &Map) const
Returns true if this and Map have identical point-wise structure.
Definition: Epetra_BlockMap.cpp:788
Epetra_BlockMap::DetermineIsOneToOne
bool DetermineIsOneToOne() const
Definition: Epetra_BlockMap.cpp:1373
Epetra_BlockMap::ReplaceCommWithSubset
Epetra_BlockMap * ReplaceCommWithSubset(const Epetra_Comm *Comm) const
Replace this BlockMap's communicator with a subset communicator.
Definition: Epetra_BlockMap.cpp:1652
Epetra_BlockMap::NumMyPoints
int NumMyPoints() const
Number of local points for this map; equals the sum of all element sizes on the calling processor.
Definition: Epetra_BlockMap.h:605
Epetra_BlockMapData::LIDHash_
Epetra_HashTable< int > * LIDHash_
Definition: Epetra_BlockMapData.h:123
Epetra_MpiComm::Comm
MPI_Comm Comm() const
Extract MPI Communicator from a Epetra_MpiComm object.
Definition: Epetra_MpiComm.h:457
Epetra_Comm::ScanSum
virtual int ScanSum(double *MyVals, double *ScanSums, int Count) const =0
Epetra_Comm Scan Sum function.
Epetra_BlockMapData::MyGlobalElements_int_
Epetra_IntSerialDenseVector MyGlobalElements_int_
Definition: Epetra_BlockMapData.h:87
Epetra_BlockMap::MyLID
bool MyLID(int lid) const
Returns true if the LID passed in belongs to the calling processor in this map, otherwise returns fal...
Definition: Epetra_BlockMap.h:487
Epetra_BlockMap::GID
int GID(int LID) const
Returns global ID of local ID, return IndexBase-1 if not found on this processor.
Definition: Epetra_BlockMap.cpp:1282
Epetra_BlockMapData
Epetra_BlockMapData: The Epetra BlockMap Data Class.
Definition: Epetra_BlockMapData.h:65
Epetra_BlockMapData::MaxAllGID_
long long MaxAllGID_
Definition: Epetra_BlockMapData.h:105
Epetra_Directory::GIDsAllUniquelyOwned
virtual bool GIDsAllUniquelyOwned() const =0
GIDsAllUniquelyOwned: returns true if all GIDs appear on just one processor.
Epetra_BlockMap::RemoveEmptyProcesses
Epetra_BlockMap * RemoveEmptyProcesses() const
Return a new BlockMap with processes with zero elements removed.
Definition: Epetra_BlockMap.cpp:1553
Epetra_BlockMap::TGlobalToLocalSetup
void TGlobalToLocalSetup()
Definition: Epetra_BlockMap.cpp:1080
Epetra_BlockMap::ConstructUserConstant
void ConstructUserConstant(int_type NumGlobal_Elements, int NumMy_Elements, const int_type *myGlobalElements, int Element_Size, int_type indexBase, const Epetra_Comm &comm, bool IsLongLong)
Definition: Epetra_BlockMap.cpp:245
Epetra_BlockMapData::LID_
Epetra_IntSerialDenseVector LID_
Definition: Epetra_BlockMapData.h:85
Epetra_BlockMapData::PointToElementList_
Epetra_IntSerialDenseVector PointToElementList_
Definition: Epetra_BlockMapData.h:94
Epetra_BlockMap::MinMyGID64
long long MinMyGID64() const
Definition: Epetra_BlockMap.h:523
Epetra_Directory::GetDirectoryEntries
virtual int GetDirectoryEntries(const Epetra_BlockMap &Map, const int NumEntries, const int *GlobalEntries, int *Procs, int *LocalEntries, int *EntrySizes, bool high_rank_sharing_procs=false) const =0
GetDirectoryEntries : Returns proc and local id info for non-local map entries.
Epetra_BlockMapData::ElementSize_
int ElementSize_
Definition: Epetra_BlockMapData.h:99
Epetra_MpiComm
Epetra_MpiComm: The Epetra MPI Communication Class.
Definition: Epetra_MpiComm.h:64
Epetra_BlockMap::ConstantElementSize
bool ConstantElementSize() const
Returns true if map has constant element size.
Definition: Epetra_BlockMap.h:675
Epetra_Object::ReportError
virtual int ReportError(const std::string Message, int ErrorCode) const
Error reporting method.
Definition: Epetra_Object.cpp:103
Epetra_Directory
Epetra_Directory: This class is a pure virtual class whose interface allows Epetra_Map and Epetr_Bloc...
Definition: Epetra_Directory.h:59
Epetra_BlockMap.h
Epetra_BlockMap::SameAs
bool SameAs(const Epetra_BlockMap &Map) const
Returns true if this and Map are identical maps.
Definition: Epetra_BlockMap.cpp:718
Epetra_BlockMapData::OneToOne_
bool OneToOne_
Definition: Epetra_BlockMapData.h:117
Epetra_BlockMap
Epetra_BlockMap: A class for partitioning block element vectors and matrices.
Definition: Epetra_BlockMap.h:194
Epetra_LongLongSerialDenseVector::Length
int Length() const
Returns length of vector.
Definition: Epetra_LongLongSerialDenseVector.h:211
Epetra_BlockMapData::MaxMyElementSize_
int MaxMyElementSize_
Definition: Epetra_BlockMapData.h:101
Epetra_Comm::SumAll
virtual int SumAll(double *PartialSums, double *GlobalSums, int Count) const =0
Epetra_Comm Global Sum function.
Epetra_IntSerialDenseVector::Size
int Size(int Length_in)
Set length of a Epetra_IntSerialDenseVector object; init values to zero.
Definition: Epetra_IntSerialDenseVector.h:139
Epetra_BlockMap::BlockMapData_
Epetra_BlockMapData * BlockMapData_
Definition: Epetra_BlockMap.h:877
Epetra_BlockMapData::MinAllGID_
long long MinAllGID_
Definition: Epetra_BlockMapData.h:104
Epetra_LongLongSerialDenseVector::Values
long long * Values()
Returns pointer to the values in vector.
Definition: Epetra_LongLongSerialDenseVector.h:214
Epetra_BlockMap::ConstructUserConstantNoComm
void ConstructUserConstantNoComm(int_type NumGlobal_Elements, int NumMy_Elements, const int_type *myGlobalElements, int ElementSize, int_type indexBase, const Epetra_Comm &comm, bool IsLongLong, bool UserIsDistributedGlobal, int_type UserMinAllGID, int_type UserMaxAllGID)
Definition: Epetra_BlockMap.cpp:553
Epetra_BlockMapData::MaxMyGID_
long long MaxMyGID_
Definition: Epetra_BlockMapData.h:107
Epetra_Comm.h
Epetra_ConfigDefs.h
Epetra_Object::toString
std::string toString(const int &x) const
Definition: Epetra_Object.h:145
Epetra_BlockMapData::LastContiguousGID_
long long LastContiguousGID_
Definition: Epetra_BlockMapData.h:121
Epetra_BlockMap::FirstPointInElementList
int * FirstPointInElementList() const
Pointer to internal array containing a mapping between the local elements and the first local point n...
Definition: Epetra_BlockMap.cpp:971
Epetra_BlockMapData::MinElementSize_
int MinElementSize_
Definition: Epetra_BlockMapData.h:102
Epetra_BlockMap::FirstPointInElement
int FirstPointInElement(int LID) const
Returns the requested entry in the FirstPointInElementList; see FirstPointInElementList() for details...
Definition: Epetra_BlockMap.cpp:928
Epetra_BlockMap::NumGlobalElements64
long long NumGlobalElements64() const
Definition: Epetra_BlockMap.h:552
Epetra_Comm::MaxAll
virtual int MaxAll(double *PartialMaxs, double *GlobalMaxs, int Count) const =0
Epetra_Comm Global Max function.
Epetra_BlockMap::MaxAllGID
int MaxAllGID() const
Returns the maximum global ID across the entire map.
Definition: Epetra_BlockMap.h:507
Epetra_BlockMap::ElementSizeList
int * ElementSizeList() const
List of the element sizes corresponding to the array MyGlobalElements().
Definition: Epetra_BlockMap.cpp:1009
Epetra_BlockMap::IndexBase
int IndexBase() const
Index base for this map.
Definition: Epetra_BlockMap.h:586
Epetra_BlockMap::MaxAllGID64
long long MaxAllGID64() const
Definition: Epetra_BlockMap.h:513
Epetra_BlockMap::PointToElementList
int * PointToElementList() const
For each local point, indicates the local element ID that the point belongs to.
Definition: Epetra_BlockMap.cpp:1044
Epetra_Comm::CreateDirectory
virtual Epetra_Directory * CreateDirectory(const Epetra_BlockMap &Map) const =0
Create a directory object for the given Epetra_BlockMap.
Epetra_BlockMap::MyGlobalElements64
long long * MyGlobalElements64() const
Definition: Epetra_BlockMap.cpp:908
Epetra_BlockMapData::MaxLID_
int MaxLID_
Definition: Epetra_BlockMapData.h:109
Epetra_BlockMap::IsDistributedGlobal
bool IsDistributedGlobal(long long NumGlobalElements, int NumMyElements) const
Definition: Epetra_BlockMap.cpp:1392
Epetra_IntSerialDenseVector::Length
int Length() const
Returns length of vector.
Definition: Epetra_IntSerialDenseVector.h:208
Epetra_BlockMap::IsOneToOne
bool IsOneToOne() const
Definition: Epetra_BlockMap.cpp:1070
Epetra_BlockMap::CheckValidNGE
void CheckValidNGE(long long NumGlobalElements)
Definition: Epetra_BlockMap.cpp:1410
Epetra_BlockMap::GID64
long long GID64(int LID) const
Definition: Epetra_BlockMap.cpp:1252
Epetra_BlockMapData::MaxElementSize_
int MaxElementSize_
Definition: Epetra_BlockMapData.h:103
Epetra_BlockMapData::IndexBase_
long long IndexBase_
Definition: Epetra_BlockMapData.h:98
Epetra_BlockMapData::OneToOneIsDetermined_
bool OneToOneIsDetermined_
Definition: Epetra_BlockMapData.h:116
Epetra_BlockMap::FindLocalElementID
int FindLocalElementID(int PointID, int &ElementID, int &ElementOffset) const
Returns the LID of the element that contains the given local PointID, and the Offset of the point in ...
Definition: Epetra_BlockMap.cpp:1304
Epetra_Comm::MyPID
virtual int MyPID() const =0
Return my process ID.
Epetra_BlockMap::EndOfConstructorOps
void EndOfConstructorOps()
Definition: Epetra_BlockMap.cpp:1423
Epetra_BlockMap::MyGlobalElements
int * MyGlobalElements() const
Pointer to internal array containing list of global IDs assigned to the calling processor.
Definition: Epetra_BlockMap.cpp:887
EPETRA_MAX
#define EPETRA_MAX(x, y)
Definition: Epetra_ConfigDefs.h:62
Epetra_BlockMapData::NumMyElements_
int NumMyElements_
Definition: Epetra_BlockMapData.h:97
Epetra_BlockMap::NumGlobalPoints64
long long NumGlobalPoints64() const
Definition: Epetra_BlockMap.h:602
Epetra_BlockMapData::GlobalIndicesLongLong_
bool GlobalIndicesLongLong_
Definition: Epetra_BlockMapData.h:119
Epetra_BlockMap::CleanupData
void CleanupData()
Definition: Epetra_BlockMap.cpp:1528