本案例演示利用Fluent UDF在计算过程中进行数据处理的基本过程。
案例实现的功能为:在计算迭代过程中实时获取计算区域内的最高温度与最低温度,并将温度单位转换为摄氏度输出到控制台窗口。
演示的UDF宏包括:
-
DEFINE_ADJUST:该UDF宏在每次迭代计算之前调用 -
DEFINE_ON_DEMAND:该UDF宏为用户手动调用 -
DEFINE_EXECUTE_AT_END:该UDF宏为每次迭代完毕后调用
注:
如果数据处理中涉及到变量全局约简,则需要注意串行代码与并行代码之间的差异,若在并行模式下运行Fluent,则需要将串行代码改造为并行代码。
”
本案例演示的cas文件采用之前的案例文件UDF02.cas。
1 DEFINE_ADJUST宏
该宏使用框架如下所示。
DEFINE_ADJUST(post_adjust, d)
{
/* Initialize min/max */
/* Check for UDMs */
/* Loop over all threads */
/* Loop over all cells */
/* Get Temperature */
/* Calculate and store °C temperature */
/* Check for min/max */
/* print min/max */
}
完整的UDF代码如下。注意下面的代码为串行代码,在并行模式下运行会出现问题,关于并行代码的改造工作,我们在后续的案例中再进行描述。
DEFINE_ADJUST(post_adjust, d)
{
real T_min = REAL_MAX, T_max = 0.0;
Thread *t;
cell_t c;
/*检查UDM是否定义*/
if (N_UDM < 1)
{
Message0("n Error: No UDM defined! Abort UDF execution.n");
return;
}
/*在所有cell threads上遍历*/
thread_loop_c(t, d){
/* 在所有cells中遍历数据 */
begin_c_loop(c, t){
/*将转换的摄氏度温度存储在UDM中*/
C_UDMI(c, t, 0) = C_T(c, t) - 273.15;
/*查找最小温度与最大温度*/
if (C_T(c, t) < T_min)
T_min = C_T(c, t);
if (C_T(c, t) > T_max)
T_max = C_T(c, t);
}
end_c_loop(c, t)
}
/*将温度转换为摄氏温度*/
T_min -= 273.15;
T_max -= 273.15;
Message0(" Minimum temperature = %.1f degCtMaximum temperature = %.1f degCn", T_min, T_max);
}
注:
若采用Fluent内置编译器进行编译,在编译之前需要去掉源代码中的中文注释,或采用英文注释进行替代,否则编译可能会出错。若使用Visual Studio编译则不存在此问题。
”
2 Fluent测试
-
启动Fluent,指定Solver Processes为1
注:
Fluent新版本已经无法采用串行模型运行。这里指定CPU数量为1,实质上依然采用的是并行模式。
”
-
读取之前的案例文件udf2.cas,卸载libudf
注:
在编译新的UDF之前,通常先要卸载已经加载的UDF。
”
-
用内置的编译器编译UDF
-
编译及加载成功后TUI窗口信息显示如下图所示
-
点击按钮Function Hooks… 打开UDF挂载对话框
-
点击Adjust右方的Edit… 按钮
-
如下图所示选择列表项post_adjust::libudf,点击Add按钮增加UDF
-
挂载完毕后的对话框如下图所示
-
初始化并开始计算,计算中出现了如下图所示的错误提示,这是因为UDF中使用了C_UDMI宏,但在使用时没有增加UDM
注:
UDM常用于求解器内部数据交换和数据保存,本案例中也可以不使用UDM。
”
-
右键选择模型树节点User Define Memory,点击菜单项Edit… 打开UDM设置对话框
-
设置Number of User-Defined Memory Locations为1,如下图所示,点击OK按钮关闭对话框
-
重新开始计算,如下图所示
查看温度分布,如下图所示。
可以看到DEFINE_ADJUST宏输出了正确的温度信息,最低温度300K(输出26.9 ℃),最高温度约525K(输出251.7℃)。
3 并行模式中运行
-
换用多核并行计算,如下图所示采用30核进行计算
-
计算中输出信息如图所示,可以看到输出的最低温度为83 ℃,最高温度为186.1℃
-
而实际云图显示的温度如下图所示
很明显并行计算时得到的最低温度、最高温度与计算结果不符。原因在于代码中并未进行全局约简,得到的数据只是node0分区中的物理量。关于并行处理的问题,我们放到后续的案例中进行处理。
4 DEFINE_ON_DEMAND宏
DEFINE_ON_DEMAND宏可以在加载后手工调用。根据前面的代码,很容易将其放置在DEFINE_ON_DEMAND宏中,完成的代码如下所示。
DEFINE_ON_DEMAND(post_demand)
{
real T_min = REAL_MAX, T_max = 0.0;
Thread *t;
cell_t c;
Domain *d = Get_Domain(1);
/* Check for UDMs */
if (N_UDM < 1) {
Message0("n Error: No UDM defined! Abort UDF execution.n");
return;
}
/* Loop over all cell threads */
thread_loop_c(t, d)
{
/* Loop over all cells */
begin_c_loop(c, t)
{
/* Calculate and store °C temperature in first UDM */
C_UDMI(c, t, 0) = C_T(c, t) - 273.15;
/* Check for min/max */
if (C_T(c, t) < T_min) T_min = C_T(c, t);
if (C_T(c, t) > T_max) T_max = C_T(c, t);
}
end_c_loop(c, t)
}
/* Convert to °C just before printing min/max, */
T_min -= 273.15;
T_max -= 273.15;
Message0(" Minimum temperature = %.1f degCtMaximum temperature = %.1f degCn", T_min, T_max);
}
采用单核运行Fluent,编译并加载UDF。需要注意的是,本案例中的DEFINE_ON_DEMAND宏读取计算域中的物理变量,因此在运行此宏之前,需要对计算域进行了初始化,或完成了计算之后再调用此宏,否则可能会出现错误。
-
点击按钮Execute on Demand… 打开对话框
-
设置Execute on Demand为post_demand::libudf,点击按钮Execute执行代码
-
代码执行后在TUI窗口输出温度信息,如下图所示
5 DEFINE_EXECUTE_AT_END宏
DEFINE_EXECUTE_AT_END宏的运行时机是在每个迭代步或时间步长计算完毕后,相同方式处理完毕的源代码如下所示。
DEFINE_EXECUTE_AT_END(post_end)
{
real T_min = REAL_MAX, T_max = 0.0;
Thread *t;
cell_t c;
Domain *d = Get_Domain(1);
/* Check for UDMs */
if (N_UDM < 1) {
Message("n Error: No UDM defined! Abort UDF execution.n");
return;
}
/* Loop over all cell threads */
thread_loop_c(t, d)
{
/* Loop over all cells */
begin_c_loop(c, t)
{
/* Calculate and store °C temperature in first UDM */
C_UDMI(c, t, 0) = C_T(c, t) - 273.15;
/* Check for min/max */
if (C_T(c, t) < T_min) T_min = C_T(c, t);
if (C_T(c, t) > T_max) T_max = C_T(c, t);
}
end_c_loop(c, t)
}
/* Convert to °C just before printing min/max, */
T_min -= 273.15;
T_max -= 273.15;
Message(" Minimum temperature = %.1f degCtMaximum temperature = %.1f degCn", T_min, T_max);
}
采用单核运行Fluent,编译UDF并加载。
-
点击按钮Function Hooks… 打开UDF挂载对话框
-
点击Adjust右方的Edit… 按钮
-
选择post_end::libudf,点击按钮Add添加该UDF宏,点击OK按钮关闭对话框
-
初始化后执行计算,计算信息如下图所示
可以看到该UDF宏能够正确调用并实现应有的功能。
相关文件下载:
本篇文章来源于微信公众号: CFD之道
评论前必须登录!
注册