Fluent船体瞬态仿真:VOF重叠网格与六自由度UDF实践

发布时间:2026/10/26 6:31:00
Fluent船体瞬态仿真:VOF重叠网格与六自由度UDF实践

简介:面向船舶水动力与CFD方向的学习者及工程人员,此案例聚焦Wigley船体在逆海波浪中航行时的升沉与纵摇,给出可直接复现的Fluent瞬态仿真设置。案例用VOF模型求解明渠流动,用明渠波浪边界生成浅层波浪,用动态网格刻画船体运动,并用UDF把运动约束为4个自由度;出口处引入数值海滩,以抑制波浪反射造成的非物理结果,对理解造波、动网格和边界处理这几个环节很有帮助。压缩包为zip格式,共2个文件、约42.4MB,主体是Fluent案例与设置文件(.gz),另附UDF源码文件(.c),可用于对照学习自由度约束的实现方式,或在此基础上调整参数。目前已有163人学习下载,适合具备一定Fluent基础、希望从入门算例过渡到船舶波浪运动仿真的读者参考。

1. 船体瞬态仿真的真实门槛:稳态算完为什么还要再跑一遍

船体阻力预报跑到稳态 RANS,半天能出一版结果,不少人到这一步就交差了。真到方案评审,对方问的是迎浪状态下阻力峰值多少、艏部涡脱落频率会不会和螺旋桨叶频撞上、垂荡纵摇的幅值响应曲线长什么样,这些稳态算不出来。用 Fluent 做船体 CFD 瞬态仿真,核心不是把求解器里的 Steady 切成 Transient 就完事,而是要把多相流自由面、重叠网格、六自由度被动运动和湍流模型重新配成一套自洽的组合。这套流程适合已经跑过稳态船体绕流、想往非定常阻力与姿态响应推进的从业者,也适合做耐波性、操纵性前期评估的团队。下面按实际拆解的步骤展开,从模型选型到网格组装,再到 UDF 挂载和结果验证,每一步给出可抄的参数和容易翻车的位置。

2. 物理模型与求解器选型:四层配置决定瞬态结果的上限

瞬态船体绕流的失败,八成不是时间步的问题,而是模型搭配从第一步就错了。船体在水面航行,涉及自由面、湍流边界层、刚体运动三个物理场,Fluent 里对应多相流模型、湍流模型、动网格三条设置线,再叠加压力-速度耦合的瞬态推进格式。这四层里任何一层用稳态那套默认值,后面的时间步和 UDF 都是白搭。

2.1 多相流模型:VOF 在船体自由面里的位置

船体绕流要捕捉水线面、艏波、艉部兴波,VOF 是常规选择。欧拉多相流模型适合气泡流、颗粒流那种相间强耦合的场景,船体自由面不需要相间拖曳力,用欧拉模型反而把自由面抹糊。混合模型更不行,它假设相间速度差很小,船体艏部的水气界面速度差很大,直接失真。

VOF 设置里有几个参数要盯住。界面重构格式选 Geo-Reconstruct,它对自由面的锐利度最好,代价是每个时间步多一次几何重构;Compressive 格式在 Fluent 里更稳一些,但界面会稍微扩散。我做船体瞬态一般先用 Geo-Reconstruct 跑短时程看界面形态,如果出现界面破碎或者相分数振荡,退到 Compressive 再对比。表面张力对船体这种特征尺度(米级)影响很小,除非做缩尺模型到厘米级才需要打开,连续表面张力模型配合 CSF 格式,系数保持默认 0.0728 N/m 即可。

相设置里主相选空气、次相选水,注意把水的密度和黏度按实际温度赋值。有人直接拿 998.2 kg/m³ 和 0.001003 kg·m/s 跑,如果模型水温是 15℃ 左右没问题,但做冷水域或者热水域就得改。相分数初始化的 patch 要用区域标记把水线以下 patch 成 1,以上 patch 成 0,重叠网格组装之后背景域和组件域都要分别 patch,漏掉组件域是常见错误。

