1、如何查看udf编译过程
本文以查看3ddp_node为例。
使用fluent编译一个udf,可以在工作目录找到makefile文件,如下图所示
打开win64
打开3ddp_node,即可找到makefile文件
2、解析udf编译过程
以文本形式打开makefile即可了解udf的编译过程
!INCLUDE USER_NT.udf #将user_nt.udf里的内容替换过来
/* user_nt.udf中的内容如下*/
/*
CSOURCES= $(SRC)udf.cpp #编译文件名
HSOURCES= #头文件
VERSION=3ddp_node #版本
PARALLEL_NODE=intel
GPU_SUPPORT=off
*/
LIB_RELEASE=2320 #ANSYS2023R2
RELEASE=23.2.0 #发行版
#FLUENT_INC是fluent的安装目录
!IF (("$(FLUENT_INC_LOCAL_RESERVED)" != "") && ("$(FLUENT_INC)" == ""))
FLUENT_INC = $(FLUENT_INC_LOCAL_RESERVED)
!ENDIF
!IF !DEFINED(FLUENT_INC)
! ERROR You need to define the environmental variable FLUENT_INC.
!ENDIF
#FLUENT_ARCH是计算机架构
!IF !DEFINED(FLUENT_ARCH)
!IF ("$(PROCESSOR_ARCHITECTURE)" == "ALPHA")
FLUENT_ARCH = ntalpha
!ENDIF
!IF ("$(PROCESSOR_ARCHITECTURE)" == "x86")
FLUENT_ARCH = ntx86
!ENDIF
!IF ("$(PROCESSOR_ARCHITECTURE)" == "AMD64")
FLUENT_ARCH = win64
!ENDIF
!IF ("$(PROCESSOR_ARCHITEW6432)" == "AMD64")
! MESSAGE You seem to be working on a 64-bit machine, but in a 32-bit build environment.
! MESSAGE If you really want to build the UDF for the "ntx86" FLUENT_ARCH, then please
! MESSAGE set the "FLUENT_ARCH" environment variable to "ntx86" before calling this.
! ERROR Aborting.
!ENDIF
# set FLUENT_LIB based on VERSION macro
#host--主机节点(host管node,host与node0通信,node0收集其余所有node的信息)
#node--计算节点(node管计算)
#dp--双精度
#2D/3D--模型维度
#GPU_SUPPORT--是否使用显卡计算
!IF (("$(VERSION)" == "2d") || ("$(VERSION)" == "3d") || \
("$(VERSION)" == "2ddp") || ("$(VERSION)" == "3ddp"))
FLUENT_LIB = fl$(LIB_RELEASE).lib
LIBS = /Libpath:"$(FLUENT_INC)"\fluent$(RELEASE)\$(FLUENT_ARCH)\$(VERSION)
!ENDIF #此处是串行,FLUENT19以后没有串行,该语句已经废弃
!IF (("$(VERSION)" == "2d_host") || ("$(VERSION)" == "3d_host") || \
("$(VERSION)" == "2ddp_host") || ("$(VERSION)" == "3ddp_host"))
COMM = net
#FLUENT_LIB是库文件,host文件需要mport.lib和fl2320.lib两个库
FLUENT_LIB = mport.lib fl$(LIB_RELEASE).lib
LIBS = /Libpath:"$(FLUENT_INC)"\fluent$(RELEASE)\$(FLUENT_ARCH)\$(VERSION) /Libpath:"$(FLUENT_INC)"\fluent$(RELEASE)\multiport\$(FLUENT_ARCH)\$(COMM)\shared
!ENDIF
#mpi并行运算库
!IF (("$(VERSION)" == "2d_node") || ("$(VERSION)" == "3d_node") || \
("$(VERSION)" == "2ddp_node") || ("$(VERSION)" == "3ddp_node"))
!IF (("$(PARALLEL_NODE)" != "none") && ("$(PARALLEL_NODE)" != "net"))
PARALLEL_NODE = mpi
!ENDIF
COMM = mpi
#FLUENT_LIB是库文件,node文件需要mport.lib和fl_intel2320.lib两个库
FLUENT_LIB = mport.lib fl_$(PARALLEL_NODE)$(LIB_RELEASE).lib
LIBS = /Libpath:"$(FLUENT_INC)"\fluent$(RELEASE)\$(FLUENT_ARCH)\$(VERSION) /Libpath:"$(FLUENT_INC)"\fluent$(RELEASE)\multiport\$(FLUENT_ARCH)\$(COMM)\shared
!ENDIF
SRC = ..\..\src^\
CC = cl
# compile flags
# /c for compile only, /Za for ansi c and __STDC__ is set
CFLAGS = /c /Za /DUDF_EXPORTING /DUDF_NT /DWIN64 /EHa /wd4224 #编译标志
TARGET = libudf.dll #编译目标
UDFDATA = udf_names.c #生成的udf_name.c文件
# generate object names from source names #从源文件生成object,object没有实际用途是过渡文件
SOURCES2 = $(CSOURCES:..\..\src\=)
#"A:B=C"是变量替换,将A中的内容B替换成C,这个语句的意思是,去掉CSOURCES前面的路径
SRC_OBJECT = $(SOURCES2:.cpp=.obj) #*.cpp文件替换成*.obj
SRC_OBJECT = $(SRC_OBJECT:.c=.obj) #*.c文件替换成*.obj
UDF_OBJECT = $(UDFDATA:.c=.obj) #*.c=文件替换成*.obj
OBJECTS = $(UDF_OBJECT) $(SRC_OBJECT) $(USER_OBJECTS) #USER_OBJECTS没有
#头文件目录,host和node一致
INCLUDES= -I. \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\$(FLUENT_ARCH)\$(VERSION) \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\main \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\addon-wrapper \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\io \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\species \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\pbns \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\numerics \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\sphysics \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\storage \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\mphase \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\bc \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\models \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\material \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\amg \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\util \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\mesh \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\udf \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\ht \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\dx \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\turbulence \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\acoustics \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\parallel \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\etc \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\ue \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\dpm \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\src\dbns \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\cortex\src \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\client\src \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\tgrid\src \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\multiport\src \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\multiport\mpi_wrapper\src \
-I"$(FLUENT_INC)"\include
GPU_LIB=
!IF ("$(GPU_SUPPORT)" == "on")
INCLUDES = $(INCLUDES) \
-I"$(FLUENT_INC)"\fluent$(RELEASE)\multiport\gpu_wrapper\include
GPU_LIB = OpenCL.lib
LIBS = $(LIBS) /Libpath:"$(FLUENT_INC)"\fluent$(RELEASE)\multiport\gpu_wrapper\$(FLUENT_ARCH)\stub
!ENDIF
default: $(TARGET)
#将库文件编译成OBJECT
$(UDF_OBJECT): $(UDFDATA)
$(CC) $(CFLAGS) $(INCLUDES) $**
$(SRC_OBJECT): $(CSOURCES)
@echo # Generating ud_io1.h #@echo是打印到控制台的命令
resolve.exe -udf $(CSOURCES) -head_file ud_io1.h
$(CC) $(CFLAGS) $(HOST_FLAGS) $(INCLUDES) $**
$(TARGET): makefile user_nt.udf $(UDF_OBJECT) $(SRC_OBJECT)
@echo # Linking $@ because of $?
link $(LIBS) /dll /out:$(TARGET) \
$(OBJECTS) $(FLUENT_LIB) $(GPU_LIB)
$(UDFDATA): makefile $(SRC_OBJECT)
@echo # Generating $@ because of $?
@echo /* This file generated automatically. */ > $@
@echo /* Do not modify. */ >> $@
@echo #include "udf.h" >> $@
@echo #include "prop.h" >> $@
@echo #include "dpm.h" >> $@
#使用sed进行文本替换
@sed -n "s/^ *\(DEFINE_[_A-Z]*(.*)\)/extern \1;/p" $(CSOURCES) >> $@
@echo __declspec(dllexport) UDF_Data udf_data[] = { >> $@
@sed -n "s/^ *DEFINE_\([_A-Z]*\)( *\([_a-zA-Z0-9]*\).*)/\{\"\2\", (void (*)(void))\2, UDF_TYPE_\1\},/p" $(CSOURCES) >> $@
@echo }; >> $@
@echo __declspec(dllexport) int n_udf_data = sizeof(udf_data)/sizeof(UDF_Data); >> $@
@echo #include "version.h" >> $@
@echo __declspec(dllexport) void UDF_Inquire_Release(int *major, int *minor, int *revision) >> $@
@echo { >> $@
@echo *major = RampantReleaseMajor; >> $@
@echo *minor = RampantReleaseMinor; >> $@
@echo *revision = RampantReleaseRevision; >> $@
@echo } >> $@
clean:
@del *.dll *.obj *.ilk *.exp *.lib *.pdb *.c
#FLUENT的当前架构
tellfluentarch:
@echo FLUENT_ARCH: $(FLUENT_ARCH)
@echo PROCESSOR_ARCHITECTURE: $(PROCESSOR_ARCHITECTURE)
@echo PROCESSOR_ARCHITEW6432: $(PROCESSOR_ARCHITEW6432)
$(OBJECTS): $(HSOURCES)