吾生有涯 学海无涯
析模有界 知识无界

Fluent UDF|EX05 并行改造

本文以案例形式演示将串行UDF代码改造为并行UDF代码。

前面的案例中,一些代码只能运行在串行模式或单CPU模式中,为了提高计算效率,有必要将串行代码改造为并行代码以使其运行于并行模式下。

1 代码改造

以前面案例中的DEFINE_ADJUST代码为例,描述如何将串行代码改写为并行代码。原始的串行代码如下所示。

DEFINE_ADJUST(post_adjust, d)
{
real T_min = REAL_MAX, T_max = 0.0;
Thread *t;
cell_t c;

if (N_UDM < 1)
{
Message0("n Error: No UDM defined! Abort UDF execution.n");
return;
}

thread_loop_c(t, d){
begin_c_loop(c, t){
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);
}

改造过程包括:

  1. 将求解数据放到计算节点中。

这可以利用预处理命令#if !RP_HOST来实现。

DEFINE_ADJUST(post_adjust, d)
{
real T_min = REAL_MAX, T_max = 0.0;
#if !RP_HOST
Thread *t;
cell_t c;
#endif

利用宏RP_HOST将求解数据放置在计算节点中。

  1. N_UDM在所有节点上是等同的,因此无需放置到node节点中。注意代码中的Message0宏仅运行在node0节点上,这里不可以使用Message宏,除非将其放到Node节点中。
DEFINE_ADJUST(post_adjust, d)
{
real T_min = REAL_MAX, T_max = 0.0;
#if !RP_HOST
Thread *t;
cell_t c;
#endif

if (N_UDM < 1)
{
Message0("n Error: No UDM defined! Abort UDF execution.n");
return;
}
  1. 循环遍历只能在Node节点中进行,不可以在Host节点中运行。
#if !RP_HOST
thread_loop_c(t, d){
begin_c_loop_int(c, t){
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)
}
#endif

注意这里将begin_c_loop修改为了begin_c_loop_int,明确指定在内部网格中进行遍历。

  1. 全局约简

代码需要从全局区域中寻找最大最小温度值,因此需要进行全局约简。利用全局约简宏PRF_GRLOW1PRF_GRHIGH1获取全局区域范围的最小最大值。

T_min = PRF_GRLOW1(T_min);
T_max = PRF_GRHIGH1(T_max);
  1. 数据传递

计算节点需要将数据传递给Host节点,利用宏node_to_host_real来完成。

node_to_host_real_2(T_min,T_max);
T_min -= 273.15;
T_max -= 273.15;
  1. 在Host节点上输出信息

    前面已经将计算数据发送至Host节点,因此这里在Host节点上输出信息。注意使用的是Message宏。

#if !RP_NODE
Message(" Minimum temperature = %.1f degCtMaximum temperature = %.1f degCn", T_min, T_max);
#endif

修改完毕后的完整代码如下所示。

DEFINE_ADJUST(post_adjust, d)
{
real T_min = REAL_MAX, T_max = 0.0;
#if !RP_HOST
Thread *t;
cell_t c;
#endif
if (N_UDM < 1)
{
Message0("n Error: No UDM defined! Abort UDF execution.n");
return;
}
#if !RP_HOST
thread_loop_c(t, d)
{
begin_c_loop_int(c, t)
{
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)
}
#endif
T_min = PRF_GRLOW1(T_min);
T_max = PRF_GRHIGH1(T_max);

node_to_host_real_2(T_min, T_max);
T_min -= 273.15;
T_max -= 273.15;
#if !RP_NODE
Message(" Minimum temperature = %.1f degCtMaximum temperature = %.1f degCn", T_min, T_max);
#endif
}

2 代码测试

  • 多核CPU并行启动Fluent
  • 编译并加载UDF
  • 计算信息如下图所示
  • 温度云图如下图所示

可以看出,采用多核CPU并行计算,经过改造后的UDF代码能够正确地实现其功能。


案例相关文件下载:

本篇文章来源于微信公众号: CFD之道

赞(2) 打赏
版权声明:未经允许,请勿随意用于商业用途。
文章名称:《Fluent UDF|EX05 并行改造》
文章链接:https://www.topcfd.cn/11770/
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。
分享到

说两句 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者吧

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫

微信扫一扫

登录

找回密码

注册