2"""Packmol RigidBody Replacer
4Finds atomistic rigid bodies in a packmol-generated xyz file and
5generates an OpenMD (omd) file with center of mass and orientational
6coordinates for rigid bodies.
11 -h, --help show this help
12 -x, use the specified packmol (.xyz) file
13 -r, --rigid-body=... use this xyz structure as the rigid body
14 -o, --output-file=... use specified output (.omd) file
18 pack2omd -x tolueneBox.xyz -r singleToluene.xyz -o tolueneBox.omd
22__author__ = "Dan Gezelter (gezelter@nd.edu)"
23__copyright__ = "Copyright (c) 2004-present The University of Notre Dame. All Rights Reserved."
35_haveOutputFileName = 0
87 'O_TIP4P-Ew': 15.9994,
110#Hmat = zeros([3,3],Float)
111#BoxInv = zeros([3],Float)
116def readFile(XYZFileName):
117 print("reading XYZ file")
119 XYZFile = open(XYZFileName, 'r')
120 # Find number of atoms first
121 line = XYZFile.readline()
125 line = XYZFile.readline()
126 for i in range(nAtoms):
127 line = XYZFile.readline()
130 indices.append(myIndex)
132 atypes.append(atomType)
136 positions.append([x, y, z])
139def readRBFile(RBFileName):
140 print("reading Rigid Body file")
142 RBFile = open(RBFileName, 'r')
143 # Find number of atoms first
144 line = RBFile.readline()
148 line = RBFile.readline()
149 for i in range(nAtoms):
150 line = RBFile.readline()
153 RBindices.append(myIndex)
155 RBatypes.append(atomType)
159 RBpositions.append([x, y, z])
169 for i in range(0, len(RBindices)):
170 myMass = mass_table[RBatypes[i]]
172 Xcom = Xcom + myMass * RBpositions[i][0]
173 Ycom = Ycom + myMass * RBpositions[i][1]
174 Zcom = Zcom + myMass * RBpositions[i][2]
175 totalMass = totalMass + myMass
177 Xcom = Xcom / totalMass
178 Ycom = Ycom / totalMass
179 Zcom = Zcom / totalMass
181 COM = [Xcom, Ycom, Zcom]
189 #find inertia tensor matrix elements
191 I = numpy.zeros((3, 3), numpy.float)
193 for i in range(0, len(RBindices)):
194 myMass = mass_table[RBatypes[i]]
196 # move the origin of the reference coordinate system to the COM
197 RBpositions[i][0] -= COM[0]
198 RBpositions[i][1] -= COM[1]
199 RBpositions[i][2] -= COM[2]
201 dx = RBpositions[i][0]
202 dy = RBpositions[i][1]
203 dz = RBpositions[i][2]
205 I[0, 0] = I[0, 0] + myMass * ( dy * dy + dz * dz )
206 I[1, 1] = I[1, 1] + myMass * ( dx * dx + dz * dz )
207 I[2, 2] = I[2, 2] + myMass * ( dx * dx + dy * dy )
209 I[0, 1] = I[0, 1] - myMass * ( dx * dy )
210 I[0, 2] = I[0, 2] - myMass * ( dx * dz )
212 I[1, 2] = I[1, 2] - myMass * ( dy * dz )
218 print("Inertia Tensor:")
222 (evals, evects) = numpy.linalg.eig(I)
230 return (COM, evals, evects)
236 for i in range(len(RBindices)):
237 ref_.append(numpy.array([RBpositions[i][0], RBpositions[i][1], RBpositions[i][2]], numpy.float))
238 mov.append(numpy.array([0, 0, 0], numpy.float))
240 print("finding rigid bodies (assuming strict packmol ordering)")
242 nBodies = int( len(indices) / len(RBindices))
246 for j in range(nBodies):
247 mov_com = numpy.zeros(3, numpy.float)
250 for i in range(len(RBindices)):
251 mov[i] = numpy.array([positions[xyzIndex][0], positions[xyzIndex][1], positions[xyzIndex][2]], numpy.float)
252 myMass = mass_table[RBatypes[i]]
253 mov_com = mov_com + myMass*mov[i]
254 totalMass = totalMass + myMass
255 Eliminate.append(xyzIndex)
256 xyzIndex = xyzIndex + 1
258 mov_com = mov_com / totalMass
260 RBpos.append(mov_com)
262 for i in range(len(RBindices)):
263 mov[i] = mov[i] - mov_com
265 R = numpy.zeros((3, 3), numpy.float)
268 for n in range(len(RBindices)):
270 # correlation matrix R:
271 # R(i,j) = sum(over n): y(n,i) * x(n,j)
272 # where x(n) and y(n) are two vector sets
274 R = R + numpy.outer(mov[n], ref_[n])
276 v, s, w = numpy.linalg.svd(R, full_matrices = True)
278 if (numpy.linalg.det(v) * numpy.linalg.det(w) < 0.0):
281 is_reflection = False
286 RotMat = numpy.zeros((3, 3), numpy.float)
289 q = numpy.array([0.0, 0.0, 0.0, 0.0], numpy.float)
291 t = RotMat[0][0] + RotMat[1][1] + RotMat[2][2] + 1.0
294 s = 0.5 / math.sqrt( t )
296 q[1] = (RotMat[1][2] - RotMat[2][1]) * s
297 q[2] = (RotMat[2][0] - RotMat[0][2]) * s
298 q[3] = (RotMat[0][1] - RotMat[1][0]) * s
304 if( ad1 >= ad2 and ad1 >= ad3 ):
305 s = 0.5 / math.sqrt( 1.0 + RotMat[0][0] - RotMat[1][1] - RotMat[2][2] )
306 q[0] = (RotMat[1][2] - RotMat[2][1]) * s
308 q[2] = (RotMat[0][1] + RotMat[1][0]) * s
309 q[3] = (RotMat[0][2] + RotMat[2][0]) * s
310 elif ( ad2 >= ad1 and ad2 >= ad3 ):
311 s = 0.5 / math.sqrt( 1.0 + RotMat[1][1] - RotMat[0][0] - RotMat[2][2] )
312 q[0] = (RotMat[2][0] - RotMat[0][2] ) * s
313 q[1] = (RotMat[0][1] + RotMat[1][0]) * s
315 q[3] = (RotMat[1][2] + RotMat[2][1]) * s
317 s = 0.5 / math.sqrt( 1.0 + RotMat[2][2] - RotMat[0][0] - RotMat[1][1] )
318 q[0] = (RotMat[0][1] - RotMat[1][0]) * s
319 q[1] = (RotMat[0][2] + RotMat[2][0]) * s
320 q[2] = (RotMat[1][2] + RotMat[2][1]) * s
327def writeFile(outputFileName):
328 outputFile = open(outputFileName, 'w')
330 outputFile.write("<OpenMD version=1>\n");
332 for metaline in metaData:
333 outputFile.write(metaline)
335 outputFile.write(" <Snapshot>\n")
337 for frameline in frameData:
338 outputFile.write(frameline)
340 outputFile.write(" <StuntDoubles>\n")
345 for i in range(len(RBpos)):
346 outputFile.write("%10d %7s %18.10g %18.10g %18.10g %13e %13e %13e %13e %13e %13e %13e %13e %13e %13e\n" % (index, sdFormat, RBpos[i][0], RBpos[i][1], RBpos[i][2], 0.0, 0.0, 0.0, RBQuats[i][0], RBQuats[i][1], RBQuats[i][2], RBQuats[i][3], 0.0, 0.0, 0.0))
351 for i in range(len(indices)):
352 if i not in Eliminate:
353 outputFile.write("%10d %7s %18.10g %18.10g %18.10g %13e %13e %13e \n" % (index, sdFormat, positions[i][0], positions[i][1], positions[i][2], 0.0, 0.0, 0.0))
355 outputFile.write(" </StuntDoubles>\n")
356 outputFile.write(" </Snapshot>\n")
357 outputFile.write("</OpenMD>\n")
362 opts, args = getopt.getopt(argv, "hr:x:o:", ["help", "rigid-body=", "xyz-file=", "output-file="])
363 except getopt.GetoptError:
366 for opt, arg in opts:
367 if opt in ("-h", "--help"):
370 elif opt in ("-x", "--xyz-file"):
372 global _haveXYZFileName
374 elif opt in ("-r", "--rigid-body"):
376 global _haveRBFileName
378 elif opt in ("-o", "--output-file"):
380 global _haveOutputFileName
381 _haveOutputFileName = 1
382 if (_haveXYZFileName != 1):
384 print("No input packmol (xyz) file was specified")
386 if (_haveRBFileName != 1):
388 print("No Rigid Body file (xyz) was specified")
390 if (_haveOutputFileName != 1):
392 print("No output file was specified")
395 readRBFile(rbFileName)
396 readFile(xyzFileName)
398 writeFile(outputFileName)
400if __name__ == "__main__":
401 if len(sys.argv) == 1: