//============================================================================= Epetra_Map* Epetra_Map::ReplaceCommWithSubset(const Epetra_Comm * theComm) const { // mfh 26 Mar 2013: The lazy way to do this is simply to recreate // the Map by calling its ordinary public constructor, using the // original Map's data. This only involves O(1) all-reduces over // the new communicator, which in the common case only includes a // small number of processes. Epetra_Map * NewMap=0; // Create the Map to return (unless theComm is NULL, in which case // we return zero). if(theComm) { // Map requires that the index base equal the global min GID. // Figuring out the global min GID requires a reduction over all // processes in the new communicator. It could be that some (or // even all) of these processes contain zero entries. (Recall // that this method, unlike removeEmptyProcesses(), may remove // an arbitrary subset of processes.) We deal with this by // doing a min over the min GID on each process if the process // has more than zero entries, or the global max GID, if that // process has zero entries. If no processes have any entries, // then the index base doesn't matter anyway. #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES if(GlobalIndicesInt()) { int MyMin, theIndexBase; MyMin = NumMyElements() > 0 ? MinMyGID() : MaxAllGID(); theComm->MinAll(&MyMin,&theIndexBase,1); NewMap = new Epetra_Map(-1,NumMyElements(),MyGlobalElements(),theIndexBase,*theComm); } else #endif #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES if(GlobalIndicesLongLong()) { long long MyMin, theIndexBase; MyMin = NumMyElements() > 0 ? MinMyGID64() : MaxAllGID64(); theComm->MinAll(&MyMin,&theIndexBase,1); NewMap = new Epetra_Map(-1,NumMyElements(),MyGlobalElements64(),theIndexBase,*theComm); } else #endif throw ReportError("Epetra_Map::ReplaceCommWithSubset ERROR, GlobalIndices type unknown.",-1); } return NewMap; }
//============================================================================== bool Epetra_BlockMap::SameAs(const Epetra_BlockMap & Map) const { // Quickest test: See if both maps share an inner data class if (this->BlockMapData_ == Map.BlockMapData_) return(true); if(!GlobalIndicesTypeMatch(Map)) return(false); // Next check other global properties that are easy global attributes if (BlockMapData_->MinAllGID_ != Map.MinAllGID64() || BlockMapData_->MaxAllGID_ != Map.MaxAllGID64() || BlockMapData_->NumGlobalElements_ != Map.NumGlobalElements64() || BlockMapData_->IndexBase_ != Map.IndexBase()) return(false); // Last possible global check for constant element sizes if (BlockMapData_->ConstantElementSize_ && BlockMapData_->ElementSize_!=Map.ElementSize()) return(false); // If we get this far, we need to check local properties and then check across // all processors to see if local properties are all true int numMyElements = BlockMapData_->NumMyElements_; int MySameMap = 1; // Assume not needed // First check if number of element is the same in each map if (numMyElements != Map.NumMyElements()) MySameMap = 0; // If numMyElements is the same, check to see that list of GIDs is the same if (MySameMap==1) { if (LinearMap() && Map.LinearMap() ) { // For linear maps, just need to check whether lower bound is the same if (MinMyGID64() != Map.MinMyGID64() ) MySameMap = 0; } else { for (int i = 0; i < numMyElements; i++) { if (GID64(i) != Map.GID64(i)) { MySameMap = 0; break; } } } } // for (int i = 0; i < numMyElements; i++) // if (GID64(i) != Map.GID64(i)) MySameMap = 0; // If GIDs are the same, check to see element sizes are the same if (MySameMap==1 && !BlockMapData_->ConstantElementSize_) { int * sizeList1 = ElementSizeList(); int * sizeList2 = Map.ElementSizeList(); for (int i = 0; i < numMyElements; i++) if (sizeList1[i] != sizeList2[i]) MySameMap=0; } // Now get min of MySameMap across all processors int GlobalSameMap = 0; int err = Comm().MinAll(&MySameMap, &GlobalSameMap, 1); assert(err==0); return(GlobalSameMap==1); }
//============================================================================== void Epetra_BlockMap::Print(ostream & os) const { int * FirstPointInElementList1 = 0; int * ElementSizeList1 = 0; if (!ConstantElementSize()) { FirstPointInElementList1 = FirstPointInElementList(); ElementSizeList1 = ElementSizeList(); } int MyPID = Comm().MyPID(); int NumProc = Comm().NumProc(); for (int iproc = 0; iproc < NumProc; iproc++) { if (MyPID == iproc) { if (MyPID == 0) { os << "\nNumber of Global Elements = "; os << NumGlobalElements64(); os << endl; os << "Number of Global Points = "; os << NumGlobalPoints64(); os << endl; os << "Maximum of all GIDs = "; os << MaxAllGID64(); os << endl; os << "Minimum of all GIDs = "; os << MinAllGID64(); os << endl; os << "Index Base = "; os << IndexBase(); os << endl; if (ConstantElementSize()) os << "Constant Element Size = "; os << ElementSize(); os << endl; } os << endl; os << "Number of Local Elements = "; os << NumMyElements(); os << endl; os << "Number of Local Points = "; os << NumMyPoints(); os << endl; os << "Maximum of my GIDs = "; os << MaxMyGID64(); os << endl; os << "Minimum of my GIDs = "; os << MinMyGID64(); os << endl; os << endl; os.width(14); os << " MyPID"; os << " "; os.width(14); os << " Local Index "; os << " "; os.width(14); os << " Global Index "; os << " "; if (!ConstantElementSize()) { os.width(14); os <<" FirstPointInElement "; os << " "; os.width(14); os <<" ElementSize "; os << " "; } os << endl; for (int i = 0; i < NumMyElements(); i++) { os.width(14); os << MyPID; os << " "; os.width(14); os << i; os << " "; os.width(14); if(BlockMapData_->GlobalIndicesLongLong_) { #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES long long * MyGlobalElements1 = MyGlobalElements64(); os << MyGlobalElements1[i]; os << " "; #else throw ReportError("Epetra_BlockMap::Print: ERROR, GlobalIndicesLongLong but no API for it.",-1); #endif } else if(BlockMapData_->GlobalIndicesInt_) { #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES int * MyGlobalElements1 = MyGlobalElements(); os << MyGlobalElements1[i]; os << " "; #else throw ReportError("Epetra_BlockMap::Print: ERROR, no GlobalIndicesLongLong but no API for it.",-1); #endif } if (!ConstantElementSize()) { os.width(14); os << FirstPointInElementList1[i]; os << " "; os.width(14); os << ElementSizeList1[i]; os << " "; } os << endl; } os << flush; } // Do a few global ops to give I/O a chance to complete Comm().Barrier(); Comm().Barrier(); Comm().Barrier(); } return; }