|
|
The following example demonstrates the linking of a FORTRAN object file test.o to ANSYS FLUENT, for use in a UDF named test_use.c. This particular UDF is not a practical application but has rather been designed to demonstrate the functionality. It uses data from a FORTRAN-derived object file to display parameters that are passed to the C function named fort_test. This on-demand UDF, when executed from the User-Defined Function Hooks dialog box, displays the values of the FORTRAN parameters and the common block and common complex numbers that are computed by the UDF, using the FORTRAN parameters.
|
|
Note that the names of the functions and data structures have been changed from the capital form in FORTRAN (e.g.,
ADDAB is changed to
addab_). This name "mangling'' is done by the compiler and is strongly system-dependent. Note also that functions returning complex numbers have different forms on different machine types, since C can return only single values and not structures. Consult your system and compiler manuals for details.
|
libudf/ultra/2d
|
The source listing for test.f is shown below.
C FORTRAN function
C test.f
C
C compile to .o file using:
C f77 -KPIC -n32 -O -c test.f (irix6 & suns)
REAL*8 FUNCTION ADDAB(A,B,C)
REAL A
REAL*8 B
REAL*8 YCOM
COMPLEX ZCOM
INTEGER C
INTEGER SIZE
COMMON //SIZE,ARRAY(10)
COMMON /TSTCOM/ICOM,XCOM,YCOM,ZCOM
ICOM=C
XCOM=A
YCOM=B
ZCOM=CMPLX(A,REAL(B))
SIZE=10
DO 100 I=1,SIZE
ARRAY(I)=I*A
100 CONTINUE
ADDAB=(A*C)*B
END
COMPLEX FUNCTION CCMPLX(A,B)
REAL A,B
CCMPLX=CMPLX(A,B)
END
|
src/ultra/2d
|
The source listing for test_use.c is as follows.
#include "udf.h"
#if defined(_WIN32)
/* Visual Fortran makes uppercase functions provide lowercase
mapping to be compatible with UNIX code */
# define addab_ ADDAB
#endif
typedef struct {float r,i;} Complex;
typedef struct {double r,i;} DComplex;
typedef struct {long double r,i;} QComplex; /* FORTRAN QUAD
PRECISION */
/* FORTRAN FUNCTION */
extern double addab_(float *a,double *b,int *c);
/* NOTE on SUN machines that FORTRAN functions returning a complex
number are actually implemented as void but with an extra
initial argument.*/
extern void ccmplx_(Complex *z,float *a,float *b);
extern void qcmplx_(QComplex *z,float *a,float *b);
/* BLANK COMMON BLOCK */
extern struct
{
int size;
float array[10];
} _BLNK__;
/* FORTRAN NAMED COMMON BLOCK */
extern struct
{
int int_c;
float float_a;
double double_b;
float cmplx_r;
float cmplx_i;
} tstcom_;
DEFINE_ON_DEMAND(fort_test)
{
float a=3.0,float_b;
double d,b=1.5;
int i,c=2;
Complex z;
QComplex qz;
d = addab_(&a,&b,&c);
Message("\n\nFortran code gives (%f * %d) * %f = %f\n",a,c,b,d);
Message("Common Block TSTCOM set to: %g %g %d\n",
tstcom_.float_a,tstcom_.double_b,tstcom_.int_c);
Message("Common Complex Number is (%f + %fj)\n",
tstcom_.cmplx_r,tstcom_.cmplx_i);
Message("BLANK Common Block has an array of size %d:
\n",_BLNK__.size);
for (i=0; i <_BLNK__.size ; i++)
{
Message("array[%d] = %g\n",i,_BLNK__.array[i]);
}
float_b=(float)b;
ccmplx_(&z,&a,&float_b);
Message("Function CCMPLX returns Complex Number:
(%g + %gj)\n",z.r,z.i);
qcmplx_(&qz,&a,&float_b);
Message("Function QCMPLX returns Complex Number:
(%g + %gj)\n",qz.r,qz.i);
}
|
#---------------------------------------------------------------#
# User modifiable section.
#---------------------------------------------------------------#
SOURCES= test_use.c
FLUENT_INC= /
path
/ansys_inc/v120/fluent
# Precompiled User Object files (for example .o files from .f
sources)
USER_OBJECTS= test.o
Note that in the previous example, path represents the directory where you installed ANSYS FLUENT.
make "FLUENT_ARCH=ultra"
|