Summary
QGmshRenderer is the canonical geometry→Gmsh engine in qiskit-metal, yet the two major community Palace wrappers — pyPalace and SQDMetal — both re-implement the entire geometry→Gmsh→physical-groups pipeline from scratch, reading the QGeometry tables directly and emitting incompatible physical-group naming conventions. The result is heavy duplication and ecosystem divergence.
This issue proposes a consolidation path that merges the best features of pyPalace and SQDMetal into a shared layer inside qiskit-metal, with PalaceToolkit as decoupled infrastructure, and adds curved (second-order) tetrahedral meshing as a new capability.
Proposal
Adopt a two-layer architecture:
qiskit-metal (geometry + layer stack)
│ QGeometry tables / QGmshRenderer primitives
▼
PalaceToolkit (topology + mesh + config + run)
├── Entity-based boolean pipeline (priority cuts + fragment)
├── pg_map naming contract (name → physical-group tag)
├── curved / high-order mesh generation
├── Palace config generator (single-pass, from pg_map + entity metadata)
└── auto-installable Palace binary (CI-friendly)
│
▼
Palace solver (.msh + .json)
1. PalaceToolkit as base infrastructure
- Auto-installable Palace binary — already shipped by PalaceToolkit (
palace_runtime.py), runnable in CI without manual Spack/build steps.
- Clean geometry-vs-topology split — the caller builds
Entity dimtags (geometry); run_meshing_pipeline owns the boolean pipeline, auto interface naming (A__B / A__None), and returns a pg_map.
- Single-direction config generation —
generate_palace_config_from_entities consumes pg_map + entity boundary_type metadata in one pass; no JSON rewriting.
- Validation and debugging tools --
verify_topology checks that the generated mesh will be accepted by Palace and produces graphical output that helps with geometry debugging duplicated/orphan tris.
2. Port SQDMetal's rich port vocabulary as Entity factories
SQDMetal has the most complete port/BC vocabulary in the ecosystem. Port these as PalaceToolkit Entity factories that emit properly-named 2D entities with boundary_type="lumped_port"/"waveport" and Direction/R/Mode metadata:
create_port_CPW_on_Launcher → Entity(boundary_type="lumped_port", ...)
create_port_CPW_on_Route
create_port_2_conds
create_port_JosephsonJunction (lumped L)
create_waveport_on_boundary
create_CPW_feed_Uclip_on_Launcher/Route (metallic U-clip + optional port)
Because PalaceToolkit's config generator already consumes entity metadata, ports flow end-to-end into the Palace JSON with no rewrite hazards (unlike SQDMetal's current set_port_impedance JSON-rewrite path).
3. Port pyPalace's curve/boundary processing and extend to curved meshes
- Boundary simplification — port pyPalace's
BoundarySimplifySettings + _decompose_ring_to_chains (merges runs of short QM polygon edges into Gmsh splines/lines before imprinting) as an optional pre-mesh step.
- Curved / high-order meshing (headline feature) — add
element_order (1 or 2) and curved flags to generate_3d_mesh / refine_near_surfaces. When element_order=2:
- set
Mesh.ElementOrder=2, Mesh.SecondOrderIncomplete=0, Mesh.HighOrderOptimize=1
- Gmsh curves tet faces to the OCC geometry → eliminates flat-facet approximation
- validate with
verify_topology and a Palace round-trip smoke test
- This is already proven in GSIM and works wonderfully; porting it here makes it available to the whole QM→Palace community.
4. EPR / kinetic inductance / farfield helpers (declarative)
Add Postprocessing builders (mirroring pyPalace's builder.Boundaries.Postprocessing_*) that append to the config dict. Covers:
- EPR dielectric interfaces (substrate-air, substrate-metal, metal-air)
- Kinetic inductance (
Boundaries.Impedance with Ls)
- Farfield (
Postprocessing.FarField)
5. Mesh↔config consistency validator
Add validate_config(pg_map, config) that asserts every physical group is referenced by exactly one boundary/material entry and vice versa — closing pyPalace's safety gap and preventing silent missing-BC bugs.
Phased rollout
- Add PalaceToolkit as optional dependency and test Palace runs on CI
- Merge SQDMetal port vocabulary as
Entity factories
- Merge pyPalace curve pre-processing and extend into curved meshes
- Merge pyPalace's
builder.Boundaries.Postprocessing
- Update SQDMetal and pyPalace to depend on the new upstream functionality so both can continue building simulation examples and other tools and avoid further divergence.
Summary
QGmshRendereris the canonical geometry→Gmsh engine in qiskit-metal, yet the two major community Palace wrappers — pyPalace and SQDMetal — both re-implement the entire geometry→Gmsh→physical-groups pipeline from scratch, reading the QGeometry tables directly and emitting incompatible physical-group naming conventions. The result is heavy duplication and ecosystem divergence.This issue proposes a consolidation path that merges the best features of pyPalace and SQDMetal into a shared layer inside qiskit-metal, with PalaceToolkit as decoupled infrastructure, and adds curved (second-order) tetrahedral meshing as a new capability.
Proposal
Adopt a two-layer architecture:
1. PalaceToolkit as base infrastructure
palace_runtime.py), runnable in CI without manual Spack/build steps.Entitydimtags (geometry);run_meshing_pipelineowns the boolean pipeline, auto interface naming (A__B/A__None), and returns apg_map.generate_palace_config_from_entitiesconsumespg_map+ entityboundary_typemetadata in one pass; no JSON rewriting.verify_topologychecks that the generated mesh will be accepted by Palace and produces graphical output that helps with geometry debugging duplicated/orphan tris.2. Port SQDMetal's rich port vocabulary as
EntityfactoriesSQDMetal has the most complete port/BC vocabulary in the ecosystem. Port these as PalaceToolkit
Entityfactories that emit properly-named 2D entities withboundary_type="lumped_port"/"waveport"andDirection/R/Modemetadata:create_port_CPW_on_Launcher→Entity(boundary_type="lumped_port", ...)create_port_CPW_on_Routecreate_port_2_condscreate_port_JosephsonJunction(lumped L)create_waveport_on_boundarycreate_CPW_feed_Uclip_on_Launcher/Route(metallic U-clip + optional port)Because PalaceToolkit's config generator already consumes entity metadata, ports flow end-to-end into the Palace JSON with no rewrite hazards (unlike SQDMetal's current
set_port_impedanceJSON-rewrite path).3. Port pyPalace's curve/boundary processing and extend to curved meshes
BoundarySimplifySettings+_decompose_ring_to_chains(merges runs of short QM polygon edges into Gmsh splines/lines before imprinting) as an optional pre-mesh step.element_order(1 or 2) andcurvedflags togenerate_3d_mesh/refine_near_surfaces. Whenelement_order=2:Mesh.ElementOrder=2,Mesh.SecondOrderIncomplete=0,Mesh.HighOrderOptimize=1verify_topologyand a Palace round-trip smoke test4. EPR / kinetic inductance / farfield helpers (declarative)
Add
Postprocessingbuilders (mirroring pyPalace'sbuilder.Boundaries.Postprocessing_*) that append to the config dict. Covers:Boundaries.ImpedancewithLs)Postprocessing.FarField)5. Mesh↔config consistency validator
Add
validate_config(pg_map, config)that asserts every physical group is referenced by exactly one boundary/material entry and vice versa — closing pyPalace's safety gap and preventing silent missing-BC bugs.Phased rollout
Entityfactoriesbuilder.Boundaries.Postprocessing