c
c
c     ###################################################
c     ##  COPYRIGHT (C)  1993  by  Jay William Ponder  ##
c     ##              All Rights Reserved              ##
c     ###################################################
c
c     ##############################################################
c     ##                                                          ##
c     ##  program testlight  --  time different neighbor schemes  ##
c     ##                                                          ##
c     ##############################################################
c
c
c     "testlight" performs a set of timing tests to compare the
c     evaluation of potential energy and energy/gradient using
c     the method of lights with a double loop over all atom pairs
c
c
      program testlight
      implicit none
      include 'sizes.i'
      include 'atoms.i'
      include 'deriv.i'
      include 'energi.i'
      include 'iounit.i'
      include 'potent.i'
      integer i,j,k,ncalls,npair,map(maxlight)
      real*8 elapsed,eps,xi,yi,zi,r2
      real*8 cev(3,maxatm),ce14(3,maxatm),cec(3,maxatm)
      real*8 xsort(maxlight),ysort(maxlight),zsort(maxlight)
      character*80 string
      logical exist,query,identical
c
c
c     read the molecular system and setup molecular mechanics
c
      call initial
      call getxyz
      call mechanic
c
c     get the number calculation cycles to be performed
c
      ncalls = 0
      query = .true.
      call nextarg (string,exist)
      if (exist) then
         read (string,*,err=10,end=10)  ncalls
         query = .false.
      end if
   10 continue
      if (query) then
         write (iout,20)
   20    format (/,' Enter Desired Number of Repetitions [1] :  ',$)
         read (input,30)  ncalls
   30    format (i10)
      end if
      if (ncalls .eq. 0)  ncalls = 1
c
c     get the timing for setup of method of lights
c
      call setime
      do k = 1, ncalls
         do i = 1, n
            xsort(i) = x(i)
            ysort(i) = y(i)
            zsort(i) = z(i)
         end do
         call lights (n,map,xsort,ysort,zsort)
      end do
      call getime (elapsed)
      write (iout,40)  ncalls
   40 format (/,' Computation Overhead :',11x,'Time',
     &           7x,i5,' Evaluations')
      write (iout,50)  elapsed
   50 format (/,' Method of Lights',11x,f10.3)
c
c     get the timing for setup of double nested loop
c
      call setime
      npair = 0
      do k = 1, ncalls
         do i = 1, n-1
            xi = x(i)
            yi = y(i)
            zi = z(i)
            do j = i+1, n
               r2 = (x(j)-xi)**2 + (y(j)-yi)**2 + (z(j)-zi)**2
               if (r2 .lt. 100.0d0)  npair = npair + 1
            end do
         end do
      end do
      call getime (elapsed)
      write (iout,60)  elapsed
   60 format (' Double Nest Loop',11x,f10.3)
c
c     get the timing for energy terms via method of lights
c
      call setime
      do k = 1, ncalls
         if (use_lj)  call elj4
         if (use_buck)  call ebuck4
         if (use_charge)  call echarge4
      end do
      call getime (elapsed)
      write (iout,70)
   70 format (/,' Potential Energy Only :',10x,'Time',
     &           8x,'E14',10x,'EV',11x,'EC')
      write (iout,80)  elapsed,e14,ev,ec
   80 format (/,' Method of Lights',11x,f10.3,3f13.4)
c
c     get the timing for energy terms via double nested loop
c
      call setime
      do k = 1, ncalls
         if (use_lj)  call elj
         if (use_buck)  call ebuck
         if (use_charge)  call echarge
      end do
      call getime (elapsed)
      write (iout,90)  elapsed,e14,ev,ec
   90 format (' Double Nest Loop',11x,f10.3,3f13.4)
c
c     get the timing for gradient via method of lights
c
      call setime
      do k = 1, ncalls
         if (use_lj)  call elj5
         if (use_buck)  call ebuck5
         if (use_charge)  call echarge5
      end do
      call getime (elapsed)
      write (iout,100)
  100 format (/,' Energy and Gradient :',12x,'Time')
      write (iout,110)  elapsed
  110 format (/,' Method of Lights',11x,f10.3)
c
c     store the method of lights gradient
c
      do i = 1, n
         do j = 1, 3
            cev(j,i) = dev(j,i)
            ce14(j,i) = de14(j,i)
            cec(j,i) = dec(j,i)
         end do
      end do
c
c     get the timing for gradient via double nested loop
c
      call setime
      do k = 1, ncalls
         if (use_lj)  call elj1
         if (use_buck)  call ebuck1
         if (use_charge)  call echarge1
      end do
      call getime (elapsed)
      write (iout,120)  elapsed
  120 format (' Double Nest Loop',11x,f10.3)
c
c     compare method of lights and double loop vdw gradient
c
      identical = .true.
      eps = 1.0d-6
      if (use_lj .or. use_buck) then
         do i = 1, n
            do j = 1, 3
               if (abs(cev(j,i)-dev(j,i)) .gt. eps) then
                  if (identical) then
                     identical = .false.
                     write (iout,130)
  130                format ()
                  end if
                  write (iout,140)  i,j,cev(j,i),dev(j,i)
  140             format (' TESTLIGHT  --  DEV Error at',2i8,2f12.4)
               end if
            end do
         end do
         do i = 1, n
            do j = 1, 3
               if (abs(ce14(j,i)-de14(j,i)) .gt. eps) then
                  if (identical) then
                     identical = .false.
                     write (iout,150)
  150                format ()
                  end if
                  write (iout,160)  i,j,ce14(j,i),de14(j,i)
  160             format (' TESTLIGHT  --  DE14 Error at',2i8,2f12.4)
               end if
            end do
         end do
      end if
c
c     compare method of lights and double loop charge gradient
c
      if (use_charge) then
         do i = 1, n
            do j = 1, 3
               if (abs(cec(j,i)-dec(j,i)) .gt. eps) then
                  if (identical) then
                     identical = .false.
                     write (iout,170)
  170                format ()
                  end if
                  write (iout,180)  i,j,cec(j,i),dec(j,i)
  180             format (' TESTLIGHT  --  DEC Error at',2i8,2f12.4)
               end if
            end do
         end do
      end if
c
c     success if method of lights and double loop give same gradient
c
      if (identical) then
         write (iout,190)
  190    format (/,' Method of Lights and Double Loop Gradients',
     &              ' are Identical')
      end if
      end
