ElectroMagneticPython 2.2.1__py3-none-any.whl → 2.2.4__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.
Files changed (46) hide show
  1. EMpy/RCWA.py +32 -12
  2. EMpy/__init__.py +10 -2
  3. EMpy/_version.py +24 -0
  4. EMpy/constants.py +0 -2
  5. EMpy/devices.py +8 -32
  6. EMpy/materials.py +1 -8
  7. EMpy/modesolvers/FD.py +34 -76
  8. EMpy/modesolvers/FMM.py +24 -23
  9. EMpy/modesolvers/__init__.py +1 -0
  10. EMpy/modesolvers/geometries.py +8 -9
  11. EMpy/transfer_matrix.py +10 -6
  12. EMpy/utils.py +12 -26
  13. electromagneticpython-2.2.4.dist-info/METADATA +99 -0
  14. electromagneticpython-2.2.4.dist-info/RECORD +45 -0
  15. {ElectroMagneticPython-2.2.1.dist-info → electromagneticpython-2.2.4.dist-info}/WHEEL +1 -1
  16. electromagneticpython-2.2.4.dist-info/top_level.txt +4 -0
  17. examples/ex_APRR.py +18 -0
  18. examples/ex_NRR.py +40 -0
  19. examples/ex_RCWA.py +95 -0
  20. examples/ex_RCWA_2.py +52 -0
  21. examples/ex_RCWA_3.py +58 -0
  22. examples/ex_SRR.py +23 -0
  23. examples/ex_laser_etch_monitor.py +241 -0
  24. examples/ex_modesolver.py +68 -0
  25. examples/ex_modesolver_2.py +58 -0
  26. examples/ex_modesolver_3.py +48 -0
  27. examples/ex_modesolver_4.py +43 -0
  28. examples/ex_modesolver_dch.py +296 -0
  29. examples/ex_modesolver_dch_anis.py +318 -0
  30. examples/ex_transfer_matrix.py +82 -0
  31. examples/ex_transfer_matrix_2.py +44 -0
  32. examples/ex_transfer_matrix_2.py.png +0 -0
  33. examples/ex_transfer_matrix_3.py +60 -0
  34. examples/lc_data.dat +27 -0
  35. examples/nk.py +1468 -0
  36. scripts/FDTD.py +741 -0
  37. tests/devices_test.py +31 -0
  38. tests/materials_test.py +1 -1
  39. tests/modesolvers_test.py +36 -0
  40. tests/transfer_matrix_test.py +134 -0
  41. tests/utils_test.py +9 -5
  42. EMpy/version.py +0 -1
  43. ElectroMagneticPython-2.2.1.dist-info/METADATA +0 -109
  44. ElectroMagneticPython-2.2.1.dist-info/RECORD +0 -22
  45. ElectroMagneticPython-2.2.1.dist-info/top_level.txt +0 -2
  46. {ElectroMagneticPython-2.2.1.dist-info → electromagneticpython-2.2.4.dist-info/licenses}/LICENSE +0 -0
EMpy/RCWA.py CHANGED
@@ -12,6 +12,7 @@ for every diffraction order and layer thickness, and an anisotropic
12
12
  one, only stable for low diffraction orders and thin layers.
13
13
 
14
14
  """
15
+
15
16
  __author__ = "Lorenzo Bolla"
16
17
 
17
18
  import numpy as np
@@ -95,7 +96,6 @@ def dispersion_relation_extraordinary(kx, ky, k, nO, nE, c):
95
96
 
96
97
 
97
98
  class RCWA:
98
-
99
99
  """Class to handle the RCWA solvers.
100
100
 
101
101
  NOTE
@@ -168,7 +168,6 @@ class RCWA:
168
168
 
169
169
 
170
170
  class IsotropicRCWA(RCWA):
171
-
172
171
  """Isotropic RCWA solver."""
173
172
 
174
173
  def solve(self, wls):
@@ -215,7 +214,11 @@ class IsotropicRCWA(RCWA):
215
214
  DE3 = np.zeros_like(DE1)
216
215
 
