void BlockSol <V1, V2>(BlockMsrMatrix M, V1 X, V2 B) where V1 : IList <double> where V2 : IList <double> // { int i0 = M.RowPartitioning.i0; int iE = M.RowPartitioning.iE; var Part = M.RowPartitioning; Debug.Assert(Part.EqualsPartition(this.CurrentStateMapping)); int J = m_LsTrk.GridDat.Cells.NoOfLocalUpdatedCells; double[] MtxVals = null; int[] Indices = null; MultidimensionalArray Block = null; double[] x = null, b = null; for (int j = 0; j < J; j++) { int bS = this.CurrentStateMapping.LocalUniqueCoordinateIndex(0, j, 0); int Nj = this.CurrentStateMapping.GetTotalNoOfCoordinatesPerCell(j); if (Block == null || Block.NoOfRows != Nj) { Block = MultidimensionalArray.Create(Nj, Nj); x = new double[Nj]; b = new double[Nj]; } else { Block.Clear(); } // extract block and part of RHS for (int iRow = 0; iRow < Nj; iRow++) { bool ZeroRow = true; //MsrMatrix.MatrixEntry[] row = M.GetRow(iRow + bS + i0); int LR = M.GetRow(iRow + bS + i0, ref Indices, ref MtxVals); //foreach (var entry in row) { for (int lr = 0; lr < LR; lr++) { int ColIndex = Indices[lr]; double Value = MtxVals[lr]; Block[iRow, ColIndex - (bS + i0)] = Value; if (Value != 0.0) { ZeroRow = false; } } b[iRow] = B[iRow + bS]; if (ZeroRow) { if (b[iRow] != 0.0) { throw new ArithmeticException(); } else { Block[iRow, iRow] = 1.0; } } } // solve Block.SolveSymmetric(x, b); // store solution for (int iRow = 0; iRow < Nj; iRow++) { X[iRow + bS] = x[iRow]; } } }