      SUBROUTINE CXFFT3(CXDATA,MX,MY,MZ,ISIGN,CXWORK)
      PARAMETER (MXTRIG=1024)
C*** Arguments:
      INTEGER ISIGN,MX,MY,MZ
      COMPLEX CXDATA(MX,MY,MZ),CXWORK(MX,MY,MZ)
C
C*** Local variables:
      INTEGER INC,JUMP,K,LOT
      CHARACTER CMSGNM*70
      INTEGER IFAX(13),IFAY(13),IFAZ(13)
      REAL TRIG(MXTRIG)
C
C*** External Subroutines:
      EXTERNAL CFFT99,CFTFAX
C
C*** SAVE statements:
      SAVE MXOLD, MYOLD, MZOLD
C
C*** DATA statements:
      DATA MXOLD,MYOLD,MZOLD/0,0,0/
C***********************************************************************
C
C Purpose:
C Calculates direct and inverse 3-dimensional FFT (in place)
C for complex matrix CXDATA.
C
C Input:
C
C CXDATA(NX, NY, NZ)   --- data array (complex). Will be overwritten.
C MX, MY, MZ           --- dimensions of CXDATA; have to be of the form
C                           2**a 3**b 5**c
C ISIGN = (-1,1)       --- (1 for inverse, -1 direct transform).
C                           Read documentation of "cfft99f.f"
C                           code for definition
C TRIGX(2*MX)
C TRIGY(2*MY)
C TRIGZ(2*MZ)          --- storage arrays. CAN NOT BE OVERWRITTEN
C                          between calls
C CXWORK(MX,MY,MZ)     --- complex work array. Can be overwritten.
C
C Output:
C
C CXDATA               --- 3D Fourier transform
C TRIGX, TRIGY, TRIGZ
C
C Local variables:
C
C IFAX(13)
C IFAY(13)
C IFAZ(13)             --- internal integer info array. Dimension 13
C                          is sufficient for very large nx, ny, nz
C MXOLD,MYOLD,MZOLD    --- switch. Keeps track of previous MX,MY,MZ
C INC
C JUMP
C LOT                  --- define how many FFTs
C                          (see "cfft99.f" documentation)
C
C External documentation for "cfft99f"
C
C              THE fft99 PACKAGE WAS WRITTEN BY 
C              CLIVE TEMPERTON AT ECMWF IN
C              NOVEMBER, 1978.  IT WAS MODIFIED, DOCUMENTED, AND TESTED
C              FOR NCAR BY RUSS REW IN SEPTEMBER, 1980.  IT WAS
C              FURTHER MODIFIED FOR THE FULLY COMPLEX CASE BY DAVE
C              FULKER IN NOVEMBER, 1980.
C
C Efficiency:
C
C The code vectorizes on CRAY-YMP and is more efficient than the
C FOURN routine from "Numerical Recipes" by  W. H. Press, B. P. Flannery
C S. A. Teukolsky, W. T. Vettering. For 64x64x32 case this code
C is >6 faster than FOURN.
C
C If speed is important for even values 
C of n=nx=ny=nz  one should insert dummy
C rows and columns to make dimension  cxdata(n+1, n+1, n+1) to
C avoid bank conflicts (on CRAY).

C History:
C Written by P.J.Flatau, 11/24/1990 with the help of C. Temperton
C 94/06/20 (PJF) added mxold, myold, mzold instead of "icall"
C                vecause of 3DFFT test code
C Copyright (C) 1993, B.T. Draine and P.J. Flatau
C This code is covered by the GNU General Public License.
***********************************************************************
C
C initialize trigs (only once)
      IF(MX.NE.MXOLD .OR. MY.NE.MYOLD .OR. MZ.NE.MZOLD)THEN
         MXOLD=MX
         MYOLD=MY
         MZOLD=MZ
         NTRIG=2*(MX+MY+MZ)
         IF(NTRIG.GT.MXTRIG)THEN
            WRITE(CMSGNM,FMT='(2I5,A)')NTRIG,MXTRIG,
     &         ' 2*NX+2*NY+2*NZ .GT. MXTRIG. Increase MXTRIG! '
            CALL ERRMSG('FATAL','CXFFT3',CMSGNM)
         ENDIF
         LTRIGX=1
         LTRIGY=1+2*MX
         LTRIGZ=1+2*MX+2*MY
         CALL CFTFAX(MX,IFAX,TRIG(LTRIGX))
         CALL CFTFAX(MY,IFAY,TRIG(LTRIGY))
         CALL CFTFAX(MZ,IFAZ,TRIG(LTRIGZ))
      ENDIF
C --- first dimension
      INC=1
      JUMP=MX
      LOT=MY*MZ
      CALL CFFT99(CXDATA,CXWORK,TRIG(LTRIGX),IFAX,INC,JUMP,MX,LOT,ISIGN)
C --- second dimension
      INC=MX
      JUMP=1
      LOT=MX
C --- one plane at a time
      DO 10 K=1,MZ
         CALL CFFT99(CXDATA(1,1,K),CXWORK,TRIG(LTRIGY),IFAY,INC,JUMP,
     &               MY,LOT,ISIGN)
   10 CONTINUE
C --- third dimension
      INC=MX*MY
      JUMP=1
      LOT=MX*MY
      CALL CFFT99(CXDATA,CXWORK,TRIG(LTRIGZ),IFAZ,INC,JUMP,MZ,LOT,ISIGN)
      RETURN
      END