217
216
  dirk1 = np.array(
218
- [np.sin(alpha) * np.cos(delta), np.sin(alpha) * np.sin(delta), np.cos(alpha)]
217
+ [
218
+ np.sin(alpha) * np.cos(delta),
219
+ np.sin(alpha) * np.sin(delta),
220
+ np.cos(alpha),
221
+ ]
219
222
  )
220
223
 
221
224
  # usefull matrices
@@ -323,7 +326,9 @@ class IsotropicRCWA(RCWA):
323
326
  # H_S_reduced = np.dot(Ky, Ky) + np.dot(Kx, linsolve(E, np.dot(Kx, E11))) - E11
324
327
  H_S_reduced = (
325
328
  (ky / k) ** 2 * I
326
- + kx[:, np.newaxis] / k * linsolve(E, kx[:, np.newaxis] / k * E11)
329
+ + kx[:, np.newaxis]
330
+ / k
331
+ * linsolve(E, kx[:, np.newaxis] / k * E11)
327
332
  - E11
328
333
  )
329
334
 
@@ -448,7 +453,6 @@ class IsotropicRCWA(RCWA):
448
453
 
449
454
 
450
455
  class AnisotropicRCWA(RCWA):
451
-
452
456
  """Anisotropic RCWA solver."""
453
457
 
454
458
  def solve(self, wls):
@@ -487,14 +491,20 @@ class AnisotropicRCWA(RCWA):
487
491
  # grating on the xy plane
488
492
  K = 2 * pi / LAMBDA * np.array([np.sin(phi), 0.0, np.cos(phi)], dtype=complex)
489
493
  dirk1 = np.array(
490
- [np.sin(alpha) * np.cos(delta), np.sin(alpha) * np.sin(delta), np.cos(alpha)]
494
+ [
495
+ np.sin(alpha) * np.cos(delta),
496
+ np.sin(alpha) * np.sin(delta),
497
+ np.cos(alpha),
498
+ ]
491
499
  )
492
500
 
493
501
  # D polarization vector
494
502
  u = np.array(
495
503
  [
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),
504
+ np.cos(psi) * np.cos(alpha) * np.cos(delta)
505
+ - np.sin(psi) * np.sin(delta),
506
+ np.cos(psi) * np.cos(alpha) * np.sin(delta)
507
+ + np.sin(psi) * np.cos(delta),
498
508
  -np.cos(psi) * np.sin(alpha),
499
509
  ]
500
510
  )
@@ -814,7 +824,11 @@ class AnisotropicRCWA(RCWA):
814
824
  denom = (k1[2] - np.dot(u, k1) * u[2]).real
