原文网址https://www.cnblogs.com/liusuanyatong/p/11259628.html
注:在此对原作者表示衷心的感谢!
1 下载并安装GCC
Fluent UDF编译之所以需要依赖于Visual Studio,主要原因是因为Fluent并未内置任何C编译器。(真真是无语了,当前的C编译器可以说是多余牛毛,而且还有很多都是不要钱的,Fluent却还要依赖于Microsoft Visual Studio。幸好现在Visual Studio推出了免费的社区版,不然以前这货的价格可不便宜,虽说有了免费的社区版,但VS臃肿的个头安装起来也挺费时间)
当前用于C/C++的编译器还是比较多的,除了微软的MSVC(就是集成在Visual Studio中的那个),比较有名的还有GCC/G++(基于GNU的C/C++编译器,在Linux系统下很是流行)、ICC(intel搞出来的C/C++编译器,针对intel体系有特别优化)、Clang(近几年风头很火的C/C++编译器,基于BSD协议)、IBM XL C++(IBM搞出来的编译器,在IBM硬件及平台上表现优异)等。
Fluent UDF实质上也是一段完整的C代码,编译型UDF需要利用编译器将这段代码编译成动态链接库(.dll),方便在运行时加载。因此理论上来说任何一款完善的C/C++编译器都可以胜任这项工作。只不过Fluent与巨硬勾搭得比较紧密又不思进取,才导致现在编译UDF需要利用到Visual Studio。
GCC是Linux的主力C/C++编译工具,在windows系统下也有一些基于GCC的编译工具,比较典型的如MinGW、MinGW-win64及TDM-GCC等。(关于它们的区别,可参见https://blog.csdn.net/crazycoder8848/article/details/25164471)。
下面参照教程,采用TDM-GCC作为Fluent UDF编译器。
-
进入TDM-GCC官网下载软件
官网地址为http://tdm-gcc.tdragon.net/download,可下载tdm64-gcc。
TDM-GCC的安装较为简单,双击后一路Next即可。
安装完毕后,可打开命令提示符窗口或powershell,在其中输入g++,若显示如下图所示信息,表示安装成功。若提示g++不是内部或外部命令之类的提示,则表示未安装好,此时可能需要将TDM-GCC的安装路径添加到环境变量Path中。
2 生成库文件
在TDM-GCC安装文件夹中找到可执行文件gendef.exe所在路径,如本机安装路径为D:TDM-GCC-64x86_64-w64-mingw32bin,将该路径添加到环境变量的Path中。
注:添加环境变量的目的只是为了方便后面调用。不添加的话后面调用时需要使用gendef.exe的完整路径。
-
命令行中利用cd命令进入到Fluent的库文件目录。这些文件夹包含C:Program FilesANSYS Incv201fluentfluent20.1.0win64下的所有文件夹以及C:Program FilesANSYS Incv201fluentfluent20.1.0multiportwin64下的所有文件夹。
这些文件夹为:
C:Program FilesANSYS IncV201fluentfluent20.1.0win642d
C:Program FilesANSYS IncV201fluentfluent20.1.0win642d_host
C:Program FilesANSYS IncV201fluentfluent20.1.0win642d_node
C:Program FilesANSYS IncV201fluentfluent20.1.0win642ddp
C:Program FilesANSYS IncV201fluentfluent20.1.0win642ddp_host
C:Program FilesANSYS IncV201fluentfluent20.1.0win642ddp_node
C:Program FilesANSYS IncV201fluentfluent20.1.0win643d
C:Program FilesANSYS IncV201fluentfluent20.1.0win643d_host
C:Program FilesANSYS IncV201fluentfluent20.1.0win643d_node
C:Program FilesANSYS IncV201fluentfluent20.1.0win643ddp
C:Program FilesANSYS IncV201fluentfluent20.1.0win643ddp_host
C:Program FilesANSYS IncV201fluentfluent20.1.0win643ddp_node
C:Program FilesANSYS IncV201fluentfluent20.1.0multiportwin64mpishared
C:Program FilesANSYS IncV201fluentfluent20.1.0multiportwin64netshared
以2d文件夹为例,利用以下命令生成def文件:
cd "C:Program FilesANSYS Incv201fluentfluent20.1.0win642d"
gendef fl2010.exe
注:这里ANSYS安装到了系统盘C盘,由于win10系统对C盘的保护,默认情况下系统盘文件夹中是没有写操作权限的。而这里需要在当前文件夹中创建def文件,因此会操作失败。若ANSYS安装在非系统盘,则不会出现这个问题。
此时两种套路:
-
将win64文件拷贝到非系统盘中进行处理
-
提升win64文件夹的权限,增加写操作权限
鼠标右键选择文件夹C:Program FilesANSYS Incv201fluentfluent20.1.0win64,点击属性弹出属性设置对话框,进入安全标签页,如下图所示,选择列表项User,点击按钮编辑…打开开权限编辑对话框
如下图所示,选中列表项Users,选中完全控制后方的允许复选框,表示对该文件夹赋予所有权限。
此时再执行命令即可生成def文件。
-
运行命令生成a文件
dlltool --dllname fl2010.exe --def fl2010.def --output-lib fl2010.a
注:这里需要花费较长时间。
此时2d文件夹下多出了一个文件名为fl2010.a的文件。
-
对win64文件夹中的所有子文件夹执行上面的操作。确保所有win64文件夹中的子文件中均包含有def文件及a文件。
需要注意,对于文件目录:
c:Program FilesANSYS Incv201fluentfluent20.1.0win642d_node
c:Program FilesANSYS Incv201fluentfluent20.1.0win642ddp_node
c:Program FilesANSYS Incv201fluentfluent20.1.0win643d_node
c:Program FilesANSYS Incv201fluentfluent20.1.0win643ddp_node使用命令:
gendef fl_mpi2010.exe
dlltool --dllname fl_mpi2010.exe --def fl_mpi2010.def --output-lib fl_mpi2010.a
对于路径:
c:Program FilesANSYS Incv201fluentfluent20.1.0multiportwin64mpishared
c:Program FilesANSYS Incv201fluentfluent20.1.0multiportwin64netshared
使用命令:
gendef mport.dll
dlltool --dllname mport.dll --def mport.def --output-lib mport.a
3 编译UDF
编译UDF所需的头文件(千万注意将src文件夹下的所有子文件夹包含进来,否在前面一堆的坑。不同Fluent版本这个子文件夹可能会有所不同):
c:Program FilesANSYS Incv201fluentfluent20.1.0win642d
c:Program FilesANSYS Incv201fluentfluent20.1.0srcmain
c: Program FilesANSYS Incv201fluentfluent20.1.0srcaddon-wrapper
c:Program FilesANSYS Incv201fluentfluent20.1.0srcio
c:Program FilesANSYS Incv201fluentfluent20.1.0srcspecies
c:Program FilesANSYS Incv201fluentfluent20.1.0srcpbns
c:Program FilesANSYS Incv201fluentfluent20.1.0srcnumerics
c:Program FilesANSYS Incv201fluentfluent20.1.0srcsphysics
c:Program FilesANSYS Incv201fluentfluent20.1.0srcstorage
c:Program FilesANSYS Incv201fluentfluent20.1.0srcmphase
c:Program FilesANSYS Incv201fluentfluent20.1.0srcbc
c:Program FilesANSYS Incv201fluentfluent20.1.0srcmodels
c:Program FilesANSYS Incv201fluentfluent20.1.0srcmaterial
c:Program FilesANSYS Incv201fluentfluent20.1.0srcamg
c:Program FilesANSYS Incv201fluentfluent20.1.0srcutil
c:Program FilesANSYS Incv201fluentfluent20.1.0srcmesh
c:Program FilesANSYS Incv201fluentfluent20.1.0srcudf
c:Program FilesANSYS Incv201fluentfluent20.1.0srcht
c:Program FilesANSYS Incv201fluentfluent20.1.0srcdx
c:Program FilesANSYS Incv201fluentfluent20.1.0srcturbulence
c:Program FilesANSYS Incv201fluentfluent20.1.0srcparallel
c:Program FilesANSYS Incv201fluentfluent20.1.0srcetc
c:Program FilesANSYS Incv201fluentfluent20.1.0srcue
c:Program FilesANSYS Incv201fluentfluent20.1.0srcdpm
c:Program FilesANSYS Incv201fluentfluent20.1.0srcdbns
C:Program FilesANSYS Incv201fluentfluent20.1.0srcacoustics
c:Program FilesANSYS Incv201fluentfluent20.1.0cortexsrc
c:Program FilesANSYS Incv201fluentfluent20.1.0clientsrc
c:Program FilesANSYS Incv201fluentfluent20.1.0tgridsrc
c:Program FilesANSYS Incv201fluentfluent20.1.0multiportsrc
c:Program FilesANSYS Incv201fluentfluent20.1.0multiportmpi_wrappersrc
-
进入UDF源代码所在路径,如E:demo -
执行命令
cd e:demo
mkdir .libudfwin642d
gcc -shared -o .libudfwin642dlibudf.dll demo.c "c:Program FilesANSYS Incv201fluentfluent20.1.0win642dfl2010.a" -I. -I"c:Program FilesANSYS Incv201fluentfluent20.1.0win642ddp" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcmain" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcaddon-wrapper" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcio" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcspecies" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcpbns" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcnumerics" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcsphysics" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcstorage" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcmphase" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcbc" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcmodels" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcmaterial" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcamg" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcutil" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcutil" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcmesh" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcudf" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcht" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcdx" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcturbulence" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcparallel" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcetc" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcue" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcdpm" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0srcdbns" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0cortexsrc" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0clientsrc" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0tgridsrc" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0multiportsrc" -I"c:Program FilesANSYS Incv201fluentfluent20.1.0multiportmpi_wrappersrc" -I"C:Program FilesANSYS Incv201fluentinclude" -I"C:Program FilesANSYS Incv201fluentfluent20.1.0srcacoustics"
-
注释掉头文件C:Program FilesANSYS Incv201fluentfluent20.1.0clientsrcsys_master.h第1473行
注意:对应错误提示:c:Program FilesANSYS Incv201fluentfluent20.1.0clientsrc/sys_master.h:1473:26: error: expected declaration specifiers or '...' before numeric constant
-
注释掉头文件c:Program FilesANSYS Incv201fluentfluent20.1.0cortexsrccx.h中第163、164行
注意:对应错误提示:error: conflicting types for '_strnicmp',这两个函数在d:/TDM-GCC-64/x86_64-w64-mingw32/include/string.h中已经定义了。要么去string.h中去掉定义,要么在cx.h中去掉。不建议改string.h,因为编译的时候依赖于该文件。
此时重新编译,顺利通过。
4 测试
需要注意的是,上面是在2d下编译的,因此打开fluent也必须是在2d下,不能用双精度。若要用双精度2d,则必须在2ddp下编译。
被编译的UDF是用于区域初始化的。其代码如下:
#include "udf.h"
DEFINE_INIT(domainInit,d)
{
cell_t c;
Thread *t;
real xc[ND_ND];
real x;
real y;
thread_loop_c(t,d)
{
begin_c_loop_all(c,t)
{
C_CENTROID(xc,c,t);
x = xc[0];
y = xc[1];
if(pow((x-0.05),2)/(0.03*0.03)+
pow(y-0.03,2)/pow(0.015,2)<1)
{
C_T(c,t) = 500;
}
else
{
C_T(c,t)=300;
}
}
end_c_loop_all(c,t)
}
}
-
读取msh文件
-
打开能量方程(本测试案例必须,因为UDF中涉及到温度)
-
打开UDF管理器
-
输入名称libudf,点击Load加载UDF
若出现下面的提示,则表示需要加载并行udf,此时需要编译并行版本udf。
并行版本编译完毕后,加载libudf,如下图所示。
#ifdef __cplusplus
#define EXPORT extern "c" __declspec(dllexport)
#else
#define EXPORT __declspec(dllexport)
#endif
#include "udf.h"
DEFINE_INIT(domainInit,d)
{
cell_t c;
Thread *t;
real xc[ND_ND];
real x;
real y;
thread_loop_c(t,d)
{
begin_c_loop_all(c,t)
{
C_CENTROID(xc,c,t);
x = xc[0];
y = xc[1];
if(pow((x-0.05),2)/(0.03*0.03)+
pow(y-0.03,2)/pow(0.015,2)<1)
{
C_T(c,t) = 500;
}
else
{
C_T(c,t)=300;
}
}
end_c_loop_all(c,t)
}
}
EXPORT UDF_Data udf_data[]={
{"domainInit",(void(*)(void))domainInit,UDF_TYPE_INIT},
};
EXPORT int n_udf_data = sizeof(udf_data)/sizeof(UDF_Data);
-
重新编译并加载,如下图所示
一切正常。
-
hook该UDF,如下图所示
-
初始化
-
温度显示
END
虽然事情最终搞定了,但整个过程还是极为繁琐。万能的知乎上有道友提供了脚本版,有兴趣的道友可以尝试着改造。脚本版地址在这里:https://zhuanlan.zhihu.com/p/90462564,我没有试过。怕麻烦的话,还是老老实实安装Visual Studio吧,社区版也是完全免费的。
本文测试文件:
https://pan.baidu.com/s/12gaTD9222Z-vLqx073dyQw
提取码:puiy
本篇文章来源于微信公众号: CFD之道
评论前必须登录!
注册