Beispiel #1
0
        public override void CalculatePerformance(double airRatio, double commandedThrottle, double flowMult, double ispMult)
        {
            // set base bits
            base.CalculatePerformance(airRatio, commandedThrottle, flowMult, ispMult);

            statusString = "Nominal";
            combusting   = running;
            if (running && ((useOxygen && !oxygen) || eair0 <= 0d))
            {
                combusting   = false;
                statusString = "No oxygen";
            }
            else if (ffFraction <= 0d)
            {
                combusting   = false;
                statusString = "No fuel";
            }
            else if (underwater)
            {
                combusting   = false;
                statusString = "Underwater";
            }

            if (combusting)
            {
                power = power0 * Math.Min(1d, rho / rho0) * SolverMathUtil.Lerp(0.01d, 1d, throttle);

                double x = vz * weight * 9.80665d / power;
                torque = power / omega / Math.Pow((x / buff + 1d), buff);

                double CLift = omega * omega * r * r * r / 3d + vx * vx * r / 4d / Math.PI;

                double CTorq = omega * omega * r * r * r * r / 4d + vx * vx * r * r / 8d / Math.PI;

                //          float CTilt = omega * r * r * r * vx / PI + r * vx * vx * vx / omega;

                thrust  = torque * ldr * CLift / CTorq;
                thrust *= flowMult * ispMult;
                //           tilt = lift / CLift * CTilt;

                fuelFlow = BSFC * power * flowMult;
                Isp      = thrust / (fuelFlow * 9.80665d);
                SFC      = 3600d / Isp;
            }
        }
