ElectroMagneticPython 2.1.5__py3-none-any.whl → 2.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- EMpy/RCWA.py +268 -268
- EMpy/devices.py +6 -6
- EMpy/transfer_matrix.py +82 -82
- EMpy/version.py +1 -1
- {ElectroMagneticPython-2.1.5.dist-info → ElectroMagneticPython-2.2.1.dist-info}/METADATA +24 -10
- {ElectroMagneticPython-2.1.5.dist-info → ElectroMagneticPython-2.2.1.dist-info}/RECORD +9 -9
- {ElectroMagneticPython-2.1.5.dist-info → ElectroMagneticPython-2.2.1.dist-info}/WHEEL +1 -1
- {ElectroMagneticPython-2.1.5.dist-info → ElectroMagneticPython-2.2.1.dist-info}/LICENSE +0 -0
- {ElectroMagneticPython-2.1.5.dist-info → ElectroMagneticPython-2.2.1.dist-info}/top_level.txt +0 -0
EMpy/RCWA.py
CHANGED
|
@@ -14,7 +14,7 @@ one, only stable for low diffraction orders and thin layers.
|
|
|
14
14
|
"""
|
|
15
15
|
__author__ = "Lorenzo Bolla"
|
|
16
16
|
|
|
17
|
-
import
|
|
17
|
+
import numpy as np
|
|
18
18
|
from scipy.linalg import toeplitz, inv, eig, solve as linsolve
|
|
19
19
|
from numpy import pi
|
|
20
20
|
|
|
@@ -41,7 +41,7 @@ def dispersion_relation_ordinary(kx, ky, k, nO):
|
|
|
41
41
|
raise ValueError("kx and ky must have the same length")
|
|
42
42
|
|
|
43
43
|
delta = (k * nO) ** 2 - (kx**2 + ky**2)
|
|
44
|
-
kz =
|
|
44
|
+
kz = np.sqrt(delta)
|
|
45
45
|
|
|
46
46
|
# Adjust sign of real/imag part
|
|
47
47
|
kz.real = abs(kz.real)
|
|
@@ -65,14 +65,14 @@ def dispersion_relation_extraordinary(kx, ky, k, nO, nE, c):
|
|
|
65
65
|
"kx and ky must have the same length and c must have 3 components"
|
|
66
66
|
)
|
|
67
67
|
|
|
68
|
-
kz =
|
|
68
|
+
kz = np.empty_like(kx)
|
|
69
69
|
|
|
70
70
|
for ii in range(0, kx.size):
|
|
71
71
|
alpha = nE**2 - nO**2
|
|
72
72
|
beta = kx[ii] / k * c[0] + ky[ii] / k * c[1]
|
|
73
73
|
|
|
74
74
|
# coeffs
|
|
75
|
-
C =
|
|
75
|
+
C = np.array(
|
|
76
76
|
[
|
|
77
77
|
nO**2 + c[2] ** 2 * alpha,
|
|
78
78
|
2.0 * c[2] * beta * alpha,
|
|
@@ -83,13 +83,13 @@ def dispersion_relation_extraordinary(kx, ky, k, nO, nE, c):
|
|
|
83
83
|
)
|
|
84
84
|
|
|
85
85
|
# two solutions of type +x or -x, purely real or purely imag
|
|
86
|
-
tmp_kz = k *
|
|
86
|
+
tmp_kz = k * np.roots(C)
|
|
87
87
|
|
|
88
88
|
# get the negative imaginary part or the positive real one
|
|
89
|
-
if
|
|
90
|
-
kz[ii] =
|
|
89
|
+
if np.any(np.isreal(tmp_kz)):
|
|
90
|
+
kz[ii] = np.absolute(tmp_kz[0])
|
|
91
91
|
else:
|
|
92
|
-
kz[ii] = -1j *
|
|
92
|
+
kz[ii] = -1j * np.absolute(tmp_kz[0])
|
|
93
93
|
|
|
94
94
|
return kz
|
|
95
95
|
|
|
@@ -145,7 +145,7 @@ class RCWA:
|
|
|
145
145
|
def get_pitch(self):
|
|
146
146
|
"""Inspect the multilayer to check that all the binary
|
|
147
147
|
gratings present have the same pitch, and return it."""
|
|
148
|
-
idx =
|
|
148
|
+
idx = np.where(
|
|
149
149
|
[
|
|
150
150
|
(
|
|
151
151
|
isinstance(m, BinaryGrating)
|
|
@@ -160,8 +160,8 @@ class RCWA:
|
|
|
160
160
|
return 1.0 # return LAMBDA: any value will do
|
|
161
161
|
else:
|
|
162
162
|
# check that all the pitches are the same!
|
|
163
|
-
l =
|
|
164
|
-
if not
|
|
163
|
+
l = np.asarray([self.multilayer[i].pitch for i in idx])
|
|
164
|
+
if not np.all(l == l[0]):
|
|
165
165
|
raise ValueError("All the BinaryGratings must have the same pitch.")
|
|
166
166
|
else:
|
|
167
167
|
return l[0]
|
|
@@ -192,7 +192,7 @@ class IsotropicRCWA(RCWA):
|
|
|
192
192
|
matrix approach", JOSA A, 12(5), 1995
|
|
193
193
|
"""
|
|
194
194
|
|
|
195
|
-
self.wls =
|
|
195
|
+
self.wls = np.atleast_1d(wls)
|
|
196
196
|
|
|
197
197
|
LAMBDA = self.LAMBDA
|
|
198
198
|
n = self.n
|
|
@@ -203,32 +203,32 @@ class IsotropicRCWA(RCWA):
|
|
|
203
203
|
phi = self.phi
|
|
204
204
|
|
|
205
205
|
nlayers = len(multilayer)
|
|
206
|
-
i =
|
|
206
|
+
i = np.arange(-n, n + 1)
|
|
207
207
|
nood = 2 * n + 1
|
|
208
208
|
hmax = nood - 1
|
|
209
209
|
|
|
210
210
|
# grating vector (on the xz plane)
|
|
211
211
|
# grating on the xy plane
|
|
212
|
-
K = 2 * pi / LAMBDA *
|
|
212
|
+
K = 2 * pi / LAMBDA * np.array([np.sin(phi), 0.0, np.cos(phi)], dtype=complex)
|
|
213
213
|
|
|
214
|
-
DE1 =
|
|
215
|
-
DE3 =
|
|
214
|
+
DE1 = np.zeros((nood, self.wls.size))
|
|
215
|
+
DE3 = np.zeros_like(DE1)
|
|
216
216
|
|
|
217
|
-
dirk1 =
|
|
218
|
-
[
|
|
217
|
+
dirk1 = np.array(
|
|
218
|
+
[np.sin(alpha) * np.cos(delta), np.sin(alpha) * np.sin(delta), np.cos(alpha)]
|
|
219
219
|
)
|
|
220
220
|
|
|
221
221
|
# usefull matrices
|
|
222
|
-
I =
|
|
223
|
-
I2 =
|
|
224
|
-
ZERO =
|
|
222
|
+
I = np.eye(i.size)
|
|
223
|
+
I2 = np.eye(i.size * 2)
|
|
224
|
+
ZERO = np.zeros_like(I)
|
|
225
225
|
|
|
226
|
-
X =
|
|
227
|
-
MTp1 =
|
|
228
|
-
MTp2 =
|
|
226
|
+
X = np.zeros((2 * nood, 2 * nood, nlayers), dtype=complex)
|
|
227
|
+
MTp1 = np.zeros((2 * nood, 2 * nood, nlayers), dtype=complex)
|
|
228
|
+
MTp2 = np.zeros_like(MTp1)
|
|
229
229
|
|
|
230
|
-
EPS2 =
|
|
231
|
-
EPS21 =
|
|
230
|
+
EPS2 = np.zeros(2 * hmax + 1, dtype=complex)
|
|
231
|
+
EPS21 = np.zeros_like(EPS2)
|
|
232
232
|
|
|
233
233
|
dlt = (i == 0).astype(int)
|
|
234
234
|
|
|
@@ -244,40 +244,40 @@ class IsotropicRCWA(RCWA):
|
|
|
244
244
|
|
|
245
245
|
# all the other wavevectors
|
|
246
246
|
tmp_x = k1[0] - i * K[0]
|
|
247
|
-
tmp_y = k1[1] *
|
|
247
|
+
tmp_y = k1[1] * np.ones_like(i)
|
|
248
248
|
tmp_z = dispersion_relation_ordinary(tmp_x, tmp_y, k, n1)
|
|
249
|
-
k1i =
|
|
249
|
+
k1i = np.r_[[tmp_x], [tmp_y], [tmp_z]]
|
|
250
250
|
|
|
251
|
-
# k2i =
|
|
251
|
+
# k2i = np.r_[[k1[0] - i*K[0]], [k1[1] - i * K[1]], [-i * K[2]]]
|
|
252
252
|
|
|
253
253
|
tmp_z = dispersion_relation_ordinary(tmp_x, tmp_y, k, n3)
|
|
254
|
-
k3i =
|
|
254
|
+
k3i = np.r_[[k1i[0, :]], [k1i[1, :]], [tmp_z]]
|
|
255
255
|
|
|
256
256
|
# aliases for constant wavevectors
|
|
257
257
|
kx = k1i[0, :]
|
|
258
258
|
ky = k1[1]
|
|
259
259
|
|
|
260
260
|
# angles of reflection
|
|
261
|
-
# phi_i =
|
|
262
|
-
phi_i =
|
|
261
|
+
# phi_i = np.arctan2(ky,kx)
|
|
262
|
+
phi_i = np.arctan2(ky, kx.real) # OKKIO
|
|
263
263
|
|
|
264
|
-
Kx =
|
|
264
|
+
Kx = np.diag(kx / k)
|
|
265
265
|
Ky = ky / k * I
|
|
266
|
-
Z1 =
|
|
267
|
-
Y1 =
|
|
268
|
-
Z3 =
|
|
269
|
-
Y3 =
|
|
270
|
-
# Fc =
|
|
271
|
-
fc =
|
|
272
|
-
# Fs =
|
|
273
|
-
fs =
|
|
274
|
-
|
|
275
|
-
MR =
|
|
276
|
-
|
|
266
|
+
Z1 = np.diag(k1i[2, :] / (k * n1**2))
|
|
267
|
+
Y1 = np.diag(k1i[2, :] / k)
|
|
268
|
+
Z3 = np.diag(k3i[2, :] / (k * n3**2))
|
|
269
|
+
Y3 = np.diag(k3i[2, :] / k)
|
|
270
|
+
# Fc = np.diag(np.cos(phi_i))
|
|
271
|
+
fc = np.cos(phi_i)
|
|
272
|
+
# Fs = np.diag(np.sin(phi_i))
|
|
273
|
+
fs = np.sin(phi_i)
|
|
274
|
+
|
|
275
|
+
MR = np.asarray(
|
|
276
|
+
np.bmat([[I, ZERO], [-1j * Y1, ZERO], [ZERO, I], [ZERO, -1j * Z1]])
|
|
277
277
|
)
|
|
278
278
|
|
|
279
|
-
MT =
|
|
280
|
-
|
|
279
|
+
MT = np.asarray(
|
|
280
|
+
np.bmat([[I, ZERO], [1j * Y3, ZERO], [ZERO, I], [ZERO, 1j * Z3]])
|
|
281
281
|
)
|
|
282
282
|
|
|
283
283
|
# internal layers (grating or layer)
|
|
@@ -293,10 +293,10 @@ class IsotropicRCWA(RCWA):
|
|
|
293
293
|
E = toeplitz(EPS2[hmax::-1], EPS2[hmax:])
|
|
294
294
|
E1 = toeplitz(EPS21[hmax::-1], EPS21[hmax:])
|
|
295
295
|
E11 = inv(E1)
|
|
296
|
-
# B =
|
|
297
|
-
B = kx[:,
|
|
298
|
-
# A =
|
|
299
|
-
A =
|
|
296
|
+
# B = np.dot(Kx, linsolve(E,Kx)) - I
|
|
297
|
+
B = kx[:, np.newaxis] / k * linsolve(E, Kx) - I
|
|
298
|
+
# A = np.dot(Kx, Kx) - E
|
|
299
|
+
A = np.diag((kx / k) ** 2) - E
|
|
300
300
|
|
|
301
301
|
# Note: solution bug alfredo
|
|
302
302
|
# randomizzo Kx un po' a caso finche' cond(A) e' piccolo (<1e10)
|
|
@@ -307,59 +307,59 @@ class IsotropicRCWA(RCWA):
|
|
|
307
307
|
if cond(A) > 1e10:
|
|
308
308
|
warning("BAD CONDITIONING: randomization of kx")
|
|
309
309
|
while cond(A) > 1e10:
|
|
310
|
-
Kx = Kx * (1 + 1e-9 *
|
|
311
|
-
B = kx[:,
|
|
312
|
-
A =
|
|
310
|
+
Kx = Kx * (1 + 1e-9 * np.rand())
|
|
311
|
+
B = kx[:, np.newaxis] / k * linsolve(E, Kx) - I
|
|
312
|
+
A = np.diag((kx / k) ** 2) - E
|
|
313
313
|
|
|
314
|
-
if
|
|
314
|
+
if np.absolute(K[2] / k) > 1e-10:
|
|
315
315
|
raise ValueError(
|
|
316
316
|
"First Order Helmholtz Operator not implemented, yet!"
|
|
317
317
|
)
|
|
318
318
|
|
|
319
|
-
elif ky == 0 or
|
|
319
|
+
elif ky == 0 or np.allclose(np.diag(Ky / ky * k), 1):
|
|
320
320
|
# lalanne
|
|
321
|
-
# H_U_reduced =
|
|
321
|
+
# H_U_reduced = np.dot(Ky, Ky) + A
|
|
322
322
|
H_U_reduced = (ky / k) ** 2 * I + A
|
|
323
|
-
# H_S_reduced =
|
|
323
|
+
# H_S_reduced = np.dot(Ky, Ky) + np.dot(Kx, linsolve(E, np.dot(Kx, E11))) - E11
|
|
324
324
|
H_S_reduced = (
|
|
325
325
|
(ky / k) ** 2 * I
|
|
326
|
-
+ kx[:,
|
|
326
|
+
+ kx[:, np.newaxis] / k * linsolve(E, kx[:, np.newaxis] / k * E11)
|
|
327
327
|
- E11
|
|
328
328
|
)
|
|
329
329
|
|
|
330
330
|
q1, W1 = eig(H_U_reduced)
|
|
331
|
-
q1 =
|
|
331
|
+
q1 = np.sqrt(q1)
|
|
332
332
|
q2, W2 = eig(H_S_reduced)
|
|
333
|
-
q2 =
|
|
333
|
+
q2 = np.sqrt(q2)
|
|
334
334
|
|
|
335
335
|
# boundary conditions
|
|
336
336
|
|
|
337
|
-
# V11 =
|
|
338
|
-
V11 = linsolve(A, W1) * q1[
|
|
339
|
-
V12 = (ky / k) *
|
|
340
|
-
V21 = (ky / k) *
|
|
341
|
-
# V22 =
|
|
342
|
-
V22 = linsolve(B, W2) * q2[
|
|
343
|
-
|
|
344
|
-
# Vss =
|
|
345
|
-
Vss = fc[:,
|
|
346
|
-
# Wss =
|
|
347
|
-
Wss = fc[:,
|
|
348
|
-
# Vsp =
|
|
349
|
-
Vsp = fc[:,
|
|
350
|
-
# Wsp =
|
|
351
|
-
Wsp = fs[:,
|
|
352
|
-
# Wpp =
|
|
353
|
-
Wpp = fc[:,
|
|
354
|
-
# Vpp =
|
|
355
|
-
Vpp = fc[:,
|
|
356
|
-
# Wps =
|
|
357
|
-
Wps = fc[:,
|
|
358
|
-
# Vps =
|
|
359
|
-
Vps = fs[:,
|
|
360
|
-
|
|
361
|
-
Mc2bar =
|
|
362
|
-
|
|
337
|
+
# V11 = np.dot(linsolve(A, W1), np.diag(q1))
|
|
338
|
+
V11 = linsolve(A, W1) * q1[np.newaxis, :]
|
|
339
|
+
V12 = (ky / k) * np.dot(linsolve(A, Kx), W2)
|
|
340
|
+
V21 = (ky / k) * np.dot(linsolve(B, Kx), linsolve(E, W1))
|
|
341
|
+
# V22 = np.dot(linsolve(B, W2), np.diag(q2))
|
|
342
|
+
V22 = linsolve(B, W2) * q2[np.newaxis, :]
|
|
343
|
+
|
|
344
|
+
# Vss = np.dot(Fc, V11)
|
|
345
|
+
Vss = fc[:, np.newaxis] * V11
|
|
346
|
+
# Wss = np.dot(Fc, W1) + np.dot(Fs, V21)
|
|
347
|
+
Wss = fc[:, np.newaxis] * W1 + fs[:, np.newaxis] * V21
|
|
348
|
+
# Vsp = np.dot(Fc, V12) - np.dot(Fs, W2)
|
|
349
|
+
Vsp = fc[:, np.newaxis] * V12 - fs[:, np.newaxis] * W2
|
|
350
|
+
# Wsp = np.dot(Fs, V22)
|
|
351
|
+
Wsp = fs[:, np.newaxis] * V22
|
|
352
|
+
# Wpp = np.dot(Fc, V22)
|
|
353
|
+
Wpp = fc[:, np.newaxis] * V22
|
|
354
|
+
# Vpp = np.dot(Fc, W2) + np.dot(Fs, V12)
|
|
355
|
+
Vpp = fc[:, np.newaxis] * W2 + fs[:, np.newaxis] * V12
|
|
356
|
+
# Wps = np.dot(Fc, V21) - np.dot(Fs, W1)
|
|
357
|
+
Wps = fc[:, np.newaxis] * V21 - fs[:, np.newaxis] * W1
|
|
358
|
+
# Vps = np.dot(Fs, V11)
|
|
359
|
+
Vps = fs[:, np.newaxis] * V11
|
|
360
|
+
|
|
361
|
+
Mc2bar = np.asarray(
|
|
362
|
+
np.bmat(
|
|
363
363
|
[
|
|
364
364
|
[Vss, Vsp, Vss, Vsp],
|
|
365
365
|
[Wss, Wsp, -Wss, -Wsp],
|
|
@@ -369,51 +369,51 @@ class IsotropicRCWA(RCWA):
|
|
|
369
369
|
)
|
|
370
370
|
)
|
|
371
371
|
|
|
372
|
-
x =
|
|
372
|
+
x = np.r_[np.exp(-k * q1 * d), np.exp(-k * q2 * d)]
|
|
373
373
|
|
|
374
|
-
# Mc1 =
|
|
375
|
-
xx =
|
|
376
|
-
Mc1 = Mc2bar * xx[
|
|
374
|
+
# Mc1 = np.dot(Mc2bar, np.diag(np.r_[np.ones_like(x), x]))
|
|
375
|
+
xx = np.r_[np.ones_like(x), x]
|
|
376
|
+
Mc1 = Mc2bar * xx[np.newaxis, :]
|
|
377
377
|
|
|
378
|
-
X[:, :, nlayer] =
|
|
378
|
+
X[:, :, nlayer] = np.diag(x)
|
|
379
379
|
|
|
380
380
|
MTp = linsolve(Mc2bar, MT)
|
|
381
381
|
MTp1[:, :, nlayer] = MTp[0 : 2 * nood, :]
|
|
382
382
|
MTp2 = MTp[2 * nood :, :]
|
|
383
383
|
|
|
384
|
-
MT =
|
|
384
|
+
MT = np.dot(
|
|
385
385
|
Mc1,
|
|
386
|
-
|
|
386
|
+
np.r_[
|
|
387
387
|
I2,
|
|
388
|
-
|
|
388
|
+
np.dot(MTp2, linsolve(MTp1[:, :, nlayer], X[:, :, nlayer])),
|
|
389
389
|
],
|
|
390
390
|
)
|
|
391
391
|
|
|
392
392
|
else:
|
|
393
393
|
ValueError("Second Order Helmholtz Operator not implemented, yet!")
|
|
394
394
|
|
|
395
|
-
# M =
|
|
396
|
-
M =
|
|
397
|
-
b =
|
|
398
|
-
|
|
399
|
-
1j *
|
|
400
|
-
-1j *
|
|
401
|
-
|
|
395
|
+
# M = np.asarray(np.bmat([-MR, MT]))
|
|
396
|
+
M = np.c_[-MR, MT]
|
|
397
|
+
b = np.r_[
|
|
398
|
+
np.sin(psi) * dlt,
|
|
399
|
+
1j * np.sin(psi) * n1 * np.cos(alpha) * dlt,
|
|
400
|
+
-1j * np.cos(psi) * n1 * dlt,
|
|
401
|
+
np.cos(psi) * np.cos(alpha) * dlt,
|
|
402
402
|
]
|
|
403
403
|
|
|
404
404
|
x = linsolve(M, b)
|
|
405
|
-
R, T =
|
|
406
|
-
Rs, Rp =
|
|
405
|
+
R, T = np.split(x, 2)
|
|
406
|
+
Rs, Rp = np.split(R, 2)
|
|
407
407
|
for ii in range(1, nlayers - 1):
|
|
408
|
-
T =
|
|
409
|
-
Ts, Tp =
|
|
408
|
+
T = np.dot(linsolve(MTp1[:, :, ii], X[:, :, ii]), T)
|
|
409
|
+
Ts, Tp = np.split(T, 2)
|
|
410
410
|
|
|
411
|
-
DE1[:, iwl] = (k1i[2, :] / (k1[2])).real *
|
|
411
|
+
DE1[:, iwl] = (k1i[2, :] / (k1[2])).real * np.absolute(Rs) ** 2 + (
|
|
412
412
|
k1i[2, :] / (k1[2] * n1**2)
|
|
413
|
-
).real *
|
|
414
|
-
DE3[:, iwl] = (k3i[2, :] / (k1[2])).real *
|
|
413
|
+
).real * np.absolute(Rp) ** 2
|
|
414
|
+
DE3[:, iwl] = (k3i[2, :] / (k1[2])).real * np.absolute(Ts) ** 2 + (
|
|
415
415
|
k3i[2, :] / (k1[2] * n3**2)
|
|
416
|
-
).real *
|
|
416
|
+
).real * np.absolute(Tp) ** 2
|
|
417
417
|
|
|
418
418
|
# save the results
|
|
419
419
|
self.DE1 = DE1
|
|
@@ -462,7 +462,7 @@ class AnisotropicRCWA(RCWA):
|
|
|
462
462
|
and transmitted.
|
|
463
463
|
"""
|
|
464
464
|
|
|
465
|
-
self.wls =
|
|
465
|
+
self.wls = np.atleast_1d(wls)
|
|
466
466
|
|
|
467
467
|
LAMBDA = self.LAMBDA
|
|
468
468
|
n = self.n
|
|
@@ -473,39 +473,39 @@ class AnisotropicRCWA(RCWA):
|
|
|
473
473
|
phi = self.phi
|
|
474
474
|
|
|
475
475
|
nlayers = len(multilayer)
|
|
476
|
-
i =
|
|
476
|
+
i = np.arange(-n, n + 1)
|
|
477
477
|
nood = 2 * n + 1
|
|
478
478
|
hmax = nood - 1
|
|
479
479
|
|
|
480
|
-
DEO1 =
|
|
481
|
-
DEO3 =
|
|
482
|
-
DEE1 =
|
|
483
|
-
DEE3 =
|
|
480
|
+
DEO1 = np.zeros((nood, self.wls.size))
|
|
481
|
+
DEO3 = np.zeros_like(DEO1)
|
|
482
|
+
DEE1 = np.zeros_like(DEO1)
|
|
483
|
+
DEE3 = np.zeros_like(DEO1)
|
|
484
484
|
|
|
485
|
-
c1 =
|
|
486
|
-
c3 =
|
|
485
|
+
c1 = np.array([1.0, 0.0, 0.0])
|
|
486
|
+
c3 = np.array([1.0, 0.0, 0.0])
|
|
487
487
|
# grating on the xy plane
|
|
488
|
-
K = 2 * pi / LAMBDA *
|
|
489
|
-
dirk1 =
|
|
490
|
-
[
|
|
488
|
+
K = 2 * pi / LAMBDA * np.array([np.sin(phi), 0.0, np.cos(phi)], dtype=complex)
|
|
489
|
+
dirk1 = np.array(
|
|
490
|
+
[np.sin(alpha) * np.cos(delta), np.sin(alpha) * np.sin(delta), np.cos(alpha)]
|
|
491
491
|
)
|
|
492
492
|
|
|
493
493
|
# D polarization vector
|
|
494
|
-
u =
|
|
494
|
+
u = np.array(
|
|
495
495
|
[
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
-
|
|
496
|
+
np.cos(psi) * np.cos(alpha) * np.cos(delta) - np.sin(psi) * np.sin(delta),
|
|
497
|
+
np.cos(psi) * np.cos(alpha) * np.sin(delta) + np.sin(psi) * np.cos(delta),
|
|
498
|
+
-np.cos(psi) * np.sin(alpha),
|
|
499
499
|
]
|
|
500
500
|
)
|
|
501
501
|
|
|
502
|
-
kO1i =
|
|
503
|
-
kE1i =
|
|
504
|
-
kO3i =
|
|
505
|
-
kE3i =
|
|
502
|
+
kO1i = np.zeros((3, i.size), dtype=complex)
|
|
503
|
+
kE1i = np.zeros_like(kO1i)
|
|
504
|
+
kO3i = np.zeros_like(kO1i)
|
|
505
|
+
kE3i = np.zeros_like(kO1i)
|
|
506
506
|
|
|
507
|
-
Mp =
|
|
508
|
-
M =
|
|
507
|
+
Mp = np.zeros((4 * nood, 4 * nood, nlayers), dtype=complex)
|
|
508
|
+
M = np.zeros((4 * nood, 4 * nood, nlayers), dtype=complex)
|
|
509
509
|
|
|
510
510
|
dlt = (i == 0).astype(int)
|
|
511
511
|
|
|
@@ -516,20 +516,20 @@ class AnisotropicRCWA(RCWA):
|
|
|
516
516
|
# wavevectors
|
|
517
517
|
k = 2 * pi / wl
|
|
518
518
|
|
|
519
|
-
eps1 =
|
|
520
|
-
eps3 =
|
|
519
|
+
eps1 = np.diag(np.asarray([nE1, nO1, nO1]) ** 2)
|
|
520
|
+
eps3 = np.diag(np.asarray([nE3, nO3, nO3]) ** 2)
|
|
521
521
|
|
|
522
522
|
# ordinary wave
|
|
523
523
|
abskO1 = k * nO1
|
|
524
524
|
# abskO3 = k * nO3
|
|
525
525
|
# extraordinary wave
|
|
526
|
-
# abskE1 = k * nO1 *nE1 /
|
|
527
|
-
# abskE3 = k * nO3 *nE3 /
|
|
526
|
+
# abskE1 = k * nO1 *nE1 / np.sqrt(nO1**2 + (nE1**2 - nO1**2) * np.dot(-c1, dirk1)**2)
|
|
527
|
+
# abskE3 = k * nO3 *nE3 / np.sqrt(nO3**2 + (nE3**2 - nO3**2) * np.dot(-c3, dirk1)**2)
|
|
528
528
|
|
|
529
529
|
k1 = abskO1 * dirk1
|
|
530
530
|
|
|
531
531
|
kO1i[0, :] = k1[0] - i * K[0]
|
|
532
|
-
kO1i[1, :] = k1[1] *
|
|
532
|
+
kO1i[1, :] = k1[1] * np.ones_like(i)
|
|
533
533
|
kO1i[2, :] = -dispersion_relation_ordinary(kO1i[0, :], kO1i[1, :], k, nO1)
|
|
534
534
|
|
|
535
535
|
kE1i[0, :] = kO1i[0, :]
|
|
@@ -548,23 +548,23 @@ class AnisotropicRCWA(RCWA):
|
|
|
548
548
|
kE3i[0, :], kE3i[1, :], k, nO3, nE3, c3
|
|
549
549
|
)
|
|
550
550
|
|
|
551
|
-
# k2i =
|
|
552
|
-
k2i =
|
|
551
|
+
# k2i = np.r_[[k1[0] - i * K[0]], [k1[1] - i * K[1]], [k1[2] - i * K[2]]]
|
|
552
|
+
k2i = np.r_[[k1[0] - i * K[0]], [k1[1] - i * K[1]], [-i * K[2]]]
|
|
553
553
|
|
|
554
554
|
# aliases for constant wavevectors
|
|
555
555
|
kx = kO1i[0, :] # o kE1i(1,;), tanto e' lo stesso
|
|
556
556
|
ky = k1[1]
|
|
557
557
|
|
|
558
558
|
# matrices
|
|
559
|
-
I =
|
|
560
|
-
ZERO =
|
|
561
|
-
Kx =
|
|
559
|
+
I = np.eye(nood, dtype=complex)
|
|
560
|
+
ZERO = np.zeros((nood, nood), dtype=complex)
|
|
561
|
+
Kx = np.diag(kx / k)
|
|
562
562
|
Ky = ky / k * I
|
|
563
|
-
Kz =
|
|
564
|
-
KO1z =
|
|
565
|
-
KE1z =
|
|
566
|
-
KO3z =
|
|
567
|
-
KE3z =
|
|
563
|
+
Kz = np.diag(k2i[2, :] / k)
|
|
564
|
+
KO1z = np.diag(kO1i[2, :] / k)
|
|
565
|
+
KE1z = np.diag(kE1i[2, :] / k)
|
|
566
|
+
KO3z = np.diag(kO3i[2, :] / k)
|
|
567
|
+
KE3z = np.diag(kE3i[2, :] / k)
|
|
568
568
|
|
|
569
569
|
ARO = Kx * eps1[0, 0] + Ky * eps1[1, 0] + KO1z * eps1[2, 0]
|
|
570
570
|
BRO = Kx * eps1[0, 1] + Ky * eps1[1, 1] + KO1z * eps1[2, 1]
|
|
@@ -590,7 +590,7 @@ class AnisotropicRCWA(RCWA):
|
|
|
590
590
|
ETE = c3[2] * Kx - c3[0] * KE3z
|
|
591
591
|
FTE = c3[0] * Ky - c3[1] * Kx
|
|
592
592
|
|
|
593
|
-
b =
|
|
593
|
+
b = np.r_[
|
|
594
594
|
u[0] * dlt,
|
|
595
595
|
u[1] * dlt,
|
|
596
596
|
(k1[1] / k * u[2] - k1[2] / k * u[1]) * dlt,
|
|
@@ -598,18 +598,18 @@ class AnisotropicRCWA(RCWA):
|
|
|
598
598
|
]
|
|
599
599
|
Ky_CRO_1 = ky / k * CRO_1
|
|
600
600
|
Ky_CRE_1 = ky / k * CRE_1
|
|
601
|
-
Kx_CRO_1 = kx[:,
|
|
602
|
-
Kx_CRE_1 = kx[:,
|
|
603
|
-
MR31 = -
|
|
604
|
-
MR32 = -
|
|
605
|
-
MR33 = -
|
|
606
|
-
MR34 = -
|
|
607
|
-
MR41 =
|
|
608
|
-
MR42 =
|
|
609
|
-
MR43 =
|
|
610
|
-
MR44 =
|
|
611
|
-
MR =
|
|
612
|
-
|
|
601
|
+
Kx_CRO_1 = kx[:, np.newaxis] / k * CRO_1
|
|
602
|
+
Kx_CRE_1 = kx[:, np.newaxis] / k * CRE_1
|
|
603
|
+
MR31 = -np.dot(Ky_CRO_1, ARO)
|
|
604
|
+
MR32 = -np.dot(Ky_CRO_1, BRO) - KO1z
|
|
605
|
+
MR33 = -np.dot(Ky_CRE_1, ARE)
|
|
606
|
+
MR34 = -np.dot(Ky_CRE_1, BRE) - KE1z
|
|
607
|
+
MR41 = np.dot(Kx_CRO_1, ARO) + KO1z
|
|
608
|
+
MR42 = np.dot(Kx_CRO_1, BRO)
|
|
609
|
+
MR43 = np.dot(Kx_CRE_1, ARE) + KE1z
|
|
610
|
+
MR44 = np.dot(Kx_CRE_1, BRE)
|
|
611
|
+
MR = np.asarray(
|
|
612
|
+
np.bmat(
|
|
613
613
|
[
|
|
614
614
|
[I, ZERO, I, ZERO],
|
|
615
615
|
[ZERO, I, ZERO, I],
|
|
@@ -621,18 +621,18 @@ class AnisotropicRCWA(RCWA):
|
|
|
621
621
|
|
|
622
622
|
Ky_CTO_1 = ky / k * CTO_1
|
|
623
623
|
Ky_CTE_1 = ky / k * CTE_1
|
|
624
|
-
Kx_CTO_1 = kx[:,
|
|
625
|
-
Kx_CTE_1 = kx[:,
|
|
626
|
-
MT31 = -
|
|
627
|
-
MT32 = -
|
|
628
|
-
MT33 = -
|
|
629
|
-
MT34 = -
|
|
630
|
-
MT41 =
|
|
631
|
-
MT42 =
|
|
632
|
-
MT43 =
|
|
633
|
-
MT44 =
|
|
634
|
-
MT =
|
|
635
|
-
|
|
624
|
+
Kx_CTO_1 = kx[:, np.newaxis] / k * CTO_1
|
|
625
|
+
Kx_CTE_1 = kx[:, np.newaxis] / k * CTE_1
|
|
626
|
+
MT31 = -np.dot(Ky_CTO_1, ATO)
|
|
627
|
+
MT32 = -np.dot(Ky_CTO_1, BTO) - KO3z
|
|
628
|
+
MT33 = -np.dot(Ky_CTE_1, ATE)
|
|
629
|
+
MT34 = -np.dot(Ky_CTE_1, BTE) - KE3z
|
|
630
|
+
MT41 = np.dot(Kx_CTO_1, ATO) + KO3z
|
|
631
|
+
MT42 = np.dot(Kx_CTO_1, BTO)
|
|
632
|
+
MT43 = np.dot(Kx_CTE_1, ATE) + KE3z
|
|
633
|
+
MT44 = np.dot(Kx_CTE_1, BTE)
|
|
634
|
+
MT = np.asarray(
|
|
635
|
+
np.bmat(
|
|
636
636
|
[
|
|
637
637
|
[I, ZERO, I, ZERO],
|
|
638
638
|
[ZERO, I, ZERO, I],
|
|
@@ -651,55 +651,55 @@ class AnisotropicRCWA(RCWA):
|
|
|
651
651
|
|
|
652
652
|
EPS2, EPS21 = layer.getEPSFourierCoeffs(wl, n, anisotropic=True)
|
|
653
653
|
|
|
654
|
-
# Exx =
|
|
655
|
-
# Exx = toeplitz(
|
|
656
|
-
Exy =
|
|
657
|
-
Exy = toeplitz(
|
|
658
|
-
Exz =
|
|
659
|
-
Exz = toeplitz(
|
|
660
|
-
|
|
661
|
-
Eyx =
|
|
662
|
-
Eyx = toeplitz(
|
|
663
|
-
Eyy =
|
|
664
|
-
Eyy = toeplitz(
|
|
665
|
-
Eyz =
|
|
666
|
-
Eyz = toeplitz(
|
|
667
|
-
|
|
668
|
-
Ezx =
|
|
669
|
-
Ezx = toeplitz(
|
|
670
|
-
Ezy =
|
|
671
|
-
Ezy = toeplitz(
|
|
672
|
-
Ezz =
|
|
673
|
-
Ezz = toeplitz(
|
|
674
|
-
|
|
675
|
-
Exx_1 =
|
|
676
|
-
Exx_1 = toeplitz(
|
|
654
|
+
# Exx = np.squeeze(EPS2[0, 0, :])
|
|
655
|
+
# Exx = toeplitz(np.flipud(Exx[0:hmax + 1]), Exx[hmax:])
|
|
656
|
+
Exy = np.squeeze(EPS2[0, 1, :])
|
|
657
|
+
Exy = toeplitz(np.flipud(Exy[0 : hmax + 1]), Exy[hmax:])
|
|
658
|
+
Exz = np.squeeze(EPS2[0, 2, :])
|
|
659
|
+
Exz = toeplitz(np.flipud(Exz[0 : hmax + 1]), Exz[hmax:])
|
|
660
|
+
|
|
661
|
+
Eyx = np.squeeze(EPS2[1, 0, :])
|
|
662
|
+
Eyx = toeplitz(np.flipud(Eyx[0 : hmax + 1]), Eyx[hmax:])
|
|
663
|
+
Eyy = np.squeeze(EPS2[1, 1, :])
|
|
664
|
+
Eyy = toeplitz(np.flipud(Eyy[0 : hmax + 1]), Eyy[hmax:])
|
|
665
|
+
Eyz = np.squeeze(EPS2[1, 2, :])
|
|
666
|
+
Eyz = toeplitz(np.flipud(Eyz[0 : hmax + 1]), Eyz[hmax:])
|
|
667
|
+
|
|
668
|
+
Ezx = np.squeeze(EPS2[2, 0, :])
|
|
669
|
+
Ezx = toeplitz(np.flipud(Ezx[0 : hmax + 1]), Ezx[hmax:])
|
|
670
|
+
Ezy = np.squeeze(EPS2[2, 1, :])
|
|
671
|
+
Ezy = toeplitz(np.flipud(Ezy[0 : hmax + 1]), Ezy[hmax:])
|
|
672
|
+
Ezz = np.squeeze(EPS2[2, 2, :])
|
|
673
|
+
Ezz = toeplitz(np.flipud(Ezz[0 : hmax + 1]), Ezz[hmax:])
|
|
674
|
+
|
|
675
|
+
Exx_1 = np.squeeze(EPS21[0, 0, :])
|
|
676
|
+
Exx_1 = toeplitz(np.flipud(Exx_1[0 : hmax + 1]), Exx_1[hmax:])
|
|
677
677
|
Exx_1_1 = inv(Exx_1)
|
|
678
678
|
|
|
679
679
|
# lalanne
|
|
680
680
|
Ezz_1 = inv(Ezz)
|
|
681
681
|
Ky_Ezz_1 = ky / k * Ezz_1
|
|
682
|
-
Kx_Ezz_1 = kx[:,
|
|
683
|
-
Exz_Ezz_1 =
|
|
684
|
-
Eyz_Ezz_1 =
|
|
685
|
-
H11 = 1j *
|
|
686
|
-
H12 = 1j *
|
|
687
|
-
H13 =
|
|
688
|
-
H14 = I -
|
|
689
|
-
H21 = 1j *
|
|
690
|
-
H22 = 1j *
|
|
691
|
-
H23 =
|
|
692
|
-
H24 = -
|
|
693
|
-
H31 =
|
|
694
|
-
H32 = Exx_1_1 -
|
|
695
|
-
H33 = 1j *
|
|
696
|
-
H34 = -1j *
|
|
697
|
-
H41 =
|
|
698
|
-
H42 = -
|
|
699
|
-
H43 = -1j *
|
|
700
|
-
H44 = 1j *
|
|
701
|
-
H = 1j *
|
|
702
|
-
|
|
682
|
+
Kx_Ezz_1 = kx[:, np.newaxis] / k * Ezz_1
|
|
683
|
+
Exz_Ezz_1 = np.dot(Exz, Ezz_1)
|
|
684
|
+
Eyz_Ezz_1 = np.dot(Eyz, Ezz_1)
|
|
685
|
+
H11 = 1j * np.dot(Ky_Ezz_1, Ezy)
|
|
686
|
+
H12 = 1j * np.dot(Ky_Ezz_1, Ezx)
|
|
687
|
+
H13 = np.dot(Ky_Ezz_1, Kx)
|
|
688
|
+
H14 = I - np.dot(Ky_Ezz_1, Ky)
|
|
689
|
+
H21 = 1j * np.dot(Kx_Ezz_1, Ezy)
|
|
690
|
+
H22 = 1j * np.dot(Kx_Ezz_1, Ezx)
|
|
691
|
+
H23 = np.dot(Kx_Ezz_1, Kx) - I
|
|
692
|
+
H24 = -np.dot(Kx_Ezz_1, Ky)
|
|
693
|
+
H31 = np.dot(Kx, Ky) + Exy - np.dot(Exz_Ezz_1, Ezy)
|
|
694
|
+
H32 = Exx_1_1 - np.dot(Ky, Ky) - np.dot(Exz_Ezz_1, Ezx)
|
|
695
|
+
H33 = 1j * np.dot(Exz_Ezz_1, Kx)
|
|
696
|
+
H34 = -1j * np.dot(Exz_Ezz_1, Ky)
|
|
697
|
+
H41 = np.dot(Kx, Kx) - Eyy + np.dot(Eyz_Ezz_1, Ezy)
|
|
698
|
+
H42 = -np.dot(Kx, Ky) - Eyx + np.dot(Eyz_Ezz_1, Ezx)
|
|
699
|
+
H43 = -1j * np.dot(Eyz_Ezz_1, Kx)
|
|
700
|
+
H44 = 1j * np.dot(Eyz_Ezz_1, Ky)
|
|
701
|
+
H = 1j * np.diag(np.repeat(np.diag(Kz), 4)) + np.asarray(
|
|
702
|
+
np.bmat(
|
|
703
703
|
[
|
|
704
704
|
[H11, H12, H13, H14],
|
|
705
705
|
[H21, H22, H23, H24],
|
|
@@ -710,7 +710,7 @@ class AnisotropicRCWA(RCWA):
|
|
|
710
710
|
)
|
|
711
711
|
|
|
712
712
|
q, W = eig(H)
|
|
713
|
-
W1, W2, W3, W4 =
|
|
713
|
+
W1, W2, W3, W4 = np.split(W, 4)
|
|
714
714
|
|
|
715
715
|
#
|
|
716
716
|
# boundary conditions
|
|
@@ -727,38 +727,38 @@ class AnisotropicRCWA(RCWA):
|
|
|
727
727
|
# [b] = [-MR Mtot.MT] [R]
|
|
728
728
|
# [0] [...........] [T]
|
|
729
729
|
|
|
730
|
-
z =
|
|
731
|
-
z[
|
|
732
|
-
D =
|
|
733
|
-
Sy0 = W1 * D[
|
|
734
|
-
Sx0 = W2 * D[
|
|
735
|
-
Uy0 = W3 * D[
|
|
736
|
-
Ux0 = W4 * D[
|
|
737
|
-
|
|
738
|
-
z = thickness *
|
|
739
|
-
z[
|
|
740
|
-
D =
|
|
741
|
-
D1 =
|
|
742
|
-
Syd = D1[:,
|
|
743
|
-
Sxd = D1[:,
|
|
744
|
-
Uyd = D1[:,
|
|
745
|
-
Uxd = D1[:,
|
|
746
|
-
|
|
747
|
-
Mp[:, :, nlayer] =
|
|
748
|
-
M[:, :, nlayer] =
|
|
749
|
-
|
|
750
|
-
Mtot =
|
|
730
|
+
z = np.zeros_like(q)
|
|
731
|
+
z[np.where(q.real > 0)] = -thickness
|
|
732
|
+
D = np.exp(k * q * z)
|
|
733
|
+
Sy0 = W1 * D[np.newaxis, :]
|
|
734
|
+
Sx0 = W2 * D[np.newaxis, :]
|
|
735
|
+
Uy0 = W3 * D[np.newaxis, :]
|
|
736
|
+
Ux0 = W4 * D[np.newaxis, :]
|
|
737
|
+
|
|
738
|
+
z = thickness * np.ones_like(q)
|
|
739
|
+
z[np.where(q.real > 0)] = 0
|
|
740
|
+
D = np.exp(k * q * z)
|
|
741
|
+
D1 = np.exp(-1j * k2i[2, :] * thickness)
|
|
742
|
+
Syd = D1[:, np.newaxis] * W1 * D[np.newaxis, :]
|
|
743
|
+
Sxd = D1[:, np.newaxis] * W2 * D[np.newaxis, :]
|
|
744
|
+
Uyd = D1[:, np.newaxis] * W3 * D[np.newaxis, :]
|
|
745
|
+
Uxd = D1[:, np.newaxis] * W4 * D[np.newaxis, :]
|
|
746
|
+
|
|
747
|
+
Mp[:, :, nlayer] = np.r_[Sx0, Sy0, -1j * Ux0, -1j * Uy0]
|
|
748
|
+
M[:, :, nlayer] = np.r_[Sxd, Syd, -1j * Uxd, -1j * Uyd]
|
|
749
|
+
|
|
750
|
+
Mtot = np.eye(4 * nood, dtype=complex)
|
|
751
751
|
for nlayer in range(1, nlayers - 1):
|
|
752
|
-
Mtot =
|
|
752
|
+
Mtot = np.dot(np.dot(Mtot, Mp[:, :, nlayer]), inv(M[:, :, nlayer]))
|
|
753
753
|
|
|
754
|
-
BC_b =
|
|
755
|
-
BC_A1 =
|
|
756
|
-
BC_A2 =
|
|
757
|
-
|
|
754
|
+
BC_b = np.r_[b, np.zeros_like(b)]
|
|
755
|
+
BC_A1 = np.c_[-MR, np.dot(Mtot, MT)]
|
|
756
|
+
BC_A2 = np.asarray(
|
|
757
|
+
np.bmat(
|
|
758
758
|
[
|
|
759
759
|
[
|
|
760
|
-
(c1[0] * I - c1[2] *
|
|
761
|
-
(c1[1] * I - c1[2] *
|
|
760
|
+
(c1[0] * I - c1[2] * np.dot(CRO_1, ARO)),
|
|
761
|
+
(c1[1] * I - c1[2] * np.dot(CRO_1, BRO)),
|
|
762
762
|
ZERO,
|
|
763
763
|
ZERO,
|
|
764
764
|
ZERO,
|
|
@@ -769,8 +769,8 @@ class AnisotropicRCWA(RCWA):
|
|
|
769
769
|
[
|
|
770
770
|
ZERO,
|
|
771
771
|
ZERO,
|
|
772
|
-
(DRE -
|
|
773
|
-
(ERE -
|
|
772
|
+
(DRE - np.dot(np.dot(FRE, CRE_1), ARE)),
|
|
773
|
+
(ERE - np.dot(np.dot(FRE, CRE_1), BRE)),
|
|
774
774
|
ZERO,
|
|
775
775
|
ZERO,
|
|
776
776
|
ZERO,
|
|
@@ -781,8 +781,8 @@ class AnisotropicRCWA(RCWA):
|
|
|
781
781
|
ZERO,
|
|
782
782
|
ZERO,
|
|
783
783
|
ZERO,
|
|
784
|
-
(c3[0] * I - c3[2] *
|
|
785
|
-
(c3[1] * I - c3[2] *
|
|
784
|
+
(c3[0] * I - c3[2] * np.dot(CTO_1, ATO)),
|
|
785
|
+
(c3[1] * I - c3[2] * np.dot(CTO_1, BTO)),
|
|
786
786
|
ZERO,
|
|
787
787
|
ZERO,
|
|
788
788
|
],
|
|
@@ -793,52 +793,52 @@ class AnisotropicRCWA(RCWA):
|
|
|
793
793
|
ZERO,
|
|
794
794
|
ZERO,
|
|
795
795
|
ZERO,
|
|
796
|
-
(DTE -
|
|
797
|
-
(ETE -
|
|
796
|
+
(DTE - np.dot(np.dot(FTE, CTE_1), ATE)),
|
|
797
|
+
(ETE - np.dot(np.dot(FTE, CTE_1), BTE)),
|
|
798
798
|
],
|
|
799
799
|
]
|
|
800
800
|
)
|
|
801
801
|
)
|
|
802
802
|
|
|
803
|
-
BC_A =
|
|
803
|
+
BC_A = np.r_[BC_A1, BC_A2]
|
|
804
804
|
|
|
805
805
|
x = linsolve(BC_A, BC_b)
|
|
806
806
|
|
|
807
|
-
ROx, ROy, REx, REy, TOx, TOy, TEx, TEy =
|
|
807
|
+
ROx, ROy, REx, REy, TOx, TOy, TEx, TEy = np.split(x, 8)
|
|
808
808
|
|
|
809
|
-
ROz = -
|
|
810
|
-
REz = -
|
|
811
|
-
TOz = -
|
|
812
|
-
TEz = -
|
|
809
|
+
ROz = -np.dot(CRO_1, (np.dot(ARO, ROx) + np.dot(BRO, ROy)))
|
|
810
|
+
REz = -np.dot(CRE_1, (np.dot(ARE, REx) + np.dot(BRE, REy)))
|
|
811
|
+
TOz = -np.dot(CTO_1, (np.dot(ATO, TOx) + np.dot(BTO, TOy)))
|
|
812
|
+
TEz = -np.dot(CTE_1, (np.dot(ATE, TEx) + np.dot(BTE, TEy)))
|
|
813
813
|
|
|
814
|
-
denom = (k1[2] -
|
|
814
|
+
denom = (k1[2] - np.dot(u, k1) * u[2]).real
|
|
815
815
|
DEO1[:, iwl] = (
|
|
816
816
|
-(
|
|
817
|
-
(
|
|
818
|
-
*
|
|
817
|
+
(np.absolute(ROx) ** 2 + np.absolute(ROy) ** 2 + np.absolute(ROz) ** 2)
|
|
818
|
+
* np.conj(kO1i[2, :])
|
|
819
819
|
- (ROx * kO1i[0, :] + ROy * kO1i[1, :] + ROz * kO1i[2, :])
|
|
820
|
-
*
|
|
820
|
+
* np.conj(ROz)
|
|
821
821
|
).real
|
|
822
822
|
/ denom
|
|
823
823
|
)
|
|
824
824
|
DEE1[:, iwl] = (
|
|
825
825
|
-(
|
|
826
|
-
(
|
|
827
|
-
*
|
|
826
|
+
(np.absolute(REx) ** 2 + np.absolute(REy) ** 2 + np.absolute(REz) ** 2)
|
|
827
|
+
* np.conj(kE1i[2, :])
|
|
828
828
|
- (REx * kE1i[0, :] + REy * kE1i[1, :] + REz * kE1i[2, :])
|
|
829
|
-
*
|
|
829
|
+
* np.conj(REz)
|
|
830
830
|
).real
|
|
831
831
|
/ denom
|
|
832
832
|
)
|
|
833
833
|
DEO3[:, iwl] = (
|
|
834
|
-
(
|
|
835
|
-
*
|
|
836
|
-
- (TOx * kO3i[0, :] + TOy * kO3i[1, :] + TOz * kO3i[2, :]) *
|
|
834
|
+
(np.absolute(TOx) ** 2 + np.absolute(TOy) ** 2 + np.absolute(TOz) ** 2)
|
|
835
|
+
* np.conj(kO3i[2, :])
|
|
836
|
+
- (TOx * kO3i[0, :] + TOy * kO3i[1, :] + TOz * kO3i[2, :]) * np.conj(TOz)
|
|
837
837
|
).real / denom
|
|
838
838
|
DEE3[:, iwl] = (
|
|
839
|
-
(
|
|
840
|
-
*
|
|
841
|
-
- (TEx * kE3i[0, :] + TEy * kE3i[1, :] + TEz * kE3i[2, :]) *
|
|
839
|
+
(np.absolute(TEx) ** 2 + np.absolute(TEy) ** 2 + np.absolute(TEz) ** 2)
|
|
840
|
+
* np.conj(kE3i[2, :])
|
|
841
|
+
- (TEx * kE3i[0, :] + TEy * kE3i[1, :] + TEz * kE3i[2, :]) * np.conj(TEz)
|
|
842
842
|
).real / denom
|
|
843
843
|
|
|
844
844
|
# save the results
|
EMpy/devices.py
CHANGED
|
@@ -619,8 +619,8 @@ class MZ(Device):
|
|
|
619
619
|
self.coupler2.sanity_check()
|
|
620
620
|
self.line.sanity_check()
|
|
621
621
|
if not (
|
|
622
|
-
numpy.
|
|
623
|
-
and numpy.
|
|
622
|
+
numpy.all(self.coupler1.wl == self.line.wl)
|
|
623
|
+
and numpy.all(self.coupler1.wl == self.coupler2.wl)
|
|
624
624
|
):
|
|
625
625
|
raise ValueError("incompatible wl")
|
|
626
626
|
|
|
@@ -808,9 +808,9 @@ class SRR(Device):
|
|
|
808
808
|
self.line1.sanity_check()
|
|
809
809
|
self.line2.sanity_check()
|
|
810
810
|
if not (
|
|
811
|
-
numpy.
|
|
812
|
-
and numpy.
|
|
813
|
-
and numpy.
|
|
811
|
+
numpy.all(self.coupler1.wl == self.coupler2.wl)
|
|
812
|
+
and numpy.all(self.coupler1.wl == self.line1.wl)
|
|
813
|
+
and numpy.all(self.coupler1.wl == self.line2.wl)
|
|
814
814
|
):
|
|
815
815
|
raise ValueError("incompatible wl")
|
|
816
816
|
|
|
@@ -926,7 +926,7 @@ class NRR(Device):
|
|
|
926
926
|
|
|
927
927
|
for K in self.Ks:
|
|
928
928
|
K.sanity_check()
|
|
929
|
-
if not (numpy.
|
|
929
|
+
if not (numpy.all(self.wl == K.wl)):
|
|
930
930
|
raise ValueError("incompatible wl")
|
|
931
931
|
if not (len(self.Ks) - 1 == len(self.neffs) == len(self.l1s) == len(self.l2s)):
|
|
932
932
|
raise ValueError("number of couplers and number of rings do not match.")
|
EMpy/transfer_matrix.py
CHANGED
|
@@ -9,7 +9,7 @@ anisotropic one.
|
|
|
9
9
|
"""
|
|
10
10
|
__author__ = "Lorenzo Bolla"
|
|
11
11
|
|
|
12
|
-
import
|
|
12
|
+
import numpy as np
|
|
13
13
|
from scipy.linalg import inv
|
|
14
14
|
from EMpy.utils import snell, norm
|
|
15
15
|
from EMpy.constants import c, mu0
|
|
@@ -60,27 +60,27 @@ class IsotropicTransferMatrix(TransferMatrix):
|
|
|
60
60
|
transmitted on s and p polarizations.
|
|
61
61
|
"""
|
|
62
62
|
|
|
63
|
-
self.wls =
|
|
63
|
+
self.wls = np.asarray(wls)
|
|
64
64
|
|
|
65
65
|
multilayer = self.multilayer
|
|
66
66
|
theta_inc = self.theta_inc
|
|
67
67
|
|
|
68
68
|
nlayers = len(multilayer)
|
|
69
|
-
d =
|
|
69
|
+
d = np.array([l.thickness for l in multilayer]).ravel()
|
|
70
70
|
|
|
71
|
-
Rs =
|
|
72
|
-
Ts =
|
|
73
|
-
Rp =
|
|
74
|
-
Tp =
|
|
71
|
+
Rs = np.zeros_like(self.wls, dtype=float)
|
|
72
|
+
Ts = np.zeros_like(self.wls, dtype=float)
|
|
73
|
+
Rp = np.zeros_like(self.wls, dtype=float)
|
|
74
|
+
Tp = np.zeros_like(self.wls, dtype=float)
|
|
75
75
|
|
|
76
|
-
Dp =
|
|
77
|
-
Ds =
|
|
78
|
-
P =
|
|
79
|
-
Ms =
|
|
80
|
-
Mp =
|
|
81
|
-
k =
|
|
76
|
+
Dp = np.zeros((2, 2), dtype=complex)
|
|
77
|
+
Ds = np.zeros((2, 2), dtype=complex)
|
|
78
|
+
P = np.zeros((2, 2), dtype=complex)
|
|
79
|
+
Ms = np.zeros((2, 2), dtype=complex)
|
|
80
|
+
Mp = np.zeros((2, 2), dtype=complex)
|
|
81
|
+
k = np.zeros((nlayers, 2), dtype=complex)
|
|
82
82
|
|
|
83
|
-
ntot =
|
|
83
|
+
ntot = np.zeros((self.wls.size, nlayers), dtype=complex)
|
|
84
84
|
for i, l in enumerate(multilayer):
|
|
85
85
|
# ntot[:,i] = l.mat.n(self.wls,l.mat.T0)
|
|
86
86
|
ntot[:, i] = l.mat.n(self.wls, l.mat.toc.T0)
|
|
@@ -89,26 +89,26 @@ class IsotropicTransferMatrix(TransferMatrix):
|
|
|
89
89
|
n = ntot[iwl, :]
|
|
90
90
|
theta = snell(theta_inc, n)
|
|
91
91
|
|
|
92
|
-
k[:, 0] = 2 *
|
|
93
|
-
k[:, 1] = 2 *
|
|
92
|
+
k[:, 0] = 2 * np.pi * n / wl * np.cos(theta)
|
|
93
|
+
k[:, 1] = 2 * np.pi * n / wl * np.sin(theta)
|
|
94
94
|
|
|
95
|
-
Ds = [[1.0, 1.0], [n[0] *
|
|
96
|
-
Dp = [[
|
|
95
|
+
Ds = [[1.0, 1.0], [n[0] * np.cos(theta[0]), -n[0] * np.cos(theta[0])]]
|
|
96
|
+
Dp = [[np.cos(theta[0]), np.cos(theta[0])], [n[0], -n[0]]]
|
|
97
97
|
Ms = inv(Ds)
|
|
98
98
|
Mp = inv(Dp)
|
|
99
99
|
|
|
100
100
|
for nn, dd, tt, kk in zip(n[1:-1], d[1:-1], theta[1:-1], k[1:-1, 0]):
|
|
101
|
-
Ds = [[1.0, 1.0], [nn *
|
|
102
|
-
Dp = [[
|
|
101
|
+
Ds = [[1.0, 1.0], [nn * np.cos(tt), -nn * np.cos(tt)]]
|
|
102
|
+
Dp = [[np.cos(tt), np.cos(tt)], [nn, -nn]]
|
|
103
103
|
phi = kk * dd
|
|
104
|
-
P = [[
|
|
105
|
-
Ms =
|
|
106
|
-
Mp =
|
|
104
|
+
P = [[np.exp(1j * phi), 0], [0, np.exp(-1j * phi)]]
|
|
105
|
+
Ms = np.dot(Ms, np.dot(Ds, np.dot(P, inv(Ds))))
|
|
106
|
+
Mp = np.dot(Mp, np.dot(Dp, np.dot(P, inv(Dp))))
|
|
107
107
|
|
|
108
|
-
Ds = [[1.0, 1.0], [n[-1] *
|
|
109
|
-
Dp = [[
|
|
110
|
-
Ms =
|
|
111
|
-
Mp =
|
|
108
|
+
Ds = [[1.0, 1.0], [n[-1] * np.cos(theta[-1]), -n[-1] * np.cos(theta[-1])]]
|
|
109
|
+
Dp = [[np.cos(theta[-1]), np.cos(theta[-1])], [n[-1], -n[-1]]]
|
|
110
|
+
Ms = np.dot(Ms, Ds)
|
|
111
|
+
Mp = np.dot(Mp, Dp)
|
|
112
112
|
|
|
113
113
|
rs = Ms[1, 0] / Ms[0, 0]
|
|
114
114
|
ts = 1.0 / Ms[0, 0]
|
|
@@ -116,15 +116,15 @@ class IsotropicTransferMatrix(TransferMatrix):
|
|
|
116
116
|
rp = Mp[1, 0] / Mp[0, 0]
|
|
117
117
|
tp = 1.0 / Mp[0, 0]
|
|
118
118
|
|
|
119
|
-
Rs[iwl] =
|
|
119
|
+
Rs[iwl] = np.absolute(rs) ** 2
|
|
120
120
|
Ts[iwl] = (
|
|
121
|
-
|
|
122
|
-
*
|
|
121
|
+
np.absolute((n[-1] * np.cos(theta[-1])) / (n[0] * np.cos(theta[0])))
|
|
122
|
+
* np.absolute(ts) ** 2
|
|
123
123
|
)
|
|
124
|
-
Rp[iwl] =
|
|
124
|
+
Rp[iwl] = np.absolute(rp) ** 2
|
|
125
125
|
Tp[iwl] = (
|
|
126
|
-
|
|
127
|
-
*
|
|
126
|
+
np.absolute((n[-1] * np.cos(theta[-1])) / (n[0] * np.cos(theta[0])))
|
|
127
|
+
* np.absolute(tp) ** 2
|
|
128
128
|
)
|
|
129
129
|
|
|
130
130
|
self.Rs = Rs
|
|
@@ -176,7 +176,7 @@ class AnisotropicTransferMatrix(TransferMatrix):
|
|
|
176
176
|
self.R, self.T = power reflected and transmitted.
|
|
177
177
|
"""
|
|
178
178
|
|
|
179
|
-
self.wls =
|
|
179
|
+
self.wls = np.asarray(wls)
|
|
180
180
|
|
|
181
181
|
multilayer = self.multilayer
|
|
182
182
|
theta_inc_x = self.theta_inc_x
|
|
@@ -190,10 +190,10 @@ class AnisotropicTransferMatrix(TransferMatrix):
|
|
|
190
190
|
gamma_i, i = 1,2,3,4 that satisfy the boundary conditions.
|
|
191
191
|
"""
|
|
192
192
|
|
|
193
|
-
omega = 2.0 *
|
|
193
|
+
omega = 2.0 * np.pi * c / wl
|
|
194
194
|
K = omega**2 * mu0 * epsilon
|
|
195
195
|
|
|
196
|
-
k0 = 2.0 *
|
|
196
|
+
k0 = 2.0 * np.pi / wl
|
|
197
197
|
K /= k0**2
|
|
198
198
|
alpha /= k0
|
|
199
199
|
beta /= k0
|
|
@@ -270,17 +270,17 @@ class AnisotropicTransferMatrix(TransferMatrix):
|
|
|
270
270
|
- K[2, 0] * K[0, 2] * K[1, 1],
|
|
271
271
|
]
|
|
272
272
|
|
|
273
|
-
gamma =
|
|
274
|
-
tmp =
|
|
273
|
+
gamma = np.roots(coeff)
|
|
274
|
+
tmp = np.sort_complex(gamma)
|
|
275
275
|
gamma = tmp[[3, 0, 2, 1]] # convention
|
|
276
276
|
|
|
277
277
|
k = (
|
|
278
278
|
k0
|
|
279
|
-
*
|
|
280
|
-
[alpha *
|
|
279
|
+
* np.array(
|
|
280
|
+
[alpha * np.ones(gamma.shape), beta * np.ones(gamma.shape), gamma]
|
|
281
281
|
).T
|
|
282
282
|
)
|
|
283
|
-
v =
|
|
283
|
+
v = np.zeros((4, 3), dtype=complex)
|
|
284
284
|
|
|
285
285
|
for i, g in enumerate(gamma):
|
|
286
286
|
# H = K + [
|
|
@@ -301,41 +301,41 @@ class AnisotropicTransferMatrix(TransferMatrix):
|
|
|
301
301
|
p3 /= norm(p3)
|
|
302
302
|
p4 = v[1, :]
|
|
303
303
|
p4 /= norm(p4)
|
|
304
|
-
p1 =
|
|
304
|
+
p1 = np.cross(p3, k[0, :])
|
|
305
305
|
p1 /= norm(p1)
|
|
306
|
-
p2 =
|
|
306
|
+
p2 = np.cross(p4, k[1, :])
|
|
307
307
|
p2 /= norm(p2)
|
|
308
308
|
|
|
309
|
-
p =
|
|
310
|
-
q = wl / (2.0 *
|
|
309
|
+
p = np.array([p1, p2, p3, p4])
|
|
310
|
+
q = wl / (2.0 * np.pi * mu0 * c) * np.cross(k, p)
|
|
311
311
|
|
|
312
312
|
return k, p, q
|
|
313
313
|
|
|
314
314
|
nlayers = len(multilayer)
|
|
315
|
-
d =
|
|
315
|
+
d = np.asarray([l.thickness for l in multilayer])
|
|
316
316
|
|
|
317
317
|
# R and T are real, because they are powers
|
|
318
318
|
# r and t are complex!
|
|
319
|
-
R =
|
|
320
|
-
T =
|
|
319
|
+
R = np.zeros((2, 2, self.wls.size))
|
|
320
|
+
T = np.zeros((2, 2, self.wls.size))
|
|
321
321
|
|
|
322
|
-
epstot =
|
|
322
|
+
epstot = np.zeros((3, 3, self.wls.size, nlayers), dtype=complex)
|
|
323
323
|
for i, l in enumerate(multilayer):
|
|
324
324
|
epstot[:, :, :, i] = l.mat.epsilonTensor(self.wls)
|
|
325
325
|
|
|
326
326
|
for iwl, wl in enumerate(self.wls):
|
|
327
327
|
epsilon = epstot[:, :, iwl, :]
|
|
328
328
|
|
|
329
|
-
kx = 2 *
|
|
330
|
-
ky = 2 *
|
|
331
|
-
x =
|
|
332
|
-
y =
|
|
333
|
-
# z =
|
|
334
|
-
k =
|
|
335
|
-
p =
|
|
336
|
-
q =
|
|
337
|
-
D =
|
|
338
|
-
P =
|
|
329
|
+
kx = 2 * np.pi / wl * np.sin(theta_inc_x)
|
|
330
|
+
ky = 2 * np.pi / wl * np.sin(theta_inc_y)
|
|
331
|
+
x = np.array([1, 0, 0], dtype=float)
|
|
332
|
+
y = np.array([0, 1, 0], dtype=float)
|
|
333
|
+
# z = np.array([0, 0, 1], dtype=float)
|
|
334
|
+
k = np.zeros((4, 3, nlayers), dtype=complex)
|
|
335
|
+
p = np.zeros((4, 3, nlayers), dtype=complex)
|
|
336
|
+
q = np.zeros((4, 3, nlayers), dtype=complex)
|
|
337
|
+
D = np.zeros((4, 4, nlayers), dtype=complex)
|
|
338
|
+
P = np.zeros((4, 4, nlayers), dtype=complex)
|
|
339
339
|
|
|
340
340
|
for i in range(nlayers):
|
|
341
341
|
k[:, :, i], p[:, :, i], q[:, :, i] = find_roots(
|
|
@@ -343,45 +343,45 @@ class AnisotropicTransferMatrix(TransferMatrix):
|
|
|
343
343
|
)
|
|
344
344
|
D[:, :, i] = [
|
|
345
345
|
[
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
346
|
+
np.dot(x, p[0, :, i]),
|
|
347
|
+
np.dot(x, p[1, :, i]),
|
|
348
|
+
np.dot(x, p[2, :, i]),
|
|
349
|
+
np.dot(x, p[3, :, i]),
|
|
350
350
|
],
|
|
351
351
|
[
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
352
|
+
np.dot(y, q[0, :, i]),
|
|
353
|
+
np.dot(y, q[1, :, i]),
|
|
354
|
+
np.dot(y, q[2, :, i]),
|
|
355
|
+
np.dot(y, q[3, :, i]),
|
|
356
356
|
],
|
|
357
357
|
[
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
358
|
+
np.dot(y, p[0, :, i]),
|
|
359
|
+
np.dot(y, p[1, :, i]),
|
|
360
|
+
np.dot(y, p[2, :, i]),
|
|
361
|
+
np.dot(y, p[3, :, i]),
|
|
362
362
|
],
|
|
363
363
|
[
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
364
|
+
np.dot(x, q[0, :, i]),
|
|
365
|
+
np.dot(x, q[1, :, i]),
|
|
366
|
+
np.dot(x, q[2, :, i]),
|
|
367
|
+
np.dot(x, q[3, :, i]),
|
|
368
368
|
],
|
|
369
369
|
]
|
|
370
370
|
|
|
371
371
|
for i in range(1, nlayers - 1):
|
|
372
|
-
P[:, :, i] =
|
|
372
|
+
P[:, :, i] = np.diag(np.exp(1j * k[:, 2, i] * d[i]))
|
|
373
373
|
|
|
374
374
|
M = inv(D[:, :, 0])
|
|
375
375
|
for i in range(1, nlayers - 1):
|
|
376
|
-
M =
|
|
377
|
-
M =
|
|
376
|
+
M = np.dot(M, np.dot(D[:, :, i], np.dot(P[:, :, i], inv(D[:, :, i]))))
|
|
377
|
+
M = np.dot(M, D[:, :, -1])
|
|
378
378
|
|
|
379
379
|
deltaM = M[0, 0] * M[2, 2] - M[0, 2] * M[2, 0]
|
|
380
380
|
|
|
381
381
|
# reflectance matrix (from yeh_electromagnetic)
|
|
382
382
|
# r = [rss rsp; rps rpp]
|
|
383
383
|
r = (
|
|
384
|
-
|
|
384
|
+
np.array(
|
|
385
385
|
[
|
|
386
386
|
[
|
|
387
387
|
M[1, 0] * M[2, 2] - M[1, 2] * M[2, 0],
|
|
@@ -399,13 +399,13 @@ class AnisotropicTransferMatrix(TransferMatrix):
|
|
|
399
399
|
|
|
400
400
|
# transmittance matrix (from yeh_electromagnetic)
|
|
401
401
|
# t = [tss tsp; tps tpp]
|
|
402
|
-
t =
|
|
402
|
+
t = np.array([[M[2, 2], -M[2, 0]], [-M[0, 2], M[0, 0]]]) / deltaM
|
|
403
403
|
|
|
404
404
|
# P_t/P_inc = |E_t|**2/|E_inc|**2 . k_t_z/k_inc_z
|
|
405
|
-
T[:, :, iwl] = (
|
|
405
|
+
T[:, :, iwl] = (np.absolute(t) ** 2 * k[0, 2, -1] / k[0, 2, 0]).real
|
|
406
406
|
|
|
407
407
|
# P_r/P_inc = |E_r|**2/|E_inc|**2
|
|
408
|
-
R[:, :, iwl] =
|
|
408
|
+
R[:, :, iwl] = np.absolute(r) ** 2
|
|
409
409
|
|
|
410
410
|
self.R = R
|
|
411
411
|
self.T = T
|
EMpy/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
version = "2.1
|
|
1
|
+
version = "2.2.1"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ElectroMagneticPython
|
|
3
|
-
Version: 2.1
|
|
3
|
+
Version: 2.2.1
|
|
4
4
|
Summary: EMpy - ElectroMagnetic Python
|
|
5
5
|
Home-page: http://lbolla.github.io/EMpy/
|
|
6
6
|
Download-URL: https://github.com/lbolla/EMpy
|
|
@@ -20,9 +20,9 @@ Classifier: Operating System :: OS Independent
|
|
|
20
20
|
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
21
21
|
Provides: EMpy
|
|
22
22
|
License-File: LICENSE
|
|
23
|
-
Requires-Dist: numpy
|
|
24
|
-
Requires-Dist: scipy
|
|
25
|
-
Requires-Dist: matplotlib
|
|
23
|
+
Requires-Dist: numpy>=1.18
|
|
24
|
+
Requires-Dist: scipy>=1.7
|
|
25
|
+
Requires-Dist: matplotlib>=3.1
|
|
26
26
|
|
|
27
27
|
EMpy - ElectroMagnetic Python
|
|
28
28
|
*****************************
|
|
@@ -57,25 +57,39 @@ Optionally, install `bvp`:
|
|
|
57
57
|
Development
|
|
58
58
|
===========
|
|
59
59
|
|
|
60
|
-
First, download the source code from https://github.com/lbolla/EMpy.
|
|
60
|
+
First, download the source code from https://github.com/lbolla/EMpy.
|
|
61
|
+
|
|
62
|
+
Create a virtualenv with, e.g:
|
|
63
|
+
|
|
64
|
+
.. code-block:: bash
|
|
65
|
+
|
|
66
|
+
$> make venv
|
|
67
|
+
|
|
68
|
+
Then, from inside a `virtualenv`, install dev environment with:
|
|
61
69
|
|
|
62
70
|
.. code-block:: bash
|
|
63
71
|
|
|
64
|
-
|
|
65
|
-
$> python setup.py develop
|
|
72
|
+
$> make develop
|
|
66
73
|
|
|
67
74
|
Run tests with:
|
|
68
75
|
|
|
69
76
|
.. code-block:: bash
|
|
70
77
|
|
|
71
|
-
|
|
78
|
+
$> make test
|
|
79
|
+
|
|
80
|
+
Upgrade dependencies with:
|
|
81
|
+
|
|
82
|
+
.. code-block:: bash
|
|
83
|
+
|
|
84
|
+
$> make requirements-upgrade
|
|
85
|
+
$> make requirements-sync
|
|
86
|
+
|
|
72
87
|
|
|
73
88
|
Release process
|
|
74
89
|
===============
|
|
75
90
|
|
|
76
91
|
1. Edit CHANGES
|
|
77
|
-
2. `
|
|
78
|
-
3. `git push && git push --tags`
|
|
92
|
+
2. `make release PART=major|minor|patch`
|
|
79
93
|
|
|
80
94
|
Citation
|
|
81
95
|
========
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
EMpy/RCWA.py,sha256=
|
|
1
|
+
EMpy/RCWA.py,sha256=8wro-KNtnWTrYN2NlV8OGGrJGnd9DDwkK3KlVJ4TU8A,32249
|
|
2
2
|
EMpy/__init__.py,sha256=PSH3TiCVO9LSBCbQIM9uyXVK0TKn0S7ngWC5dGYuaPs,1003
|
|
3
3
|
EMpy/constants.py,sha256=x1N8eRXQW_gdr1557n7tvUXiM4RW_Fc_EydLd5AUC1o,723
|
|
4
|
-
EMpy/devices.py,sha256=
|
|
4
|
+
EMpy/devices.py,sha256=OQLxSAKXafBgrbWd-WNcVTOkxdBhZ-UXsW7ukoIwaYA,37895
|
|
5
5
|
EMpy/materials.py,sha256=r9SaTf4u3JBszGpVB-62VLhQp6SoQb78AsmrxLoTMkc,10687
|
|
6
6
|
EMpy/scattering.py,sha256=1rY8_TI0kzTLYwpFSSXndaO9FzDzVPRVow55vzIDQiM,7339
|
|
7
|
-
EMpy/transfer_matrix.py,sha256=
|
|
7
|
+
EMpy/transfer_matrix.py,sha256=Z3EK4MYsV5sUGTyXWieXVLg-18Wctm_3jR5LNS04r1k,14582
|
|
8
8
|
EMpy/utils.py,sha256=o-XBTXtOVOff-us4Br2zP0u2PLJFqdsq28QxvoEpZrc,42008
|
|
9
|
-
EMpy/version.py,sha256=
|
|
9
|
+
EMpy/version.py,sha256=d4pHXdSvDQjlx5mLFhqVvjzHBiA0Fow5fJ7IpFZUFeI,18
|
|
10
10
|
EMpy/modesolvers/FD.py,sha256=DIZGfAfGTPJfD83VsTvIO0gcMjvw1dci23F9PK3okow,80097
|
|
11
11
|
EMpy/modesolvers/FMM.py,sha256=FaIvg1aOsdM8pxdVNCBiqr4eTM-6oqPZPTxLanG3tXo,78366
|
|
12
12
|
EMpy/modesolvers/__init__.py,sha256=bAFq4_6rPDV4RgFx6rct9ywRDLCt_pGhiVtgC6L9A_Y,221
|
|
@@ -15,8 +15,8 @@ EMpy/modesolvers/interface.py,sha256=spMy30TFedYXJHcoV3yUdGkycGt5cplJUCeZui6a5MY
|
|
|
15
15
|
tests/__init__.py,sha256=XNMyfmlHhqih2xHEklXlmQ8GVUAdiiWrkT3trIOMpRQ,29
|
|
16
16
|
tests/materials_test.py,sha256=v_UlUvPkiKqkkPNFywbTGTTO4eNnuk-itZPr5YIEUWw,1875
|
|
17
17
|
tests/utils_test.py,sha256=Voe_Ph9LDDf47Vnt04hHLXoTPFGYXeRqzQDVkvPUVy8,597
|
|
18
|
-
ElectroMagneticPython-2.1.
|
|
19
|
-
ElectroMagneticPython-2.1.
|
|
20
|
-
ElectroMagneticPython-2.1.
|
|
21
|
-
ElectroMagneticPython-2.1.
|
|
22
|
-
ElectroMagneticPython-2.1.
|
|
18
|
+
ElectroMagneticPython-2.2.1.dist-info/LICENSE,sha256=NlQFsrkwMvQ2aD8531IDm6Rk01KzlI42HVzK5M1Hpw8,1065
|
|
19
|
+
ElectroMagneticPython-2.2.1.dist-info/METADATA,sha256=Bk8GnVNqdRF6iuFDVIRE_5XA-YqsEG0I8hBV4jVqgE8,2476
|
|
20
|
+
ElectroMagneticPython-2.2.1.dist-info/WHEEL,sha256=A3WOREP4zgxI0fKrHUG8DC8013e3dK3n7a6HDbcEIwE,91
|
|
21
|
+
ElectroMagneticPython-2.2.1.dist-info/top_level.txt,sha256=JCRI2zyREl3Lql3CyAFrqXFLGqMV0LqdsqQisk907AI,11
|
|
22
|
+
ElectroMagneticPython-2.2.1.dist-info/RECORD,,
|
|
File without changes
|
{ElectroMagneticPython-2.1.5.dist-info → ElectroMagneticPython-2.2.1.dist-info}/top_level.txt
RENAMED
|
File without changes
|