User Defined Programming

Embed Size (px)

Citation preview

  • 7/30/2019 User Defined Programming

    1/33

    1

    ME469B/6/GI 1

    User Programming

    What are User Defined Functions

    Introduction to C

    Set-Up C User Routines in Fluent

    Implementing a Custom Turbulence Model

    Programming in other CFD Commercial Codes

    Acknowledgement: this handout is partially based on Fluent training material

    ME469B/6/GI 2

    Introduction to UDF Programming

    Why programming in commercial codes?

    The codes are general-purpose but cannot anticipate all needs

    New (physical) models can be developed in a user-friendly environment

    Large number of problems (test-cases) can be addressed with the same implementation

    What is a the User Defined Function (UDF)?

    C (Fluent) orFORTRAN (StarCD, CFX) routines programmed by the user linked to

    the solver to perform certain operations:

    initialization

    special boundary condition (i.e. space or time dependent)

    material properties

    source terms reaction rates

    postprocessing and reporting

    debugging

    .

  • 7/30/2019 User Defined Programming

    2/33

    2

    ME469B/6/GI 3

    A Simple UDF Example

    Specify a Parabolic Velocity Profile at the Inlet

    Goal: The UDF (inlet_parab) set the values of the x-velocity component at the cell faces

    of the inlet boundary zone

    1) Determine the cell-faces belonging to the inlet zone

    2) Loop on all those faces3) Determine the coordinate of the face centroid

    4) Specify the x-velocity component

    Inlet

    zone

    ME469B/6/GI 4

    Parabolic Velocity Profile:

    A Simple UDF Example

    function inlet_parab

    Definitions

    Loop over all the inlet cell faces

    Evaluate the face centroid coordinates

    The function return the velocity

  • 7/30/2019 User Defined Programming

    3/33

    3

    ME469B/6/GI 5

    A Simple UDF Example

    Compile/interpret the UDF:

    Define User Defined

    Attach the profile to the inlet zone

    Define Boundary Condition

    Equivalent to attach the profile from a separate simulation

    ME469B/6/GI 6

    Solve the equations

    Solve Iterate

    Final Result

    A Simple UDF Example

  • 7/30/2019 User Defined Programming

    4/33

    4

    ME469B/6/GI 7

    C Programming

    Typical C function:

    ME469B/6/GI 8

    C vs. FORTRAN

  • 7/30/2019 User Defined Programming

    5/33

    5

    ME469B/6/GI 9

    Basic Programming Rules

    Statements MUST end with a semicolon ;

    Comments are placed anywhere in the program between /* */

    Statements are grouped by curly brackets { }

    Variables defined within the body functions are local

    Variables defined outside the body functions are global and can be used by

    all the functions that follows

    Variables MUST be ALWAYS defined explicitly

    Integer/real/double functions have to return a integer/real/double value

    C is case sensitive!

    ME469B/6/GI 10

    Basic Statements

    Arithmetic expressions in C look like FORTRAN

    a = y + (i-b)/4;

    Functions which return values can be used in assignment

    a = mycompute(y,i,b);

    Functions which do not return values can be called directly

    mystuff(a,y,i,b);

    Mathematical and various other default functions are available

    a = pow(b,2); /* pow(x,y) returns x raised to y */

  • 7/30/2019 User Defined Programming

    6/33

    6

    ME469B/6/GI 11

    Data Types and Arrays

    Arrays of variables are defined using the notation

    Note the brackets are square [] not round ()!!

    Note that the arrays ALWAYS start from 0

    Standard C types are: Integer, Real, Double, Char

    C allows to define additional types

    typedef struct list{int id, float x[3], int id_next};

    int a[10]; /*define an array of ten integers */

    ME469B/6/GI 12

    Pointers

    A pointer is a variable which contain the address of another variable

    Pointers are defined as:

    int *a_p; /* pointer to an integer variable */int a; /* an integer variable */

    Set-up a pointer

    a = 1;

    a_p = &a; /* &a return the address of variable a */

    *a_p returns the content of the address pointed by a_p

  • 7/30/2019 User Defined Programming

    7/33

    7

    ME469B/6/GI 13

    Operators

    Arithmetic Operators Logical Operators

    ME469B/6/GI 14

    Conditional Statements

    if and if-else Example

  • 7/30/2019 User Defined Programming

    8/33

    8

    ME469B/6/GI 15

    Loop Procedure

    for loops Example

    ME469B/6/GI 16

    C Preprocessor

    It handles Macro substitutions

    #define A B#define my_f(x,y) x+y*3-5

    The preprocessor replaces A with B

    It also handles file inclusion

    #include udf.h

    #include math.h

    The files to be included MUST reside in the currect directory

  • 7/30/2019 User Defined Programming

    9/33

    9

    ME469B/6/GI 17

    Programming in C

    Of course much more than just this.

    Additional information are:

    http://www.cs.cf.ac.uk/Dave/C/CE.html

    Plenty of books:

    The C Programming Language, Kernighan & Ritchie, 1988

    ME469B/6/GI 18

    UDF in Commercial CFD Codes

    Commercial CFD codes allow the development of User Defined Functions

    for various applications. Anyway, the core of the software is closed.

    UDF must be compiled and linked to the main code

    Most codes provide macros and additional tools to facilitate the use of UDFs

    In Fluent there are two options:

    Interpreted

    The code is executed on a line-by-line basis at run time

    + does not need a separate compiler (completely automatic)

    - slows down the execution and uses more memory- somewhat limited in scope

    Compiled

    A library of UDF is compiled and linked to the main code

    Overcomes all the disadvantages reported above

  • 7/30/2019 User Defined Programming

    10/33

    10

    ME469B/6/GI 19

    Interpret the UDFs

    Define User Defined Interpreted

    Default stack size might be too small for large arrays!

    Display of code translation in assembly

    (and eventual compiling errors)

    ME469B/6/GI 20

    Compile the UDFs

    Define User Defined Compiled

    The library MUST be precompiled in a directory tree

  • 7/30/2019 User Defined Programming

    11/33

    11

    ME469B/6/GI 21

    Directory tree for compiled UDFs

    my_library

    Makefile src lnx86

    makefile my_udf.c

    2d 3d

    makefile my_udf.c libudf.so

    makefile my_udf.c libudf.so

    Machine dependent

    irix6r10

    ultra

    hp700

    ME469B/6/GI 22

    Makefiles for UDFs

    In the directory

    /usr/local/Fluent.Inc/fluent6/src

    There are two files

    Makefile.udf to be copied in the directory my_librarymakefile.udf to be copied in the directory my_library/src

    The first one does not require modifications.

    In the second one two macros MUST be modified

    SOURCE = my_udf.c

    FLUENT_INC = /usr/local/Fluent.Inc

  • 7/30/2019 User Defined Programming

    12/33

    12

    ME469B/6/GI 23

    UDFs in FLUENT

    Boundary Conditions

    Initial Conditions

    Adjust Function

    Source Terms

    Material Properties

    Execute on Demand

    User Defined Scalars

    User Defined Memory

    Pointers to threads

    Geometry Macros

    Cell and Face Variables

    Arithmetic and Trigonometric Functions

    Available MACROS

    Programming

    Tools

    ME469B/6/GI 24

    Boundary Conditions

    The inlet profile specification is based on the macro DEFINE_PROFILE

    DEFINE_PROFILE can be used for wall boundary conditions as well

    to impose temperature, velocity, shear stress, etc.

    It is possible to specify a constant value, a position-dependent or

    time-dependent values and to link the values on the boundary to the values

    in the internal cells

    Note that the BCs are applied to the faces of the cells (face centroids)

    x

    x

    x

    BC

    Internal

    Values

  • 7/30/2019 User Defined Programming

    13/33

    13

    ME469B/6/GI 25

    Initial Conditions

    The initial condition specification can be performed using the macro DEFINE_INIT

    Space-dependent conditions might be imposed

    The routine is executed once at the beginning of the solution process

    It is attached in the UDFs hooks

    Define User Defined Function Hooks

    ME469B/6/GI 26

    Initial Conditions

    Note that the difference between the DEFINE_PROFILE and DEFINE_INIT

    is that the former performs a loop on the face-centroids belonging to a certain

    zone whereas the latter loops on the cell-centroids

    Example:

  • 7/30/2019 User Defined Programming

    14/33

    14

    ME469B/6/GI 27

    Adjust Function

    Similar to the DEFINE_INIT but it is executed every iteration: DEFINE_ADJUST

    Can be used for postprocessing, clipping, etc.

    It is attached in the UDFs hooks

    Define User Defined Function Hooks

    ME469B/6/GI 28

    Source Terms

    To add a source term in the equations: DEFINE_SOURCE

    Can be used for:

    Continuity

    Momentum (component by component)

    Turbulent quantities

    Energy

    It is different from the previous macros because it works on a cell-by-cell basis

    (no need to perform loops!)

  • 7/30/2019 User Defined Programming

    15/33

    15

    ME469B/6/GI 29

    Define Boundary Conditions Fluid

    Source Terms

    Activate source terms

    Attach the UDF

    ME469B/6/GI 30

    Source Terms

    In FLUENT the source terms are written in the form

    S(f) = A + B f

    wheref is the dependent variableA is treated explicitly and B f is treated implicitly

    In the DEFINE_SOURCE both terms A and B have to be specified

  • 7/30/2019 User Defined Programming

    16/33

    16

    ME469B/6/GI 31

    Material Properties

    To define the properties of the materials : DEFINE_PROPERTIES

    Can be used for:

    Viscosity

    Density

    Thermal Conductivity

    .

    As for the source terms works on a cell-by-cell basis

    ME469B/6/GI 32

    Material Properties

    Define Material Property

    All the available UDFs

    Are shown in the menu

  • 7/30/2019 User Defined Programming

    17/33

    17

    ME469B/6/GI 33

    Execute on Demand

    Define User Defined Execute on Demand

    To perform operations instantaneously : EXECUTE_ON_DEMAND

    It is executed when activated by the user

    Can be used for:

    Debugging

    Postprocessing

    .

    ME469B/6/GI 34

    User Defined Scalar

    In addition to the Continuity and Momentum Equations (and Energy)

    generic transport equations can be solved (up to 50!)

    To include scalars in the calculations

    1) Define the number of scalars

    Define User Defined User Defined Scalars

    2) Define the diffusion and source terms in the generic equation

  • 7/30/2019 User Defined Programming

    18/33

    18

    ME469B/6/GI 35

    User Defined Scalar

    Define Material Property

    When UDS are defined in the material property panel the diffusivity of the

    scalars MUST be defined

    Note that the default diffusivity for the scalars is constant and equal to 1!

    ME469B/6/GI 36

    User Defined Scalar

    Boundary conditions for the scalars can be defined as

    Constant Value

    Constant Gradient

    User Defined

    Define Boundary Conditions Wall

  • 7/30/2019 User Defined Programming

    19/33

    19

    ME469B/6/GI 37

    User Defined Scalar

    The Source terms for the scalars are set using the DEFINE_SOURCE macro

    Introduced before

    The scalar equations can be further customized

    1) Convective terms can be modified using the macro

    DEFINE_UDS_FLUX

    2) Unsteady term can be modified using the macro

    DEFINE_UDS_UNSTEADY

    ME469B/6/GI 38

    User Defined Memory

    The User Defined Scalars are used to solve additional equations eventually

    coupled to the mean flow equations

    Sometimes it is useful to define temporary field variables to store and retrieve

    values not directly available

    UDM are defined:

    More efficient storage compared to User Defined Scalars

    Define User Defined User Defined Memory

  • 7/30/2019 User Defined Programming

    20/33

    20

    ME469B/6/GI 39

    I/O in UDF

    User Defined Scalars and User Defined Memory are AUTOMATICALLY

    Stored in the Fluent Data files

    Additional I/O (from and to the Fluent Case and Data files) can be

    Accomplished using the macro DEFINE_RW_FILE

    Define User Defined Function Hooks

    ME469B/6/GI 40

    Detailed Programming

    The macros introduced before are interpreted/compiled and attached to

    the various Fluent panels

    The detailed programming is based on additional macros that allow to

    loop on cells to retrieve field variables, etc.

    Loop Macros

    Geometry Macros

    Field Variable Macros

    Control Macros

    Arithmetic and Trigonometric Macros

    Before looking at the Macros, the Fluent Data structure in introduced

  • 7/30/2019 User Defined Programming

    21/33

    21

    ME469B/6/GI 41

    Data Structure

    It is based on a hierarchy of structures

    Threads (zones) are collection of cells or faces

    Domain is a collections of threads

    Domain

    Thread

    Cell

    Thread

    Face

    Thread

    Face

    ME469B/6/GI 42

    Every zone is associated to a single ID (available in the boundary conditions menu)

    Threads

    Given the ID of a thread the pointer can be retrieved as:

    Thread *tf = Lookup_Thread(domain, ID);

    Given the thread pointer the ID of the zone can be retrieved as:

    ID = THREAD_ID(thread);

    zone

    ID

  • 7/30/2019 User Defined Programming

    22/33

    22

    ME469B/6/GI 43

    Loop Macros

    ME469B/6/GI 44

    cell0cell1

    x

    face

    Cell-face connectivity

    When looping on faces the surrounding cells can be accessed using the macros:

    cell0_thread = F_C0_THREAD(face,thread)

    cell1_thread = F_C1_THREAD(face,thread)

    cell0_id = F_C0(face,thread)cell1_id = F_C1(face,thread)

    When looping on cells adjacent faces and cells can be accessed using the macros:

    for(nf=0;nf

  • 7/30/2019 User Defined Programming

    23/33

    23

    ME469B/6/GI 45

    Geometry Macros

    Many more available; refer to the FLUENT UDF Manual

    ME469B/6/GI 46

    Field Variables Macros

  • 7/30/2019 User Defined Programming

    24/33

    24

    ME469B/6/GI 47

    Field Variables Macros

    Many more available; refer to the FLUENT UDF Manual

    ME469B/6/GI 48

    Control Macros

    Many more available; refer to the FLUENT UDF Manual

  • 7/30/2019 User Defined Programming

    25/33

    25

    ME469B/6/GI 49

    An example of User Defined Programming

    Development of a custom turbulence model can be accomplished using the

    UDFs.

    k-e model with damping functions formulation:

    Low-Re k-e model

    Transport

    Equations

    ME469B/6/GI 50

    Low-Re k-e model

    An example of User Defined Programming

    Eddy Viscosity

    Damping functions

    Turbulent Reynolds number definitions

    Wall boundary conditions

    y

    P =Turbulent Kinetic Energy Production

    S = Strain Rate Magnitude

  • 7/30/2019 User Defined Programming

    26/33

    26

    ME469B/6/GI 51

    Required UDF Routines

    Source Terms DEFINE_SOURCE(k_source, thread, eqn)

    DEFINE_SOURCE(d_source, thread, eqn)

    Diffusivity DEFINE_PROPERTY(ke_diffusivity, domain)

    Boundary Condition DEFINE_PROFILE(wall_d_bc, domain)

    Adjust Routine DEFINE_ADJUST(turb_adjust, domain)

    ME469B/6/GI 52

    Required field variables

    Density C_R(cell,thread)

    Molecular viscosity C_MU(cell,thread)

    Eddy viscosity C_MU_T(cell,thread)

    Strain Rate Magnitude Strain_rate(cell,thread)

    Wall distance C_WALL_DIST(cell,thread)

  • 7/30/2019 User Defined Programming

    27/33

    27

    ME469B/6/GI 53

    #include "udf.h"

    /* Turbulence model constants */#define C_MU 0.09#define SIG_TKE 1.0#define SIG_TDR 1.3#define C1_D 1.44#define C2_D 1.92

    /* User-defined scalars */enum{

    TKE,TDR,N_REQUIRED_UDS

    };

    UDF Header

    Required: includes all Fluent macros

    Constant definitions (global)

    Assign a number to each scalar

    ME469B/6/GI 54

    /* Reynolds number definitions */real Re_y(cell_t c, Thread *t){ return C_R(c,t)*sqrt(C_UDSI(c,t,TKE))*C_WALL_DIST(c,t)/C_MU_L(c,t);}

    real Re_t(cell_t c, Thread *t){ return C_R(c,t)*SQR(C_UDSI(c,t,TKE))/C_MU_L(c,t)/C_UDSI(c,t,TDR);}

    /* Damping Functions */real f_mu(cell_t c, Thread *t){ return tanh(0.008*Re_y(c,t))*(1.+4/pow(Re_t(c,t),0.75));}

    real f_1(cell_t c, Thread *t){ return 1.;}

    real f_2(cell_t c, Thread *t){ return (1.-2/9*exp(-Re_t(c,t)*Re_t(c,t)/36))*(1.-exp(-Re_y(c,t)/12));}

    Damping Functions

    These are defined on a cell-by-cell basis

  • 7/30/2019 User Defined Programming

    28/33

    28

    ME469B/6/GI 55

    Source Term Routines

    DEFINE_SOURCE(k_source, c, t, dS, eqn){

    real G_k;

    G_k = C_MU_T(c,t)*SQR(Strainrate_Mag(c,t));

    dS[eqn] = -2.*C_R(c,t)*C_R(c,t)*C_MU*f_mu(c,t)*C_UDSI(c,t,TKE)/C_MU_T(c,t);

    return G_k - C_R(c,t)*C_R(c,t)*C_MU*f_mu(c,t)*SQR(C_UDSI(c,t,TKE))/C_MU_T(c,t);}

    The production term in the k equation is:

    e is obtained from the definition of the eddy viscosity to increase the coupling

    between the equations and to define an implicit term

    ME469B/6/GI 56

    Source Term Routines

    DEFINE_SOURCE(d_source, c, t, dS, eqn){

    real G_k;

    G_k = C_MU_T(c,t)*SQR(Strainrate_Mag(c,t));

    dS[eqn] = C1_D*f_1(c,t)*G_k/C_UDSI(c,t,TKE)- 2.*C2_D*f_2(c,t)*C_R(c,t)*C_UDSI(c,t,TDR)/C_UDSI(c,t,TKE);

    return C1_D*f_1(c,t)*G_k*C_UDSI(c,t,TDR)/C_UDSI(c,t,TKE)

    - C2_D*f_2(c,t)*C_R(c,t)*SQR(C_UDSI(c,t,TDR))/C_UDSI(c,t,TKE);}

    The production term in the e equation is:

    It contains already both k and e. No need for manipulations!

  • 7/30/2019 User Defined Programming

    29/33

    29

    ME469B/6/GI 57

    Diffusivity

    DEFINE_DIFFUSIVITY(ke_diffusivity, c, t, eqn){

    real diff;real mu = C_MU_L(c,t);real mu_t = C_R(c,t)*C_MU*f_mu(c,t)*SQR(C_UDSI(c,t,TKE))/C_UDSI(c,t,TDR);

    switch (eqn)

    {case TKE:

    diff = mu_t/SIG_TKE + mu;break;

    case TDR:diff = mu_t/SIG_TDR + mu;break;

    default:

    diff = mu_t + mu;}return diff;

    }

    The diffusion terms in the scalar equations are set-up together

    But each equation can have

    a different value

    ME469B/6/GI 58

    Eddy Viscosity

    DEFINE_ADJUST(turb_adjust, domain){

    Thread *t;cell_t c;

    /* Set the turbulent viscosity */thread_loop_c (t, domain)if (FLUID_THREAD_P(t)){begin_c_loop(c,t){

    C_MU_T(c,t) = C_R(c,t)*C_MU*f_mu(c,t)*SQR(C_UDSI(c,t,TKE))/C_UDSI(c,t,TDR);}end_c_loop(c,t)

    }}

    The eddy viscosity is set in the adjust routine (called at the beginning of each

    Iteration) and it is used in the mean flow and in the scalar equations

  • 7/30/2019 User Defined Programming

    30/33

    30

    ME469B/6/GI 59

    Wall Boundary Conditions

    DEFINE_PROFILE(wall_d_bc, t, position){

    face_t f;cell_t c0;Thread *t0 = t->t0; /* t0 is cell thread */real xw[ND_ND], xc[ND_ND], dx[ND_ND], rootk, dy, drootkdy;

    begin_f_loop(f,t){c0 = F_C0(f,t);rootk = sqrt(MAX(C_UDSI(c0,t0,TKE), 0.));F_CENTROID(xw,f,t);C_CENTROID(xc,c0,t0);NV_VV(dx, =, xc, -, xw);

    dy = ND_MAG(dx[0], dx[1], dx[2]);drootkdy = rootk/dy;F_PROFILE(f,t,position) = 2.*C_MU_L(c0,t0)/C_R(c0,t0)*drootkdy*drootkdy;

    }end_f_loop(f,t)

    }

    Only the boundary condition fore is complicated because it requires the value of thederivative of k (the square root of k)

    The derivative is rootk/dy

    rootk is the sqrt of k in

    the adjacent cell center

    dy is the distance between

    cell and face center

    ME469B/6/GI 60

    Set-Up the Problem

    Set-Up a case using the standard k-e

    Define two scalars (TKE, TDR)

    Compile and Attach the UDFs

    Deactivate the Equations for k and e

    Initialize and solve the RANS + TKE and TDR

  • 7/30/2019 User Defined Programming

    31/33

    31

    ME469B/6/GI 61

    Attach the UDF

    Source terms

    Boundary conditions

    ME469B/6/GI 62

    Open UDF Library

    Output in the text window

    Are the functions available

    After compiling the library

    It can be opened in Fluent

  • 7/30/2019 User Defined Programming

    32/33

    32

    ME469B/6/GI 63

    Perform the Simulation

    The convergence is for the mean flow + the two scalars(turbulent quantities deactivated!)

    For postprocessing purposes the UDS have to be used instead of turbulent quantities

    ME469B/6/GI 64

    Additional Information

    Many additional macros are available to implement different physical models

    combustion models

    particles-based models

    .

    It is formally possible to develop additional numerical methods

    flux discretizations

    variable reconstruction and clipping

    .

    Information are available in the FLUENT UDF manual (class web site)

  • 7/30/2019 User Defined Programming

    33/33

    ME469B/6/GI 65

    UDF in other commercial CFD CodesCFX

    CFX (v4) is a structured code; the data structure is much simpler because the

    field variables are accessed directly. It uses 1D arrays where the quantities are

    stored in succession

    CFX UDFs are written in FORTRAN

    For example:

    U(I,J,K)U(IJK) where IJK = (K-1)*NI*NJ+(J-1)*NI

    There are no macros, but examples of subroutines to perform the customization

    USRBCUSRSRCUSRDIF.

    ME469B/6/GI 66

    UDF in other commercial CFD CodesStar-CD

    StarCD is an unstructured code similar to Fluent in term of data organization

    But similar to CFX for the organization of the UDF.

    StarCD has threads (as Fluent) and the UDF work normally on a cell-by-cell

    basis

    StarCD UDFs are written in FORTRAN

    There are no macros, but examples of subroutines to perform the customization

    BCDEFW

    SORSCADIFFUS

    .