c
c
c     ###################################################
c     ##  COPYRIGHT (C)  1990  by  Jay William Ponder  ##
c     ##              All Rights Reserved              ##
c     ###################################################
c
c     #################################################################
c     ##                                                             ##
c     ##  subroutine beeman  --  computes a molecular dynamics step  ##
c     ##                                                             ##
c     #################################################################
c
c
c     "beeman" performs a single molecular dynamics time step
c     by means of a Beeman multistep recursion formula; the
c     actual coefficients in the recursions are the "Better
c     Beeman" values due to Bernie Brooks which equalize the
c     expected errors in the potential and kinetic energies
c
c
      subroutine beeman (istep,dt,dt_8,dt2_8,ndump)
      implicit none
      include 'sizes.i'
      include 'atmtyp.i'
      include 'atoms.i'
      include 'bath.i'
      include 'bound.i'
      include 'moldyn.i'
      include 'shake.i'
      include 'units.i'
      include 'usage.i'
      integer i,j,istep,ndump
      real*8 dt,dt_8,dt2_8,e_tot,e_kin,e_pot
      real*8 temp,pres,vol,derivs(3,maxatm)
      real*8 xterm,yterm,zterm
      real*8 x_old(maxatm),y_old(maxatm),z_old(maxatm)
c
c
c     store the current atom positions, then find new atom
c     positions and half-step velocities via Beeman recursion
c
      do i = 1, n
         if (use(i)) then
            x_old(i) = x(i)
            y_old(i) = y(i)
            z_old(i) = z(i)
            xterm = 5.0d0*a(1,i) - a_old(1,i)
            yterm = 5.0d0*a(2,i) - a_old(2,i)
            zterm = 5.0d0*a(3,i) - a_old(3,i)
            x(i) = x(i) + v(1,i)*dt + xterm*dt2_8
            y(i) = y(i) + v(2,i)*dt + yterm*dt2_8
            z(i) = z(i) + v(3,i)*dt + zterm*dt2_8
            v(1,i) = v(1,i) + xterm*dt_8
            v(2,i) = v(2,i) + yterm*dt_8
            v(3,i) = v(3,i) + zterm*dt_8
         end if
      end do
c
c     apply "rattle" to correct atom positions and velocities
c
      if (use_rattle)  call rattle (dt,x_old,y_old,z_old)
c
c     get the potential energy and atomic forces
c
      call gradient (e_pot,derivs)
c
c     use Newton's second law to get the next accelerations;
c     find the full-step velocities using the Beeman recursion
c
      do i = 1, n
         if (use(i)) then
            do j = 1, 3
               a_old(j,i) = a(j,i)
               a(j,i) = -convert * derivs(j,i) / mass(i)
               v(j,i) = v(j,i) + (3.0d0*a(j,i)+a_old(j,i))*dt_8
            end do
         end if
      end do
c
c     use "rattle" method to get corrected full-step velocities
c
      if (use_rattle)  call rattle2 (dt)
c
c     sum the total kinetic energy over all atoms
c
      e_kin = 0.0d0
      do i = 1, n
         if (use(i)) then
            do j = 1, 3
               e_kin = e_kin + mass(i)*v(j,i)**2
            end do
         end if
      end do
      e_kin = 0.5d0 * e_kin / convert
c
c     determine system temperature and total energy
c
      temp = 2.0d0 * e_kin / (dble(3*nuse-nrat-6) * gasconst)
      e_tot = e_kin + e_pot
c
c     control temperature and pressure via external bath coupling
c
      if (isothermal)  call temper (dt,temp)
      if (isobaric)  call pressure (dt,pres,vol,e_kin)
c
c     compute any averages or statistics for this step
c
      call mdstat (istep,dt,e_tot,e_pot,e_kin,temp,pres,vol,ndump)
      return
      end
