水库群联调演示
串联水库群的逐日水量平衡演算器。可以直接玩页面自带的合成来水序列,也可以把你自己的水文序列贴进来真算 —— 拖入一份逐日来水 CSV、把各库的死库容 / 正常蓄水位库容 / 汛限库容 / 下泄能力 / 各控制线填进参数表,页面就按你的数据逐日推演:蒸渗损失、分级供水、生态基流优先、库间联合补水、超蓄弃水,逐库与全系统的水量平衡闭合残差都算出来摆在明处。全部运算在你的浏览器里完成,数据不上传。
两种数据来源,界面上永远标注当前用的是哪一种。①页面合成序列:来水由"正弦年周期 × 对数正态随机扰动"合成,随机数取自固定种子的线性同余发生器 —— 同一组参数任何人任何时候打开都得到同一条过程线,可复现、可对拍;库容与需水为示意量级,不对应任何真实水库。②你上传的序列:逐日 CSV,格式校验不通过就直接拒绝、不会静默跑出一个看着合理的结果;水量平衡闭合残差超阈值时报警并停止出图。
一、水文序列输入
1. 来水序列 CSV必填项
第一列 date(YYYY-MM-DD,必须逐日连续),其后每座水库一列本区间天然来水,列名即水库名。单位在下面选。完整规格见本节末尾的格式表。
把 .csv / .txt 文件拖到这里,或点这里选文件
也可以直接把内容粘贴到下面的文本框
还没有载入任何上传序列,当前用的是页面合成序列。
2. 需水序列 CSV可选
不传就用参数表里的常量需水(灌溉需水峰值 × 年内高斯型分配、生态基流恒定)。传了就逐日按你的需水算。日期必须与当前生效的来水序列完全同起止、同天数。列数 = 水库数(仅灌溉需水),或 2 × 水库数(前 N 列灌溉、后 N 列生态基流)。
当前用常量需水(参数表里的灌溉需水峰值 + 生态基流)。
3. 水库参数表 CSV可选
表头驱动、列序不限。必填 name、cap(正常蓄水位库容)、dead(死库容);flood(汛限库容)、outlet(下泄能力)、init(初始蓄水率)、eco、irr、qin、area(集水面积)、zHi / zLo / jointFloor(三条控制线)缺省时用页面默认值或全局滑块值。行数即水库数;已载入上传序列时行数必须与序列列数一致。
当前用页面默认参数(可用滑块微调,或在这里成批贴入)。
CSV 格式规格
| 分隔符 | 制表符 / 逗号 / 分号,按此优先级自动识别(同一行内不混用)。不支持引号包裹的字段,所以水库名里不要出现逗号。 |
| 注释与空行 | # 开头的整行、以及全空行,一律跳过。行号报错时报的是文件里的原始行号。 |
| 表头 | 必须有。序列表第一列表头须为 date/日期/时间/day/ymd 之一;其余各列的表头即水库名。 |
| 日期 | YYYY-MM-DD,也接受 YYYY/M/D 与 YYYY年M月D日。必须是合法日历日(认闰年)、逐日连续、不重复、不倒序。缺日 / 重日 / 倒序一律拒绝并报出缺的是哪几天。 |
| 数值 | 有限实数,允许科学计数法,不允许空单元格、不允许非数值、不允许负值。 |
| 来水单位 | 万 m³/d(原值直用)/ m³/s(× 8.64)/ mm/d(× 该库集水面积 km² × 0.1)。选 mm/d 时必须先在参数表里给每座库填好 area,否则拒绝。 |
| 需水表 | 日期规则同上,且必须与生效来水序列同起止同天数。列数 = 水库数(灌溉)或 2 × 水库数(前 N 灌溉、后 N 生态)。 |
| 规模上限 | 天数 2 ~ 40000;水库数 1 ~ 50;另有 天数 × 水库数 ≤ 800000 的格点上限(浏览器内存所限)。任一条超出即拒绝,不做截断。 |
二、调度参数
拖动即重算。水库按表中顺序首尾相接:上一座的出库(生态下泄 + 库间补水 + 弃水)汇入下一座,各库另有本区间的天然来水。上传序列的列序 = 从上游到下游的顺序。
三、关键指标与水量平衡校核
四、过程线
图 1 各库蓄水过程线(以兴利库容占比表示,0% = 死水位,100% = 正常蓄水位)
图 2 各库出库流量过程线(=生态下泄 + 灌溉供水 + 库间补水 + 弃水)
图 3 各库区间天然来水过程线(不含上游水库下泄)
五、水量平衡表
单位:万 m³,统计区间 = 整条序列。"入库"含上游水库下泄;"闭合残差" = 入库 −(蓄变 + 生态下泄 + 灌溉供水 + 库间补水 + 弃水 + 损失),逐库真算,理论值为 0,实际只剩浮点舍入。求和用 Neumaier 补偿求和,避免长序列的累加误差被当成模型误差。判定闭合看的是相对残差(残差 ÷ 入库量):绝对残差必然随水量量级一起长大(62 年序列的入流是 365 天序列的六十多倍,双精度尾数噪声也就跟着放大六十多倍),拿一个固定的绝对阈值去卡它,只会在换了单位或换了序列长度之后误判。
六、模型说明
水量平衡方程
| S(t) | 第 t 日末蓄水量,万 m³ |
| I(t) | 第 t 日入库水量 = 本区间天然来水(合成或你上传的那一列)+ 上游水库当日下泄(生态下泄 + 库间补水 + 弃水),万 m³ |
| R生态、R灌溉、R弃水 | 当日生态下泄、灌溉供水、弃水,万 m³ |
| R补水 | 联合调度下为下游水库补送的水量(关闭联合调度时恒为 0),万 m³ |
| L(t) | 蒸发渗漏损失 = 损失率 × S(t−1),并以不击穿死库容为限,万 m³ |
| S汛限 | 汛限库容,万 m³。汛期(全局参数给起止月份)蓄水上限降到该值,超出即弃水;填成与正常蓄水位库容相等即等于不设汛限(页面默认如此,所以默认演算结果与不带该功能时一致) |
| Q下泄能力 | 放水建筑物过流能力,m³/s;×8.64 换算为万 m³/日(1 m³/s × 86400 s = 8.64 万 m³)。弃水走溢洪道,不受此限 |
逐日代入示例(取当前参数下的真实演算结果)
逐日演算次序
- 先扣损失:L = min(损失率 × S(t−1), 可用水量 − 死库容)。
- 按分级调度水位定供水系数:蓄水率 ≥ 加大供水线 → 加大供水;介于两线之间 → 正常供水;低于限制供水线 → 限制供水(按系数打折)。三条控制线可全局给,也可在参数表里逐库覆盖。
- 生态基流优先满足,其次灌溉需水;两者合计受下泄能力与"不击穿死库容"双重约束。
- 联合调度补水:先自下而上估算下游水库当日缺口(缺口 = 需水 − 本库可用蓄水 − 本区间来水),上游水库在自身蓄水率高于"补水控制线"、且下泄能力尚有余量时按缺口补送。关闭该开关即退化为各库独立运行,可直接对比两种方案的保证率差。
- 供水与补水后若蓄水量仍超过当日蓄水上限(汛期取汛限库容,非汛期取正常蓄水位库容),超出部分作弃水下泄(溢洪道能力按不控制处理)。
- 上一座库的生态下泄、库间补水与弃水计入下一座水库当日入库;灌溉供水视为引出河道、不再进入下游水库。
补水量的估算只用下游水库时段初蓄水与本区间来水、不含上游当日来水,属偏保守的上限估计 —— 多补的水会留在下游库内或形成弃水,因此这一简化不会破坏水量平衡闭合,只会让联合调度的效益略偏保守。真实工程中此处应换成径流预报 + 优化调度模型,本页只演示调度规则如何影响演算结果。
合成来水序列(只在"页面合成序列"这一档生效)
Q̄ 为该库区间来水多年平均流量(滑块给定),λ 为年型系数(枯 0.5 ~ 丰 1.6),σ 为随机波动强度,ρ = 0.85 为日尺度自相关系数(保证过程线连续成"场次"而非白噪声),z(t) 为标准正态随机数,由"12 个均匀随机数求和减 6"构造(Irwin–Hall 近似);均匀随机数取自线性同余发生器 x ← (1664525·x + 1013904223) mod 2³²。各库共用一个区域分量 ε区域(相关系数 0.65),因此丰枯同步而非各自独立 —— 这正是水库群联合调度值得做的前提。指数项减去 σ²/2 是为了让对数正态扰动的期望保持为 1,即长期均值不被随机项抬高。载入上传序列后这一整套合成逻辑就不参与演算了,年型系数 / 随机种子 / 波动强度三个滑块会自动置灰。
指标口径
| 供水保证率 | 该库生态基流与灌溉需水同时足额满足的天数占序列总天数之比(按日计的时段保证率)。系统保证率要求各库当日全部满足。 |
| 弃水总量 | 各库弃水之和;上游弃水会进入下游水库、仍有被再次调蓄利用的机会,因此另列"出系统弃水"(末库弃水),后者才是真正流出研究范围的水量。 |
| 最低蓄水 | 全序列蓄水量最小值及其出现日期,对应最低运行水位的出现时机(本模型只演算库容,不做库容–水位曲线换算)。 |
| 水量平衡校核 | 系统入流总量 −(系统总蓄变 + 各库灌溉供水 + 末库生态下泄 + 末库弃水 + 各库损失)。内部环节首尾相消,残差应为浮点量级。相对残差超过 1×10⁻⁹ 即判为未闭合:页面会报警并停止出图,因为这时候的过程线不可信。 |