Skip to content

Add qBIC metasurface sensor notebook - #527

Open
jungmin-flex wants to merge 5 commits into
pre/2.12from
jungmin/qBICsensor
Open

Add qBIC metasurface sensor notebook#527
jungmin-flex wants to merge 5 commits into
pre/2.12from
jungmin/qBICsensor

Conversation

@jungmin-flex

@jungmin-flex jungmin-flex commented Jun 23, 2026

Copy link
Copy Markdown

Summary

  • Adds a qBIC metasurface sensor notebook based on the pre/2.12 branch.
  • Reproduces the main sensing workflow, including geometry construction, symmetry-breaking parameter sweeps, absorption spectra, refractive-index sensing analysis, and near-field visualization.
  • Includes convergence checks and documentation of the plane-wave normalization used for field plots.

Scope

This PR adds a self-contained example notebook only.

Notes for review

  • The notebook is intended as an educational/reproducible workflow for a qBIC metasurface sensor.
  • Simulation assumptions, parameter definitions, and analysis steps are described in the notebook markdown cells.
  • Large intermediate simulation outputs are not included.

Note

Low Risk
Documentation and example-only changes with no production code, auth, or data-path impact.

Overview
Adds a self-contained example notebook for a qBIC metasurface sensor (ported from pre/2.12), covering geometry setup, symmetry-breaking parameter sweeps, absorption spectra, refractive-index sensing, and near-field plots, plus convergence checks and notes on plane-wave normalization for fields.

The notebook is wired into the periodic metamaterials/gratings case-study docs via the existing MetasurfaceBIC toctree entry—no application or library API changes.

Reviewed by Cursor Bugbot for commit 6a0190c. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Spell Check Report

QMRSMetasurface.ipynb:

Cell 1, Line 1: 'Ultrasensitive', 'biosensing', 'quasi-BIC'
  > # Ultrasensitive biosensing with 3D quasi-BIC metasurfaces
Cell 5, Line 6: 'supercell'
  > P2 = P * np.sqrt(2)  # doubled supercell period (µm)
Cell 5, Line 17: 'nanometre'
  > nm = 1e-3  # nanometre in Tidy3D units (µm)
Cell 5, Line 28: 'particle-A'
  > D_A = 300 * nm  # particle-A diameter
Cell 5, Line 29: 'particle-B'
  > D_B = D_A  # particle-B diameter (symmetric base case)
Cell 5, Line 30: 'particle-A'
  > Z_A = 200 * nm  # particle-A hole depth
Cell 5, Line 32: 'particle-B'
  > Z_B = Z_A - del_Z  # particle-B hole depth
Cell 7, Line 11: 'Primitive-cell', 'auto-grid', 'nanohole', 'refractive-index'
  > """Primitive-cell FDTD simulation.
Cell 7, Line 38: 'au-A'
  > name="au-A",
Cell 7, Line 48: 'au-B'
  > name="au-B",
Cell 7, Line 72: 'au-sub'
  > name="au-sub",
Cell 7, Line 118: '-sub'
  > name="TiO2-sub",
Cell 10, Line 3: 'grid-convergence'
  > This implementation uses Tidy3D's automatic nonuniform grid. We therefore first perform a grid-convergence study to verify that the simulated spectral response is insensitive to further mesh refinement.
Cell 12, Line 1: '-steps-per-wavelength', 'automatic-grid'
  > Reflectance and transmittance fluxes are used to compute the absorptance, $A = 1 - R - T$. The absorption spectra are compared across six automatic-grid resolutions spanning 15–40 steps per wavelength. Based on this comparison, the 30-steps-per-wavelength grid is selected and used throughout the remainder of this notebook.
Cell 20, Line 1: 'refractive-index'
  > ## Bulk refractive-index perturbation
Cell 22, Line 5: 'analyte', 'non-local', 'refractive-index', 'refractometric', 'resonance-frequency'
  > The local qBIC_L branch has relatively strong field overlap with the superstrate and therefore responds predominantly through a resonance-frequency shift, as in conventional refractometric sensing. The non-local qBIC_U branch has weaker direct analyte overlap and undergoes comparatively little frequency shift, but its radiative loss rate changes strongly. This conversion of a real refractive-index perturbation into an intensity response is the defining QMRS mechanism.
Cell 24, Line 1: 'supercell', 'two-cell'
  > #### Near-field response in a rotated two-cell supercell
Cell 24, Line 5: 'two-cell'
  > `make_sim2` starts from `make_sim(**kwargs)` and constructs the rotated two-cell geometry with `updated_copy`. The domain, structures, monitors, and grid snapping points are replaced; the boundary conditions, source, background medium, termination specification, and shutoff threshold are inherited.
Cell 24, Line 7: 'bulk-index'
  > > **Dependency:** Run the bulk-index sweep first to obtain the resonance frequencies `f_L0`, `f_L1`, and `f_U`.
Cell 25, Line 2: 'array-like', 'primitive-cell', 'supercell'
  > """2×2 supercell FDTD simulation for near-field visualization.
