Files
multi_energy_complementarity/tests/test_grid_priority.py

216 lines
8.2 KiB
Python
Raw Normal View History

2025-12-27 19:15:56 +08:00
"""
测试优先上网逻辑
该程序创建一个测试场景验证系统是否优先上网而不是弃风弃光
作者: iFlow CLI
创建日期: 2025-12-26
"""
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'src'))
import pandas as pd
from excel_reader import create_excel_template
from storage_optimization import optimize_storage_capacity, SystemParameters
def create_test_excel():
"""创建测试用的Excel文件有明显的发电盈余"""
# 创建24小时数据其中某些小时有大量盈余
hours = 24
# 设计数据在6-12点有大量光伏出力超过负荷
solar = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10.0, 15.0, 20.0, 20.0, 15.0, 10.0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
wind = [2.0] * 24 # 稳定的风电
thermal = [3.0] * 24 # 稳定的火电
load = [5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 8.0, 8.0, 9.0, 9.0, 8.0, 8.0, 6.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]
# 验证长度
print(f"数据长度检查: solar={len(solar)}, wind={len(wind)}, thermal={len(thermal)}, load={len(load)}")
# 设置严格的上网电量限制10%),迫使系统在超出限制时弃风弃光
params = SystemParameters(
max_curtailment_wind=0.15, # 允许15%弃风
max_curtailment_solar=0.15, # 允许15%弃光
max_grid_ratio=0.1, # 严格限制上网电量比例10%
storage_efficiency=0.9,
discharge_rate=1.0,
charge_rate=1.0,
max_storage_capacity=5.0 # 限制储能容量,增加上网压力
)
# 创建DataFrame
df = pd.DataFrame({
'小时': range(1, hours + 1),
'光伏出力(MW)': solar,
'风电出力(MW)': wind,
'火电出力(MW)': thermal,
'负荷需求(MW)': load
})
# 保存到Excel
filename = 'test_grid_priority.xlsx'
with pd.ExcelWriter(filename, engine='openpyxl') as writer:
df.to_excel(writer, sheet_name='数据', index=False)
# 添加参数工作表
parameters_df = pd.DataFrame({
'参数名称': [
'最大弃风率',
'最大弃光率',
'最大上网电量比例',
'储能效率',
'放电倍率',
'充电倍率',
'最大储能容量'
],
'参数值': [
0.15, # 最大弃风率
0.15, # 最大弃光率
0.1, # 最大上网电量比例(严格限制)
0.9, # 储能效率
1.0, # 放电倍率
1.0, # 充电倍率
5.0 # 最大储能容量(限制)
],
'参数说明': [
'允许的最大弃风率0.0-1.0',
'允许的最大弃光率0.0-1.0',
'允许的最大上网电量比例0.0-∞,只限制上网电量)',
'储能充放电效率0.0-1.0',
'储能放电倍率C-rate>0',
'储能充电倍率C-rate>0',
'储能容量上限MWh空表示无限制'
],
'取值范围': [
'0.0-1.0',
'0.0-1.0',
'≥0.0',
'0.0-1.0',
'>0',
'>0',
'>0或空'
],
'默认值': [
'0.1',
'0.1',
'0.2',
'0.9',
'1.0',
'1.0',
'无限制'
]
})
parameters_df.to_excel(writer, sheet_name='参数', index=False)
# 添加说明工作表
description_df = pd.DataFrame({
'项目': ['数据说明', '数据类型', '时间范围', '单位', '注意事项', '参数说明'],
'内容': [
'测试优先上网逻辑的数据',
'24小时电力数据',
'1-24小时',
'MW (兆瓦)',
'所有数值必须为非负数',
'设置了严格的上网电量限制(10%)和储能容量限制(5MWh)'
]
})
description_df.to_excel(writer, sheet_name='说明', index=False)
print(f"测试Excel文件已创建{filename}")
return filename
def test_grid_priority():
"""测试优先上网逻辑"""
print("=== 测试优先上网逻辑 ===\n")
# 创建测试文件
test_file = create_test_excel()
# 从Excel读取数据
from excel_reader import read_excel_data
data = read_excel_data(test_file, include_parameters=True)
solar_output = data['solar_output']
wind_output = data['wind_output']
thermal_output = data['thermal_output']
load_demand = data['load_demand']
params = data['system_parameters']
print("测试数据概况:")
print(f"光伏出力范围: {min(solar_output):.1f} - {max(solar_output):.1f} MW")
print(f"风电出力: {wind_output[0]:.1f} MW (恒定)")
print(f"火电出力: {thermal_output[0]:.1f} MW (恒定)")
print(f"负荷需求范围: {min(load_demand):.1f} - {max(load_demand):.1f} MW")
print(f"\n系统参数:")
print(f"最大上网电量比例: {params.max_grid_ratio}")
print(f"最大储能容量: {params.max_storage_capacity} MWh")
print(f"最大弃风率: {params.max_curtailment_wind}")
print(f"最大弃光率: {params.max_curtailment_solar}")
# 计算总发电量和负荷
total_generation = sum(solar_output) + sum(wind_output) + sum(thermal_output)
total_load = sum(load_demand)
total_surplus = total_generation - total_load
print(f"\n能量平衡:")
print(f"总发电量: {total_generation:.1f} MWh")
print(f"总负荷: {total_load:.1f} MWh")
print(f"总盈余: {total_surplus:.1f} MWh")
# 运行优化
print("\n正在运行储能容量优化...")
result = optimize_storage_capacity(
solar_output, wind_output, thermal_output, load_demand, params
)
# 分析结果
total_grid_feed_in = sum(result['grid_feed_in'])
total_curtailed_wind = sum(result['curtailed_wind'])
total_curtailed_solar = sum(result['curtailed_solar'])
print(f"\n=== 优化结果 ===")
print(f"所需储能容量: {result['required_storage_capacity']:.2f} MWh")
print(f"实际上网电量: {total_grid_feed_in:.2f} MWh")
print(f"上网电量比例: {result['total_grid_feed_in_ratio']:.3f}")
print(f"弃风量: {total_curtailed_wind:.2f} MWh")
print(f"弃光量: {total_curtailed_solar:.2f} MWh")
print(f"弃风率: {result['total_curtailment_wind_ratio']:.3f}")
print(f"弃光率: {result['total_curtailment_solar_ratio']:.3f}")
# 验证优先上网逻辑
max_allowed_grid = total_generation * params.max_grid_ratio
print(f"\n=== 验证优先上网逻辑 ===")
print(f"最大允许上网电量: {max_allowed_grid:.2f} MWh")
print(f"实际上网电量: {total_grid_feed_in:.2f} MWh")
if abs(total_grid_feed_in - max_allowed_grid) < 1.0: # 允许1MW误差
print("[OK] 验证通过:系统优先上网,达到上网电量限制上限")
else:
print("[ERROR] 验证失败:系统未充分利用上网电量限制")
if total_curtailed_wind > 0 or total_curtailed_solar > 0:
print("[OK] 验证通过:在上网电量限制达到后,系统开始弃风弃光")
else:
print("[INFO] 注意:没有弃风弃光,可能盈余电力全部被储能或上网消化")
# 查看具体小时的弃风弃光情况
print(f"\n=== 详细分析(盈余时段) ===")
for hour in range(6, 13): # 6-12点是光伏出力高峰
available = solar_output[hour] + wind_output[hour] + thermal_output[hour]
demand = load_demand[hour]
surplus = available - demand
grid = result['grid_feed_in'][hour]
curtailed = result['curtailed_wind'][hour] + result['curtailed_solar'][hour]
if surplus > 0:
print(f"小时{hour}: 盈余{surplus:.1f}MW -> 上网{grid:.1f}MW + 弃风弃光{curtailed:.1f}MW")
print(f"\n测试完成!")
if __name__ == "__main__":
test_grid_priority()