删除max_grid_feed_in_ratio_absolute变量。
This commit is contained in:
@@ -262,11 +262,11 @@ def example_5_high_load_grid_purchase_scenario():
|
|||||||
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,
|
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]
|
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(
|
params = SystemParameters(
|
||||||
max_curtailment_wind=0.05, # 严格的弃风控制
|
max_curtailment_wind=0.05, # 严格的弃风控制
|
||||||
max_curtailment_solar=0.02, # 严格的弃光控制
|
max_curtailment_solar=0.02, # 严格的弃光控制
|
||||||
max_grid_ratio=-0.3, # 负值表示允许从电网购电,最大购电比例30%
|
max_grid_ratio=0.3, # 上网电量比例限制为30%,但不限制购电
|
||||||
storage_efficiency=0.9, # 储能效率90%
|
storage_efficiency=0.9, # 储能效率90%
|
||||||
discharge_rate=2.0, # 2C放电,满足高峰需求
|
discharge_rate=2.0, # 2C放电,满足高峰需求
|
||||||
charge_rate=1.0, # 1C充电
|
charge_rate=1.0, # 1C充电
|
||||||
@@ -280,7 +280,7 @@ def example_5_high_load_grid_purchase_scenario():
|
|||||||
print(f"是否达到容量上限: {'是' if result['capacity_limit_reached'] else '否'}")
|
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_wind_ratio']:.3f} (约束: {params.max_curtailment_wind})")
|
||||||
print(f"实际弃光率: {result['total_curtailment_solar_ratio']:.3f} (约束: {params.max_curtailment_solar})")
|
print(f"实际弃光率: {result['total_curtailment_solar_ratio']:.3f} (约束: {params.max_curtailment_solar})")
|
||||||
print(f"实际上网电量比例: {result['total_grid_feed_in_ratio']:.3f} (负值表示购电)")
|
print(f"实际上网电量比例: {result['total_grid_feed_in_ratio']:.3f} (负值表示购电,正值表示上网)")
|
||||||
print(f"能量平衡校验: {'通过' if result['energy_balance_check'] else '未通过'}")
|
print(f"能量平衡校验: {'通过' if result['energy_balance_check'] else '未通过'}")
|
||||||
|
|
||||||
# 调试信息
|
# 调试信息
|
||||||
@@ -332,6 +332,56 @@ def example_5_high_load_grid_purchase_scenario():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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():
|
def example_4_capacity_limited_scenario():
|
||||||
"""示例4: 储能容量限制场景"""
|
"""示例4: 储能容量限制场景"""
|
||||||
print("\n=== 示例4: 储能容量限制场景 ===")
|
print("\n=== 示例4: 储能容量限制场景 ===")
|
||||||
@@ -382,61 +432,67 @@ def compare_scenarios():
|
|||||||
"""比较不同场景的结果"""
|
"""比较不同场景的结果"""
|
||||||
print("\n=== 场景比较 ===")
|
print("\n=== 场景比较 ===")
|
||||||
|
|
||||||
# 运行五个场景
|
# 运行六个场景
|
||||||
data1 = example_1_basic_scenario()
|
data1 = example_1_basic_scenario()
|
||||||
data2 = example_2_high_renewable_scenario()
|
data2 = example_2_high_renewable_scenario()
|
||||||
data3 = example_3_winter_scenario()
|
data3 = example_3_winter_scenario()
|
||||||
data4 = example_4_capacity_limited_scenario()
|
data4 = example_4_capacity_limited_scenario()
|
||||||
data5 = example_5_high_load_grid_purchase_scenario()
|
data5 = example_5_high_load_grid_purchase_scenario()
|
||||||
|
data6 = example_6_grid_ratio_limited_scenario()
|
||||||
|
|
||||||
# 比较结果
|
# 比较结果
|
||||||
scenarios = ['基础场景', '高可再生能源场景', '冬季场景', '容量限制场景', '高负荷购电场景']
|
scenarios = ['基础场景', '高可再生能源场景', '冬季场景', '容量限制场景', '高负荷购电场景', '上网电量比例限制场景']
|
||||||
storage_capacities = [
|
storage_capacities = [
|
||||||
data1['result']['required_storage_capacity'],
|
data1['result']['required_storage_capacity'],
|
||||||
data2['result']['required_storage_capacity'],
|
data2['result']['required_storage_capacity'],
|
||||||
data3['result']['required_storage_capacity'],
|
data3['result']['required_storage_capacity'],
|
||||||
data4['result']['required_storage_capacity'],
|
data4['result']['required_storage_capacity'],
|
||||||
data5['result']['required_storage_capacity']
|
data5['result']['required_storage_capacity'],
|
||||||
|
data6['result']['required_storage_capacity']
|
||||||
]
|
]
|
||||||
curtailment_wind = [
|
curtailment_wind = [
|
||||||
data1['result']['total_curtailment_wind_ratio'],
|
data1['result']['total_curtailment_wind_ratio'],
|
||||||
data2['result']['total_curtailment_wind_ratio'],
|
data2['result']['total_curtailment_wind_ratio'],
|
||||||
data3['result']['total_curtailment_wind_ratio'],
|
data3['result']['total_curtailment_wind_ratio'],
|
||||||
data4['result']['total_curtailment_wind_ratio'],
|
data4['result']['total_curtailment_wind_ratio'],
|
||||||
data5['result']['total_curtailment_wind_ratio']
|
data5['result']['total_curtailment_wind_ratio'],
|
||||||
|
data6['result']['total_curtailment_wind_ratio']
|
||||||
]
|
]
|
||||||
curtailment_solar = [
|
curtailment_solar = [
|
||||||
data1['result']['total_curtailment_solar_ratio'],
|
data1['result']['total_curtailment_solar_ratio'],
|
||||||
data2['result']['total_curtailment_solar_ratio'],
|
data2['result']['total_curtailment_solar_ratio'],
|
||||||
data3['result']['total_curtailment_solar_ratio'],
|
data3['result']['total_curtailment_solar_ratio'],
|
||||||
data4['result']['total_curtailment_solar_ratio'],
|
data4['result']['total_curtailment_solar_ratio'],
|
||||||
data5['result']['total_curtailment_solar_ratio']
|
data5['result']['total_curtailment_solar_ratio'],
|
||||||
|
data6['result']['total_curtailment_solar_ratio']
|
||||||
]
|
]
|
||||||
grid_feed_in = [
|
grid_feed_in = [
|
||||||
data1['result']['total_grid_feed_in_ratio'],
|
data1['result']['total_grid_feed_in_ratio'],
|
||||||
data2['result']['total_grid_feed_in_ratio'],
|
data2['result']['total_grid_feed_in_ratio'],
|
||||||
data3['result']['total_grid_feed_in_ratio'],
|
data3['result']['total_grid_feed_in_ratio'],
|
||||||
data4['result']['total_grid_feed_in_ratio'],
|
data4['result']['total_grid_feed_in_ratio'],
|
||||||
data5['result']['total_grid_feed_in_ratio']
|
data5['result']['total_grid_feed_in_ratio'],
|
||||||
|
data6['result']['total_grid_feed_in_ratio']
|
||||||
]
|
]
|
||||||
capacity_limit = [
|
capacity_limit = [
|
||||||
'无',
|
'无',
|
||||||
'无',
|
'无',
|
||||||
'无',
|
'无',
|
||||||
f"{data4['result']['max_storage_limit']:.1f}MWh",
|
f"{data4['result']['max_storage_limit']:.1f}MWh",
|
||||||
f"{data5['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("\n场景比较结果:")
|
||||||
print(f"{'场景':<15} {'储能容量(MWh)':<12} {'容量限制':<10} {'弃风率':<8} {'弃光率':<8} {'上网/购电':<8}")
|
print(f"{'场景':<15} {'储能容量(MWh)':<12} {'容量限制':<10} {'弃风率':<8} {'弃光率':<8} {'上网比例':<8}")
|
||||||
print("-" * 80)
|
print("-" * 80)
|
||||||
for i, scenario in enumerate(scenarios):
|
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}↓"
|
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) else ""
|
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} "
|
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}")
|
f"{curtailment_solar[i]:<8.3f} {grid_text:<8} {limit_reached}")
|
||||||
|
|
||||||
return data1, data2, data3, data4, data5
|
return data1, data2, data3, data4, data5, data6
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
@@ -444,7 +500,7 @@ if __name__ == "__main__":
|
|||||||
print("=" * 50)
|
print("=" * 50)
|
||||||
|
|
||||||
# 运行示例
|
# 运行示例
|
||||||
data1, data2, data3, data4, data5 = compare_scenarios()
|
data1, data2, data3, data4, data5, data6 = compare_scenarios()
|
||||||
|
|
||||||
# 绘制图表(如果matplotlib可用)
|
# 绘制图表(如果matplotlib可用)
|
||||||
try:
|
try:
|
||||||
@@ -463,6 +519,9 @@ if __name__ == "__main__":
|
|||||||
plot_results(data5['result'], "高负荷购电场景储能运行情况",
|
plot_results(data5['result'], "高负荷购电场景储能运行情况",
|
||||||
data5['solar_output'], data5['wind_output'],
|
data5['solar_output'], data5['wind_output'],
|
||||||
data5['thermal_output'], data5['load_demand'])
|
data5['thermal_output'], data5['load_demand'])
|
||||||
|
plot_results(data6['result'], "上网电量比例限制场景储能运行情况",
|
||||||
|
data6['solar_output'], data6['wind_output'],
|
||||||
|
data6['thermal_output'], data6['load_demand'])
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print("\n注意: matplotlib未安装,无法绘制图表")
|
print("\n注意: matplotlib未安装,无法绘制图表")
|
||||||
print("要安装matplotlib,请运行: pip install matplotlib")
|
print("要安装matplotlib,请运行: pip install matplotlib")
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class SystemParameters:
|
|||||||
"""系统参数配置类"""
|
"""系统参数配置类"""
|
||||||
max_curtailment_wind: float = 0.1 # 最大允许弃风率 (0.0-1.0)
|
max_curtailment_wind: float = 0.1 # 最大允许弃风率 (0.0-1.0)
|
||||||
max_curtailment_solar: float = 0.1 # 最大允许弃光率 (0.0-1.0)
|
max_curtailment_solar: float = 0.1 # 最大允许弃光率 (0.0-1.0)
|
||||||
max_grid_ratio: float = 0.2 # 最大允许上网电量比例 (0.0-1.0)
|
max_grid_ratio: float = 0.2 # 最大允许上网电量比例 (0.0-∞,只限制上网电量,不限制购电)
|
||||||
storage_efficiency: float = 0.9 # 储能充放电效率 (0.0-1.0)
|
storage_efficiency: float = 0.9 # 储能充放电效率 (0.0-1.0)
|
||||||
discharge_rate: float = 1.0 # 储能放电倍率 (C-rate)
|
discharge_rate: float = 1.0 # 储能放电倍率 (C-rate)
|
||||||
charge_rate: float = 1.0 # 储能充电倍率 (C-rate)
|
charge_rate: float = 1.0 # 储能充电倍率 (C-rate)
|
||||||
@@ -70,8 +70,9 @@ def validate_inputs(
|
|||||||
raise ValueError("弃风率必须在0.0-1.0之间")
|
raise ValueError("弃风率必须在0.0-1.0之间")
|
||||||
if not (0.0 <= params.max_curtailment_solar <= 1.0):
|
if not (0.0 <= params.max_curtailment_solar <= 1.0):
|
||||||
raise ValueError("弃光率必须在0.0-1.0之间")
|
raise ValueError("弃光率必须在0.0-1.0之间")
|
||||||
if not (-1.0 <= params.max_grid_ratio <= 1.0):
|
# max_grid_ratio只限制上网电量比例,必须为非负值
|
||||||
raise ValueError("上网电量比例必须在-1.0到1.0之间(负值表示购电)")
|
if not (0.0 <= params.max_grid_ratio):
|
||||||
|
raise ValueError("上网电量比例限制必须为非负值")
|
||||||
if not (0.0 < params.storage_efficiency <= 1.0):
|
if not (0.0 < params.storage_efficiency <= 1.0):
|
||||||
raise ValueError("储能效率必须在0.0-1.0之间")
|
raise ValueError("储能效率必须在0.0-1.0之间")
|
||||||
if params.discharge_rate <= 0 or params.charge_rate <= 0:
|
if params.discharge_rate <= 0 or params.charge_rate <= 0:
|
||||||
@@ -212,16 +213,10 @@ def calculate_energy_balance(
|
|||||||
# 计算剩余缺电,需要从电网购电
|
# 计算剩余缺电,需要从电网购电
|
||||||
remaining_deficit = power_deficit - actual_discharge
|
remaining_deficit = power_deficit - actual_discharge
|
||||||
|
|
||||||
# 如果还有缺电且允许购电,则从电网购电
|
# 如果还有缺电,从电网购电
|
||||||
if remaining_deficit > 0:
|
if remaining_deficit > 0:
|
||||||
# 检查是否允许购电(max_grid_ratio为负值)
|
# 购电功率为负值,表示从电网输入
|
||||||
if params.max_grid_ratio < 0:
|
grid_feed_in[hour] = -remaining_deficit
|
||||||
# 购电功率为负值,表示从电网输入
|
|
||||||
grid_feed_in[hour] = -remaining_deficit
|
|
||||||
else:
|
|
||||||
# 不允许购电,缺电部分无法满足
|
|
||||||
# 在实际系统中可能需要削减负荷
|
|
||||||
grid_feed_in[hour] = 0 # 不购电
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'storage_profile': storage_soc.tolist(),
|
'storage_profile': storage_soc.tolist(),
|
||||||
@@ -333,12 +328,15 @@ def optimize_storage_capacity(
|
|||||||
constraint_results = check_constraints(solar_output, wind_output, thermal_output, balance_result, params)
|
constraint_results = check_constraints(solar_output, wind_output, thermal_output, balance_result, params)
|
||||||
|
|
||||||
# 检查是否满足所有约束
|
# 检查是否满足所有约束
|
||||||
# 对于负的max_grid_ratio(购电约束),实际grid_feed_in_ratio应该大于等于约束值
|
# max_grid_ratio只限制上网电量比例,不约束购电
|
||||||
grid_constraint_satisfied = (
|
# 只有当grid_feed_in为正时(上网)才需要检查约束
|
||||||
constraint_results['total_grid_feed_in_ratio'] <= params.max_grid_ratio
|
total_grid_feed_in = sum(balance_result['grid_feed_in'])
|
||||||
if params.max_grid_ratio >= 0
|
if total_grid_feed_in > 0:
|
||||||
else constraint_results['total_grid_feed_in_ratio'] >= params.max_grid_ratio
|
# 有上网电量,检查是否超过限制
|
||||||
)
|
grid_constraint_satisfied = constraint_results['total_grid_feed_in_ratio'] <= params.max_grid_ratio
|
||||||
|
else:
|
||||||
|
# 没有上网电量或为负值(购电),总是满足约束
|
||||||
|
grid_constraint_satisfied = True
|
||||||
|
|
||||||
constraints_satisfied = (
|
constraints_satisfied = (
|
||||||
constraint_results['total_curtailment_wind_ratio'] <= params.max_curtailment_wind and
|
constraint_results['total_curtailment_wind_ratio'] <= params.max_curtailment_wind and
|
||||||
|
|||||||
Reference in New Issue
Block a user