考虑了储能上限。
This commit is contained in:
@@ -230,46 +230,104 @@ def plot_results(result, title, solar_output, wind_output, thermal_output, load_
|
|||||||
plt.show()
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
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():
|
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()
|
||||||
|
|
||||||
# 比较结果
|
# 比较结果
|
||||||
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']
|
||||||
]
|
]
|
||||||
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']
|
||||||
]
|
]
|
||||||
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']
|
||||||
]
|
]
|
||||||
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']
|
||||||
|
]
|
||||||
|
capacity_limit = [
|
||||||
|
'无',
|
||||||
|
'无',
|
||||||
|
'无',
|
||||||
|
f"{data4['result']['max_storage_limit']:.1f}MWh"
|
||||||
]
|
]
|
||||||
|
|
||||||
print("\n场景比较结果:")
|
print("\n场景比较结果:")
|
||||||
print(f"{'场景':<15} {'储能容量(MWh)':<12} {'弃风率':<8} {'弃光率':<8} {'上网比例':<8}")
|
print(f"{'场景':<15} {'储能容量(MWh)':<12} {'容量限制':<10} {'弃风率':<8} {'弃光率':<8} {'上网比例':<8}")
|
||||||
print("-" * 55)
|
print("-" * 75)
|
||||||
for i, scenario in enumerate(scenarios):
|
for i, scenario in enumerate(scenarios):
|
||||||
print(f"{scenario:<15} {storage_capacities[i]:<12.2f} {curtailment_wind[i]:<8.3f} "
|
limit_reached = "✓" if data4['result']['capacity_limit_reached'] and i == 3 else ""
|
||||||
f"{curtailment_solar[i]:<8.3f} {grid_feed_in[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_feed_in[i]:<8.3f} {limit_reached}")
|
||||||
|
|
||||||
return data1, data2, data3
|
return data1, data2, data3, data4
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
@@ -277,7 +335,7 @@ if __name__ == "__main__":
|
|||||||
print("=" * 50)
|
print("=" * 50)
|
||||||
|
|
||||||
# 运行示例
|
# 运行示例
|
||||||
data1, data2, data3 = compare_scenarios()
|
data1, data2, data3, data4 = compare_scenarios()
|
||||||
|
|
||||||
# 绘制图表(如果matplotlib可用)
|
# 绘制图表(如果matplotlib可用)
|
||||||
try:
|
try:
|
||||||
@@ -290,6 +348,9 @@ if __name__ == "__main__":
|
|||||||
plot_results(data3['result'], "冬季场景储能运行情况",
|
plot_results(data3['result'], "冬季场景储能运行情况",
|
||||||
data3['solar_output'], data3['wind_output'],
|
data3['solar_output'], data3['wind_output'],
|
||||||
data3['thermal_output'], data3['load_demand'])
|
data3['thermal_output'], data3['load_demand'])
|
||||||
|
plot_results(data4['result'], "容量限制场景储能运行情况",
|
||||||
|
data4['solar_output'], data4['wind_output'],
|
||||||
|
data4['thermal_output'], data4['load_demand'])
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print("\n注意: matplotlib未安装,无法绘制图表")
|
print("\n注意: matplotlib未安装,无法绘制图表")
|
||||||
print("要安装matplotlib,请运行: pip install matplotlib")
|
print("要安装matplotlib,请运行: pip install matplotlib")
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ class SystemParameters:
|
|||||||
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)
|
||||||
|
max_storage_capacity: Optional[float] = None # 储能容量上限 (MWh),None表示无限制
|
||||||
|
|
||||||
|
|
||||||
def validate_inputs(
|
def validate_inputs(
|
||||||
@@ -75,6 +76,8 @@ def validate_inputs(
|
|||||||
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:
|
||||||
raise ValueError("充放电倍率必须大于0")
|
raise ValueError("充放电倍率必须大于0")
|
||||||
|
if params.max_storage_capacity is not None and params.max_storage_capacity <= 0:
|
||||||
|
raise ValueError("储能容量上限必须大于0")
|
||||||
|
|
||||||
|
|
||||||
def calculate_energy_balance(
|
def calculate_energy_balance(
|
||||||
@@ -293,11 +296,18 @@ def optimize_storage_capacity(
|
|||||||
|
|
||||||
# 初始化搜索范围
|
# 初始化搜索范围
|
||||||
lower_bound = 0.0
|
lower_bound = 0.0
|
||||||
upper_bound = max(sum(solar_output) + sum(wind_output) + sum(thermal_output), sum(load_demand))
|
theoretical_max = max(sum(solar_output) + sum(wind_output) + sum(thermal_output), sum(load_demand))
|
||||||
|
|
||||||
|
# 应用储能容量上限限制
|
||||||
|
if params.max_storage_capacity is not None:
|
||||||
|
upper_bound = min(theoretical_max, params.max_storage_capacity)
|
||||||
|
else:
|
||||||
|
upper_bound = theoretical_max
|
||||||
|
|
||||||
# 二分搜索寻找最小储能容量
|
# 二分搜索寻找最小储能容量
|
||||||
best_capacity = upper_bound
|
best_capacity = upper_bound
|
||||||
best_result = None
|
best_result = None
|
||||||
|
solution_found = False # 标记是否找到可行解
|
||||||
|
|
||||||
for iteration in range(max_iterations):
|
for iteration in range(max_iterations):
|
||||||
mid_capacity = (lower_bound + upper_bound) / 2
|
mid_capacity = (lower_bound + upper_bound) / 2
|
||||||
@@ -326,6 +336,7 @@ def optimize_storage_capacity(
|
|||||||
# 满足条件,尝试减小容量
|
# 满足条件,尝试减小容量
|
||||||
best_capacity = mid_capacity
|
best_capacity = mid_capacity
|
||||||
best_result = {**balance_result, **constraint_results}
|
best_result = {**balance_result, **constraint_results}
|
||||||
|
solution_found = True
|
||||||
upper_bound = mid_capacity
|
upper_bound = mid_capacity
|
||||||
else:
|
else:
|
||||||
# 不满足条件,增大容量
|
# 不满足条件,增大容量
|
||||||
@@ -335,8 +346,20 @@ def optimize_storage_capacity(
|
|||||||
if upper_bound - lower_bound < tolerance:
|
if upper_bound - lower_bound < tolerance:
|
||||||
break
|
break
|
||||||
|
|
||||||
# 如果没有找到可行解,使用最大容量
|
# 处理储能容量上限限制的情况
|
||||||
if best_result is None:
|
if not solution_found and params.max_storage_capacity is not None:
|
||||||
|
print(f"警告:在储能容量上限 {params.max_storage_capacity:.2f} MWh 内无法找到满足所有约束的解")
|
||||||
|
print("使用最大允许容量进行计算,但某些约束条件可能无法满足")
|
||||||
|
|
||||||
|
# 使用最大允许容量计算结果
|
||||||
|
balance_result = calculate_energy_balance(
|
||||||
|
solar_output, wind_output, thermal_output, load_demand, params, params.max_storage_capacity
|
||||||
|
)
|
||||||
|
constraint_results = check_constraints(solar_output, wind_output, thermal_output, balance_result, params)
|
||||||
|
best_result = {**balance_result, **constraint_results}
|
||||||
|
best_capacity = params.max_storage_capacity
|
||||||
|
elif best_result is None:
|
||||||
|
# 如果没有找到可行解(且没有容量上限限制),使用最大容量
|
||||||
balance_result = calculate_energy_balance(
|
balance_result = calculate_energy_balance(
|
||||||
solar_output, wind_output, thermal_output, load_demand, params, upper_bound
|
solar_output, wind_output, thermal_output, load_demand, params, upper_bound
|
||||||
)
|
)
|
||||||
@@ -380,7 +403,10 @@ def optimize_storage_capacity(
|
|||||||
'total_curtailment_wind_ratio': best_result['total_curtailment_wind_ratio'],
|
'total_curtailment_wind_ratio': best_result['total_curtailment_wind_ratio'],
|
||||||
'total_curtailment_solar_ratio': best_result['total_curtailment_solar_ratio'],
|
'total_curtailment_solar_ratio': best_result['total_curtailment_solar_ratio'],
|
||||||
'total_grid_feed_in_ratio': best_result['total_grid_feed_in_ratio'],
|
'total_grid_feed_in_ratio': best_result['total_grid_feed_in_ratio'],
|
||||||
'energy_balance_check': energy_balance_check
|
'energy_balance_check': energy_balance_check,
|
||||||
|
'capacity_limit_reached': params.max_storage_capacity is not None and best_capacity >= params.max_storage_capacity,
|
||||||
|
'theoretical_optimal_capacity': best_capacity if solution_found else None,
|
||||||
|
'max_storage_limit': params.max_storage_capacity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user