UDF第3章写UDF详解 联系客服

发布时间 : 星期四 文章UDF第3章写UDF详解更新完毕开始阅读

inlet_x_velocity使用DEFINE_PROFLIE宏来定义(在Section 4.3.5中描述)。它的自变量是thread和index。Thread是一个指向面线索的指针,而index是一个每个循环内为变量设置数值标签的整数。DEFINE_PROPERTY在udf.h文件中一个返回void的数据类型。

函数由声明变量f作为face_t数据类型开始。一维数组x和变量y是real 数据类型。循环宏用来在区域中每个面上循环以创建型线或数据数组。在每个循环内,F_CENTROID为含有index f的面输出面质心的值(数组 x),index f在由thread指向的线索上。存储在x[1]中的y坐标分配给变量y,它用于计算x速度。然后这个值分配给F_PROFILE, 它使用整数index(由求解器传递个它)来设置内存中面上的x速度值。

3.10.5写入Case或Data文件或从中读取的函数(Functions that Write to or Read from a Case or Data File)

下面的C源代码包含了写信息到data文件和读回它的函数例子。这是一个包含多个连接在一起的UDF的单个C文件例子。

/******************************************************************/ /* UDF that increment a variable, write it to a data file */ /* and read it back in */ /******************************************************************/

#include \

int kount = 0; /* define global variable kount */

DEFINE_ADJUST(demo_calc, domain) {

kount++;

printf(\}

DEFINE_RW_FILE(writer, fp) {

printf(\

fprintf(fp, \}

DEFINE_RW_FILE(reader, fp) {

printf(\ fscanf(fp, \}

在顶部的列表中,整数kount被定义为全局的(由于它被源代码文件中的所有三个函数使用)并初始化为0。名字为demo_calc的第一个函数,使用DEFINE_SDJUST 宏来定义。(关于DEFINE_ADJUST的详细信息见Section 4.2.1)。在demo_calc中,kount的值每次迭代后增加因为每次迭代调用DEFINE_ADJUST一次。名字为writer的第二个函数,使用DEFINE_RW_FILE宏来定义。(关于DEFINE_RW_FILE的详细信息见Section 4.2.4)。当保存数据文件时,它指示FLUENT写当前kount值到数据文件。名字为reader的第三个函数,当读取数据文件时,它指示FLUENT从这个数据文件中读取kount的值。

这三个函数一起工作如下。如果你运行10次迭代计算(kount将增加到值为10)并保存这个数据文件,当前kount(10)的值被写入你的数据文件。如果你读这个数据返回到FLUENT并继续计算,kount将以值10开始随着每次迭代继续增加。注意,你可尽你所想的保存静态变量,但是必须保证以与它们被写的相同顺序来读取它们。

3.11为多相流应用写UDF(Writing UDF for Mulutiphase Applications)

当一个多相流模型在FLUENT中被激活时,属性和变量的存储和对单相一样应当为所有相的混合设置它们。这可以通过使用附加线索(thread)和区域数据结构在代码中得以表明。

3.11.1多相应用的数据结构(Data Structure for Multiphase Applications) 区域和线程(Domains and Threads)

在多相流应用中,最高级别的区域被用作超级区域。每相占据的区域用作子区域第三种

类型区域是相互作用区,为了定义相间的相互作用才引入它的。当混合属性和变量必要时(所有相的和),超级区域用于这些数量而子区域携带了单相的信息。在单一相中混合的概念用于描述所有种类(成分)的和而在多相中它描述了所有相的总和。这个区别是非常重要的因为以后代码将延伸到多相多组分(例如,这里相是种类的混合)。

由于求解器的数据存储在线程(thread)数据结构中,线程必须既和超级区域相联系又和每个子区域相联系。就是说,对定义在超级区域上的每个单元或面线程,有相应的单元或面线程定义在每个子区域上。定义在超级区域每个线程上的某些信息与子区域每个相应线程上的共享。与超级区域相关的线程被用作超级线程,而与子区域相关的线程被用作相级别线程或子线程。区域和线程的层次总结在Figure 3.11.1中。

Figure 3.11.1: Domain and Thread Structure Hierarchy

Figure 3.11.1也引入了domain_id和phase_domain_indexed的概念。domain_id在UDF中用于辨别超级区域从主要和次要的相级别区域中。超级区域的domain_id值总是被指定为1。相互作用区域也有相同的domain_id。domain_ids不必要如Figure3.11.1显示的顺序排列。dhase_domain_index在UDF中用于从次要相级别线程中辨别主要相级别线程。对主要相级别线程,phase_domain_index总是分配值为0。 访问数据(Accessing Data)

当你写UDF或为多相应用使用宏时,参考与尝试访问其属性的相(subdomain)或混合(super domain)相关的数据结构(thread or domain)是很重要的。作为例子,宏C_R(c,t)将返回线程t的单元c上的密度。如果t是指向超级线程的指针,那么返回的是混合密度。如果t是指向子线程的指针,那么返回的是相密度。

当传递到你的UDF的线程或区域指针不被你的函数需要时,也有一些例子。这取决于你使用的多相模型,你尝试修改的属性或项(例如,你使用的那个DEFINE宏),还有受到影响的相或混合。为了更好地理解这点,回想一个混合模型和欧拉多相模型之间区别的例子。在混合模型中,为混合相求解单一的动量方程,混合相的属性由它的相的总和来决定。在欧拉模型中,动量方程为每一相求解。当使用混合模型时,FLUENT允许你直接为混合相指定动量源项(使用DEFINE_SOURCE),但是不能为欧拉模型。对后者,你可以为单个相指定动量源项。因此,多相模型及被UDF修改的项,决定了那哪个区域或线程是需要的。 从求解器传递到你的UDF的特定的区域或线程的结构取决于你使用的DEFINE宏。例如,DEFINE_INIT和DEFINE_ADJUST函数总是传递与超级区域相关的区域结构。DEFINE_ON_DEMAND函数不能传递任何区域结构。如果你的UDF不能明确地传递指针到你的函数定义要求的线程或区域,那么你可以使用multiphase-specific utility macro找会它(见第6章)。为了你方便使用,表3.11.1-3.11.6总结了每个多相模型和相,在该相上为每个给定变量指定了UDF。从这些信息,你可推断出那些区域结构是从求解器传递到UDF的。 单相和多相模型应用UDF之间的区别(Differences Between UDF for Single-Phase and Multiphase Applications)

注:在许多例子中,为单相流动写的UDF源代码和为多相流动写的是相同的。例如,假设函数只从它被连接(hooked)到的相级别区域访问数据,为单相边界型线(使用DEFINE_PROFIEL定义的)写的C代码为多相边界型线写的代码之间是没有区别的。然而,如果那些函数从除混合级别区域之外的任何区域访问数据,调整和初始化UDF的代码对单相和多相流动是不同的。

3.11.2 对多相模型使用UDF(Using UDF for Multiphase Models)

在多相模型中,从求解器传递到你的UDF的数据结构(例如区域和线程指针)取决于你使用的DEFINE宏。传递哪一个特定的区域或线程取决于函数连接到求解器的什么地方。例如,被连接到混合模型的函数传递超级区域结构,而连接到特定相的函数传递子区域结构。表3.11.1-3.11.6列举了DEFINE和对每个多相模型UDF被连接到的相。从这些信息你可推断出那些数据结构被传递。回想DEFINE_ADJUST和DEFINE_INIT UDF are hardwired to the mixture-level domain,而DEFINE_ON_DEMAND函数不能连接到任何区域。 Table 3.11.1: DEFINE Macro Usage for the VOF Model