public FlowSoundParameters GetFlowSoundParameters(double Thrust, FlowParameters flowParameters) // см. метод с аналогичной сигнатурой в IModel { double OverExpandedDiameter = 2 * 1 / flowParameters.NozzleMachNumber * Math.Sqrt( flowParameters.MassFlow * flowParameters.NozzleFlowVelocity / (Math.PI * 1.0125E5 * flowParameters.NozzleAdiabaticIndex)); double UndisturbedSupersonicFlowLength = 1.75 * OverExpandedDiameter * Math.Pow(1 + 0.38 * flowParameters.NozzleMachNumber, 2); double SupersonicFlowLength = OverExpandedDiameter * (5 * Math.Pow(flowParameters.NozzleMachNumber, 1.8) + 0.8); double DistanceToPointdOfMaximalSoundLevel = 1.5 * UndisturbedSupersonicFlowLength; double _98ProzentSoundPowerRadiatingFlowLength = 5 * UndisturbedSupersonicFlowLength; double DistanceToPointOfFlowDestruction = 8.38 * UndisturbedSupersonicFlowLength; double MechanicalPower = 0.5 * Thrust * flowParameters.NozzleFlowVelocity; double SoundPowerRatio = 0.22; double SoundPower = MechanicalPower * SoundPowerRatio / 100; double SoundMaximalPowerConeHalfAngle = 30; return(new FlowSoundParameters( MechanicalPower, SoundPower, SoundPowerRatio, SoundMaximalPowerConeHalfAngle, UndisturbedSupersonicFlowLength, DistanceToPointdOfMaximalSoundLevel, SupersonicFlowLength, _98ProzentSoundPowerRadiatingFlowLength, DistanceToPointOfFlowDestruction)); }
public ApplyEngineParametersEventArgs( double Thrust, FlowParameters FlowParameters) { this.Thrust = Thrust; this.FlowParameters = FlowParameters; }
public void OpenEngineNoiseInputData( string FileName, out double Thrust, out FlowParameters FlowParameters, out EngineSoundContourParameters ContourParameters) { engineNoiseModel.Open(FileName, out Thrust, out FlowParameters, out ContourParameters); }
public EngineSoundLevel GetEngineSoundLevel(double Thrust, FlowParameters FlowParameters) // см. метод с аналогичной сигнатурой в IModel { var EngineSoundLevelAtFrequency = GetEngineSoundLevelAtFrequency(Thrust, FlowParameters); return((Radius, Angle) => 10 * Math.Log10(EngineSoundLevelAtFrequency(Radius, Angle) .Select(x => Math.Pow(10, 0.1 * x.Value)) .Sum())); }
private void AddFlowParameters(Dictionary <string, string> flowParameters) { foreach (var parameter in flowParameters) { var flowParameter = new FlowParameter(Id, parameter.Key, parameter.Value); FlowParameters.Add(flowParameter); } }
public void OpenEngineNoiseInputData( XmlDocument xmlDoc, out double Thrust, out FlowParameters FlowParameters, out EngineSoundContourParameters ContourParameters) { engineNoiseModel.Open(xmlDoc, out Thrust, out FlowParameters, out ContourParameters); }
public void SaveEngineNoiseInputData( string FileName, double Thrust, FlowParameters FlowParameters, EngineSoundContourParameters ContourParameters) { engineNoiseModel.Save(FileName, Thrust, FlowParameters, ContourParameters); }
public ApplyFlightNoisePartialInputDataEventArgs( Part Part, Ballistics Ballistics, FlowParameters FlowParameters) { this.Part = Part; this.Ballistics = Ballistics; this.FlowParameters = FlowParameters; }
public void Open( string FileName, out double Thrust, out FlowParameters FlowParameters, out EngineSoundContourParameters ContourParameters) // см. метод с аналогичной сигнатурой в IModel { var xmlDoc = new XmlDocument(); xmlDoc.Load(FileName); Open(FileName, out Thrust, out FlowParameters, out ContourParameters); }
} // Спектр частот public FireTestNoiseCalculationInputData( double Thrust, FlowParameters FlowParameters, List <WeatherParameters> WeatherParameters, RadiusInterval RadiusInterval, FrequencyBand FrequencyBand) : this() { this.Thrust = Thrust; this.FlowParameters = FlowParameters; this.WeatherParameters = WeatherParameters; this.RadiusInterval = RadiusInterval; this.FrequencyBand = FrequencyBand; }
} // Погодные условия public FlightSoundCalculationInputData( RocketBallistics RocketBallistics, VehicleBallistics VehicleBallistics, FlowParameters RocketFlowParameters, FlowParameters VehicleFlowParameters, List <WeatherParameters> WeatherParameters) : this() { this.RocketBallistics = RocketBallistics; this.VehicleBallistics = VehicleBallistics; this.RocketFlowParameters = RocketFlowParameters; this.VehicleFlowParameters = VehicleFlowParameters; this.WeatherParameters = WeatherParameters; }
public void Open( XmlDocument xmlDoc, out double Thrust, out FlowParameters FlowParameters, out EngineSoundContourParameters ContourParameters) // см. метод с аналогичной сигнатурой в IModel { Func <XmlNode, double> GetThrust = Node => Convert.ToDouble(Node.InnerText); Func <XmlNode, FlowParameters> GetFlowParameters = Node => new FlowParameters( Convert.ToDouble(Node.Attributes["MassFlow"].Value), Convert.ToDouble(Node.Attributes["NozzleDiameter"].Value), Convert.ToDouble(Node.Attributes["NozzleMachNumber"].Value), Convert.ToDouble(Node.Attributes["NozzleFlowVelocity"].Value), Convert.ToDouble(Node.Attributes["ChamberSoundVelocity"].Value), Convert.ToDouble(Node.Attributes["NozzleAdiabaticIndex"].Value)); Func <XmlNode, List <WeatherParameters> > GetWeatherParameters = Node => Node.ChildNodes.Cast <XmlNode>().Select(x => new WeatherParameters( x.Name, Convert.ToDouble(x.Attributes["Humidity"].Value), Convert.ToDouble(x.Attributes["Temperature"].Value))).ToList(); Func <XmlNode, Dictionary <double, Color> > GetSoundLevels = Node => { if (Node == null) { return(null); } return(Node.ChildNodes.Cast <XmlNode>() .Select(x => new { SoundLevel = Convert.ToDouble(x.InnerText), Color = Color.FromArgb( Convert.ToInt32(x.Attributes["A"].Value), Convert.ToInt32(x.Attributes["R"].Value), Convert.ToInt32(x.Attributes["G"].Value), Convert.ToInt32(x.Attributes["B"].Value)) }) .ToDictionary(x => x.SoundLevel, x => x.Color)); }; var Root = xmlDoc.ChildNodes[0]; Func <XmlNode, string, XmlNode> FindNode = (Node, ChildNodeName) => Node.ChildNodes.Cast <XmlNode>().FirstOrDefault(x => x.Name == ChildNodeName); Thrust = GetThrust(FindNode(Root, "Thrust")); FlowParameters = GetFlowParameters(FindNode(Root, "FlowParameters")); var contourParanetersNode = FindNode(Root, "ContourParaneters"); ContourParameters = new EngineSoundContourParameters( Convert.ToInt32(contourParanetersNode.Attributes["Width"].Value), Convert.ToInt32(contourParanetersNode.Attributes["Height"].Value), Convert.ToInt32(contourParanetersNode.Attributes["NozzleCoordinate"].Value), Convert.ToInt32(contourParanetersNode.Attributes["MinSoundLevel"].Value), Convert.ToInt32(contourParanetersNode.Attributes["MaxSoundLevel"].Value)); }
public StaticSoundLevel GetStaticSoundLevel(double Thrust, FlowParameters flowParameters, FrequencyBand frequencyBand) // см. метод с аналогичной сигнатурой в IModel { double[] Frequencies, FrequencyBands; // массив среднегеометрических частот и ширин частотных полос // определение массивов Frequencies, FrequencyBands по исходному спектру частот frequencyBand if (frequencyBand == FrequencyBand.Infra) { FrequenciesAggregator.Infra(out Frequencies, out FrequencyBands); } else if (frequencyBand == FrequencyBand.Ultra) { FrequenciesAggregator.Ultra(out Frequencies, out FrequencyBands); } else { FrequenciesAggregator.Normal(out Frequencies, out FrequencyBands); } double[] spectralDecomposition = SpectralDecomposition.Get(1.01325E5, flowParameters, Frequencies, FrequencyBands); // Разложение шума на спектр по частотам // Определение функции, возвращающей уровень шума от двиагтеля на расстоянии Radius от сопла под углом Angle к напрвлению оси газовой струи при погодных условиях weatherParameters return((Radius, Angle, weatherParameters) => { double[] atmospherePropagation = new double[Frequencies.Length]; // массив затуханий звука на частотах Frequencies на расстоянии Radius при погодных условиях weatherParameters var atmosphereParameters = new AtmosphereParameters(weatherParameters.Temperature, 1.01325E5); // создание объекта, хранящего атмосферные параметры for (int j = 0; j < Frequencies.Length; j++) { atmospherePropagation[j] = Atmosphere.AbsorptionRatio(weatherParameters.Humidity, atmosphereParameters, Frequencies[j]) * Radius; // заполнение массива atmospherePropagation } double L0 = 10 * Math.Log10(0.5 * 0.0022 * Thrust * flowParameters.NozzleFlowVelocity) + 120 - 11 - 20 * Math.Log10(Radius) + DI.Interpolate(Angle * 180 / Math.PI); // Уровень шума в искомой точке без учёта корреляции по шкале A и затухания звука double L = 0; // Уровень шума в искомой точке с учётом корреляции по шкале A и затухания звука for (int i = 0; i < Frequencies.Length; i++) { double correction = frequencyBand == FrequencyBand.Normal ? Correction.Get(i) : 0; // корреляции по шкале Aв случае расчёта в слышимом диапазоне частот double CurrentL = L0 + spectralDecomposition[i] - atmospherePropagation[i] + correction; // Уровень шума в искомой точке на частоте Frequencies[i] с учётом корреляции по шкале A и затуханием звука if (CurrentL > 0) { L += Math.Pow(10, 0.1 * CurrentL); // логарифмическое суммиррование уровней шума на частотах Frequencies[i] } } if (L > 0) { return 10 * Math.Log10(L); } else { return 0; } }); }
public SaveFireTestNoiseInputDataEventArgs( string FileName, double Thrust, FlowParameters FlowParameters, List <WeatherParameters> WeatherParameters, Dictionary <double, Color> SoundLevels, RadiusInterval RadiusInterval, FrequencyBand FrequencyBand) { this.FileName = FileName; this.Thrust = Thrust; this.FlowParameters = FlowParameters; this.WeatherParameters = WeatherParameters; this.SoundLevels = SoundLevels; this.RadiusInterval = RadiusInterval; this.FrequencyBand = FrequencyBand; }
public SaveEngineNoiseInputDataEventArgs( string FileName, double Thrust, FlowParameters FlowParameters, double ContourAreaWidth, double ContourAreaHeight, double NozzleCoordinate, double MinSoundLevel, double MaxSoundLevel) { this.FileName = FileName; this.Thrust = Thrust; this.FlowParameters = FlowParameters; this.ContourAreaWidth = ContourAreaWidth; this.ContourAreaHeight = ContourAreaHeight; this.NozzleCoordinate = NozzleCoordinate; this.MinSoundLevel = MinSoundLevel; this.MaxSoundLevel = MaxSoundLevel; }
public SaveFlightNoiseInputDataEventArgs( string FileName, RocketBallistics RocketBallistics, VehicleBallistics VehicleBallistics, FlowParameters RocketFlowParameters, FlowParameters VehicleFlowParameters, List <WeatherParameters> WeatherParameters, Dictionary <double, Color> SoundLevels, RadiusInterval RadiusInterval, FrequencyBand FrequencyBand) { this.FileName = FileName; this.RocketBallistics = RocketBallistics; this.VehicleBallistics = VehicleBallistics; this.RocketFlowParameters = RocketFlowParameters; this.VehicleFlowParameters = VehicleFlowParameters; this.WeatherParameters = WeatherParameters; this.SoundLevels = SoundLevels; this.RadiusInterval = RadiusInterval; this.FrequencyBand = FrequencyBand; }
public void Save( string FileName, double Thrust, FlowParameters FlowParameters, EngineSoundContourParameters ContourParameters) // см. метод с аналогичной сигнатурой в IModel { var xmlDoc = new XmlDocument(); var Root = xmlDoc.CreateElement("EngineNoiseInputData"); Action <XmlNode, string, double> AddAttribute = (node, name, value) => { var attribute = xmlDoc.CreateAttribute(name); attribute.Value = value.ToString(); node.Attributes.Append(attribute); }; var thrustNode = xmlDoc.CreateElement("Thrust"); thrustNode.InnerText = Thrust.ToString(); Root.AppendChild(thrustNode); var flowParametersNode = xmlDoc.CreateElement("FlowParameters"); AddAttribute(flowParametersNode, "MassFlow", FlowParameters.MassFlow); AddAttribute(flowParametersNode, "NozzleDiameter", FlowParameters.NozzleDiameter); AddAttribute(flowParametersNode, "NozzleMachNumber", FlowParameters.NozzleMachNumber); AddAttribute(flowParametersNode, "NozzleFlowVelocity", FlowParameters.NozzleFlowVelocity); AddAttribute(flowParametersNode, "ChamberSoundVelocity", FlowParameters.ChamberSoundVelocity); AddAttribute(flowParametersNode, "NozzleAdiabaticIndex", FlowParameters.NozzleAdiabaticIndex); Root.AppendChild(flowParametersNode); var contourParanetersNode = xmlDoc.CreateElement("ContourParaneters"); AddAttribute(contourParanetersNode, "Width", ContourParameters.ContourAreaWidth); AddAttribute(contourParanetersNode, "Height", ContourParameters.ContourAreaHeight); AddAttribute(contourParanetersNode, "NozzleCoordinate", ContourParameters.NozzleCoordinate); AddAttribute(contourParanetersNode, "MinSoundLevel", ContourParameters.MinSoundLevel); AddAttribute(contourParanetersNode, "MaxSoundLevel", ContourParameters.MaxSoundLevel); Root.AppendChild(contourParanetersNode); xmlDoc.AppendChild(Root); xmlDoc.Save(FileName); }
public void Calculate( double Thrust, FlowParameters FlowParameters, out EngineAcousticsLoadSummary summary) // см. метод с аналогичной сигнатурой в IModel { var FlowSoundParameters = GetFlowSoundParameters(Thrust, FlowParameters); var EngineSoundLevelAtFrequency = GetEngineSoundLevelAtFrequency(Thrust, FlowParameters); var engineSoundLevel = GetEngineSoundLevel(Thrust, FlowParameters); var FrequencyCharacteristik = EngineSoundLevelAtFrequency(1, Math.PI / 2); var Angles = new List <double>(); for (int i = 0; i <= 180; i += 10) { Angles.Add(i); } var RadiationPattern = Angles .Select(x => new { Angle = x, SoundLevel = engineSoundLevel(1, x * Math.PI / 180) }) .ToDictionary(x => x.Angle, x => x.SoundLevel); var EngineAcousticsLoadAtFrequency = EngineSoundLevelAtFrequency(FlowSoundParameters.DistanceToPointOfMaximalSoundLevel, Math.PI); var EngineAcousticsLoadSummary = engineSoundLevel(FlowSoundParameters.DistanceToPointOfMaximalSoundLevel, Math.PI); summary = new EngineAcousticsLoadSummary(FlowSoundParameters, FrequencyCharacteristik, RadiationPattern, EngineAcousticsLoadAtFrequency, EngineAcousticsLoadSummary); }
public static double[] Get // Функция, возвращающая разложение шума на спектр по частотам ( double Pressure, // Давлению на какой-либо высоте FlowParameters flowParameters, // Параметры газовой струи double[] Frequencies, // Среднегеометрические частоты double[] FrequencyBands // Ширины частотных полос ) { double CoreLength = 1.75 * 2 * 1 / flowParameters.NozzleMachNumber * Math.Sqrt(flowParameters.MassFlow * flowParameters.NozzleFlowVelocity / (Math.PI * Pressure * flowParameters.NozzleAdiabaticIndex)) * Math.Pow(1 + 0.38 * flowParameters.NozzleMachNumber, 2); // Длина невозмущённого сверхзвукового потока double JetLength = 5 * CoreLength; // Расстояние от выходного сечения сопла до конца участка газовой струи, излучаю-щего ~98% звуковой мощности int StepCount = 15; // Количество участков разбиения газовой струи double Step = JetLength / StepCount; // Шаг разбиения газовой струи double[] Sh = new double[StepCount]; // Массив чисел Струхаля участков газовой струи double[] x = new double[StepCount]; // Массив координат участков газовой струи double[] NSP = new double[Frequencies.Length]; // Частотный спектр шума double NozzleSoundVelocity = flowParameters.NozzleFlowVelocity / flowParameters.NozzleMachNumber; // Скорость звука на срезе сопла for (int j = 1; j <= StepCount; j++) // Заполнение массивов координат и чисел Струхаля участков газовой струи { x[j - 1] = j * Step; Sh[j - 1] = x[j - 1] * NozzleSoundVelocity / (flowParameters.NozzleFlowVelocity * flowParameters.ChamberSoundVelocity); } for (int i = 0; i < Frequencies.Length; i++) // Определение частотного спектра шума { double CurrentNSP = 0; // Переменная-заготовка для элемента частотного спектра, соответсвующего частоте Frequencies[i] for (int j = 0; j < StepCount; j++) // Логарифмическое суммирование уровней шума от участков газовой струи на частоте Frequencies[i] { CurrentNSP += Math.Pow(10, 0.1 * (NRSP.Interpolate(Frequencies[i] * Sh[j]) + 10 * Math.Log10(FrequencyBands[i] * Sh[j]) + NRSPL.Interpolate(x[j] / CoreLength) + 10 * Math.Log10(Step / CoreLength))); } NSP[i] = 10 * Math.Log10(CurrentNSP); // Определение элемента частотного спектра, соответсвующего частоте Frequencies[i] } return(NSP); }
public void CalculateEngineAcousticsLoadSummary(double Thrust, FlowParameters FlowParameters, out EngineAcousticsLoadSummary summary) { engineNoiseModel.Calculate(Thrust, FlowParameters, out summary); }
public FlightSoundLevel GetFlightSoundLevel(Ballistics ballistics, FlowParameters flowParameters, FrequencyBand frequencyBand) { return(flightNoiseModel.GetFlightSoundLevel(ballistics, flowParameters, frequencyBand)); }
public void Calculate( double Thrust, FlowParameters FlowParameters, EngineSoundContourParameters ContourParameters, out EngineSoundContour EngineSoundContour) // см. метод с аналогичной сигнатурой в IModel { var FlowSoundParameters = GetFlowSoundParameters(Thrust, FlowParameters); var EngineSoundLevel = GetEngineSoundLevel(Thrust, FlowParameters); int Nx, Ny, W, H; if (ContourParameters.ContourAreaWidth >= ContourParameters.ContourAreaHeight) { Ny = 51; H = 1000; Nx = (int)(Ny * ContourParameters.ContourAreaWidth / ContourParameters.ContourAreaHeight); W = (int)(H * ContourParameters.ContourAreaWidth / ContourParameters.ContourAreaHeight); } else { Nx = 51; W = 1000; Ny = (int)(Nx * ContourParameters.ContourAreaHeight / ContourParameters.ContourAreaWidth); H = (int)(W * ContourParameters.ContourAreaHeight / ContourParameters.ContourAreaWidth); } var X = new double[Nx]; var Y = new double[Ny]; double dX = ContourParameters.ContourAreaWidth / (Nx - 1); double dY = ContourParameters.ContourAreaHeight / (Ny - 1); for (int i = 0; i < Nx; i++) { X[i] = i * dX; } for (int i = 0; i < Ny; i++) { Y[i] = i * dY; } var SoundLevels = new double[Nx, Ny]; for (int i = 0; i < Nx; i++) { double x = X[i] - FlowSoundParameters.DistanceToPointOfMaximalSoundLevel - ContourParameters.NozzleCoordinate; x = Math.Abs(x) < 0.001 ? 0.001 : x; for (int j = 0; j < Ny; j++) { double y = Math.Abs(Y[j] - ContourParameters.ContourAreaHeight / 2); double Angle; if (x == 0) { Angle = Math.Sign(y) * Math.PI / 2; } else { Angle = Math.Atan(y / Math.Abs(x)); if (x < 0) { Angle = Math.PI - Angle; } } double Radius = Math.Sqrt(x * x + y * y); SoundLevels[i, j] = EngineSoundLevel(Radius, Angle); } } var Contour = new Bitmap(W, H); EngineSoundContour = new EngineSoundContour(X, Y, SoundLevels, Contour); ModifyEngineSoundContour(ContourParameters.MinSoundLevel, ContourParameters.MaxSoundLevel, ref EngineSoundContour); }
public StaticSoundLevel GetStaticSoundLevel(double Thrust, FlowParameters flowParameters, FrequencyBand frequencyBand) { return(fireTestNoiseModel.GetStaticSoundLevel(Thrust, flowParameters, frequencyBand)); }
public EngineSoundLevel GetEngineSoundLevel(double Thrust, FlowParameters FlowParameters) { return(engineNoiseModel.GetEngineSoundLevel(Thrust, FlowParameters)); }
public void CalculateEngineSoundContour(double Thrust, FlowParameters FlowParameters, EngineSoundContourParameters ContourParameters, out EngineSoundContour EngineSoundContour) { engineNoiseModel.Calculate(Thrust, FlowParameters, ContourParameters, out EngineSoundContour); }
public EngineSoundLevelAtFrequency GetEngineSoundLevelAtFrequency(double Thrust, FlowParameters FlowParameters) // см. метод с аналогичной сигнатурой в IModel { double[] ExpandedFrequencies, ExpandedFrequenciesBand; FrequenciesAggregator.Expanded(out ExpandedFrequencies, out ExpandedFrequenciesBand); double[] spectralDecomposition = SpectralDecomposition.Get(1.01325E5, FlowParameters, ExpandedFrequencies, ExpandedFrequenciesBand); double L0 = 10 * Math.Log10(0.5 * 0.0022 * Thrust * FlowParameters.NozzleFlowVelocity) + 120 - 11; return((Radius, Angle) => { var L = L0 - 20 * Math.Log10(Radius) + DI.Interpolate(Angle * 180 / Math.PI); var Result = new Dictionary <double, double>(); for (int i = 0; i < ExpandedFrequencies.Length; i++) { Result.Add(ExpandedFrequencies[i], L + spectralDecomposition[i]); } return Result; }); }
public EngineSoundLevelAtFrequency GetEngineSoundLevelAtFrequency(double Thrust, FlowParameters FlowParameters) { return(engineNoiseModel.GetEngineSoundLevelAtFrequency(Thrust, FlowParameters)); }
public FlowSoundParameters GetFlowSoundParameters(double Thrust, FlowParameters flowParameters) { return(engineNoiseModel.GetFlowSoundParameters(Thrust, flowParameters)); }