You are on page 1of 39

2012

ANSYS FLUENT GUIDE


Advanced FLUENT User-Defined Functions
You can access and manipulate almost every solver data and fully control the
solution process in UDF-s written in C programming Language.

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir
http://www.ssadeghi.ir
| Confidential
4/23/2012

0BIntroduction

Table of Contents
1

Introduction .................................................................................................................................... 4

User Access to the FLUENT Solver................................................................................................... 4

C Programming ................................................................................................................................ 5

Cfd Programming in FLUENT ........................................................................................................... 7

UDF Basics ....................................................................................................................................... 7

Using UDFs in the Solvers ................................................................................................................ 8

Data structure overview.................................................................................................................. 8


7.1

The Domain ............................................................................................................................. 8

7.2

The Threads ............................................................................................................................. 9

7.3

Cell and Face Datatypes .......................................................................................................... 9

7.4

Some Additional info on Faces ................................................................................................ 9

Fluent UDF Data Structure Summary ............................................................................................ 10

Geometry Macros ......................................................................................................................... 11

10

Cell Field Variable Macros ......................................................................................................... 12

11

Face Field Variable Macros ....................................................................................................... 13

12

Looping and Thread Macros...................................................................................................... 14

13

Macros ....................................................................................................................................... 15

13.1

DEFINE Macros ...................................................................................................................... 15

13.2

Othe UDF Applications .......................................................................................................... 16

14

User Defined Memories ............................................................................................................ 17

15

User Defined Scalars.................................................................................................................. 18

16

Interpreted vs. Compiled UDFs ................................................................................................ 19

17

UDF Technical Support .............................................................................................................. 19

18

Example: Parabolic Inlet Velocity Profile .................................................................................. 20

18.1

Step 1: Prepare the Source Code .......................................................................................... 20

18.2

Step 3: Interpret or Compile the UDF ................................................................................... 20

18.3

Step 4: Activate the UDF ....................................................................................................... 21

18.4

Steps 5 and 6: Run the Calculations ...................................................................................... 21

18.5

Numerical Solution of the Example ....................................................................................... 21

19

Example: Checking Effect of Porous Zone on Momentum Equation ........................................ 22

19.1

Using Fluent Built-in Porous Zone ......................................................................................... 22

19.2

Using Momentum Source Terms........................................................................................... 23

20

Example: Modeling Fuel Cell ..................................................................................................... 24


Saeed Sadeghi (saeed@me.iut.ac.ir)
http://www.ssadeghi.ir

0BIntroduction

20.1

Preparation............................................................................................................................ 24

20.2

Mesh ...................................................................................................................................... 24

20.3

General Settings .................................................................................................................... 24

20.4

Models ................................................................................................................................... 25

20.5

Materials ............................................................................................................................... 25

20.6

Boundary Conditions ............................................................................................................. 26

20.6.1

Setting Velocity Inlet ..................................................................................................... 29

20.6.2

Pressure Outlet.............................................................................................................. 29

20.7

Writing UDF ........................................................................................................................... 30

20.7.1
20.8
21

Compiling the UDF......................................................................................................... 32

Checking Oxygen Mass Balance ............................................................................................ 37


Fluent Frequently Asked Questions .......................................................................................... 39

21.1

My UDF won't interpret or compile - what is wrong? .......................................................... 39

21.2

How to Set Environment Variables ....................................................................................... 39

21.2.1

On Windows 32 Bit ........................................................................................................ 39

21.2.2

On Windows 64 Bit ........................................................................................................ 39

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

0BIntroduction

1 Introduction
What is a User Defined Function?
o A UDF is a routine (programmed by the user) written in C which can be dynamically linked with
the solver.
Standard C functions
e.g., trigonometric, exponential, control blocks, do-loops, file i/o, etc.
Pre-Defined Macros
Allows access to field variable, material property, and cell geometry data.
Why build UDFs?
o Standard interface cannot be programmed to anticipate all needs.
Customization of boundary conditions, source terms, reaction rates, material properties,
etc.
Adjust functions (once per iteration)
Execute on Demand functions
Solution Initialization

2 User Access to the FLUENT Solver

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

2BC Programming

3 C Programming

Basic syntax rules:


o Each statement must be terminated with a semicolon ;
o Comments can be inserted anywhere between /* and */
o Variables must be explicitly declared (unlike in FORTRAN)
o Compound statements must be enclosed by { }
o Functions have the following format:
return-value-type function-name (parameter-list)
{ function body }

o Macros are defined in the header files, they can be used just like functions
Built-in data types: int, float, double, enum, Boolean:
int niter, a;

/* declaring niter and a as integers */

float dx[10];

/* dx is a real array with 10 members, the array index always starts from
dx[0] */

enum { X, Y, Z }; /* X, Y, Z are enumeration constants 0, 1, 2 */

pointer is a special kind of variable that contains the memory address, not content, of
another variable
Pointers are declared using the * notation:

int *ip;

/* ip is declared as a pointer to integer */

We can make a pointer point to the address of predefined variable as follows:


