ElectroMagneticPython 2.2.1__py3-none-any.whl → 2.2.3__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 (44) hide show
  1. EMpy/RCWA.py +32 -12
  2. EMpy/__init__.py +10 -2
  3. EMpy/_version.py +34 -0
  4. EMpy/devices.py +4 -27
  5. EMpy/materials.py +1 -6
  6. EMpy/modesolvers/FD.py +34 -72
  7. EMpy/modesolvers/FMM.py +24 -23
  8. EMpy/modesolvers/__init__.py +1 -0
  9. EMpy/modesolvers/geometries.py +8 -9
  10. EMpy/transfer_matrix.py +1 -1
  11. EMpy/utils.py +12 -24
  12. electromagneticpython-2.2.3.dist-info/METADATA +99 -0
  13. electromagneticpython-2.2.3.dist-info/RECORD +44 -0
  14. {ElectroMagneticPython-2.2.1.dist-info → electromagneticpython-2.2.3.dist-info}/WHEEL +1 -1
  15. electromagneticpython-2.2.3.dist-info/top_level.txt +4 -0
  16. examples/ex_APRR.py +18 -0
  17. examples/ex_NRR.py +40 -0
  18. examples/ex_RCWA.py +95 -0
  19. examples/ex_RCWA_2.py +52 -0
  20. examples/ex_RCWA_3.py +58 -0
  21. examples/ex_SRR.py +23 -0
  22. examples/ex_laser_etch_monitor.py +241 -0
  23. examples/ex_modesolver.py +68 -0
  24. examples/ex_modesolver_2.py +58 -0
  25. examples/ex_modesolver_3.py +48 -0
  26. examples/ex_modesolver_4.py +43 -0
  27. examples/ex_modesolver_dch.py +296 -0
  28. examples/ex_modesolver_dch_anis.py +318 -0
  29. examples/ex_transfer_matrix.py +82 -0
  30. examples/ex_transfer_matrix_2.py +44 -0
  31. examples/ex_transfer_matrix_2.py.png +0 -0
  32. examples/ex_transfer_matrix_3.py +60 -0
  33. examples/lc_data.dat +27 -0
  34. examples/nk.py +1468 -0
  35. scripts/FDTD.py +741 -0
  36. tests/devices_test.py +31 -0
  37. tests/materials_test.py +1 -1
  38. tests/modesolvers_test.py +36 -0
  39. tests/utils_test.py +9 -5
  40. EMpy/version.py +0 -1
  41. ElectroMagneticPython-2.2.1.dist-info/METADATA +0 -109
  42. ElectroMagneticPython-2.2.1.dist-info/RECORD +0 -22
  43. ElectroMagneticPython-2.2.1.dist-info/top_level.txt +0 -2
  44. {ElectroMagneticPython-2.2.1.dist-info → electromagneticpython-2.2.3.dist-info/licenses}/LICENSE +0 -0
@@ -1,8 +1,7 @@
1
- """Geometries.
1
+ """Geometries."""
2
2
 
3
- """
3
+ from matplotlib import pyplot as plt
4
4
  import numpy
5
- import pylab
6
5
 
7
6
  from EMpy.modesolvers.interface import interface_matrix
8
7
 
@@ -89,8 +88,8 @@ class SWG:
89
88
  numpy.abs(coeffLHS) ** 2 * tmp[:, numpy.newaxis] * const_z
90
89
  + numpy.abs(coeffRHS) ** 2 * tmp[:, numpy.newaxis] * const_z
91
90
  )
92
- pylab.hot()
93
- pylab.contourf(x, z0 + z, numpy.abs(f).T, 16)
91
+ plt.hot()
92
+ plt.contourf(x, z0 + z, numpy.abs(f).T, 16)
94
93
 
95
94
 
96
95
  class SimpleJoint:
@@ -221,9 +220,9 @@ class GenericDevice:
221
220
  for d in self.devlist:
222
221
  d.plot(sumx, nxy, nz, z0=z)
223
222
  z += d.length
224
- pylab.ylabel("z")
223
+ plt.ylabel("z")
225
224
  if sumx is None:
226
- pylab.xlabel("y")
225
+ plt.xlabel("y")
227
226
  else:
228
- pylab.xlabel("x")
229
- pylab.axis("tight")
227
+ plt.xlabel("x")
228
+ plt.axis("tight")
EMpy/transfer_matrix.py CHANGED
@@ -7,6 +7,7 @@ any thickness.
7
7
  Two versions of the algorithm are present: an isotropic one and an
8
8
  anisotropic one.
9
9
  """
10
+
10
11
  __author__ = "Lorenzo Bolla"
11
12
 
12
13
  import numpy as np
@@ -18,7 +19,6 @@ from EMpy.constants import c, mu0
18
19
 
19
20
 
20
21
  class TransferMatrix:
21
-
22
22
  """Class to handle the transfer matrix solvers."""
23
23
 
24
24
  def __init__(self, multilayer):
EMpy/utils.py CHANGED
@@ -4,18 +4,20 @@
4
4
 
5
5
  __author__ = "Lorenzo Bolla"
6
6
 
7
+ import time
8
+ import sys
9
+
10
+ from matplotlib import pyplot as plt
7
11
  import numpy
8
- import EMpy.constants
9
- import EMpy.materials
10
12
  import scipy.linalg
11
13
  import scipy.interpolate
12
14
  import scipy.optimize
13
- import time
14
- import sys
15
15
 
16
+ import EMpy.constants
17
+ import EMpy.materials
16
18
 
17
- class Layer:
18
19
 
20
+ class Layer:
19
21
  """A layer is defined by a material (iso or aniso) and a thickness."""
20
22
 
21
23
  def __init__(self, mat, thickness):
@@ -96,9 +98,7 @@ class BinaryGrating:
96
98
  f = self.dc
97
99
  h = numpy.arange(-hmax, hmax + 1)
98
100
  EPS = (rix1**2 - rix2**2) * f * numpy.sinc(h * f) + rix2**2 * (h == 0)
99
- EPS1 = (rix1**-2 - rix2**-2) * f * numpy.sinc(h * f) + rix2**-2 * (
100
- h == 0
101
- )
101
+ EPS1 = (rix1**-2 - rix2**-2) * f * numpy.sinc(h * f) + rix2**-2 * (h == 0)
102
102
  return EPS, EPS1
103
103
  else:
104
104
  # anisotropic
@@ -694,7 +694,6 @@ class LiquidCrystalCell:
694
694
 
695
695
 
696
696
  class Multilayer:
697
-
698
697
  """A Multilayer is a list of layers with some more methods."""
699
698
 
700
699
  def __init__(self, data=None):
@@ -816,22 +815,17 @@ class Slice(Multilayer):
816
815
  return self[0]
817
816
 
818
817
  def plot(self, x0, x1, nmin, nmax, wl=1.55e-6):
819
- try:
820
- import pylab
821
- except ImportError:
822
- warning("no pylab installed")
823
- return
824
818
  y0 = 0
825
819
  # ytot = sum([l.thickness for l in self])
826
820
  for l in self:
827
821
  y1 = y0 + l.thickness
828
822
  n = l.mat.n(wl)
829
823
  r = 1.0 - (1.0 * (n - nmin) / (nmax - nmin))
830
- pylab.fill(
824
+ plt.fill(
831
825
  [x0, x1, x1, x0], [y0, y0, y1, y1], ec="yellow", fc=(r, r, r), alpha=0.5
832
826
  )
833
827
  y0 = y1
834
- pylab.axis("image")
828
+ plt.axis("image")
835
829
 
836
830
  def __str__(self):
837
831
  return "width = %e\n%s" % (self.width, Multilayer.__str__(self))
@@ -916,11 +910,6 @@ class CrossSection(list):
916
910
  return eps
917
911
 
918
912
  def plot(self, wl=1.55e-6):
919
- try:
920
- import pylab
921
- except ImportError:
922
- warning("no pylab installed")
923
- return
924
913
  x0 = 0
925
914
  ns = [[l.mat.n(wl) for l in s] for s in self]
926
915
  nmax = max(max(ns))
@@ -929,7 +918,7 @@ class CrossSection(list):
929
918
  x1 = x0 + s.width
930
919
  s.plot(x0, x1, nmin, nmax, wl=wl)
931
920
  x0 = x1
932
- pylab.axis("image")
921
+ plt.axis("image")
933
922
 
934
923
 
935
924
  class Peak:
@@ -1218,7 +1207,7 @@ def interp2(x, y, xp, yp, fp):
1218
1207
 
1219
1208
  def trapz2(f, x=None, y=None, dx=1.0, dy=1.0):
1220
1209
  """Double integrate."""
1221
- return numpy.trapz(numpy.trapz(f, x=y, dx=dy), x=x, dx=dx)
1210
+ return numpy.trapezoid(numpy.trapezoid(f, x=y, dx=dy), x=x, dx=dx)
1222
1211
 
1223
1212
 
1224
1213
  def centered1d(x):
@@ -1251,7 +1240,6 @@ def warning(s):
1251
1240
 
1252
1241
 
1253
1242
  class ProgressBar:
1254
-
1255
1243
  """Creates a text-based progress bar. Call the object with the `print'
1256
1244
  command to see the progress bar, which looks something like this:
1257
1245
 
@@ -0,0 +1,99 @@
1
+ Metadata-Version: 2.4
2
+ Name: ElectroMagneticPython
3
+ Version: 2.2.3
4
+ Summary: EMpy - ElectroMagnetic Python
5
+ Author-email: Lorenzo Bolla <code@lbolla.info>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, http://lbolla.github.io/EMpy/
8
+ Project-URL: Repository, https://github.com/lbolla/EMpy
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: Natural Language :: English
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Topic :: Scientific/Engineering :: Physics
16
+ Requires-Python: >=3.10
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: numpy>=1.18
20
+ Requires-Dist: scipy>=1.7
21
+ Requires-Dist: matplotlib>=3.1
22
+ Dynamic: license-file
23
+
24
+ # EMpy - ElectroMagnetic Python
25
+
26
+ [![CI](https://github.com/lbolla/EMpy/actions/workflows/python-app.yml/badge.svg)](https://github.com/lbolla/EMpy/actions/workflows/python-app.yml) [![PyPI](https://badge.fury.io/py/ElectroMagneticPython.svg)](https://badge.fury.io/py/ElectroMagneticPython)
27
+
28
+ `EMpy - ElectroMagnetic Python` is a suite of algorithms widely known and used in electromagnetic problems and optics: the transfer matrix algorithm, the rigorous coupled wave analysis algorithm and more.
29
+
30
+ Run the examples in `examples/*` to have an idea how EMpy works.
31
+
32
+ Visit https://lbolla.github.io/EMpy/ for more information.
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ pip install ElectromagneticPython
38
+ ```
39
+
40
+ Optionally, install `bvp`:
41
+
42
+ ```bash
43
+ pip install scikits.bvp1lg
44
+ ```
45
+
46
+ ## Development
47
+
48
+ First, download the source code from https://github.com/lbolla/EMpy.
49
+
50
+ EMpy is managed with `uv` (https://docs.astral.sh/uv/):
51
+
52
+ Install dev environment with:
53
+
54
+ ```bash
55
+ make develop
56
+ ```
57
+
58
+ Run tests with:
59
+
60
+ ```bash
61
+ make test
62
+ ```
63
+
64
+ Run examples with, e.g.:
65
+ ```bash
66
+ uv run examples/ex_APRR.py
67
+ ```
68
+
69
+ Upgrade dependencies with `uv`:
70
+
71
+ ```bash
72
+ make upgrade
73
+ ```
74
+
75
+ ## Release process
76
+
77
+ Package version is handled by `setuptools_scm`/`uv`:
78
+
79
+ ```bash
80
+ make release PART=...
81
+ ```
82
+
83
+ GitHub actions will build and upload the package to PyPI.
84
+
85
+ ## Citation
86
+
87
+ If you find EMpy useful in your job, please consider adding a citation.
88
+
89
+ As reference:
90
+
91
+ ```
92
+ Bolla, L. (2017). EMpy [Computer software]. https://github.com/lbolla/EMpy/
93
+ ```
94
+
95
+ As text:
96
+
97
+ ```
98
+ We used EMpy (version x.y.z) to complete our work.
99
+ ```
@@ -0,0 +1,44 @@
1
+ EMpy/RCWA.py,sha256=ORsYHvt1p7TIR3vKYQfhigRH1RnHyAX98kkGMkmxIi0,32673
2
+ EMpy/__init__.py,sha256=aAaHG0VlGltUrWWZ4JMlVms2HDGj7RZ3CYNKqpZVYtM,1285
3
+ EMpy/_version.py,sha256=KPjL9Q7mJ1mOq60evnMRyAe7ifMMp2BfVmDRydV9x98,704
4
+ EMpy/constants.py,sha256=x1N8eRXQW_gdr1557n7tvUXiM4RW_Fc_EydLd5AUC1o,723
5
+ EMpy/devices.py,sha256=Tu7CVvrhqfHBSf1EiDNPnUG4Dn6MDb6qgg2VpafmdHs,37760
6
+ EMpy/materials.py,sha256=pgEM4Izy6HTA87Rl_GtNiiq5AKzc3M54fVFPFRnA8_I,10682
7
+ EMpy/scattering.py,sha256=1rY8_TI0kzTLYwpFSSXndaO9FzDzVPRVow55vzIDQiM,7339
8
+ EMpy/transfer_matrix.py,sha256=wSFqcEQYNUV4oM5SlZkglwRVyU5_w5dvRENXHfRXQpQ,14582
9
+ EMpy/utils.py,sha256=hIZ07CqM1lhRTIujbReGldlBkUjzI3iXAyAReEATBqA,41762
10
+ EMpy/modesolvers/FD.py,sha256=vKQOTgXY3-KzODAX0IOAfLbcFHUbpRt0MgteRLU3vjk,79281
11
+ EMpy/modesolvers/FMM.py,sha256=Z0HL_QGeJoQC9vyY2obBomcey0ZzVT5YZmD2-hABqZ8,78351
12
+ EMpy/modesolvers/__init__.py,sha256=rg8pzFcZd7cihqfXYj0sQamogjtMV3ObNXCNbFD3bu0,222
13
+ EMpy/modesolvers/geometries.py,sha256=X8Jd1iNoPRl5ibZiaKG13lHDIzejQ6PfrB6Zbe_c5lg,7906
14
+ EMpy/modesolvers/interface.py,sha256=spMy30TFedYXJHcoV3yUdGkycGt5cplJUCeZui6a5MY,2397
15
+ electromagneticpython-2.2.3.dist-info/licenses/LICENSE,sha256=NlQFsrkwMvQ2aD8531IDm6Rk01KzlI42HVzK5M1Hpw8,1065
16
+ examples/ex_APRR.py,sha256=f3-LOPoLNSxjqfwAJJNjVSnKYB88CIULhbjzkzdavXA,459
17
+ examples/ex_NRR.py,sha256=NVs4UASVdwiogZDSOfGAoSnbBByhB8EBLu4x3CDOnyE,900
18
+ examples/ex_RCWA.py,sha256=05Cvv3BqFgSDn_u2iZsV65HdmvVbNljgJfISaPsqd1o,2733
19
+ examples/ex_RCWA_2.py,sha256=Iwb75g2OYWayBpGn2P5BlPBh_50ZeM354eJ3kjj8pgg,1455
20
+ examples/ex_RCWA_3.py,sha256=unROedjRchAnLmyqPdhkl2-qekmddtWw6d8i6oo5VQU,1329
21
+ examples/ex_SRR.py,sha256=ciRDjn0IlpThYVLpSkn2dW6oOnJwt7_c7JJzMydl444,612
22
+ examples/ex_laser_etch_monitor.py,sha256=n6Ov8BvStKw-2veSNvX2nmR2VQJyWfsyOSh1ggvZ2qM,7589
23
+ examples/ex_modesolver.py,sha256=gD06Z2DXrxVCfakAIkqNR5k7ynSz5e1hfEYvt8ZyO0w,1529
24
+ examples/ex_modesolver_2.py,sha256=nWohSs9eftfY06wsg13M3UHBMcmM0QdPrOEWNta28mo,1264
25
+ examples/ex_modesolver_3.py,sha256=RA6LvitShITChg4DWFleI8FUUOnSUwIOCsxfW4VByGg,1209
26
+ examples/ex_modesolver_4.py,sha256=9JUjg6NK7IjwSgQvg3D_n6l_Cr0ev6hEoJGS0xffrFo,901
27
+ examples/ex_modesolver_dch.py,sha256=ha38QB7rLklEnTNfF_C0b8u7gTGKIk_T3FB0TMib5eM,7314
28
+ examples/ex_modesolver_dch_anis.py,sha256=Ye4nV5FXVxjT-FtJ3CyjzjXh9pmx9A0mbv-CkZxIN3Y,8184
29
+ examples/ex_transfer_matrix.py,sha256=JyC_MPrrfpNItYmMQjm5RbMWXe7CSd96RplJrntdOaI,1789
30
+ examples/ex_transfer_matrix_2.py,sha256=i1YMmrOSWDK0YS9aGF2thFD4_suNZsRJvs7Ei62sHAI,1058
31
+ examples/ex_transfer_matrix_2.py.png,sha256=-cgjAE1t_6UPJyOZbAagaaBs-odr59A1RYldSpMOo0M,34886
32
+ examples/ex_transfer_matrix_3.py,sha256=J8GePd3b45TmGJWL_Df7GFg-4FN8846WS9j7l9TmvRs,1501
33
+ examples/lc_data.dat,sha256=MrT57K7PZV0YT2GPU9LjO6WlC-xCd6n841P57tQW5_s,4151
34
+ examples/nk.py,sha256=hjUhwu4QzXCR0_PSKAnQ0RTD4mfe7xCYW6AbrSu4d3U,43161
35
+ scripts/FDTD.py,sha256=eK3Ra8GqkgWGP_oAPrM5pXlxERWgrwl2jwJIwoYGDfE,25308
36
+ tests/__init__.py,sha256=XNMyfmlHhqih2xHEklXlmQ8GVUAdiiWrkT3trIOMpRQ,29
37
+ tests/devices_test.py,sha256=UbmJgHp7kNVQyBYwxgaAierUVMvC7Pq5Jv7BKdFQPSw,890
38
+ tests/materials_test.py,sha256=-Z8ZmqwgSCg2AJwF_4j-RH8Ct7AOOWhV67lyMm5dcO8,1846
39
+ tests/modesolvers_test.py,sha256=v_nRDbKlda4w7A5mbZZl5fKYa2GlgLzHZaKDJZzGyrM,984
40
+ tests/utils_test.py,sha256=QnG4O_FHrX6tXH1MuocFXxptOuOtoU-dR-crCtADzQw,721
41
+ electromagneticpython-2.2.3.dist-info/METADATA,sha256=XB6uQFtMcIOL-56FDLYMqR1_i_Cne79NZP4UApAC8os,2351
42
+ electromagneticpython-2.2.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
43
+ electromagneticpython-2.2.3.dist-info/top_level.txt,sha256=CosMJsXjoaa3iZmCrZf7E0eorTFxpEFfrtfUx1YWIHA,28
44
+ electromagneticpython-2.2.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.7.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,4 @@
1
+ EMpy
2
+ examples
3
+ scripts
4
+ tests
examples/ex_APRR.py ADDED
@@ -0,0 +1,18 @@
1
+ """All-pass ring resonator example."""
2
+
3
+ from matplotlib import pyplot as plt
4
+ import numpy
5
+
6
+ import EMpy
7
+
8
+ wls = numpy.linspace(1.5e-6, 1.6e-6, 1000)
9
+ K = EMpy.devices.Coupler(wls, numpy.sqrt(0.08), 1.0)
10
+ l = 2 * numpy.pi * 5e-6
11
+ SWG = EMpy.devices.SWG(400, 220, 125).solve(wls)
12
+ APRR = EMpy.devices.APRR(K, SWG.neff, l).solve()
13
+
14
+ plt.plot(wls, numpy.unwrap(numpy.angle(APRR.THRU)), "r.-")
15
+ plt.axis("tight")
16
+ plt.xlabel("wavelength /m")
17
+ plt.ylabel("phase")
18
+ plt.show()
examples/ex_NRR.py ADDED
@@ -0,0 +1,40 @@
1
+ """N-Ring resonators example."""
2
+
3
+
4
+ from matplotlib import pyplot as plt
5
+ import numpy
6
+
7
+ import EMpy
8
+
9
+ wls = numpy.linspace(1.53e-6, 1.57e-6, 1000)
10
+
11
+ Ks = [
12
+ EMpy.devices.Coupler(wls, numpy.sqrt(0.08), 1.0),
13
+ EMpy.devices.Coupler(wls, numpy.sqrt(0.008), 1.0),
14
+ EMpy.devices.Coupler(wls, numpy.sqrt(0.006), 1.0),
15
+ EMpy.devices.Coupler(wls, numpy.sqrt(0.09), 1.0),
16
+ ]
17
+
18
+ R = 5e-6
19
+ l1s = [numpy.pi * R, numpy.pi * R, numpy.pi * R]
20
+ l2s = [numpy.pi * R, numpy.pi * R, numpy.pi * R]
21
+
22
+ SWG = EMpy.devices.SWG(400, 220, 125).solve(wls)
23
+ neffs = [SWG.neff, SWG.neff, SWG.neff]
24
+
25
+ NRR = EMpy.devices.NRR(Ks, neffs, l1s, l2s).solve()
26
+
27
+ plt.plot(
28
+ wls,
29
+ 20 * numpy.log10(numpy.absolute(NRR.THRU)),
30
+ "r.-",
31
+ wls,
32
+ 20 * numpy.log10(numpy.absolute(NRR.DROP)),
33
+ "g.-",
34
+ )
35
+ plt.axis("tight")
36
+ plt.ylim([-30, 0])
37
+ plt.xlabel("wavelength /m")
38
+ plt.ylabel("power /dB")
39
+ plt.legend(("THRU", "DROP"))
40
+ plt.show()
examples/ex_RCWA.py ADDED
@@ -0,0 +1,95 @@
1
+ """Rigorous Coupled Wave Analysis example."""
2
+
3
+ from matplotlib import pyplot as plt
4
+ import numpy
5
+
6
+ import EMpy
7
+ from EMpy.materials import (
8
+ IsotropicMaterial,
9
+ AnisotropicMaterial,
10
+ RefractiveIndex,
11
+ EpsilonTensor,
12
+ )
13
+
14
+ alpha = 0.0
15
+ delta = 0.0
16
+ # psi = EMpy.utils.deg2rad(0.) # TM
17
+ # psi = EMpy.utils.deg2rad(90.) # TE
18
+ psi = EMpy.utils.deg2rad(70.0) # hybrid
19
+ phi = EMpy.utils.deg2rad(90.0)
20
+
21
+ LAMBDA = 1016e-9 # grating periodicity
22
+ n = 2 # orders of diffraction
23
+
24
+ UV6 = IsotropicMaterial("UV6", n0=RefractiveIndex(n0_const=1.560))
25
+ SiN = AnisotropicMaterial(
26
+ "SiN",
27
+ epsilon_tensor=EpsilonTensor(
28
+ epsilon_tensor_const=EMpy.constants.eps0
29
+ * EMpy.utils.euler_rotate(
30
+ numpy.diag(numpy.asarray([1.8550, 1.8750, 1.9130]) ** 2),
31
+ EMpy.utils.deg2rad(14),
32
+ EMpy.utils.deg2rad(25),
33
+ EMpy.utils.deg2rad(32),
34
+ )
35
+ ),
36
+ )
37
+ BPTEOS = IsotropicMaterial("BPTEOS", n0=RefractiveIndex(n0_const=1.448))
38
+ ARC1 = IsotropicMaterial("ARC1", n0=RefractiveIndex(n0_const=1.448))
39
+
40
+ EFF = IsotropicMaterial("EFF", n0=RefractiveIndex(n0_const=1.6))
41
+
42
+ multilayer1 = EMpy.utils.Multilayer(
43
+ [
44
+ EMpy.utils.Layer(EMpy.materials.Air, numpy.inf),
45
+ EMpy.utils.Layer(SiN, 226e-9),
46
+ EMpy.utils.Layer(BPTEOS, 226e-9),
47
+ EMpy.utils.BinaryGrating(SiN, BPTEOS, 0.659, LAMBDA, 123e-9),
48
+ EMpy.utils.Layer(SiN, 219e-9),
49
+ EMpy.utils.Layer(EMpy.materials.SiO2, 2188e-9),
50
+ EMpy.utils.Layer(EMpy.materials.Si, numpy.inf),
51
+ ]
52
+ )
53
+
54
+ multilayer2 = EMpy.utils.Multilayer(
55
+ [
56
+ EMpy.utils.Layer(EMpy.materials.Air, numpy.inf),
57
+ EMpy.utils.Layer(SiN, 226e-9),
58
+ EMpy.utils.Layer(BPTEOS, 226e-9),
59
+ EMpy.utils.Layer(IsotropicMaterial(n0=RefractiveIndex(n0_const=1.6)), 123e-9),
60
+ EMpy.utils.Layer(SiN, 219e-9),
61
+ EMpy.utils.Layer(EMpy.materials.SiO2, 2188e-9),
62
+ EMpy.utils.Layer(EMpy.materials.Si, numpy.inf),
63
+ ]
64
+ )
65
+
66
+ wls = numpy.linspace(1.45e-6, 1.75e-6, 301)
67
+
68
+ solution1 = EMpy.RCWA.AnisotropicRCWA(multilayer1, alpha, delta, psi, phi, n).solve(wls)
69
+ solution2 = EMpy.RCWA.AnisotropicRCWA(multilayer2, alpha, delta, psi, phi, n).solve(wls)
70
+
71
+ um = 1e-6
72
+ plt.plot(
73
+ # wls / um, solution1.DEO1[n, :], 'k.-',
74
+ # wls / um, solution1.DEO3[n, :], 'r.-',
75
+ wls / um,
76
+ solution1.DEE1[n, :],
77
+ "b.-",
78
+ wls / um,
79
+ solution1.DEE3[n, :],
80
+ "g.-",
81
+ # wls / um, solution2.DEO1[n, :], 'k--',
82
+ # wls / um, solution2.DEO3[n, :], 'r--',
83
+ wls / um,
84
+ solution2.DEE1[n, :],
85
+ "b--",
86
+ wls / um,
87
+ solution2.DEE3[n, :],
88
+ "g--",
89
+ )
90
+ plt.xlabel("wavelength [um]")
91
+ plt.ylabel("diffraction efficiency")
92
+ plt.legend(("DEO1", "DEO3", "DEE1", "DEE3"))
93
+ plt.axis("tight")
94
+ plt.ylim([0, 0.15])
95
+ plt.show()
examples/ex_RCWA_2.py ADDED
@@ -0,0 +1,52 @@
1
+ """Rigorous Coupled Wave Analysis example.
2
+
3
+ Inspired by Moharam, "Formulation for stable and efficient implementation of the rigorous coupled-wave analysis of
4
+ binary gratings", JOSA A, 12(5), 1995
5
+ """
6
+
7
+ from matplotlib import pyplot as plt
8
+ import numpy
9
+
10
+ import EMpy
11
+ from EMpy.materials import IsotropicMaterial, RefractiveIndex
12
+
13
+ alpha = EMpy.utils.deg2rad(10.0)
14
+ delta = EMpy.utils.deg2rad(0.0)
15
+ psi = EMpy.utils.deg2rad(0.0) # TE
16
+ phi = EMpy.utils.deg2rad(90.0)
17
+
18
+ wl = numpy.array([1.55e-6])
19
+ ds = numpy.linspace(0.0, 5.0, 100) * wl
20
+ LAMBDA = 10 * wl
21
+
22
+ n = 3 # orders of diffraction
23
+
24
+ Top = IsotropicMaterial("Top", n0=RefractiveIndex(n0_const=1.0))
25
+ Bottom = IsotropicMaterial("Bottom", n0=RefractiveIndex(n0_const=2.04))
26
+
27
+ solutions = []
28
+ for d in ds:
29
+ multilayer = EMpy.utils.Multilayer(
30
+ [
31
+ EMpy.utils.Layer(Top, numpy.inf),
32
+ EMpy.utils.BinaryGrating(Top, Bottom, 0.3, LAMBDA, d),
33
+ EMpy.utils.Layer(Bottom, numpy.inf),
34
+ ]
35
+ )
36
+
37
+ solution = EMpy.RCWA.IsotropicRCWA(multilayer, alpha, delta, psi, phi, n).solve(wl)
38
+ solutions.append(solution)
39
+
40
+ DE1 = numpy.zeros(len(solutions))
41
+ DE3 = numpy.zeros(len(solutions))
42
+ for ss, s in enumerate(solutions):
43
+ DE1[ss] = s.DE1[n, 0]
44
+ DE3[ss] = s.DE3[n, 0]
45
+
46
+ plt.plot(ds / wl, DE1[:], "k.-", ds / wl, DE3[:], "r.-")
47
+ plt.xlabel("normalized groove depth")
48
+ plt.ylabel("diffraction efficiency")
49
+ plt.legend(("DE1", "DE3"))
50
+ plt.axis("tight")
51
+ plt.ylim([0, 1])
52
+ plt.show()
examples/ex_RCWA_3.py ADDED
@@ -0,0 +1,58 @@
1
+ """Rigorous Coupled Wave Analysis example."""
2
+
3
+
4
+ from matplotlib import pyplot as plt
5
+ import numpy
6
+
7
+ import EMpy
8
+ from EMpy.materials import IsotropicMaterial, RefractiveIndex
9
+
10
+ alpha = EMpy.utils.deg2rad(30.0)
11
+ delta = EMpy.utils.deg2rad(45.0)
12
+ psi = EMpy.utils.deg2rad(0.0) # TE
13
+ phi = EMpy.utils.deg2rad(90.0)
14
+
15
+ wls = numpy.linspace(1.5495e-6, 1.550e-6, 101)
16
+
17
+ LAMBDA = 1.0e-6 # grating periodicity
18
+ n = 3 # orders of diffraction
19
+
20
+ Top = IsotropicMaterial("Top", n0=RefractiveIndex(n0_const=1.0))
21
+ Bottom = IsotropicMaterial("Bottom", n0=RefractiveIndex(n0_const=3.47))
22
+
23
+ multilayer = EMpy.utils.Multilayer(
24
+ [
25
+ EMpy.utils.Layer(Top, numpy.inf),
26
+ EMpy.utils.BinaryGrating(Top, Bottom, 0.4, LAMBDA, 0.01),
27
+ EMpy.utils.Layer(Bottom, numpy.inf),
28
+ ]
29
+ )
30
+
31
+ solution = EMpy.RCWA.IsotropicRCWA(multilayer, alpha, delta, psi, phi, n).solve(wls)
32
+
33
+ plt.plot(
34
+ wls,
35
+ solution.DE1[n, :],
36
+ "ko-",
37
+ wls,
38
+ solution.DE3[n, :],
39
+ "ro-",
40
+ wls,
41
+ solution.DE1[n - 1, :],
42
+ "kx-",
43
+ wls,
44
+ solution.DE3[n - 1, :],
45
+ "rx-",
46
+ wls,
47
+ solution.DE1[n + 1, :],
48
+ "k.-",
49
+ wls,
50
+ solution.DE3[n + 1, :],
51
+ "r.-",
52
+ )
53
+ plt.xlabel("wavelength /m")
54
+ plt.ylabel("diffraction efficiency")
55
+ plt.legend(("DE1:0", "DE3:0", "DE1:-1", "DE3:-1", "DE1:+1", "DE3:+1"))
56
+ plt.axis("tight")
57
+ plt.ylim([0, 1])
58
+ plt.show()
examples/ex_SRR.py ADDED
@@ -0,0 +1,23 @@
1
+ """Single ring resonator example."""
2
+
3
+
4
+ from matplotlib import pyplot as plt
5
+ import numpy
6
+
7
+ import EMpy
8
+
9
+ wls = numpy.linspace(1.53e-6, 1.56e-6, 1000)
10
+ K1 = EMpy.devices.Coupler(wls, numpy.sqrt(0.08), 1.0)
11
+ K2 = EMpy.devices.Coupler(wls, numpy.sqrt(0.08), 1.0)
12
+ l1 = numpy.pi * 5e-6
13
+ l2 = numpy.pi * 5e-6
14
+ SWG = EMpy.devices.SWG(488, 220, 25).solve(wls)
15
+ SRR = EMpy.devices.SRR(K1, K2, SWG.neff, l1, l2).solve()
16
+
17
+ plt.plot(wls, numpy.absolute(SRR.THRU), "r.-", wls, numpy.absolute(SRR.DROP), "g.-")
18
+ plt.axis("tight")
19
+ plt.ylim([0, 1])
20
+ plt.xlabel("wavelength /m")
21
+ plt.ylabel("power")
22
+ plt.legend(("THRU", "DROP"))
23
+ plt.show()