public Vector Start_Solver(CSlR_Matrix A, Vector F, Preconditioner.Type_Preconditioner PREC)
        {
            switch (PREC)
            {
            case Preconditioner.Type_Preconditioner.Diagonal_Preconditioner:
            {
                Preconditioner = new Diagonal_Preconditioner(A);
                break;
            }

            case Preconditioner.Type_Preconditioner.LU_Decomposition:
            {
                Preconditioner = new LU_Preconditioner(A);
                break;
            }
            }

            int    n   = A.N;
            Vector RES = new Vector(n);

            for (int i = 0; i < n; i++)
            {
                RES.Elem[i] = 0.0;
            }

            Vector r    = new Vector(n);
            Vector rs   = new Vector(n);
            Vector p    = new Vector(n);
            Vector ps   = new Vector(n);
            Vector vec  = new Vector(n);
            Vector vec2 = new Vector(n);

            double alpha, beta, sc1, sc2;
            bool   Flag = true;

            A.Mult_MV(RES, vec);
            for (int i = 0; i < n; i++)
            {
                r.Elem[i] = F.Elem[i] - vec.Elem[i];
            }

            Preconditioner.Start_Preconditioner(r, ps);

            for (int i = 0; i < n; i++)
            {
                r.Elem[i]  = ps.Elem[i];
                rs.Elem[i] = ps.Elem[i];
                p.Elem[i]  = ps.Elem[i];
            }

            while (Flag && Iter < Max_Iter)
            {
                sc1 = r * rs;

                A.Mult_MV(p, vec);
                Preconditioner.Start_Preconditioner(vec, vec2);
                sc2 = vec2 * ps;

                alpha = sc1 / sc2;

                for (int i = 0; i < n; i++)
                {
                    RES.Elem[i] += alpha * p.Elem[i];
                    r.Elem[i]   -= alpha * vec2.Elem[i];
                }

                Preconditioner.Start_Tr_Preconditioner(ps, vec);
                A.Mult_MtV(vec, vec2);
                for (int i = 0; i < n; i++)
                {
                    rs.Elem[i] -= alpha * vec2.Elem[i];
                }
                sc2 = r * rs;

                beta = sc2 / sc1;

                double Norma_r = r.Norma();
                if (Norma_r < Eps)
                {
                    Flag = false;
                }

                if (Math.Abs(beta) < Double.Epsilon)
                {
                    throw new Exception("BiConjurate_Gradient_Method: diverges given ~r(0)");
                }

                for (int i = 0; i < n; i++)
                {
                    p.Elem[i]  = r.Elem[i] + beta * p.Elem[i];
                    ps.Elem[i] = rs.Elem[i] + beta * ps.Elem[i];
                }

                Iter++;
                Console.WriteLine("{0,-20}    {1,-20}", Iter, Norma_r);
            }

            return(RES);
        }
Esempio n. 2
0
        public Vector Start_Solver(CSlR_Matrix A, Vector F, int PREC)
        {
            int n = A.N;
            // решение
            Vector RES = new Vector(n);

            for (int i = 0; i < n; i++)
            {
                RES.Elem[i] = 0.0;
            }
            //реализация предобусловливателя
            switch (PREC)
            {
            case 1: { Pr = new Diag_Predconditioner(A); break; }

            case 2: { Pr = new ILU_Decomposition(A); break; }
                // default: { Pr = new E_Predconditioner(); break; }
            }
            var r        = new Vector(n);
            var p        = new Vector(n);
            var r_       = new Vector(n);
            var p_       = new Vector(n);
            var vec      = new Vector(n);
            var vec_     = new Vector(n);
            var vec_help = new Vector(n);

            // параметры
            double alpha, betta, sc1, sc2;

            // флаг для остановки
            int Flag = 0;

            // ||r||
            double nev_r = 0;

            // начало Bi_Conjugate_Gradient_Method


            A.Mult_MV(RES, vec_help);
            for (int i = 0; i < n; i++)
            {
                vec_help.Elem[i] = F.Elem[i] - vec_help.Elem[i];
            }
            Pr.Start_Predconditioner(vec_help, r); // в r предобусловленная система-невязка
            p.Copy(r);
            r_.Copy(r);
            p_.Copy(r_);
            while (Flag != 1 && Iter < Max_Iter)
            {
                sc1 = r * r_;
                A.Mult_MV(p, vec_help);
                Pr.Start_Predconditioner(vec_help, vec);
                sc2   = vec * p_;
                alpha = sc1 / sc2;
                for (int i = 0; i < n; i++)
                {
                    RES.Elem[i] += alpha * p.Elem[i];
                    r.Elem[i]   -= alpha * vec.Elem[i];
                }
                Pr.Start_Tr_Predconditioner(p_, vec_help);
                A.Mult_MtV(vec_help, vec_);
                for (int i = 0; i < n; i++)
                {
                    r_.Elem[i] -= alpha * vec_.Elem[i];
                }
                sc2   = r * r_;
                betta = sc2 / sc1;
                nev_r = r.Norm();
                if (nev_r < Eps)
                {
                    Flag = 1;
                }
                if (Flag == 0)
                {
                    for (int i = 0; i < n; i++)
                    {
                        p.Elem[i]  = r.Elem[i] + betta * p.Elem[i];
                        p_.Elem[i] = r_.Elem[i] + betta * p_.Elem[i];
                    }
                }
                //Console.WriteLine("{0,-20} {1,-20}", Iter, nev_r.ToString("E"));
                Console.WriteLine(nev_r.ToString("E"));
                Iter++;
            }
            return(RES);
        }