简介:这份研究报告文档以江苏省兴化市平旺湖为研究对象,借助MIKE21 FM二维水动力模型构建湖区水动力模型,对比退圩还湖工程实施前后20年一遇洪水条件下湖区河道槽蓄能力与洪水特征值的变化,适合水利、水文、环境工程方向的学生、科研人员及规划设计者参考。全文围绕退圩还湖前后的地形重塑、水体流速与流场、淹没水深、蓄洪量等内容展开,并给出平旺湖网格划分、边界条件与模拟结果分析,可作为同类湖泊退圩还湖工程的理论参考与建模思路借鉴。资源包内仅含1个docx文档,约21KB,即研究报告正文,便于直接阅读与引用。目前已有96人学习,篇幅精炼但覆盖模型构建、方案对比与结论全过程。读者可从中获取MIKE21 FM在湖泊水动力模拟中的具体应用流程、退圩还湖防洪效益的量化结论,以及槽蓄能力变化的分析方法。
1. 退圩还湖工程洪水模拟为什么绕不开MIKE21 FM
里下河腹部地区的湖泊湖荡被围垦多年,圩区种养殖把自由水面蚕食殆尽,调蓄库容锐减,水动力条件恶化。平旺湖5.169 km²的保护面积上分布着6个圩区,退圩还湖前湖泊基本没有明显岸线,水体流动停滞,防洪排涝能力严重退化。要论证退圩还湖到底能不能把调蓄能力找回来,一维模型就不够用了——它处理不了湖区复杂的流态和双向往复流。MIKE21 FM采用无结构网格,能贴体拟合湖岸线和圩埂边界,配合闸泵调度边界条件,可以把退圩还湖前后湖区流场、断面流速、淹没水深和槽蓄量的变化算清楚。这套建模思路对做湖泊水动力分析的从业者来说,是可以直接迁移到其他退圩还湖项目的技术框架。
2. 平旺湖二维水动力模型构建:从地形xyz到FM网格
模型能不能算准,取决于三件事:地形数据是否干净、网格是否贴合边界、开边界条件是否合理。平旺湖的地形数据要分别处理退圩还湖前后两套,转换成.xyz格式后导入MIKE Zero的Mesh Generator。这一步看起来只是导数据,实际上网格质量和地形插值的平滑程度直接决定了后续计算的稳定性。
2.1 地形数据准备与网格生成参数
退圩还湖前的地形反映的是圩区密布、塘埂交错的原始状态;退圩还湖后湖底经过重塑,平均高程约-0.5 m,常水位水深控制在1.5 m左右。两套地形分别建网格:还湖前网格1483个、节点869个;还湖后网格1708个、节点992个。节点数增加说明还湖后湖岸线变复杂了,环湖堤防和新增岛屿都需要更密的网格来刻画。
生成网格时通常先用较粗的网格做一次试算,确认计算不发散后再局部加密。常见做法是给圩埂和堤防线附近设置加密区,最大网格面积控制在500~1000 m²以内。下面是生成.xyz地形文件并检查数据的Python示例:
import numpy as np import pandas as pd # 读取原始地形散点数据,格式为 x, y, z df = pd.read_csv("pingwang_before.xyz", sep=r"\s+", header=None, names=["x", "y", "z"]) # 剔除异常高程点:保留高程在 -3.0 到 5.0 m 之间的数据 mask = (df["z"] >= -3.0) & (df["z"] <= 5.0) df_clean = df[mask].copy() # 按空间范围裁剪,确保只在湖区+下官河范围内插值 df_clean = df_clean[(df_clean["x"] >= 400000) & (df_clean["x"] <= 410000)] df_clean = df_clean[(df_clean["y"] >= 3650000) & (df_clean["y"] <= 3660000)] # 输出清洗后的xyz文件,Mesh Generator可直接导入 df_clean.to_csv("pingwang_before_clean.xyz", sep=" ", header=False, index=False, float_format="%.3f") print(f"清洗前点数:{len(df)},清洗后点数:{len(df_clean)}")这段代码做了三件事:过滤异常高程、按空间范围裁剪、输出规范化的.xyz文件。参数方面,高程上下限按当地实测地形取值范围设定,本例取-3.0到5.0 m;空间裁剪范围用平面坐标框定,避免把区域外的散点混进来。导入Mesh Generator之后,插值方法一般选自然邻点插值或反距离加权,地形的平滑次数不宜超过3次,否则会把圩埂等关键微地形抹掉。
2.2 开边界、初始条件与模拟时段设置
平旺湖模型设了两个开边界:上边界取在下官河入口断面,给定20 a一遇洪水过程线;下边界取在下官河出口断面,给定20 a一遇水位过程线。初始水位恒定1.08 m,初始流速设为0。模型模拟时段为2003年6月29日11:00至7月15日16:00,时间步长1800 s,总模拟步数778步。
| 参数项 | 退圩还湖前 | 退圩还湖后 |
|---|---|---|
| 网格数 | 1483 | 1708 |
| 节点数 | 869 | 992 |
| 初始水位 | 1.08 m | 1.08 m |
| 初始流速 | 0 | 0 |
| 时间步长 | 1800 s | 1800 s |
| 模拟步数 | 778 | 778 |
| 上边界 | 下官河入口洪水过程 | 下官河入口洪水过程 |
| 下边界 | 下官河出口水位过程 | 下官河出口水位过程 |
时间步长的选取需要兼顾稳定性和计算效率。1800 s(30分钟)对于湖区缓流来说是合理的,CFL数不会有问题。如果算出来出现发散,先检查网格最小边长和时间步长的匹配关系,再排查地形插值有没有出现负水深。
注意:初始水位不要随意设成0。里下河地区湖荡常水位一般在1.0 m左右,初始水位设低了模型需要额外时间收敛,前几百步的结果不可用。
3. MIKE21 FM水动力参数率定与断面验证怎么做
参数率定是模型能不能信的关键。MIKE21 FM里影响最大的两个参数是糙率n和涡黏系数。很多初学者一上来就把涡黏系数调大试图让计算稳定,结果流场被过度抹平,断面流速算出来偏低。正确的顺序是先固定涡黏系数用默认值,率定糙率,糙率对齐了再回头看涡黏系数是否需要微调。
3.1 糙率n的取值区间与率定方法
天然河道的糙率取值范围一般在0.025~0.040之间。平旺湖模型的率定糙率区间取0.030~0.035,经率定后n取0.035。率定过程是:先用0.030算一遍,对比验证断面的水位和流速;再用0.035算一遍,看误差往哪个方向变化。如果模拟水位高于实测水位,说明糙率偏大,需要往小调;反之则往大调。
import mikeio # 读取糙率率定结果中的断面水位时间序列 dfs0 = mikeio.read("section_1_1_n0035.dfs0") water_level = dfs0["Water Level"].to_numpy() time = dfs0.time # 提取洪峰对应时刻的水位值 peak_idx = water_level.argmax() print(f"洪峰时刻:{time[peak_idx]},洪峰水位:{water_level[peak_idx]:.3f} m") # 与实测报告中的断面平均水位对比 observed = 1.85 # 示例值,来自退圩还湖项目报告 error_pct = abs(water_level[peak_idx] - observed) / observed * 100 print(f"水位相对误差:{error_pct:.2f}%")这里用mikeio读取.dfs0结果文件,提取洪峰水位并计算与实测值的相对误差。参数说明:dfs0文件存的是时间序列,名称为Water Level;observed值来自《兴化市退圩还湖项目报告》里的下官河出口断面实测数据。率定合格的标准是水位误差控制在0.1%以内。
3.2 涡黏系数与Smagorinsky公式
涡黏系数采用Smagorinsky公式计算,默认参数取0.28。Smagorinsky系数的作用是控制水平涡黏性,值越大流场越平滑、越不容易发散,但也会削弱局部流速梯度。平旺湖湖区属于缓流浅水环境,0.28这个默认值不需要大改。如果退圩还湖后湖区流速计算结果变化幅度太小,可以把系数降到0.20左右再试算一次,对比断面流速的变化。
3.3 验证断面误差控制与结果评判
验证断面选在下官河1-1断面,分别用10 a一遇和20 a一遇来水条件做验证。结果如下:
| 验证工况 | 糙率n | 水位误差 | 流速误差 |
|---|---|---|---|
| 10 a一遇 | 0.035 | < 0.1% | < 8% |
| 20 a一遇 | 0.035 | < 0.1% | < 7% |
水位误差控制在0.1%以内,20 a一遇的流速误差在7%以内,10 a一遇在8%以内。这个精度对于退圩还湖工程的防洪效益论证是够用的。验证时需要注意的是:断面平均流速的提取方式要和实测报告的统计口径一致,如果实测给的是断面平均流速,模型结果就不能用最大点流速去对比。
提示:率定和验证不要用同一场洪水。用2003年6月那场洪水率定,验证最好用另一年份的洪水过程,否则误差好看但没有外推能力。
4. 退圩还湖前后槽蓄能力与洪水特征对比实战
模型率定通过之后,真正的分析才开始。平旺湖项目的核心问题是:退圩还湖到底让湖区的调蓄能力恢复了多少?防洪效益体现在哪些指标上?分析路径是沿下官河从上游到下游布设监测断面,提取洪峰流量、流速、淹没水深和蓄洪量四个指标做前后对比。
4.1 槽蓄量与下泄流量的提取方法
选取下官河中游2-2断面和下游1-1断面作为监测断面。退圩还湖工程实施后,下游断面下泄流量减小了0.96 m³/s,槽蓄量增加了2.1 m³/s。槽蓄量增加意味着河道中段多“存”了水,洪峰被削平了,下游的防洪压力自然减轻。
import mikeio import numpy as np # 读取两个断面的流量时间序列 dfs0_mid = mikeio.read("section_2_2_discharge.dfs0") dfs0_down = mikeio.read("section_1_1_discharge.dfs0") q_mid = dfs0_mid["Discharge"].to_numpy() q_down = dfs0_down["Discharge"].to_numpy() time = dfs0_mid.time # 计算洪峰流量 peak_mid = q_mid.max() peak_down = q_down.max() # 槽蓄量增量 = 中游洪峰 - 下游洪峰(简化估算) storage_increase = peak_mid - peak_down print(f"中游2-2断面洪峰流量:{peak_mid:.2f} m³/s") print(f"下游1-1断面洪峰流量:{peak_down:.2f} m³/s") print(f"槽蓄量增量:{storage_increase:.2f} m³/s") # 计算退圩还湖前后下游断面洪峰流量差 q_down_before = 15.30 # 还湖前下游洪峰,示例值 q_down_after = q_down_before - 0.96 print(f"下泄流量削减量:{q_down_before - q_down_after:.2f} m³/s")这段代码从两个断面的.dfs0文件中读取流量过程线,提取洪峰流量并计算槽蓄量增量。参数说明:Discharge是MIKE结果文件中的流量项名称;q_down_before来自退圩还湖前的模拟结果,需要在同一模型中切换地形文件重新计算才能得到。实际项目中两个工况要分别建模型文件夹,不要混在一起跑。
4.2 断面最大流速与湖区流场变化
退圩还湖前河道断面最大水体流速为0.057 m/s,退圩还湖后为0.085 m/s。行洪至370 h时,还湖后流速相比还湖前增长率达到最大,流速增大了0.046 m/s。流速增大意味着湖区水体交换加快,不易产生淤积,水生态环境也会跟着改善。
流场的变化更有意思:退圩还湖后湖区水体在周边闸泵的控制调度下呈南北往复流动。这种往复流是湖泊自由水面恢复后的典型流态,说明平旺湖整体与下官河连通性变好了。
4.3 淹没水深与蓄洪量过程线对比
淹没水深和蓄洪量是防洪效益最直观的两个指标。20 a一遇条件下,退圩还湖后湖区最大淹没水深减小约0.02 m,蓄洪量在行洪至280 h时减小最大,减小量为1.19×10⁶ m³。
| 指标 | 退圩还湖前 | 退圩还湖后 | 变化量 |
|---|---|---|---|
| 下游断面下泄流量 | 基准值 | 减小 | -0.96 m³/s |
| 河道槽蓄量 | 基准值 | 增加 | +2.1 m³/s |
| 断面最大流速 | 0.057 m/s | 0.085 m/s | +0.028 m/s |
| 最大淹没水深 | 基准值 | 减小 | -0.02 m |
| 蓄洪量(280 h) | 基准值 | 减小 | -1.19×10⁶ m³ |
淹没水深减小0.02 m看起来不大,但放到整个湖区面积上换算成蓄洪量就是百万立方米级别的差异。这两个指标要合在一起看,不能只报淹没水深减小而忽略蓄洪量的变化过程。
注意:蓄洪量的减小有两种可能的原因——一种是退圩还湖后调蓄能力增强,洪水被更多地蓄在河道里;另一种是湖区面积缩小导致总蓄水量下降。平旺湖项目里排泥场占用了0.79 km²,分析时要区分排泥场占用和调蓄能力提升各自贡献了多少。
5. 从dfs结果到工程判据的进阶处理技巧
算完模型只是第一步,把.dfsu和.dfs0结果文件转成能给评审专家看的图表,才是交付的关键。MIKE Zero自带的后处理工具能出图,但批量提取数据、做多工况对比,用Python的mikeio库效率高得多。
5.1 批量提取淹没水深包络
20 a一遇工况下,需要提取整个模拟时段内的最大淹没水深分布。逐个时间步翻结果文件不现实,用mikeio读全时段然后取最大值:
import mikeio import numpy as np # 读取整个模拟时段的dfs1结果文件 dfs1 = mikeio.read("pingwang_after_20a.dfs1") # 获取淹没水深项,逐时间步取最大值 depth = dfs1["Total water depth"].to_numpy() # shape: (time, nodes) max_depth = np.max(depth, axis=0) # 将最大淹没水深写回新的dfs1文件 max_depth_da = dfs1["Total water depth"][0].copy() max_depth_da.values = max_depth max_depth_da.name = "Max inundation depth" dfs1_out = mikeio.Dataset([max_depth_da]) dfs1_out.to_dfs("pingwang_after_max_depth.dfs1") print(f"最大淹没水深:{max_depth.max():.2f} m") print(f"最小淹没水深:{max_depth.min():.2f} m")这段代码读取整个时序的.dfs1文件,对每个网格节点取时间维最大值,输出一张最大淹没水深包络图。参数说明:Total water depth是MIKE结果中水深项的默认名称,如果模型里改了名称需要对应调整;输出的dfs1文件可以直接导入MIKE Zero的Result Viewer出彩色等值线图。
5.2 多工况对比的自动化脚本框架
平旺湖项目至少涉及退圩还湖前后两个工况,每个工况还要跑10 a一遇和20 a一遇两个频率。四个算例如果用GUI逐个点,重复劳动太多。常见做法是建一个算例目录结构,用Python脚本批量生成输入文件、调用MIKE计算引擎、采集结果。核心逻辑是把地形文件、边界条件文件和参数文件作为变量,其余保持模板不变。判断模型收敛是否正常,看的是计算日志里的CFL数和总水量平衡误差,CFL超过1就要缩时间步长,水量平衡误差超过1%就要检查边界条件有没有设错。
提示:批量跑算例时,每个算例单独建一个文件夹,输出结果不要覆盖上一次的。排泥场占用、圩埂拆除范围这些地形差异要通过不同的.xyz文件区分,不要在同一个网格文件里改。
本文还有配套的精品资源,点击获取