Fortran TLM Code

Disclaimer: This software is provided "as is", without any form of support. Use at your own risk.

You can use any part of this code in your own work provided that this source is acknowledged.


      PROGRAM TLM3D
*************************************************************
*                                                           *
* Transmission-line modelling of electromagnetic fields in  *
* 3-dimensions using the symmetrical condensed node.        *
*                                                           *
* Written by:                                               *
*   J L Herring                                             *
*                                                           *
* E-mail: tlm@jlherring.uk                                  *
* WWW:    http://www.jlherring.uk/tlm/                      *
*                                                           *
* History:                                                  *
*   Date started    : 10 Dec 1995                           *
*   Updated         : 10 Dec 1995 (HP-UX) 1.00              *
*   Current version : 30 Jun 1996 (HP-UX) 1.10              *
*                     - more efficient scattering           *
*                     - two-sided internal boundaries       *
*                                                           *
*************************************************************

      IMPLICIT NONE

*---- constant declarations

      CHARACTER*(*) VERSN
      INTEGER INUNT,OUTUNT
      INTEGER XMAX0,YMAX0,ZMAX0
      INTEGER NMBCS0,NMNEX0,NMNOU0
      INTEGER PYNX,PZNX,PXNY,PZNY,PYNZ,PXNZ
      INTEGER PYPZ,PZPY,PZPX,PXPZ,PXPY,PYPX
      REAL    Z0

      PARAMETER ( VERSN = '1.10' )
      PARAMETER ( INUNT=7,OUTUNT=8 )
      PARAMETER ( XMAX0=16,YMAX0=16,ZMAX0=16 )
      PARAMETER ( NMBCS0=20,NMNEX0=10,NMNOU0=10 )
      PARAMETER ( PYNX= 1,PZNX= 2,PXNY= 3,PZNY= 4,PYNZ= 5,PXNZ= 6 )
      PARAMETER ( PYPZ= 7,PZPY= 8,PZPX= 9,PXPZ=10,PXPY=11,PYPX=12 )
      PARAMETER ( Z0=376.7 )

*---- variable declarations

      CHARACTER*80 LINE,COMM
      CHARACTER*40 INNAME,OUTNAM
      CHARACTER*2  LORIEN
      CHARACTER    TYP,DIRN,LSIGN
      LOGICAL EX
      INTEGER ERR,N,X,Y,Z,I
      INTEGER X1,Y1,Z1,D,T
      INTEGER XMAX,YMAX,ZMAX,NUMDT
      INTEGER NUMBCS,NUMNEX,NUMNOU
      REAL    DL,VE,VH,OUT
      REAL    VYNX,VZNX,VXNY,VZNY,VYNZ,VXNZ
      REAL    VYPZ,VZPY,VZPX,VXPZ,VXPY,VYPX
      REAL    RHO,V0,VTEMP,VDIFF

*---- array declarations

      CHARACTER BDIRN(NMBCS0),BSIGN(NMBCS0)
      INTEGER BOX1(NMBCS0),BOY1(NMBCS0),BOZ1(NMBCS0)
      INTEGER BOX2(NMBCS0),BOY2(NMBCS0),BOZ2(NMBCS0)
      REAL BRHO(NMBCS0)

      CHARACTER*3 NEID(NMNEX0)
      INTEGER NEX1(NMNEX0),NEY1(NMNEX0),NEZ1(NMNEX0)
      INTEGER NEX2(NMNEX0),NEY2(NMNEX0),NEZ2(NMNEX0)
      REAL NEAMP(NMNEX0)

      CHARACTER*2 NOID(NMNOU0)
      INTEGER NOX1(NMNOU0),NOY1(NMNOU0),NOZ1(NMNOU0)

      COMMON/COMV/V
      REAL V(12,XMAX0,YMAX0,ZMAX0)

