Download this example

Download this example as a Jupyter Notebook or as a Python script.


PCB AC analysis#

This example shows how to use PyAEDT to create a design in Q3D Extractor and run a simulation starting from an EDB project.

Keywords: Q3D, PCB.

Perform imports and define constants#

Perform required imports.

[1]:
import os
import tempfile
import time

import ansys.aedt.core
import pyedb
from ansys.aedt.core.examples.downloads import download_file

Define constants.

[2]:
AEDT_VERSION = "2026.1"
NUM_CORES = 4
NG_MODE = False  # Open AEDT UI when it is launched.

Create temporary directory#

Create a temporary directory where downloaded data or dumped data can be stored. If you’d like to retrieve the project data for subsequent use, the temporary folder name is given by temp_folder.name.

[3]:
temp_folder = tempfile.TemporaryDirectory(suffix=".ansys")

Set up project files and path#

Download needed project file and set up temporary project directory.

[4]:
project_dir = os.path.join(temp_folder.name, "edb")
aedb_project = download_file(source="edb/ANSYS-HSD_V1.aedb", local_path=project_dir)

project_name = os.path.join(temp_folder.name, "HSD")
output_edb = os.path.join(project_dir, project_name + ".aedb")
output_q3d = os.path.join(project_dir, project_name + "_q3d.aedt")

Open EDB and create cutout#

Open the EDB project and create a cutout on the selected nets before exporting to Q3D.

[5]:
edb = pyedb.Edb(edbpath=aedb_project, version=AEDT_VERSION)
cutout_points = edb.cutout(
    ["CLOCK_I2C_SCL", "CLOCK_I2C_SDA"],
    ["GND"],
    output_aedb_path=output_edb,
    use_pyaedt_extent_computing=True,
)
C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\pyedb\generic\design_types.py:375: UserWarning: You are using PyEDB with grpc, which is currently in beta. Some feature might be missing or not working as expected. Please report any issue you find to the PyEDB team.
  warnings.warn(GRPC_BETA_WARNING, UserWarning)
PyEDB INFO: Logger is initialized in EDB.
PyEDB INFO: legacy v0.75.0
PyEDB INFO: Python version 3.10.11 (tags/v3.10.11:7d4cc5a, Apr  5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)]
PyEDB INFO: Using PyEDB with gRPC as Beta until ANSYS 2027R1 official release.
PyEDB INFO: Logger is initialized in EDB.
PyEDB INFO: legacy v0.75.0
PyEDB INFO: Python version 3.10.11 (tags/v3.10.11:7d4cc5a, Apr  5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)]
PyEDB INFO: Grpc session started
PyEDB INFO: Grpc session started: pid=6660
PyEDB INFO: RPC session acquired (open databases: 1)
PyEDB INFO: Database ANSYS-HSD_V1.aedb Opened in 2026.1
PyEDB INFO: Cell main Opened
PyEDB INFO: Refreshing the Components dictionary.
PyEDB INFO: Builder was initialized.
PyEDB INFO: EDB initialized.
PyEDB INFO: -----------------------------------------
PyEDB INFO: Trying cutout with 2.0mm expansion size
PyEDB INFO: -----------------------------------------
PyEDB INFO: GRPC cut-out started
PyEDB INFO: [READ] Data collection finished in 2.892 s
PyEDB INFO: Nets:348, padstack_instances:5699, primitives:2107, components:509
PyEDB INFO: [EXTENT] Polygon created in 0.571 s
PyEDB INFO: [COMPUTE] Decision lists ready in 18.578 s
PyEDB INFO: Starting single write-pass
PyEDB INFO: Deleting 345 nets
PyEDB INFO: 5599 pad-stack instances deleted in 0.161 s
PyEDB INFO: 3810 primitives deleted in 0.095 s
PyEDB INFO: 9 primitives created in 0.191 s
C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\pyedb\workflows\utilities\cutout.py:778: FutureWarning: Accessing deprecated property numpins. use num_pins property instead
  components_to_delete = [comp for comp in all_components if comp.numpins == 0]
PyEDB INFO: 497 components deleted in 0.780 s
PyEDB INFO: Refreshing the Components dictionary.
PyEDB INFO: [WRITE] All writes finished in 3.561 s
PyEDB INFO: GRPC-safe cut-out completed Elapsed time: 0m 26sec
PyEDB INFO: Cutout completed in 1 iterations with expansion size of 2.0mm Elapsed time: 0m 26sec

Identify locations of pins#

Identify \((x,y)\) pin locations on the components to define where to assign sources and sinks for Q3D.

