示例#1
0
        public void step(ref object a, double t, double theta = 1.0)
        {
            Utils.QL_REQUIRE(t - dt_ > -1e-8, () => "a step towards negative time given");
            double intermediateTimeStep = dt_.Value * alpha_;

            object fStar = a;

            trapezoidalScheme_.setStep(intermediateTimeStep);
            trapezoidalScheme_.step(ref fStar, t);

            bcSet_.setTime(Math.Max(0.0, t - dt_.Value));
            bcSet_.applyBeforeSolving(map_, a as Vector);

            Vector fStarVec = fStar as Vector;
            Vector f        = (1.0 / alpha_ * fStarVec - Math.Pow(1.0 - alpha_, 2.0) / alpha_ * (a as Vector)) / (2.0 - alpha_);

            if (map_.size() == 1)
            {
                a = map_.solve_splitting(0, f, -beta_.Value);
            }
            else
            {
                if (solverType_ == SolverType.BiCGstab)
                {
                    BiCGStab.MatrixMult preconditioner = x => map_.preconditioner(x, -beta_.Value);
                    BiCGStab.MatrixMult applyF         = x => this.apply(x);

                    BiCGStabResult result =
                        new BiCGStab(applyF, Math.Max(10, (a as Vector).Count), relTol_, preconditioner).solve(f, f);

                    iterations_ += result.Iterations;
                    a            = result.X;
                }
                else if (solverType_ == SolverType.GMRES)
                {
                    GMRES.MatrixMult preconditioner = x => map_.preconditioner(x, -beta_.Value);
                    GMRES.MatrixMult applyF         = x => this.apply(x);

                    GMRESResult result =
                        new GMRES(applyF, Math.Max(10, (a as Vector).Count) / 10, relTol_, preconditioner).solve(f, f);

                    iterations_ += result.Errors.Count;
                    a            = result.X;
                }
                else
                {
                    Utils.QL_FAIL("unknown/illegal solver type");
                }
            }
            bcSet_.applyAfterSolving(a as Vector);
        }
示例#2
0
        public void step(ref object a, double t, double theta = 1.0)
        {
            Utils.QL_REQUIRE(t - dt_.Value > -1e-8, () => "a step towards negative time given");
            map_.setTime(Math.Max(0.0, t - dt_.Value), t);
            bcSet_.setTime(Math.Max(0.0, t - dt_.Value));

            bcSet_.applyBeforeSolving(map_, a as Vector);

            if (map_.size() == 1)
            {
                a = map_.solve_splitting(0, a as Vector, -theta * dt_.Value);
            }
            else
            {
                if (solverType_ == SolverType.BiCGstab)
                {
                    BiCGStab.MatrixMult preconditioner = x => map_.preconditioner(x, -theta * dt_.Value);
                    BiCGStab.MatrixMult applyF         = x => this.apply(x, theta);

                    BiCGStabResult result =
                        new BiCGStab(applyF, Math.Max(10, (a as Vector).Count), relTol_, preconditioner).solve(a as Vector, a as Vector);

                    iterations_ += result.Iterations;
                    a            = result.X;
                }
                else if (solverType_ == SolverType.GMRES)
                {
                    GMRES.MatrixMult preconditioner = x => map_.preconditioner(x, -theta * dt_.Value);
                    GMRES.MatrixMult applyF         = x => this.apply(x, theta);

                    GMRESResult result =
                        new GMRES(applyF, Math.Max(10, (a as Vector).Count) / 10, relTol_, preconditioner).solve(a as Vector, a as Vector);

                    iterations_ += result.Errors.Count;
                    a            = result.X;
                }
                else
                {
                    Utils.QL_FAIL("unknown/illegal solver type");
                }
            }
            bcSet_.applyAfterSolving(a as Vector);
        }