[ANSYS, Inc. Logo] return to home search
next up previous contents index

2.5.4 DEFINE_DPM_EROSION



Description


You can use DEFINE_DPM_EROSION to specify the erosion and accretion rates calculated as the particle stream strikes a wall surface. The function is called when the particle encounters a reflecting surface.



Usage



DEFINE_DPM_EROSION( name, p, t, f, normal, alpha, Vmag, mdot)


Argument Type Description
symbol name UDF name.
Tracked_Particle *p Pointer to the Tracked_Particle data structure which
  contains data related to the particle being tracked.
Thread *t Pointer to the face thread the particle is currently hitting.
face_t f Index of the face that the particle is hitting.
real normal[] Array that contains the unit vector that is normal to the face.
real alpha Variable that represents the impact angle between the particle
  path and the face (in radians).
real Vmag Variable that represents the magnitude of the particle velocity
  (in m/s).
real mdot Flow rate of the particle stream as it hits the face (in kg/s).
   
Function returns  
void  
   

There are eight arguments to DEFINE_DPM_EROSION: name, p, t, f, normal, alpha, Vmag, and mdot. You supply name, the name of the UDF. p, t, f, normal, alpha, Vmag, and mdot are variables that are passed by the ANSYS FLUENT solver to your UDF. Your UDF will need to compute the values for the erosion rate and/or accretion rate and store the values at the faces in F_STORAGE_R(f,t,SV_DPMS_EROSION) and F_STORAGE_R (f,t,SV_DPMS_ACCRETION), respectively.

figure   

Pointer p can be used as an argument to the macros defined in Section  3.2.7 to obtain information about particle properties (e.g., injection properties).



Example


The following is an example of a compiled UDF that uses DEFINE_DPM_EROSION to extend postprocessing of wall impacts in a 2D axisymmetric flow. It provides additional information on how the local particle deposition rate depends on the diameter and normal velocity of the particles. It is based on the assumption that every wall impact leads to more accretion, and, therefore, every trajectory is "evaporated" at its first wall impact. (This is done by first setting a DPM user scalar within DEFINE_DPM_EROSION, which is then evaluated within DEFINE_DPM_LAW, where P_MASS is set to zero.) User-defined memory locations (UDMLs) are used to store and visualize the following:

Before tracing the particles, you will have to reset the UDMLs and assign the global domain pointer by executing the DEFINE_ON_DEMAND function.

/***********************************************************************
   UDF for extending postprocessing of wall impacts
************************************************************************/
#include "udf.h"

#define MIN_IMPACT_VELO -1000.
  /* Minimum particle velocity normal to wall (m/s) to allow Accretion.*/

Domain *domain; /* Get the domain pointer and assign it later to domain*/

enum            /* Enumeration of used User-Defined Memory Locations. */
{
  NUM_OF_HITS,    /* Number of particle hits into wall face considered.*/
  AVG_DIAMETER,    /* Average diameter of particles that hit the wall. */
  AVG_RADI_VELO,    /* Average radial velocity of ""  ""  ------------ */
  NUM_OF_USED_UDM
};

int UDM_checked = 0;     /* Availability of UDMLs checked? */

void reset_UDM_s(void);  /* Function to follow below. */

int check_for_UDM(void)      /* Check for UDMLs' availability... */
{
  Thread *t;

  if (UDM_checked)
    return UDM_checked;

/* if (!rp_axi)*/
 /* Internal_Error("UDF-Error: only valid for 2d-axisymmetric cases!\n");*/
  thread_loop_c(t,domain)    /* We require all cell threads to */
    {                         /* provide space in memory for UDML */
      if (FLUID_THREAD_P(t))
        if (NULLP(THREAD_STORAGE(t,SV_UDM_I)))
            return 0;
    }

  UDM_checked = 1;     /* To make the following work properly... */
  reset_UDM_s();       /* This line will be executed only once, */
  return UDM_checked;  /* because check_for_UDM checks for */
}                      /* UDM_checked first. */

void
reset_UDM_s(void)
{
  Thread *t;
  cell_t  c;
  face_t  f;
  int     i;

  if (!check_for_UDM())  /* Don't do it, if memory is not available. */
    return;

  Message("Resetting User Defined Memory...\n");

  thread_loop_f(t, domain)
    {
      if (NNULLP(THREAD_STORAGE(t,SV_UDM_I)))
        {
          begin_f_loop(f,t)
            {
              for (i = 0; i < NUM_OF_USED_UDM; i++)
                F_UDMI(f,t,i) = 0.;
            }
          end_f_loop(f, t)
        }
      else
        {
          Message("Skipping FACE thread no. %d..\n", THREAD_ID(t));
        }
    }
  thread_loop_c(t,domain)
    {
      if (NNULLP(THREAD_STORAGE(t,SV_UDM_I)))
        {
          begin_c_loop(c,t)
            {
              for (i = 0; i < NUM_OF_USED_UDM; i++)
                C_UDMI(c,t,i) = 0.;
            }
          end_c_loop(c,t)
        }
      else
        {
          Message(" Skipping CELL thread no. %d..\n", THREAD_ID(t));
        }
    }                /* Skipping Cell Threads can happen if the user */
                            /* uses reset_UDM prior to initializing. */
  Message(" --- Done.\n");
}

