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

2.3.20 DEFINE_SOX_RATE



Description


You can use DEFINE_SOX_RATE to specify a custom SOx rate that can either replace the internally-calculated SOx rate in the source term equation, or be added to the ANSYS FLUENT rate. Example 1 demonstrates this use of DEFINE_SOX_RATE. The default functionality is to add user-defined rates to the ANSYS FLUENT-calculated rates. If the Replace with UDF Rate option is enabled in the SOx Model dialog box, then the ANSYS FLUENT-calculated rate will not be used and it will instead be replaced by the SOx rate you have defined in your UDF. When you hook a SOx rate UDF to the graphical interface without checking the Replace with UDF Rate box, then the user-defined SOx rate will be added to the internally-calculated rate for the source term calculation.

DEFINE_SOX_RATE may also be used to calculate the upper limit for the integration of the temperature PDF (when temperature is accounted for in the turbulence interaction modeling). You can calculate a custom maximum limit ( $T_{\rm max}$) for each cell and then assign it to the POLLUT_CTMAX(Pollut_Par) macro (see Section  3.2.7 for further details about data access macros). Example 2 demonstrates this use of DEFINE_SOX_RATE.

figure   

If you want to use DEFINE_SOX_RATE only for the purpose of specifying $T_{\rm max}$, be sure that the user-defined SOx rate does not alter the internally-calculated rate for the source term calculation.



Usage



DEFINE_SOX_RATE( name, c, t, Pollut, Pollut_Par, SOx)


Argument Type Description
symbol name UDF name.
cell_t c Cell index.
Thread *t Pointer to cell thread on which the SOx rate
  is to be applied.
Pollut_Cell *Pollut Pointer to the data structure that
  contains the common data at each cell.
Pollut_Parameter *Pollut_Par Pointer to the data structure that
  contains auxiliary data.
SOx_Parameter *SOx Pointer to the data structure that contains
  data specific to the SOx model.
   
Function returns  
void  
   

There are six arguments to DEFINE_SOX_RATE: name, c, t, Pollut, Pollut_Par and SOx. You will supply name, the name of the UDF. c, t, Pollut, Pollut_Par and SOx are variables that are passed by the ANSYS FLUENT solver to your function. A DEFINE_SOX_RATE function does not output a value. The calculated SO $_2$ rates (or other pollutant species rates) are returned through the Pollut structure as the forward rate POLLUT_FRATE(Pollut) and reverse rate POLLUT_RRATE(Pollut), respectively.

figure   

The data contained within the SOx structure is specific only to the SOx model. Alternatively, the Pollut structure contains data at each cell that is useful for all pollutant species (e.g., forward and reverse rates, gas phase temperature, density). The Pollut_Par structure contains auxiliary data common for all pollutant species (e.g. equation solved, universal gas constant, species molecular weights). Note that molecular weights extracted from the Pollut_Par structure (i.e., Pollut_Par->sp[IDX(i)].mw for pollutant species--NO, HCN, etc.--and Pollut_Par->sp[i].mw for other species, such as O $_2$) has units of kg/kg-mol.



Example 1


The following compiled UDF, named user_sox, computes the rates for SO $_2$ and SO $_3$ formation according to the reaction given in Equation  2.3-10. Note that this UDF will replace the ANSYS FLUENT rate only if you select the Replace with UDF Rate option in the SOx Model dialog box. Otherwise, the rate computed in the UDF will be added to ANSYS FLUENT's default rate. See Section  6.2.20 for details.

It is assumed that the release of fuel sulfur from fuel is proportional to the rate of release of volatiles and all sulfur is in the form of SO $_2$ when released to the gas phase. The reversible reaction for SO $_2$/SO $_3$ is given below:


 {\rm SO}_3 + {\rm O} \longleftrightarrow {\rm SO}_2 + {\rm O}_2 (2.3-10)

with forward and reverse rates of reaction ( $k_f$ and $k_r$, respectively) in the Arrhenius form

$k_f = 1.2e^6 e^{(-39765.575/RT)}$

$k_r = 1.0e^4 T^{-1}e^{(-10464.625/RT)}$

The O atom concentration in the gas phase ( $o_{eq}$) is computed using the partial equilibrium assumption, which states

$o_{eq} = 36.64 T^{0.5} e^{(-27123.0/RT)} \sqrt{[O_2]}$