*---- display program details

      WRITE(*,*)
      WRITE(*,*) 'TLM3D (v'//VERSN//') - '//
     ;           'Transmission-Line Modelling in 3-Dimensions'
      WRITE(*,*)
      WRITE(*,*) 'Limits :'
      WRITE(*,99010) 'mesh      ',XMAX0,YMAX0,ZMAX0
      WRITE(*,99020) 'boundaries',NMBCS0
      WRITE(*,99020) 'excite    ',NMNEX0
      WRITE(*,99020) 'output    ',NMNOU0
      WRITE(*,*)
99010 FORMAT(1X,'  ',A,' = ',I2,' x ',I2,' x ',I2)
99020 FORMAT(1X,'  ',A,' = ',I2)

*---- open input file

      WRITE(*,*) 'Name of input file : '
      READ(*,'(A)') INNAME
      INQUIRE(FILE=INNAME,EXIST=EX)
      IF (.NOT.EX) STOP 'File does not exist'
      OPEN(INUNT,FILE=INNAME,STATUS='OLD',ACCESS='SEQUENTIAL',
     ;  FORM='FORMATTED',IOSTAT=ERR)
      IF (ERR.NE.0) STOP 'File cannot be opened'
      REWIND(INUNT)

*---- set default data

      OUTNAM = '?'
      XMAX = XMAX0
      YMAX = YMAX0
      ZMAX = ZMAX0
      DL = 1.0
      NUMDT = 0
      NUMBCS = 0
      NUMNEX = 0
      NUMNOU = 0

*---- read input file

11010 READ(INUNT,'(A)',IOSTAT=ERR) LINE
      IF (ERR.NE.0) STOP 'Error reading file'
      IF (LINE(1:1).EQ.'!') GOTO 11010
      IF (LINE(1:1).NE.':') STOP 'Start of data expected'
      COMM = LINE(2:80)

*------ mesh size
      IF (COMM.EQ.'MESH') THEN
        READ(INUNT,*) XMAX,YMAX,ZMAX
        IF (XMAX.GT.XMAX0.OR.YMAX.GT.YMAX0.OR.ZMAX.GT.ZMAX0)
     ;    STOP 'Too big'

*------ node spacing
      ELSE IF (COMM.EQ.'DL') THEN
        READ(INUNT,*) DL

*------ number of timesteps
      ELSE IF (COMM.EQ.'TIMESTEPS') THEN
        READ(INUNT,*) NUMDT

*------ output file
      ELSE IF (COMM.EQ.'OUTPUT_FILE') THEN
        READ(INUNT,*) OUTNAM

*------ boundaries
      ELSE IF (COMM.EQ.'BOUNDARIES') THEN
        READ(INUNT,*) NUMBCS
        IF (NUMBCS.GT.NMBCS0) STOP 'Too many boundaries'
        DO 12010, I = 1, NUMBCS
          READ(INUNT,*) BRHO(I),LORIEN,BOX1(I),BOY1(I),BOZ1(I),
     ;                  BOX2(I),BOY2(I),BOZ2(I)
          BDIRN(I) = LORIEN(1:1)
          BSIGN(I) = LORIEN(2:2)
        IF ((BSIGN(I).NE.'N'.AND.BSIGN(I).NE.'P'.AND.
     ;        BSIGN(I).NE.'0').OR.
     ;      BOX1(I).LT.1.OR.BOX2(I).GT.XMAX.OR.BOX2(I).LT.BOX1(I).OR.
     ;      BOY1(I).LT.1.OR.BOY2(I).GT.YMAX.OR.BOY2(I).LT.BOY1(I).OR.
     ;      BOZ1(I).LT.1.OR.BOZ2(I).GT.ZMAX.OR.BOZ2(I).LT.BOZ1(I).OR.
     ;      BDIRN(I).EQ.'X'.AND.(BOX1(I).NE.BOX2(I).OR.
     ;        (BSIGN(I).EQ.'0'.AND.BOX2(I).EQ.XMAX)).OR.
     ;      BDIRN(I).EQ.'Y'.AND.(BOY1(I).NE.BOY2(I).OR.
     ;        (BSIGN(I).EQ.'0'.AND.BOY2(I).EQ.YMAX)).OR.
     ;      BDIRN(I).EQ.'Z'.AND.(BOZ1(I).NE.BOZ2(I).OR.
     ;        (BSIGN(I).EQ.'0'.AND.BOZ2(I).EQ.ZMAX)))
     ;        STOP 'Bad boundary coordinates'
