标准功能到不了的地方,用户自定义函数(UDF)是合法的延伸通道:从自定义边界剖面、体积源项,到刚体运动律、专属的输出统计,UDF 以 C 语言回调的形式挂进求解器的执行循环。本节按"边界-源项-运动"三类经典用途各给一份源码模板,讲清解释型与编译型的选择、挂钩与调试纪律,让二次开发从玄学变成工程。
UDF 不是独立程序,而是被求解器在特定时机调用的回调函数。理解它只需要一张"插座墙"地图:边界剖面插座(DEFINE_PROFILE)在边界条件施放时被调用,逐面或逐单元返回目标值;源项插座(DEFINE_SOURCE)在方程组装时被调用,按单元返回源项及其对变量的导数;运动插座(DEFINE_CG_MOTION 或 DEFINE_GRID_MOTION)在动网格更新时被调用,给出刚体速度或网格点位移;物性插座(DEFINE_PROPERTY)在物性更新时被调用;执行与输出类宏(DEFINE_EXECUTE、DEFINE_ON_DEMAND)在迭代节点或手动触发时运行。写 UDF 前先回答"我的逻辑该挂在哪个插座、每次迭代被调用几次"——调用时机不明是 UDF 逻辑错误的第一来源。
模板一:抛物线入口速度剖面(DEFINE_PROFILE)。管道入口希望给定充分发展的抛物线速度分布而不是均匀值:
#include "udf.h" DEFINE_PROFILE(parabolic_inlet, thread, position) { real x[ND_ND]; /* 面中心坐标 */ real r, R = 0.025; /* 管半径 25 毫米 */ face_t f; begin_f_loop(f, thread) { F_CENTROID(x, f, thread); r = sqrt(x[1]*x[1] + x[2]*x[2]); F_PROFILE(f, thread, position) = 2.0 * 1.0 * (1.0 - (r*r)/(R*R)); } end_f_loop(f, thread) }
逻辑只有三步:遍历面、算半径、按抛物线公式填值。常数(平均速度与半径)建议提升为宏定义并在注释里写明量纲,半年后接手的人会感谢现在的你。
模板二:随温度的体积热源(DEFINE_SOURCE)。模拟电阻发热随温升自限的特性:
#include "udf.h" DEFINE_SOURCE(temp_heat_source, c, t, dS, eqn) { real T = C_T(c, t); real src = 1.0e6 * (1.0 - 0.002 * (T - 300.0)); if (src < 0.0) src = 0.0; /* 自限后不再放热 */ dS[eqn] = -1.0e6 * 0.002; /* 源项对温度的导数,助收敛 */ return src; }
注意 dS 导数项:它改善源项强耦合问题的收敛性,是老手与新手 UDF 的分水岭细节。源项量级务必先手算核查——量级写错的源项会让求解器把整个物理算到火星上去。
模板三:正弦摆动刚体(DEFINE_CG_MOTION)。配合第八章动网格,给阀瓣或摆叶一个预设运动律:
#include "udf.h" DEFINE_CG_MOTION(valve_swing, dt, vel, omega, time, dtime) { real freq = 2.0, amp = 0.35; /* 赫兹与弧度幅值 */ NV_S(vel, =, 0.0); NV_S(omega, =, 0.0); omega[2] = amp * 2.0 * M_PI * freq * cos(2.0 * M_PI * freq * time); }
运动律写的是速度而不是位移(求解器自行积分),这是第八章"崩溃诊断"里"UDF 把速度写成位移"事故的源头,也是调试的第一检查点。
解释型 UDF 即写即用,不依赖编译器环境,适合逻辑简单、只用基础宏的场合;编译型 UDF 需要编译链接到求解器,能使用全部宏与外部库,性能更好,逻辑复杂或调用高级宏时是唯一选择。调试纪律四条:先在微型算例(几个网格)上跑通再上正式模型;用 Message 宏打印关键变量(只打印代表性单元或面,全量打印会拖垮性能);每次只改一处,改动前后各存一版 journal;正式算例启动前,先用几个迭代步核验 UDF 输出的量级与分布是否符合手算预期。UDF 的验收单条款只有一条但极重:挂进正式计算前,它的输出被人独立验算过。
背景。某储罐呼吸阀仿真需要按厂商特性曲线给阀门开度相关联的局部阻力,标准多孔介质模型无法表达随阀前压力连续变化的阻力系数。团队决定用 UDF 挂动量源项实现。
操作。第一版直接在正式模型上挂 DEFINE_SOURCE,半小时后发散。按调试纪律回退到微型算例:两单元流道加特性曲线源项,Message 打印显示源项在迭代早期出现负绝对值越界——特性曲线的拟合多项式在设计范围外发散。改用带区间限幅的分段线性拟合,微型算例通过;再上正式模型,配合第九章的欠松弛策略(源项方程松弛因子降到零点五)稳定收敛。
结果。呼吸阀的流量-压差特性与厂商标定曲线偏差在百分之五以内,储罐惰化过程的压力轨迹输出用于置换时间评估,UDF 源码连同验算记录进入项目模板库。
解读。案例浓缩了 UDF 工程化的三条经验:特性输入优先用限幅分段拟合而不是高阶多项式(外推行为可控);源项类 UDF 必须配导数项与松弛策略(收敛稳定性是设计出来的不是碰上的);验算记录与源码同库保存(UDF 是代码,按代码的规格管理,版本可追溯)。
变式。需要访问更深层求解数据(梯度重构、自定义湍流封闭)时转向编译型 UDF 与高级宏;群体平衡、电化学源项等深度定制则评估是否改用求解器开放接口或专用模块,UDF 不是唯一解——维护成本要计入选型。