where $[O_2]$ is the molar concentration of oxygen. Here, all units are in m-gmol-J-sec.

The function so2_so3_rate is used to compute the forward and reverse rates for both SO $_2$ and SO $_3$.

The rate of release of SO $_2$ from volatiles ( $S_{{\rm SO}_2,{\rm volatile}}$) is given by:


S_{{\rm SO}_2,{\rm volatile}} = \frac {1000 r_{\rm volatile} Y_{\rm S,volatile} Y_{{\rm S},{\rm SO}_2}} {M_{w,{\rm S}} V}

where $r_{\rm volatile}$ is the rate of release of volatiles in kg/sec, $Y_{\rm S,volatile}$ is the mass fraction of sulfur species in volatiles, $Y_{{\rm S},{\rm SO}_2}$ is the mass fraction of fuel S that converts to SO $_2$, $M_{w,{\rm S}}$ is the molecular weight of sulfur in kg/kg-mol, and $V$ is the cell volume in m $^{3}$.

See Section  3.2.7 for details about the SOx macros (e.g., POLLUT_EQN, MOLECON, ARRH) that are used in pollutant rate calculations in this UDF.

/*****************************************************************
   UDF example of User-Defined SOx Rate for ANSYS FLUENT 12 or later

   If used with the "Replace with UDF" radio button activated,
   this UDF will replace the default fluent SOx rates.
   
   The flag "Pollut_Par->pollut_io_pdf == IN_PDF" should always
   be used for rates other than that from char N, so that if
   requested, the contributions will be PDF integrated. Any
   contribution from char must be included within a switch
   statement of the form "Pollut_Par->pollut_io_pdf == OUT_PDF".
   *
   * Arguments:
   *   char sox_func_name           - UDF name
   *   cell_t c                     - Cell index
   *   Thread *t                    - Pointer to cell thread on
   *                                  which the SOx rate is to be
   *                                  applied
   *   Pollut_Cell *Pollut          - Pointer to Pollut structure
   *   Pollut_Parameter *Pollut_Par - Pointer to Pollut_Par 
   *                                  structure
   *   SOx_Parameter *SOx           - Pointer to SOx structure

*****************************************************************/

#include "udf.h"

static void so2_so3_rate(cell_t c, Thread* t, Pollut_Cell *Pollut,
                  Pollut_Parameter *Pollut_Par, SOx_Parameter *SOx);

DEFINE_SOX_RATE(user_sox, c, t, Pollut, Pollut_Par, SOx)
{
  POLLUT_FRATE(Pollut) = 0.0;
  POLLUT_RRATE(Pollut) = 0.0;

  switch (Pollut_Par->pollut_io_pdf) {
  case IN_PDF:
    /* Included source terms other than those from char */

    if (SOx->user_replace) {
      /* This rate replaces the default ANSYS FLUENT rate */
      so2_so3_rate(c,t,Pollut,Pollut_Par,SOx);
    }
    else {
      /* This rate is added to the default ANSYS FLUENT rate */
      so2_so3_rate(c,t,Pollut,Pollut_Par,SOx);
    }
    break;
  case OUT_PDF:
    /* Char Contributions, must be included here */
    break;

  default:
    /* Not used */
    break;
  }

}