int a=1;
int *ip;
ip = &a; /* &a returns the address of variable a */
printf(content of address pointed to by ip = %d\n, *ip);
Pointers are also used to point to the beginning of an array
o Thus pointers are used to address arrays in C
Array variables can be defined using the notation name[size], where name is the variable
name and size is an integer which defines the number of elements in the array (from 0 to
size-1)
Operators
=

(assignment)

+, -, *, /, % (modulus)
<, >, >=, <=, ==, !=
++ increment; i++ is pors-increment; use the current value of I in the expression, then
increment I by 1 (i=i+)
-- decrement: jpost-decrement, use the current value of j, then decrement j by 1 (j=j-1)
+= addition assignment:
Saeed Sadeghi (saeed@me.iut.ac.ir)
http://www.ssadeghi.ir

2BC Programming
agg += single;

/* it means agg = agg + single; */

*= multiplication assignment, -= subtraction assignment, /= division assignment

Basic control structures


if ( )
<statement>;
if ( )
<statement>;
else
<statement>;
if ( )
<statement>;
else if ( )
<statement>;
For Loops:
for ( k=0; k<NUM; k++ )
<statement>;
While loops:
While ( )
<statement>;
Conditional operator ( ? : )
( condition ? operand a : operand b )
example:

false
real At = (rp_axi ? At*2*M_PI : At );
true

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

Cfd Programming in FLUENT

4 Cfd Programming in FLUENT

We (as CFD programmers in FLUENT) want to know how FLUENT organizes data so that we
know:
o How to access mesh information for a particular cell zone or a face zone
Cell centroids, cell volumes, the neighbors, etc.
Face centroids, face areas, face normal directions (vectors), etc.
o How to access field data for cells (and faces): pressure, velocity, density, etc.
o How to efficiently loop through these cells or faces in the codes
How to sypply customized source terms, boundary conditions, and fluid properties, etc., to
the solver
How to modify the behaviors or specific model parameters for various physical models as in
turbulence, reactions kinetics, multiphase, and dynamic mesh, etc.
How to implement users own governing equations in the finite-volume framework of
FLUENT solver

5 UDF Basics
UDFs assigns values (e.g., boundary data, source terms)
to individual cells and cell faces in fluid and boundary
zones.
o In a UDF, zones are referred to as threads.
o A looping macro is used to access individual cells
belonging to a thread.
e.g., a face-loop macro visits 563 faces on face zone
3 (velocity-inlet).
Position of each face is available to
calculate and assign spatially
varying properties.
Thread and variable references are
automatically passed to UDF when
assigned to boundary in GUI.
Values returned to the solver by UDFs must
be in SI units.

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

4BUsing UDFs in the Solvers

6 Using UDFs in the Solvers


The basic steps for using UDFs in FLUENT are as follows:
STEP 1: Create a file containing the UDF source code
STEP 2: Start the solver and read in your case/data files
STEP 3: Interpret or Compile the UDF
STEP 4: Assign the UDF to the appropriate variable and zone in BC panel.
STEP 5: Set the UDF update frequency in the Iterate panel.
STEP 6: Run the calculation

7 Data structure overview

7.1 The Domain

Domain is the set of connectivity and hierarchy info for the entire data structure in a given
problem for single phase flows. It includes:
o All fluid zones (fluid threads)
o All solid zones (solid threads)
o All boundary zones (boundary threads)
Cell: cell is the computational unit, conservation equations are solved over each cell
Face: direction in the outward normal
Threads: represent the collection of cells or faces; a Thread represents a fluid or solid or
boundary zone
Multiphase simulations (singlephase simulations use single domain only)
o Each phase has its own Domain-structure
o Geometric and common property information are shared among sub-domains
Saeed Sadeghi (saeed@me.iut.ac.ir)
http://www.ssadeghi.ir

5BData structure overview

Multiphase UDF will be discussed later

7.2 The Threads

A Thread is a sub-set of the Domain structure


Individual fluid, solid and each boundary zones are identified as zones and their
datatype is Thread
zone and Thread terms are often used interchangeably
Some further details about Zone/Thread ID and Thread-datatype:
o Zones are identified at mesh level with an integer ID in the Define/Boundary
Condition panel
o Threads, a Fluent-specific datatype, store structured information about the mesh,
connectivity, models, property, etc. all in one place
o Users identify zones through the IDs
o Zone/Thread-ID and Threads are correlated through UDF macros

7.3 Cell and Face Datatypes

Control volumes of fluid and solid zones are also called cells in FLUENT
o The data structure for the cell zones is typed as cell_t (the cell thread index)
o The data structure for the cell faces is typed as face_t (the face thread index)
A fluid or solid zone is called a cell zone, which can be accessed by using cell threads
Boundary or internal faces can be accessed by using face threads

7.4 Some Additional info on Faces


Each Control volume has a finite number of faces
o Faces on the boundary are also typed face_t; their ensemble are listed as boundary facethreads with the
o fluid & solid cell-threads under Defineo Boundary_Condition panel
o Those faces which are inside the flow-domain and do not
o share any external boundary are not accessible from GUI
o (because you do not need them)
o They can still be accessed from User-Defined-Functions

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

6BFluent UDF Data Structure Summary

10

8 Fluent UDF Data Structure Summary

