Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@ The format of this changelog is based on
## Upcoming

- Added `xor2d` for polygon XOR
- Improved support for wave port boundaries in a `SolidModel`

+ `SolidModelTargets` now take `wave_port_layers`, a list of layer symbols used to define wave port boundary conditions
+ Added support for `LineSegment` in SolidModel
+ Added `add_wave_ports!` to automatically place wave port boundaries where specified paths/routes intersect the simulation area
+ Added option to use wave ports instead of lumped ports in the single transmon example

## 1.6.0 (2025-10-16)

- Improved metadata handling for `LayoutTarget` and `SolidModelTarget`

+ SolidModelTargets will now ignore `NORENDER_META` (the `:norender` layer)
+ SolidModelTargets now take `ignored_layers`, a list of layer symbols which are not rendered
+ LayoutTargets now allow overriding the mapping of `GDSMeta` by setting `target.map_meta_dict[my_gdsmeta] = my_override`, allowing changes to different `GDSMeta` or `nothing` rather than always mapping a `GDSMeta` to itself
Expand All @@ -29,7 +35,7 @@ The format of this changelog is based on
## 1.5.0 (2025-10-10)

- Added `auto_speed`, `endpoints_curvature`, and `auto_curvature` keyword options to `bspline!` and `BSplineRouting`

+ `auto_speed` sets the speed at endpoints to avoid sharp bends (minimizing the integrated square of the curvature derivative with respect to arclength)
+ `endpoints_curvature` sets boundary conditions on the curvature (by inserting extra waypoints)
+ `auto_curvature` B-spline sets curvature at endpoints to match previous segment (or to zero if there is no previous segment)
Expand Down
85 changes: 57 additions & 28 deletions examples/SingleTransmon/SingleTransmon.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module SingleTransmon
using FileIO, CSV, DataFrames, JSON, JSONSchema
using DeviceLayout, DeviceLayout.SchematicDrivenLayout, DeviceLayout.PreferredUnits
import .SchematicDrivenLayout.ExamplePDK
import .SchematicDrivenLayout.ExamplePDK: LayerVocabulary, L1_TARGET, add_bridges!
import .SchematicDrivenLayout.ExamplePDK: LayerVocabulary, L1_TARGET, add_bridges!, add_wave_ports!
using .ExamplePDK.Transmons, .ExamplePDK.ReadoutResonators
import .ExamplePDK.SimpleJunctions: ExampleSimpleJunction
import DeviceLayout: uconvert
Expand All @@ -24,6 +24,7 @@ using PRIMA
n_meander_turns=5,
hanger_length=500μm,
bend_radius=50μm,
wave_ports::Bool=false,
save_mesh::Bool=false,
save_gds::Bool=false)

