Fluent UDF(七)向量宏

前述章节 UDF 案例中穿插应用了一些向量和维度宏(如定义数组x[ND_ND]),Fluent 提供了一些预定义宏来处理二维和三维问题,并对向量进行操作运算。本文将系统介绍这类向量运算和维度处理宏。

在 UDF 中处理二维和三维表达式的方法有两种。第一种方法是使用显式方法,在条件语句中使用 RP_2DRP_3D 来控制UDF的编译运行;第二种方法使用通用的 3D 表达式,并使用 NDNV 宏在 2D 问题编译时删除 z 分量。NV 宏对向量进行操作, ND 宏对向量分量进行操作。

1. RP_2D 和 RP_3D 宏

在条件语句中使用 RP_2D 或 RP_3D 宏将指示编译器分别对RP宏标记部分进行编译。

示例:3D 问题中使用 RP_3D 对旋流项进行操作

#if RP_3D

/* 计算旋流项 */

#endif
2. ND 宏

在 UDF 中,可以使用 ND 宏来实现通用的维度表达式,根据问题维度的不同,ND宏会自动删除处理对应的向量分量。ND 宏适用于 2D 和 3D 情况,无需进行任何修改。

2.1. ND_ND

ND_ND是一个整型常量,在二维问题下ND_ND=2,三维问题ND_ND=3

该宏在UDF中使用比较频繁,例如前述章节定义一个数组储存面心坐标:

        real FC[ND_ND];  //定义数组存储面心坐标,根据问题维度不同ND_ND取值不同
        F_CENTROID(FC, face, face_thread);  // 获取面 face 的质心坐标,并存储在 FC 数组中
        fx = FC[0];  // 获取 x 坐标
        fy = FC[1];  // 获取 y 坐标

如下 UDF 片段定义一个数组并对数组元素进行遍历赋值,使用ND_ND操作宏使得代码在 2D 和 3D 模式下都能正确执行,而无需分别编写不同维度的代码。

// 定义一个数组 A
real A[ND_ND][ND_ND];

// 循环变量 i 和 j
int i, j;

// 外层循环:遍历数组的行
for (i = 0; i < ND_ND; ++i)
{
    // 内层循环:遍历数组的列
    for (j = 0; j < ND_ND; ++j)
    {
        // 将函数 f(i, j) 的返回值赋值给数组 A 的相应位置
        A[i][j] = f(i, j);
    }
}

2.2. ND_SUM

ND_SUM宏用于计算 ND_ND 各分量和。

// 在 2D 模式下
real sum_2d = ND_SUM(x, y); // 结果为 x + y

// 在 3D 模式下
real sum_3d = ND_SUM(x, y, z); // 结果为 x + y + z

示例:

// 定义变量
real x = 1.0;
real y = 2.0;
real z = 3.0;

// 计算和
real sum;

// 在 2D 模式下,sum 将是 x + y
// 在 3D 模式下,sum 将是 x + y + z
sum = ND_SUM(x, y, z);

printf("The sum is: %f\n", sum);

2.3. ND_SET

ND_SET 用于生成 ND_ND 赋值语句。其根据当前模拟的维度(2D 或 3D),生成适当数量的赋值语句。

ND_SET(u, v, w, C_U(c, t), C_V(c, t), C_W(c, t))
// u = C_U(c, t);
// v = C_V(c, t);

#if RP_3D
// w = C_W(c, t);
#endif

UDF示例:

#include "udf.h"

DEFINE_ADJUST(set_velocity_components, domain)
{
  cell_t c;
  Thread *t;
  real u, v, w;

  /* 遍历所有单元格 */
  begin_c_loop(c, t)
  {
    /* 使用 ND_SET 宏生成适当的赋值语句 */
    ND_SET(u, v, w, C_U(c, t), C_V(c, t), C_W(c, t));

    /* 现在可以使用 u, v, w 进行其他操作 */
    message("Velocity components: u = %f, v = %f, w = %f\n", u, v, w);
  }
  end_c_loop(c, t)
}

3. NV 宏

前述 ND 宏是对向量各分量进行操作,而 NV宏 则对维度为ND_ND不同向量进行操作运算。

3.1. NV_V

NV_V 宏对两个向量执行操作。假设我们有两个向量 ax,并希望将 x 的值赋给 a,我们可以使用以下代码:

NV_V(a, =, x);

这段代码在二维计算中相当于:

a[0] = x[0];
a[1] = x[1];

