Post on 10-Jul-2018
transcript
Making “User Defined Functions”Work for You
Anirudh Mukhopadhyay
2002 Fluent Users’ Group Meeting
2UGM 2002
Agenda
u General Introduction to User Defined Functions
u Introduction to C Programming
u Fluent Data Structure and Macro-s
u Interpreted / Compiled UDF
u UDF Hooks - ‘DEFINE’ macro-s
u User Defined Scalars and Memories
u UDF for Discrete Phase and Multiphase Flows
u UDF for Parallel FLUENT
u Miscellaneous Functions / Macros
3UGM 2002
Why Build UDFs?u Standard interface can not be programmed to anticipate all needsu Customization of boundary conditions, source terms, reaction rates (volume
and surface), propertiesu Solution initializationu Adjust functions (once per iteration)u Solve for user defined scalarsu Modify model specific parametersu Many more...u Limitations
l Not all solution variables or solver models can be accessed by UDFsl Example: Cannot change specific heat (would require additional solver
capabilities)
4UGM 2002
User Access to Fluent Solveru Fluent is so designed that the user can access the solver at some strategic
instances during the solution process
FlowDiagram
ofFLUENTSolvers
Segregated Solver Coupled Solver
Initialize Begin Loop
Exit Loop Repeat
CheckConvergence
Update Properties Solve EddyDissipation
Solve TurbulenceKinetic Energy
Solve Species
Solve Energy
Solve Mass Continuity;Update Velocity
Solve U-Momentum
Solve V-Momentum
Solve W-Momentum
Solve MassMomentum &
Energy
User-defined
ADJUST
Source termsSource terms
Source terms
Boxes inblueblue are
someimportant
useraccesspoints
UserDefinedInitialize
User-Defined PropertiesUser-Defined Boundary Conditions
5UGM 2002
User Defined Functions in Fluent
u UDF’s in FLUENT are available for:u Profiles (Boundary Conditions)
velocity, temperature,turbulence, species, scalars
u Source terms (Fluid and solid zones)mass, momentum, energy,species, turbulence, scalars
u Propertiesviscosity, conductivity, density,scattering_phase_function (exceptspecific heat)
u Initialization
zone and variable specific initializationu Global Functions
adjust, read, write, execute_on_demandu Scalar Functions
unsteady term, flux vector, diffusivityu Model Specific Functions
reaction rates, discrete phase model,turbulent viscosity
u User Defined Functions are not just any C-functions:u User access needs specific “Type” of function callsu These Function types or ‘macro’-s are defined in the header file:
~Fluent.Inc/fluentx.y/src/udf.h
6UGM 2002
A Brief Introduction to ‘C’
u This presentation will introduce only essential syntaxand aspects
u In general, Macro-s (hook-ups) are available foraccessing various locations in the code during theiterationsu C functionsu C data typesu Pointers and arraysu Expressions and statementsu C arithmetic and logical operatorsu Control flowu C preprocessor directives
7UGM 2002
The Basic Form of a C Function/*A simple C function*/ /* Comments are delineated by the character sequence */
/* comments can be placed anywhere in a C listing use comments liberally to document your UDFs */#include “udf.h” /* A preprocessor directive for including files */#define PI 3.14159 /* A preprocessor directive for macro substitution */
float a = 1.2345; /* Global scope: variables defined outside the function body for use by all functions which follow the definition */
int my-function(int x) /* Function declaration (integer type) */ { /* C functions are enclosed by curly braces ({...}) */
/* All C statements must end with a semicolon (;) */ int y,z; /* Local scope: Declare data type for variables y, z variables defined within the function body are local to the function */ y = 11; /* Set y = 11 */ z = a*(x+y)*PI; /* Compute z */
printf(“z = %d”,z); /* Print output to screen */ return z; /* Return integer value */
} /* Right curly brace closes body of function */
u If a function is defined with a specific type, it should return a value of the sametype (using the return statement)
8UGM 2002
Compilers
u C compilers include a library of standard math, I/O, and utility functionswhich can be used in your C code
u Common I/O functionsu scanf (...)- formatted read (like FORTRAN READ)u printf(...)- formatted print (like FORTRAN WRITE)
u Common math functionsu sin (x) - sine functionu cos (x) - cosine functionu exp (x) - exponential functionu sqrt(x) - square root function
u For the UDF compiler, all of the standard functions aredefined in the file udf.huu NOTE:NOTE: you do not need a copy ofyou do not need a copy of udf udf.h when you compile your UDF;.h when you compile your UDF;
the solver gets this from the Fluent.Inc/fluent6.x/the solver gets this from the Fluent.Inc/fluent6.x/srcsrc/ directory/ directory
9UGM 2002
Comparison with FORTRAN
u C functions are similar to FORTRAN function subroutines
/*A simple C function*/ C An equivalent FORTRAN function int myfunction(int x) INTEGER FUNCTION MYFUNCTION(X) { int y,z; INTEGER X,Y,Z y = 11; Y = 11 z = x+y; Z = X+Y printf(“z = %d”,z); WRITE (*,100) Z return z; MYFUNCTION = Z 100 FORMAT(“Z = “,I5) } END
u Arithmetic operators = assignment + addition - subtraction * multiplication / division % modulo++ increment-- decrement
u Logical operators< less than<= less than or equal to > greater than>= greater than or equal to== equal to!= not equal to
10UGM 2002
C Data Types
u The UDF interpreter supports standard C data typesu int,long - integer data types
u float,double, real - floating point (real) data types
u char - character data type
u Functions which do not return values are given the type void
void myfunction(int x) {...} /*No return needed*/
u C also allows you to create “user-defined” types using typedef
typedef struct list {int a;float b;int c;};
typedef struct list mylist; /* mylist is of type structure list*/
mylist x,y,z; /* x,y,z are “struct list” type */
11UGM 2002
Pointers and Arrays
u Pointers can also point to the beginning of an arrayu Thus pointers are strongly connected to arrays in C
u Arrays of variables can be defined using the notation name[size] wherename is the variable name and size is an integer which defines the numberof elements in the array
u Some examples int a[10]; float radii[5]; a[0] = 1; radii[4] = 3.14159265;
content of address pointed to by ip = 1
u A pointer is the variable that contains the address of another variableu Pointers are defined using the * notation
int *ip; /* a pointer to an integer variable */
u 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);
Notes about C arrays:Notes about C arrays:The index of C arrays start at 0The index of C arrays start at 0
12UGM 2002
/* C code */if (q != 1) {a = 0; b = 1;}if (x < 0.) y = x/50.;else y = x/25.;
Control Flow - “If” and “for” Statements
u ‘if’ and ‘if-else’ statements
if (logical-expression) {statements}if (logical-expression) {statements}else {statements}
u Example
u ‘for’ statement
for (begin;end;increment){statements}
where:
begin = expression, executed at start of loop
end = logical expression to test for loop termination
increment= expression which is executed at the end of each loop iteration (usually incrementing a counter)
/* C code:Print integers 1-10 and their squares */int i, j, n = 10;for (i = 1 ; i <= n ; i++){ j = i*i; printf(“%d %d\n”,i,j);}
u Example
13UGM 2002
The C Preprocessoru The UDF interpreter supports C preprocessor directivesu Macro substitutions using: #define name replacement
#define RAD 1.2345
u The preprocessor simply substitutes the characters of name with those ofreplacement
u File inclusion using the directive #include#include “udf.h”
u The files named in quotes must reside in your current directory (except for udf.hwhich is read automatically by the solver as noted earlier)
u Some topics not discussed hereu while and do-while control statements, structures and unions, recursion, reading
and writing files along with many details!
u For more information on C programming, consult:The C Programming Language, 2nd Ed.by Brian Kernighan and Dennis RitchiePrentice-Hall, 1988
Fluent Data Structure and Macros
Building blocks of the data
Access to variables at any point
Loop for zones
Loop for space points
Access various control locations in the code
15UGM 2002
Data structures in FLUENT
Domain
CellCell
Thread
face
cellcell
Boundary (face thread or zone) Fluid (cell thread or zone)
Domain
Cell
16UGM 2002
The Domainu “Domain” is the set of connectivity and hierarchy info for the entire data
structure in a given problem. It includes:Ø all fluid zones (‘fluid threads’)Ø all solid zones (‘solid threads’)Ø all boundary zones (‘boundary threads’)
u Cell/face - Computational unit, face is one side. Conservation equations are solved over a cell
u Thread - is the collection of cells or faces; defines afluid/solid/boundary zone
u Note:u FLUENT6 introduces the concept of multi-“domain” for multiphase simulations
(singlephase simulations uses single domain only)l Each phase has its own “Domain”-structurel Geometric & common property information will be duplicated among ‘domains’l Multiphase UDF will be discussed later
17UGM 2002
The Threadsu A ‘Thread’ is a sub-set of the ‘Domain’ structure
u Individual ‘fluid’, ‘solid’ and each ‘boundary’ zones are identified as‘zones’ and their datatype is maintained as ‘Thread’
u ‘Zone’ and ‘Thread’ terms are often used interchangeably
u But Zone/Thread ID and Thread-datatype are different:l Zones are identified at mesh level with an ‘integer’ ID in the Define-
Boundary_Condition panel
l Threads are Fluent-specific datatype that store structured information aboutthe mesh, connectivity, models, property, etc. all in one place
l Users identify zones through the ID-s
l Zone/Thread-ID and Threads are correlated through macro-s
18UGM 2002
Domain and Threads
Wall
PorousMedium
Fluid-1
Solid-1
Solid-2
Outlet
Wall
Fluid-2Inlet
DomainDomainofof
AnalysisAnalysis
CorrespondingCorrespondingData setData set
InletFluid-2
Fluid-1
Solid-1
OutletPorousMedium
Solid-2Wall
DomainDomain
ThreadsThreads
19UGM 2002
Cell and Face Datatypesu Control volumes (equivalent of ‘FEM:Elements’) of fluid and solid zones are
called ‘cell’ in FLUENTu The data structure for the control volumes is typed as ‘cell_t’
u The data structure for the control volume faces is typed as ‘face_t’
u A fluid or solid zone is comprised of cellsu The Thread that identifies the cells in a Fluid or Solid Thread, is a ‘Cell-
Thread’
u A boundary zone is comprised of faces of the adjacent control volumes orcellsu The Thread that identifies the faces on a boundary is a
‘Face-Thread’
20UGM 2002
Some additional info on Facesu Each Control volume will have a finite number of facesfinite number of faces (4 for tets, 6 for
hex and 5 for pyramids, and wedges)u Faces on the boundary are also typed ‘face_t’; their ensemble are listed as
boundary face-threads with the fluid & solid cell-threads underDefine-Boundary_Condition panel
u Those faces which are inside the flow-domain and do not share any externalboundary are not accessible from GUI (because you do not need them)
u They can still be accessed from User-Defined-Functions
21UGM 2002
Cell- & face-Threads, Cell_t & face_t Datatypes
TypeType ExampleExample DetailsDetailsDomain *d pointer to the collection of all threadsThread *t pointer to a threadCell_t c cell identifierface_t f face identifierNode *node pointer to a node
Boundary face-threadthe boundary-face ensembleFluid cell-thread
the Control-volumeensemble Internal face-thread
the Internal-face ensembleassociated to cell-threads
Nodes
22UGM 2002
Geometry Macro-s (1)u (c,t) A cell, c of a thread, t
u C_NNODES(c, t); No of nodes in a cell
u C_NFACES(c, t); No. of faces in a cell
u F_NNODES(f, t); No. of nodes in a face
u C_CENTROID(x, c, t); x, y, z-coords of cell centroid
u F_CENTROID(x, f, t); x, y, z-coords of face centroid
u F_AREA(A, f, t); Area vector of a face;
u NV_MAG(A); Area-magnitude
u C_VOLUME(c, t); Volume of a cell
u C_VOLUME_2D(c, t); Volume of a 2D cell
(Depth: 1m in 2D; 2*π m in 2D-axi)u NODE_X(nn); Node x-coord;
u NODE_Y(nn); Node x-coord;
u NODE_Z(nn); Node x-coord;
Location of cell variablesC_CENTROID(X,c,t); X: X[3]
C_NNODES(c,t) = 8C_NFACES(c,t) = 6F_NNODES(f,t) = 4 each
A Hex cellFaces
Nodes
23UGM 2002
Looping Macro-s for Geometry (2)
u thread_loop_c(t, d); Loop over cell threadsu thread_loop_f(t, d); Loop over face threads
u begin_c_loop(c, t); Loop over cells in a cell threadu end_c_loop(c, t);
u begin_f_loop Loop over faces in a face threadu end_f_loopu f_edge_loop(f, t,en); Loop over edges in a face thread
u f_node_loop(f, t,nn); Loop over nodes in a face thread
u c_node_loop(c, t,nn); Loop over nodes in a cell thread
u c_face_loop(c, t,fn); Loop over faces in a cell thread
24UGM 2002
Pointer to a Thread
int ID = 1;Thread *tf = Lookup_Thread(domain,ID);begin_f_loop(f, tf) { F_CENTROID(FC, f, tf); printf("x:%f y:%f",FC[0], FC[1]); }end_f_loop(f, tf)
u Given the integer ID of a thread, it is possible to retrieve the pointer to thatthread -
int ID = 1; Thread *tf = Lookup_Thread(domain, ID);u Conversely, given the pointer to a thread, it is possible to retrieve the
integer ID of that thread -int ID = 1;if (THREAD_ID(tf)==1)...
int ID = 1;thread_loop_f (tf, domain) { if (THREAD_ID(tf)==1) begin_f_loop(f, tf) { F_CENTROID(FC, f, tf); printf("x:%f y:%f",FC[0],FC[1]); } end_f_loop(f, tf) }
UsageUsage
25UGM 2002
Cells across a face and Their Threadsu These macros help to identify the neighboring cells of a faceu This information may be required of some of the more sophisticated
UDFs that loop throughu faces of a boundary thread oru a particular cell
u Associated with a given face f, and its thread tf, are potentially twoadjacent cells denoted c0 and c1(named by right-hand rule).u If the face is on the boundary of the domain, c1 is defined as NULL and
only c0 exists
u The following macros return the ID of the cells c0 and c1, as well as theassociated threads:
c0 = F_C0(f,tf); /* returns ID for c0*/ tc0 = THREAD_T0(tf); /* returns the cell thread for c0 */ c1 = F_C1(f,tf); /*returns ID for c1 */ tc1 = THREAD_T1(tf); /* returns the cell thread for c1 */
c1,tc1
c0,tc0 f,tf
26UGM 2002
Cell Variables (1)
u C_R(c,t) Density
u C_P(c,t) Pressureu C_U(c,t)u C_V(c,t) Velocity componentsu C_W(c,t)u C_T(c,t) Temperatureu C_H(c,t) Enthalpyu C_K(c,t) Turbulent kinetic energyu C_D(c,t) Turbulent energy dissipationu C_YI(c,t,i) Species mass fractionu C_UDSI(c,t,i) User defined scalar
27UGM 2002
Cell Variables (2)
u C_DUDX(c,t)u C_DUDY(c,t)u C_DUDZ(c,t)u C_DVDX(c,t)u C_DVDY(c,t) Velocity derivativesu C_DVDZ(c,t)u C_DWDX(c,t)u C_DWDY(c,t)u C_DWDZ(c,t)u C_MU_L(c,t)u C_MU_T(c,t) Viscositiesu C_MU_EFF(c,t)u C_DP(c,t)[i] Pressure derivativesu C_D_DENSITY(c,t)[i] Density derivatives
28UGM 2002
Cell Variables (3)
u C_K_L(c,t)u C_K_T(c,t) Thermal conductivitiesu C_K_EFF(c,t)u C_CP(c,t) Specific heatu C_RGAS(c,t) Gas constantu C_DIFF_L(c,t,i) Species diffusivityu C_DIFF_EFF(c,t,i)
29UGM 2002
Face Variables
u F_P(f,t) Pressureu F_U(f,t)u F_V(f,t) Velocity componentsu F_W(f,t)u F_T(f,t) Temperatureu F_H(f,t) Enthalpyu F_K(f,t) Turbulent kinetic energyu F_D(f,t) Turbulent energy dissipationu F_YI(f,t,i) Species mass fractionu F_UDSI(f,t,i) User defined scalaru F_PROFILE(f,t,i)Boundary profile storage
30UGM 2002
UDF Macro-s (Types of UDF)u UDF’s in FLUENT are available for:
u Boundary conditions : Profilesu Fluid and solid zones : Source termsu Fluid/solid, particle, flow : Propertiesu UDS unsteady, flux, diffusivity : Scalar Functionsu Zone and variable specific initialization : Initializationu Adjust, read/write, execute_on_demand : Global Functionu Convective & radiative : Wall-heat-flux
(Alternative: profile)(Alternative: profile)u Reaction rates, dpm, slip velocity,… : Model Specific Functions
31UGM 2002
UDF Macro-s (Types of UDF)u Available UDF Macro-s :
u Profiles : DEFINE_PROFILEu Source terms : DEFINE_SOURCEu Properties : DEFINE_PROPERTYu Scalar Functions : DEFINE_UNSTEADY
DEFINE_FLUXDEFINE_DIFFUSIVITY
u Initialization : DEFINE_INITu Global Functions : DEFINE_ADJUST
DEFINE_ON_DEMANDDEFINE_RW_FILE
u Wall-heat-flux : DEFINE_HEAT_FLUXu Model Specific Functions : DEFINE_DPM_…
DEFINE_SR_RATEDEFINE_VR_RATEDEFINE_SCAT_PHASE_FUNCDEFINE_DRIFT_DIAMETERDEFINE_SLIP_VELOCITY
32UGM 2002
The udf.h Fileu The udf-macros are defined in the ‘udf.h’ fileu udf.h is a fluent header file in the ~/Fluent.Inc/Fluentx.y/src/
directoryu udf.h must be included at the top in each and every udf file
u A file may contain more than one UDFu User can use multiple files for UDF
u Any UDF you might write must use one of the ‘DEFINE_…’ macro-s fromthis udf.h file
#define DEFINE_PROFILE(name, t, i) void name(Thread *t, int i)#define DEFINE_PROPERTY(name,c,t) real name(cell_t c, Thread *t)#define DEFINE_SOURCE(name, c, t, dS, i) \ real name(cell_t c, Thread *t, real dS[], int i)#define DEFINE_INIT(name, domain) void name(Domain *domain)#define DEFINE_ADJUST(name, domain) void name(Domain *domain)#define DEFINE_DIFFUSIVITY(name, c, t, i) \ real name(cell_t c, Thread *t, int i)
Part of the ‘Part of the ‘udfudf.h’ file from .h’ file from ~~/Fluent.Inc//Fluent.Inc/fluentfluentxx..yy//srcsrc directory directory
Interpret / Compile UDFs and TheirUsage
On-the-fly and pre-compiled UDF-s
Working with UNIX / NT
Steps in Compilation
A quick example
34UGM 2002
How to use the UDF
u First, we need to write and save the C-source file containing theappropriate DEFINE_MACRO routine(s).
u To use this file, the steps are:1: Interpret Interpret / / CompileCompile the UDF2: Start the solver (FLUENT) and read in your case/data files3: Assign the UDFs in the BC and/or other panels for the appropriate
zones4: Set the UDF update frequency in the Iterate panel5: Run the calculation as usual
u Note: Values obtained from and returned to the solver byUDFs must be in SI unitsmust be in SI units
35UGM 2002
Interpreted Vs. Compiled Codeu UDFs can be ‘interpreted’ on-the-fly using the standard ‘GUI’
u does not need a separate compiler and are architecture-independentu It translates the C-source to assembly languageu Executes the code on line-by-line instantaneously
l performs slower than compiled UDFsu The interpreter resides in the computer’s memory
l involves extra memory usage
u UDFs can be precompiled before invoking in FLUENTu Needs a compileru It translates the C-source to machine language (object modules)u Needs to follow a standard multi-step procedure (will be discussed later)u Creates ‘shared libraries’ linked with the rest of the solver
ALL INTERPRETED UDF-S CAN ALSO BE COMPILEDTHOUGH THE CONVERSE IS NOT TRUE
36UGM 2002
Interpreted UDFsu Interpreter limitations:
u mixed mode arithmetic,u structure references etc.u cannot be linked to compiled system or user librariesu less powerful than compiled UDFs due to limitations in
the C language supported by the interpreter
u In particular, interpreted UDFs cannot contain:u non ANSI-C prototypes for syntaxu declarations of local structures, unions, pointers to functions,
and arrays of functionsu direct structure references
u Interpreted UDFs can indirectly access data stored in a FLUENTstructure only via a set of macro-s
37UGM 2002
Interpreting the UDF
u Define ÕUser DefinedÕFunctions ÕInterpreted…
Listing appearing on Fluent windows:
w_profile: .local.pointer thread (r0) .local.int position (r1)0 .local.end0 save .local.int f (r6)8 push.int 010 save .local.int. . . ..L1:132 restore133 restore134 ret.vuClick Compile
uThe assembly language code willscroll past window
}Skipping display here
38UGM 2002
u User sees two different UNIX specificMakefiles (makefile.udf andmakefile.udf2) in the director: ~Fluent.Inc/fluentx.y/src
u Make a directory to put your library in:u mkdir libudfu cd libudf
u Copy makefile.udf2 to this directoryu cp makefile.udf2 ./Makefile
u Make a directory called srcu mkdir src
u Put source code in the src directoryu Copy makefile.udf to src directory as
makefile
u Edit the SOURCES andFLUENT_INC macros
Compiling the UDF for UNIX# Makefile for user defined functions.## sccs id: %W% %G%#--------------------------#
# User modifiable section.#--------------------------#SOURCES= w-profile.cFLUENT_INC=/usr/local/Fluent.Inc
#------------------------## Build targets (do not modify belowthis line).#------------------------#
}
{
39UGM 2002
Compiling the UDF for UNIX (2)u Make directories for the versions you want to build
u mkdir ultrau mkdir ultra/2du mkdir ultra/3d
u Build the shared libraries by typingu make “FLUENT_ARCH=<your architecture>”
u where your architecture may be ultra, hp700 etc. in the libudf directory andyou will see
# building library in ultra/2d# building library in ultra/3d
u Run the solver and click onDefine Õ User Defined Õ Functions Õ Compiled...
u At the prompt type in the path to your libudf directory: the solver willautomatically look for the right architecture and version
Opening library "libp1/ultra/2d/libudf.so"... my_profile energy_sourceDone.
!! Note: If there are problems with the build, you can do a complete rebuild by typing nmake clean
40UGM 2002
Compiling the UDF for UNIX (3)
libudf libudf
MakefileMakefile srcsrc ultraultra
makefilemakefile w-profile.cw-profile.c
2d2d 3d3d
makefilemakefile w-profile.cw-profile.c libudf.solibudf.so makefilemakefile w-profile.cw-profile.c libudf.solibudf.so
41UGM 2002
Compiling the UDF for NTu Make a directory to put your library in:
u mkdir libudfu cd libudf
u Make a directory called srcu mkdir srcu Put source code
u Create a directory called ntx86u Create 2d, 3d, 2ddp,...uu In each directory,In each directory, copy the makefile_nt.udf and user_nt.udf files from
~Fluent.Inc/fluentx.y/src directoryu Edit user_nt.udf for:
l SOURCES = $(SRC)w_profile.c $(SRC)udfexample2.c …l VERSION = 2d / 3d / 2ddp / 3ddp (only one of these)(only one of these)l PARALLEL_NODE = none / smpi / vmpi / net (only one of these)(only one of these)
u Build the shared libraries inin each directory: each directory:u In an MS-DOS Command Prompt window, go to your build directory (e.g., \libudf\ntx86\2d\), and type:
nmake
!! Note: If there are problems with the build, you can do a complete rebuild by typing nmake clean
42UGM 2002
Compiling the UDF for NT (2)u Run the solver and click on
Define Õ User Defined Õ Functions Õ Compiled...u At the prompt type in the path to your libudf directory: the solver will
automatically look for the right architecture and version
Opening library "libp1/ultra/2d/libudf.so"... w_profile energy_sourceDone.
43UGM 2002
Compiling the UDF for NT (3)
libudf libudf
srcsrc ntx86ntx86
w-profile.cw-profile.c
2d2d 3d3d
makefilemakefile user_nt.udfuser_nt.udf libudf.dlllibudf.dll makefilemakefile user_nt.udfuser_nt.udf libudf.dlllibudf.dll... ...
44UGM 2002
Using UDFs - Example
u A non-uniform inlet velocity is to be imposed on the 2D turbine vane shownbelow. The x-velocity variation is to be specified as
u(y) = 20 [ 1 - (y/0.067)2]
x
y
u
45UGM 2002
Source Code for Example#include "udf.h"
DEFINE_PROFILE(velocity_profile, thread, position){ float x[3]; /* this will hold the position vector*/ float y; face_t f;
begin_f_loop(f, thread) { F_CENTROID(x,f,thread); y = x[1]; F_PROFILE(f, thread, position) = 20.*(1.- y*y /(.067*.067)); } end_f_loop(f, thread) }
46UGM 2002
Activating the UDF
uAccess the boundary condition paneluSwitch from constant to the UDF function in the VelocityMagnitude dropdown list
47UGM 2002
Run the Calculation
uRun the calculation as usualuYou can change the UDF Profile Update Interval in theIterate panel (here it is set to 1)
48UGM 2002
Solution of Example problemuThe figure at right showsvelocity field throughoutturbine blade passageuThe bottom figure shows thevelocity plot at the inletuNotice the imposed parabolicprofile
UDF Hooks - ‘DEFINE’ Macros
Different Types of UDF-s and
Some examples
50UGM 2002
Boundary Profiles: DEFINE_PROFILEu You can use this UDF to
specify
u Walll temperaturel heat flux, shear stress
u Inletsl velocityl temperaturel turbulencel speciesl scalars
u The macro begin_f_looploops over all faces on theselected boundary thread
u The F_PROFILE macroapplies the value to face, f onthe thread
#include "udf.h"
DEFINE_PROFILE(w_profile, thread, position){ face_t f; real b_val;
begin_f_loop(f, thread) { b_val = …/* your boundary value*/ F_PROFILE(f, thread, position) = b_val; } end_f_loop(f, thread)}
Userspecified
name
Argumentsfrom thesolver tothis UDF
thread : The thread of the boundary towhich the profile is attached
position : A solver internal variable(identifies the stack location ofthe profile in the data stack)
User can rename the variables at will: DEFINE_PROFILE(my_prof, t, pos)
It’s amust!
51UGM 2002
Example 1: Transient Inlet VelocityuPulsatile flow in a tube
Vx = Vo + A sin(ωt)
where Vo = 20 m/s, A = 5 m/s, ω = 10 rad/suBoundary condition is applied at inlet
#include "udf.h"DEFINE_PROFILE(unsteady_v, t, pos){ float t, velocity; face_t f; begin_f_loop(f, t) { t = RP_Get_Real("flow-time"); velocity = 20.0 + 5.0*sin(10.*t); F_PROFILE(f, t, pos) = velocity; } end_f_loop(f, loop)}
Inlet
WallExit
Pipe Axis
52UGM 2002
Example 1: Results of Transient Inlet Velocity
uTime history of the average velocity at the pipe exit shows sinusoidal oscillationwith a mean of 20 and amplitude of 5.
AverageVelocityMagnitude
Flow Time
53UGM 2002
Example 2: Fully Developed Turbulent Inlet
Inlet Channel
Expansion
uProfiles for inlet velocity, k and ε areused to approximate fully developedflow conditionsuVelocity profile follows 1/7 power lawuTurbulent kinetic energy varies linearlyfrom a near-wall peak to a prescribedcore-flow valueuDissipation is prescribed by a mixing-length modeluUsed to minimize the domain size and sensitivity to inlet boundary conditions
54UGM 2002
Example 2: Results of Fully DevelopedTurbulent Inlet
u Axial velocity profile changes little downstream of inlet boundary
55UGM 2002
Example 2: Results of Fully Developed Inlet
u Turbulence quantities change little downstream of the inlet
Turbulent Kinetic EnergyDissipation Rate
Turbulent Kinetic Energy
56UGM 2002
Example 3: Sinusoidal Wall Temperature
uLower wall temperature variessinusoidally with x-position accordingto
Tx = 300 + 100 sin(π x/L)
uInlet fluid enters at 300 KuUpper wall is insulated
Inlet
Adiabatic Wall
Exit
Heated Wall
Temperature:Temperature: F_PROFILE(f, t, pos) = 300.+100.*sin(PI*x/0.005);
57UGM 2002
Example 3: Results of Sinusoidal Wall Temperature
u Wall (and fluid) temperature reaches peak at midlength of channel
Static Temperature (K)
58UGM 2002
Source Terms (1)
u The solvers compute source terms using the linearized form S = A + B φ
where φ is the dependent variable, A is the explicit part of the source term and Bφis the implicit part
u A recommended linearization is where φ is the dependent variable
u User needs to specify S and . Solver computes the proper linearized form
)*(*
* φφφ −∂∂+=
SSS
φ∂∂S
59UGM 2002
Source Terms (2)
u Source term UDFs can be created for:u continuityu momentumu k, εu energyu speciesu User defined scalars
u Energy source term UDFs may also be defined for solid zonesu NOTE: The units on all source terms are of the form generation-rate /
volumeFor example, a source term for the continuity equation would have units of(kg/s/m3)
60UGM 2002
Source Terms (3)
u Solver call this UDF for each cell inthe zone
u The solver passes the UDF the cellpointer associated with the cell
u The variable dS[eqn] sets up theimplicit part of the source term for theequation the source term is used for
u Note that the UDF returns a floatingpoint value for the explicit part of thesource and is called only once for eachcell
include "udf.h"
DEFINE_SOURCE(cell_y_source1, cell, thread, dS, eqn){
real source;real bub_num;cell_t cc;
dS[eqn] = 0.0;
source =/*your source here*/;
return source;}
61UGM 2002
Source Terms (4)
u To activate source terms DefineÕBoundary ConditionsÕfluid-1 and clickon Source Terms
62UGM 2002
Example 4: Position Dependent Porous Media
u Channel flow with porous plugu x-momentum loss is linear in y-position, starting from zero at lower wallu Fluid flows preferentially near the bottom of the channel
Velocity Vectors (m/s)
Porous Plug
InletOutlet
63UGM 2002
Example 5: Bubble Generated Momentum
uA column of bubbles imparts verticalmomentum inside a sparging tank.uThe rate of momentum addition iscorrelated to bubble size and numberdensity.uThis simple model can be used inplace of a more costly multiphasemodel. Bubble Plume
64UGM 2002
Example 5: Result of Bubble Generated Momentum
uThe rising plume of bubbles creates circulation throughout the tank
65UGM 2002
Initialization
uInitializes solutions forentire domain, similar to“patching” of valuesuExecuted once at thebeginning of solution process
#include "udf.h"DEFINE_INIT(my_init_function, domain){ cell_t c; Thread *thread; real xc[ND_ND]; thread_loop_c (thread,domain) { begin_c_loop (c,thread) {
C_CENTROID(xc,c,thread);if (sqrt(ND_SUM(pow(xc[0]-0.5,2.), pow(xc[1] - 0.5,2.),
pow(xc[2] - 0.5,2.))) < 0.25) C_T(c,thread) = 400.;else
C_T(c,thread) = 300.; } end_c_loop (c,thread) }}
66UGM 2002
Adjust Function
uFunction called for everyiterationuIntegrate the turbulentdissipation over the wholedomain and print it to the textuser interface
DEFINE_ADJUST(my_adjust, domain){ /* Integrate dissipation. */ real sum_diss=0.; thread_loop_c (thread,domain) { begin_c_loop (c,thread)
sum_diss += C_D(c,thread)* C_VOLUME(c,thread); end_c_loop (c,thread) } Message(“Volume integral of turbulent dissipation : %g\n”,sum_diss);}
67UGM 2002
User Defined I/O
uAbility to read/write custom data incase/data files
u Can save and restore custom variables ofany data types (e.g., integer, real,Boolean, structure)
u Useful to save “dynamic” information(e.g., number of occurrences inconditional sampling)
u Defined using DEFINE_RW_FILE macrou Selected in the User-Defined Function
Hooks panel
68UGM 2002
User Defined I/O (2)#include "udf.h"int count = 0; /* define and initialize static variable
count */DEFINE_ADJUST(it_count, domain){ count++; printf("count = %d\n",count);}DEFINE_RW_FILE(writer, fp){ printf("Writing UDF data to data file...\n"); fprintf(fp, "%d",count); /* write out count to data file
*/}DEFINE_RW_FILE(reader, fp){ printf("Reading UDF data from data file...\n"); fscanf(fp, "%d",&count); /* read count from data file */}
69UGM 2002
Wall Heat Flux Function
uThe Wall Heat Flux Function allowsusers to include fluid-side diffusiveand radiative wall heat fluxes interms of heat transfer coefficientsucid[ ] array stores the diffusivefluxesucir[ ] stores radiative fluxesuApplies to all walls
#include "udf.h"
DEFINE_HEAT_FLUX(heat_flux,f, t, c0, t0, cid, cir){ cid[0] = 0.; cid[1] = 50.; cid[2] = 50.; cid[3] = 0.;}
43210
"
43210
"
wwcr
wwcd
TcirTcirTcircirq
TcidTcidTcidcidq
−−+=
−−+=
&
&
Note:Note: DEFINE_PROFILE DEFINE_PROFILE is ais abetter alternativebetter alternative
70UGM 2002
Properties(1)
uUDF’s can be used to defineu Viscosityu Thermal Conductivityu Mass Diffusivityu Density
uUDF’s cannot be used to definespecific heatuThe function is called for everycell in the zone
#include "udf.h"DEFINE_PROPERTY(user_vis, cell, thread){ real temp, mu_lam; temp = C_T(cell, thread); { if (temp > 288.) mu_lam = 5.5e-3; else if (temp >= 286.&& temp<=288.) mu_lam = 143.2135 - 0.49725 * temp; else mu_lam = 1.0; } return mu_lam;}
286KTK 288T286K
288KT
1T0.49725-143.2
105.5 3
<≤≤
>
=
−
µ
71UGM 2002
Properties (2)
uTo activate the UDF, select user-defined from the property dropdown listuWhen you select the user-definedoption, a panel will appear with thenames of your UDF’suSelect the name of the appropriateUDF
72UGM 2002
Example 6: Temperature Dependent Viscosity
uWarm fluid enters thechannel flowing from leftto right.uViscosity increases as thefluid is cooled by contactwith the cold upper wall.
Contours of molecular viscosity (kg/ms)
73UGM 2002
Example 7: Custom Reaction Rate
uSpecies A is converted to Species BuReaction occurs only in a thin porous regionuSpecies A is consumed shortly after entering the porous reaction zone
Contours of mass fraction of species A
Inlet
Outlet
Porous reaction zone
74UGM 2002
Time Step: DEFINE_DELTATu In Fluent, you may use adaptive
timesteping based on minimum andmaximum values of timesteps as wellas other parameters
u Adaptive timestepping is activated byselecting the corresponding radio-button in the Solve-Iteratepanel for unsteady problems
u DEFINE_DELTAT lets the usercontrol the timestep based on anycustom logic/algorithm
#include "udf.h"DEFINE_DELTAT(mydeltat, domain){ real time_step; real flow_time = RP_Get_Real("flow-time"); if (flow_time < 0.5) time_step = 0.1; else time_step = 0.2; return time_step;}
mydeltat
75UGM 2002
Turbulent Viscosity: DEFINE_TURBULENT_VISCOSITY
u Any custom relation for theturbulent viscosityformulation can be adoptedusing this UDF hook
u The variable names for theconstants in the standard k-εmodel are:u C1 : M_keC1u C2 : M_keC2u Cµ : M_keCmuu σk : M_keigku σε : M_keigeu σε : M_keprt
DEFINE_TURBULENT_VISCOSITY(my_mut,cell,thread){ real mu_t; real rho = C_R(cell,thread); real k=C_K(cell,thread); real epsilon=C_D(cell,thread); mut= M_keCmu*rho*SQR(k)/epsilon; return mut;}
2
tk
Cµµ ρε
=
User Defined Scalars and Memories
UDF-s for User Defined Scalar Field Solution
User Specified Storage of custom Data
UDF for Execution-on-Demand
77UGM 2002
User Defined Scalars (1)
uFLUENT can solve generic transportequations for User Defined ScalarsuThe menu is accessed throughDefineÕModelsÕUser-DefinedScalars…uUser specifies number of User- DefinedScalars and UDF can be used for parts ofscalar transport equation :
u Advective: DEFINE_UDS_FLUXu Unsteady: DEFINE_UDS_UNSTEADYu Diffusivity: DEFINE_DIFFUSIVITY
( ) Sx
Dx
uxt jj
j
j
+
∂∂
∂∂=
∂∂+
∂∂ φφρρφ)(
78UGM 2002
User Defined Scalars (2)uUser Defined Scalar convective andtime derivatives can be modified
DEFINE_UDS_UNSTEADY(uns_time, cell,thread, i, apu, su){ real physical_dt, vol, rho, phi_old; physical_dt = RP_Get_Real("physical-time-step"); vol = C_VOLUME(cell,thread);
rho = Rhod; *apu = -rho*vol /physical_dt;/*implicit part*/ phi_old =C_STORAGE_R(cell,thread,SV_UDSI_M1(i)); *su =rho*vol*phi_old/physical_dt;/*explicitpart*/}
DEFINE_UDS_FLUX(flux, f, t, i){ if (i == 0) return 0.; if NNULLP(THREAD_STORAGE(t,SV_FLUX)) return F_FLUX(f,t); return 0.;}
79UGM 2002
User Defined Scalars (3)
uThe Boundary Conditions for theUser Defined Scalar can bespecified as Specified Flux orSpecified Value
uThe diffusivity for the UserDefined Scalar can be specifiedthrough MaterialÕuser-defined-diffusivity panel as aconstant or asUser-Defined Function
80UGM 2002
User Defined Scalars (4)uThe User Defined Scalars andtheir gradients can be used inUDF’s
DEFINE_ADJUST(adjust_fcn, domain){ Thread *t; int nt; cell_t c; face_t f; int ns; real p_dis = 0.;/* Do nothing if gradient isn't allocated yet. */if (! Data_Valid_P())return;/* Compute power dissipated. */thread_loop_c (t, domain) if (FLUID_THREAD_P(t)) {
begin_c_loop_all (c,t) {
C_UDSI(c,t,1) +=K_EL*NV_MAG2(C_UDSI_G(c,t,0))*C_VOLUME(c,t);
}end_c_loop_all (c, t)
}}
81UGM 2002
User Defined Memory (UDM)u User-allocated memory
u Allow users to allocate memory (up to 500 locations)to store and retrieve the values of field variablesfield variablescomputed by UDF’s (for postprocessing and use byother UDFs)
u Same array dimension and size as any flow variableu More efficient storage compared to User Defined
Scalars: UDMs are not solved foru Number of User-Defined Memory Locations is
specified in the User-Defined Memory panelu Accessible via macros
l Cell values: C_UDMI(c,t,i)l Face values: F_UDMI(f,t,i)
u Saved to FLUENT data file
500
82UGM 2002
User Defined Memory (2)
DEFINE_ON_DEMAND(scaled_temp){ Domain *domain = Get_domain(1);/* Compute scaled temperature store in user-definedmemory */thread_loop_c(t,domain) {
begin_c_loop(c,t) { temp = C_T(c,t); C_UDMI(c,t,0)=(temp - tmin)/(tmax-tmin); }end_c_loop(c,t) }}
83UGM 2002
Execute on Demand
uThis provides a hook to execute anyset of calculation or I/O operations atwill of the user while the solver is notiteratinguExecuted instantaneously whenactivated by useruDefineÕUser-Defined ÕExecute on Demand...
extern Domain *domain;#define SETMIN(a,b)((b)<(a)?(a=b):(a))#define SETMAX(a,b)((b)>(a)?(a=b):(a))DEFINE_ON_DEMAND(scaled_temp){thread_loop_c(t,domain){
real tmin=-1.e10, tmax=1.e10; /* Compute min & max temperature */ begin_c_loop(c,t) { SETMIN(tmin,C_T(c,t)); SETMAX(tmax,C_T(c,t)); } end_c_loop(c,t) }}
User Defined Function forDiscrete Phase Model
UDF to access Discrete Phase Properties, location etc.
UDF to add Custom DPM Physics and Chemistry
UDF to output DPM results
UDF to model Scalar fields with DPM
85UGM 2002
DPM Macros (1)
u Tracked_particle *p DPM Datatypeu DPM tracks particles in Lagrangian frameu Particle data at current position
u P_DIAM(p) Particle diameteru P_VEL(p)[I] Particle Velocityu P_T(p) Particle Temperatureu P_RHO(p) Particle densityu P_MASS(p) Particle massu P_TIME(p) Current time for particleu P_DT(p) Particle time stepu P_LF(p) Particle liquid fractionu P_VFF(p) Particle volatile fraction
86UGM 2002
DPM Macros (2)u Values of particle properties at entry to current cell
u P_DIAM0(p) Diameteru P_VEL0(p)[i] Velocityu P_TO(p) Temperatureu P_RHO0(p) Densityu P_MASS0(p) Massu P_TIME0(p) Timeu P_LF0(p) Liquid fraction
u Values of particle properties at injection into domainu P_INIT_DIAM(p) Diameter
u P_INIT_MASS(p) Mass
u P_INIT_RHO(p) Density
u P_INIT_TEMP(p) Temperature
u P_INIT_LF(p) Liquid fraction
87UGM 2002
DPM Macros (3)
u P_EVAP_SPECIES_INDEX(p) Evaporating species index in mixtureu P_DEVOL_SPECIES_INDEX(p) Devolatilizing species index in mixtureu P_OXID_SPECIES_INDEX(p) Oxidizing species index in mixture
u P_PROD_SPECIES_INDEX(p) Combustion product species index in mixtureu P_CURRENT_LAW(p) Current law indexu P_NEXT_LAW(p) Next particle law index
88UGM 2002
DPM Macros (4)u Material Properties for particles
u P_MATERIAL(p) Material pointer for particlesu DPM_SWELLING_COEFFI(p) Swell coefficient for devolatilizationu DPM_EMISSIVITY(p) Particle radiation emissivityu DPM_SCATT_FACTOR(p) Particle radiation scattering factoru DPM_EVAPORATION_TEMPERATURE(p)Evaporation temperatureu DPM_BOILING_TEMPERATURE(p) Boiling temperatureu DPM_LATENT_HEAT(p) Latent Heatu DPM_HEAT_OF_PYROLYSIS(p) Heat of pyrolysisu DPM_HEAT_OF_REACTION(p) Heat of reactionu DPM_VOLATILE_FRACTION(p) Volatile fractionu DPM_CHAR_REACTION(p) Char fractionu DPM_SPECIFIC_HEAT(p, t) Specific Heat at temperature t
89UGM 2002
DPM Functions (1)
u The following functions can be modeled:u Body force - custom body forces on the particlesu Drag - user defined drag coefficient between
particles and fluidu Source Terms - access particle source termsu Output - user can modify what is written out to the
sampling plane outputu Erosion - called when particle encounters
“reflecting” surfaceu DPM Law - custom laws for particlesu Scalar Update - allows users to update a scalar every
time a particle position is updatedu Switch - change the criteria for switching between laws
90UGM 2002
DPM Functions (2)
u DEFINE_DPM_BODY_FORCE Body forceu DEFINE_DPM_DRAG Dragu DEFINE_DPM_SOURCE Source termsu DEFINE_OUTPUT Outputu DEFINE_DPM_LAW Custom lawu DEFINE_DPM_EROSION Erosionu DEFINE_DPM_INJECTION_INIT Initialize injectionsu DEFINE_DPM_SCALAR_UPDATE Update scalarsu DEFINE_DPM_SWITCH Switch laws
* Note: the arguments to these functions are described in the UDFmanual posted in http://www.fluentusers.com/fluent6/doc/ori/html/udf/main_pre.htm
91UGM 2002
DPM Functions (3)uThe function shown models a custom lawuThe parameter p is a pointer to data structure of type Tracked Particle
#include "udf.h"#include "dpm.h"DEFINE_DPM_LAW(Evapor_Swelling_Law, p, ci){ real swelling_coeff = 1.1; /* first, call standard evaporation routine to calculate mass andheat transfer */ Vaporization_Law(p); /* compute new particle diameter and density */ P_DIAM(p) = P_INIT_DIAM(p)*(1. + (swelling_coeff - 1.)* (P_INIT_MASS(p) P_MASS(p))/ (DPM_VOLATILE_FRACTION(p)*P_INIT_MASS(p))); P_RHO(p) = P_MASS(p) / (3.14159*P_DIAM(p) *P_DIAM(p)*P_DIAM(p)/6); P_RHO(p) = MAX(0.1, MIN(1e5, P_RHO(p)));}
92UGM 2002
DPM Functions (4)
uThe law is activated throughDefineÕModelsÕDispersedPhaseÕInjections…Create
uThe Set Injections Properties panelcomes up where Custom is activatedunder Laws
uThis brings up the Custom Lawspanel where the user can specify theappropriate law
UDFs for Multiphase Flows
Data Structure for Multiphase Flows
Threads, Domains, Phase Indices and Looping Macro-s
UDF Define-Macros
Miscellaneous Macro-s
94UGM 2002
Recap: Single Phase Data Structure
CorrespondingData structure
Wall
PorousMedium
Fluid-1
Solid-1
Solid-2
Outlet
Wall
Fluid-2InletDomainof
Analysis
InletFluid-2
Fluid-1
Solid-1
OutletPorousMedium
Solid-2Wall
DomainDomain
ThreadsThreads
95UGM 2002
Data Structure for Multiphase Modelsu Data Structure in multiphase models involve multiple domains:
u Super Domain: This is the top-level domain contains all phase-independent and mixturedata: geometry, connectivity, property
u Sub-Domains: Each phase has a sub-domain that inherits the mixture-specific data andmaintains the phase-specific data
u Interaction Domain: To activate the phase interaction mechanisms
Sub-Domains
Threads
InletFluid-2
Fluid-1
Solid-1
OutletPorousMedium
Solid-2Wall
Threads
InletFluid-2
Fluid-1
Solid-1
OutletPorousMedium
Solid-2Wall
Threads
InletFluid-2
Fluid-1
Solid-1
OutletPorousMedium
Solid-2Wall
Interaction Domain
InletFluid-2
Fluid-1
Solid-1
OutletPorousMedium
Solid-2Wall
SuperDomain
Threads
Primary PhaseDomain
Secondary PhaseDomains
Sub-Threads
96UGM 2002
The Threads in Multi-Domainsu The mixture:
u In single-phase, a mixture represents the sum over all the speciesu In multiphase it represents the sum over all the phases
u This distinction is importantu Also, the code will later be extended to multiphase multi-component fluids
(where, for example, a phase could be a mixture of species)
u Thread data structures:u Threads must be associated with the super domain and all sub-domains
l For each cell / face thread of the super domain, there is a corresponding cell / facethread for each sub-domain
l Some of the information defined in one thread of the super domain is shared with thecorresponding threads of each of the sub-domains
l Threads associated with the super domain are referred to as super-threadsl Threads associated with the subdomain are referred to as phase-level threads or sub-
threads
97UGM 2002
The Domain-Ids and The Thread-Ids
u For multiphase models, the domains need to beidentified by unique Ids (including Interaction domain)
u Domain_ID of the super (mixture) domain is always ‘1’u Domain_IDs are not necessarily ordered sequentiallyu Therefore, to access the phase domains, each phase
also has a phase_domain_index:u ‘0’ for the primary phaseu ‘N-1’ for the last secondary phaseu phase_domain_index is used in UDFs to retrieve phase thread pointers
l Useful when you want to access data for another phase from an UDF for a particular phase
98UGM 2002
Domain Looping Macrou sub_domain_loop(subdomain, mixture_domain, phase_index)
u Loops over all phases (sub-domains) in a mixtureu mixture_domain is already availableu subdomain & phase_index are defined locally, initialized within the macro
u An Example for the loop, Domain_ID and the phase_domain_index:
DEFINE_ADJUST(print_id, mix_domain){Domain *s_d;/*subdomain pointer, locally defined*/int p_d; /* loop counter for phase_domain_index, locally defined*/int p_d_id; /* mix_domain is available*/sub_domain_loop(s_d, mix_domain, p_d)
{ p_d_id = DOMAIN_ID(s_d); Message("the phase domain id = %d and the phase
domain index = %d\n", p_d_id, p_d); }
}
99UGM 2002
Thread Looping Macrou sub_thread_loop(subthread,mixture_thread,phase_index)
u Loops over all threads in a mixtureu mixture_thread is already availableu subthread & phase_index are defined locally, initialized within the macro
An Example:/*compute bulk density of mixture and store it in a UDM*/DEFINE_ADJUST(calc_den, mix_domain){ Thread *mix_thread; thread_loop_c(mix_thread,mix_domain){ cell_t c;
begin_c_loop(c,mix_thread) { Thread *s_t;
int p_d_i; C_UDMI(c,mix_thread,0) = 0.; sub_thread_loop(s_t, mix_thread, p_d_i) C_UDMI(c,mix_thread,0) += C_VOF(c,s_t)*C_R(c,s_t); end_c_loop(c,mix_thread) }}}
100UGM 2002
Other Looping Macrosu mp_thread_loop_c(cell_thread, mixture_domain, pt)
u cell_thread is a pointer to mixture thread in the mixture_domainu mixture_domain is already assumed to be availableu pt is an array of thread pointers
u mp_thread_loop_f(face_threads, mixture_domain, pt)u face_threads is a pointer to face thread in the mixture_domainu mixture_domain is already assumed to be availableu pt is an array of thread pointers pointing to the phase-level threads
An Example:DEFINE_ADJUST(print_vof, mix_domain){ Thread *mix_thread;
Thread **pt; mp_thread_loop_c(mix_thread, mix_domain, pt) {cell_t c; begin_c_loop(c, mix_thread) Message(“cell volume fraction = %f\n”,C_VOF(c,pt[0]));
end_c_loop(c, mix_thread)}}
101UGM 2002
Access the Right Thread / Domain
u While writing UDF’s, it is important that the right thread / domain is accessedu C_R(cell,thread) will return
l The mixture density if thread is the mixture thread orl The phase densities if it is the phase thread
u In general the type of ‘DEFINE’ macro determines which thread or domain (mixture or phase) getspassed to your UDFu DEFINE_INIT and DEFINE_ADJUST functions always get passed the domain
structure associated with the super domainu DEFINE_ON_DEMAND functions are not passed any domain structures
u If your UDF is not explicitly passed the pointer to the thread or domain required, thenyou can use a multiphase-specific utility macro to retrieve it
u See Chapter 3 of the Fluent6 UDF manual, tables 3.11.1-3.11.6 for a description ofarguments to macros
102UGM 2002
Access Variables External to a UDFu Get_Domain(Domain-ID)
u Usage: Domain *domain=Get_Domain(n);‘n’ is the Domain-ID, as appear in Define-Phase GUI; for mixture domain, it isalways ‘1’
u DOMAIN_ID(domain)
u Usage: int domain_id = Domain_ID(subdomain);‘subdomain’ is the pointer to a phase-level domain; returned domain_id is thesame integer ID displayed in the GUI under Define-Phases panel
u DOMAIN_SUB_DOMAIN(mixture_domain,ph_domain_index)u Usage: Domain *mixture_domain;
Domain *subdomain = DOMAIN_SUB_DOMAIN (mixture_domain, phase_domain_index);
returns the phase pointer subdomain for the phase_domain_index
103UGM 2002
Access Variables External to a UDF (2)u THREAD_SUB_THREAD(mixture_thread,ph_domain_index)
u Usage: int ph_d_index = 0; /* primary phase index is 0 */ Thread *mix_th;/* mixture-level thread pointer */ Thread *subth=THREAD_SUB_THREAD(mix_th, ph_d_index);
returns the phase-level thread pointer for the given ph_d_index
u THREAD_SUB_THREADS(mixture_thread)
u Usage: Thread *mixture_thread; Thread **pt; /* initialize pt: pointer array */ pt = THREAD_SUB_THREADS(mixture_thread)
returns the pointer array, pt, whose elements contain pointers to phase-levelthreads (subthreads)
104UGM 2002
Access Variables External to a UDF (3)
u THREAD_SUPER_THREAD(subthread)u Usage:
Thread *subthread; /*pointer to a phase thread within the mixture*/Thread *mix_thread=THREAD_SUPER_THREAD(subthread)
returns mixture thread pointeru DOMAIN_SUPER_DOMAIN(subdomain)
u Usage:Domain *subdomain; /*pointer to a phase domain within the mixture*/Domain *mixture_domain = DOMAIN_SUPER_DOMAIN(subdomain)
returns mixture domain pointer
105UGM 2002
Access Variables External to a UDF (4)u PHASE_DOMAIN_INDEX(subdomain)
u Usage:Domain *subdomain; /*points to a phase domain within the mixture*/int phase_domain_index = PHASE_DOMAIN_INDEX(subdomain)
returns the phase domain index for the phase domain (subdomain) pointer;It is an integer that starts with ‘0’ for the primary phase and is incrementedby one for each secondary phase
u THREAD_DOMAIN(thread)u Usage:
Thread *subthread; /*points to a phase thread within the mixture*/ Thread *mix_thread=THREAD_SUPER_THREAD(subthread) Domain *subd=THREAD_DOMAIN(subthread); /*points to a phase domain*/ Domain *mixd=THREAD_DOMAIN(subthread); /*points to mixture domain*/
returns domain pointer for the thread
106UGM 2002
Exchange Macros(1)
u DEFINE_EXCHANGE_PROPERTY( name, c, mixture_thread, second_column_phase_index, first_column_phase_index)u This macro is used to specify custom drag &
lift coefficients for the Eulerian multiphase modelu mixture_thread points to the mixture threadu c is the index of a cell on the mixture_threadu first_column_phase_index and second_column_phase_index are integer
identifiers corresponding to the pair of phases in your multiphase flowu The identifiers correspond to the phases that are selected in the
Phase-Interaction panel in the GUIu The UDF returns the real value of the lift or drag coefficient
FirstColumn
Second Column
107UGM 2002
Exchange Macros(2)u DEFINE_VECTOR_EXCHANGE_PROPERTY(name, c,mixture_thread,
second_column_phase_index,first_column_phase_index,vector_result)u This macro is used to specify custom slip velocities for multiphase Mixture model
u mixture_thread points to the mixture threadu c is the index of a cell on the mixture_threadu first_column_phase_index and second_column_phase_index are integer
identifiers corresponding to the pair of phases in your multiphase flowu The identifiers correspond to the phases that are selected in the
Phase-Interaction panel in the GUIu The UDF is passed the real pointer to the slip velocity vector vector_result, and it will
need to set the components of the slip velocity vector
108UGM 2002
Exchange Macros(3)An Example:
#include "udf.h”#include "sg_mphase.h"DEFINE_VECTOR_EXCHANGE_PROPERTY(custom_slip, c, mixture_thread,second_column_phase_index, first_column_phase_index, vector_result){ real grav[2] = {0., -9.81}; real K = 5.e4; real pgrad_x, pgrad_y; Thread *pt, *st;/* thread pointers for primary & secondary phases*/
pt = THREAD_SUB_THREAD(mixture_thread, second_column_phase_index); st = THREAD_SUB_THREAD(mixture_thread, first_column_phase_index);/* Now the threads are known for primary (0) & secondary(1) phases */ pgrad_x = C_DP(c, mixture_thread)[0]; pgrad_y = C_DP(c, mixture_thread)[1]; vector_result[0] = -(pgrad_x/K)+(((C_R(c,st)-C_R(c,pt))/K)*grav[0]); vector_result[1] = -(pgrad_y/K)+(((C_R(c,st)-C_R(c,pt))/K)*grav[1]);}
109UGM 2002
Cavitation Macrosu DEFINE_CAVITATION_RATE (name,c,t,p,rhoV,rhoL,vofV,
p_v,n_b,mdot)u You can use this macro to model the creation of vapor due to pressure tension in a
multiphase flowu It is applied in the User-Defined-Function-Hooks→Cavitation-Mass-Rate-
Function panelu t is a pointer to the mixture-level threadu c is the index of a cell on the thread pointed to by tu The remaining arguments are real pointers to the following data:
l Shared pressure (p), vapor density (rhoV), liquid density (rhoL), vapor volume fraction (vofV),vaporization pressure (p_v), number of bubbles per unit volume (n_b), and rate of vapor formation(mdot)
u The UDF sets the value referenced by the real pointer mdot, to the cavitation rate
110UGM 2002
Miscellaneous: Multiphase Macros
u Phase diameteru C_PHASE_DIAMETER(c,phase_thread)
u Phase Volume-fractionu C_VOF(c,phase_thread)
u Phase velocity gradientsu C_U_G(c, phase_thread)u C_V_G(c, phase_thread)u C_W_G(c, phase_thread)
111UGM 2002
Miscellaneous : Multiphase Macrosu Phase volume fraction gradients: C_VOF_G(c,phase_thread)
u Memory needs to be allocated and gradients need to be explicitly calculated
*Domain *pDomain = DOMAIN_SUB_DOMAIN(domain,P_PHASE);Alloc_Storage_Vars (pDomain,SV_VOF_RG,SV_VOF_G,SV_NULL);Scalar_Reconstruction(pDomain,SV_VOF,-1,SV_VOF_RG, NULL);Scalar_Derivatives (pDomain,SV_VOF,-1,SV_VOF_G,SV_VOF_RG, Vof_Deriv_Accumulate);
112UGM 2002
Miscellaneous: Multiphase Macrosu Check if a given thread is a “super” or “sub” thread
u THREAD_SUPER_THREAD(thread) is NULL for mixture thread and notNULL for phase threads
u mixture : if ( NULLP (THREAD_SUPER_THREAD(thread)))u phase : if (!NULLP (THREAD_SUPER_THREAD(thread)))
UDF in Parallel FLUENT
Parallel Fluent Process Chart
Directory Structure for Parallel Fluent
Compiler Directives, Globals, and File I/O
114UGM 2002
Parallel Fluent
Print messages
“(%iterate 5)”Pr
int m
essa
ges
“(%
itera
te 5
)”
Cortex Host
Compute-Node-0
Compute-Node-1
Compute-Node-2
Compute-Node-3
“(%
itera
te 5
)”
“(%ite
rate
5)”
“(%iterate 5)”
mes
sage
s
Print messages
u Compute nodes labeled consecutivelystarting at 0
u Host labeled 999999u Host connected to Cortex and Compute-
Node-0u Each compute node (virtually)
connected to every other compute node
“(%
itera
te 5
)”“(
%ite
rate
5)”
115UGM 2002
fluent6.0 Directory
Parallel Fluent Directories
2d
fluent-version
src
fluent6.0
lib Architecture
2d_node fluent_netnet -versionfluent_smpismpi-versionfluent_vmpivmpi-versionfluent_pvmpvm -version
2d_host
fluent-version
*.hmakefiles
e.g. ultra,hpux11, alpha,
ntx86...
116UGM 2002
Compiler Directives
u #if RP_NODEu Compute-Node
u #if RP_HOSTu Host
u #if PARALLELu Equivalent to #if RP_HOST || RP_NODE
u #if !PARALLELu Serial
“#if” is a compiler directive;Similar to “#define”A “#endif” is used to close a “#if”
117UGM 2002
Parallel FLUENT Globalsu int node_zero = 0;u int node_host = 999999;u int compute_node_count;u int myid; /* multiport id */
u often used in conjunction with partition idl C_PART(c,t) stores partition id at each celll Partition id of exterior cell is the multiport id of neighboring compute-node
u I_AM_NODE_HOST_P: Boolean that compares myid to node_hostu I_AM_NODE_ZERO_P: Boolean that compares myid to node_zero
118UGM 2002
Parallel File Outputu In a parallel session, file I/O can be done only through the Node_ZeroExample:
#if PARALLELif (I_AM_NODE_ZERO_P){ sprintf (ntim,”outfile-%d", ntime); if (fd == NULL) /*Open a new file */ {fd = fopen(ntim,"w");}/* if new file “open” failed, try to append */ if (fd == NULL) /* reopen the file in append-mode*/ {fd = fopen(ntim,"a"); Message( "Appending to existing file: %s", ntim); fprintf(fd,"\nAppend begins at: %f \n", f_time);}}#endif
119UGM 2002
Parallel Utilitiesu Sum over all cells in a parallel run means quantities within the data scope of each
compute nodeu For a global sum in parallel fluent use PRF_GRSUM1(variable) macroExample:
/* compute local sum on each compute-node */a =0;begin_f_loop() /* loop over faces */{a += ...; /* put your local sum function here */}end_f_loopa = PRF_GRSUM1(a); /*compute global sum, and assign */
/*it to variable named ‘a’ */...
Miscellaneous Functions/Macros
Trigonometric and Other Mathematical Functions
Standard I/O Functions
Special Macro-s and Vector Utilities
121UGM 2002
Trigonometric Functions
u double acos (double x); returns the arc-cosine of xu double asin (double x); returns the arc-sine of xu double atan (double x); returns the arc-tangent of xu double atan2 (double x, double y); returns the arc-tangent of x/yu double cos (double x); returns the cosine of xu double sin (double x); returns the sine of xu double tan (double x); returns the tangent of xu double cosh (double x); returns the hyperbolic cosine of xu double sinh (double x); returns the hyperbolic sine of xu double tanh (double x); returns the hyperbolic tangent of x
122UGM 2002
Miscellaneous Math-Functions
u double sqrt (double x); returns the square root of xu double pow (double x, double y); returns xy
u double exp (double x); returns ex
u double log (double x); returns ln(x)u double log10 (double x); returns ln10(x)u double fabs (double x); returns |x|u double ceil (double x); smallest integer not less than xu double floor (double x); largest integer not greater than x
u The macro UNIVERSAL_GAS_CONSTANT returns the value of the universal gasconstant (8314.34), which is expressed in SI units of J/Kmol-K
u The macro M_PI returns the value of π
123UGM 2002
Standard I/O Functionsu use Message instead of printf in compiled UDFs (UNIX only)
Message ("Volume integral: %g\n", sum_vol);
u FILE *fopen(char *filename, char *type); opens a fileu int fclose(FILE *fd); closes a fileu int fprintf(FILE *fd, char *format, ...); formatted print to a fileu int printf(char, *format, ...); print to screenu int fscanf(FILE *fd, char *format, ...); formatted read from a file
uu Example:Example: FILE *fd; real f1, f2; fd = fopen(“data.txt”,”r”); fscanf(fd, “%f %f”,&f1,&f2); fclose(fd);
See your system manual pages forSee your system manual pages formore detailsmore detailsNote that for parallel runs, the I/ONote that for parallel runs, the I/Omacros need to be differentmacros need to be different
124UGM 2002
Special Macro-suboolean Data_Valid_P() Equals 1 if data is available, 0 if not
Usage: if(!Data_Valid_P())return;
uboolean FLUID_THREAD_P(t0) true if thread t0 fluid threaduboolean SOLID_THREAD_P(t0) true if thread t0 is solid threaduboolean BOUNDARY_FACE_THREAD_P(t0) true if thread t0 is boundary threaduNULLP(T_STORAGE_R_NV(t0, SV_UDSI_G(p1)))
- Checks for storage allocation of user definedscalarsuRP_Get_Real(“flow-time”) Returns actual timeuRP_Get_Integer(“time-step”) Returns time step numberuRP_Get_Real(“physical-time-step”) Returns time step
125UGM 2002
Miscellaneous: Vector Utilitiesu ND_ND in the declaration of a vector or matrix stands for the actual fluent
dimension (2D / 3D)u X[ND_ND] is equivalent to:
u 2D: X[2]u 3D: X[3]
u NV_MAG computes the magnitude of a vector: X[ND_ND]u NV_MAG(x) is equivalent to:
u 2D: sqrt(x[0]*x[0] + x[1]*x[1]);u 3D: sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
u NV_MAG2 computes the sum of squares of vector componentsu NV_MAG2(x) is equivalent to:
u 2D: (x[0]*x[0] + x[1]*x[1]);u 3D: (x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
126UGM 2002
Miscellaneous: Vector Utilitiesu ND_SUM computes the sum of ND_ND argumentsu ND_SUM(x,y,z) is equivalent to:
u 2D: x + y;u 3D: x + y + z;
u ND_SET generates ND_ND assignment statementsu 2D: ND_SET(u,v,C_U(c,t),C_V(c,t)) is equivalent to:
l u = C_U(c, t);l v = C_V(c, t);
u 3D: ND_SET(u,v,w,C_U(c,t),C_V(c,t),C_W(c,t))is equivalent to:l u = C_U(c, t);l v = C_V(c, t);l w = C_W(c, t);
127UGM 2002
Miscellaneous: Vector Utilities
u NV_V performs an operation on two vectorsu NV_V(a, =, x);u a[0] = x[0]; a[1] = x[1]; etc.u Note that if you use + = instead of = in the above equation, then you get a[0]+=
x[0]; etc.
u NV_VV is a vector operator . The operation that is performed on the elementsdepends upon what is used as an argument in place of the + signsu NV_VV(a, =, x, +, y)/* The ‘+’ symbol can be replaced by (-, /,*) */u 2D: a[0]= x[0]+y[0], a[1]= x[1]+y[1];u 3D: a[0]= x[0]+y[0], a[1]= x[1]+y[1], a[2]= x[2]+y[2];
128UGM 2002
Miscellaneous: Vector Utilitiesu NV_V_VS adds a vector to another which is multiplied by a scalar
u NV_V_VS(a,=, x,+,y,*,0.5);u 2D: a[0]=x[0]+(y[0]*0.5), a[1]=x[1]+(y[1]*0.5);u Note that + sign can be replaced by -, /, or *, and ‘*’ sign can be replaced by ‘/’
u NV_VS_VS adds a vector to another which are each multiplied by a scalaru NV_VS_VS(a,=,x,*,2.0,+,y,*,0.5);u 2D: a[0]=(x[0]*2.0)+(y[0]*0.5),
a[1]=(x[1]*2.0)+(y[1]*0.5);u Note that + sign can be used in place of -, *, or /, and ‘*’ sign can be replaced by ‘/’
129UGM 2002
Miscellaneous: Vector Utilities
u The dot products of two sets of vector or componentsu ND_DOT(x,y,z,u,v,w) is equivalent to:
u 2D: (x*u+y*v);u 3D: (x*u+y*v+z*w);
u NV_DOT(x,u) is equivalent to:u 2D: (x[0]*u[0]+x[1]*u[1]);u 3D: (x[0]*u[0]+x[1]*u[1]+x[2]*u[2]);
u NVD_DOT(x,u,v,w) is equivalent to:u 2D: (x[0]*u+x[1]*v);u 3D: (x[0]*u+x[1]*v+x[2]*w);
u NV_CROSS(a,x,y)is available for 3D only:u It returns the cross product of vectors x and y in the new vector a
130UGM 2002
Closure
u All UDF-s must be written in SI unitsu UDF-s open up a virtually endless opportunity to extend the modeling
capabilities of the basic FLUENT codeu Details of the examples and all working macros & parameters are
available in the UDF manual at:http://www.fluentusers.com/fluent6/doc/ori/html/udf/main_pre.htm