c
c
c     ###################################################
c     ##  COPYRIGHT (C)  1990  by  Jay William Ponder  ##
c     ##              All Rights Reserved              ##
c     ###################################################
c
c     #################################################################
c     ##                                                             ##
c     ##  subroutine mdstat  --  compute averages for MD trajectory  ##
c     ##                                                             ##
c     #################################################################
c
c
c     "mdstat" is called at each molecular dynamics time step to
c     form statistics on various average values and fluctuations,
c     and to periodically save the state of the trajectory
c
c
      subroutine mdstat (istep,dt,e_tot,e_pot,e_kin,temp,pres,vol,ndump)
      implicit none
      include 'sizes.i'
      include 'atoms.i'
      include 'bath.i'
      include 'files.i'
      include 'inform.i'
      include 'inter.i'
      include 'iounit.i'
      include 'molcul.i'
      include 'units.i'
      include 'usage.i'
      include 'warp.i'
      integer istep,ixyz,iend
      integer idump,ndump,lext,freeunit
      integer period,modstep,moddump
      real*8 dt,e_tot,e_pot,e_kin
      real*8 temp,pres,vol,pico,dens
      real*8 fluctuate,fluctuate2,intfluct,intfluct2
      real*8 potfluct,potfluct2,kinfluct,kinfluct2
      real*8 tfluct,tfluct2,pfluct,pfluct2,dfluct,dfluct2
      real*8 e_tot_sum,e_tot2_sum,e_int_sum,e_int2_sum
      real*8 e_tot_ave,e_tot2_ave,e_int_ave,e_int2_ave
      real*8 e_pot_sum,e_pot2_sum,e_kin_sum,e_kin2_sum
      real*8 e_pot_ave,e_pot2_ave,e_kin_ave,e_kin2_ave
      real*8 temp_sum,temp2_sum,temp_ave,temp2_ave
      real*8 pres_sum,pres2_sum,pres_ave,pres2_ave
      real*8 dens_sum,dens2_sum,dens_ave,dens2_ave
      character*7 ext
      character*60 coordfile,endfile
      logical exist
      save e_tot_sum,e_tot2_sum,e_int_sum,e_int2_sum
      save e_pot_sum,e_pot2_sum,e_kin_sum,e_kin2_sum
      save temp_sum,temp2_sum,pres_sum,pres2_sum
      save dens_sum,dens2_sum
c
c
c     write energy, temperature and pressure for current step
c
      if (verbose) then
         if (isobaric) then
            write (iout,10)  istep,e_tot,e_pot,e_kin,temp,pres
   10       format (i10,2f14.4,f12.4,2f11.2)
         else
            write (iout,20)  istep,e_tot,e_pot,e_kin,temp
   20       format (i10,2f14.4,f12.4,f11.2)
         end if
      end if
c
c     set number of steps for average and coordinate output
c
      period = 100
      modstep = mod(istep,period)
      moddump = mod(istep,ndump)
c
c     zero out summation variables for new averaging period
c
      if (modstep .eq. 1) then
         e_tot_sum = 0.0d0
         e_tot2_sum = 0.0d0
         e_pot_sum = 0.0d0
         e_pot2_sum = 0.0d0
         e_kin_sum = 0.0d0
         e_kin2_sum = 0.0d0
         e_int_sum = 0.0d0
         e_int2_sum = 0.0d0
         temp_sum = 0.0d0
         temp2_sum = 0.0d0
         pres_sum = 0.0d0
         pres2_sum = 0.0d0
         dens_sum = 0.0d0
         dens2_sum = 0.0d0
      end if
