public const double NOMINAL_AIR_DENSITY = 1.2041; // кг/м3 /// <summary> /// расчет мощностной характеристики на основе основных параметров ВЭУ /// </summary> /// <param name="selectedEquipment"></param> /// <returns></returns> public static Dictionary <double, double> CalculatePerformanceCharacteristic(EquipmentItemInfo selectedEquipment) { if (!selectedEquipment.EnoughDataToCalculateCharacteristic) { throw new WindEnergyException("Недостаточно данных для расчета мощностной характеристики"); } LinearInterpolateMethod interpolator = new LinearInterpolateMethod(new Dictionary <double, double>() { { 0, 0 }, { selectedEquipment.MinWindSpeed, 0 }, { selectedEquipment.NomWindSpeed, selectedEquipment.Power }, { selectedEquipment.MaxWindSpeed, selectedEquipment.Power }, { selectedEquipment.MaxWindSpeed + MIN_WIND_SPEED_STEP, 0 }, { 31, 0 }, }); Dictionary <double, double> res = new Dictionary <double, double>(); for (double speed = 1; speed <= 30; speed++) { res.Add(speed, interpolator.GetValue(speed)); } return(res); }
private void dataGridView1_SelectionChanged(object sender, EventArgs e) { if (dataGridViewEquipments.SelectedRows.Count == 0) { return; } selectedEquipment = ((EquipmentItemInfo)dataGridViewEquipments.SelectedRows[0].DataBoundItem).Clone(); recalculateInterface(); }
public FormPowerCalculatorResult(RawRange range, EquipmentItemInfo selectedEquipment, double startHeight, SuitAMSResultItem ams, bool needRecalcWithAirDensity) { this.range = range ?? throw new ArgumentNullException(nameof(range)); this.equipment = selectedEquipment ?? throw new ArgumentNullException(nameof(selectedEquipment)); this.ams = ams; InitializeComponent(); equipment = selectedEquipment; this.startHeight = startHeight; this.needRecalcWithAirDensity = needRecalcWithAirDensity; foreach (double h in equipment.TowerHeight) { _ = comboBoxTowerHeights.Items.Add(h); } comboBoxTowerHeights.SelectedItem = equipment.TowerHeight.First(); Text = $"Расчет ВЭУ {selectedEquipment.Developer} - {selectedEquipment.Model}"; refreshInterface(); }
/// <summary> /// основной расчет для ВЭУ по заданному ряду /// </summary> /// <param name="range"></param> /// <param name="equipment"></param> /// <param name="h"></param> /// <param name="startHeight"></param> /// <param name="ams">выбранная АМС для пересчета на высоту или null, если не надо проводить пересчет</param> /// <param name="needRecalcWithAirDensity"></param> /// <returns></returns> public async static Task <PowerCalculatorResult> Calculate(RawRange range, EquipmentItemInfo equipment, double h, double startHeight, SuitAMSResultItem ams, bool needRecalcWithAirDensity) { //пересчитать ряд на высоту h (считаем, что ряд на высоте startHeight) //расчитать Ni для каждого наблюдения //расчитать основные показатели Э, kиум, Эуд, hиум //расчитать кривую обеспеченности //проверка, надо ли пересчитывать скорости ветра на высоту RawRange altedRange; if (ams != null) { altedRange = await RangeElevator.ProcessRange(range, new ElevatorParameters() { ToHeight = h, Coordinates = range.Position, HellmanCoefficientSource = HellmanCoefficientSource.AMSAnalog, SelectedAMS = ams, FromHeight = startHeight }); } else { altedRange = range; } //если надо, то пересчитываем мощностную характеристику с учетом плотности воздуха Dictionary <double, double> characteristic; if (needRecalcWithAirDensity) { characteristic = RecalcPerfomanceCharacteristicWithAirDensity(range.AirDensity, equipment.PerformanceCharacteristic, equipment); } else { characteristic = equipment.PerformanceCharacteristic; } //расчет мощности для каждого наблюдения и годовой выработки LinearInterpolateMethod interpolator = new LinearInterpolateMethod(characteristic); Dictionary <double, double> production = new Dictionary <double, double>(); Dictionary <DateTime, double> productionRange = new Dictionary <DateTime, double>(); Dictionary <Months, double> energyByMonth = new Dictionary <Months, double>(); double totalE = 0; for (int i = 0; i < altedRange.Count; i++) { RawItem item = altedRange[i]; double N; if (!interpolator.InBounds(item.Speed)) { N = 0; //мощность в кВт } else { N = interpolator.GetValue(item.Speed); //мощность в кВт } production.Add(item.DateArgument, N); productionRange.Add(item.Date, N); //расчет выработки if (i > 0) { double energyBit = N * (item.DateArgument - altedRange[i - 1].DateArgument) / 60; //перевод в часы (DateArgumet в минутах) totalE += energyBit; //суммарная выработка в кВт*ч //выработка по месяцам Months month = (Months)item.Date.Month; if (energyByMonth.ContainsKey(month)) { energyByMonth[month] += energyBit; } else { energyByMonth.Add(month, energyBit); } } } //поскольку ряд мб произвольной длины, то надо привести выработку к среднегодовой //коэффициент пересчета к одному году double yearKoeff = 8760 / ((altedRange.Last().Date - altedRange.First().Date).TotalHours); double E = totalE * yearKoeff; //коэфф использования установленной мощности double kium = E / (equipment.Power * 8760); //выработка уже приведена к году, используем как есть //удельная выработка double Edensity = E / (Math.PI * Math.Pow(equipment.Diameter, 2) / 4); // Эгод/Fом //число часов использования установленной мощности double hium = E / equipment.Power; //выработка уже приведена к году, используем как есть PowerCalculatorResult result = new PowerCalculatorResult() { YearEnergy = E, TotalEnergy = totalE, EnergyByMonth = energyByMonth, EDensity = Edensity, Kium = kium, Hium = hium, SupportingPower = calculateSupportingPower(production), Production = productionRange, Equipment = equipment, TowerHeight = h, Range = range }; return(result); }
/// <summary> /// пересчет мощностной характеристики с учетом плотности воздуха /// </summary> /// <param name="airDensity">плотность воздуха в точке</param> /// <param name="performanceCharacteristic">характеристика для пересчета</param> /// <param name="equipment">информация о ВЭУ которой принадлежит эта характеристика</param> /// <returns></returns> public static Dictionary <double, double> RecalcPerfomanceCharacteristicWithAirDensity(double airDensity, Dictionary <double, double> performanceCharacteristic, EquipmentItemInfo equipment) { if (double.IsNaN(airDensity)) { throw new ArgumentException($"Параметр не может быть NaN: {nameof(airDensity)}"); } double koeff = airDensity / NOMINAL_AIR_DENSITY; //характеристику из БД разделить на ном плотность и умножить на фактическую Dictionary <double, double> res = new Dictionary <double, double>(); foreach (double speed in performanceCharacteristic.Keys) { res.Add(speed, performanceCharacteristic[speed] * koeff); } return(res); }