12010   CONTINUE

*------ excitation
      ELSE IF (COMM.EQ.'EXCITE') THEN
        READ(INUNT,*) NUMNEX
        IF (NUMNEX.GT.NMNEX0) STOP 'Too many excite'
        DO 13010, I = 1, NUMNEX
          READ(INUNT,*) NEID(I),NEAMP(I),NEX1(I),NEY1(I),NEZ1(I),
     ;                  NEX2(I),NEY2(I),NEZ2(I)
        IF (NEX1(I).LT.1.OR.NEX2(I).GT.XMAX.OR.NEX2(I).LT.NEX1(I).OR.
     ;      NEY1(I).LT.1.OR.NEY2(I).GT.YMAX.OR.NEY2(I).LT.NEY1(I).OR.
     ;      NEZ1(I).LT.1.OR.NEZ2(I).GT.ZMAX.OR.NEZ2(I).LT.NEZ1(I))
     ;      STOP 'Bad excitation coordinates'
13010   CONTINUE

*------ output
      ELSE IF (COMM.EQ.'OUTPUT') THEN
        READ(INUNT,*) NUMNOU
        IF (NUMNOU.GT.NMNOU0) STOP 'Too many output'
        DO 14010, I = 1, NUMNOU
          READ(INUNT,*) NOID(I),NOX1(I),NOY1(I),NOZ1(I)
        IF (NOX1(I).LT.1.OR.NOX1(I).GT.XMAX.OR.
     ;      NOY1(I).LT.1.OR.NOY1(I).GT.YMAX.OR.
     ;      NOZ1(I).LT.1.OR.NOZ1(I).GT.ZMAX)
     ;      STOP 'Bad output coordinates'
14010   CONTINUE

*---- end of read

      ELSE IF (COMM.NE.'END') THEN
        STOP 'Data not recognised'
      END IF
      IF (COMM.NE.'END') GOTO 11010
      CLOSE(INUNT)
      WRITE(*,*) 'Input file closed'

*---- open output file

      IF (OUTNAM.EQ.'?') THEN
        WRITE(*,*) 'Name of output file : '
        READ(*,'(A)') OUTNAM
      END IF
      OPEN(OUTUNT,FILE=OUTNAM,STATUS='NEW',ACCESS='SEQUENTIAL',
     ;  FORM='FORMATTED',IOSTAT=ERR)
      IF (ERR.NE.0) STOP 'Output file cannot be opened'

*---- clear array

      DO 21010, Z = 1, ZMAX
        DO 21020, Y = 1, YMAX
          DO 21030, X = 1, XMAX
            DO 21040, D = 1, 12
              V(D,X,Y,Z) = 0.0
21040        CONTINUE
21030      CONTINUE
21020    CONTINUE
21010  CONTINUE

*---- excite

       DO 22010, N = 1, NUMNEX

        TYP  = NEID(N)(1:1)
        DIRN = NEID(N)(2:2)
        IF (TYP.EQ.'E') THEN
          VE = - DL * NEAMP(N) / 2.0
        ELSE IF (TYP.EQ.'H') THEN
          VH = DL * Z0 * NEAMP(N) / 2.0
        ELSE
          STOP 'Excitation field error'
        END IF

        DO 22020, Z = NEZ1(N), NEZ2(N)
          DO 22030, Y = NEY1(N), NEY2(N)
            DO 22040, X = NEX1(N), NEX2(N)

              IF (TYP.EQ.'E') THEN
                IF (DIRN.EQ.'X') THEN
                  V(PYNX,X,Y,Z) = V(PYNX,X,Y,Z) + VE
                  V(PZNX,X,Y,Z) = V(PZNX,X,Y,Z) + VE
                  V(PYPX,X,Y,Z) = V(PYPX,X,Y,Z) + VE
                  V(PZPX,X,Y,Z) = V(PZPX,X,Y,Z) + VE
                ELSE IF (DIRN.EQ.'Y') THEN
                  V(PZNY,X,Y,Z) = V(PZNY,X,Y,Z) + VE
                  V(PXNY,X,Y,Z) = V(PXNY,X,Y,Z) + VE
                  V(PZPY,X,Y,Z) = V(PZPY,X,Y,Z) + VE
                  V(PXPY,X,Y,Z) = V(PXPY,X,Y,Z) + VE
                ELSE IF (DIRN.EQ.'Z') THEN
                  V(PXNZ,X,Y,Z) = V(PXNZ,X,Y,Z) + VE
                  V(PYNZ,X,Y,Z) = V(PYNZ,X,Y,Z) + VE
                  V(PXPZ,X,Y,Z) = V(PXPZ,X,Y,Z) + VE
                  V(PYPZ,X,Y,Z) = V(PYPZ,X,Y,Z) + VE
                ELSE
                  STOP 'E-field excitation error'
                END IF

              ELSE IF (TYP.EQ.'H') THEN
                IF (DIRN.EQ.'X') THEN
                  V(PZNY,X,Y,Z) = V(PZNY,X,Y,Z) + VH
                  V(PYNZ,X,Y,Z) = V(PYNZ,X,Y,Z) - VH
                  V(PZPY,X,Y,Z) = V(PZPY,X,Y,Z) - VH
                  V(PYPZ,X,Y,Z) = V(PYPZ,X,Y,Z) + VH
                ELSE IF (DIRN.EQ.'Y') THEN
                  V(PXNZ,X,Y,Z) = V(PXNZ,X,Y,Z) + VH
                  V(PZNX,X,Y,Z) = V(PZNX,X,Y,Z) - VH
                  V(PXPZ,X,Y,Z) = V(PXPZ,X,Y,Z) - VH
                  V(PZPX,X,Y,Z) = V(PZPX,X,Y,Z) + VH
                ELSE IF (DIRN.EQ.'Z') THEN
                  V(PYNX,X,Y,Z) = V(PYNX,X,Y,Z) + VH
                  V(PXNY,X,Y,Z) = V(PXNY,X,Y,Z) - VH
                  V(PYPX,X,Y,Z) = V(PYPX,X,Y,Z) - VH
                  V(PXPY,X,Y,Z) = V(PXPY,X,Y,Z) + VH
                ELSE
                  STOP 'H-field excitation error'
                END IF

              END IF

22040       CONTINUE
22030     CONTINUE
22020   CONTINUE

22010 CONTINUE

*---- start calculation

      WRITE(*,*) 'Start of calculation'

      DO 30010, T = 1, NUMDT

      WRITE(*,99100) 100.0*REAL(T-1)/REAL(NUMDT)
99100 FORMAT(1X,F6.3,' %')

