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()); }
protected void CalculateMainCombustionChamberParameters() { //Calc geometry throatArea = throatDiameter * throatDiameter * 0.25 * Math.PI; nozzleArea = throatArea * areaRatio; nozzleDiameter = Math.Sqrt(nozzleArea / (0.25 * Math.PI)); //Generate engine prefab for this OF ratio and cham pres enginePrefab = biPropConfig.CalcPrefabData(chamberOFRatio, chamberPresMPa); //Calc mass flow for a choked nozzle massFlowChamber = (enginePrefab.nozzleGamma + 1.0) / (enginePrefab.nozzleGamma - 1.0); massFlowChamber = Math.Pow(2.0 / (enginePrefab.nozzleGamma + 1.0), massFlowChamber); massFlowChamber *= enginePrefab.nozzleGamma * enginePrefab.nozzleMWgMol; massFlowChamber /= (GAS_CONSTANT * enginePrefab.chamberTempK); massFlowChamber = Math.Sqrt(massFlowChamber); massFlowChamber *= enginePrefab.chamberPresMPa * throatArea; massFlowChamber *= 1000.0; //convert from 1000 t/s (due to MPa) to t/s reactionEfficiency = CalculateChamberReactionEfficiency(); //reaction efficiency acts to increase mass flow massFlowChamber /= reactionEfficiency; massFlowChamberFuel = massFlowChamber / (chamberOFRatio + 1.0); massFlowChamberOx = massFlowChamberFuel * chamberOFRatio; massFlowTotal = massFlowChamber; overallOFRatio = chamberOFRatio; thrustVacAux = thrustSLAux = 0; }
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; prefab.chamberCp = 0; prefab.nozzleCp = 0; prefab.frozenAreaRatio = frozenAreaRatio; 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]; prefab.chamberCp = (chamberCpData[i] - chamberCpData[i - 1]) * indexFactor + chamberCpData[i - 1]; prefab.nozzleCp = (nozzleCpData[i] - nozzleCpData[i - 1]) * indexFactor + nozzleCpData[i - 1]; break; } if (prefab.chamberTempK <= 0) { Debug.LogError("[ProcEngines] Error in data tables, could not solve"); } return(prefab); }
public EngineDataPrefab CalcDataAtPresAndTemp(double combustorPressure, double turbineInletTemp, bool oxRich) { if (oxRich) //start at the higher OF ratios and count down { EngineDataPrefab prefab1 = mixtureData[mixtureData.Length - 1].CalcData(combustorPressure); for (int i = mixtureData.Length - 2; i >= 0; --i) { EngineDataPrefab prefab2 = mixtureData[i].CalcData(combustorPressure); if (prefab2.chamberTempK < turbineInletTemp) //if prefab2 (closer to stoich) is too low, then we're not hot enough yet. { //switch prefab1 to be prefab2 and calc a new prefab2 that is hopefully hotter than the temp we want prefab1 = prefab2; continue; } double indexFactor = turbineInletTemp - prefab2.chamberTempK; indexFactor /= (prefab1.chamberTempK - prefab2.chamberTempK); //this gives us a pseudo-index factor that can be used to calculate properties between the input data double desiredOF = (prefab1.OFRatio - prefab2.OFRatio) * indexFactor + prefab2.OFRatio; EngineDataPrefab results = (prefab1 - prefab2) * indexFactor + prefab2; return(results); } } else { EngineDataPrefab prefab1 = mixtureData[0].CalcData(combustorPressure); for (int i = 1; i < mixtureData.Length; ++i) { EngineDataPrefab prefab2 = mixtureData[i].CalcData(combustorPressure); if (prefab2.chamberTempK < turbineInletTemp) { prefab1 = prefab2; 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; EngineDataPrefab results = (prefab2 - prefab1) * indexFactor + prefab1; return(results); } } Debug.LogError("[ProcEngines] Error in data tables, could not solve"); return(new EngineDataPrefab()); }
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); }
void SolveGasGenTurbine(bool oxRich) { double gasGenInjectorPresDrop = injectorPressureRatioDrop * 3.0 / 2.0; if (gasGenInjectorPresDrop < 0.2) { gasGenInjectorPresDrop = 0.2; } double gasGenPresMPa = chamberPresMPa * (1.0 + injectorPressureRatioDrop) / (1.0 + gasGenInjectorPresDrop); gasGenPrefab = biPropConfig.CalcDataAtPresAndTemp(gasGenPresMPa, turbineInletTempK, oxRich); //assume that gas gen runs at same pressure as chamber CalcTurbineExhaustBackPressure(); turbinePresRatio = gasGenPresMPa / turbineBackPresMPa; double gammaPower = -(gasGenPrefab.nozzleGamma - 1.0) / gasGenPrefab.nozzleGamma; double[] gasGenOFRatio = new double[] { gasGenPrefab.OFRatio }; turbopump.UpdateMixture(biPropConfig); turbopump.CalculateTurbineProperties(turbinePresRatio, gasGenPrefab); turbineMassFlow = MathUtils.BrentsMethod(IterateSolveGasGenTurbine, gasGenOFRatio, 0, 1.5 * massFlowChamber, 0.000001, int.MaxValue); massFlowTotal += turbineMassFlow; overallOFRatio = chamberOFRatio; overallOFRatio *= massFlowChamber / massFlowTotal; overallOFRatio += gasGenPrefab.OFRatio * turbineMassFlow / massFlowTotal; massFlowFrac = turbineMassFlow / massFlowTotal; CalcTurbineExhaustThrust(); }
public void CalculateTurbineProperties(double turbinePresRatio, EngineDataPrefab turbineInletConditions) { this.turbineInletConditions = turbineInletConditions; CalculateTurbineProperties(turbinePresRatio); }