修复可用电量计算。

This commit is contained in:
dmy
2025-12-26 02:28:54 +08:00
parent 65be7e52dd
commit 269e985d83
3 changed files with 188 additions and 42 deletions

View File

@@ -101,16 +101,46 @@ def read_system_parameters(file_path: str) -> SystemParameters:
except (ValueError, TypeError): except (ValueError, TypeError):
raise ValueError(f"参数 '{param_name}' 的值 '{param_value}' 不是有效的数值") raise ValueError(f"参数 '{param_name}' 的值 '{param_value}' 不是有效的数值")
# 创建SystemParameters对象 # 读取各参数值,如果找不到则使用默认值
return SystemParameters( get_param_value = lambda param_name: df_params.loc[df_params['参数名称'] == param_name, '参数值'].iloc[0] if param_name in df_params['参数名称'].values else None
max_curtailment_wind=params_dict.get('最大弃风率', 0.1),
max_curtailment_solar=params_dict.get('最大弃光率', 0.1), max_storage_capacity = get_param_value('最大储能容量')
max_grid_ratio=params_dict.get('最大上网电量比例', 0.2), # 处理空值或字符串"空"
storage_efficiency=params_dict.get('储能效率', 0.9), if pd.isna(max_storage_capacity) or max_storage_capacity == '':
discharge_rate=params_dict.get('放电倍率', 1.0), max_storage_capacity = None
charge_rate=params_dict.get('充电倍率', 1.0),
max_storage_capacity=params_dict.get('最大储能容量', None) try:
) return SystemParameters(
max_curtailment_wind=get_param_value('最大弃风率') or 0.1,
max_curtailment_solar=get_param_value('最大弃光率') or 0.1,
max_grid_ratio=get_param_value('最大上网电量比例') or 0.2,
storage_efficiency=get_param_value('储能效率') or 0.9,
discharge_rate=get_param_value('放电倍率') or 1.0,
charge_rate=get_param_value('充电倍率') or 1.0,
max_storage_capacity=max_storage_capacity,
rated_thermal_capacity=get_param_value('额定火电装机容量') or 100.0,
rated_solar_capacity=get_param_value('额定光伏装机容量') or 100.0,
rated_wind_capacity=get_param_value('额定风电装机容量') or 100.0,
available_thermal_energy=get_param_value('火电可用发电量') or 2400.0,
available_solar_energy=get_param_value('光伏可用发电量') or 600.0,
available_wind_energy=get_param_value('风电可用发电量') or 1200.0
)
except (KeyError, IndexError, Exception) as e:
print(f"读取参数失败:{str(e)},使用默认参数")
return SystemParameters(
max_curtailment_wind=0.1,
max_curtailment_solar=0.1,
max_grid_ratio=0.2,
storage_efficiency=0.9,
discharge_rate=1.0,
charge_rate=1.0,
rated_thermal_capacity=100.0,
rated_solar_capacity=100.0,
rated_wind_capacity=100.0,
available_thermal_energy=2400.0,
available_solar_energy=600.0,
available_wind_energy=1200.0
)
except Exception as e: except Exception as e:
print(f"读取参数工作表失败,使用默认参数:{str(e)}") print(f"读取参数工作表失败,使用默认参数:{str(e)}")
@@ -261,7 +291,13 @@ def create_excel_template(file_path: str, data_type: str = "8760"):
'储能效率', '储能效率',
'放电倍率', '放电倍率',
'充电倍率', '充电倍率',
'最大储能容量' '最大储能容量',
'额定火电装机容量',
'额定光伏装机容量',
'额定风电装机容量',
'火电可用发电量',
'光伏可用发电量',
'风电可用发电量'
], ],
'参数值': [ '参数值': [
0.1, # 最大弃风率 0.1, # 最大弃风率
@@ -270,7 +306,13 @@ def create_excel_template(file_path: str, data_type: str = "8760"):
0.9, # 储能效率 0.9, # 储能效率
1.0, # 放电倍率 1.0, # 放电倍率
1.0, # 充电倍率 1.0, # 充电倍率
'' # 最大储能容量(空表示无限制) '', # 最大储能容量(空表示无限制)
100.0, # 额定火电装机容量
100.0, # 额定光伏装机容量
100.0, # 额定风电装机容量
2400.0, # 火电可用发电量
600.0, # 光伏可用发电量
1200.0 # 风电可用发电量
], ],
'参数说明': [ '参数说明': [
'允许的最大弃风率0.0-1.0', '允许的最大弃风率0.0-1.0',
@@ -279,7 +321,13 @@ def create_excel_template(file_path: str, data_type: str = "8760"):
'储能充放电效率0.0-1.0', '储能充放电效率0.0-1.0',
'储能放电倍率C-rate>0', '储能放电倍率C-rate>0',
'储能充电倍率C-rate>0', '储能充电倍率C-rate>0',
'储能容量上限MWh空表示无限制' '储能容量上限MWh空表示无限制',
'额定火电装机容量MW',
'额定光伏装机容量MW',
'额定风电装机容量MW',
'火电可用发电量MWh',
'光伏可用发电量MWh',
'风电可用发电量MWh'
], ],
'取值范围': [ '取值范围': [
'0.0-1.0', '0.0-1.0',
@@ -288,7 +336,13 @@ def create_excel_template(file_path: str, data_type: str = "8760"):
'0.0-1.0', '0.0-1.0',
'>0', '>0',
'>0', '>0',
'>0或空' '>0或空',
'>0',
'>0',
'>0',
'≥0',
'≥0',
'≥0'
], ],
'默认值': [ '默认值': [
'0.1', '0.1',
@@ -297,7 +351,13 @@ def create_excel_template(file_path: str, data_type: str = "8760"):
'0.9', '0.9',
'1.0', '1.0',
'1.0', '1.0',
'无限制' '无限制',
'100.0',
'100.0',
'100.0',
'2400.0',
'600.0',
'1200.0'
] ]
}) })
parameters_df.to_excel(writer, sheet_name='参数', index=False) parameters_df.to_excel(writer, sheet_name='参数', index=False)

