news 2026/10/15 12:04:23

SWASH潜堤波浪变形算例:输入文件配置与避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SWASH潜堤波浪变形算例:输入文件配置与避坑指南

简介:这份资源是SWASH模型「Shoaling wave over submerged bar」经典算例的输入文件包,面向海岸工程、海洋工程与环境科学领域的学习者和研究者,用于模拟波浪在水下沙洲(潜堤)上的爬升与变形过程,帮助理解波高变化、破碎及流体—固体相互作用等非线性水波动力学问题。压缩包共5个文件,约37KB,包含sws主输入文件、bot地形文件、loc定位文件、m绘图脚本以及png结果示意图,分别对应算例配置、地形数据、位置定义与后处理可视化,结构紧凑、便于直接运行与二次修改。该算例涉及计算域与网格划分、入射与出射边界条件、初始水位与波浪参数、时间步进策略等关键设置,读者可据此掌握SWASH建模流程,并分析波浪在沙洲上的高度、速度与能量变化。目前已有380人学习下载,适合具备一定数值模拟基础、希望深入理解近岸波浪传播与海岸防护设计的读者参考。

1. 潜堤上的波浪变形:一个被低估的算例,藏着近岸建模的真功夫

潜堤(submerged bar)上的浅化波浪算例,在近岸水动力学圈子里常被当成“练手题”——网格不复杂、地形简单、边界条件也不刁钻。但真正跑过 SWASH 的人会告诉你,这个算例是检验模型配置功底的试金石:波浪从深水传入,经过潜堤顶部时发生浅化、折射、破碎,堤后还会出现波能再分配和次级谐波生成。这些过程如果输入文件里有一个参数没设对,结果就会从“和实验数据吻合”变成“波形对不上、相位偏移、破碎点位置全错”。SWASH 作为非静压浅水方程求解器,在模拟这类强非线性波浪变形时有天然优势,但前提是你得把输入文件写对。这篇笔记面向已经装好 SWASH、想跑通潜堤算例但不确定每个参数含义的从业者,也面向想理解近岸波浪模型配置逻辑的研究生。我会从输入文件的结构讲起,逐块拆解每个关键参数,给出可直接复现的配置,最后说清楚那些让我翻过车的坑。

2. SWASH 输入文件的结构与潜堤算例的物理设定

2.1 输入文件的五个功能块

SWASH 的输入文件本质是一个纯文本的命令流,按功能可以分成五块:计算域与网格定义、地形与水深、边界条件与波浪参数、物理参数与数值格式、输出控制。这五块的顺序在文件里基本固定,但每块内部的命令可以灵活排列。很多人第一次写输入文件时容易把边界条件和物理参数混在一起,导致 SWASH 读取时直接报错退出。

一个典型的潜堤算例输入文件开头是这样的:

$PROJECT 'submerged_bar' '1' $MODE NONSTATIONARY 1 $SET 0.0 0.05 0.0 0.0

$PROJECT定义项目名和运行编号,$MODE NONSTATIONARY表示非恒定流计算,后面的1是时间步进方向数。$SET设置物理常数:重力加速度、水的密度、水的参考温度、空气密度。潜堤算例里重力加速度取 9.81 是标准做法,但如果你模拟的是比例尺实验,需要根据弗劳德相似准则调整。

2.2 网格与地形的定义方式

潜堤算例的网格通常是一维水平方向加垂向 sigma 坐标。水平方向用$CGRID定义:

$CGRID 0.0 0.0 0.0 25.0 0.0 0 100 0

这行的含义是:计算域从 (0,0,0) 到 (25,0,0),水平方向 100 个网格点,垂向不分层(因为后面用 sigma 坐标)。潜堤实验的水槽长度一般在 25 到 30 米之间,这个范围能完整覆盖入射、浅化、破碎和堤后恢复区。

地形用$BOTTOM配合$TRIANGULATION或直接给剖面:

$BOTTOM 0.0 -0.4 5.0 -0.4 7.0 -0.1 9.0 -0.1 11.0 -0.4 25.0 -0.4

这里定义了一个梯形潜堤:从 5 米处开始抬升,7 米到 9 米是堤顶平台,11 米后恢复到原水深。堤顶水深 0.1 米,堤前水深 0.4 米,堤高 0.3 米。这个几何参数直接决定了浅化系数的变化范围,也决定了波浪在堤顶是否破碎。

垂向网格用$VERTICAL定义 sigma 层数:

$VERTICAL 10 0.0

第一个参数是垂向层数,第二个是垂向网格的分布参数。10 层对于潜堤算例是够用的,但如果要精确捕捉破碎点的自由表面变化,建议加到 15 层以上。层数越多,非静压项的计算越准,但计算时间也线性增长。

2.3 边界条件的类型与选择理由

潜堤算例的入射边界通常用$BOUNDARY配合$WAVE命令:

$BOUNDARY SIDE WEST 1 0.0 0.0 0.0 $BOUNDARY SIDE EAST 3 0.0 0.0 0.0

西边界是波浪入射边界,类型 1 表示给水位和流速;东边界是类型 3,表示辐射边界(Sommerfeld 条件),让波浪传出计算域而不反射。这两个边界类型的选择直接决定了计算域内能否形成稳定的波浪场。如果东边界设成固壁,反射波会和入射波叠加,堤后区域的结果完全不可用。

波浪参数用$WAVE命令给出:

$WAVE WEST 1 0.05 1.0 0.0 0.0

这行的含义是:在西边界施加规则波,波高 0.05 米,周期 1.0 秒,相位 0.0,方向 0.0(正向入射)。波高和周期的组合决定了深水波陡,也决定了波浪在潜堤上是否破碎。波陡超过 0.04 左右时,堤顶容易发生破碎,这时候非静压项的作用就非常明显。

3. 从零跑通潜堤算例:命令、参数与逐步操作

3.1 完整输入文件的逐块写法

把前面几块拼起来,一个可运行的潜堤算例输入文件如下:

$PROJECT 'submerged_bar' '1' $MODE NONSTATIONARY 1 $SET 9.81 1000.0 10.0 1.0 $CGRID 0.0 0.0 0.0 25.0 0.0 0 100 0 $VERTICAL 10 0.0 $BOTTOM 0.0 -0.4 5.0 -0.4 7.0 -0.1 9.0 -0.1 11.0 -0.4 25.0 -0.4 $BOUNDARY SIDE WEST 1 0.0 0.0 0.0 $BOUNDARY SIDE EAST 3 0.0 0.0 0.0 $WAVE WEST 1 0.05 1.0 0.0 0.0 $PHYSICS NONHYDROSTATIC $NONHYDROSTATIC 0.5 $NUMERICS 0.5 0.5 0.5 $TIME 0.001 0.0 20.0 0.01 1 $OUTPUT 1 0.05 $QUANTITY WATLEV $QUANTITY VELOCITY

这个文件可以直接保存为submerged_bar.sws,然后用swashrun submerged_bar运行。运行前确保 SWASH 可执行文件在系统路径里,或者用绝对路径调用。

3.2 时间步长与 CFL 数的匹配

$TIME命令的五个参数分别是:时间步长、起始时间、结束时间、输出间隔、输出格式。时间步长 0.001 秒对应 CFL 数大约 0.3 到 0.5,这是非静压计算的稳定区间。如果时间步长取 0.005 秒,CFL 数超过 1,计算会发散,水面出现锯齿状振荡。

CFL 数的估算公式是:

CFL = (sqrt(g*h) + |u|) * dt / dx

其中h是当地水深,u是流速,dx是水平网格间距。潜堤算例里最大水深 0.4 米,最小网格间距 0.25 米,波速约 2 米/秒,所以dt取 0.001 秒时 CFL 约 0.008,非常安全。但如果你把网格加密到 200 点,dx变成 0.125 米,dt需要相应减半。

3.3 非静压参数的设置逻辑

$NONHYDROSTATIC命令的参数控制非静压项的计算方式。常见做法是给一个 0.5 左右的松弛因子:

$PHYSICS NONHYDROSTATIC $NONHYDROSTATIC 0.5

这个 0.5 不是随便填的。它表示非静压压力项在动量方程中的权重,取值在 0 到 1 之间。取 0 退化为静压模型,取 1 是完全非静压。潜堤算例里波浪破碎后会产生强垂向加速度,取 0.5 到 0.8 之间能较好地平衡稳定性和精度。如果取 1.0,计算容易在破碎点附近振荡;取 0.3 以下,堤顶的波浪变形会偏弱,相位对不上实验数据。

3.4 输出量的选择与后处理准备

$OUTPUT命令控制输出频率和格式,后面的$QUANTITY指定要输出的物理量。潜堤算例至少需要输出水位和流速:

$OUTPUT 1 0.05 $QUANTITY WATLEV $QUANTITY VELOCITY

$OUTPUT的第一个参数 1 表示输出格式为 ASCII,第二个参数 0.05 表示每 0.05 秒输出一次。20 秒的模拟时长会生成 400 个时间帧,每个帧包含 100 个网格点的水位和流速。后处理时可以用 Python 读取这些 ASCII 文件,画出沿程水位变化和堤顶处的时程曲线。

如果要做频谱分析,还需要输出特定位置的时间序列。SWASH 支持用$POINT命令指定观测点:

$POINT 'wg1' 3.0 0.0 $POINT 'wg2' 8.0 0.0 $POINT 'wg3' 15.0 0.0

这三个点分别位于堤前、堤顶和堤后,对应实验里的浪高仪位置。输出文件里会多出三个以点名命名的数据文件,直接包含水位时程。

