Up: Listing of key Previous: GAUSS.F

BURN3D.F

c**************************  burn3d.f  *******************************

c  PROBLEM DEFINITION

c  In a random multi-phase structure, a question that is important 
c  is whether a particular phase percolates through the microstructure 
c  or not.  This program is designed to answer that question, for
c  a general 3-D multi-phase random microstructure.  The burning
c  algorithm checks whether a percolation threshold exists in a periodic 
c  image. The program searches all three directions, using periodic
c  boundary conditions in the two perpendicular directions for 
c  each burn.

c  Variables

c  There are a maximum of "ntot" phases possible, numbered 1,2,3,... 
c  The label of the phase being burned is "phase", and is an input variable.
c  The value assigned to burned pixels is "burned" and is equal to ntot+1.
c  To burn on more than one phase at a time, just use
c  "phase2", "phase3", etc., and check for these values too, whenever 
c  the value "phase" is checked for. (See manual)
c  A value of 0 is assigned to the variables percx, percy, and 
c  percz for non-continuity, and 1 for percolation (continuity) in the
c  given direction.

c  Dimensions

c  (USER) The variable pix is dimensioned the size of the system.
c  The variables old and new are dimensioned 1/10 the size of the system,
c  but with three components. (A minimum of 1000 should be used
c  to dimension these variables, so that small systems will have enough
c  computation room.) These array dimensions should be changed 
c  simultaneously in all subroutines using a global replacement statement.

c  (USER) Dimensions of main arrays
      integer*2 pix(1000000),old(100000,3),new(100000,3)
      integer*2 burned,phase

c  (USER) Unit = 9 is the input file, unit 7 is the output file
      open(unit=9,file='microstructure.dat')
      open(unit=7,file='output.out')

c  (USER) system size ns = nx x ny x nz
      nx=100
      ny=100
      nz=100
      ns=nx*ny*nz

c  (USER) Identify the label of the phase to be burned
      phase=1
c  (USER) Total number of phases allowed in problem
      ntot=100
c  Label of burned pixel
      burned=ntot+1
      
c  Read in microstructure file
      do 330 k=1,nz
      do 330 j=1,ny
      do 330 i=1,nx
      m=nx*ny*(k-1)+nx*(j-1)+i
      read(9,*) pix(m)
330   continue

c  Call the subroutine that actually does the burning
      call fire(pix,nx,ny,nz,percz,percy,percx,new,old,phase,burned)
c  Output the values of perc*, showing the continuity of the three 
c  principal directions
      write(7,*) ' percx = ',percx
      write(7,*) ' percy = ',percy
      write(7,*) ' percz = ',percz
      end

c  This subroutine does the actual burning.  The burning starts with the 
c  k=1 or j=1 or i=1 plane, and then iteratively burnes through the system,
c  until there are no more acessible pixels to be burned.  To be burned,
c  a pixel must be next to a previously burned pixel.

      subroutine fire(pix,nx,ny,nz,percz,percy,percx,new,old,
     &  phase,burned)

      integer*2 pix(1000000)
      integer*2 old(100000,3),new(100000,3)
      integer*2 in(6),jn(6),kn(6),phase,burned

c  System size
      ns=nx*ny*nz

c  Direction labels to check for burning path (nearest neighbor information
c  in 3-D digital system).
      in(1)=-1
      in(2)=1
      in(3)=0
      in(4)=0
      in(5)=0
      in(6)=0
      jn(1)=0
      jn(2)=0
      jn(3)=-1
      jn(4)=1
      jn(5)=0
      jn(6)=0
      kn(1)=0
      kn(2)=0
      kn(3)=0
      kn(4)=0
      kn(5)=-1
      kn(6)=1

c  Initialize percolation flags
      percx=0.0
      percy=0.0
      percz=0.0

      do 3000 ijk=1,3
c  Build up first burned pixels from i or j or k=1 layer, according to
c  choice of ijk (ijk = 1, k = 1;  ijk = 2, j = 1;  ijk = 3, i = 1).
c  Store(i,j,k) labels in array old().

      iold=0

      if(ijk.eq.1) then
      n2=ny
      n1=nx
      end if
      if(ijk.eq.2) then
      n2=nz
      n1=nx
      end if
      if(ijk.eq.3) then
      n2=ny
      n1=nz
      end if

      do 1000 jj=1,n2
      do 1000 ii=1,n1
      if(ijk.eq.1) then
      i=ii
      j=jj
      k=1
      end if
      if(ijk.eq.2) then
      i=ii
      j=1
      k=jj
      end if
      if(ijk.eq.3) then
      i=1
      j=jj
      k=ii
      end if
      m=nx*ny*(k-1)+nx*(j-1)+i

      if(pix(m).eq.phase) then
      pix(m)=burned
      iold=iold+1
      old(iold,1)=i
      old(iold,2)=j
      old(iold,3)=k
      end if