The data structure for accessing a cell zone is typed as cell_t (the cell thread index); the
data structure for faces is typed as face_t' (the face thread index)

Type

Example

Declaration

Domain

*d

d is a pointer to domain thread

Thread

*t

t is a pointer to thread

Cell_t

*c

c is cell thread index

Face_t

f is a face thread index

Node

*node

node is pointer to a node

Each thread (zone) has a unique integer ID available in the


boundary condition panel (or can be listed by the list-zone
TUI command: /grid/modify-zones/list-zones)
Given a correct ID, the Lookup_Thread macro can retrieve
the thread pointer
Int ID = 7;
Thread *tf = Lookup_Thread (domain, ID);

Conversely, given a thread pointer tf, the zone ID can be


retrieved
ID = THREAD_ID(tf);

Once we have the correct pointer (for a specific zone), we can access the members belonging
to the zone without any problem. Thread pointer provides the leading address of the thread
(zone)

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

7BGeometry Macros

9 Geometry Macros

C_NNODES(c, t)
C_NFACES(c, t)
F_NNODES(f, t)
C_CENTROID(x, c, t)
F_CENTROID(x, f, t)
centroid
F_AREA(A, f, t)
NV_MAG(A)
C_VOLUME(c, t)
C_VOLUME_2D(c, t)

Number of nodes in a cell


No. of faces in a cell
No. of nodes in face
x, y, z - coords of cell centroid
x, y, z coords of face
Area vector of a face
Area-magnitude
Volume of a cell
Volume of a 2D cell

(Depth is 1m in 2D; 2* m in axi-symmetric solver)

NODE_X(nn)
Node x-coord; (nn is a node pointer)
NODE_Y(nn)
Node y-coord;
NODE_Z(nn)
Node z-coord;
real flow_time();
returns actual time
int time_step;
returns time step number
RP_GET_Real(physical-time-step);
returns time step size

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

11

8BCell Field Variable Macros

10 Cell Field Variable Macros


C_R(c, t);
C_P(c,t);
C_U(c,t);
C_V(c,t);
C_W(c,t);
C_T(c,t);
C_H(c,t);
C_K(c,t);
C_D(c,t);
C_YI(c,t,i);
C_UDSI(c,t,i);
C_UDMI(c,t,i);

density
pressure
u-velocity
v-velocity
w-velocity
temperature
enthalpy
turbulent KE
tke dissipation
species mass fraction
UDS scalars
UDM scalars

C_DUDX(c,t);
C_DUDY(c,t);
C_DYDZ(c,t);
C_DVDX(c,t);
C_DVDY(c,t);
C_DVDZ(c,t);
C_DWDX(c,t);
C_DWDY(c,t);
C_DWDZ(c,t);

velocity derivative
velocity derivative
velocity derivative
velocity derivative
velocity derivative
velocity derivative
velocity derivative
velocity derivative
velocity derivative

C_MU_L(c,t);
C_MU_T(c,t);
C_MU_EFF(c,t);
C_K_L(c,t);
C_K_T(c,t);
C_K_EFF(c,t);
C_CP(C c,t);
C_RGAS(c,t);
C_DIFF_L(c,t);
C_DIFF_EFF(c,t);

laminar viscosity
turbulent viscosity
effective viscosity
laminar thermal conductivity
turbulent thermal conductivity
effective thermal conductivity
specific heat
gas constant
laminar species diffusivity
effective species diffusivity

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

12

9BFace Field Variable Macros

11 Face Field Variable Macros


Face field variables are only available when using the segregated solver and generally, only at
exterior boundaries.
F_R(f, t);
F_P(f, t);
F_U(f, t);
F_V(f, t);
F_W(f, t);
F_T(f, t);
F_H(f, t);
F_K(f, t);
F_D(f, t);
F_YI(f, t);
F_UDSI(f, t);
F_UMI(f, t);
F_FLUX(f, t);

density
pressure
u-velocity
v-velocity
w-velocity
temperature
enthalpy
turbulent KE
tke dissipation
species mass fraction
UDS scalars
UDM scalars
Mass flux across face f, defined out of domain at boundaries.

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

13

10BLooping and Thread Macros

12 Looping and Thread Macros


cell_t c;

defines a cell

face_t f;

defines a face

Thread *t;

pointer to a thread

Domain *d;

pointer to collection of all threads

thread_loop_c(t, d)
{
..........
}
thread_loop_f(t, d)
{
.
}
begin_c_loop(c, t)
{
.
}
end_c_loop
befing_f_loop(c, t)
{
.
}
C_face_loop(f, t, n)
{
.
}

Specialized variable types


used for referencing

loop that steps through all cell threads in domain

loop that steps through all face threads in domain

Loop that steps through all cells in a thread

Loop that steps through all faces in a thread

Loop that visits all faces of cell c in thread t

Thread *tf = Lookup_Thread(domain, ID);

return thread pointer of integer ID of zone

THREAD_ID(tf);

returns zone integer ID of thread pointer

Code enclosed in { } is executed in loop.

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

14

11BMacros

