enable tinker2lmp.py to generate bitorsions
This commit is contained in:
@ -7,6 +7,7 @@
|
|||||||
# -amoeba file = AMOEBA PRM force field file name (required, or hippo)
|
# -amoeba file = AMOEBA PRM force field file name (required, or hippo)
|
||||||
# -hippo file = HIPPO PRM force field file name (required, or amoeba)
|
# -hippo file = HIPPO PRM force field file name (required, or amoeba)
|
||||||
# -data file = LAMMPS data file to output (required)
|
# -data file = LAMMPS data file to output (required)
|
||||||
|
# -bitorsion file = LAMMPS fix bitorsion file to output (required if BiTorsions)
|
||||||
# -nopbc = non-periodic system (default)
|
# -nopbc = non-periodic system (default)
|
||||||
# -pbc xhi yhi zhi = periodic system from 0 to hi in each dimension (optional)
|
# -pbc xhi yhi zhi = periodic system from 0 to hi in each dimension (optional)
|
||||||
|
|
||||||
@ -31,6 +32,7 @@ def error(txt=""):
|
|||||||
print " -amoeba file"
|
print " -amoeba file"
|
||||||
print " -hippo file"
|
print " -hippo file"
|
||||||
print " -data file"
|
print " -data file"
|
||||||
|
print " -bitorsion file"
|
||||||
print " -nopbc"
|
print " -nopbc"
|
||||||
print " -pbc xhi yhi zhi"
|
print " -pbc xhi yhi zhi"
|
||||||
else: print "ERROR:",txt
|
else: print "ERROR:",txt
|
||||||
@ -108,6 +110,7 @@ class PRMfile:
|
|||||||
self.opbendparams = self.opbend()
|
self.opbendparams = self.opbend()
|
||||||
self.ureyparams = self.ureybonds()
|
self.ureyparams = self.ureybonds()
|
||||||
self.pitorsionparams = self.pitorsions()
|
self.pitorsionparams = self.pitorsions()
|
||||||
|
self.bitorsionparams = self.bitorsions()
|
||||||
self.ntypes = len(self.masses)
|
self.ntypes = len(self.masses)
|
||||||
|
|
||||||
# find a section in the PRM file
|
# find a section in the PRM file
|
||||||
@ -329,10 +332,10 @@ class PRMfile:
|
|||||||
class4 = int(words[4])
|
class4 = int(words[4])
|
||||||
|
|
||||||
if len(words) <= 5:
|
if len(words) <= 5:
|
||||||
error("Torsion has no params: %d %d %d %d" % \
|
error("torsion has no params: %d %d %d %d" % \
|
||||||
(class1,class2,class3,class4))
|
(class1,class2,class3,class4))
|
||||||
if (len(words)-5) % 3:
|
if (len(words)-5) % 3:
|
||||||
error("Torsion does not have triplets of params: %d %d %d %d" % \
|
error("torsion does not have triplets of params: %d %d %d %d" % \
|
||||||
(class1,class2,class3,class4))
|
(class1,class2,class3,class4))
|
||||||
|
|
||||||
mfourier = (len(words)-5) / 3
|
mfourier = (len(words)-5) / 3
|
||||||
@ -399,7 +402,7 @@ class PRMfile:
|
|||||||
iline += 1
|
iline += 1
|
||||||
return params
|
return params
|
||||||
|
|
||||||
# Pi Torsion params, will be read from data file by fix pitorsion
|
# PiTorsion params, will be read from data file by fix pitorsion
|
||||||
|
|
||||||
def pitorsions(self):
|
def pitorsions(self):
|
||||||
params = []
|
params = []
|
||||||
@ -421,6 +424,43 @@ class PRMfile:
|
|||||||
iline += 1
|
iline += 1
|
||||||
return params
|
return params
|
||||||
|
|
||||||
|
# BiTorsion params, will be read from data file by fix bitorsion
|
||||||
|
|
||||||
|
def bitorsions(self):
|
||||||
|
params = []
|
||||||
|
iline = self.find_section("Torsion-Torsion Parameters")
|
||||||
|
if iline < 0: return params
|
||||||
|
iline += 3
|
||||||
|
|
||||||
|
while iline < self.nlines:
|
||||||
|
words = self.lines[iline].split()
|
||||||
|
if len(words):
|
||||||
|
if words[0].startswith("###########"): break
|
||||||
|
if words[0] == "tortors":
|
||||||
|
class1 = int(words[1])
|
||||||
|
class2 = int(words[2])
|
||||||
|
class3 = int(words[3])
|
||||||
|
class4 = int(words[4])
|
||||||
|
class5 = int(words[5])
|
||||||
|
nx = int(words[6])
|
||||||
|
ny = int(words[7])
|
||||||
|
iline += 1
|
||||||
|
array = []
|
||||||
|
for iy in range(ny):
|
||||||
|
xrow = []
|
||||||
|
for ix in range(nx):
|
||||||
|
words = self.lines[iline].split()
|
||||||
|
xgrid = float(words[0])
|
||||||
|
ygrid = float(words[1])
|
||||||
|
value = float(words[2])
|
||||||
|
tuple3 = (xgrid,ygrid,value)
|
||||||
|
xrow.append(tuple3)
|
||||||
|
iline += 1
|
||||||
|
array.append(xrow)
|
||||||
|
params.append((class1,class2,class3,class4,class5,nx,ny,array))
|
||||||
|
iline += 1
|
||||||
|
return params
|
||||||
|
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
# main program
|
# main program
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
@ -434,6 +474,7 @@ amoeba = hippo = 0
|
|||||||
xyzfile = ""
|
xyzfile = ""
|
||||||
prmfile = ""
|
prmfile = ""
|
||||||
datafile = ""
|
datafile = ""
|
||||||
|
bitorsionfile = ""
|
||||||
pbcflag = 0
|
pbcflag = 0
|
||||||
|
|
||||||
iarg = 0
|
iarg = 0
|
||||||
@ -456,6 +497,10 @@ while iarg < narg:
|
|||||||
if iarg + 2 > narg: error()
|
if iarg + 2 > narg: error()
|
||||||
datafile = args[iarg+1]
|
datafile = args[iarg+1]
|
||||||
iarg += 2
|
iarg += 2
|
||||||
|
elif args[iarg] == "-bitorsion":
|
||||||
|
if iarg + 2 > narg: error()
|
||||||
|
bitorsionfile = args[iarg+1]
|
||||||
|
iarg += 2
|
||||||
elif args[iarg] == "-nopbc":
|
elif args[iarg] == "-nopbc":
|
||||||
pbcflag = 0
|
pbcflag = 0
|
||||||
iarg += 1
|
iarg += 1
|
||||||
@ -673,11 +718,7 @@ for atom1,atom2,atom3 in alist:
|
|||||||
elif (c3,c2,c1) in ubdict:
|
elif (c3,c2,c1) in ubdict:
|
||||||
ublist.append((atom3,atom2,atom1))
|
ublist.append((atom3,atom2,atom1))
|
||||||
|
|
||||||
# ----------------------------------------
|
# create pitorslist = list of 6-body interactions
|
||||||
# create list of 6-body Pi-Torsion interactions
|
|
||||||
# ----------------------------------------
|
|
||||||
|
|
||||||
# create ptorslist = list of 6-body interactions
|
|
||||||
# based on central bond, each bond atom is bonded to exactly 2 other atoms
|
# based on central bond, each bond atom is bonded to exactly 2 other atoms
|
||||||
# avoid double counting by requiring atom1 < atom2
|
# avoid double counting by requiring atom1 < atom2
|
||||||
# NOTE: need more info on how to order the 6 atoms for Tinker to compute on
|
# NOTE: need more info on how to order the 6 atoms for Tinker to compute on
|
||||||
@ -716,9 +757,28 @@ for atom1 in id:
|
|||||||
|
|
||||||
pitorsionlist.append((atom3,atom4,atom1,atom2,atom5,atom6))
|
pitorsionlist.append((atom3,atom4,atom1,atom2,atom5,atom6))
|
||||||
|
|
||||||
# DEBUG - if uncommented, no PiTorsions appear in data file
|
# create bitorslist = list of 5-body interactions
|
||||||
|
# generate topology via double loop over neighbors of central atom3
|
||||||
|
# additional double loop over bonds of atom2 and bonds of atom4
|
||||||
|
# avoid double counting the reverse bitorsion by use of btdict dictionary
|
||||||
|
|
||||||
#pitorsionlist = []
|
type = xyz.type
|
||||||
|
classes = prm.classes
|
||||||
|
bonds = xyz.bonds
|
||||||
|
|
||||||
|
bitorsionlist = []
|
||||||
|
btdict = {}
|
||||||
|
|
||||||
|
for atom3 in id:
|
||||||
|
for atom2 in bonds[atom3-1]:
|
||||||
|
for atom4 in bonds[atom3-1]:
|
||||||
|
if atom2 == atom4: continue
|
||||||
|
for atom1 in bonds[atom2-1]:
|
||||||
|
for atom5 in bonds[atom4-1]:
|
||||||
|
if atom1 == atom3 or atom5 == atom3 or atom1 == atom5: continue
|
||||||
|
if (atom5,atom4,atom3,atom2,atom1) in btdict: continue
|
||||||
|
bitorsionlist.append((atom1,atom2,atom3,atom4,atom5))
|
||||||
|
btdict[(atom1,atom2,atom3,atom4,atom5)] = 1
|
||||||
|
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
# create lists of bond/angle/dihedral/improper types
|
# create lists of bond/angle/dihedral/improper types
|
||||||
@ -752,7 +812,7 @@ for atom1,atom2 in blist:
|
|||||||
|
|
||||||
if (c1,c2) in bdict: m,params = bdict[(c1,c2)]
|
if (c1,c2) in bdict: m,params = bdict[(c1,c2)]
|
||||||
elif (c2,c1) in bdict: m,params = bdict[(c2,c1)]
|
elif (c2,c1) in bdict: m,params = bdict[(c2,c1)]
|
||||||
else: error("Bond not found: %d %d: %d %d" % (atom1,atom2,c1,c2))
|
else: error("bond not found: %d %d: %d %d" % (atom1,atom2,c1,c2))
|
||||||
|
|
||||||
if not flags[m]:
|
if not flags[m]:
|
||||||
v1,v2,v3,v4 = params[2:]
|
v1,v2,v3,v4 = params[2:]
|
||||||
@ -869,7 +929,7 @@ for i,one in enumerate(alist):
|
|||||||
m += 2
|
m += 2
|
||||||
|
|
||||||
else:
|
else:
|
||||||
error("Angle not found: %d %d %d: %d %d %d" % (atom1,atom2,atom3,c1,c2,c3))
|
error("angle not found: %d %d %d: %d %d %d" % (atom1,atom2,atom3,c1,c2,c3))
|
||||||
|
|
||||||
if not flags[m]:
|
if not flags[m]:
|
||||||
pflag,ubflag,v1,v2,v3,v4,v5,v6 = params[3][which-1]
|
pflag,ubflag,v1,v2,v3,v4,v5,v6 = params[3][which-1]
|
||||||
@ -979,7 +1039,7 @@ for atom1,atom2,atom3,atom4 in dlist:
|
|||||||
if (c1,c2,c3,c4) in ddict: m,params = ddict[(c1,c2,c3,c4)]
|
if (c1,c2,c3,c4) in ddict: m,params = ddict[(c1,c2,c3,c4)]
|
||||||
elif (c4,c3,c2,c1) in ddict: m,params = ddict[(c4,c3,c2,c1)]
|
elif (c4,c3,c2,c1) in ddict: m,params = ddict[(c4,c3,c2,c1)]
|
||||||
else:
|
else:
|
||||||
error("Dihedral not found: %d %d %d %d: %d %d %d %d" % \
|
error("dihedral not found: %d %d %d %d: %d %d %d %d" % \
|
||||||
(atom1,atom2,atom3,atom4,c1,c2,c3,c4))
|
(atom1,atom2,atom3,atom4,c1,c2,c3,c4))
|
||||||
|
|
||||||
if not flags[m]:
|
if not flags[m]:
|
||||||
@ -1063,7 +1123,7 @@ for tmp1,tmp2,atom1,atom2,tmp3,tmp4 in pitorsionlist:
|
|||||||
c1 = classes[type1-1]
|
c1 = classes[type1-1]
|
||||||
c2 = classes[type2-1]
|
c2 = classes[type2-1]
|
||||||
|
|
||||||
# 6-tuple is only a PiTorsion if central 2 atoms math an entry in PRM file
|
# 6-tuple is only a PiTorsion if central 2 atoms match an entry in PRM file
|
||||||
# pitorsionlist_reduced = list of just these 6-tuples
|
# pitorsionlist_reduced = list of just these 6-tuples
|
||||||
|
|
||||||
if (c1,c2) in pitdict or (c2,c1) in pitdict:
|
if (c1,c2) in pitdict or (c2,c1) in pitdict:
|
||||||
@ -1081,6 +1141,57 @@ for tmp1,tmp2,atom1,atom2,tmp3,tmp4 in pitorsionlist:
|
|||||||
|
|
||||||
pitorsionlist = pitorsionlist_reduced
|
pitorsionlist = pitorsionlist_reduced
|
||||||
|
|
||||||
|
# generate bitorsiontype = LAMMPS type of each bitorsion
|
||||||
|
# generate bitorsionparams = LAMMPS params for each bitorsion type
|
||||||
|
# flags[i] = which LAMMPS bitorsion type (1-N) the Ith Tinker PRM file btors is
|
||||||
|
# 0 = none
|
||||||
|
# convert prm.bitorsionparams to a dictionary for efficient searching
|
||||||
|
# key = (class1,class2,class3,class4,class5)
|
||||||
|
# value = (M,params) where M is index into prm.bitorsionparams
|
||||||
|
|
||||||
|
id = xyz.id
|
||||||
|
type = xyz.type
|
||||||
|
classes = prm.classes
|
||||||
|
|
||||||
|
bitdict = {}
|
||||||
|
for m,params in enumerate(prm.bitorsionparams):
|
||||||
|
bitdict[(params[0],params[1],params[2],params[3],params[4])] = (m,params)
|
||||||
|
|
||||||
|
flags = len(prm.bitorsionparams)*[0]
|
||||||
|
bitorsiontype = []
|
||||||
|
bitorsionparams = []
|
||||||
|
bitorsionlist_reduced = []
|
||||||
|
|
||||||
|
for atom1,atom2,atom3,atom4,atom5 in bitorsionlist:
|
||||||
|
type1 = type[atom1-1]
|
||||||
|
type2 = type[atom2-1]
|
||||||
|
type3 = type[atom3-1]
|
||||||
|
type4 = type[atom4-1]
|
||||||
|
type5 = type[atom5-1]
|
||||||
|
c1 = classes[type1-1]
|
||||||
|
c2 = classes[type2-1]
|
||||||
|
c3 = classes[type3-1]
|
||||||
|
c4 = classes[type4-1]
|
||||||
|
c5 = classes[type5-1]
|
||||||
|
|
||||||
|
# 5-tuple is only a BiTorsion if 5 atoms match an entry in PRM file
|
||||||
|
# bitorsionlist_reduced = list of just these 5-tuples
|
||||||
|
|
||||||
|
if (c1,c2,c3,c4,c5) in bitdict or (c5,c4,c3,c2,c1) in bitdict:
|
||||||
|
if (c1,c2,c3,c4,c5) in bitdict: m,params = bitdict[(c1,c2,c3,c4,c5)]
|
||||||
|
else: m,params = bitdict[(c5,c4,c3,c2,c1)]
|
||||||
|
bitorsionlist_reduced.append((atom1,atom2,atom3,atom4,atom5))
|
||||||
|
|
||||||
|
if not flags[m]:
|
||||||
|
v1 = params[5:]
|
||||||
|
bitorsionparams.append(v1)
|
||||||
|
flags[m] = len(bitorsionparams)
|
||||||
|
bitorsiontype.append(flags[m])
|
||||||
|
|
||||||
|
# replace original bitorsionlist with reduced version
|
||||||
|
|
||||||
|
bitorsionlist = bitorsionlist_reduced
|
||||||
|
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
# assign each atom to a Tinker group
|
# assign each atom to a Tinker group
|
||||||
# NOTE: doing this inside LAMMPS now
|
# NOTE: doing this inside LAMMPS now
|
||||||
@ -1136,6 +1247,7 @@ nangles = len(alist)
|
|||||||
ndihedrals = len(dlist)
|
ndihedrals = len(dlist)
|
||||||
nimpropers = len(olist)
|
nimpropers = len(olist)
|
||||||
npitorsions = len(pitorsionlist)
|
npitorsions = len(pitorsionlist)
|
||||||
|
nbitorsions = len(bitorsionlist)
|
||||||
|
|
||||||
# data file header values
|
# data file header values
|
||||||
|
|
||||||
@ -1271,6 +1383,36 @@ if npitorsions:
|
|||||||
lines.append(line+'\n')
|
lines.append(line+'\n')
|
||||||
d.sections["PiTorsions"] = lines
|
d.sections["PiTorsions"] = lines
|
||||||
|
|
||||||
|
if nbitorsions:
|
||||||
|
d.headers["bitorsions"] = len(pitorsionlist)
|
||||||
|
|
||||||
|
# if there are bitorsions, then -bitorsion file must have been specified
|
||||||
|
|
||||||
|
if not bitorsionfile:
|
||||||
|
error("no -bitorsion file was specified, but %d bitorsions exist" % \
|
||||||
|
nbitorsions)
|
||||||
|
|
||||||
|
fp = open(bitorsionfile,'w')
|
||||||
|
print >>fp,"Tinker BiTorsion parameter file for fix bitorsion\n"
|
||||||
|
print >>fp,"%d bitorsion types" % len(bitorsionparams)
|
||||||
|
itype = 0
|
||||||
|
for nx,ny,array in bitorsionparams:
|
||||||
|
itype += 1
|
||||||
|
print >>fp
|
||||||
|
print >>fp,itype,nx,ny
|
||||||
|
for ix in range(nx):
|
||||||
|
for iy in range(ny):
|
||||||
|
xgrid,ygrid,value = array[ix][iy]
|
||||||
|
print >>fp," ",xgrid,ygrid,value
|
||||||
|
fp.close()
|
||||||
|
|
||||||
|
lines = []
|
||||||
|
for i,one in enumerate(bitorsionlist):
|
||||||
|
line = "%d %d %d %d %d %d %d" % \
|
||||||
|
(i+1,bitorsiontype[i],one[0],one[1],one[2],one[3],one[4])
|
||||||
|
lines.append(line+'\n')
|
||||||
|
d.sections["BiTorsions"] = lines
|
||||||
|
|
||||||
d.write(datafile)
|
d.write(datafile)
|
||||||
|
|
||||||
# print stats to screen
|
# print stats to screen
|
||||||
@ -1286,8 +1428,10 @@ print "Nangles =",nangles
|
|||||||
print "Ndihedrals =",ndihedrals
|
print "Ndihedrals =",ndihedrals
|
||||||
print "Nimpropers =",nimpropers
|
print "Nimpropers =",nimpropers
|
||||||
print "Npitorsions =",npitorsions
|
print "Npitorsions =",npitorsions
|
||||||
|
print "Nbitorsions =",nbitorsions
|
||||||
print "Nbondtypes =",len(bparams)
|
print "Nbondtypes =",len(bparams)
|
||||||
print "Nangletypes =",len(aparams)
|
print "Nangletypes =",len(aparams)
|
||||||
print "Ndihedraltypes =",len(dparams)
|
print "Ndihedraltypes =",len(dparams)
|
||||||
print "Nimpropertypes =",len(oparams)
|
print "Nimpropertypes =",len(oparams)
|
||||||
print "Npitorsiontypes =",len(pitorsionparams)
|
print "Npitorsiontypes =",len(pitorsionparams)
|
||||||
|
print "Nbitorsiontypes =",len(bitorsionparams)
|
||||||
|
|||||||
Reference in New Issue
Block a user