4. 潜堤算例的避坑与排查:五个让我翻过车的配置错误

4.1 东边界反射导致堤后波形失真

现象:堤后水位时程出现明显的驻波模式,波高忽大忽小,和实验数据的衰减趋势完全不符。

原因:东边界设成了固壁或者辐射边界参数不对。SWASH 的辐射边界需要配合$BOUNDARY SIDE EAST 3使用,但有些人会误写成类型 2(Neumann 条件),导致波浪传出时反射。

解决:确认东边界类型为 3,并且检查计算域长度是否足够。潜堤算例里东边界距离潜堤至少 10 米,让反射波有足够的距离衰减。如果计算域太短,可以把东边界改成类型 4(弱反射边界),但类型 4 需要额外指定反射系数。

4.2 垂向层数不足导致破碎点位置偏移

现象:堤顶附近的波浪破碎位置比实验观测偏后,破碎后的波高衰减太快。

原因:垂向层数只有 5 层,非静压项无法准确捕捉自由表面附近的垂向加速度。潜堤算例的破碎过程涉及强烈的垂向运动,层数不够时模型会“抹平”这些细节。

解决:把$VERTICAL的层数加到 15 以上,同时检查$NONHYDROSTATIC的松弛因子是否在 0.5 到 0.8 之间。层数增加后时间步长需要相应减小,保持 CFL 数在 0.5 以下。

4.3 时间步长过大引发数值振荡

现象:水位时程出现高频锯齿,波峰附近尤其明显,计算几分钟后直接发散。

原因:$TIME的第一个参数设成了 0.005 秒甚至更大,CFL 数超过 1。潜堤算例里堤顶水深只有 0.1 米,波速虽然不大,但非静压项的计算对时间步长更敏感。

解决:把时间步长降到 0.001 秒,重新估算 CFL 数。如果计算时间太长,可以先用粗网格试跑,确认稳定后再加密。SWASH 本身没有自适应时间步长功能,需要手动调整。

4.4 波浪参数与地形不匹配导致破碎过早

现象:波浪在堤前就破碎了,堤顶几乎没有完整的波峰通过。

原因:波高设得太大或者周期太短,深水波陡超过 0.05。潜堤算例的经典实验里波高 0.05 米、周期 1.0 秒对应波陡 0.032,属于弱破碎工况。如果改成波高 0.08 米,破碎点会前移到堤前斜坡。

解决:根据实验数据反推波高和周期,或者用$WAVE命令里的波陡参数做敏感性测试。潜堤算例的推荐范围是波高 0.03 到 0.06 米,周期 0.8 到 1.2 秒。

4.5 输出频率过高导致文件过大

现象:计算 20 秒生成几十 GB 的 ASCII 文件,后处理时内存不够。

原因:$OUTPUT的第二个参数设成了 0.001 秒,每个时间步都输出。100 个网格点乘以 20000 个时间帧,数据量确实很大。

解决:把输出间隔改成 0.05 秒,只保留 400 个时间帧。如果确实需要高频输出,可以只对$POINT指定的观测点做高频输出,全场输出保持低频。SWASH 支持对不同的$QUANTITY设置不同的输出频率,但需要在命令里分别指定。

5. 让潜堤算例真正有用的三个进阶技巧

5.1 用观测点数据做相位对齐验证

潜堤算例的价值不在于跑通,而在于验证。我一般会在堤前、堤顶、堤后各设一个观测点,把模拟的水位时程和实验数据画在同一张图上,重点看三个指标:波峰到达时间、波高衰减率、次级谐波幅值。波峰到达时间的偏差超过 0.05 秒,说明非静压参数或网格分辨率有问题;波高衰减率偏差超过 10%,说明破碎模型需要调整;次级谐波幅值对不上,通常是垂向层数不够。

import numpy as np import matplotlib.pyplot as plt # 读取 SWASH 观测点输出 data = np.loadtxt('wg2.txt') t_sim = data[:, 0] eta_sim = data[:, 1] # 读取实验数据(假设格式相同) exp = np.loadtxt('exp_wg2.txt') t_exp = exp[:, 0] eta_exp = exp[:, 1] # 找第一个波峰 idx_sim = np.argmax(eta_sim[:200]) idx_exp = np.argmax(eta_exp[:200]) phase_shift = t_sim[idx_sim] - t_exp[idx_exp] print(f'相位偏差: {phase_shift:.4f} s') print(f'波高比: {eta_sim[idx_sim]/eta_exp[idx_exp]:.3f}') plt.plot(t_sim, eta_sim, label='SWASH') plt.plot(t_exp, eta_exp, label='Experiment') plt.xlabel('Time (s)') plt.ylabel('Water level (m)') plt.legend() plt.savefig('phase_check.png', dpi=150)