13 Macros
Macros are pre-defined (Fluent) functions:
o Allows definition of UDF functionality and function name (DEFINE_ macro)
o Allow access to field variables, cell information, looping capabilities, etc.
Macros are defined in header files.
o The udf.h header file must be included in your source code.
#include udf.h
o The header files must be accessible in your path.
Typically stored in Fluent.Inc/src/directory.
o Other .h header files may need to be included.
Depends upon relevant variables and macros needed in your UDF, e.g.,
dpm.h for DPM variable access
A list of often used macros is provided in the UDF Users Guide.

13.1 DEFINE Macros


Any UDF you write must begin with a DEFINE_ macro:
o 18 general purpose macros and 13 DPM-related macros (not listed);
DEFINE_ADJUST(name,domain);

general purpose UDF called every iteration

DEFINE_INIT(name,domain);

UDF used to initialize field variables

DEFINE_ON_DEMAND(name);

defines an execute-on-demand function

DEFINE_RW_FILE(name,face,thread,index);

customize reads/writes to case/data files

DEFINE PROFILE(name,thread,index);

defines boundary profiles

DEFINE_SOURCE(name,cell,thread,ds,index);

defines source terms

DEFINE_HEAT_FLUX(name,face,thread,c0,t0,cid,cir);

defines heat flux

DEFINE_PROPERTY(name,cell,thread);

defines material properties

DEFINE_DIFFUSIVITY(name,cell,thread,index);

defines UDF and species diffusivities

DEFINE_UDS_FLUX(name,face,thread,index);

defines UDS flux terms

DEFINE_UDS_UNSTEADY(name,face,thread,index);

defines UDS transient terms

DEFINE_SR_RATE(name,face,thread,r,mw,yi,rr);

defines surface reaction rates

DEFINE_VR_RATE(name,cell,thread,r,mw,yi,rr,rr_t);

defines vol. reaction rates

DEFINE_SCAT_PHASE_FUNC(name,cell,face);
DEFINE_DELTAT(name, domain);

defines scattering phase function for DOM

defines variable time step size for unsteady problems

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

15

11BMacros
DEFINE_TURBULENT_VISCOSIT(name, cell, thread);

defines procedure for calculating turbulent


viscosity

DEFINE_TURB_PREMIX_SOURCE(name, cell, thread, turbflamespeed, source);


flame speed
DEFINE_NOX_RATE(name, cell, thread, nox);

16

defines turbulent

defines NOx production and destruction rates

13.2 Othe UDF Applications


In addition to defining boundary values, source terms and material properties, UDFs can be used
for:
o Initialization
Executes once per initialization
o Adjust
Executes every iteration
o Wall Heat Flux
Defines fluid-side diffusive and radiative wall heat
fluxes in terms of heat transfer coefficients
Applies to all walls
o User Defined Surface and Volumetric Reactions
o Read-Write to/from case and data files
Read order and Write order must be same.
o Execute-on-Demand capability
Not accessible during solve

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

/12BUser Defined Memories

14 User Defined Memories


User-allocated memory
o Up to 500 field variables can be defined.
o Can be accessed by UDFs:
C_UDMI(cell, thread, index);
F_UDMI(face, thread, index);
o Can be accessed for post-processing.
o Information is stored in data file.

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

17

13BUser Defined Scalars

18

15 User Defined Scalars


FLUNET can solve (up to 50) generic transport equations
for User Defined Scalars:

+
t
x i

k
k 1,..., N scalars
=
Fi k
S=
k
k
x i

User Specifies:
Define Models User-Defined Scalars
o Number of User-Defined Scalars
o Flux Function F
DEFINE_UDS_FLUX(name, face, thread, index)
DEFINE_UDS_UNSTEADY(name, cell, thread, index)
case statement can be used to associate multiple flux and transient functions with each
UDS.
o Example
Can be used to determine magnetic and/or electric field in a fluid zone.
User must also specify:
o Source terms
o Diffusivity,
case statement needed to
define UDF diffusivities for
each UDS.
o Boundary Conditions for each
UDS.
Specified Flux or Specified
Value.
Define as constant or with UDF.

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

14BInterpreted vs. Compiled UDFs

19

16 Interpreted vs. Compiled UDFs


Functions can either be read in and interpreted at run time or compiled and grouped into a shared
library that is linked with the standard FLUENT executable.
Interpreted vs. compiled code
o Interpreter
Interpreter is a large program that sits in the computers memory.
Executes code on a line by line basis instantaneously
Advantages does not need a separate compiler
Disadvantage slow and takes up space in memory
o Compiler (refer to Users Guide for instructions)
Code is translated once into machine language (object modules).
Efficient way to run UDFs. Uses Makefiles
Creates shared libraries which are linked with the rest of the solver
Overcomes interpreter limitations e.g. mixed mode arithmetic, structure references etc.

17 UDF Technical Support


Because UDFs can be very complicated, Fluent Inc. does not assume responsibility for the
accuracy or stability of solutions obtained using UDFs that are user-generated.
o Support will be limited to guidance related to communication between a UDF and the FLUENT
solver.
o Other aspects of the UDF development process that include conceptual function design,
implementation (writing C code), compilation and debugging of C source code, execution of
the UDF, and function design verification will remain the responsibility of the UDF author.
A consulting option is available for complex projects.

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

