乐于分享
好东西不私藏

Ansys Fluent文档-UDF篇:通用DEFINE宏(一)

Ansys Fluent文档-UDF篇:通用DEFINE宏(一)

2.1 引言

①在源代码中,必须将DEFINE宏的所有参数放在同一行。将DEFINE语句拆分成多行会导致编译错误。

②确保宏(如DEFINE_PROFILE)与参数的第一个括号之间没有空格,否则在Windows中会导致错误。

不要在源代码的注释中包含DEFINE宏语句(例如DEFINE_PROFILE)。这会导致编译错误。

2.2 通用DEFINE

1DEFINE_ADJUST

①描述

DEFINE_ADJUST是一种通用宏,可用于调整或修改未作为参数传递的Fluent变量。例如,可以使用DEFINE_ADJUST来修改流动变量(如速度、压力)并计算积分。还可以用它来对域内的标量进行积分,并根据结果调整边界条件。使用DEFINE_ADJUST定义的函数会在每次迭代时执行,并在求解输运方程之前的每次迭代开始时被调用。

②用法

DEFINE_ADJUST (name, d)

nameUDF名称;

Domain *d:指向调整函数所要应用的域。域参数提供了对网格中所有单元和面线程的访问。对于多相流,求解器传递给函数的指针是混合物级别的域。

DEFINE_ADJUST有两个参数:named。需要提供UDF的名称name,而d则由Fluent求解器传递给的UDF

③示例1

以下名为my_adjustUDF通过DEFINE_ADJUST在整个域上积分湍流耗散值,随后在控制台中显示该值。此UDF在每次迭代时被调用一次,可在Fluent中作为解释型或编译型UDF执行。

 #include"udf.h" DEFINE_ADJUST(my_adjust,d) {    Thread *t;      // 声明线程指针,用于遍历不同的网格区域(边界、内部区域等)    /* Integrate dissipation. */    real sum_diss=0.     // 声明并初始化实型变量sum_diss为0,用于累加湍流耗散率的体积积分值    cell_t c;      // 声明单元索引,用于遍历网格中的每个单元    thread_loop_c(t,d)      // 循环遍历计算域中的所有单元线程(包括不同区域和边界)    {     begin_c_loop(c,t)       // 开始在当前线程t中循环遍历所有单元      sum_diss += C_D(c,t)* C_VOLUME(c,t);        //累加:当前单元的湍流耗散率 × 单元体积;C_D(c,t): 获取单元(c,t)的湍流耗散率值;C_VOLUME(c,t): 获取单元(c,t)的体积     end_c_loop(c,t)        // 结束当前线程的单元循环    }    printf("Volume integral of turbulent dissipation: %g\n", sum_diss);      //输出体积积分结果到控制台,%g: 自动选择浮点数格式输出 } 

④示例2

以下名为adjust_fcnUDF使用DEFINE_ADJUST宏,将用户自定义标量定义为另一个用户自定义标量梯度的函数。该函数在每次迭代中调用一次,并在Fluent中以编译型UDF的形式执行。