DEFINE_DPM_SCALAR_UPDATE(dpm_scalup,c,t,if_init,p)
{  if (if_init)
    P_USER_REAL(p, 0) = 0;    /* Simple initialization. Used later for
                                stopping trajectory calculation */
}

DEFINE_DPM_EROSION(dpm_accr, p, t, f, normal, alpha, Vmag, Mdot)
{
  real A[ND_ND], area;
  int num_in_data;
  Thread *t0;
  cell_t  c0;

  real radi_pos[2], radius, imp_vel[2], vel_ortho;

/* The following is ONLY valid for 2d-axisymmetric calculations!!! */
/* Additional effort is necessary because DPM tracking is done in  */
/* THREE dimensions for TWO-dimensional axisymmetric calculations. */

  radi_pos[0] = P_POS(p)[1];      /* Radial location vector. */
  radi_pos[1] = P_POS(p)[2];      /* (Y and Z in 0 and 1...) */

  radius = NV_MAG(radi_pos);
  NV_VS(radi_pos, =, radi_pos, /, radius);
                               /* Normalized radius direction vector.*/
  imp_vel[0] = P_VEL(p)[0];    /* Axial particle velocity component. */
  imp_vel[1] = NVD_DOT(radi_pos, P_VEL(p)[1], P_VEL(p)[2], 0.);
  /* Dot product of normalized radius vector and y & z components */
  /* of particle velocity vector gives _radial_ particle velocity */
  /* component  */
  vel_ortho = NV_DOT(imp_vel, normal); /*velocity orthogonal to wall */

  if (vel_ortho < MIN_IMPACT_VELO)  /* See above, MIN_IMPACT_VELO */
    return;

  if (!UDM_checked)       /* We will need some UDMs, */
    if (!check_for_UDM()) /* so check for their availability.. */
      return;             /* (Using int variable for speed, could */
                          /*  even just call check_for UDFM().) */
  c0 = F_C0(f,t);
  t0 = THREAD_T0(t);

  num_in_data = F_UDMI(f,t,NUM_OF_HITS);

/* Average diameter of particles that hit the particular wall face:*/
  F_UDMI(f,t,AVG_DIAMETER) = (P_DIAM(p)
                          +  num_in_data * F_UDMI(f,t,AVG_DIAMETER))
                             / (num_in_data + 1);
  C_UDMI(c0,t0,AVG_DIAMETER) = F_UDMI(f,t,AVG_DIAMETER);

/* Average velocity normal to wall of particles hitting the wall:*/
  F_UDMI(f,t,AVG_RADI_VELO) = (vel_ortho
                        +  num_in_data * F_UDMI(f,t,AVG_RADI_VELO))
                           / (num_in_data + 1);
  C_UDMI(c0,t0,AVG_RADI_VELO) = F_UDMI(f,t,AVG_RADI_VELO);

  F_UDMI(f, t, NUM_OF_HITS) = num_in_data + 1;
  C_UDMI(c0,t0,NUM_OF_HITS) = num_in_data + 1;

  F_AREA(A,f,t);
  area = NV_MAG(A);
  F_STORAGE_R(f,t,SV_DPMS_ACCRETION) += Mdot / area;
                                           /* copied from source. */

  P_USER_REAL(p,0) = 1.;     /* "Evaporate" */
}

DEFINE_DPM_LAW(stop_dpm_law,p,if_cpld)
{
  if (0. < P_USER_REAL(p,0))
    P_MASS(p) = 0.;          /* "Evaporate" */
}

DEFINE_ON_DEMAND(reset_UDM)
{
  /* assign domain pointer with global domain */
  domain = Get_Domain(1);
  reset_UDM_s();
}



Hooking an Erosion/Accretion UDF to ANSYS FLUENT


After the UDF that you have defined using DEFINE_DPM_EROSION is interpreted (Chapter  4) or compiled (Chapter  5), the name of the argument that you supplied as the first DEFINE macro argument will become visible in the Discrete Phase Model dialog box in ANSYS FLUENT. See Section  6.4.4 for details on how to hook your DEFINE_DPM_EROSION UDF to ANSYS FLUENT.


next up previous contents index Previous: 2.5.3 DEFINE_DPM_DRAG
Up: 2.5 Discrete Phase Model
Next: 2.5.5 DEFINE_DPM_HEAT_MASS
Release 12.0 © ANSYS, Inc. 2009-01-14