-
Notifications
You must be signed in to change notification settings - Fork 0
/
vernier_filter.py
112 lines (93 loc) · 2.87 KB
/
vernier_filter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import numpy as np
import matplotlib.pyplot as plt
import lumapi
# Connect to FDTD
fdtd = lumapi.FDTD()
# Create first ring structure
fdtd.addring()
fdtd.set("name", "ring1")
fdtd.set("x", 0)
fdtd.set("y", 0)
fdtd.set("inner radius", 0.5e-6)
fdtd.set("outer radius", 1.0e-6)
fdtd.set("z span", 0.22e-6)
fdtd.set("material", "Si (Silicon) - Palik")
# Create second ring structure
fdtd.addring()
fdtd.set("name", "ring2")
fdtd.set("x", 1.5e-6) # Offset in x direction
fdtd.set("y", 0)
fdtd.set("inner radius", 0.6e-6) # Different size
fdtd.set("outer radius", 1.1e-6) # Different size
fdtd.set("z span", 0.22e-6)
fdtd.set("material", "Si (Silicon) - Palik")
# Set up FDTD region
fdtd.addfdtd()
fdtd.set("dimension", "2D")
fdtd.set("x", 0)
fdtd.set("y", 0)
fdtd.set("x span", 2.0e-6)
fdtd.set("y span", 2.0e-6)
fdtd.set("mesh type", "auto")
# Add a source
fdtd.addmode()
fdtd.set("name", "source")
fdtd.set("x", -0.5e-6)
fdtd.set("y", 0)
fdtd.set("y span", 0.3e-6)
freq_center = 250e12 # 250 THz
freq_span = 100e12 # 100 THz
fdtd.set("center frequency", freq_center)
fdtd.set("frequency span", freq_span)
# Add a monitor
fdtd.addpower()
fdtd.set("name", "monitor")
fdtd.set("x", 0.5e-6)
fdtd.set("y", 0)
fdtd.set("x span", 0.5e-6) # Change 'y span' to 'x span'
fdtd.set("override global monitor settings", 1)
fdtd.set("use wavelength spacing", 1)
# Add a field profile monitor
fdtd.addprofile()
fdtd.set("name", "E_monitor")
fdtd.set("x", 0.5e-6)
fdtd.set("y", 0)
fdtd.set("x span", 0.5e-6) # Change 'y span' to 'x span'
fdtd.set("override global monitor settings", 1)
fdtd.set("use wavelength spacing", 1)
# Run the simulation
fdtd.run()
# Get the field profile
#print(fdtd.getdata("E_monitor"))
x = fdtd.getdata("E_monitor", "x")
y = fdtd.getdata("E_monitor", "y")
z = fdtd.getdata("E_monitor", "z")
Ex = fdtd.getdata("E_monitor", "Ex")
Ey = fdtd.getdata("E_monitor", "Ey")
Ez = fdtd.getdata("E_monitor", "Ez")
print(f"x.shape = {x.shape}")
print(f"y.shape = {y.shape}")
# Get the frequency data
f = fdtd.getdata("E_monitor", "f")
# Find the index of the center frequency
idx = np.abs(f - freq_center).argmin()
# Select the electric field components at the center frequency and the specific z-index
Ex0 = Ex[:, :, 0, idx]
Ey0 = Ey[:, :, 0, idx]
print(f"Ex.shape = {Ex.shape}")
print(f"Ex0.shape = {Ex0.shape}")
# Compute the magnitude of the electric field
E = np.sqrt(np.abs(Ex0)**2 + np.abs(Ey0)**2)
# The x, y, and E arrays should be 2D arrays with shapes (19, 73) for plotting
x, y = np.meshgrid(x.ravel(), y.ravel())
E = E.reshape(x.shape)
# Check the shapes
print(f"x.shape = {x.shape}") # Should print (19, 73)
print(f"y.shape = {y.shape}") # Should print (19, 73)
print(f"E.shape = {E.shape}") # Should print (19, 73)
# Plot the field profile
plt.pcolormesh(x, y, E, shading='auto')
plt.colorbar(label="Electric field (a.u.)")
plt.xlabel("x position (m)")
plt.ylabel("y position (m)")
plt.show()