c
c     Contains various routines for manipulating arrays
c     Largely stuff that needs to be done in multiple
c     contexts, has self-explanatory names,
c     and the details of which are not essential to
c     the simulation algorithm
c     

c
c     step fills x with 0:nx+1 items between fxMin and fxMax
      subroutine step(x, fxMin, fxMax, nx, 
     *     bBounds)

      implicit none

      real*8 x, fxMin, fxMax
      integer i, nx
      logical bBounds

      dimension x(0:nx+1)

      real*8 fCurr, fStepPerIval

      if(bBounds .EQV. .TRUE.) then
         fStepPerIval = (fxMax-fxMin)/(nx)
         fCurr = -1.d0*fStepPerIval
      else
         fStepPerIval = (fxMax-fxMin)/(nx+2)
         fCurr = 0.d0
      endif

      do i=0,nx+1
         x(i) = fCurr
         fCurr = fCurr+fStepPerIval
      enddo

      return 
      end

      subroutine set_const_2d(x, nx, ny, nMax, fConst)
      implicit none
      real*8 x, fConst
      integer nx, ny,nMax
      dimension x(0:nMax+1,0:nMax+1)
      integer i,j

      do j=0,ny+1
         do i=0,nx+1
            x(i,j) = fConst
         enddo
      enddo

      return
      end

c     ----------------------------------------------------------
c     minMax
c     ----------------------------------------------------------
      subroutine getMinMax(A,nX,nY,nMax,
     *     valMin, valMax)
      implicit none

      real*8 A, valMin, valMax
      integer nX,nY,nMax,i,j

      dimension A(0:nMax+1,0:nMax+1)

      valMin = A(1,1)
      valMax = A(1,1)
      
      do j=1,nY
         do i=1,nX
            valMin = valMin+A(i,j)-
     *           dabs(valMin-A(i,j))
            valMax = valMax+A(i,j)-
     *           dabs(valMax-A(i,j))
            valMin = 5.d-1*valMin
            valMax = 5.d-1*valMax
         enddo
      enddo

      return
      end

c     ----------------------------------------------------------
c     UVminMax
c     ----------------------------------------------------------
      subroutine getUvMinMax(A,nX,nY,nMax,
     *     valMin, valMax, iChannel)
      implicit none

      real*8 A, valMin, valMax
      integer nX,nY,nMax, iChannel
      integer i,j

      dimension A(2,0:nMax+1,0:nMax+1)

      valMin = A(iChannel, 1,1)
      valMax = A(iChannel,1,1)
      
      do j=1,nY
         do i=1,nX
            valMin = valMin+
     *           A(iChannel,i,j)-
     *           dabs(valMin-
     *           A(iChannel,i,j))
            valMax = valMax+
     *           A(iChannel,i,j)+
     *           dabs(valMax-
     *           A(iChannel,i,j))
            valMin = 5.d-1*valMin
            valMax = 5.d-1*valMax
         enddo
      enddo

      return
      end


      subroutine mul_and_copy(xFrom, 
     *     xTo, fScale, nX, nY,
     *     nMaxFrom, nMaxTo,
     *     bDoBoundaries)

      integer i,j
      integer xmin,xmax,ymin,ymax
      integer nx, ny
      integer nMaxFrom,nMaxTo

      logical bDoBoundaries

      real*8 xFrom, xTo, fScale

      dimension xFrom(0:nX+1,0:nMaxFrom+1)
      dimension xTo(0:nX+1,0:nMaxTo+1)

      if(bDoBoundaries .EQV. .TRUE.) then
         xmin = 0
         ymin = 0
         xmax = nX+1
         ymax = nY+1
      else
         xmin = 0
         ymin = 0
         xmax = nx
         ymax = ny
      endif

      do j=ymin,ymax
         do i=xmin,xmax
            xTo(i,j) =
     *           fScale*xFrom(i,j)
         enddo
      enddo

      return
      end

c
c     After call is complete,
c     Sum is a linear combination of A and B
c     
      subroutine makeLinComb(A,B,Sum,
     *     nX,nY,nAmax,nBmax,nSumMax,
     *     scaleA,scaleB, bDoBounds)

      real*8 A,B,Sum
      real*8 scaleA, scaleB

      integer nX, nY
      integer nAMax, nBMax, nSumMax
      integer xMin,xMax
      integer yMin,yMax

      logical bDoBounds

      dimension A(0:nAmax+1,0:nAMax+1)
      dimension B(0:nBmax+1,0:nBMax+1)
      dimension Sum(0:nSummax+1,0:nSumMax+1)

      if(bDoBounds .EQV. .TRUE.) then
         xMin = 0
         yMin = 0
         xMax = nX+1
         yMax = nY+1
      else
         xMin = 1
         yMin = 1
         xMax = nX
         yMax = nY
      endif

      do j=yMin,yMax
         do i=xMin,xMax
            Sum(i,j) = 
     *           scaleA*A(i,j) +
     *           scaleB*B(i,j)
         enddo
      enddo

      return
      end