7自定义函数(UDF)7.1,概述用户自定义函数(User-DefinedFunctions,即UDFs)可以提高FLUENT程序的标准计算功能。
它是用C语言书写的,有两种执行方式:interpreted型和compiled型。
Interpreted型比较容易使用,但是可使用代码(C语言的函数等)和运行速度有限制。
Compiled型运行速度快,而且也没有代码使用范围的限制,但使用略为繁琐。
边界条件剖面UDFs用宏DEFINE_PROFILE定义。
有关例子可以在5.1和6.1中找到。
源项UDFs可以定义除了DO辐射模型之外的任意输运方程的源项。
它用宏DEFINE_SOURCE定义。
有关例子在5.2和6.2中可以找到。
物性UDFs可用来定义物质的物理性质,除了比热之外,其它物性参数都可以定义。
例如,我们可以定义依赖于温度的粘性系数。
反应速率UDFs用来定义表面或体积反应的反应速率,分别用宏DEFINE_SR_RATE和DEFINE_VR_RATE定义,例子见6.4。
UDFs还可以对任意用户自定义标量的输运方程进行初始化,定义壁面热流量,或计算存贮变量值(用用户自定义标量或用户自定义内存量)使之用于后处理。
UDFs有着广泛的应用,本文并不能一一叙述。
如果在使用中遇到问题,可以联系FLUENT技术支部门要求帮助。
7.1.1书写UDFs的基本步骤在使用UDFs处理FLUENT模型的过程中,我们一般按照下面五步进行:1.概念上函数设计2.使用C语言书写3.编译调试C程序4.执行UDF5.分析与比较结果第一步分析我们所处理的模型,目的是得到我们要书写的UDF的数学表达式。
第二步将数学表达式转化成C语言源代码。
第三步编译调试C语言源代码。
第四步在FLUENT中执行UDF。
最后一步,将所得到的结果与我们要求的进行比较,如果不满足要求,则需要重复上面的步骤,直到与我们期望的吻合为止。
7.1.2Interpreted型与Compiled型比较CompiledUDFs执行的是机器语言,这和FLUENT本身运行的方式是一样的。
一个叫做Makefile的过程能够激活C编辑器,编译我们的C语言代码,从而建立一个目标代码库,目标代码库中包含有高级C语言的低级机器语言诠释。
在运行的时候,一个叫做“dynamicloading”的过程将目标代码库与FLUENT连接。
一旦连接之后,连接关系就会在case文件中与目标代码库一起保存,所以读入case文件时,FLUENT就会自动加载与目标代码库的连接。
这些库的建立是基于特定计算机和特定FLUENT版本的,所以升级FLUENT版本后,就必须重新建立相应的库。
相反,InterpretedUDFs是在运行的时候直接装载编译C语言代码的。
在这种情况下,生成的机器代码不依赖于计算机和FLUENT版本。
编译后,函数信息将会保存在case文件中,所以读入case文件时,FLUENT也会自动加载相应的函数。
InterpretedUDFs具有较强的可移植性,而且编译比较简单。
对于简单的UDFs,如果对运行速度要求不高,一般就采用Interpreted型的。
下面列出的是两种UDFs的一些特性:1.InterpretedUDFs——独立于计算机结构;——能够完全当作CompiledUDFs使用;——不能与其它编译系统或用户库连接;——只支持部分C语言,不能包含:goto语句,非ANSI-C语法,结构,联合,函数指针,函数数组等。
!InterpretedUDFs能够使用FLUENT提供的宏,间接引用存贮于FLUENT的变量,详见2.10。
2.CompiledUDFs——运行速度比InterpretedUDFs快;——能够完全于C语言结合;——能够用任何兼容ANSI-C的编辑器编译;——对不同FLUENT版本(2D或3D)需要建立不同的共享库;——不一定能够当作InterpretedUDFs使用。
我们在使用中首先要根据具体情况,明确使用哪种UDFs,然后才能进一步去实现,在使用中要注意上面叙述的事项。
第二节书写UDFs7.2.1概述书写Interpreted型和Compiled型用户自定义函数的过程和书写格式是一样的。
主要的区别在于与C语言的结合程度,Compiled型能够完全使用C语言的语法,而Interpreted型只能使用其中一小部分,这在前面有过论述。
7.2.2UDF格式通用的UDF格式由三部分组成:1.定义恒定常数和包含库文件,分别由#DEFINE和#INCLUDE陈述(见2.3);2.宏DEFINE_*定义UDF函数(见2.4);3.函数体部分(见2.9)包含库有udf.h,sg.h,mem.h,prop.h,dpm.h等,其中udf.h是必不可少的,书写格式为#include“udf.h”;所有数值都应采用SI单位制;函数体部分字母采用小写,Interpreted型只能够包含FLUENT支持的C语言语法和函数。
7.2.3包含库udf.h库文件udf.h必须C函数开头包含。
7.2.4定义函数7.2.4.1简介Fluent公司提供了一套宏,来帮助我们定义函数。
这些宏都以DEFINE_开始,对它们的解释包含在udf.h文件中,所以我们必需要包含库udf.h。
为了方便使用,我们把对udf.h文件中解释宏列在附录A中。
UDF使用宏DEFINE_定义,括号列表中第一个参数代表函数名。
例如DEFINE_PROFILE(inlet_x_velocity,thread,position)定义了一个名为inlet_x_velocity的函数。
!所有函数名必须小写紧接着函数名的是函数的输入参数,如上函数inlet_x_velocity有两个输入参数:thread和position,thread是一个指针,指向数据类型Thread,position是个整数(见2.4.3)。
UDF编译和连接之后,函数名就会出现在FLUENT相应的下拉列表内。
如上述函数,编译连接之后,就能在相应的边界条件面板内找到一个名为inlet_x_velocity的函数,选定之后就可以使用。
7.2.4.2udf.h文件中对宏DEFINE_的解释在udf.h文件中,对附录A的宏作了解释,例如:#defineDEFINE_PROFILE(name,t,I)voidname(Thread*t,inti)通用的宏解释格式为#definemacroreplacement-text在编译前,C预处理器(即cpp)先进行宏替代。
例如DEFINE_PROFILE(inlet_x_velocity,thread,position)替代为voidinlet_x_velocity(Thread*thread,intposition)替代后的函数返回实型值或不返回任何值。
如上述函数由于是void型的,所以不返回任何值。
7.2.4.3宏DEFINE宏DEFINE是用来定义UDFs的,可以分为三类:通用的,离散相的和多相的。
从宏DEFINE下划线的后缀,我们可以看出该宏是用来定义哪种类型函数的。
如DEFINE_SOURCE定义的函数用来修改输运方程源项,DEFINE_PROPERTY定义的函数用来定义物质的物理性质。
通用的宏在2.5详述,离散相和多相的分别在2.6中详述。
下面是附录A的简列。
通用类型:1.DEFINE_ADJUST2.DEFINE_DIFFUSIVITY3.DEFINE_HEAT_FLUX4.DEFINE_INIT5.DEFINE_ON_DEMAND6.DEFINE_PROFILE7.DEFINE_PROPERTY8.DEFINE_RW_FILE9.DEFINE_SCAT_PHASE_FUNC10.DEFINE_SOURCE11.DEFINE_SR_RATE12.DEFINE_UDS_FLUX13.DEFINE_UDS_UNSTEADY14.DEFINE_VR_RATE离散相模型:1.DEFINE_DPM_BODY_FORCE2.DEFINE_DPM_DRAG3.DEFINE_DPM_EROSION4.DEFINE_DPM_INJECTION_INIT5.DEFINE_DPM_LAW6.DEFINE_DPM_OUTPUT7.DEFINE_DPM_PROPERTY8.DEFINE_DPM_SCALAR_UPDATE9.DEFINE_DPM_SOURCE10.DEFINE_DPM_SWITCH多相模型:1.DEFINE_DRIFT_DIAMETER2.DEFINE_SLIP_VELOCITY7.2.4.2数据类型的定义作为对C语言数据类型的补充,FLUENT定义了几种特殊的数据类型,最常用的是:Thread,cell_t,face_t,Node和Domain。
Thread是相应边界或网格区域的结构类型数据;cell_t表示单独一个控制体体积元,用来定义源项或物性;face_t对应于网格面,用来定义入口边界条件等;Node表示相应的网格节点;Domain是一种结构,其中包含所有的threads,cells,faces和nodes。
!Thread,cell_t,face_t,Node和Domain要区分大小写。
7.2.5通用宏及其定义的函数宏DEFINE用来定义UDFs,下面是通用宏的具体解释。
该函数在每一步迭代开始前,即在求解输运方程前执行。
可以用来修改调节流场变量,计算积分或微分等。
参数domain在执行时,传递给处理器,通知处理器该函数作用于整个流场的网格区域。
如何激活该函数请参见4.6,具体求解例子见5.3,5.6和5.7。
该函数定义的是组分扩散系数或者用户自定义标量输运方程的扩散系数,c代表网格,t是指向网格线的指针,i表示第几种组分或第几个用户自定义标量(传递给处理器)。
函数返回的是实型数据。
例子见5.3。
该函数定义的是网格与邻近壁面之间扩散和辐射热流量。
f表示壁面,t指向壁面线,c0表示邻近壁面的网格,t0指向网格线。
函数中需要给出热扩散系数(cid)和辐射系数(cir),才能求出扩散热流量(qid)和辐射热流量(qir)。
如何激活函数见4.7,例子见5.6。
该函数用于初始化流场变量,它在FLUENT默认的初始化之后执行。
作用区域是全场,无返回值。
函数的激活见4.5,例子见5.4.1和5.5。
,例子见5.8。
该函数定义边界条件。
t指向定义边界条件的网格线,i用来表示边界的位置。
函数在执行时,需要循环扫遍所有的边界网格线,值存贮在F_PROFILE(f,t,i)中,无返回值。
选择使用本函数见4.1,例子见5.1.1,5.1.2,5.1.3,5.3,6.1.1和6.1.2。
该函数用来定义物质物性参数。
c表示网格,t表示网格线,返回实型值。
使用见4.3,例子见6.3.1。
该函数用于读写case和data文件。
fp是指向所读写文件的指针。
使用见4.11,例子见2.9.8。
该函数定义DO(DiscreteOrdinate)辐射模型中的散射相函数(radiationscatteringphasefunction)。
计算两个变量:从i向到j向散射的辐射能量分数和前向散射因子(forwardscatteringfactor)。
c表示的是i和j向夹角的余弦值,散射的能量分数由函数返回,前向散射因子存贮在指针f所指的变量中。
处理器对每种物质,都会调用此函数,分别建立各物质的散射矩阵。
该函数定义,除了DO辐射模型之外,输运方程的源项。
在计算中,函数需要扫描全场网格。
c表示网格,t表示网格线,dS表示源项对所求输运方程的标量的偏导数,用于对源项的线性化;i标志所定义源项对应于哪个输运方程。
使用见4.2,例子见5.2.1,5.2.2,5.3,6.2.1。
该函数定义表面化学反应速率。
函数无返回值,使用见4.8。
该函数定义用户自定义标量输运方程(user-definedscalartransportequations)的对流通量。
f,t分别表示所求通量的面和面的线,i表示第几个输运方程(有处理器传递给本函数)。
该函数定义用户自定义标量输运方程的非稳态项。
c表示网格,t表示网格线,i表示第几个输运方程。
在FLUENT中,非稳态项移到RHS中,并以下面的方式离散:方程右边第一项为apu,第二项为su。
本函数无返回值。
该函数定义体积化学反应速率。
函数无返回值,使用见4.8,例子见6.4.1。
7.2.6离散相模型宏及其定义的函数离散模型(DPM)的宏定义的函数与通用宏所定义的函数书写格式是一样的。
下面是具体的宏定义。
该函数用于定义除了重力和拉力之外的所有体积力。
p为结构指针,i可取0,1,3分别表示三个方向的体积力。
函数返回的是加速度。
使用见4.4,例子见5.4.2。
7.2.6.2DEFINE_DPM_DRAG()()()11_--+-=--≈-=nnnntVtVVtdVttermunsteadyφρφρρφρφρφ该函数定义拉力系数CD,Re为Reynolds数,与颗粒直径和相对于液相速度有关。
拉力定义为:函数返回的值是18*CD*Re/24。
使用见4.4,例子见5.4.3。
该函数定义颗粒撞击壁面湮灭或产生速率。
t为撞击面的线,f为撞击面;数组normal存贮撞击面的单位法向量;alpha中存贮颗粒轨道与撞击面的夹角;Vmag存贮颗粒速度大小,mdot存贮颗粒与壁面撞击率。
函数无返回值,颗粒湮灭或产生的计算结果存贮在面变量F_STORAGE_R(f,t,SV_DPMS_EROSION)和F_STORAGE_R(f,t,SV_DPMS_ACCRETION)中。
使用见4.4。
该函数用于定义颗粒注入轨道时的物理性质。
I是指针,指向颗粒产生时的轨道。
对每一次注入,该函数需要在第一步DPM迭代前调用两次,在随后颗粒进入区域前每一次迭代中再调用一次。
颗粒的初始化,诸如位置,直径和速度可以通过该函数设定。
函数无返回值。
该函数定义液滴和燃烧颗粒的热和质量传输速率。
p的意义如前所述,ci表示连续相和离散相是否耦合求解,取1时表示耦合,0时表示不耦合。
颗粒的性质随着液滴和颗粒与其周围物质发生传热、传质而改变。
输出信息存贮于指针fp所指向的文件,函数无返回值。
例子见5.4.1。
24Re182DppDCDF=ρμ该函数用于定义离散相物质的物理性质。
p为结构指针,c表示网格,t表示网格线。
函数返回实型值。
c表示颗粒当前所处的网格,t为该网格线。
initialize在初始调用本函数时,取为1,其后调用时,取为0。
在计算变量对颗粒轨道的积分时,FLUENT就调用本函数。
函数的使用见4.4,例子见5.4.1。
该函数用于计算,给定网格中的颗粒在与质量、动量和能量交换项耦合DPM求解前的源项。
c表示当前颗粒所在的网格,t为网格线,S为结构指针,指向源项结构dpms_t,其中包含网格的源项。
p为结构指针。
函数求得的源项存贮于S指定的变量中,无返回值。
该函数是FLUENT默认的颗粒定律与用户自定义的颗粒定律之间,或不同的默认定律和自定义定律之间的开关函数。
p为结构指针,ci为1时,表示连续相与离散相耦合求解,0时表示不耦合求解。
具体含义可以参见相应章节。
7.2.7多相模型的宏及其定义的函数t为网格线。
函数返回颗粒或液滴的直径。
使用见4.10。
整个网格区域,无返回值。
使用见4.9。
7.2.8特定线的指针在很多应用UDF的场合,需要在一条特定的线上进行操作。
为满足这种要求,首先,可以从BoundaryConditions面板得到需要操作的线的ID,然后就可用宏Lookup_Thread将指针指向该条线。
在下面的例子中,C语言函数Print_Thread_Face_Centroids调用FLUENT的宏Lookup_Thread将指针指向特定的线,然后将线上所有面的质心坐标输入文件中。
宏DEFINE_ON_DEMAND定义的函数get_coords取出其中的两条线,并打印线上所有面的质心坐标。
#include“udf.h”externDomain*domainFILE*foutstaticvoidPrint_Thread_Face_Centroids(Domain*domain,intid){realFC[2];face_tf;Thread*t=Lookup_Thread(domain,id);fprintf(fout,“threadid%d\n”,id);begin_f_loop(f,,t){F_CENTROID(FC,f,t);fprintf(fout,“f%d%g%g%g\n”,f,FC[0],FC[1],FC[2]);}end_f_loop(f,t)fprintf(fout,“\n”);}DEFINE_ON_DEMAND(get_coords){fout=fopen(“faces.out”,“w”);Printf_Thread_Face_Centroids(domain,2);Printf_Thread_Face_Centroids(domain,4);fclose(fout);}7.2.9函数体7.2.9.1介绍用户自定义函数体部分包含在紧跟着宏DEFINE_定义的大括弧内,如下例。
这和标准C语言函数体的定义是相同的。
DEFINE_PROPERTY(cell_viscosity,cell,thread){realmu_lam;realtemp=C_T(cell,thread);if(temp>288.)mu_lam=5.5e-3;elseif(temp>286.)mu_lam=143.2135–0.49725*temp;elsemu_lam=1.;returnmu_lam;}7.2.9.2InterpretedUDFs的限制性Interpreted型书写函数体时并不能完全应用C语言函数,这在前面有过论述。
此外,数量的单位制必须采用国际单位制。
7.2.9.3函数的功能UDFs执行五种功能:1.返回变量值;2.调节参数;3.返回变量值并且调节参数;4.调节FLUENT的变量(不以参数形式传递);5.向case或data文件读写信息。
宏定义的函数返回类型如果不是void型,就返回实型值。
下面的例子分别说明不同功能的函数。
7.2.9.4返回变量值下面的UDF计算与温度有关的粘性系数,并返回该值。
#include“udf.h”DEFINE_PROPERTY(cell_viscosity,cell,thread)/*定义物性的宏*/{realmu_lam;realtemp=C_T(cell,thread);/*变量temp存放网格的温度*/if(temp>288.)mu_lam=5.5e-3;elseif(temp>286.)mu_lam=143.2135–0.49725*temp;elsemu_lam=1.;returnmu_lam;/*变量mu_lam存放粘性系数值,函数返回该值*/}7.2.9.5调节参数下面的UDF给出简单二元气相系统的体积反应速率。
#include“udf.h”#defineK12.0e-2#defineK25.DEFINE_VR_RATE(user_rate,cell,thread,r,mole_weight,species_mf,rate,rr_t){reals1=species_mf[0];realmw1=mole_weight[0];if(FLUID_THREAD_P(thread)&&THREAD_VAR(thread).fluid.porous)*rate=K1*s1/pow((1.+K2*s1),2.)/mw1;else*rate=0.;}函数名为user_rate,函数体中用if语句判断是否处于多孔介质区,仅在多孔介质区有化学反应。
7.2.9.6返回变量值并调节参数下面的UDF定义的是swirl-velocity的源项。
#include“udf.h”#defineOMEGA50/*rotationalspeedofswirler*/#defineWEIGHT1.e20/*weightingcoefficientsinlinearizedequation*/DEFINE_SOURCE(user_swirl,cell,thread,dS,eqn){realw_vel,x[ND_ND],y,source;CENTROID(x,cell,thread);y=x[1];w_vel=y*OMEGA;/*linearw_velocityatthecell*/source=WEIGHT*(w_vel–C_WSWIRL(cell,thread));dS[eqn]=-WEIGHT;returnsource;}函数名为user_swirl,函数计算了变量source并且返回其值。
函数的各项参数的意义参见2.5.10。
7.2.9.7调节FLUENT变量下面的函数调节存贮于内存的FLUENT变量,函数定义了x方向速度的边界条件。
#include“udf.h”DEFINE_PROFILE(inlet_x_velocity,thread,position){realx[ND_ND];realy;face_tf;begin_f_loop(f,thread){F_CENTROID(x,f,thread);y=x[1];F_PROFILE(f,thread,position)=20.-y*y/(.0745*.0745)*20;}end_f_loop(f,thread)}函数的参数position是个数字标签,标记每一步循环(loop)中被设置的变量。
函数调节的FLUENT变量F_PROFILE。
7.2.9.8读写data或case文件下面的函数介绍了如何读写静态变量kount,如何计算静态变量请参见4.6。
#include“udf.h”intkount=0;/*定义静态变量kount*/DEFINE_ADJUST(demo_calc,domain){kount++;printf(“kount=%d\n”,kount);}DEFINE_RW_FILE(writer,fp){printf(“WritingUDFdatatodatafile…\n”);fprintf(fp,”%d”,kount);/*将kount写入data文件中*/}DEFINE_RW_FILE(writer,fp){printf(“ReadingUDFdatafromdatafile…\n”);fscanf(fp,“%d”,&kount);/*从数据文件中读取kount值*/}上面有三个函数。
如果迭代10次,则kount值为10,然后将当前值10存贮到数据文件中,如果下次将kount值读入FLUENT继续运算,则kount将在10的基础上增加。
我们可以存贮任意多的静态变量,不过读写顺序必须一致。
7.2.10解法器函数(SolverFunctions)7.2.10.1概述在很多情况下,UDF需要得到FLUENT解法器中的数据。
例如:1.所求解的变量及其导数(例如,速度,温度等);2.网格和面几何性质(例如,面面积,网格体积,网格质心坐标等);3.物质的物理性质(例如,密度,粘性系数,导热系数等)。
!我们可以取出比热,但是不能修改。
我们可以利用下一节所列FLUENT提供的解法器函数,得到解法器中的数据。
这里所说的函数是从广义上讲的,因为其中包括函数和宏,只有在源文件appropriate.h中定义的才是真正的函数。
!如果使用的是Interpreted型的UDF,则只能使用这些FLUENT提供的解法器函数。
解法器函数可以与C函数一起在函数体中混合使用。
为方便起见,一些最常用的C函数列在附录B中。
下面章节列出的函数中包括它们的参数,参数类型和返回值,还有对该函数说明的源文件。
例如C_CENTROID(x,c,t)有三个参数:x,c和t,其中c和t为输入参数,x为输出参数,输出网格的坐标值。
7.2.10.2辅助几何关系7.2.10.4节点坐标与节点(网格)速度7.2.10.5面变量7.2.10.6网格变量下面列表中的是网格变量,不像面变量,网格变量在耦合与非耦合计算中都能获取(availableinboththesegregated7.2.10.7循环宏如果要实现扫描全场的网格就需要使用循环宏。
下面给出两种类型的循环宏。
一种以begin开始,end结束,用来扫描线上的所有网格和面;另一种用来扫描所有的线。
cell_tc;face_tf;Thread*t;Domain*d;begin_c_loop(c,t){}end_c_loop(c,t)/*循环遍历线上的所有网格*/begin_f_loop(f,t){}end_f_loop(f,t)/*循环遍历线上的所有面*/thread_loop_c(t,d){}/*遍历网格线*/thread_loop_f(t,d){}/*遍历面上的线*/7.2.10.8数据的可得性在书写UDF的时候,要保证出现在函数中的数据是能够从解法器上获得的。
为了检验数据的这种可得性,我们可以使用函数Data_Valid_p,如果数据正确该函数返回值为1,否则返回0。
IntData_Valid_P();/*取自文件case.h*/当我们读取case文件时,就会装载相应的UDF。
如果此时函数用到一个未初始化的变量,诸如内部网格速度,计算就会发生错误。
为了避免这种类型的错误发生,解法器会执行一条ifelse语句。
如果数据可得,就按照正常情况执行下去;否则,就停止运算。
一旦流场初始化之后,函数会被重新激活,然后读取正确的数据运行。
7.2.10.9设置面变量值的函数宏F_PROFILE设置的是面上的变量值,该函数在设置边界面时使用。
face_tf;Thread*t;F_PROFILE(f,,t,,nvar)/*frommem.h*/函数中的参数nvar不需用户设定,而是由FLUENT解法器传递给UDF。
nvar是特定边界的数字标签。
我们在定义边界条件面板定义边界条件时,解法器就设定nvar的值。
!整型变量nvar是不能改变的,只能由FLUENT解法器传递。
7.2.11DPM宏下面列出的离散相模型的宏定义在源文件dpm.h中,变量p是指向结构Tracked_Particle的指针(Tracked_Particle*p)。
下面3.3和3.4节也分别介绍了Interpreted型和Compiled型UDF的编译和连接。
7.3.1概述我们在第一章就介绍过Interpreted型和Compiled型UDF的区别以及各自的特点,在此不再累述。
为了显示区别,FLUENT中两种UDF的设置面板是不同的。
Interpreted型面板有一个Compile按钮,点击时就会对源文件进行编译;Compiled型面板有一个open按钮,点击时会打开事先编译好的机器源代码库,然后连接运行。
UDF是用宏DEFINE_定义的,对宏的解释在udf.h文件中。
udf.h文件存放的位置为path/Fluent.Inc/fluent5.x/src/udf.h,path为FLUENT安装路径。
在编译的时候,编译器会自动到src目录下搜寻udf.h文件。
注意,在更新src目录时不能移去udf.h文件,因为该文件在近期是无法更新的。
如果系统搜寻不到udf.h文件,编译连接工作将无法进行。
7.3.2Interpreted型UDFs本节介绍了如何编译Interpreted型UDFs。
编译之后,case文件会记录编译过程,FLUENT在读取case文件时会自动加载UDFs。
7.3.2.1编译Interpreted型UDFs一般,我们按照下面的步骤编译UDF:1.将UDF的C源程序拷贝到当前工作目录,如果不在当前目录,则编译时需要指定该文件的具体路径。
如果使用并行运算,按照3.2.2设置;2.运行FLUENT程序;3.读取(或建立)case文件;4.在InterpretedUDFs面板编译UDF(例如,vprofile.c)。
Define→User-Defined→Functions→Interpreted…图3.2.1InterpretedUDFs面板(a)在SourceFileName中输入C源文件名(如vprofile.c)。
如果源文件不在当前工作目录下,则需要输入完整路径。
(b)在CPPCommandName中输入C预处理程序名。
如果安装了/contrib组件,则会出现默认的预处理程序名:cpp。
对于WindowsNT用户,标准安装过程会自动安装默认的预处理程序。
当然,我们还可以选择系统中其它的预处理程序。
(c)StackSize默认值取10000,如果我们处理的问题变量很多,10000个栈会溢出,则需要加大该值。
(d)点击Compile键进行编译。
如果选中DisplayAssemblyListing按钮,编译时会出现下面的信息提示:(e)点击Close关闭。
!如果我们需要编译的InterpretedUDF不止一个,可以将UDFs写入单个C源文件,如all.c,然后以同样的方式进行编译连接就可以了。
7.3.2.2WindowsNT系统网络并行运算的目录结构如果我们使用的是WindowsNT系统的并行版FLUENT,就需要以特定的方式组织文件目录。
3.2.1中的第一步必须以下面的步骤代替:1.在Fluent.Inc目录下建立一个名为udf的可写子目录。
2.在目录udf下建立一个目录(例如,Fluent.Inc\udf\myudf),将C源文件拷入其中,如myudf目录下。
如果多位用户使用,可以再建立其它目录(如Fluent.Inc\udf\abcudf或xyz)。
!由于C源文件不在当前工作目录下,编译时需要输入文件路径。
如:\\
3.如果已有case文件,应保证其在当前工作目录下。
7.3.2.3调试InterpretedUDFs如果编译有错,在相应窗口中会出现错误信息。
如果因为屏幕翻动无法看清,则应该关闭DisplayAssemblyListing选项。
7.3.2.4InterpretedUDFs常见编译错误C源文件如果不是在当前工作目录下,而在编译时没有指明具体路径,就会出现下面的错误:如果将case文件拷贝到了其他目录,而没有将C源文件一起拷过去,会出现同样的错误。
7.3.3Compiled型UDFs一般,我们按照下面的步骤编译连接Compiled型UDFs:1.在工作目录下建立相应的目录(见3.3.1);2.编译UDFs并建立共享库(见3.3.2);3.运行FLUENT;4.读取(或建立)case文件(case文件如果事先以存在,应保证在当前工作目录下);5.连接共享库到FLUENT执行(见3.3.3)。
连接成功后,出现下面信息:7.3.3.1建立目录结构UNIX和WindowsNT系统所建目录结构是不一样的,下面分别进行说明。
UNIX系统UNIX系统编译CompiledUDFs需要两个文件:Makefile和makefile。
makefile文件是可修改的,C源文件名就在其中设定。
下面的步骤概括介绍了目录结构的建立过程,从图3.3.1可以看得更清楚。
图3.3.1中的目录结构适用于两种版本:单精度2D运算和单精度2D并行运算。
注意不需要向版本目录(2d,2d_host,2d_node)中拷入任何文件,图中所示文件在编译时会自动生成。