在三维计算中相当于:

a[0] = x[0];
a[1] = x[1];
a[2] = x[2];
3.2. NV_VV

NV_VV 宏对向量各分量执行操作。宏的调用形式为 NV_VV(a, =, x, +, y);,其含义是在 a 向量的各个分量上执行指定操作,将 xy 向量的相应分量根据操作符进行计算,并赋给 a。执行的操作取决于宏调用中 + 号位置使用运算符号(如 -/*)。

NV_VV(a, =, x, +, y)
// 2D: a[0] = x[0] + y[0], a[1] = x[1] + y[1];
3.3. NV_V_VS

NV_V_VS 宏用于执行向量与标量的乘积运算。

NV_V_VS(a, =, x, +, y, *, 0.5);
// 2D: a[0] = x[0] + (y[0]*0.5), a[1] = x[1] + (y[1]*0.5);

请注意,可以用 -、/* 替换 + 号,* 号可以用 / 替换。

3.4. NV_VS_VS

NV_V_VS 宏用于执行向量与标量的混合运算。

NV_VS_VS(a, =, x, *, 2.0, +, y, *, 0.5);
// 2D: 
a[0] = (x[0]*2.0) + (y[0]*0.5), 
a[1] = (x[1]*2.0) + (y[1]*0.5);

//3D:
a[0] = (x[0]*2.0) + (y[0]*0.5);
a[1] = (x[1]*2.0) + (y[1]*0.5);
a[2] = (x[2]*2.0) + (y[2]*0.5);

同理,可以用 -、/* 替换 + 号,* 号可以用 / 替换。

4. 向量运算宏

向量运算在 UDF 中的应用非常广泛,涵盖了从基础的速度和力的计算到复杂的涡度和轨迹分析等多个方面,在 UDF 中,可以使用一些宏来执行向量操作,例如计算向量的模、点积和叉积等。

4.1. 向量大小

NV_MAG 操作宏用于计算向量的模,即向量各分量平方和的平方根。

NV_MAG(x)
// 2D: sqrt(x[0]*x[0] + x[1]*x[1]);
// 3D: sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);

使用示例:

real magnitude;
real vector[ND_ND] = {3.0, 4.0, 0.0}; // 一个三维向量,z 分量为 0 表示二维情况
magnitude = NV_MAG(vector);

NV_MAG2操作宏用于计算向量各分量的平方和。

NV_MAG2(x)
// 2D: (x[0]*x[0] + x[1]*x[1]);
// 3D: (x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
4.2. 向量点积

ND_DOTNV_DOT 用于计算两个向量的点积。ND_DOT 适用于分别提供的向量分量,而 NV_DOT 适用于向量数组。

ND_DOT(x, y, z, u, v, w)
// 2D: (x*u + y*v);
// 3D: (x*u + y*v + z*w);

NV_DOT(x, u)
// 2D: (x[0]*u[0] + x[1]*u[1]);
// 3D: (x[0]*u[0] + x[1]*u[1] + x[2]*u[2]);

NVD_DOT(x, u, v, w)
// 2D: (x[0]*u + x[1]*v);
// 3D: (x[0]*u + x[1]*v + x[2]*w);
4.3. 向量叉积

ND_CROSSNV_CROSS 用于计算两个向量的叉积。对于二维情况,叉积的结果为零,因为在二维中,向量没有 z 分量。

ND_CROSS_X(x0, x1, x2, y0, y1, y2)
// 2D: 0.0
// 3D: (((x1)*(y2))-(y1)*(x2)))

ND_CROSS_Y(x0, x1, x2, y0, y1, y2)
// 2D: 0.0
// 3D: (((x2)*(y0))-(y2)*(x0)))

ND_CROSS_Z(x0, x1, x2, y0, y1, y2)
// 2D 和 3D: (((x0)*(y1))-(y0)*(x1)))

NV_CROSS_X(x, y)
ND_CROSS_X(x[0], x[1], x[2], y[0], y[1], y[2])

NV_CROSS_Y(x, y)
ND_CROSS_Y(x[0], x[1], x[2], y[0], y[1], y[2])

NV_CROSS_Z(x, y)
ND_CROSS_Z(x[0], x[1], x[2], y[0], y[1], y[2])

NV_CROSS(a, x, y)
// a[0] = NV_CROSS_X(x, y);
// a[1] = NV_CROSS_Y(x, y);
// a[2] = NV_CROSS_Z(x, y);
  • 19
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值