mirror of
https://github.com/edoverg/modeconverter.git
synced 2026-10-14 23:06:39 +00:00
48 KiB
48 KiB
In [86]:
import meep as mp
import numpy as np
import numpy.matlib
import matplotlib.pyplot as plt
resolution = 120 # pixels/unit length
wvl_min = 1.5
wvl_max = 1.6
wvl_cen = 0.5*(wvl_min+wvl_max)
fmin = 1/wvl_max
fmax = 1/wvl_min
fcen = 0.5*(fmin+fmax)
df = fmax-fmin
nfreq = 10
dpml = 1.0 #PML thickness
dsub = 1.5 + wvl_cen #substrate thickness
dpad = dsub #passind between cell and PML
k_point = mp.Vector3(0,0,0) #used for PBC
n_si = 3.43 #silicon refractive index
si = mp.Medium(index=n_si)
n_air = 1.0 #air refractive index
air = mp.Medium(index=n_air)In [87]:
P = 0.7 #unit cell pitch
h = 0.7 #pillar height
sim_z_size = dpml + dsub + dpad + dpml
sim_x_size = P
sim_y_size = P
major_ax = 0.3 #major axis of the ellipse
minor_ax = 0.2 #minor axis of the ellipse
substrate_geo = mp.Block(
material = si,
size = mp.Vector3(mp.inf, mp.inf, dsub+dpml),
center = mp.Vector3(0,0,-(dsub+dpml)/2),
)
ellipse_geo = mp.Ellipsoid(
size = mp.Vector3(major_ax, minor_ax, 2*dpad),
center = mp.Vector3(0,0,0),
material = si,
)
ellipse_geo.do_averaging = True
cut_box_1 = mp.Block(
material = air,
size = mp.Vector3(major_ax, minor_ax, dpad-h),
center = mp.Vector3(0,0,(dpad-h)/2+h)
)
cut_box_2 = mp.Block(
material = air,
size = mp.Vector3(major_ax, minor_ax, dpad),
center = mp.Vector3(0,0,-dpad/2)
)
source_position = mp.Vector3(0,0,-wvl_cen) #source position in the middle of the substrate
source = mp.Source(
mp.GaussianSource(fcen, fwidth=df),
component = mp.Ex,
center = source_position,
size = mp.Vector3(sim_x_size, sim_y_size, 0),
)
cell_size = mp.Vector3(sim_x_size, sim_y_size, sim_z_size)
pml_layers = [mp.PML(dpml,direction=mp.Z)]
def elliptic_cylinder_func(p):
# p is an mp.Vector3 point (x, y, z)
if (p.x / (minor_ax/2)) ** 2 + (p.y / (major_ax/2)) ** 2 <= 1.0 and abs(p.z) <= h and abs(p.z) >= 0:
return si
return air
elliptic_cylinder_func.do_averaging = True
test_ell = mp.Block(
center=mp.Vector3(0, 0, h/2),
size=mp.Vector3(2*minor_ax, 2*major_ax, h),
material=elliptic_cylinder_func,
)
sim = mp.Simulation(
resolution = resolution,
cell_size = cell_size,
boundary_layers = pml_layers,
sources = [source],
#geometry = [ ellipse_geo, cut_box_1, cut_box_2, substrate_geo ],
geometry = [test_ell, substrate_geo],
material_function = elliptic_cylinder_func,
default_material = air,
k_point = k_point,
)
monitor_position = mp.Vector3(0,0,h+wvl_cen)
flux_mon = sim.add_flux(
fcen, df, nfreq, mp.FluxRegion(center=monitor_position, size=mp.Vector3(sim_x_size, sim_y_size, 0))
)
f, ax = plt.subplots(1,2,dpi=120)
yz_plane = mp.Volume(center=mp.Vector3(0,0,0), size=mp.Vector3(0,sim_y_size,sim_z_size))
xy_plane = mp.Volume(center=mp.Vector3(0,0,h/2), size=mp.Vector3(sim_x_size,sim_y_size,0))
sim.plot2D(ax=ax[0],output_plane=yz_plane,show_sources=True,show_monitors=True)
sim.plot2D(ax=ax[1],output_plane=xy_plane,show_sources=True,show_monitors=True,show_epsilon=True)
ax[1].set_xlim(-sim_x_size/2, sim_x_size/2)
ax[1].set_ylim(-sim_y_size/2, sim_y_size/2)
plt.show()
block, center = (0,0,0.35)
size (0.4,0.6,0.7)
axes (1,0,0), (0,1,0), (0,0,1)
block, center = (0,0,-2.025)
size (1e+20,1e+20,4.05)
axes (1,0,0), (0,1,0), (0,0,1)
dielectric constant epsilon diagonal = (11.7649,11.7649,11.7649)
block, center = (0,0,0.35)
size (0.4,0.6,0.7)
axes (1,0,0), (0,1,0), (0,0,1)
block, center = (0,0,-2.025)
size (1e+20,1e+20,4.05)
axes (1,0,0), (0,1,0), (0,0,1)
dielectric constant epsilon diagonal = (11.7649,11.7649,11.7649)
In [88]:
obs_point = monitor_position
stop_cond = mp.stop_when_fields_decayed(25, mp.Ex, obs_point, 1e-6)
sim.run(until_after_sources=stop_cond)
eps_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(0,sim_y_size,sim_z_size), component=mp.Dielectric)
ex_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(0,sim_y_size,sim_z_size), component=mp.Ex)
plt.figure()
plt.imshow(eps_data, interpolation='spline36', cmap='binary')
plt.imshow(ex_data, interpolation='spline36', cmap='RdBu', alpha=0.9)
plt.show()-----------
Initializing structure...
time for choose_chunkdivision = 0.00579405 s
Working in 3D dimensions.
Computational cell is 0.7 x 0.7 x 8.1 with resolution 120
block, center = (0,0,0.35)
size (0.4,0.6,0.7)
axes (1,0,0), (0,1,0), (0,0,1)
block, center = (0,0,-2.025)
size (1e+20,1e+20,4.05)
axes (1,0,0), (0,1,0), (0,0,1)
dielectric constant epsilon diagonal = (11.7649,11.7649,11.7649)
subpixel-averaging is 8.96239% done, 40.9949 s remaining
subpixel-averaging is 18.719% done, 17.5123 s remaining
subpixel-averaging is 28.1353% done, 10.2434 s remaining
subpixel-averaging is 37.5516% done, 6.67275 s remaining
subpixel-averaging is 47.4217% done, 4.43799 s remaining
subpixel-averaging is 57.2918% done, 3.01498 s remaining
subpixel-averaging is 66.9351% done, 1.99351 s remaining
subpixel-averaging is 77.1455% done, 1.18899 s remaining
subpixel-averaging is 87.129% done, 0.594217 s remaining
subpixel-averaging is 96.8857% done, 0.129903 s remaining
subpixel-averaging is 3.31345% done, 116.772 s remaining
subpixel-averaging is 6.60798% done, 56.6936 s remaining
subpixel-averaging is 9.86465% done, 36.645 s remaining
subpixel-averaging is 13.1592% done, 26.4271 s remaining
subpixel-averaging is 16.4727% done, 20.3888 s remaining
subpixel-averaging is 19.7483% done, 16.3062 s remaining
subpixel-averaging is 23.0807% done, 13.3563 s remaining
subpixel-averaging is 26.3373% done, 11.2352 s remaining
subpixel-averaging is 29.5751% done, 9.54566 s remaining
subpixel-averaging is 32.9075% done, 8.18746 s remaining
subpixel-averaging is 35.8044% done, 120.738 s remaining
subpixel-averaging is 35.8233% done, 109.194 s remaining
[31m---------------------------------------------------------------------------[39m [31mKeyboardInterrupt[39m Traceback (most recent call last) [36mCell[39m[36m [39m[32mIn[87][39m[32m, line 47[39m, in [36melliptic_cylinder_func[39m[34m(p)[39m [32m---> [39m[32m47[39m [38;5;28;01mdef[39;00m elliptic_cylinder_func(p): [32m 48[39m [38;5;66;03m# p is an mp.Vector3 point (x, y, z)[39;00m [32m 49[39m [38;5;28;01mif[39;00m (p.x / (minor_ax/[32m2[39m)) ** [32m2[39m + (p.y / (major_ax/[32m2[39m)) ** [32m2[39m <= [32m1.0[39m [38;5;28;01mand[39;00m abs(p.z) <= h [38;5;28;01mand[39;00m abs(p.z) >= [32m0[39m: [32m 50[39m [38;5;28;01mreturn[39;00m si [31mKeyboardInterrupt[39m:
[31m---------------------------------------------------------------------------[39m [31mRuntimeError[39m Traceback (most recent call last) [36mCell[39m[36m [39m[32mIn[88][39m[32m, line 3[39m [32m 1[39m obs_point = monitor_position [32m 2[39m stop_cond = mp.stop_when_fields_decayed([32m25[39m, mp.Ex, obs_point, [32m1e-6[39m) [32m----> [39m[32m3[39m sim.run(until_after_sources=stop_cond) [32m 4[39m eps_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3([32m0[39m,sim_y_size,sim_z_size), component=mp.Dielectric) [32m 5[39m ex_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3([32m0[39m,sim_y_size,sim_z_size), component=mp.Ex) [32m 6[39m plt.figure() [36mFile [39m[32m~/miniconda3/envs/mp/lib/python3.13/site-packages/meep/simulation.py:4553[39m, in [36mSimulation.run[39m[34m(self, *step_funcs, **kwargs)[39m [32m 4550[39m until_after_sources = kwargs.pop([33m"[39m[33muntil_after_sources[39m[33m"[39m, [38;5;28;01mNone[39;00m) [32m 4552[39m [38;5;28;01mif[39;00m [38;5;28mself[39m.fields [38;5;129;01mis[39;00m [38;5;28;01mNone[39;00m: [32m-> [39m[32m4553[39m [30;43mself[39;49m[30;43m.[39;49m[30;43minit_sim[39;49m[30;43m([39;49m[30;43m)[39;49m [32m 4555[39m [38;5;28mself[39m._evaluate_dft_objects() [32m 4556[39m [38;5;28mself[39m._check_material_frequencies() [36mFile [39m[32m~/miniconda3/envs/mp/lib/python3.13/site-packages/meep/simulation.py:2482[39m, in [36mSimulation.init_sim[39m[34m(self)[39m [32m 2479[39m warnings.warn(eps_warning, [38;5;167;01mRuntimeWarning[39;00m) [32m 2481[39m [38;5;28;01mif[39;00m [38;5;28mself[39m.structure [38;5;129;01mis[39;00m [38;5;28;01mNone[39;00m: [32m-> [39m[32m2482[39m [30;43mself[39;49m[30;43m.[39;49m[30;43m_init_structure[39;49m[30;43m([39;49m[30;43mself[39;49m[30;43m.[39;49m[30;43mk_point[39;49m[30;43m)[39;49m [32m 2484[39m [38;5;28mself[39m.fields = mp.fields( [32m 2485[39m [38;5;28mself[39m.structure, [32m 2486[39m [38;5;28mself[39m.m [38;5;28;01mif[39;00m [38;5;28mself[39m.is_cylindrical [38;5;28;01melse[39;00m [32m0[39m, [32m (...)[39m[32m 2491[39m [38;5;28mself[39m.bfast_scaled_k, [32m 2492[39m ) [32m 2494[39m [38;5;28;01mif[39;00m [38;5;28mself[39m.force_all_components [38;5;129;01mand[39;00m [38;5;28mself[39m.dimensions != [32m1[39m: [36mFile [39m[32m~/miniconda3/envs/mp/lib/python3.13/site-packages/meep/simulation.py:2095[39m, in [36mSimulation._init_structure[39m[34m(self, k)[39m [32m 2057[39m [38;5;28mself[39m.gv = gv [32m 2058[39m [38;5;28mself[39m.structure = mp.create_structure( [32m 2059[39m [38;5;28mself[39m.cell_size, [32m 2060[39m [38;5;28mself[39m.dft_data_list, [32m (...)[39m[32m 2093[39m ), [32m 2094[39m ) [32m-> [39m[32m2095[39m [38;5;28mself[39m.geps = [30;43mmp[39;49m[30;43m.[39;49m[30;43m_set_materials[39;49m[30;43m([39;49m [32m 2096[39m [30;43m [39;49m[30;43mself[39;49m[30;43m.[39;49m[30;43mstructure[39;49m[30;43m,[39;49m [32m 2097[39m [30;43m [39;49m[30;43mself[39;49m[30;43m.[39;49m[30;43mcell_size[39;49m[30;43m,[39;49m [32m 2098[39m [30;43m [39;49m[30;43mself[39;49m[30;43m.[39;49m[30;43mgv[39;49m[30;43m,[39;49m [32m 2099[39m [30;43m [39;49m[30;43mself[39;49m[30;43m.[39;49m[30;43meps_averaging[39;49m[30;43m,[39;49m [32m 2100[39m [30;43m [39;49m[30;43mself[39;49m[30;43m.[39;49m[30;43msubpixel_tol[39;49m[30;43m,[39;49m [32m 2101[39m [30;43m [39;49m[30;43mself[39;49m[30;43m.[39;49m[30;43msubpixel_maxeval[39;49m[30;43m,[39;49m [32m 2102[39m [30;43m [39;49m[30;43mself[39;49m[30;43m.[39;49m[30;43mgeometry[39;49m[30;43m,[39;49m [32m 2103[39m [30;43m [39;49m[30;43mself[39;49m[30;43m.[39;49m[30;43mgeometry_center[39;49m[30;43m,[39;49m [32m 2104[39m [30;43m [39;49m[30;43mself[39;49m[30;43m.[39;49m[30;43mensure_periodicity[39;49m[30;43m [39;49m[30;43;01mand[39;49;00m[30;43m [39;49m[30;43;01mnot[39;49;00m[30;43m [39;49m[30;43;01mnot[39;49;00m[30;43m [39;49m[30;43mself[39;49m[30;43m.[39;49m[30;43mk_point[39;49m[30;43m,[39;49m [32m 2105[39m [30;43m [39;49m[30;43mself[39;49m[30;43m.[39;49m[30;43mdefault_material[39;49m[30;43m,[39;49m [32m 2106[39m [30;43m [39;49m[30;43mabsorbers[39;49m[30;43m,[39;49m [32m 2107[39m [30;43m [39;49m[30;43mself[39;49m[30;43m.[39;49m[30;43mextra_materials[39;49m[30;43m,[39;49m [32m 2108[39m [30;43m [39;49m[30;43mself[39;49m[30;43m.[39;49m[30;43msplit_chunks_evenly[39;49m[30;43m,[39;49m [32m 2109[39m [30;43m [39;49m[30;43;01mTrue[39;49;00m[30;43m,[39;49m [32m 2110[39m [30;43m [39;49m[30;43;01mNone[39;49;00m[30;43m,[39;49m [32m 2111[39m [30;43m [39;49m[30;43;01mFalse[39;49;00m[30;43m,[39;49m [32m 2112[39m [30;43m [39;49m[30;43;01mNone[39;49;00m[30;43m,[39;49m [32m 2113[39m [30;43m[39;49m[30;43m)[39;49m [32m 2115[39m [38;5;28;01mif[39;00m [38;5;28mself[39m._output_stats [38;5;129;01mis[39;00m [38;5;129;01mnot[39;00m [38;5;28;01mNone[39;00m: [32m 2116[39m sys.exit([32m0[39m) [36mFile [39m[32m~/miniconda3/envs/mp/lib/python3.13/site-packages/meep/__init__.py:4430[39m, in [36m_set_materials[39m[34m(s, cell_size, gv, use_anisotropic_averaging, tol, maxeval, gobj_list, center, _ensure_periodicity, _default_material, alist, extra_materials, split_chunks_evenly, set_materials, existing_geps, output_chunk_costs, my_bp)[39m [32m 4429[39m [38;5;28;01mdef[39;00m[38;5;250m [39m[34m_set_materials[39m(s, cell_size, gv, use_anisotropic_averaging, tol, maxeval, gobj_list, center, _ensure_periodicity, _default_material, alist, extra_materials, split_chunks_evenly, set_materials, existing_geps, output_chunk_costs, my_bp): [32m-> [39m[32m4430[39m [38;5;28;01mreturn[39;00m [30;43m_meep[39;49m[30;43m.[39;49m[30;43m_set_materials[39;49m[30;43m([39;49m[30;43ms[39;49m[30;43m,[39;49m[30;43m [39;49m[30;43mcell_size[39;49m[30;43m,[39;49m[30;43m [39;49m[30;43mgv[39;49m[30;43m,[39;49m[30;43m [39;49m[30;43muse_anisotropic_averaging[39;49m[30;43m,[39;49m[30;43m [39;49m[30;43mtol[39;49m[30;43m,[39;49m[30;43m [39;49m[30;43mmaxeval[39;49m[30;43m,[39;49m[30;43m [39;49m[30;43mgobj_list[39;49m[30;43m,[39;49m[30;43m [39;49m[30;43mcenter[39;49m[30;43m,[39;49m[30;43m [39;49m[30;43m_ensure_periodicity[39;49m[30;43m,[39;49m[30;43m [39;49m[30;43m_default_material[39;49m[30;43m,[39;49m[30;43m [39;49m[30;43malist[39;49m[30;43m,[39;49m[30;43m [39;49m[30;43mextra_materials[39;49m[30;43m,[39;49m[30;43m [39;49m[30;43msplit_chunks_evenly[39;49m[30;43m,[39;49m[30;43m [39;49m[30;43mset_materials[39;49m[30;43m,[39;49m[30;43m [39;49m[30;43mexisting_geps[39;49m[30;43m,[39;49m[30;43m [39;49m[30;43moutput_chunk_costs[39;49m[30;43m,[39;49m[30;43m [39;49m[30;43mmy_bp[39;49m[30;43m)[39;49m [31mRuntimeError[39m: meep: Error in typemaps
In [ ]:
input_flux = mp.get_fluxes(flux_mon)
plt.plot(np.array(input_flux)/np.max(input_flux))In [ ]:
sim.reset_meep()
def make_unit_cell(D):
pillar_geo = mp.Cylinder(
material = si,
radius = D/2,
height = h,
center = mp.Vector3(0,0,h/2),
)
return pillar_geo
def make_unit_cell_sim(D):
pillar_geo = make_unit_cell(D)
geometries = [substrate_geo, pillar_geo]
sim = mp.Simulation(
resolution = resolution,
cell_size = cell_size,
boundary_layers = pml_layers,
geometry = geometries,
default_material = air,
k_point = k_point,
sources = [source],
)
f = plt.figure(dpi=120)
sim.plot2D(ax=f.gca(),output_plane=yz_plane,show_sources=True,show_monitors=True)
plt.show()
mode_mon = sim.add_flux(
fcen, df, nfreq, mp.FluxRegion(center=monitor_position, size=mp.Vector3(sim_x_size, sim_y_size, 0))
)
sim.run(until_after_sources=300)
freqs = mp.get_eigenmode_freqs(mode_mon)
res = sim.get_eigenmode_coefficients(
mode_mon, [1], eig_parity=mp.EVEN_Y
)
coeffs = res.alpha
mode_wvl = [1/freqs[nf] for nf in range(nfreq)]
mode_tran = [abs(coeffs[0,nf,0])**2 / input_flux[nf] for nf in range(nfreq)]
mode_phase = [np.angle(coeffs[0,nf,0]) for nf in range(nfreq)]
return mode_wvl, mode_tran, mode_phase
diameters = np.linspace(0.1, 0.7, 4)
mode_tran_arr = np.empty((len(diameters), nfreq))
mode_phase_arr = np.empty((len(diameters), nfreq))
for i, D in enumerate(diameters):
mode_wvl, mode_tran, mode_phase = make_unit_cell_sim(D)
mode_tran_arr[i,:] = mode_tran
mode_phase_arr[i,:] = mode_phase
#make a 2d plot of the transmission and phase as a function of wavelength and diameter
plt.figure(dpi=120)
plt.subplot(2,1,1)
plt.imshow(mode_tran_arr, extent=[wvl_min*1e6, wvl_max*1e6, diameters[0], diameters[-1]], aspect='auto', origin='lower', cmap='viridis')
plt.colorbar(label='Transmission')
plt.ylabel('Diameter (um)')
plt.title('Transmission vs Wavelength and Diameter')
plt.subplot(2,1,2)
plt.imshow(mode_phase_arr, extent=[wvl_min*1e6, wvl_max*1e6, diameters[0], diameters[-1]], aspect='auto', origin='lower', cmap='twilight')
plt.colorbar(label='Phase (radians)')
plt.ylabel('Diameter (um)')
plt.xlabel('Wavelength (um)')
plt.title('Phase vs Wavelength and Diameter')
plt.tight_layout()
plt.show()In [ ]:
print(input_flux[0])