420 lines
15 KiB
Python
420 lines
15 KiB
Python
"""
|
||
光伏优化模块场景演示
|
||
|
||
该文件展示了光伏优化模块在不同场景下的应用,包括:
|
||
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()
|