*---- output

      DO 41010, N = 1, NUMNOU

        TYP  = NOID(N)(1:1)
        DIRN = NOID(N)(2:2)

        Z = NOZ1(N)
        Y = NOY1(N)
        X = NOX1(N)

        IF (TYP.EQ.'E') THEN
          IF (DIRN.EQ.'X') THEN
            OUT = V(PYNX,X,Y,Z) + V(PZNX,X,Y,Z) +
     ;            V(PYPX,X,Y,Z) + V(PZPX,X,Y,Z)
          ELSE IF (DIRN.EQ.'Y') THEN
            OUT = V(PZNY,X,Y,Z) + V(PXNY,X,Y,Z) +
     ;            V(PZPY,X,Y,Z) + V(PXPY,X,Y,Z)
          ELSE IF (DIRN.EQ.'Z') THEN
            OUT = V(PXNZ,X,Y,Z) + V(PYNZ,X,Y,Z) +
     ;            V(PXPZ,X,Y,Z) + V(PYPZ,X,Y,Z)
          ELSE
            STOP 'E-field output error'
          END IF
          OUT = - OUT / DL / 2.0
 
        ELSE IF (TYP.EQ.'H') THEN
          IF (DIRN.EQ.'X') THEN
            OUT = V(PZNY,X,Y,Z) - V(PYNZ,X,Y,Z) -
     ;            V(PZPY,X,Y,Z) + V(PYPZ,X,Y,Z)
          ELSE IF (DIRN.EQ.'Y') THEN
            OUT = V(PXNZ,X,Y,Z) - V(PZNX,X,Y,Z) -
     ;            V(PXPZ,X,Y,Z) + V(PZPX,X,Y,Z)
          ELSE IF (DIRN.EQ.'Z') THEN
            OUT = V(PYNX,X,Y,Z) - V(PXNY,X,Y,Z) -
     ;            V(PYPX,X,Y,Z) + V(PXPY,X,Y,Z)
          ELSE
            STOP 'H-field output error'
          END IF
          OUT = OUT / Z0 / DL / 2.0

        ELSE
          STOP 'Output field error'
        END IF

        WRITE(OUTUNT,99200) OUT
99200 FORMAT(1X,E13.6)

41010 CONTINUE

*---- scatter

      DO 42010, Z = 1, ZMAX
        DO 42020, Y = 1, YMAX
          DO 42030, X = 1, XMAX

            VYNX = V(PYNX,X,Y,Z)
            VZNX = V(PZNX,X,Y,Z)
            VXNY = V(PXNY,X,Y,Z)
            VZNY = V(PZNY,X,Y,Z)
            VYNZ = V(PYNZ,X,Y,Z)
            VXNZ = V(PXNZ,X,Y,Z)
            VYPZ = V(PYPZ,X,Y,Z)
            VZPY = V(PZPY,X,Y,Z)
            VZPX = V(PZPX,X,Y,Z)
            VXPZ = V(PXPZ,X,Y,Z)
            VXPY = V(PXPY,X,Y,Z)
            VYPX = V(PYPX,X,Y,Z)

            VDIFF = VXPY - VXNY
            VTEMP = 0.5 * ( VZNX + VZPX + VDIFF )
            V(PYPX,X,Y,Z) = VTEMP
            V(PYNX,X,Y,Z) = VTEMP - VDIFF

            VDIFF = VXPZ - VXNZ
            VTEMP = 0.5 * ( VYNX + VYPX + VDIFF )
            V(PZPX,X,Y,Z) = VTEMP
            V(PZNX,X,Y,Z) = VTEMP - VDIFF

            VDIFF = VYPZ - VYNZ
            VTEMP = 0.5 * ( VXNY + VXPY + VDIFF )
            V(PZPY,X,Y,Z) = VTEMP
            V(PZNY,X,Y,Z) = VTEMP - VDIFF

            VDIFF = VYPX - VYNX
            VTEMP = 0.5 * ( VZNY + VZPY + VDIFF )
            V(PXPY,X,Y,Z) = VTEMP
            V(PXNY,X,Y,Z) = VTEMP - VDIFF

            VDIFF = VZPX - VZNX
            VTEMP = 0.5 * ( VYNZ + VYPZ + VDIFF )
            V(PXPZ,X,Y,Z) = VTEMP
            V(PXNZ,X,Y,Z) = VTEMP - VDIFF

            VDIFF = VZPY - VZNY
            VTEMP = 0.5 * ( VXNZ + VXPZ + VDIFF )
            V(PYPZ,X,Y,Z) = VTEMP
            V(PYNZ,X,Y,Z) = VTEMP - VDIFF