[6]:
pin_u13_scl = [i for i in edb.components["U13"].pins.values() if i.net_name == "CLOCK_I2C_SCL"]
pin_u1_scl = [i for i in edb.components["U1"].pins.values() if i.net_name == "CLOCK_I2C_SCL"]
pin_u13_sda = [i for i in edb.components["U13"].pins.values() if i.net_name == "CLOCK_I2C_SDA"]
pin_u1_sda = [i for i in edb.components["U1"].pins.values() if i.net_name == "CLOCK_I2C_SDA"]

Append Z elevation positions#

Note: The factor 1000 converts from meters to millimeters.

[7]:
location_u13_scl = [i * 1000 for i in pin_u13_scl[0].position]
location_u13_scl.append(edb.components["U13"].upper_elevation * 1000)

location_u1_scl = [i * 1000 for i in pin_u1_scl[0].position]
location_u1_scl.append(edb.components["U1"].upper_elevation * 1000)

location_u13_sda = [i * 1000 for i in pin_u13_sda[0].position]
location_u13_sda.append(edb.components["U13"].upper_elevation * 1000)

location_u1_sda = [i * 1000 for i in pin_u1_sda[0].position]
location_u1_sda.append(edb.components["U1"].upper_elevation * 1000)

Save and close EDB#

Save and close EDB. Then, open the EDB project in HFSS 3D Layout to generate the 3D model.

[8]:
edb.save()
edb.close()

h3d = ansys.aedt.core.Hfss3dLayout(output_edb, version=AEDT_VERSION, non_graphical=NG_MODE, new_desktop=True)
PyEDB INFO: RPC session released (open databases: 0)
PyAEDT INFO: Python version 3.10.11 (tags/v3.10.11:7d4cc5a, Apr  5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)].
PyAEDT INFO: PyAEDT version 1.0.dev0.
PyAEDT INFO: Initializing new Desktop session.
PyAEDT INFO: AEDT version 2026.1.
PyAEDT INFO: New AEDT session is starting on gRPC port 50076.
PyAEDT INFO: Starting new AEDT gRPC session on port 50076.
PyAEDT INFO: Launching AEDT server with gRPC transport mode: wnua
PyAEDT INFO: Electronics Desktop started on gRPC port 50076 after 10.2 seconds.
PyAEDT INFO: AEDT installation Path C:\Program Files\ANSYS Inc\v261\AnsysEM
PyAEDT INFO: Connected to AEDT gRPC session on port 50076.
PyAEDT INFO: Non-graphical mode detected. Disabling Desktop logs.
PyAEDT INFO: EDB folder C:\Users\ansys\AppData\Local\Temp\tmpy_qu79su.ansys\HSD.aedb has been imported to project HSD
PyAEDT INFO: Active Design set to 0;main
PyAEDT INFO: AEDT objects correctly read

Set up the Q3D Project#

Use HFSS 3D Layout to export the model to Q3D Extractor. The named parameter keep_net_name=True ensures that net names are retained when the model is exported from HFSS 3D Layout.

