protected override MsrMatrix ComputeMatrix() { MsrMatrix Approx = m_Approx.AssemblyMatrix; MsrMatrix ApproxInv = new MsrMatrix(Approx.RowPartitioning, Approx.ColPartition); switch (m_SolverConf.PredictorApproximation) { case PredictorApproximations.Identity: case PredictorApproximations.Identity_IP1: case PredictorApproximations.Diagonal: int i0 = Approx.RowPartitioning.i0; int LocalLength = Approx.RowPartitioning.LocalLength; for (int row = 0; row < LocalLength; row++) { double Approx_ii = Approx[row + i0, row + i0]; ApproxInv[row + i0, row + i0] = 1.0 / Approx_ii; } break; case PredictorApproximations.BlockDiagonal: BlockDiagonalMatrix ApproxBlock = new BlockDiagonalMatrix(Approx, Approx.RowPartitioning.LocalLength / m_LocalNoOfCells, Approx.ColPartition.LocalLength / m_LocalNoOfCells); BlockDiagonalMatrix ApproxBlockInv = ApproxBlock.Invert(); ApproxInv.Acc(1.0, ApproxBlockInv); break; default: throw new ArgumentException(); } return(ApproxInv); }
public void Init(MultigridOperator op) { BlockMsrMatrix M = op.OperatorMatrix; var MgMap = op.Mapping; this.m_MultigridOp = op; if (!M.RowPartitioning.Equals(MgMap.Partitioning)) { throw new ArgumentException("Row partitioning mismatch."); } if (!M.ColPartition.Equals(MgMap.Partitioning)) { throw new ArgumentException("Column partitioning mismatch."); } Mtx = M; int L = M.RowPartitioning.LocalLength; /* * diag = new double[L]; * int i0 = Mtx.RowPartitioning.i0; * * for(int i = 0; i < L; i++) { * diag[i] = Mtx[i0 + i, i0 + i]; * } */ if (op.Mapping.MaximalLength != op.Mapping.MinimalLength) { // 'BlockDiagonalMatrix' should be completely replaced by 'BlockMsrMatrix' throw new NotImplementedException("todo - Block Jacobi for variable block Sizes"); } int Nblk = op.Mapping.MaximalLength; Diag = new BlockDiagonalMatrix(M.ToMsrMatrix(), Nblk, Nblk); invDiag = Diag.Invert(); invDiag.CheckForNanOrInfM(); }