; Fluent TUI:VOF 与相设置骨架(可粘进 journal) /define/models/multiphase/model vof /define/models/multiphase/vof/interface-reconstruction-method geo-reconstruct /define/models/multiphase/vof/surface-tension? no /define/materials/copy water-liquid /define/phases/phase-1/primary-phase? yes /define/phases/phase-2/set-phase water-liquid

上面这段 TUI 依次锁定了 VOF 模型、界面重构方式、关闭表面张力、复制水材料并指定主次相。geo-reconstruct是界面锐利度的关键,如果后面发现自由面碎裂严重,把这一行改成compressive再重跑。surface-tension? no对米级船体没问题,缩尺到厘米级模型时把它改成yes并确认 CSF 参数。

2.2 湍流模型:k-ω SST 在船体绕流里的取舍

船体绕流有逆压梯度、有流动分离、有艏艉部的强曲率,k-ε 在分离区偏耗散,SST 把 k-ω 的近壁优势和 k-ε 的远场优势拼在一起,是船体 CFD 的常规起点。Realizable k-ε 也能跑,但分离点位置会比 SST 靠后,阻力预报偏低,做瞬态涡脱落的时候更明显。

SST 的关键参数是壁面处理和 y+。船体表面第一层网格高度按目标 y+ 反算,y+ 取 1 附近用增强壁面处理,y+ 在 30 到 100 之间用壁面函数。瞬态仿真里我倾向把 y+ 压到 1 以下,因为非定常分离对近壁分辨率更敏感。湍流入口给水力直径和湍流强度,船体计算域入口用速度入口,湍流强度取 1% 到 5%,水力直径按计算域入口高度给,别拿船宽凑。

; Fluent TUI:k-omega SST 与壁面处理 /define/models/viscous/ke-sst? yes /define/models/viscous/near-wall-treatment/enhanced-wall-treatment? yes /define/boundary-conditions/velocity-inlet/inlet yes yes no 2.0 no 0 no 0.01 0.5

第一行选 SST,第二行开增强壁面处理对应 y+≈1,第三行是速度入口的批量设置:速度 2.0 m/s、湍流强度 0.01、水力直径 0.5 m。这几个值要按实际工况替换,水力直径尤其不能拍脑袋,取小了入口湍流黏性比偏高,艏部边界层会偏厚。

2.3 动网格路线:重叠网格和滑移网格的边界

船体瞬态有垂荡、纵摇,还可能叠加横摇,刚体运动幅度大,滑移网格要求交界面始终贴合,船体一抬起来交界面就错位。重叠网格(Overset)让组件网格在背景网格里自由移动,交界面由求解器插值,适合大幅度运动。滑移网格留给螺旋桨旋转、泵叶轮这类绕固定轴转的场景,船体姿态响应别用它。

重叠网格的代价是交界面插值引入数值耗散,而且组件域和背景域的网格尺度不能差太多,差一个量级以上插值误差会明显。组件域包住船体,背景域包住整个计算域,两个域在船体附近重叠。Fluent 里用 Overset Interface 把两个域的交界面配成 overset 类型,初始化之后检查Overset Mesh面板里的 donor/acceptor 数量,acceptor 数量异常多说明交界面穿过了网格太密的区域。

2.4 求解器与压力-速度耦合的瞬态适配

稳态常用的 SIMPLE 在瞬态里收敛慢,瞬态推荐 PISO 或者 Coupled。PISO 每个时间步做两次邻域修正,适合自由面这种强非线性的问题;Coupled 把动量方程和连续方程联立求解,时间步小的时候更稳。我用 PISO,压力亚松弛 0.3、动量 0.7,库朗数控制在 1 到 5 之间。

时间推进格式选有界二阶隐式(Bounded Second Order Implicit),一阶隐式数值耗散太大,涡脱落会被抹平;二阶隐式在自由面附近可能振荡,有界版本压住了振荡又保留了二阶精度。这个选项在Solve > Methods里,瞬态跑之前确认一下,默认有时候是一阶。

