c
c
c     ###################################################
c     ##  COPYRIGHT (C)  1992  by  Jay William Ponder  ##
c     ##              All Rights Reserved              ##
c     ###################################################
c
c     ################################################################
c     ##                                                            ##
c     ##  subroutine restrain  --  initialize geometric restraints  ##
c     ##                                                            ##
c     ################################################################
c
c
c     "restrain" defines any geometric restraint interaction terms
c     to be included in the potential energy calculation
c
c
      subroutine restrain
      implicit none
      include 'sizes.i'
      include 'iounit.i'
      include 'keys.i'
      include 'potent.i'
      include 'restrn.i'
      integer i,ia,ib,ic,id,ip,next
      real*8 xp,yp,zp,p1
      real*8 d1,d2,d3
      real*8 t1,t2,t3
      character*20 keyword
      character*80 record,string
c
c
c     set the default values for the restraint variables
c
      npfix = 0
      ndfix = 0
      ntfix = 0
      depth = 0.0d0
      width = 0.0d0
      use_basin = .false.
      use_wall = .false.
c
c     search the keywords for restraint parameters
c
      do i = 1, nkey
         next = 1
         record = keyline(i)
         call gettext (record,keyword,next)
         call upcase (keyword)
c
c     specified atom will be restrained to a specified position
c
         if (keyword(1:18) .eq. 'RESTRAIN-POSITION ') then
            xp = 0.0d0
            yp = 0.0d0
            zp = 0.0d0
            p1 = 0.0d0
            string = record(next:80)
            read (string,*,err=10,end=10)  ip,xp,yp,zp,p1
   10       continue
            if (p1 .eq. 0.0d0)  p1 = 100.0d0
            npfix = npfix + 1
            ipfix(npfix) = ip
            xpfix(npfix) = xp
            ypfix(npfix) = yp
            zpfix(npfix) = zp
            pfix(npfix) = p1
            if (npfix .gt. maxfix) then
               write (iout,20)
   20          format (/,' RESTRAIN  --  Too many Position',
     &                    ' Restraints; Increase MAXFIX')
               call fatal
            end if
c
c     distance between two atoms will be restrained to a range
c
         else if (keyword(1:18) .eq. 'RESTRAIN-DISTANCE ') then
            d1 = 0.0d0
            d2 = 0.0d0
            d3 = 0.0d0
            string = record(next:80)
            read (string,*,err=30,end=30)  ia,ib,d1,d2,d3
   30       continue
            if (d2 .eq. 0.0d0)  d2 = d1
            if (d3 .eq. 0.0d0)  d3 = 100.0d0
            ndfix = ndfix + 1
            idfix(1,ndfix) = ia
            idfix(2,ndfix) = ib
            dfix(1,ndfix) = d1
            dfix(2,ndfix) = d2
            dfix(3,ndfix) = d3
            if (ndfix .gt. maxfix) then
               write (iout,40)
   40          format (/,' RESTRAIN  --  Too many Distance',
     &                    ' Restraints; Increase MAXFIX')
               call fatal
            end if
c
c     dihedral angle of four atoms will be restrained to a range
c
         else if (keyword(1:18).eq.'RESTRAIN-DIHEDRAL ') then
            t1 = 0.0d0
            t2 = 0.0d0
            t3 = 0.0d0
            string = record(next:80)
            read (string,*,err=50,end=50)  ia,ib,ic,id,t1,t2,t3
   50       continue
            if (t2 .eq. 0.0d0)  t2 = t1
            if (t3 .eq. 0.0d0)  t3 = 1.0d0
            dowhile (t1 .gt. 180.0d0)
               t1 = t1 - 360.0d0
            end do
            dowhile (t1 .lt. -180.0d0)
               t1 = t1 + 360.0d0
            end do
            dowhile (t2 .gt. 180.0d0)
               t2 = t2 - 360.0d0
            end do
            dowhile (t2 .lt. -180.0d0)
               t2 = t2 + 360.0d0
            end do
            ntfix = ntfix + 1
            itfix(1,ntfix) = ia
            itfix(2,ntfix) = ib
            itfix(3,ntfix) = ic
            itfix(4,ntfix) = id
            tfix(1,ntfix) = t1
            tfix(2,ntfix) = t2
            tfix(3,ntfix) = t3
            if (ntfix .gt. maxfix) then
               write (iout,60)
   60          format (/,' RESTRAIN  --  Too many Torsional',
     &                    ' Restraints; Increase MAXFIX')
               call fatal
            end if
c
c     shallow Gaussian basin restraint between all pairs of atoms
c
         else if (keyword(1:6) .eq. 'BASIN ') then
            string = record(next:80)
            read (string,*,err=70,end=70)  depth,width
   70       continue
            use_basin = .true.
            if (depth .eq. 0.0d0)  use_basin = .false.
            if (width .eq. 0.0d0)  use_basin = .false.
            if (depth .gt. 0.0d0)  depth = -depth
c
c     boundary wall to restrain atoms to a spherical droplet
c
         else if (keyword(1:5) .eq. 'WALL ') then
            string = record(next:80)
            read (string,*,err=80,end=80)  rwall
   80       continue
            if (rwall .gt. 0.0d0)  use_wall = .true.
         end if
      end do
c
c     if geometric restraints are not used, turn off the potential
c
      if (npfix.eq.0 .and. ndfix.eq.0 .and. ntfix.eq.0 .and.
     &         .not.use_basin .and. .not.use_wall) then
          use_geom = .false.
      end if
      return
      end
