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 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.palace import DrivenSim

PDK.activate()

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(substrate_thickness=2.0, air_above=300.0)

    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")
Warning : 6 ill-shaped tets are still in the mesh
Warning : 1 ill-shaped tets are still in the mesh
Warning : ------------------------------
Warning : Mesh generation error summary
Warning :     2 warnings
Warning :     0 errors
Warning : Check the full log for details
Warning : ------------------------------


Warning : 5 ill-shaped tets are still in the mesh
Warning : ------------------------------
Warning : Mesh generation error summary
Warning :     1 warning
Warning :     0 errors
Warning : Check the full log for details
Warning : ------------------------------


Warning : 8 ill-shaped tets are still in the mesh


Warning : ------------------------------
Warning : Mesh generation error summary
Warning :     1 warning
Warning :     0 errors
Warning : Check the full log for details
Warning : ------------------------------


Warning : 7 ill-shaped tets are still in the mesh
Warning : ------------------------------
Warning : Mesh generation error summary
Warning :     1 warning
Warning :     0 errors
Warning : Check the full log for details
Warning : ------------------------------


Warning : 13 ill-shaped tets are still in the mesh


Configured 5 simulations


Warning : ------------------------------
Warning : Mesh generation error summary
Warning :     1 warning
Warning :     0 errors
Warning : Check the full log for details
Warning : ------------------------------

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)
    job_ids.append(job_id)

print(f"Started {len(job_ids)} jobs: {job_ids}")
Job started: palace-3461b17a


Job started: palace-7f77a495


Job started: palace-26df0ea6


Job started: palace-d6cfbe23


Job started: palace-52fd63e4
Started 5 jobs: ['019cbe1a-88ed-78c0-90eb-4d07e85dfc6d', '019cbe1a-8e65-7d82-95fe-031d291e9da0', '019cbe1a-93fa-7522-8d09-bea0b677c8ff', '019cbe1a-9b19-72c2-8a64-88441cd25dee', '019cbe1a-a0c3-7711-96b2-80ce7db2051e']

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-3461b17a                completed    2m 50s
  palace-7f77a495                completed    2m 56s
  palace-26df0ea6                completed    5m 16s
  palace-d6cfbe23                completed    5m 39s
  palace-52fd63e4                completed    6m 53s


Extracting results.tar.gz...
Downloaded 6 files to /home/runner/work/gsim/gsim/nbs/sim-data-palace-3461b17a


Extracting results.tar.gz...
Downloaded 6 files to /home/runner/work/gsim/gsim/nbs/sim-data-palace-7f77a495


Extracting results.tar.gz...
Downloaded 6 files to /home/runner/work/gsim/gsim/nbs/sim-data-palace-26df0ea6


Extracting results.tar.gz...
Downloaded 6 files to /home/runner/work/gsim/gsim/nbs/sim-data-palace-d6cfbe23


Extracting results.tar.gz...
Downloaded 6 files to /home/runner/work/gsim/gsim/nbs/sim-data-palace-52fd63e4

Plot S11 and S21 comparison

import matplotlib.pyplot as plt
import pandas as pd

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

for w, result_files in zip(widths, results):
    csv_path = result_files["port-S.csv"]
    df = pd.read_csv(csv_path)
    df.columns = df.columns.str.strip()
    freq = df["f (GHz)"]

    ax1.plot(freq, df["|S[1][1]| (dB)"], marker=".", label=f"w={w:.1f} um")
    ax2.plot(freq, df["|S[2][1]| (dB)"], marker=".", label=f"w={w:.1f} um")

ax1.set_xlabel("Frequency (GHz)")
ax1.set_ylabel("|S11| (dB)")
ax1.set_title("S11 — Return Loss vs Width")
ax1.legend()
ax1.grid(True)

ax2.set_xlabel("Frequency (GHz)")
ax2.set_ylabel("|S21| (dB)")
ax2.set_title("S21 — Insertion Loss vs Width")
ax2.legend()
ax2.grid(True)

plt.tight_layout()

png