Cell 25, Line 73: 'au-sub'
  > name="au-sub",
Cell 25, Line 112: '-sub'
  > name="tio2-sub",
Cell 28, Line 1: 'absorption-peak', 'off-resonant'
  > Each qBIC branch is sampled at its own absorption-peak frequency for each refractive index. This avoids comparing one state on resonance with the other state at an off-resonant frequency.

Checked 1 notebook(s). Found spelling errors in 1 file(s).
Generated by GitHub Action run: https://github.com/flexcompute/tidy3d-notebooks/actions/runs/28215752128

@FilipeFcp

Copy link
Copy Markdown
Contributor

Thanks @jungmin-flex, this looks like a very nice addition.

I wonder if the simulation domain could be a bit smaller in z. Maybe just one wavelength above and bellow the structure.

I couldn’t open the paper, so I couldn’t check the comparison directly. Does the notebook show good agreement with the reference results?

I noticed that the notebook does not have metadata yet and is not listed in any .rst file. Are you familiar with this process? I can help with some instructions and/or share a skill that handles this. It would also be nice to add a representative schematic image to the notebook.

Finally, I’m not fully sure what our current convention is for ### headers, but I think they should use title case. Maybe @tomflexcompute can confirm.

@tomflexcompute tomflexcompute left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jungmin-flex thank you for the great addition.

A few additional steps we need to take:

  1. Add metadata to the notebook. You can follow the instructions here https://www.notion.so/flexcompute/How-to-add-metadata-to-a-case-study-or-tutorial-notebook-696f9dd642f14964af4eb1242226451e

  2. Add the notebook to the rst file. In this case I believe docs/case_studies/metamaterials_gratings_periodic.rst.

  3. Create a 3D schematic thumbnail image. You can reference other thumbnail images in our example library. Typically we use Blender to create it but these days AI can make a decent image too. Feel free to try.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit cdb1fec. Configure here.

Comment thread QMRSMetasurface.ipynb
}
],
"source": [
"sim_base = make_sim()\n",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Geometry params not passed

Medium Severity

Base and convergence simulations call make_sim() without forwarding the D_A, D_B, Z_A, and Z_B values defined in the setup cell. Editing those globals changes the documented geometry but not the built Simulation, so plots and grid studies can silently use stale defaults.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit cdb1fec. Configure here.

@jungmin-flex

Copy link
Copy Markdown
Author

Regarding @FilipeFcp ’s first comment, I tested reducing the simulation size in the z direction to approximately one wavelength. However, the long evanescent tails near resonance caused inaccuracies, particularly on the −z side. The current domain size (3λ in the −z direction and 1λ in the +z direction) appears to be close to the minimum needed to keep the reflectance, transmittance, and absorptance spectra physically reasonable between 0 and 1.

I also added the metadata and schematics, and updated the .rst file accordingly.

@tomflexcompute tomflexcompute left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @jungmin-flex . Looks great. The schematic usually uses a transparent or white background. Could you change that?

@jungmin-flex

Copy link
Copy Markdown
Author

Thank you @jungmin-flex . Looks great. The schematic usually uses a transparent or white background. Could you change that?

Sure, just updated the schematic image: (1) lowered the transparency of the top layer a bit to better show the depth difference between A and B sites, (2) camera angle, (3) and transparent background as well.

@tomflexcompute tomflexcompute left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! Thanks @jungmin-flex . The last piece of the puzzle is linting. You can see now the merge is blocked since we have a linting check. You can install ruff and run ruff format on the notebook. Then should be good to go. @FilipeFcp feel free to take a final look.

@tomflexcompute

Copy link
Copy Markdown
Contributor

It looks like ruff format still failed. Maybe it's due to a different version. @FilipeFcp what's the current ruff version that we use?

@jungmin-flex

Copy link
Copy Markdown
Author

It looks like ruff format still failed. Maybe it's due to a different version. @FilipeFcp what's the current ruff version that we use?

Yes possibly I installed a wrong version with conda, so I reinstalled it using pip and it seems working

@tomflexcompute

Copy link
Copy Markdown
Contributor

Yes that's great. Feel free to squash all commits -> rebase -> merge later today after Filipe takes a final look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants