重构了目录结构
This commit is contained in:
533
scripts/example_usage.py
Normal file
533
scripts/example_usage.py
Normal file
@@ -0,0 +1,533 @@
|
||||
"""
|
||||
多能互补系统储能容量优化计算程序使用示例
|
||||
|
||||
该文件展示了如何使用储能优化程序处理不同的实际场景。
|
||||
|
||||
作者: iFlow CLI
|
||||
创建日期: 2025-12-25
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'src'))
|
||||
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from storage_optimization import optimize_storage_capacity, SystemParameters
|
||||
|
||||
# 配置matplotlib支持中文显示
|
||||
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'DejaVu Sans']
|
||||
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
|
||||
|
||||
|
||||
def example_1_basic_scenario():
|
||||
"""示例1: 基础场景"""
|
||||
print("=== 示例1: 基础场景 ===")
|
||||
|
||||
# 基础数据 - 夏日典型日
|
||||
solar_output = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 2.0, 4.0, 6.0, 8.0, 9.0,
|
||||
8.0, 6.0, 4.0, 2.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
|
||||
wind_output = [4.0, 4.5, 5.0, 5.5, 5.0, 4.5, 4.0, 3.5, 3.0, 2.5, 2.0, 1.5,
|
||||
1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 5.0, 4.5, 4.0]
|
||||
|
||||
thermal_output = [8.0] * 24 # 火电基荷
|
||||
|
||||
load_demand = [6.0, 5.5, 5.0, 5.0, 5.5, 7.0, 9.0, 12.0, 15.0, 18.0, 20.0, 19.0,
|
||||
18.0, 17.0, 16.0, 15.0, 14.0, 13.0, 12.0, 10.0, 8.0, 7.0, 6.0, 6.0]
|
||||
|
||||
# 系统参数
|
||||
params = SystemParameters(
|
||||
max_curtailment_wind=0.1, # 最大弃风率10%
|
||||
max_curtailment_solar=0.05, # 最大弃光率5%
|
||||
max_grid_ratio=0.15, # 最大上网电量比例15%
|
||||
storage_efficiency=0.9, # 储能效率90%
|
||||
discharge_rate=1.0, # 1C放电
|
||||
charge_rate=1.0 # 1C充电
|
||||
)
|
||||
|
||||
# 计算最优储能容量
|
||||
result = optimize_storage_capacity(solar_output, wind_output, thermal_output, load_demand, params)
|
||||
|
||||
# 打印结果
|
||||
print(f"所需储能容量: {result['required_storage_capacity']:.2f} MWh")
|
||||
print(f"实际弃风率: {result['total_curtailment_wind_ratio']:.3f} (约束: {params.max_curtailment_wind})")
|
||||
print(f"实际弃光率: {result['total_curtailment_solar_ratio']:.3f} (约束: {params.max_curtailment_solar})")
|
||||
print(f"实际上网电量比例: {result['total_grid_feed_in_ratio']:.3f} (约束: {params.max_grid_ratio})")
|
||||
print(f"能量平衡校验: {'通过' if result['energy_balance_check'] else '未通过'}")
|
||||
|
||||
return {
|
||||
'result': result,
|
||||
'solar_output': solar_output,
|
||||
'wind_output': wind_output,
|
||||
'thermal_output': thermal_output,
|
||||
'load_demand': load_demand
|
||||
}
|
||||
|
||||
|
||||
def example_2_high_renewable_scenario():
|
||||
"""示例2: 高可再生能源渗透场景"""
|
||||
print("\n=== 示例2: 高可再生能源渗透场景 ===")
|
||||
|
||||
# 高可再生能源数据
|
||||
solar_output = [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 3.0, 6.0, 10.0, 14.0, 18.0, 20.0,
|
||||
18.0, 14.0, 10.0, 6.0, 3.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
|
||||
wind_output = [8.0, 9.0, 10.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0,
|
||||
3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 10.0, 9.0, 8.0]
|
||||
|
||||
thermal_output = [4.0] * 24 # 较低的火电基荷
|
||||
|
||||
load_demand = [8.0, 7.5, 7.0, 7.0, 7.5, 9.0, 11.0, 14.0, 17.0, 20.0, 22.0, 21.0,
|
||||
20.0, 19.0, 18.0, 17.0, 16.0, 15.0, 14.0, 12.0, 10.0, 9.0, 8.0, 8.0]
|
||||
|
||||
# 系统参数 - 较高的弃风弃光容忍度
|
||||
params = SystemParameters(
|
||||
max_curtailment_wind=0.2, # 最大弃风率20%
|
||||
max_curtailment_solar=0.15, # 最大弃光率15%
|
||||
max_grid_ratio=0.25, # 最大上网电量比例25%
|
||||
storage_efficiency=0.85, # 较低的储能效率
|
||||
discharge_rate=1.0,
|
||||
charge_rate=1.0
|
||||
)
|
||||
|
||||
result = optimize_storage_capacity(solar_output, wind_output, thermal_output, load_demand, params)
|
||||
|
||||
print(f"所需储能容量: {result['required_storage_capacity']:.2f} MWh")
|
||||
print(f"实际弃风率: {result['total_curtailment_wind_ratio']:.3f}")
|
||||
print(f"实际弃光率: {result['total_curtailment_solar_ratio']:.3f}")
|
||||
print(f"实际上网电量比例: {result['total_grid_feed_in_ratio']:.3f}")
|
||||
print(f"能量平衡校验: {'通过' if result['energy_balance_check'] else '未通过'}")
|
||||
|
||||
return {
|
||||
'result': result,
|
||||
'solar_output': solar_output,
|
||||
'wind_output': wind_output,
|
||||
'thermal_output': thermal_output,
|
||||
'load_demand': load_demand
|
||||
}
|
||||
|
||||
|
||||
def example_3_winter_scenario():
|
||||
"""示例3: 冬季场景"""
|
||||
print("\n=== 示例3: 冬季场景 ===")
|
||||
|
||||
# 冬季数据 - 光照弱,风电强,负荷高
|
||||
solar_output = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.8, 1.5, 2.0, 2.5, 2.8,
|
||||
2.5, 2.0, 1.5, 0.8, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
|
||||
wind_output = [12.0, 13.0, 14.0, 15.0, 14.0, 13.0, 12.0, 11.0, 10.0, 9.0, 8.0, 7.0,
|
||||
7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 14.0, 13.0, 12.0]
|
||||
|
||||
thermal_output = [12.0] * 24 # 高火电基荷
|
||||
|
||||
load_demand = [12.0, 11.5, 11.0, 11.0, 11.5, 13.0, 15.0, 18.0, 21.0, 24.0, 26.0, 25.0,
|
||||
24.0, 23.0, 22.0, 21.0, 20.0, 19.0, 18.0, 16.0, 14.0, 13.0, 12.0, 12.0]
|
||||
|
||||
# 系统参数 - 严格的弃风弃光控制
|
||||
params = SystemParameters(
|
||||
max_curtailment_wind=0.05, # 严格的弃风控制
|
||||
max_curtailment_solar=0.02, # 严格的弃光控制
|
||||
max_grid_ratio=0.1, # 低上网电量比例
|
||||
storage_efficiency=0.92, # 高储能效率
|
||||
discharge_rate=1.0,
|
||||
charge_rate=1.0
|
||||
)
|
||||
|
||||
result = optimize_storage_capacity(solar_output, wind_output, thermal_output, load_demand, params)
|
||||
|
||||
print(f"所需储能容量: {result['required_storage_capacity']:.2f} MWh")
|
||||
print(f"实际弃风率: {result['total_curtailment_wind_ratio']:.3f}")
|
||||
print(f"实际弃光率: {result['total_curtailment_solar_ratio']:.3f}")
|
||||
print(f"实际上网电量比例: {result['total_grid_feed_in_ratio']:.3f}")
|
||||
print(f"能量平衡校验: {'通过' if result['energy_balance_check'] else '未通过'}")
|
||||
|
||||
return {
|
||||
'result': result,
|
||||
'solar_output': solar_output,
|
||||
'wind_output': wind_output,
|
||||
'thermal_output': thermal_output,
|
||||
'load_demand': load_demand
|
||||
}
|
||||
|
||||
|
||||
def plot_results(result, title, solar_output, wind_output, thermal_output, load_demand):
|
||||
"""绘制结果图表"""
|
||||
hours = list(range(24))
|
||||
|
||||
fig, ((ax1, ax2), (ax3, ax4), (ax5, ax6)) = plt.subplots(3, 2, figsize=(16, 12))
|
||||
fig.suptitle(title, fontsize=16)
|
||||
|
||||
# 发电与负荷对比
|
||||
ax1.plot(hours, load_demand, 'r-', linewidth=2, label='负荷需求')
|
||||
ax1.plot(hours, thermal_output, 'b-', linewidth=2, label='火电出力')
|
||||
ax1.plot(hours, wind_output, 'g-', linewidth=2, label='风电出力')
|
||||
ax1.plot(hours, solar_output, 'orange', linewidth=2, label='光伏出力')
|
||||
|
||||
# 计算总发电量
|
||||
total_generation = [thermal_output[i] + wind_output[i] + solar_output[i] for i in range(24)]
|
||||
ax1.plot(hours, total_generation, 'k--', linewidth=1.5, alpha=0.7, label='总发电量')
|
||||
|
||||
ax1.set_title('发电与负荷曲线')
|
||||
ax1.set_xlabel('时间 (小时)')
|
||||
ax1.set_ylabel('功率 (MW)')
|
||||
ax1.legend()
|
||||
ax1.grid(True)
|
||||
|
||||
# 储能状态
|
||||
ax2.plot(hours, result['storage_profile'], 'b-', linewidth=2)
|
||||
ax2.set_title('储能状态 (MWh)')
|
||||
ax2.set_xlabel('时间 (小时)')
|
||||
ax2.set_ylabel('储能容量 (MWh)')
|
||||
ax2.grid(True)
|
||||
|
||||
# 充放电功率
|
||||
ax3.plot(hours, result['charge_profile'], 'g-', label='充电', linewidth=2)
|
||||
ax3.plot(hours, [-p for p in result['discharge_profile']], 'r-', label='放电', linewidth=2)
|
||||
ax3.set_title('储能充放电功率 (MW)')
|
||||
ax3.set_xlabel('时间 (小时)')
|
||||
ax3.set_ylabel('功率 (MW)')
|
||||
ax3.legend()
|
||||
ax3.grid(True)
|
||||
|
||||
# 弃风弃光
|
||||
ax4.plot(hours, result['curtailed_wind'], 'c-', label='弃风', linewidth=2)
|
||||
ax4.plot(hours, result['curtailed_solar'], 'm-', label='弃光', linewidth=2)
|
||||
ax4.set_title('弃风弃光量 (MW)')
|
||||
ax4.set_xlabel('时间 (小时)')
|
||||
ax4.set_ylabel('功率 (MW)')
|
||||
ax4.legend()
|
||||
ax4.grid(True)
|
||||
|
||||
# 上网电量/购电量
|
||||
ax5.plot(hours, result['grid_feed_in'], 'orange', linewidth=2)
|
||||
ax5.axhline(y=0, color='black', linestyle='-', linewidth=0.5, alpha=0.5)
|
||||
ax5.fill_between(hours, 0, result['grid_feed_in'],
|
||||
where=[x >= 0 for x in result['grid_feed_in']],
|
||||
alpha=0.3, color='green', label='上网')
|
||||
ax5.fill_between(hours, 0, result['grid_feed_in'],
|
||||
where=[x < 0 for x in result['grid_feed_in']],
|
||||
alpha=0.3, color='red', label='购电')
|
||||
|
||||
# 动态设置标题
|
||||
total_grid = sum(result['grid_feed_in'])
|
||||
if total_grid < 0:
|
||||
ax5.set_title(f'购电量 (总计: {abs(total_grid):.1f} MWh)')
|
||||
else:
|
||||
ax5.set_title(f'上网电量 (总计: {total_grid:.1f} MWh)')
|
||||
|
||||
ax5.set_xlabel('时间 (小时)')
|
||||
ax5.set_ylabel('功率 (MW)')
|
||||
ax5.legend()
|
||||
ax5.grid(True)
|
||||
|
||||
# 能量平衡分析
|
||||
total_gen = sum(thermal_output) + sum(wind_output) + sum(solar_output)
|
||||
total_load = sum(load_demand)
|
||||
total_curtailed = sum(result['curtailed_wind']) + sum(result['curtailed_solar'])
|
||||
total_grid = sum(result['grid_feed_in'])
|
||||
total_charge = sum(result['charge_profile'])
|
||||
total_discharge = sum(result['discharge_profile'])
|
||||
|
||||
# 创建能量平衡柱状图
|
||||
categories = ['总发电量', '总负荷', '弃风弃光', '上网电量', '储能充电', '储能放电']
|
||||
values = [total_gen, total_load, total_curtailed, total_grid, total_charge, total_discharge]
|
||||
colors = ['blue', 'red', 'orange', 'green', 'cyan', 'magenta']
|
||||
|
||||
bars = ax6.bar(categories, values, color=colors, alpha=0.7)
|
||||
ax6.set_title('能量平衡分析')
|
||||
ax6.set_ylabel('能量 (MWh)')
|
||||
ax6.grid(True, axis='y', alpha=0.3)
|
||||
|
||||
# 在柱状图上添加数值标签
|
||||
for bar, value in zip(bars, values):
|
||||
height = bar.get_height()
|
||||
ax6.text(bar.get_x() + bar.get_width()/2., height,
|
||||
f'{value:.1f}', ha='center', va='bottom', fontsize=9)
|
||||
|
||||
plt.tight_layout()
|
||||
plt.show()
|
||||
|
||||
|
||||
def example_5_high_load_grid_purchase_scenario():
|
||||
"""示例5: 高负荷购电场景"""
|
||||
print("\n=== 示例5: 高负荷购电场景 ===")
|
||||
|
||||
# 高负荷场景数据 - 有充电和放电时段
|
||||
solar_output = [0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 4.0, 6.0, 8.0, 10.0, 9.0, 8.0,
|
||||
7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
|
||||
wind_output = [5.0, 5.5, 6.0, 6.5, 6.0, 5.5, 5.0, 4.5, 4.0, 3.5, 3.0, 2.5,
|
||||
2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 5.5, 5.0, 5.0]
|
||||
|
||||
thermal_output = [8.0] * 24 # 火电基荷
|
||||
|
||||
# 负荷曲线:夜间低负荷(充电时段),白天高负荷(放电和购电时段)
|
||||
load_demand = [10.0, 9.0, 8.0, 7.0, 8.0, 12.0, 18.0, 25.0, 35.0, 42.0, 45.0, 43.0,
|
||||
40.0, 38.0, 35.0, 30.0, 25.0, 20.0, 15.0, 12.0, 11.0, 10.0, 10.0, 10.0]
|
||||
|
||||
# 系统参数 - max_grid_ratio只限制上网电量比例,不限制购电
|
||||
params = SystemParameters(
|
||||
max_curtailment_wind=0.05, # 严格的弃风控制
|
||||
max_curtailment_solar=0.02, # 严格的弃光控制
|
||||
max_grid_ratio=0.3, # 上网电量比例限制为30%,但不限制购电
|
||||
storage_efficiency=0.9, # 储能效率90%
|
||||
discharge_rate=2.0, # 2C放电,满足高峰需求
|
||||
charge_rate=1.0, # 1C充电
|
||||
max_storage_capacity=8.0 # 限制储能容量为8MWh,确保储能被充分利用
|
||||
)
|
||||
|
||||
result = optimize_storage_capacity(solar_output, wind_output, thermal_output, load_demand, params, tolerance=0.1)
|
||||
|
||||
print(f"所需储能容量: {result['required_storage_capacity']:.2f} MWh")
|
||||
print(f"储能容量上限: {result['max_storage_limit']:.2f} MWh")
|
||||
print(f"是否达到容量上限: {'是' if result['capacity_limit_reached'] else '否'}")
|
||||
print(f"实际弃风率: {result['total_curtailment_wind_ratio']:.3f} (约束: {params.max_curtailment_wind})")
|
||||
print(f"实际弃光率: {result['total_curtailment_solar_ratio']:.3f} (约束: {params.max_curtailment_solar})")
|
||||
print(f"实际上网电量比例: {result['total_grid_feed_in_ratio']:.3f} (负值表示购电,正值表示上网)")
|
||||
print(f"能量平衡校验: {'通过' if result['energy_balance_check'] else '未通过'}")
|
||||
|
||||
# 调试信息
|
||||
total_gen = sum(solar_output) + sum(wind_output) + sum(thermal_output)
|
||||
total_load = sum(load_demand)
|
||||
total_charge = sum(result['charge_profile'])
|
||||
total_discharge = sum(result['discharge_profile'])
|
||||
|
||||
print(f"\n=== 调试信息 ===")
|
||||
print(f"总发电量: {total_gen:.2f} MWh")
|
||||
print(f"总负荷: {total_load:.2f} MWh")
|
||||
print(f"负荷-发电差: {total_load - total_gen:.2f} MWh")
|
||||
print(f"总充电量: {total_charge:.2f} MWh")
|
||||
print(f"总放电量: {total_discharge:.2f} MWh")
|
||||
print(f"储能净变化: {total_discharge - total_charge:.2f} MWh")
|
||||
|
||||
# 计算购电量统计
|
||||
total_grid_feed = sum(result['grid_feed_in'])
|
||||
if total_grid_feed < 0:
|
||||
print(f"总购电量: {abs(total_grid_feed):.2f} MWh")
|
||||
|
||||
# 显示前几个小时的详细情况
|
||||
print(f"\n前6小时详细情况:")
|
||||
print(f"小时 | 发电 | 负荷 | 储能充电 | 储能放电 | 购电")
|
||||
print("-" * 55)
|
||||
for i in range(6):
|
||||
gen = solar_output[i] + wind_output[i] + thermal_output[i]
|
||||
charge = result['charge_profile'][i]
|
||||
discharge = result['discharge_profile'][i]
|
||||
grid = result['grid_feed_in'][i]
|
||||
print(f"{i:2d} | {gen:4.1f} | {load_demand[i]:4.1f} | {charge:7.2f} | {discharge:7.2f} | {grid:5.2f}")
|
||||
|
||||
# 计算最大缺电功率
|
||||
max_deficit = 0
|
||||
for hour in range(24):
|
||||
total_gen = solar_output[hour] + wind_output[hour] + thermal_output[hour]
|
||||
deficit = max(0, load_demand[hour] - total_gen - result['discharge_profile'][hour])
|
||||
max_deficit = max(max_deficit, deficit)
|
||||
|
||||
if max_deficit > 0:
|
||||
print(f"\n最大缺电功率: {max_deficit:.2f} MW")
|
||||
|
||||
return {
|
||||
'result': result,
|
||||
'solar_output': solar_output,
|
||||
'wind_output': wind_output,
|
||||
'thermal_output': thermal_output,
|
||||
'load_demand': load_demand
|
||||
}
|
||||
|
||||
|
||||
def example_6_grid_ratio_limited_scenario():
|
||||
"""示例6: 上网电量比例限制场景"""
|
||||
print("\n=== 示例6: 上网电量比例限制场景 ===")
|
||||
|
||||
# 高可再生能源场景 - 有大量盈余电力
|
||||
solar_output = [0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 5.0, 8.0, 12.0, 16.0, 20.0, 18.0,
|
||||
15.0, 12.0, 8.0, 5.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
|
||||
wind_output = [8.0, 9.0, 10.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0,
|
||||
3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 10.0, 9.0, 8.0]
|
||||
|
||||
thermal_output = [6.0] * 24 # 中等火电出力
|
||||
|
||||
# 低负荷场景 - 有大量盈余电力
|
||||
load_demand = [8.0, 7.0, 6.0, 6.0, 7.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0, 18.0,
|
||||
16.0, 14.0, 12.0, 10.0, 9.0, 8.0, 7.0, 6.0, 6.0, 7.0, 8.0, 8.0]
|
||||
|
||||
# 系统参数 - 限制上网电量比例
|
||||
params = SystemParameters(
|
||||
max_curtailment_wind=0.15, # 允许一定弃风
|
||||
max_curtailment_solar=0.1, # 允许一定弃光
|
||||
max_grid_ratio=0.15, # 限制上网电量比例为15%
|
||||
storage_efficiency=0.9, # 储能效率90%
|
||||
discharge_rate=1.0, # 1C放电
|
||||
charge_rate=1.0, # 1C充电
|
||||
max_storage_capacity=100.0 # 足够大的储能容量
|
||||
)
|
||||
|
||||
result = optimize_storage_capacity(solar_output, wind_output, thermal_output, load_demand, params)
|
||||
|
||||
print(f"所需储能容量: {result['required_storage_capacity']:.2f} MWh")
|
||||
print(f"上网电量比例限制: {params.max_grid_ratio:.1%}")
|
||||
print(f"实际上网电量比例: {result['total_grid_feed_in_ratio']:.3f}")
|
||||
print(f"实际弃风率: {result['total_curtailment_wind_ratio']:.3f} (约束: {params.max_curtailment_wind})")
|
||||
print(f"实际弃光率: {result['total_curtailment_solar_ratio']:.3f} (约束: {params.max_curtailment_solar})")
|
||||
print(f"能量平衡校验: {'通过' if result['energy_balance_check'] else '未通过'}")
|
||||
|
||||
# 检查是否达到上网电量比例限制
|
||||
if result['total_grid_feed_in_ratio'] >= params.max_grid_ratio - 0.01:
|
||||
print("注意:已达到上网电量比例限制")
|
||||
|
||||
return {
|
||||
'result': result,
|
||||
'solar_output': solar_output,
|
||||
'wind_output': wind_output,
|
||||
'thermal_output': thermal_output,
|
||||
'load_demand': load_demand
|
||||
}
|
||||
|
||||
|
||||
def example_4_capacity_limited_scenario():
|
||||
"""示例4: 储能容量限制场景"""
|
||||
print("\n=== 示例4: 储能容量限制场景 ===")
|
||||
|
||||
# 使用基础场景的数据
|
||||
solar_output = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 2.0, 4.0, 6.0, 8.0, 9.0,
|
||||
8.0, 6.0, 4.0, 2.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
|
||||
wind_output = [4.0, 4.5, 5.0, 5.5, 5.0, 4.5, 4.0, 3.5, 3.0, 2.5, 2.0, 1.5,
|
||||
1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 5.0, 4.5, 4.0]
|
||||
|
||||
thermal_output = [8.0] * 24
|
||||
|
||||
load_demand = [6.0, 5.5, 5.0, 5.0, 5.5, 7.0, 9.0, 12.0, 15.0, 18.0, 20.0, 19.0,
|
||||
18.0, 17.0, 16.0, 15.0, 14.0, 13.0, 12.0, 10.0, 8.0, 7.0, 6.0, 6.0]
|
||||
|
||||
# 系统参数 - 设置储能容量上限为10 MWh
|
||||
params = SystemParameters(
|
||||
max_curtailment_wind=0.1,
|
||||
max_curtailment_solar=0.05,
|
||||
max_grid_ratio=0.15,
|
||||
storage_efficiency=0.9,
|
||||
discharge_rate=1.0,
|
||||
charge_rate=1.0,
|
||||
max_storage_capacity=10.0 # 限制储能容量上限为10 MWh
|
||||
)
|
||||
|
||||
result = optimize_storage_capacity(solar_output, wind_output, thermal_output, load_demand, params)
|
||||
|
||||
print(f"所需储能容量: {result['required_storage_capacity']:.2f} MWh")
|
||||
print(f"储能容量上限: {result['max_storage_limit']:.2f} MWh")
|
||||
print(f"是否达到容量上限: {'是' if result['capacity_limit_reached'] else '否'}")
|
||||
print(f"实际弃风率: {result['total_curtailment_wind_ratio']:.3f} (约束: {params.max_curtailment_wind})")
|
||||
print(f"实际弃光率: {result['total_curtailment_solar_ratio']:.3f} (约束: {params.max_curtailment_solar})")
|
||||
print(f"实际上网电量比例: {result['total_grid_feed_in_ratio']:.3f} (约束: {params.max_grid_ratio})")
|
||||
print(f"能量平衡校验: {'通过' if result['energy_balance_check'] else '未通过'}")
|
||||
|
||||
return {
|
||||
'result': result,
|
||||
'solar_output': solar_output,
|
||||
'wind_output': wind_output,
|
||||
'thermal_output': thermal_output,
|
||||
'load_demand': load_demand
|
||||
}
|
||||
|
||||
|
||||
def compare_scenarios():
|
||||
"""比较不同场景的结果"""
|
||||
print("\n=== 场景比较 ===")
|
||||
|
||||
# 运行六个场景
|
||||
data1 = example_1_basic_scenario()
|
||||
data2 = example_2_high_renewable_scenario()
|
||||
data3 = example_3_winter_scenario()
|
||||
data4 = example_4_capacity_limited_scenario()
|
||||
data5 = example_5_high_load_grid_purchase_scenario()
|
||||
data6 = example_6_grid_ratio_limited_scenario()
|
||||
|
||||
# 比较结果
|
||||
scenarios = ['基础场景', '高可再生能源场景', '冬季场景', '容量限制场景', '高负荷购电场景', '上网电量比例限制场景']
|
||||
storage_capacities = [
|
||||
data1['result']['required_storage_capacity'],
|
||||
data2['result']['required_storage_capacity'],
|
||||
data3['result']['required_storage_capacity'],
|
||||
data4['result']['required_storage_capacity'],
|
||||
data5['result']['required_storage_capacity'],
|
||||
data6['result']['required_storage_capacity']
|
||||
]
|
||||
curtailment_wind = [
|
||||
data1['result']['total_curtailment_wind_ratio'],
|
||||
data2['result']['total_curtailment_wind_ratio'],
|
||||
data3['result']['total_curtailment_wind_ratio'],
|
||||
data4['result']['total_curtailment_wind_ratio'],
|
||||
data5['result']['total_curtailment_wind_ratio'],
|
||||
data6['result']['total_curtailment_wind_ratio']
|
||||
]
|
||||
curtailment_solar = [
|
||||
data1['result']['total_curtailment_solar_ratio'],
|
||||
data2['result']['total_curtailment_solar_ratio'],
|
||||
data3['result']['total_curtailment_solar_ratio'],
|
||||
data4['result']['total_curtailment_solar_ratio'],
|
||||
data5['result']['total_curtailment_solar_ratio'],
|
||||
data6['result']['total_curtailment_solar_ratio']
|
||||
]
|
||||
grid_feed_in = [
|
||||
data1['result']['total_grid_feed_in_ratio'],
|
||||
data2['result']['total_grid_feed_in_ratio'],
|
||||
data3['result']['total_grid_feed_in_ratio'],
|
||||
data4['result']['total_grid_feed_in_ratio'],
|
||||
data5['result']['total_grid_feed_in_ratio'],
|
||||
data6['result']['total_grid_feed_in_ratio']
|
||||
]
|
||||
capacity_limit = [
|
||||
'无',
|
||||
'无',
|
||||
'无',
|
||||
f"{data4['result']['max_storage_limit']:.1f}MWh",
|
||||
f"{data5['result']['max_storage_limit']:.1f}MWh",
|
||||
f"{data6['result']['max_storage_limit']:.1f}MWh"
|
||||
]
|
||||
|
||||
print("\n场景比较结果:")
|
||||
print(f"{'场景':<15} {'储能容量(MWh)':<12} {'容量限制':<10} {'弃风率':<8} {'弃光率':<8} {'上网比例':<8}")
|
||||
print("-" * 80)
|
||||
for i, scenario in enumerate(scenarios):
|
||||
grid_text = f"{grid_feed_in[i]:.3f}" if grid_feed_in[i] >= 0 else f"{abs(grid_feed_in[i]):.3f}↓"
|
||||
limit_reached = "*" if (data4['result']['capacity_limit_reached'] and i == 3) or (data5['result']['capacity_limit_reached'] and i == 4) or (data6['result']['max_storage_limit'] and i == 5) else ""
|
||||
print(f"{scenario:<15} {storage_capacities[i]:<12.2f} {capacity_limit[i]:<10} {curtailment_wind[i]:<8.3f} "
|
||||
f"{curtailment_solar[i]:<8.3f} {grid_text:<8} {limit_reached}")
|
||||
|
||||
return data1, data2, data3, data4, data5, data6
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("多能互补系统储能容量优化计算程序示例")
|
||||
print("=" * 50)
|
||||
|
||||
# 运行示例
|
||||
data1, data2, data3, data4, data5, data6 = compare_scenarios()
|
||||
|
||||
# 绘制图表(如果matplotlib可用)
|
||||
try:
|
||||
plot_results(data1['result'], "基础场景储能运行情况",
|
||||
data1['solar_output'], data1['wind_output'],
|
||||
data1['thermal_output'], data1['load_demand'])
|
||||
plot_results(data2['result'], "高可再生能源场景储能运行情况",
|
||||
data2['solar_output'], data2['wind_output'],
|
||||
data2['thermal_output'], data2['load_demand'])
|
||||
plot_results(data3['result'], "冬季场景储能运行情况",
|
||||
data3['solar_output'], data3['wind_output'],
|
||||
data3['thermal_output'], data3['load_demand'])
|
||||
plot_results(data4['result'], "容量限制场景储能运行情况",
|
||||
data4['solar_output'], data4['wind_output'],
|
||||
data4['thermal_output'], data4['load_demand'])
|
||||
plot_results(data5['result'], "高负荷购电场景储能运行情况",
|
||||
data5['solar_output'], data5['wind_output'],
|
||||
data5['thermal_output'], data5['load_demand'])
|
||||
plot_results(data6['result'], "上网电量比例限制场景储能运行情况",
|
||||
data6['solar_output'], data6['wind_output'],
|
||||
data6['thermal_output'], data6['load_demand'])
|
||||
except ImportError:
|
||||
print("\n注意: matplotlib未安装,无法绘制图表")
|
||||
print("要安装matplotlib,请运行: pip install matplotlib")
|
||||
|
||||
print("\n示例运行完成!")
|
||||
541
scripts/solar_optimization_examples.py
Normal file
541
scripts/solar_optimization_examples.py
Normal file
@@ -0,0 +1,541 @@
|
||||
"""
|
||||
光伏优化模块场景示例
|
||||
|
||||
该文件展示了光伏优化模块在不同场景下的应用,包括:
|
||||
1. 典型日场景 - 基础优化示例
|
||||
2. 高负荷场景 - 夏季高峰用电场景
|
||||
3. 低负荷场景 - 春秋季低负荷场景
|
||||
4. 风光互补场景 - 风电和光伏协同优化
|
||||
5. 储能受限场景 - 储能容量受限情况下的优化
|
||||
|
||||
作者: iFlow CLI
|
||||
创建日期: 2025-12-26
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'src'))
|
||||
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from typing import List, Dict
|
||||
from solar_optimization import optimize_solar_output, plot_optimization_results, export_optimization_results
|
||||
from storage_optimization import SystemParameters
|
||||
|
||||
|
||||
def scenario_1_typical_day():
|
||||
"""
|
||||
场景1:典型日场景
|
||||
- 标准24小时负荷曲线
|
||||
- 适中风光出力
|
||||
- 常规系统参数
|
||||
"""
|
||||
print("=" * 60)
|
||||
print("场景1:典型日场景 - 基础优化示例")
|
||||
print("=" * 60)
|
||||
|
||||
# 典型日光伏出力(中午高峰)
|
||||
solar_output = [0.0] * 6 + [0.5, 1.0, 2.0, 3.5, 5.0, 6.0, 5.5, 4.0, 2.5, 1.0, 0.5, 0.0] + [0.0] * 6
|
||||
|
||||
# 典型日风电出力(夜间和早晨较高)
|
||||
wind_output = [4.0, 5.0, 4.5, 3.5, 2.5, 2.0, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 2.0, 3.0, 4.0, 5.0, 4.5, 4.0, 3.5, 3.0, 2.5, 2.0, 1.5, 1.0]
|
||||
|
||||
# 火电基础出力
|
||||
thermal_output = [8.0] * 24
|
||||
|
||||
# 典型日负荷曲线(早晚高峰)
|
||||
load_demand = [2.0, 2.5, 3.0, 4.0, 6.0, 9.0, 12.0, 15.0, 18.0, 20.0, 19.0, 18.0,
|
||||
17.0, 16.0, 18.0, 19.0, 20.0, 18.0, 15.0, 12.0, 8.0, 5.0, 3.0, 2.0]
|
||||
|
||||
# 标准系统参数
|
||||
params = SystemParameters(
|
||||
max_curtailment_wind=0.1,
|
||||
max_curtailment_solar=0.1,
|
||||
max_grid_ratio=0.15,
|
||||
storage_efficiency=0.9,
|
||||
discharge_rate=1.0,
|
||||
charge_rate=1.0,
|
||||
rated_thermal_capacity=100.0,
|
||||
rated_solar_capacity=50.0,
|
||||
rated_wind_capacity=50.0,
|
||||
available_thermal_energy=2000.0,
|
||||
available_solar_energy=400.0,
|
||||
available_wind_energy=600.0
|
||||
)
|
||||
|
||||
# 执行优化
|
||||
result = optimize_solar_output(
|
||||
solar_output, wind_output, thermal_output, load_demand, params
|
||||
)
|
||||
|
||||
# 输出结果
|
||||
print_scenario_result("典型日场景", result)
|
||||
|
||||
# 绘制结果
|
||||
plot_optimization_results(result, show_window=False)
|
||||
|
||||
# 导出结果
|
||||
filename = export_optimization_results(result, "scenario_1_typical_day.xlsx")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def scenario_2_high_load():
|
||||
"""
|
||||
场景2:高负荷场景
|
||||
- 夏季高温,空调负荷高
|
||||
- 白天负荷特别高
|
||||
- 光伏出力与负荷匹配度较低
|
||||
"""
|
||||
print("=" * 60)
|
||||
print("场景2:高负荷场景 - 夏季高峰用电")
|
||||
print("=" * 60)
|
||||
|
||||
# 夏季光伏出力(较强)
|
||||
solar_output = [0.0] * 5 + [0.8, 1.5, 3.0, 4.5, 6.0, 7.5, 8.0, 7.0, 5.0, 3.0, 1.5, 0.5, 0.0, 0.0] + [0.0] * 5
|
||||
|
||||
# 夏季风电出力(相对较低)
|
||||
wind_output = [2.0, 2.5, 3.0, 2.5, 2.0, 1.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.5, 2.0, 2.5, 3.0, 2.5, 2.0, 1.8, 1.6, 1.4, 1.2, 1.0, 0.8]
|
||||
|
||||
# 火电高峰出力
|
||||
thermal_output = [12.0] * 24
|
||||
|
||||
# 夏季高负荷曲线(空调导致白天负荷极高)
|
||||
load_demand = [3.0, 3.5, 4.0, 5.0, 8.0, 12.0, 18.0, 25.0, 30.0, 32.0, 31.0, 30.0,
|
||||
29.0, 28.0, 30.0, 31.0, 32.0, 28.0, 22.0, 18.0, 12.0, 8.0, 5.0, 3.0]
|
||||
|
||||
# 高负荷场景参数(更宽松的弃风弃光限制)
|
||||
params = SystemParameters(
|
||||
max_curtailment_wind=0.15,
|
||||
max_curtailment_solar=0.15,
|
||||
max_grid_ratio=0.25,
|
||||
storage_efficiency=0.85,
|
||||
discharge_rate=1.2,
|
||||
charge_rate=1.2,
|
||||
rated_thermal_capacity=150.0,
|
||||
rated_solar_capacity=80.0,
|
||||
rated_wind_capacity=40.0,
|
||||
available_thermal_energy=3000.0,
|
||||
available_solar_energy=600.0,
|
||||
available_wind_energy=400.0
|
||||
)
|
||||
|
||||
# 执行优化
|
||||
result = optimize_solar_output(
|
||||
solar_output, wind_output, thermal_output, load_demand, params
|
||||
)
|
||||
|
||||
# 输出结果
|
||||
print_scenario_result("高负荷场景", result)
|
||||
|
||||
# 绘制结果
|
||||
plot_optimization_results(result, show_window=False)
|
||||
|
||||
# 导出结果
|
||||
filename = export_optimization_results(result, "scenario_2_high_load.xlsx")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def scenario_3_low_load():
|
||||
"""
|
||||
场景3:低负荷场景
|
||||
- 春秋季,负荷较低
|
||||
- 光伏出力相对较高
|
||||
- 容易出现电力盈余
|
||||
"""
|
||||
print("=" * 60)
|
||||
print("场景3:低负荷场景 - 春秋季低负荷")
|
||||
print("=" * 60)
|
||||
|
||||
# 春秋季光伏出力(适中)
|
||||
solar_output = [0.0] * 6 + [1.0, 2.0, 3.5, 5.0, 6.5, 7.0, 6.5, 5.0, 3.5, 2.0, 1.0, 0.0] + [0.0] * 6
|
||||
|
||||
# 春秋季风电出力(较好)
|
||||
wind_output = [5.0, 6.0, 5.5, 4.5, 3.5, 3.0, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 3.0, 4.0, 5.0, 6.0, 5.5, 5.0, 4.5, 4.0, 3.5, 3.0, 2.5, 2.0]
|
||||
|
||||
# 火电基础出力(较低)
|
||||
thermal_output = [5.0] * 24
|
||||
|
||||
# 春秋季低负荷曲线
|
||||
load_demand = [2.0, 2.2, 2.5, 3.0, 4.0, 6.0, 8.0, 10.0, 12.0, 13.0, 12.5, 12.0,
|
||||
11.5, 11.0, 12.0, 12.5, 13.0, 11.0, 9.0, 7.0, 5.0, 3.5, 2.5, 2.0]
|
||||
|
||||
# 低负荷场景参数(更严格的弃风弃光限制)
|
||||
params = SystemParameters(
|
||||
max_curtailment_wind=0.05,
|
||||
max_curtailment_solar=0.05,
|
||||
max_grid_ratio=0.1,
|
||||
storage_efficiency=0.92,
|
||||
discharge_rate=0.8,
|
||||
charge_rate=0.8,
|
||||
rated_thermal_capacity=80.0,
|
||||
rated_solar_capacity=60.0,
|
||||
rated_wind_capacity=60.0,
|
||||
available_thermal_energy=1500.0,
|
||||
available_solar_energy=500.0,
|
||||
available_wind_energy=700.0
|
||||
)
|
||||
|
||||
# 执行优化
|
||||
result = optimize_solar_output(
|
||||
solar_output, wind_output, thermal_output, load_demand, params
|
||||
)
|
||||
|
||||
# 输出结果
|
||||
print_scenario_result("低负荷场景", result)
|
||||
|
||||
# 绘制结果
|
||||
plot_optimization_results(result, show_window=False)
|
||||
|
||||
# 导出结果
|
||||
filename = export_optimization_results(result, "scenario_3_low_load.xlsx")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def scenario_4_wind_solar_complement():
|
||||
"""
|
||||
场景4:风光互补场景
|
||||
- 风电和光伏出力时间互补性强
|
||||
- 夜间风电高,白天光伏高
|
||||
- 系统整体平衡性较好
|
||||
"""
|
||||
print("=" * 60)
|
||||
print("场景4:风光互补场景 - 风电和光伏协同优化")
|
||||
print("=" * 60)
|
||||
|
||||
# 光伏出力(标准日间模式)
|
||||
solar_output = [0.0] * 6 + [0.5, 1.5, 3.0, 4.5, 6.0, 7.0, 6.0, 4.5, 3.0, 1.5, 0.5, 0.0] + [0.0] * 6
|
||||
|
||||
# 风电出力(与光伏互补,夜间和早晚较高)
|
||||
wind_output = [8.0, 9.0, 8.5, 7.0, 5.0, 3.0, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 3.0, 5.0, 7.0, 8.0, 8.5, 8.0, 7.5, 7.0, 6.5, 6.0, 5.5, 5.0]
|
||||
|
||||
# 火电出力(作为补充)
|
||||
thermal_output = [6.0] * 24
|
||||
|
||||
# 负荷曲线(相对平稳)
|
||||
load_demand = [4.0, 4.5, 5.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0, 17.0, 16.5, 16.0,
|
||||
15.5, 15.0, 16.0, 16.5, 17.0, 15.0, 13.0, 11.0, 9.0, 7.0, 5.0, 4.0]
|
||||
|
||||
# 风光互补场景参数
|
||||
params = SystemParameters(
|
||||
max_curtailment_wind=0.08,
|
||||
max_curtailment_solar=0.08,
|
||||
max_grid_ratio=0.12,
|
||||
storage_efficiency=0.9,
|
||||
discharge_rate=1.0,
|
||||
charge_rate=1.0,
|
||||
rated_thermal_capacity=100.0,
|
||||
rated_solar_capacity=70.0,
|
||||
rated_wind_capacity=70.0,
|
||||
available_thermal_energy=1800.0,
|
||||
available_solar_energy=450.0,
|
||||
available_wind_energy=800.0
|
||||
)
|
||||
|
||||
# 执行优化
|
||||
result = optimize_solar_output(
|
||||
solar_output, wind_output, thermal_output, load_demand, params
|
||||
)
|
||||
|
||||
# 输出结果
|
||||
print_scenario_result("风光互补场景", result)
|
||||
|
||||
# 绘制结果
|
||||
plot_optimization_results(result, show_window=False)
|
||||
|
||||
# 导出结果
|
||||
filename = export_optimization_results(result, "scenario_4_wind_solar_complement.xlsx")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def scenario_5_storage_limited():
|
||||
"""
|
||||
场景5:储能受限场景
|
||||
- 储能容量受限
|
||||
- 需要更精确的光伏出力调节
|
||||
- 对电网交换更敏感
|
||||
"""
|
||||
print("=" * 60)
|
||||
print("场景5:储能受限场景 - 储能容量受限情况下的优化")
|
||||
print("=" * 60)
|
||||
|
||||
# 标准光伏出力
|
||||
solar_output = [0.0] * 6 + [1.0, 2.0, 3.0, 4.5, 6.0, 7.0, 6.0, 4.5, 3.0, 2.0, 1.0, 0.0] + [0.0] * 6
|
||||
|
||||
# 标准风电出力
|
||||
wind_output = [3.0, 4.0, 3.5, 3.0, 2.5, 2.0, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 2.0, 3.0, 3.5, 4.0, 3.5, 3.0, 2.8, 2.6, 2.4, 2.2, 2.0, 1.8]
|
||||
|
||||
# 火电出力
|
||||
thermal_output = [7.0] * 24
|
||||
|
||||
# 标准负荷曲线
|
||||
load_demand = [3.0, 3.5, 4.0, 5.0, 7.0, 10.0, 13.0, 16.0, 18.0, 19.0, 18.5, 18.0,
|
||||
17.5, 17.0, 18.0, 18.5, 19.0, 17.0, 14.0, 11.0, 8.0, 6.0, 4.0, 3.0]
|
||||
|
||||
# 储能受限场景参数(储能容量限制为50MWh)
|
||||
params = SystemParameters(
|
||||
max_curtailment_wind=0.12,
|
||||
max_curtailment_solar=0.12,
|
||||
max_grid_ratio=0.2,
|
||||
storage_efficiency=0.88,
|
||||
discharge_rate=1.5,
|
||||
charge_rate=1.5,
|
||||
max_storage_capacity=50.0, # 储能容量受限
|
||||
rated_thermal_capacity=100.0,
|
||||
rated_solar_capacity=60.0,
|
||||
rated_wind_capacity=50.0,
|
||||
available_thermal_energy=2000.0,
|
||||
available_solar_energy=480.0,
|
||||
available_wind_energy=550.0
|
||||
)
|
||||
|
||||
# 执行优化
|
||||
result = optimize_solar_output(
|
||||
solar_output, wind_output, thermal_output, load_demand, params
|
||||
)
|
||||
|
||||
# 输出结果
|
||||
print_scenario_result("储能受限场景", result)
|
||||
|
||||
# 绘制结果
|
||||
plot_optimization_results(result, show_window=False)
|
||||
|
||||
# 导出结果
|
||||
filename = export_optimization_results(result, "scenario_5_storage_limited.xlsx")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def print_scenario_result(scenario_name: str, result):
|
||||
"""
|
||||
打印场景优化结果
|
||||
|
||||
Args:
|
||||
scenario_name: 场景名称
|
||||
result: 优化结果
|
||||
"""
|
||||
print(f"\n=== {scenario_name}优化结果 ===")
|
||||
print(f"最优光伏系数: {result.optimal_solar_coefficient:.3f}")
|
||||
print(f"最小电网交换电量: {result.min_grid_exchange:.2f} MWh")
|
||||
print(f" - 购电量: {result.grid_purchase:.2f} MWh")
|
||||
print(f" - 上网电量: {result.grid_feed_in:.2f} MWh")
|
||||
print(f"所需储能容量: {result.storage_result['required_storage_capacity']:.2f} MWh")
|
||||
print(f"优化后弃风率: {result.storage_result['total_curtailment_wind_ratio']:.3f}")
|
||||
print(f"优化后弃光率: {result.storage_result['total_curtailment_solar_ratio']:.3f}")
|
||||
print(f"优化后上网电量比例: {result.storage_result['total_grid_feed_in_ratio']:.3f}")
|
||||
|
||||
# 分析优化效果
|
||||
if result.optimal_solar_coefficient > 1.0:
|
||||
print(f"分析:建议将光伏出力提高 {(result.optimal_solar_coefficient - 1.0) * 100:.1f}% 以减少电网依赖")
|
||||
elif result.optimal_solar_coefficient < 1.0:
|
||||
print(f"分析:建议将光伏出力降低 {(1.0 - result.optimal_solar_coefficient) * 100:.1f}% 以避免电力过剩")
|
||||
else:
|
||||
print("分析:当前光伏出力已经是最优配置")
|
||||
|
||||
|
||||
def compare_scenarios(results: List[Dict]):
|
||||
"""
|
||||
对比不同场景的优化结果
|
||||
|
||||
Args:
|
||||
results: 各场景优化结果列表
|
||||
"""
|
||||
print("\n" + "=" * 80)
|
||||
print("场景对比分析")
|
||||
print("=" * 80)
|
||||
|
||||
scenario_names = [
|
||||
"典型日场景",
|
||||
"高负荷场景",
|
||||
"低负荷场景",
|
||||
"风光互补场景",
|
||||
"储能受限场景"
|
||||
]
|
||||
|
||||
# 创建对比表格
|
||||
print(f"{'场景名称':<12} {'最优系数':<8} {'电网交换(MWh)':<12} {'购电量(MWh)':<10} {'上网电量(MWh)':<12} {'储能容量(MWh)':<12}")
|
||||
print("-" * 80)
|
||||
|
||||
for i, (name, result) in enumerate(zip(scenario_names, results)):
|
||||
print(f"{name:<12} {result.optimal_solar_coefficient:<8.3f} "
|
||||
f"{result.min_grid_exchange:<12.2f} {result.grid_purchase:<10.2f} "
|
||||
f"{result.grid_feed_in:<12.2f} {result.storage_result['required_storage_capacity']:<12.2f}")
|
||||
|
||||
# 分析趋势
|
||||
print("\n=== 趋势分析 ===")
|
||||
|
||||
# 找出最优和最差场景
|
||||
min_exchange_result = min(results, key=lambda x: x.min_grid_exchange)
|
||||
max_exchange_result = max(results, key=lambda x: x.min_grid_exchange)
|
||||
|
||||
min_exchange_idx = results.index(min_exchange_result)
|
||||
max_exchange_idx = results.index(max_exchange_result)
|
||||
|
||||
print(f"电网交换最小场景:{scenario_names[min_exchange_idx]} ({min_exchange_result.min_grid_exchange:.2f} MWh)")
|
||||
print(f"电网交换最大场景:{scenario_names[max_exchange_idx]} ({max_exchange_result.min_grid_exchange:.2f} MWh)")
|
||||
|
||||
# 分析光伏系数趋势
|
||||
avg_coefficient = sum(r.optimal_solar_coefficient for r in results) / len(results)
|
||||
print(f"平均最优光伏系数:{avg_coefficient:.3f}")
|
||||
|
||||
high_coefficient_scenarios = [name for name, result in zip(scenario_names, results)
|
||||
if result.optimal_solar_coefficient > avg_coefficient]
|
||||
low_coefficient_scenarios = [name for name, result in zip(scenario_names, results)
|
||||
if result.optimal_solar_coefficient < avg_coefficient]
|
||||
|
||||
if high_coefficient_scenarios:
|
||||
print(f"需要提高光伏出力的场景:{', '.join(high_coefficient_scenarios)}")
|
||||
if low_coefficient_scenarios:
|
||||
print(f"需要降低光伏出力的场景:{', '.join(low_coefficient_scenarios)}")
|
||||
|
||||
|
||||
def plot_scenario_comparison(results: List[Dict]):
|
||||
"""
|
||||
绘制场景对比图表
|
||||
|
||||
Args:
|
||||
results: 各场景优化结果列表
|
||||
"""
|
||||
scenario_names = [
|
||||
"典型日",
|
||||
"高负荷",
|
||||
"低负荷",
|
||||
"风光互补",
|
||||
"储能受限"
|
||||
]
|
||||
|
||||
# 设置中文字体
|
||||
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'DejaVu Sans']
|
||||
plt.rcParams['axes.unicode_minus'] = False
|
||||
|
||||
# 创建图形
|
||||
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(16, 12))
|
||||
fig.suptitle('光伏优化场景对比分析', fontsize=16, fontweight='bold')
|
||||
|
||||
# 1. 最优光伏系数对比
|
||||
coefficients = [r.optimal_solar_coefficient for r in results]
|
||||
bars1 = ax1.bar(scenario_names, coefficients, color='skyblue', alpha=0.7)
|
||||
ax1.set_ylabel('最优光伏系数')
|
||||
ax1.set_title('各场景最优光伏系数对比')
|
||||
ax1.grid(True, alpha=0.3, axis='y')
|
||||
ax1.axhline(y=1.0, color='red', linestyle='--', alpha=0.7, label='原始系数')
|
||||
|
||||
# 添加数值标签
|
||||
for bar, coeff in zip(bars1, coefficients):
|
||||
height = bar.get_height()
|
||||
ax1.text(bar.get_x() + bar.get_width()/2., height + 0.01,
|
||||
f'{coeff:.3f}', ha='center', va='bottom', fontweight='bold')
|
||||
|
||||
# 2. 电网交换电量对比
|
||||
exchanges = [r.min_grid_exchange for r in results]
|
||||
purchases = [r.grid_purchase for r in results]
|
||||
feed_ins = [r.grid_feed_in for r in results]
|
||||
|
||||
x = np.arange(len(scenario_names))
|
||||
width = 0.25
|
||||
|
||||
bars2 = ax2.bar(x - width, purchases, width, label='购电量', color='purple', alpha=0.7)
|
||||
bars3 = ax2.bar(x, feed_ins, width, label='上网电量', color='brown', alpha=0.7)
|
||||
bars4 = ax2.bar(x + width, exchanges, width, label='总交换电量', color='orange', alpha=0.7)
|
||||
|
||||
ax2.set_ylabel('电量 (MWh)')
|
||||
ax2.set_title('电网交换电量对比')
|
||||
ax2.set_xticks(x)
|
||||
ax2.set_xticklabels(scenario_names)
|
||||
ax2.legend()
|
||||
ax2.grid(True, alpha=0.3, axis='y')
|
||||
|
||||
# 3. 储能容量需求对比
|
||||
storage_capacities = [r.storage_result['required_storage_capacity'] for r in results]
|
||||
bars5 = ax3.bar(scenario_names, storage_capacities, color='green', alpha=0.7)
|
||||
ax3.set_ylabel('储能容量 (MWh)')
|
||||
ax3.set_title('各场景储能容量需求对比')
|
||||
ax3.grid(True, alpha=0.3, axis='y')
|
||||
|
||||
# 添加数值标签
|
||||
for bar, capacity in zip(bars5, storage_capacities):
|
||||
height = bar.get_height()
|
||||
ax3.text(bar.get_x() + bar.get_width()/2., height + height*0.01,
|
||||
f'{capacity:.1f}', ha='center', va='bottom', fontweight='bold')
|
||||
|
||||
# 4. 弃风弃光率对比
|
||||
curtailment_winds = [r.storage_result['total_curtailment_wind_ratio'] for r in results]
|
||||
curtailment_solars = [r.storage_result['total_curtailment_solar_ratio'] for r in results]
|
||||
|
||||
bars6 = ax4.bar(x - width/2, curtailment_winds, width, label='弃风率', color='blue', alpha=0.7)
|
||||
bars7 = ax4.bar(x + width/2, curtailment_solars, width, label='弃光率', color='orange', alpha=0.7)
|
||||
|
||||
ax4.set_ylabel('弃风弃光率')
|
||||
ax4.set_title('各场景弃风弃光率对比')
|
||||
ax4.set_xticks(x)
|
||||
ax4.set_xticklabels(scenario_names)
|
||||
ax4.legend()
|
||||
ax4.grid(True, alpha=0.3, axis='y')
|
||||
|
||||
# 调整布局
|
||||
plt.tight_layout()
|
||||
|
||||
# 保存图片
|
||||
plt.savefig('solar_optimization_scenario_comparison.png', dpi=300, bbox_inches='tight')
|
||||
plt.close()
|
||||
|
||||
print("场景对比图表已保存为 'solar_optimization_scenario_comparison.png'")
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数,运行所有场景示例"""
|
||||
print("光伏优化模块场景示例")
|
||||
print("运行5个不同场景的优化分析...")
|
||||
|
||||
# 运行所有场景
|
||||
results = []
|
||||
|
||||
try:
|
||||
# 场景1:典型日场景
|
||||
result1 = scenario_1_typical_day()
|
||||
results.append(result1)
|
||||
|
||||
# 场景2:高负荷场景
|
||||
result2 = scenario_2_high_load()
|
||||
results.append(result2)
|
||||
|
||||
# 场景3:低负荷场景
|
||||
result3 = scenario_3_low_load()
|
||||
results.append(result3)
|
||||
|
||||
# 场景4:风光互补场景
|
||||
result4 = scenario_4_wind_solar_complement()
|
||||
results.append(result4)
|
||||
|
||||
# 场景5:储能受限场景
|
||||
result5 = scenario_5_storage_limited()
|
||||
results.append(result5)
|
||||
|
||||
# 对比分析
|
||||
compare_scenarios(results)
|
||||
|
||||
# 绘制对比图表
|
||||
plot_scenario_comparison(results)
|
||||
|
||||
print("\n" + "=" * 80)
|
||||
print("所有场景示例运行完成!")
|
||||
print("=" * 80)
|
||||
print("生成的文件:")
|
||||
print("- scenario_1_typical_day.xlsx")
|
||||
print("- scenario_2_high_load.xlsx")
|
||||
print("- scenario_3_low_load.xlsx")
|
||||
print("- scenario_4_wind_solar_complement.xlsx")
|
||||
print("- scenario_5_storage_limited.xlsx")
|
||||
print("- solar_optimization_scenario_comparison.png")
|
||||
|
||||
except Exception as e:
|
||||
print(f"运行场景示例时出错:{str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
419
scripts/solar_scenarios_demo.py
Normal file
419
scripts/solar_scenarios_demo.py
Normal file
@@ -0,0 +1,419 @@
|
||||
"""
|
||||
光伏优化模块场景演示
|
||||
|
||||
该文件展示了光伏优化模块在不同场景下的应用,包括:
|
||||
1. 典型日场景 - 基础优化示例
|
||||
2. 高负荷场景 - 夏季高峰用电场景
|
||||
3. 低负荷场景 - 春秋季低负荷场景
|
||||
4. 风光互补场景 - 风电和光伏协同优化
|
||||
5. 储能受限场景 - 储能容量受限情况下的优化
|
||||
|
||||
作者: iFlow CLI
|
||||
创建日期: 2025-12-26
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'src'))
|
||||
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from solar_optimization import optimize_solar_output, export_optimization_results
|
||||
from storage_optimization import SystemParameters
|
||||
|
||||
|
||||
def scenario_1_typical_day():
|
||||
"""场景1:典型日场景"""
|
||||
print("=" * 60)
|
||||
print("场景1:典型日场景 - 基础优化示例")
|
||||
print("=" * 60)
|
||||
|
||||
# 典型日数据(24小时)
|
||||
solar_output = [0.0] * 6 + [0.5, 1.0, 2.0, 3.5, 5.0, 6.0, 5.5, 4.0, 2.5, 1.0, 0.5, 0.0] + [0.0] * 6
|
||||
wind_output = [4.0, 5.0, 4.5, 3.5, 2.5, 2.0, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 2.0, 3.0, 4.0, 5.0, 4.5, 4.0, 3.5, 3.0, 2.5, 2.0, 1.5, 1.0]
|
||||
thermal_output = [8.0] * 24
|
||||
load_demand = [2.0, 2.5, 3.0, 4.0, 6.0, 9.0, 12.0, 15.0, 18.0, 20.0, 19.0, 18.0,
|
||||
17.0, 16.0, 18.0, 19.0, 20.0, 18.0, 15.0, 12.0, 8.0, 5.0, 3.0, 2.0]
|
||||
|
||||
# 系统参数
|
||||
params = SystemParameters(
|
||||
max_curtailment_wind=0.1,
|
||||
max_curtailment_solar=0.1,
|
||||
max_grid_ratio=0.15,
|
||||
storage_efficiency=0.9,
|
||||
discharge_rate=1.0,
|
||||
charge_rate=1.0,
|
||||
rated_thermal_capacity=100.0,
|
||||
rated_solar_capacity=50.0,
|
||||
rated_wind_capacity=50.0,
|
||||
available_thermal_energy=2000.0,
|
||||
available_solar_energy=400.0,
|
||||
available_wind_energy=600.0
|
||||
)
|
||||
|
||||
# 执行优化
|
||||
result = optimize_solar_output(solar_output, wind_output, thermal_output, load_demand, params)
|
||||
|
||||
# 输出结果
|
||||
print_scenario_result("典型日场景", result)
|
||||
|
||||
# 绘制光伏对比图
|
||||
plot_solar_comparison(result, "典型日场景")
|
||||
|
||||
# 导出结果
|
||||
export_optimization_results(result, "scenario_1_typical_day.xlsx")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def scenario_2_high_load():
|
||||
"""场景2:高负荷场景"""
|
||||
print("=" * 60)
|
||||
print("场景2:高负荷场景 - 夏季高峰用电")
|
||||
print("=" * 60)
|
||||
|
||||
# 夏季高负荷数据
|
||||
solar_output = [0.0] * 5 + [0.8, 1.5, 3.0, 4.5, 6.0, 7.5, 8.0, 7.0, 5.0, 3.0, 1.5, 0.5, 0.0, 0.0] + [0.0] * 5
|
||||
wind_output = [2.0, 2.5, 3.0, 2.5, 2.0, 1.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.5, 2.0, 2.5, 3.0, 2.5, 2.0, 1.8, 1.6, 1.4, 1.2, 1.0, 0.8]
|
||||
thermal_output = [12.0] * 24
|
||||
load_demand = [3.0, 3.5, 4.0, 5.0, 8.0, 12.0, 18.0, 25.0, 30.0, 32.0, 31.0, 30.0,
|
||||
29.0, 28.0, 30.0, 31.0, 32.0, 28.0, 22.0, 18.0, 12.0, 8.0, 5.0, 3.0]
|
||||
|
||||
# 高负荷场景参数
|
||||
params = SystemParameters(
|
||||
max_curtailment_wind=0.15,
|
||||
max_curtailment_solar=0.15,
|
||||
max_grid_ratio=0.25,
|
||||
storage_efficiency=0.85,
|
||||
discharge_rate=1.2,
|
||||
charge_rate=1.2,
|
||||
rated_thermal_capacity=150.0,
|
||||
rated_solar_capacity=80.0,
|
||||
rated_wind_capacity=40.0,
|
||||
available_thermal_energy=3000.0,
|
||||
available_solar_energy=600.0,
|
||||
available_wind_energy=400.0
|
||||
)
|
||||
|
||||
# 执行优化
|
||||
result = optimize_solar_output(solar_output, wind_output, thermal_output, load_demand, params)
|
||||
|
||||
# 输出结果
|
||||
print_scenario_result("高负荷场景", result)
|
||||
|
||||
# 绘制光伏对比图
|
||||
plot_solar_comparison(result, "高负荷场景")
|
||||
|
||||
# 导出结果
|
||||
export_optimization_results(result, "scenario_2_high_load.xlsx")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def scenario_3_low_load():
|
||||
"""场景3:低负荷场景"""
|
||||
print("=" * 60)
|
||||
print("场景3:低负荷场景 - 春秋季低负荷")
|
||||
print("=" * 60)
|
||||
|
||||
# 春秋季低负荷数据
|
||||
solar_output = [0.0] * 6 + [1.0, 2.0, 3.5, 5.0, 6.5, 7.0, 6.5, 5.0, 3.5, 2.0, 1.0, 0.0] + [0.0] * 6
|
||||
wind_output = [5.0, 6.0, 5.5, 4.5, 3.5, 3.0, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 3.0, 4.0, 5.0, 6.0, 5.5, 5.0, 4.5, 4.0, 3.5, 3.0, 2.5, 2.0]
|
||||
thermal_output = [5.0] * 24
|
||||
load_demand = [2.0, 2.2, 2.5, 3.0, 4.0, 6.0, 8.0, 10.0, 12.0, 13.0, 12.5, 12.0,
|
||||
11.5, 11.0, 12.0, 12.5, 13.0, 11.0, 9.0, 7.0, 5.0, 3.5, 2.5, 2.0]
|
||||
|
||||
# 低负荷场景参数
|
||||
params = SystemParameters(
|
||||
max_curtailment_wind=0.05,
|
||||
max_curtailment_solar=0.05,
|
||||
max_grid_ratio=0.1,
|
||||
storage_efficiency=0.92,
|
||||
discharge_rate=0.8,
|
||||
charge_rate=0.8,
|
||||
rated_thermal_capacity=80.0,
|
||||
rated_solar_capacity=60.0,
|
||||
rated_wind_capacity=60.0,
|
||||
available_thermal_energy=1500.0,
|
||||
available_solar_energy=500.0,
|
||||
available_wind_energy=700.0
|
||||
)
|
||||
|
||||
# 执行优化
|
||||
result = optimize_solar_output(solar_output, wind_output, thermal_output, load_demand, params)
|
||||
|
||||
# 输出结果
|
||||
print_scenario_result("低负荷场景", result)
|
||||
|
||||
# 绘制光伏对比图
|
||||
plot_solar_comparison(result, "低负荷场景")
|
||||
|
||||
# 导出结果
|
||||
export_optimization_results(result, "scenario_3_low_load.xlsx")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def scenario_4_wind_solar_complement():
|
||||
"""场景4:风光互补场景"""
|
||||
print("=" * 60)
|
||||
print("场景4:风光互补场景 - 风电和光伏协同优化")
|
||||
print("=" * 60)
|
||||
|
||||
# 风光互补数据
|
||||
solar_output = [0.0] * 6 + [0.5, 1.5, 3.0, 4.5, 6.0, 7.0, 6.0, 4.5, 3.0, 1.5, 0.5, 0.0] + [0.0] * 6
|
||||
wind_output = [8.0, 9.0, 8.5, 7.0, 5.0, 3.0, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 3.0, 5.0, 7.0, 8.0, 8.5, 8.0, 7.5, 7.0, 6.5, 6.0, 5.5, 5.0]
|
||||
thermal_output = [6.0] * 24
|
||||
load_demand = [4.0, 4.5, 5.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0, 17.0, 16.5, 16.0,
|
||||
15.5, 15.0, 16.0, 16.5, 17.0, 15.0, 13.0, 11.0, 9.0, 7.0, 5.0, 4.0]
|
||||
|
||||
# 风光互补场景参数
|
||||
params = SystemParameters(
|
||||
max_curtailment_wind=0.08,
|
||||
max_curtailment_solar=0.08,
|
||||
max_grid_ratio=0.12,
|
||||
storage_efficiency=0.9,
|
||||
discharge_rate=1.0,
|
||||
charge_rate=1.0,
|
||||
rated_thermal_capacity=100.0,
|
||||
rated_solar_capacity=70.0,
|
||||
rated_wind_capacity=70.0,
|
||||
available_thermal_energy=1800.0,
|
||||
available_solar_energy=450.0,
|
||||
available_wind_energy=800.0
|
||||
)
|
||||
|
||||
# 执行优化
|
||||
result = optimize_solar_output(solar_output, wind_output, thermal_output, load_demand, params)
|
||||
|
||||
# 输出结果
|
||||
print_scenario_result("风光互补场景", result)
|
||||
|
||||
# 绘制光伏对比图
|
||||
plot_solar_comparison(result, "风光互补场景")
|
||||
|
||||
# 导出结果
|
||||
export_optimization_results(result, "scenario_4_wind_solar_complement.xlsx")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def scenario_5_storage_limited():
|
||||
"""场景5:储能受限场景"""
|
||||
print("=" * 60)
|
||||
print("场景5:储能受限场景 - 储能容量受限情况下的优化")
|
||||
print("=" * 60)
|
||||
|
||||
# 储能受限数据
|
||||
solar_output = [0.0] * 6 + [1.0, 2.0, 3.0, 4.5, 6.0, 7.0, 6.0, 4.5, 3.0, 2.0, 1.0, 0.0] + [0.0] * 6
|
||||
wind_output = [3.0, 4.0, 3.5, 3.0, 2.5, 2.0, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 2.0, 3.0, 3.5, 4.0, 3.5, 3.0, 2.8, 2.6, 2.4, 2.2, 2.0, 1.8]
|
||||
thermal_output = [7.0] * 24
|
||||
load_demand = [3.0, 3.5, 4.0, 5.0, 7.0, 10.0, 13.0, 16.0, 18.0, 19.0, 18.5, 18.0,
|
||||
17.5, 17.0, 18.0, 18.5, 19.0, 17.0, 14.0, 11.0, 8.0, 6.0, 4.0, 3.0]
|
||||
|
||||
# 储能受限场景参数
|
||||
params = SystemParameters(
|
||||
max_curtailment_wind=0.12,
|
||||
max_curtailment_solar=0.12,
|
||||
max_grid_ratio=0.2,
|
||||
storage_efficiency=0.88,
|
||||
discharge_rate=1.5,
|
||||
charge_rate=1.5,
|
||||
max_storage_capacity=50.0, # 储能容量受限
|
||||
rated_thermal_capacity=100.0,
|
||||
rated_solar_capacity=60.0,
|
||||
rated_wind_capacity=50.0,
|
||||
available_thermal_energy=2000.0,
|
||||
available_solar_energy=480.0,
|
||||
available_wind_energy=550.0
|
||||
)
|
||||
|
||||
# 执行优化
|
||||
result = optimize_solar_output(solar_output, wind_output, thermal_output, load_demand, params)
|
||||
|
||||
# 输出结果
|
||||
print_scenario_result("储能受限场景", result)
|
||||
|
||||
# 绘制光伏对比图
|
||||
plot_solar_comparison(result, "储能受限场景")
|
||||
|
||||
# 导出结果
|
||||
export_optimization_results(result, "scenario_5_storage_limited.xlsx")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def print_scenario_result(scenario_name: str, result):
|
||||
"""打印场景优化结果"""
|
||||
print(f"\n=== {scenario_name}优化结果 ===")
|
||||
print(f"最优光伏系数: {result.optimal_solar_coefficient:.3f}")
|
||||
print(f"最小电网交换电量: {result.min_grid_exchange:.2f} MWh")
|
||||
print(f" - 购电量: {result.grid_purchase:.2f} MWh")
|
||||
print(f" - 上网电量: {result.grid_feed_in:.2f} MWh")
|
||||
print(f"所需储能容量: {result.storage_result['required_storage_capacity']:.2f} MWh")
|
||||
print(f"优化后弃风率: {result.storage_result['total_curtailment_wind_ratio']:.3f}")
|
||||
print(f"优化后弃光率: {result.storage_result['total_curtailment_solar_ratio']:.3f}")
|
||||
print(f"优化后上网电量比例: {result.storage_result['total_grid_feed_in_ratio']:.3f}")
|
||||
|
||||
# 分析优化效果
|
||||
if result.optimal_solar_coefficient > 1.0:
|
||||
print(f"分析:建议将光伏出力提高 {(result.optimal_solar_coefficient - 1.0) * 100:.1f}% 以减少电网依赖")
|
||||
elif result.optimal_solar_coefficient < 1.0:
|
||||
print(f"分析:建议将光伏出力降低 {(1.0 - result.optimal_solar_coefficient) * 100:.1f}% 以避免电力过剩")
|
||||
else:
|
||||
print("分析:当前光伏出力已经是最优配置")
|
||||
|
||||
|
||||
def plot_solar_comparison(result, scenario_name, show_window=True):
|
||||
"""
|
||||
绘制光伏出力对比图
|
||||
|
||||
Args:
|
||||
result: 光伏优化结果
|
||||
scenario_name: 场景名称
|
||||
show_window: 是否显示图形窗口
|
||||
"""
|
||||
# 设置中文字体
|
||||
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'DejaVu Sans']
|
||||
plt.rcParams['axes.unicode_minus'] = False
|
||||
|
||||
hours = list(range(len(result.original_solar_output)))
|
||||
|
||||
# 创建图形
|
||||
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8))
|
||||
fig.suptitle(f'{scenario_name} - 光伏优化结果 (系数: {result.optimal_solar_coefficient:.3f})',
|
||||
fontsize=14, fontweight='bold')
|
||||
|
||||
# === 第一个子图:光伏出力对比 ===
|
||||
ax1.plot(hours, result.original_solar_output, 'b-', linewidth=2,
|
||||
label='原始光伏出力', alpha=0.7)
|
||||
ax1.plot(hours, result.optimized_solar_output, 'r-', linewidth=2,
|
||||
label=f'优化后光伏出力')
|
||||
|
||||
ax1.set_xlabel('时间 (小时)')
|
||||
ax1.set_ylabel('功率 (MW)')
|
||||
ax1.set_title('光伏出力曲线对比')
|
||||
ax1.legend(loc='upper right')
|
||||
ax1.grid(True, alpha=0.3)
|
||||
ax1.set_xlim(0, max(hours))
|
||||
|
||||
# === 第二个子图:电网交换电量组成 ===
|
||||
categories = ['购电量', '上网电量']
|
||||
values = [result.grid_purchase, result.grid_feed_in]
|
||||
colors = ['purple', 'brown']
|
||||
|
||||
bars = ax2.bar(categories, values, color=colors, alpha=0.7)
|
||||
ax2.set_ylabel('电量 (MWh)')
|
||||
ax2.set_title(f'电网交换电量组成 (总计: {result.min_grid_exchange:.2f} MWh)')
|
||||
ax2.grid(True, alpha=0.3, axis='y')
|
||||
|
||||
# 在柱状图上添加数值标签
|
||||
for bar, value in zip(bars, values):
|
||||
height = bar.get_height()
|
||||
ax2.text(bar.get_x() + bar.get_width()/2., height + height*0.01,
|
||||
f'{value:.2f}', ha='center', va='bottom', fontweight='bold')
|
||||
|
||||
# 调整布局
|
||||
plt.tight_layout()
|
||||
|
||||
# 根据参数决定是否显示图形窗口
|
||||
if show_window:
|
||||
try:
|
||||
plt.show()
|
||||
except Exception as e:
|
||||
print(f"无法显示图形窗口:{str(e)}")
|
||||
else:
|
||||
plt.close()
|
||||
|
||||
|
||||
def compare_scenarios(results):
|
||||
"""对比不同场景的优化结果"""
|
||||
print("\n" + "=" * 80)
|
||||
print("场景对比分析")
|
||||
print("=" * 80)
|
||||
|
||||
scenario_names = [
|
||||
"典型日场景",
|
||||
"高负荷场景",
|
||||
"低负荷场景",
|
||||
"风光互补场景",
|
||||
"储能受限场景"
|
||||
]
|
||||
|
||||
# 创建对比表格
|
||||
print(f"{'场景名称':<12} {'最优系数':<8} {'电网交换(MWh)':<12} {'购电量(MWh)':<10} {'上网电量(MWh)':<12} {'储能容量(MWh)':<12}")
|
||||
print("-" * 80)
|
||||
|
||||
for i, (name, result) in enumerate(zip(scenario_names, results)):
|
||||
print(f"{name:<12} {result.optimal_solar_coefficient:<8.3f} "
|
||||
f"{result.min_grid_exchange:<12.2f} {result.grid_purchase:<10.2f} "
|
||||
f"{result.grid_feed_in:<12.2f} {result.storage_result['required_storage_capacity']:<12.2f}")
|
||||
|
||||
# 分析趋势
|
||||
print("\n=== 趋势分析 ===")
|
||||
|
||||
# 找出最优和最差场景
|
||||
min_exchange_result = min(results, key=lambda x: x.min_grid_exchange)
|
||||
max_exchange_result = max(results, key=lambda x: x.min_grid_exchange)
|
||||
|
||||
min_exchange_idx = results.index(min_exchange_result)
|
||||
max_exchange_idx = results.index(max_exchange_result)
|
||||
|
||||
print(f"电网交换最小场景:{scenario_names[min_exchange_idx]} ({min_exchange_result.min_grid_exchange:.2f} MWh)")
|
||||
print(f"电网交换最大场景:{scenario_names[max_exchange_idx]} ({max_exchange_result.min_grid_exchange:.2f} MWh)")
|
||||
|
||||
# 分析光伏系数趋势
|
||||
avg_coefficient = sum(r.optimal_solar_coefficient for r in results) / len(results)
|
||||
print(f"平均最优光伏系数:{avg_coefficient:.3f}")
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数,运行所有场景示例"""
|
||||
print("光伏优化模块场景演示")
|
||||
print("运行5个不同场景的优化分析...")
|
||||
|
||||
# 运行所有场景
|
||||
results = []
|
||||
|
||||
try:
|
||||
# 场景1:典型日场景
|
||||
result1 = scenario_1_typical_day()
|
||||
results.append(result1)
|
||||
|
||||
# 场景2:高负荷场景
|
||||
result2 = scenario_2_high_load()
|
||||
results.append(result2)
|
||||
|
||||
# 场景3:低负荷场景
|
||||
result3 = scenario_3_low_load()
|
||||
results.append(result3)
|
||||
|
||||
# 场景4:风光互补场景
|
||||
result4 = scenario_4_wind_solar_complement()
|
||||
results.append(result4)
|
||||
|
||||
# 场景5:储能受限场景
|
||||
result5 = scenario_5_storage_limited()
|
||||
results.append(result5)
|
||||
|
||||
# 对比分析
|
||||
compare_scenarios(results)
|
||||
|
||||
print("\n" + "=" * 80)
|
||||
print("所有场景演示完成!")
|
||||
print("=" * 80)
|
||||
print("生成的文件:")
|
||||
print("- scenario_1_typical_day.xlsx")
|
||||
print("- scenario_2_high_load.xlsx")
|
||||
print("- scenario_3_low_load.xlsx")
|
||||
print("- scenario_4_wind_solar_complement.xlsx")
|
||||
print("- scenario_5_storage_limited.xlsx")
|
||||
|
||||
except Exception as e:
|
||||
print(f"运行场景演示时出错:{str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user