1
- |PyPI License | |PyPI PyVersions | |PyPI Version | |Build Status | |DeepSource | |Codecov | |Documentation Status |
1
+ |PyPI License | |PyPI PyVersions | |PyPI Version | |Build Status | |DeepSource | |Codecov | |Documentation Status | | DOI |
2
2
3
3
================
4
4
PWE Framework for 3D/2D/1D Photonic Crystal Analysis
@@ -10,51 +10,75 @@ Quick examples:
10
10
11
11
.. code-block :: python
12
12
13
- """ 2D example."""
14
- from morpho import BrillouinZonePath as BZPath
15
- from morpho import Geometry, Solver2D
16
- from morpho import SymmetryPoint as SPoint
13
+ """ 2D example."""
14
+ import matplotlib.pyplot as plt
15
+ import numpy as np
17
16
18
- Nx, Ny = 64 , 64
19
- P, Q = 5 , 5
20
- a = 1
21
- eps_r = 9.8
22
- mu_r = 1.0
17
+ from morpho import BrillouinZonePath as BZPath
18
+ from morpho import Geometry, Solver
19
+ from morpho import SymmetryPoint as SPoint
23
20
24
- # Define the symmetry points
25
- G = SPoint((0 , 0 ), " Γ" )
26
- X = SPoint((1 / 2 , 0 ), " X" )
27
- M = SPoint((1 / 2 , 1 / 2 ), " M" )
21
+ # Input parameters
22
+ a = 1 # normalized lattice length
23
+ r = 0.2 * a # cylinder radius
24
+ N1, N2 = 64 , 64 # discretization
25
+ P, Q = 7 , 7 # number of fourier terms
26
+ EPS_R = 9.8 # permittivity
27
+ MU_R = 1.0 # permeability
28
28
29
- t1, t2, t3 = (a, 0 , 0 ), (0 , a, 0 ), (0 , 0 , a)
29
+ # Define the symmetry points
30
+ G = SPoint((0.0 , 0.0 ), " Γ" )
31
+ X = SPoint((0.5 , 0.0 ), " X" )
32
+ M = SPoint((0.5 , 0.5 ), " M" )
30
33
31
- # Construct the bloch wave path
32
- bz_path = BZPath([G, X, M, G], t1, t2, n_points = 100 )
34
+ # Lattice vectors
35
+ a1, a2 = (a, 0 ), ( 0 , a )
33
36
34
- # Construct the geometry
35
- geo = Geometry(t1, t2, None , Nx, Ny, 1 )
37
+ # Construct the bloch wave path
38
+ bz_path = BZPath(a1, a2, [G, X, M, G], n_points = 100 )
36
39
40
+ # Construct the geometry
41
+ geo = Geometry(a1, a2, N1, N2)
37
42
38
- # Define the permitivity profile
39
- @geo.set_epsr_f
40
- def epsr_f ():
41
- """ Define eps_r profile function."""
42
- mask = geo.x** 2 + geo.y** 2 <= 0.2 ** 2
43
- geo.eps_r[mask] = eps_r
44
43
44
+ # Define the permitivity profile
45
+ @geo.overwrite
46
+ def eps_rf (eps_r , x , y ):
47
+ """ Define eps_r profile function."""
48
+ mask = x** 2 + y** 2 <= 0.2 ** 2
49
+ eps_r[mask] = EPS_R
45
50
46
- # Define the permeability profile
47
- @geo.set_mur_f
48
- def mur_f ():
49
- """ Define mu_r profile function."""
50
51
52
+ # Solve
53
+ solver_tm = Solver(geo, bz_path, P = P, Q = Q, pol = " TM" )
54
+ solver_te = Solver(geo, bz_path, P = P, Q = Q, pol = " TE" )
51
55
52
- # Solve
53
- solver_tm = Solver2D(geometry = geo, path = bz_path, P = P, Q = Q, pol = " TM" )
54
- solver_tm.run()
56
+ solver_tm.run()
57
+ solver_te.run()
55
58
56
- solver_te = Solver2D(geometry = geo, path = bz_path, P = P, Q = Q, pol = " TE" )
57
- solver_te.run()
59
+ # Results:
60
+ beta_len = bz_path.betas.cumsum
61
+ wn_tm = np.vstack(solver_tm.wn)
62
+ wn_te = np.vstack(solver_te.wn)
63
+
64
+ _, ax = plt.subplots(figsize = (5 , 4 ))
65
+
66
+ ax.set_xticklabels(bz_path.point_names)
67
+ ax.set_xticks(bz_path.point_locations)
68
+ ax.set_xlim(0 , bz_path.point_locations[- 1 ])
69
+ ax.set_ylim(0 , 0.8 )
70
+ ax.set_xlabel(r " Bloch Wave Vector $ k$ " )
71
+ ax.set_ylabel(r " Frequency $ {\o mega a}/{2\p i c}$ " )
72
+ ax.plot(beta_len, wn_tm * a / (2 * np.pi), " b-" , label = " TM" )
73
+ ax.plot(beta_len, wn_te * a / (2 * np.pi), " r-" , label = " TE" )
74
+ ax.grid(True )
75
+ handles, labels = ax.get_legend_handles_labels()
76
+ labels, ids = np.unique(labels, return_index = True )
77
+ handles = [handles[i] for i in ids]
78
+ ax.legend(handles, labels, loc = " best" )
79
+
80
+ plt.tight_layout()
81
+ plt.show()
58
82
59
83
60
84
Results:
@@ -64,54 +88,69 @@ Results:
64
88
65
89
.. code-block :: python
66
90
67
- """ 3D example."""
68
- from pwe import BrillouinZonePath as BZPath
69
- from pwe import Geometry, Solver
70
- from pwe import SymmetryPoint as SPoint
91
+ """ 3D example."""
92
+ import matplotlib.pyplot as plt
93
+ import numpy as np
94
+
95
+ from morpho import BrillouinZonePath as BZPath
96
+ from morpho import Geometry, Solver
97
+ from morpho import SymmetryPoint as SPoint
71
98
72
- Nx, Ny, Nz = 128 , 128 , 128
73
- P, Q, R = 3 , 3 , 3
99
+ N1, N2, N3 = 64 , 64 , 64
100
+ P, Q, R = 3 , 3 , 3
74
101
75
- a = 1
76
- w = 0.2 * a
77
- eps_r = 2.34
78
- mu_r = 1.0
102
+ a = 1
103
+ w = 0.2 * a
104
+ EPS_R = 2.34
105
+ MU_R = 1.0
79
106
80
- # Define the symmetry points
81
- G = SPoint((0 , 0 , 0 ), " Γ" )
82
- Z = SPoint((0 , 0 , 1 / 2 ), " Z" )
83
- X = SPoint((1 / 2 , 0 , 0 ), " X" )
84
- D = SPoint((1 / 2 , 1 / 2 , 1 / 2 ), " D" )
85
- T = SPoint((1 / 2 , 0 , 1 / 2 ), " T" )
107
+ # Define the symmetry points
108
+ G = SPoint((0 , 0 , 0 ), " Γ" )
109
+ Z = SPoint((0 , 0 , 1 / 2 ), " Z" )
110
+ X = SPoint((1 / 2 , 0 , 0 ), " X" )
111
+ D = SPoint((1 / 2 , 1 / 2 , 1 / 2 ), " D" )
112
+ T = SPoint((1 / 2 , 0 , 1 / 2 ), " T" )
86
113
87
- t1, t2, t3 = (a, 0 , 0 ), (0 , a, 0 ), (0 , 0 , a)
114
+ a1, a2, a3 = (a, 0 , 0 ), (0 , a, 0 ), (0 , 0 , a)
88
115
89
- # Construct the bloch wave path
90
- bz_path = BZPath([D, Z, G, Z, T, X], t1, t2, t3 , 200 )
116
+ # Construct the bloch wave path
117
+ bz_path = BZPath(a1, a2, a3, [D, Z, G, Z, T, X], 200 )
91
118
92
- # Construct the geometry
93
- geo = Geometry(t1, t2, t3, Nx, Ny, Nz )
119
+ # Construct the geometry
120
+ geo = Geometry(a1, a2, a3, N1, N2, N3 )
94
121
95
122
96
- # Define the permitivity profile
97
- @geo.set_epsr_f
98
- def epsr_f ( ):
99
- """ Define eps_r profile function."""
100
- mask1 = (abs (geo. x) >= a/ 2 - w/ 2 ) & (abs (geo. y) >= a/ 2 - w/ 2 )
101
- mask2 = (abs (geo. x) >= a/ 2 - w/ 2 ) & (abs (geo. z) >= a/ 2 - w/ 2 )
102
- mask3 = (abs (geo. y) >= a/ 2 - w/ 2 ) & (abs (geo. z) >= a/ 2 - w/ 2 )
103
- geo. eps_r[mask1 | mask2 | mask3] = eps_r
123
+ # Define the permitivity profile
124
+ @geo.overwrite
125
+ def eps_rf ( eps_r , x , y , z ):
126
+ """ Define eps_r profile function."""
127
+ mask1 = (abs (x) >= a/ 2 - w/ 2 ) & (abs (y) >= a/ 2 - w/ 2 )
128
+ mask2 = (abs (x) >= a/ 2 - w/ 2 ) & (abs (z) >= a/ 2 - w/ 2 )
129
+ mask3 = (abs (y) >= a/ 2 - w/ 2 ) & (abs (z) >= a/ 2 - w/ 2 )
130
+ eps_r[mask1 | mask2 | mask3] = EPS_R
104
131
105
132
106
- # Define the permeability profile
107
- @geo.set_mur_f
108
- def mur_f ():
109
- """ Define mu_r profile function."""
133
+ # Solve
134
+ solver = Solver(geo, bz_path, P = P, Q = Q, R = R)
135
+ solver.run()
110
136
137
+ # Results:
138
+ beta_len = bz_path.betas.cumsum
139
+ wn = np.vstack(solver.wn)
111
140
112
- # Solve
113
- solver = Solver(geometry = geo, path = bz_path, P = P, Q = Q, R = R)
114
- solver.run()
141
+ _, ax = plt.subplots(figsize = (5 , 4 ))
142
+
143
+ ax.set_xticklabels(bz_path.point_names)
144
+ ax.set_xticks(bz_path.point_locations)
145
+ ax.set_xlim(0 , bz_path.point_locations[- 1 ])
146
+ ax.set_ylim(0 , 1.6 )
147
+ ax.set_xlabel(r " Bloch Wave Vector $ k$ " )
148
+ ax.set_ylabel(r " Frequency $ {\o mega a}/{2\p i c}$ " )
149
+ ax.plot(beta_len, wn * a / (2 * np.pi), " k-" )
150
+ ax.grid(True )
151
+
152
+ plt.tight_layout()
153
+ plt.show()
115
154
116
155
Results:
117
156
**********
@@ -144,3 +183,6 @@ References:
144
183
145
184
.. |Documentation Status | image :: https://readthedocs.org/projects/morpho-py/badge/?version=latest
146
185
:target: https://morpho-py.readthedocs.io/en/latest/?badge=latest
186
+
187
+ .. |DOI | image :: https://zenodo.org/badge/341691173.svg
188
+ :target: https://zenodo.org/badge/latestdoi/341691173
0 commit comments