Beispiel #2
0
        public override void CalculatePerformance(double airRatio, double commandedThrottle, double flowMult, double ispMult)
        {
            // set base bits
            base.CalculatePerformance(airRatio, commandedThrottle, flowMult, ispMult);

            // if we're not combusting, don't combust and start cooling off
            combusting   = running;
            statusString = "Nominal";
            if (running && (!oxygen || eair0 <= 0d))
            {
                combusting   = false;
                statusString = "No oxygen";
            }
            else if (ffFraction <= 0d)
            {
                combusting   = false;
                statusString = "No fuel";
            }
            else if (airRatio < 0.01d)
            {
                combusting   = false;
                statusString = "Insufficient intake area";
            }
            else if (underwater)
            {
                combusting   = false;
                statusString = "Nozzle in water";
            }

            if (combusting)
            {
                if (Tt7 > 0)
                {
                    if (unifiedThrottle)
                    {
                        mainThrottle = commandedThrottle;
                        abThrottle   = commandedThrottle;
                    }
                    else
                    {
                        mainThrottle = Math.Min(commandedThrottle * 1.5d, 1d);
                        abThrottle   = Math.Max(commandedThrottle * 3d - 2d, 0d);
                    }
                }
                else
                {
                    mainThrottle = commandedThrottle;
                    abThrottle   = 0d;
                }

                double coreThrottle = SolverMathUtil.Lerp(minThrottle, 1d, mainThrottle);

                prat3 = CPR;
                double invfac      = eta_c * th1.Gamma / (th1.Gamma - 1.0);
                double turbineWork = 0d;
                for (int i = 0; i < 20; i++)    //use iteration to calculate CPR
                {
                    th3 = th1.AdiabaticProcessWithPressureRatio(prat3, efficiency: eta_c);
                    // FIXME use ffFraction here? Instead of just multiplying thrust by fuel fraction in the module?
                    // is so, set multiplyThrustByFuelFrac = false in the ModuleEnginesAJEJet.
                    th4 = th3.AddFuelToTemperature(Tt4, h_f, throttle: coreThrottle);
                    th5 = th4.AdiabaticProcessWithTempRatio(TTR, out turbineWork, eta_t);

                    th3 = th1.AdiabaticProcessWithWork(turbineWork / (1d + fanWorkConstant), efficiency: eta_c);

                    double x = prat3;

                    prat3 = th3.P / th1.P;

                    if (Math.Abs(x - prat3) < 0.01)
                    {
                        break;
                    }
                }

                if (BPR > 0d)
                {
                    th2           = th1.AdiabaticProcessWithWork(turbineWork * fanWorkConstant / (1d + fanWorkConstant) / BPR, efficiency: eta_c);
                    th2.MassRatio = BPR;
                    prat2         = th2.P / th1.P;
                }

                if (exhaustMixer && BPR > 0)//exhaust mixer
                {
                    th2.P *= 0.98;
                    th6    = EngineThermodynamics.MixStreams(th5, th2);
                }
                else
                {
                    th6 = th5;
                }

                if (Tt7 > 0)
                {
                    th7 = th6.AddFuelToTemperature(Tt7, h_f, throttle: abThrottle);
                }
                else
                {
                    th7 = th6;
                }

                //Nozzle code is from NASA

                double p8, V8;
                //double A8;
                double epr = th7.P / th1.P;
                double etr = th7.T / th1.T;

                // The factor of 0.75 implies that the mach number of air entering the compressor is about 0.5
                // The factor can be calculated as
                // 1 / (1 - ff_ab) * sqrt(gamma_c/gamma_ab * R_ab / R_c) * M * (1 + (gamma_c + 1)/2 * M^2)^(-(gamma_c + 1)/(2 * (gamma_c - 1)) / ((gamma_ab + 1) / 2)^(-(gamma_ab + 1)/(2 * (gamma_ab - 1))
                //
                //A8 = .75 * Aref * th7.MassRatio * Math.Sqrt(th1.Gamma / th7.Gamma * th7.R / th1.R) * Math.Sqrt(etr) / epr;//ratio of nozzle area to ref area
                //double area8max = .75 * Math.Sqrt(etr) / epr;//ratio of nozzle area to ref area
                //A8 = area8max * Aref;
                //if (exhaustMixer && BPR > 0)
                //    A8 *= (1 + BPR);
                //double eair = th7.P * Math.Sqrt(th7.Gamma / th7.R / th7.T) *
                //    Math.Pow((0.5d + 0.5d * th7.Gamma), 0.5d * (1d + th7.Gamma) / (1d - th7.Gamma));//corrected mass flow per area
                //mdot = eair * A8;

                // Assume turbine is choked all the time
                coreAirflow = th4.CalculateMassFlow(Aref * turbineAreaRatio, 1d) / th4.MassRatio;
                mdot        = th7.MassRatio * coreAirflow;

                if (!adjustableNozzle)
                {
                    p8 = th7.ChokedPressure();
                    if (p8 < th0.P)
                    {
                        p8 = th0.P;
                    }
                }
                else
                {
                    p8 = th0.P;
                }
                double exitEnergy = th7.Cp * th7.T * eta_n * (1.0 - Math.Pow(p8 / th7.P, th7.R / th7.Cp));
                V8  = Math.Sqrt(Math.Abs(2d * exitEnergy));    //exit velocity - may be negative under certain conditions
                V8 *= Math.Sign(exitEnergy);
                double exitMach = th7.CalculateMach(Math.Abs(V8));
                Anozzle = th7.CalculateFlowArea(mdot, exitMach);
                thrust  = V8 * mdot + (p8 - th0.P) * Anozzle;
                thrust -= mdot * (1d - th7.FF) * (vel);//ram drag

                if (BPR > 0d && FPR > 1d && exhaustMixer == false)
                {
                    //fan thrust from NASA
                    double pfexit = th2.ChokedPressure();
                    if (pfexit < th0.P)
                    {
                        pfexit = th0.P;
                    }
                    double fExitEnergy = th2.Cp * th2.T * eta_n * (1d - Math.Pow(pfexit / th2.P, th2.R / th2.Cp));
                    double ues         = Math.Sqrt(Math.Abs(2d * fExitEnergy));
                    ues *= Math.Sign(fExitEnergy);
                    double bypassAirFlow = coreAirflow * th2.MassRatio; // th2.MassRatio will be equal to BPR at this point
                    double ANozzleBypass = th2.CalculateFlowArea(bypassAirFlow, th2.CalculateMach(ues));
                    thrust += bypassAirFlow * ues + (pfexit - p0) * ANozzleBypass;
                    thrust -= bypassAirFlow * vel;
                }

                thrust  *= flowMult * ispMult;
                fuelFlow = mdot * th7.FF * flowMult;
                Isp      = thrust / (fuelFlow * 9.80665);
                SFC      = 3600d / Isp;

                /*
                 * debugstring = "";
                 * debugstring += "TTR:\t" + TTR.ToString("F3") + "\r\n";
                 * debugstring += "CPR:\t" + prat3.ToString("F3") + "\r\n"; ;
                 * debugstring += "p0: " + th0.P.ToString("F2") + "\tt0: " + th0.T.ToString("F2") + "\r\n";
                 * debugstring += "P1: " + th1.P.ToString("F2") + "\tT1: " + th1.T.ToString("F2") + "\r\n";
                 * debugstring += "P2: " + th2.P.ToString("F2") + "\tT2: " + th2.T.ToString("F2") + "\r\n";
                 * debugstring += "P3: " + th3.P.ToString("F2") + "\tT3: " + th3.T.ToString("F2") + "\r\n";
                 * debugstring += "P4: " + th4.P.ToString("F2") + "\tT4: " + th4.T.ToString("F2") + "\r\n";
                 * debugstring += "P5: " + th5.P.ToString("F2") + "\tT5: " + th5.T.ToString("F2") + "\r\n";
                 * debugstring += "P6: " + th6.P.ToString("F2") + "\tT6: " + th6.T.ToString("F2") + "\r\n";
                 * debugstring += "P7: " + th7.P.ToString("F2") + "\tT7: " + th7.ToString("F2") + "\r\n";
                 * debugstring += "EPR: " + epr.ToString("F2") + "\tETR: " + etr.ToString("F2") + "\r\n";
                 *
                 * debugstring += "FF: " + th5.FF.ToString("P") + "\t";
                 * debugstring += "FF_AB: " + th7.FF.ToString("P") + "\r\n";
                 * debugstring += "V8: " + V8.ToString("F2") + "\tA8: " + A8.ToString("F2") + "\r\n";
                 * debugstring += "Thrust: " + (thrust / 1000).ToString("F1") + "\tmdot: " + mdot.ToString("F2") + "\r\n";
                 * debugstring += "Isp: " + Isp.ToString("F0") + "\tSFC: " + (3600 / Isp).ToString("F3") + "\r\n";
                 * Debug.Log(debugstring);*/
            }
            else
            {
                double shutdownScalar = Math.Pow(spoolFactor, TimeWarp.fixedDeltaTime);

                th3.T = Math.Max(t0, th3.T * shutdownScalar - 4d);

                mainThrottle = Math.Max(0d, mainThrottle * shutdownScalar - 0.05d);
                if (Tt7 > 0)
                {
                    abThrottle = Math.Max(0d, abThrottle * shutdownScalar - 0.05d);
                }
            }
            // Set FX power
            if (Tt7 == 0)
            {
                fxPower = (float)mainThrottle;
            }
            else
            {
                fxPower = (float)(mainThrottle * 0.25d + abThrottle * 0.75d);
            }
        }