2.8. User-Defined Scalar (UDS) Transport Equation DEFINE Macros

This section provides information on how you can define UDFs that can be used in UDS transport equations in Ansys Fluent. See User-Defined Scalar (UDS) Transport Equations in the User’s Guide for UDS equation theory and details on how to set up scalar equations. Descriptions of DEFINE macros for UDS applications are provided below. Definitions of DEFINE macros are contained in the udf.h header file. For your convenience, they are also listed in Appendix B: DEFINE Macro Definitions. Detailed examples of user-defined scalar transport UDFs can be found in User-Defined Scalars.

2.8.1. Introduction

For each of the scalar equations you specified in your Ansys Fluent model you can supply a unique UDF for the diffusion coefficients, flux, and unsteady terms in the scalar transport equation. For multiphase you have the added benefit of specifying UDFs on a per-phase basis in both fluid and solid zones. Additionally, you can specify a UDF for each source term you define for a given scalar equation as well as boundary conditions on wall, inflow, and outflow boundaries.

2.8.1.1. Diffusion Coefficient UDFs

For each of the scalar equations you have specified in your Ansys Fluent model using the User-Defined Scalars dialog box you can supply a unique user-defined function (UDF) for isotropic and anisotropic diffusivity for both fluid and solid materials. Recall that Ansys Fluent computes the diffusion coefficient in the UDS equation.

Isotropic diffusivity UDFs are defined using the DEFINE_DIFFUSIVITY macro ( DEFINE_DIFFUSIVITY ) and anisotropic coefficients UDFs are defined using DEFINE_ANISOTROPIC_DIFFUSIVITY ( DEFINE_ANISOTROPIC_DIFFUSIVITY ). Additional pre-defined macros that you can use when coding UDS functions are provided in User-Defined Scalar (UDS) Transport Equation Macros.

2.8.1.2. Flux UDFs

For each of the scalar equations you have specified in your Ansys Fluent model using the User-Defined Scalars dialog box you can supply a unique user-defined function (or UDF) for the advective flux term. Recall that Ansys Fluent computes the flux in the UDS equation.

UDS Flux UDFs are defined using the DEFINE_UDS_FLUX macro ( DEFINE_UDS_FLUX ). Additional pre-defined macros that you can use when coding scalar flux UDFs are provided in User-Defined Scalar (UDS) Transport Equation Macros.

2.8.1.3. Unsteady UDFs

For each of the scalar equations you have specified in your Ansys Fluent model using the User-Defined Scalars dialog box you can supply a unique UDF for the unsteady function. Recall that Ansys Fluent computes the unsteady term in the UDS equation.

Scalar Unsteady UDFs are defined using the DEFINE_UDS_UNSTEADY macro ( DEFINE_UDS_UNSTEADY ). Additional pre-defined macros that you can use when coding scalar unsteady UDFs are provided in User-Defined Scalar (UDS) Transport Equation Macros.

2.8.1.4. Source Term UDFs

For each of the scalar equations you have specified in your Ansys Fluent model using the User-Defined Scalars dialog box you can supply a unique UDF for each source. Recall that Ansys Fluent computes the source term in the UDS equation.

Scalar source UDFs are defined using the DEFINE_SOURCE macro and must compute the source term, , and its derivative ( DEFINE_SOURCE ). Additional pre-defined macros that you can use when coding scalar source term UDFs are provided in User-Defined Scalar (UDS) Transport Equation Macros.

2.8.1.5. Fixed Value Boundary Condition UDFs

For each of the scalar equations you have specified in your Ansys Fluent model using the User-Defined Scalars dialog box you can supply a fixed value profile UDF for fluid boundaries.

Fixed value UDFs are defined using the DEFINE_PROFILE macro. See DEFINE_PROFILE for details. Additional pre-defined macros that you can use for coding scalar transport equation UDFs are provided in User-Defined Scalar (UDS) Transport Equation Macros.