; Fluent TUI:瞬态求解器与推进格式 /define/models/unsteady-2nd-order? yes /solve/set/p-v-coupling 3 /solve/set/equations/volume-fraction yes /solve/set/under-relaxation/pressure 0.3 /solve/set/under-relaxation/momentum 0.7

p-v-coupling 3在多数版本里对应 PISO;unsteady-2nd-order? yes打开有界二阶隐式;体积分数方程在 VOF 瞬态里必须参与求解,漏掉这一行自由面根本不动。亚松弛系数按上面给的值,压力再低会拖慢收敛,动量再高容易在自由面附近振荡。

3. 计算域与重叠网格:从船体表面到背景域的可复现流程

模型选型定下来之后,网格质量直接决定瞬态能不能跑住。船体瞬态对网格的要求比稳态苛刻:重叠网格的交界面插值、自由面的界面锐利度、边界层的 y+ 控制,三个约束叠在一起。这一章按计算域、船体表面网格、重叠组装三步走,每步给出可复现的尺寸和检查项。

3.1 计算域尺寸与边界条件的经验取值

计算域太小,阻塞效应会把阻力抬高,艉部回流也会被出口边界压住。常规取值:入口距艏垂线 1 到 2 倍船长,出口距艉垂线 3 到 5 倍船长,侧向和上方各 1.5 到 2 倍船长,下方取 1 倍船长(水深足够时)。做浅水或者受限航道另算,那属于另一个场景。

边界条件配法:入口速度入口,出口压力出口,侧壁和顶部用对称或者滑移壁面,底部用壁面(模拟水底)或者对称。船体表面无滑移壁面。出口用压力出口时注意回流方向,瞬态里艉部有可能出现回流,回流湍流强度给 5%、回流水力直径按出口高度给,别用默认值。

提示:出口距离不够时,艉部涡结构还没充分发展就被切掉,阻力时程会出现虚假的高频振荡。先把出口拉到 5 倍船长跑一段,再往回收,对比阻力均值,差 2% 以内才算出口位置合理。

3.2 船体表面网格与边界层第一层高度

船体表面用非结构三角形面网格,曲率大的地方(艏部、艉部、舭部)局部加密。边界层用棱柱层,第一层高度按 y+ 反算:

# 第一层高度估算(平板边界层近似) # y+ = 1, U = 2 m/s, L = 5 m, nu = 1e-6 m^2/s # Re_L = U*L/nu = 1e7 # Cf ≈ 0.058*Re_L^(-0.2) = 0.00289 # tau_w = 0.5*rho*U^2*Cf = 5.78 Pa # u_tau = sqrt(tau_w/rho) = 0.0761 m/s # y1 = y+ * nu / u_tau = 1.31e-5 m

按上面这组数,第一层高度约 0.013 mm。实际建模取 0.01 到 0.02 mm 都在可接受范围,棱柱层增长率 1.2,层数 15 到 20 层,保证边界层总厚度覆盖到 y+≈100 以外。艏部驻点附近 y+ 会偏高,加密面网格把第一层高度再压一点,或者跑完之后用Wall Yplus云图检查,艏部超过 5 就局部再调。

棱柱层生成失败是常事,艏部曲率大的地方棱柱层容易挤穿。Fluent Meshing 里把Prism的Growth Rate降到 1.15,Number of Layers先设 10 层跑通,再往上加。挤穿的地方用Improve Prism局部修,修不掉的把面网格再加密一轮。

3.3 重叠网格的组装与交界面检查

组件域包住船体,背景域包住整个计算域,两个域在船体周围重叠一圈。组件域的边界离船体表面至少 0.5 倍船长,太近交界面插值误差会传到船体表面。背景域在重叠区域的网格尺度和组件域接近,差一个量级插值会明显耗散。

