Skip to content

Palace Width Sweep: Parallel Simulation

Sweep the microstrip width from 5 to 50 um (5 points), run all simulations in parallel on GDSFactory+ cloud using the non-blocking API, then compare S11 and S21 across widths.

Requirements:

  • IHP PDK: uv pip install ihp-gdsfactory
  • GDSFactory+ account for cloud simulation

Define the sweep

import gdsfactoryplus as gfp

pdk = gfp.get_pdk()
pdk.activate()
import numpy as np

widths = np.arange(2, 21, 4)

Build components and configure simulations

import gdsfactory as gf
from ihp import LAYER, PDK, cells

from gsim.common.stack import get_stack
from gsim.palace import DrivenSim

PDK.activate()

stack = get_stack(air_above=300.0)  # auto-detects active PDK

sims = []

for w in widths:
    # Build component
    c = gf.Component()
    r1 = c << cells.straight_metal(length=1000, width=w)

    r = c.get_region(layer=LAYER.TopMetal2drawing)
    r_sized = r.sized(+20000)
    c.add_polygon(r_sized, layer=LAYER.Metal1drawing)
    c.add_ports(r1.ports)

    # Configure simulation
    sim = DrivenSim()
    sim.set_output_dir(f"./palace-sim-w{w:.1f}")
    sim.set_geometry(c)
    sim.set_stack(stack)

    for port in c.ports:
        sim.add_port(
            port.name, from_layer="metal1", to_layer="topmetal2", geometry="via"
        )

    sim.set_driven(fmin=1e9, fmax=100e9, num_points=80)
    sim.mesh(preset="default")

    sims.append(sim)

print(f"Configured {len(sims)} simulations")
21:34:40 | WARNING  | Small conductor feature detected (2.000 um) may be under-resolved by refined_mesh_size=5.000 um. The heuristic target is <= 1.000 um (2 cells/feature). Pass auto_size=True to scale the mesh down.


/tmp/ipykernel_4798/3909240475.py:9: UserWarning: get_stack(air_above/air_below) is deprecated and ignored. Use simulation.set_airbox(margin_x=..., margin_y=..., z_above=..., z_below=...).
  stack = get_stack(air_above=300.0)  # auto-detects active PDK


21:34:42 | WARNING  | Absorbing boundary is applied to solid dielectric surfaces (sin, sio2) because the model has no air region, which produces large spurious insertion loss and reflection. Add an airbox via set_airbox(margin_x=..., margin_y=..., z_above=..., z_below=...). Note that get_stack(air_above=...) is deprecated and ignored.


21:34:42 | WARNING  | Small conductor feature detected (6.000 um) may be under-resolved by refined_mesh_size=5.000 um. The heuristic target is <= 3.000 um (2 cells/feature). Pass auto_size=True to scale the mesh down.


21:34:45 | WARNING  | Absorbing boundary is applied to solid dielectric surfaces (sin, sio2) because the model has no air region, which produces large spurious insertion loss and reflection. Add an airbox via set_airbox(margin_x=..., margin_y=..., z_above=..., z_below=...). Note that get_stack(air_above=...) is deprecated and ignored.


21:34:47 | WARNING  | Absorbing boundary is applied to solid dielectric surfaces (sin, sio2) because the model has no air region, which produces large spurious insertion loss and reflection. Add an airbox via set_airbox(margin_x=..., margin_y=..., z_above=..., z_below=...). Note that get_stack(air_above=...) is deprecated and ignored.


21:34:49 | WARNING  | Absorbing boundary is applied to solid dielectric surfaces (sin, sio2) because the model has no air region, which produces large spurious insertion loss and reflection. Add an airbox via set_airbox(margin_x=..., margin_y=..., z_above=..., z_below=...). Note that get_stack(air_above=...) is deprecated and ignored.


21:34:52 | WARNING  | Absorbing boundary is applied to solid dielectric surfaces (sin, sio2) because the model has no air region, which produces large spurious insertion loss and reflection. Add an airbox via set_airbox(margin_x=..., margin_y=..., z_above=..., z_below=...). Note that get_stack(air_above=...) is deprecated and ignored.


Configured 5 simulations

Upload and start all jobs (non-blocking)

# Upload and start all jobs without waiting
job_ids = []
for sim in sims:
    job_id = sim.run(wait=False, check_cache=True)
    job_ids.append(job_id)

print(f"Started {len(job_ids)} jobs: {job_ids}")
Info    : Reading 'palace-sim-w2.0/palace.msh'...
Info    : 5322 nodes
Info    : 35421 elements
Info    : Done reading 'palace-sim-w2.0/palace.msh'
Info    : Reading 'palace-sim-w2.0/palace.msh'...
Info    : 5322 nodes
Info    : 35421 elements
Info    : Done reading 'palace-sim-w2.0/palace.msh'
Info    : Reading 'palace-sim-w2.0/palace.msh'...
Info    : 5322 nodes
Info    : 35421 elements
Info    : Done reading 'palace-sim-w2.0/palace.msh'


