int TBlockMapToHandle(FILE * handle, const Epetra_BlockMap & map) { const Epetra_Comm & comm = map.Comm(); int numProc = comm.NumProc(); bool doSizes = !map.ConstantElementSize(); if (numProc==1) { int_type * myElements = 0; map.MyGlobalElementsPtr(myElements); int * elementSizeList = 0; if (doSizes) elementSizeList = map.ElementSizeList(); return(writeBlockMap(handle, map.NumGlobalElements64(), myElements, elementSizeList, doSizes)); } int numRows = map.NumMyElements(); Epetra_Map allGidsMap((int_type) -1, numRows, (int_type) 0,comm); typename Epetra_GIDTypeVector<int_type>::impl allGids(allGidsMap); for (int i=0; i<numRows; i++) allGids[i] = (int_type) map.GID64(i); Epetra_IntVector allSizes(allGidsMap); for (int i=0; i<numRows; i++) allSizes[i] = map.ElementSize(i); // Now construct a Map on PE 0 by strip-mining the rows of the input matrix map. int numChunks = numProc; int stripSize = allGids.GlobalLength64()/numChunks; int remainder = allGids.GlobalLength64()%numChunks; int curStart = 0; int curStripSize = 0; typename Epetra_GIDTypeSerialDenseVector<int_type>::impl importGidList; Epetra_IntSerialDenseVector importSizeList; if (comm.MyPID()==0) { importGidList.Size(stripSize+1); // Set size of vector to max needed if (doSizes) importSizeList.Size(stripSize+1); // Set size of vector to max needed } for (int i=0; i<numChunks; i++) { if (comm.MyPID()==0) { // Only PE 0 does this part curStripSize = stripSize; if (i<remainder) curStripSize++; // handle leftovers for (int j=0; j<curStripSize; j++) importGidList[j] = j + curStart; curStart += curStripSize; } // The following import map will be non-trivial only on PE 0. Epetra_Map importGidMap((int_type) -1, curStripSize, importGidList.Values(), 0, comm); Epetra_Import gidImporter(importGidMap, allGidsMap); typename Epetra_GIDTypeVector<int_type>::impl importGids(importGidMap); if (importGids.Import(allGids, gidImporter, Insert)) return(-1); Epetra_IntVector importSizes(importGidMap); if (doSizes) if (importSizes.Import(allSizes, gidImporter, Insert)) return(-1); // importGids (and importSizes, if non-trivial block map) // now have a list of GIDs (and sizes, respectively) for the current strip of map. int_type * myElements = importGids.Values(); int * elementSizeList = 0; if (doSizes) elementSizeList = importSizes.Values(); // Finally we are ready to write this strip of the map to file writeBlockMap(handle, importGids.MyLength(), myElements, elementSizeList, doSizes); } return(0); }
//============================================================================== 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); }