Encyclopaedia Index

### FUNCTion library for use in GROUND coding

#### 1. The FNxxx subroutines

A library of subroutines is available for CALLing from GROUND coding when arithmetic operations are to be performed on EARTH arrays.

These subroutines operate on STOREd or SOLVEd phi-variables, COefficients, VALues, and auxiliary variables, or on parts of the F-array for which storage has been created by MAKE, NFUSER or GXMAKE.

In the following argument lists:

• Y always refers to the index of the EARTH variable, which the function returns as an array of values;
• X,X1,X2 etc refer to the indices of the EARTH arrays which are used in calculating Y;
• A,B,C etc. are real constants;
• LOGIC is a logical constant, and
• I is an integer constant.

The variable Y is calculated over the area of the 'PATCH' which is currently active. The limits of this patch are set by COVAL in the SATELLITE, when the function is responding to the setting of the coefficient or value of COVAL to GRND.

Otherwise it is calculated over the whole of the constant-z slab, unless IXF, IXL, IYF and IYL are explicitly set before the function CALL.

The functions are (with recently-introduced ones presented first:-

```
FNZERO_IN_SLD_VAC              Y = 0.0 in cells occupied by solid
or having zero volume porosity
FNQUOT(Y,X1,X2)                Y = X1 / X2
FN0(Y,X)                       Y = X
FN1(Y,A)                       Y = A
FN2(Y,X,A,B)                   Y = A + B*X
FN3(Y,X,A,B,C)                 Y = A + B*X + C*X**2
FN4(Y,X,A,B,C,D)               Y = A + B*X + C*X**2 + D*X**3
FN5(Y,X,A,B,C,D,E)             Y = A + B*X + C*X**2 + D*X**3+E*X**4
FN6(Y,X,A,B)                   Y = 1./(A + B*X)
FN7(Y,X,A,B,C)                 Y = (A + B*X)/(1.0 + C*X)
FN8(Y,X,A,B,C,D)               Y = A*(X + B)**C + D
FN9(Y,X,A,B,C,D)               Y = A*((X + B)**C)/(1.0 + D*X)
FN10(Y,X1,X2,A,B1,B2)          Y = A + B1*X1 + B2*X2
FN11(Y,X1,X2,A,B1,B2,C1,C2,C12)
Y = A + B1*X1 + B2*X2 + C1*X1**2 + C2*X2**2 + C12*X1*X2
FN12(Y,X1,X2,X3,A,B1,B2,B3) Y = A + B1*X1 + B2*X2 + B3*X3
FN13(Y,X1,X2,X3,X4,A,B1,B2,B3,B4)
Y = A + B1*X1 + B2*X2 + B3*X3 + B4*X4
FN14(Y,X1,X2,X3,X4,X5,A,B1,B2,B3,B4,B5)
Y = A + B1*X1 + B2*X2 + B3*X3 + B4*X4 + B5*X5
FN15(Y,X1,X2,A,B1) Y = (A + B1*X1)/X2
FN16(Y,X1,X2,A,B1,B2) Y = (A + B1*X1)/(1.0 + B2*X2)
FN17(Y,X1,X2,X3,A,B1,B2,B3) Y = (A + B1*X1)/(1.0 + B2*X2 + B3*X3)
FN18(Y,X1,X2,X3,X4,A,B1,B2,B3,B4)
Y = (A + B1*X1 + B2*X2)/(1.0 + B3*X3 + B4*X4)
FN19(Y,X1,X2,X3,X4,A,B,C) Y = A*X1*X2*X3*EXP(B/(C + X4))
FN20(A,X1,X2,X3) A=PATCH-WISE SUM AT SLAB of X1*X2*X3
FN21(Y,X1,X2,A,B) Y = A + B*X1*X2
FN22(Y,A) Y = AMAX1(Y,A)
FN23(Y,A) Y = AMIN1(Y,A)
FN24(Y,X1,X2,A,B,C) Y = A * X1 + B * AMAX1(0.0,X2 + C)
FN25(Y,A) Y = A * Y
FN26(Y,X) Y = Y * X

FN026(Y,X1,X2): Y = X1 * X2
FN27(Y,X) Y = Y / X
FN27D(Y,X1,X2): Y = Y / (X1 * X2)

FN28(Y,X,A) Y = A / X
FN28P2(Y,X1,X2,A,B): Y = A / (X1 + B * X2)

FN29(Y,IPHASE,IDIR,IU,IV,IW) Y = resultant velocity of the phase
along wall, the normal to which is specified by IDIR as follows:
IDIR=1 for x direction;
IDIR=2 for y direction; and
IDIR=3 for z direction.

The last 3 arguments must be set as follows:
IU=1 if STORE(U1)=.true., else IU=0;
IV=1 if STORE(V1)=.true., else IV=0; and,
IW=1 if STORE(W1)=.true., else IW=0.

The second parameter IPHASE = 1 for first-phase velocities,
U1, V1, W1; and
IPHASE = 2 for second-phase velocities,
U2, V2, W2.

FN30(Y) Y = SQRT(Y)
FN30a(Y,X) Y = SQRT(X)
FN31(Y,X1,X2,A,B1,B2) Y = A * (X1**B1) * (X2**B2)
FN32(Y,X,A,B) Y = Y * exp(A/(B + X))
FN33(Y,A) Y = Y + A
FN34(Y,X,A) Y = Y + A * X
FN35(Y,X,A,B) Y = Y + A * X**B
FN36(Y,X,A,B) Y = Y + A * exp(B * X)
FN37(Y,X,A) Y = Y * X**A
FN38(Y,X,A) Y = Y * A * exp(B * X)
FN39(Y,X1,X2,X3,X4) Y = X1 * X2 + X3 * X4
FN40(Y) Y = ABS(Y)
FN41(Y,X,A,B) Y = SIN(A * X + B)
FN42(Y,X,A,B) Y = COS(A * X + B)
FN43(Y,X,A,B) Y = ALOG(A * X + B)
FN44(Y,X,A,B,C) Y = A * X / (1.0 + B * X ** C)
FN45(Y,X,A) Y = Y * SIN(X +A)
FN46(Y,X,A,B) Y = Y * (A + B * X)
FN47(Y,A,B) Y = AMAX1(A,AMIN1(B,Y))
FN48(Y,X1,X2,X3,X4,A,B) Y = A*X1*X2 + B*X3*X4
FN49(Y,X) Y = Y + X**2
FN50(Y,I) Y = Y**I
FN51(Y,A) Y = Y**A
FN52(Y,X,I) Y = Y * X**I
FN53(Y,X1,X2,A) Y = Y + A*X1*X2
FN54(Y,X1,X2,A) Y = Y + A*X1/X2
FN55(Y,X1,X2,X3,A) Y = A*X1*X2*X3
FN56(Y,X1,X2,X3,A) Y = A*X1*X2/X3
FN57(Y,X1,X2,X3,A) Y = Y + A*X1*X2*X3
FN58(Y,X) Y = X where X > 0.0
FN59(Y,X) Y = 0.0 where X = 0.0
FN60(Y,X) Y = Y + X
FN61(Y,X,A) Y = A * X**3
FN62(Y,X,A) Y = A * Y/X**3
FN63(Y,X,A) Y = A * X**4
FN64(Y,X,A) Y = Y + A * X**4
FN65(Y1,Y2,A) Y1 = A, Y2 = A
FN66(Y,X,A,B) Y = AMAX1(0.0, A + B*X)
FN67(Y,X1,X2,X3,B1,B2) Y = (B1*X1 + B2*X2)/X3
FN68(Y,X1,X2,X3,A,B) Y = (A + B*X1)/(X2*X3)
FN69(Y,X,A,B) Y = Y * (A + B/X)
FN70(Y,X,A,B) Y = B/X when X >> A
FN71(Y,X1,A,B) Y = A * X1**B
FN72(Y,X1,A,I) Y = A * X1**I
FN73(Y,X1,A,I) Y = A * Y * X1**I
FN74(Y,X1,A,B,C)
Y = A * ((X1+C)**3 + (X1+C)**2*(B+C) + (X1+C)*(B+C)**2 + (B+C)**3
FN75(X,X1,A,B,C)
Y = A * abs(X1 - B)**C
FN76(Y,X1,X2) Y = Y * X1 / X2
FN77(Y,X1,X2) Y = Y * X1 * X2
FN78(Y,X1,X2,X3,A) Y = Y + A*X1 * X2 / X3
FN79(A,X1,X2,X3,X4) A = Patchwise sum of X1*X2*X3*X4
FN80(A,X1,X2) A = Patchwise sum of X1*X2
FN82(Y,X1,A,B) Y = AMAX1(Y , A + B*X1)
FN83(Y,X1,A,B) Y = AMIN1(Y , A + B*X1)
FN84(Y,X1,X2,A,B) Y = A / (X1 + B*X2)
FN85(Y,X1,X2,A) Y = Y * X1 * (A - X2)
FN95(Y,X1,A,B,C) Y = A * (X1 - B)**C
FN96(Y,X1,X2,A) Y = Y / (X1 * X2)**A
FN97(Y,X1,X2,A,B,C) Y = A * X1 * (X2 - B)**C
FN98(Y,CM,A,B,C) superseded by GXMDOT
FN99(Y,X,CF,A,B,C,D) superseded by GXCFIP
FN101(Y,X,A) Y is a solution of x = (y - 0.5*sin(2.0*y)) / pi.
This is used for determining the half-angle y subtended at
the centre of a circular pipe by the surface of a liquid layer,
given the volume fraction, X, of the liquid.
The solution is obtained by iteration, which ceases after 20
cycles or when Y changes by less than A, whichever happens first.
FN102(Y,X,A,B,C) y=a*b*(c**3)*(.6666*(sinx)**3-cosx*(x-0.5*sin2x))
This calculates the hydrostatic force on the segment of the
cross-section of a circular-sectioned pipe occupied by the
heavier fluid.
The half-angle at each cross-section is X, supplied by FN101 .
A is the acceleration due to gravity.
B is the density difference between the heavier and lighter fluids.
C is the radius of the pipe.
FN103(Y,X,IDIR) Y = X(next)-X
where IDIR =1,2,3 or for north, south, east or west.
FN104(Y,X,IPLUS) Y = -X and X = Y(next)
This subroutine puts -X into Y, and then adds X;
here 'next' refers to the north when IPLUS=1 and
east when IPLUS=NY.
FN105(Y,X1,X2,IPLUS) Y = X1
unless X2 is negative, in which case Y = X1 shifted IPLUS cells
from the current one.
For example, if X2 refers to v velocities and IPLUS is 1,
Y = X1 in the North cell when v is negative.
FN107(Y,X1,X2,X3) Y = a weighted average of X1 and X2,
the weighting factor depending on the ratio of the values of
convection flux X3 to the time flux, ie. on the Courant number.
FN108(Y,SUM) which returns the patchwise sum of all Y's at the
current Z slab in SUM.
FN108D(X1,X2,SUM1,SUM2) which returns the patchwise sum of X1 in SUM1,
and that  X2 in SUM2
FN109(Y,X1,X2,X3) Y = X1*(X2-X3)
FN110(Y,X1,X2) for X2 >= 0 , Y = Y + X2
for X2 >0 , X1="X1" X2
FN111(Y,X) Y = Y/SQRT(ABS(Y)) X = X/ABS(Y)
FN112(Y,X1,X2,X3) Y=Y+X1*(X2-X3)
FN117(Y,X1,X2,IPLUS) Source term for fully-implicit
central- differencing scheme with non-uniform grid

FNDUDX(Y,U1)  for y=d(u1)/dx ; FNDUDX(Y,U2) for y=d(u2)/dx.
FNDUDY(Y,U1)  for y=d(u1)/dy ; FNDUDY(Y,U2) for y=d(u2)/dy.
FNDUDZ(Y,U1)  for y=d(u1)/dz ; FNDUDZ(Y,U2) for y=d(u2)/dz.
FNDVDX(Y,V1)  for y=d(v1)/dx ; FNDVDX(Y,V2) for y=d(v2)/dx.
FNDVDY(Y,V1)  for y=d(v1)/dy ; FNDVDY(Y,V2) for y=d(v2)/dy.
FNDVDZ(Y,V1)  for y=d(v1)/dz ; FNDVDZ(Y,V2) for y=d(v2)/dz.
FNDWDX(Y,W1)  for y=d(w1)/dx ; FNDWDX(Y,W2) for y=d(w2)/dx.
FNDWDY(Y,W1)  for y=d(w1)/dy ; FNDWDY(Y,W2) for y=d(w2)/dy.
FNDWDZ(Y,W1)  for y=d(w1)/dz ; FNDWDZ(Y,W2) for y=d(w2)/dz.

FNDSDX(Y,SCAL) for y=d(scal)/dx
FNDSDY(Y,SCAL) for y=d(scal)/dy
FNDSDZ(Y,SCAL) for y=d(scal)/dz
(scal is any EARTH index for a scalar dependent variable)

FNGENK(Y,1) for phase-1 , &
FNGENK(Y,2) for phase-2.
Y = 2*( (du/dx)**2 + (dv/dy)**2 + (dw/dz)**2 ) +
(du/dy + dv/dx)**2 + (du/dz + dw/dx)**2 +
(dw/dy + dv/dz)**2

Y = the turbulence-energy-generation rate.
x, y & z = distances. u,v & w = velocities.
For BFC calculations, the subroutine GXGENB uses the
cartesian velocity components UCRT, VCRT AND WCRT.
It is called from GXGENK.

FNSYM(Y,IFACE) Set symmetry values at boundaries
FNVLSQ(Y,1) for phase-1, and
FNVLSQ(Y,2) for phase-2, where Y = U**2 + V**2 + W**2 ,
for use in calculations involving the kinetic energy
of the mean motion.
Only velocities flowing into the cells are taken into account.
FNAV(Y,X,'next') Y = the average of X and X(next),
where 'next' is 'N', 'S', 'E', 'W', 'H' or 'L' .
FNIFDV(Y,X,A,LOGIC):
for LOGIC = .TRUE.  , Y = Y / X
for LOGIC = .FALSE. , Y = Y / A
FNIFML(Y,X,A,LOGIC):
for LOGIC = .TRUE.  , Y = Y * X
FNMAX(Y,X) Y = AMAX1(Y,X)
FNGBFC(Y,iref,IZ)
See SUBROU
section on BFC subroutines.
FNVSLP(Y,A) Y = the maximum of A and
the absolute interphase slip velocity into Y.
If STORE(VREL) is present in Q1, Y will be copied into
LBNAME('VREL').
```

See the Encyclopaedia entry SUBROU for further service subroutines which can be used in GROUND subroutines.

### FUNCTION SUBROUTINES for use in GROUND coding, other than FNxxx

The following function subroutines are available for use in GROUND coding. Uses of many of them are exemplified in GREX3 and GX... They interact with the EARTH module of PHOENICS by accessing the F-array (See the corresponding PHENC entry for an explanation of how they are to be used).

WARNING: integer and logical functions must be declared as such in subroutines in which they are used, eg:

INTEGER HIGH LOGICAL WHF

The functions are:-

### Integer Functions

ANYZ(block-location index,any IZ)
AUX(SWV block-location index)
EAST(INDVAR)
HIGH(INDVAR)
INDONE(INDVAR,IYY,IXX)
INDYX(INDVAR)
INDZ(INDVRZ,IZZ)
L0F(INDVAR)
LOW(INDVAR)
LBNAME('variable name')
LBZ(LB,IZZ)
OLD(INDVAR)
NORTH(INDVAR)
SOUTH(INDVAR)
WEST(INDVAR)

### Real functions

GETONE(INDVAR,VALUE,IYY,IXX)
GETYX(LB,2D array name,NYDIM,NXDIM)
GETZ(INDVAR,1D array name,GZ,NZDIM)
PRNYX('name',array name,NYDIM,NXDIM)
SETYX(LB,2D array name,NYDIM,NXDIM)
VARONE(INDVAR,IYY,IXX)
VARYX(INDVAR)
VARZ(INDVRZ,IZZ)

### CNV(INDVAR)

tests whether the variable has its built-in convection terms activated.

### DFN(INDVAR)

tests whether the variable has its built-in diffusion terms activated.

### EQZ(real variable)

tests whether the variable is equal to 0.0 .

### FLUID1(INDVAR)

tests whether the variable belongs to the first phase fluid or not.

### GEZ(real variable)

tests whether the variable is greater than or equal to 0.0 .

### GRN(real variable)

tests whether the variable equals GRND.

### GRNDNO(number,variable)

tests whether the variable has been set equal to GRNDnumber in the SATELLITE.

### GTZ(real variable)

tests whether the variable is greater than 0.0 .

### HRM(INDVAR)

tests whether the variable is to have its diffusion terms represented by harmonic averaging.

### IPT(INDVAR)

tests whether the variable has its inter-phase transport terms activated.

### LEZ(real variable)

tests whether the variable is less than or equal to 0.0

### LTZ(real variable)

tests whether the variable is less than 0.0 .

### NEZ(real variable)

tests whether the variable is not equal to 0.0 .

### PBP(INDVAR)

tests whether the variable is to have its linear equations solved Jacobi point-by-point.

### PRINT(INDVAR)

tests whether the variable is to have its field tabulated.

### PRNCOR(INDVAR)

tests whether the variable is to have its linear-equation corrections monitored.

### PRNRES(INDVAR)

tests whether the variable is to have its whole-field residuals tabulated/plotted.

### PRNSLR(INDVAR)

tests whether the variable is to have its slab-wise residuals printed (at IZMON).

### PRNSPT(INDVAR)

tests whether the variable is to have its spot-values tabulated plotted.

### PRNWHR(INDVAR)

tests whether the variable is to have its whole-field residuals printed.

### QEQ(variable 1, variable 2)

tests whether real variable 1 is equal to variable 2 .

### QGE(variable 1, variable 2)

tests whether real variable 1 is greater than or equal to variable 2.

### QGT(variable 1, variable 2)

tests whether real variable 1 is greater than variable 2 .

### QLE(variable 1, variable 2)

tests whether real variable 1 is less than or equal to variable 2 .

### QLT(variable 1, variable 2)

tests whether real variable 1 is less than variable 2 .

### QNE(variable 1, variable 2)

tests whether real variable 1 is not equal to variable 2 .

### SOLVE(INDVAR)

tests whether the variable is the dependent variable of a differential equation which is being solved.

### SOR(INDVAR)

tests whether the variable has its built-in source terms activated.

### STORE(INDVAR)

tests whether storage has been provided for the variable in the SATELLITE.

### TRN(INDVAR)

tests whether the variable has its built-in transient term activated

### WHF(INDVAR)

tests whether the variable is to have its linear equations solved in a whole-field manner.

### XPL(INDVAR)

tests whether the variable is to be represented by explicit finite-domain equations.