Expand All @@ -41,6 +42,7 @@ function single_transmon(;
n_meander_turns=5,
hanger_length=500μm,
bend_radius=50μm,
wave_ports::Bool=false,
save_mesh::Bool=false,
save_gds::Bool=false,
mesh_order=2
Expand Down Expand Up @@ -90,7 +92,7 @@ function single_transmon(;
bridge=BRIDGE_STYLE
)
## Readout path
readout_length = 2700μm
readout_length = wave_ports ? 4mm : 2700μm
p_readout = Path(
Point(0μm, 0μm);
α0=π / 2,
Expand All @@ -101,15 +103,17 @@ function single_transmon(;
straight!(p_readout, readout_length / 2, PATH_STYLE)

# Readout lumped ports - squares on CPW trace, one at each end
csport = CoordinateSystem(uniquename("port"), nm)
render!(
csport,
only_simulated(centered(Rectangle(cpw_width, cpw_width))),
LayerVocabulary.PORT
)
# Attach with port center `cpw_width` from the end (instead of `cpw_width/2`) to avoid corner effects
attach!(p_readout, sref(csport), cpw_width, i=1) # @ start
attach!(p_readout, sref(csport), readout_length / 2 - cpw_width, i=2) # @ end
if !wave_ports
csport = CoordinateSystem(uniquename("port"), nm)
render!(
csport,
only_simulated(centered(Rectangle(cpw_width, cpw_width))),
LayerVocabulary.PORT
)
# Attach with port center `cpw_width` from the end (instead of `cpw_width/2`) to avoid corner effects
attach!(p_readout, sref(csport), cpw_width, i=1) # @ start
attach!(p_readout, sref(csport), readout_length / 2 - cpw_width, i=2) # @ end
end

#### Build schematic graph
g = SchematicGraph("single-transmon")
Expand All @@ -130,7 +134,7 @@ function single_transmon(;

#### Prepare solid model
# Specify the extent of the simulation domain.
substrate_x = 4mm
substrate_x = 4mm # wave port domain boundary needs to touch the readout line
substrate_y = 3.7mm

center_xyz = DeviceLayout.center(floorplan)
Expand All @@ -144,10 +148,17 @@ function single_transmon(;
# Define rectangle that gets extruded to generate substrate volume
render!(floorplan.coordinate_system, chip, LayerVocabulary.CHIP_AREA)

# Add wave ports
wave_ports && add_wave_ports!(floorplan, [p_readout_node], sim_area, 0.6mm, LayerVocabulary.WAVE_PORT)

check!(floorplan)

# Need to pass generated physical group names so they can be retained
tech = ExamplePDK.singlechip_solidmodel_target("port_1", "port_2", "lumped_element")
if wave_ports
tech = ExamplePDK.singlechip_solidmodel_target("wave_port_1", "wave_port_2", "lumped_element")
else
tech = ExamplePDK.singlechip_solidmodel_target("port_1", "port_2", "lumped_element")
end
sm = SolidModel("test", overwrite=true)

# Adjust mesh_scale to increase the resolution of the mesh, < 1 will result in greater
Expand Down Expand Up @@ -178,7 +189,7 @@ function single_transmon(;
end

"""
configfile(sm::SolidModel; palace_build=nothing, solver_order=2, amr=0)
configfile(sm::SolidModel; palace_build=nothing, solver_order=2, amr=0, wave_ports=false)

Given a `SolidModel`, assemble a dictionary defining a configuration file for use within
Palace.
Expand All @@ -190,7 +201,7 @@ Palace.
high-order spaces.
- `amr = 0`: Maximum number of adaptive mesh refinement (AMR) iterations.
"""
function configfile(sm::SolidModel; palace_build=nothing, solver_order=2, amr=0)
function configfile(sm::SolidModel; palace_build=nothing, solver_order=2, amr=0, wave_ports=false)
attributes = SolidModels.attributes(sm)

config = Dict(
Expand Down Expand Up @@ -234,19 +245,37 @@ function configfile(sm::SolidModel; palace_build=nothing, solver_order=2, amr=0)
"Attributes" => [attributes["exterior_boundary"]],
"Order" => 1
),
(wave_ports ?
(
"WavePort" => [
Dict(
"Index" => 1,
"Attributes" => [attributes["wave_port_1"]]
),
Dict(
"Index" => 2,
"Attributes" => [attributes["wave_port_2"]]
),],
)
: ()
)...,
"LumpedPort" => [
Dict(
"Index" => 1,
"Attributes" => [attributes["port_1"]],
"R" => 50,
"Direction" => "+X"
),
Dict(
"Index" => 2,
"Attributes" => [attributes["port_2"]],
"R" => 50,
"Direction" => "+X"
),
(wave_ports ? () :
(
Dict(
"Index" => 1,
"Attributes" => [attributes["port_1"]],
"R" => 50,
"Direction" => "+X"
),
Dict(
"Index" => 2,
"Attributes" => [attributes["port_2"]],
"R" => 50,
"Direction" => "+X"
),
)
)...,
Dict(
"Index" => 3,
"Attributes" => [attributes["lumped_element"]],
Expand All @@ -258,7 +287,7 @@ function configfile(sm::SolidModel; palace_build=nothing, solver_order=2, amr=0)
),
"Solver" => Dict(
"Order" => solver_order,
"Eigenmode" => Dict("N" => 2, "Tol" => 1.0e-6, "Target" => 1, "Save" => 2),
"Eigenmode" => Dict("N" => 2, "Tol" => 1.0e-6, "Target" => 2.5, "Save" => 2),
"Linear" => Dict("Type" => "Default", "Tol" => 1.0e-7, "MaxIts" => 500)
)
)
Expand Down
2 changes: 2 additions & 0 deletions src/DeviceLayout.jl
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ include("polygons.jl")
import .Polygons:
Polygon,
Ellipse,
LineSegment,
Circle,
ClippedPolygon,
RelativeRounded,
Expand All @@ -390,6 +391,7 @@ import .Polygons:
export Polygons,
Polygon,
Ellipse,
LineSegment,
Circle,
ClippedPolygon,
RelativeRounded,
Expand Down
8 changes: 6 additions & 2 deletions src/polygons.jl
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ import IntervalTrees: IntervalTree, IntervalValue
import IntervalSets.(..)
import IntervalSets.endpoints

export Polygon, ClippedPolygon, Ellipse, Circle
export Polygon, ClippedPolygon, Ellipse, Circle, LineSegment
export circle,
circle_polygon,
clip,
Expand Down Expand Up @@ -1517,12 +1517,16 @@ end

### cutting algorithm

abstract type D1{T} end
abstract type D1{T} <: GeometryEntity{T} end
Δy(d1::D1) = d1.p1.y - d1.p0.y
Δx(d1::D1) = d1.p1.x - d1.p0.x

ab(p0, p1) = Point(gety(p1) - gety(p0), getx(p0) - getx(p1))

to_polygons(::D1{T}) where {T} = Polygon{T}[]

transform(d1::T, f::Transformation) where {T <: D1} = T(f(d1.p0), f(d1.p1))

"""
LineSegment{T} <: D1{T}

Expand Down
27 changes: 21 additions & 6 deletions src/schematics/ExamplePDK/ExamplePDK.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ const LAYER_RECORD = (;
simulated_area = GDSMeta(200, 0),
port = GDSMeta(210, 0),
lumped_element = GDSMeta(211, 0),
wave_port = GDSMeta(212, 0),
mesh_control = GDSMeta(220, 0),
integration = GDSMeta(230, 0)
)
Expand Down Expand Up @@ -104,10 +105,14 @@ const EXAMPLE_FLIPCHIP_TECHNOLOGY = ProcessTechnology(
(; # Use unrealistic thicknesses for the sake of clearer visualizations
chip_thicknesses=[100μm, 100μm], # [Bottom chip, top chip] (for calculating z height by level)
flipchip_gaps=[80μm], # Space between chip surfaces (for calculating z height by level)
height=(; simulated_area=-1mm), # z height at the bottom of simulation volume
height=(; # z height at the bottom
simulated_area=-1mm,
wave_port=[-160μm, -160μm]
),
thickness=(; # Extrusion distances for various layers
simulated_area=2mm,
chip_area=[100μm, 100μm], # For levelwise layers, specify thickness for each level
wave_port=[400μm, 400μm],
bump=80μm
)
)
Expand All @@ -121,8 +126,15 @@ single chip assembly.
const EXAMPLE_SINGLECHIP_TECHNOLOGY = ProcessTechnology(
LAYER_RECORD,
(;
height=(; simulated_area=-1mm), # z height at the bottom of simulation volume
thickness=(; simulated_area=2mm, chip_area=525μm) # Extrusion distances for various layers
height=(; # z height at the bottom
simulated_area=-1mm,
wave_port=-200μm
),
thickness=(; # Extrusion distances for various layers
simulated_area=2mm,
chip_area=525μm,
wave_port=400μm
)
)
)

Expand Down Expand Up @@ -153,7 +165,8 @@ const SINGLECHIP_SOLIDMODEL_TARGET = SolidModelTarget(
simulation=true, # Optional simulation-only geometry entities will be rendered
bounding_layers=[:simulated_area], # SIMULATED_AREA defines the simulation bounds
substrate_layers=[:chip_area], # CHIP_AREA will be extruded downward
indexed_layers=[:port, :lumped_element, :integration], # Automatically index these layers
indexed_layers=[:port, :lumped_element, :integration, :wave_port], # Automatically index these layers
wave_port_layers=[:wave_port], # WAVE_PORT are 1D line segments in x-y to be extruded in z
postrender_ops=[ # Manual definition of operations to run after 2D rendering
( # Get metal ground plane by subtracting negative from writeable area
"metal", # Output group name
Expand Down Expand Up @@ -242,9 +255,11 @@ const FLIPCHIP_SOLIDMODEL_TARGET = SolidModelTarget(
:metal_positive,
:chip_area, # and for chip and bridge extrusion in opposite directions by layer
:bridge_base,
:bridge
:bridge,
:wave_port
],
indexed_layers=[:port, :lumped_element, :integration],
indexed_layers=[:port, :lumped_element, :integration, :wave_port],
wave_port_layers=[:wave_port],
postrender_ops=[
( # Get metal ground plane by subtracting negative from writeable area
"metal_L1",
Expand Down
Loading