修复了逻辑,优先弃光,当达到最大弃光比例后,再弃风。

This commit is contained in:
dmy
2025-12-27 16:30:50 +08:00
parent 25fc0b33aa
commit 4dbe3d5083

View File

@@ -145,28 +145,11 @@ def calculate_energy_balance(
# 设置初始储能状态 # 设置初始储能状态
storage_soc[0] = initial_soc storage_soc[0] = initial_soc
# 计算总发电潜力
total_potential_wind = np.sum(wind)
total_potential_solar = np.sum(solar)
# 判断是否只有一种可再生能源
has_wind = total_potential_wind > 0
has_solar = total_potential_solar > 0
single_renewable = (has_wind and not has_solar) or (has_solar and not has_wind)
# 计算允许的最大弃风弃光量 # 计算允许的最大弃风弃光量
if single_renewable: # 新逻辑:弃光受最大弃光比例限制,弃风不受限制
# 只有一种可再生能源时,弃电量不受限制 total_solar_potential = sum(solar_output)
max_curtailed_wind_total = float('inf') max_curtailed_solar_total = total_solar_potential * params.max_curtailment_solar
max_curtailed_solar_total = float('inf') max_curtailed_wind_total = float('inf') # 弃风不受限制
elif params.max_grid_ratio == 0:
# 上网电量限制为0时所有超额电力都必须被弃掉不受弃风弃光限制
max_curtailed_wind_total = float('inf')
max_curtailed_solar_total = float('inf')
else:
# 有多种可再生能源且上网电量限制不为0时应用弃风弃光限制
max_curtailed_wind_total = total_potential_wind * params.max_curtailment_wind
max_curtailed_solar_total = total_potential_solar * params.max_curtailment_solar
# 初始化累计弃风弃光量 # 初始化累计弃风弃光量
accumulated_curtailed_wind = 0.0 accumulated_curtailed_wind = 0.0
@@ -224,55 +207,24 @@ def calculate_energy_balance(
# 剩余电力考虑弃风弃光 # 剩余电力考虑弃风弃光
remaining_surplus -= grid_feed_allowed remaining_surplus -= grid_feed_allowed
# 计算弃风弃光(优先弃光,然后弃风 # 计算弃风弃光(新逻辑:先弃光,当达到最大弃光比例后,再弃风,弃风不限
if remaining_surplus > 0: if remaining_surplus > 0:
# 在单一可再生能源场景下,弃风弃光不受限制 # 计算当前还能弃光的量
if single_renewable: remaining_solar_curtailment_quota = max_curtailed_solar_total - accumulated_curtailed_solar
# 优先弃光
if solar[hour] > 0:
curtailed_solar[hour] = min(solar[hour], remaining_surplus)
remaining_surplus -= curtailed_solar[hour]
accumulated_curtailed_solar += curtailed_solar[hour]
# 如果还有剩余,弃风 # 优先弃光,但不超过最大弃光比例
if remaining_surplus > 0 and wind[hour] > 0: if solar[hour] > 0 and remaining_solar_curtailment_quota > 0:
curtailed_wind[hour] = min(wind[hour], remaining_surplus) # 可以弃光的量取:光伏出力、剩余盈余电力、剩余弃光配额的最小值
remaining_surplus -= curtailed_wind[hour] curtailed_solar[hour] = min(solar[hour], remaining_surplus, remaining_solar_curtailment_quota)
accumulated_curtailed_wind += curtailed_wind[hour] remaining_surplus -= curtailed_solar[hour]
else: accumulated_curtailed_solar += curtailed_solar[hour]
# 混合可再生能源场景,弃风弃光受限制
# 计算当前可弃光量
if max_curtailed_solar_total == float('inf'):
# 无限制弃光
available_solar_curtail = solar[hour]
else:
# 受限制弃光
available_solar_curtail = min(
solar[hour],
max_curtailed_solar_total - accumulated_curtailed_solar
)
if available_solar_curtail > 0: # 如果还有剩余电力,弃风(弃风不限)
curtailed_solar[hour] = min(available_solar_curtail, remaining_surplus) if remaining_surplus > 0 and wind[hour] > 0:
remaining_surplus -= curtailed_solar[hour] # 弃风不受限制,可以弃掉所有剩余风电
accumulated_curtailed_solar += curtailed_solar[hour] curtailed_wind[hour] = min(wind[hour], remaining_surplus)
remaining_surplus -= curtailed_wind[hour]
# 如果还有剩余,弃风 accumulated_curtailed_wind += curtailed_wind[hour]
if remaining_surplus > 0:
if max_curtailed_wind_total == float('inf'):
# 无限制弃风
available_wind_curtail = wind[hour]
else:
# 受限制弃风
available_wind_curtail = min(
wind[hour],
max_curtailed_wind_total - accumulated_curtailed_wind
)
if available_wind_curtail > 0:
curtailed_wind[hour] = min(available_wind_curtail, remaining_surplus)
remaining_surplus -= curtailed_wind[hour]
accumulated_curtailed_wind += curtailed_wind[hour]
# 确保电力平衡:如果仍有剩余电力,强制弃掉(安全机制) # 确保电力平衡:如果仍有剩余电力,强制弃掉(安全机制)
if remaining_surplus > 0: if remaining_surplus > 0:
@@ -408,6 +360,7 @@ def check_constraints(
solar_output: 光伏出力曲线 (MW) - 支持24小时或8760小时 solar_output: 光伏出力曲线 (MW) - 支持24小时或8760小时
wind_output: 风电出力曲线 (MW) - 支持24小时或8760小时 wind_output: 风电出力曲线 (MW) - 支持24小时或8760小时
thermal_output: 火电出力曲线 (MW) - 支持24小时或8760小时 thermal_output: 火电出力曲线 (MW) - 支持24小时或8760小时
load_demand: 负荷曲线 (MW) - 支持24小时或8760小时
balance_result: 电能平衡计算结果 balance_result: 电能平衡计算结果
params: 系统参数配置 params: 系统参数配置
@@ -456,7 +409,6 @@ def optimize_storage_capacity(
Args: Args:
solar_output: 光伏出力曲线 (MW) - 支持24小时或8760小时 solar_output: 光伏出力曲线 (MW) - 支持24小时或8760小时
wind_output: 风电出力曲线 (MW) - 支持24小时或8760小时 wind_output: 风电出力曲线 (MW) - 支持24小时或8760小时
thermal_output: 火电出力曲线 (MW) - 支持24小时或8760小时
load_demand: 负荷曲线 (MW) - 支持24小时或8760小时 load_demand: 负荷曲线 (MW) - 支持24小时或8760小时
params: 系统参数配置 params: 系统参数配置
max_iterations: 最大迭代次数 max_iterations: 最大迭代次数
@@ -527,18 +479,21 @@ def optimize_storage_capacity(
else: else:
grid_constraint_satisfied = True grid_constraint_satisfied = True
has_wind = sum(wind_output) > 0 # 新逻辑:弃光受最大弃光比例限制,弃风不受限制
has_solar = sum(solar_output) > 0 solar_constraint_satisfied = constraint_results['total_curtailment_solar_ratio'] <= params.max_curtailment_solar
single_renewable = (has_wind and not has_solar) or (has_solar and not has_wind) # 弃风不受限制,始终满足
grid_quota_zero = params.max_grid_ratio == 0 wind_constraint_satisfied = True
if single_renewable or grid_quota_zero: # 考虑浮点数误差判断上网电量比例是否为0
constraints_satisfied = grid_constraint_satisfied grid_quota_zero = abs(params.max_grid_ratio) < 1e-10
if grid_quota_zero:
constraints_satisfied = grid_constraint_satisfied and solar_constraint_satisfied
else: else:
constraints_satisfied = ( constraints_satisfied = (
constraint_results['total_curtailment_wind_ratio'] <= params.max_curtailment_wind and solar_constraint_satisfied and # 弃光受限制
constraint_results['total_curtailment_solar_ratio'] <= params.max_curtailment_solar and wind_constraint_satisfied and # 弃风不受限制
grid_constraint_satisfied grid_constraint_satisfied # 上网电量受限制
) )
# 检查储能日平衡(周期结束时储能状态应接近初始值) # 检查储能日平衡(周期结束时储能状态应接近初始值)