组装步骤:先在 Fluent Meshing 里分别生成组件域和背景域网格,导出成两个.msh,在 Fluent 里用Append合并,然后Domain > Mesh > Overset Interfaces > Create把两个域的交界面配成 overset 对。初始化之后打开Overset Mesh面板,看Acceptor Cells和Donor Cells的数量,acceptor 数量应该在组件域边界附近合理分布,如果 acceptor 密密麻麻铺满整个背景域,说明交界面配错了或者两个域的重叠区网格尺度差太多。

注意:重叠网格初始化之后一定要做一次Mesh Check,看有没有orphan cells。orphan cells 是既没有 donor 也没有 acceptor 的孤立单元,数量不为零时求解器会在这些单元上给出虚假的力,阻力时程会出现尖刺。

4. 瞬态求解设置:UDF、时间步与监测的落地操作

网格和模型都配好之后,瞬态设置是最后一道关。这一章按 UDF 编译、时间步选取、监测点配置三步走,每步给出可抄的代码和参数,顺带说清楚失败时看哪里。

4.1 六自由度运动 UDF 的编译与挂载

船体姿态响应用 Fluent 内置的六自由度求解器,配DEFINE_SDOF_PROPERTIES宏定义质量和惯量。不用自己写DEFINE_CG_MOTION去积分解运动方程,内置求解器已经把运动方程和网格更新串好了,自己写反而容易把时间积分搞错。

/* ship_sdof.c —— 船体六自由度被动运动属性 编译:User-Defined > Functions > Compiled 挂载:Dynamic Mesh > Six DOF Properties > ship_hull */ #include "udf.h" DEFINE_SDOF_PROPERTIES(ship_hull, prop, dt, time, dtime) { /* 质量和惯量按缩尺模型给,实船换算时按弗劳德相似 */ prop[SDOF_MASS] = 85.0; /* kg,模型质量 */ prop[SDOF_IXX] = 12.5; /* kg·m²,横摇惯量 */ prop[SDOF_IYY] = 48.0; /* kg·m²,纵摇惯量 */ prop[SDOF_IZZ] = 52.0; /* kg·m²,艏摇惯量 */ /* 约束:放开垂荡、纵摇、横摇,锁住纵荡、横荡、艏摇 */ prop[SDOF_ZERO_TRANS_X] = TRUE; /* 锁纵荡,阻力由固定约束反力输出 */ prop[SDOF_ZERO_TRANS_Y] = FALSE; /* 放开横荡 */ prop[SDOF_ZERO_TRANS_Z] = FALSE; /* 放开垂荡 */ prop[SDOF_ZERO_ROT_X] = FALSE; /* 放开横摇 */ prop[SDOF_ZERO_ROT_Y] = FALSE; /* 放开纵摇 */ prop[SDOF_ZERO_ROT_Z] = TRUE; /* 锁艏摇 */ /* 重心位置,相对全局原点,单位 m */ prop[SDOF_LOAD_CG] = TRUE; prop[SDOF_CG_X] = 1.25; prop[SDOF_CG_Y] = 0.0; prop[SDOF_CG_Z] = 0.05; Message0("SDOF loaded: mass=%.2f kg, Iyy=%.2f kg.m2\n", prop[SDOF_MASS], prop[SDOF_IYY]); }

这段 UDF 的关键在约束位。纵荡锁住、阻力由六自由度求解器输出的约束反力给出,这样阻力时程直接从Six DOF报告里读,不用再单独配力监测。垂荡和纵摇放开,船体在波浪里自由响应。质量和惯量按缩尺模型给,实船换算时按弗劳德相似缩比,惯量按 ρL⁵ 缩比,别直接把实船质量填进去,网格尺度对不上会算飞。

编译时注意 Fluent 的编译器版本,Windows 下用内置的 MinGW 或者 Visual Studio,编译报nmake找不到多半是环境变量没配好。编译成功后在Dynamic Mesh > Six DOF Properties里新建一个属性,UDF 选ship_hull,把组件域的运动指定到这个属性上。

4.2 时间步长、库朗数与内迭代次数

