小木虫论坛-奔跑鱼为避免原网页失效,此处将重点截图。
胡坤老师-流沙CAE-CFD之道-Fluent 并行UDF丨04 数据遍历宏
本文不详细讲解并行模式下:
1、网格单元的三种类型(内部单元和外部单元,外部单元又分为规则和扩展),
2、网格面的四种类型(内部面、边界面和外部面,内部面包括分区边界面,边界面是相对于整个thread也即整个几何区域而言的)。
重点总结一共有多少相关遍历宏,以及它们之间的区别,最后讲本人的认识。仅供参考,如有错误欢迎批评!
begin_c_loop_int
此宏遍历所有内部单元。
end_c_loop_int
begin_c_loop_ext
此宏遍历所有外部单元,包括规则和扩展。
end_c_loop_ext
begin_c_loop_rext
此宏遍历所有规则外部单元。
end_c_loop_rext
begin_c_loop_eext
此宏遍历所有扩展外部单元。
end_c_loop_eext
此处主要参考和更通俗地总结上面小木虫论坛的回答。
1、在并行UDF中,begin…end_c_loop和begin…end _c_loop_all宏将执行相同的工作。也即在并行UDF中begin…end_c_loop和begin…end _c_loop_all宏都将遍历内部单元和规则外部单元。
2、源头内容中,说这两者在host节点上和node节点上存在不同,借鉴的是mem.h的代码。但是我认为host节点不存储网格数据,因此不能用于循环遍历,也即host节点压根就不能用这个宏。
3、因此我的观点是,能不用这个begin…end _c_loop_all宏,就别用,在官方文档中,其实也很少用这个宏,另外也压根就没花章节去讲这个宏。
4、在串行UDF中,可以用begin…end_c_loop宏,但是在并行UDF中一般来说用遍历内部单元的begin…end_c_loop_int宏。因为这样就不存在重复遍历。
5、在并行UDF中,begin…end_c_loop_int_ext宏才是遍历所有单元(内部单元和所有类型的外部单元)的宏;而不是begin…end_c_loop和begin…end _c_loop_all宏。
另外,如果有人打算实际测试一下,有一个思路是——只开两个核心,将模型建的简单一些,然后编写两套demand宏,一套用begin…end_c_loop宏,另一套用begin…end _c_loop_all宏,分别编译成并行UDF,然后用host节点输出坐标,看是否相同。
begin…end_f_loop_int和begin…end_f_loop_ext分别用于遍历内部面和外部面。官方文档说不建议使用这两个宏,文档中也没有详细说是遍历什么面。
我估计begin…end_f_loop_int遍历的是内部面,而不包括分区边界面;begin…end_f_loop_ext遍历的是外部面。当然只是猜想。
实际使用过程中更多是将PRINCIPAL_FACE_P宏和begin…end_f_loop宏搭配使用以构建并行UDF代码。
begin…end_f_loop宏用于遍历内部面和边界面(注意不是分区边界面)。
在并行UDF中,这个宏往往需要搭配PRINCIPAL_FACE_P(f,tf)来使用,PRINCIPAL_FACE_P宏可以判断某个分区边界面是不是“真正”属于当前计算节点。
因为每一个分区边界面只能从属于一个计算节点,相邻计算节点之间共用一套分区边界面,所以如果只用begin…end_f_loop宏就会重复遍历分区边界面。所以fluent udf的语言设计师就设计了PRINCIPAL_FACE_P宏来判断分区边界面是否应该在某一次遍历中被考虑。
因为在很多地方(官方文档、民间教程)对于循环遍历宏的表述,采用了诸如begin…end_c_loop_all的简写形式,如果你搜索开始——begin_c_loop_all,就没办法搜索到所有描述相关内容的文章或出处。