예제 #1
0
파일: Utils.cs 프로젝트: rohitvuppala/BoSSS
        public static BlockMsrMatrix CreateShapeOfOnes(BlockMsrMatrix A)
        {
            var rowmap    = A._RowPartitioning;
            var colmap    = A._ColPartitioning;
            int RowBlocks = rowmap.LocalNoOfBlocks;
            int ColBlocks = colmap.LocalNoOfBlocks;

            BlockMsrMatrix B = new BlockMsrMatrix(rowmap, colmap);

            Partitioning rowpart = new Partitioning(RowBlocks);

            for (int iBlock = rowpart.i0; iBlock < rowpart.iE; iBlock++)
            {
                for (int jBlock = rowpart.i0; jBlock < rowpart.iE; jBlock++)
                {
                    int i0   = rowmap.GetBlockI0(iBlock);
                    int j0   = colmap.GetBlockI0(jBlock);
                    int iL   = rowmap.GetBlockLen(iBlock);
                    int jL   = colmap.GetBlockLen(jBlock);
                    var subM = MultidimensionalArray.Create(iL, jL);
                    A.ReadBlock(i0, j0, subM);
                    subM.ApplyAll(i => i != 0.0 ? 1 : 0);
                    B.AccBlock(i0, j0, 1.0, subM);
                }
            }
            double min, max;
            int    minc, minr, maxc, maxr;

            B.GetMinimumAndMaximum_MPILocal(out min, out minr, out minc, out max, out maxr, out maxc);
            Debug.Assert(min == 0);
            Debug.Assert(max == 1);
            return(B);
        }
예제 #2
0
파일: IBMUtility.cs 프로젝트: xyuan/BoSSS
        internal static MultidimensionalArray GetBlock(BlockMsrMatrix Mtx, int jCell)
        {
            Debug.Assert(Mtx._RowPartitioning.FirstBlock + jCell == Mtx._ColPartitioning.FirstBlock + jCell);
            int jCellGlb = Mtx._RowPartitioning.FirstBlock + jCell;
            int i0Glb    = Mtx._RowPartitioning.GetBlockI0(jCellGlb);
            int j0Glb    = Mtx._ColPartitioning.GetBlockI0(jCellGlb);
            int Mblk     = Mtx._RowPartitioning.GetBlockLen(jCellGlb);
            int Nblk     = Mtx._ColPartitioning.GetBlockLen(jCellGlb);
            MultidimensionalArray ret = MultidimensionalArray.Create(Mblk, Nblk);

            Mtx.ReadBlock(i0Glb, j0Glb, ret);
            return(ret);
        }
예제 #3
0
        private MultidimensionalArray GetBlock(BlockMsrMatrix target, bool ignoreVarCoupling, bool ignoreSpecCoupling, int iLoc, int jLoc)
        {
            var _Sblocks = MultidimensionalArray.Create(BMLoc.GetLengthOfCell(iLoc), BMLoc.GetLengthOfCell(jLoc));


            for (int iVar = 0; iVar < StructuredNi0[iLoc].Length; iVar++)     // loop over (row/codomain/test) variables
            {
                for (int jVar = 0; jVar < StructuredNi0[jLoc].Length; jVar++) // loop over (column/domain/trial) variables
                {
                    if (ignoreVarCoupling && jVar != iVar)
                    {
                        continue;
                    }
                    for (int iSpc = 0; iSpc < StructuredNi0[iLoc][iVar].Length; iSpc++)   // loop over species
                    {
                        for (int jSpc = 0; jSpc < StructuredNi0[jLoc][jVar].Length; jSpc++)
                        {
                            if (ignoreSpecCoupling && jSpc != iSpc)
                            {
                                continue;
                            }
                            for (int iMode = 0; iMode < StructuredNi0[iLoc][iVar][iSpc].Length; iMode++)
                            {
                                for (int jMode = 0; jMode < StructuredNi0[jLoc][jVar][jSpc].Length; jMode++)
                                {
                                    extNi0 RowNi0   = StructuredNi0[iLoc][iVar][iSpc][iMode];
                                    extNi0 ColNi0   = StructuredNi0[jLoc][jVar][jSpc][jMode];
                                    int    Targeti0 = RowNi0.Gi0;
                                    int    Targetj0 = ColNi0.Gi0;
                                    int    Subi0    = BMLoc.GetRelativeSubBlockOffset(iLoc, iVar, iSpc, iMode);
                                    int    Subj0    = BMLoc.GetRelativeSubBlockOffset(jLoc, jVar, jSpc, jMode);
                                    int    Subie    = Subi0 + RowNi0.N - 1;
                                    int    Subje    = Subj0 + ColNi0.N - 1;

                                    target.ReadBlock(Targeti0, Targetj0,
                                                     _Sblocks.ExtractSubArrayShallow(new int[] { Subi0, Subj0 }, new int[] { Subie, Subje }));
                                }
                            }
                        }
                    }
                }
            }

            return(_Sblocks);
        }