815
825
  DEO1[:, iwl] = (
816
826
  -(
817
- (np.absolute(ROx) ** 2 + np.absolute(ROy) ** 2 + np.absolute(ROz) ** 2)
827
+ (
828
+ np.absolute(ROx) ** 2
829
+ + np.absolute(ROy) ** 2
830
+ + np.absolute(ROz) ** 2
831
+ )
818
832
  * np.conj(kO1i[2, :])
819
833
  - (ROx * kO1i[0, :] + ROy * kO1i[1, :] + ROz * kO1i[2, :])
820
834
  * np.conj(ROz)
@@ -823,7 +837,11 @@ class AnisotropicRCWA(RCWA):
823
837
  )
824
838
  DEE1[:, iwl] = (
825
839
  -(
826
- (np.absolute(REx) ** 2 + np.absolute(REy) ** 2 + np.absolute(REz) ** 2)
840
+ (
841
+ np.absolute(REx) ** 2
842
+ + np.absolute(REy) ** 2
843
+ + np.absolute(REz) ** 2
844
+ )
827
845
  * np.conj(kE1i[2, :])
828
846
  - (REx * kE1i[0, :] + REy * kE1i[1, :] + REz * kE1i[2, :])
829
847
  * np.conj(REz)
@@ -833,12 +851,14 @@ class AnisotropicRCWA(RCWA):
833
851
  DEO3[:, iwl] = (
834
852
  (np.absolute(TOx) ** 2 + np.absolute(TOy) ** 2 + np.absolute(TOz) ** 2)
835
853
  * np.conj(kO3i[2, :])
836
- - (TOx * kO3i[0, :] + TOy * kO3i[1, :] + TOz * kO3i[2, :]) * np.conj(TOz)
854
+ - (TOx * kO3i[0, :] + TOy * kO3i[1, :] + TOz * kO3i[2, :])
855
+ * np.conj(TOz)
837
856
  ).real / denom
838
857
  DEE3[:, iwl] = (
839
858
  (np.absolute(TEx) ** 2 + np.absolute(TEy) ** 2 + np.absolute(TEz) ** 2)
840
859
  * np.conj(kE3i[2, :])
841
- - (TEx * kE3i[0, :] + TEy * kE3i[1, :] + TEz * kE3i[2, :]) * np.conj(TEz)
860
+ - (TEx * kE3i[0, :] + TEy * kE3i[1, :] + TEz * kE3i[2, :])
861
+ * np.conj(TEz)
842
862
  ).real / denom
843
863
 
844
864
  # save the results
EMpy/__init__.py CHANGED
@@ -10,6 +10,7 @@ The package contains some useful routines to study electromagnetic problems with
10
10
  It is based on U{numpy<http://numpy.scipy.org>} and U{scipy<http://www.scipy.org>}.
11
11
 
12
12
  """
13
+
13
14
  __all__ = [
14
15
  "constants",
15
16
  "devices",
@@ -30,6 +31,13 @@ from . import RCWA
30
31
  from . import scattering
31
32
  from . import transfer_matrix
32
33
  from . import utils
33
- from .version import version
34
34
 
35
- __version__ = version
35
+ try:
36
+ from ._version import version as __version__
37
+ except ImportError:
38
+ # Fallback for development environments or edge cases
39
+ try:
40
+ from importlib.metadata import version, PackageNotFoundError
41
+ __version__ = version("electromagneticpython")
42
+ except PackageNotFoundError:
43
+ __version__ = "0.0.0.dev0"
EMpy/_version.py ADDED
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '2.2.4'
22
+ __version_tuple__ = version_tuple = (2, 2, 4)
23
+
24
+ __commit_id__ = commit_id = 'gd8c276251'
EMpy/constants.py CHANGED
@@ -1,5 +1,3 @@
1
- # pylint: disable=C0301
2
-
3
1
  """Useful constants.
4
2
 
5
3
  Constants used in mathematics and electromagnetism.
EMpy/devices.py CHANGED
@@ -1,5 +1,3 @@
1
- # pylint: disable=C0302,W0622,W1001,R0902,R0903,W0201,R0913,R0914,C0325,W0221
2
-
3
1
  """Set of objects and functions to describe the behaviour of some
4
2
  widely known devices and build new ones.
5
3
 
@@ -31,6 +29,7 @@ devices, new ones can be studied.
31
29
  isnumber=8367>}
32
30
 
33
31
  """
32
+
34
33
  __author__ = "Lorenzo Bolla"
35
34
 
36
35
  import numpy
@@ -39,7 +38,6 @@ from functools import reduce
39
38
 
40
39
 
41
40
  class DeviceMatrix:
42
-
43
41
  """Device Matrix.
44
42
 
45
43
  Base class for TransferMatrix and ChainMatrix.
@@ -62,7 +60,7 @@ class DeviceMatrix:
62
60
  return self.__data
63
61
 
64
62
  def setdata(self, value):
65
- self.__data = numpy.asmatrix(value)
63
+ self.__data = numpy.array(value)
66
64
 
67
65
  __data = None
68
66
  data = property(fget=getdata, fset=setdata, doc="data")
@@ -83,7 +81,6 @@ class DeviceMatrix:
83
81
 
84
82
 
85
83
  class TransferMatrix(DeviceMatrix):
86
-
87
84
  """Transfer Matrix.
88
85
 
89
86
  Notation::
@@ -138,6 +135,7 @@ class TransferMatrix(DeviceMatrix):
138
135
 
139
136
  Notation::
140
137
 
138
+
141
139
  b12 = H1 a12 and d12 = H2 c12, but b12 == c12,
142
140
 
143
141
  therefore::
@@ -154,11 +152,10 @@ class TransferMatrix(DeviceMatrix):
154
152
 
155
153
  """
156
154
 
157
- return TransferMatrix(M.to_transfer().data * self.data)
155
+ return TransferMatrix(M.to_transfer().data @ self.data)
158
156
 
159
157
 
160
158
  class ChainMatrix(DeviceMatrix):
161
-
162
159
  """Chain Matrix.
163
160
 
164
161
  Notation::
@@ -229,7 +226,7 @@ class ChainMatrix(DeviceMatrix):
229
226
 
230
227
  """
231
228
 
232
- return ChainMatrix(self.data * M.to_chain().data)
229
+ return ChainMatrix(self.data @ M.to_chain().data)
233
230
 
234
231
 
235
232
  def composeTM(A, B):
@@ -289,7 +286,6 @@ def composeCMlist(CMlist):
289
286
 
290
287
 
291
288
  class Device:
292
-
293
289
  """Generic device.
294
290
 
295
291
  Notes
@@ -307,7 +303,6 @@ class Device:
307
303
 
308
304
 
309
305
  class Coupler(Device):
310
-
311
306
  """Coupler.
312
307
 
313
308
  Examples
@@ -436,7 +431,6 @@ class Coupler(Device):
436
431
 
437
432
 
438
433
  class Line(Device):
439
-
440
434
  """Line.
441
435
 
442
436
  Notes
@@ -570,7 +564,6 @@ class Line(Device):
570
564
 
571
565
 
572
566
  class MZ(Device):
573
-
574
567
  """Mach-Zehnder Interferometer (MZI).
575
568
 
576
569
  A MZI is made of two L{Coupler}s connected by a L{Line}.
@@ -679,7 +672,6 @@ class MZ(Device):
679
672
 
680
673
 
681
674
  class APRR(Device):
682
-
683
675
  """All-Pass Ring Resonator.
684
676
 
685
677
  An APRR is made of a L{Coupler} with a feedback line (the ring).
@@ -746,7 +738,6 @@ class APRR(Device):
746
738
 
747
739
 
748
740
  class SRR(Device):
749
-
750
741
  """Single Ring Resonator.
751
742
 
752
743
  A SRR is made of the parallel of a L{Coupler} a feedback line (the
@@ -872,7 +863,6 @@ class SRR(Device):
872
863
 
873
864
 
874
865
  class NRR(Device):
875
-
876
866
  """N-Rings Resonator.
877
867
 
878
868
  A NRR is made of the parallel of two lines connected by N ring resonators.
@@ -996,7 +986,6 @@ class NRR(Device):
996
986
 
997
987
 
998
988
  class T_TCRR(Device):
999
-
1000
989
  """Tunable Triple-Coupled Ring Resonator.
1001
990
 
1002
991
  A T_TCRR is made of a L{MZ}, with a feedback line.
@@ -1056,8 +1045,7 @@ class T_TCRR(Device):
1056
1045
  t4 = numpy.exp(-1j * beta * l[3])
1057
1046
 
1058
1047
  denom = (
1059
- q**3 * Kbar[2] * t3 * t4 * (Kbar[0] * Kbar[1] * t1 - K[0] * K[1] * t2)
1060
- - 1.0
1048
+ q**3 * Kbar[2] * t3 * t4 * (Kbar[0] * Kbar[1] * t1 - K[0] * K[1] * t2) - 1.0
1061
1049
  )
1062
1050
  self.DROP = (
1063
1051
  q**3 * K[2] * t3 * (K[0] * Kbar[1] * t1 + Kbar[0] * K[1] * t2) / denom
@@ -1071,7 +1059,6 @@ class T_TCRR(Device):
1071
1059
 
1072
1060
 
1073
1061
  class T_CRTCRR(Device):
1074
-
1075
1062
  """Tunable Coupled Ring Triple-Coupled Ring Resonator.
1076
1063
 
1077
1064
  NOTE
@@ -1129,16 +1116,7 @@ class T_CRTCRR(Device):
1129
1116
  - q**2 * Kbar[1] * t2**2 * (Kbar[2] - q**3 * t1**2 * N1)
1130
1117
  )
1131
1118
  self.DROP = (
1132
- 1j
1133
- * q**4
1134
- * K[0]
1135
- * K[1]
1136
- * K[2]
1137
- * Kbar[0]
1138
- * t1**1.5
1139
- * t2
1140
- * (1 + t31)
1141
- / denom
1119
+ 1j * q**4 * K[0] * K[1] * K[2] * Kbar[0] * t1**1.5 * t2 * (1 + t31) / denom
1142
1120
  )
1143
1121
  self.THRU = (
1144
1122
  q**2
@@ -1156,7 +1134,6 @@ class T_CRTCRR(Device):
1156
1134
 
1157
1135
 
1158
1136
  class T_CTCRR(Device):
1159
-
1160
1137
  """Tunable Coupled Triple Coupled Ring Resonator.
1161
1138
 
1162
1139
  NOTE
@@ -1363,7 +1340,6 @@ class SWG(Device):
1363
1340
 
1364
1341
 
1365
1342
  class Etalon(Device):
1366
-
1367
1343
  """Etalon.
1368
1344
 
1369
1345
  @ivar R: Reflectivity.
@@ -1402,7 +1378,7 @@ class Etalon(Device):
1402
1378
  self.wl0 = numpy.mean(wls)
1403
1379
  self.FSRwl = self.wl0**2 / (2 * n * l * numpy.cos(self.theta) + self.wl0)
1404
1380
 
1405
- (self.f0, self.FSR) = EMpy.utils.wl2f(self.wl0, self.FSRwl)
1381
+ self.f0, self.FSR = EMpy.utils.wl2f(self.wl0, self.FSRwl)
1406
1382
 
1407
1383
  self.FINESSE = numpy.pi / (2 * numpy.arcsin(1.0 / numpy.sqrt(self.F)))
1408
1384
  # self.FINESSE = numpy.pi * numpy.sqrt(self.F) / 2.
EMpy/materials.py CHANGED
@@ -1,10 +1,9 @@
1
- # pylint: disable=W0622,R0903,R0902,R0913,W0633
2
-
3
1
  """Functions and objects to manipulate materials.
4
2
 
5
3
  A material is an object with a refractive index function.
6
4
 
7
5
  """
6
+
8
7
  from functools import partial
9
8
 
10
9
  import numpy
@@ -15,7 +14,6 @@ __author__ = "Lorenzo Bolla"
15
14
 
16
15
 
17
16
  class Material:
18
-
19
17
  """Generic class to handle materials.
20
18
 
21
19
  This class is intended to be subclassed to obtain isotropic and
@@ -28,7 +26,6 @@ class Material:
28
26
 
29
27
 
30
28
  class RefractiveIndex:
31
-
32
29
  """Refractive Index.
33
30
 
34
31
  Unaware of temperature.
@@ -146,7 +143,6 @@ class RefractiveIndex:
146
143
 
147
144
 
148
145
  class ThermalOpticCoefficient:
149
-
150
146
  """Thermal Optic Coefficient."""
151
147
 
152
148
  def __init__(self, data=None, T0=300):
@@ -168,7 +164,6 @@ class ThermalOpticCoefficient:
168
164
 
169
165
 
170
166
  class IsotropicMaterial(Material):
171
-
172
167
  """Subclasses Material to describe isotropic materials.
173
168
 
174
169
  Frequency dispersion and thermic aware.
@@ -232,7 +227,6 @@ class EpsilonTensor:
232
227
 
233
228
 
234
229
  class AnisotropicMaterial(Material):
235
-
236
230
  """Subclass Material to describe anisotropic materials.
237
231
 
238
232
  No frequency dispersion nor thermic aware.
@@ -292,7 +286,6 @@ BK7 = IsotropicMaterial(
292
286
 
293
287
 
294
288
  class LiquidCrystal(Material):
295
-
296
289
  """Liquid Crystal.
297
290
 
298
291
  A liquid crystal is determined by it ordinary and extraordinary
EMpy/modesolvers/FD.py CHANGED
@@ -1,7 +1,3 @@
1
- # pylint: disable=line-too-long,too-many-locals,too-many-statements,too-many-branches
2
- # pylint: disable=redefined-builtin,wildcard-import,unused-wildcard-import
3
- # pylint: disable=attribute-defined-outside-init,too-many-instance-attributes
4
- # pylint: disable=arguments-differ,too-many-arguments
5
1
  """Finite Difference Modesolver.
6
2
 
7
3
  @see: Fallahkhair, "Vector Finite Difference Modesolver for Anisotropic Dielectric Waveguides",
@@ -10,6 +6,8 @@
10
6
  @see: http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=12734&objectType=FILE
11
7
 
12
8
  """
9
+
10
+ from matplotlib import pyplot as plt
13
11
  import numpy
14
12
  import scipy
15
13
  import scipy.optimize
@@ -19,7 +17,6 @@ from EMpy.modesolvers.interface import Mode, ModeSolver
19
17
 
20
18
 
21
19
  class SVFDModeSolver(ModeSolver):
22
-
23
20
  """
24
21
  This function calculates the modes of a dielectric waveguide
25
22
  using the semivectorial finite difference method.
@@ -142,10 +139,8 @@ class SVFDModeSolver(ModeSolver):
142
139
  * (p * (ep - ew) + 2 * w * ew)
143
140
  * ee
144
141
  / (
145
- (p * (ep - ee) + 2 * e * ee)
146
- * (p**2 * (ep - ew) + 4 * w**2 * ew)
147
- + (p * (ep - ew) + 2 * w * ew)
148
- * (p**2 * (ep - ee) + 4 * e**2 * ee)
142
+ (p * (ep - ee) + 2 * e * ee) * (p**2 * (ep - ew) + 4 * w**2 * ew)
143
+ + (p * (ep - ew) + 2 * w * ew) * (p**2 * (ep - ee) + 4 * e**2 * ee)
149
144
  )
150
145
  )
151
146
  Aw = (
@@ -153,10 +148,8 @@ class SVFDModeSolver(ModeSolver):
153
148
  * (p * (ep - ee) + 2 * e * ee)
154
149
  * ew
155
150
  / (
156
- (p * (ep - ee) + 2 * e * ee)
157
- * (p**2 * (ep - ew) + 4 * w**2 * ew)
158
- + (p * (ep - ew) + 2 * w * ew)
159
- * (p**2 * (ep - ee) + 4 * e**2 * ee)
151
+ (p * (ep - ee) + 2 * e * ee) * (p**2 * (ep - ew) + 4 * w**2 * ew)
152
+ + (p * (ep - ew) + 2 * w * ew) * (p**2 * (ep - ee) + 4 * e**2 * ee)
160
153
  )
161
154
  )
162
155
  Ap = ep * k**2 - An - As - Ae * ep / ee - Aw * ep / ew
@@ -169,10 +162,8 @@ class SVFDModeSolver(ModeSolver):
169
162
  * (q * (ep - es) + 2 * s * es)
170
163
  * en
171
164
  / (
172
- (q * (ep - en) + 2 * n * en)
173
- * (q**2 * (ep - es) + 4 * s**2 * es)
174
- + (q * (ep - es) + 2 * s * es)
175
- * (q**2 * (ep - en) + 4 * n**2 * en)
165
+ (q * (ep - en) + 2 * n * en) * (q**2 * (ep - es) + 4 * s**2 * es)
166
+ + (q * (ep - es) + 2 * s * es) * (q**2 * (ep - en) + 4 * n**2 * en)
176
167
  )
177
168
  )
178
169
  As = (
@@ -180,10 +171,8 @@ class SVFDModeSolver(ModeSolver):
180
171
  * (q * (ep - en) + 2 * n * en)
181
172
  * es
182
173
  / (
183
- (q * (ep - en) + 2 * n * en)
184
- * (q**2 * (ep - es) + 4 * s**2 * es)
185
- + (q * (ep - es) + 2 * s * es)
186
- * (q**2 * (ep - en) + 4 * n**2 * en)
174
+ (q * (ep - en) + 2 * n * en) * (q**2 * (ep - es) + 4 * s**2 * es)
175
+ + (q * (ep - es) + 2 * s * es) * (q**2 * (ep - en) + 4 * n**2 * en)
187
176
  )
188
177
  )
189
178
  Ae = 2 / e / (e + w)
@@ -255,14 +244,14 @@ class SVFDModeSolver(ModeSolver):
255
244
  return A
256
245
 
257
246
  def solve(self, neigs, tol):
258
- from scipy.sparse.linalg import eigen
247
+ from scipy.sparse import linalg
259
248
 
260
249
  self.nmodes = neigs
261
250
  self.tol = tol
262
251
 
263
252
  A = self.build_matrix()
264
253
 
265
- eigvals, eigvecs = eigen.eigs( # type: ignore
254
+ eigvals, eigvecs = linalg.eigs( # type: ignore
266
255
  A, k=neigs, which="LR", tol=tol, ncv=10 * neigs, return_eigenvectors=True
267
256
  )
268
257
 
@@ -296,7 +285,6 @@ class SVFDModeSolver(ModeSolver):
296
285
 
297
286
 
298
287
  class VFDModeSolver(ModeSolver):
299
-
300
288
  """
301
289
  The VFDModeSolver class computes the electric and magnetic fields
302
290
  for modes of a dielectric waveguide using the "Vector Finite
@@ -1135,12 +1123,7 @@ class VFDModeSolver(ModeSolver):
1135
1123
  (n * ezz1 * ezz2 / eyy1 + s * ezz2 * ezz1 / eyy2)
1136
1124
  * (
1137
1125
  0.5 * n * ezz4 * ezz3 / eyy4 * (2.0 / e**2 - eyx4 / ezz4 / n / e)
1138
- + 0.5
1139
- * s
1140
- * ezz3
1141
- * ezz4
1142
- / eyy3
1143
- * (2.0 / e**2 + eyx3 / ezz3 / s / e)
1126
+ + 0.5 * s * ezz3 * ezz4 / eyy3 * (2.0 / e**2 + eyx3 / ezz3 / s / e)
1144
1127
  )
1145
1128
  / ezz4
1146
1129
  / ezz3
@@ -1190,12 +1173,7 @@ class VFDModeSolver(ModeSolver):
1190
1173
  (-n * ezz4 * ezz3 / eyy4 - s * ezz3 * ezz4 / eyy3)
1191
1174
  * (
1192
1175
  0.5 * n * ezz1 * ezz2 / eyy1 * (2.0 / w**2 + eyx1 / ezz1 / n / w)
1193
- + 0.5
1194
- * s
1195
- * ezz2
1196
- * ezz1
1197
- / eyy2
1198
- * (2.0 / w**2 - eyx2 / ezz2 / s / w)
1176
+ + 0.5 * s * ezz2 * ezz1 / eyy2 * (2.0 / w**2 - eyx2 / ezz2 / s / w)
1199
1177
  )
1200
1178
  / ezz4
1201
1179
  / ezz3
@@ -1517,12 +1495,7 @@ class VFDModeSolver(ModeSolver):
1517
1495
  + (ezz3 / exx2 * ezz2 * w + ezz2 / exx3 * ezz3 * e)
1518
1496
  * (
1519
1497
  0.5 * ezz4 * (2.0 / n**2 + exy1 / ezz1 / n / w) / exx1 * ezz1 * w
1520
- + 0.5
1521
- * ezz1
1522
- * (2.0 / n**2 - exy4 / ezz4 / n / e)
1523
- / exx4
1524
- * ezz4
1525
- * e
1498
+ + 0.5 * ezz1 * (2.0 / n**2 - exy4 / ezz4 / n / e) / exx4 * ezz4 * e
1526
1499
  )
1527
1500
  / ezz3
1528
1501
  / ezz2
@@ -1572,12 +1545,7 @@ class VFDModeSolver(ModeSolver):
1572
1545
  - (ezz4 / exx1 * ezz1 * w + ezz1 / exx4 * ezz4 * e)
1573
1546
  * (
1574
1547
  0.5 * ezz3 * (2.0 / s**2 - exy2 / ezz2 / s / w) / exx2 * ezz2 * w
1575
- + 0.5
1576
- * ezz2
1577
- * (2.0 / s**2 + exy3 / ezz3 / s / e)
1578
- / exx3
1579
- * ezz3
1580
- * e
1548
+ + 0.5 * ezz2 * (2.0 / s**2 + exy3 / ezz3 / s / e) / exx3 * ezz3 * e
1581
1549
  )
1582
1550
  / ezz3
1583
1551
  / ezz2
@@ -2066,7 +2034,7 @@ class VFDModeSolver(ModeSolver):
2066
2034
  Ez = solver.modes[0].Ez
2067
2035
  """
2068
2036
 
2069
- from scipy.sparse.linalg import eigen
2037
+ from scipy.sparse import linalg
2070
2038
 
2071
2039
  self.nmodes = neigs
2072
2040
  self.tol = tol
@@ -2081,7 +2049,7 @@ class VFDModeSolver(ModeSolver):
2081
2049
  shift = None
2082
2050
 
2083
2051
  # Here is where the actual mode-solving takes place!
2084
- [eigvals, eigvecs] = eigen.eigs(
2052
+ [eigvals, eigvecs] = linalg.eigs(
2085
2053
  A,
2086
2054
  k=neigs,
2087
2055
  which="LR",
@@ -2320,14 +2288,9 @@ class FDMode(Mode):
2320
2288
 
2321
2289
  @staticmethod
2322
2290
  def plot_field(x, y, field):
2323
- try:
2324
- import pylab
2325
- except ImportError:
2326
- print("no pylab installed")
2327
- return
2328
- pylab.hot()
2329
- pylab.contour(x, y, numpy.abs(field.T), 16)
2330
- pylab.axis("image")
2291
+ plt.hot()
2292
+ plt.contour(x, y, numpy.abs(field.T), 16)
2293
+ plt.axis("image")
2331
2294
 
2332
2295
  def plot_Ex(self, x=None, y=None):
2333
2296
  if x is None:
@@ -2385,30 +2348,25 @@ class FDMode(Mode):
2385
2348
 
2386
2349
  def plot(self):
2387
2350
  """Plot the mode's fields."""
2388
- try:
2389
- import pylab
2390
- except ImportError:
2391
- print("no pylab installed")
2392
- return
2393
- pylab.figure()
2394
- pylab.subplot(2, 3, 1)
2351
+ plt.figure()
2352
+ plt.subplot(2, 3, 1)
2395
2353
  self.plot_Ex()
2396
- pylab.title("Ex")
2397
- pylab.subplot(2, 3, 2)
2354
+ plt.title("Ex")
2355
+ plt.subplot(2, 3, 2)
2398
2356
  self.plot_Ey()
2399
- pylab.title("Ey")
2400
- pylab.subplot(2, 3, 3)
2357
+ plt.title("Ey")
2358
+ plt.subplot(2, 3, 3)
2401
2359
  self.plot_Ez()
2402
- pylab.title("Ez")
2403
- pylab.subplot(2, 3, 4)
2360
+ plt.title("Ez")
2361
+ plt.subplot(2, 3, 4)
2404
2362
  self.plot_Hx()
2405
- pylab.title("Hx")
2406
- pylab.subplot(2, 3, 5)
2363
+ plt.title("Hx")
2364
+ plt.subplot(2, 3, 5)
2407
2365
  self.plot_Hy()
2408
- pylab.title("Hy")
2409
- pylab.subplot(2, 3, 6)
2366
+ plt.title("Hy")
2367
+ plt.subplot(2, 3, 6)
2410
2368
  self.plot_Hz()
2411
- pylab.title("Hz")
2369
+ plt.title("Hz")
2412
2370
 
2413
2371
 
2414
2372
  def stretchmesh(x, y, nlayers, factor, method="PPPP"):