public void OdeSine2() { Func <double, IList <double>, IList <double> > f2 = (double x, IList <double> y) => new double[] { -y[0] }; double[] y0 = new double[] { 0.0 }; double[] yp0 = new double[] { 1.0 }; ColumnVector z = MultiFunctionMath.SolveConservativeOde(f2, 0.0, y0, yp0, 5.0); }
public void OdeOrbit() { // This is a simple Keplerian orbit. // Hull (1972) constructed initial conditions that guarantee a given orbital eccentricity // and a period of 2 \pi with unit masses and unit gravitational constant. Func <double, IList <double>, IList <double> > rhs = (double t, IList <double> r) => { double d = MoreMath.Hypot(r[0], r[1]); double d3 = MoreMath.Pow(d, 3); return(new double[] { -r[0] / d3, -r[1] / d3 }); }; EvaluationSettings settings = new EvaluationSettings() { RelativePrecision = 1.0E-12, AbsolutePrecision = 1.0E-24, EvaluationBudget = 10000 }; settings.UpdateHandler = (EvaluationResult a) => { OdeResult <IList <double> > b = (OdeResult <IList <double> >)a; Console.WriteLine("{0} {1}", b.EvaluationCount, b.X); }; //double e = 0.5; foreach (double e in TestUtilities.GenerateUniformRealValues(0.0, 1.0, 8)) { Console.WriteLine("e = {0}", e); ColumnVector r0 = new ColumnVector(1.0 - e, 0.0); ColumnVector rp0 = new ColumnVector(0.0, Math.Sqrt((1.0 + e) / (1.0 - e))); settings.UpdateHandler = (EvaluationResult a) => { OdeResult <IList <double> > b = (OdeResult <IList <double> >)a; Console.WriteLine(" {0} {1}", b.EvaluationCount, b.X); Console.WriteLine(" {0} ?= {1}", OrbitEnergy(b.Y, b.YPrime), OrbitEnergy(r0, rp0)); Assert.IsTrue(TestUtilities.IsNearlyEqual(OrbitAngularMomentum(b.Y, b.YPrime), OrbitAngularMomentum(r0, rp0), settings)); Assert.IsTrue(TestUtilities.IsNearlyEqual(OrbitEnergy(b.Y, b.YPrime), OrbitEnergy(r0, rp0), new EvaluationSettings() { RelativePrecision = 2.0E-12 })); }; ColumnVector r1 = MultiFunctionMath.SolveConservativeOde(rhs, 0.0, r0, rp0, 2.0 * Math.PI, settings); // The Assert.IsTrue(TestUtilities.IsNearlyEqual(r0, r1, new EvaluationSettings() { RelativePrecision = 1.0E-9 })); } }