16BExample: Parabolic Inlet Velocity Profile

20

18 Example: Parabolic Inlet Velocity Profile

We would like to impose a parabolic inlet velocity to the 2D elbow shown.


The x velocity is to be specified as

y 2
u=
( y ) 20 1

0.0745

y =0

18.1 Step 1: Prepare the Source Code

The DEFINE_PROFILE macro allows the function inlet_x_velocity to be defined.


o All UDFs begin with a DEFINE_ macro.
o inlet_x_velocity will be identifiable in solver GUI.
o thread and nv are arguments of the DEFINE_PROFILE macro, which are used to
identify the zone and variable being defined, respectively.
o The macro begin_f_loop loops over all faces f, pointed by thread.
The F_CENTROID macro assigns cell position vector to x[].
The F_PROFILE macro applies the velocity component to face f.

18.2 Step 3: Interpret or Compile the UDF


Define User-Defined Functions
Interpreted

Add the UDF source code to the Source


File Name list.
Click Interpret.
The assembly language code will
display in the FLUENT console.

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

Define User-Defined Functions


Compiled

Add the UDF source code to the Source


files list.
Click Build to create UDF library.
Click Load to load the library.
You can also unload a library if needed.
Define User-Defined Functions
Manage

16BExample: Parabolic Inlet Velocity Profile

18.3 Step 4: Activate the UDF

Open the boundary condition panel for the


surface to which you would like to apply the
UDF.
Switch from Constant to the UDF function in
the X_Velocity drop-down list.

18.4 Steps 5 and 6: Run the Calculations

You can change the UDF Profile Update Interval in the Iterate
panel (default value is 1).
o This setting controls how often (either iterations or
time steps if unsteady) the UDF profile is updated.
Run the calculation as usual.

18.5 Numerical Solution of the Example

The figure at the right shows the velocity


field through the 2D elbow.
The bottom figure shows the velocity
vectors at the inlet. Notice the imposed
parabolic profile.

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

21

17BExample: Checking Effect of Porous Zone on Momentum Equation

22

19 Example: Checking Effect of Porous Zone on Momentum Equation


Many industrial applications such as filters, catalyst beds and packing, involve modeling the flow
through porous media. This tutorial illustrates how to set up and solve a problem involving gas flow
through porous media.
The problem solved here involves gas flow through a channel using FLUENT in two different ways to
validate it. In the first one we use porous zone parameters and in the second one we write a UDF
includes momentum source terms for porous zone pressure drop.

19.1 Using Fluent Built-in Porous Zone


File Read Case
Read a mesh file
Define Boundary Conditions
Select fluid zone then Click Set to enter the fluid zone parameters.
Check the Porous Zone to enable porous zone
On Porous zone, set the Viscous Resistance equal to 5.68e6 (1/m2) in both directions.
Change the Fluid Porosity from 1 to 0.4 at the end of this Porous Zone Tab.
For inlet condition, set the Velocity inlet equal to 1 (m/s) on the inlet velocity magnitude
normal to boundary.
To solve the case, go to: Solve Iterate
Number of Iterations = 1000
After convergence we can display results as follows.

Figure 19-1: Static pressure in the channel (Pascal).

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

17BExample: Checking Effect of Porous Zone on Momentum Equation

19.2 Using Momentum Source Terms

#include "udf.h"
#define por_gdl
0.4
#define i_permeability 5.68e6
// Inverse Permeability (1/m^2)
#define urf
0.1
// under relaxation factor for stability of momentum source term
real s1=0., s2=0.;
DEFINE_SOURCE(xmom_src,c,t,dS,eqn)
{
real source, mu, u;
mu = C_MU_L(c,t);
u = C_U(c,t);
source = -(mu*u*i_permeability);
dS[eqn] = -(mu*i_permeability);
s1 = s1*(1-urf) + source*urf;
return s1;
}
DEFINE_SOURCE(ymom_src,c,t,dS,eqn)
{
real source, mu, v;
mu = C_MU_L(c,t);
v = C_V(c,t);
source = -(mu*v*i_permeability);
dS[eqn] = -(mu*i_permeability);
s2 = s2*(1-urf) + source*urf;
return s2;
}

Figure 19-2: Static pressure in the channel (Pascal).

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

23

18BExample: Modeling Fuel Cell

24

20 Example: Modeling Fuel Cell


20.1 Preparation
Use FLUENT Launcher to start 2D version of ANSYS FLUENT.
Note: The Display Options are enabled by default. Therefore, once you read in the mesh, it will be
displayed in the embedded graphics windows.

20.2 Mesh
1. Read the mesh file
File Read Mesh
2. Check the mesh
General Check
ANSYS FLUENT will perform various checks on the mesh and report the progress in the ANSYS
FLUENT console window. Ensure that the minimum volume reported is a positive number.
3. Scale the mesh
General Scale

(a) Select mm (millimeter) from the Mesh Was Created In drop-down list in the Scaling group
box.
(b) Click Scale to scale the mesh.
(c) Close the Scale Mesh dialog box.
4. Check the mesh.
General Check
Note: It is a good idea to check the mesh after you manipulate it (i.e., scale, convert to polyhedral,
merge, separate, fuse, add zones, or smooth and swap). This will ensure that the quality of the mesh
has not been compromised.

