
C----------------------------------------------------------------------C
C
C  Copy edge spin values between neighboring processors. 
C
C
C  N.B. The syntax of KXCHAN is
C
C  KXCHAN(ibuf, ilen, isrc,  itype,
C         obuf, olen, odest, otype)
C
C  which is equivalent to
C
C  KXREAD(obuf, olen, odest, otype)
C  KXWRIT(ibuf, ilen, isrc,  itype)
C
C  i.e. olen bytes are taken from obuf and written to the node odest, 
C       while ilen bytes are read in from isrc and put into ibuf.
C 
C----------------------------------------------------------------------C



C----------------------------------------------------------------------C
C
C   Get the values of the spins along edges in positive directions.
C   This is all that is required to do measurements.
C
C----------------------------------------------------------------------C

	SUBROUTINE spin_edges
	INCLUDE "common.h"
	INTEGER type,len,vlen,voffset,items
        INTEGER d1,d2
        
	type = EDGE

C ----  left edge -> right edge  (right node passes to left node). 
        vlen = 4
        voffset = imax_int
        items = jsiz
   	d1 = KXVCHA(spin(isiz+1,1),vlen,voffset,items,right,type,
     &              spin(1,1),     vlen,voffset,items,left, type)

C ----  bottom edge -> top edge  (top node passes to bottom node). 
        len = isiz_int
   	d2 = KXCHAN(spin(1,jsiz+1),len,top,   type,
     &              spin(1,1),     len,bottom,type)

C ----  Debug!
C       CALL KMULTI(6)
C       IF ((d1.NE.items) .OR. (d2.NE.len)) THEN
C         WRITE(6,*) 'spin exchange', d1,items, d2,len
C       ENDIF
C       CALL KFLUSH(6)
C       CALL KSINGL(6)

	RETURN
	END



C----------------------------------------------------------------------C
C
C   Get the values of the spins along edges in all directions.
C   Need this for Metropolis update with blocked data communications.
C
C----------------------------------------------------------------------C

	SUBROUTINE all_edges
	INCLUDE "common.h"
	INTEGER type,len,vlen,voffset,items
        INTEGER d1,d2,d3,d4

	type = EDGE

C ----  left edge -> right edge  (right node passes to left node). 
        vlen = 4
        voffset = imax_int
        items = jsiz
   	d1 = KXVCHA(spin(isiz+1,1),vlen,voffset,items,right,type,
     &              spin(1,1),     vlen,voffset,items,left, type)

C ----  right edge -> left edge  (left node passes to right node). 
   	d2 = KXVCHA(spin(0,1),   vlen,voffset,items,left, type,
     &              spin(isiz,1),vlen,voffset,items,right,type)


C ----  bottom edge -> top edge  (top node passes to bottom node). 
        len = isiz_int
   	d3 = KXCHAN(spin(1,jsiz+1),len,top,   type,
     &              spin(1,1),     len,bottom,type)

C ----  top edge -> bottom edge  (bottom node passes to top node). 
   	d4 = KXCHAN(spin(1,0),   len,bottom,type,
     &              spin(1,jsiz),len,top,   type)

	RETURN
	END




C----------------------------------------------------------------------C
C
C   Get the value of the spin at site (i,j). This may require 
C   some communication if (i,j) is on another processor. 
C
C----------------------------------------------------------------------C

	FUNCTION get_spin(i,j)
	INCLUDE "common.h"
	INTEGER get_spin,i,j
	INTEGER type,len

	type = EDGE
	len = 4

   	IF (i.GT.isiz) THEN 
      	  CALL KXCHAN(spin(isiz+1,j),len,right,type,
     &                spin(1,j),     len,left, type)
   	ELSE IF (i.LT.1) THEN
      	  CALL KXCHAN(spin(0,j),   len,left, type,
     &                spin(isiz,j),len,right,type)
   	ELSE IF (j.GT.jsiz) THEN
      	  CALL KXCHAN(spin(i,jsiz+1),len,top,   type,
     &                spin(i,1),     len,bottom,type)
   	ELSE IF (j.LT.1) THEN
      	  CALL KXCHAN(spin(i,0),   len,bottom,type,
     &                spin(i,jsiz),len,top,   type)
   	ENDIF

   	get_spin = spin(i,j)

	RETURN
	END