2.8.1.6. Wall, Inflow, and Outflow Boundary Condition UDFs

For each of the scalar equations you have specified in your Ansys Fluent model using the User-Defined Scalars dialog box you can supply a specified value or flux UDF for all wall, inflow, and outflow boundaries.

Wall, inflow, and outflow boundary UDFs are defined using the DEFINE_PROFILE macro ( DEFINE_PROFILE ). Additional pre-defined macros that you can use for coding scalar transport equation UDFs are provided in User-Defined Scalar (UDS) Transport Equation Macros.

2.8.2. DEFINE_ANISOTROPIC_DIFFUSIVITY

2.8.2.1. Description

You can use DEFINE_ANISOTROPIC_DIFFUSIVITY to specify an anisotropic diffusivity for a user-defined scalar (UDS) transport equation. See Anisotropic Diffusion in the User's Guide for details about anisotropic diffusivity material properties in Ansys Fluent.

2.8.2.2. Usage

DEFINE_ANISOTROPIC_DIFFUSIVITY (name, c, t, i, dmatrix)

Argument Type

Description

symbol name

UDF name.

cell_t c

Cell index.

Thread *t

Pointer to cell thread on which the anisotropic diffusivity function is to be applied.

int i

Index that identifies the user-defined scalar.

real dmatrix[ND_ND][ND_ND]

Anisotropic diffusivity matrix to be filled in by user.

Function returns

void

There are five arguments to DEFINE_ANISOTROPIC_DIFFUSIVITY: name, c, t, i, and dmatrix. You will supply name, the name of the UDF. c, t, i, and dmatrix are variables that are passed by the Ansys Fluent solver to your UDF. Your function will compute the diffusivity tensor for a single cell and fill dmatrix with it. Note that anisotropic diffusivity UDFs are called by Ansys Fluent from within a loop on cell threads. Consequently, your UDF will not need to loop over cells in a thread since Ansys Fluent is doing it outside of the function call.

2.8.2.3. Example

The following UDF, named cyl_ortho_diff computes the anisotropic diffusivity matrix for a cylindrical shell which has different diffusivities in radial, tangential, and axial directions. This function can be executed as a compiled UDF.

/***************************************************************
   Example UDF that demonstrates DEFINE_ANISOTROPIC_DIFFUSIVITY
 ***************************************************************/
 #include "udf.h"
 
 /* Computation of anisotropic diffusivity matrix for
 * cylindrical orthotropic diffusivity */
 
 /* axis definition for cylindrical diffusivity */
 static const real origin[3] = {0.0, 0.0, 0.0};
 static const real axis[3]  = {0.0, 0.0, 1.0};
 
 /* diffusivities in radial, tangential and axial directions */
 static const real diff[3] = {1.0, 0.01, 0.01};
 
 DEFINE_ANISOTROPIC_DIFFUSIVITY(cyl_ortho_diff,c,t,i,dmatrix)
 {
    real x[3][3]; /* principal direction matrix for cell in cartesian coords. */
    real xcent[ND_ND];
    real R;
    C_CENTROID(xcent,c,t);
    NV_VV(x[0],=,xcent,-,origin);
   #if RP_3D
      NV_V(x[2],=,axis);
   #endif
   #if RP_3D
      R = NV_DOT(x[0],x[2]);
      NV_VS(x[0],-=,x[2],*,R);
   #endif
    R = NV_MAG(x[0]);
    if (R > 0.0)
       NV_S(x[0],/=,R);
   #if RP_3D
    N3V_CROSS(x[1],x[2],x[0]);
   #else
      x[1][0] = -x[0][1];
      x[1][1] = x[0][0];
   #endif
    /* dmatrix is computed as xT*diff*x */
    dmatrix[0][0] = diff[0]*x[0][0]*x[0][0]
       + diff[1]*x[1][0]*x[1][0]
   #if RP_3D
     + diff[2]*x[2][0]*x[2][0]
   #endif
   ;
    dmatrix[1][1] = diff[0]*x[0][1]*x[0][1]
     + diff[1]*x[1][1]*x[1][1]
   #if RP_3D
     + diff[2]*x[2][1]*x[2][1]
   #endif
     ;
    dmatrix[1][0] = diff[0]*x[0][1]*x[0][0]
     + diff[1]*x[1][1]*x[1][0]
   #if RP_3D
     + diff[2]*x[2][1]*x[2][0]
   #endif
   ;
    dmatrix[0][1] = dmatrix[1][0];
   
   #if RP_3D
    dmatrix[2][2] = diff[0]*x[0][2]*x[0][2]
     + diff[1]*x[1][2]*x[1][2]
     + diff[2]*x[2][2]*x[2][2]
     ;
    dmatrix[0][2] = diff[0]*x[0][0]*x[0][2]
     + diff[1]*x[1][0]*x[1][2]
     + diff[2]*x[2][0]*x[2][2]
     ;
    dmatrix[2][0] = dmatrix[0][2];  
   dmatrix[1][2] = diff[0]*x[0][1]*x[0][2]
     + diff[1]*x[1][1]*x[1][2]
     + diff[2]*x[2][1]*x[2][2]
     ;
    dmatrix[2][1] = dmatrix[1][2];
   #endif
 } 