20.3 General Settings


Define Models Solver
1. Retain the default settings for the solver.
Saeed Sadeghi (saeed@me.iut.ac.ir)
http://www.ssadeghi.ir

18BExample: Modeling Fuel Cell

20.4 Models
Define Models Species Transport & Reaction

(a) Enable Species Transport


(b) Click OK to Close the Species Model box.

(c) FLUENT will notify that Available material properties or method have changed. Please
confirm the property values before continuing. Click OK to close the dialog box.

20.5 Materials
Define Materials
1. Revise the properties for the mixture materials.
Define Material Mixture

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

25

18BExample: Modeling Fuel Cell

26

(a) Click the Edit button to the right of the Mixture Species drop-down list to open Species
dialog box.

You can add or remove species from the mixture material as necessary using the Species dialog box.
i.
ii.

Retain the default selections from the Selected Species selection list.
Click OK to close the Species dialog box.

(b) Click Change/Create to accept the material property settings.


(c) Close the Create/Edit Materials dialog box.

20.6 Boundary Conditions


Define Operating Conditions
Because the effect of gravity can be neglected, Retain setting in Operating Conditions and Click OK to
Close the dialog box.

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

18BExample: Modeling Fuel Cell

Define Boundary Conditions

(a) Set Boundary condition for gdl fluid zone, by clicking on the Set button

(b) Check Porous zone radio button to enable porous zone.


(c) Set value for Viscous Resistance in both directions. These parameters are inverse of
permeability (1/m^2).
Fluent uses these values for calculating momentum source term due to the porous
zone.

(d) Set the porosity of the porous zone.


(e) Click Ok to save data.
Saeed Sadeghi (saeed@me.iut.ac.ir)
http://www.ssadeghi.ir

27

18BExample: Modeling Fuel Cell

(f) Set Boundary condition for cl fluid zone, by clicking on the Set button

(g) Check the porous zone button to enable the cl porous zone.
(h) Set viscous resistance variables for both directions.

(i) Now you should set porosity for cl porous zone that is equal to 0.1, here.

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

28

18BExample: Modeling Fuel Cell

29

20.6.1 Setting Velocity Inlet


(a) By selecting inlet at Boundary Condition dialog box and Clicking on set button, you will see
the Velocity inlet dialog box, which can be used to specify inlet conditions such as inlet
velocity, temperature, species mass fraction, etc.
(b) Set Velocity magnitude equal to 0.03 (m/s), that is entering the domain normal to the
boundary face.

(c) Click the Species Tab to set mass fraction of species. Fluent will automatically calculate the
mass fraction of the last specie, that is equal to 1 minus sum of the mass fraction of the other
species.

20.6.2 Pressure Outlet


(a) Click on the outlet to set outlet conditions.
Saeed Sadeghi (saeed@me.iut.ac.ir)
http://www.ssadeghi.ir

18BExample: Modeling Fuel Cell

30

(b) Select pressure outlet on the right side of the boundary conditions dialog box, to specify
pressure at the outlet of the fuel cell.
(c) Click set button to enter Pressure Outlet dialog box.
(d) To prevent solution damage by reverse flows, we should specify outlet conditions near to
real condition.
(e) For this, we have chosen inlet species mass fraction for the outlet condition.
(f) Leave the other parameters by default and click OK.

20.7 Writing UDF


#include "udf.h"
#define por_cl 0.1
#define por_gdl 0.4
#define i_permeability 5.68e6 //5.681e10
// (1/m^2)
#define R
UNIVERSAL_GAS_CONSTANT // 8.3143 kJ/kmol.K this is known within Fluent
#define zita_cat
2.e3
#define V_oc
1.207
#define j_ref_cat
20.
#define alpha_cat
2.
#define lambda_cat
1.
#define phi_sol
0.
#define phi_mem
0.
#define C_ref_o2
1.
#define F
9.65e4
// C/kmol
#define h_cl
0.02e-3
// Cathalyst layer thickness [m]
#define L
71.12e-3
// Channel Length [m]
#define diff_o2
#define diff_h2o
#define diff_n2

3.2348e-5
3.89e-5
2.88e-5

/* mass diffusivity of oxygen */


/* mass diffusivity of water */
/* mass diffusivity of nitrogen */

#define i_h2o 0
#define i_o2 1
#define i_n2 2
#define mw_h2o
#define mw_o2

18.
32.

// kg/kmol
// kg/kmol

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

18BExample: Modeling Fuel Cell


#define mw_n2

28.

// kg/kmol