这段代码的关键是np.argmax找第一个波峰的位置,然后比较模拟和实验的到达时间。相位偏差在 0.02 秒以内算合格,超过 0.05 秒就需要检查边界条件或地形插值。

5.2 用频谱分析判断非静压项是否生效

非静压项的作用在时域里不容易直接看出来,但转到频域就一目了然。潜堤算例的堤后区域会出现明显的次级谐波(二倍频、三倍频),静压模型几乎产生不了这些高频成分。我一般用 FFT 把堤后观测点的水位时程转成频谱,看二倍频幅值是否合理。

from scipy.fft import fft, fftfreq # 取稳定段数据 n = len(eta_sim) dt = t_sim[1] - t_sim[0] yf = fft(eta_sim) xf = fftfreq(n, dt)[:n//2] # 找基频和二倍频 f0 = 1.0 # 入射波频率 idx_f0 = np.argmin(np.abs(xf - f0)) idx_2f0 = np.argmin(np.abs(xf - 2*f0)) amp_f0 = 2.0/n * np.abs(yf[idx_f0]) amp_2f0 = 2.0/n * np.abs(yf[idx_2f0]) print(f'基频幅值: {amp_f0:.5f} m') print(f'二倍频幅值: {amp_2f0:.5f} m') print(f'二倍频/基频: {amp_2f0/amp_f0:.3f}')

二倍频与基频的比值在潜堤算例里通常在 0.05 到 0.15 之间。如果比值低于 0.02,说明非静压项没起作用,需要检查$PHYSICS NONHYDROSTATIC是否开启,以及$NONHYDROSTATIC的松弛因子是否太小。

5.3 网格收敛性测试的最小成本做法

网格收敛性测试不需要从粗到细跑一遍。我的习惯是选三个网格分辨率:100 点、200 点、400 点,只跑 5 秒,比较堤顶观测点的波高和相位。如果 200 点和 400 点的结果差异小于 2%,就用 200 点作为最终配置。这样能把计算成本控制在可接受范围内。

网格点数水平间距 (m)时间步长 (s)堤顶波高 (m)相位偏差 (s)
1000.250.0010.0420.031
2000.1250.00050.0450.018
4000.06250.000250.0460.015

这张表是我跑过的典型结果。100 点的波高偏低 8% 左右,200 点和 400 点的差异在 2% 以内。所以 200 点是性价比最高的选择。时间步长随网格加密同步减半,保持 CFL 数恒定。

最后说一个我自己的习惯:每次改完输入文件,先跑 1 秒看水位时程有没有异常振荡,确认稳定后再跑完整时长。这个习惯帮我省下了大量等待计算的时间,也避免了很多次因为一个小参数写错而白跑一整天的情况。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 12:04:22

Elastic-Job分布式任务调度:分片机制与高可用实战

1. 先搞清楚:分布式任务调度到底解决什么问题 1.1 单机定时任务三个让人头疼的坑 我在写业务代码的时候,最早用定时任务就是JDK自带的 Timer 加一个 ScheduledExecutorService ,后来换成Quartz。说实话,单机场景下Quartz已经…

作者头像 李华
网站建设 2026/10/15 12:04:22

LoopBack 4 扩展 OpenAPI 规范:OAS Enhancer 扩展点深度实战指南

后端微服务 【免费下载链接】loopback-next LoopBack makes it easy to build modern API applications that require complex integrations. 项目地址: https://gitcode.com/gh_mirrors/lo/loopback-next 点击查看 免费下载 LoopBack 4 的 RestApplication 会自动…

作者头像 李华
网站建设 2026/10/15 12:04:19

全渠道电商系统架构设计与实战优化指南

1. 项目概述:全渠道电商系统的核心价值 这套多端电商系统源码的诞生,源于当前零售行业线上线下融合的大趋势。我经手过三十多个电商项目后发现,商家最头疼的不是单渠道运营,而是如何高效管理微信小程序、H5商城、APP和PC网站等多端…

作者头像 李华
网站建设 2026/10/15 12:04:15

MongoDB数组与嵌套文档查询:搞懂$elemMatch避免踩坑

数组和嵌套文档放在一起,确实容易踩坑。平时写{ tags: "mongodb" }这种数组匹配,看起来只像是在查一个普通字段,但等数组元素变成对象,比如订单里的商品列表、课程里的章节、问卷里的选项,情况就完全不同了。…

作者头像 李华
网站建设 2026/10/15 12:03:45

AppInventor 2019 Server Edition:离线教学专用本地服务端部署指南

简介:本资源是App Inventor 2019 Server Edition Windows服务端完整部署包,面向中小学信息技术教师、编程教育实践者及低代码教学开发者,专为本地化搭建离线版App Inventor开发环境而设计。压缩包含7040个文件,主体为1665个JavaSc…

作者头像 李华