/// <summary> /// returns all external rows of <paramref name="M"/> /// corresponding to ghost cells of <paramref name="map"/>, /// which are located on other Mpi-ranks. /// </summary> /// <param name="map">Multigrid mapping</param> /// <param name="M">matrix distributed according to <paramref name="map"/></param> /// <returns></returns> public static BlockMsrMatrix GetAllExternalRows(MultigridMapping map, BlockMsrMatrix M) { var extcells = map.AggGrid.iLogicalCells.NoOfExternalCells.ForLoop(i => i + map.LocalNoOfBlocks); var SBS = new SubBlockSelector(map); SBS.CellSelector(extcells, false); var AllExtMask = new BlockMaskExt(SBS, 0); var ExternalRows_BlockI0 = AllExtMask.GetAllSubMatrixCellOffsets(); var ExternalRows_BlockN = AllExtMask.GetAllSubMatrixCellLength(); var ExternalRowsIndices = AllExtMask.m_GlobalMask; BlockPartitioning PermRow = new BlockPartitioning(ExternalRowsIndices.Count, ExternalRows_BlockI0, ExternalRows_BlockN, M.MPI_Comm, i0isLocal: true); BlockMsrMatrix Perm = new BlockMsrMatrix(PermRow, M._RowPartitioning); for (int iRow = 0; iRow < ExternalRowsIndices.Count; iRow++) { Debug.Assert(M._RowPartitioning.IsInLocalRange(ExternalRowsIndices[iRow]) == false); Perm[iRow + PermRow.i0, ExternalRowsIndices[iRow]] = 1; } #if TEST Perm.SaveToTextFileSparseDebug("Perm"); #endif return(BlockMsrMatrix.Multiply(Perm, M)); }