42030     CONTINUE
42020   CONTINUE
42010 CONTINUE

*---- boundaries

      DO 43010, N = 1, NUMBCS

        DIRN = BDIRN(N)
        LSIGN = BSIGN(N)
        RHO  = BRHO(N)

        IF (DIRN.EQ.'X') THEN
          X = BOX1(N)

          IF (LSIGN.EQ.'N'.AND.X.EQ.1) THEN
            DO 43110, Z = BOZ1(N), BOZ2(N)
              DO 43120, Y = BOY1(N), BOY2(N)
                V(PXNY,X,Y,Z) = RHO * V(PXNY,X,Y,Z)
                V(PXNZ,X,Y,Z) = RHO * V(PXNZ,X,Y,Z)
43120         CONTINUE
43110       CONTINUE

          ELSE IF (LSIGN.EQ.'P'.AND.X.EQ.XMAX) THEN
            DO 43130, Z = BOZ1(N), BOZ2(N)
              DO 43140, Y = BOY1(N), BOY2(N)
                V(PXPZ,X,Y,Z) = RHO * V(PXPZ,X,Y,Z)
                V(PXPY,X,Y,Z) = RHO * V(PXPY,X,Y,Z)
43140         CONTINUE
43130      CONTINUE

          ELSE
	    IF (LSIGN.EQ.'N') X = X - 1
	    X1 = X + 1
            DO 43150, Z = BOZ1(N), BOZ2(N)
              DO 43160, Y = BOY1(N), BOY2(N)
	        VTEMP = V(PXPY,X,Y,Z)
		V(PXPY,X,Y,Z) = RHO * V(PXNY,X1,Y,Z)
		V(PXNY,X1,Y,Z) = RHO * VTEMP
	        VTEMP = V(PXPZ,X,Y,Z)
		V(PXPZ,X,Y,Z) = RHO * V(PXNZ,X1,Y,Z)
		V(PXNZ,X1,Y,Z) = RHO * VTEMP
43160         CONTINUE
43150       CONTINUE

          END IF

        ELSE IF (DIRN.EQ.'Y') THEN
          Y = BOY1(N)

          IF (LSIGN.EQ.'N'.AND.Y.EQ.1) THEN
            DO 43210, Z = BOZ1(N), BOZ2(N)
              DO 43220, X = BOX1(N), BOX2(N)
                V(PYNZ,X,Y,Z) = RHO * V(PYNZ,X,Y,Z)
                V(PYNX,X,Y,Z) = RHO * V(PYNX,X,Y,Z)
43220         CONTINUE
43210       CONTINUE

          ELSE IF (LSIGN.EQ.'P'.AND.Y.EQ.YMAX) THEN
            DO 43230, Z = BOZ1(N), BOZ2(N)
              DO 43240, X = BOX1(N), BOX2(N)
                V(PYPZ,X,Y,Z) = RHO * V(PYPZ,X,Y,Z)
                V(PYPX,X,Y,Z) = RHO * V(PYPX,X,Y,Z)
43240         CONTINUE
43230       CONTINUE

          ELSE
	    IF (LSIGN.EQ.'N') Y = Y - 1
	    Y1 = Y + 1
            DO 43250, Z = BOZ1(N), BOZ2(N)
              DO 43260, X = BOX1(N), BOX2(N)
                VTEMP = V(PYPZ,X,Y,Z)
		V(PYPZ,X,Y,Z) = RHO * V(PYNZ,X,Y1,Z)
		V(PYNZ,X,Y1,Z) = RHO * VTEMP
		VTEMP = V(PYPX,X,Y,Z)
		V(PYPX,X,Y,Z) = RHO * V(PYNX,X,Y1,Z)
		V(PYNX,X,Y1,Z) = RHO * VTEMP
