import pandas as pd import math from scipy.optimize import fsolve import os import sys # 获取当前文件的绝对路径 current_dir = os.path.dirname(os.path.abspath(__file__)) print(current_dir) # 添加当前目录到sys.path sys.path.append(current_dir) def wind_farm_analysis(device_name, area_km2, electricity_price, file_path, velocity_avg, T_avg, lateral_spacing_factor=5, longitudinal_spacing_factor=10, q=0.02, altitude=11, hub_height=100, Cp=0.45, eta=0.8, cost_per_mw=5000): """ 封装函数:分析风电场的风机数量及各项经济和技术指标 参数: device_name (str): 设备名称 area_km2 (float): 风电场面积(平方公里) electricity_price (float): 电价(元/kWh) file_path (str): 风机参数 Excel 文件路径 velocity_avg (float): 全年平均风速 T_path (str): 全年平均温度 lateral_spacing_factor (float): 横向间距因子(默认为 5D) longitudinal_spacing_factor (float): 纵向间距因子(默认为 10D) q (float): 运维成本占初始投资成本的比例(默认 0.02 表示 2%) altitude (float): 海拔高度(m),默认 11m hub_height (float): 轮毂高度(m),默认 100m Cp (float): 风能利用系数,默认 0.45 eta (float): 总系统效率,默认 0.8 cost_per_mw (float): 每 MW 投资成本(万元/MW),默认 5000 万元/MW 返回: dict: 包含风电场分析结果的字典 """ def estimate_wind_turbine_count(area_km2, blade_diameter): area_m2 = area_km2 * 1_000_000 lateral_spacing = lateral_spacing_factor * blade_diameter longitudinal_spacing = longitudinal_spacing_factor * blade_diameter turbine_area = lateral_spacing * longitudinal_spacing turbine_count = int(area_m2 / turbine_area) print(f"单台风机占地面积: {turbine_area:,} 平方米 " f"(横向间距: {lateral_spacing} 米, 纵向间距: {longitudinal_spacing} 米)") print(f"估算风机数量: {turbine_count} 台") return turbine_count def get_wind_turbine_specs(device_name, file_path): try: df = pd.read_excel(file_path) match = df[df.iloc[:, 0] == device_name] if not match.empty: rated_power = match.iloc[0, 1] swept_area = match.iloc[0, 7] # 扫风面积 blade_diameter = match.iloc[0, 6] # 叶片直径 print(f"找到设备 '{device_name}',额定功率: {rated_power} kW, " f"扫风面积: {swept_area} m², 叶片直径: {blade_diameter} 米") return rated_power, swept_area, blade_diameter else: raise ValueError(f"未找到设备名称: {device_name}") except FileNotFoundError: raise FileNotFoundError(f"文件未找到: {file_path}") except Exception as e: raise Exception(f"发生错误: {str(e)}") def air_density(altitude, hub_height, T0): z = altitude + hub_height LR = 0.0065 T = T0 - LR * z + 273.15 return (353.05 / T) * math.exp(-0.034 * (z / T)) def wind_power_density(densities, velocity_avg): rho_v3 = densities * velocity_avg return 0.5 * rho_v3 def estimated_wind_power(num_turbines, rated_power): if not isinstance(num_turbines, int) or num_turbines < 0: raise ValueError("风机数量必须为非负整数") return rated_power * num_turbines def calculate_power_output(S, w, Cp, eta): # 瓦时 return w * S * Cp * 8760 * eta def calculate_equivalent_hours(P, P_r): if P_r == 0: raise ValueError("额定功率不能为 0") return (P / 1000) / P_r def calculate_environmental_benefits(E_p_million_kwh): """计算环境收益""" if E_p_million_kwh < 0: raise ValueError("年发电量需≥0") return { "coal_reduction": E_p_million_kwh * 0.404 * 10, "CO2_reduction": E_p_million_kwh * 0.977 * 10, "SO2_reduction": E_p_million_kwh * 0.03 * 10, "NOX_reduction": E_p_million_kwh * 0.015 * 10 } def calculate_reference_yield(E_p, electricity_price, IC, q, n=20): def npv_equation(irr, p, w, ic, q_val, n=n): term1 = (1 + irr) ** (-1) term2 = irr * (1 + irr) ** (-1) if irr != 0 else float('inf') pv_revenue = p * w * (term1 / term2) * (1 - (1 + irr) ** (-n)) pv_salvage = q_val * ic * (term1 / term2) * (1 - (1 + irr) ** (-n)) return pv_revenue - ic + pv_salvage irr_guess = 0.1 irr = float(fsolve(npv_equation, irr_guess, args=(E_p, electricity_price, IC, q))[0]) if not 0 <= irr <= 1: raise ValueError(f"IRR计算结果{irr:.4f}不合理") return irr * 100 # 获取设备信息 rated_power, swept_area, blade_diameter = get_wind_turbine_specs(device_name, file_path) # 估算风机数量 num_turbines = estimate_wind_turbine_count(area_km2, blade_diameter) # 读取温度数据并计算空气密度 avg_density = air_density(altitude, hub_height, T_avg) # 计算风功率密度 wpd = wind_power_density(avg_density, velocity_avg) # 计算装机容量 total_power = estimated_wind_power(num_turbines, rated_power) # 计算初始投资成本 IC = total_power * cost_per_mw * 1000000 # 计算年发电量 kwh P_test = calculate_power_output(swept_area, wpd, Cp, eta) * num_turbines # 计算等效小时数 h = calculate_equivalent_hours(P_test, rated_power) # 计算 IRR P_test_IRR = P_test/1000 irr = calculate_reference_yield(P_test_IRR, electricity_price, IC, q) env_benefits = calculate_environmental_benefits((P_test / 10000000)) # 返回结果 out = { "device": device_name, "rated_power": rated_power, "swept_area": swept_area, "blade_diameter": blade_diameter, "num_turbines": num_turbines, "avg_density": avg_density, "wpd": wpd, "total_power": total_power, "annual_power_output": P_test / 10000000, # 万 kWh "equivalent_hours": h, "IRR": irr } out.update(env_benefits) return out # 主程序 if __name__ == "__main__": file_path = f"{current_dir}/wind_product.xlsx" v_avg = 4.2 tavg = 15 device_name = "GW165-5.2" area_km2 = 23.2 electricity_price = 0.45 result = wind_farm_analysis( device_name=device_name, area_km2=area_km2, electricity_price=electricity_price, file_path=file_path, velocity_avg=v_avg, T_avg=tavg ) print(result) """ { "code": 200, "data": { "device": "GW165-5.2", "rated_power": 5.2, "swept_area": 21382, "blade_diameter": 165, "num_turbines": 23, "avg_density": 1.2118668826686871, "wpd": 1.9995803564033336, "total_power": 119.60000000000001, "annual_power_output": 310.11418354861905, "equivalent_hours": 596.3734299011904, "IRR": 9.985793133871693, "coal_reduction": 12528.61301536421, "CO2_reduction": 30298.155732700077, "SO2_reduction": 930.342550645857, "NOX_reduction": 465.1712753229285 } } """