58
main.py
View File

@@ -287,7 +287,13 @@ def export_results_to_excel(solar_output, wind_output, thermal_output, load_dema
'储能效率', '储能效率',
'放电倍率', '放电倍率',
'充电倍率', '充电倍率',
'最大储能容量' '最大储能容量',
'额定火电装机容量',
'额定光伏装机容量',
'额定风电装机容量',
'火电可用发电量',
'光伏可用发电量',
'风电可用发电量'
], ],
'参数值': [ '参数值': [
params.max_curtailment_wind, params.max_curtailment_wind,
@@ -296,7 +302,13 @@ def export_results_to_excel(solar_output, wind_output, thermal_output, load_dema
params.storage_efficiency, params.storage_efficiency,
params.discharge_rate, params.discharge_rate,
params.charge_rate, params.charge_rate,
params.max_storage_capacity if params.max_storage_capacity is not None else "无限制" params.max_storage_capacity if params.max_storage_capacity is not None else "无限制",
params.rated_thermal_capacity,
params.rated_solar_capacity,
params.rated_wind_capacity,
params.available_thermal_energy,
params.available_solar_energy,
params.available_wind_energy
], ],
'单位': [ '单位': [
"比例", "比例",
@@ -305,6 +317,12 @@ def export_results_to_excel(solar_output, wind_output, thermal_output, load_dema
"效率", "效率",
"C-rate", "C-rate",
"C-rate", "C-rate",
"MWh",
"MW",
"MW",
"MW",
"MWh",
"MWh",
"MWh" "MWh"
] ]
}) })
@@ -427,6 +445,12 @@ def main():
print(f" 放电倍率: {params.discharge_rate}") print(f" 放电倍率: {params.discharge_rate}")
print(f" 充电倍率: {params.charge_rate}") print(f" 充电倍率: {params.charge_rate}")
print(f" 最大储能容量: {params.max_storage_capacity}") print(f" 最大储能容量: {params.max_storage_capacity}")
print(f" 额定火电装机容量: {params.rated_thermal_capacity} MW")
print(f" 额定光伏装机容量: {params.rated_solar_capacity} MW")
print(f" 额定风电装机容量: {params.rated_wind_capacity} MW")
print(f" 火电可用发电量: {params.available_thermal_energy} MWh")
print(f" 光伏可用发电量: {params.available_solar_energy} MWh")
print(f" 风电可用发电量: {params.available_wind_energy} MWh")
else: else:
print("\n警告:未找到系统参数,使用默认参数") print("\n警告:未找到系统参数,使用默认参数")
params = SystemParameters( params = SystemParameters(
@@ -435,7 +459,13 @@ def main():
max_grid_ratio=0.2, max_grid_ratio=0.2,
storage_efficiency=0.9, storage_efficiency=0.9,
discharge_rate=1.0, discharge_rate=1.0,
charge_rate=1.0 charge_rate=1.0,
rated_thermal_capacity=100.0,
rated_solar_capacity=100.0,
rated_wind_capacity=100.0,
available_thermal_energy=2400.0,
available_solar_energy=600.0,
available_wind_energy=1200.0
) )
# 显示数据统计 # 显示数据统计
@@ -474,7 +504,13 @@ def main():
max_grid_ratio=0.2, max_grid_ratio=0.2,
storage_efficiency=0.9, storage_efficiency=0.9,
discharge_rate=1.0, discharge_rate=1.0,
charge_rate=1.0 charge_rate=1.0,
rated_thermal_capacity=100.0,
rated_solar_capacity=100.0,
rated_wind_capacity=100.0,
available_thermal_energy=2400.0,
available_solar_energy=600.0,
available_wind_energy=1200.0
) )
# 对于 --yearly 参数,也需要设置默认参数 # 对于 --yearly 参数,也需要设置默认参数
@@ -485,7 +521,13 @@ def main():
max_grid_ratio=0.2, max_grid_ratio=0.2,
storage_efficiency=0.9, storage_efficiency=0.9,
discharge_rate=1.0, discharge_rate=1.0,
charge_rate=1.0 charge_rate=1.0,
rated_thermal_capacity=100.0,
rated_solar_capacity=100.0,
rated_wind_capacity=100.0,
available_thermal_energy=2400.0,
available_solar_energy=600.0,
available_wind_energy=1200.0
) )
# 显示当前使用的系统参数 # 显示当前使用的系统参数
@@ -497,6 +539,12 @@ def main():
print(f"放电倍率: {params.discharge_rate}") print(f"放电倍率: {params.discharge_rate}")
print(f"充电倍率: {params.charge_rate}") print(f"充电倍率: {params.charge_rate}")
print(f"最大储能容量: {params.max_storage_capacity if params.max_storage_capacity is not None else '无限制'}") print(f"最大储能容量: {params.max_storage_capacity if params.max_storage_capacity is not None else '无限制'}")
print(f"额定火电装机容量: {params.rated_thermal_capacity} MW")
print(f"额定光伏装机容量: {params.rated_solar_capacity} MW")
print(f"额定风电装机容量: {params.rated_wind_capacity} MW")
print(f"火电可用发电量: {params.available_thermal_energy} MWh")
print(f"光伏可用发电量: {params.available_solar_energy} MWh")
print(f"风电可用发电量: {params.available_wind_energy} MWh")
print("=" * 40) print("=" * 40)
# 计算最优储能容量 # 计算最优储能容量

View File

@@ -23,6 +23,14 @@ class SystemParameters:
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表示无限制 max_storage_capacity: Optional[float] = None # 储能容量上限 (MWh)None表示无限制
# 新增额定装机容量参数
rated_thermal_capacity: float = 100.0 # 额定火电装机容量 (MW)
rated_solar_capacity: float = 100.0 # 额定光伏装机容量 (MW)
rated_wind_capacity: float = 100.0 # 额定风电装机容量 (MW)
# 新增可用发电量参数
available_thermal_energy: float = 2400.0 # 火电可用发电量 (MWh)
available_solar_energy: float = 600.0 # 光伏可用发电量 (MWh)
available_wind_energy: float = 1200.0 # 风电可用发电量 (MWh)
def validate_inputs( def validate_inputs(
@@ -79,6 +87,20 @@ def validate_inputs(
raise ValueError("充放电倍率必须大于0") raise ValueError("充放电倍率必须大于0")
if params.max_storage_capacity is not None and params.max_storage_capacity <= 0: if params.max_storage_capacity is not None and params.max_storage_capacity <= 0:
raise ValueError("储能容量上限必须大于0") raise ValueError("储能容量上限必须大于0")
# 验证新增的额定装机容量参数
if params.rated_thermal_capacity <= 0:
raise ValueError("额定火电装机容量必须大于0")
if params.rated_solar_capacity <= 0:
raise ValueError("额定光伏装机容量必须大于0")
if params.rated_wind_capacity <= 0:
raise ValueError("额定风电装机容量必须大于0")
# 验证新增的可用发电量参数
if params.available_thermal_energy < 0:
raise ValueError("火电可用发电量必须为非负值")
if params.available_solar_energy < 0:
raise ValueError("光伏可用发电量必须为非负值")
if params.available_wind_energy < 0:
raise ValueError("风电可用发电量必须为非负值")
def calculate_energy_balance( def calculate_energy_balance(
@@ -130,6 +152,13 @@ def calculate_energy_balance(
accumulated_curtailed_wind = 0.0 accumulated_curtailed_wind = 0.0
accumulated_curtailed_solar = 0.0 accumulated_curtailed_solar = 0.0
# 计算总可用发电量上限(不考虑火电)
total_available_energy = params.available_solar_energy + params.available_wind_energy
max_total_grid_feed_in = total_available_energy * params.max_grid_ratio
# 初始化累计上网电量
cumulative_grid_feed_in = 0.0
# 逐小时计算 # 逐小时计算
for hour in range(hours): for hour in range(hours):
# 确保储能状态不为负 # 确保储能状态不为负
@@ -145,7 +174,7 @@ def calculate_energy_balance(
power_surplus = available_generation - demand power_surplus = available_generation - demand
if power_surplus > 0: if power_surplus > 0:
# 有盈余电力,优先储能,然后上网 # 有盈余电力,优先储能
max_charge = min( max_charge = min(
storage_capacity - storage_soc[hour], # 储能空间限制 storage_capacity - storage_soc[hour], # 储能空间限制
storage_capacity * params.charge_rate, # 充电功率限制 storage_capacity * params.charge_rate, # 充电功率限制
@@ -160,36 +189,45 @@ def calculate_energy_balance(
if hour < hours - 1: if hour < hours - 1:
storage_soc[hour + 1] = storage_soc[hour] + actual_charge * params.storage_efficiency storage_soc[hour + 1] = storage_soc[hour] + actual_charge * params.storage_efficiency
# 剩余电力考虑弃风弃光和上网 # 剩余电力优先上网,超出上网电量比例限制时才弃风弃光
remaining_surplus = power_surplus - actual_charge remaining_surplus = power_surplus - actual_charge
# 计算弃风弃光(优先弃风,然后弃光) # 计算当前允许的最大上网电量
# 基于总可用发电量和已累计上网电量
remaining_grid_quota = max_total_grid_feed_in - cumulative_grid_feed_in
# 优先上网,但不超过剩余配额
grid_feed_allowed = min(remaining_surplus, max(0, remaining_grid_quota))
grid_feed_in[hour] = grid_feed_allowed
cumulative_grid_feed_in += grid_feed_allowed
# 剩余电力考虑弃风弃光
remaining_surplus -= grid_feed_allowed
# 计算弃风弃光(优先弃光,然后弃风)
if remaining_surplus > 0: if remaining_surplus > 0:
# 计算当前可弃 # 计算当前可弃
available_wind_curtail = min( available_solar_curtail = min(
wind[hour], solar[hour],
max_curtailed_wind_total - accumulated_curtailed_wind max_curtailed_solar_total - accumulated_curtailed_solar
) )
if available_wind_curtail > 0: if available_solar_curtail > 0:
curtailed_wind[hour] = min(available_wind_curtail, remaining_surplus) curtailed_solar[hour] = min(available_solar_curtail, remaining_surplus)
remaining_surplus -= curtailed_wind[hour] remaining_surplus -= curtailed_solar[hour]
accumulated_curtailed_wind += curtailed_wind[hour] accumulated_curtailed_solar += curtailed_solar[hour]
# 如果还有剩余,弃 # 如果还有剩余,弃
if remaining_surplus > 0: if remaining_surplus > 0:
available_solar_curtail = min( available_wind_curtail = min(
solar[hour], wind[hour],
max_curtailed_solar_total - accumulated_curtailed_solar max_curtailed_wind_total - accumulated_curtailed_wind
) )
if available_solar_curtail > 0: if available_wind_curtail > 0:
curtailed_solar[hour] = min(available_solar_curtail, remaining_surplus) curtailed_wind[hour] = min(available_wind_curtail, remaining_surplus)
remaining_surplus -= curtailed_solar[hour] remaining_surplus -= curtailed_wind[hour]
accumulated_curtailed_solar += curtailed_solar[hour] accumulated_curtailed_wind += curtailed_wind[hour]
# 最终剩余电力上网
grid_feed_in[hour] = max(0, remaining_surplus)
else: else:
# 电力不足,优先放电 # 电力不足,优先放电