      Program Project02

      INTEGER   Ndx, Nfx, Ngraph, Nbound, Nmovie, Nrat
      PARAMETER ( Nfx = 1600 )
      REAL*8    DT, DX, Delta, Time, Timpt, Q(-1:1,-Nfx:Nfx)

      OPEN(7, FILE = 'Project02.dat' , FORM = 'formatted'  )
         READ(7, 200, ERR = 1000 ) DT, DX, Delta, Time, Timpt
 200     FORMAT(4(11X,E10.4 / ),11X,E10.4)
         READ(7, 210, ERR = 1000 ) Ngraph, Nmovie, Nbound
 210     FORMAT(2(11X,I5 / ),11X,I5)
      CLOSE(7)

      Ndx = INT(1.0D0/DX)
      IF ( DT .GE. DX ) THEN
         PRINT *, 'DT is too large.'
         STOP
      ENDIF

      CALL BODY(DT,DX,Delta,Time,Timpt,Ngraph,Nmovie,Nbound,Q,Ndx)
      STOP

 1000 PRINT *, "Error in reading file"
      STOP
      END

C***********************************************************************
      
      SUBROUTINE BODY(DT,DX,Delta,Time,Timpt,Ngraph,Nmovie,Nbound,Q,Ndx)

      INTEGER   i, j, Ngraph, Nbound, Nmovie, Ndx, Nnon0, Ntime, Nslice
      REAL*8    DT, DX, Delta, Q(-1:1,-Ndx:Ndx), Qdum, Time, Timpt, pi
      PARAMETER ( pi = 3.141593D0 )
      CHARACTER*64 fname

C Set your initial conditions

      Nnon0 = INT(Ndx*0.2D0)
      DO j = -Ndx, -Nnon0-1
         Q(1,j) = 0.0D0
      ENDDO 
      
      DO j = -Nnon0, Nnon0
         IF ( Ngraph .EQ. 1 ) THEN
            Q(1,j) = COS(pi/Delta*(DX*j))/2.0D0 + 0.5D0
         ELSE
            Q(1,j) = 0.04D0*EXP( -(DX*j)**2 / Delta**2 )
         ENDIF
      ENDDO 

      DO j = Nnon0+1, Ndx
         Q(1,j) = 0.0D0
      ENDDO 

      IF ( Nmovie .NE. 0 .OR. Timpt .EQ. 0.0D0 ) THEN
         open(unit=98,file='slice.0')
            DO j = -Ndx, Ndx 
               Qdum = Q(1,j)
               IF ( ABS(Qdum) .LT. 1.0D-89 ) Qdum = 0.0D0
               WRITE(98,220) j*DX, Qdum
 220           FORMAT(1X,F9.6,2X,E17.10)
            ENDDO
         close(unit=98)
      ENDIF

C Now determine your backwards step using the analytical solution.

 400  DO j = -Ndx, -Nnon0-1
         Q(0,j) = 0.0D0
      ENDDO

      DO j = -Nnon0, Nnon0-1
         IF ( Ngraph .EQ. 1 ) THEN
            Q(0,j) = COS(pi/Delta*(DX*j + DT))/2.0D0 + 0.5D0
         ELSE
            Q(0,j) = 0.04D0*EXP( -(DX*j + DT)**2 / Delta**2 )
         ENDIF
      ENDDO 

      DO j = Nnon0, Ndx
         Q(0,j) = 0.0D0
      ENDDO

C Now evolve the current grid.

      Ntime = INT(Time/DT)
      IF ( Nmovie .EQ. 1 ) PRINT *, 'Ntime = ', Ntime
      DO i = 1, Ntime
         DO j = -Ndx, Ndx
            Q(-1,j) = Q(0,j)
            Q(0,j) = Q(1,j)
         ENDDO
         DO j = -Ndx+1, Ndx-1
            Q(1,j) = 2.0D0*Q(0,j) - Q(-1,j) + ( Q(0,j+1) 
     /               - 2.0D0*Q(0,j) + Q(0,j-1) )*( DT/DX )**2
         ENDDO
         IF ( Nbound .EQ. -1 ) THEN
            Q(1,Ndx) = 2.0D0*Q(0,Ndx) - Q(-1,Ndx) + ( Q(0,-Ndx+1) 
     /                 - 2.0D0*Q(0,Ndx) + Q(0,Ndx-1) )*( DT/DX )**2
            Q(1,-Ndx) = Q(1,Ndx)
         ELSEIF ( Nbound .EQ. 0 ) THEN
            Q(1,Ndx) = 0.0D0
            Q(1,-Ndx) = 0.0D0
         ELSEIF ( Nbound .EQ. 1 ) THEN
            Q(1,Ndx) = ( 4.0D0*Q(0,Ndx) - Q(-1,Ndx) + ( DT/DX )
     /                 *( 4.0D0*Q(1,Ndx-1) - Q(1,Ndx-2) ) ) /
     /                 ( 3.0D0*( 1.0D0 +( DT/DX ) ) )
            Q(1,-Ndx) = ( 4.0D0*Q(0,-Ndx) - Q(-1,-Ndx) + ( DT/DX )
     /                  *( 4.0D0*Q(1,-Ndx+1) - Q(1,-Ndx+2) ) ) /
     /                  ( 3.0D0*( 1.0D0 +( DT/DX ) ) )
         ELSE
            PRINT *, 'Invalid value of Nbound' 
            STOP
         ENDIF
       
         Nslice = INT(Timpt/DT)
         IF ( Nmovie .EQ. 0 ) THEN
            IF ( i .NE. Nslice ) GOTO 600
         ENDIF

   	 if (i .lt. 10) then
	   write(fname,901) i
         end if
         if (i .gt. 9 .and. i .lt. 100) then
            write(fname,902) i
         end if
         if (i .gt. 99 .and. i .lt. 1000) then
            write(fname,903) i
         end if
         if (i .gt. 999 .and. i .lt. 10000) then
            write(fname,904) i
         end if

         open(unit=99,file=fname)
            DO j = -Ndx, Ndx 
            Qdum = Q(1,j)
            IF ( ABS(Qdum) .LT. 1.0D-89 ) Qdum = 0.0D0
               WRITE(99,220) j*DX, Qdum
            ENDDO
         close(unit=99)

 600  ENDDO

 901  FORMAT('slice','.',I1) 
 902  FORMAT('slice','.',I2) 
 903  FORMAT('slice','.',I3) 
 904  FORMAT('slice','.',I4) 
      RETURN
      END
