《Fluent里的用户自定义函数.ppt》由会员分享,可在线阅读,更多相关《Fluent里的用户自定义函数.ppt(65页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、用户自定义函数UDF用户自定义函数用户自定义函数或UDF是用户自编的程序它可以被动态的连接到Fluent求解器上来提高求解器性能用户自定义函数用C语言编写使用DEFINE宏来定义UDFs中可使用标准C语言的库函数也可使用预定义宏FluentInc.提供通过这些预定义宏可以获得Fluent求解器得到的数据UDF分类与区别UDFs使用时可以被当作解释函数解释函数或编译函数编译函数解释函数解释函数在运行时读入并解释编译编译UDFs则在编译时被嵌入共享库中并与Fluent连接解释解释UDFs用起来简单但是有源代码和速度方面的限制不足。编译型编译型UDFs执行起来较快也没有源代码限制但设置和使用较为麻烦
2、UDF的用途满足用户个性化需求边界条件材料性质表面与体积反应速率输运方程源项用户标量输运方程(UDS)调节每次迭代值初始化流场异步执行后处理改善模型改进(离散项模型,多相混合物模型,辐射模型等)UDF举例上壁面温度300K绝热壁面绝热壁面温度:315K温度分布Profile处理(Temppoint26)(x0.00E-032.00E-034.00E-036.00E-038.00E-031.00E-021.20E-021.40E-021.60E-021.80E-022.00E-022.20E-022.40E-022.60E-022.80E-023.00E-023.20E-023.40E-023.
3、60E-023.80E-024.00E-024.20E-024.40E-024.60E-024.80E-025.00E-02)(y0.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+000.00E+00)(t3.49E+023.50E+023.50E+02
4、3.47E+023.46E+023.44E+023.41E+023.39E+023.36E+023.33E+023.31E+023.28E+023.26E+023.24E+023.22E+023.20E+023.19E+023.18E+023.17E+023.16E+023.16E+023.16E+023.15E+023.15E+023.15E+023.15E+02)Profile处理要点(和一般计算一样设置求解器,模型等)DefineProfileRead(数据)DefineBoundaryCondition所需设置的面ThermalTemperatureTempt(和一般计算一样,设置其它
5、边值条件、初值条件及求解与结果检查等)UDF处理温度#includeudf.hDEFINE_PROFILE(bottom_temperature,thread,position)realxND_ND;/*thiswillholdthepositionvector*/realy;face_tf;begin_f_loop(f,thread)F_CENTROID(x,f,thread);y=x0;F_PROFILE(f,thread,position)=315.+(y-.044)*(y-.044)/.044/.044*35.;end_f_loop(f,thread)UDF设置边界温度处理要点(和一般
6、计算一样设置求解器,模型等)DefineUserdefinedFunctions(InterpretedOrCompiled)编译DefineBoundaryCondition所需设置的面ThermalTemperatureBottomTemperature(和一般计算一样,设置其它边值条件、初值条件及求解与结果检查等)侧面与地面两处UDF定义一个以上UDF上壁面温度300K温度抛物线分布绝热壁面温度:315K温度分布UDF编写#includeudf.hDEFINE_PROFILE(bottom_temperature,thread,position)程序1DEFINE_PROFILE(sid
7、e_temperature,thread,position)程序2DEFINE_PROFILE(inlet_velocity,thread,position)程序3。边界温度分布左侧温度分布下面温度分布场温度分布UDF编写用C语言注释/*这是刘某人讲课示范用的程序*/数据类型数据类型Int:整型 Long:长整型 Real:实数Float:浮点型 Double:双精度 Char:字符型UDF解释函数在单精度算法中定义real类型为float型,在双精度算法宏定义real为double型。因为解释函数自动作如此分配,所以使用在UDF中声明所有的float和double数据变量时使用real数据类
8、型是很好的编程习惯。局部变量局部变量局部变量只用于单一的函数中。当函数调用时,就被创建了,函数返回之后,这个变量就不存在了,局部变量在函数内部(大括号内)声明。在下面的例子中,mu_lam和temp是局部变量。DEFINE_PROPERTY(cell_viscosity,cell,thread)realmu_lam;realtemp=C_T(cell,thread);if(temp288.)mu_lam=5.5e-3;elseif(temp286.)mu_lam=143.2135-0.49725*temp;elsemu_lam=1.;returnmu_lam;FLUENT求解过程中UDFs的先
9、后顺序非耦合求解器耦合求解器FLUENT 网格拓扑 单元(cell)区域被分割成的控制容积 单元中心(cell center)FLUENT中场数据存储的地方 面(face)单元(2D or 3D)的边界 边(edge)面(3D)的边界 节点(node)网格点 单元线索(cell thread)在其中分配了材料数据和源项的单元组 面线索(face thread)在其中分配了边界数据的面组 节点线索(node thread)节点组 区域(domain)由网格定义的所有节点、面和单元线索的组合 Fluent数据类型cell_t face_t Thread NodeDomain cell_t是线索(t
10、hread)内单元标识符的数据类型。它是一个识别给定线索内单元的整数索引。face_t是线索内面标识符的数据类型。它是一个识别给定线索内面的整数索引。Thread数据类型是FLUENT中的数据结构。它充当了一个与它描述的单元或面的组合相关的数据容器。Node数据类型也是FLUENT中的数据结构。它充当了一个与单元或面的拐角相关的数据容器。Domain数据类型代表了FLUENT中最高水平的数据结构。它充当了一个与网格中所有节点、面和单元线索组合相关的数据容器。使用DEFINE Macros定义UDFDEFINE_MACRONAME(udf_name,passed-in variables)这里括
11、号内第一个自变量是你的UDF的名称。名称自变量是情形敏感的必须用小写字母小写字母指定。一旦函数被编译(和连接),你为你的UDF选择的名字在FLUENT下拉列表中将变成可见的和可选的。第二套输入到DEFINE 宏的自变量是从FLUENT求解器传递到你的函数的变量。DEFINE_PROFILE(inlet_x_velocity,thread,index)用两个从FLUENT传递到函数的变量thread和index定义了名字为inlet_x_velocity的分布函数。这些passed-in变量是边界条件区域的ID(作为指向thread的指针)而index确定了被存储的变量。一旦UDF被编译,它的名
12、字(例如,inlet_x_velocity)将在FLUENT适当的边界条件面板(例如,Velocity Inlet面板)的下拉列表中变为可见的和可选的。UDF源文件中包含udf.h文件#include udf.h 通过在你的UDF源文件中包含udf.h,编译过程中所有的DEFINE宏的定义与源代码一起被包含进来。udf.h文件也为所有的C库函数头文件包含#include指示,与大部分头文件是针对Fluent提供的宏和函数是一样的(例如,mem.h)。除非有另外的指示,没必要在你的UDF中个别地包含这些头文件。DEFINE_PROFILE(inlet_x_velocity,thread,inde
13、x)定义在udf.h文件中为#define DEFINE_PROFILE(name,t,i)void name(Thread*t,int i)在编译过程中延伸为 void inlet_x_velocity(Thread*thread,int index)名字为inlet_x_velocity的函数不返回值由于它被声明为空的数据类型。UDF任务返回值 修改自变量 返回值和修改自变量 修改FLUENT变量(不能作为自变量传递)写信息到(或读取信息从)case或data文件返回值DEFINE_PROPERTY返回一个udf.h中指定的real数据类型。两个real变量传入函数:通过函数计算层流粘度m
14、u_lam的值,其是温度C_T(cell,thread)的函数。根据单元体温度,计算出mu_lam,在函数结尾,mu_lam值被返回。DEFINE_PROPERTY(cell_viscosity,cell,thread)real mu_lam;real temp=C_T(cell,thread);if(temp 288.)mu_lam=5.5e-3;else if(temp 286.)mu_lam=143.2135-0.49725*temp;else mu_lam=1.;return mu_lam;Function that Modify an Argument判断单元是否在多孔区域,给多孔介
15、质区域定义反应速率;real指针变量rr是一个传递给函数的自变量。UDF使用废弃操作符*分配反应速率值给废弃指针*rr。指针rr指向的目标是设置反应速率。通过这个操作,存储在内存中这个指针上的字符的地址被改变了,不再是指针地址本身#include udf.h#define K1 2.0e-2#define K2 5.DEFINE_VR_RATE(user_rate,c,t,r,mole_weight,species_mf,rr,rr_t)real s1=species_mf0;real mw1=mole_weight0;if(FLUID_THREAD_P(t)&THREAD_VAR(t).fl
16、uid.porous)*rr=K1*s1/pow(1.+K2*s1),2.0)/mw1;else*rr=0.;返回一个值和修改一个自变量的函数DEFINE_SOURCE返回一个在udf.h中指定的数据类型。函数采用自变量ds(它是数组的名字)并设置由eqn指定的元素为关于速度(w_vel)导数的值。(这是z动量方程源项)。这个函数也计算了旋转速度源项的值source,并返回这个值到求解器。#include udf.h#define OMEGA 50./*rotational speed of swirler*/#define WEIGHT 1.e20/*weighting coefficien
17、ts in linearized equation*/DEFINE_SOURCE(user_swirl,cell,thread,dS,eqn)real w_vel,xND_ND,y,source;C_CENTROID(x,cell,thread);y=x1;w_vel=y*OMEGA;/*linear w-velocity at the cell*/source=WEIGHT*(w_vel-C_WSWIRL(cell,thread);dSeqn=-WEIGHT;return source;修改FLUENT变量的函数函数由声明变量f作为face_t数据类型开始。一维数组x和变量y是real 数据
18、类型。循环宏用来在区域中每个面上循环以创建型线或数据数组。在每个循环内,F_CENTROID为含有index f的面输出面质心的值(数组x),index f在由thread指向的线索上。存储在x1中的y坐标分配给变量y,它用于计算x速度。然后这个值分配给F_PROFILE,它使用整数index(由求解器传递个它)来设置内存中面上的x速度值。DEFINE_PROFILE(inlet_x_velocity,thread,index)real xND_ND;/*this will hold the position vector*/real y;face_t f;begin_f_loop(f,thr
19、ead)F_CENTROID(x,f,thread);y=x1;F_PROFILE(f,thread,index)=20.-y*y/(.0745*.0745)*20.;end_f_loop(f,thread)写/读Case或Data文件在顶部整数kount被定义为全局的(由于它被源代码文件中的所有三个函数使 用)并 初 始 化 为 0。名 字 为demo_calc的 第 一 个 函 数,使 用DEFINE_ADJUST 宏来定义。在demo_calc中,kount的值每次迭代后 增 加 因 为 每 次 迭 代 调 用DEFINE_ADJUST一次。名 字 为 writer的 第 二 个 函 数
20、,使 用DEFINE_RW_FILE宏来定义。当保存数据文件时,它指示FLUENT写当前kount值到数据文件。名字为reader的第三个函数,当读取数据文件时,它指示FLUENT从这个数据文件中读取kount的值。这三个函数一起工作如下。如果你运行10次迭代计算(kount将增加到值为10)并 保 存 这 个 数 据 文 件,当 前kount(10)的值被写入你的数据文件。如果你读这个数据返回到FLUENT并继续计算,kount将以值10开始随着每次迭代继续增加。#include udf.h int kount=0;/*define global variable kount*/DEFINE
21、_ADJUST(demo_calc,domain)kount+;printf(kount=%dn,kount);DEFINE_RW_FILE(writer,fp)printf(Writing UDF data to data file.n);fprintf(fp,%d,kount);/*write out kount to data file*/DEFINE_RW_FILE(reader,fp)printf(Reading UDF data from data file.n);fscanf(fp,%d,&kount);/*read kount from data file*/DEFINE_AD
22、JUST功能及其使用方法功能DEFINE_ADJUST是一个用于调节和修改FLUENT变量的通用宏。可以用DEFINE_ADJUST来修改流动变量(如:速度,压力)并计算积分。用来对某一标量在整个流场上积分,然后在该结果的基础上调节边界条件。在每一步迭代中都可以执行用DEFINE_ADJUST定义的宏,并在解输运方程之前的每一步迭代中调用它。DEFINE_ADJUST(name,d)DEFINE_ADJUST有两个参变量:name和d。name是你所指定的UDF的名字。当你的UDF编译并连接时,你的FLUENT图形用户界面就会显示这个名字,此时你就可以选择它了。d是FLUENT解算器传给你的U
23、DF的变量。D是一个指向区域的指针,调节函数被应用于这个区域上。区域变量提供了存取网格中所有单元和表面的线程。对于多相流,由解算器传给函数的区域指针是混合层区域指针。DEFINE_ADJUST函数不返回任何值给解算器。DEFINE_INIT用DEFINE_INIT宏来定义一组解的初始值。DEFINE_INIT完成和修补一样的功能,只是它以另一种方式UDF来完成。每一次初始化时DEFINE_INIT函数都会被执行一次,并在解算器完成默认的初始化之后立即被调用。因为它是在流场初始化之后被调用的,所以它最常用于设定流动变量的初值。DEFINE_INIT(name,d)DEFINE_INIT有两个参变
24、量:name和d。name是你所指定的UDF的名字。当你的UDF编译并连接时,你的FLUENT图形用户界面就会显示这个名字,此时你就可以选择它了。d是FLUENT解算器传给你的UDF的变量所作用的计算区域DEFINE_INIT举例举例下面的UDF名字是my_init_func,它在某一个解中初始化了流动变量。在解过程开始时它被执行了一次。它可以作为解释程序或者编译后的UDF在FLUENT中执行。#include udf.h DEFINE_INIT(my_init_function,domain)cell_t c;Thread*t;real xcND_ND;/*loop over all cel
25、l threads in the domain*/thread_loop_c(t,domain)/*loop over all cells*/begin_c_loop_all(c,t)C_CENTROID(xc,c,t);if(sqrt(ND_SUM(pow(xc0-0.5,2.),pow(xc1-0.5,2.),pow(xc2-0.5,2.)0.25)C_T(c,t)=400.;else C_T(c,t)=300.;end_c_loop_all(c,t)DEFINE_ON_DEMAND#include udf.h DEFINE_ON_DEMAND(on_demand_calc)Domain*
26、d;/*declare domain pointer since it is not passed a*/*argument to DEFINE macro*/real tavg=0.;real tmax=0.;real tmin=0.;real temp,volume,vol_tot;Thread*t;cell_t c;d=Get_Domain(1);/*Get the domain using Fluent utility*/*Loop over all cell threads in the domain*/thread_loop_c(t,d)/*Compute max,min,volu
27、me-averaged temperature*/*Loop over all cells*/begin_c_loop(c,t)volume=C_VOLUME(c,t);/*get cell volume*/temp=C_T(c,t);/*get cell temperature*/if(temp tmax|tmax=0.)tmax=temp;vol_tot+=volume;tavg+=temp*volume;end_c_loop(c,t)tavg/=vol_tot;printf(n Tmin=%g Tmax=%g Tavg=%gn,tmin,tmax,tavg);/*Compute temp
28、erature function and store in user-defined memory*/*(location index 0)*/begin_c_loop(c,t)temp=C_T(c,t);C_UDMI(c,t,0)=(temp-tmin)/(tmax-tmin);end_c_loop(c,t)DEFINEDEFINE_DELTATDEFINE_DIFFUSIVITYDEFINE_HEAT_FLUXDEFINE_NOX_RATEDEFINE_PROFILEDEFINE_PROPERTYDEFINE_SCAT_PHASE_FUNCDEFINE_SOURCEDEFINE_SR_RA
29、TEDEFINE_TURB_PREMIX_SOURCEDEFINE_TURBULENT_VISCOSITYDEFINE_UDS_FLUXDEFINE_UDS_UNSTEADYDEFINE_VR_RATE提取Fluent中变量值C_T(c,t)celltc,Thread*t温度C_P(c,t)celltc,Thread*t压力C_U(c,t)celltc,Thread*tu方向的速度C_V(c,t)celltc,Thread*tv方向的速度C_W(c,t)celltc,Thread*tw方向的速度C_H(c,t)celltc,Thread*t焓C_YI(c,t,i)celltc,Thread*t
30、,inti物质质量分数C_K(c,t)celltc,Thread*t湍流运动能C_D(c,t)celltc,Thread*t耗散率速度导数名称(参数)名称(参数)参数类型参数类型返回值返回值C DUDX(c,t)cell t c,Thread*tvelocity derivativeC DUDY(c,t)cell t c,Thread*tvelocity derivativeC DUDZ(c,t)cell t c,Thread*tvelocity derivativeC DVDX(c,t)cell t c,Thread*tvelocity derivativeC DVDY(c,t)cell t
31、 c,Thread*tvelocity derivativeC DVDZ(c,t)cell t c,Thread*tvelocity derivativeC DWDX(c,t)cell t c,Thread*tvelocity derivativeC DWDY(c,t)cell t c,Thread*tvelocity derivativeC DWDZ(c,t)cell t c,Thread*tvelocity derivativeC_R(c,t)cell t c,Thread*t密度C_MU L(c,t)cell t c,Thread*t层流粘性系数C_MU T(c,t)cell t c,T
32、hread*t湍流粘性系数C_MU EFF(c,t)cell t c,Thread*t有效粘度C_K_L(c,t)cell t c,Thread*t层流热传导系数C_K_T(c,t)cell t c,Thread*t湍流热传导系数C_K_ EFF(c,t)cell t c,Thread*t有效热传导系数C_CP(c,t)cell t c,Thread*t比热C_RGAS(c,t)cell t c,Thread*t通用气体常数C_DIFF L(c,t,i,j)cell t c,Thread*t,int i,int j层流扩散率物性参数循环宏6.2.1LoopingoverCellThreadsi
33、naDomain(thread_loop_c)查询控制区的单元线6.2.2LoopingoverFaceThreadsinaDomain(thread_loop_f)查询控制区的面6.2.3LoopingoverCellsinaCellThread(begin.end_c_loop)查询单元线中的单元6.2.4LoopingoverFacesinaFaceThread(begin.end_f_loop)查询面单元中的面6.2.5LoopingoverFacesonaCell(c_face_loop)查询单元面6.2.6LoopingoverNodesofaCell(c_node_loop)查询
34、单元节点UDF编译连接InterpretedUDFs:解释的UDF被编译成与体系结构无关的中间代码或伪码。这一代码调用时是在内部模拟器或解释器上运行。与体系结构无关的代码牺牲了程序性能,但其UDF可易于共享在不同的结构体系之间,即操作系统和FLUENT版本中。CompiledUDFs:编译后的UDF由C语言系统的编译器编译成本地目标码。这一过程须在FLUENT运行前完成。在FLUENT运行时会执行存放于共享库里的目标码,这一过程称为“动态装载”。InterpretedUDFsCompiledUDFs方法一在你case所在的目录下,建立libudf在libudf下建立两个src和ntx86子目录
35、源程序(*.c)放进src;在ntx86下再建2d、2d_host、2d_node等(2d)然后在2d文件夹下,把Fluent.Incfluent6.srcmakefile_nt.udf和Fluent.Incfluent6.srcuser_nt.udf拷进去,将makefile_nt.udf重命名为makefile接着修改user_nt.udf里的内容,要改成以下格式:SOURCES=$(SRC)udfexample.c(源程序名字)VERSION=2d(是二维还是三维)PARALLEL_NODE=none(有没有并行)最后点开始-程序-附件-命令提示符,进入DOS界面,访问libudfntx
36、862d,然后敲nmake,这样就OK了.然后在FLUENT里load这个libudf就行了.CompiledUDFs方法二在CompiledUDF里,点addsourcecodes,找到源程序,加入,然后build,再LOAD就行了。(如果在在原来的文件夹下已经有(如果在在原来的文件夹下已经有libudf文件夹文件夹,那你把它删了再进行上面的步骤那你把它删了再进行上面的步骤,或者你把或者你把libudf文件夹改成其它任何名字)文件夹改成其它任何名字)CompiledUDFs要点设置比较严格,步骤繁琐,但计算效率高。有些语句有变化(在UDF中,要在控制窗口显示一些值,比如说压力值,用Inter
37、pretedUDF时就得用printf语句,而在CompiledUDF时就得用Message语句,二者不能互用.激活UDF已计算值的调整已计算值的调整激活模型明确激活模型明确UDFUDS求解用户自定义标量输运方程如电磁流体(用于自定义标量求解磁场)磁场对流体的加速与阻尼用UDF加入方程中标量输运基本理论单相流动,对于任意标量,Fluent求解方程UDS只能用于流体区域计算多相流动,对于任意标量,Fluent求解方程定常单相流求解方程无对流通量质量流率计算出对流通量用户自定义通量UDS求解过程1、确定用户自定义标量数Define-userdefined-scalars最多50个UDS求解过程(续
38、)给定FluxFunctionnone,massflowrate,user-definedfunction(DEFINE_UDF_FLUXUDS求解过程(续)设定UnsteadyFunctionnone(default),user-definedfunction(DEFINE_UDS_UNSTEADY)UDS求解过程(续)设定边界条件Define-boundaryconditionsUDS求解过程(续)(如果有源项)流体面板define-boundaryconditions-fluidUDS求解过程(续)设定求解参数,给定初始值,计算检查求解结果scalar-nDiffusionCoef.OfScalar-n