模块7 的 KW 是集总单河段;真实的 channel routing 是网络:每格自己解 KW,把出流交给唯一下游格(D8),按"上游先算"的拓扑序扫一遍。本页在 Y 形河网上让你看见水波走、看见支流叠加。
我们的教学网络:全部当河道格、单位格距、一个 alpha——机制不变、去掉工程细节。lab 里 blocks/network.py 与此页代码一致。
同一场 10mm 雨落在四个不同位置,出口听到的"回声"完全不同——距离=延迟+衰减。改代码或拖参数重跑。
先厘清一件事:EF5 里 CRESTModel.cpp 只管产流,routing 是独立插件,配置文件里 route=lr 或 route=kw 二选一(也可配 sac+kw 等)。所以"CREST 的 routing"有两个答案:
| lr = LinearRoute(Wang 2011 原生 CREST 汇流) | kw = KinematicRoute(FLASH 业务标配) | |
|---|---|---|
| 快流机制 | 水库漏出 leak=S×LEAKO(:82) + travel-time 投递 | 逐格运动波隐式方程 + Newton 迭代(:210-230) |
| 延迟来自 | 速度:nexTime=格长/速度,速度=depth^0.66·√S·(RIVER|COEM)(:244) | 蓄量:隐式项 αQ^β 即每格非线性蓄量 |
| 投递方式 | 沿下游累加 nexTime 直到用完一步,把水线性插值分给落点前后两格(:279-310) —— 可跨多格 | 解完推给唯一下游格(:238) |
| 主旋钮 | LEAKO / LEAKI / COEM / RIVER / TH / UNDER | ALPHA(河道) / ALPHA0(坡面) / β=0.6硬编码 / LEAKI / UNDER / TH |
| 慢流(interflow) | 两者完全相同:IR 水库 leak=S×LEAKI + speedUnder=UNDER×√slope 的 travel-time 投递(kw:245-253,:492 与 lr 同构)→ 换 route 只换了快流物理 | |
| 求解方式 | 直接计算(无迭代):算速度 → 走 → 投递 | 迭代求解:每格每步 Newton 解隐式方程 |
| 实测成本 (本课 Python 实现) | 13/121/241 格:19 / 65 / 60 ms 平均只走 1.06 格(跨多格是能力、非常态) | 19 / 92 / 123 ms → 241 格时慢 2.0× Newton 平均 1.13 次收敛(上限10次几乎不触发) |
| 河道格特殊处理 | 河道格快流直通不入库(:89-91) | 河道格解两次:坡面(ALPHA0,状态PO) + 河道(ALPHA,状态PQ)(:285,:338) |
成本说明(诚实):2× 差距部分是实现差异——lr 把最贵的速度计算向量化了,kw 的 Newton 是逐格标量循环(含 pow)。EF5 的 C++/OpenMP 下常数因子不同,但结构性差异成立:kw 每格每步迭代求解,lr 直接算。另:Newton 平均 1.13 次就收敛,因为上一步的 Q 是极好的初值——"10 次迭代"是安全网不是常态。
三个源码级发现:
① "Coupled" 已成历史名:Wang 2011 的产流↔汇流反馈(汇流水回灌下游格)在 EF5 中被注释掉了(CRESTModel.cpp:137-140, :152-153, :237-238)。
② "LinearRoute" 其实非线性:速度每步按水深重算 → 传播时间随流量剧变。实测同一河网源头脉冲:1mm 峰现 t=59、20mm 峰现 t=19、200mm 峰现 t=10。名字只是说"蓄量-出流"是线性的。
③ kw 是混合体:只有 overland/channel 用运动波,interflow 仍是水库+travel-time(同 lr)。
④ 两者都因拓扑序扫描(flow-accum 排序)能在同一步内跨越全网——差别不在"能跳几格",而在"延迟由速度还是蓄量决定"。
过程线只告诉你"出口什么时候有水"。要理解 routing,得看水在空间上随时间怎么移动: 横轴时间、纵轴河道位置、颜色 = 该格的水量。洪水波会显示成一条斜纹—— 斜纹的斜率就是波速。拖动脉冲大小,看斜纹变陡(变快):这就是非线性的可视化。
最小可手算算例:3 格链 0→1→2→出口,t=0 时给 cell0 灌 10mm。
下面把每一步的每一个中间量都打印出来——蓄量、漏出、水深、速度、nexTime、下游行走过程、插值权重、投递去向(lr);
以及 rhs 组装与每一次 Newton 迭代(kw)。