第一章.介绍本章简要地介绍了用户自定义函数(UDF)及其在Fluent中的用法。在1.1到1.6节中我们会介绍一下什么是UDF;如何使用UDF,以及为什么要使用UDF,在1.7中将一步步的演示一个UDF例子。1.1什么是UDF?1.2为什么要使用UDF?1.3UDF的局限1.4Fluent5到Fluent6UDF的变化1.5UDF基础1.6解释和编译UDF的比较1.7一个step-by-stepUDF例子1.1什么是UDF?用户自定义函数,或UDF,是用户自编的程序,它可以动态的连接到Fluent求解器上来提高求解器性能。用户自定义函数用C语言编写。使用DEFINE宏来定义。UDF中可使用标准C语言的库函数,也可使用FluentInc.提供的预定义宏,通过这些预定义宏,可以获得Fluent求解器得到的数据。UDF使用时可以被当作解释函数或编译函数。解释函数在运行时读入并解释。而编译UDF则在编译时被嵌入共享库中并与Fluent连接。解释UDF用起来简单,但是有源代码和速度方面的限制不足。编译UDF执行起来较快,也没有源代码限制,但设置和使用较为麻烦。1.2为什么要使用UDF?一般说来,任何一种软件都不可能满足每一个人的要求,FLUENT也一样,其标准界面及功能并不能满足每个用户的需要。UDF正是为解决这种问题而来,使用它我们可以编写FLUENT代码来满足不同用户的特殊需要。当然,FLUENT的UDF并不是什么问题都可以解决的,在下面的章节中我们就会具体介绍一下FLUENTUDF的具体功能。现在先简要介绍一下UDF的一些功能:z定制边界条件,定义材料属性,定义表面和体积反应率,定义FLUENT输运方程中的源项,用户自定义标量输运方程(UDS)中的源项扩散率函数等等。z在每次迭代的基础上调节计算值z方案的初始化z(需要时)UDF的异步执行z后处理功能的改善zFLUENT模型的改进(例如离散项模型,多项混合物模型,离散发射辐射模型)由上可以看出FLUENTUDF并不涉及到各种算法的改善,这不能不说是一个遗憾。当然为了源代码的保密我们还是可以理解这样的做法的。其实,如果这些代码能够部分开放,哪怕就一点点,我想FLUENT会像LINUX一样发展更为迅速,使用更为广泛。遗憾的是,从目前来看,这只是一种幻想。什么时候中国人可以出自己的精品?1.3UDF的局限尽管UDF在FLUENT中有着广泛的用途,但是并非所有的情况都可以使用UDF。UDF并不能访问所有的变量和FLUENT模型。例如,它不能调节比热值;调节该值需要使用求解器的其它功能。如果您不知道是否可以用UDF解决某个特定的问题,您可以求助您的技术支持。1.4Fluent5到Fluent6UDF的变化如果你有FLUENT5的UDF编程经验,请注意在FLUENT6种的下列变化:•FLUENT6中加入了大量的通用多相模型。Whenoneofthesegeneralmultiphasemodelsisenabled,storagemustbesetasideforthemixtureaswellastheindividualphases.Thisfunctionalityismanifestedinthecodethroughtheuseofadditionalthreadanddomaindatastructures.Consequently,somepredefinedmacroshavebeenaddedthatallowaccesstodatacontainedwithinmixture-levelandphase-leveldomainandthreadstructures.SeeSection3.11fordetailsonwritingUDFformultiphaseapplications.IfyouhaveaFLUENT5UDFwithanexternaldomaindeclarationthatyouwanttouseinFLUENT6,thentheexternstatementmustbereplacedbyacalltotheGet_DomainutilityandassignmenttoaDomainpointerasshownbelow.TheFluent-providedutility,Get_Domain(1),returnsthepointertothemixture-leveldomain.SeeSection6.5.1formoredetailsonGet_Domain.ExampleexternDomain*domain;DEFINE_ON_DEMAND(my_udf){...}istobereplacedbyDEFINE_ON_DEMAND(my_udf){Domain*domain;domain=Get_Domain(1);...}ThemacroC_VOFaccessesvolumefractionvaluesfromtheFLUENTsolver.C_VOF(c,pt[i])hastwoarguments,candpt[i].cisthecellidentifier.pt[i]isthepointertothecorrespondingphase-levelthreadfortheithphase,whereiisthephase_domain_index.Forexample,C_VOF(c,pt[i])canbeusedtoreturnthevolumefractionoftheithphasefluidatcellc.Thepointerpt[i]canalsoberetrievedusingTHREAD_SUB_THREAD,discussedinSection6.5.4,usingiasanargument.•ForcompiledUDF,themakefilecalledMakefile.udfthatwasprovidedinpreviousFLUENTreleaseshasbeenrenamedtomakefile.udf2.SeeSection7.3.2formoredetails.•Formultiphaseflowproblems,youwillneedtosupplyyourownuser-definedscalarfluxfunctioninsteadofusingthedefaultfunctionprovidedbyFLUENT.•DEFINE_PROPERTYistobeusedtodefineUDFforparticleordropletdiameterforthemixturemodel,previouslytheAlgebraicSlipMixtureModel(ASMM),insteadoftheDEFINE_DRIFT_DIAMmacro.1.5UDF基础•1.5.1输运方程•1.5.2单元(Cells),面,区域(Zones)和线(Threads)•1.5.3操作•1.5.4求解器数据•1.5.5运行1.5.1输运方程FLUENT求解器建立在有限容积法的基础上,这种方法将计算域离散为有限数目的控制体或是单元。网格单元是FLUENT中基本的计算单元,这些单元的守恒特性必须保证。也就是说普通输运方程,例如质量,动量,能量方程的积分形式可以应用到每个单元:(1.5.1)此处,是描述普通输运数量的变量(ageneraltransportablequantity),根据所求解的输运方程它可取不同的值。下面是在输运方程中可求解的的子集。TransportEquationVariableforcontinuity1xmomentumvelocity(u)ymomentumvelocity(v)zmomentumvelocity(w)energyenthalpy(h)turbulentkineticenergykturbulentdissipationratespeciestransportmassfractionofspecies(Yi)守恒与否需要知道通过单元边界的通量。因此,需计算出单元和面上的属性值(properties)。1.5.2单元(Cells),面,区域(Zones)和线(Threads)单元和单元面被组合为一些区域(zones),这些区域规定了计算域(例如,入口,出口,壁面)的物理组成(physicalcomponents)。当用户使用FLUENT中的UDF时,用户的UDF可调用流体区域或是边界区域的计算变量(solutionvariables)。UDF需要获得适当的变量,比如说是区域参考(azonereference)和单元ID,以便标定各个单元。区域(Azone)是一群单元或单元面的集合,它可以由模型和区域的物理特征(比如入口,出口,壁面,流体区域)来标定。例如,一些被指定为面域(afacezone)的单元面可以被指定为velocity-inlet类型,由此,速度也就可指定了。线(Athread)是FLUENT数据结构的内部名称,可被用来指定一个区域。Thread结构可作为数据储存器来使用,这些数据对于它所表示的单元和面来说是公用的(TheThreadstructureactsasacontainerfordatathatiscommontothegroupofcellsorfacesthatitrepresents)。1.5.3操作多数的UDF任务需要在一个线的所有单元和面上重复执行。比如,定义一个自定义轮廓函数(acustomprofilefunction)则会对一个面线上(inafacethread)的所有单元和面进行循环。为了用户方便,FluentInc.向用户提供了一些循环宏工具(loopingmacroutilities)来执行对单元,面,节点(nodes)和线(threads)的重复操作。例如,单元循环宏(Cell-loopingmacros)可以对给定单元线上的所有单元进行循环操作(loopovercellsinagivencellthreadallowingaccesstoallofthecells)。而面循环宏(Face-loopingmacros)则可调用所有给定面线(agivenfacethread)的面。Fluent提供的循环工具请见Chapter6。在某些情况下,UDF需要对某个变量操作,而这个变量恰恰又不能直接被当作变量来传递调用。比如,如果用户使用DEFINE_ADJUST宏来定义UDF,求解器将不会向它传递thread指针。这种情况下,用户函数需要用Fluent提供的宏来调用线指针(threadpointer)。见Chapter6。1.5.4求解器数据通过FLUENT用户界面将C函数(它已被编译和连接)连接到求解器上可实现调用求解器变量。一旦UDF和求解器正确连接,无论何时,函数都可调用求解器数据。这些数据将会被作为用户变量自动地传递给UDF。注意,所有的求解器变量,不管是求解器传递给UDF的,还是UDF传递给求解器的,都使用SI单位。1.5.5运行UDF将会在预定时刻被FLUENT调用。但是,也可对它们进行异步执行,使用DEFINE_ON_DEMAND宏,还可在需要时(ondemand)执行。详情请见4.2.31.6解释和编译UDF的比较编译UDF和FLUENT的构建方式一样。脚本Makefile被用来调用C编译器来构建一个当地目标代码库(anativeobjectcodelibrary)。目标代码库包含高级C语言源代码的机器语言翻译。代码库在FLUENT运行时由“动态加载”(``dynamicloading'')过程连接到FLUENT上。连接后,与共享库的联系(theassociationwiththesharedlibrary)将会被保存在用户的case文件中,这样,当FLUENT以后再读入case文件时,此编译库将会与FLUENT自动连