public EngineDataPrefab CalcDataAtPresAndTemp(double combustorPressure, double turbineInletTemp, bool oxRich) { //if(oxRich) //start at the higher OF ratios and count down //{ // //} //else //{ EngineDataPrefab prefab2 = mixtureData[0].CalcData(combustorPressure); for (int i = 1; i < mixtureData.Length; ++i) { EngineDataPrefab prefab1 = mixtureData[i].CalcData(combustorPressure); if (prefab1.chamberTempK < turbineInletTemp) { prefab2 = prefab1; continue; } double indexFactor = turbineInletTemp - prefab1.chamberTempK; indexFactor /= (prefab2.chamberTempK - prefab1.chamberTempK); //this gives us a pseudo-index factor that can be used to calculate properties between the input data double desiredOF = (prefab2.OFRatio - prefab1.OFRatio) * indexFactor + prefab1.OFRatio; return(CalcPrefabData(desiredOF, combustorPressure, i - 1)); } //} Debug.LogError("[ProcEngines] Error in data tables, could not solve"); return(new EngineDataPrefab()); }
public EngineDataPrefab CalcPrefabData(double oFRatio, double chamberPres) { for (int i = 1; i < mixtureOFRatios.Length; ++i) { double oF2 = mixtureOFRatios[i]; if (oF2 < oFRatio) { continue; } double oF1 = mixtureOFRatios[i - 1]; EngineDataPrefab prefab1, prefab2; prefab1 = mixtureData[i - 1].CalcData(chamberPres); prefab2 = mixtureData[i].CalcData(chamberPres); double indexFactor = oFRatio - oF1; indexFactor /= (oF2 - oF1); //this gives us a pseudo-index factor that can be used to calculate properties between the input data EngineDataPrefab results = (prefab2 - prefab1) * indexFactor + prefab1; return(results); } Debug.LogError("[ProcEngines] Error in data tables, could not solve"); return(new EngineDataPrefab()); }
void CalculatePreBurnerParameters(bool runOxRich) { double injectorPressureDrop = 0.3; //TODO: make injector pres drop vary with throttle capability, tech level double regenerativeCoolingPresDrop = 0.15; //TODO: make cooling pres draop vary with cooling needs, tech level double tankPresMPa = 0.2; //TODO: make variable of some kind; double preburnerTurbineOutputPresMPa = chamberPresMPa * (1 + injectorPressureDrop); double preburnerPressureMPa = preburnerTurbineOutputPresMPa * turbinePresRatio; //TODO: allow separate ox, fuel turbines double oxPumpPresRiseMPa = preburnerPressureMPa - tankPresMPa; double fuelPumpPresRiseMPa = preburnerPressureMPa * (1 + regenerativeCoolingPresDrop) - tankPresMPa; //assume that only fuel is used for regen cooling double pumpEfficiency = 0.8; //TODO: make vary with fuel type and with tech level double oxPumpPower = massFlowChamberOx * oxPumpPresRiseMPa * 1000000 / (propConfig.GetOxDensity() * pumpEfficiency); //convert MPa to Pa, but allow tonnes to cancel double fuelPumpPower = massFlowChamberFuel * fuelPumpPresRiseMPa * 1000000 / (propConfig.GetFuelDensity() * pumpEfficiency); //convert MPa to Pa, but allow tonnes to cancel double turbinePowerReq = oxPumpPower + fuelPumpPower; double turbineEfficiency = 0.7; //TODO: make vary with tech level double turbineInletTempK = 1000; //TODO: make variable, add film cooling reqs for temps above 800 EngineDataPrefab combustorPrefab = propConfig.CalcDataAtPresAndTemp(preburnerPressureMPa, turbineInletTempK, false); }
public EngineDataPrefab CalcData(double inputChamberPres) { EngineDataPrefab prefab = new EngineDataPrefab(); prefab.OFRatio = oFRatio; prefab.chamberPresMPa = inputChamberPres; prefab.chamberTempK = 0; prefab.nozzleTempK = 0; prefab.nozzlePresMPa = 0; prefab.nozzleMWgMol = 0; prefab.nozzleGamma = 0; prefab.nozzleMach = 0; if (inputChamberPres < minChamPres) { Debug.LogError("[ProcEngines] Error: chamber pressure of " + inputChamberPres + " is below min pressure of " + minChamPres + " for " + mixtureName + " at O//F " + oFRatio); return(prefab); } if (inputChamberPres > maxChamPres) { Debug.LogError("[ProcEngines] Error: chamber pressure of " + inputChamberPres + " is below min pressure of " + maxChamPres + " for " + mixtureName + " at O//F " + oFRatio); return(prefab); } for (int i = 1; i < chamberPresMPaData.Length; ++i) { double chamPres2 = chamberPresMPaData[i]; if (chamPres2 < inputChamberPres) { continue; } double chamPres1 = chamberPresMPaData[i - 1]; double indexFactor = inputChamberPres - chamPres1; indexFactor /= (chamPres2 - chamPres1); //this gives us a pseudo-index factor that can be used to calculate properties between the input data prefab.chamberTempK = (chamberTempKData[i] - chamberTempKData[i - 1]) * indexFactor + chamberTempKData[i - 1]; prefab.nozzleTempK = (nozzleTempKData[i] - nozzleTempKData[i - 1]) * indexFactor + nozzleTempKData[i - 1]; prefab.nozzlePresMPa = (nozzlePresMPaData[i] - nozzlePresMPaData[i - 1]) * indexFactor + nozzlePresMPaData[i - 1]; prefab.nozzleMWgMol = (nozzleMolWeightgMolData[i] - nozzleMolWeightgMolData[i - 1]) * indexFactor + nozzleMolWeightgMolData[i - 1]; prefab.nozzleGamma = (nozzleGammaData[i] - nozzleGammaData[i - 1]) * indexFactor + nozzleGammaData[i - 1]; prefab.nozzleMach = (nozzleMachData[i] - nozzleMachData[i - 1]) * indexFactor + nozzleMachData[i - 1]; break; } if (prefab.chamberTempK <= 0) { Debug.LogError("[ProcEngines] Error in data tables, could not solve"); } return(prefab); }
public static EngineDataPrefab operator -(EngineDataPrefab a, EngineDataPrefab b) { EngineDataPrefab prefab = new EngineDataPrefab(); prefab.OFRatio = a.OFRatio - b.OFRatio; prefab.chamberPresMPa = a.chamberPresMPa - b.chamberPresMPa; prefab.chamberTempK = a.chamberTempK - b.chamberTempK; prefab.nozzlePresMPa = a.nozzlePresMPa - b.nozzlePresMPa; prefab.nozzleTempK = a.nozzleTempK - b.nozzleTempK; prefab.nozzleMWgMol = a.nozzleMWgMol - b.nozzleMWgMol; prefab.nozzleGamma = a.nozzleGamma - b.nozzleGamma; prefab.nozzleMach = a.nozzleMach - b.nozzleMach; prefab.frozenAreaRatio = a.frozenAreaRatio - b.frozenAreaRatio; return(prefab); }
public static EngineDataPrefab operator *(EngineDataPrefab a, double b) { EngineDataPrefab prefab = new EngineDataPrefab(); prefab.OFRatio = a.OFRatio * b; prefab.chamberPresMPa = a.chamberPresMPa * b; prefab.chamberTempK = a.chamberTempK * b; prefab.nozzlePresMPa = a.nozzlePresMPa * b; prefab.nozzleTempK = a.nozzleTempK * b; prefab.nozzleMWgMol = a.nozzleMWgMol * b; prefab.nozzleGamma = a.nozzleGamma * b; prefab.nozzleMach = a.nozzleMach * b; prefab.frozenAreaRatio = a.frozenAreaRatio * b; return(prefab); }
public EngineDataPrefab CalcPrefabData(double oFRatio, double chamberPres, int indexLow) { double oF2 = mixtureOFRatios[indexLow + 1]; double oF1 = mixtureOFRatios[indexLow]; EngineDataPrefab prefab1, prefab2; prefab1 = mixtureData[indexLow].CalcData(chamberPres); prefab2 = mixtureData[indexLow + 1].CalcData(chamberPres); double indexFactor = oFRatio - oF1; indexFactor /= (oF2 - oF1); //this gives us a pseudo-index factor that can be used to calculate properties between the input data EngineDataPrefab results = (prefab2 - prefab1) * indexFactor + prefab1; return(results); }
public static EngineDataPrefab operator +(EngineDataPrefab a, EngineDataPrefab b) { EngineDataPrefab prefab = new EngineDataPrefab(); prefab.OFRatio = a.OFRatio + b.OFRatio; prefab.chamberPresMPa = a.chamberPresMPa + b.chamberPresMPa; prefab.chamberTempK = a.chamberTempK + b.chamberTempK; prefab.nozzlePresMPa = a.nozzlePresMPa + b.nozzlePresMPa; prefab.nozzleTempK = a.nozzleTempK + b.nozzleTempK; prefab.nozzleMWgMol = a.nozzleMWgMol + b.nozzleMWgMol; prefab.nozzleGamma = a.nozzleGamma + b.nozzleGamma; prefab.nozzleMach = a.nozzleMach + b.nozzleMach; prefab.chamberCp = a.chamberCp + b.chamberCp; prefab.nozzleCp = a.nozzleCp + b.nozzleCp; prefab.frozenAreaRatio = a.frozenAreaRatio + b.frozenAreaRatio; return(prefab); }
double turbinePresRatio = 2; //keep it low for staged combustion void CalculateChamberParameters() { //Calc geometry nozzleArea = nozzleDiameter * nozzleDiameter * 0.25 * Math.PI; throatArea = nozzleArea * areaRatio; //Generate engine prefab for this OF ratio and cham pres enginePrefab = propConfig.CalcPrefabData(chamberOFRatio, chamberPresMPa); //Calc mass flow for a choked nozzle massFlowChamber = (enginePrefab.nozzleGamma + 1) / (enginePrefab.nozzleGamma - 1); massFlowChamber = Math.Pow(2 / (enginePrefab.nozzleGamma + 1), massFlowChamber); massFlowChamber *= enginePrefab.nozzleGamma * enginePrefab.nozzleMWgMol; massFlowChamber /= (GAS_CONSTANT * enginePrefab.chamberTempK); massFlowChamber = Math.Sqrt(massFlowChamber); massFlowChamber *= enginePrefab.chamberPresMPa * throatArea; massFlowChamber *= 1000; //convert from 1000 t/s (due to MPa) to t/s double effectiveFrozenAreaRatio = NozzleAeroUtils.AreaRatioFromMach(enginePrefab.nozzleMach, enginePrefab.nozzleGamma); double effectiveExitAreaRatio = areaRatio * enginePrefab.frozenAreaRatio / effectiveFrozenAreaRatio; double exitMach = NozzleAeroUtils.MachFromAreaRatio(effectiveExitAreaRatio, enginePrefab.nozzleGamma); double isentropicRatio = 0.5 * (enginePrefab.nozzleGamma - 1); isentropicRatio = (1 + isentropicRatio * enginePrefab.nozzleMach * enginePrefab.nozzleMach) / (1 + isentropicRatio * exitMach * exitMach); double exitTemp = isentropicRatio * enginePrefab.nozzleTempK; exitPressureMPa = Math.Pow(isentropicRatio, enginePrefab.nozzleGamma / (enginePrefab.nozzleGamma - 1)) * enginePrefab.nozzlePresMPa; double exitSonicVelocity = Math.Sqrt(enginePrefab.nozzleGamma * GAS_CONSTANT / enginePrefab.nozzleMWgMol * exitTemp); exhaustVelocityOpt = exitSonicVelocity * exitMach; thrustChamberVac = exhaustVelocityOpt * massFlowChamber + exitPressureMPa * nozzleArea * 1000; thrustChamberSL = exhaustVelocityOpt * massFlowChamber + (exitPressureMPa - 0.1013) * nozzleArea * 1000; massFlowChamberFuel = massFlowChamber / (chamberOFRatio + 1); massFlowChamberOx = massFlowChamberFuel * chamberOFRatio; }