时间步按库朗数反算:Co = U·Δt/Δx。船体表面附近 Δx 最小,取边界层第一层高度或者艏部最密的面网格尺寸。按 U=2 m/s、Δx=0.01 m、Co=2 算,Δt=0.01 s。实际取 0.005 s 更稳,代价是计算量翻倍。涡脱落周期按 Strouhal 数估,船体艉部涡脱落 St≈0.2,特征长度取船宽,周期 T = B/(St·U),时间步取 T/100 到 T/200 能分辨涡脱落。

每个时间步的内迭代次数设 40 到 60,收敛判据残差降到 1e-4 以下,或者监测的阻力变化小于 0.5%。内迭代不够,每个时间步的解没收敛,误差会累积成虚假的低频振荡。判断内迭代够不够,看Continuity残差曲线在每个时间步末尾有没有压下去,压不下去就把内迭代加到 80,或者把压力亚松弛再降一点。

4.3 力与力矩监测的采样设置

监测点配三组:船体阻力(X 方向力)、升力(Z 方向力)、纵摇力矩(Y 方向力矩)。用Report Definitions > Force Report,选船体壁面,力的方向按全局坐标。采样频率每个时间步采一次,输出格式选.out,后处理用 Python 或者 Excel 读。

; Fluent TUI:监测点与时间步 /solve/set/time-step 0.005 /solve/set/max-iter-per-time-step 50 /solve/monitors/residual/convergence-criteria 1e-4 1e-4 1e-4 1e-4 1e-4 /solve/report-definitions/add force-rx ship-hull yes yes 1 0 0 /solve/report-definitions/add force-rz ship-hull yes yes 0 0 1

前三行定时间步、内迭代和残差判据;后两行加阻力和升力监测,1 0 0和0 0 1是力方向向量。力矩监测把方向向量换成0 1 0并选moment类型。监测文件在每个时间步追加一行,跑几千步之后文件会很大,后处理时按需截取。

5. 避坑与排查:五个高频翻车点及处理路径

瞬态船体仿真跑崩的方式很集中,下面五条是我在实际项目里反复遇到的,按现象、原因、解决三步写清楚。

5.1 负体积报错:重叠网格更新时单元翻转

现象:求解几十步之后报Negative cell volume detected,位置集中在组件域和背景域的交界面附近。原因:时间步太大,船体垂荡速度乘时间步超过交界面单元尺寸,网格更新时单元被压穿;或者组件域边界离船体太近,运动幅度大时边界扫过背景域的密网格。解决:先把时间步砍半跑,确认是不是时间步的问题;如果砍半还报,把组件域边界往外推 0.2 倍船长,让重叠区落在背景域网格较疏的位置。再不行就在Dynamic Mesh里把Smoothing打开,扩散系数设 1.5,让网格更新时先做光顺再重构。

5.2 交界面插值引起的力振荡

现象:阻力时程上叠加了高频毛刺,频率和涡脱落对不上,幅值还不小。原因:组件域和背景域在重叠区的网格尺度差太多,插值误差在交界面上来回反射;或者 acceptor 单元分布不均,某些区域的 donor 找不到合适匹配。解决:把背景域重叠区的网格加密到和组件域同量级,面网格尺寸差控制在 2 倍以内;用Overset Mesh面板看 acceptor 分布,局部加密 acceptor 稀疏的区域。还压不住就把交界面从 overset 改成Interface配 sliding 对,代价是运动幅度受限。

5.3 湍流入口与壁面处理不匹配

现象:艏部边界层厚度明显偏厚,阻力比稳态结果高 8% 以上。原因:入口湍流强度给太大(比如直接填 10%),或者水力直径拍脑袋填了个小值,入口湍流黏性比偏高,边界层在入口段就被催厚了。解决:入口湍流强度按来流条件给 1% 到 5%,水力直径按入口高度给,别拿船宽凑。跑完之后用Turbulent Viscosity Ratio云图看入口段,比值超过 100 就把入口参数往回调。

5.4 时间步与库朗数失配

