/// <summary> /// ~ /// </summary> public void Init(MultigridOperator op) { BlockMsrMatrix M = op.OperatorMatrix; var MgMap = op.Mapping; this.m_MultigridOp = op; if (!M.RowPartitioning.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Row partitioning mismatch."); } if (!M.ColPartition.EqualsPartition(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"); Diag = new BlockMsrMatrix(M._RowPartitioning, M._ColPartitioning); invDiag = new BlockMsrMatrix(M._RowPartitioning, M._ColPartitioning); int Jloc = MgMap.LocalNoOfBlocks; int j0 = MgMap.FirstBlock; MultidimensionalArray temp = null; for (int j = 0; j < Jloc; j++) { int jBlock = j + j0; int Nblk = MgMap.GetBlockLen(jBlock); int i0 = MgMap.GetBlockI0(jBlock); if (temp == null || temp.NoOfCols != Nblk) { temp = MultidimensionalArray.Create(Nblk, Nblk); } M.ReadBlock(i0, i0, temp); Diag.AccBlock(i0, i0, 1.0, temp, 0.0); temp.Invert(); invDiag.AccBlock(i0, i0, 1.0, temp, 0.0); } #if DEBUG invDiag.CheckForNanOrInfM(); #endif }