Function Format
A user-defined function has the following form (in C).
#include "acusim.h"
#include "udf.h"
UDF_PROTOTYPE(usrFunc) ;
Void usrFunc (
UdfHd udfHd, /* Opaque handle for accessing data */
Real* outVec, /* Output vector */
Integer nItems, /* Number of items in outVec */
Integer vecDim /* Vector dimension of outVec */
) {
...
outVec[0] = ... ;
} /* end of usrFunc() */
The header file acusim.h defines the standard C header file, such as
stdio.h and stdarg.h. In addition, the data types
used by AcuSolve are defined. The relevant types are:
- Integer
- Type integer
- Real
- Type floating point
- String
- Type string
- Void
- Type void
The header file udf.h contains the definitions and declarations needed by
the user function:
- The definitions of symbolic constants, such as UDF_VISCOSITY and UDF_ELM_VELOCITY. These constants are used to access data.
- The prototypes of support routines
- The macro UDF_PROTOTYPE(), which may be used to prototype the user function
In addition, it contains the useful macros min(a,b), max(a,b), and abs(a) for the computation of minimum, maximum, and absolute value of integers or floating point numbers.
The user-function name (generically called usrFunc above) may be any name supported in C that starts with the letters usr. This naming convention avoids any potential conflict in function name space.
Four arguments are passed to a user-defined function:
|
This is an opaque handle (pointer) which
contains the necessary information for accessing various data. All supporting routines
require this argument. For example, to access the current time step pass udfHd to the
function udfGetTimeStep(), as in:
|
||||||||||||||||||||||||
|
This is the resulting vector of the user function. You must fill this vector before returning. On input this array contains all zeros. | ||||||||||||||||||||||||
|
This is the first dimension of outVec, which
specifies the number of items that needs to be filled. The value of this parameter depends
on command category. In particular:
where the "Number of Elements" is the number of elements in a block, "Number of Nodes" is the number of nodes in a block, "Number of Surfaces" is the number of surfaces in a block, and "Number of Nodal Pairs" is the number of pairs of nodes in a block. |
||||||||||||||||||||||||
|
This is the second dimension of outVec, which
specifies the vector dimension of the particular data. The value of this parameter also
depends on command category. In particular:
|
The fastest dimension of outVec is nItems, and not vecDim. For example, to fill in a constant
gravity given via user values, you may write the following
code:
#include "acusim.h"
#include "udf.h"
UDF_PROTOTYPE(usrGrav) ;
Void usrGrav (
UdfHd udfHd, /* Opaque handle for accessing data */
Real* outVec, /* Output vector */
Integer nItems, /* Number of items in outVec */
Integer vecDim /* Vector dimension of outVec */
) {
Integer dir ; /* a running direction index */
Integer elem ; /* a running element index */
Real* usrVals ; /* user values */
udfCheckNumUsrVals( udfHd, 3 ) ; /* check for error */
usrVals = udfGetUsrVals( udfHd ) ; /* get the user vals */
for ( dir = 0 ; dir < vecDim ; dir++ ) {
for ( elem = 0 ; elem < nItems ; elem++ ) {
outVec[elem+dir*nItems] = usrVals[dir] ;
}
}
} /* end of usrGrav() */
The corresponding input file command may
be:
GRAVITY( "my gravity" ) {
type = user_function
user_function = "usrGrav"
user_values = { 0, 0, -9.81 }
}
AcuSolve only accesses user-defined functions that are written in
C. To write a user-function in Fortran, you must write a C cover
function via which Fortran routine(s) are called. This cover
function is accessed by AcuSolve. For the above example the C file
may
contain:
#include "acusim.h"
#include "udf.h"
UDF_PROTOTYPE(usrGrav) ;
#define usrGravF usrgravf_ /* FORTRAN name conversion */
Void usrGrav (
UdfHd udfHd, /* Opaque handle for accessing data */
Real* outVec, /* Output vector */
Integer nItems, /* Number of items in outVec */
Integer vecDim /* Vector dimension of outVec */
) {
Real* usrVals ; /* user values */
udfCheckNumUsrVals( udfHd, 3 ) ; /* check for error */
usrVals = udfGetUsrVals( udfHd ) ; /* get the user vals */
usrGravF( outVec, usrVals, &nItems ) ;
} /* end of usrGrav() */
While the Fortran file may
contain:
subroutine usrGravF ( grav, usrVals, nElems )
integer nElems
real*8 grav (nElems, 3), usrVals (3)
integer i, j
c
c ... fill in the vector
c
do j = 1, 3
do i = 1, nElems
grav(i,j) = usrVals (j)
enddo
enddo
c
c return
c
return
end
Note: You are responsible for Fortran/C name conversion.