include"udf.h"DEFINE_ADJUST(adjust_fcn,d){    Thread *t;      // 声明线程指针,用于遍历不同的网格区域    cell_t c;       // 声明单元索引,用于遍历网格单元    real K_EL = 1.0;      // 声明并初始化常数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而不是begin_c_loop,表示包含所有单元(包括挂起的单元)            begin_c_loop_all(c,t)            {                // 更新用户自定义标量(UDS)索引1的值:                // C_UDSI_G(c,t,0): 获取UDS索引0的梯度向量                // NV_MAG2(): 计算向量的平方模(各分量的平方和)                // ... * C_VOLUME(c,t): 再乘以单元体积                // 最后将结果累加到UDS索引1的当前值上                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)  // 结束单元循环        }    }}

2DEFINE_DELTAT

①描述

DEFINE_DELTAT是一个通用宏,可用于在瞬态问题求解过程中控制时间步长的大小。请注意,仅当在FluentRun Calculation任务页面中从Type下拉列表选择User-Defined Function时,此宏才可使用。

②用法

DEFINE_DELTAT (name, d)

nameUDF名称;

Domain *d:指向时间步进控制函数所要应用的域。域参数提供了对网格中所有单元和面线程的访问。对于多相流,求解器传递给函数的指针是混合物级别的域。

DEFINE_DELTAT有两个参数:namedomain。需要提供name,即UDF的名称。domainFluent求解器传递给UDFUDF需要计算物理时间步长的实际值并将其返回给求解器。

③示例

以下名为mydeltatUDF是一个简单函数,展示了如何使用DEFINE_DELTAT来改变模拟中的时间步长值。首先,使用CURRENT_TIME获取当前模拟时间的值(该值被赋予变量flow_time)。在计算的前0.5秒内,时间步长设置为0.1;模拟剩余部分的时间步长则设置为0.2。随后将时间步长变量返回给求解器。 

include"udf.h" DEFINE_DELTAT(mydeltat,d) {   real time_step;   real flow_time = CURRENT_TIME;   if (flow_time < 0.5)       time_step = 0.1;   else       time_step = 0.2;   return time_step; }

3DEFINE_EXECUTE_AT_END

①描述

DEFINE_EXECUTE_AT_END是一种通用宏,可在稳态运行的迭代结束时或瞬态运行的时间步长结束时执行。当需要在这些特定时刻计算流量参数时,可使用DEFINE_EXECUTE_AT_END。请注意,无需指定执行末端UDF是在时间步长结束时还是在迭代结束时执行——在Fluent模型中选择稳态或非稳态时间方法时,系统会自动完成此判定。

②用法

DEFINE_EXECUTE_AT_END(name)

nameUDF名称;

DEFINE_EXECUTE_AT_END只有一个参数:name。需要提供UDF的名称。与DEFINE_ADJUST不同,DEFINE_EXECUTE_AT_END不会传递域指针。因此,如果函数需要访问域指针,则需要使用工具Get_Domain(ID)显式获取它。如果UDF在多相流解决方案中需要访问相域指针,则需要将相应的相ID传递给Get_Domain以获取它。

③示例

以下名为execute_at_endUDF,通过DEFINE_EXECUTE_AT_END将整个域中的湍流耗散进行积分,并在当前迭代或时间步结束时在控制台中显示。该UDF可在Fluent中作为解释型或编译型UDF执行。

include"udf.h"DEFINE_EXECUTE_AT_END(execute_at_end){    Domain *d;  // 声明域指针,用于指向计算域    Thread *t;  // 声明线程指针,用于遍历不同的网格区域    /* Integrate dissipation. */    real sum_diss = 0.;      // 声明并初始化实型变量sum_diss为0,用于累加湍流耗散率的体积积分值    cell_t c;      // 声明单元索引,用于遍历网格中的每个单元    // 获取计算域指针    // Get_Domain(1): 获取域ID为1的域,在多相流中通常指混合物域    d = Get_Domain(1);  /* mixture domain if multiphase */    // 循环遍历计算域中的所有单元线程    thread_loop_c(t,d)    {        // 检查当前线程是否为流体线程(排除固体区域等)        if (FLUID_THREAD_P(t))        {            // 开始在当前流体线程中循环遍历所有单元            begin_c_loop(c,t)                // 累加:当前单元的湍流耗散率 × 单元体积                // C_D(c,t): 获取单元(c,t)的湍流耗散率值(通常是k-epsilon模型中的ε)                // C_VOLUME(c,t): 获取单元(c,t)的体积                sum_diss += C_D(c,t) * C_VOLUME(c,t);            // 结束当前线程的单元循环            end_c_loop(c,t)        }    }    // 输出湍流耗散率的体积积分结果到控制台    // %g: 自动选择浮点数格式输出    printf("Volume integral of turbulent dissipation: %g\n", sum_diss);    // 强制刷新标准输出缓冲区,确保信息立即显示在控制台    fflush(stdout);}

4DEFINE_EXECUTE_AT_EXIT

①描述

DEFINE_EXECUTE_AT_EXIT是一个通用宏,可用于在Fluent会话结束时执行函数。

②用法

DEFINE_EXECUTE_AT_EXIT(name)

nameUDF名称;

DEFINE_EXECUTE_AT_END只有一个参数:name。需要提供UDF的名称。

5DEFINE_EXECUTE_FROM_GUI

①描述

DEFINE_EXECUTE_FROM_GUI是一种通用宏,可用于定义通过用户自定义图形界面(GUI)执行的UDF。例如,使用DEFINE_EXECUTE_FROM_GUI定义的C函数可在用户自定义GUI中点击按钮时执行

②用法

DEFINE_EXECUTE_FROM_GUI (name,libname,mode)

nameUDF名称;

char *libnameFluent中已加载的UDF库名称;

int mode:从Scheme程序中传递的整数,用于定义用户自定义GUI

DEFINE_EXECUTE_FROM_GUI有三个参数:namelibnamemode。需要提供name,即UDF的名称。变量libnamemodeFluent求解器传递给UDF。整型变量mode从定义用户自定义GUIScheme程序传递而来,代表GUI对话框中可用的用户选项。每个选项都可以调用UDF中不同的C函数。例如,用户自定义的GUI对话框可能有多个按钮。每个按钮可由不同的整数表示,点击时将执行相应的C函数。

重要提示:DEFINE_EXECUTE_FROM_GUI必须作为编译型UDF实现,且每个UDF库中只能存在一个此类函数。

③示例

以下名为reset_udmUDF在用户自定义GUI对话框中的重置按钮被点击时,会重置所有用户自定义内存(UDM)值。按钮点击动作由0表示,该值由Fluent求解器传递给UDF

 include"udf.h"DEFINE_EXECUTE_FROM_GUI(reset_udm, myudflib, mode){    Domain *domain = Get_Domain(1);     /* Get domain pointer */      // 获取域指针,参数1通常表示主域或混合物域    Thread *t;   // 声明线程指针,用于遍历不同的网格区域    cell_t c;    // 声明单元索引,用于遍历网格单元    int i;       // 声明整数变量,用于循环计数器    /* Return if mode is not zero */      if (mode != 0return;      // 检查执行模式,如果mode不为0,则直接返回(通常mode=0表示执行操作)    /* Return if no User-Defined Memory is defined in Ansys Fluent */    if (n_udm == 0return;      // 检查Fluent中是否定义了用户自定义内存(UDM),如果没有定义,则直接返回    /* Loop over all cell threads in domain */    // 循环遍历计算域中的所有单元线程    thread_loop_c(t, domain)    {        /* Loop over all cells */        // 开始在当前线程中循环遍历所有单元        begin_c_loop(c, t)        {            /* Set all UDMs to zero */            // 循环遍历所有已定义的UDM索引            for (i = 0; i < n_udm; i++)            {                // 将当前单元的每个UDM值设置为0.0                C_UDMI(c, t, i) = 0.0;            }        }        end_c_loop(c, t);  // 结束单元循环    }}

参考资料:Ansys Fluent UDF Manual》 2023R1

CFD理论基础合集(持续更新中):

Ansys Fluent帮助文档-UDF篇:用户自定义函数概述(UDFs)(一)

Ansys Fluent帮助文档-UDF篇:用户自定义函数概述(UDFs)(二)

特别感谢您的阅读、点赞、转发、推荐!

本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » Ansys Fluent文档-UDF篇:通用DEFINE宏(一)

评论 抢沙发

1 + 9 =
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
×
订阅图标按钮