예제 #4
0
        private static void ExtractBlock(
            int[] _i0s,
            int[] _Lns,
            bool Sp2Full,
            BlockMsrMatrix MtxSp, ref MultidimensionalArray MtxFl) //
        {
            Debug.Assert(_i0s.Length == _Lns.Length);
            int E = _i0s.Length;

            int NN = _Lns.Sum();

            if (MtxFl == null || MtxFl.NoOfRows != NN)
            {
                Debug.Assert(Sp2Full == true);
                MtxFl = MultidimensionalArray.Create(NN, NN);
            }
            else
            {
                if (Sp2Full)
                {
                    MtxFl.Clear();
                }
            }

            if (!Sp2Full)
            {
                Debug.Assert(MtxSp != null);
            }


            int i0Rowloc = 0;

            for (int eRow = 0; eRow < E; eRow++)   // loop over variables in configuration
            {
                int i0Row = _i0s[eRow];
                int NRow  = _Lns[eRow];

                int i0Colloc = 0;
                for (int eCol = 0; eCol < E; eCol++)   // loop over variables in configuration
                {
                    int i0Col = _i0s[eCol];
                    int NCol  = _Lns[eCol];

                    MultidimensionalArray MtxFl_blk;
                    if (i0Rowloc == 0 && NRow == MtxFl.GetLength(0) && i0Colloc == 0 && NCol == MtxFl.GetLength(1))
                    {
                        MtxFl_blk = MtxFl;
                    }
                    else
                    {
                        MtxFl_blk = MtxFl.ExtractSubArrayShallow(new[] { i0Rowloc, i0Colloc }, new[] { i0Rowloc + NRow - 1, i0Colloc + NCol - 1 });
                    }

                    if (Sp2Full)
                    {
                        if (MtxSp != null)
                        {
                            MtxSp.ReadBlock(i0Row, i0Col, MtxFl_blk);
                        }
                        else
                        {
                            MtxFl_blk.AccEye(1.0);
                        }
                    }
                    else
                    {
                        MtxSp.AccBlock(i0Row, i0Col, 1.0, MtxFl_blk, 0.0);
                    }
#if DEBUG
                    for (int n_row = 0; n_row < NRow; n_row++)     // row loop...
                    {
                        for (int n_col = 0; n_col < NCol; n_col++) // column loop...
                        {
                            Debug.Assert(MtxFl[n_row + i0Rowloc, n_col + i0Colloc] == ((MtxSp != null) ? (MtxSp[n_row + i0Row, n_col + i0Col]) : (n_col == n_row ? 1.0 : 0.0)));
                        }
                    }
#endif
                    i0Colloc += NCol;
                }
                i0Rowloc += NRow;
            }
        }
예제 #5
0
파일: IBMUtility.cs 프로젝트: xyuan/BoSSS
        /// <summary>
        /// Specialized version of
        /// <see cref="BlockDiagonalMatrix.SpMV{VectorType1, VectorType2}(double, VectorType1, double, VectorType2)"/>
        /// where each block corresponds to an individual cell and where the
        /// multiplication shall only be performed over the cells in a given
        /// <paramref name="mask"/>
        /// </summary>
        /// <typeparam name="VectorType1"></typeparam>
        /// <typeparam name="VectorType2"></typeparam>
        /// <param name="M"></param>
        /// <param name="alpha"></param>
        /// <param name="a"></param>
        /// <param name="beta"></param>
        /// <param name="acc"></param>
        /// <param name="mask"></param>
        internal static void SubMatrixSpMV <VectorType1, VectorType2>(BlockMsrMatrix M, double alpha, VectorType1 a, double beta, VectorType2 acc, CellMask mask)
            where VectorType1 : IList <double>
            where VectorType2 : IList <double>
        {
            if (acc.Count != M.RowPartitioning.LocalLength)
            {
                throw new ArgumentException("mismatch between accumulator and number of rows, i.e. row partition.", "acc");
            }
            if (a.Count != M.ColPartition.LocalLength)
            {
                throw new ArgumentException("mismatch between input vector 'a' and number of columns, i.e. column partition.", "a");
            }

            //int M1 = M.NoOfColsPerBlock;
            //int N1 = M.NoOfRowsPerBlock;
            double[] aBuf = null;// new double[M1];
            MultidimensionalArray Mbuf = null;

            int Glob_cell0 = mask.GridData.CellPartitioning.i0;

            foreach (int cell in mask.ItemEnum)
            {
                //int i0 = cell * N1; // row
                //int j0 = cell * M1; // col
                int i0Glob = M._RowPartitioning.GetBlockI0(cell + Glob_cell0);
                int j0Glob = M._ColPartitioning.GetBlockI0(cell + Glob_cell0);
                int i0     = i0Glob - M._RowPartitioning.i0;
                int j0     = j0Glob - M._RowPartitioning.i0;
                int M1     = M._RowPartitioning.GetBlockLen(cell + Glob_cell0);
                int N1     = M._ColPartitioning.GetBlockLen(cell + Glob_cell0);

                if (aBuf == null || aBuf.Length < M1)
                {
                    aBuf = new double[M1];
                }

                for (int j = 0; j < M1; j++)
                {
                    aBuf[j] = a[j + j0];
                }

                if (Mbuf == null || Mbuf.GetLength(0) != M1 || Mbuf.GetLength(1) != N1)
                {
                    Mbuf = MultidimensionalArray.Create(M1, N1);
                }

                M.ReadBlock(i0Glob, j0Glob, Mbuf);

                for (int i = 0; i < N1; i++)
                {
                    double _acc = 0;

                    for (int j = 0; j < M1; j++)
                    {
                        _acc += Mbuf[i, j] * aBuf[j];
                    }

                    acc[i + i0] = acc[i + i0] * beta + _acc * alpha;
                }
            }
        }
        private static void ExtractBlock(int jCell,
                                         AggregationGridBasis basis, int[] Degrees,
                                         ChangeOfBasisConfig conf,
                                         int E, int[] _i0s, bool Sp2Full,
                                         BlockMsrMatrix MtxSp, ref MultidimensionalArray MtxFl)
        {
            int NN = conf.VarIndex.Sum(iVar => basis.GetLength(jCell, Degrees[iVar]));

            if (MtxFl == null || MtxFl.NoOfRows != NN)
            {
                Debug.Assert(Sp2Full == true);
                MtxFl = MultidimensionalArray.Create(NN, NN);
            }
            else
            {
                if (Sp2Full)
                {
                    MtxFl.Clear();
                }
            }

            if (!Sp2Full)
            {
                Debug.Assert(MtxSp != null);
            }


            int i0Rowloc = 0;

            for (int eRow = 0; eRow < E; eRow++)   // loop over variables in configuration
            {
                int i0Row   = _i0s[eRow];
                int iVarRow = conf.VarIndex[eRow];

                int NRow = basis.GetLength(jCell, Degrees[iVarRow]);

                int i0Colloc = 0;
                for (int eCol = 0; eCol < E; eCol++)   // loop over variables in configuration

                {
                    int i0Col   = _i0s[eCol];
                    int iVarCol = conf.VarIndex[eCol];

                    int NCol = basis.GetLength(jCell, Degrees[iVarCol]);

                    MultidimensionalArray MtxFl_blk;
                    if (i0Rowloc == 0 && NRow == MtxFl.GetLength(0) && i0Colloc == 0 && NCol == MtxFl.GetLength(1))
                    {
                        MtxFl_blk = MtxFl;
                    }
                    else
                    {
                        MtxFl_blk = MtxFl.ExtractSubArrayShallow(new[] { i0Rowloc, i0Colloc }, new[] { i0Rowloc + NRow - 1, i0Colloc + NCol - 1 });
                    }

                    /*
                     * for(int n_row = 0; n_row < NRow; n_row++) { // row loop...
                     *  for(int n_col = 0; n_col < NCol; n_col++) { // column loop...
                     *      if(Sp2Full) {
                     *          // copy from sparse to full
                     *          MtxFl[n_row + i0Rowloc, n_col + i0Colloc] = (MtxSp != null) ? ( MtxSp[n_row + i0Row, n_col + i0Col]) : (n_col == n_row ? 1.0 : 0.0);
                     *      } else {
                     *          // the other way around.
                     *          MtxSp[n_row + i0Row, n_col + i0Col] = MtxFl[n_row + i0Rowloc, n_col + i0Colloc];
                     *      }
                     *  }
                     * }
                     */

                    if (Sp2Full)
                    {
                        if (MtxSp != null)
                        {
                            MtxSp.ReadBlock(i0Row, i0Col, MtxFl_blk);
                        }
                        else
                        {
                            MtxFl_blk.AccEye(1.0);
                        }
                    }
                    else
                    {
#if DEBUG
                        Debug.Assert(MtxSp != null);
                        //for (int n_row = 0; n_row < NRow; n_row++) { // row loop...
                        //    for (int n_col = 0; n_col < NCol; n_col++) { // column loop...
                        //        Debug.Assert(MtxSp[n_row + i0Row, n_col + i0Col] == 0.0);
                        //    }
                        //}
#endif
                        MtxSp.AccBlock(i0Row, i0Col, 1.0, MtxFl_blk, 0.0);
                    }
#if DEBUG
                    for (int n_row = 0; n_row < NRow; n_row++)     // row loop...
                    {
                        for (int n_col = 0; n_col < NCol; n_col++) // column loop...
                        {
                            Debug.Assert(MtxFl[n_row + i0Rowloc, n_col + i0Colloc] == ((MtxSp != null) ? (MtxSp[n_row + i0Row, n_col + i0Col]) : (n_col == n_row ? 1.0 : 0.0)));
                        }
                    }
#endif


                    i0Colloc += NCol;
                }
                i0Rowloc += NRow;
            }
        }
예제 #7
0
        void BlockSol <V1, V2>(BlockMsrMatrix M, V1 X, V2 B)
            where V1 : IList <double>
            where V2 : IList <double> //
        {
            Debug.Assert(X.Count == M.ColPartition.LocalLength);
            Debug.Assert(B.Count == M.RowPartitioning.LocalLength);

            var Part = M.RowPartitioning;

            Debug.Assert(Part.EqualsPartition(this.CurrentStateMapping));

            int J = m_LsTrk.GridDat.Cells.NoOfLocalUpdatedCells;

            Debug.Assert(J == M._RowPartitioning.LocalNoOfBlocks);
            Debug.Assert(J == M._ColPartitioning.LocalNoOfBlocks);

            var basisS   = this.CurrentStateMapping.BasisS.ToArray();
            int NoOfVars = basisS.Length;

            MultidimensionalArray Block = null;

            double[] x = null, b = null;
#if DEBUG
            var unusedIndex = new System.Collections.BitArray(B.Count);
#endif

            for (int j = 0; j < J; j++)   // loop over cells...

            {
                for (int iVar = 0; iVar < NoOfVars; iVar++)
                {
                    int bS = this.CurrentStateMapping.LocalUniqueCoordinateIndex(iVar, j, 0);
                    int Nj = basisS[iVar].GetLength(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
                    M.ReadBlock(bS + M._RowPartitioning.i0, bS + M._ColPartitioning.i0, Block);

                    // extract part of RHS
                    for (int iRow = 0; iRow < Nj; iRow++)
                    {
                        bool ZeroRow = Block.GetRow(iRow).L2NormPow2() == 0;
                        b[iRow] = B[iRow + bS];

                        if (ZeroRow)
                        {
                            if (b[iRow] != 0.0)
                            {
                                throw new ArithmeticException();
                            }
                            else
                            {
                                Block[iRow, iRow] = 1.0;
                            }
                        }
#if DEBUG
                        unusedIndex[iRow + bS] = true;
#endif
                    }

                    // solve
                    Block.SolveSymmetric(x, b);

                    // store solution
                    for (int iRow = 0; iRow < Nj; iRow++)
                    {
                        X[iRow + bS] = x[iRow];
                    }
                }
            }
#if DEBUG
            for (int i = 0; i < unusedIndex.Length; i++)
            {
                if (unusedIndex[i] == false && B[i] != 0.0)
                {
                    throw new ArithmeticException("Non-zero entry in void region.");
                }
            }
#endif
        }
예제 #8
0
        private void AuxGetSubBlockMatrix(BlockMsrMatrix target, BlockMsrMatrix source, BlockMaskBase mask, bool ignoreCellCoupling, bool ignoreVarCoupling, bool ignoreSpecCoupling)
        {
            bool IsLocalMask = mask.GetType() == typeof(BlockMaskLoc);

            extNi0[][][][] RowNi0s = mask.m_StructuredNi0;
            extNi0[][][][] ColNi0s = this.StructuredNi0;

            int auxIdx = 0;

            for (int iLoc = 0; iLoc < RowNi0s.Length; iLoc++)
            {
                for (int jLoc = 0; jLoc < ColNi0s.Length; jLoc++)
                {
                    if (ignoreCellCoupling && jLoc != iLoc)
                    {
                        continue;
                    }
                    for (int iVar = 0; iVar < RowNi0s[iLoc].Length; iVar++)
                    {
                        for (int jVar = 0; jVar < ColNi0s[jLoc].Length; jVar++)
                        {
                            if (ignoreVarCoupling && jVar != iVar)
                            {
                                continue;
                            }
                            for (int iSpc = 0; iSpc < RowNi0s[iLoc][iVar].Length; iSpc++)
                            {
                                for (int jSpc = 0; jSpc < ColNi0s[jLoc][jVar].Length; jSpc++)
                                {
                                    if (ignoreSpecCoupling && jSpc != iSpc)
                                    {
                                        continue;
                                    }
                                    for (int iMode = 0; iMode < RowNi0s[iLoc][iVar][iSpc].Length; iMode++)
                                    {
                                        int Trgi0 = RowNi0s[iLoc][iVar][iSpc][iMode].Si0;
                                        for (int jMode = 0; jMode < ColNi0s[jLoc][jVar][jSpc].Length; jMode++)
                                        {
                                            extNi0 RowNi0 = RowNi0s[iLoc][iVar][iSpc][iMode];
                                            extNi0 ColNi0 = ColNi0s[jLoc][jVar][jSpc][jMode];
                                            int    Srci0  = IsLocalMask? RowNi0.Gi0: RowNi0.Li0 + source._RowPartitioning.i0 - m_map.LocalLength;
                                            int    Srcj0  = ColNi0.Gi0;

                                            var tmpBlock = MultidimensionalArray.Create(RowNi0.N, ColNi0.N);

                                            int Trgj0 = ColNi0s[jLoc][jVar][jSpc][jMode].Si0;
#if Debug
                                            SubMSR.ReadBlock(SubRowIdx, SubColIdx, tmpBlock);
                                            Debug.Assert(tmpBlock.Sum() == 0);
                                            Debug.Assert(tmpBlock.InfNorm() == 0);
#endif

                                            try {
                                                source.ReadBlock(Srci0, Srcj0,
                                                                 tmpBlock);
                                            } catch (Exception e) {
                                                Console.WriteLine("row: " + Srci0);
                                                Console.WriteLine("col: " + Srcj0);
                                                throw new Exception(e.Message);
                                            }
                                            Debug.Assert(Trgi0 < target.RowPartitioning.LocalLength);
                                            Debug.Assert(Trgj0 < target.ColPartition.LocalLength);


                                            target.AccBlock(Trgi0, Trgj0, 1.0, tmpBlock);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    auxIdx++;
                }
                auxIdx++;
            }
        }
예제 #9
0
        private MultidimensionalArray[] AuxGetSubBlocks(BlockMsrMatrix source, BlockMaskBase mask, bool ignoreCellCoupling, bool ignoreVarCoupling, bool ignoreSpecCoupling)
        {
            bool IsLocMask = mask.GetType() == typeof(BlockMaskLoc); // if external cells are masked, we have to consider other offsets ...

            int NoOfCells = mask.m_StructuredNi0.Length;
            int size      = ignoreCellCoupling ? NoOfCells : NoOfCells * NoOfCells;

            MultidimensionalArray[] Sblocks = new MultidimensionalArray[size];

            int auxIdx = 0;

            for (int iLoc = 0; iLoc < mask.m_StructuredNi0.Length; iLoc++)
            {
                for (int jLoc = 0; jLoc < mask.m_StructuredNi0.Length; jLoc++)
                {
                    if (ignoreCellCoupling && jLoc != iLoc)
                    {
                        continue;
                    }
                    int CellBlockLen = mask.GetLengthOfCell(jLoc);
                    Sblocks[auxIdx] = MultidimensionalArray.Create(CellBlockLen, CellBlockLen);
                    for (int iVar = 0; iVar < mask.m_StructuredNi0[iLoc].Length; iVar++)
                    {
                        for (int jVar = 0; jVar < mask.m_StructuredNi0[jLoc].Length; jVar++)
                        {
                            if (ignoreVarCoupling && jVar != iVar)
                            {
                                continue;
                            }
                            for (int iSpc = 0; iSpc < mask.m_StructuredNi0[iLoc][iVar].Length; iSpc++)
                            {
                                for (int jSpc = 0; jSpc < mask.m_StructuredNi0[jLoc][jVar].Length; jSpc++)
                                {
                                    if (ignoreSpecCoupling && jSpc != iSpc)
                                    {
                                        continue;
                                    }
                                    for (int iMode = 0; iMode < mask.m_StructuredNi0[iLoc][iVar][iSpc].Length; iMode++)
                                    {
                                        for (int jMode = 0; jMode < mask.m_StructuredNi0[jLoc][jVar][jSpc].Length; jMode++)
                                        {
                                            extNi0 RowNi0   = mask.m_StructuredNi0[iLoc][iVar][iSpc][iMode];
                                            extNi0 ColNi0   = mask.m_StructuredNi0[jLoc][jVar][jSpc][jMode];
                                            int    Targeti0 = IsLocMask ? RowNi0.Gi0 : RowNi0.Li0 + source._RowPartitioning.i0 - m_map.LocalLength;
                                            int    Targetj0 = ColNi0.Gi0;
                                            int    Subi0    = mask.GetRelativeSubBlockOffset(iLoc, iVar, iSpc, iMode);
                                            int    Subj0    = mask.GetRelativeSubBlockOffset(jLoc, jVar, jSpc, jMode);
                                            int    Subie    = Subi0 + RowNi0.N - 1;
                                            int    Subje    = Subj0 + ColNi0.N - 1;

                                            var tmp = Sblocks[auxIdx].ExtractSubArrayShallow(new int[] { Subi0, Subj0 }, new int[] { Subie, Subje });

                                            Debug.Assert((m_map.IsInLocalRange(Targeti0) && m_map.IsInLocalRange(Targetj0) && mask.GetType() == typeof(BlockMaskLoc)) || mask.GetType() == typeof(BlockMaskExt));

                                            try {
                                                source.ReadBlock(Targeti0, Targetj0, tmp
                                                                 );
                                            } catch (Exception e) {
                                                Console.WriteLine("row: " + Targeti0);
                                                Console.WriteLine("col: " + Targetj0);
                                                throw new Exception(e.Message);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    auxIdx++;
                }
            }
            return(Sblocks);
        }
예제 #10
0
        /// <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
        }
예제 #11
0
        public static void SubBlockExtractionWithCoupling(
            [Values(XDGusage.none, XDGusage.all)] XDGusage UseXdg,
            [Values(2)] int DGOrder,
            [Values(MatrixShape.diagonal, MatrixShape.diagonal_var, MatrixShape.diagonal_spec, MatrixShape.diagonal_var_spec)] MatrixShape MShape
            )
        {
            Utils.TestInit((int)UseXdg, DGOrder, (int)MShape);
            Console.WriteLine("ExtractDiagonalBlocks({0},{1},{2})", UseXdg, DGOrder, MShape);

            //Arrange --- get multigridoperator
            MultigridOperator MGOp = Utils.CreateTestMGOperator(UseXdg, DGOrder, MShape);
            BlockMsrMatrix    M    = MGOp.OperatorMatrix;
            MultigridMapping  map  = MGOp.Mapping;

            //Arrange --- setup masking
            SubBlockSelector SBS  = new SubBlockSelector(map);
            BlockMask        mask = new BlockMask(SBS, null);

            bool[] coupling = Utils.SetCoupling(MShape);

            //Arrange --- some time measurement
            Stopwatch stw = new Stopwatch();

            stw.Reset();

            //Arrange --- setup auxiliary matrix
            //this will show us if more is extracted, than it should ...
            var Mprep = new BlockMsrMatrix(map);

            Mprep.Acc(1.0, M);

            //Act --- diagonal subblock extraction
            stw.Start();
            var blocks = mask.GetDiagonalBlocks(Mprep, coupling[0], coupling[1]);

            stw.Stop();

            //Assert --- all diagonal blocks are extracted
            Assert.IsTrue(blocks.Length == map.LocalNoOfBlocks);


            for (int i = 0; i < map.LocalNoOfBlocks; i++)
            {
                //Arrange --- get ith diagonal block of M: M_i
                int iBlock = i + map.AggGrid.CellPartitioning.i0;
                int L      = map.GetBlockLen(iBlock);
                int i0     = map.GetBlockI0(iBlock);
                var Mblock = MultidimensionalArray.Create(L, L);
                M.ReadBlock(i0, i0, Mblock);

                //Act --- M_i-Mones_i
                Mblock.Acc(-1.0, blocks[i]);

                //Assert --- are extracted blocks and
                Assert.IsTrue(Mblock.InfNorm() == 0.0, String.Format("infNorm of block {0} neq 0!", i));
            }



            //BlockMsrMatrix all1;
            //all1.SetAll(1);
            //Generate broken diagonal matrix, die zur Maske passt: M
            //M+all1=M_prep
            //Wende Extraction auf M_prep an, Man sollte nun M bekommen
            //Test: M_prep-extract(M_prep)=all1
            //Test-crit: Result.SumEntries=DOF^2 oder Result.Max()==Result.Min()==1
            //oder (besser)
            //Test: M-extract(M_prep)=zeros
            //Test-crit: Result.InfNorm()==0

            //Der Test kann für ExtractSubMatrix mit ignore coupling wiederholt werden
            //eventuell: Testmatrix finden mit brauchbaren Nebendiagonalen für einen Fall

            //Was wird getestet: funktioniert ignorecoupling richtig?
        }