//---------------------------------------------------------
        //Initialization Functions

        /// <summary>
        /// Sets the freestream properties
        /// </summary>
        /// <param name="altitude">altitude in m</param>
        /// <param name="pressure">pressure in kPa</param>
        /// <param name="temperature">temperature in K</param>
        /// <param name="velocity">velocity in m/s</param>
        /// <param name="hasOxygen">does the atmosphere contain oxygen</param>
        /// <param name="isUnderwater">Is the engine's thrust transform underwater</param>
        virtual public void SetFreestreamAndInlet(EngineThermodynamics ambientTherm, EngineThermodynamics inletTherm, double altitude, double inMach, Vector3 inVel, bool hasOxygen, bool isUnderwater)
        {
            th0.CopyFrom(ambientTherm);
            th1.CopyFrom(inletTherm);
            alt        = altitude;
            p0         = ambientTherm.P;
            t0         = ambientTherm.T;
            rho        = ambientTherm.Rho;
            oxygen     = hasOxygen;
            underwater = isUnderwater;
            velocity   = inVel;
            vel        = velocity.magnitude;
            mach       = inMach;
            Q          = 0.5d * rho * vel * vel;

            P1   = inletTherm.P;
            T1   = inletTherm.T;
            Rho1 = inletTherm.Rho;

            gamma_c       = inletTherm.Gamma;
            inv_gamma_c   = 1d / gamma_c;
            inv_gamma_cm1 = 1d / (gamma_c - 1d);
            Cp_c          = inletTherm.Cp;
            Cv_c          = inletTherm.Cv;
            R_c           = inletTherm.R;

            eair0 = ambientTherm.SpeedOfSound(0d);
            M0    = vel / eair0;
        }
        /// <summary>
        /// Sets the freestream properties to static conditions : sea level and not moving
        /// </summary>
        /// <param name="usePlanetarium">Whether to use Planetarium.fetch.Home to get static conditions or use standard Earth conditions</param>
        /// <param name="overallTPR">Total pressure recovery of inlet</param>
        protected void SetStaticConditions(bool usePlanetarium = true, double overallTPR = 1d)
        {
            EngineThermodynamics ambientTherm = new EngineThermodynamics();

            ambientTherm.FromStandardConditions(usePlanetarium);

            EngineThermodynamics inletTherm = new EngineThermodynamics();

            inletTherm.CopyFrom(ambientTherm);
            inletTherm.P *= overallTPR;

            SetFreestreamAndInlet(ambientTherm, inletTherm, 0d, 0d, Vector3.zero, true, false);
        }
        protected string GetThrustInfo()
        {
            string output = "";
            if (engineSolver == null || !(engineSolver is SolverRF))
                CreateEngine();
            rfSolver.SetEngineStatus(true, true, true);
            // get stats
            double pressure = 101.325d, temperature = 288.15d, density = 1.225d;
            if (Planetarium.fetch != null)
            {
                CelestialBody home = Planetarium.fetch.Home;
                if (home != null)
                {
                    pressure = home.GetPressure(0d);
                    temperature = home.GetTemperature(0d);
                    density = home.GetDensity(pressure, temperature);
                }
            }
            ambientTherm = new EngineThermodynamics();
            ambientTherm.FromAmbientConditions(pressure, temperature, density);
            inletTherm = new EngineThermodynamics();
            inletTherm.CopyFrom(ambientTherm);

            currentThrottle = 1f;
            lastPropellantFraction = 1d;
            bool oldE = EngineIgnited;
            EngineIgnited = true;
            rfSolver.UpdateThrustRatio(1d);

            UpdateFlightCondition(ambientTherm, 0d, Vector3d.zero, 0d, true);
            double thrustASL = (engineSolver.GetThrust() * 0.001d);

            if (atmChangeFlow) // If it's a jet
            {
                output += "<b>Static Thrust: </b>" + (thrustASL).ToString("0.0##") + " kN" + ThrottleString();
                if (useVelCurve) // if thrust changes with mach
                {
                    float vMin, vMax, tMin, tMax;
                    velCurve.FindMinMaxValue(out vMin, out vMax, out tMin, out tMax); // get the max mult, and thus report maximum thrust possible.
                    output += "\n<b>Max. Thrust: </b>" + (thrustASL* vMax).ToString("0.0##") + " kN Mach " + tMax.ToString("0.#");
                }
            }
            else
            {
                // get stats again
                double spaceHeight = 131000d;
                pressure = 0d;
                density = 0d;
                if (Planetarium.fetch != null)
                {
                    CelestialBody home = Planetarium.fetch.Home;
                    if (home != null)
                    {
                        temperature = home.GetTemperature(home.atmosphereDepth + 1d);
                        spaceHeight = home.atmosphereDepth + 1000d;
                    }
                }
                else
                    temperature = PhysicsGlobals.SpaceTemperature;
                ambientTherm.FromAmbientConditions(pressure, temperature, density);

                UpdateFlightCondition(ambientTherm, spaceHeight, Vector3d.zero, 0d, true);
                double thrustVac = (engineSolver.GetThrust() * 0.001d);

                if (thrustASL != thrustVac)
                {
                    output += (throttleLocked ? "<b>" : "<b>Max. ") + "Thrust (Vac.): </b>" + (thrustVac).ToString("0.0##") + " kN" + ThrottleString()
                        + "\n" + (throttleLocked ? "<b>" : "<b>Max. ") + "Thrust (ASL): </b>" + (thrustASL).ToString("0.0##") + " kN";
                }
                else
                {
                    output += (throttleLocked ? "<b>" : "<b>Max. ") + "Thrust: </b>" + (thrustVac).ToString("0.0##") + " kN" + ThrottleString();
                }
            }
            output += "\n";
            EngineIgnited = oldE;
            return output;
        }