1000  continue

c  If no pixels burned in first layer, then phase can't possibly percolate,
c  so move to next direction
      if(iold.eq.0) goto 3000

c  Now start building up new burned pixels from old set of burned pixels,
c  thus propagating the fire.
60    inew=0
      do 100 i=1,iold
      ii=old(i,1)
      jj=old(i,2)
      kk=old(i,3)
c  check all six nearest neighbors of previously burned pixel
      do 90 n=1,6
      i1=ii+in(n)
      j1=jj+jn(n)
      k1=kk+kn(n)

c  Periodic boundary conditions
c  (USER)  Can replace with hard boundary conditions
c  if desired to remove periodicity. Keep the ijk if statements and the 
c  goto 90 statements, and change the other if statements to have 
c  goto 90 as well. That way the program does not allow "wrappping"
c  around to find a neighbor. (See manual)
      if(ijk.eq.1) then
      if(k1.lt.1.or.k1.gt.nz) goto 90
      if(i1.lt.1) i1=i1+nx
      if(i1.gt.nx) i1=i1-nx
      if(j1.lt.1) j1=j1+ny
      if(j1.gt.ny) j1=j1-ny
      end if
      if(ijk.eq.2) then
      if(j1.lt.1.or.j1.gt.ny) goto 90
      if(i1.lt.1) i1=i1+nx
      if(i1.gt.nx) i1=i1-nx
      if(k1.lt.1) k1=k1+nz
      if(k1.gt.nz) k1=k1-nz
      end if
      if(ijk.eq.3) then
      if(i1.lt.1.or.i1.gt.nx) goto 90
      if(k1.lt.1) k1=k1+nz
      if(k1.gt.nz) k1=k1-nz
      if(j1.lt.1) j1=j1+ny
      if(j1.gt.ny) j1=j1-ny
      end if

c  Store (i,j,k) labels of newly burned pixels in array new().
      m1=nx*ny*(k1-1)+nx*(j1-1)+i1
      if(pix(m1).eq.phase) then
      pix(m1)=burned
      inew=inew+1
      new(inew,1)=i1
      new(inew,2)=j1
      new(inew,3)=k1
      end if
90    continue
100   continue

c  If new pixels were burned, then transfer labels to old() array, start
c  burning process over again.
      if(inew.gt.0) then
      iold=inew
      do 150 i=1,inew
      old(i,1)=new(i,1)
      old(i,2)=new(i,2)
      old(i,3)=new(i,3)
150   continue
      goto 60
      end if

c  If no new burned pixels, then check to see if the last layer of the image
c  has any burned pixels in it.  If so, then there is continuity.  If not,
c  then there is no continuity.

      if(ijk.eq.1) then
      n2=ny
      n1=nx
      end if
      if(ijk.eq.2) then
      n2=nz
      n1=nx
      end if
      if(ijk.eq.3) then
      n2=ny
      n1=nz
      end if

      do 30 jj=1,n2
      do 30 ii=1,n1
      if(ijk.eq.1) then
      i=ii
      j=jj
      k=nz
      end if
      if(ijk.eq.2) then
      i=ii
      j=ny
      k=jj
      end if
      if(ijk.eq.3) then
      i=nx
      j=jj
      k=ii
      end if
      m=nx*ny*(k-1)+nx*(j-1)+i
      if(pix(m).eq.burned) then
      if(ijk.eq.1) percz=1.0
      if(ijk.eq.2) percy=1.0
      if(ijk.eq.3) percx=1.0
      end if
30    continue

c  Restore burned pixels back to their original label
      call restore(pix,ns,phase,burned)

3000  continue
      return
      end

c This subroutine restores the burned pixels back to their original, unburned
c value (phase).

      subroutine restore(pix,ns,phase,burned)
      integer*2 pix(1000000),phase,burned

      do 10 m=1,ns
      if(pix(m).eq.burned) pix(m)=phase
10    continue
      return
      end



Up: Listing of key Previous: GAUSS.F