Cache hit: reusing job 01a183ea-c913-7143-822f-657cc042664f
Info    : Reading 'palace-sim-w6.0/palace.msh'...
Info    : 5722 nodes
Info    : 38443 elements
Info    : Done reading 'palace-sim-w6.0/palace.msh'
Info    : Reading 'palace-sim-w6.0/palace.msh'...
Info    : 5722 nodes
Info    : 38443 elements
Info    : Done reading 'palace-sim-w6.0/palace.msh'
Info    : Reading 'palace-sim-w6.0/palace.msh'...
Info    : 5722 nodes
Info    : 38443 elements
Info    : Done reading 'palace-sim-w6.0/palace.msh'


Cache hit: reusing job 01a183ea-d00a-77ae-b83e-57020028038c
Info    : Reading 'palace-sim-w10.0/palace.msh'...
Info    : 5796 nodes
Info    : 39011 elements
Info    : Done reading 'palace-sim-w10.0/palace.msh'
Info    : Reading 'palace-sim-w10.0/palace.msh'...
Info    : 5796 nodes
Info    : 39011 elements
Info    : Done reading 'palace-sim-w10.0/palace.msh'
Info    : Reading 'palace-sim-w10.0/palace.msh'...
Info    : 5796 nodes
Info    : 39011 elements
Info    : Done reading 'palace-sim-w10.0/palace.msh'


Cache hit: reusing job 01a183ea-d74c-757b-9141-41e1daa4c737
Info    : Reading 'palace-sim-w14.0/palace.msh'...
Info    : 5784 nodes
Info    : 38804 elements
Info    : Done reading 'palace-sim-w14.0/palace.msh'
Info    : Reading 'palace-sim-w14.0/palace.msh'...
Info    : 5784 nodes
Info    : 38804 elements
Info    : Done reading 'palace-sim-w14.0/palace.msh'
Info    : Reading 'palace-sim-w14.0/palace.msh'...
Info    : 5784 nodes
Info    : 38804 elements
Info    : Done reading 'palace-sim-w14.0/palace.msh'


Cache hit: reusing job 01a183ea-dec5-7497-a9ba-40d216bd375b
Info    : Reading 'palace-sim-w18.0/palace.msh'...
Info    : 6115 nodes
Info    : 41268 elements
Info    : Done reading 'palace-sim-w18.0/palace.msh'
Info    : Reading 'palace-sim-w18.0/palace.msh'...
Info    : 6115 nodes
Info    : 41268 elements
Info    : Done reading 'palace-sim-w18.0/palace.msh'
Info    : Reading 'palace-sim-w18.0/palace.msh'...
Info    : 6115 nodes
Info    : 41268 elements
Info    : Done reading 'palace-sim-w18.0/palace.msh'


Cache hit: reusing job 01a183ea-e673-7291-a72e-0b493273dbdf
Started 5 jobs: ['01a183ea-c913-7143-822f-657cc042664f', '01a183ea-d00a-77ae-b83e-57020028038c', '01a183ea-d74c-757b-9141-41e1daa4c737', '01a183ea-dec5-7497-a9ba-40d216bd375b', '01a183ea-e673-7291-a72e-0b493273dbdf']

Wait for all jobs to complete

import gsim

# Poll all jobs concurrently, download and parse results
results = gsim.wait_for_results(job_ids)
Waiting for 5 jobs...
  palace-23923594                [####################] 100% complete     elapsed 0m 00s
  palace-9cc55cd3                [####################] 100% complete     elapsed 0m 00s
  palace-be233336                [####################] 100% complete     elapsed 0m 00s
  palace-1be742a3                [####################] 100% complete     elapsed 0m 00s
  palace-9f1c9ab5                [####################] 100% complete     elapsed 0m 00s


Extracting results.tar.gz...
Downloaded 12 files to /home/runner/work/simulation-templates/simulation-templates/docs/notebooks/sim-data-palace-23923594


Extracting results.tar.gz...
Downloaded 12 files to /home/runner/work/simulation-templates/simulation-templates/docs/notebooks/sim-data-palace-9cc55cd3


Extracting results.tar.gz...
Downloaded 12 files to /home/runner/work/simulation-templates/simulation-templates/docs/notebooks/sim-data-palace-be233336


Extracting results.tar.gz...
Downloaded 12 files to /home/runner/work/simulation-templates/simulation-templates/docs/notebooks/sim-data-palace-1be742a3


Extracting results.tar.gz...
Downloaded 12 files to /home/runner/work/simulation-templates/simulation-templates/docs/notebooks/sim-data-palace-9f1c9ab5

Plot S11 and S21 comparison

import matplotlib.pyplot as plt

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(6, 6))

for w, sp in zip(widths, results, strict=True):
    ax1.plot(sp.freq, sp.s11.db, label=f"w={w:.1f} um")
    ax2.plot(sp.freq, sp.s21.db, label=f"w={w:.1f} um")

ax1.set(
    xlabel="Frequency (GHz)", ylabel="|S11| (dB)", title="S11 — Return Loss vs Width"
)
ax1.legend()
ax1.grid(True)

ax2.set(
    xlabel="Frequency (GHz)", ylabel="|S21| (dB)", title="S21 — Insertion Loss vs Width"
)
ax2.legend()
ax2.grid(True)

plt.tight_layout()

png