Exemple #4
0
        private void FixedUpdate()
        {
            if (!HighLogic.LoadedSceneIsFlight || !vessel)
            {
                return;
            }
            if (vessel.altitude > vessel.mainBody.atmosphereDepth)
            {
                return;
            }
            int newCount = vessel.Parts.Count;

            if (partsCount != newCount)
            {
                partsCount = newCount;
                updatePartsList();
            }


            InletArea  = 0d;
            EngineArea = 0d;
            OverallTPR = 0d;
            AreaRatio  = 0d;

            for (int j = engineList.Count - 1; j >= 0; --j)
            {
                ModuleEnginesSolver e = engineList[j];
                if ((object)e != null && e.EngineIgnited)
                {
                    EngineArea += e.Need_Area;
                }
            }

            for (int j = inletList.Count - 1; j >= 0; --j)
            {
                AJEInlet i = inletList[j];
                if ((object)i != null)
                {
                    double area = i.UsableArea();
                    InletArea  += area;
                    OverallTPR += area * i.overallTPR;
                }
            }

            if (InletArea > 0d)
            {
                if (EngineArea > 0d)
                {
                    AreaRatio   = Math.Min(1d, InletArea / EngineArea);
                    OverallTPR /= InletArea;
                    OverallTPR *= AreaRatio;
                }
                else
                {
                    AreaRatio = 1d;
                }
            }

            AmbientTherm.FromVesselAmbientConditions(vessel);
            Mach = vessel.mach;

            // Transform from static frame to vessel frame, increasing total pressure and temperature
            if (vessel.srfSpeed < 0.01d)
            {
                InletTherm.CopyFrom(AmbientTherm);
            }
            else
            {
                InletTherm.FromChangeReferenceFrame(AmbientTherm, vessel.srfSpeed);
            }
            InletTherm.P *= OverallTPR; // TPR accounts for loss of total pressure by inlet

            // Push parameters to each engine

            for (int i = engineList.Count - 1; i >= 0; --i)
            {
                engineList[i].UpdateInletEffects(InletTherm, AreaRatio, OverallTPR);
            }
        }
        protected string GetStaticThrustInfo(bool primaryField)//TODO WIP
        {
            string output = "";
            if (engineSolver == null || !(engineSolver is SolverDEV))
                CreateEngine();
            SolverDEV devSolver = (engineSolver as SolverDEV);
            devSolver.SetEngineStatus(true, true, true);
            // get stats
            double pressure = 101.325d, temperature = 288.15d, density = 1.225d;
            if (Planetarium.fetch != null) {
                CelestialBody home = Planetarium.fetch.Home;
                if (home != null) {
                    pressure = home.GetPressure(0d);
                    temperature = home.GetTemperature(0d);
                    density = home.GetDensity(pressure, temperature);
                }
            }


            currentThrottle = 1f;
            lastPropellantFraction = 1d;
            bool oldE = EngineIgnited;
            EngineIgnited = true;
            devSolver.UpdateThrustRatio(1d);

            ambientTherm = new EngineThermodynamics();
            ambientTherm.FromAmbientConditions(pressure, temperature, density);
            inletTherm = new EngineThermodynamics();
            inletTherm.CopyFrom(ambientTherm);
            UpdateFlightCondition(ambientTherm, 0d, Vector3d.zero, 0d, true);
            double thrust_atm = (devSolver.GetThrust() * 0.001d);
            double Isp_atm = devSolver.GetIsp();
            double Cstar_atm = devSolver.Cstar;
            double Ct_atm = devSolver.Ct;

            ambientTherm = new EngineThermodynamics();
            ambientTherm.FromAmbientConditions(0d, 4d, 0d);
            inletTherm = new EngineThermodynamics();
            inletTherm.CopyFrom(ambientTherm);
            UpdateFlightCondition(ambientTherm, 0d, Vector3d.zero, 0d, true);
            double thrust_vac = (devSolver.GetThrust() * 0.001d);
            double Isp_vac = devSolver.GetIsp();
            double Cstar_vac = devSolver.Cstar;
            double Ct_vac = devSolver.Ct;
            double P_vac = devSolver.GetEnginePressure();
            double T_vac = devSolver.GetEngineTemp();

            ambientTherm = new EngineThermodynamics();
            ambientTherm.FromAmbientConditions(pressure * 2, temperature, density * 2);
            inletTherm = new EngineThermodynamics();
            inletTherm.CopyFrom(ambientTherm);
            UpdateFlightCondition(ambientTherm, 0d, Vector3d.zero, 0d, true);
            double thrust_2atm = (devSolver.GetThrust() * 0.001d);
            double Isp_2atm = devSolver.GetIsp();
            double Cstar_2atm = devSolver.Cstar;
            double Ct_2atm = devSolver.Ct;


            FloatCurve tC = new FloatCurve();
            tC.Add(0, (float)Isp_vac);
            tC.Add(1, (float)Isp_atm);
            tC.Add(2, (float)Isp_2atm);
            atmosphereCurve = tC;
            maxThrust = (float)Math.Max(thrust_vac, thrust_atm);

            output += "<b>Max. Thrust(<color=#00FF99>ASL</color>/<color=#99CCFF>Vac.</color>):</b> <color=#00FF99>" + thrust_atm.ToString("N2") + "</color><b>/</b><color=#99CCFF>" + thrust_vac.ToString("N1") + "</color>kN ";
            output += ThrottleString()+"\n";
            output += "<b>Isp(<color=#00FF99>ASL</color>/<color=#99CCFF>Vac.</color>):</b> <color=#00FF99>" + Isp_atm.ToString("N2") + "</color><b>/</b><color=#99CCFF>" + Isp_vac.ToString("N2") + "</color>s\n";
            output += "<b><color=#0099ff>Ignitions Available: </color></b>" + ignitions + "\n";
            output += "<b><color=#0099ff>Max. Burn time: </color></b>" + maxBurnTime + " Sec.\n";
            if (!primaryField) {
                output += "<b>C*(<color=#00FF99>ASL</color>/<color=#99CCFF>Vac.</color>):</b> <color=#00FF99>" + Cstar_atm.ToString("N2") + "</color><b>/</b><color=#99CCFF>" + Cstar_vac.ToString("N2") + "</color>m/s\n";
                output += "<b>Ct(<color=#00FF99>ASL</color>/<color=#99CCFF>Vac.</color>):</b> <color=#00FF99>" + Ct_atm.ToString("N2") + "</color><b>/</b><color=#99CCFF>" + Ct_vac.ToString("N2") + "</color>\n";
                output += $"<b>Chamber Pressure:\n</b>{P_vac.ToString("N1")}<b>/</b>{nominalPcns.ToString("N1")}kPa\n<b>Chamber Temperature:\n</b>{T_vac.ToString("N1")}<b>/</b>{nominalTcns.ToString("N1")}K\n";
                output += $"<b>Nozzle Exit Pressure: </b>{nominalPe} kPa\n<b>Nozzle Throat Area:</b>{At} m^2\n";
            }

            output += "\n";
            EngineIgnited = oldE;
            return output;
        }
        /// <summary>
        /// Sets the freestream properties to static conditions : sea level and not moving
        /// </summary>
        /// <param name="usePlanetarium">Whether to use Planetarium.fetch.Home to get static conditions or use standard Earth conditions</param>
        /// <param name="overallTPR">Total pressure recovery of inlet</param>
        protected void SetStaticConditions(bool usePlanetarium = true, double overallTPR = 1d)
        {
            EngineThermodynamics ambientTherm = new EngineThermodynamics();
            ambientTherm.FromStandardConditions(usePlanetarium);

            EngineThermodynamics inletTherm = new EngineThermodynamics();
            inletTherm.CopyFrom(ambientTherm);
            inletTherm.P *= overallTPR;

            SetFreestreamAndInlet(ambientTherm, inletTherm, 0d, 0d, Vector3.zero, true);
        }