Running Parallel UDF on Linux OS
Platform: Apocrita, QMUL, HPC
Goal: imposing 2nd stokes wave on velocity inlet BC, ANSYS Fluent
velocity components of 2nd Stokes wave is defined by UDF
Steps:
1.
Edit source code
2.
Setup the Directory structure
3.
Build the UDF library
. Load the UDF Library Load and Hood the UDF to specified BCs in journal file
. Load the UDF Library Load and Hood the UDF to specified BCs in journal file
1. Source code
x component of 2nd stokes wave
/*second order stokes wave at inlet Boundary, wave velocity components are from equations 3.27 and 3.58, Pengzhi lin. numerical modeling of water waves. CRC press, 2008*/
#include "udf.h"
#define pi 3.14159265359 /*define constants*/
#define U 0.6 /*free stream velocity*/
#define H 0.076 /*wave height*/
#define g 9.81 /*gravity acceleration*/
#define L 4.8 /*wave length*/
#define d 1.6 /*water depth*/
#define T 1.456/*effective wave period (include doppler effect)*/
/*DEFINE_PROFILE: define an inlet velocity profile that varies as a function of z coordinates or t.*/
DEFINE_PROFILE(x_velocity,ft,var) /* DEFINE Macros, ft is a thread; var:index */
{
/*define variables*/
real r[ND_ND]; /*Coordinates, r[0] mean x coordinates, r[1] means y coordinates*/
real k; /*wave number*/
real z; /*z(vertical) axis, gravity direction*/
real omega; /*effective wave angular velocity*/
real t; /*t*/
k = 2.0*pi/L; /*assign values to variables*/
omega=2.0*pi/T;
t = CURRENT_TIME; /* Special Fluent macro, current running t */
face_t f; /* "f" is a face index for each face on the boundary */
begin_f_loop(f,ft)/* face loop macro ,loop over all faces in a given face thread,i.e. "ft" */
{
F_CENTROID(r,f,ft); /*F_CENTROID finds the coordinate position of the centroid of the face "f" and stores the coordinates in the "r" array */
z =r[1]; /* r[1] is y coordinate,r[2] is z coordinate */
F_PROFILE(f,ft,var) = U + H*g*k*cosh(k*(z-0.782+d))*cos(-omega*t)/(2.0*(omega-k*U)*cosh(k*d)) + 3.0*H*H*(omega-k*U)*k*cosh(2.0*k*(z-0.782+d))*cos(-2.0*omega*t)/(16.0*pow(sinh(k*d),4.0));
/*x-velocity component (flow direction): u_r+U= U + H*g*k*cosh(k*(z+d))*cos(-omega*t)/(2.0*(omega-k*U)*cosh(k*d)) + 3.0*H*H*(omega-k*U)*k*cosh(2.0*k*(z+d))*cos(-2.0*omega*t)/(16.0*pow(sinh(k*d),4.0)); z=0 is the mean free surface levelin the theory model, however, free surface level is z=-0.782m in the Fluent geometry model*/
}
end_f_loop(f,ft)
}
vertical component of 2nd stokes wave
/*vertical-velocity component (flow direction) of second order stokes wave at inlet Boundary, wave velocity components are from equations 3.27 and 3.58, Pengzhi lin. numerical modeling of water waves. CRC press, 2008*/
#include "udf.h"
#define pi 3.14159265359 /*define constants*/
#define U 0.6 /*free stream velocity*/
#define H 0.076 /*wave height*/
#define g 9.81 /*gravity acceleration*/
#define L 4.8 /*wave length*/
#define d 1.6 /*water depth*/
#define T 1.456/*effective wave period (include doppler effect)*/
/*DEFINE_PROFILE: define an inlet velocity profile that varies as a function of z coordinates or t.*/
DEFINE_PROFILE(vertical_velocity,ft,var) /* DEFINE Macros, ft is a thread; var:index */
{
/*define variables*/
real r[ND_ND]; /*Coordinates, r[0] mean x coordinates, r[1] means y coordinates; r[2] is z coordinates*/
real k; /*wave number*/
real z; /*z(vertical) axis*/
real omega; /*effective wave angular velocity*/
real t; /*t*/
k = 2.0*pi/L; /*assign values to variables*/
omega=2.0*pi/T;
t = CURRENT_TIME; /* Special Fluent macro, current running t */
face_t f; /* f is a face index for each face on the boundary */
begin_f_loop(f,ft)/* face loop macro ,loop over all faces in a given face thread "ft" */
{
F_CENTROID(r,f,ft); /*F_CENTROID finds the coordinate position of the centroid of the face "f" and stores the coordinates in the "r" array */
z =r[1]; /* r[1] means y coordinates */
F_PROFILE(f,ft,var) = H*g*k*sinh(k*(z-0.782+d))*sin(-omega*t)/(2.0*(omega-k*U)*cosh(k*d)) + 3.0*H*H*(omega-k*U)*k*sinh(2.0*k*(z-0.782+d))*sin(-2.0*omega*t)/(16.0*pow(sinh(k*d),4.0));
/* in the Fluent mode, free surface level is z=0.782m, positive z is in the gravity direction,however, z=0 is the mean free surface level, and z is negative gravity direction in the theory of wave */
/* verticla velocity: w_r= 2.0*a*g*k*sinh(k*(z+d))*sin(-omega*t)/(2.0*(omega-k*U)*cosh(k*d)) + 3.0*2.0*a*2.0*a*(omega-k*U)*k*sinh(2.0*k*(z+d))*sin(-2.0*omega*t)/(16.0*pow(sinh(k*d),4.0)); */
}
end_f_loop(f,ft)
}
2. Set Up the Directory Structure
For compiled UDFs
on Linux OS, three ANSYS Fluent files are required to build your shared UDF
library: makefile.udf,
makefile.udf2,
and user.udf.
#
Makefile to call user's makfile for user defined functions. # Usage: make "FLUENT_ARCH=arch"
Steps
1. In your working directory, make a directory
that will store your UDF library (for example, libudf).
2. Copy makefile.udf2 to
the library directory and and name it “Makefile”
cp /share/apps/ansys/17.0.0/v170/fluent/fluent17.0.0/src/udf/makefile.udf2 /data/home/exw692/UDF/libudf/
cp /share/apps/ansys/17.0.0/v170/fluent/fluent17.0.0/src/udf/makefile.udf2 /data/home/exw692/UDF/libudf/
Notes
Installation path of makefile on Apocrita
/share/apps/ansys/17.0.0/v170/fluent/fluent17.0.0/src/udf/makefile.udfInstallation path of makefile on Apocrita
/share/apps/ansys/17.0.0/v170/Icepak/icepak17.0/Fluent.Inc/fluent17.0.0/src/udf/makefile.udf
/share/apps/ansys/18.0.0/v180/AFD/afd/linx64/runTimeLibraries/fluent/fluent18.0.0/src/udf/makefile.udf
/share/apps/ansys/18.0.0/v180/fluent/fluent18.0.0/src/udf/makefile.udf
/share/apps/ansys/18.0.0/v180/Icepak/icepak18.0/Fluent.Inc/fluent18.0.0/src/udf/makefile.udf
3. In the “libudf”
library directory, make a source directory named “src”.
4. Copy source
file (udf.c) to /src directory
5. Copy makefile.udf to
the /src directory
cp /share/apps/ansys/17.0.0/v170/fluent/fluent17.0.0/src/udf/makefile.udf /data/home/exw692/UDF/libudf/src
or
cp /share/apps/ansys/18.0.0/v180/fluent/fluent18.0.0/src/udf/makefile.udf /data/home/exw692/UDF/libudf/src
6. create two sub-directories in directory named“lnamd64”
Possible file names
2d or 3d single-precision
serial 2D or 3D
2ddp or 3ddp double-precision
serial 2D or 3D
2d_node and 2d_host single-precision
parallel 2D
3d_node and 3d_host single-precision
parallel 3D
2ddp_node and 2ddp_host double-precision parallel 2D
3ddp_node
and 3ddp_host double-precision
parallel 3D
i.e.
7. Copy user.udf from
path/ansys_inc/v171/fluent/fluent17.1.0/src/user.udf
to all the sub-folders, libudf/lnamd64/3ddp_host,
libudf/lnamd64/3ddp_node).
8. copy the “udf.h”
Header File in Your Files, /libudf, /src
/
/
/
3. Build the UDF Library
After you have set
up the folder structure and put the files in the proper places, you can compile
and build the shared library using the TUI.
1. Edit
every user.udf
file
set the following
parameters: CSOURCES,
HSOURCES,
and ANSYS Fluent path.
/
/
CSOURCES = vertical_component_2nd_stokes_wave.c
x_component_2nd_stokes_wave.c
HSOURCES = udf.h
FLUENT_INC=/share/apps/ansys/17.0.0/v170/fluent
/
#CSOURCES: The name
of your source file(s)
#HSOURCES: name of
head file
#FLUENT_INC: fluent
installation path
2. execute
the Makefile
make "FLUENT_ARCH=lnamd64"
In your library directory (for example, libudf), execute the Makefile by typing a command that begins
with make and includes the architecture of the machine you will run ANSYS Fluent on, which you identified
in a previous step. For example, for the Linux (lnamd64) architecture type:
make "FLUENT_ARCH=lnamd64"
with make and includes the architecture of the machine you will run ANSYS Fluent on, which you identified
in a previous step. For example, for the Linux (lnamd64) architecture type:
make "FLUENT_ARCH=lnamd64"
4. Load the UDF Library and hook UDF to specified BCs
rc e387_UDF.cas.gz
rd e387_UDF_800.dat.gz
;load UDF library "libudf"
/define/user-defined/compiled-functions/ load "libudf"
;set boundary condition at velocity inlet
/define boundary-conditions velocity-inlet inlet no yes yes no 0 yes no 0 yes yes "udf" "x_velocity::libudf" yes yes "udf" "vertical_velocity::libudf" yes no 1 no 1
;set drag moment and monitor in y coordinate on "blades" surface
/solve/monitors/force/unscaled? Yes
/solve/monitors/force/set-drag-monitor cd yes blades () no yes cd-1 no no 0 1 0
/solve/monitors/force/set-moment-monitor moment yes blades () no yes cm-history no no 0 0 0 0 1 0
;save residuals
(display "Save the residual in a file") (newline)
(let ((writefile (lambda (p)
(define np (length (residual-history "iteration")))
(let loop ((i 0))
(if (not (= i np))
(begin (define j (+ i 1))
(display (list-ref (residual-history "iteration") (- np j)) p) (display " " p)
(display (list-ref (residual-history "continuity") (- np j)) p) (display " " p)
(display (list-ref (residual-history "x-velocity") (- np j)) p) (display " " p)
(display (list-ref (residual-history "y-velocity") (- np j)) p) (display " " p)
(display (list-ref (residual-history "z-velocity") (- np j)) p) (display " " p)
(display (list-ref (residual-history "k") (- np j)) p) (display " " p)
(display (list-ref (residual-history "omega") (- np j)) p)
(newline p)
(loop (+ i 1))
)
)
)
) )
(output-port (open-output-file "residual_1000_e387_udf.dat")))
(writefile output-port)
(close-output-port output-port))
solve/set/time-step 0.02
solve/dual-time-iterate 100 20
wd e387_UDF_900.dat.gz
exit
yes
rd e387_UDF_800.dat.gz
;load UDF library "libudf"
/define/user-defined/compiled-functions/ load "libudf"
;set boundary condition at velocity inlet
/define boundary-conditions velocity-inlet inlet no yes yes no 0 yes no 0 yes yes "udf" "x_velocity::libudf" yes yes "udf" "vertical_velocity::libudf" yes no 1 no 1
;set drag moment and monitor in y coordinate on "blades" surface
/solve/monitors/force/unscaled? Yes
/solve/monitors/force/set-drag-monitor cd yes blades () no yes cd-1 no no 0 1 0
/solve/monitors/force/set-moment-monitor moment yes blades () no yes cm-history no no 0 0 0 0 1 0
;save residuals
(display "Save the residual in a file") (newline)
(let ((writefile (lambda (p)
(define np (length (residual-history "iteration")))
(let loop ((i 0))
(if (not (= i np))
(begin (define j (+ i 1))
(display (list-ref (residual-history "iteration") (- np j)) p) (display " " p)
(display (list-ref (residual-history "continuity") (- np j)) p) (display " " p)
(display (list-ref (residual-history "x-velocity") (- np j)) p) (display " " p)
(display (list-ref (residual-history "y-velocity") (- np j)) p) (display " " p)
(display (list-ref (residual-history "z-velocity") (- np j)) p) (display " " p)
(display (list-ref (residual-history "k") (- np j)) p) (display " " p)
(display (list-ref (residual-history "omega") (- np j)) p)
(newline p)
(loop (+ i 1))
)
)
)
) )
(output-port (open-output-file "residual_1000_e387_udf.dat")))
(writefile output-port)
(close-output-port output-port))
solve/set/time-step 0.02
solve/dual-time-iterate 100 20
wd e387_UDF_900.dat.gz
exit
yes
Reference
https://support.ansys.com/AnsysCustomerPortal/en_us/Knowledge%20Resources/Solutions/FLUENT/2041940
https://support.ansys.com/AnsysCustomerPortal/en_us/Knowledge%20Resources/Solutions/FLUENT/2050493
Comments
Post a Comment