尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

LISFLOOD-FP 水文模拟避坑指南:单位、参数与结果文件详解

LISFLOOD-FP 水文模拟避坑指南:单位、参数与结果文件详解 搞水文模拟这几年LISFLOOD-FP算是让我又爱又恨的一个模型。爱的是它逻辑简明网格化汇流模拟在平原洪涝里效率高恨的是它那些藏在细节里的坑稍不留神就让你跑出来一堆“看起来合理、实际全错”的结果。今天这篇就把最劝退新人的三块内容一次性捋清楚数据单位怎么统一参数文件到底怎么写才不报错以及results文件夹里那一堆结果文件分别是什么、怎么看。这篇东西不是教科书翻译是我自己跑模型时踩过的坑、一个个试出来的经验汇总。适合刚接触LISFLOOD-FP的研究生、做洪水风险图的技术人员以及被par文件反复折磨的工程师参考。1. LISFLOOD-FP数据单位避坑大部分报错和“诡异结果”都是单位问题1.1 模型输入数据都有哪些单位分别是什么LISFLOOD-FP的核心输入数据就几类地形高程、流量/雨量、初始水深和边界条件。这些数据单位不统一模型不会报错但输出的淹没范围、水深、流速全都会偏离物理意义。先说地形数据。DEM文件是模型的底图单位必须是米m。这里容易犯的错是拿到一个经纬度坐标系的DEM高程值单位虽然是米但水平方向不是米而是度。LISFLOOD-FP本身不判断投影你给它什么它就算什么。如果水平单位是度、高程单位是米模型计算流速时会把“度”当成米来算结果就是流速差了好几个数量级水量在网格之间移动的速度完全失控。再说流量和降雨。流量边界条件河道入流单位是立方米每秒m³/s降雨输入一般用毫米每小时mm/hr或毫米每天mm/day。这俩也特别容易混。有人拿到水文站提供的日径流数据单位是m³/s结果当成mm/hr填进去出的淹没范围比实际大了好几个量级。最后是初始水深。如果没有实测初始水面分布一般默认全网格0米。这个单位不踩坑但要注意如果你用上一次模拟的结尾水深文件作为这次模拟的初始条件那个文件单位是米直接引用即可。1.2 单位换算的核心逻辑统一到“米和秒”LISFLOOD-FP的内核计算全部基于国际单位制SI即长度用米、时间用秒。所以所有输入数据在进入模型前都必须换算到这一套体系。常见换算场景有三个降雨强度换算水文上常用的mm/hr要先换算成m/s。因为模型计算的格子水深变化是“每秒钟水深增加多少米”所以1 mm/hr 1 / (1000 × 3600) m/s也就是约2.78×10⁻⁷ m/s。流量过程线时间单位如果实测流量是逐日数据时间步长本身不受影响但你设置的模拟时长sim_time如果是按秒算的必须把天数换算成秒。1天86400秒。栅格分辨率DEM的栅格大小cell size如果原始数据是30米那没问题如果是0.0003度约30米必须先投影成米制坐标系再输入模型。这个步骤我用GDAL的gdalwarp做过很多次投影方法建议用双线性插值避免高程在重采样时产生锯齿。1.3 一次单位错误导致的典型翻车案例去年帮一个课题组排查过一次模拟结果异常的问题。他们用LISFLOOD-FP模拟某小型流域的暴雨淹没结果淹没范围几乎覆盖了整个流域最大水深超过50米一眼就知道不对。排查过程很曲折先检查DEM高程没问题再看参数文件时间步长、模拟时长也合理最后把降雨文件翻出来发现降雨强度填的是“50 mm/hr”但文件头注释写的是“该数据为小时降雨量”。看着没问题对吧问题出在单位换算他们把50 mm/hr直接当成50 m/s输进去了。50 mm/hr换算成m/s是1.39×10⁻⁵直接输50数值大了360万倍。模拟结果自然是全流域一片汪洋。这类问题最大的特点是不报错但结果离谱。所以拿到任何模拟结果第一件事不是看淹得多漂亮而是先看最大水深和淹没范围是否符合常识量级。2. 参数文件核心结构解析par文件的每行都是关键2.1 参数文件长什么样主结构拆解LISFLOOD-FP的参数文件是文本格式每一行一个参数指令格式是“参数名 值”。编辑器建议用Notepad或者VS Code千万不要用Windows自带记事本改因为编码问题可能导致解析失败。典型的最小可用参数文件长这样DEMfile dem.asc resroot output/ccm sim_time 86400 initial 0 step 5 massint 1000 outinterval 3600 output 4逐行解释一下DEMfile指定DEM文件名。这个路径是相对当前工作目录的建议用相对路径而不是绝对路径。resroot结果文件的前缀。所有输出文件都会以这个前缀命名相当于给这次模拟的结果“打标签”。sim_time模拟总时长单位是秒。这里86400秒1天。initial初始条件。0表示从零水深开始也可以填1表示从上次模拟结果继续。step计算时间步长单位是秒。这个很关键取值要满足CFL条件后文细说。massint质量守恒统计的输出间隔单位是秒。建议和outinterval一致。outinterval结果输出间隔单位是秒。output输出类型选择。2.2 边界条件文件.bci怎么写才不报错边界条件boundary condition文件在参数文件里用bci关键字指定。格式如下Q 1 100 1800 200 Q 2 100 2400 300第一列Q表示流量边界第二列是边界编号第三列是流量值第四列是持续时间秒第五列是时间延迟秒。意思就是在模拟开始后的第200秒编号为1的边界开始注入1800秒的100 m³/s恒定流量。边界条件这里有几个高频坑网格编号必须和DEM文件的行列位置对应。这个不对应不会报错但流量会注到错误的位置。持续时间不能超过模拟总时长。如果你设了sim_time 86400但边界持续时间写的是1728002天模型会在模拟结束后还默认边界持续注水结果后面全是稳态流动白跑。多段流量过程线要衔接好。比如你要模拟一个洪峰过程流量是100、200、150三段每段持续3600秒那起始时间应依次设为0、3600、7200形成连续的过程线否则会有一段空白期没有流量输入。2.3 参数含义速查表参数名单位/取值含义说明常见错误sim_time秒模拟总时长把天当秒填模拟时长被严重缩短step秒计算时间步长设置过大模型数值发散报错massint秒质量守恒统计间隔设置过大水量平衡误差看不准outinterval秒结果文件输出间隔设置过小结果文件数量爆炸initial0或1初始水深条件设为1但没指定初始文件直接报错resroot字符串结果文件前缀路径目录不存在运行直接失败pth字符串降雨文件前缀文件名匹配不上降雨不生效ebc字符串蒸发文件前缀同上蒸发项被静默忽略2.4 时间步长怎么选CFL条件实测LISFLOOD-FP是显式数值格式时间步长必须满足CFL条件不然数值就会发散水深变成NaN整个模拟直接崩掉。CFL条件的简化判断是一个时间步内水流不能流过超过一个网格。公式可以粗略写成step ≤ cell_size / max_flow_speed其中max_flow_speed需要预估最大流速。比如你的研究区是平原区最大流速大概2 m/sDEM分辨率30米那时间步长不能超过15秒。我实际用下来平原区30米分辨率步长设8~10秒比较稳山区坡度大、流速快的区域步长要缩到2~5秒否则一跑就发散。一个实用的判断方法跑500个时间步后暂停看一眼质量守恒文件里的总水量如果出现非物理的增长或衰减说明步长可能过大了需要缩小。2.5 文件路径的坑WIndows/Linux下路径分隔符差异参数文件里的路径分隔符在Windows下用反斜杠\在Linux下用正斜杠/。很多人把Windows下写好的参数文件直接拷贝到Linux服务器跑结果报错找不到文件。解决办法很简单参数文件里统一用正斜杠/。Windows下很多软件能自动识别正斜杠路径Linux下当然也能识别。另一个容易忽略的小坑是文件名尽量不要带空格和中文部分版本的模型对非ASCII文件名支持不友好会莫名报错。3. results文件夹里的秘密输出文件全解析3.1 结果文件命名规则与内容对照模型跑完results目录下会生成一大堆文件。不少人打开文件夹直接懵了.mm、.mx、.sum、.csv、.asc一堆后缀不知道先看哪个。按我的经验先把它们分成三组第一组日志与统计.sum文件是质量守恒统计记录了每个时间步的总水量、进水量、出水量变化。.lis文件是运行日志对应每次运行的基本信息包括版本、参数文件内容、运行耗时。第二组空间结果.mm文件最大水深maximum water depth单位米。这是最常用的结果画洪水淹没范围图就靠它。.mx文件最大流量模数maximum flow单位m²/s表示网格之间最大单位宽度流量。这个文件可以用来分析洪峰传播路径。与DEM文件同名的.depth系列文件如果参数文件开了时序输出会生成多个带时间戳的水深快照。第三组时间序列.csv文件指定网格点的水深、流量时间序列便于做过程和实测值对比。3.2 深度解析.sum文件怎么读.sum文件是这样一段一段的t0 Total volume: 0.0000 Boundary inflow: 0.0000 rainfall: 0.0000 t100 Total volume: 1250.0000 Boundary inflow: 1250.0000 rainfall: 0.0000注意第二列的Total volume单位是立方米它是整个模拟域内当前时刻的总蓄水量。做水量平衡检查时要看的是Total volume的增长速率是否和边界输入流量一致。比如边界注水10 m³/s每个100秒时间步的总水量应该增加1000 m³。如果你看到的是增加1300 m³有30%的误差那就要检查单位或者时间步长了。我用这个办法抓到过两次单位错误非常有效。3.3 用Python快速读取结果文件LISFLOOD-FP输出的ASCII栅格文件其实就是带6行文件头的文本。用Python的numpy就能直接读取不需要额外安装GIS库。import numpy as np import pandas as pd import matplotlib.pyplot as plt def read_lisflood_asc(filepath): 读取LISFLOOD-FP输出的ASCII栅格文件 with open(filepath, r) as f: # 读取文件头 header {} for _ in range(6): line f.readline().strip().split() header[line[0]] float(line[1]) # 读取数据部分 data np.loadtxt(f) return data, header depth, header read_lisflood_asc(output/ccm.mm) print(f最大水深范围{depth.min():.3f} ~ {depth.max():.3f} m) # 绘制淹没范围 plt.figure(figsize(10, 6)) plt.imshow(depth, cmapBlues, vmin0) plt.colorbar(labelDepth (m)) plt.title(Maximum Water Depth) plt.show() # 读取栅格单元大小统计总淹没面积 cell_size header[cellsize] # 单位米 flooded_area (depth 0.01).sum() * cell_size * cell_size print(f淹没面积水深1cm{flooded_area / 1e6:.2f} km²)这里有个小细节LISFLOOD模拟的地形如果是带初始水深的小于某个阈值的网格可能不是真正的干涸而是数值上的残留。所以统计淹没范围时我会设定一个水深阈值通常1cm或5cm低于阈值的网格不计入淹没范围。.cvs结果读取用pandas即可。输出文件如果带BOM头pd.read_csv会识别异常加个encodingutf-8-sig就解决了。3.4 结果合理性检查的三个硬指标拿到结果后别急着出图先做三件事第一件事看淹没范围是否“贴地”。把.mm文件叠到DEM上如果高海拔区域出现大范围积水八成是单位问题或DEM负值问题——DEM存在“凹陷”区域sink水会聚集在这些假凹陷里。解决办法是在ArcGIS或QGIS里做一次填洼fill sinks预处理。第二件事看最大水深是否合理。平原河网区历史洪水的积水深度一般在0.5~3米之间。如果你算出来都是10米以上第一反应应该是检查单位而不是觉得“这次洪水百年一遇所以深”。大概率是流量单位搞错了或者步长太大数值发散了。第三件事对水量平衡。打开.sum文件把最后一个时刻的Total volume减去初始时刻的Total volume等于边界入流量乘以模拟总时长加上降雨总量减去蒸发量。如果两边差很多说明有数值泄漏或参数设置疏漏。4. 常见运行报错与排查技巧实录4.1 运行阶段报错速查表报错描述可能原因处理办法Error opening DEM fileDEM文件名拼错或路径不对检查大小写和文件是否存在NaN detected in simulation时间步长过大数值发散缩小step值到原来的1/3~1/5no cells above threshold流量太小入流没超过DEM高程检查bci边界流量单位或检查DEM高程单位boundary condition errorbci文件格式错误检查列数和数字格式末尾不能有多余空格time step exceeded设定的step太大按CFL条件重新估算internal write error输出目录不存在或无权限提前创建目录确保可写4.2 最坑的静默失败大气降水文件被忽略有次跑模拟模型没报错结果文件也能生成但淹没范围始终不变。排查到最后发现是降水量文件的前缀pth参数写错了模型根本没读到降雨数据导致整个模拟只有河道入流在起作用。LISFLOOD-FP读取降雨文件的方式是参数文件里pth rain_表示读取当前目录下所有以rain_开头的文件作为降雨数据。如果文件名写的是Rain_data.asc而参数文件写的是pth rain对不上就静默跳过了。我给这类静默失败总结了一个经验法则每次修改参数文件后先跑一个超短模拟比如5秒然后立刻看.sum文件里的水量变化如果入流量符合预期再跑正式模拟。这一步多花两分钟能省下后面几小时的排查时间。4.3 数据边界效应问题天然河道模拟通常会遇到边界效应模拟域边缘水位被人工地“垫高”或“悬空”。LISFLOOD-FP默认边界是封闭的水到边界就出不去了会在边界堆积。解决办法是给模拟域设置足够的缓冲区或者在边界加开敞边界条件open boundary。实际操作中把研究区向外扩展至少5~10个网格以减小边界效应对核心区域的影响。还有一种做法是把研究区裁剪范围扩大跑完后再用小范围掩膜截取核心区结果。我一般用前者简单直接。4.4 用日志文件反向定位问题当模型跑挂了先看.lis文件再按时间顺序倒着看.sum文件。.lis文件里记录了每一步的参数快照能帮你确认模型实际读进去的参数和你的预期是否一致。很多时候参数文件里的注释符用错了——LISFLOOD-FP注释符是#不是//也不是%。如果你用//注释模型会直接解析失败但报错信息往往不直接指向注释行而是说某行参数格式错误。一个细节参数文件里不要用制表符Tab作为分隔符模型解析时会按空格拆分Tab在某些编译版本下会解析出错。统一用空格是最稳的。5. 实战模拟一次完整的参数文件与结果解析过程前面把零散的知识点讲完了这里走一遍完整的实操流程把上面所有内容串起来。5.1 场景设定假设我们要模拟某平原河网区域在一次设计洪水过程中的淹没情况。DEM分辨率30米包含500列、400行共20万个网格。研究区面积约18 km²。水文数据设计洪水过程线历时12小时峰值出现在第6小时最大流量1200 m³/s。没有实测淹没范围数据用于验证所以需要特别留意结果合理性。5.2 参数文件完整配置# LISFLOOD-FP simulation for flood inundation mapping DEMfile dem_30m.asc flowdirfile flowdir.asc resroot output/flood_event sim_time 43200 initial 1 step 2 start 0 massint 600 outinterval 1800 output 3 bci river_boundary.bci pth rain_这里sim_time43200秒12小时。step2秒是保守设置因为研究区有部分河道坡度较大局部流速可能超过3 m/s30米分辨率下步长上限约10秒我取2秒来确保数值稳定。start 0表示从第0秒开始。initial 1在正式模拟中表示从零水深开始注意不同版本对initial的取值含义略有差异新版本中1表示冷启动旧版本可能不同看文档确认。massint和outinterval分别为600秒和1800秒意味着每10分钟生成一次质量统计每30分钟输出一次水深快照。5.3 边界条件文件设计Q 1 100 3600 0 Q 1 300 3600 3600 Q 1 600 3600 7200 Q 1 900 3600 10800 Q 1 1200 3600 14400 Q 1 900 3600 18000 Q 1 600 3600 21600 Q 1 300 3600 25200 Q 1 100 3600 28800这是把12小时的设计洪水过程线离散为8段恒定流量简化处理。每段流量持续1小时起始时间依次增加3600秒构成一个先涨后落的完整洪峰过程。5.4 结果解读实操模拟完成后检查output目录应有以下文件flood_event.sum # 质量守恒统计每隔600秒记录 flood_event.mm # 最大水深分布栅格 flood_event.mx # 最大流量模数栅格 flood_event-0001.asc # 第1800秒的水深快照 flood_event-0002.asc # 第3600秒的水深快照 ... dem_30m.depth # 与DEM同名的最终水深文件先看sum文件的最后几行t42600 Total volume: 24192000.0 Boundary inflow: 24192000.0 rainfall: 0.0如果按8段平均流量估算总入流量每段流量×3600秒之和100×3600 300×3600 600×3600 900×3600 1200×3600 900×3600 600×3600 300×3600 100×3600 4200×3600 15120000 m³。但是sum文件显示最后时刻总水量为24192000 m³比理论入流量多了约900万m³多出来的部分是降雨贡献。如果pth_dir参数指定了降雨数据这部分是正常的。如果没有降雨数据那就是边界条件重复注水检查bci文件的时间设置。再看.mm文件统计淹没范围是否合理。30米分辨率网格水深大于1cm的网格数量如果超过30000个约27 km²超出研究区面积就需要检查边界条件和DEM负值预处理。检查一下洪水传播时间。找到.hmax时间序列或对比不同时刻的快照洪峰到达下游的时间是否符合曼宁公式的粗略估算V (1/n) × R^(2/3) × S^(1/2)假设河道曼宁系数n0.035水力半径R约2米坡降S0.001则流速约2.1 m/s洪峰传播速度约等于流速12小时洪峰应该能传播约90 km。如果模拟结果中洪峰3小时就到下游边界说明阻力设置有问题或步长过大导致数值扩散过快。5.5 模型率定参数的取用经验LISFLOOD-FP里没有直接的曼宁系数参数设置阻力通过糙率文件friction file控制单位是曼宁n值。不同土地利用类型的糙率参考值地表类型曼宁n值硬质地面城市0.015~0.030农田0.035~0.045林地0.060~0.120河道0.030~0.050实测下来城市洪涝模拟中糙率抬高到0.05以上会让淹没范围显著扩大水深也更接近实际情况。原因是城市地表不仅有管道排水还有建筑阻水、街区微地形等这些在30米分辨率的DEM中根本不体现只能靠糙率补偿。6. 家里蹲几个月的实操心得权当结尾最后再聊几句不太会在文档里写的东西。LISFLOOD-FP这个模型上手不难但想跑出能说服审稿人、能对上实测数据的结果功夫全在数据处理和参数微调上。我见过太多人花大把时间折腾模型算法本身却连DEM的负值都没填平输出结果质量自然上不去。我个人实际跑下来的习惯了每一次模拟都保留一份完整的参数文件、输入数据清单和结果摘要。跑完一个方案立刻把.max水深图和.sum水量平衡截图存到一个固定的文件夹里命名带上工况编号。这样后面写报告、复现结果、给同事排查问题的时候效率能翻一倍。另外分享一个排查问题的小技巧当结果和预期对不上时不要急着改参数反复跑先做减法。把降雨去掉、把边界条件简化成恒定流量、把地形换成平整坡面一步步从最简单的场景测起确认每一层都能解释通了再逐步加回复杂度。这个方法帮我定位过无数个隐藏很深的配置错误也帮课题组新同学免去许多瞎试的弯路。希望你读完这篇之后至少能把单位、参数和结果文件这三座大山翻过去后面的路走起来就顺畅了。
返回列表