/// <summary> /// Local condition number formed by the block of each cell and its neighbors. /// </summary> /// <returns> /// one value per cell: /// - index: local cell index /// - content: condition number (one norm) of the local stencil /// </returns> public double[] StencilCondNumbers() { using (new FuncTrace()) { int J = m_map.LocalNoOfBlocks; Debug.Assert(J == m_map.GridDat.iLogicalCells.NoOfLocalUpdatedCells); var Mtx = m_MultigridOp.OperatorMatrix; Debug.Assert(Mtx._ColPartitioning.LocalNoOfBlocks == J); Debug.Assert(Mtx._RowPartitioning.LocalNoOfBlocks == J); var grd = m_MultigridOp.Mapping.AggGrid; double[] BCN = new double[J]; for (int j = 0; j < J; j++) { var LocBlk = grd.GetCellNeighboursViaEdges(j).Select(t => t.Item1).ToList(); LocBlk.Add(j); for (int i = 0; i < LocBlk.Count; i++) { if (LocBlk[i] >= J) { LocBlk.RemoveAt(i); i--; } } var Sel = new SubBlockSelector(m_MultigridOp.Mapping); Sel.VariableSelector(this.VarGroup); Sel.CellSelector(LocBlk, global: false); var Mask = new BlockMask(Sel); MultidimensionalArray[,] Blocks = Mask.GetFullSubBlocks(Mtx, ignoreSpecCoupling: false, ignoreVarCoupling: false); MultidimensionalArray FullBlock = Blocks.Cat(); BCN[j] = FullBlock.Cond('I'); } return(BCN); } }