UDF学习笔记

有时 fluent 自带的边界条件等不满足我们的需求,需要使用 udf 进行更改,比如一个泄漏口流量随时间变化。对于大多数没有编程基础的小伙伴来说,直接看 fluent udf 的官方文档比较吃力,花费大量的时间还找不到相关的函数。

1、UDF 常见的循环宏

简写

1
2
3
4
5
6
7
8
9
d::domin(指针)

ct,t:cell thread(指针)

ft,f_thread:face thread(指针)

c:cell thread(变量)

f:face thread(变量)
C

1.1 对域 d 中的所有单元循环

1
thread_loop_f(ft,d) {  };
C

1.2 对域 d 中的所有面 thread 循环

1
thread_loop_f(ft,d) {  };
C

1.3 对 thread t 中的所有单元循环

1
2
3
begin_c_loop(c,t)
{ }
end_c_loop(c,t);
C

1.4 对面 thread 中所有面循环

1
2
3
begin_f_loop(f,f_thread)
{ }
end_f_loop(f,f_thread)
C

2、相关案例

2.1 风速随高度变化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "udf.h"
DEFINE_PROFILE(inlet_x,thread,index)
{
real y,v0,h0;
real x[ND_ND];//用来存储质心坐标
face_t f;
v0=1;
h0=2;
begin_f_loop(f,thread)
{
//这里传入的x是质心
F_CENTROID(x,f,thread);//F_CENTROID 获得面中心的坐标
y=x[2];
F_PROFILE(f,thread,index) = v0*pow(y/h0,0.2);
end_f_loop(f,thread)
}
}
C

2.2 速度随时间变化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "udf.h"
DEFINE_PROFILE(inlet_V,thread,i)
{
face_t f;// 定义一个面f
real flow_time = CURRENT_TIME;//定义一个实数flow_time获取当前时间
begin_f_loop(f,thread)
{
if(flow_time >=0 )
F_PROFILE(f,thread,i) = 1.5+0.5*sin(2*3.14159*0.1*flow_time);
else
F_PROFILE(f,thread,i) = 1.5;
}
end_f_loop(f,thread)
}
C

2.3 压力随着高度变化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "udf.h"

DEFINE_PROFILE(pressure_profile,t,i)
{
real x[ND_ND];
real y;
face_t f;
begin_f_loop(f,t)
{
F_CENTROID(X,f,t);//F_CENTROID 获得面中心的坐标,用来计算每个面的压力
y = x[1];// 获取y数值,0表示x,1表示y,2表示z
F_FPOFILE(f,t,i) = 1.1e5 - y*y/(.0745*.0745)*0.1e5;
}
end_f_loop(f,t)
}
C

2.4 材料属性随温度变化

1
2
3
4
5
6
7
8
9
10
11
12
13
#include "udf.h"
DEFILE_PROPERTY(steel_heat,c,t)
{
real s_t;
real = Tk = C_T(c,t);//读取当前的温度
if(Tk<=273.15)
s_t = 14;
else if(Tk<=1273.15)
s_t = 14-(Tk-273.15)*0.004;
else
s_t = 10;
return s_t;
}
C

2.5 质量流量随时间变化

以下名为 INTERT_MF 的 UDF 最初指定前 10 毫秒的质量流量为 3.0 千克/秒,然后在接下来的 10 毫秒内将其增加到 4.0 千克/秒,之后指定 5.0 千克/秒。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "udf.h"
DEFINE_PROFILE(inlet_mf,th,i)
{
face_t f;
real flow_time = CURRENT_TIME;/*查找当前流动的时间*/
begin_f_loop(f,th)
{
if(flow_time <= 0.01)
F_PROFILE(f,th,i) = 3.0;
else if(flow_time <= 0.02)
F_PROFILE(f,th,i) = 4.0;
else
F_PROFILE(f,th,i) = 5.0;
}
end_f_loop(f,th);
}
C

2.6 时间步长的改变

DEFINE_DELTAT

1
2
3
4
5
6
7
8
9
10
11
DEFINE DELTAT (mydeltat,d)
{
real time_step;
real flow_time = CURRENT_TIME;
if (flow_time 0.5)
time_step = 0.1;
else
time_step = 0.2;
return time_step;
}

C

