fluent UDF-Ch4
- 格式:doc
- 大小:736.50 KB
- 文档页数:90
如何在FLUENT中激活你的UDF
UDF(User-Defined Function)可以定义为用户自定义的函数,在FLUENT中可以用于模拟各种复杂的流体流动状态。
通常,UDF有一个C或Fortran编写的函数代码,这样就可以用UDF来描述出与物理特性密切相关的各种条件。
UDF在FLUENT当中可以用于向流体添加几何体阻力,调节参数,或者在一些channel中调整速度等。
激活FLUENT中的UDF有几步操作:
1)编写代码:首先,需要使用C或Fortran语言对UDF函数进行编写,根据不同的功能来定义不同的UDF函数,比如用来描述自定义的速度边界,输入静力学条件,改变流线型等。
2)编译代码:编写完代码以后需要将其编译成UDF库,使用
fluent_se.exe或fluent_des.exe编译UDF,在编译的过程中UDF会将编写的代码编译成为一个DLL文件,文件名是udf_func.dll。
3)加载UDF库:当编译完成,就可以在FLUENT中加载UDF库,可以在菜单栏中点击Utilities-User Defined Function-Load/Unload,选择文件udf_func.dll,点击Load,即可将UDF库加载到FLUENT中,UDF也就激活了。
4)定义UDF:加载完UDF库后,可以在UDF Manager界面中看到新添加的UDF,可以选择这些UDF,比如选择速度边界UDF,点击Define按钮,定义UDF,可以在弹出的窗口中输入速度边界UDF函数,或者添加参数等。
经过上述几步,UDF就激活了,可以在FLUENT中使用了。
计算流体力学作业FLUENT 模拟燃烧问题描述:长为2m、直径为的圆筒形燃烧器结构如图1所示,燃烧筒壁上嵌有三块厚为 m,高 m的薄板,以利于甲烷与空气的混合。
燃烧火焰为湍流扩散火焰。
在燃烧器中心有一个直径为 m、长为 m、壁厚为 m的小喷嘴,甲烷以60 m/s的速度从小喷嘴注入燃烧器。
空气从喷嘴周围以 m/s的速度进入燃烧器。
总当量比大约是(甲烷含量超过空气约28%),甲烷气体在燃烧器中高速流动,并与低速流动的空气混合,基于甲烷喷嘴直径的雷诺数约为×103。
假定燃料完全燃烧并转换为:CH4+2O2→CO2+2H2O反应过程是通过化学计量系数、形成焓和控制化学反应率的相应参数来定义的。
利用FLUENT的finite-rate化学反应模型对一个圆筒形燃烧器内的甲烷和空气的混合物的流动和燃烧过程进行研究。
1、建立物理模型,选择材料属性,定义带化学组分混合与反应的湍流流动边界条件2、使用非耦合求解器求解燃烧问题3、对燃烧组分的比热分别为常量和变量的情况进行计算,并比较其结果4、利用分布云图检查反应流的计算结果5、预测热力型和快速型的NO X含量6、使用场函数计算器进行NO含量计算一、利用GAMBIT建立计算模型第1步启动GAMBIT,建立基本结构分析:圆筒燃烧器是一个轴对称的结构,可简化为二维流动,故只要建立轴对称面上的二维结构就可以了,几何结构如图2所示。
(1)建立新文件夹在F盘根目录下建立一个名为combustion的文件夹。
(2)启动GAMBIT(3)创建对称轴①创建两端点。
A(0,0,0),B(2,0,0)②将两端点连成线(4)创建小喷嘴及空气进口边界①创建C、D、E、F、G点②连接AC、CD、DE、DF、FG。
(5)创建燃烧筒壁面、隔板和出口①创建H、I、J、K、L、M、N点(y轴为,z轴为0)。
②将H、I、J、K、L、M、N向Y轴负方向复制,距离为板高度。
③连接GH、HO、OP、PI、IJ、JQ、QR、RK、KL、LS、ST、TM、MN、NB。
FLUENT_UDF官方培训教程
必须原创
FLUENT UDF全称为Fluent User Defined Functions,是ANSYS Fluent有限元分析软件的一种高级应用技术,主要用于定制流体、多相流及热传导模拟中的特殊调整元件。
本文介绍如何使用FLUENT-UDF进行实际模拟的培训教程。
一、FLUENTUDF的概念
FLUENT UDF是一种定制的技术,它可以灵活地增强Fluent本身的模拟能力,并让用户能够自定义函数来调整流体、多相流及热传导模拟中的特殊参数。
FLUENT UDF是一种可以定义特殊参数和条件的技术,它可以让Fluent本身的模拟更加强大。
用户可以根据实际的需求自定义这些特殊参数,从而实现更加全面和精确的模拟。
二、FLUENTUDF的步骤
2.编写UDF函数:
UDF函数可以用C或Fortran语言编写,也可以用Fluent自带的UDFEasy编译器编写。
编写UDF函数的基本步骤是:
(1)编写UDF函数的声明,它在编译器的第一行声明,用于定义函数的相关参数;
(2)编写函数代码,用于计算流体及热传导的相关参数;
(3)编写函数的结束部分,使函数返回正确的值并运行成功。
fluent之UDF⽂件的操作
下⽂转⾃沙场醉客之博客:
可⽤txt⽂件进⾏UDF编程,之后将⽂件改为.c⽂件。
(也可⽤VC编程,保存为.c⽂件)
将程序导⼊到Fluent中利⽤编译功能,具体操作
在 fluent中的Define -> Use-Defined -> Compiled 打开之后,选择source files下⾯的Add...,找到编写好的.c⽂件打开,点击Build,就会⽣成⼀个以liberary name命名的⽂件夹,编译好的资料就放在这个⽂件夹⾥⾯,最后点击load就会将编译好的内容导⼊到Fluent中,这样你在有UDF选项的下拉菜单中就会看到你编好的程序名称。
利⽤UDF编程和C语⾔编程很相似,所以最好知道⼀些C语⾔编程的基础,再掌握⼀些Fluent的UDF固有的⼀些命令,基本上⼀些简单的程序就都没问题了。
第四章DEFINE宏(未完整翻译)本章介绍了Fluent公司所提供的预定义宏,我们需要用这些预定义宏来定义UDF。
在本章中这些宏就是指DEFINE宏。
∙ 4.1 概述∙ 4.2 通用解算器DEFINE宏∙ 4.3 模型指定DEFINE宏∙ 4.4 多相DEFINE宏∙ 4.5 离散相模型DEFINE宏4.1 概述DEFINE宏一般分为如下四类:∙通用解算器∙模型指定∙多相∙离散相模型(DPM)对于本章所列出的每一个DEFINE宏,本章都提供了使用该宏的源代码的例子。
很多例子广泛的使用了其它章节讨论的宏,如解算器读取(第五章)和utilities (Chapter 6)。
需要注意的是,并不是本章所有的例子都是可以在FLUENT中执行的完整的函数。
这些例子只是演示一下如何使用宏。
除了离散相模型DEFINE宏之外的所有宏的定义都包含在udf.h文件中。
离散相模型DEFINE宏的定义包含在dpm.h文件中。
为了方便大家,所有的定义都列于附录A中。
其实udf.h头文件已经包含了dpm.h文件,所以在你的UDF源代码中就不必包含dpm.h文件了。
注意:在你的源代码中,DEFINE宏的所有参变量必须在同一行,如果将DEFINE声明分为几行就会导致编译错误。
4.2 通用解算器DEFINE宏本节所介绍的DEFINE宏执行了FLUENT中模型相关的通用解算器函数。
表4.2.1提供了FLUENT中DEFINE宏,以及这些宏定义的功能和激活这些宏的面板的快速参考向导。
每一个DEFINE宏的定义都在udf.h头文件中,具体可以参考附录A。
∙DEFINE_ADJUST (4.2.1节)∙DEFINE_INIT (4.2.2节)∙DEFINE_ON_DEMAND (4.2.3节)∙DEFINE_RW_FILE (4.2.4节)∙ 4.2.1 DEFINE_ADJUST∙ 4.2.2 DEFINE_INIT∙ 4.2.3 DEFINE_ON_DEMAND∙ 4.2.4 DEFINE_RW_FILE4.2.1 DEFINE_ADJUST功能和使用方法的介绍DEFINE_ADJUST是一个用于调节和修改FLUENT变量的通用宏。
fluent udf 温度梯度Fluent UDF (User Defined Function) 是用于在ANSYS Fluent软件中自定义计算和模拟的方法。
温度梯度是描述温度变化率的数值,通常表示为温度随空间位置的导数。
可以使用Fluent UDF来计算温度梯度。
编写Fluent UDF以计算温度梯度需要以下步骤:1. 在ANSYS Fluent中创建一个新的用户定义内存(DEFINE)函数。
这可以通过选择“Define”>“User-defined”>“Functions”来完成。
2. 在用户定义函数编辑器中编写UDF代码来计算温度梯度。
代码应包括定义和初始化变量、读取相应的物理场参数(如温度)、计算温度梯度并将其发送回流场。
3. 在Fluent中加载和编译UDF代码。
这可以通过选择“Define”>“User-defined”>“Compiled”>“Load”来完成。
确保编译和加载过程中没有错误。
4. 在Fluent设置中应用UDF,在“Boundary Conditions”或“Cell Zones”等相应位置中选择使用刚刚编译的UDF进行温度梯度计算。
这可以通过选择“Define”>“Boundary Conditions”或“Define”>“Cell Zones”来完成。
5. 运行模拟,并在需要的位置和时刻监视温度梯度的值。
这可以通过在Fluent中选择相应的监视器(如表格或曲线)来实现。
需要注意的是,编写Fluent UDF需要一定的编程知识和理解,因此建议在使用之前熟悉Fluent UDF编程的基本概念和使用方法。
5.2 单元格宏流体变量宏名称(参数)参数类型返回值C_T(c,t) cell t c, Thread *t 温度C_T_G(c,t) cell t c, Thread *t 温度梯度矢量C_T_G(c,t)[i] cell t c, Thread *t, int i 温度梯度矢量的分量C_T_RG(c,t) cell t c, Thread *t 改造后的温度梯度矢量C_T_RG(c,t)[i] cell t c, Thread *t, int i 改造后的温度梯度矢量的分量C_T_M1(c,t) cell t c, Thread *t 温度的前一次步长C_T_M2(c,t) cell t c, Thread *t 温度的前二次步长C_P(c,t) cell t c, Thread *t 压力C_DP(c,t) cell t c, Thread *t 压力梯度矢量C_DP(c,t)[i] cell t c, Thread *t, int i 压力梯度矢量的分量C_U(c,t) cell t c, Thread *t u 方向的速度C _V(c,t) cell t c, Thread *t v方向的速度C_W(c,t) cell t c, Thread *t w方向的速度C_H(c,t) cell t c, Thread *t 焓C_YI(c,t,i) cell t c, Thread *t, int i 物质质量分数C_K(c,t) cell t c, Thread *t 湍流运动能C_D(c,t) cell t c, Thread *t 湍流运动能的分散速率C_O(c,t) cell t c, Thread *t 确定的分散速率读写导数的宏名称(参数)参数类型返回值C DUDX(c,t) cell t c, Thread *t velocity derivativeC DUDY(c,t) cell t c, Thread *t velocity derivativeC DUDZ(c,t) cell t c, Thread *t velocity derivativeC DVDX(c,t) cell t c, Thread *t velocity derivativeC DVDY(c,t) cell t c, Thread *t velocity derivativeC DVDZ(c,t) cell t c, Thread *t velocity derivativeC DWDX(c,t) cell t c, Thread *t velocity derivativeC DWDY(c,t) cell t c, Thread *t velocity derivativeC DWDZ(c,t) cell t c, Thread *t velocity derivative存取材料性质的宏名称(参数)参数类型返回值C_FMEAN(c,t) cell t c, Thread *t 第一次混合分数的平均值C_FMEAN2(c,t) cell t c, Thread *t 第一次混合分数的平均值C_FVAR(c,t) cell t c, Thread *t 第一次混合分数变量C_FVAR2(c,t) cell t c, Thread *t 第二次混合分数变量C_PREMIXC(c,t) cell t c, Thread *t 反应过程变量C_LAM FLAME SPEED(c,t) cell t c, Thread *t 层流焰速度C_CRITICAL STRAIN cell t c, Thread *t 临界应变速度RATE(c,t)C_ POLLUT(c,t,i) cell t c, Thread *t, int i 第i个污染物质的质量分数C_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, Thread *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 jC_DIFF EFF(c,t,i) cell t c, Thread *t, int i 物质的有效扩散率C_ABS COEFF(c,t) cell t c, Thread *t 吸附系数C_SCAT COEFF(c,t) cell t c, Thread *t 扩散系数C_NUT(c,t) cell t c, Thread *t 湍流速度forSpalart-Allmaras为单元格读写用户定义的标量和存储器的宏名称(参数)参数类型返回值C _UDSI(c,t,i) cell t c, Thread *t, int i 用户定义的标量(单元格)C_UDSI M(c,t,i) cell t c, Thread *t, int i 前一次步长下用户定义的标量(单元格)C_UDSI_DIFF(c,t,i) cell t c, Thread *t, int i 用户定义的标量的分散率(单元格)C_UDMI(c,t,i) cell t c, Thread *t, int i 用户定义的存储器(单元格)给雷诺兹压力模型读写变量的宏名字(参数)参数类型返回值C RUU(c,t) cell t c, Thread *t uu 雷诺兹压力C RVV(c,t) cell t c, Thread *t vv 雷诺兹压力C RWW(c,t) cell t c, Thread *t ww 雷诺兹压力C RUV(c,t) cell t c, Thread *t uv雷诺兹压力sC RVW(c,t) cell t c, Thread *t vw 雷诺兹压力C RUW(c,t) cell t c, Thread *t uw 雷诺兹压力5.3表面宏mem.h中的流体变量读写的宏名称(参数)参数类型返回值F_R(f,t) face t f, Thread *t, 密度F_P(f,t) face t f, Thread *t, 压力F_U(f,t) face t f, Thread *t, u方向的速度F_V(f,t) face t f, Thread *t, v 方向的速度F_W(f,t) face t f, Thread *t, w方向的速度F_T(f,t) face t f, Thread *t, 温度F_H(f,t) face t f, Thread *t, 焓F_K(f t) face t f, Thread *t, 湍流运动能F_D(f,t) face t f, Thread *t, 湍流运动能的分散速率F_YI(f,t,i) face t f, Thread *t, int i 物质的质量分数F_FLUX(f,t) face t f, Thread *t 通过边界表面的质量流速用于给表面读写用户定义的标量和存储器的宏名称(参数)参数类型返回值F_UDSI(f,t,i) face t f, Thread *t, int i 用户确定的标量(表面)F_UDMI(f,t,i) face t f, Thread *t, int i 用户定义的存储器(表面)混合面变量宏其余的表面变量宏在表5.3.3中列出名称(参数)参数类型返回值F_C0(f,t) face t f, Thread *tF_C0_THREAD(f,t) face t f, Thread *tF_C1(f,t) face t f, Thread *tF_C1_ THREAD(f,t) face t f, Thread *t5.4几何宏5.4.1节点和面的数量在表5.4.1中列出的宏C_NNODES和C_NFACES返回相应的节点和面的整数值。
在使用Fluent软件进行模拟计算时,经常会遇到需要自定义用户子程序(User Defined Function,简称UDF)的情况。
UDF是Fluent中用户自己编写的函数,用于描述流场中的边界条件、源项等物理过程。
为了正确地使用UDF并进行模拟计算,我们需要了解如何编写和编译UDF。
本教程将向大家介绍如何使用ANSYS Fluent进行UDF的编译,并提供一些常见问题的解决方法。
一、准备工作在进行UDF编译之前,我们需要进行一些准备工作。
1. 确保已安装ANSYS Fluent软件,并且能够正常运行;2. 确保已安装C/C++编译器,常见的编译器有Microsoft Visual Studio、GCC等;3. 编写好UDF的源代码文件,可以使用任何文本编辑器编写,但建议使用支持C/C++语法高亮的编辑器,以便于排查语法错误。
二、设置Fluent编译环境在进行UDF编译之前,我们需要设置Fluent的编译环境,以确保编译器可以正确地识别Fluent的API。
1. 打开命令行终端(Windows系统为cmd,Linux/Unix系统为Terminal);2. 运行以下命令设置Fluent的编译环境:对于Windows系统:```bashcd C:\Program Files\ANSYS Inc\v200\fluentfluent 3d -i```对于Linux/Unix系统:```bashcd /usr/ansys_inc/v200/fluent./fluent 3d -t xxx -g -i```其中,xxx是你的图形界面类型,可以根据你实际的图形界面类型进行替换,一般为Gl 或 X11。
运行上述命令后,Fluent将会启动,并且设置了编译环境。
在Fluent 的命令行界面中,我们可以进行UDF的编译和加载。
三、编译UDF在设置了Fluent的编译环境后,我们可以开始编译UDF了。
1. 将编写好的UDF源代码文件(后缀名通常为.c或.cpp)放置在Fluent的工作目录中;2. 在Fluent的命令行界面中,输入以下命令进行编译:```bash/define/user-definedpiled-functions load my_udf-name/define/user-definedpiled-functionspile my_udf-name/define/user-definedpiled-functions write my_udf-name/exit```其中,my_udf-name是你的UDF源代码文件的文件名(不包括后缀名),例如my_udf。
Fluent_UDF_中文教程Fluent_UDF是Fluent中的用户定义函数,能够定制化模拟中的物理过程和边界条件。
通过Fluent_UDF,用户可自由地编写自己的程序,以扩展Fluent的功能。
Fluent_UDF具有灵活性和可移植性,可以用C语言或Fortran语言编写。
下面我们将介绍Fluent_UDF的使用方法和编写过程。
1. Fluent_UDF的基本概念在Fluent中运行的模拟,都是由CFD模型和相应的物理模型组成。
CFD模型负责离散化解决流动方程,在CFD模型的基础上,物理模型定义了流体在不同条件下的行为,例如燃烧过程、湍流模型、多相流模型等。
而Fluent_UDF则是一套可以编写自定义的物理模型或者边界条件的库,可以与Fluent中的各类模型进行整合工作。
用户可以通过编写Fluent_UDF来与Fluent交互,其中可以定义用户自定义的边界条件,定义新的物性模型、初始或边界条件以及仿真的物理过程等。
2. Fluent_UDF编译器Fluent_UDF需要使用自带的编译器来编译用户自定义函数,这个编译器名为Fluent_Compiler。
Windows系统下,Fluent_Compiler可在Fluent程序安装目录内找到。
在运行Fluent程序之前,用户需要确保其系统环境变量中设置了编译器路径的系统变量。
Linux系统下,Fluent_Compiler亦随Fluent程序安装,其使用方法与Windows类似。
3. Fluent_UDF文件夹的创建在Fluent安装目录下,用户必须创建一个名为udf的文件夹,以存储用户自定义的函数。
用户可以在命令行中进入Fluent 安装目录下的udf文件夹中,输入以下命令创建文件:mkdir myudf其中myudf是用户自定义的函数文件夹名称。
4. Fluent_UDF函数编写Fluent_UDF支持两种编程语言:C语言和Fortran语言。
Fluent模拟化学反应的udf例题及出售联系方式:*******************众所周知,反应器内的诸多化学反应速率方程不一定采用标准阿伦尼乌斯的表达型式,而可能采用双曲线等较为复杂的速率型式。
一旦化学反应速率方程不是标准的阿伦尼乌斯来表达,则Fluent的直接设置不能够满足用户要求,这个时候一定需要c语言等外接程序,才能够获得理想的结果。
鉴于此,本人采用fluen+udf的方法来计算带有化学反应的模拟,读者可以对udf稍加修改即可获得需要的化学反应模拟的要求。
采用fluent的有限速率型式(以下简称:fluent有限速率模型)计算结果作为模拟标准,将fluent外挂udf程序(以下简称:udf反应速率模型)计算与之比较,从而说明本人采用的fluent+udf模拟方法的正确性及准确性。
联系方式:*******************,欢迎探讨!第1页 / 共10页1.反应器结构及边界反应器结构如下图一(二维轴对称结构)。
圆柱形燃烧器内,300K 的甲烷以0.01 m/s 与300K的空气以0.05 m/s速度进入反应器并且发生化学反应,假设其发生的化学反应为:CH4+1.5O2=CO+2H2O反应速率采取r=k*[C CH4]^a*[C O2]^b。
其中:指前因子k=A*e^(-Ea/RT), Ea为活化能;[C CH4]、[C O2]分别为CH4及O2的浓度;a、b为CH4及O2的Rate Exponent。
图一反应器结构及边界条件联系方式:*******************,欢迎探讨!第2页 / 共10页联系方式:*******************,欢迎探讨! 第3页 / 共10页 2. 计算过程监控Fluent 有限速率模型计算的残差曲线监控图,如图二。
图二 Fluent 有限速率模型的曲线监控图更改udf 书写化学方程的残差曲线监控图,如图三。
可以看到,fluent 内添加udf 后,残差会有一个跳跃,但是经过一段时间的计算,各残差恢复稳定。
如果你选择Troe作为反应类型,你可以在Troe Parameter下指定Alpha,T1,T2,T3的值(方程13.1-22中的α,1T,2T和3T)。
如果你选择SRI反应类型, 你可以在SRI Parameter下指定a,b,c,d,e的值(方程13.1-22中的a,b,c,d和e)。
6.如果你使用层流/有限速率或是EDC模型模拟湍流-化学反应的相互作用,且反应是可逆的,则打开对于Arrhenius Rate的Include Backward Reaction选项。
当选定这一选项时,你将不能编辑产物的Rate Exponent,这些值将被设定为与相应的Stoich.系数相等。
如果你不希望使用FLUENT的缺省值,或者你在定义你自己的反应,你将还需要指定标准状态觞和标准状态焓,以在逆向反应速率常数计算中使用(方程13.1-10)。
注意可逆反应选项对于涡耗散或有限速率/涡耗散湍流-化学反应相互作用模型是不可获得的。
7.如果你使用湍流-化学反应相互作用的涡耗散或有限速率/涡耗散模型,你可以在Mixing Rate标题下输入A和B的值。
但是注意除非你有可靠的数据,不要改变这些值/在大多数情况下,你只需要简单地使用缺省值。
A是湍流混合速率的常数A(方程13.1-25和13.1-26),当一种物质作为反应物在反应中出现时用于这种物质。
缺省值为4.0,根据Magnussen等人给出的经验值[149]。
B是湍流混合速率的常数B(方程13.1-25和13.1-26),当一种物质作为产物在反应中出现时用于这种物质。
缺省值为0.5,根据Magnussen 等人给出的经验值[149]。
8.对于每一种你需要定义的反应重复步骤2-7。
完成所有反应后,点OK 。
定义燃料混合物的物质和反应经常会遇到这种情况,燃烧系统中的燃料不能用一种纯物质(例如CH4或C2H6)来描述)。
复杂的烃类,包括燃料油乃至木材片),很难用这种纯物质来定义。
FLUENTUDF1. IntroductionFLUENTUDF is a feature of the ANSYS FLUENT software package that allows users to define their own user-defined functions (UDFs) using the C programming language. UDFs provide the flexibility to customize and extend the functionality of FLUENT for specific simulations or applications. This document provides an overview of FLUENTUDF, its features, and a step-by-step guide on how to create and use UDFs in FLUENT.2. Features of FLUENTUDFFLUENTUDF offers several features that enable users to create customized functions for their simulations:2.1. Access to FLUENT Data StructuresUDFs in FLUENT have direct access to the underlying data structures and solver routines of FLUENT. Users can access and modify various properties and variables such as flow conditions, boundary conditions, mesh information, and solver parameters.2.2. Ability to Define Custom Boundary ConditionsWith FLUENTUDF, users can define their own boundary conditions that are not available in the standard FLUENT package. This allows for greater flexibility in modeling complex real-world scenarios.2.3. Integration of User-Defined EquationsUsers can integrate user-defined equations into the FLUENT solver by writing UDFs. This enables the simulation of custom physical phenomena that are not supported by the default FLUENT equations.2.4. Event-Based UDFsFLUENTUDF allows users to define UDFs that are triggered by specific events during the simulation. Examples of event-based UDFs include UDFs that modify boundary conditions based on certain conditions, UDFs that change solver parameters during the simulation, and UDFs that output data at specific time steps.3. Creating a UDF in FLUENTTo create a UDF in FLUENT, follow these steps:3.1. Set up the Development EnvironmentBefore creating a UDF, make sure that you have a properly set up development environment. This includes installing a C compiler, setting up the necessary compiler flags, and configuring the FLUENT build system to recognize the UDF files.3.2. Write the UDFOpen a text editor and write the necessary code for your UDF. FLUENT provides a set of API functions that you can use to interact with FLUENT data structures and solver routines. These functions include macros for accessing flow properties, boundary conditions, and mesh information.3.3. Compile the UDFCompile your UDF using the C compiler. Make sure to link against the FLUENT libraries and include the necessary header files. Check for any compilation errors and fix them if necessary.3.4. Load the UDF into FLUENTOnce the UDF is compiled successfully, load it into FLUENT using the。
第一章.介绍本章简要地介绍了用户自定义函数(UDF)及其在Fluent中的用法。
在1.1到1.6节中我们会介绍一下什么是UDF;如何使用UDF,以及为什么要使用UDF,在1.7中将一步步的演示一个UDF例子。
1.1 什么是UDF?1.2 为什么要使用UDF?1.3 UDF的局限1.4 Fluent5到Fluent6 UDF的变化1.5 UDF基础1.6 解释和编译UDF的比较1.7一个step-by-stepUDF例子1.1什么是UDF?用户自定义函数,或UDF,是用户自编的程序,它可以动态的连接到Fluent求解器上来提高求解器性能。
用户自定义函数用C语言编写。
使用DEFINE宏来定义。
UDF中可使用标准C语言的库函数,也可使用Fluent Inc.提供的预定义宏,通过这些预定义宏,可以获得Fluent求解器得到的数据。
UDF使用时可以被当作解释函数或编译函数。
解释函数在运行时读入并解释。
而编译UDF则在编译时被嵌入共享库中并与Fluent连接。
解释UDF用起来简单,但是有源代码和速度方面的限制不足。
编译UDF执行起来较快,也没有源代码限制,但设置和使用较为麻烦。
1.2为什么要使用UDF?一般说来,任何一种软件都不可能满足每一个人的要求,FLUENT也一样,其标准界面及功能并不能满足每个用户的需要。
UDF正是为解决这种问题而来,使用它我们可以编写FLUENT代码来满足不同用户的特殊需要。
当然,FLUENT的UDF并不是什么问题都可以解决的,在下面的章节中我们就会具体介绍一下FLUENT UDF的具体功能。
现在先简要介绍一下UDF的一些功能:z定制边界条件,定义材料属性,定义表面和体积反应率,定义FLUENT输运方程中的源项,用户自定义标量输运方程(UDS)中的源项扩散率函数等等。
z在每次迭代的基础上调节计算值z方案的初始化z(需要时)UDF的异步执行z后处理功能的改善z FLUENT模型的改进(例如离散项模型,多项混合物模型,离散发射辐射模型)由上可以看出FLUENT UDF并不涉及到各种算法的改善,这不能不说是一个遗憾。
Fluent-UDF_Coal-Combustion-Multiphase-Flow-Processes ---Codes for various kinds of heterogeneous reactions【第一部分-Part1】#include "udf.h"#include "stdio.h"#include "time.h"#define SMALL_S 1.e-29#define eps_g_small 1.#define eps_s_small 1.e-6#define spe_small 1.e-6#define spe_small_comb 1.e-6#define TMAX 3000.#define TMIN 280.#define Rgas 1.987 /* cal/mol.K */ /*UNIVERSAL_GAS_CONSTANT;*/#define PR_NUMBER(cp,mu,k) ((cp)*(mu)/(k))#define IP_HEAT_COEFF(vofP,vofS,k,nu,d) ((vofP)*(vofS)*6.*(k)*(Nu)/(d)/(d))#define Carbon_Init_MF 0.541#define Volatile_Init_MF 0.418#define Moisture_Init_MF 0.026#define Ash_Init_MF (1.-Carbon_Init_MF-Volatile_Init_MF-Moisture_Init_MF)#define rho_c (1000.)#define rho_ash (2931)#define rho_liq_water (998.2)#define rho_volatile (1000.)#define solid_rho (1./(Carbon_Init_MF/rho_c+Volatile_Init_MF/rho_volatile+Moisture_Init_MF/rho_liq_water+Ash _Init_MF/rho_ash))/* Functions Defination */void SolidFuel_Reactant(cell_t c, Thread *t, Hetero_Reaction *hr, double* y_carbon, double* mol_weight);void volatile_mass_fractions();void SetSpeciesIndex();void read_c3m_data();double satPressure(double T);double Get_Phase_Index(Hetero_Reaction *hr);double Turbulent_rr(cell_t c, Thread *t, Hetero_Reaction *r, real yi[MAX_PHASES][MAX_SPE_EQNS]);double Mass_Transfer_Coeff(cell_t c, Thread *tp, Thread *ts);double heat_gunn_udf(cell_t c, Thread *ti, Thread *tj);double rr_combustion(cell_t c, Thread *t, Thread *ts, Thread *tp, double yi_O2, double y_ash, double y_carbon);double rr_steam_gasif(cell_t c, Thread *t, Thread *ts, Thread *tp, double p_h2o, double p_co, double p_h2, double y_carbon, double mol_weight, double* direction);double rr_co2_gasif(cell_t c, Thread *t, Thread *ts, Thread *tp, double y_co, double y_co2, double y_carbon, double mol_weight, double* direction);double rr_h2_gasif(cell_t c, Thread *t, Thread *ts, Thread *tp, double y_h2, double y_ch4, double y_carbon, double mol_weight, double* direction);int IP_CH4 = 0, IS_CH4 = 0, IP_CO = 0, IS_CO = 0,IP_CO2 = 0, IS_CO2 = 0, IP_H2 = 0, IS_H2 = 0,IP_H2O = 0, IS_H2O = 0, IP_O2 = 0, IS_O2 = 0,IP_H2S = 0, IS_H2S = 0, IP_CL2 = 0, IS_CL2 = 0,IP_NH3 = 0, IS_NH3 = 0, IP_N2 = 0, IS_N2 = 0,IP_TAR = 0, IS_TAR = 0, IP_C = 0, IS_C = 0,IP_VOL = 0, IS_VOL = 0, IP_MOISTURE = 0, IS_MOISTURE = 0,IP_ASH = 0, IS_ASH = 0, IP_SOOT = 0, IS_SOOT = 0,IP_PAH = 0, IS_PAH = 0, IP_OIL = 0, IS_OIL = 0,IP_ASH_R = 0, IS_ASH_R = 0, IP_C_R = 0, IS_C_R = 0,IP_C2H2 = 0, IS_C2H2 = 0, IP_SLURRY = 0, IS_SLURRY = 0,IP_C2H4 = 0, IS_C2H4 = 0, IP_C2H6 = 0, IS_C2H6 = 0,IP_C3H6 = 0, IS_C3H6 = 0, IP_C3H8 = 0, IS_C3H8 = 0,IP_SLURRY_D = 0, IS_SLURRY_D = 0, IP_SAND = 0, IS_SAND = 0,IP_ASH_D = 0, IS_ASH_D = 0;int current_c3m_solid_phase = 0;cxboolean init_flag = TRUE;cxboolean PCCL_Devol = FALSE;cxboolean MGAS_Devol = FALSE;cxboolean CPD_Devol = FALSE;cxboolean FGDVC_Devol = FALSE;cxboolean HPTR_Devol = FALSE;cxboolean MGAS_Moisture = FALSE;cxboolean PCCL_Moisture = FALSE;cxboolean MGAS_TarCracking = FALSE;cxboolean PCCL_2nd_Pyro = FALSE;cxboolean MGAS_Gasif = FALSE;cxboolean PCCL_Gasif = FALSE;cxboolean PCCL_TarCracking = FALSE;cxboolean MGAS_WGS = FALSE;cxboolean PCCL_soot_gasif = FALSE;cxboolean MGAS_char_combustion = FALSE;cxboolean PCCL_char_combustion = FALSE;cxboolean PCCL_soot_oxidation = FALSE;cxboolean TAR_oxidation = FALSE;cxboolean MGAS_gas_phase_oxidation = FALSE;doubleavg_mf_h2o,avg_mf_co,avg_mf_h2,avg_mf_ch4,avg_mf_co2,avg_c,avg_volatile,avg_moisture,av g_ash;/* coal analysis variables */double fc_ar=0.,vm_ar=0.,ash_ar=0.,moist_ar=0.;double f_ep_a = 0.;double mw[MAX_PHASES][MAX_SPE_EQNS];double A1_devolatilization=0.0, E1_devolatilization=0.0; /* pan : Oct 2012 */double A2_devolatilization=0.0, E2_devolatilization=0.0; /* pan : Oct 2012 */double A_tar_cracking=0.0 , E_tar_cracking=0.0;double A_steam_gasification=0.0, E_steam_gasification=0.0;double K_steam_gasification=0.0, N_steam_gasification=0.0; /* pan : Oct 2012 */double Annealing_steam_gasification=1.0; /* pan : Oct 2012 */double A_co2_gasification=0.0, E_co2_gasification=0.0;double K_co2_gasification=0.0, N_co2_gasification=0.0; /* pan : Oct 2012 */double Annealing_co2_gasification=1.0; /* pan : Oct 2012 */double A_h2_gasification=0.0, E_h2_gasification=0.0;double N_h2_gasification=0.0; /* pan : Oct 2012 */double Annealing_h2_gasification=1.0; /* pan : Oct 2012 */double A_soot_steam_gasification=0.0, E_soot_steam_gasification=0.0; /* pan : oct 2012 */ double K_soot_steam_gasification=0.0, N_soot_steam_gasification=0.0; /* pan : Oct 2012 */ double Annealing_soot_steam_gasification=0.0; /* pan : Oct 2012 */double A_soot_co2_gasification=0.0, E_soot_co2_gasification=0.0; /* pan : Oct 2012 */ double K_soot_co2_gasification=0.0, N_soot_co2_gasification=0.0; /* pan : Oct 2012 */ double Annealing_soot_co2_gasification=0.0; /* pan : Oct 2012 */double A_soot_h2_gasification=0.0, E_soot_h2_gasification=0.0; /* pan : Oct 2012 */ double N_soot_h2_gasification=0.0; /* pan : Oct 2012 */double Annealing_soot_h2_gasification=0.0; /* pan : Oct 2012 */double A_Soot_Combustion = 0.0, E_Soot_Combustion = 0.0;double A_c_combustion = 8710. /* g/(atm.cm^2.s) */, E_c_combustion = 27000. /* cal/mole */; double Annealing_c_combustion=0.0 , N_c_combustion=0.0; /* pan : Oct 2012 */double A_moisture_release = 0.0, E_moisture_release = 0.0;double wg3 = 0.014;double Moisture_Flux;DEFINE_ADJUST(gasification,domain){if(init_flag){#if !RP_HOSTif(0) SetSpeciesIndex();#endif#if !RP_NODEvolatile_mass_fractions();#endifhost_to_node_real_5(fc_ar,vm_ar,ash_ar,moist_ar,f_ep_a);host_to_node_int_4(PCCL_Devol,MGAS_Devol,MGAS_Moisture,PCCL_2nd_Pyro);host_to_node_int_3(MGAS_Gasif,PCCL_Gasif,PCCL_Moisture);host_to_node_int_3(CPD_Devol,FGDVC_Devol,HPTR_Devol); /* pan : Oct 2012 */host_to_node_int_3(PCCL_TarCracking,MGAS_WGS,PCCL_soot_gasif); /* pan : Oct 2012 */host_to_node_int_1(PCCL_char_combustion); /* pan : Oct 2012 */host_to_node_int_3(MGAS_char_combustion,TAR_oxidation,MGAS_gas_phase_oxidation); /* pan : Oct 2012 */host_to_node_real_2(A_moisture_release, E_moisture_release);host_to_node_real_2(A1_devolatilization, E1_devolatilization); /* pan : Oct 2012 ... added the "1" */host_to_node_real_2(A2_devolatilization, E2_devolatilization); /* pan : Oct 2012 */host_to_node_real_2(A_tar_cracking, E_tar_cracking);host_to_node_real_2(A_steam_gasification, E_steam_gasification);host_to_node_real_2(K_steam_gasification, N_steam_gasification); /* pan : Oct 2012 */host_to_node_real_1(Annealing_steam_gasification);/* pan : Oct 2012 */host_to_node_real_2(A_co2_gasification, E_co2_gasification);host_to_node_real_2(K_co2_gasification, N_co2_gasification); /* pan : Oct 2012 */host_to_node_real_1(Annealing_co2_gasification);/* pan : Oct 2012 */host_to_node_real_2(A_h2_gasification, E_h2_gasification);host_to_node_real_2(Annealing_h2_gasification, N_h2_gasification); /* pan : Oct 2012 */host_to_node_real_2(A_soot_steam_gasification, E_soot_steam_gasification); /* pan : Oct 2012 */host_to_node_real_2(K_soot_steam_gasification, N_soot_steam_gasification); /* pan : Oct 2012 */host_to_node_real_1(Annealing_soot_steam_gasification);/* pan : Oct 2012 */host_to_node_real_2(A_soot_co2_gasification, E_soot_co2_gasification); /* pan : Oct 2012 */host_to_node_real_2(K_soot_co2_gasification, N_soot_co2_gasification); /* pan : Oct 2012 */host_to_node_real_1(Annealing_soot_co2_gasification);/* pan : Oct 2012 */host_to_node_real_2(A_soot_h2_gasification, E_soot_h2_gasification); /* pan : Oct 2012 */host_to_node_real_2(Annealing_soot_h2_gasification, N_soot_h2_gasification); /* pan : Oct 2012 */host_to_node_real_2(A_Soot_Combustion, E_Soot_Combustion);host_to_node_real_2(A_c_combustion, E_c_combustion); /* pan : Oct 2012 */host_to_node_real_2(N_c_combustion, Annealing_c_combustion); /* pan : Oct 2012 */host_to_node_real_2(wg3,Moisture_Flux);init_flag = FALSE;} /* end init_flag */}DEFINE_ON_DEMAND(Devol_and_Tar_Cracking){#if !RP_NODEvolatile_mass_fractions();#endif}void SetSpeciesIndex(){Domain *domain = Get_Domain(1);int n, ns, MAX_SPE_EQNS_PRIM = 0;Domain *subdomain;/*int n_phases = DOMAIN_N_DOMAINS(domain);*//* search all the species and saved the Molecular Weight */sub_domain_loop(subdomain, domain, n){Material *m_mat, *s_mat;if (DOMAIN_NSPE(subdomain) > 0){m_mat = Pick_Material(DOMAIN_MATERIAL_NAME(subdomain),NULL);mixture_species_loop(m_mat,s_mat,ns){if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"ch4")){IP_CH4 = n;IS_CH4 = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"co")){IP_CO = n;IS_CO = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"c2h2")){IP_C2H2 = n;IS_C2H2 = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"c2h4")){IP_C2H4 = n;IS_C2H4 = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"c2h6")){IP_C2H6 = n;IS_C2H6 = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"c3h6")){IP_C3H6 = n;IS_C3H6 = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"c3h8")){IP_C3H8 = n;IS_C3H8 = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"co2")){IP_CO2 = n;IS_CO2 = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"h2")){IP_H2 = n;IS_H2 = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"h2o")){IP_H2O = n;IS_H2O = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"o2")){IP_O2 = n;IS_O2 = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"h2s")){IP_H2S = n;IS_H2S = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"cl2")){IP_CL2 = n;IS_CL2 = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"nh3")){IP_NH3 = n;IS_NH3 = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"n2")){IP_N2 = n;IS_N2 = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"oil")){IP_OIL = n;IS_OIL = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"pah")){IP_PAH = n;IS_PAH = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"tar")){IP_TAR = n;IS_TAR = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"c")){IP_C = n;IS_C = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"c_recycle")){IP_C_R = n;IS_C_R = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"soot")){IP_SOOT = n;IS_SOOT = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"volatile")){IP_VOL = n;IS_VOL = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"h2o<l>")){IP_MOISTURE = n;IS_MOISTURE = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"h2o<l>-slurry")){IP_SLURRY = n;IS_SLURRY = ns;mw[n][ns] = MATERIAL_PROP(s_mat,PROP_mwi);}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"h2o<l>-dummy")){IP_SLURRY_D = n;IS_SLURRY_D = ns;mw[n][ns] = MATERIAL_PROP(s_mat,PROP_mwi);}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"ash-coal")){IP_ASH = n;IS_ASH = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"ash-dummy")){IP_ASH_D = n;IS_ASH_D = ns;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"ash-recycle")){IP_ASH_R = n;IS_ASH_R = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}else if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"si<s>")){IP_SAND = n;IS_SAND = ns;if(n == 0)MAX_SPE_EQNS_PRIM +=1;}mw[n][ns] = MATERIAL_PROP(s_mat,PROP_mwi);}}else{s_mat = Pick_Material(DOMAIN_MATERIAL_NAME(subdomain),NULL);mw[n][0] = MATERIAL_PROP(s_mat,PROP_mwi);}}}DEFINE_HET_RXN_RATE(moisture_release,c,t,hr,mw,yi,rr,rr_t){Thread **pt = THREAD_SUB_THREADS(t);int index_phase = Get_Phase_Index(hr);Thread *ts = pt[index_phase]; /* solid phase */double prod = 0.0, Ts = C_T(c,ts);double Pt = MAX(0.1,(op_pres+C_P(c,t)));double Tsat = 1./(0.0727/log(Pt/611.) - 0.0042) + 273.;*rr = 0;/* Set the phase and species indices. Ash species index is initialized to zero, with all other indices.Ash species index is used as a flag to execute SetSpeciesIndex only once. This is done by the firstreaction, defined in the heterogeneous reaction panel in FLUENT GUI.*/if(IS_ASH == 0)SetSpeciesIndex();if(C_VOF(c, ts) > 0.0 && Ts >= Tsat){if(MGAS_Moisture){prod = yi[IP_MOISTURE][IS_MOISTURE]*C_R(c,ts)/mw[IP_MOISTURE][IS_MOISTURE]; /* kg-mol/m^3*/ A_moisture_release = A1_devolatilization;E_moisture_release = E1_devolatilization;*rr = A_moisture_release*exp(-E_moisture_release/(Rgas*Ts)) * prod*C_VOF(c, ts); /* kmol/(m3.s) */}if(PCCL_Moisture){*rr = 6. * C_VOF(c, ts) / C_PHASE_DIAMETER(c,ts) * Moisture_Flux /mw[IP_MOISTURE][IS_MOISTURE] ; /* kmol/(m3.s) */}}}DEFINE_HET_RXN_RATE(devolatilization,c,t,hr,mw,yi,rr,rr_t){Thread **pt = THREAD_SUB_THREADS(t);int index_phase = Get_Phase_Index(hr);Thread *ts = pt[index_phase]; /* solid phase */double x0_star = 0., x_star =0.;double Ts = C_T(c,ts);*rr = 0.0;/* Set the phase and species indices. Ash species index is initialized to zero, with all other indices.Ash species index is used as a flag to execute SetSpeciesIndex only once. This is done by the firstreaction, defined in the heterogeneous reaction panel in FLUENT GUI.*/if(IS_ASH == 0)SetSpeciesIndex();/*Volatile Matter --> c1 Tar + c2 CO + c3 CO2 + c4 CH4 + c5 H2 + c6 H2O + c7 H2S + c8 NH3*/if(C_YI(c,ts,IS_MOISTURE) < spe_small){if(MGAS_Devol){if(Ts<1223)x0_star = pow((867.2/MAX((Ts-273.),1.)),3.914) / 100.;x_star = solid_rho * (fc_ar/100. + vm_ar/100.)/C_R(c,ts) * x0_star;A2_devolatilization = 0.0;E2_devolatilization = 0.0;}if((PCCL_Devol || CPD_Devol || FGDVC_Devol || HPTR_Devol) && yi[IP_VOL][IS_VOL] > x_star){*rr = (A1_devolatilization *exp(-E1_devolatilization/(1.987*Ts)) + A2_devolatilization *exp(-E2_devolatilization/(1.987*Ts)))*(yi[IP_VOL][IS_VOL]-x_star)*C_VOF(c,ts)*C_R(c,ts)/mw[IP_VOL][IS_VOL];}}}DEFINE_HET_RXN_RATE(tar_comb,c,t,r,mw,yi,rr,rr_t){Thread **pt = THREAD_SUB_THREADS(t);Thread *tp = pt[0]; /* gas phase */double T_g = MAX(TMIN, C_T(c,tp));double rho_g = C_R(c,tp)*1.e-3; /* g/cm^3 */double rr_turb = 1e+20;*rr = 0.0;/* Set the phase and species indices. Ash species index is initialized to zero, with all other indices.Ash species index is used as a flag to execute SetSpeciesIndex only once. This is done by the firstreaction, defined in the heterogeneous reaction panel in FLUENT GUI.*/if(IS_ASH == 0)SetSpeciesIndex();if (rp_ke)rr_turb = Turbulent_rr(c, t, r, yi);if(yi[IP_O2][IS_O2] > spe_small_comb){double tmp_exp, tmp_o2, tmp_tar;T_g = MIN(T_g, TMAX);tmp_exp = 3.8e11 * exp(-30000./(Rgas*T_g)); /* 30000 ---> 60000*/tmp_o2 = pow(rho_g*yi[IP_O2][IS_O2]/mw[IP_O2][IS_O2],1.5);tmp_tar = pow(rho_g*yi[IP_TAR][IS_TAR]/mw[IP_TAR][IS_TAR],0.25);*rr = tmp_exp * tmp_o2 * tmp_tar * C_VOF(c,tp); /* mol/cm^3.s */*rr *= 1000.; /* kmol/(m^3 .s) */*rr = MIN(*rr, rr_turb);}}DEFINE_HET_RXN_RATE(tar_cracking,c,t,r,mw,yi,rr,rr_t){Thread **pt = THREAD_SUB_THREADS(t);Thread *tp = pt[0]; /* gas phase */double prod = 0.0;double T_g = MAX(TMIN, C_T(c,tp));double rr_turb = 1e+20;*rr = 0.0;/* Set the phase and species indices. Ash species index is initialized to zero, with all other indices.Ash species index is used as a flag to execute SetSpeciesIndex only once. This is done by the firstreaction, defined in the heterogeneous reaction panel in FLUENT GUI.*/if(IS_ASH == 0)SetSpeciesIndex();if (rp_ke)rr_turb = Turbulent_rr(c, t, r, yi);if(yi[IP_TAR][IS_TAR] > spe_small){prod = yi[IP_TAR][IS_TAR]*C_R(c,tp)*C_VOF(c,tp)/mw[IP_TAR][IS_TAR];*rr = A_tar_cracking*exp(-E_tar_cracking/(1.987*T_g))* prod*C_VOF(c, tp); /* kmol/(m3.s) */}}DEFINE_HET_RXN_RATE(co_comb,c,t,r,mw,yi,rr,rr_t){Thread **pt = THREAD_SUB_THREADS(t);Thread *tp = pt[0]; /* gas phase */double T_g = MAX(TMIN, C_T(c,tp));double rho_g = C_R(c,tp)*1.e-3; /* g/cm^3 */double rr_turb = 1e+20;*rr = 0;/* Set the phase and species indices. Ash species index is initialized to zero, with all other indices.Ash species index is used as a flag to execute SetSpeciesIndex only once. This is done by the firstreaction, defined in the heterogeneous reaction panel in FLUENT GUI.*/if(IS_ASH == 0)SetSpeciesIndex();if(yi[IP_O2][IS_O2] > spe_small_comb){double tmp_exp, p_o2, p_co, p_h2o;if (rp_ke)rr_turb = Turbulent_rr(c, t, r, yi);T_g = MIN(T_g, TMAX);tmp_exp = 3.98e+14 * exp(-40000./(Rgas*T_g)); /*40000 ---> 80000 */p_o2 = pow(rho_g*yi[IP_O2][IS_O2]/mw[IP_O2][IS_O2],0.25);p_co = rho_g*yi[IP_CO][IS_CO]/mw[IP_CO][IS_CO];p_h2o = pow(rho_g*yi[IP_H2O][IS_H2O]/mw[IP_H2O][IS_H2O], 0.5);*rr = tmp_exp * p_o2 * p_co * p_h2o * C_VOF(c,tp); /* mol/cm^3.s */*rr *= 1000.; /* kmol/(m^3 .s) */*rr = MIN(*rr, rr_turb);}}DEFINE_HET_RXN_RATE(ch4_comb,c,t,r,mw,yi,rr,rr_t){Thread **pt = THREAD_SUB_THREADS(t);Thread *tp = pt[0]; /* gas phase */double T_g = MAX(TMIN, C_T(c,tp));double rho_g = C_R(c,tp)*1.e-3; /* g/cm^3 */double rr_turb = 1e+20;*rr = 0;/* Set the phase and species indices. Ash species index is initialized to zero, with all other indices.Ash species index is used as a flag to execute SetSpeciesIndex only once. This is done by the firstreaction, defined in the heterogeneous reaction panel in FLUENT GUI.*/if(IS_ASH == 0)SetSpeciesIndex();if(yi[IP_O2][IS_O2] > spe_small_comb){double p_o2, p_ch4;if (rp_ke)rr_turb = Turbulent_rr(c, t, r, yi);T_g = MIN(T_g, TMAX);p_o2 = pow(rho_g*yi[IP_O2][IS_O2]/mw[IP_O2][IS_O2],1.3);p_ch4 = pow(rho_g*yi[IP_CH4][IS_CH4]/mw[IP_CH4][IS_CH4],0.2);*rr = 6.7e12 * exp(-48400./(Rgas*T_g)) * p_o2 * p_ch4 * C_VOF(c,tp); /* mol/cm^3.s */*rr *= 1000.; /* kmol/(m^3 .s) */*rr = MIN(*rr, rr_turb);}}DEFINE_HET_RXN_RATE(h2_comb,c,t,r,mw,yi,rr,rr_t){Thread **pt = THREAD_SUB_THREADS(t);Thread *tp = pt[0]; /* gas phase */double T_g = MAX(TMIN, C_T(c,tp));double rho_g = C_R(c,tp)*1.e-3; /* g/cm^3 */double rr_turb = 1e+20;*rr = 0;/* Set the phase and species indices. Ash species index is initialized to zero, with all other indices.Ash species index is used as a flag to execute SetSpeciesIndex only once. This is done by the firstreaction, defined in the heterogeneous reaction panel in FLUENT GUI.*/if(IS_ASH == 0)SetSpeciesIndex();if(yi[IP_O2][IS_O2] > spe_small_comb){double tmp_exp, tmp_o2, tmp_h2;if (rp_ke)rr_turb = Turbulent_rr(c, t, r, yi);T_g = MIN(T_g, TMAX);tmp_exp = 1.08e16 * exp(-30000./(Rgas*T_g)); /* 30000 ----> 60000 cal/mole */ /* cm3/gmole-s */tmp_o2 = rho_g*yi[IP_O2][IS_O2]/mw[IP_O2][IS_O2]; /* gmole/cm3 */tmp_h2 = rho_g*yi[IP_H2][IS_H2]/mw[IP_H2][IS_H2]; /* gmole/cm3 */*rr = tmp_exp * tmp_o2 * tmp_h2 * C_VOF(c,tp); /* mol/cm^3.s */*rr *= 1000.; /* kmol/(m^3 .s) */*rr = MIN(*rr, rr_turb);}}DEFINE_HET_RXN_RATE(WGS_char,c,t,hr,mw,yi,rr,rr_t){Domain *domain = Get_Domain(1);Domain *subdomain;Thread **pt = THREAD_SUB_THREADS(t);Thread *tp = pt[0]; /* gas phase */double T_g = C_T(c,tp), f3 = 0., k3=1.;double Pt = MAX(0.1,(op_pres+C_P(c,t))/101325);double p_co = 0., p_h2o = 0., p_co2 = 0., p_h2=0., sum = 0.0;int phase_domain_index, ns;double rr_turb = 1e+20;*rr = 0;/* Set the phase and species indices. Ash species index is initialized to zero, with all other indices.Ash species index is used as a flag to execute SetSpeciesIndex only once. This is done by the firstreaction, defined in the heterogeneous reaction panel in FLUENT GUI.*/if(IS_ASH == 0)SetSpeciesIndex();sub_domain_loop(subdomain, domain, phase_domain_index){if(phase_domain_index > 0){Thread *ts = pt[phase_domain_index]; /* solid phase */Material *m_mat, *s_mat;if (DOMAIN_NSPE(subdomain) > 0){m_mat = Pick_Material(DOMAIN_MATERIAL_NAME(subdomain),NULL);mixture_species_loop(m_mat,s_mat,ns){if (0 == strcmp(MIXTURE_SPECIE_NAME(m_mat,ns),"ash-coal")){sum +=C_VOF(c,ts)*C_YI(c,ts,IS_ASH)*C_R(c,ts)*1.e-3;}}}}}if (rp_ke)rr_turb = Turbulent_rr(c, t, hr, yi);if(C_VOF(c, tp) < 1.0){T_g = MIN(T_g, TMAX);f3 = sum *exp(-8.91+5553/T_g);k3 = exp( -3.63061 + 3955.71/T_g );p_co = C_R(c,tp) * UNIVERSAL_GAS_CONSTANT * C_T(c,tp)* yi[IP_CO][IS_CO]/mw[IP_CO][IS_CO] / 101325.;p_co2 = C_R(c,tp) * UNIVERSAL_GAS_CONSTANT * C_T(c,tp)* yi[IP_CO2][IS_CO2]/mw[IP_CO2][IS_CO2] / 101325.;p_h2o = C_R(c,tp) * UNIVERSAL_GAS_CONSTANT * C_T(c,tp)* yi[IP_H2O][IS_H2O]/mw[IP_H2O][IS_H2O] / 101325.;p_h2 = C_R(c,tp) * UNIVERSAL_GAS_CONSTANT * C_T(c,tp)* yi[IP_H2][IS_H2]/mw[IP_H2][IS_H2] / 101325.;*rr = 2.877e+5 * wg3 * f3 * pow (Pt, 0.5-Pt/250.) * exp(-27760/Rgas/T_g)*(p_co * p_h2o /Pt/Pt - p_co2 * p_h2 /Pt/Pt / k3) * C_VOF(c,tp); /* mol/cm^3.s */*rr *= 1000.; /* kmol/(m^3 .s) */*rr = MIN(*rr, rr_turb);}}DEFINE_HET_RXN_RATE(soot_comb,c,t,r,mw,yi,rr,rr_t){Thread **pt = THREAD_SUB_THREADS(t);Thread *tp = pt[0]; /* gas phase */double T_g = MIN(TMAX, MAX(TMIN, C_T(c,tp)));double rr_turb = 1e+20;double soot_dia = 8.e-6;*rr = 0;/* Set the phase and species indices. Ash species index is initialized to zero, with all other indices.Ash species index is used as a flag to execute SetSpeciesIndex only once. This is done by the firstreaction, defined in the heterogeneous reaction panel in FLUENT GUI.*/if(IS_ASH == 0)SetSpeciesIndex();double y_o2 = yi[IP_O2][IS_O2];if(y_o2 > spe_small_comb){double tmp1_exp, tmp2_exp;if (rp_ke)rr_turb = Turbulent_rr(c, t, r, yi);double P_o2 = C_R(c,tp) * UNIVERSAL_GAS_CONSTANT * T_g*y_o2/mw[IP_O2][IS_O2]/ 101325.;tmp1_exp = 240.*exp(-15100./T_g)*P_o2/(1.+21.3*exp(2060./T_g));tmp2_exp = 5.35e-2*exp(-7640./T_g)*P_o2;double tmp3_exp = 1.51e5*exp(-48800./T_g);double tmp4_exp = 4.46e-3*exp(-7640./T_g)*P_o2;double chi = tmp4_exp/(tmp3_exp+tmp4_exp);double prod = tmp1_exp*chi+tmp2_exp*(1.-chi); /* g/cm2-s */prod *= 10.; /* kg/m2-s */*rr = (6.*C_VOF(c, tp)/soot_dia)*prod/mw[IP_SOOT][IS_SOOT]; /* kmol/m^3.s */*rr = MIN(*rr, rr_turb);}}DEFINE_HET_RXN_RATE(SteamGasif,c,t,hr,mw,yi,rr,rr_t){Thread **pt = THREAD_SUB_THREADS(t);Thread *tp = pt[0]; /* gas phase */int index_phase = Get_Phase_Index(hr);Thread *ts = pt[index_phase]; /* solid phase */*rr = 0;double direction = 0.0, mol_weight, y_carbon;/*C(s) + H2O ---> CO + H2Set the phase and species indices. Ash species index is initialized to zero, with all other indices.Ash species index is used as a flag to execute SetSpeciesIndex only once. This is done bythe firstreaction, defined in the heterogeneous reaction panel in FLUENT GUI.*/if(IS_ASH == 0)SetSpeciesIndex();double RoRT = C_R(c,tp) * UNIVERSAL_GAS_CONSTANT * C_T(c,tp);double p_h2o = RoRT * yi[IP_H2O][IS_H2O]/mw[IP_H2O][IS_H2O]/ 101325.;double p_co = RoRT * yi[IP_CO][IS_CO]/mw[IP_CO][IS_CO] / 101325.;double p_h2 = RoRT * yi[IP_H2][IS_H2]/mw[IP_H2][IS_H2] / 101325.;SolidFuel_Reactant(c, t, hr, &y_carbon, &mol_weight);if(C_VOF(c, ts) >= eps_s_small){*rr = rr_steam_gasif(c, t, ts, tp, p_h2o, p_co, p_h2, y_carbon, mol_weight, &direction); /* mol/(cm^3 .s) */if( direction < 0.0) /* negative value implies reverse steam gasification */*rr = 0.0;}}DEFINE_HET_RXN_RATE(Soot_H2O_Gasif,c,t,r,mw,yi,rr,rr_t){Thread **pt = THREAD_SUB_THREADS(t);Thread *tp = pt[0]; /* gas phase */*rr = 0;double rr_turb = 1e+20;double T_g = MIN((MAX(TMIN,C_T(c,tp))),TMAX);/*1/25 Soot + H2O ---> CO + H2Set the phase and species indices. Ash species index is initialized to zero, with all other indices.Ash species index is used as a flag to execute SetSpeciesIndex only once. This is done by the firstreaction, defined in the heterogeneous reaction panel in FLUENT GUI.*/if(IS_ASH == 0)SetSpeciesIndex();double RoRT = C_R(c,tp) * UNIVERSAL_GAS_CONSTANT * C_T(c,tp);double p_h2o = RoRT * yi[IP_H2O][IS_H2O]/mw[IP_H2O][IS_H2O]/ 101325.;double p_h2 = RoRT * yi[IP_H2][IS_H2]/mw[IP_H2][IS_H2] / 101325.;if (rp_ke)rr_turb = Turbulent_rr(c, t, r, yi);double prod = yi[IP_SOOT][IS_SOOT]*(C_R(c,tp)*1e-03)/mw[IP_SOOT][IS_SOOT]*C_VOF(c,tp); /*1e-3 is to convert density from kg/m^3 to g/cm^3 */*rr = A_soot_steam_gasification*exp(-E_soot_steam_gasification/Rgas/T_g)* Annealing_soot_steam_gasification * prod *pow(p_h2o, N_soot_steam_gasification)/(1.+K_soot_steam_gasification*p_h2); /* mol/cm^3.s */*rr *= 1000.; /* kmol/(m^3 .s) */*rr = MIN(*rr, rr_turb);}。
第四章DEFINE宏本章介绍了Fluent公司所提供的预定义宏,我们需要用这些预定义宏来定义UDF。
在本章中这些宏就是指DEFINE宏。
本章由如下几节组成:∙ 4.1 概述∙ 4.2 通用解算器DEFINE宏∙ 4.3 模型指定DEFINE宏∙ 4.4 多相DEFINE宏∙ 4.5 离散相模型DEFINE宏4.1 概述DEFINE宏一般分为如下四类:∙通用解算器∙模型指定∙多相∙离散相模型(DPM)对于本章所列出的每一个DEFINE宏,本章都提供了使用该宏的源代码的例子。
很多例子广泛的使用了其它章节讨论的宏,如解算器读取(第五章)和utilities (Chapter 6)。
需要注意的是,并不是本章所有的例子都是可以在FLUENT中执行的完整的函数。
这些例子只是演示一下如何使用宏。
除了离散相模型DEFINE宏之外的所有宏的定义都包含在udf.h文件中。
离散相模型DEFINE宏的定义包含在dpm.h文件中。
为了方便大家,所有的定义都列于附录A中。
其实udf.h头文件已经包含了dpm.h文件,所以在你的UDF源代码中就不必包含dpm.h文件了。
注意:在你的源代码中,DEFINE宏的所有参变量必须在同一行,如果将DEFINE声明分为几行就会导致编译错误。
4.2 通用解算器DEFINE宏本节所介绍的DEFINE宏执行了FLUENT中模型相关的通用解算器函数。
表4.2.1提供了FLUENT中DEFINE宏,以及这些宏定义的功能和激活这些宏的面板的快速参考向导。
每一个DEFINE宏的定义都在udf.h头文件中,具体可以参考附录A。
∙DEFINE_ADJUST (4.2.1节)∙DEFINE_INIT (4.2.2节)∙DEFINE_ON_DEMAND (4.2.3节)∙DEFINE_RW_FILE (4.2.4节)∙ 4.2.1 DEFINE_ADJUST∙ 4.2.2 DEFINE_INIT∙ 4.2.3 DEFINE_ON_DEMAND∙ 4.2.4 DEFINE_RW_FILE4.2.1 DEFINE_ADJUST功能和使用方法的介绍DEFINE_ADJUST是一个用于调节和修改FLUENT变量的通用宏。
例如,你可以用DEFINE_ADJUST来修改流动变量(如:速度,压力)并计算积分。
你可以用它来对某一标量在整个流场上积分,然后在该结果的基础上调节边界条件。
在每一步迭代中都可以执行用DEFINE_ADJUST定义的宏,并在解输运方程之前的每一步迭代中调用它。
参考图3.3.1 和3.3.2 for可以大致了解一下当DEFINE_ADJUST被调用时FLUENT解的过程DEFINE_ADJUST有两个参变量:name和d。
name是你所指定的UDF的名字。
当你的UDF编译并连接时,你的FLUENT图形用户界面就会显示这个名字,此时你就可以选择它了。
d是FLUENT解算器传给你的UDF的变量。
D是一个指向区域的指针,调节函数被应用于这个区域上。
区域变量提供了存取网格中所有单元和表面的线程。
对于多相流,由解算器传给函数的区域指针是混合层区域指针。
DEFINE_ADJUST函数不返回任何值给解算器。
例子1下面的UDF名字是adjust,它使用DEFINE_ADJUST对湍流耗散在整个区域上积分。
然后这个值会打印在控制台窗口中。
每一步迭代都会调用这个UDF。
它可以作为解释程序或者编译后的UDF在FLUENT中执行。
/*******************************************************************/ /* 积分湍流耗散并将其打印到控制台窗口的UDF */ /********************************************************************/ #include "udf.h"DEFINE_ADJUST(my_adjust, d){Thread *t;/* Integrate dissipation. */real sum_diss=0.;cell_t c;thread_loop_c (t,d){begin_c_loop (c,t)sum_diss += C_D(c,t)*C_VOLUME(c,t);end_c_loop (c,t)}printf("Volume integral of turbulent dissipation: %g\n", sum_diss);}例子:2下面UDF的名字是adjust_fcn,它用DEFINE_ADJUST指定了某一自定义标量是另一自定义标量的梯度的函数。
该函数在每一次迭代中都会被调用。
它可以作为编译后的UDF在FLUENT中执行。
/********************************************************************/ /* UDF for defining user-defined scalars and their gradients *//********************************************************************/#include "udf.h"DEFINE_ADJUST(adjust_fcn, d){Thread *t;cell_t c;real K_EL = 1.0;/* Do nothing if gradient isn't allocated yet. */if (! Data_Valid_P())return;thread_loop_c (t, d){if (FLUID_THREAD_P(t)){begin_c_loop_all (c,t){C_UDSI(c,t,1) += K_EL*NV_MAG2(C_UDSI_G(c,t,0))*C_VOLUME(c,t);}end_c_loop_all (c, t)}}}Activating an Adjust UDF in FLUENT在为adjust UDF的源代码进行编译和连接之后,你可以在FLUENT中的User-Defined Function Hooks面板激活这个函数。
更详细的内容请参阅8.1.1节。
4.2.2 DEFINE_INIT功能和使用方法的介绍你可以用DEFINE_INIT宏来定义一组解的初始值。
DEFINE_INIT 完成和修补一样的功能,只是它以另一种方式——UDF来完成。
每一次初始化时DEFINE_INIT函数都会被执行一次,并在解算器完成默认的初始化之后立即被调用。
因为它是在流场初始化之后被调用的,所以它最常用于设定流动变量的初值。
参考图3.3.1和3.3.2关于FLUENT解过程的介绍可以看出什么时候调用DEFINE_INIT函数。
DEFINE_INIT有两个参变量:name和d。
name是你所指定的UDF的名字。
当你的UDF编译并连接时,你的FLUENT图形用户界面就会显示这个名字,此时你就可以选择它了。
d是FLUENT解算器传给你的UDF的变量。
d is a pointer to the domain over which the initialization function is to be applied. The domain argument provides access to all cell and face threads in the mesh. For multiphase flows, the domain pointer that is passed to the function by the solver is the mixture-level domain pointer. A DEFINE_INIT function does not return a value to the solver.例子下面的UDF名字是my_init_func,它在某一个解中初始化了流动变量。
在解过程开始时它被执行了一次。
它可以作为解释程序或者编译后的UDF在FLUENT中执行。
/*******************************************************************/ /* UDF for initializing flow field variables *//******************************************************************** ***/#include "udf.h"DEFINE_INIT(my_init_function, domain){cell_t c;Thread *t;real xc[ND_ND];/* loop over all cell 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(xc[0] - 0.5,2.),pow(xc[1] - 0.5,2.),pow(xc[2] - 0.5,2.))) < 0.25)C_T(c,t) = 400.;elseC_T(c,t) = 300.;}end_c_loop_all (c,t)}}The macro ND_SUM(a, b, c) that is used in the UDF computes the sum of the first two arguments (2D) or all three arguments (3D). It is useful for writing functions involving vector operations so that the same function can be used for 2D and 3D. For a 2D case, the third argument is ignored. See Chapter 5 for a description of predefined solver access macros (e.g., C_CENTROID) and Chapter 6 for utility macros (e.g., ND_SUM).Activating an Initialization UDF in FLUENT编译并连接UDF源代码之后。