[9]:
setup = h3d.create_setup()
setup.export_to_q3d(output_q3d, keep_net_name=True)
h3d.close_project()
time.sleep(3)
PyAEDT INFO: Project: HSD, Design: main, [info]  Translation Info: Export complete (00:00:04). (08:11:57 AM  May 16, 2026)
PyAEDT INFO: Project: HSD, Design: main, [info]  File written to C:/Users/ansys/AppData/Local/Temp/tmpy_qu79su.ansys/HSD_q3d.aedt. (08:11:57 AM  May 16, 2026)
PyAEDT INFO: Loading Modeler.
PyAEDT INFO: Modeler loaded.
PyAEDT INFO: Modeler class has been initialized! Elapsed time: 0m 0sec
PyAEDT INFO: No EDB gRPC setting provided. Enabling gRPC for EDB.
PyAEDT INFO: Loading EDB with Grpc enabled.
PyEDB INFO: Logger is initialized in EDB.
PyEDB INFO: legacy v0.75.0
PyEDB INFO: Python version 3.10.11 (tags/v3.10.11:7d4cc5a, Apr  5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)]
PyEDB INFO: Using PyEDB with gRPC as Beta until ANSYS 2027R1 official release.
PyEDB WARNING: AEDT project-related file C:\Users\ansys\AppData\Local\Temp\tmpy_qu79su.ansys\HSD.aedt exists and may need to be deleted before opening the EDB in HFSS 3D Layout.
PyEDB WARNING: AEDT project-related file C:\Users\ansys\AppData\Local\Temp\tmpy_qu79su.ansys\HSD.aedt.lock exists and may need to be deleted before opening the EDB in HFSS 3D Layout.
PyEDB INFO: Logger is initialized in EDB.
PyEDB INFO: legacy v0.75.0
PyEDB INFO: Python version 3.10.11 (tags/v3.10.11:7d4cc5a, Apr  5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)]
PyEDB INFO: Grpc session started
PyEDB INFO: Grpc session started: pid=11524
PyEDB INFO: RPC session acquired (open databases: 1)
PyEDB INFO: Database HSD.aedb Opened in 2026.1
PyEDB INFO: Cell main Opened
PyEDB INFO: Refreshing the Components dictionary.
PyEDB INFO: Builder was initialized.
PyEDB INFO: EDB initialized.
PyAEDT INFO: Processing net GND...
PyAEDT INFO: Processing net CLOCK_I2C_SDA...
PyAEDT INFO: Processing net CLOCK_I2C_SCL...
PyAEDT INFO: Net processing completed.
PyAEDT INFO: Processing vias...
PyAEDT INFO: Vias processing completed.
PyAEDT INFO: Python version 3.10.11 (tags/v3.10.11:7d4cc5a, Apr  5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)].
PyAEDT INFO: Parsing C:\Users\ansys\AppData\Local\Temp\tmpy_qu79su.ansys\HSD_q3d.aedt.
PyAEDT INFO: PyAEDT version 1.0.dev0.
PyAEDT INFO: Returning found Desktop session with PID 4020!
PyAEDT INFO: File C:\Users\ansys\AppData\Local\Temp\tmpy_qu79su.ansys\HSD_q3d.aedt correctly loaded. Elapsed time: 0m 0sec
PyAEDT INFO: Project HSD_q3d has been opened.
PyAEDT INFO: Active Design set to Q3DDesign1
PyAEDT INFO: AEDT objects correctly read
PyAEDT INFO: Modeler class has been initialized! Elapsed time: 0m 0sec
PyAEDT INFO: Materials class has been initialized! Elapsed time: 0m 0sec
PyAEDT INFO: Renaming primitives for net GND...
PyAEDT INFO: Parsing design objects. This operation can take time
PyAEDT INFO: Refreshing bodies from Object Info
PyAEDT INFO: Bodies Info Refreshed Elapsed time: 0m 0sec
PyAEDT INFO: 3D Modeler objects parsed. Elapsed time: 0m 0sec
PyAEDT INFO: Parsing design objects. This operation can take time
PyAEDT INFO: Refreshing bodies from Object Info
PyAEDT INFO: Bodies Info Refreshed Elapsed time: 0m 0sec
PyAEDT INFO: 3D Modeler objects parsed. Elapsed time: 0m 0sec
PyAEDT INFO: Union of 2 objects has been executed.
PyAEDT INFO: Renaming primitives for net CLOCK_I2C_SDA...
PyAEDT INFO: Parsing design objects. This operation can take time
PyAEDT INFO: Refreshing bodies from Object Info
PyAEDT INFO: Bodies Info Refreshed Elapsed time: 0m 0sec
PyAEDT INFO: 3D Modeler objects parsed. Elapsed time: 0m 0sec
PyAEDT INFO: Union of 5 objects has been executed.
PyAEDT INFO: Renaming primitives for net CLOCK_I2C_SCL...
PyAEDT INFO: Parsing design objects. This operation can take time
PyAEDT INFO: Refreshing bodies from Object Info
PyAEDT INFO: Bodies Info Refreshed Elapsed time: 0m 0sec
PyAEDT INFO: 3D Modeler objects parsed. Elapsed time: 0m 0sec
PyAEDT INFO: Union of 5 objects has been executed.
PyAEDT INFO: No new nets identified
PyAEDT INFO: Closing the AEDT Project HSD_q3d
PyAEDT INFO: Project HSD_q3d closed correctly
PyEDB INFO: RPC session released (open databases: 0)
PyAEDT INFO: Closing the AEDT Project HSD
PyAEDT INFO: Project HSD closed correctly

Open the newly created Q3D project and display the layout.

[10]:
q3d = ansys.aedt.core.Q3d(output_q3d, version=AEDT_VERSION)
q3d.plot(
    show=False,
    assignment=["CLOCK_I2C_SCL", "CLOCK_I2C_SDA"],
    output_file=os.path.join(temp_folder.name, "Q3D.jpg"),
    plot_air_objects=False,
)
PyAEDT INFO: Python version 3.10.11 (tags/v3.10.11:7d4cc5a, Apr  5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)].
PyAEDT INFO: Parsing C:\Users\ansys\AppData\Local\Temp\tmpy_qu79su.ansys\HSD_q3d.aedt.
PyAEDT INFO: PyAEDT version 1.0.dev0.
PyAEDT INFO: Returning found Desktop session with PID 4020!
PyAEDT INFO: File C:\Users\ansys\AppData\Local\Temp\tmpy_qu79su.ansys\HSD_q3d.aedt correctly loaded. Elapsed time: 0m 0sec
PyAEDT INFO: Project HSD_q3d has been opened.
PyAEDT INFO: Active Design set to Q3DDesign1
PyAEDT INFO: AEDT objects correctly read
PyAEDT INFO: PostProcessor class has been initialized! Elapsed time: 0m 0sec
PyAEDT INFO: Post class has been initialized! Elapsed time: 0m 0sec
PyAEDT INFO: Modeler class has been initialized! Elapsed time: 0m 0sec
[10]:
Class: ansys.aedt.core.visualization.plot.pyvista.ModelPlotter