static void so2_so3_rate(cell_t c, Thread* t, Pollut_Cell *Pollut,
                  Pollut_Parameter *Pollut_Par, SOx_Parameter *SOx)
{
  /* Pollut_Par->nfstreams = Number of fuel streams
   * Pollut->r_fuel_gls[i] = Rate of volatile release for stream "i"
   *                         per unit volume in kg/m3-sec
   * SOx->Ys_fuelvolat[i] = Mass fraction of S in volatile stream "i"
   * SOx->fuels_so2_frac[i] = Partition fraction of SO2 in stream "i"
   */
  real kf,kr,rf=0,rr=0;
  real o_eq;
  real r_volatile,Ys_volatile,fuels_so2_frac;

  Rate_Const K_F = {1.2e6,  0.0, 39765.575};
  Rate_Const K_R = {1.0e4, -1.0, 10464.625};
  Rate_Const K_O = {36.64,  0.5, 27123.0};

  /* SO3 + O <-> SO2 + O2 */
  kf = ARRH(Pollut, K_F);
  kr = ARRH(Pollut, K_R);

  o_eq  = ARRH(Pollut, K_O)*sqrt(MOLECON(Pollut, O2));

  if (POLLUT_EQN(Pollut_Par) == EQ_SO2) {
    int ifstream;

    Ys_volatile = 1.e-04;
    fuels_so2_frac = 1.;

    for(ifstream=0; ifstream<Pollut_Par->nfstreams; ifstream++) {
      rf += Pollut->r_fuel_gls[ifstream]*SOx->Ys_fuelvolat[ifstream]
          *SOx->fuels_so2_frac[ifstream]*1000./Pollut_Par->sp[S].mw;
    }
    rf += kf*o_eq*MOLECON(Pollut, IDX(SO3));
    rr = -kr*MOLECON(Pollut, O2)*MOLECON(Pollut, IDX(SO2));
  }
  else if (POLLUT_EQN(Pollut_Par) == EQ_SO3) {
    rf = kr*MOLECON(Pollut, O2)*MOLECON(Pollut, IDX(SO2));
    rr = -kf*o_eq*MOLECON(Pollut, IDX(SO3));
  }

  POLLUT_FRATE(Pollut) += rf;
  POLLUT_RRATE(Pollut) += rr;
}



Example 2


The following compiled UDF, named sox_func_name, specifies a custom maximum limit ( $T_{\rm max}$) for the integration of the temperature PDF for each cell. Note that this UDF does not alter the internally-calculated SOx rate.

See Section  3.2.7 for details about the SOx macro ( POLLUT_CTMAX) used in this UDF.

/************************************************************
   UDF example of User-Defined Tmax value

   *
   * Arguments:
   *   char sox_func_name           - UDF name
   *   cell_t c                     - Cell index
   *   Thread *t                    - Pointer to cell thread
   *                                  on which the SOx rate
   *                                  is to be applied
   *   Pollut_Cell *Pollut          - Pointer to Pollut_Cell
   *                                  structure
   *   Pollut_Parameter *Pollut_Par - Pointer to Pollut_Parameter
   *                                  structure
   *   SOx_Parameter *SOx           - Pointer to SOx_Parameter
   *                                  structure

   ANSYS FLUENT Version: 12.0 or later
*************************************************************/

#include "udf.h"

int ud_sox_do_once=1;

enum
{
  CELL_TMAX=0,
  N_REQUIRED_UDM
};

/*Compute/assign Tmax at each cell*/
real ud_eval_cell_tmax(cell_t c,Thread *t)
{
  real tmax = 0.;

  /* Compute cell-based Tmax value */
  tmax = 1.1*C_T(c,t); /* This is only an example */

  return tmax;
}

DEFINE_SOX_RATE(user_sox, c, t, Pollut, Pollut_Par, SOx)
{
  /* Assign cell-based Tmax value */
  POLLUT_CTMAX(Pollut_Par) = ud_eval_cell_tmax(c,t);
  /*POLLUT_CTMAX(Pollut_Par) = C_UDMI(c,t,CELL_TMAX);*/
}

DEFINE_ON_DEMAND(init_tmax)
{
  Domain *domain;
  register Thread *t;
  register cell_t c;

  Message("Computing/Storing cell Tmax values\n");
  domain = Get_Domain(1);

  /* Store User-Defined Tmax at each cell */
  if(ud_sox_do_once == 1) {
    if(n_udm < N_REQUIRED_UDM)
      Error("Not enough udm allocated\n");

    thread_loop_c (t,domain)
      begin_c_loop (c,t)
        C_UDMI(c,t,CELL_TMAX) = ud_eval_cell_tmax(c,t);
      end_c_loop (c,t)
    ud_sox_do_once = 0;
  }
  Message("Computing cell Tmax values completed..\n");
}



Hooking a SOx Rate UDF to ANSYS FLUENT


After the UDF that you have defined using DEFINE_SOX_RATE is compiled (Chapter  5), the name of the argument that you supplied as the first DEFINE macro argument (e.g., user_sox) will become visible and selectable in the SOx Model dialog box in ANSYS FLUENT. See Section  6.2.20 for details.


next up previous contents index Previous: 2.3.19 DEFINE_SOURCE
Up: 2.3 Model-Specific DEFINE Macros
Next: 2.3.21 DEFINE_SPECIFIC_HEAT
Release 12.0 © ANSYS, Inc. 2009-01-14