Epetra Package Browser (Single Doxygen Collection) Development
Epetra_BlockMap.h
Go to the documentation of this file.
00001 /*
00002 //@HEADER
00003 // ************************************************************************
00004 //
00005 //               Epetra: Linear Algebra Services Package
00006 //                 Copyright 2011 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00039 //
00040 // ************************************************************************
00041 //@HEADER
00042 */
00043 
00044 #ifndef EPETRA_BLOCKMAP_H
00045 #define EPETRA_BLOCKMAP_H
00046 
00047 #include "Epetra_ConfigDefs.h"
00048 #include "Epetra_Object.h"
00049 #include "Epetra_BlockMapData.h"
00050 
00051 
00053 
00194 class EPETRA_LIB_DLL_EXPORT Epetra_BlockMap: public Epetra_Object {
00195   friend class Epetra_Directory;
00196   friend class Epetra_LocalMap;
00197  public:
00199 
00200 
00201 
00224 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00225   Epetra_BlockMap(int NumGlobalElements, int ElementSize, int IndexBase, const Epetra_Comm& Comm);
00226 #endif
00227 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00228   Epetra_BlockMap(long long NumGlobalElements, int ElementSize, int IndexBase, const Epetra_Comm& Comm);
00229   Epetra_BlockMap(long long NumGlobalElements, int ElementSize, long long IndexBase, const Epetra_Comm& Comm);
00230 #endif
00231 
00233 
00262 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00263   Epetra_BlockMap(int NumGlobalElements, int NumMyElements,
00264      int ElementSize, int IndexBase, const Epetra_Comm& Comm);
00265 #endif
00266 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00267   Epetra_BlockMap(long long NumGlobalElements, int NumMyElements,
00268     int ElementSize, int IndexBase, const Epetra_Comm& Comm);
00269   Epetra_BlockMap(long long NumGlobalElements, int NumMyElements,
00270     int ElementSize, long long IndexBase, const Epetra_Comm& Comm);
00271 #endif
00272 
00274 
00310 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00311   Epetra_BlockMap(int NumGlobalElements, int NumMyElements,
00312                   const int *MyGlobalElements,
00313        int ElementSize, int IndexBase, const Epetra_Comm& Comm);
00314 #endif
00315 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00316   Epetra_BlockMap(long long NumGlobalElements, int NumMyElements,
00317                   const long long *MyGlobalElements,
00318       int ElementSize, int IndexBase, const Epetra_Comm& Comm);
00319   Epetra_BlockMap(long long NumGlobalElements, int NumMyElements,
00320                   const long long *MyGlobalElements,
00321       int ElementSize, long long IndexBase, const Epetra_Comm& Comm);
00322 #endif
00323 
00325 
00362 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00363   Epetra_BlockMap(int NumGlobalElements, int NumMyElements,
00364                   const int *MyGlobalElements,
00365       const int *ElementSizeList, int IndexBase,
00366                   const Epetra_Comm& Comm);
00367 #endif
00368 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00369   Epetra_BlockMap(long long NumGlobalElements, int NumMyElements,
00370                   const long long *MyGlobalElements,
00371       const int *ElementSizeList, int IndexBase,
00372                   const Epetra_Comm& Comm);
00373   Epetra_BlockMap(long long NumGlobalElements, int NumMyElements,
00374                   const long long *MyGlobalElements,
00375       const int *ElementSizeList, long long IndexBase,
00376                   const Epetra_Comm& Comm);
00377 #endif
00378 
00379 #if defined(EPETRA_NO_32BIT_GLOBAL_INDICES) && defined(EPETRA_NO_64BIT_GLOBAL_INDICES)
00380   // default implementation so that no compiler/linker error in case neither 32 nor 64
00381   // bit indices present.
00382   Epetra_BlockMap() {}
00383 #endif
00384 
00385 
00387 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00388   Epetra_BlockMap(long long NumGlobal_Elements, int NumMy_Elements,
00389                   const long long * myGlobalElements,
00390                   int ElementSize, int indexBase,
00391                   const Epetra_Comm& comm,
00392                   bool UserIsDistributedGlobal,
00393                   long long UserMinAllGID, long long UserMaxAllGID);
00394   Epetra_BlockMap(long long NumGlobal_Elements, int NumMy_Elements,
00395                   const long long * myGlobalElements,
00396                   int ElementSize, long long indexBase,
00397                   const Epetra_Comm& comm,
00398                   bool UserIsDistributedGlobal,
00399                   long long UserMinAllGID, long long UserMaxAllGID);
00400 #endif
00401 
00402 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00403   Epetra_BlockMap(int NumGlobal_Elements, int NumMy_Elements,
00404                  const int * myGlobalElements,
00405                  int ElementSize, int indexBase,
00406                  const Epetra_Comm& comm,
00407                  bool UserIsDistributedGlobal,
00408                  int UserMinAllGID, int UserMaxAllGID);
00409 #endif
00410 
00411 
00413   Epetra_BlockMap(const Epetra_BlockMap& map);
00414 
00416   virtual ~Epetra_BlockMap(void);
00418 
00420 
00421 
00422 
00429 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00430   int RemoteIDList(int NumIDs, const int * GIDList, int * PIDList, int * LIDList) const {
00431     return(RemoteIDList(NumIDs, GIDList, PIDList, LIDList, 0));
00432   };
00433 #endif
00434 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00435   int RemoteIDList(int NumIDs, const long long * GIDList, int * PIDList, int * LIDList) const {
00436     return(RemoteIDList(NumIDs, GIDList, PIDList, LIDList, 0));
00437   };
00438 #endif
00439 
00441 
00446 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00447   int RemoteIDList(int NumIDs, const int * GIDList, int * PIDList, int * LIDList, int * SizeList) const;
00448 #endif
00449 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00450   int RemoteIDList(int NumIDs, const long long * GIDList, int * PIDList, int * LIDList, int * SizeList) const;
00451 #endif
00452 
00454 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00455   int  LID(int GID) const;
00456 #endif
00457 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00458   int  LID(long long GID) const;
00459 #endif
00460 
00461 #if defined(EPETRA_NO_32BIT_GLOBAL_INDICES) && defined(EPETRA_NO_64BIT_GLOBAL_INDICES)
00462   // default implementation so that no compiler/linker error in case neither 32 nor 64
00463   // bit indices present.
00464   int  LID(long long GID) const { return -1; }
00465   bool MyGID(long long GID_in) const { return false; }
00466 #endif
00467 
00469 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00470   int  GID(int LID) const;
00471 #endif
00472   long long  GID64(int LID) const;
00473 
00475   int FindLocalElementID(int PointID, int & ElementID, int & ElementOffset)  const;
00476 
00478 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00479   bool  MyGID(int GID_in) const {return(LID(GID_in)!=-1);};
00480 #endif
00481 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00482   bool  MyGID(long long GID_in) const {return(LID(GID_in)!=-1);};
00483 #endif
00484 
00486   // bool  MyLID(int LID_in) const {return(GID64(LID_in)!=BlockMapData_->IndexBase_-1);};
00487   bool MyLID(int lid) const {
00488     if ((BlockMapData_->NumMyElements_ == 0) ||
00489         (lid < BlockMapData_->MinLID_) || (lid > BlockMapData_->MaxLID_)) {
00490       return false;
00491     }
00492     return true;
00493   }
00494 
00496 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00497   int  MinAllGID() const {
00498     if(GlobalIndicesInt())
00499       return (int) MinAllGID64();
00500     throw "Epetra_BlockMap::MinAllGID: GlobalIndices not int.";
00501   }
00502 #endif
00503   long long  MinAllGID64() const {return(BlockMapData_->MinAllGID_);};
00504 
00506 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00507   int  MaxAllGID() const {
00508     if(GlobalIndicesInt())
00509       return (int) MaxAllGID64();
00510     throw "Epetra_BlockMap::MaxAllGID: GlobalIndices not int.";
00511   }
00512 #endif
00513   long long  MaxAllGID64() const {return(BlockMapData_->MaxAllGID_);};
00514 
00516 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00517   int  MinMyGID() const {
00518     if(GlobalIndicesInt())
00519       return (int) MinMyGID64();
00520     throw "Epetra_BlockMap::MinMyGID: GlobalIndices not int.";
00521   }
00522 #endif
00523   long long  MinMyGID64() const {return(BlockMapData_->MinMyGID_);};
00524 
00526 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00527   int  MaxMyGID() const {
00528     if(GlobalIndicesInt())
00529       return (int) MaxMyGID64();
00530     throw "Epetra_BlockMap::MaxMyGID: GlobalIndices not int.";
00531   }
00532 #endif
00533   long long  MaxMyGID64() const {return(BlockMapData_->MaxMyGID_);};
00534 
00536   int  MinLID() const {return(BlockMapData_->MinLID_);};
00537 
00539   int  MaxLID() const {return(BlockMapData_->MaxLID_);};
00541 
00543 
00544 
00545 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00546   int  NumGlobalElements() const {
00547     if(GlobalIndicesInt())
00548       return (int) NumGlobalElements64();
00549     throw "Epetra_BlockMap::NumGlobalElements: GlobalIndices not int.";
00550   }
00551 #endif
00552   long long  NumGlobalElements64() const {return(BlockMapData_->NumGlobalElements_);};
00553 
00555   int  NumMyElements() const {return(BlockMapData_->NumMyElements_);};
00556 
00558 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00559   int MyGlobalElements(int * MyGlobalElementList) const;
00560 #endif
00561 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00562   int MyGlobalElements(long long * MyGlobalElementList) const;
00563 #endif
00564 
00565 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00566   int MyGlobalElementsPtr(int *& MyGlobalElementList) const;
00567 #endif
00568 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00569   int MyGlobalElementsPtr(long long *& MyGlobalElementList) const;
00570 #endif
00571 
00573   int  ElementSize() const {return(BlockMapData_->ElementSize_);};
00574 
00576   int  ElementSize(int LID) const;
00577 
00579 
00582   int  FirstPointInElement(int LID) const;
00583 
00584 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00585 
00586   int  IndexBase() const {
00587     if(GlobalIndicesInt() || IndexBase64() == (long long) static_cast<int>(IndexBase64()))
00588       return (int) IndexBase64();
00589     throw "Epetra_BlockMap::IndexBase: GlobalIndices not int and IndexBase cannot fit an int.";
00590   }
00591 #endif
00592   long long  IndexBase64() const {return(BlockMapData_->IndexBase_);};
00593 
00595 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00596   int  NumGlobalPoints() const {
00597     if(GlobalIndicesInt())
00598       return (int) NumGlobalPoints64();
00599     throw "Epetra_BlockMap::NumGlobalPoints: GlobalIndices not int.";
00600   }
00601 #endif
00602   long long  NumGlobalPoints64() const {return(BlockMapData_->NumGlobalPoints_);};
00603 
00605   int  NumMyPoints() const {return(BlockMapData_->NumMyPoints_);};
00606 
00608   int  MinMyElementSize() const {return(BlockMapData_->MinMyElementSize_);};
00609 
00611   int  MaxMyElementSize() const {return(BlockMapData_->MaxMyElementSize_);};
00612 
00614   int  MinElementSize() const {return(BlockMapData_->MinElementSize_);};
00615 
00617   int  MaxElementSize() const {return(BlockMapData_->MaxElementSize_);};
00619 
00621 
00622 
00623 
00628   bool  UniqueGIDs() const {return(IsOneToOne());};
00629 
00630 /*
00631 *******************************************************************************
00632   Ideally GlobalIndicesInt and GlobalIndicesLongLong should be within the
00633   preprocessor macros and any code using them should also be within the
00634   corresponding macro.  However, when initially moving to 64-bit we did not
00635   have macros and all the code is written using run-time checks.  In future,
00636   the code can be converted to follow the macro system.  Hence this comment.
00637   -- Chetan Jhurani
00638 
00639   Future code:
00640 
00641 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00643   bool  GlobalIndicesInt()      const { return BlockMapData_->GlobalIndicesInt_; }
00644 #endif
00645 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00647   bool  GlobalIndicesLongLong() const { return BlockMapData_->GlobalIndicesLongLong_; }
00648 #endif
00649 *******************************************************************************
00650 */
00651 
00653   bool  GlobalIndicesInt()      const { return BlockMapData_->GlobalIndicesInt_; }
00655   bool  GlobalIndicesLongLong() const { return BlockMapData_->GlobalIndicesLongLong_; }
00656 
00657   template<typename int_type>
00658   bool GlobalIndicesIsType() const;
00659 
00660   bool GlobalIndicesTypeValid() const { return BlockMapData_->GlobalIndicesInt_ || BlockMapData_->GlobalIndicesLongLong_; }
00661 
00662   bool GlobalIndicesTypeMatch(const Epetra_BlockMap& other) const
00663   {
00664     return
00665 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00666       GlobalIndicesInt() == other.GlobalIndicesInt() &&
00667 #endif
00668 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00669       GlobalIndicesLongLong() == other.GlobalIndicesLongLong() &&
00670 #endif
00671       true;
00672   }
00673 
00675   bool  ConstantElementSize() const {return(BlockMapData_->ConstantElementSize_);};
00676 
00678   bool SameAs(const Epetra_BlockMap & Map) const;
00679 
00681 
00684   bool PointSameAs(const Epetra_BlockMap & Map) const;
00685 
00687   bool  LinearMap() const {return(BlockMapData_->LinearMap_);};
00688 
00690   bool  DistributedGlobal() const {return(BlockMapData_->DistributedGlobal_);};
00692 
00694 
00695 
00697 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00698   int * MyGlobalElements() const;
00699 #endif
00700 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00701   long long * MyGlobalElements64() const;
00702 #endif
00703 
00704   // Helper function to avoid scattering ifdef in other code.
00705   void MyGlobalElements(const int*& IntGIDs, const long long*& LLGIDs) const {
00706 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00707     if(GlobalIndicesInt()) {
00708       IntGIDs = MyGlobalElements();
00709       return;
00710     }
00711 #endif
00712 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00713     if(GlobalIndicesLongLong()) {
00714       LLGIDs = MyGlobalElements64();
00715       return;
00716     }
00717 #endif
00718   }
00719 
00720   // Helper function to avoid scattering ifdef in other code.
00721   void MyGlobalElements(int*& IntGIDs, long long*& LLGIDs) {
00722 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00723     if(GlobalIndicesInt()) {
00724       IntGIDs = MyGlobalElements();
00725       return;
00726     }
00727 #endif
00728 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00729     if(GlobalIndicesLongLong()) {
00730       LLGIDs = MyGlobalElements64();
00731       return;
00732     }
00733 #endif
00734   }
00735 
00737 
00740   int * FirstPointInElementList() const;
00741 
00743   int * ElementSizeList() const;
00744 
00746   int * PointToElementList() const;
00747 
00749   int ElementSizeList(int * ElementSizeList)const;
00750 
00752   int FirstPointInElementList(int * FirstPointInElementList)const;
00753 
00755   int PointToElementList(int * PointToElementList) const;
00756 
00758 
00760 
00761 
00763   virtual void Print(std::ostream & os) const;
00764 
00766   const Epetra_Comm & Comm() const {return(*BlockMapData_->Comm_);}
00767 
00768   bool IsOneToOne() const;
00769 
00771   Epetra_BlockMap & operator=(const Epetra_BlockMap & map);
00772 
00774 
00776 
00777 
00779 
00780   int ReferenceCount() const {return(BlockMapData_->ReferenceCount());}
00781 
00783 
00784   const Epetra_BlockMapData * DataPtr() const {return(BlockMapData_);}
00785 
00829   Epetra_BlockMap * RemoveEmptyProcesses() const;
00830 
00858   Epetra_BlockMap* ReplaceCommWithSubset(const Epetra_Comm * Comm) const;
00859 
00861 
00862  private: // These need to be accessible to derived map classes.
00863 
00864   void GlobalToLocalSetup();
00865   bool DetermineIsOneToOne() const;
00866   bool IsDistributedGlobal(long long NumGlobalElements, int NumMyElements) const;
00867   void CheckValidNGE(long long NumGlobalElements);
00868   void EndOfConstructorOps();
00869 
00870  protected:
00871   void CleanupData();
00872 
00873   Epetra_BlockMapData * BlockMapData_;
00874 
00875 private:
00876 
00877 
00878   void ConstructAutoUniform(long long NumGlobal_Elements, int Element_Size,
00879       long long Index_Base, const Epetra_Comm& comm, bool IsLongLong);
00880 
00881   void ConstructUserLinear(long long NumGlobal_Elements, int NumMy_Elements,
00882       int Element_Size, long long Index_Base, const Epetra_Comm& comm, bool IsLongLong);
00883 
00884   template<typename int_type>
00885   void ConstructUserConstant(int_type NumGlobal_Elements, int NumMy_Elements,
00886       const int_type * myGlobalElements,
00887       int Element_Size, int_type indexBase,
00888       const Epetra_Comm& comm, bool IsLongLong);
00889 
00890   template<typename int_type>
00891   void ConstructUserVariable(int_type NumGlobal_Elements, int NumMy_Elements,
00892       const int_type * myGlobalElements,
00893       const int *elementSizeList, int_type indexBase,
00894       const Epetra_Comm& comm, bool IsLongLong);
00895 
00896   template<typename int_type>
00897   void ConstructUserConstantNoComm(int_type NumGlobal_Elements, int NumMy_Elements,
00898       const int_type * myGlobalElements,
00899       int ElementSize, int_type indexBase,
00900       const Epetra_Comm& comm, bool IsLongLong,
00901       bool UserIsDistributedGlobal,
00902       int_type UserMinAllGID, int_type UserMaxAllGID);
00903 
00904   template<typename int_type>
00905   int_type& MyGlobalElementVal(int i);
00906 
00907   template<typename int_type>
00908   int_type MyGlobalElementValGet(int i);
00909 
00910   template<typename int_type>
00911   int SizeMyGlobalElement(int n);
00912 
00913   template<typename int_type>
00914   void TGlobalToLocalSetup();
00915 };
00916 
00917 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00918 template<> inline bool       Epetra_BlockMap::GlobalIndicesIsType<long long>() const { return BlockMapData_->GlobalIndicesLongLong_; }
00919 template<> inline long long& Epetra_BlockMap::MyGlobalElementVal<long long>(int i) { return BlockMapData_->MyGlobalElements_LL_[i]; }
00920 template<> inline long long  Epetra_BlockMap::MyGlobalElementValGet<long long>(int i) { return BlockMapData_->MyGlobalElements_LL_[i]; }
00921 template<> inline int        Epetra_BlockMap::SizeMyGlobalElement<long long>(int n) { return BlockMapData_->MyGlobalElements_LL_.Size(n); }
00922 #endif
00923 
00924 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00925 template<> inline bool Epetra_BlockMap::GlobalIndicesIsType<int>()       const { return BlockMapData_->GlobalIndicesInt_; }
00926 template<> inline int& Epetra_BlockMap::MyGlobalElementVal<int>      (int i) { return BlockMapData_->MyGlobalElements_int_[i]; }
00927 template<> inline int  Epetra_BlockMap::MyGlobalElementValGet<int>      (int i) { return BlockMapData_->MyGlobalElements_int_[i]; }
00928 template<> inline int  Epetra_BlockMap::SizeMyGlobalElement<int>      (int n) { return BlockMapData_->MyGlobalElements_int_.Size(n); }
00929 #endif
00930 
00931 #endif /* EPETRA_BLOCKMAP_H */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines