# Function Format

An AcuTrace user-defined function has the following form (in C).

```
#include "acusim.h"
#include "ufp.h"
UFP_PROTOTYPE(usrFunc);
Void usrFunc (
UfpHd ufpHd, /* 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() */
```

Note that

- The order of the arguments is slightly different than the order in an AcuSolve user-defined function.
- The first argument is "ufpHd" not "udfHd".
- The header file "ufp.h" is included, not "udf.h".

- Integer
- type integer
- Real
- type floating point
- String
- type string
- Void
- type void

- The definitions of symbolic constants, such as UFP_PARTICLE_MARKER and UFP_PARTICLE_ID. These constants are used to access data.
- The prototypes of support routines
- The macro UFP_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.

- ufpHd
- 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 pass ufpHd to the
function ufpGetTime(), as in:
`Real time ; ... time = ufpGetTime( ufpHd ) ;`

- outVec
- This is the resulting vector of the user function. You must fill this vector before returning. On input this array contains all zeros.
- nItems
- This is the first dimension of outVec, which specifies the number of items that needs to be filled.
- vecDim
- This is the second dimension of outVec, which specifies the vector dimension of the particular data.

```
#include "acusim.h"
#include "ufp.h"
UFP_PROTOTYPE(usrEnergy);
Void usrEnergy (
UfpHd ufpHd, /* 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 */
Real* t_fluid ; /* fluid temperature */
Real* h_particle ; /* particle energy */
Real mpXcp ; /* mass * c_p for particle */
Real cond ; /* conductivity */
Real* jac ; /* source jacobian */
usrVals = ufpGetUsrVals( ufpHd ) ;
cond = usrVals[0] ;
mpXcp = usrVals[1] ;
t_fluid = ufpGetFlowData( ufpHd,UFP_FLOW_TEMPERATURE ) ;
h_particle = ufpGetUdfData( ufpHd, 0 ) ;
outVec[0] = -cond * ( h_particle[0] / mpXcp - t_fluid [0] ) ;
jac = ufpGetJac( ufpHd, UFP_JAC_UDF_VARIABLES ) ;
jac[0] = -cond / mpXcp ;
}
```

```
#include "acusim.h"
#include "ufp.h"
UFP_PROTOTYPE(usrEnergy);
Void usrEnergy (
UfpHd ufpHd, /* Opaque handle for accessing data */
Real* outVec, /* Vector dimension of outVec */
Integer nItems, /* Number of items in outVec */
Integer vecDim, /* Vector dimension of outVec */
)
{
Real* usrVals ; /* user values */
Real* t_fluid ; /* fluid temperature */
Real* h_particle ; /* particle energy */
Real* jac ; /* source jacobian */
usrVals = ufpGetUsrVals( ufpHd ) ;
t_fluid = ufpGetFlowData( ufpHd, UFP_FLOW_TEMPERATURE ) ;
h_particle = ufpGetUdfData( ufpHd, 0 ) ;
jac = ufpGetJac( ufpHd, UFP_JAC_UDF_VARIABLES ) ;
usrEnergyF( usrVals, t_fluid, h_particle, jac, outVec ) ;
}
```

```
subroutine usrEnergyF ( usrVals, t_fluid, h_particle, jac, outVec )
real*8 usrVals(2), t_fluid, h_particle, jac, outVec
real*8 cond, mpXcp
cond = usrVals(1)
mpXcp = usrVals(2)
outVec = -cond * ( h_particle / mpXcp – tFluid )
jac = -cond / mpXcp
return
end
```

Note that you are responsible for Fortran/C name conversion.

```
#include "acusim.h"
#include "ufp.h"
UFP_PROTOTYPE(usrVel);
Void usrVel (
UfpHd ufpHd, /* Opaque handle for accessing data */
Real* outVec, /* Output Vector */
Integer nItems, /* Number of items in outVec */
Integer vecDim /* Vector dimension of outVec */
)
{
Real *data ;
Integer dir, item ;
if ( vecDim != 3 ) {
printf( "vecDim = %d, but must equal 3 instead\n", vecDim ) ;
exit( 0 ) ;
}
data = ufpGetFlowData( ufpHd, UFP_FLOW_VELOCITY ) ;
for ( dir = 0 ; dir < 3 ; dir++ ) {
for ( item = 0 ; item < nItems; item++ ) {
outVec[item+dir*nItems] = data[dir] ;
}
}
}
```

In the current uses of AcuTrace user defined functions, nItems always equals 1.