Download app.py from jwt625/BPM: direct link, hf CLI and curl.
- Browser
- Download file 6.36 kB
-
https://huggingface.co/spaces/jwt625/BPM/resolve/main/app.py
- Command line
-
hf download hf://spaces/jwt625/BPM/app.py
-
curl -L -o app.py https://huggingface.co/spaces/jwt625/BPM/resolve/main/app.py
6.36 kB
| import numpy as np | |
| import matplotlib | |
| matplotlib.use("Agg") | |
| import matplotlib.pyplot as plt | |
| import tempfile | |
| import gradio as gr | |
| from bpm.refractive_index import ( | |
| generate_waveguide_n_r2, | |
| generate_MMI_n_r2 | |
| ) | |
| from bpm.mode_solver import slab_mode_source | |
| from bpm.core import run_bpm | |
| from bpm.pml import generate_sigma_x | |
| def run_waveguide(w, l, L_bend, n_WG, wavelength, ind_m): | |
| # --- Simulation setup (Waveguide S-bend) --- | |
| domain_size = 50.0 | |
| z_total = 500.0 | |
| Nx, Nz = 256, 2000 | |
| x = np.linspace(-domain_size/2, domain_size/2, Nx) | |
| z = np.linspace(0, z_total, Nz) | |
| n0 = 1.0 | |
| # Refractive index map | |
| n_r2 = generate_waveguide_n_r2(x, z, l, L_bend, w, n_WG, n0) | |
| # Launch slab mode | |
| E0 = slab_mode_source(x, w, n_WG, n0, wavelength, ind_m, x0=0) | |
| E = np.zeros((Nx, Nz), dtype=np.complex128) | |
| E[:, 0] = E0 | |
| # PML + BPM | |
| dx = domain_size / Nx | |
| dz = z[1] - z[0] | |
| sigma_x = generate_sigma_x(x, dx, wavelength, domain_size) | |
| E_out = run_bpm(E, n_r2, x, z, dx, dz, n0, sigma_x, wavelength) | |
| # Plot | |
| fig, ax = plt.subplots(figsize=(8,6)) | |
| im = ax.imshow( | |
| np.abs(E_out)**2, | |
| extent=[x[0], x[-1], z[0], z[-1]], | |
| origin='lower', | |
| aspect='auto', | |
| cmap='inferno' | |
| ) | |
| ax.set_title("Waveguide S-bend BPM Propagation") | |
| ax.set_xlabel("x (µm)") | |
| ax.set_ylabel("z (µm)") | |
| fig.colorbar(im, ax=ax, label="Intensity") | |
| # Save data for download | |
| tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".npz") | |
| np.savez(tmp.name, E_out=E_out, x=x, z=z) | |
| tmp.close() | |
| return fig, tmp.name | |
| def run_mmi(z_start, L_MMI, w_MMI, w_wg, d, n_WG, wavelength, ind_m): | |
| # --- Simulation setup (MMI Splitter) --- | |
| domain_size = 50.0 | |
| z_total = 250.0 | |
| Nx, Nz = 256, 1024 | |
| x = np.linspace(-domain_size/2, domain_size/2, Nx) | |
| z = np.linspace(0, z_total, Nz) | |
| n0 = 1.0 | |
| # For simplicity, use the same core and MMI index | |
| n_MMI = n_WG | |
| # Refractive index map | |
| n_r2 = generate_MMI_n_r2( | |
| x, z, | |
| z_MMI_start = z_start, | |
| L_MMI = L_MMI, | |
| w_MMI = w_MMI, | |
| w_wg = w_wg, | |
| d = d, | |
| n_WG = n_WG, | |
| n_MMI = n_MMI, | |
| n0 = n0 | |
| ) | |
| # Launch slab mode in left waveguide | |
| E0 = slab_mode_source(x, w_wg, n_WG, n0, wavelength, ind_m, x0=-d/2) | |
| E = np.zeros((Nx, Nz), dtype=np.complex128) | |
| E[:,0] = E0 | |
| # PML + BPM | |
| dx = domain_size / Nx | |
| dz = z[1] - z[0] | |
| sigma_x = generate_sigma_x(x, dx, wavelength, domain_size) | |
| E_out = run_bpm(E, n_r2, x, z, dx, dz, n0, sigma_x, wavelength) | |
| # Plot | |
| fig, ax = plt.subplots(figsize=(8,6)) | |
| im = ax.imshow( | |
| np.abs(E_out)**2, | |
| extent=[x[0], x[-1], z[0], z[-1]], | |
| origin='lower', | |
| aspect='auto', | |
| cmap='inferno' | |
| ) | |
| ax.set_title("MMI Splitter BPM Propagation") | |
| ax.set_xlabel("x (µm)") | |
| ax.set_ylabel("z (µm)") | |
| fig.colorbar(im, ax=ax, label="Intensity") | |
| # Save data | |
| tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".npz") | |
| np.savez(tmp.name, E_out=E_out, x=x, z=z) | |
| tmp.close() | |
| return fig, tmp.name | |
| def run_dispatcher( | |
| sim_type, | |
| # waveguide args | |
| w, l, L_bend, | |
| # mmi args | |
| z_start, L_MMI, w_MMI, w_wg, d, | |
| # common args | |
| n_WG, wavelength, ind_m | |
| ): | |
| if sim_type == "Waveguide S-bend": | |
| return run_waveguide(w, l, L_bend, n_WG, wavelength, ind_m) | |
| else: | |
| return run_mmi(z_start, L_MMI, w_MMI, w_wg, d, n_WG, wavelength, ind_m) | |
| with gr.Blocks() as demo: | |
| gr.Markdown("## BPM Simulation Dashboard") | |
| # 1) Simulation selector | |
| sim_type = gr.Radio( | |
| choices=["Waveguide S-bend", "MMI Splitter"], | |
| value="Waveguide S-bend", | |
| label="Simulation Type" | |
| ) | |
| with gr.Row(): | |
| # 2) Waveguide parameters panel | |
| with gr.Column(visible=True) as waveguide_panel: | |
| w_slider = gr.Slider(0.1, 5.0, value=1.0, step=0.1, label="Waveguide width w (µm)") | |
| l_slider = gr.Slider(0.0, 10.0, value=5.0, step=0.1, label="Lateral offset l (µm)") | |
| Lb_slider = gr.Slider(50.0, 500.0,value=200.0,step=10.0,label="S-bend length L (µm)") | |
| # 3) MMI parameters panel | |
| with gr.Column(visible=False) as mmi_panel: | |
| z0_slider = gr.Slider(0.0, 200.0, value=50.0, step=1.0, label="MMI start z₀ (µm)") | |
| Lmmi_slider = gr.Slider(10.0, 300.0,value=130.0,step=5.0, label="MMI length L (µm)") | |
| wmmi_slider = gr.Slider(2.0, 20.0, value=8.0, step=0.5, label="MMI width w_MMI (µm)") | |
| wwg_slider = gr.Slider(0.5, 5.0, value=2.0, step=0.1, label="I/O waveguide width w_wg (µm)") | |
| d_slider = gr.Slider(1.0, 20.0, value=4.0, step=0.5, label="Waveguide separation d (µm)") | |
| # 4) Common parameters | |
| with gr.Column(scale=1): | |
| n_WG_slider = gr.Slider(1.0, 2.0, value=1.1, step=0.01, label="Core refractive index n_WG") | |
| wavelength_slider= gr.Slider(0.4, 1.6, value=0.532,step=0.01, label="Wavelength λ (µm)") | |
| ind_m_slider = gr.Slider(0, 4, value=0, step=1, label="Mode index ind_m") | |
| run_button = gr.Button("Run BPM") | |
| download_button = gr.DownloadButton(label="Download data") | |
| # 5) Plot output | |
| with gr.Column(scale=2): | |
| plot_output = gr.Plot() | |
| # 6) Toggle panels on sim_type change | |
| sim_type.change( | |
| fn=lambda choice: ( | |
| gr.update(visible=(choice=="Waveguide S-bend")), | |
| gr.update(visible=(choice=="MMI Splitter")) | |
| ), | |
| inputs=sim_type, | |
| outputs=[waveguide_panel, mmi_panel] | |
| ) | |
| # 7) Wire up Run button + auto-update | |
| all_inputs = [ | |
| sim_type, | |
| w_slider, l_slider, Lb_slider, | |
| z0_slider, Lmmi_slider, wmmi_slider, wwg_slider, d_slider, | |
| n_WG_slider, wavelength_slider, ind_m_slider | |
| ] | |
| run_button.click( | |
| fn=run_dispatcher, | |
| inputs=all_inputs, | |
| outputs=[plot_output, download_button] | |
| ) | |
| for inp in all_inputs: | |
| inp.change( | |
| fn=run_dispatcher, | |
| inputs=all_inputs, | |
| outputs=[plot_output, download_button] | |
| ) | |
| demo.launch() | |