/// <summary> /// Returns a Backward-Differentiation-Formula of order <paramref name="i"/>. /// </summary> static public BDFSchemeCoeffs BDF(int i) { BDFSchemeCoeffs R = new BDFSchemeCoeffs(); switch (i) { case 1: R.theta1 = 1.0; R.theta0 = 0.0; R.beta = new[] { 1.0 }; break; case 2: R.theta1 = 2.0 / 3.0; R.theta0 = 0.0; R.beta = new[] { 4.0 / 3.0, -1.0 / 3.0 }; break; case 3: R.theta1 = 6.0 / 11.0; R.theta0 = 0.0; R.beta = new[] { 18.0 / 11.0, -9.0 / 11.0, 2.0 / 11.0 }; break; case 4: R.theta1 = 12.0 / 25.0; R.theta0 = 0.0; R.beta = new[] { 48.0 / 25.0, -36.0 / 25.0, 16.0 / 25, -3.0 / 25.0 }; break; case 5: R.theta1 = 60.0 / 137.0; R.theta0 = 0.0; R.beta = new[] { 300.0 / 137.0, -300.0 / 137.0, 200.0 / 137.0, -75.0 / 137.0, 12.0 / 137.0 }; break; case 6: R.theta1 = 60.0 / 147.0; R.theta0 = 0.0; R.beta = new[] { 360.0 / 147.0, -450.0 / 147.0, 400.0 / 147.0, -225.0 / 147.0, 72.0 / 147.0, -10.0 / 147.0 }; break; default: throw new NotImplementedException("BDF scheme of order " + i + " is not supported."); } if (Math.Abs(R.beta.Sum() - 1.0) > 1.0e-10) { throw new ApplicationException(); } return(R); }
/// <summary> /// Returns an Explicit-Euler formula. /// </summary> static public BDFSchemeCoeffs ExplicitEuler() { BDFSchemeCoeffs R = new BDFSchemeCoeffs(); R.theta1 = 0.0; R.theta0 = 1.0; R.beta = new[] { 1.0 }; if (Math.Abs(R.beta.Sum() - 1.0) > 1.0e-10) { throw new ApplicationException(); } return(R); }
/// <summary> /// Returns a Crank-Nicolson formula. /// </summary> static public BDFSchemeCoeffs CrankNicolson() { BDFSchemeCoeffs R = new BDFSchemeCoeffs(); R.theta1 = 0.5; R.theta0 = 0.5; R.beta = new[] { 1.0 }; if (Math.Abs(R.beta.Sum() - 1.0) > 1.0e-10) { throw new ApplicationException(); } return(R); }
/// <summary> /// Initilizes a Chain of BDF-Schemes starting from ImplicitEuler up to the desired order, /// this is required e.g. when starting a simulation. /// Then the first step is done by implicit Euler, the second step by BDF2 and so forth /// </summary> /// <param name="BDForder"></param> /// <returns>An Array of BDSchemes from implicit euler, entry[i] up to the desired order, entry[0] /// Hack: /// 0 = Explicit Euler /// -1 = Crank-Nicholson /// </returns> public static BDFSchemeCoeffs[] GetChain(int BDForder) { BDFSchemeCoeffs[] SchemeChain; switch (BDForder) { case -1: SchemeChain = new BDFSchemeCoeffs[] { BDFSchemeCoeffs.CrankNicolson() }; break; case 0: SchemeChain = new BDFSchemeCoeffs[] { BDFSchemeCoeffs.ExplicitEuler() }; break; default: SchemeChain = new BDFSchemeCoeffs[BDForder]; for (int i = BDForder; i >= 1; i--) { SchemeChain[BDForder - i] = BDFSchemeCoeffs.BDF(i); } break; } return(SchemeChain); }