2.8.2.4. Hooking an Anisotropic Diffusivity UDF to Ansys Fluent

After the UDF that you have defined using DEFINE_ANISOTROPIC_DIFFUSIVITY is interpreted (Interpreting UDFs) or compiled (Compiling UDFs), the name of the argument that you supplied as the first DEFINE macro argument (for example, cyl_ortho_diff) will become selectable via the UDS Diffusion Coefficients dialog box. You’ll first need to select defined-per-uds for UDS Diffusivity in the Create/Edit Materials dialog box, then select the user-defined-anisotropic option for Coefficient from the UDS Diffusion Coefficients dialog box for a particular user-defined scalar diffusion equation (for example, uds-0). See Hooking DEFINE_ANISOTROPIC_DIFFUSIVITY UDFs for details.

2.8.3. DEFINE_UDS_FLUX

2.8.3.1. Description

You can use DEFINE_UDS_FLUX to customize how the advective flux term is computed in your user-defined scalar (UDS) transport equations. Note that this macro is for fluid cell zones only, as it cannot be used to calculate convective flux in a solid zone. See User-Defined Scalar (UDS) Transport Equations in the User's Guide for details on setting up and solving UDS transport equations.

2.8.3.2. Usage

DEFINE_UDS_FLUX (name,f,t,i)

Argument Type

Description

symbol name

UDF name.

face_t f

Face index.

Thread *t

Pointer to face thread on which the user-defined scalar flux is to be applied.

int i

Index that identifies the user-defined scalar for which the flux term is to be set.

Function returns

real

There are four arguments to DEFINE_UDS_FLUX: name, f, t, and i. You supply name, the name of the UDF. f, t, and i are variables that are passed by the Ansys Fluent solver to your UDF. Your UDF will need to return the real value of the mass flow rate through the given face to the solver.

The advection term in the differential transport equation has the following most general form:

(2–27)

where is the user-defined scalar conservation quantity and is a vector field. In the default advection term, is, by default, the product of the scalar density and the velocity vector:

(2–28)

To define the advection term in Equation 2–27 using DEFINE_UDS_FLUX, your UDF must return the scalar value to Ansys Fluent, where is the same as defined in Equation 2–27 and is the face normal vector of the face.


Important:  Note that the advective flux field that is supplied by your UDF should be divergence-free (that is, it satisfies the continuity equation). In discrete terms this means that the sum of fluxes over all the faces of each cell should be zero. If the advective field is not divergence-free, then is not "conserved" and will result in overshoots/undershoots in the cell value of .


