3.4. Vector and Dimension Macros

Ansys Fluent provides some utilities that you can use in your UDFs to access or manipulate vector quantities and deal with two and three dimensions. These utilities are implemented as macros in the code.

There is a naming convention for vector utility macros. V denotes a vector, S denotes a scalar, and D denotes a sequence of three vector components of which the third is always ignored for a two-dimensional calculation. The standard order of operations convention of parentheses, exponents, multiplication, division, addition, and subtraction (PEMDAS) is not followed in vector functions. Instead, the underscore (_) sign is used to group operands into pairs, so that operations are performed on the elements of pairs before they are performed on groups.


Important:  Note that all of the vector utilities in this section have been designed to work correctly in 2D and 3D. Consequently, you do not need to do any testing to determine this in your UDF.


3.4.1. Macros for Dealing with Two and Three Dimensions

There are two ways that you can deal with expressions involving two and three dimensions in your UDF. The first is to use an explicit method to direct the compiler to compile separate sections of the code for 2D and 3D, respectively. This is done using RP_2D and RP_3D in conditional-if statements. The second method allows you to include general 3D expressions in your UDF, and use ND and NV macros that will remove the z-components when compiling with RP_2D. NV macros operate on vectors while ND macros operate on separate components.

3.4.1.1. RP_2D and RP_3D

The use of a RP_2D and RP_3D macro in a conditional-if statement will direct the compiler to compile separate sections of the code for 2D and 3D, respectively. For example, if you want to direct the compiler to compute swirl terms for the 3D version of Ansys Fluent only, then you would use the following conditional compile statement in your UDF:

 #if RP_3D
 /* compute swirl terms */
 #endif 

3.4.2. The ND Macros

The use of ND macros in a UDF allows you to include general 3D expressions in your code, and the ND macros take care of removing the z components of a vector when you are compiling with RP_2D.

3.4.2.1. ND_ND

The constant ND_ND is defined as 2 for RP_2D (Ansys Fluent 2D) and 3 for RP_3D (Ansys Fluent 3D). It can be used when you want to build a matrix in 2D and a matrix in 3D. When you use ND_ND, your UDF will work for both 2D and 3D cases, without requiring any modifications.

 real A[ND_ND][ND_ND]
 
 for (i=0; i<ND_ND; ++i)
  for (j=0; j<ND_ND; ++j)
  A[i][j] = f(i, j); 

3.4.2.2. ND_SUM

The utility ND_SUM computes the sum of ND_ND arguments.

 ND_SUM(x, y, z)
  2D: x + y;
  3D: x + y + z;
 

3.4.2.3. ND_SET

The utility ND_SET generates ND_ND assignment statements.

 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 3D:
 21
  w = C_W(c, t);
 

3.4.3. The NV Macros

The NV macros have the same purpose as ND macros, but they operate on vectors (that is, arrays of length ND_ND) instead of separate components.

3.4.3.1. NV_V

The utility NV_V performs an operation on two vectors.

 NV_V(a, =, x);
  a[0] = x[0]; a[1] = x[1]; etc. 

Note that if you use + = instead of = in the above equation, then you get

   a[0]+=x[0]; etc. 

See DEFINE_GRID_MOTION for an example UDF that utilizes NV_V.

3.4.3.2. NV_VV

The utility NV_VV performs operations on vector elements. The operation that is performed on the elements depends upon what symbol (-,/,*) is used as an argument in place of the + signs in the following macro call.

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

See DEFINE_GRID_MOTION for an example UDF that utilizes NV_VV.

3.4.3.3. NV_V_VS

The utility NV_V_VS adds a vector to another vector which is multiplied by a scalar.

 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);

Note that the + sign can be replaced by -, /, or *, and the * sign can be replaced by /.

3.4.3.4. NV_VS_VS

The utility NV_VS_VS adds a vector to another vector which are each multiplied by a scalar.

 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); 

Note that the + sign can be used in place of -, *, or /, and the * sign can be replaced by /.

3.4.4. Vector Operation Macros

There are macros that you can use in your UDFs that will allow you to perform operations such as computing the vector magnitude, dot product, and cross product. For example, you can use the real function NV_MAG(V) to compute the magnitude of vector V. Alternatively, you can use the real function NV_MAG2(V) to obtain the square of the magnitude of vector V.

3.4.4.1. Vector Magnitude Using NV_MAG and NV_MAG2

The utility NV_MAG computes the magnitude of a vector. This is taken as the square root of the sum of the squares of the vector components.

 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]); 

The utility NV_MAG2 computes the sum of squares of vector components.

 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]);

See DEFINE_DPM_BC for an example UDF that utilizes NV_MAG.

3.4.4.2. Dot Product

The following utilities compute the dot product of two sets of vector components.

 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);

See DEFINE_DOM_SPECULAR_REFLECTIVITY for an example UDF that utilizes NV_DOT.

3.4.4.3. Cross Product

For 3D, the CROSS macros return the specified component of the vector cross product. For 2D, the macros return the cross product of the vectors with the z-component of each vector set to 0.

 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 and 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); 

See DEFINE_GRID_MOTION for an example UDF that utilizes NV_CROSS.