ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/samples/Madelung/dipoles/buildDipolarArray
Revision: 1898
Committed: Mon Jul 8 21:09:21 2013 UTC (12 years, 2 months ago) by gezelter
File size: 13139 byte(s)
Log Message:
More work on the Luttinger & Tisza structure generator

File Contents

# Content
1 #! /usr/bin/env python
2
3 """Dipolar Lattice Builder
4
5 Creates cubic lattices of dipoles to test the dipole-dipole
6 interaction code.
7
8 Usage: buildDipolarArray
9
10 Options:
11 -h, --help show this help
12 -a, --array-type-A use array type "A" (default)
13 -b, --array-type-B use array type "B"
14 -l, --lattice=... use the specified lattice ( SC, FCC, or BCC )
15 -d, --direction=... use dipole orientation (001, 111, or 011)
16 -c, --constant=... use the specified lattice constant
17 -n use the specified number of unit cells
18 -o, --output-file=... use specified output (.xyz) file
19
20 Type "A" arrays have nearest neighbor strings of antiparallel dipoles.
21
22 Type "B" arrays have nearest neighbor strings of antiparallel dipoles
23 if the dipoles are contained in a plane perpendicular to the dipole
24 direction that passes through the dipole.
25
26 Example:
27 buildDipolarArray -a -l fcc -d 001 -c 5 -n 3 -o A_fcc_001.xyz
28
29 """
30
31 __author__ = "Dan Gezelter (gezelter@nd.edu)"
32 __version__ = "$Revision: 1639 $"
33 __date__ = "$Date: 2011-09-24 16:18:07 -0400 (Sat, 24 Sep 2011) $"
34
35 __copyright__ = "Copyright (c) 2013 by the University of Notre Dame"
36 __license__ = "OpenMD"
37
38 import sys
39 import getopt
40 import string
41 import math
42 import numpy
43
44 def usage():
45 print __doc__
46
47
48
49 def createLattice(latticeType, latticeNumber, latticeConstant, dipoleDirection, doTypeA, outputFileName):
50 # The following section creates 24 basic arrays from Luttinger and
51 # Tisza:
52
53 # The six unit vectors are: 3 spatial and 3 to describe the
54 # orientation of the dipole.
55
56 e1 = numpy.array([1.0,0.0,0.0,0.0,0.0,0.0])
57 e2 = numpy.array([0.0,1.0,0.0,0.0,0.0,0.0])
58 e3 = numpy.array([0.0,0.0,1.0,0.0,0.0,0.0])
59 e4 = numpy.array([0.0,0.0,0.0,1.0,0.0,0.0])
60 e5 = numpy.array([0.0,0.0,0.0,0.0,1.0,0.0])
61 e6 = numpy.array([0.0,0.0,0.0,0.0,0.0,1.0])
62
63 # Parameters describing the 8 basic arrays:
64 cell = numpy.array([[0,0,0],[0,0,1],[1,0,0],[0,1,0],
65 [1,1,0],[0,1,1],[1,0,1],[1,1,1]])
66
67 X = numpy.zeros(384).reshape((8,8,6))
68 Y = numpy.zeros(384).reshape((8,8,6))
69 Z = numpy.zeros(384).reshape((8,8,6))
70 # mX, mY, and mZ arrays have dipole direction flipped
71 mX = numpy.zeros(384).reshape((8,8,6))
72 mY = numpy.zeros(384).reshape((8,8,6))
73 mZ = numpy.zeros(384).reshape((8,8,6))
74
75 # create the 24 basic arrays using Eq. 12 in Luttinger & Tisza:
76 for i in range(8):
77 which = 0
78 for l1 in range(2):
79 for l2 in range(2):
80 for l3 in range(2):
81 lvals = numpy.array([l1,l2,l3])
82 value = math.pow(-1, numpy.dot(cell[i], lvals))
83 Xvec = (l1*e1 + l2*e2 + l3*e3) + value * e4
84 Yvec = (l1*e1 + l2*e2 + l3*e3) + value * e5
85 Zvec = (l1*e1 + l2*e2 + l3*e3) + value * e6
86 mXvec = (l1*e1 + l2*e2 + l3*e3) - value * e4
87 mYvec = (l1*e1 + l2*e2 + l3*e3) - value * e5
88 mZvec = (l1*e1 + l2*e2 + l3*e3) - value * e6
89 X[i][which] = Xvec
90 Y[i][which] = Yvec
91 Z[i][which] = Zvec
92 mX[i][which] = mXvec
93 mY[i][which] = mYvec
94 mZ[i][which] = mZvec
95 which = which + 1
96
97 # The simple cubic array has only one site at the lattice point:
98 lp = numpy.array([0.0,0.0,0.0,0.0,0.0,0.0])
99
100 # The body-centered cubic array also has a body-centerered site:
101 bc = numpy.array([0.5,0.5,0.5,0.0,0.0,0.0])
102
103 # The face-centered cubic array also has 3 face-centered sites:
104 xy = numpy.array([0.5,0.5,0.0,0.0,0.0,0.0])
105 yz = numpy.array([0.0,0.5,0.5,0.0,0.0,0.0])
106 xz = numpy.array([0.5,0.0,0.5,0.0,0.0,0.0])
107
108 sc = numpy.array([[0.0,0.0,0.0]])
109
110 bcc = numpy.array([[0.0,0.0,0.0],
111 [0.5,0.5,0.5]])
112
113 fcc = numpy.array([[0.0,0.0,0.0],
114 [0.5,0.5,0.0],
115 [0.0,0.5,0.5],
116 [0.5,0.0,0.5]])
117
118 known_case = False
119 if (doTypeA):
120 if (latticeType.lower() == 'sc'):
121 basic_array = Z[5]+lp
122 known_case = True
123 if (latticeType.lower() == 'bcc'):
124 if (dipoleDirection.lower() == '001'):
125 basic_array = numpy.append(Z[1]+lp, mZ[1]+bc, axis=0)
126 known_case = True
127 if (dipoleDirection.lower() == '111'):
128 basic_array = numpy.append(Z[5]+X[7]+Y[6]+lp,
129 Z[5]+X[7]+Y[6]+bc, axis=0)
130 known_case = True
131 if (latticeType.lower() == 'fcc'):
132 if (dipoleDirection.lower() == '001'):
133 basic_array = numpy.append(Z[1]+lp, Z[1]+xy, axis=0)
134 basic_array = numpy.append(basic_array, mZ[1]+yz, axis=0)
135 basic_array = numpy.append(basic_array, mZ[1]+xz, axis=0)
136 known_case = True
137 if (dipoleDirection.lower() == '011'):
138 basic_array = numpy.append(Z[1]+Y[1]+lp, Z[1]+Y[1]+yz, axis=0)
139 basic_array = numpy.append(basic_array, mZ[1]+mY[1]+xy, axis=0)
140 basic_array = numpy.append(basic_array, mZ[1]+mY[1]+xz, axis=0)
141 known_case = True
142 else:
143 if (latticeType.lower() == 'sc'):
144 basic_array = Z[5]+lp
145 known_case = True
146 if (latticeType.lower() == 'bcc'):
147 if (dipoleDirection.lower() == '001'):
148 basic_array = numpy.append(Z[5]+lp, mZ[5]+bc, axis=0)
149 known_case = True
150 if (dipoleDirection.lower() == '111'):
151 basic_array = numpy.append(Z[5]+X[7]+Y[6]+lp,
152 Z[5]+X[7]+Y[6]+bc, axis=0)
153 known_case = True
154 if (latticeType.lower() == 'fcc'):
155 if (dipoleDirection.lower() == '001'):
156 basic_array = numpy.append(Z[1]+lp, Z[1]+yz, axis=0)
157 basic_array = numpy.append(basic_array, mZ[1]+xy, axis=0)
158 basic_array = numpy.append(basic_array, mZ[1]+xz, axis=0)
159 known_case = True
160 if (dipoleDirection.lower() == '011'):
161 basic_array = numpy.append(Z[8]+Y[8]+lp, Z[8]+Y[8]+xy, axis=0)
162 basic_array = numpy.append(basic_array, Z[8]+Y[8]+yz, axis=0)
163 basic_array = numpy.append(basic_array, mZ[8]+mY[8]+xz, axis=0)
164 known_case = True
165
166 if (not known_case):
167 print "unhandled combination of lattice and dipole direction"
168 print __doc__
169
170 print basic_array
171
172 bravais_lattice = []
173 for i in range(latticeNumber):
174 for j in range(latticeNumber):
175 for k in range(latticeNumber):
176 for l in range(len(basic_array)):
177 bravais_lattice.append(2*i*e1 + 2*j*e2 + 2*k*e3 + basic_array[l])
178
179 outputFile = open(outputFileName, 'w')
180
181 outputFile.write('<OpenMD version=2>\n')
182 outputFile.write(' <MetaData>\n')
183 outputFile.write(' molecule{\n')
184 outputFile.write(' name = \"D\";\n')
185 outputFile.write(' \n')
186 outputFile.write(' atom[0]{\n')
187 outputFile.write(' type = \"D\";\n')
188 outputFile.write(' position(0.0, 0.0, 0.0);\n')
189 outputFile.write(' orientation(0.0, 0.0, 0.0);\n')
190 outputFile.write(' }\n')
191 outputFile.write(' }\n')
192 outputFile.write(' component{\n')
193 outputFile.write(' type = \"D\";\n')
194 outputFile.write(' nMol = '+ repr(len(bravais_lattice)) + ';\n')
195 outputFile.write(' }\n')
196
197 outputFile.write(' ensemble = NVE;\n')
198 outputFile.write(' forceField = \"Multipole\";\n')
199
200 outputFile.write(' cutoffMethod = \"shifted_force\";\n')
201 outputFile.write(' electrostaticScreeningMethod = \"damped\";\n')
202
203 outputFile.write(' cutoffRadius = 9.0;\n')
204 outputFile.write(' dampingAlpha = 0.18;\n')
205 outputFile.write(' statFileFormat = \"TIME|TOTAL_ENERGY|POTENTIAL_ENERGY|KINETIC_ENERGY|TEMPERATURE|PRESSURE|VOLUME|CONSERVED_QUANTITY|ELECTROSTATIC_POTENTIAL\";\n')
206 outputFile.write(' dt = 1.0;\n')
207 outputFile.write(' runTime = 1.0;\n')
208 outputFile.write(' sampleTime = 1.0;\n')
209 outputFile.write(' statusTime = 1.0;\n')
210 outputFile.write(' </MetaData>\n')
211 outputFile.write(' <Snapshot>\n')
212 outputFile.write(' <FrameData>\n');
213 outputFile.write(" Time: %.10g\n" % (0.0))
214
215 Hxx = 2.0 * latticeConstant * latticeNumber
216 Hyy = 2.0 * latticeConstant * latticeNumber
217 Hzz = 2.0 * latticeConstant * latticeNumber
218
219 outputFile.write(' Hmat: {{%d, 0, 0}, {0, %d, 0}, {0, 0, %d}}\n' % (Hxx, Hyy, Hzz))
220 outputFile.write(' </FrameData>\n')
221 outputFile.write(' <StuntDoubles>\n')
222 sdFormat = 'pvqj'
223 index = 0
224
225 for i in range(len(bravais_lattice)):
226 xcart = latticeConstant*(bravais_lattice[i][0])
227 ycart = latticeConstant*(bravais_lattice[i][1])
228 zcart = latticeConstant*(bravais_lattice[i][2])
229 dx = bravais_lattice[i][3]
230 dy = bravais_lattice[i][4]
231 dz = bravais_lattice[i][5]
232
233 uz = numpy.array([dx, dy, dz])
234 uz = uz/numpy.linalg.norm(uz)
235
236 uy = numpy.array([0.0, 1.0, 0.0])
237 uy = uy - uz * numpy.vdot(uy, uz) / numpy.vdot(uz, uz)
238 uy = uy/numpy.linalg.norm(uy)
239
240 ux = numpy.cross(uy, uz)
241
242 RotMat = [ux, uy, uz]
243
244 q = [0.0, 0.0, 0.0, 0.0]
245
246 # RotMat to Quat code is out of OpenMD's SquareMatrix3.hpp code:
247
248 t = RotMat[0][0] + RotMat[1][1] + RotMat[2][2] + 1.0
249
250 if( t > 1e-6 ):
251 s = 0.5 / math.sqrt( t )
252 q[0] = 0.25 / s
253 q[1] = (RotMat[1][2] - RotMat[2][1]) * s
254 q[2] = (RotMat[2][0] - RotMat[0][2]) * s
255 q[3] = (RotMat[0][1] - RotMat[1][0]) * s
256 else:
257 ad1 = RotMat[0][0]
258 ad2 = RotMat[1][1]
259 ad3 = RotMat[2][2]
260
261 if( ad1 >= ad2 and ad1 >= ad3 ):
262 s = 0.5 / math.sqrt( 1.0 + RotMat[0][0] - RotMat[1][1] - RotMat[2][2] )
263 q[0] = (RotMat[1][2] - RotMat[2][1]) * s
264 q[1] = 0.25 / s
265 q[2] = (RotMat[0][1] + RotMat[1][0]) * s
266 q[3] = (RotMat[0][2] + RotMat[2][0]) * s
267 elif ( ad2 >= ad1 and ad2 >= ad3 ):
268 s = 0.5 / math.sqrt( 1.0 + RotMat[1][1] - RotMat[0][0] - RotMat[2][2] )
269 q[0] = (RotMat[2][0] - RotMat[0][2] ) * s
270 q[1] = (RotMat[0][1] + RotMat[1][0]) * s
271 q[2] = 0.25 / s
272 q[3] = (RotMat[1][2] + RotMat[2][1]) * s
273 else:
274 s = 0.5 / math.sqrt( 1.0 + RotMat[2][2] - RotMat[0][0] - RotMat[1][1] )
275 q[0] = (RotMat[0][1] - RotMat[1][0]) * s
276 q[1] = (RotMat[0][2] + RotMat[2][0]) * s
277 q[2] = (RotMat[1][2] + RotMat[2][1]) * s
278 q[3] = 0.25 / s
279
280
281 outputFile.write("%10d %7s %18.10g %18.10g %18.10g %13e %13e %13e %13e %13e %13e %13e %13e %13e %13e\n" % (index, sdFormat, xcart, ycart, zcart, 0.0, 0.0, 0.0, q[0], q[1], q[2], q[3], 0.0, 0.0, 0.0))
282 index = index+1
283
284 outputFile.write(" </StuntDoubles>\n")
285 outputFile.write(" </Snapshot>\n")
286 outputFile.write("</OpenMD>\n")
287 outputFile.close()
288
289 outputFile.close()
290
291 def main(argv):
292
293 doTypeA = True
294 haveOutputFileName = False
295 latticeType = "fcc"
296 dipoleDirection = "001"
297 latticeNumber = 3
298 latticeConstant = 4
299 try:
300 opts, args = getopt.getopt(argv, "habl:d:c:n:o:", ["help","array-type-A", "array-type-B", "lattice=" "direction=", "constant=", "output-file="])
301 except getopt.GetoptError:
302 usage()
303 sys.exit(2)
304 for opt, arg in opts:
305 if opt in ("-h", "--help"):
306 usage()
307 sys.exit()
308 elif opt in ("-a", "--array-type-A"):
309 doTypeA = True
310 elif opt in ("-b", "--array-type-B"):
311 doTypeA = False
312 elif opt in ("-l", "--lattice"):
313 latticeType = arg
314 elif opt in ("-d", "--direction"):
315 dipoleDirection = arg
316 elif opt in ("-c", "--constant"):
317 latticeConstant = float(arg)
318 elif opt in ("-n"):
319 latticeNumber = int(arg)
320 elif opt in ("-o", "--output-file"):
321 outputFileName = arg
322 haveOutputFileName = True
323 if (not haveOutputFileName):
324 usage()
325 print "No output file was specified"
326 sys.exit()
327
328 createLattice(latticeType, latticeNumber, latticeConstant, dipoleDirection, doTypeA, outputFileName);
329
330 if __name__ == "__main__":
331 if len(sys.argv) == 1:
332 usage()
333 sys.exit()
334 main(sys.argv[1:])

Properties

Name Value
svn:executable *