新增梯级水电系统¶
目标。 在算例中引入一个多站点的梯级水电系统 (如新的流域),包含按电站建立的水库物理过程和站间水流延迟路由。
这是 "新增技术" 中最重的秘籍,因为在 PREP-SHOT 中每个水电站都是一等技术 (而非聚合在一起)。每个电站在 tech_registry.csv 中占一行,并在约 10 个水库相关文件中各占一行。完整示例可参阅随仓库提供的湄公河下游算例 (examples/southeast_asia,57 个电站) 与泰国算例 (examples/thailand,13 个电站)。
步骤¶
1. 选定电站 slug。 不允许空格,需去掉点号。一个 3 站梯级的例子:
Upper_Dam, Middle_Dam, Lower_Dam
2. 将每个电站注册为水电技术。 在 tech_registry.csv 中:
tech,name,carrier,is_storage
Upper_Dam,Upper Dam,hydro,False
Middle_Dam,Middle Dam,hydro,False
Lower_Dam,Lower Dam,hydro,False
carrier='hydro' 是特殊处理的;模型会为这些技术加载完整的水库物理约束。
3. 将每个电站映射到区域。 在 reservoir_zone.csv 中:
tech,unit,zone
Upper_Dam,zone_code,BA1
Middle_Dam,zone_code,BA1
Lower_Dam,zone_code,BA2
4. 填写按电站的水库参数。 以下文件每个电站各占一行:
reservoir_capacity_max.csv (MW, generator nameplate)
reservoir_capacity_min.csv (MW, usually 0)
reservoir_outflow_max.csv (m^3/s)
reservoir_outflow_min.csv (m^3/s, environmental flow)
reservoir_generation_flow_max.csv (m^3/s through turbines)
reservoir_head.csv (m, designed)
reservoir_coefficient.csv (efficiency, typically ~8.5)
5. 随时间变化的输入。 reservoir_inflow.csv 需为每个 (station, year, month, hour) 提供一行;``reservoir_storage_max.csv`` 与 reservoir_storage_min.csv 同理 (虽然这些通常在月内恒定)。期初/期末库容写入 reservoir_initial_storage_level.csv 与 reservoir_final_storage_level.csv。
6. 梯级路由。 在 reservoir_water_delay_time.csv 中定义相连电站之间的水流时间:
upstream_tech,downstream_tech,delay
Upper_Dam,Middle_Dam,2
Middle_Dam,Lower_Dam,4
延迟单位为小时。无下游条目的电站为末端 (水流离开建模系统)。
7. 分段函数。 还有两个文件用长格式按电站描述非线性水电物理:
reservoir_forebay_level_volume_function.csv-- forebay elevation as a function of reservoir volume.reservoir_tailrace_level_discharge_function.csv-- tailrace elevation as a function of total discharge.
PREP-SHOT 在水头迭代循环中将其线性化。
8. 已有装机 (可选)。 若梯级中部分电站已建成:
tech,zone,commission_year,unit,capacity
Upper_Dam,BA1,2020,MW,150
Middle_Dam,BA1,2020,MW,200
9. 按技术的文件。 别忘了 8 个与水库无关的按技术索引文件 (lifetime、fuel_price、emission_factor、fixed_OM_cost、variable_OM_cost、investment_cost、ramp_up、ramp_down)——每个电站都需一行,即便绝大多数为零 (无燃料、无排放)。
验证¶
import xarray as xr
ds = xr.open_dataset("output/year.nc")
cascade = ["Upper_Dam", "Middle_Dam", "Lower_Dam"]
print("Installed:")
print(ds["install"].sel(tech=cascade).to_pandas())
print("\nGeneration (sum over time):")
print(ds["gen"].sel(tech=cascade).sum(["hour", "month", "zone"]).to_pandas())
# Reservoir trajectories (only when isinflow=true)
print("\nGeneration flow (sum over hours, by month, year):")
print(ds["genflow"].sel(station=cascade).sum("hour").to_pandas())
常见陷阱¶
slug 必须保持一致。 同一个电站名必须出现在每个引用它的 CSV 中:
tech_registry、reservoir_zone、所有reservoir_*文件以及按技术索引的文件。任何一处拼错都会导致加载失败。梯级方向。
upstream_tech始终是水离开的那个电站;``downstream_tech`` 是其下游的下一个电站。颠倒这两列会静默地产生无意义的结果。入流数据形状。
reservoir_inflow.csv按 (站、年、月、时) 索引。在hour=8760, month=1配置下,每站为 8760 行——较大但不可避免。开发期间可减小 hour 数量。约束可能导致模型不可行。 若任一电站的
reservoir_outflow_min大于reservoir_outflow_max,或所需出力在过多小时数中超过capacity_max,HiGHS 会报告不可行,但不会给出松弛信息。请检查你的上下界。
查看 examples/southeast_asia/input/ 是了解完整 57 站梯级数据集长什么样的最快方法。