Skip to content

feat: add MeepMeshSim for GMSH mesh-based photonic simulations#39

Draft
vvahidd wants to merge 9 commits intomainfrom
meep-mesh-sim
Draft

feat: add MeepMeshSim for GMSH mesh-based photonic simulations#39
vvahidd wants to merge 9 commits intomainfrom
meep-mesh-sim

Conversation

@vvahidd
Copy link
Copy Markdown
Contributor

@vvahidd vvahidd commented Feb 26, 2026

Summary

  • Add MeepMeshSim class — alternative mesh-based workflow for Meep that mirrors Palace's mesh()write_config() pattern
  • Produces GMSH .msh + mesh_config.json that fully describes a photonic problem (materials, source, monitors, domain, solver)
  • Add include_airbox flag to generate_mesh() / add_dielectrics() — defaults to True for Palace (RF), False for Meep (photonics)
  • Add material field to volume groups in mesh config JSON for consistency with layer_volumes
  • New gsim.common.mesh module for solver-agnostic GMSH mesh generation

Test plan

  • uv run pytest tests/meep/test_mesh_sim.py -v — 21 new tests pass
  • uv run pytest tests/common/test_mesh.py -v — common mesh tests pass
  • uv run pytest tests/ — all existing tests still pass
  • Notebook nbs/mesh_ybranch.ipynb produces .msh + mesh_config.json

vvahidd added 5 commits March 19, 2026 10:01
Add an alternative mesh-based workflow for Meep that mirrors Palace's
mesh() → write_config() pattern. Produces a GMSH .msh + mesh_config.json
that fully describes a photonic problem.

- MeepMeshSim class with geometry/source/domain/solver setters
- mesh_config.py writer for JSON problem definition
- include_airbox flag on generate_mesh (default False for photonics)
- gsim.common.mesh module for solver-agnostic GMSH mesh generation
- 21 new tests + notebook demo
Palace mesh modules import shared utilities from gsim.common.mesh
instead of duplicating them. Also includes auto-generated api.md.
After fragmentation, identify waveguide boundary faces at each
gdsfactory port location and assign them as named surface physical
groups (port_<name>). Port metadata (center, width, orientation,
layer, z_range) is serialized into mesh_config.json. Also hardcode
mesh filename to mesh.msh for consistent cloud runner expectations.
…ation

The previous truncation `[:len(tags)]` dropped dielectric volume fragments
when fragmentation split boxes into more pieces than the original count.
Now layer/metal volume tags are collected first and excluded from dielectric
groups, ensuring all fragments are assigned without double-counting.

Also improved plot_mesh to render per-group with colors by default, with
the largest volume (e.g. cladding) as a transparent wireframe so inner
structures like waveguide cores are visible.
Adjacent dielectric boxes of the same material are now merged into a
single GMSH box (e.g. box+clad SiO2 → one volume), eliminating
coincident faces and sliver tets. Different-material boxes sharing a
z-boundary use removeAllDuplicates() to cleanly resolve the shared face.

Also adds a regression test verifying box/clad XY consistency, improves
the mesh summary in notebooks, and removes the plot_mesh_slice feature.
vvahidd added 4 commits March 19, 2026 10:59
Add mesh_scale param to generate_mesh() for post-generation coordinate
scaling. MeepMeshSim passes 1000.0 to convert um→nm. mesh_config.json
now includes length_scale (1e-9) and nanometers_per_cell instead of
resolution in pixels/um.
Port centers, widths, z_ranges, wavelengths, and domain margins are now
written in nm, consistent with length_scale=1e-9 and the mesh coordinates.
- Port normals now computed at mesh generation (generator.py) as 3D unit
  vectors in the global mesh frame; serializer passes them through verbatim.
  When ports gain out-of-plane tilt, only the upstream computation changes.
- port_surfaces JSON trimmed to the minimum-sufficient contract
  (phys_group + normal + layer). Center/width/z_range are recoverable from
  the mesh triangles, so keeping them in JSON duplicated the source of truth.
- domain.pml now serialized as integer pml_cells (pml x resolution) instead
  of a micron value, matching what the solver actually consumes.
- mesh_priority added to volumes/layer_volumes, ranked by refractive index
  (highest n -> priority 1), matching gplugins/femwell/meshwell convention.

Adds a port-surfaces pass-through test covering both axis-aligned and
out-of-plane-tilted normals.
single-clad notebook uses one dielectric box wrapping the core above and
below (one SiO2 physical group); split-clad was re-executed to refresh
outputs against the new mesh_config.json schema.
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.

1 participant