示例#1
0
文件: _IJMatrix.cs 项目: xyuan/BoSSS
        /// <summary>
        /// initializes this matrix to be a copy of <paramref name="mtx"/>;
        /// </summary>
        /// <param name="mtx"></param>
        public IJMatrix(IMutableMatrixEx mtx)
        {
            if (mtx.RowPartitioning.MPI_Comm != mtx.ColPartition.MPI_Comm)
            {
                throw new ArgumentException();
            }
            if (mtx.RowPartitioning.IsMutable)
            {
                throw new ArgumentException();
            }
            if (mtx.ColPartition.IsMutable)
            {
                throw new ArgumentException();
            }

            m_RowPartition = mtx.RowPartitioning;
            m_ColPartition = mtx.ColPartition;


            if (mtx.NoOfRows != mtx.NoOfCols)
            {
                throw new ArgumentException("matrix must be quadratic.", "mtx");
            }

            if (mtx.NoOfRows > (int.MaxValue - 2))
            {
                throw new ApplicationException("unable to create HYPRE matrix: no. of matrix rows is larger than HYPRE index type (32 bit signed int);");
            }
            if (mtx.NoOfCols > (int.MaxValue - 2))
            {
                throw new ApplicationException("unable to create HYPRE matrix: no. of matrix columns is larger than HYPRE index type (32 bit signed int);");
            }


            // matrix: init
            MPI_Comm comm   = csMPI.Raw._COMM.WORLD;
            int      ilower = (int)mtx.RowPartitioning.i0;
            int      iupper = (int)ilower + mtx.RowPartitioning.LocalLength - 1;
            int      jlower = (int)mtx.ColPartition.i0;
            int      jupper = (int)jlower + mtx.ColPartition.LocalLength - 1;

            HypreException.Check(Wrappers.IJMatrix.Create(comm, ilower, iupper, jlower, jupper, out m_IJMatrix));
            HypreException.Check(Wrappers.IJMatrix.SetObjectType(m_IJMatrix, Wrappers.Constants.HYPRE_PARCSR));
            HypreException.Check(Wrappers.IJMatrix.Initialize(m_IJMatrix));

            // matrix: set values, row by row ...
            int nrows, lmax = mtx.GetMaxNoOfNonZerosPerRow();

            int[]    rows   = new int[1], cols = new int[lmax], ncols = new int[1];
            double[] values = new double[lmax];
            int      LR;

            int[]    col = null;
            double[] val = null;
            for (int i = 0; i < mtx.RowPartitioning.LocalLength; i++)
            {
                int iRowGlob = i + mtx.RowPartitioning.i0;
                LR = mtx.GetRow(iRowGlob, ref col, ref val);

                nrows    = 1;
                rows[0]  = iRowGlob;
                ncols[0] = LR;
                int cnt = 0;
                for (int j = 0; j < LR; j++)
                {
                    if (val[j] != 0.0)
                    {
                        cols[cnt]   = col[j];
                        values[cnt] = val[j];
                        cnt++;
                    }
                }
                if (cnt <= 0)
                {
                    throw new ArgumentException(string.Format("Zero matrix row detected (local row index: {0}, global row index: {1}).", i, iRowGlob));
                }

                HypreException.Check(Wrappers.IJMatrix.SetValues(m_IJMatrix, nrows, ncols, rows, cols, values));
            }

            // matrix: assembly
            HypreException.Check(Wrappers.IJMatrix.Assemble(m_IJMatrix));
            HypreException.Check(Wrappers.IJMatrix.GetObject(m_IJMatrix, out m_ParCSR_matrix));
        }