//============================================================================== int Ifpack_CrsRiluk::BlockGraph2PointGraph(const Epetra_CrsGraph & BG, Epetra_CrsGraph & PG, bool Upper) { if (!BG.IndicesAreLocal()) {EPETRA_CHK_ERR(-1);} // Must have done FillComplete on BG int * ColFirstPointInElementList = BG.RowMap().FirstPointInElementList(); int * ColElementSizeList = BG.RowMap().ElementSizeList(); if (BG.Importer()!=0) { ColFirstPointInElementList = BG.ImportMap().FirstPointInElementList(); ColElementSizeList = BG.ImportMap().ElementSizeList(); } int Length = (BG.MaxNumIndices()+1) * BG.ImportMap().MaxMyElementSize(); vector<int> tmpIndices(Length); int BlockRow, BlockOffset, NumEntries; int NumBlockEntries; int * BlockIndices; int NumMyRows_tmp = PG.NumMyRows(); for (int i=0; i<NumMyRows_tmp; i++) { EPETRA_CHK_ERR(BG.RowMap().FindLocalElementID(i, BlockRow, BlockOffset)); EPETRA_CHK_ERR(BG.ExtractMyRowView(BlockRow, NumBlockEntries, BlockIndices)); int * ptr = &tmpIndices[0]; // Set pointer to beginning of buffer int RowDim = BG.RowMap().ElementSize(BlockRow); NumEntries = 0; // This next line make sure that the off-diagonal entries in the block diagonal of the // original block entry matrix are included in the nonzero pattern of the point graph if (Upper) { int jstart = i+1; int jstop = EPETRA_MIN(NumMyRows_tmp,i+RowDim-BlockOffset); for (int j= jstart; j< jstop; j++) {*ptr++ = j; NumEntries++;} } for (int j=0; j<NumBlockEntries; j++) { int ColDim = ColElementSizeList[BlockIndices[j]]; NumEntries += ColDim; assert(NumEntries<=Length); // Sanity test int Index = ColFirstPointInElementList[BlockIndices[j]]; for (int k=0; k < ColDim; k++) *ptr++ = Index++; } // This next line make sure that the off-diagonal entries in the block diagonal of the // original block entry matrix are included in the nonzero pattern of the point graph if (!Upper) { int jstart = EPETRA_MAX(0,i-RowDim+1); int jstop = i; for (int j = jstart; j < jstop; j++) {*ptr++ = j; NumEntries++;} } EPETRA_CHK_ERR(PG.InsertMyIndices(i, NumEntries, &tmpIndices[0])); } SetAllocated(true); return(0); }
//============================================================================ Epetra_CrsGraph* Ifpack_CreateOverlappingCrsMatrix(const Epetra_CrsGraph* Graph, const int OverlappingLevel) { if (OverlappingLevel == 0) return(0); // All done if (Graph->Comm().NumProc() == 1) return(0); // All done Epetra_CrsGraph* OverlappingGraph; Epetra_BlockMap* OverlappingMap; OverlappingGraph = const_cast<Epetra_CrsGraph*>(Graph); OverlappingMap = const_cast<Epetra_BlockMap*>(&(Graph->RowMap())); Epetra_CrsGraph* OldGraph; Epetra_BlockMap* OldMap; const Epetra_BlockMap* DomainMap = &(Graph->DomainMap()); const Epetra_BlockMap* RangeMap = &(Graph->RangeMap()); for (int level = 1; level <= OverlappingLevel ; ++level) { OldGraph = OverlappingGraph; OldMap = OverlappingMap; Epetra_Import* OverlappingImporter; OverlappingImporter = const_cast<Epetra_Import*>(OldGraph->Importer()); OverlappingMap = new Epetra_BlockMap(OverlappingImporter->TargetMap()); if (level < OverlappingLevel) OverlappingGraph = new Epetra_CrsGraph(Copy, *OverlappingMap, 0); else // On last iteration, we want to filter out all columns except // those that correspond // to rows in the graph. This assures that our matrix is square OverlappingGraph = new Epetra_CrsGraph(Copy, *OverlappingMap, *OverlappingMap, 0); OverlappingGraph->Import(*OldGraph, *OverlappingImporter, Insert); if (level < OverlappingLevel) OverlappingGraph->FillComplete(*DomainMap, *RangeMap); else { // Copy last OverlapImporter because we will use it later OverlappingImporter = new Epetra_Import(*OverlappingMap, *DomainMap); OverlappingGraph->FillComplete(*DomainMap, *RangeMap); } if (level > 1) { delete OldGraph; delete OldMap; } delete OverlappingMap; OverlappingGraph->FillComplete(); } return(OverlappingGraph); }