benchmarking of replicated systems

This commit is contained in:
Steve Plimpton
2022-06-01 13:19:47 -06:00
parent d7c1e54538
commit ea3467ab32
13 changed files with 218 additions and 39920 deletions

View File

@ -10,6 +10,8 @@
# -bitorsion file = LAMMPS fix bitorsion file to output (required if BiTorsions)
# -nopbc = non-periodic system (default)
# -pbc xhi yhi zhi = periodic system from 0 to hi in each dimension (optional)
# -rep Nx Ny Nz outfile = replicate periodic system by Nx by Ny by Nz (optional)
# outfile = new xyz file to write out, Null if no file
# Author: Steve Plimpton
@ -43,8 +45,10 @@ def error(txt=""):
class XYZfile:
def __init__(self,file):
lines = open(file,'r').readlines()
header = lines[0]
natoms = int(lines[0].split()[0])
id = []
label = []
type = []
x = []
y = []
@ -54,6 +58,7 @@ class XYZfile:
for line in lines[1:natoms+1]:
words = line.split()
id.append(int(words[0]))
label.append(words[1])
x.append(words[2])
y.append(words[3])
z.append(words[4])
@ -61,15 +66,171 @@ class XYZfile:
blist = words[6:]
blist = [int(one) for one in blist]
bonds.append(blist)
self.header = header
self.natoms = natoms
self.id = id
self.label = label
self.type = type
self.x = x
self.y = y
self.z = z
self.bonds = bonds
# set bond images flags in each dim for each bond of each atom
# used for replication of a periodic system
# 0 = bond partner is closer then half box in dim
# -1 = bond partner is on other side of lower box bound in dim
# +1 = bond partner is on other side of upper box bound in dim
def bond_images(self):
xhalfsq = 0.25 * boxhi[0]*boxhi[0]
yhalfsq = 0.25 * boxhi[1]*boxhi[1]
zhalfsq = 0.25 * boxhi[2]*boxhi[2]
x = self.x
y = self.y
z = self.z
bonds = self.bonds
imageflags = []
for i in range(self.natoms):
xi = float(x[i])
yi = float(y[i])
zi = float(z[i])
oneflags = []
for j in bonds[i]:
xj = float(x[j-1])
yj = float(y[j-1])
zj = float(z[j-1])
dx = xi - xj
dy = yi - yj
dz = zi - zj
if dx*dx <= xhalfsq: ximage = 0
elif xi < xj: ximage = -1
elif xi > xj: ximage = 1
if dy*dy <= yhalfsq: yimage = 0
elif yi < yj: yimage = -1
elif yi > yj: yimage = 1
if dz*dz <= zhalfsq: zimage = 0
elif zi < zj: zimage = -1
elif zi > zj: zimage = 1
oneflags.append((ximage,yimage,zimage))
imageflags.append(oneflags)
self.imageflags = imageflags
# replicate system by Nx and Ny and Nz in each dim
# rebuild data structs (except imageflags) in this class
# also alter global boxhi
def replicate(self,nx,ny,nz):
natoms = self.natoms
id = self.id
label = self.label
type = self.type
x = self.x
y = self.y
z = self.z
bonds = self.bonds
imageflags = self.imageflags
xbox = boxhi[0]
ybox = boxhi[1]
zbox = boxhi[2]
idnew = []
labelnew = []
typenew = []
xnew = []
ynew = []
znew = []
bondsnew = []
count = 0
for k in range(nz):
for j in range(ny):
for i in range(nx):
for m in range(natoms):
count += 1
idnew.append(count)
labelnew.append(label[m])
typenew.append(type[m])
xnew.append(str(float(x[m]) + i*xbox))
ynew.append(str(float(y[m]) + j*ybox))
znew.append(str(float(z[m]) + k*zbox))
oneflags = imageflags[m]
onebonds = []
for n,mbond in enumerate(bonds[m]):
# ijk new = which replicated box the mbond atom is in
if oneflags[n][0] == 0: inew = i
elif oneflags[n][0] == -1: inew = i - 1
elif oneflags[n][0] == 1: inew = i + 1
if inew < 0: inew = nx-1
if inew == nx: inew = 0
if oneflags[n][1] == 0: jnew = j
elif oneflags[n][1] == -1: jnew = j - 1
elif oneflags[n][1] == 1: jnew = j + 1
if jnew < 0: jnew = ny-1
if jnew == ny: jnew = 0
if oneflags[n][2] == 0: knew = k
elif oneflags[n][2] == -1: knew = k - 1
elif oneflags[n][2] == 1: knew = k + 1
if knew < 0: knew = nz-1
if knew == nz: knew = 0
# bondnew = replicated atom ID of bond partner
# based on replication box (inew,jnew,knew) that owns it
bondnew = mbond + natoms*(knew*ny*nx + jnew*nx + inew)
onebonds.append(bondnew)
bondsnew.append(onebonds)
self.natoms = natoms * nx*ny*nz
self.id = idnew
self.label = labelnew
self.type = typenew
self.x = xnew
self.y = ynew
self.z = znew
self.bonds = bondsnew
# write out new xyzfile for replicated system
def output(self,outfile):
fp = open(outfile,'w')
words = self.header.split()
print >>fp,self.natoms,"replicated",' '.join(words[1:])
id = self.id
label = self.label
type = self.type
x = self.x
y = self.y
z = self.z
bonds = self.bonds
# NOTE: worry about formatting of line
for i in range(self.natoms):
print >>fp,i+1,label[i],x[i],y[i],z[i],type[i],
for j in bonds[i]: print >>fp,j,
print >>fp
fp.close()
# triplet of atoms in an angle = atom 1,2,3
# atom2 is center atom
# nbonds = number of atoms which atom2 is bonded to
@ -157,6 +318,26 @@ class PRMfile:
iline += 1
return classes,masses
# replicate per-atom data: classes and masses
def replicate_peratom(self,nx,ny,nz):
classes = self.classes
masses = self.masses
natoms = len(self.masses)
classes_new = []
masses_new = []
for k in range(nz):
for j in range(ny):
for i in range(nx):
for m in range(natoms):
classes_new.append(classes[m])
masses_new.append(masses[m])
self.classes = classes_new
self.masses = masses_new
# polarization groups
def polarize(self):
@ -476,6 +657,7 @@ prmfile = ""
datafile = ""
bitorsionfile = ""
pbcflag = 0
repflag = 0
iarg = 0
while iarg < narg:
@ -512,6 +694,15 @@ while iarg < narg:
zhi = float(args[iarg+3])
boxhi = [xhi,yhi,zhi]
iarg += 4
elif args[iarg] == "-rep":
if iarg + 5 > narg: error()
repflag = 1
nxrep = int(args[iarg+1])
nyrep = int(args[iarg+2])
nzrep = int(args[iarg+3])
outxyz = args[iarg+4]
if outxyz == "NULL": outxyz = ""
iarg += 5
else: error()
# error check
@ -519,12 +710,27 @@ while iarg < narg:
if not xyzfile: error("xyzfile not specified")
if not prmfile: error("prmfile not specified")
if not datafile: error("datafile not specified")
if not pbcflag and repflag: error("cannot replicate non-periodic system")
if repflag and (nxrep <= 0 or nyrep <= 0 or nzrep <= 0):
error("replication factors <= 0 not allowed")
# read Tinker xyz and prm files
xyz = XYZfile(xyzfile)
prm = PRMfile(prmfile)
# replicate system if requested
# both in XYZ and PRM classes
if repflag:
xyz.bond_images()
xyz.replicate(nxrep,nyrep,nzrep)
if outxyz: xyz.output(outxyz)
prm.replicate_peratom(nxrep,nyrep,nzrep)
boxhi[0] *= nxrep
boxhi[1] *= nyrep
boxhi[2] *= nzrep
# create LAMMPS box bounds based on pbcflag
natoms = xyz.natoms