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); }
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); }