enum{ current };
real R_cat(cell_t c, Thread *t)
{
// this routine returns Reraction_Rate_cat as "R_cat"
real eta_cat, C_o2, T, xyz[ND_ND], x ,y, z, Reraction_Rate_cat, i, i0_over_C_ref;
C_o2 = C_YI(c,t,i_o2);
T = C_T(c,t);
//eta_cat = phi_sol-phi_mem-V_oc;
i=C_UDMI(c,t,current);
i0_over_C_ref=0.8*1e4; //[A/m^2] Ref. Khakbaz-Kermani
eta_cat = R*T / (alpha_cat*F) * log(i/C_o2/i0_over_C_ref);
//Butler-Volmer Ref.
Khakbaz-Kermani
C_CENTROID(xyz,c,t);
x=xyz[0];
y=xyz[1];
//z=xyz[2];
// Option 0
// Reraction_Rate_cat = 10000.0;
// Option 1
Reraction_Rate_cat = 100000. *(1.0 - x/L);
// Option 2
from Fluent FC manual
// Reraction_Rate_cat = (zita_cat*j_ref_cat)*pow(C_o2/C_ref_o2,lambda_cat)*(exp(alpha_cat*F*eta_cat/(R*T)));
// Option 3
// Reraction_Rate_cat = (zita_cat*j_ref_cat)*pow(C_o2/C_ref_o2,lambda_cat)*(exp(alpha_cat*F*eta_cat/(R*T)));
return Reraction_Rate_cat;
}
DEFINE_SOURCE(O2_src,c,t,dS,eqn)
{
real source;
source = -mw_o2*R_cat(c,t)/(4.*F) *por_cl;// (kg/kmol)()/(C/kmol)
//Message("%f, %f, %f, %f, %f\n",mw_o2,R_cat(c,t),por_cl, source, F);
C_UDMI(c,t,current)= -4.*F /mw_o2 *source *h_cl; // this is local current density
dS[eqn] = 0.0;
return source;
}
DEFINE_SOURCE(H2O_src,c,t,dS,eqn)
{
real source;
source = +mw_h2o*R_cat(c,t)/(2.*F) *por_cl;
Saeed Sadeghi (saeed@me.iut.ac.ir)
http://www.ssadeghi.ir

31

18BExample: Modeling Fuel Cell


dS[eqn] = 0.0;
return source;
}
DEFINE_SOURCE(MASS_src,c,t,dS,eqn)
{
real source;
source = ( -mw_o2/(4.*F) + mw_h2o/(2.*F) )*R_cat(c,t) *por_cl;
dS[eqn] = 0.0;
return source;
}
DEFINE_DIFFUSIVITY(mix_diff, c, t, i)
{
real diff;
switch (i)
{
case 0:
diff = diff_h2o*por_cl*sqrt(por_cl);
break;
case 1:
diff = diff_o2*por_cl*sqrt(por_cl);
break;
case 2:
diff = diff_n2*por_cl*sqrt(por_cl);
break;
default:
diff = 0.0;
}
return diff;
}
20.7.1 Compiling the UDF
Define User-Defined Functions Compiled

Add the UDF source files and headers if needed.

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

32

18BExample: Modeling Fuel Cell

33

Build the UDF and then click on Load to load the Library that is named libudf.
Note that the UDF source files should be in the directory that contains your case and data
files. Click OK to build the library.

Now the fluent creates library libudf.lib, object libudf.exp and other required files.
You can load the library if fluent reveal no error and the message Done have seen at the
end of the commend window.

By loading the library, fluent command window show all defined functions. Here it shows
O2_src, H2O_src, MASS_src, .
Saeed Sadeghi (saeed@me.iut.ac.ir)
http://www.ssadeghi.ir

18BExample: Modeling Fuel Cell

34

If you have build and load a udf before, be sure to unload it in the Manage dialog box. Else
an error will appear that an libudf is in use.

Now you should hook functions to its specified equation.


On the cl fluid zone, check Source Terms.

On the Source Terms Tab, click Edit in front of Mass equation.


Then add a source and select MASS_src and click ok to add the source term on solution.
Repeat this procedure for the other equations, such as H2O, O2, .

We have used a UDM in the UDF, so we should specify a UDM for it.
Go to: Define User-Defined Memory then set the number of UDM-s.
Saeed Sadeghi (saeed@me.iut.ac.ir)
http://www.ssadeghi.ir

18BExample: Modeling Fuel Cell

35

Fluent enables the energy equation by enabling Species Transport equation. In this example,
we dont need the energy equation. To prevent solving this equation go to Solve Solution
Controls and click on Energy in Equations box.

To have a good initial guess for better and time saving convergence, we can specify the
conditions of inlet to the all domain.
So, Solve Initialize Solution Initialize, Compute from inlet and click on Init to specify its
condition to all domains.

You can change Residual criteria and Residual window settings. Solve Monitors
Residual.
To prevent printing on command window, uncheck print. And to show residual on the
residual window, check the plot box.

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

18BExample: Modeling Fuel Cell

On iterate window, Solve Iterate, specify the number iterations and start iteration by
clicking on iterate.

Figure 20-1: Scaled Residuals

Figure 20-2: Mass fraction of H2O on top and bottom walls

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

36

18BExample: Modeling Fuel Cell

37

20.8 Checking Oxygen Mass Balance


To check Oxygen mass balance, we should calculate the rate of oxygen mass enters the domain at
the inlet (kg/s), the rate of oxygen mass consumes at the catalyst layer (kg/s), and the rate of oxygen
mass exits the domain from outlet.
So, we should add a macro to the end of previous UDF as follows:
DEFINE_ON_DEMAND(data)
{
real A[ND_ND];
real sum;
int inlet_ID = 7;
int outlet_ID = 6;
int cl_ID = 2;
Domain *d = Get_Domain(1);
Thread *t_inlet = Lookup_Thread (d,inlet_ID);
Thread *t_outlet = Lookup_Thread (d,outlet_ID);
Thread *t_cl = Lookup_Thread (d,cl_ID);
face_t f;
cell_t c;
///////////////////////////
sum = 0.;
begin_f_loop(f,t_inlet)
{
F_AREA(A,f,t_inlet);
sum += F_FLUX(f,t_inlet) *F_YI(f,t_inlet,i_o2)*1.e6;
}
end_f_loop(f,t_inlet);
Message("inlet = %f *e-6(kg/s)\n", sum);
///////////////////////////
sum =0.;
begin_f_loop(f,t_outlet)
{
F_AREA(A,f,t_outlet);
sum += F_FLUX(f,t_outlet) *F_YI(f,t_outlet,i_o2)*1.e6;
}
end_f_loop(f,t_outlet);
Message("outlet= %f *e-6(kg/s)\n", sum);
///////////////////////////
sum =0.;
begin_c_loop(c,t_cl)
{
sum += -mw_o2*R_cat(c,t_cl)/(4.*F) *por_cl*C_VOLUME(c,t_cl)*1.e6;
}
end_c_loop(f,t_cl);
Message("porous= %f *e-6(kg/s)\n", sum);
}

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

18BExample: Modeling Fuel Cell

38

The macro DEFINE_ON_DEMAN executes when we want. For example at the beginning,
intermediate and at the end of solution, it can be executed.
The array A is defined in ND_ND dimension to reserve area.
ND_ND is a Fluent macro that is equal to 2 in 2-dimensioanl and 3 in 3-dimensional case.
sum is defined to summarize value of cells in a group cells (Threads)
inlet_ID, outlet_ID and cl_ID are the number of zone that can be found in Boundary
Conditions dialog box.

Get_Domain(1) specifies the domain to the 1 to d which is defined as Domain pointer


Lookup_Thread (d,ID) is defined to find the Thread which its ID number is equal to inlet_D,
outlet_ID and cl_ID.
With face_t and cell_t we can define variables that reserves face and cell data.
begin_f_loop(f,t_inlet), loops throw all faces of the Thread t_inlet that its ID is 7.
F_AREA(A,f,t_inlet), returns area of the face f of thread t_inlet.
F_FLUX(f,t_inlet), returns the mass flow rate the face f of the thread t_inlet.
F_YI(f,t_inlet,i_o2), returns mass fraction of the specie that its ID is i_o2 of the face f of the
thread t_inlet.
Message(\n,), is used to write mass flow rate of Oxygen on the fluent command
window. Result is written below:
inlet = -5.721122 *e-6(kg/s)
outlet= 5.153047 *e-6(kg/s)
porous= -0.589597 *e-6(kg/s)

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

19BFluent Frequently Asked Questions

39

21 Fluent Frequently Asked Questions


21.1 My UDF won't interpret or compile - what is wrong?
The answer depends upon what exactly has happened.

If Fluent complains about not being able to find a compiler, then check to make sure that the
compiler is properly installed. On Windows machines, it is possible to install the Visual C++
compiler without fully setting up the command line compiler (which Fluent needs to be able
to find). During the installation process, you need to select the "register environment
variables" option. Failure to do so will likely lead to complaints about things being "not
recognized as an internal or external command, operable program or batch file" or missing
DLL's. It is theoretically possible to fix this issue by setting the appropriate environment
variables, but keep in mind that even when nmake can be found there still may be DLL
issues. The easy path is probably reinstallation of Visual Studio (taking special care to make
sure that the command line interface is set up properly), but the reinstallation path is always
perilous. If you have long term experience using Windows you should probably know the
risks, and if you don't you should consult an expert.
If you are interpreting, keep in mind that not everything that is supported for compiled UDF's
is supported for interpreted UDF's. This is true both for the UDF interface and the C
language. If you are doing something pretty involved and it fails inexplicably, try compiling to
see if that makes a difference.
There is also the possibility of coding errors. Keep in mind that your source code gets run
through the C preprocessor (to change the Fluent macros into C code), so unintended
interactions are very possible.

21.2 How to Set Environment Variables


21.2.1 On Windows 32 Bit
If you are using Windows 32 bit, its better to install Visual Studio 2005 (Just install Visual
C++, deselect other components)
Then, Go to this address: C:\Program Files\Microsoft Visual Studio\VC98\bin\
Double click VCVARS32.BAT
Then go the FLUENT install address: C:\fluent.inc\ntbin\ntx86\
And double click setenv.exe
21.2.2 On Windows 64 Bit
If you are using Window 64 Bit, its better to install Visual Studio 2008 (Just install Visual
C++, deselect other components)
Then, Go to this address: C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\
Double click vcvars32.BAT
Go to the FLUENT install add: C:\Program Files\ANSYS Inc\v121\fluent\ntbin\win64\
And double click setenv.exe

Saeed Sadeghi (saeed@me.iut.ac.ir)


http://www.ssadeghi.ir

You might also like