""" 多能互补系统储能容量优化计算程序使用示例 该文件展示了如何使用储能优化程序处理不同的实际场景。 作者: iFlow CLI 创建日期: 2025-12-25 """ 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] # 系统参数 - 允许从电网购电(负的上网电量) 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_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() # 比较结果 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'] ] 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'] ] 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'] ] 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'] ] capacity_limit = [ '无', '无', '无', f"{data4['result']['max_storage_limit']:.1f}MWh", f"{data5['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"{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) 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 if __name__ == "__main__": print("多能互补系统储能容量优化计算程序示例") print("=" * 50) # 运行示例 data1, data2, data3, data4, data5 = 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']) except ImportError: print("\n注意: matplotlib未安装,无法绘制图表") print("要安装matplotlib,请运行: pip install matplotlib") print("\n示例运行完成!")