|||
由于最近需要使用Fluent做一个二维翼型运动的算例,需要对翼型监测翼型的升力、阻力以及区分翼型表面的压力和阻力的作用力大小,所以需要编写自己的UDF。无奈之前对此一窍不通,只好向万能的网友求助。但是在浏览完各大论坛、贴吧以及微博以后,发现大家对一些需要用到的关键宏和预定义函数的意见不统一,而且可参考的并行算例太少,于是只好一边求助Fluent官方帮助文档一边自己测试,最终经过一个月的努力,终于在自己的电脑以及服务器上完成了有关计算UDF的算例测试。在此,为了给以后可能需要用到UDF的朋友提供更多参考和借鉴,遂将自己使用的一些关键宏的用法和大家分享一下,也是对前人工作的总结汇总,欢迎大家的批评指正,共同进步。废话,不多说了,开始进入正题。
一. Fluent 并行UDF编译环境配置
网上对Ansys12.0以上版本并行编译环境配置的意见大同小异,主要分为两步:
1.设置电脑的环境变量
“我得电脑—高级系统设置——用户变量—新建OR编辑”,添加INCLUDE, LIB, Path
三个环境变量。详情请查看微博链接(在这里十分感谢博主的分享的宝贵经验):
http://blog.sina.com.cn/s/blog_4ea4d4450102uzu5.html
INCLUDE=C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include;
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include;
LIB =C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\amd64;
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib\x64;
Path=C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\amd64;
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE;
2.修改Fluent的udf.bat编译文件
例如我的ANSYS安装在D盘的Program文件夹下,在D:\Program Files\ANSYS Inc\v160\fluent\ntbin\win64下找到udf.bat文件,打开udf.bat文件,修改对应本机安装的microsoft visual studio版本的路径。详细请参考微博链接(同样十分感谢博主的分享):
http://blog.sina.com.cn/s/blog_4a0a8b5d0100uqht.html
二. 翼型运动UDF常用宏
1.控制运动规律的宏
1)你可以使用DEFINE_TRANSIENT_PROFILE (name, current_time)宏来返回物体绕转
轴运动随时间变化的角速度,当然也可以定义刚体的平移运动。例如:(示例来源于Ansys官
方帮助文档。“rotation_rate”对应返回角速度,“vel”则对应返回平移速度。注意的是该
宏返回给求解器一个实数,因而如果是既存在平移也存在旋转运动,你需要使用两次该宏分别进行定义。)
#include "udf.h"
DEFINE_TRANSIENT_PROFILE(rotation_rate_ramp,time)
{
real rotation_rate = 0.0;
if (time < 0.1)
{
rotation_rate = 2500.0 * time;
}
else
{
rotation_rate = 250.0;
}
return rotation_rate;
}
2)你还可以使用DEFINE_CG_MOTION (name, dt, vel, omega, time, dtime)来同时指
定区域的平移和旋转运动,该宏在使用动网格技术进行运动边界问题的模拟中最常使用到。而
(1)中的DEFINE_TRANSIENT_PROFILE则常和滑移网格技术一起用来处理简单的绕固定轴
的旋转问题。值得注意的是在DEFINE_CG_MOTION的使用过程中你可以配合使用相应的动网
格宏DT_CG(dt)、DT_VEL_CG(dt)、DT_OMEGA_CG(t)等来获取与运动区域有关的转轴中心、
平移速度和角度等信息。这给使用动网格求解多自由度运动问题的控制和有关变量的计算带来
了极大便利。而在非DEFINE_CG_MOTION宏中直接调用DT_CG(dt)时,貌似会出现问题。
(在我的UDF中使用(1)中的宏定义了翼型运动,但是在DEFINE_EXECUTE_AT_END中为了
获取实时转轴位置时,直接采用DT_CG(dt)提示编译出错。此时,我是通过定义静态变量来记
录转轴位置的有关信息。)在此附上官方帮助文档的示例:
/************************************************************
* 1-degree of freedom equation of motion (X direction) * compiled UDF
************************************************************/
#include "udf.h"
static real v_prev = 0.0;
DEFINE_CG_MOTION(piston,dt,vel,omega,time,dtime)
{
Thread *t;
face_t f;
real NV_VEC(A);
real force, dv;
/* reset velocities */
NV_S(vel, =, 0.0);
NV_S(omega, =, 0.0);
if (!Data_Valid_P())
return;
/* get the thread pointer for which this motion is defined */
t = DT_THREAD(dt);
/* compute pressure force on body by looping through all faces */
force = 0.0;
begin_f_loop(f,t)
{
F_AREA(A,f,t);
force += F_P(f,t) * NV_MAG(A);
}
end_f_loop(f,t)
/* compute change in velocity, that is, dv = F * dt / mass velocity update using explicit Euler formula */
dv = dtime * force / 50.0;
v_prev += dv;
Message ("time = %f, x_vel = %f, force = %f\n", time, v_prev,
force);
/* set x-component of velocity */
vel[0] = v_prev;
}
3)此外,还可以使用DEFINE_ZONE_MOTION来定义区域的相对运动。但是,本人没
有直接测试过,如有需要可以参阅官方帮助文档。
#include "udf.h"
DEFINE_ZONE_MOTION(fmotion,omega,axis,origin,velocity,time,dtime)
{
if (time < 0.1)
{
*omega = 2500.0 * time;
}
else
{
*omega = 250.0;
}
N3V_D (velocity,=,1.0,0.0,0.0);
N3V_S(origin,=,0.0); /* default values, line could be omitted */
N3V_D(axis,=,0.0,0.0,1.0); /* default values, line could be omitted */
return;
}
2. 非定常计算常用宏
1)RP_Get_Real("flow-time"),效果等同于CURRENT_TIME,用以获取非定常计算的当前
物理时间;
2)RP_Get_Real("physical-time-step"),效果等同于CURRENT_TIMESTEP,用以获取非
定常计算的当前时间步长;
3)RP_Get_Integer("time-step"),效果等同于N_TIME,用以获取非定常计算的当前时间
步;
3. 壁面力、力矩计算常用宏
1)Compute_Force_And_Moment (d, t, x_cg, f_body, m_body, TRUE),是一个在求解
物体运动时很实用的一个宏,但是就像其他很多宏一样,在Ansys的官方帮助文档中,并没有
它的简介,只能在头文件里找到它,像我这样的小白,一般很难看明白。但通过查阅各种论
坛、微博帖子以后,并结合自己的使用经历,先就此进行一下总结,并就一部分对该宏不当
的说明进行补充说明:1)其中 d、t 均为指针,分别指向计算域以及所关心边界的线指针(
其中在单相流中 d 通常使用Get_Domain (1) 获得流体控制区指针。而后者在DEFINE_CG_MOTION这类宏中直接最为已知变量传入,可以直接调用,在其他宏中,则可以
使用 Lookup_Thread (domain,zone_ID) 的方式获得),x_cg是物体边界的中心位置,
f_body 是物体所受水作用力,m_body 是物体所受外力对于中心位置的力矩。2)并行情况
下,直接调用 Compute_force_and_moment宏将在各个节点中同时得到物体的所受合力情
况,不需要再将各节点的计算结果进行累加。但值得注意的是:该宏最后的逻辑变量TRUE与
FALSE,并不表示是否调用该宏。而是表示是否在主节点host中也运行该宏以在主节点也得到
力和力矩的计算结果。虽然Fluent主节点中并不存储与网格单元有关的物理量信息(因而不能
在主节点进行网格有关具体物理量的计算)。但是直接调用 Compute_force_and_moment
也能直接获得力与力矩的正确计算结果。
2)F_STORAGE_R_N3V (f,tf,SV_WALL_SHEAR) 可以用于计算壁面单元剪切应力,一般
通过壁面循环获得单个节点中总的剪切应力,再通过全局规约求和得到物体总的壁面粘性力大
小。一般使用类似:N3V_VS(force_viscous, = , F_STORAGE_R_N3V(f_index, airfoil,
SV_WALL_SHEAR), *, -1.0*DEEP),其中需要乘以(-1)是为了获得粘性力正确的方向,而在
cfd-online中有人说在二位情况中需要乘以一个深度的参考量,这一点本人还没有验证,有知
道的朋友欢迎留言纠正。详情可参阅:(博主应该是大神,再次表示感谢!)
http://blog.sina.com.cn/s/profile_1478582273.html
3) F_P(f,t) 可以用来获取壁面面单元的压力值,其中 face_t f, Thread *t。值得注意
的是在官方帮助文档中曾提到:“F_P(f,t) is not available in the density-based solver”。
这不禁使我疑惑在可压条件下应该如何获取壁面单元压力大小。希望能有大神帮助答疑解惑。
4. 并行计算常用宏
1)#if !RP_NODE,#if !RP_HOST , #if RP_NODE分别表示其后语句仅在主节点或串
行下编译、仅在计算节点或串行下编译,以及仅在计算节点下编译。
2)PRF_GRSUM1,PRF_GRSUM等全局规约操作,前者表示对向量或者数组操作,后
者表示仅对单一变量操作。其中,在对向量或者数组进行操作时,还需额外提供一个缓存地址
用以规约操作。
3)host_to_node_type_num(val_1,val_2,...,val_num) 以及
node_to_host_type_num(val_1,val_2,...,val_num) 可以方便的实现主节点和计算节点之间的数据传
递。
4)PRINCIPAL_FACE_P(f,t)一个在并行UDF中很实用的宏,官方解释为“to test
whether a given face is the principal face, before including it in a face loop
summation. In the sample source code below, the area of a face is added to the total
area only if it is the principal face. Note that PRINCIPAL_FACE_P is always TRUE for
the serial version”,个人理解为该宏用以避免在计算节点分配过程中的交界面的重复计算。
以上便是个人过去一段时间的一点UDF学习心得,希望能给刚开始接触UDF的朋友提供
一定的参考。文中多有错误与不足,欢迎大家批评指正,谢谢!