8 def generate_trianglepoints(maxlayer
, include_origin
= False, v3d
= True, circular
= True, sixthindices
= False, mirrorindices
= False):
9 _e6
= np
.array([[math
.cos(2*math
.pi
*i
/6),math
.sin(2*math
.pi
*i
/6),0] if v3d
else [math
.cos(2*math
.pi
*i
/6),math
.sin(2*math
.pi
*i
/6)] for i
in range(6)])
10 points
= np
.empty((3*maxlayer
*(maxlayer
+1)+(1 if include_origin
else 0), 3 if v3d
else 2))
13 points
[0] = np
.array((0,0,0) if v3d
else (0,0))
16 si
= np
.empty((6,(maxlayer
*(maxlayer
+1))//2), dtype
=int)
20 mi
= np
.empty((2,0,), dtype
=int)
22 #layer indices start from one!
23 ilayer
= np
.arange(1, maxlayer
+1) # We need first to "copy" layer indices to correspond to the Muster count
24 mustercount
= (ilayer
- 1)//2
25 mustercum
= np
.cumsum(mustercount
)
26 layerstart
= np
.zeros((mustercum
[maxlayer
- 1]), dtype
=int)
27 layerstart
[mustercum
[:(maxlayer
-1)]] = 1
28 layer
= np
.cumsum(layerstart
) + 2 # That's it
29 lb
= 3*layer
*(layer
-1) # layer base (lowest) index
30 li
= np
.arange(len(layer
)) - mustercum
[layer
-2] # muster indices for each layers
31 mi
= np
.empty((2, len(layer
)), dtype
=int)
32 mi
[0] = lb
+ 1 + li
+ include_origin
33 mi
[1] = lb
+ layer
- (1 + li
) + include_origin
34 # there are two non-musters in each even layer, one non-muster in each odd
35 layer
= (2*np
.arange(((3*maxlayer
)//2))+1)//3 + 1
36 nmi
= 3*layer
*(layer
-1)
37 nmi
[2::3] += layer
[2::3] // 2 # second non-musters in even layers
40 for layer
in range(1,maxlayer
+1):
45 points
[point_i
:(point_i
+layer
)] = base
[nx
,:] + ar
[:,nx
] * shift
[nx
,:]
47 si
[i
, sii
[i
]:sii
[i
]+layer
] = point_i
+ ar
51 mask
= (np
.sum(points
* points
, axis
= -1) <= maxlayer
* maxlayer
* 3/ 4 + 0.1) # UGLY FIX OF ASYMMETRY BECAUSE OF ROUNDING ERROR
54 cum
= np
.cumsum(mask
) - 1
59 cum
= np
.cumsum(mask
) - 1
66 if not (mirrorindices
or sixthindices
):
69 return {'points': points
,
70 'si' : si
if sixthindices
else None,
71 'mi' : mi
if mirrorindices
else None,
72 'nmi' : nmi
if mirrorindices
else None}
74 def generate_trianglepoints_hexcomplement(maxlayer
, v3d
= True, circular
= True, thirdindices
= False, mirrorindices
=False):
75 _e6
= np
.array([[math
.cos(2*math
.pi
*i
/6),math
.sin(2*math
.pi
*i
/6),0] if v3d
else [math
.cos(2*math
.pi
*i
/6),math
.sin(2*math
.pi
*i
/6)] for i
in range(6)])
76 _f6
= np
.array([[-math
.sin(2*math
.pi
*i
/6),math
.cos(2*math
.pi
*i
/6),0] if v3d
else [math
.sin(2*math
.pi
*i
/6),-math
.cos(2*math
.pi
*i
/6)] for i
in range(6)])
77 points
= np
.empty((3*maxlayer
*maxlayer
, 3 if v3d
else 2))
79 # 3 * layer ** 2 is the basis index for a layer, a layer contains 3 * (2*layer + 1) points
81 ii
= np
.arange(maxlayer
**2)
82 layer
= np
.empty((maxlayer
**2), dtype
=int)
83 layer
= np
.sqrt(ii
, out
=layer
, casting
='unsafe')
84 #ti0 = 2*layer**2 + ii
85 ti
= np
.arange(3)[:, nx
] * (2*layer
+ 1)[nx
, :] + (2*layer
**2 + ii
)[nx
,:]
87 ii
= np
.arange(((maxlayer
-1)*maxlayer
)//2)
88 layer
= np
.empty((((maxlayer
-1)*maxlayer
)//2), dtype
=int)
89 layer
= (np
.sqrt(1+8*ii
, out
=layer
, casting
='unsafe')+1)//2
90 li
= ii
- ((layer
) * (layer
-1))//2# numbers indices in a each layer
91 lb
= 3*layer
**2 # base index of a layer
92 mi
= np
.empty((2,len(layer
)), dtype
=int)
93 mi
[0] = lb
+ li
+ layer
% 2
94 mi
[1] = lb
+ 2*layer
- li
95 # indices of non-mirrored/self-mirrored
96 layer
= np
.arange(maxlayer
)
98 nmi
= lb
+ ((layer
+ 1) % 2) * layer
99 for layer
in range(0,maxlayer
):
100 if (layer
% 2): # odd layer
102 base
= _f6
[(2*i
-1)%6] * ((0.5 + 1.5 * layer
) / _s3
)
103 shift
= _e6
[(2*i
+2)%6]
104 count
= (layer
+ 1) // 2
105 ar
= np
.arange(count
)
106 points
[point_i
:point_i
+count
,:] = base
+ ar
[:,nx
]*shift
[nx
,:]
109 base
= _e6
[(2*i
+1)%6]*layer
+ _f6
[(2*i
)%6] / _s3
110 shift
= _e6
[(2*i
+3)%6]
112 ar
= np
.arange(count
)
113 points
[point_i
:point_i
+count
,:] = base
+ ar
[:,nx
]*shift
[nx
,:]
116 base
= _e6
[(2*i
+2)%6]*layer
+ _f6
[(2*i
)%6] / _s3
117 shift
= _e6
[(2*i
+4)%6]
118 count
= (layer
+ 1) // 2
119 ar
= np
.arange(count
)
120 points
[point_i
:point_i
+count
,:] = base
+ ar
[:,nx
]*shift
[nx
,:]
124 shift
= _e6
[(2*i
+2)%6]
125 base
= _f6
[(2*i
-1)%6] * ((0.5 + 1.5 * layer
) / _s3
) + shift
/ 2
127 ar
= np
.arange(count
)
128 points
[point_i
:point_i
+count
,:] = base
+ ar
[:,nx
]*shift
[nx
,:]
131 base
= _e6
[(2*i
+1)%6]*layer
+ _f6
[(2*i
)%6] / _s3
132 shift
= _e6
[(2*i
+3)%6]
134 ar
= np
.arange(count
)
135 points
[point_i
:point_i
+count
,:] = base
+ ar
[:,nx
]*shift
[nx
,:]
138 base
= _e6
[(2*i
+2)%6]*layer
+ _f6
[(2*i
)%6] / _s3
139 shift
= _e6
[(2*i
+4)%6]
140 count
= (layer
+ 2) // 2
141 ar
= np
.arange(count
)
142 points
[point_i
:point_i
+count
,:] = base
+ ar
[:,nx
]*shift
[nx
,:]
147 mask
= (np
.sum(points
* points
, axis
= -1) <= maxlayer
* maxlayer
* 3/ 4 + 0.01) # UGLY FIX OF ASYMMETRY BECAUSE OF ROUNDING ERROR
148 points
= points
[mask
]
150 cum
= np
.cumsum(mask
) - 1
155 cum
= np
.cumsum(mask
) - 1
162 if not (mirrorindices
or thirdindices
):
165 return {'points': points
,
166 'ti' : ti
if thirdindices
else None,
167 'mi' : mi
if mirrorindices
else None,
168 'nmi' : nmi
if mirrorindices
else None
172 from .cycommon
import get_mn_y
173 from .cytranslations
import trans_calculator
174 from .qpms_p
import cart2sph
176 def hexlattice_precalc_AB_save(file, lMax
, k_hexside
, maxlayer
, circular
=True, savepointinfo
= False, J_scat
=3):
179 'k_hexside' : k_hexside
,
180 'maxlayer' : maxlayer
,
181 'circular' : circular
,
182 'savepointinfo' : savepointinfo
,
185 tpdict
= generate_trianglepoints(maxlayer
, v3d
=True, circular
=circular
, sixthindices
=True, mirrorindices
=True)
186 tphcdict
= generate_trianglepoints_hexcomplement(maxlayer
, v3d
=True, circular
=circular
, thirdindices
=True, mirrorindices
=True)
187 my
, ny
= get_mn_y(lMax
)
189 a_self_nm
= np
.empty((tpdict
['nmi'].shape
[0],nelem
,nelem
), dtype
=complex)
190 b_self_nm
= np
.empty((tpdict
['nmi'].shape
[0],nelem
,nelem
), dtype
=complex)
191 a_self_m0
= np
.empty((tpdict
['mi'].shape
[1],nelem
,nelem
), dtype
=complex)
192 b_self_m0
= np
.empty((tpdict
['mi'].shape
[1],nelem
,nelem
), dtype
=complex)
193 a_d2u_nm
= np
.empty((tphcdict
['nmi'].shape
[0],nelem
,nelem
), dtype
=complex)
194 b_d2u_nm
= np
.empty((tphcdict
['nmi'].shape
[0],nelem
,nelem
), dtype
=complex)
195 a_d2u_m0
= np
.empty((tphcdict
['mi'].shape
[1],nelem
,nelem
), dtype
=complex)
196 b_d2u_m0
= np
.empty((tphcdict
['mi'].shape
[1],nelem
,nelem
), dtype
=complex)
198 k_0
= k_hexside
*_s3
# not really a wave vector here because of the normalisation!
199 tc
= trans_calculator(lMax
)
203 points
= tpdict
['points'][tpdict
['nmi']]
204 d_i2j
= cart2sph(points
)
205 a_self_nm
, b_self_nm
= tc
.get_AB_arrays(k_0
*d_i2j
[:,0],d_i2j
[:,1],d_i2j
[:,2],np
.array([False]),J_scat
)
207 points
= tpdict
['points'][tpdict
['mi'][0]]
208 d_i2j
= cart2sph(points
)
209 a_self_m0
, b_self_m0
= tc
.get_AB_arrays(k_0
*d_i2j
[:,0],d_i2j
[:,1],d_i2j
[:,2],np
.array([False]),J_scat
)
211 points
= tphcdict
['points'][tphcdict
['nmi']]
212 d_i2j
= cart2sph(points
)
213 a_d2u_nm
, b_d2u_nm
= tc
.get_AB_arrays(k_0
*d_i2j
[:,0],d_i2j
[:,1],d_i2j
[:,2],np
.array([False]),J_scat
)
215 points
= tphcdict
['points'][tphcdict
['mi'][0]]
216 d_i2j
= cart2sph(points
)
217 a_d2u_m0
, b_d2u_m0
= tc
.get_AB_arrays(k_0
*d_i2j
[:,0],d_i2j
[:,1],d_i2j
[:,2],np
.array([False]),J_scat
)
220 'a_self_nm' : a_self_nm
,
221 'a_self_m0' : a_self_m0
,
222 'b_self_nm' : b_self_nm
,
223 'b_self_m0' : b_self_m0
,
224 'a_d2u_nm' : a_d2u_nm
,
225 'a_d2u_m0' : a_d2u_m0
,
226 'b_d2u_nm' : b_d2u_nm
,
227 'b_d2u_m0' : b_d2u_m0
,
228 'precalc_params' : params
231 tosave
['tp_points'] = tpdict
['points'],
232 tosave
['tp_si'] = tpdict
['si'],
233 tosave
['tp_mi'] = tpdict
['mi'],
234 tosave
['tp_nmi'] = tpdict
['nmi']
235 tosave
['tphc_points'] = tphcdict
['points'],
236 tosave
['tphc_ti'] = tphcdict
['ti'],
237 tosave
['tphc_mi'] = tphcdict
['mi'],
238 tosave
['tphc_nmi'] = tphcdict
['nmi']
239 np
.savez(file, **tosave
)
241 def hexlattice_precalc_AB_loadunwrap(file, tpdict
= None, tphcdict
= None, return_points
= False):
243 precalc_params
= npz
['precalc_params'][()]
244 my
, ny
= get_mn_y(precalc_params
['lMax'])
246 # this I should have made more universal...
247 if precalc_params
['savepointinfo']:
250 'points' : npz
['tp_points'],
253 'nmi' : npz
['tp_nmi'],
257 'points' : npz
['tphc_points'],
258 'ti' : npz
['tphc_ti'],
259 'mi' : npz
['tphc_mi'],
260 'nmi' : npz
['tphc_nmi']
264 tpdict
= generate_trianglepoints(maxlayer
= precalc_params
['maxlayer'], v3d
=True,
265 circular
=precalc_params
['circular'], sixthindices
=True, mirrorindices
=True)
267 tphcdict
= generate_trianglepoints_hexcomplement(maxlayer
=precalc_params
['maxlayer'], v3d
=True,
268 circular
=precalc_params
['circular'], thirdindices
=True, mirrorindices
=True)
270 # For some obscure reason, I keep getting trailing single-dimension in the beginning for these arrays
271 for a
in (tpdict
['points'], tphcdict
['points'], tpdict
['si'], tpdict
['mi'],
272 tphcdict
['ti'], tphcdict
['mi']):
274 a
.shape
= a
.shape
[1::]
276 self_tr
= tpdict
['points']
277 d2u_tr
= tphcdict
['points']
278 if len(self_tr
.shape
)>2:
279 self_tr
= np
.reshape(self_tr
, self_tr
.shape
[1::])
280 if len(d2u_tr
.shape
)>2:
281 d2u_tr
= np
.reshape(d2u_tr
, d2u_tr
.shape
[1::])
283 a_self
= np
.empty((self_tr
.shape
[0],nelem
,nelem
), dtype
=complex)
284 b_self
= np
.empty((self_tr
.shape
[0],nelem
,nelem
), dtype
=complex)
285 a_d2u
= np
.empty(( d2u_tr
.shape
[0],nelem
,nelem
), dtype
=complex)
286 b_d2u
= np
.empty(( d2u_tr
.shape
[0],nelem
,nelem
), dtype
=complex)
287 a_self
[tpdict
['nmi']]=npz
['a_self_nm']
288 a_self
[tpdict
['mi'][0]]=npz
['a_self_m0']
289 b_self
[tpdict
['nmi']]=npz
['b_self_nm']
290 b_self
[tpdict
['mi'][0]]=npz
['b_self_m0']
291 mirrorangles
= cart2sph(self_tr
[tpdict
['mi'][1]])[:,2] - cart2sph(self_tr
[tpdict
['mi'][0]])[:,2]
292 a_self
[tpdict
['mi'][1],:,:] = a_self
[tpdict
['mi'][0],:,:] * np
.exp(1j
*mirrorangles
[:,nx
,nx
]*(my
[nx
,nx
,:]-my
[nx
,:,nx
]))
293 b_self
[tpdict
['mi'][1],:,:] = b_self
[tpdict
['mi'][0],:,:] * np
.exp(1j
*mirrorangles
[:,nx
,nx
]*(my
[nx
,nx
,:]-my
[nx
,:,nx
]))
295 a_self
[tpdict
['si'][i
],:,:] = a_self
[tpdict
['si'][0],:,:] * np
.exp(1j
*math
.pi
/3*i
*(my
[nx
,:]-my
[:,nx
]))
296 b_self
[tpdict
['si'][i
],:,:] = b_self
[tpdict
['si'][0],:,:] * np
.exp(1j
*math
.pi
/3*i
*(my
[nx
,:]-my
[:,nx
]))
297 a_d2u
[tphcdict
['nmi']]=npz
['a_d2u_nm']
298 a_d2u
[tphcdict
['mi'][0]]=npz
['a_d2u_m0']
299 b_d2u
[tphcdict
['nmi']]=npz
['b_d2u_nm']
300 b_d2u
[tphcdict
['mi'][0]]=npz
['b_d2u_m0']
301 mirrorangles
= cart2sph(self_tr
[tphcdict
['mi'][1]])[:,2] - cart2sph(self_tr
[tphcdict
['mi'][0]])[:,2]
302 a_d2u
[tphcdict
['mi'][1],:,:] = a_d2u
[tphcdict
['mi'][0],:,:] * np
.exp(1j
*mirrorangles
[:,nx
,nx
]*(my
[nx
,nx
,:]-my
[nx
,:,nx
]))
303 b_d2u
[tphcdict
['mi'][1],:,:] = b_d2u
[tphcdict
['mi'][0],:,:] * np
.exp(1j
*mirrorangles
[:,nx
,nx
]*(my
[nx
,nx
,:]-my
[nx
,:,nx
]))
305 a_d2u
[tphcdict
['ti'][i
],:,:] = a_d2u
[tphcdict
['ti'][0],:,:] * np
.exp(i
*2j
*math
.pi
/3*(my
[nx
,:]-my
[:,nx
]))
306 b_d2u
[tphcdict
['ti'][i
],:,:] = b_d2u
[tphcdict
['ti'][0],:,:] * np
.exp(i
*2j
*math
.pi
/3*(my
[nx
,:]-my
[:,nx
]))
307 a_u2d
= a_d2u
* (-1)**(my
[nx
,:]-my
[:,nx
])
308 b_u2d
= b_d2u
* (-1)**(my
[nx
,:]-my
[:,nx
])
317 for k
in precalc_params
.keys():
318 d
[k
] = precalc_params
[k
]
320 d
['d2u_tr'] = tphcdict
['points']
321 d
['u2d_tr'] = -tphcdict
['points']
322 d
['self_tr'] = tpdict
['points']
325 def hexlattice_get_AB(lMax
, k_hexside
, maxlayer
, circular
=True, return_points
= True, J_scat
=3):
328 'k_hexside' : k_hexside
,
329 'maxlayer' : maxlayer
,
330 'circular' : circular
,
331 'savepointinfo' : return_points
, # should I delete this key?
334 tpdict
= generate_trianglepoints(maxlayer
, v3d
=True, circular
=circular
, sixthindices
=True, mirrorindices
=True)
335 tphcdict
= generate_trianglepoints_hexcomplement(maxlayer
, v3d
=True, circular
=circular
, thirdindices
=True, mirrorindices
=True)
336 my
, ny
= get_mn_y(lMax
)
338 a_self_nm
= np
.empty((tpdict
['nmi'].shape
[0],nelem
,nelem
), dtype
=complex)
339 b_self_nm
= np
.empty((tpdict
['nmi'].shape
[0],nelem
,nelem
), dtype
=complex)
340 a_self_m0
= np
.empty((tpdict
['mi'].shape
[1],nelem
,nelem
), dtype
=complex)
341 b_self_m0
= np
.empty((tpdict
['mi'].shape
[1],nelem
,nelem
), dtype
=complex)
342 a_d2u_nm
= np
.empty((tphcdict
['nmi'].shape
[0],nelem
,nelem
), dtype
=complex)
343 b_d2u_nm
= np
.empty((tphcdict
['nmi'].shape
[0],nelem
,nelem
), dtype
=complex)
344 a_d2u_m0
= np
.empty((tphcdict
['mi'].shape
[1],nelem
,nelem
), dtype
=complex)
345 b_d2u_m0
= np
.empty((tphcdict
['mi'].shape
[1],nelem
,nelem
), dtype
=complex)
347 k_0
= k_hexside
*_s3
# not really a wave vector here because of the normalisation!
348 tc
= trans_calculator(lMax
)
352 points
= tpdict
['points'][tpdict
['nmi']]
353 d_i2j
= cart2sph(points
)
354 a_self_nm
, b_self_nm
= tc
.get_AB_arrays(k_0
*d_i2j
[:,0],d_i2j
[:,1],d_i2j
[:,2],np
.array([False]),J_scat
)
356 points
= tpdict
['points'][tpdict
['mi'][0]]
357 d_i2j
= cart2sph(points
)
358 a_self_m0
, b_self_m0
= tc
.get_AB_arrays(k_0
*d_i2j
[:,0],d_i2j
[:,1],d_i2j
[:,2],np
.array([False]),J_scat
)
360 points
= tphcdict
['points'][tphcdict
['nmi']]
361 d_i2j
= cart2sph(points
)
362 a_d2u_nm
, b_d2u_nm
= tc
.get_AB_arrays(k_0
*d_i2j
[:,0],d_i2j
[:,1],d_i2j
[:,2],np
.array([False]),J_scat
)
364 points
= tphcdict
['points'][tphcdict
['mi'][0]]
365 d_i2j
= cart2sph(points
)
366 a_d2u_m0
, b_d2u_m0
= tc
.get_AB_arrays(k_0
*d_i2j
[:,0],d_i2j
[:,1],d_i2j
[:,2],np
.array([False]),J_scat
)
369 'a_self_nm' : a_self_nm,
370 'a_self_m0' : a_self_m0,
371 'b_self_nm' : b_self_nm,
372 'b_self_m0' : b_self_m0,
373 'a_d2u_nm' : a_d2u_nm,
374 'a_d2u_m0' : a_d2u_m0,
375 'b_d2u_nm' : b_d2u_nm,
376 'b_d2u_m0' : b_d2u_m0,
377 'precalc_params' : params
380 tosave['tp_points'] = tpdict['points'],
381 tosave['tp_si'] = tpdict['si'],
382 tosave['tp_mi'] = tpdict['mi'],
383 tosave['tp_nmi'] = tpdict['nmi']
384 tosave['tphc_points'] = tphcdict['points'],
385 tosave['tphc_ti'] = tphcdict['ti'],
386 tosave['tphc_mi'] = tphcdict['mi'],
387 tosave['tphc_nmi'] = tphcdict['nmi']
388 np.savez(file, **tosave)
390 self_tr
= tpdict
['points']
391 d2u_tr
= tphcdict
['points']
392 if len(self_tr
.shape
)>2:
393 self_tr
= np
.reshape(self_tr
, self_tr
.shape
[1::])
394 if len(d2u_tr
.shape
)>2:
395 d2u_tr
= np
.reshape(d2u_tr
, d2u_tr
.shape
[1::])
397 a_self
= np
.empty((self_tr
.shape
[0],nelem
,nelem
), dtype
=complex)
398 b_self
= np
.empty((self_tr
.shape
[0],nelem
,nelem
), dtype
=complex)
399 a_d2u
= np
.empty(( d2u_tr
.shape
[0],nelem
,nelem
), dtype
=complex)
400 b_d2u
= np
.empty(( d2u_tr
.shape
[0],nelem
,nelem
), dtype
=complex)
401 a_self
[tpdict
['nmi']]=a_self_nm
402 a_self
[tpdict
['mi'][0]]=a_self_m0
403 b_self
[tpdict
['nmi']]=b_self_nm
404 b_self
[tpdict
['mi'][0]]=b_self_m0
405 mirrorangles
= cart2sph(self_tr
[tpdict
['mi'][1]])[:,2] - cart2sph(self_tr
[tpdict
['mi'][0]])[:,2]
406 a_self
[tpdict
['mi'][1],:,:] = a_self
[tpdict
['mi'][0],:,:] * np
.exp(1j
*mirrorangles
[:,nx
,nx
]*(my
[nx
,nx
,:]-my
[nx
,:,nx
]))
407 b_self
[tpdict
['mi'][1],:,:] = b_self
[tpdict
['mi'][0],:,:] * np
.exp(1j
*mirrorangles
[:,nx
,nx
]*(my
[nx
,nx
,:]-my
[nx
,:,nx
]))
409 a_self
[tpdict
['si'][i
],:,:] = a_self
[tpdict
['si'][0],:,:] * np
.exp(1j
*math
.pi
/3*i
*(my
[nx
,:]-my
[:,nx
]))
410 b_self
[tpdict
['si'][i
],:,:] = b_self
[tpdict
['si'][0],:,:] * np
.exp(1j
*math
.pi
/3*i
*(my
[nx
,:]-my
[:,nx
]))
411 a_d2u
[tphcdict
['nmi']]=a_d2u_nm
412 a_d2u
[tphcdict
['mi'][0]]=a_d2u_m0
413 b_d2u
[tphcdict
['nmi']]=b_d2u_nm
414 b_d2u
[tphcdict
['mi'][0]]=b_d2u_m0
415 mirrorangles
= cart2sph(self_tr
[tphcdict
['mi'][1]])[:,2] - cart2sph(self_tr
[tphcdict
['mi'][0]])[:,2]
416 a_d2u
[tphcdict
['mi'][1],:,:] = a_d2u
[tphcdict
['mi'][0],:,:] * np
.exp(1j
*mirrorangles
[:,nx
,nx
]*(my
[nx
,nx
,:]-my
[nx
,:,nx
]))
417 b_d2u
[tphcdict
['mi'][1],:,:] = b_d2u
[tphcdict
['mi'][0],:,:] * np
.exp(1j
*mirrorangles
[:,nx
,nx
]*(my
[nx
,nx
,:]-my
[nx
,:,nx
]))
419 a_d2u
[tphcdict
['ti'][i
],:,:] = a_d2u
[tphcdict
['ti'][0],:,:] * np
.exp(i
*2j
*math
.pi
/3*(my
[nx
,:]-my
[:,nx
]))
420 b_d2u
[tphcdict
['ti'][i
],:,:] = b_d2u
[tphcdict
['ti'][0],:,:] * np
.exp(i
*2j
*math
.pi
/3*(my
[nx
,:]-my
[:,nx
]))
421 a_u2d
= a_d2u
* (-1)**(my
[nx
,:]-my
[:,nx
])
422 b_u2d
= b_d2u
* (-1)**(my
[nx
,:]-my
[:,nx
])
431 for k
in params
.keys():
434 d
['d2u_tr'] = tphcdict
['points']
435 d
['u2d_tr'] = -tphcdict
['points']
436 d
['self_tr'] = tpdict
['points']
439 from scipy
.constants
import c
440 from .timetrack
import _time_b
, _time_e
441 from .tmatrices
import symz_indexarrays
443 def hexlattice_zsym_getSVD(lMax
, TMatrices_om
, epsilon_b
, hexside
, maxlayer
, omega
, klist
, gaussianSigma
=False, onlyNmin
=0, verbose
=False):
444 btime
= _time_b(verbose
)
445 nelem
= lMax
* (lMax
+ 2)
446 n2id
= np
.identity(2*nelem
)
447 n2id
.shape
= (2,nelem
,2,nelem
)
449 k_0
= omega
* math
.sqrt(epsilon_b
) / c
450 tdic
= hexlattice_get_AB(lMax
,k_0
*hexside
,maxlayer
)
451 a_self
= tdic
['a_self'][:,:nelem
,:nelem
]
452 b_self
= tdic
['b_self'][:,:nelem
,:nelem
]
453 a_u2d
= tdic
['a_u2d'][:,:nelem
,:nelem
]
454 b_u2d
= tdic
['b_u2d'][:,:nelem
,:nelem
]
455 a_d2u
= tdic
['a_d2u'][:,:nelem
,:nelem
]
456 b_d2u
= tdic
['b_d2u'][:,:nelem
,:nelem
]
457 unitcell_translations
= tdic
['self_tr']*hexside
*_s3
458 u2d_translations
= tdic
['u2d_tr']*hexside
*_s3
459 d2u_translations
= tdic
['d2u_tr']*hexside
*_s3
462 sbtime
= _time_b(verbose
, step
='Calculating gaussian envelope')
463 unitcell_envelope
= np
.exp(-np
.sum(tdic
['self_tr']**2,axis
=-1)/(2*gaussianSigma
**2))
464 u2d_envelope
= np
.exp(-np
.sum(tdic
['u2d_tr']**2,axis
=-1)/(2*gaussianSigma
**2))
465 d2u_envelope
= np
.exp(-np
.sum(tdic
['d2u_tr']**2,axis
=-1)/(2*gaussianSigma
**2))
466 _time_e(sbtime
, verbose
, step
='Calculating gaussian envelope')
468 #TMatrices_om = TMatrices_interp(omega)
470 svUfullTElist
= np
.full((klist
.shape
[0], 2*nelem
, 2*nelem
), np
.nan
, dtype
=complex)
471 svVfullTElist
= np
.full((klist
.shape
[0], 2*nelem
, 2*nelem
), np
.nan
, dtype
=complex)
472 svSfullTElist
= np
.full((klist
.shape
[0], 2*nelem
), np
.nan
, dtype
=complex)
473 svUfullTMlist
= np
.full((klist
.shape
[0], 2*nelem
, 2*nelem
), np
.nan
, dtype
=complex)
474 svVfullTMlist
= np
.full((klist
.shape
[0], 2*nelem
, 2*nelem
), np
.nan
, dtype
=complex)
475 svSfullTMlist
= np
.full((klist
.shape
[0], 2*nelem
), np
.nan
, dtype
=complex)
477 minsvTElist
= np
.full((klist
.shape
[0], onlyNmin
),np
.nan
)
478 minsvTMlist
= np
.full((klist
.shape
[0], onlyNmin
),np
.nan
)
480 leftmatrixlist
= np
.full((klist
.shape
[0],2,2,nelem
,2,2,nelem
),np
.nan
,dtype
=complex)
481 #isNaNlist = np.zeros((klist.shape[0]), dtype=bool)
482 isNaNlist
= (k_0
*k_0
- klist
[:,0]**2 - klist
[:,1]**2 < 0)
483 nnlist
= np
.logical_not(isNaNlist
)
485 sbtime
= _time_b(verbose
, step
='Initialization of matrices for SVD for a given list of k\'s')
488 #ki = np.arange(klist.shape[0])[k_0*k_0 - klist[:,0]**2 - klist[:,1]**2 >= 0]
491 phases_self
= np
.exp(1j
*np
.tensordot(k
,unitcell_translations
,axes
=(-1,-1)))
492 phases_u2d
= np
.exp(1j
*np
.tensordot(k
,u2d_translations
,axes
=(-1,-1)))
493 phases_d2u
= np
.exp(1j
*np
.tensordot(k
,d2u_translations
,axes
=(-1,-1)))
495 phases_self
*= unitcell_envelope
496 phases_u2d
*= u2d_envelope
497 phases_d2u
*= d2u_envelope
498 leftmatrix
= np
.zeros((k
.shape
[0],2,2,nelem
, 2,2,nelem
), dtype
=complex)
501 leftmatrix
[:,0,0,:,0,0,:] = np
.tensordot(phases_self
,a_self
, axes
=(-1,0)) # u2u, E2E
502 leftmatrix
[:,1,0,:,1,0,:] = leftmatrix
[:,0,0,:,0,0,:] # d2d, E2E
503 leftmatrix
[:,0,1,:,0,1,:] = leftmatrix
[:,0,0,:,0,0,:] # u2u, M2M
504 leftmatrix
[:,1,1,:,1,1,:] = leftmatrix
[:,0,0,:,0,0,:] # d2d, M2M
505 leftmatrix
[:,0,0,:,0,1,:] = np
.tensordot(phases_self
,b_self
, axes
=(-1,0)) # u2u, M2E
506 leftmatrix
[:,0,1,:,0,0,:] = leftmatrix
[:,0,0,:,0,1,:] # u2u, E2M
507 leftmatrix
[:,1,1,:,1,0,:] = leftmatrix
[:,0,0,:,0,1,:] # d2d, E2M
508 leftmatrix
[:,1,0,:,1,1,:] = leftmatrix
[:,0,0,:,0,1,:] # d2d, M2E
509 leftmatrix
[:,0,0,:,1,0,:] = np
.tensordot(phases_d2u
, a_d2u
,axes
=(-1,0)) #d2u,E2E
510 leftmatrix
[:,0,1,:,1,1,:] = leftmatrix
[:,0,0,:,1,0,:] #d2u, M2M
511 leftmatrix
[:,1,0,:,0,0,:] = np
.tensordot(phases_u2d
, a_u2d
,axes
=(-1,0)) #u2d,E2E
512 leftmatrix
[:,1,1,:,0,1,:] = leftmatrix
[:,1,0,:,0,0,:] #u2d, M2M
513 leftmatrix
[:,0,0,:,1,1,:] = np
.tensordot(phases_d2u
, b_d2u
,axes
=(-1,0)) #d2u,M2E
514 leftmatrix
[:,0,1,:,1,0,:] = leftmatrix
[:,0,0,:,1,1,:] #d2u, E2M
515 leftmatrix
[:,1,0,:,0,1,:] = np
.tensordot(phases_u2d
, b_u2d
,axes
=(-1,0)) #u2d,M2E
516 leftmatrix
[:,1,1,:,0,0,:] = leftmatrix
[:,1,0,:,0,1,:] #u2d, E2M
517 #leftmatrix is now the translation matrix T
519 leftmatrix
[:,j
] = np
.rollaxis(-np
.tensordot(TMatrices_om
[j
], leftmatrix
[:,j
], axes
=([-2,-1],[1,2])),2)
520 # at this point, jth row of leftmatrix is that of -MT
521 leftmatrix
[:,j
,:,:,j
,:,:] += n2id
522 #now we are done, 1-MT
524 leftmatrixlist
[nnlist
] = leftmatrix
527 # sem nějaká rozumná smyčka
528 for ki in range(klist.shape[0]):
530 if (k_0*k_0 - k[0]*k[0] - k[1]*k[1] < 0):
534 phases_self = np.exp(1j*np.tensordot(k,unitcell_translations,axes=(0,-1)))
535 phases_u2d = np.exp(1j*np.tensordot(k,u2d_translations,axes=(0,-1)))
536 phases_d2u = np.exp(1j*np.tensordot(k,d2u_translations,axes=(0,-1)))
538 phases_self *= unitcell_envelope
539 phases_u2d *= u2d_envelope
540 phases_d2u *= d2u_envelope
541 leftmatrix = np.zeros((2,2,nelem, 2,2,nelem), dtype=complex)
544 leftmatrix[0,0,:,0,0,:] = np.tensordot(a_self,phases_self, axes=(0,-1)) # u2u, E2E
545 leftmatrix[1,0,:,1,0,:] = leftmatrix[0,0,:,0,0,:] # d2d, E2E
546 leftmatrix[0,1,:,0,1,:] = leftmatrix[0,0,:,0,0,:] # u2u, M2M
547 leftmatrix[1,1,:,1,1,:] = leftmatrix[0,0,:,0,0,:] # d2d, M2M
548 leftmatrix[0,0,:,0,1,:] = np.tensordot(b_self,phases_self, axes=(0,-1)) # u2u, M2E
549 leftmatrix[0,1,:,0,0,:] = leftmatrix[0,0,:,0,1,:] # u2u, E2M
550 leftmatrix[1,1,:,1,0,:] = leftmatrix[0,0,:,0,1,:] # d2d, E2M
551 leftmatrix[1,0,:,1,1,:] = leftmatrix[0,0,:,0,1,:] # d2d, M2E
552 leftmatrix[0,0,:,1,0,:] = np.tensordot(a_d2u, phases_d2u,axes=(0,-1)) #d2u,E2E
553 leftmatrix[0,1,:,1,1,:] = leftmatrix[0,0,:,1,0,:] #d2u, M2M
554 leftmatrix[1,0,:,0,0,:] = np.tensordot(a_u2d, phases_u2d,axes=(0,-1)) #u2d,E2E
555 leftmatrix[1,1,:,0,1,:] = leftmatrix[1,0,:,0,0,:] #u2d, M2M
556 leftmatrix[0,0,:,1,1,:] = np.tensordot(b_d2u, phases_d2u,axes=(0,-1)) #d2u,M2E
557 leftmatrix[0,1,:,1,0,:] = leftmatrix[0,0,:,1,1,:] #d2u, E2M
558 leftmatrix[1,0,:,0,1,:] = np.tensordot(b_u2d, phases_u2d,axes=(0,-1)) #u2d,M2E
559 leftmatrix[1,1,:,0,0,:] = leftmatrix[1,0,:,0,1,:] #u2d, E2M
560 #leftmatrix is now the translation matrix T
562 leftmatrix[j] = -np.tensordot(TMatrices_om[j], leftmatrix[j], axes=([-2,-1],[0,1]))
563 # at this point, jth row of leftmatrix is that of -MT
564 leftmatrix[j,:,:,j,:,:] += n2id
565 #now we are done, 1-MT
567 leftmatrixlist[ki] = leftmatrix
570 leftmatrixlist_s
= np
.reshape(leftmatrixlist
,(klist
.shape
[0], 2*2*nelem
,2*2*nelem
))[nnlist
]
571 TEč
, TMč
= symz_indexarrays(lMax
, 2)
572 leftmatrixlist_TE
= leftmatrixlist_s
[np
.ix_(np
.arange(leftmatrixlist_s
.shape
[0]),TEč
,TEč
)]
573 leftmatrixlist_TM
= leftmatrixlist_s
[np
.ix_(np
.arange(leftmatrixlist_s
.shape
[0]),TMč
,TMč
)]
574 _time_e(sbtime
, verbose
, step
='Initializing matrices for SVD for a given list of k\'s')
576 sbtime
= _time_b(verbose
, step
='Calculating SVDs for a given list of k\'s.')
578 svUfullTElist
[nnlist
], svSfullTElist
[nnlist
], svVfullTElist
[nnlist
] = np
.linalg
.svd(leftmatrixlist_TE
, compute_uv
=True)
579 svUfullTMlist
[nnlist
], svSfullTMlist
[nnlist
], svVfullTMlist
[nnlist
] = np
.linalg
.svd(leftmatrixlist_TM
, compute_uv
=True)
580 _time_e(sbtime
, verbose
, step
='Calculating SVDs for a given list of k\'s.')
581 _time_e(btime
, verbose
)
582 return ((svUfullTElist
, svSfullTElist
, svVfullTElist
), (svUfullTMlist
, svSfullTMlist
, svVfullTMlist
))
584 minsvTElist
[nnlist
] = np
.linalg
.svd(leftmatrixlist_TE
, compute_uv
=False)[...,-onlyNmin
:]
585 minsvTMlist
[nnlist
] = np
.linalg
.svd(leftmatrixlist_TM
, compute_uv
=False)[...,-onlyNmin
:]
586 _time_e(sbtime
, verbose
, step
='Calculating SVDs for a given list of k\'s.')
587 _time_e(btime
, verbose
)
588 return (minsvTElist
, minsvTMlist
)