You will need to compute in your UDF using, for example, predefined macros for velocity vector and scalar density that Ansys Fluent has provided (see Additional Macros for Writing UDFs) or using your own prescription. The first case is illustrated in the sample C source code, shown below.


Important:  Note that if more than one scalar is being solved, you can use a conditional if statement in your UDF to define a different flux function for each i. i = is associated with scalar-0 (the first scalar equation being solved).



Important:  Note also that must have units of mass flow rate in SI (that is, kg/s).


/*********************************************************************
    sample C source code that computes dot product of psi and A
    Note that this is not a complete C function
 **********************************************************************/
 
 real NV_VEC(psi), NV_VEC(A);   /* declaring vectors psi and A */
        /* defining psi in terms of velocity field */
 NV_D(psi, =, F_U(f,t), F_V(f,t), F_W(f,t));
 
 NV_S(psi, *=, F_R(f,t))  /* multiplying density to get psi vector  */
 
 F_AREA(A,f,t)    /* face normal vector returned from F_AREA */
 
 return NV_DOT(psi,A);  /* dot product of the two returned   */ 

Additionally, since most quantities in Ansys Fluent are not allocated in memory for interior faces, only for boundary faces (for example, wall zones), your UDF will also need to calculate interior face values from the cell values of adjacent cells. This is most easily done using the arithmetic mean method. Vector arithmetic can be coded in C using the NV_ and ND_ macros (see Additional Macros for Writing UDFs).

Note that if you had to implement the default advection term in a UDF without the fluid density in the definition of (see above), you could simply put the following line in your DEFINE_UDS_FLUX UDF:

return F_FLUX(f,t) / rho; 

where the denominator can be determined by averaging the adjacent cell’s density values C_R(F_C0(f,t),THREAD_T0(t)) and C_R(F_C1(f,t),THREAD_T1(t)).

2.8.3.3. Example

The following UDF, named my_uds_flux, returns the mass flow rate through a given face. The flux is usually available through the Ansys Fluent-supplied macro F_FLUX(f,t) (Face Macros). The sign of flux that is computed by the Ansys Fluent solver is positive if the flow direction is the same as the face area normal direction (as determined by F_AREA - see Face Area Vector (F_AREA)), and is negative if the flow direction and the face area normal directions are opposite. By convention, face area normals always point out of the domain for boundary faces, and they point in the direction from cell c0 to cell c1 for interior faces.

The UDF must be executed as a compiled UDF.

/**********************************************************************/
 /* UDF that implements a simplified advective term in the   */
 /* scalar transport equation           */
 /**********************************************************************/
 
 #include "udf.h"
 
 DEFINE_UDS_FLUX(my_uds_flux,f,t,i)
 {
    cell_t c0, c1 = -1;
    Thread *t0, *t1 = NULL;
    real NV_VEC(psi_vec), NV_VEC(A), flux = 0.0;
    c0 = F_C0(f,t);
    t0 = F_C0_THREAD(f,t);
    F_AREA(A, f, t);
    /* If face lies at domain boundary, use face values; */
    /* If face lies IN the domain, use average of adjacent cells. */
   if (BOUNDARY_FACE_THREAD_P(t)) /*Most face values will be available*/
    {
       real dens;
       /* Depending on its BC, density may not be set on face thread*/
       if (NNULLP(THREAD_STORAGE(t,SV_DENSITY)))
         dens = F_R(f,t);  /* Set dens to face value if available */
       else
         dens = C_R(c0,t0); /* else, set dens to cell value */
       NV_DS(psi_vec, =, F_U(f,t), F_V(f,t), F_W(f,t), *, dens);
       flux = NV_DOT(psi_vec, A); /* flux through Face */  }
    else
    {
     c1 = F_C1(f,t);   /* Get cell on other side of face */
     t1 = F_C1_THREAD(f,t);
     NV_DS(psi_vec, =, C_U(c0,t0),C_V(c0,t0),C_W(c0,t0),*,C_R(c0,t0));
     NV_DS(psi_vec, +=, C_U(c1,t1),C_V(c1,t1),C_W(c1,t1),*,C_R(c1,t1));
     flux = NV_DOT(psi_vec, A)/2.0; /* Average flux through face */
    }
  /* Ansys Fluent will multiply the returned value by phi_f (the scalar’s
  value at the face) to get the ‘‘complete’’ advective term. */
  return flux;
 } 