43260         CONTINUE
43250       CONTINUE

          END IF

        ELSE IF (DIRN.EQ.'Z') THEN
          Z = BOZ1(N)

          IF (LSIGN.EQ.'N'.AND.Z.EQ.1) THEN
            DO 43310, Y = BOY1(N), BOY2(N)
              DO 43320, X = BOX1(N), BOX2(N)
                V(PZNX,X,Y,Z) = RHO * V(PZNX,X,Y,Z)
                V(PZNY,X,Y,Z) = RHO * V(PZNY,X,Y,Z)
43320         CONTINUE
43310       CONTINUE

          ELSE IF (LSIGN.EQ.'P'.AND.Z.EQ.ZMAX) THEN
            DO 43330, Y = BOY1(N), BOY2(N)
              DO 43340, X = BOX1(N), BOX2(N)
                V(PZPX,X,Y,Z) = RHO * V(PZPX,X,Y,Z)
                V(PZPY,X,Y,Z) = RHO * V(PZPY,X,Y,Z)
43340         CONTINUE
43330       CONTINUE

          ELSE
	    IF (LSIGN.EQ.'N') Z = Z - 1
	    Z1 = Z + 1
            DO 43350, Y = BOY1(N), BOY2(N)
              DO 43360, X = BOX1(N), BOX2(N)
                VTEMP = V(PZPX,X,Y,Z)
                V(PZPX,X,Y,Z) = RHO * V(PZNX,X,Y,Z1)
		V(PZNX,X,Y,Z1) = RHO * VTEMP
		VTEMP = V(PZPY,X,Y,Z)
		V(PZPY,X,Y,Z) = RHO * V(PZNY,X,Y,Z1)
		V(PZNY,X,Y,Z1) = RHO * VTEMP
43360         CONTINUE
43350       CONTINUE

          END IF

        ELSE
          STOP 'Boundary direction error'
        END IF

43010 CONTINUE

*---- connect

      DO 44010, Z = 1, ZMAX
        Z1 = Z + 1
        DO 44020, Y = 1, YMAX
          Y1 = Y + 1
          DO 44030, X = 1, XMAX
            X1 = X + 1
 
            IF (X.LT.XMAX) THEN
              V0 = V(PXPZ,X,Y,Z)
              V(PXPZ,X,Y,Z) = V(PXNZ,X1,Y,Z)
              V(PXNZ,X1,Y,Z) = V0
              V0 = V(PXPY,X,Y,Z)
              V(PXPY,X,Y,Z) = V(PXNY,X1,Y,Z)
              V(PXNY,X1,Y,Z) = V0
            END IF
 
            IF (Y.LT.YMAX) THEN
              V0 = V(PYPZ,X,Y,Z)
              V(PYPZ,X,Y,Z) = V(PYNZ,X,Y1,Z)
              V(PYNZ,X,Y1,Z) = V0
              V0 = V(PYPX,X,Y,Z)
              V(PYPX,X,Y,Z) = V(PYNX,X,Y1,Z)
              V(PYNX,X,Y1,Z) = V0
            END IF
 
            IF (Z.LT.ZMAX) THEN
              V0 = V(PZPY,X,Y,Z)
              V(PZPY,X,Y,Z) = V(PZNY,X,Y,Z1)
              V(PZNY,X,Y,Z1) = V0
              V0 = V(PZPX,X,Y,Z)
              V(PZPX,X,Y,Z) = V(PZNX,X,Y,Z1)
              V(PZNX,X,Y,Z1) = V0
            END IF
 
44030     CONTINUE
44020   CONTINUE
44010 CONTINUE

*---- end calculation

30010 CONTINUE

*---- close output file

      CLOSE(OUTUNT)
      WRITE(*,*) 'Output file closed'
      WRITE(*,*)
      END