1 | "GSASII - Space group interpretion routines" |
---|
2 | |
---|
3 | |
---|
4 | import numpy as np |
---|
5 | import sys |
---|
6 | import os.path |
---|
7 | # determine a binary path pased on the host OS and the python version, path is relative to |
---|
8 | # location of this file |
---|
9 | if sys.platform == "win32": |
---|
10 | bindir = '../binwin%d.%d' % sys.version_info[0:2] |
---|
11 | elif sys.platform == "darwin": |
---|
12 | bindir = '../binmac%d.%d' % sys.version_info[0:2] |
---|
13 | else: |
---|
14 | bindir = '../bin' |
---|
15 | if os.path.exists(os.path.join(sys.path[0],bindir)): sys.path.insert(0,os.path.join(sys.path[0],bindir)) |
---|
16 | |
---|
17 | import pypowder as pyd |
---|
18 | |
---|
19 | def SpcGroup(SGSymbol): |
---|
20 | ''' |
---|
21 | input: space group symbol (string) with spaces between axial fields |
---|
22 | returns [SGError,SGData] |
---|
23 | SGError = 0 for no errors; >0 for errors (see SGErrors below for details) |
---|
24 | returns dictionary SGData with entries: |
---|
25 | 'SpGrp': space group symbol slightly cleaned up |
---|
26 | 'Laue': one of '-1','2/m','mmm','4/m','4/mmm','3R','3mR','3', |
---|
27 | '3m1','31m','6/m','6/mmm','m3','m3m' |
---|
28 | 'SGInv': boolean; True if centrosymmetric, False if not |
---|
29 | 'SGLatt': one of 'P','A','B','C','I','F','R' |
---|
30 | 'SGUniq': one of 'a','b','c' if monoclinic, '' otherwise |
---|
31 | 'SGCen': cell centering vectors [0,0,0] at least |
---|
32 | 'SGOps': symmetry operations as [M,T] so that M*x+T = x' |
---|
33 | 'SGSys': one of 'triclinic','monoclinic','orthorhombic','tetragonal','rhombohedral','trigonal','hexagonal','cubic' |
---|
34 | ''' |
---|
35 | LaueSym = ('-1','2/m','mmm','4/m','4/mmm','3R','3mR','3','3m1','31m','6/m','6/mmm','m3','m3m') |
---|
36 | LattSym = ('P','A','B','C','I','F','R') |
---|
37 | UniqSym = ('','','a','b','c','',) |
---|
38 | SysSym = ('triclinic','monoclinic','orthorhombic','tetragonal','rhombohedral','trigonal','hexagonal','cubic') |
---|
39 | SGData = {} |
---|
40 | SGData['SpGrp'] = SGSymbol.strip().lower().capitalize() |
---|
41 | SGInfo = pyd.sgforpy(SGSymbol) |
---|
42 | SGData['SGLaue'] = LaueSym[SGInfo[0]-1] |
---|
43 | SGData['SGInv'] = bool(SGInfo[1]) |
---|
44 | SGData['SGLatt'] = LattSym[SGInfo[2]-1] |
---|
45 | SGData['SGUniq'] = UniqSym[SGInfo[3]+1] |
---|
46 | if SGData['SGLatt'] == 'P': |
---|
47 | SGData['SGCen'] = [[0,0,0],] |
---|
48 | elif SGData['SGLatt'] == 'A': |
---|
49 | SGData['SGCen'] = [[0,0,0],[0,.5,.5],] |
---|
50 | elif SGData['SGLatt'] == 'B': |
---|
51 | SGData['SGCen'] = [[0,0,0],[.5,0,.5],] |
---|
52 | elif SGData['SGLatt'] == 'C': |
---|
53 | SGData['SGCen'] = [[0,0,0],[.5,.5,0,],] |
---|
54 | elif SGData['SGLatt'] == 'I': |
---|
55 | SGData['SGCen'] = [[0,0,0],[.5,.5,.5],] |
---|
56 | elif SGData['SGLatt'] == 'F': |
---|
57 | SGData['SGCen'] = [[0,0,0],[0,.5,.5],[.5,0,.5],[.5,.5,0,],] |
---|
58 | elif SGData['SGLatt'] == 'R': |
---|
59 | SGData['SGCen'] = [[0,0,0],[1./3.,2./3.,2./3.],[2./3.,1./3.,1./3.],] |
---|
60 | SGData['SGOps'] = [] |
---|
61 | for i in range(SGInfo[5]): |
---|
62 | Mat = SGInfo[6][i] |
---|
63 | Trns = SGInfo[7][i] |
---|
64 | SGData['SGOps'].append([Mat,Trns]) |
---|
65 | if SGData['SGLaue'] in '-1': |
---|
66 | SGData['SGSys'] = SysSym[0] |
---|
67 | elif SGData['SGLaue'] in '2/m': |
---|
68 | SGData['SGSys'] = SysSym[1] |
---|
69 | elif SGData['SGLaue'] in 'mmm': |
---|
70 | SGData['SGSys'] = SysSym[2] |
---|
71 | elif SGData['SGLaue'] in ['4/m','4/mmm']: |
---|
72 | SGData['SGSys'] = SysSym[3] |
---|
73 | elif SGData['SGLaue'] in ['3R','3mR']: |
---|
74 | SGData['SGSys'] = SysSym[4] |
---|
75 | elif SGData['SGLaue'] in ['3','3m1','31m']: |
---|
76 | SGData['SGSys'] = SysSym[5] |
---|
77 | elif SGData['SGLaue'] in ['6/m','6/mmm']: |
---|
78 | SGData['SGSys'] = SysSym[6] |
---|
79 | elif SGData['SGLaue'] in ['m3','m3m']: |
---|
80 | SGData['SGSys'] = SysSym[7] |
---|
81 | return SGInfo[8],SGData |
---|
82 | |
---|
83 | def SGErrors(IErr): |
---|
84 | '''Interprets the error message code from SpcGroup. Used in SpaceGroup. |
---|
85 | input: SGError, from SpcGroup |
---|
86 | returns a string with the error message or "Unknown error" |
---|
87 | ''' |
---|
88 | |
---|
89 | ErrString = [' ', |
---|
90 | 'Less than 2 operator fields were found', |
---|
91 | 'Illegal Lattice type, not P, A, B, C, I, F or R', |
---|
92 | 'Rhombohedral lattice requires a 3-axis', |
---|
93 | 'Minus sign does not preceed 1, 2, 3, 4 or 6', |
---|
94 | 'Either a 5-axis anywhere or a 3-axis in field not allowed', |
---|
95 | ' ', |
---|
96 | 'I for COMPUTED GO TO out of range.', |
---|
97 | 'An a-glide mirror normal to A not allowed', |
---|
98 | 'A b-glide mirror normal to B not allowed', |
---|
99 | 'A c-glide mirror normal to C not allowed', |
---|
100 | 'D-glide in a primitive lattice not allowed', |
---|
101 | 'A 4-axis not allowed in the 2nd operator field', |
---|
102 | 'A 6-axis not allowed in the 2nd operator field', |
---|
103 | 'More than 24 matrices needed to define group', |
---|
104 | ' ', |
---|
105 | 'Improper construction of a rotation operator', |
---|
106 | 'Mirror following a / not allowed', |
---|
107 | 'A translation conflict between operators', |
---|
108 | 'The 2bar operator is not allowed', |
---|
109 | '3 fields are legal only in R & m3 cubic groups', |
---|
110 | 'Syntax error. Expected I -4 3 d at this point', |
---|
111 | ' ', |
---|
112 | 'A or B centered tetragonal not allowed', |
---|
113 | ' ','unknown error in sgroup',' ',' ',' ', |
---|
114 | 'Illegal character in the space group symbol', |
---|
115 | ] |
---|
116 | try: |
---|
117 | return ErrString[IErr] |
---|
118 | except: |
---|
119 | return "Unknown error" |
---|
120 | |
---|
121 | def SGPrint(SGData): |
---|
122 | ''' |
---|
123 | Print the output of SpcGroup in a nicely formatted way. Used in SpaceGroup |
---|
124 | input: SGData, from SpcGroup |
---|
125 | returns a list of strings with the space group details |
---|
126 | ''' |
---|
127 | XYZ = ('-Z ','-Y ','-X ','X-Y','ERR','Y-X',' X ',' Y ',' Z ','+X ','+Y ','+Z ') |
---|
128 | TRA = (' ','ERR','1/6','1/4','1/3','ERR','1/2','ERR','2/3','3/4','5/6','ERR') |
---|
129 | POL = (' ','x','y','x y','z','x z','y z','xyz','111') |
---|
130 | Mult = len(SGData['SGCen'])*len(SGData['SGOps'])*(int(SGData['SGInv'])+1) |
---|
131 | NP = [1,2,4] |
---|
132 | NPZ = [0,1] |
---|
133 | for M,T in SGData['SGOps']: |
---|
134 | for i in range(3): |
---|
135 | if M[i][i] <= 0.: NP[i] = 0 |
---|
136 | if M[0][2] > 0: NPZ[0] = 8 |
---|
137 | if M[1][2] > 0: NPZ[1] = 0 |
---|
138 | NPol = (NP[0]+NP[1]+NP[2]+NPZ[0]*NPZ[1])*(1-int(SGData['SGInv'])) |
---|
139 | SGText = [] |
---|
140 | SGText.append('Space Group '+SGData['SpGrp']) |
---|
141 | CentStr = 'centrosymmetric' |
---|
142 | if not SGData['SGInv']: |
---|
143 | CentStr = 'non'+CentStr |
---|
144 | if SGData['SGLatt'] in 'ABCIFR': |
---|
145 | SGText.append('The lattice is '+CentStr+' '+SGData['SGLatt']+'-centered '+SGData['SGSys'].lower()) |
---|
146 | else: |
---|
147 | SGText.append('The lattice is '+CentStr+' '+'primitive '+SGData['SGSys'].lower()) |
---|
148 | SGText.append('Multiplicity of a general site is '+str(Mult)) |
---|
149 | SGText.append('The Laue symmetry is '+SGData['SGLaue']) |
---|
150 | if SGData['SGUniq'] in ['a','b','c']: |
---|
151 | SGText.append('The unique monoclinic axis is '+SGData['SGUniq']) |
---|
152 | if SGData['SGInv']: |
---|
153 | SGText.append('The inversion center is located at 0,0,0') |
---|
154 | if NPol: |
---|
155 | SGText.append('The location of the origin is arbitrary in '+POL[NPol]) |
---|
156 | SGText.append('\n'+'The equivalent positions are:') |
---|
157 | if SGData['SGLatt'] in 'A': |
---|
158 | SGText.append('\n'+' (0,0,0; 0,1/2,1/2)+') |
---|
159 | elif SGData['SGLatt'] in 'B': |
---|
160 | SGText.append('\n'+' (0,0,0; 1/2,0,1/2)+') |
---|
161 | elif SGData['SGLatt'] in 'C': |
---|
162 | SGText.append('\n'+' (0,0,0; 1/2,1/2,0)+') |
---|
163 | elif SGData['SGLatt'] in 'I': |
---|
164 | SGText.append('\n'+' (0,0,0; 1/2,1/2,1/2)+') |
---|
165 | elif SGData['SGLatt'] in 'F': |
---|
166 | SGText.append('\n'+' (0,0,0; 0,1/2,1/2; 1/2,0,1/2; 1/2,1/2,0)+') |
---|
167 | elif SGData['SGLatt'] in 'R': |
---|
168 | SGText.append('\n'+' (0,0,0; 1/3,2/3,2/3; 2/3,1/3,1/3)+') |
---|
169 | if SGData['SGLaue'] in ['-1','2/m','mmm','4/m','4/mmm']: |
---|
170 | Ncol = 2 |
---|
171 | else: |
---|
172 | Ncol = 3 |
---|
173 | line = '' |
---|
174 | for iop,[M,T] in enumerate(SGData['SGOps']): |
---|
175 | if iop % Ncol == 0: |
---|
176 | SGText.append(line) |
---|
177 | line = '' |
---|
178 | Fld = '(%2i) ' % (iop+1) |
---|
179 | for j in range(3): |
---|
180 | IJ = int(round(2*M[j][0]+3*M[j][1]+4*M[j][2]+4)) % 12 |
---|
181 | IK = int(round(T[j]*12)) % 12 |
---|
182 | if IK > 0 and IJ > 4: IJ += 3 |
---|
183 | Fld += TRA[IK]+XYZ[IJ] |
---|
184 | if j != 2: Fld += ',' |
---|
185 | line += Fld |
---|
186 | SGText.append(line) |
---|
187 | return SGText |
---|
188 | |
---|
189 | def SpaceGroup(SgSym): |
---|
190 | ''' |
---|
191 | Print the output of SpcGroup in a nicely formatted way. |
---|
192 | input: space group symbol (string) with spaces between axial fields |
---|
193 | returns nothing |
---|
194 | ''' |
---|
195 | E,A = SpcGroup(SgSym) |
---|
196 | if E > 0: |
---|
197 | print SGErrors(E) |
---|
198 | return |
---|
199 | for l in SGPrint(A): |
---|
200 | print l |
---|
201 | |
---|
202 | def MoveToUnitCell(XYZ): |
---|
203 | ''' |
---|
204 | Translates a set of coordinates so that all values are >=0 and < 1 |
---|
205 | input: a list or numpy array of any length. Note that the object is modified in place. |
---|
206 | output: none |
---|
207 | ''' |
---|
208 | for i,x in enumerate(XYZ): |
---|
209 | x = ((x % 1.0)+1.0) % 1.0 |
---|
210 | if x > 0.9999: x = 0.0 |
---|
211 | XYZ[i] = x |
---|
212 | |
---|
213 | def GenAtom(XYZ,SGData,ifAll=False): |
---|
214 | ''' |
---|
215 | Generates the equivalent positions for a specified coordinate and space group |
---|
216 | input: |
---|
217 | XYZ an array, tuple or list containing 3 elements: x, y & z |
---|
218 | SGData, from SpcGroup |
---|
219 | ifAll=True causes the return to provide the unique set of |
---|
220 | equivalent positions |
---|
221 | =False causes the input position to be repeated. This is the default, |
---|
222 | but why someone would want this, I am not sure. |
---|
223 | Returns a list of two element tuples: |
---|
224 | The first element is the coordinate as a three-element array and |
---|
225 | the second describes the symmetry used to generate the site, of form [-][C]SS |
---|
226 | C indicates a centering operation was used (omitted if the 1st, [0,0,0]) |
---|
227 | SS is the symmetry operator number (1-24) |
---|
228 | - indicates the center of symmetry was used (omitted otherwise) |
---|
229 | ''' |
---|
230 | XYZEquiv = [] |
---|
231 | Idup = [] |
---|
232 | X = np.array(XYZ) |
---|
233 | MoveToUnitCell(X) |
---|
234 | XYZEquiv.append(np.array(X)) |
---|
235 | Idup.append(1) |
---|
236 | for ic,cen in enumerate(SGData['SGCen']): |
---|
237 | C = np.array(cen) |
---|
238 | for invers in range(int(SGData['SGInv']+1)): |
---|
239 | for io,ops in enumerate(SGData['SGOps']): |
---|
240 | idup = ((io+1)+100*ic)*(1-2*invers) |
---|
241 | T = np.array(ops[1]) |
---|
242 | M = np.array(ops[0]) |
---|
243 | newX = np.sum(M*X,axis=1)+T |
---|
244 | if invers: |
---|
245 | newX = -newX |
---|
246 | newX += C |
---|
247 | MoveToUnitCell(newX) |
---|
248 | New = True |
---|
249 | if ifAll: |
---|
250 | if np.allclose(newX,X,atol=0.0002): |
---|
251 | New = False |
---|
252 | idup = 0 |
---|
253 | XYZEquiv.append(newX) |
---|
254 | else: |
---|
255 | for oldX in XYZEquiv[:-1]: |
---|
256 | if np.allclose(newX,oldX,atol=0.0002): |
---|
257 | New = False |
---|
258 | idup = 0 |
---|
259 | if New or ifAll: |
---|
260 | XYZEquiv.append(newX) |
---|
261 | if ifAll and len(XYZEquiv) == 2: |
---|
262 | Idup.append(1) |
---|
263 | else: |
---|
264 | Idup.append(idup) |
---|
265 | if ifAll: |
---|
266 | return zip(XYZEquiv[1:],Idup[1:]) #eliminate duplicate initial entry |
---|
267 | else: |
---|
268 | return zip(XYZEquiv,Idup) |
---|
269 | |
---|
270 | def GetOprPtrName(key): |
---|
271 | OprPtrName = { |
---|
272 | '-6643':[ 2,' 1bar ', 1],'6479' :[ 10,' 2z ', 2],'-6479':[ 9,' mz ', 3], |
---|
273 | '6481' :[ 7,' my ', 4],'-6481':[ 6,' 2y ', 5],'6641' :[ 4,' mx ', 6], |
---|
274 | '-6641':[ 3,' 2x ', 7],'6591' :[ 28,' m+-0 ', 8],'-6591':[ 27,' 2+-0 ', 9], |
---|
275 | '6531' :[ 25,' m110 ',10],'-6531':[ 24,' 2110 ',11],'6537' :[ 61,' 4z ',12], |
---|
276 | '-6537':[ 62,' -4z ',13],'975' :[ 68,' 3+++1',14],'6456' :[ 114,' 3z1 ',15], |
---|
277 | '-489' :[ 73,' 3+-- ',16],'483' :[ 78,' 3-+- ',17],'-969' :[ 83,' 3--+ ',18], |
---|
278 | '819' :[ 22,' m+0- ',19],'-819' :[ 21,' 2+0- ',20],'2431' :[ 16,' m0+- ',21], |
---|
279 | '-2431':[ 15,' 20+- ',22],'-657' :[ 19,' m101 ',23],'657' :[ 18,' 2101 ',24], |
---|
280 | '1943' :[ 48,' -4x ',25],'-1943':[ 47,' 4x ',26],'-2429':[ 13,' m011 ',27], |
---|
281 | '2429' :[ 12,' 2011 ',28],'639' :[ 55,' -4y ',29],'-639' :[ 54,' 4y ',30], |
---|
282 | '-6484':[ 146,' 2010 ', 4],'6484' :[ 139,' m010 ', 5],'-6668':[ 145,' 2100 ', 6], |
---|
283 | '6668' :[ 138,' m100 ', 7],'-6454':[ 148,' 2120 ',18],'6454' :[ 141,' m120 ',19], |
---|
284 | '-6638':[ 149,' 2210 ',20],'6638' :[ 142,' m210 ',21], #search ends here |
---|
285 | '2223' :[ 68,' 3+++2',39], |
---|
286 | '6538' :[ 106,' 6z1 ',40],'-2169':[ 83,' 3--+2',41],'2151' :[ 73,' 3+--2',42], |
---|
287 | '2205' :[ 79,'-3-+-2',43],'-2205':[ 78,' 3-+-2',44],'489' :[ 74,'-3+--1',45], |
---|
288 | '801' :[ 53,' 4y1 ',46],'1945' :[ 47,' 4x3 ',47],'-6585':[ 62,' -4z3 ',48], |
---|
289 | '6585' :[ 61,' 4z3 ',49],'6584' :[ 114,' 3z2 ',50],'6666' :[ 106,' 6z5 ',51], |
---|
290 | '6643' :[ 1,' Iden ',52],'-801' :[ 55,' -4y1 ',53],'-1945':[ 48,' -4x3 ',54], |
---|
291 | '-6666':[ 105,' -6z5 ',55],'-6538':[ 105,' -6z1 ',56],'-2223':[ 69,'-3+++2',57], |
---|
292 | '-975' :[ 69,'-3+++1',58],'-6456':[ 113,' -3z1 ',59],'-483' :[ 79,'-3-+-1',60], |
---|
293 | '969' :[ 84,'-3--+1',61],'-6584':[ 113,' -3z2 ',62],'2169' :[ 84,'-3--+2',63], |
---|
294 | '-2151':[ 74,'-3+--2',64],'0':[0,' ????',0] |
---|
295 | } |
---|
296 | return OprPtrName[key] |
---|
297 | |
---|
298 | def GetKNsym(key): |
---|
299 | KNsym = { |
---|
300 | '0' :' 1 ','1' :' -1 ','64' :' 2(100)','32' :' m(100)', |
---|
301 | '97' :'2/m(100)','16' :' 2(010)','8' :' m(010)','25' :'2/m(010)', |
---|
302 | '2' :' 2(001)','4' :' m(001)','7' :'2/m(001)','134217728' :' 2(011)', |
---|
303 | '67108864' :' m(011)','201326593' :'2/m(011)','2097152' :' 2(0+-)','1048576' :' m(0+-)', |
---|
304 | '3145729' :'2/m(0+-)','8388608' :' 2(101)','4194304' :' m(101)','12582913' :'2/m(101)', |
---|
305 | '524288' :' 2(+0-)','262144' :' m(+0-)','796433' :'2/m(+0-)','1024' :' 2(110)', |
---|
306 | '512' :' m(110)','1537' :'2/m(110)','256' :' 2(+-0)','128' :' m(+-0)', |
---|
307 | '385' :'2/m(+-0)','76' :'mm2(100)','52' :'mm2(010)','42' :'mm2(001)', |
---|
308 | '135266336' :'mm2(011)','69206048' :'mm2(0+-)','8650760' :'mm2(101)','4718600' :'mm2(+0-)', |
---|
309 | '1156' :'mm2(110)','772' :'mm2(+-0)','82' :' 222 ','136314944' :'222(100)', |
---|
310 | '8912912' :'222(010)','1282' :'222(001)','127' :' mmm ','204472417' :'mmm(100)', |
---|
311 | '13369369' :'mmm(010)','1927' :'mmm(001)','33554496' :' 4(100)','16777280' :' -4(100)', |
---|
312 | '50331745' :'4/m(100)','169869394' :'422(100)','84934738' :'-42m 100','101711948' :'4mm(100)', |
---|
313 | '254804095' :'4/mmm100','536870928 ':' 4(010)','268435472' :' -4(010)','805306393' :'4/m (10)', |
---|
314 | '545783890' :'422(010)','272891986' :'-42m 010','541327412' :'4mm(010)','818675839' :'4/mmm010', |
---|
315 | '2050' :' 4(001)','4098' :' -4(001)','6151' :'4/m(001)','3410' :'422(001)', |
---|
316 | '4818' :'-42m 001','2730' :'4mm(001)','8191' :'4/mmm001','8192' :' 3(111)', |
---|
317 | '8193' :' -3(111)','2629888' :' 32(111)','1319040' :' 3m(111)','3940737' :'-3m(111)', |
---|
318 | '32768' :' 3(+--)','32769' :' -3(+--)','10519552' :' 32(+--)','5276160' :' 3m(+--)', |
---|
319 | '15762945' :'-3m(+--)','65536' :' 3(-+-)','65537' :' -3(-+-)','134808576' :' 32(-+-)', |
---|
320 | '67437056' :' 3m(-+-)','202180097' :'-3m(-+-)','131072' :' 3(--+)','131073' :' -3(--+)', |
---|
321 | '142737664' :' 32(--+)','71434368' :' 3m(--+)','214040961' :'-3m(--+)','237650' :' 23 ', |
---|
322 | '237695' :' m3 ','715894098' :' 432 ','358068946' :' -43m ','1073725439':' m3m ', |
---|
323 | '68157504' :' mm2d100','4456464' :' mm2d010','642' :' mm2d001','153092172' :'-4m2 100', |
---|
324 | '277348404' :'-4m2 010','5418' :'-4m2 001','1075726335':' 6/mmm ','1074414420':'-6m2 100', |
---|
325 | '1075070124':'-6m2 120','1075069650':' 6mm ','1074414890':' 622 ','1073758215':' 6/m ', |
---|
326 | '1073758212':' -6 ','1073758210':' 6 ','1073759865':'-3m(100)','1075724673':'-3m(120)', |
---|
327 | '1073758800':' 3m(100)','1075069056':' 3m(120)','1073759272':' 32(100)','1074413824':' 32(120)', |
---|
328 | '1073758209':' -3 ','1073758208':' 3 ','1074135143':'mmm(100)','1075314719':'mmm(010)', |
---|
329 | '1073743751':'mmm(110)','1074004034':' mm2z100','1074790418':' mm2z010','1073742466':' mm2z110', |
---|
330 | '1074004004':'mm2(100)','1074790412':'mm2(010)','1073742980':'mm2(110)','1073872964':'mm2(120)', |
---|
331 | '1074266132':'mm2(210)','1073742596':'mm2(+-0)','1073872930':'222(100)','1074266122':'222(010)', |
---|
332 | '1073743106':'222(110)','1073741831':'2/m(001)','1073741921':'2/m(100)','1073741849':'2/m(010)', |
---|
333 | '1073743361':'2/m(110)','1074135041':'2/m(120)','1075314689':'2/m(210)','1073742209':'2/m(+-0)', |
---|
334 | '1073741828':' m(001) ','1073741888':' m(100) ','1073741840':' m(010) ','1073742336':' m(110) ', |
---|
335 | '1074003968':' m(120) ','1074790400':' m(210) ','1073741952':' m(+-0) ','1073741826':' 2(001) ', |
---|
336 | '1073741856':' 2(100) ','1073741832':' 2(010) ','1073742848':' 2(110) ','1073872896':' 2(120) ', |
---|
337 | '1074266112':' 2(210) ','1073742080':' 2(+-0) ','1073741825':' -1 ' |
---|
338 | } |
---|
339 | return KNsym[key] |
---|
340 | |
---|
341 | def GetNXUPQsym(siteSym): |
---|
342 | NXUPQsym = { |
---|
343 | ' 1 ':(28,29,28,28),' -1 ':( 1,29,28, 0),' 2(100)':(12,18,12,25),' m(100)':(25,18,12,25), |
---|
344 | '2/m(100)':( 1,18, 0,-1),' 2(010)':(13,17,13,24),' m(010)':(24,17,13,24),'2/m(010)':( 1,17, 0,-1), |
---|
345 | ' 2(001)':(14,16,14,23),' m(001)':(23,16,14,23),'2/m(001)':( 1,16, 0,-1),' 2(011)':(10,23,10,22), |
---|
346 | ' m(011)':(22,23,10,22),'2/m(011)':( 1,23, 0,-1),' 2(0+-)':(11,24,11,21),' m(0+-)':(21,24,11,21), |
---|
347 | '2/m(0+-)':( 1,24, 0,-1),' 2(101)':( 8,21, 8,20),' m(101)':(20,21, 8,20),'2/m(101)':( 1,21, 0,-1), |
---|
348 | ' 2(+0-)':( 9,22, 9,19),' m(+0-)':(19,22, 9,19),'2/m(+0-)':( 1,22, 0,-1),' 2(110)':( 6,19, 6,18), |
---|
349 | ' m(110)':(18,19, 6,18),'2/m(110)':( 1,19, 0,-1),' 2(+-0)':( 7,20, 7,17),' m(+-0)':(17,20, 7,17), |
---|
350 | '2/m(+-0)':( 1,20, 0,-1),'mm2(100)':(12,10, 0,-1),'mm2(010)':(13,10, 0,-1),'mm2(001)':(14,10, 0,-1), |
---|
351 | 'mm2(011)':(10,13, 0,-1),'mm2(0+-)':(11,13, 0,-1),'mm2(101)':( 8,12, 0,-1),'mm2(+0-)':( 9,12, 0,-1), |
---|
352 | 'mm2(110)':( 6,11, 0,-1),'mm2(+-0)':( 7,11, 0,-1),' 222 ':( 1,10, 0,-1),'222(100)':( 1,13, 0,-1), |
---|
353 | '222(010)':( 1,12, 0,-1),'222(001)':( 1,11, 0,-1),' mmm ':( 1,10, 0,-1),'mmm(100)':( 1,13, 0,-1), |
---|
354 | 'mmm(010)':( 1,12, 0,-1),'mmm(001)':( 1,11, 0,-1),' 4(100)':(12, 4,12, 0),' -4(100)':( 1, 4,12, 0), |
---|
355 | '4/m(100)':( 1, 4,12,-1),'422(100)':( 1, 4, 0,-1),'-42m 100':( 1, 4, 0,-1),'4mm(100)':(12, 4, 0,-1), |
---|
356 | '4/mmm100':( 1, 4, 0,-1),' 4(010)':(13, 3,13, 0),' -4(010)':( 1, 3,13, 0),'4/m (10)':( 1, 3,13,-1), |
---|
357 | '422(010)':( 1, 3, 0,-1),'-42m 010':( 1, 3, 0,-1),'4mm(010)':(13, 3, 0,-1),'4/mmm010':(1, 3, 0,-1,), |
---|
358 | ' 4(001)':(14, 2,14, 0),' -4(001)':( 1, 2,14, 0),'4/m(001)':( 1, 2,14,-1),'422(001)':( 1, 2, 0,-1), |
---|
359 | '-42m 001':( 1, 2, 0,-1),'4mm(001)':(14, 2, 0,-1),'4/mmm001':( 1, 2, 0,-1),' 3(111)':( 2, 5, 2, 0), |
---|
360 | ' -3(111)':( 1, 5, 2, 0),' 32(111)':( 1, 5, 0, 2),' 3m(111)':( 2, 5, 0, 2),'-3m(111)':( 1, 5, 0,-1), |
---|
361 | ' 3(+--)':( 5, 8, 5, 0),' -3(+--)':( 1, 8, 5, 0),' 32(+--)':( 1, 8, 0, 5),' 3m(+--)':( 5, 8, 0, 5), |
---|
362 | '-3m(+--)':( 1, 8, 0,-1),' 3(-+-)':( 4, 7, 4, 0),' -3(-+-)':( 1, 7, 4, 0),' 32(-+-)':( 1, 7, 0, 4), |
---|
363 | ' 3m(-+-)':( 4, 7, 0, 4),'-3m(-+-)':( 1, 7, 0,-1),' 3(--+)':( 3, 6, 3, 0),' -3(--+)':( 1, 6, 3, 0), |
---|
364 | ' 32(--+)':( 1, 6, 0, 3),' 3m(--+)':( 3, 6, 0, 3),'-3m(--+)':( 1, 6, 0,-1),' 23 ':( 1, 1, 0, 0), |
---|
365 | ' m3 ':( 1, 1, 0, 0),' 432 ':( 1, 1, 0, 0),' -43m ':( 1, 1, 0, 0),' m3m ':( 1, 1, 0, 0), |
---|
366 | ' mm2d100':(12,13, 0,-1),' mm2d010':(13,12, 0,-1),' mm2d001':(14,11, 0,-1),'-4m2 100':( 1, 4, 0,-1), |
---|
367 | '-4m2 010':( 1, 3, 0,-1),'-4m2 001':( 1, 2, 0,-1),' 6/mmm ':( 1, 9, 0,-1),'-6m2 100':( 1, 9, 0,-1), |
---|
368 | '-6m2 120':( 1, 9, 0,-1),' 6mm ':(14, 9, 0,-1),' 622 ':( 1, 9, 0,-1),' 6/m ':( 1, 9,14,-1), |
---|
369 | ' -6 ':( 1, 9,14, 0),' 6 ':(14, 9,14, 0),'-3m(100)':( 1, 9, 0,-1),'-3m(120)':( 1, 9, 0,-1), |
---|
370 | ' 3m(100)':(14, 9, 0,14),' 3m(120)':(14, 9, 0,14),' 32(100)':( 1, 9, 0,14),' 32(120)':( 1, 9, 0,14), |
---|
371 | ' -3 ':( 1, 9,14, 0),' 3 ':(14, 9,14, 0),'mmm(100)':( 1,14, 0,-1),'mmm(010)':( 1,15, 0,-1), |
---|
372 | 'mmm(110)':( 1,11, 0,-1),' mm2z100':(14,14, 0,-1),' mm2z010':(14,15, 0,-1),' mm2z110':(14,11, 0,-1), |
---|
373 | 'mm2(100)':(12,14, 0,-1),'mm2(010)':(13,15, 0,-1),'mm2(110)':( 6,11, 0,-1),'mm2(120)':(15,14, 0,-1), |
---|
374 | 'mm2(210)':(16,15, 0,-1),'mm2(+-0)':( 7,11, 0,-1),'222(100)':( 1,14, 0,-1),'222(010)':( 1,15, 0,-1), |
---|
375 | '222(110)':( 1,11, 0,-1),'2/m(001)':( 1,16,14,-1),'2/m(100)':( 1,25,12,-1),'2/m(010)':( 1,28,13,-1), |
---|
376 | '2/m(110)':( 1,19, 6,-1),'2/m(120)':( 1,27,15,-1),'2/m(210)':( 1,26,16,-1),'2/m(+-0)':( 1,20,17,-1), |
---|
377 | ' m(001) ':(23,16,14,23),' m(100) ':(26,25,12,26),' m(010) ':(27,28,13,27),' m(110) ':(18,19, 6,18), |
---|
378 | ' m(120) ':(24,27,15,24),' m(210) ':(25,26,16,25),' m(+-0) ':(17,20, 7,17),' 2(001) ':(14,16,14,23), |
---|
379 | ' 2(100) ':(12,25,12,26),' 2(010) ':(13,28,13,27),' 2(110) ':( 6,19, 6,18),' 2(120) ':(15,27,15,24), |
---|
380 | ' 2(210) ':(16,26,16,25),' 2(+-0) ':( 7,20, 7,17),' -1 ':( 1,29,28, 0) |
---|
381 | } |
---|
382 | return NXUPQsym[siteSym] |
---|
383 | |
---|
384 | def GetCSxinel(siteSym): |
---|
385 | CSxinel = [[], # 0th empty - indices are Fortran style |
---|
386 | [[0,0,0],[ 0.0, 0.0, 0.0]], # 0 0 0 |
---|
387 | [[1,1,1],[ 1.0, 1.0, 1.0]], # X X X |
---|
388 | [[1,1,1],[ 1.0, 1.0,-1.0]], # X X -X |
---|
389 | [[1,1,1],[ 1.0,-1.0, 1.0]], # X -X X |
---|
390 | [[1,1,1],[ 1.0,-1.0,-1.0]], # -X X X |
---|
391 | [[1,1,0],[ 1.0, 1.0, 0.0]], # X X 0 |
---|
392 | [[1,1,0],[ 1.0,-1.0, 0.0]], # X -X 0 |
---|
393 | [[1,0,1],[ 1.0, 0.0, 1.0]], # X 0 X |
---|
394 | [[1,0,1],[ 1.0, 0.0,-1.0]], # X 0 -X |
---|
395 | [[0,1,1],[ 0.0, 1.0, 1.0]], # 0 Y Y |
---|
396 | [[0,1,1],[ 0.0, 1.0,-1.0]], # 0 Y -Y |
---|
397 | [[1,0,0],[ 1.0, 0.0, 0.0]], # X 0 0 |
---|
398 | [[0,1,0],[ 0.0, 1.0, 0.0]], # 0 Y 0 |
---|
399 | [[0,0,1],[ 0.0, 0.0, 1.0]], # 0 0 Z |
---|
400 | [[1,1,0],[ 1.0, 2.0, 0.0]], # X 2X 0 |
---|
401 | [[1,1,0],[ 2.0, 1.0, 0.0]], # 2X X 0 |
---|
402 | [[1,1,2],[ 1.0, 1.0, 1.0]], # X X Z |
---|
403 | [[1,1,2],[ 1.0,-1.0, 1.0]], # X -X Z |
---|
404 | [[1,2,1],[ 1.0, 1.0, 1.0]], # X Y X |
---|
405 | [[1,2,1],[ 1.0, 1.0,-1.0]], # X Y -X |
---|
406 | [[1,2,2],[ 1.0, 1.0, 1.0]], # X Y Y |
---|
407 | [[1,2,2],[ 1.0, 1.0,-1.0]], # X Y -Y |
---|
408 | [[1,2,0],[ 1.0, 1.0, 0.0]], # X Y 0 |
---|
409 | [[1,0,2],[ 1.0, 0.0, 1.0]], # X 0 Z |
---|
410 | [[0,1,2],[ 0.0, 1.0, 1.0]], # 0 Y Z |
---|
411 | [[1,1,2],[ 1.0, 2.0, 1.0]], # X 2X Z |
---|
412 | [[1,1,2],[ 2.0, 1.0, 1.0]], # 2X X Z |
---|
413 | [[1,2,3],[ 1.0, 1.0, 1.0]], # X Y Z |
---|
414 | ] |
---|
415 | indx = GetNXUPQsym(siteSym) |
---|
416 | return CSxinel[indx[0]] |
---|
417 | |
---|
418 | def GetCSuinel(siteSym): |
---|
419 | CSuinel = [[], # 0th empty - indices are Fortran style |
---|
420 | [[1,1,1,0,0,0],[ 1.0, 1.0, 1.0, 0.0, 0.0, 0.0]], # A A A 0 0 0 |
---|
421 | [[1,1,2,0,0,0],[ 1.0, 1.0, 1.0, 0.0, 0.0, 0.0]], # A A C 0 0 0 |
---|
422 | [[1,2,1,0,0,0],[ 1.0, 1.0, 1.0, 0.0, 0.0, 0.0]], # A B A 0 0 0 |
---|
423 | [[1,2,2,0,0,0],[ 1.0, 1.0, 1.0, 0.0, 0.0, 0.0]], # A B B 0 0 0 |
---|
424 | [[1,1,1,2,2,2],[ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]], # A A A D D D |
---|
425 | [[1,1,1,2,2,2],[ 1.0, 1.0, 1.0, 1.0,-1.0,-1.0]], # A A A D -D -D |
---|
426 | [[1,1,1,2,2,2],[ 1.0, 1.0, 1.0, 1.0,-1.0, 1.0]], # A A A D -D D |
---|
427 | [[1,1,1,2,2,2],[ 1.0, 1.0, 1.0, 1.0, 1.0,-1.0]], # A A A D D -D |
---|
428 | [[1,1,2,1,0,0],[ 1.0, 1.0, 1.0, 0.5, 0.0, 0.0]], # A A C A/2 0 0 |
---|
429 | [[1,2,3,0,0,],[ 1.0, 1.0, 1.0, 0.0, 0.0, 0.0]], # A B C 0 0 0 |
---|
430 | [[1,1,2,3,0,],[ 1.0, 1.0, 1.0, 1.0, 0.0, 0.0]], # A A C D 0 0 |
---|
431 | [[1,2,1,0,3,],[ 1.0, 1.0, 1.0, 0.0, 1.0, 0.0]], # A B A 0 E 0 |
---|
432 | [[1,2,2,0,0,],[ 1.0, 1.0, 1.0, 0.0, 0.0, 1.0]], # A B B 0 0 F |
---|
433 | [[1,2,3,2,0,],[ 1.0, 1.0, 1.0, 0.5, 0.0, 0.0]], # A B C B/2 0 0 |
---|
434 | [[1,2,3,1,0,],[ 1.0, 1.0, 1.0, 0.5, 0.0, 0.0]], # A B C A/2 0 0 |
---|
435 | [[1,2,3,4,0,],[ 1.0, 1.0, 1.0, 1.0, 0.0, 0.0]], # A B C D 0 0 |
---|
436 | [[1,2,3,0,4,],[ 1.0, 1.0, 1.0, 0.0, 1.0, 0.0]], # A B C 0 E 0 |
---|
437 | [[1,2,3,0,0,],[ 1.0, 1.0, 1.0, 0.0, 0.0, 1.0]], # A B C 0 0 F |
---|
438 | [[1,1,2,3,4,],[ 1.0, 1.0, 1.0, 1.0, 1.0,-1.0]], # A A C D E -E |
---|
439 | [[1,1,2,3,4,],[ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]], # A A C D E E |
---|
440 | [[1,2,1,3,4,],[ 1.0, 1.0, 1.0, 1.0, 1.0,-1.0]], # A B A D E -D |
---|
441 | [[1,2,1,3,4,],[ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]], # A B A D E D |
---|
442 | [[1,2,2,3,3,],[ 1.0, 1.0, 1.0, 1.0,-1.0, 1.0]], # A B B D -D F |
---|
443 | [[1,2,2,3,3,],[ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]], # A B B D D F |
---|
444 | [[1,2,3,2,4,],[ 1.0, 1.0, 1.0, 0.5, 0.5, 1.0]], # A B C B/2 F/2 F |
---|
445 | [[1,2,3,1,0,],[ 1.0, 1.0, 1.0, 0.5, 0.0, 1.0]], # A B C A/2 0 F |
---|
446 | [[1,2,3,2,4,],[ 1.0, 1.0, 1.0, 0.5, 1.0, 0.0]], # A B C B/2 E 0 |
---|
447 | [[1,2,3,1,4,],[ 1.0, 1.0, 1.0, 0.5, 1.0, 0.5]], # A B C A/2 E E/2 |
---|
448 | [[1,2,3,4,5,],[ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]], # A B C D E F |
---|
449 | ] |
---|
450 | indx = GetNXUPQsym(siteSym) |
---|
451 | return CSuinel[indx[1]] |
---|
452 | |
---|
453 | def SytSym(XYZ,SGData): |
---|
454 | ''' |
---|
455 | Generates the number of equivalent positions and a site symmetry code for a specified coordinate and space group |
---|
456 | input: |
---|
457 | XYZ: an array, tuple or list containing 3 elements: x, y & z |
---|
458 | SGData: from SpcGroup |
---|
459 | Returns a two element tuple: |
---|
460 | The 1st element is a code for the site symmetry (see GetOprPtrName) |
---|
461 | The 2nd element is the site multiplicity |
---|
462 | ''' |
---|
463 | def PackRot(SGOps): |
---|
464 | IRT = [] |
---|
465 | for ops in SGOps: |
---|
466 | M = ops[0] |
---|
467 | irt = 0 |
---|
468 | for j in range(2,-1,-1): |
---|
469 | for k in range(2,-1,-1): |
---|
470 | irt *= 3 |
---|
471 | irt += M[k][j] |
---|
472 | IRT.append(int(irt)) |
---|
473 | return IRT |
---|
474 | |
---|
475 | SymName = '' |
---|
476 | Mult = 1 |
---|
477 | Isym = 0 |
---|
478 | if SGData['SGLaue'] in ['3','3m1','31m','6/m','6/mmm']: |
---|
479 | Isym = 1073741824 |
---|
480 | Jdup = 1 |
---|
481 | Xeqv = GenAtom(XYZ,SGData,True) |
---|
482 | IRT = PackRot(SGData['SGOps']) |
---|
483 | L = -1 |
---|
484 | for ic,cen in enumerate(SGData['SGCen']): |
---|
485 | for invers in range(int(SGData['SGInv']+1)): |
---|
486 | for io,ops in enumerate(SGData['SGOps']): |
---|
487 | irtx = (1-2*invers)*IRT[io] |
---|
488 | L += 1 |
---|
489 | if not Xeqv[L][1]: |
---|
490 | Jdup += 1 |
---|
491 | jx = GetOprPtrName(str(irtx)) |
---|
492 | if jx[2] < 39: |
---|
493 | Isym += 2**(jx[2]-1) |
---|
494 | if Isym == 1073741824: Isym = 0 |
---|
495 | Mult = len(SGData['SGOps'])*len(SGData['SGCen'])*(int(SGData['SGInv'])+1)/Jdup |
---|
496 | |
---|
497 | return GetKNsym(str(Isym)),Mult |
---|
498 | |
---|