예제 #1
0
        /// <summary>
        /// calls the PCG solver
        /// </summary>
        /// <param name="Converged">true if converged</param>
        /// <param name="NoOfIter">no of iterations done by solver</param>
        /// <param name="Unknowns"></param>
        /// <param name="Rhs"></param>
        protected override void CallSolver(out int NoOfIter, out bool Converged, IJVector Unknowns, IJVector Rhs)
        {
            if (m_Solver.p == IntPtr.Zero)
            {
                throw new ApplicationException("solver not initialized");
            }

            HypreException.Check(Wrappers.PCG.Setup(m_Solver, m_Matrix.m_ParCSR_matrix, Rhs.ParCRS_vector, Unknowns.ParCRS_vector));
            Wrappers.PCG.Solve(m_Solver, m_Matrix.m_ParCSR_matrix, Rhs.ParCRS_vector, Unknowns.ParCRS_vector);

            // We don't want to raise an exception for
            // a 'method did not converge'- or 'numerical breakdown' - Error
            // that may occur in HYPRE
            Wrappers.Utilities.HYPRE_ClearAllErrors();

            int Con;

            HypreException.Check(Wrappers.PCG.GetConverged(m_Solver, out Con));
            if (Con != 0)
            {
                Converged = true;
            }
            else
            {
                Converged = false;
            }

            HypreException.Check(Wrappers.PCG.GetNumIterations(m_Solver, out NoOfIter));
        }
예제 #2
0
파일: _IJMatrix.cs 프로젝트: xyuan/BoSSS
        /// <summary>
        /// general matrix/vector product; see <see cref="ISparseMatrix.SpMV"/>;
        /// </summary>
        /// <typeparam name="VectorType1"></typeparam>
        /// <typeparam name="VectorType2"></typeparam>
        /// <param name="alpha"></param>
        /// <param name="a"></param>
        /// <param name="beta"></param>
        /// <param name="acc"></param>
        public void SpMV <VectorType1, VectorType2>(double alpha, VectorType1 a, double beta, VectorType2 acc)
            where VectorType1 : System.Collections.Generic.IList <double>
            where VectorType2 : System.Collections.Generic.IList <double>
        {
            if (a.Count < ColPartition.LocalLength)
            {
                throw new ArgumentException("length/count of 'a' must be equal to local length of column partition", "a");
            }
            if (acc.Count < RowPartitioning.LocalLength)
            {
                throw new ArgumentException("length/count of 'acc' must be greater or equal to local length of row partition", "acc");
            }
            if (object.ReferenceEquals(a, acc))
            {
                throw new ArgumentException("in-place computation is not supported.", "a,acc");
            }


            IJVector _acc = new IJVector(RowPartitioning);

            if (beta != 0.0)
            {
                _acc.SetValues(acc);
            }
            IJVector _a = new IJVector(ColPartition);

            _a.SetValues(a);

            HypreException.Check(Wrappers.ParCSRMatrix.ParCSRMatrixMatvec(alpha, m_ParCSR_matrix, _a.ParCRS_vector, beta, _acc.ParCRS_vector));

            _acc.GetValues(acc);

            _acc.Dispose();
            _a.Dispose();
        }
예제 #3
0
        /// <summary>
        /// see <see cref="Solver.CallSolver"/>
        /// </summary>
        /// <remarks>
        /// ParaSails should be used only as aa implicit preconditioner, this method
        /// exists only for reasons of compability and completeness.
        /// </remarks>
        protected override void CallSolver(out int NoOfIter, out bool Converged, IJVector Unknowns, IJVector Rhs)
        {
            if (m_Solver.p == IntPtr.Zero)
            {
                throw new ApplicationException("solver not initialized");
            }

            HypreException.Check(Wrappers.ParaSails.__HYPRE_ParaSailsSetup(m_Solver, m_Matrix.m_ParCSR_matrix, Rhs.ParCRS_vector, Unknowns.ParCRS_vector));
            Wrappers.ParaSails.__HYPRE_ParaSailsSolve(m_Solver, m_Matrix.m_ParCSR_matrix, Rhs.ParCRS_vector, Unknowns.ParCRS_vector);
            // We dont want to raise an exception for
            // a 'method did not converge'- or 'nomerical breakdown' - Error
            // that may occur in HYPRE
            Wrappers.Utilities.HYPRE_ClearAllErrors();

            NoOfIter  = 1;
            Converged = true;
        }
예제 #4
0
 /// <summary>
 /// calls the corresponding HYPRE solver function
 /// </summary>
 /// <param name="Converged">true if converged</param>
 /// <param name="NoOfIter">no of iterations done by solver</param>
 /// <param name="Unknowns">on input, the starting value for the iterative process;
 /// on output, an approximpate solution to the linear problem.</param>
 /// <param name="Rhs">
 /// on input, the right-hand-side of the problem.
 /// </param>
 protected abstract void CallSolver(out int NoOfIter, out bool Converged, IJVector Unknowns, IJVector Rhs);
예제 #5
0
        /// <summary>
        /// solves the equation system
        /// (diag(<paramref name="d"/>) + <paramref name="Scale"/>*M)*<paramref name="x"/>=<paramref name="rhs"/>,
        /// where diag(<paramref name="d"/>) denotes a diagonal matrix with the diagonal vector <paramref name="d"/>;
        /// </summary>
        /// <typeparam name="Tunknowns"></typeparam>
        /// <typeparam name="Trhs"></typeparam>
        /// <typeparam name="Tdiag"></typeparam>
        /// <param name="Scale">
        /// scaling of the matrix (does not apply to <paramref name="d"/>);
        /// must be unequal to 0;
        /// this scaling does not alter the matrix-it's the same after the return of this method.
        /// </param>
        /// <param name="d">
        /// diagonal vector; can be null;
        /// length must be equal to the Nupdate-length of the matrix mapping;
        /// may be altered during execution;
        /// </param>
        /// <param name="x">on exit, the approximate solution to the equation system;
        /// </param>
        /// <param name="rhs">
        /// right hand side of the equation system; may be overwritten;
        /// </param>
        public SolverResult Solve <Tdiag, Tunknowns, Trhs>(double Scale, Tdiag d, Tunknowns x, Trhs rhs)
            where Tdiag : IList <double>
            where Tunknowns : IList <double>
            where Trhs : IList <double>
        {
            using (new FuncTrace()) {
                SolverResult res = new SolverResult();

                Stopwatch st = new Stopwatch();
                st.Reset();
                st.Start();

                // modify diagonal
                // ===============

                // truly, we're not solving (diag(d) + Scale*M)*x = rhs,
                // but ((1.0/Scale)*diag(d) + M) = (1.0/Scale)*rhs

                double ooScale = 1.0 / Scale;
                int    N       = int.MinValue;
                if (d != null)
                {
                    int i0 = (int)m_Matrix.RowPartitioning.i0;

                    N = m_Matrix.RowPartitioning.LocalLength;
                    int Nd = d.Count;
                    if (d.Count > N || N % Nd != 0)
                    {
                        throw new ArgumentException("length must be equal to or a factor of the number of rows stored on this processor", "d");
                    }

                    int ix = 0;
                    for (int i = 0; i < N; i++)
                    {
                        double vadd = d[ix];
                        ix++;
                        if (ix >= Nd)
                        {
                            ix = 0;
                        }

                        if (vadd != 0.0)
                        {
                            int    iglob = i + i0;
                            double v     = m_Matrix.GetDiagonalElement(iglob);
                            v += ooScale * vadd;
                            m_Matrix.SetDiagonalElement(iglob, v);
                        }
                    }
                }


                // scale rhs
                // =========

                if (ooScale != 1.0)
                {
                    for (int i = 0; i < N; i++)
                    {
                        rhs[i] *= ooScale;
                    }
                }


                // pass values to HYPRE
                // ====================
                IJVector Unknowns = new IJVector(m_Matrix.ColPartition);
                IJVector Rhs      = new IJVector(m_Matrix.RowPartitioning);

                Unknowns.SetValues <Tunknowns>(x);
                Rhs.SetValues <Trhs>(rhs);

                CallSolver(out res.NoOfIterations, out res.Converged, Unknowns, Rhs);


                // return
                // ======

                if (d != null)
                {
                    int ix = 0;
                    int Nd = d.Count;

                    int i0 = (int)m_Matrix.RowPartitioning.i0;

                    for (int i = 0; i < N; i++)
                    {
                        double vadd = d[ix];
                        ix++;
                        if (ix >= Nd)
                        {
                            ix = 0;
                        }

                        if (vadd != 0.0)
                        {
                            int    iglob = i + i0;
                            double v     = m_Matrix.GetDiagonalElement(iglob);
                            v -= ooScale * vadd;
                            m_Matrix.SetDiagonalElement(iglob, v);
                        }
                    }
                }



                Unknowns.GetValues <Tunknowns>(x);

                Unknowns.Dispose();
                Rhs.Dispose();

                st.Stop();
                res.RunTime = st.Elapsed;
                return(res);
            }
        }