1. 简介
今天我们接着说Fluent UDF功能,我们经常使用的UDF宏主要有以下几种:
DEFINE_PROFILE: 定义模型边界
DEFINE_ADJUST: 用于协调计算过程中物理量
DEFINE_INIT: 初始化宏,用于自定义初始化
DEFINE_PROPERTY: 定义材料物性
上述的几种宏基本上无论使用什么物理模型都会用到,还有部分宏是在特定的模型下才会使用,如使用DPM模型时用DEFINE_DPM_SOURCE宏来定义DPM源项,而普通的物理模型下源项通过DEFINE_SOURCE宏定义即可。
今天我们主要了解DEFINE_PROFILE宏的使用,DEFINE_PROFILE宏可以用来定义边界条件,当边界条件比较复杂时,如定义壁面温度Tw=f(y),即壁面温度是y的函数可以使用DEFINE_PROFILE宏进行定义。DEFINE_PROFILE宏可以用来定义的边界物理量如下:
• velocity, pressure, temperature
• mass flux
• species mass fraction (species transport)(组分质量分数,只在组分输运方程中可用)
• volume fraction (multiphase models)(体积分数,在多相流中可用)
• wall thermal conditions (temperature, heat flux, heat generation rate, heat transfer coefficients, and external emissivity, etc.)
• wall roughness conditions()
• wall shear and stress conditions
• wall adhesion contact angle壁面接触角 (VOF multiphase model)
2. 模型及UDF代码
下面我们通过一个实例对DEFINE_PROFILE宏做一个简单的应用。如图1所示,流体从IN边界流入,从OUT边界流出,IN边界流体流速不是定值,而是随着y轴发生变化。
图1.模型示意图
流体流速vin函数
(1)
接下来就是UDF的编写了,先贴上代码
1. #include "udf.h"
2. #include "math.h" //包含头文件
3.
4. DEFINE_PROFILE(velocity, t, i) //边界条件宏
5. {
6. real x, y,xd[ND_ND]; //定义变量
7. face_t f; //定义面指针
8. begin_f_loop(f, t) //对边界面进行循环
9. {
10. F_CENTROID(xd, f, t); //获取坐标
11. x = xd[0]; //xd[0]表示x坐标,xd[1]表示y坐标
12. y = xd[1];
13. F_PROFILE(f, t, i) = 2*y+1; //速度函数
14. }
15. end_f_loop(f, t)
16. }
对于前两行,是UDF所包含的头文件,这两行代码是必写的,其他的情况还需要增加其他的头文件,如多相流时,需要用到#include "sg_mphase.h"。
DEFINE_PROFILE(velocity, t, i)定义边界宏,其中第一个参数velocity为这个宏的名字,可以任意取名;t即thread,表示指向边界的线程,关于UDF中的face、cell、thread、domain这些概念,理解起来比较复杂,以后会逐渐提及。i标识要定义的变量的索引。这里的t要和代码中的t保持相同,如果进行更改,其他地方的t也要相应更改。而对i不必理会。
第6行,real是UDF中声明变量的关键字,替代了C语言中的double这样的关键字,但本质是相同的。因此可以认为就是real x, y=double x, y,即声明了两个变量,而xd[ND_ND]则是UDF中表示数组的方法,等同于C语言中的数组声明。对于第7行,face_t表示声明指针,只不过这个指针是指向面的,与此对应的还有cell_t声明网格指针。
第8行的begin_f_loop(f, t),可以理解为一个循环语句,中间的f表示对面进行循环,UDF中类似的语句有很多。后面的两个参数f,t,实际上就是在t这个thread上对所以的f进行循环。15行的end_f_loop(f, t)表示结束面循环
第10行的F_CENTROID(xd, f, t)表示获取t线程上的f面的质心,并赋值给数组xd。实际上就是获取面的坐标(x,y),并赋给xd。其中xd[0]表示x坐标,xd[1]表示y坐标。因此11和12句就是将x坐标赋值给x,将y坐标赋值给y。
第13句的F_PROFILE(f, t, i) = 2*y+1是给边界条件赋值的语句。这条语句F_PROFILE(f, t, i)表示要赋值的物理量,等于号之后的表示赋值函数。这条语句并没有指出是在哪个边界给什么物理量赋值,因此将这个UDF加载在哪个边界什么物理量上就是给它赋值。
3. FLUENT操作
1. 打开fluent,read-mesh,将mesh导入Fluent中。
2. General界面保持默认,稳态不考虑重力
图2.General界面
3. 打开k-e湍流模型,能量方程不打开
图3.湍流模型
4. 流体材料设置为空气
图4.流体材料
5. 导入UDF文件,一般有两种方法可以将编写好的C语言代码导入到Fluent中。第一种是interpreted解释型,如图5,单击interpreted,出现图6的界面,单击Browse选择编写好的代码文件图7,单击OK,返回图8界面,单击interpret。此时如果控制窗口没有出现Error字样,说明UDF没有问题。
还有另一种导入UDF的方法-Compiled编译型,编译型方法导入UDF需要首先配置好环境变量,然后与解释型类似的操作。两种方法的区别:解释型相对简单很多,不必配置环境变量,同时计算过程中消耗内存也较低,但当UDF代码比较复杂时,或者用到一些高级宏时,解释型无法 正常使用;编译型需要配置环境变量,计算过程会消耗一定的内存,但是对于任意的UDF都适用。这里由于UDF比较简单,我们使用解释型即可
图5.解释型UDF
图6.解释型UDF导入文件
图7.选择UDF代码
图8.对UDF进行解释
图9.控制窗口
6. 边界条件设置,IN设置为velocity-inlet,OUT设置为pressure-outlet,wall_t、wall_b均设置为wall。
当导入UDF后,双击IN边界,单击Velocity Magnitude后面的constant会多出来udf velocity,这里的velocity就是我们编写的UDF,选择udf velocity,IN边界的速度就会按照代码中的函数变化。其他边界均保持默认设置
从这里我们可以看出,对于DEFINE_PROFILE边界宏,UDF代码中并没有指定物理量,因此设置什么物理量边界和自己的操作有关。如将我们写好的速度函数代码,设置到速度方向上,仍然是可以的,只不过物理意义发生了变化。
图10.速度UDF加载
图11.将速度UDF加载到速度Y方向上
7. 初始化:使用Hybrid Initialization进行初始化。
图12.初始化
8. 计算:设置计算步数为1000步,单击calculate
图13.Calculate
4. 结果
1. 通过后处理查看速度云图
图14.速度云图
2. 进口y方向速度曲线图
图15.速度曲线图显示设置
图16.进口y方向速度曲线图