用户自定义函数.ppt
用户自定义函数,UDF,用户自定义函数,用户自定义函数或UDF是用户自编的程序它可以被动态的连接到Fluent求解器上来提高求解器性能用户自定义函数用C语言编写使用DEFINE宏来定义UDFs中可使用标准C语言的库函数也可使用预定义宏FluentInc.提供通过这些预定义宏可以获得Fluent求解器得到的数据,UDF分类与区别,UDFs使用时可以被当作解释函数或编译函数解释函数在运行时读入并解释编译UDFs则在编译时被嵌入共享库中并与Fluent连接解释UDFs用起来简单但是有源代码和速度方面的限制不足。编译型UDFs执行起来较快也没有源代码限制但设置和使用较为麻烦,UDF的用途-满足用户个性化需求,边界条件材料性质表面与体积反应速率输运方程源项用户标量输运方程(UDS)调节每次迭代值初始化流场异步执行后处理改善模型改进(离散项模型,多相混合物模型,辐射模型等),UDF举例,,,,上壁面温度300K,绝热壁面,绝热壁面,温度315K,,温度分布,Profile处理,Temppoint26x0.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.60E-023.80E-024.00E-024.20E-024.40E-024.60E-024.80E-025.00E-02y0.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E000.00E00t3.49E023.50E023.50E023.47E023.46E023.44E023.41E023.39E023.36E023.33E023.31E023.28E023.26E023.24E023.22E023.20E023.19E023.18E023.17E023.16E023.16E023.16E023.15E023.15E023.15E023.15E02,Profile处理要点,和一般计算一样设置求解器,模型等)Define-Profile-Read(数据)Define-BoundaryCondition-所需设置的面-Thermal-Temperature-Tempt(和一般计算一样,设置其它边值条件、初值条件及求解与结果检查等),UDF处理温度,include“udf.h“DEFINE_PROFILEbottom_temperature,thread,position{realx[ND_ND];/*thiswillholdthepositionvector*/realy;face_tf;begin_f_loopf,thread{F_CENTROIDx,f,thread;yx[0];F_PROFILEf,thread,position315.y-.044*y-.044/.044/.044*35.;}end_f_loopf,thread},UDF设置边界温度处理要点,和一般计算一样设置求解器,模型等)Define-Userdefined-Functions-(InterpretedOrCompiled)-编译Define-BoundaryCondition-所需设置的面-Thermal-Temperature-BottomTemperature(和一般计算一样,设置其它边值条件、初值条件及求解与结果检查等),侧面与地面两处UDF,定义一个以上UDF,,,,上壁面温度300K,温度抛物线分布,绝热壁面,温度315K,,温度分布,,UDF编写,include“udf.h“DEFINE_PROFILEbottom_temperature,thread,position{程序1}DEFINE_PROFILEside_temperature,thread,position{程序2}DEFINE_PROFILEinlet_velocity,thread,position{程序3。。。。。。},边界温度分布,左侧温度分布下面温度分布,场温度分布,UDF编写-用C语言,注释/*这是刘某人讲课示范用的程序*/数据类型Int整型Long长整型Real实数Float浮点型Double双精度Char字符型UDF解释函数在单精度算法中定义real类型为float型,在双精度算法宏定义real为double型。因为解释函数自动作如此分配,所以使用在UDF中声明所有的float和double数据变量时使用real数据类型是很好的编程习惯。,局部变量,局部变量只用于单一的函数中。当函数调用时,就被创建了,函数返回之后,这个变量就不存在了,局部变量在函数内部(大括号内)声明。在下面的例子中,mu_lam和temp是局部变量。,DEFINE_PROPERTYcell_viscosity,cell,thread{realmu_lam;realtempC_Tcell,thread;iftemp288.mu_lam5.5e-3;elseiftemp286.mu_lam143.2135-0.49725*temp;elsemu_lam1.;returnmu_lam;},FLUENT求解过程中UDFs的先后顺序,非耦合求解器,耦合求解器,FLUENT网格拓扑,单元(cell)区域被分割成的控制容积单元中心(cellcenter)FLUENT中场数据存储的地方面(face)单元(2Dor3D)的边界边(edge)面(3D)的边界节点(node)网格点单元线索(cellthread)在其中分配了材料数据和源项的单元组面线索(facethread)在其中分配了边界数据的面组节点线索(nodethread)节点组区域(domain)由网格定义的所有节点、面和单元线索的组合,Fluent数据类型,cell_tface_tThreadNodeDomain,cell_t是线索(thread)内单元标识符的数据类型。它是一个识别给定线索内单元的整数索引。face_t是线索内面标识符的数据类型。它是一个识别给定线索内面的整数索引。Thread数据类型是FLUENT中的数据结构。它充当了一个与它描述的单元或面的组合相关的数据容器。Node数据类型也是FLUENT中的数据结构。它充当了一个与单元或面的拐角相关的数据容器。Domain数据类型代表了FLUENT中最高水平的数据结构。它充当了一个与网格中所有节点、面和单元线索组合相关的数据容器。,使用DEFINEMacros定义UDF,DEFINE_MACRONAMEudf_name,passed-invariables这里括号内第一个自变量是你的UDF的名称。名称自变量是情形敏感的必须用小写字母指定。一旦函数被编译(和连接),你为你的UDF选择的名字在FLUENT下拉列表中将变成可见的和可选的。第二套输入到DEFINE宏的自变量是从FLUENT求解器传递到你的函数的变量。,,DEFINE_PROFILEinlet_x_velocity,thread,index用两个从FLUENT传递到函数的变量thread和index定义了名字为inlet_x_velocity的分布函数。这些passed-in变量是边界条件区域的ID(作为指向thread的指针)而index确定了被存储的变量。一旦UDF被编译,它的名字(例如,inlet_x_velocity)将在FLUENT适当的边界条件面板(例如,VelocityInlet面板)的下拉列表中变为可见的和可选的。,UDF源文件中包含udf.h文件,include“udf.h“通过在你的UDF源文件中包含udf.h,编译过程中所有的DEFINE宏的定义与源代码一起被包含进来。udf.h文件也为所有的C库函数头文件包含include指示,与大部分头文件是针对Fluent提供的宏和函数是一样的(例如,mem.h)。除非有另外的指示,没必要在你的UDF中个别地包含这些头文件。,DEFINE_PROFILEinlet_x_velocity,thread,index定义在udf.h文件中为defineDEFINE_PROFILEname,t,ivoidnameThread*t,inti在编译过程中延伸为voidinlet_x_velocityThread*thread,intindex名字为inlet_x_velocity的函数不返回值由于它被声明为空的数据类型。,UDF任务,返回值修改自变量返回值和修改自变量修改FLUENT变量(不能作为自变量传递)写信息到(或读取信息从)case或data文件,返回值,DEFINE_PROPERTY返回一个udf.h中指定的real数据类型。两个real变量传入函数通过函数计算层流粘度mu_lam的值,其是温度C_Tcell,thread的函数。根据单元体温度,计算出mu_lam,在函数结尾,mu_lam值被返回。,DEFINE_PROPERTYcell_viscosity,cell,thread{realmu_lam;realtempC_Tcell,thread;iftemp288.mu_lam5.5e-3;elseiftemp286.mu_lam143.2135-0.49725*temp;elsemu_lam1.;returnmu_lam;},FunctionthatModifyanArgument,判断单元是否在多孔区域,给多孔介质区域定义反应速率;real指针变量rr是一个传递给函数的自变量。UDF使用废弃操作符*分配反应速率值给废弃指针*rr。指针rr指向的目标是设置反应速率。通过这个操作,存储在内存中这个指针上的字符的地址被改变了,不再是指针地址本身,include“udf.h“defineK12.0e-2defineK25.DEFINE_VR_RATEuser_rate,c,t,r,mole_weight,species_mf,rr,rr_t{reals1species_mf[0];realmw1mole_weight[0];ifFLUID_THREAD_Pt},返回一个值和修改一个自变量的函数,DEFINE_SOURCE返回一个在udf.h中指定的数据类型。函数采用自变量ds(它是数组的名字)并设置由eqn指定的元素为关于速度(w_vel)导数的值。(这是z动量方程源项)。这个函数也计算了旋转速度源项的值source,并返回这个值到求解器。,include“udf.h“defineOMEGA50./*rotationalspeedofswirler*/defineWEIGHT1.e20/*weightingcoefficientsinlinearizedequation*/DEFINE_SOURCEuser_swirl,cell,thread,dS,eqn{realw_vel,x[ND_ND],y,source;C_CENTROIDx,cell,thread;yx[1];w_vely*OMEGA;/*linearw-velocityatthecell*/sourceWEIGHT*w_vel-C_WSWIRLcell,thread;dS[eqn]-WEIGHT;returnsource;},修改FLUENT变量的函数,函数由声明变量f作为face_t数据类型开始。一维数组x和变量y是real数据类型。循环宏用来在区域中每个面上循环以创建型线或数据数组。在每个循环内,F_CENTROID为含有indexf的面输出面质心的值(数组x),indexf在由thread指向的线索上。存储在x[1]中的y坐标分配给变量y,它用于计算x速度。然后这个值分配给F_PROFILE,它使用整数index(由求解器传递个它)来设置内存中面上的x速度值。,DEFINE_PROFILEinlet_x_velocity,thread,index{realx[ND_ND];/*thiswillholdthepositionvector*/realy;face_tf;begin_f_loopf,thread{F_CENTROIDx,f,thread;yx[1];F_PROFILEf,thread,index20.-y*y/.0745*.0745*20.;}end_f_loopf,thread},写/读Case或Data文件,在顶部整数kount被定义为全局的(由于它被源代码文件中的所有三个函数使用)并初始化为0。名字为demo_calc的第一个函数,使用DEFINE_ADJUST宏来定义。在demo_calc中,kount的值每次迭代后增加因为每次迭代调用DEFINE_ADJUST一次。名字为writer的第二个函数,使用DEFINE_RW_FILE宏来定义。当保存数据文件时,它指示FLUENT写当前kount值到数据文件。名字为reader的第三个函数,当读取数据文件时,它指示FLUENT从这个数据文件中读取kount的值。这三个函数一起工作如下。如果你运行10次迭代计算(kount将增加到值为10)并保存这个数据文件,当前kount10的值被写入你的数据文件。如果你读这个数据返回到FLUENT并继续计算,kount将以值10开始随着每次迭代继续增加。,include“udf.h“intkount0;/*defineglobalvariablekount*/DEFINE_ADJUSTdemo_calc,domain{kount;printf“kountd\n“,kount;}DEFINE_RW_FILEwriter,fp{printf“WritingUDFdatatodatafile...\n“;fprintffp,“d“,kount;/*writeoutkounttodatafile*/}DEFINE_RW_FILEreader,fp{printf“ReadingUDFdatafromdatafile...\n“;fscanffp,“d“,/*readkountfromdatafile*/},DEFINE_ADJUST,功能及其使用方法,功能,DEFINE_ADJUST是一个用于调节和修改FLUENT变量的通用宏。可以用DEFINE_ADJUST来修改流动变量(如速度,压力)并计算积分。用来对某一标量在整个流场上积分,然后在该结果的基础上调节边界条件。在每一步迭代中都可以执行用DEFINE_ADJUST定义的宏,并在解输运方程之前的每一步迭代中调用它。,DEFINE_ADJUSTname,d,DEFINE_ADJUST有两个参变量name和d。name是你所指定的UDF的名字。当你的UDF编译并连接时,你的FLUENT图形用户界面就会显示这个名字,此时你就可以选择它了。d是FLUENT解算器传给你的UDF的变量。D是一个指向区域的指针,调节函数被应用于这个区域上。区域变量提供了存取网格中所有单元和表面的线程。对于多相流,由解算器传给函数的区域指针是混合层区域指针。DEFINE_ADJUST函数不返回任何值给解算器。,DEFINE_INIT,用DEFINE_INIT宏来定义一组解的初始值。DEFINE_INIT完成和修补一样的功能,只是它以另一种方式UDF来完成。每一次初始化时DEFINE_INIT函数都会被执行一次,并在解算器完成默认的初始化之后立即被调用。因为它是在流场初始化之后被调用的,所以它最常用于设定流动变量的初值。,DEFINE_INITname,d,DEFINE_INIT有两个参变量name和d。name是你所指定的UDF的名字。当你的UDF编译并连接时,你的FLUENT图形用户界面就会显示这个名字,此时你就可以选择它了。d是FLUENT解算器传给你的UDF的变量所作用的计算区域,DEFINE_INIT举例,下面的UDF名字是my_init_func,它在某一个解中初始化了流动变量。在解过程开始时它被执行了一次。它可以作为解释程序或者编译后的UDF在FLUENT中执行。,include“udf.h“DEFINE_INITmy_init_function,domain{cell_tc;Thread*t;realxc[ND_ND];/*loopoverallcellthreadsinthedomain*/thread_loop_ct,domain{/*loopoverallcells*/begin_c_loop_allc,t{C_CENTROIDxc,c,t;ifsqrtND_SUMpowxc[0]-0.5,2.,powxc[1]-0.5,2.,powxc[2]-0.5,2.程序-附件-命令提示符,进入DOS界面,访问\libudf\ntx86\2d,然后敲nmake,这样就OK了.然后在FLUENT里load这个libudf就行了.,CompiledUDFs-方法二,在CompiledUDF里,点addsourcecodes,找到源程序,加入,然后build,再LOAD就行了。(如果在在原来的文件夹下已经有libudf文件夹,那你把它删了再进行上面的步骤,或者你把libudf文件夹改成其它任何名字),CompiledUDFs要点,设置比较严格,步骤繁琐,但计算效率高。有些语句有变化(在UDF中,要在控制窗口显示一些值,比如说压力值,用InterpretedUDF时就得用printf语句,而在CompiledUDF时就得用Message语句,二者不能互用.,激活UDF,已计算值的调整,,,激活模型明确UDF,,,,,,,UDS,求解用户自定义标量输运方程如电磁流体(用于自定义标量求解磁场)磁场对流体的加速与阻尼用UDF加入方程中,标量输运基本理论,单相流动,对于任意标量,Fluent求解方程,UDS只能用于流体区域计算,多相流动,对于任意标量,Fluent求解方程,定常单相流求解方程,无对流通量质量流率计算出对流通量用户自定义通量,UDS求解过程,1、确定用户自定义标量数Define-userdefined-scalars,,,,最多50个,UDS求解过程(续),给定FluxFunctionnone,massflowrate,user-definedfunctionDEFINE_UDF_FLUX,UDS求解过程(续),设定UnsteadyFunctionnonedefault,user-definedfunction(DEFINE_UDS_UNSTEADY,UDS求解过程(续),设定边界条件Define-boundaryconditions,UDS求解过程(续),(如果有源项)流体面板define-boundaryconditions-fluid,UDS求解过程(续),设定求解参数,给定初始值,计算检查求解结果scalar-nDiffusionCoef.OfScalar-n,