c
c     print header for the averages over a group of recent steps
c
      if (modstep .eq. 0) then
         pico = 1.0d+12 * dt * dble(istep)
         write (iout,30)  period,istep,pico
   30    format (/,' Values over the last ',i3,' out of',i8,
     &              ' Dynamics Steps',
     &           //,' Cumulative Time :',1x,f15.4,' Picosecond')
      end if
c
c     compute total energy and fluctuation for recent steps
c
      e_tot_sum = e_tot_sum + e_tot
      e_tot2_sum = e_tot2_sum + e_tot**2
      if (modstep .eq. 0) then
         e_tot_ave = e_tot_sum / dble(period)
         e_tot2_ave = e_tot2_sum / dble(period)
         fluctuate2 = e_tot2_ave - e_tot_ave**2
         if (fluctuate2 .gt. 0.0d0) then
            fluctuate = sqrt(fluctuate2)
         else
            fluctuate = 0.0d0
         end if
         write (iout,40)  e_tot_ave,fluctuate
   40    format (' Total Energy :',4x,f15.4,' Kcal/mole',3x,
     &              '(+/-',f9.4,')')
      end if
c
c     compute average potential energy and its fluctuation
c
      e_pot_sum = e_pot_sum + e_pot
      e_pot2_sum = e_pot2_sum + e_pot**2
      if (modstep .eq. 0) then
         e_pot_ave = e_pot_sum / dble(period)
         e_pot2_ave = e_pot2_sum / dble(period)
         potfluct2 = e_pot2_ave - e_pot_ave**2
         if (potfluct2 .gt. 0.0d0) then
            potfluct = sqrt(potfluct2)
         else
            potfluct = 0.0d0
         end if
         write (iout,50)  e_pot_ave,potfluct
   50    format (' Potential Energy :',f15.4,' Kcal/mole',3x,
     &              '(+/-',f9.4,')')
      end if
c
c     compute average kinetic energy and its fluctuation
c
      e_kin_sum = e_kin_sum + e_kin
      e_kin2_sum = e_kin2_sum + e_kin**2
      if (modstep .eq. 0) then
         e_kin_ave = e_kin_sum / dble(period)
         e_kin2_ave = e_kin2_sum / dble(period)
         kinfluct2 = e_kin2_ave - e_kin_ave**2
         if (kinfluct2 .gt. 0.0d0) then
            kinfluct = sqrt(kinfluct2)
         else
            kinfluct = 0.0d0
         end if
         write (iout,60)  e_kin_ave,kinfluct
   60    format (' Kinetic Energy :',2x,f15.4,' Kcal/mole',3x,
     &              '(+/-',f9.4,')')
      end if
c
c     compute average intermolecular energy and its fluctuation
c
      if (nmol.ne.1 .and. nmol.ne.n) then
         e_int_sum = e_int_sum + einter
         e_int2_sum = e_int2_sum + einter**2
         if (modstep .eq. 0) then
            e_int_ave = e_int_sum / dble(period)
            e_int2_ave = e_int2_sum / dble(period)
            intfluct2 = e_int2_ave - e_int_ave**2
            if (intfluct2 .gt. 0.0d0) then
               intfluct = sqrt(intfluct2)
            else
               intfluct = 0.0d0
            end if
            write (iout,70)  e_int_ave,intfluct
   70       format (' Intermolecular :',2x,f15.4,' Kcal/mole',3x,
     &                 '(+/-',f9.4,')')
         end if
      end if
c
c     compute the average temperature and its fluctuation
c
      temp_sum = temp_sum + temp
      temp2_sum = temp2_sum + temp**2
      if (modstep .eq. 0) then
         temp_ave = temp_sum / dble(period)
         temp2_ave = temp2_sum / dble(period)
         tfluct2 = temp2_ave - temp_ave**2
         if (tfluct2 .gt. 0.0d0) then
            tfluct = sqrt(tfluct2)
         else
            tfluct = 0.0d0
         end if
         write (iout,80)  temp_ave,tfluct
   80    format (' Temperature :',5x,f15.2,' Kelvin',6x,
     &              '(+/-',f9.2,')')
      end if
c
c     compute the average pressure and its fluctuation
c
      if (isobaric) then
         pres_sum = pres_sum + pres
         pres2_sum = pres2_sum + pres**2
         if (modstep .eq. 0) then
            pres_ave = pres_sum / dble(period)
            pres2_ave = pres2_sum / dble(period)
            pfluct2 = pres2_ave - pres_ave**2
            if (pfluct2 .gt. 0.0d0) then
               pfluct = sqrt(pfluct2)
            else
               pfluct = 0.0d0
            end if
            write (iout,90)  pres_ave,pfluct
   90       format (' Pressure :',8x,f15.2,' Atmosphere',2x,
     &                 '(+/-',f9.2,')')
         end if
c
c     compute the average density and its fluctuation
c
         dens = (1.0d24/avogadro) * (totmass/vol)
         dens_sum = dens_sum + dens
         dens2_sum = dens2_sum + dens**2
         if (modstep .eq. 0) then
            dens_ave = dens_sum / dble(period)
            dens2_ave = dens2_sum / dble(period)
            dfluct2 = dens2_ave - dens_ave**2
            if (dfluct2 .gt. 0.0d0) then
               dfluct = sqrt(dfluct2)
            else
               dfluct = 0.0d0
            end if
            write (iout,100)  dens_ave,dfluct
  100       format (' Density :',9x,f15.4,' Grams/cc',4x,
     &                 '(+/-',f9.4,')')
         end if
      end if
c
c     current value of diffusion equation smoothing deformation
c
      if (use_deform) then
         if (modstep .eq. 0) then
            write (iout,110)  deform
  110       format (' Deformation :',5x,f15.3,' Sqr Angs')
         end if
      end if
c
c     save a structure along the trajectory every so often
c
      if (moddump .eq. 0) then
         idump = nprior + istep/ndump
         lext = 3
         call numeral (idump,ext,lext)
         ixyz = freeunit ()
         coordfile = filename(1:leng)//'.'//ext(1:lext)
         call version (coordfile,'new')
         open (unit=ixyz,file=coordfile,status='new')
         call prtxyz (ixyz)
         close (unit=ixyz)
c
c     save information needed for a restart to a file
c
         call prtdyn
c
c     check for requested termination of the dynamics run
c
         iend = freeunit ()
         endfile = filename(1:leng)//'.end'
         inquire (file=endfile,exist=exist)
         if (exist) then
            write (iout,120)
  120       format (/,' Molecular Dynamics run Terminating due to',
     &                 ' User Request')
            call fatal
         end if
      end if
      return
      end