现象:自由面在艏部出现非物理的破碎,相分数在 0 和 1 之间剧烈振荡。原因:时间步太大,自由面在一个时间步内移动超过一个网格单元,VOF 的界面重构跟不上。解决:按自由面附近的网格尺寸重算时间步,Co 控制在 1 以内。自由面附近网格尺寸通常比边界层大,时间步受边界层限制,两边取小值。还压不住就把界面重构从geo-reconstruct换成compressive,牺牲一点锐利度换稳定性。

5.5 监测信号混叠

现象:阻力时程做频谱分析,出现一个和涡脱落无关的低频峰,幅值还挺大。原因:监测采样频率太低,每个时间步采一次但时间步本身太大,涡脱落的高频成分被混叠到低频;或者监测面选错了,把船体壁面和背景域的交界面一起算进去,交界面上的插值误差被当成力信号。解决:时间步按涡脱落周期 T/200 重设,别图省事用大时间步;监测面只选船体壁面,别把内部交界面加进去。做完频谱之后拿 Strouhal 数对一下,峰值频率对应的 St 应该在 0.2 附近,对不上就是采样或者监测面出了问题。

6. 后处理与验证:把瞬态阻力曲线坐实的做法

瞬态跑完,阻力时程拿到手,别急着报均值。先看曲线有没有进入统计稳态,前 30% 到 50% 的时程通常是启动瞬态,船体从初始位置往平衡位置沉降,这段不能进统计。取后 50% 做时间平均,同时算标准差,标准差超过均值 5% 说明振荡还没稳定,要么加长时程,要么检查上面那五个坑。

频谱分析用 Python 的scipy.signal.welch,采样频率按时间步倒数给,nperseg取 1024 到 2048,重叠 50%。峰值频率对应的 Strouhal 数按 St = f·B/U 算,船体艉部涡脱落应该在 0.15 到 0.25 之间。对不上先别怀疑模型,先查采样频率和时间步。

import numpy as np from scipy.signal import welch import matplotlib.pyplot as plt # 读 Fluent 力监测输出,跳过前若干行文件头 data = np.loadtxt("force-rx.out", skiprows=3) t = data[:, 1] # 时间列 fx = data[:, 2] # 阻力列 # 截掉前 40% 启动瞬态 n0 = int(0.4 * len(t)) t, fx = t[n0:], fx[n0:] # 去均值后做 Welch 谱 fs = 1.0 / np.mean(np.diff(t)) f, Pxx = welch(fx - fx.mean(), fs=fs, nperseg=2048, noverlap=1024) # 峰值频率与 Strouhal 数 f_peak = f[np.argmax(Pxx)] St = f_peak * 0.8 / 2.0 # B=0.8 m, U=2.0 m/s print(f"peak f = {f_peak:.3f} Hz, St = {St:.3f}")

这段脚本做了三件事:截掉启动瞬态、去均值、Welch 谱估计。nperseg取 2048 是在频率分辨率和谱平滑之间折中,时程短的时候降到 1024。算出来的 St 落在 0.15 到 0.25 之外,先回查时间步和监测面,别一上来就改湍流模型。

验证环节做两件事。一是和稳态结果对比,瞬态时间平均阻力应该和稳态阻力差在 3% 以内,差太多说明瞬态设置里有一层和稳态不一致,常见的是湍流入口参数或者壁面处理。二是和經驗公式对比,ITTC-78 摩擦阻力系数公式加形状因子估总阻力,量级对上再细看成分。两条都对上,这套瞬态结果才算能往外报。

后处理里还有一个容易忽略的点:自由面形态。用Volume Fraction云图看艏波和艉波,波高和波形和试验或者经验公式对一下。波形对不上但阻力对得上,说明阻力成分里兴波和摩擦的分配有问题,这时候回头看网格和自由面重构格式,别只盯阻力曲线。我一般会把自由面云图、阻力时程、频谱三张图放在一起看,三张图互相印证才算跑通。从那以后我每次开新船型瞬态之前,都强制先把这五条避坑项过一遍再提交计算,省下来的调试时间比多跑两版网格值当。希望帮到你。

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