2.8.3.4. Hooking a UDS Flux Function to Ansys Fluent

After the UDF that you have defined using DEFINE_UDS_FLUX is interpreted (Interpreting UDFs) or compiled (Compiling UDFs), the name of the argument that you supplied as the first DEFINE macro argument (for example, my_uds_flux) will become visible and selectable in the User-Defined Scalars dialog box in Ansys Fluent. See Hooking DEFINE_UDS_FLUX UDFs for details.

2.8.4. DEFINE_UDS_UNSTEADY

2.8.4.1. Description

You can use DEFINE_UDS_UNSTEADY to customize unsteady terms in your user-defined scalar (UDS) transport equations. See User-Defined Scalar (UDS) Transport Equations in the User's Guide for details on setting up and solving UDS transport equations.

2.8.4.2. Usage

DEFINE_UDS_UNSTEADY (name,c,t,i,apu,su)

Argument Type

Description

symbol name

UDF name.

cell_t c

Cell index.

Thread *t

Pointer to cell thread on which the unsteady term for the user-defined scalar transport equation is to be applied.

int i

Index that identifies the user-defined scalar for which the unsteady term is to be set.

real *apu

Pointer to central coefficient.

real *su

Pointer to source term.

Function returns

void

There are six arguments to DEFINE_UDS_UNSTEADY: name, c, t, i, apu, and su. You supply name, the name of the UDF. c, t, and i are variables that are passed by the Ansys Fluent solver to your UDF. Your UDF will need to set the values of the unsteady terms referenced by the real pointers apu and su to the central coefficient and source term, respectively.

The Ansys Fluent solver expects that the transient term will be decomposed into a source term, su, and a central coefficient term, apu. These terms are included in the equation set in a similar manner to the way the explicit and implicit components of a source term might be handled. Hence, the unsteady term is moved to the right-hand side and discretized as follows:

(2–29)

Equation 2–29 shows how su and apu are defined. Note that if more than one scalar is being solved, a conditional if statement can be used in your UDF to define a different unsteady term for each i. i= is associated with scalar-0 (the first scalar equation being solved).

2.8.4.3. Example

The following UDF, named my_uds_unsteady, modifies user-defined scalar time derivatives using DEFINE_UDS_UNSTEADY. The source code can be interpreted or compiled in Ansys Fluent.

/***********************************************************************
   UDF for specifying user-defined scalar time derivatives
 ************************************************************************/
 
 #include "udf.h"
 
 DEFINE_UDS_UNSTEADY(my_uds_unsteady,c,t,i,apu,su)
 {
    real physical_dt, vol, rho, phi_old;
    physical_dt = RP_Get_Real("physical-time-step");
    vol = C_VOLUME(c,t);
    rho = C_R_M1(c,t);
    *apu = -rho*vol / physical_dt;/*implicit part*/
    phi_old = C_STORAGE_R(c,t,SV_UDSI_M1(i));
    *su = rho*vol*phi_old/physical_dt;/*explicit part*/
 } 

2.8.4.4. Hooking a UDS Unsteady Function to Ansys Fluent

After the UDF that you have defined using DEFINE_UDS_UNSTEADY is interpreted (Interpreting UDFs) or compiled (Compiling UDFs), the name of the argument that you supplied as the first DEFINE macro argument (for example, my_uds_unsteady) will become visible and selectable in the User-Defined Scalars dialog box in Ansys Fluent. See Hooking DEFINE_UDS_UNSTEADY UDFs for details.