Beispiel #1
0
        public override ISimulation <RocketSimulationMoment> GenerateSimulation(double t1, double t2)
        {
            double burnTime = t1 + _propellantMass / _massLossRate;

            var xa = new IntervalIndexer <Func <double, double> >();

            xa.AddInterval((Endpoints.Closed(t1), Endpoints.Closed(burnTime)),
                           (t) => RocketAEquation(t, t1));
            xa.AddInterval((Endpoints.Open(burnTime), Endpoints.Unbounded),
                           (t) => 0);

            var xv = new IntervalIndexer <Func <double, double> >();

            xv.AddInterval((Endpoints.Closed(t1), Endpoints.Closed(burnTime)),
                           (t) => RocketVEquation(t, t1));
            xv.AddInterval((Endpoints.Open(burnTime), Endpoints.Unbounded),
                           (t) => RocketVEquation(burnTime, t1));

            var x = new IntervalIndexer <Func <double, double> >();

            x.AddInterval((Endpoints.Closed(t1), Endpoints.Closed(burnTime)),
                          (t) => RocketXEquation(t, t1));
            x.AddInterval((Endpoints.Open(burnTime), Endpoints.Unbounded),
                          (t) => RocketXEquation(burnTime, t1) + RocketVEquation(burnTime, t1) * (t - burnTime));

            return(new RocketSimulation(_baseMass, _propellantMass, _massLossRate, burnTime, xa, xv, x));
        }
        public override ISimulation <AngularMomentumSimulationMoment> GenerateSimulation(double t1, double t2)
        {
            var(massByR, radius) = (_disc.SpecificMassByR, _disc.Radius);

            var momentOfInertiaByR = massByR * new Polynomial(0, 0, 1);
            var momentOfInertia    = momentOfInertiaByR.DefiniteIntegral(radius);

            var angularAcceleration = (_force * radius) / momentOfInertia;

            var angleOverTime = (new Polynomial(angularAcceleration)).AntiDerivative(_angularVel0).AntiDerivative();
            var anglet        = new IntervalIndexer <Polynomial>();

            anglet.AddInterval((Endpoints.Closed(t1), Endpoints.Closed(t2)), angleOverTime);

            var defaultIndexer = new IntervalIndexer <Polynomial>(new Polynomial());

            return(new AngularMomentumSimulation(_disc, defaultIndexer, anglet, defaultIndexer, defaultIndexer));
        }
        public override ISimulation <AngularMomentumSimulationMoment> GenerateSimulation(double t1, double t2)
        {
            var vt     = new IntervalIndexer <Polynomial>();
            var xt     = new IntervalIndexer <Polynomial>();
            var omegat = new IntervalIndexer <Polynomial>();
            var anglet = new IntervalIndexer <Polynomial>();

            var v     = new Polynomial(_v0);
            var omega = new Polynomial(_omega0);

            var vOnSurface = v + omega * _disk.Radius;

            var t = t1;

            var vOnSurface0 = vOnSurface.Evaluate(t);

            // There's friction that acts on the disk
            if (vOnSurface0.CompareTo(0, 6e-5) != 0)
            {
                var circumferenceByR = new Polynomial(0, 2 * System.Math.PI);
                var tMass            = (circumferenceByR * _disk.SpecificMassByR).DefiniteIntegral(_disk.Radius);
                var rSquared         = new Polynomial(0, 0, 1);
                var iZ       = ((circumferenceByR * _disk.SpecificMassByR) * rSquared).DefiniteIntegral(_disk.Radius);
                var friction = (-System.Math.Sign(vOnSurface0)) * (_coOfKineticFriction * tMass * g0);

                var torque = _disk.Radius * friction;
                var angularAcceleration = torque / iZ;
                omega = (new Polynomial(angularAcceleration)).AntiDerivative(_omega0);

                var a = friction / tMass;
                v = (new Polynomial(a)).AntiDerivative(_v0);

                vOnSurface = v + omega * _disk.Radius;

                var tf = t2;
                try
                {
                    tf = vOnSurface.Roots(0, t1, t2).First();
                }
                catch (InvalidOperationException)
                {
                }

                var slipInterval = (Endpoints.Closed(t), Endpoints.Open(tf));

                vt.AddInterval(slipInterval, v);
                xt.AddInterval(slipInterval, v.AntiDerivative());
                omegat.AddInterval(slipInterval, omega);
                anglet.AddInterval(slipInterval, omega.AntiDerivative());

                t = tf;
            }

            if (t < t2)
            {
                var noSlipInterval = (Endpoints.Closed(t), Endpoints.Unbounded);

                vt.AddInterval(
                    noSlipInterval,
                    new Polynomial(v.Evaluate(t))
                    );
                xt.AddInterval(
                    noSlipInterval,
                    new Polynomial(v.AntiDerivative().Evaluate(t), v.Evaluate(t))
                    .Offset(-t)
                    );

                omegat.AddInterval(
                    noSlipInterval,
                    new Polynomial(omega.Evaluate(t))
                    );
                anglet.AddInterval(
                    noSlipInterval,
                    new Polynomial(omega.AntiDerivative().Evaluate(t), omega.Evaluate(t))
                    .Offset(-t)
                    );
            }

            return(new AngularMomentumSimulation(_disk, omegat, anglet, vt, xt));
        }