GreenTransPowerCalculate/wind/wind_total.py

204 lines
7.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
}
"""