Use the previously calculated positions to identify faces and assign sources and sinks on nets.

[11]:
f1 = q3d.modeler.get_faceid_from_position(location_u13_scl, assignment="CLOCK_I2C_SCL")
q3d.source(f1, net_name="CLOCK_I2C_SCL")
f1 = q3d.modeler.get_faceid_from_position(location_u13_sda, assignment="CLOCK_I2C_SDA")
q3d.source(f1, net_name="CLOCK_I2C_SDA")
f1 = q3d.modeler.get_faceid_from_position(location_u1_scl, assignment="CLOCK_I2C_SCL")
q3d.sink(f1, net_name="CLOCK_I2C_SCL")
f1 = q3d.modeler.get_faceid_from_position(location_u1_sda, assignment="CLOCK_I2C_SDA")
q3d.sink(f1, net_name="CLOCK_I2C_SDA")
PyAEDT INFO: Parsing design objects. This operation can take time
PyAEDT INFO: Refreshing bodies from Object Info
PyAEDT INFO: Bodies Info Refreshed Elapsed time: 0m 0sec
PyAEDT INFO: 3D Modeler objects parsed. Elapsed time: 0m 0sec
PyAEDT INFO: Boundary Source Source_O1KW2H has been created.
PyAEDT INFO: Boundary Source Source_HEJWPS has been created.
PyAEDT INFO: Boundary Sink Sink_M6V2O2 has been created.
PyAEDT INFO: Boundary Sink Sink_CLWOS6 has been created.
[11]:
Sink_CLWOS6

Define the solution setup and the frequency sweep ranging from DC to 2GHz.

[12]:
setup = q3d.create_setup()
setup.dc_enabled = True
setup.capacitance_enabled = False
sweep = setup.add_sweep()
sweep.add_subrange("LinearStep", 0, end=2, count=0.05, unit="GHz", clear=True)
setup.analyze(cores=NUM_CORES)
PyAEDT INFO: Project HSD_q3d Saved correctly
PyAEDT INFO: Key Desktop/ActiveDSOConfigurations/Q3D Extractor correctly changed.
PyAEDT INFO: Solving design setup MySetupAuto
PyAEDT INFO: Design setup MySetupAuto solved correctly in 0.0h 4.0m 41.0s
PyAEDT INFO: Key Desktop/ActiveDSOConfigurations/Q3D Extractor correctly changed.

Solve#

Compute AC inductance and resistance.

[13]:
traces_acl = q3d.post.available_report_quantities(quantities_category="ACL Matrix")
solution = q3d.post.get_solution_data(traces_acl)
PyAEDT WARNING: No report category provided. Automatically identified Matrix
PyAEDT INFO: Solution Correctly loaded. Elapsed time: 0m 0sec
PyAEDT INFO: Solution Correctly parsed. Elapsed time: 0m 0sec

Postprocess#

Plot AC inductance and resistance.

[14]:
solution.plot()
traces_acr = q3d.post.available_report_quantities(quantities_category="ACR Matrix")
solution2 = q3d.post.get_solution_data(traces_acr)
solution2.plot()
PyAEDT WARNING: No report category provided. Automatically identified Matrix
PyAEDT INFO: Solution Correctly loaded. Elapsed time: 0m 0sec
PyAEDT INFO: Solution Correctly parsed. Elapsed time: 0m 0sec
[14]:
../../../../_images/examples_high_frequency_layout_power_integrity_ac_q3d_29_1.png
../../../../_images/examples_high_frequency_layout_power_integrity_ac_q3d_29_2.png
../../../../_images/examples_high_frequency_layout_power_integrity_ac_q3d_29_3.png

Release AEDT#

[15]:
q3d.save_project()
q3d.release_desktop()
# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory.
time.sleep(3)
PyAEDT INFO: Project HSD_q3d Saved correctly
PyAEDT INFO: Desktop has been released and closed.

Clean up#

All project files are saved in the folder temp_folder.name. If you’ve run this example as a Jupyter notebook, you can retrieve those project files. The following cell removes all temporary files, including the project folder.

[16]:
temp_folder.cleanup()

Download this example

Download this example as a Jupyter Notebook or as a Python script.