示例#1
0
        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);
        }
示例#2
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
                }));
            }
        }