2.7 蒸发冷凝模型源相

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include "udf.h"
#include "sg_mphase.h"
#define T_SAT 373.15 //饱和温度373.15 K
#define LAT_HT 1.e3 //汽化潜热1000 J/kg
// 液相质量源项
DEFINE_SOURCE(liq_src, cell, pri_th, dS, eqn)
{
Thread *mix_th, *sec_th;
real m_dot_l;
// mix_th存储主相的Thread指针;sec_th存储次相指针,注意ID
mix_th = THREAD_SUPER_THREAD(pri_th);
sec_th = THREAD_SUB_THREAD(mix_th, 1);
// 温度大于饱和温度,表示为蒸发
if (C_T(cell, mix_th) >= T_SAT)
{
//计算蒸发量,注意液相质量流量为负值,0.1为coeff值
m_dot_l = -0.1 * C_VOF(cell, pri_th) * C_R(cell, pri_th) *
fabs(C_T(cell, pri_th) - T_SAT) / T_SAT;
//对体积分数求导
dS[eqn] = -0.1 * C_R(cell, pri_th) *
fabs(C_T(cell, pri_th) - T_SAT) / T_SAT;
}
else
{
//计算冷凝量,液相质量分数为正值
m_dot_l = 0.1 * C_VOF(cell, sec_th) * C_R(cell, sec_th) *
fabs(T_SAT - C_T(cell, mix_th)) / T_SAT;
//若对体积分数求导得到的值为正,干脆直接赋零值
dS[eqn] = 0.;
}
return m_dot_l;
}
// 气相质量源项,解释同上
DEFINE_SOURCE(vap_src, cell, sec_th, dS, eqn)
{
Thread *mix_th, *pri_th;
real m_dot_v;
mix_th = THREAD_SUPER_THREAD(sec_th);
pri_th = THREAD_SUB_THREAD(mix_th, 0);
if (C_T(cell, mix_th) >= T_SAT)
{
m_dot_v = 0.1 * C_VOF(cell, pri_th) * C_R(cell, pri_th) *
fabs(C_T(cell, mix_th) - T_SAT) / T_SAT;
dS[eqn] = 0.;
}
else
{
m_dot_v = -0.1 * C_VOF(cell, sec_th) * C_R(cell, sec_th) *
fabs(T_SAT - C_T(cell, mix_th)) / T_SAT;
dS[eqn] = -0.1 * C_R(cell, sec_th) *
fabs(C_T(cell, sec_th) - T_SAT) / T_SAT;
}
return m_dot_v;
}
//混合相的能量源项
DEFINE_SOURCE(enrg_src, cell, mix_th, dS, eqn)
{
Thread *pri_th, *sec_th;
real m_dot;
pri_th = THREAD_SUB_THREAD(mix_th, 0);
sec_th = THREAD_SUB_THREAD(mix_th, 1);
if (C_T(cell, mix_th) >= T_SAT)
{
// 得到蒸发量,Lee模型
m_dot = -0.1 * C_VOF(cell, pri_th) * C_R(cell, pri_th) *
fabs(C_T(cell, pri_th) - T_SAT) / T_SAT;
//对温度求导,若为负则保留,否则赋值零
dS[eqn] = -0.1 * C_VOF(cell, pri_th) * C_R(cell, pri_th) / T_SAT;
}
else
{
//得到冷凝量
m_dot = 0.1 * C_VOF(cell, sec_th) * C_R(cell, sec_th) *
fabs(T_SAT - C_T(cell, mix_th)) / T_SAT;
dS[eqn] = -0.1 * C_VOF(cell, sec_th) * C_R(cell, sec_th) / T_SAT;
}

// 返回热量值,利用潜热与质量流量的乘积得到
return LAT_HT * m_dot;
}
C

3、函数

3.1 DEFINE_PROFILE

  1. 使用 DEFINE_PROFILE 定义一个自定义边界配置文件,该边界配置文件随空间坐标或时间的函数而变化。

  2. 边界的变量可以是速度、压力、温度、湍流动能、湍流耗散率、质量流率等(见手册 2.3.17)

用法DEFINE_PROFILE (name,t,i)

thread *t:指向要应用边界条件的线程的指针。

int i:标识要定义的变量的索引。

3.2 DEFILE_PROPERTY

  1. 定义材料的属性

  2. 可以是密度、粘度、热导率、吸收和扩散系数、层流火焰速度、应变率等

对于多相流

传热系数(Mixture)、颗粒或液滴直径(Mixture)

用法

1
DEFILE_PROPERTY(name,c,t)
C

4、常用宏

4.1 流场变量宏

C_R(c,t) 密度(Density)
C_P(c,t) 压力(Pressure)
C_U(c,t) x 方向速度(U-velocity)
C_V(c,t) y 方向速度(V-velocity)
C_W(c,t) z 方向速度(W-velocity)
C_T(c,t) 温度(Temperature)
C_H(c,t) 焓(Enthalpy)

其他

4.2 几何和时间宏

CURRENT_TIME;获取当前模拟时间的值;


UDF学习笔记
http://example.com/2024/03/17/009 UDF学习笔记/
作者
DB
发布于
2024年3月17日
许可协议