diff --git a/examples/index.rst b/examples/index.rst index 1abeea50f3..a914229014 100644 --- a/examples/index.rst +++ b/examples/index.rst @@ -6,8 +6,6 @@ :maxdepth: 2 - legacy_pyaedt_integration/index - legacy_standalone/index use_configuration/index diff --git a/examples/legacy_pyaedt_integration/03_5G_antenna_example.py b/examples/legacy_pyaedt_integration/03_5G_antenna_example.py deleted file mode 100644 index edc4911b1b..0000000000 --- a/examples/legacy_pyaedt_integration/03_5G_antenna_example.py +++ /dev/null @@ -1,288 +0,0 @@ -# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates. -# SPDX-License-Identifier: MIT -# -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -# ## EDB: 5G linear array antenna -# -# This example shows how you can use HFSS 3D Layout to create and solve a 5G linear array antenna. - -# ## Perform required imports -# -# Perform required imports. - -import os -import tempfile - -from ansys.aedt.core import Hfss3dLayout - -import pyedb -from pyedb.generic.general_methods import generate_unique_name - -# ## Set non-graphical mode -# -# Set non-graphical mode. The default is ``False``. - -non_graphical = False - - -class Patch: - def __init__(self, width=0.0, height=0.0, position=0.0): - self.width = width - self.height = height - self.position = position - - @property - def points(self): - return [ - [self.position, -self.height / 2], - [self.position + self.width, -self.height / 2], - [self.position + self.width, self.height / 2], - [self.position, self.height / 2], - ] - - -class Line: - def __init__(self, length=0.0, width=0.0, position=0.0): - self.length = length - self.width = width - self.position = position - - @property - def points(self): - return [ - [self.position, -self.width / 2], - [self.position + self.length, -self.width / 2], - [self.position + self.length, self.width / 2], - [self.position, self.width / 2], - ] - - -class LinearArray: - def __init__(self, nb_patch=1, array_length=10e-3, array_width=5e-3): - self.nbpatch = nb_patch - self.length = array_length - self.width = array_width - - @property - def points(self): - return [ - [-1e-3, -self.width / 2 - 1e-3], - [self.length + 1e-3, -self.width / 2 - 1e-3], - [self.length + 1e-3, self.width / 2 + 1e-3], - [-1e-3, self.width / 2 + 1e-3], - ] - - -tmpfold = tempfile.gettempdir() -aedb_path = os.path.join(tmpfold, generate_unique_name("pcb") + ".aedb") -print(aedb_path) -edb = pyedb.Edb(edbpath=aedb_path, edbversion="2024.2") - -# ## Add stackup layers -# -# Add the stackup layers. -layers = { - "TOP": {"type": "signal", "thicness": "35um", "material": "copper"}, - "Substrat": {"type": "dielectric", "thicness": "0.5mm", "material": "Duroid (tm)"}, - "GND": {"type": "signal", "thicness": "35um", "material": "copper"}, - "Gap": {"type": "dielectric", "thicness": "0.05mm", "material": "Air"}, - "Virt_GND": {"type": "signal", "thicness": "35um", "material": "copper"}, -} - -edb.stackup.load(layers) - - -# ## Create linear array -# -# Create the first patch of the linear array. - -first_patch = Patch(width=1.4e-3, height=1.2e-3, position=0.0) -edb.modeler.create_polygon(first_patch.points, "TOP", net_name="Array_antenna") -# First line -first_line = Line(length=2.4e-3, width=0.3e-3, position=first_patch.width) -edb.modeler.create_polygon(first_line.points, "TOP", net_name="Array_antenna") - -# ## Patch linear array -# -# Patch the linear array. - -patch = Patch(width=2.29e-3, height=3.3e-3) -line = Line(length=1.9e-3, width=0.2e-3) -linear_array = LinearArray(nb_patch=8, array_width=patch.height) - -current_patch = 1 -current_position = first_line.position + first_line.length - -while current_patch <= linear_array.nbpatch: - patch.position = current_position - edb.modeler.create_polygon(patch.points, "TOP", net_name="Array_antenna") - current_position += patch.width - if current_patch < linear_array.nbpatch: - line.position = current_position - edb.modeler.create_polygon(line.points, "TOP", net_name="Array_antenna") - current_position += line.length - current_patch += 1 - -linear_array.length = current_position - -# ## Add ground -# -# Add a ground. - -edb.modeler.create_polygon(linear_array.points, "GND", net_name="GND") - - -# ## Add connector pin -# -# Add a central connector pin. - -edb.padstacks.create(padstackname="Connector_pin", holediam="100um", paddiam="0", antipaddiam="200um") -con_pin = edb.padstacks.place( - [first_patch.width / 4, 0], - "Connector_pin", - net_name="Array_antenna", - fromlayer="TOP", - tolayer="GND", - via_name="coax", -) - -# ## Add connector ground -# -# Add a connector ground. - -edb.modeler.create_polygon(first_patch.points, "Virt_GND", net_name="GND") -edb.padstacks.create("gnd_via", "100um", "0", "0") -con_ref1 = edb.padstacks.place( - [first_patch.points[0][0] + 0.2e-3, first_patch.points[0][1] + 0.2e-3], - "gnd_via", - fromlayer="GND", - tolayer="Virt_GND", - net_name="GND", -) -con_ref2 = edb.padstacks.place( - [first_patch.points[1][0] - 0.2e-3, first_patch.points[1][1] + 0.2e-3], - "gnd_via", - fromlayer="GND", - tolayer="Virt_GND", - net_name="GND", -) -con_ref3 = edb.padstacks.place( - [first_patch.points[2][0] - 0.2e-3, first_patch.points[2][1] - 0.2e-3], - "gnd_via", - fromlayer="GND", - tolayer="Virt_GND", - net_name="GND", -) -con_ref4 = edb.padstacks.place( - [first_patch.points[3][0] + 0.2e-3, first_patch.points[3][1] - 0.2e-3], - "gnd_via", - fromlayer="GND", - tolayer="Virt_GND", - net_name="GND", -) - -# ## Add excitation port -# -# Add an excitation port. - -edb.padstacks.set_solderball(con_pin, "Virt_GND", isTopPlaced=False, ballDiam=0.1e-3) -port_name = edb.padstacks.create_coax_port(con_pin) - - -# ## Plot geometry -# -# Plot the geometry. - -edb.nets.plot(None) - -# ## Save and close Edb instance prior to opening it in Electronics Desktop. -# -# Save EDB. - -edb.save_edb() -edb.close_edb() -print("EDB saved correctly to {}. You can import in AEDT.".format(aedb_path)) - -# ## Launch HFSS 3D Layout and open EDB -# -# Launch HFSS 3D Layout and open EDB. - -h3d = Hfss3dLayout( - projectname=aedb_path, specified_version="2024.2", new_desktop_session=True, non_graphical=non_graphical -) - -# ## Plot geometry -# -# Plot the geometry. The EDB methods are also accessible from the ``Hfss3dlayout`` class. - -h3d.modeler.edb.nets.plot(None) - -# ## Create setup and sweeps -# -# Getters and setters facilitate the settings on the nested property dictionary. -# Previously, you had to use these commands: -# -# ``setup.props["AdaptiveSettings"]["SingleFrequencyDataList"]["AdaptiveFrequencyData"]["AdaptiveFrequency"] = "20GHz"`` -# ``setup.props["AdaptiveSettings"]["SingleFrequencyDataList"]["AdaptiveFrequencyData"]["MaxPasses"] = 4`` -# -# You can now use the simpler approach that follows. - -setup = h3d.create_setup() - -setup["AdaptiveFrequency"] = "20GHz" -setup["AdaptiveSettings/SingleFrequencyDataList/AdaptiveFrequencyData/MaxPasses"] = 4 -h3d.create_linear_count_sweep( - setupname=setup.name, - unit="GHz", - freqstart=20, - freqstop=50, - num_of_freq_points=1001, - sweepname="sweep1", - sweep_type="Interpolating", - interpolation_tol_percent=1, - interpolation_max_solutions=255, - save_fields=False, - use_q3d_for_dc=False, -) - -# ## Solve setup and create report -# -# Solve the project and create a report. - -h3d.analyze() -h3d.post.create_report(["db(S({0},{1}))".format(port_name, port_name)]) - - -# ## Plot results outside AEDT -# -# Plot results using Matplotlib. - -solution = h3d.post.get_solution_data(["S({0},{1})".format(port_name, port_name)]) -solution.plot() - -# ## Close AEDT -# -# After the simulation completes, you can close AEDT or release it using the -# :func:`dotnet.Desktop.release_desktop` method. -# All methods provide for saving the project before closing AEDT. - -h3d.save_project() -h3d.release_desktop() diff --git a/examples/legacy_pyaedt_integration/03_5G_antenna_example_parametrics.py b/examples/legacy_pyaedt_integration/03_5G_antenna_example_parametrics.py deleted file mode 100644 index 15466d452c..0000000000 --- a/examples/legacy_pyaedt_integration/03_5G_antenna_example_parametrics.py +++ /dev/null @@ -1,384 +0,0 @@ -# # EDB: Layout Components -# -# This example shows how you can use EDB to create a parametric component using -# 3D Layout and use it in HFSS 3D. - -# ## Perform required imports -# -# Perform required imports, which includes importing the ``Hfss3dlayout`` object -# and initializing it on version 2023 R2. - -# + -import os -import tempfile - -import ansys.aedt.core - -import pyedb - -# - - -# ## Set non-graphical mode - -non_graphical = False - -# ## Create data classes -# -# Data classes are useful to do calculations and store variables. -# There are three data classes: ``Patch``, ``Line``, and ``Array``. - - -# + -class Patch: - def __init__(self, width=0.0, height=0.0, position=0.0): - self.width = width - self.height = height - self.position = position - - @property - def points(self): - return [ - [self.position, "-{}/2".format(self.height)], - ["{} + {}".format(self.position, self.width), "-{}/2".format(self.height)], - ["{} + {}".format(self.position, self.width), "{}/2".format(self.height)], - [self.position, "{}/2".format(self.height)], - ] - - -class Line: - def __init__(self, length=0.0, width=0.0, position=0.0): - self.length = length - self.width = width - self.position = position - - @property - def points(self): - return [ - [self.position, "-{}/2".format(self.width)], - ["{} + {}".format(self.position, self.length), "-{}/2".format(self.width)], - ["{} + {}".format(self.position, self.length), "{}/2".format(self.width)], - [self.position, "{}/2".format(self.width)], - ] - - -class LinearArray: - def __init__(self, nb_patch=1, array_length=10e-3, array_width=5e-3): - self.nbpatch = nb_patch - self.length = array_length - self.width = array_width - - @property - def points(self): - return [ - [-1e-3, "-{}/2-1e-3".format(self.width)], - ["{}+1e-3".format(self.length), "-{}/2-1e-3".format(self.width)], - ["{}+1e-3".format(self.length), "{}/2+1e-3".format(self.width)], - [-1e-3, "{}/2+1e-3".format(self.width)], - ] - - -# - - -# ## Launch EDB -# -# PyEDB.Edb allows to open existing Edb project or create a new empty project. - -# + -temp_dir = tempfile.TemporaryDirectory(suffix=".ansys") -aedb_path = os.path.join(temp_dir.name, "linear_array.aedb") - -# Select EDB version (change it manually if needed, e.g. "2024.2") -edb_version = "2024.2" -print(f"EDB version: {edb_version}") - -# Create an instance of the Edb class. -edb = pyedb.Edb(edbpath=aedb_path, edbversion=edb_version) -# - - -# Add stackup layers -layers = { - "materials": {"copper_high_cond": {"conductivity": 60000000}}, - "layers": { - "TOP": {"type": "signal", "thicness": "35um", "material": "copper_high_cond"}, - "Substrat": {"type": "dielectric", "thicness": "0.5mm", "material": "Duroid (tm)"}, - "GND": {"type": "signal", "thicness": "35um", "material": "copper"}, - "Gap": {"type": "dielectric", "thicness": "0.05mm", "material": "Air"}, - "Virt_GND": {"type": "signal", "thicness": "35um", "material": "copper"}, - }, -} - -edb.stackup.load(layers) - -# Create the first patch and feed line using the ``Patch``, ``Line``classes defined above. -# -# Define parameters: - -# + -edb["w1"] = 1.4e-3 -edb["h1"] = 1.2e-3 -edb["initial_position"] = 0.0 -edb["l1"] = 2.4e-3 -edb["trace_w"] = 0.3e-3 - -first_patch = Patch(width="w1", height="h1", position="initial_position") -edb.modeler.create_polygon(first_patch.points, "TOP", net_name="Array_antenna") -# - - -# First line - -first_line = Line(length="l1", width="trace_w", position=first_patch.width) -edb.modeler.create_polygon(first_line.points, "TOP", net_name="Array_antenna") - -# Now use the ``LinearArray`` class to create the array. - -# + -edb["w2"] = 2.29e-3 -edb["h2"] = 3.3e-3 -edb["l2"] = 1.9e-3 -edb["trace_w2"] = 0.2e-3 - -patch = Patch(width="w2", height="h2") -line = Line(length="l2", width="trace_w2") -linear_array = LinearArray(nb_patch=8, array_width=patch.height) - -current_patch = 1 -current_position = "{} + {}".format(first_line.position, first_line.length) - -while current_patch <= linear_array.nbpatch: - patch.position = current_position - edb.modeler.create_polygon(patch.points, "TOP", net_name="Array_antenna") - current_position = "{} + {}".format(current_position, patch.width) - if current_patch < linear_array.nbpatch: - line.position = current_position - edb.modeler.create_polygon(line.points, "TOP", net_name="Array_antenna") - current_position = "{} + {}".format(current_position, line.length) - current_patch += 1 - -linear_array.length = current_position -# - - -# Add the ground conductor. - -edb.modeler.create_polygon(linear_array.points, "GND", net_name="GND") - -# Add the connector pin to use to assign the port. - -edb.padstacks.create(padstackname="Connector_pin", holediam="100um", paddiam="0", antipaddiam="200um") -con_pin = edb.padstacks.place( - ["{}/4.0".format(first_patch.width), 0], - "Connector_pin", - net_name="Array_antenna", - fromlayer="TOP", - tolayer="GND", - via_name="coax", -) - -# Add a connector ground. - -edb.modeler.create_polygon(first_patch.points, "Virt_GND", net_name="GND") -edb.padstacks.create("gnd_via", "100um", "0", "0") -edb["via_spacing"] = 0.2e-3 -con_ref1 = edb.padstacks.place( - [ - "{} + {}".format(first_patch.points[0][0], "via_spacing"), - "{} + {}".format(first_patch.points[0][1], "via_spacing"), - ], - "gnd_via", - fromlayer="GND", - tolayer="Virt_GND", - net_name="GND", -) -con_ref2 = edb.padstacks.place( - [ - "{} + {}".format(first_patch.points[1][0], "-via_spacing"), - "{} + {}".format(first_patch.points[1][1], "via_spacing"), - ], - "gnd_via", - fromlayer="GND", - tolayer="Virt_GND", - net_name="GND", -) -con_ref3 = edb.padstacks.place( - [ - "{} + {}".format(first_patch.points[2][0], "-via_spacing"), - "{} + {}".format(first_patch.points[2][1], "-via_spacing"), - ], - "gnd_via", - fromlayer="GND", - tolayer="Virt_GND", - net_name="GND", -) -con_ref4 = edb.padstacks.place( - [ - "{} + {}".format(first_patch.points[3][0], "via_spacing"), - "{} + {}".format(first_patch.points[3][1], "-via_spacing"), - ], - "gnd_via", - fromlayer="GND", - tolayer="Virt_GND", - net_name="GND", -) - -# Define the port. - -edb.padstacks.set_solderball(con_pin, "Virt_GND", isTopPlaced=False, ballDiam=0.1e-3) -port_name = edb.padstacks.create_coax_port(con_pin) - -# Display the model using the ``Edb.nets.plot()`` method. - -edb.nets.plot() - -# The EDB is complete. Now close the EDB and import it into HFSS as a "Layout Component". - -edb.save_edb() -edb.close_edb() -print("EDB saved correctly to {}. You can import in AEDT.".format(aedb_path)) - -# ## 3D component in HFSS -# -# First create an instance of the ``pyaedt.Hfss`` class. If you set -# > ``non_graphical = False -# -# then AEDT user interface will be visible after the following cell is executed. -# It is now possible to monitor the progress in the UI as each of the following cells is executed. -# All commands can be run without the UI by changing the value of ``non_graphical``. - -h3d = ansys.aedt.core.Hfss( - projectname="Demo_3DComp", - designname="Linear_Array", - specified_version="2024.2", - new_desktop_session=True, - non_graphical=non_graphical, - close_on_exit=True, - solution_type="Terminal", -) - -# Set units to ``mm``. - -h3d.modeler.model_units = "mm" - -# ## Import the EDB as a 3D component -# -# One or more layout components can be imported into HFSS. -# The combination of layout data and 3D CAD data helps streamline model creation and setup. - -component = h3d.modeler.insert_layout_component(aedb_path, parameter_mapping=True) - -# ## Expose the component parameters -# -# If a layout component is parametric, you can expose and change parameters in HFSS - -# + -component.parameters - -w1_name = "{}_{}".format("w1", h3d.modeler.user_defined_component_names[0]) -h3d[w1_name] = 0.0015 -# - - -# ### Radiation Boundary Assignment -# -# The 3D domain includes the air volume surrounding the antenna. -# This antenna will be simulted from 20 GHz - 50 GHz. -# -# A "radiation boundary" will be assigned to the outer boundaries of the domain. -# This boundary should be roughly one quarter wavelength away from the radiating structure: -# -# $$ \lambda/4 = \frac{c_0}{4 f} \approx 2.8mm $$ - -# + -h3d.modeler.fit_all() - -h3d.modeler.create_air_region(2.8, 2.8, 2.8, 2.8, 2.8, 2.8, is_percentage=False) -h3d.assign_radiation_boundary_to_objects("Region") -# - - -# ### Set up analysis -# -# The finite element mesh is adapted iteratively. -# The maximum number of adaptive passes is set using the ``MaximumPasses`` property. -# This model converges such that the $S_{11}$ is independent of the mesh. -# The default accuracy setting is: -# $$ \max(|\Delta S|) < 0.02 $$ - -setup = h3d.create_setup() -setup.props["Frequency"] = "20GHz" -setup.props["MaximumPasses"] = 10 - -# Specify properties of the frequency sweep: - -sweep1 = setup.add_sweep(sweepname="20GHz_to_50GHz") -sweep1.props["RangeStart"] = "20GHz" -sweep1.props["RangeEnd"] = "50GHz" -sweep1.update() - -# Solve the project - -h3d.analyze() - -# ## Plot results outside AEDT -# -# Plot results using Matplotlib. - -trace = h3d.get_traces_for_plot() -solution = h3d.post.get_solution_data(trace[0]) -solution.plot() - -# ## Plot far fields in AEDT -# -# Plot radiation patterns in AEDT. - -# + -variations = {} -variations["Freq"] = ["20GHz"] -variations["Theta"] = ["All"] -variations["Phi"] = ["All"] -h3d.insert_infinite_sphere(name="3D") - -new_report = h3d.post.reports_by_category.far_field("db(RealizedGainTotal)", h3d.nominal_adaptive, "3D") -new_report.variations = variations -new_report.primary_sweep = "Theta" -new_report.create("Realized2D") -# - - -# ## Plot far fields in AEDT -# -# Plot radiation patterns in AEDT - -new_report.report_type = "3D Polar Plot" -new_report.secondary_sweep = "Phi" -new_report.create("Realized3D") - -# ## Plot far fields outside AEDT -# -# Plot radiation patterns outside AEDT - -solutions_custom = new_report.get_solution_data() -solutions_custom.plot_3d() - -# ## Plot E Field on nets and layers -# -# Plot E Field on nets and layers in AEDT - -h3d.post.create_fieldplot_layers_nets( - [["TOP", "Array_antenna"]], - "Mag_E", - intrinsics={"Freq": "20GHz", "Phase": "0deg"}, - plot_name="E_Layers", -) - -# ## Close AEDT -# -# After the simulation completes, the application can be released from the -# :func:`ansys.aedt.core.Desktop.release_desktop` method. -# All methods provide for saving the project before closing AEDT. - -h3d.save_project(os.path.join(temp_dir.name, "test_layout.aedt")) -h3d.release_desktop() - -# ### Clean up the temporary directory -# -# The following command removes the project and the temporary directory. -# If you'd like to save this project, save it to a folder of your choice prior -# to running the following cell. - -temp_dir.cleanup() diff --git a/examples/legacy_pyaedt_integration/04_edb_parametrized_design.py b/examples/legacy_pyaedt_integration/04_edb_parametrized_design.py deleted file mode 100644 index d0029a7223..0000000000 --- a/examples/legacy_pyaedt_integration/04_edb_parametrized_design.py +++ /dev/null @@ -1,349 +0,0 @@ -# # EDB: fully parametrized design -# -# This example shows how to use the EDB interface along with HFSS 3D Layout to create and solve a -# parameterized layout. The layout shows a differential via transition on a printed circuit board -# with back-to-back microstrip to stripline transitions. -# The model is fully parameterized to enable investigation of the transition performance on the -# many degrees of freedom. -# -# The resulting model is shown below -# -# - -# + -import os -import tempfile - -import ansys.aedt.core - -import pyedb - -# - - -# ## Set non-graphical mode -# -# Set non-graphical mode. The default is ``False``, which opens -# the AEDT UI. - -non_graphical = False - -# ## Launch EDB. - -# + -temp_dir = tempfile.TemporaryDirectory(suffix=".ansys") -aedb_path = os.path.join(temp_dir.name, "pcb.aedb") - -# Select EDB version (change it manually if needed, e.g. "2024.2") -edb_version = "2024.2" -print(f"EDB version: {edb_version}") - -edb = pyedb.Edb(edbpath=aedb_path, edbversion=edb_version) -# - - -# Define the parameters. - -# + -params = { - "$ms_width": "0.4mm", - "$sl_width": "0.2mm", - "$ms_spacing": "0.2mm", - "$sl_spacing": "0.1mm", - "$via_spacing": "0.5mm", - "$via_diam": "0.3mm", - "$pad_diam": "0.6mm", - "$anti_pad_diam": "0.7mm", - "$pcb_len": "15mm", - "$pcb_w": "5mm", - "$x_size": "1.2mm", - "$y_size": "1mm", - "$corner_rad": "0.5mm", -} - -for par_name in params: - edb.add_project_variable(par_name, params[par_name]) -# - - -# Define the stackup layers from bottom to top. - -layers = { - "top": {"type": "signal", "thickness": "35um", "material": "copper"}, - "diel_1": {"type": "dielectric", "thickness": "275um", "material": "FR4_epoxy"}, - "sig_1": {"type": "signal", "thickness": "35um", "material": "copper"}, - "diel_2": {"type": "dielectric", "thickness": "275um", "material": "FR4_epoxy"}, - "sig_2": {"type": "signal", "thickness": "35um", "material": "copper"}, - "diel_3": {"type": "dielectric", "thickness": "275um", "material": "FR4_epoxy"}, - "bottom": {"type": "signal", "thickness": "35um", "material": "copper"}, -} -layer_names = list(layers.keys())[::-1] -# Create the EDB stackup. -# Define the bottom layer -edb.stackup.load(layers) - - -# Create a parametrized padstack for the signal via. - -signal_via_padstack = "automated_via" -edb.padstacks.create( - padstackname=signal_via_padstack, - holediam="$via_diam", - paddiam="$pad_diam", - antipaddiam="", - antipad_shape="Bullet", - x_size="$x_size", - y_size="$y_size", - corner_radius="$corner_rad", - start_layer=layer_names[-1], - stop_layer=layer_names[-3], -) - -# Assign net names. There are only two signal nets. - -net_p = "p" -net_n = "n" - -# Place the signal vias. - -edb.padstacks.place( - position=["$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing)/2"], - definition_name=signal_via_padstack, - net_name=net_p, - via_name="", - rotation=90.0, -) - -edb.padstacks.place( - position=["2*$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing)/2"], - definition_name=signal_via_padstack, - net_name=net_p, - via_name="", - rotation=90.0, -) - -edb.padstacks.place( - position=["$pcb_len/3", "-($ms_width+$ms_spacing+$via_spacing)/2"], - definition_name=signal_via_padstack, - net_name=net_n, - via_name="", - rotation=-90.0, -) - -edb.padstacks.place( - position=["2*$pcb_len/3", "-($ms_width+$ms_spacing+$via_spacing)/2"], - definition_name=signal_via_padstack, - net_name=net_n, - via_name="", - rotation=-90.0, -) - - -# ## Draw parametrized traces -# -# Trace width and the routing (Microstrip-Stripline-Microstrip). -# Applies to both p and n nets. - -# Trace width, n and p -width = ["$ms_width", "$sl_width", "$ms_width"] -# Routing layer, n and p -route_layer = [layer_names[-1], layer_names[4], layer_names[-1]] - -# Define points for three traces in the "p" net - -points_p = [ - [ - ["0.0", "($ms_width+$ms_spacing)/2"], - ["$pcb_len/3-2*$via_spacing", "($ms_width+$ms_spacing)/2"], - ["$pcb_len/3-$via_spacing", "($ms_width+$ms_spacing+$via_spacing)/2"], - ["$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing)/2"], - ], - [ - ["$pcb_len/3", "($ms_width+$sl_spacing+$via_spacing)/2"], - ["$pcb_len/3+$via_spacing", "($ms_width+$sl_spacing+$via_spacing)/2"], - ["$pcb_len/3+2*$via_spacing", "($sl_width+$sl_spacing)/2"], - ["2*$pcb_len/3-2*$via_spacing", "($sl_width+$sl_spacing)/2"], - ["2*$pcb_len/3-$via_spacing", "($ms_width+$sl_spacing+$via_spacing)/2"], - ["2*$pcb_len/3", "($ms_width+$sl_spacing+$via_spacing)/2"], - ], - [ - ["2*$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing)/2"], - ["2*$pcb_len/3+$via_spacing", "($ms_width+$ms_spacing+$via_spacing)/2"], - ["2*$pcb_len/3+2*$via_spacing", "($ms_width+$ms_spacing)/2"], - ["$pcb_len", "($ms_width+$ms_spacing)/2"], - ], -] - -# Define points for three traces in the "n" net - -points_n = [ - [ - ["0.0", "-($ms_width+$ms_spacing)/2"], - ["$pcb_len/3-2*$via_spacing", "-($ms_width+$ms_spacing)/2"], - ["$pcb_len/3-$via_spacing", "-($ms_width+$ms_spacing+$via_spacing)/2"], - ["$pcb_len/3", "-($ms_width+$ms_spacing+$via_spacing)/2"], - ], - [ - ["$pcb_len/3", "-($ms_width+$sl_spacing+$via_spacing)/2"], - ["$pcb_len/3+$via_spacing", "-($ms_width+$sl_spacing+$via_spacing)/2"], - ["$pcb_len/3+2*$via_spacing", "-($ms_width+$sl_spacing)/2"], - ["2*$pcb_len/3-2*$via_spacing", "-($ms_width+$sl_spacing)/2"], - ["2*$pcb_len/3-$via_spacing", "-($ms_width+$sl_spacing+$via_spacing)/2"], - ["2*$pcb_len/3", "-($ms_width+$sl_spacing+$via_spacing)/2"], - ], - [ - ["2*$pcb_len/3", "-($ms_width+$ms_spacing+$via_spacing)/2"], - ["2*$pcb_len/3 + $via_spacing", "-($ms_width+$ms_spacing+$via_spacing)/2"], - ["2*$pcb_len/3 + 2*$via_spacing", "-($ms_width+$ms_spacing)/2"], - ["$pcb_len", "-($ms_width + $ms_spacing)/2"], - ], -] - -# Add traces to the EDB. - -trace_p = [] -trace_n = [] -for n in range(len(points_p)): - trace_p.append(edb.modeler.create_trace(points_p[n], route_layer[n], width[n], net_p, "Flat", "Flat")) - trace_n.append(edb.modeler.create_trace(points_n[n], route_layer[n], width[n], net_n, "Flat", "Flat")) - -# Create the wave ports - -p1 = edb.hfss.create_differential_wave_port( - trace_p[0].id, - ["0.0", "($ms_width+$ms_spacing)/2"], - trace_n[0].id, - ["0.0", "-($ms_width+$ms_spacing)/2"], - "wave_port_1", -) - -pos_p1 = p1[1].terminals[0].name -neg_p1 = p1[1].terminals[1].name - -p2 = edb.hfss.create_differential_wave_port( - trace_p[2].id, - ["$pcb_len", "($ms_width+$ms_spacing)/2"], - trace_n[2].id, - ["$pcb_len", "-($ms_width + $ms_spacing)/2"], - "wave_port_2", -) - -pos_p2 = p2[1].terminals[0].name -neg_p2 = p2[1].terminals[1].name - -# Draw a conducting rectangle on the ground layers. - -gnd_poly = [ - [0.0, "-$pcb_w/2"], - ["$pcb_len", "-$pcb_w/2"], - ["$pcb_len", "$pcb_w/2"], - [0.0, "$pcb_w/2"], -] -gnd_shape = edb.modeler.Shape("polygon", points=gnd_poly) - -# Void in ground for traces on the signal routing layer - -# + -void_poly = [ - ["$pcb_len/3", "-($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2-$via_spacing/2"], - [ - "$pcb_len/3 + $via_spacing", - "-($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2-$via_spacing/2", - ], - ["$pcb_len/3 + 2*$via_spacing", "-($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2"], - ["2*$pcb_len/3 - 2*$via_spacing", "-($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2"], - [ - "2*$pcb_len/3 - $via_spacing", - "-($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2-$via_spacing/2", - ], - ["2*$pcb_len/3", "-($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2-$via_spacing/2"], - ["2*$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2+$via_spacing/2"], - [ - "2*$pcb_len/3 - $via_spacing", - "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2+$via_spacing/2", - ], - ["2*$pcb_len/3 - 2*$via_spacing", "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2"], - ["$pcb_len/3 + 2*$via_spacing", "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2"], - [ - "$pcb_len/3 + $via_spacing", - "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2+$via_spacing/2", - ], - ["$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2+$via_spacing/2"], - ["$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2"], -] - -void_shape = edb.modeler.Shape("polygon", points=void_poly) -# - - -# Add ground conductors. - -# + -for layer in layer_names[:-1:2]: - # add void if the layer is the signal routing layer. - void = [void_shape] if layer == route_layer[1] else [] - - edb.modeler.create_polygon(main_shape=gnd_shape, layer_name=layer, voids=void, net_name="gnd") -# - - -# Plot the layout. - -edb.nets.plot(None) - -# Save the EDB. - -edb.save_edb() -edb.close_edb() - -# Open the project in HFSS 3D Layout. - -h3d = ansys.aedt.core.Hfss3dLayout( - project=aedb_path, - version=edb_version, - non_graphical=non_graphical, - new_desktop=True, -) - -# ## Add HFSS simulation setup -# -# Add HFSS simulation setup. - -# + -setup = h3d.create_setup() -setup.props["AdaptiveSettings"]["SingleFrequencyDataList"]["AdaptiveFrequencyData"]["MaxPasses"] = 3 - -h3d.create_linear_count_sweep( - setup=setup.name, - unit="GHz", - start_frequency=0, - stop_frequency=10, - num_of_freq_points=1001, - name="sweep1", - sweep_type="Interpolating", - interpolation_tol_percent=1, - interpolation_max_solutions=255, - save_fields=False, - use_q3d_for_dc=False, -) -# - - -# Define the differential pairs to used to calculate differential and common mode -# s-parameters. - -h3d.set_differential_pair(differential_mode="In", assignment=pos_p1, reference=neg_p1) -h3d.set_differential_pair(differential_mode="Out", assignment=pos_p2, reference=neg_p2) - -# Solve the project. - -h3d.analyze() - -# Plot the results and shut down AEDT. - -solutions = h3d.post.get_solution_data(["dB(S(In,In))", "dB(S(In,Out))"], context="Differential Pairs") -solutions.plot() -h3d.release_desktop() - -# Note that the ground nets are only connected to each other due -# to the wave ports. The problem with poor grounding can be seen in the -# S-parameters. This example can be downloaded as a Jupyter Notebook, so -# you can modify it. Try changing parameters or adding ground vias to improve performance. -# -# The final cell cleans up the temporary directory, removing all files. - -temp_dir.cleanup() diff --git a/examples/legacy_pyaedt_integration/09_Configuration.py b/examples/legacy_pyaedt_integration/09_Configuration.py deleted file mode 100644 index 90458a4d0f..0000000000 --- a/examples/legacy_pyaedt_integration/09_Configuration.py +++ /dev/null @@ -1,230 +0,0 @@ -# # EDB: Pin to Pin project -# -# This example demonstrates the use of the Electronics -# Database (EDB) interface to create a layout using the BOM and -# a configuration file. - -# ## Perform required imports -# -# The ``Hfss3dlayout`` class provides an interface to -# the 3D Layout editor in AEDT. -# on version 2023 R2. - -# + -import os -import tempfile - -import ansys.aedt.core - -import pyedb -from pyedb.misc.downloads import download_file - -# - - -# Download the AEDB file and copy it to a temporary folder. - -temp_dir = tempfile.TemporaryDirectory(suffix=".ansys") -target_aedb = download_file("edb/ANSYS-HSD_V1.aedb", destination=temp_dir.name) -print("Project folder is", target_aedb) - -# ## Launch EDB -# -# Launch the ``pyedb.Edb`` class using EDB 2023 R2. Length units are SI. - -# + -# Select EDB version (change it manually if needed, e.g. "2024.2") -edb_version = "2024.2" -print(f"EDB version: {edb_version}") - -edbapp = pyedb.Edb(target_aedb, edbversion=edb_version) -# - - -# ## Import definitions -# -# The definition file uses the [json](https://www.json.org/json-en.html) to -# map layout part numbers to their corresponding models. -# -# The model may be an RLC, S-parameter, or -# [SPICE](https://en.wikipedia.org/wiki/SPICE) model definition. -# Once imported, the definition is applied to the components in the layout. -# In this example, the JSON file is in the ``*.aedb`` folder and has the following format: -# ``` json -# { -# "SParameterModel": { -# "GRM32_DC0V_25degC_series": "./GRM32_DC0V_25degC_series.s2p" -# }, -# "SPICEModel": { -# "GRM32_DC0V_25degC": "./GRM32_DC0V_25degC.mod" -# }, -# "Definitions": { -# "CAPC1005X05N": { -# "Component_type": "Capacitor", -# "Model_type": "RLC", -# "Res": 1, -# "Ind": 2, -# "Cap": 3, -# "Is_parallel": false -# }, -# "'CAPC3216X180X55ML20T25": { -# "Component_type": "Capacitor", -# "Model_type": "SParameterModel", -# "Model_name": "GRM32_DC0V_25degC_series" -# }, -# "'CAPC3216X180X20ML20": { -# "Component_type": "Capacitor", -# "Model_type": "SPICEModel", -# "Model_name": "GRM32_DC0V_25degC" -# } -# } -# } -# ``` -# -# The ``Edb.components.import_definitions()`` method imports the component definitions that map -# electrical models to the components in the simulation model. - -edbapp.components.import_definition(os.path.join(target_aedb, "1_comp_definition.json")) - -# ## Import BOM -# -# The bill of materials (BOM) file provides the list of all components -# by reference designator, part name, component type, and nominal value. -# -# Components that are not contained in the BOM are deactivated in the -# simulation model. -# This example saves the CSV file in the ``aedb`` folder. -# -# ``` -# +------------+-----------------------+-----------+------------+ -# | RefDes | Part name | Type | Value | -# +============+=======================+===========+============+ -# | C380 | CAPC1005X55X25LL05T10 | Capacitor | 11nF | -# +------------+-----------------------+-----------+------------+ -# ``` -# -# Having red the information in the BOM and definitions file, electrical models can be -# assigned to all of the components in the simulation model. - -edbapp.components.import_bom( - os.path.join(target_aedb, "0_bom.csv"), - refdes_col=0, - part_name_col=1, - comp_type_col=2, - value_col=3, -) - -# ## Verify a Component -# -# Component property allows to access all components instances and their property with -# getters and setters. - -comp = edbapp.components["C1"] -comp.model_type, comp.value - -# ## Check component definition -# -# When an s-parameter model is associated to a component it will be available in -# nport_comp_definition property. - -edbapp.components.nport_comp_definition -edbapp.save_edb() - -# ## Configure the simulation setup -# -# This step enables the following: -# -# - Definition of the nets to include in the cutout region -# - Cutout details -# - Components to create the ports on -# - Simulation settings -# -# The ``Edb.new_simulaton_configuration()`` method returns an instance -# of the ``SimulationConfiguration`` class. - -# + -sim_setup = edbapp.new_simulation_configuration() -sim_setup.solver_type = sim_setup.SOLVER_TYPE.SiwaveSYZ -sim_setup.batch_solve_settings.cutout_subdesign_expansion = 0.003 -sim_setup.batch_solve_settings.do_cutout_subdesign = True -sim_setup.batch_solve_settings.use_pyaedt_cutout = True -sim_setup.ac_settings.max_arc_points = 6 -sim_setup.ac_settings.max_num_passes = 5 - -sim_setup.batch_solve_settings.signal_nets = [ - "PCIe_Gen4_TX2_CAP_P", - "PCIe_Gen4_TX2_CAP_N", - "PCIe_Gen4_TX2_P", - "PCIe_Gen4_TX2_N", -] -sim_setup.batch_solve_settings.components = ["U1", "X1"] -sim_setup.batch_solve_settings.power_nets = ["GND", "GND_DP"] -sim_setup.ac_settings.start_freq = "100Hz" -sim_setup.ac_settings.stop_freq = "6GHz" -sim_setup.ac_settings.step_freq = "10MHz" -# - - -# ## Implement the setup -# -# The cutout and all other simulation settings are applied to the simulation model. - -sim_setup.export_json(os.path.join(temp_dir.name, "configuration.json")) -edbapp.build_simulation_project(sim_setup) - -# ## Display the cutout -# -# Plot cutout once finished. The model is ready to simulate. - -edbapp.nets.plot(None, None) - -# ## Save and close EDB -# -# EDB is saved and re-opened in HFSS -# 3D Layout, where the HFSS simulation can be run. - -edbapp.save_edb() -edbapp.close_edb() - -# ## Open Electronics Desktop -# -# The EDB is opened in AEDT Hfss3DLayout. -# -# Set ``non_graphical=True`` to run the simulation in non-graphical mode. - -aedt_version = edb_version - -h3d = ansys.aedt.core.Hfss3dLayout( - specified_version=aedt_version, - projectname=target_aedb, - non_graphical=False, - new_desktop_session=False, -) - -# ## Analyze -# -# This project is ready to solve. -# Executing the following cell runs the HFSS simulation on the layout. - -h3d.analyze() - -# ## View results -# -# S-parameter data is loaded at the end of simulation. - -solutions = h3d.post.get_solution_data() - -# ## Plot results -# -# Plot S-Parameter data. - -solutions.plot(solutions.expressions, "db20") - -# ## Save and close AEDT -# -# HFSS 3D Layout is saved and closed. - -h3d.save_project() -h3d.release_desktop() - -# Clean up the temporary directory. All files and the temporary project -# folder will be deleted in the next step. - -temp_dir.cleanup() diff --git a/examples/legacy_pyaedt_integration/12_edb_sma_connector_on_board.py b/examples/legacy_pyaedt_integration/12_edb_sma_connector_on_board.py deleted file mode 100644 index fc6dec849e..0000000000 --- a/examples/legacy_pyaedt_integration/12_edb_sma_connector_on_board.py +++ /dev/null @@ -1,212 +0,0 @@ -# # EDB: geometry creation -# -# This example shows how to -# 1. Create a parameterized PCB with an SMA connector footprint for a single-ended -# SMA connector launch footprint.. -# 2. Place 3D component on PCB. -# 3. Create HFSS setup and frequency sweep with a mesh operation. -# 4. Create return loss plot - -# ## See the finished project -# -# - -# ## Create a parameterized PCB -# -# Import dependencies. - -import os -import tempfile - -import ansys.aedt.core -import numpy as np - -import pyedb -from pyedb.misc.downloads import download_file - -# Create the EDB. - -# + -temp_dir = tempfile.TemporaryDirectory(suffix=".ansys") -working_folder = temp_dir.name - -# Select EDB version (change it manually if needed, e.g. "2024.2") -edb_version = "2024.2" -print(f"EDB version: {edb_version}") - -aedb_path = os.path.join(working_folder, "pcb.aedb") -print("AEDB file is located in {}".format(aedb_path)) - -edb = pyedb.Edb(edbpath=aedb_path, edbversion=edb_version) -# - - - -# ## Create Stackup -# -# While this code explicitly defines the stackup, you can import it -# from a from a CSV or XML file using the -# ``Edb.stackup.load()`` method. - -edb.add_design_variable("$DIEL_T", "0.15mm") - -layers = { - "materials": {"ANSYS_FR4": {"permittivity": 3.5, "dielectric_loss_tangent": 0.005}}, - "layers": { - "TOP": {"type": "signal", "thickness": "0.05"}, - "D1": {"type": "dielectric", "thickness": "$DIEL_T", "material": "ANSYS_FR4"}, - "L2": {"type": "signal", "thickness": "0.05"}, - "D2": {"type": "dielectric", "thickness": "$DIEL_T", "material": "ANSYS_FR4"}, - "L3": {"type": "signal", "thickness": "0.05"}, - "D3": {"type": "dielectric", "thickness": "$DIEL_T", "material": "ANSYS_FR4"}, - "L4": {"type": "signal", "thickness": "0.05"}, - "D4": {"type": "dielectric", "thickness": "$DIEL_T", "material": "ANSYS_FR4"}, - "L5": {"type": "signal", "thickness": "0.05"}, - "D5": {"type": "dielectric", "thickness": "$DIEL_T", "material": "ANSYS_FR4"}, - "BOT": {"type": "signal", "thickness": "0.035"}, - }, -} - -edb.stackup.load(layers) - - -# Create ground conductors. - -# + -edb.add_design_variable("PCB_W", "20mm") -edb.add_design_variable("PCB_L", "20mm") - -gnd_dict = {} -for layer_name in edb.stackup.signal_layers.keys(): - gnd_dict[layer_name] = edb.modeler.create_rectangle(layer_name, "GND", [0, "PCB_W/-2"], ["PCB_L", "PCB_W/2"]) -# - - -# ## Create signal net -# -# Create signal net on layer 3, and add clearance to the ground plane. - -# + -edb.add_design_variable("SIG_L", "10mm") -edb.add_design_variable("SIG_W", "0.1mm") -edb.add_design_variable("SIG_C", "0.3mm") - -signal_path = (["5mm", 0], ["SIG_L+5mm", 0]) -signal_trace = edb.modeler.create_trace(signal_path, "L3", "SIG_W", "SIG", "Flat", "Flat") - -signal_path = (["5mm", 0], ["PCB_L", 0]) -clr = edb.modeler.create_trace(signal_path, "L3", "SIG_C*2+SIG_W", "SIG", "Flat", "Flat") -gnd_dict["L3"].add_void(clr) -# - - -# ## Place signal vias -# -# Create the via padstack definition and place the signal vias. - -edb.add_design_variable("SG_VIA_D", "1mm") -edb.add_design_variable("$VIA_AP_D", "1.2mm") -edb.padstacks.create("ANSYS_VIA", "0.3mm", "0.5mm", "$VIA_AP_D") -edb.padstacks.place(["5mm", 0], "ANSYS_VIA", "SIG") - -# Create ground vias around the SMA -# connector launch footprint. The vias -# are placed around the circumference -# of the launch from 35 degrees to 325 -# degrees. - -for i in np.arange(30, 326, 35): - px = np.cos(i / 180 * np.pi) - py = np.sin(i / 180 * np.pi) - edb.padstacks.place(["{}*{}+5mm".format("SG_VIA_D", px), "{}*{}".format("SG_VIA_D", py)], "ANSYS_VIA", "GND") - -# Create ground vias along the signal trace. - -for i in np.arange(2e-3, edb.variables["SIG_L"].value - 2e-3, 2e-3): - edb.padstacks.place(["{}+5mm".format(i), "1mm"], "ANSYS_VIA", "GND") - edb.padstacks.place(["{}+5mm".format(i), "-1mm"], "ANSYS_VIA", "GND") - -# Create a wave port at the end of the signal trace. - -signal_trace.create_edge_port("port_1", "End", "Wave", horizontal_extent_factor=10) - -# ## Set up HFSS simulation -# -# The ``max_num_passes`` argument sets an upper limit on the -# number of adaptive passes for mesh refinement. -# -# For broadband applications when the simulation results may be used -# to generate a SPICE model, the outer domain boundary can be -# located roughly $$ d=\lambda/8 $$ from the internal structures -# in the model. - -# + -extend_domain = 3e11 / 5e9 / 8.0 # Quarter wavelength at 4 GHz. -edb.design_options.antipads_always_on = True -edb.hfss.hfss_extent_info.air_box_horizontal_extent = extend_domain -edb.hfss.hfss_extent_info.air_box_positive_vertical_extent = extend_domain -edb.hfss.hfss_extent_info.air_box_negative_vertical_extent = extend_domain - -setup = edb.create_hfss_setup("Setup1") -setup.set_solution_single_frequency("5GHz", max_num_passes=8, max_delta_s="0.02") -setup.hfss_solver_settings.order_basis = "first" -# - - -# Add a mesh operation to the setup. - -edb.setups["Setup1"].add_length_mesh_operation({"SIG": ["L3"]}, "m1", max_length="0.1mm") - -# Add a frequency sweep to setup. -# -# When the simulation results are to -# be used for transient SPICE analysis, you should -# use the following strategy: -# -# - DC point -# - Logarithmic sweep from 1 kHz to 100 MHz -# - Linear scale for higher frequencies. - -setup.add_frequency_sweep( - "Sweep1", - frequency_sweep=[ - ["linear count", "0", "1KHz", 1], - ["log scale", "1KHz", "100MHz", 10], - ["linear scale", "0.1GHz", "5GHz", "0.1GHz"], - ], -) - -# Save and close EDB. - -edb.save_edb() -edb.close_edb() - -# Launch HFSS 3D Layout. - -h3d = ansys.aedt.core.Hfss3dLayout(aedb_path, specified_version=edb_version, new_desktop_session=True) - -# Place a 3D component. - -full_comp_name = download_file("component_3d", filename="SMA_RF_SURFACE_MOUNT.a3dcomp", destination=working_folder) -comp = h3d.modeler.place_3d_component( - component_path=full_comp_name, - number_of_terminals=1, - placement_layer="TOP", - component_name="my_connector", - pos_x="5mm", - pos_y=0.000, -) - -# ## Run simulation - -h3d.analyze(num_cores=4) - -# ## Visualize the return loss. - -h3d.post.create_report("dB(S(port_1, port_1))") - -# ## Save and close the project. - -h3d.save_project() -print("Project is saved to {}".format(h3d.project_path)) -h3d.release_desktop(True, True) - -# ## Clean up the temporary folder. - -temp_dir.cleanup() diff --git a/examples/legacy_pyaedt_integration/13_edb_create_component.py b/examples/legacy_pyaedt_integration/13_edb_create_component.py deleted file mode 100644 index fcf8120233..0000000000 --- a/examples/legacy_pyaedt_integration/13_edb_create_component.py +++ /dev/null @@ -1,251 +0,0 @@ -# # EDB: Layout Creation and Setup -# -# This example demonstrates how to to -# -# 1. Create a layout layer stackup. -# 2. Define padstacks. -# 3. Place padstack instances in the layout where the connectors are located. -# 4. Create primitives such as polygons and traces. -# 5. Create "components" from the padstack definitions using "pins". -# >The "component" in EDB acts as a placeholder to enable automatic -# >placement of electrical models, or -# >as in this example to assign ports. In many -# >cases the EDB is imported from a 3rd party layout, in which case the -# >concept of a "component" as a placeholder is needed to map -# >models to the components on the PCB for later use in the -# >simulation. -# 7. Create the HFSS simulation setup and assign ports where the connectors are located. - -# ## View PCB trace model -# -# Here is an image of the model that is created in this example. -# -# -# -# The rectangular sheets at each end of the PCB enable placement of ports where the connectors -# are located. - -# Initialize the EDB layout object. - -# + -import os -import tempfile - -import ansys.aedt.core - -from pyedb import Edb - -temp_dir = tempfile.TemporaryDirectory(suffix=".ansys") -aedb_path = os.path.join(temp_dir.name, "component_example.aedb") - -# Select EDB version (change it manually if needed, e.g. "2024.2") -edb_version = "2024.2" -print(f"EDB version: {edb_version}") - -edb = Edb(edbpath=aedb_path, edbversion=edb_version) -print("EDB is located at {}".format(aedb_path)) -# - - -# Initialize variables - -layout_count = 12 -diel_material_name = "FR4_epoxy" -diel_thickness = "0.15mm" -cond_thickness_outer = "0.05mm" -cond_thickness_inner = "0.017mm" -soldermask_thickness = "0.05mm" -trace_in_layer = "TOP" -trace_out_layer = "L10" -trace_width = "200um" -connector_size = 2e-3 -conectors_position = [[0, 0], [10e-3, 0]] - -# Create the stackup - -edb.stackup.create_symmetric_stackup( - layer_count=layout_count, - inner_layer_thickness=cond_thickness_inner, - outer_layer_thickness=cond_thickness_outer, - soldermask_thickness=soldermask_thickness, - dielectric_thickness=diel_thickness, - dielectric_material=diel_material_name, -) - -# Create ground planes - -ground_layers = [ - layer_name for layer_name in edb.stackup.signal_layers.keys() if layer_name not in [trace_in_layer, trace_out_layer] -] -plane_shape = edb.modeler.Shape("rectangle", pointA=["-3mm", "-3mm"], pointB=["13mm", "3mm"]) -for i in ground_layers: - edb.modeler.create_polygon(plane_shape, i, net_name="VSS") - -# ### Add design parameters -# -# Parameters that are preceded by a _"$"_ character have project-wide scope. -# Therefore, the padstack **definition** and hence all instances of that padstack -# rely on the parameters. -# -# Parameters such as _"trace_in_width"_ and _"trace_out_width"_ have local scope and -# are only used in in the design. - -edb.add_design_variable("$via_hole_size", "0.3mm") -edb.add_design_variable("$antipaddiam", "0.7mm") -edb.add_design_variable("$paddiam", "0.5mm") -edb.add_design_variable("trace_in_width", "0.2mm", is_parameter=True) -edb.add_design_variable("trace_out_width", "0.1mm", is_parameter=True) - -# ### Create the connector component -# -# The component definition is used to place the connector on the PCB. First define the padstacks. - -edb.padstacks.create_padstack( - padstackname="Via", holediam="$via_hole_size", antipaddiam="$antipaddiam", paddiam="$paddiam" -) - -# Create the first connector - -component1_pins = [ - edb.padstacks.place_padstack( - conectors_position[0], - "Via", - net_name="VDD", - fromlayer=trace_in_layer, - tolayer=trace_out_layer, - ), - edb.padstacks.place_padstack( - [ - conectors_position[0][0] - connector_size / 2, - conectors_position[0][1] - connector_size / 2, - ], - "Via", - net_name="VSS", - ), - edb.padstacks.place_padstack( - [ - conectors_position[0][0] + connector_size / 2, - conectors_position[0][1] - connector_size / 2, - ], - "Via", - net_name="VSS", - ), - edb.padstacks.place_padstack( - [ - conectors_position[0][0] + connector_size / 2, - conectors_position[0][1] + connector_size / 2, - ], - "Via", - net_name="VSS", - ), - edb.padstacks.place_padstack( - [ - conectors_position[0][0] - connector_size / 2, - conectors_position[0][1] + connector_size / 2, - ], - "Via", - net_name="VSS", - ), -] - -# Create the second connector - -component2_pins = [ - edb.padstacks.place_padstack( - conectors_position[-1], - "Via", - net_name="VDD", - fromlayer=trace_in_layer, - tolayer=trace_out_layer, - ), - edb.padstacks.place_padstack( - [ - conectors_position[1][0] - connector_size / 2, - conectors_position[1][1] - connector_size / 2, - ], - "Via", - net_name="VSS", - ), - edb.padstacks.place_padstack( - [ - conectors_position[1][0] + connector_size / 2, - conectors_position[1][1] - connector_size / 2, - ], - "Via", - net_name="VSS", - ), - edb.padstacks.place_padstack( - [ - conectors_position[1][0] + connector_size / 2, - conectors_position[1][1] + connector_size / 2, - ], - "Via", - net_name="VSS", - ), - edb.padstacks.place_padstack( - [ - conectors_position[1][0] - connector_size / 2, - conectors_position[1][1] + connector_size / 2, - ], - "Via", - net_name="VSS", - ), -] - -# ### Define pins -# -# Pins are fist defined to allow a component to subsequently connect to the remainder -# of the model. In this case, ports are assigned at the connector instances using the pins. - -for padstack_instance in list(edb.padstacks.instances.values()): - padstack_instance.is_pin = True - -# Create components from the pins - -edb.components.create(component1_pins, "connector_1") -edb.components.create(component2_pins, "connector_2") - -# Create ports on the pins and insert a simulation setup using the -# ``SimulationConfiguration`` class. - -sim_setup = edb.new_simulation_configuration() -sim_setup.solver_type = sim_setup.SOLVER_TYPE.Hfss3dLayout -sim_setup.batch_solve_settings.cutout_subdesign_expansion = 0.01 -sim_setup.batch_solve_settings.do_cutout_subdesign = False -sim_setup.batch_solve_settings.signal_nets = ["VDD"] -sim_setup.batch_solve_settings.components = ["connector_1", "connector_2"] -sim_setup.batch_solve_settings.power_nets = ["VSS"] -sim_setup.ac_settings.start_freq = "0GHz" -sim_setup.ac_settings.stop_freq = "5GHz" -sim_setup.ac_settings.step_freq = "1GHz" -edb.build_simulation_project(sim_setup) - -# Save the EDB and open it in the 3D Layout editor. If ``non_graphical==False``, -# there may be a delay while AEDT starts. - -edb.save_edb() -edb.close_edb() -h3d = ansys.aedt.core.Hfss3dLayout( - specified_version="2024.2", - projectname=aedb_path, - non_graphical=False, # Set non_graphical = False to launch AEDT in graphical mode. - new_desktop_session=True, -) - -# ### Release the application from the Python kernel -# -# It is important to release the application from the Python kernel after -# execution of the script. The default behavior of the ``release_desktop()`` method closes all open -# projects and closes the application. -# -# If you want to conintue working on the project in graphical mode -# after script execution, call the following method with both arguments set to ``False``. - -h3d.release_desktop(close_projects=True, close_desktop=True) - -# ### Clean up the temporary directory -# -# The following command cleans up the temporary directory, thereby removing all -# project files. If you'd like to save this project, save it to a folder of your choice -# prior to running the following cell. - -temp_dir.cleanup() diff --git a/examples/legacy_pyaedt_integration/14_edb_create_parametrized_design.py b/examples/legacy_pyaedt_integration/14_edb_create_parametrized_design.py deleted file mode 100644 index 3c1f081e60..0000000000 --- a/examples/legacy_pyaedt_integration/14_edb_create_parametrized_design.py +++ /dev/null @@ -1,113 +0,0 @@ -# # EDB: parameterized design -# -# This example shows how to -# 1. Set up an HFSS project using SimulationConfiguration class. -# 2. Create automatically parametrized design. -# -# This image shows the layout created in this example: -# -# -# - -# ## Import dependencies. - -import tempfile - -import ansys.aedt.core - -import pyedb -from pyedb.misc.downloads import download_file - -# ## Create an instance of a pyedb.Edb object. - -# + -temp_dir = tempfile.TemporaryDirectory(suffix=".ansys") -target_aedb = download_file("edb/ANSYS-HSD_V1.aedb", destination=temp_dir.name) -print("Project is located in ", target_aedb) - -# Select EDB version (change it manually if needed, e.g. "2024.2") -edb_version = "2024.2" -print(f"EDB version: {edb_version}") - -edb = pyedb.Edb(edbpath=target_aedb, edbversion=edb_version) -print("AEDB file is located in {}".format(target_aedb)) -# - - -# ## Prepare the layout for the simulation -# -# The ``new_simulation_configuration()`` method creates an instance of -# the ``SimulationConfiguration`` class. This class helps define all preprocessing steps -# required to set up the PCB for simulation. After the simulation configuration has been defined, -# they are applied to the EDB using the ``Edb.build_simulation()`` method. - -simulation_configuration = edb.new_simulation_configuration() -simulation_configuration.signal_nets = [ - "PCIe_Gen4_RX0_P", - "PCIe_Gen4_RX0_N", - "PCIe_Gen4_RX1_P", - "PCIe_Gen4_RX1_N", -] -simulation_configuration.power_nets = ["GND"] -simulation_configuration.components = ["X1", "U1"] -simulation_configuration.do_cutout_subdesign = True -simulation_configuration.start_freq = "OGHz" -simulation_configuration.stop_freq = "20GHz" -simulation_configuration.step_freq = "10MHz" - -# Now apply the simulation setup to the EDB. - -edb.build_simulation_project(simulation_configuration) - -# ## Parameterize -# -# The layout can automatically be set up to enable parametric studies. For example, the -# impact of antipad diameter or trace width on signal integrity performance may be invested -# parametrically. - -edb.auto_parametrize_design(layers=True, materials=True, via_holes=True, pads=True, antipads=True, traces=True) -edb.save_edb() -edb.close_edb() - -# ## Open project in AEDT -# -# All manipulations thus far have been executed using the EDB API, which provides fast, -# streamlined processing of layout data in non-graphical mode. The layout and simulation -# setup can be visualized by opening it using the 3D Layout editor in AEDT. -# -# Note that there may be some delay while AEDT is being launched. - -hfss = ansys.aedt.core.Hfss3dLayout( - projectname=target_aedb, - specified_version=edb_version, - non_graphical=False, - new_desktop_session=True, -) - -# The following cell can be used to ensure that the design is valid for simulation. - -validation_info = hfss.validate_full_design() -is_ready_to_simulate = True - -# + -for s in validation_info[0]: - if "error" in s: - print(s) - is_ready_to_simulate = False - -if is_ready_to_simulate: - print("The model is ready for simulation.") -else: - print("There are errors in the model that must be fixed.") -# - - -# ## Release the application from the Python kernel -# -# It is important to release the application from the Python kernel after -# execution of the script. The default behavior of the ``release_desktop()`` method closes all open -# projects and closes the application. -# -# If you want to continue working on the project in graphical mode -# after script execution, call the following method with both arguments set to ``False``. - -hfss.release_desktop(close_projects=True, close_desktop=True) -temp_dir.cleanup() # Remove the temporary folder and files. All data will be removd! diff --git a/examples/legacy_pyaedt_integration/15_ac_analysis.py b/examples/legacy_pyaedt_integration/15_ac_analysis.py deleted file mode 100644 index 48488cacc0..0000000000 --- a/examples/legacy_pyaedt_integration/15_ac_analysis.py +++ /dev/null @@ -1,177 +0,0 @@ -# # EDB: Network Analysis in SIwave -# -# This example shows how to use PyAEDT to set up SYZ analysis on a -# [serdes](https://en.wikipedia.org/wiki/SerDes) channel. -# The signal input is applied differetially. The positive net is _"PCIe_Gen4_TX3_CAP_P"_. -# The negative net is _"PCIe_Gen4_TX3_CAP_N"_. In this example, ports are placed on the -# driver and -# receiver components. - -# ### Perform required imports -# -# Perform required imports, which includes importing a section. - -import tempfile -import time - -import ansys.aedt.core - -import pyedb -from pyedb.misc.downloads import download_file - -# ### Download file -# -# Download the AEDB file and copy it in the temporary folder. - -# + -temp_dir = tempfile.TemporaryDirectory(suffix=".ansys") -edb_full_path = download_file("edb/ANSYS-HSD_V1.aedb", destination=temp_dir.name) -time.sleep(5) - -print(edb_full_path) -# - - -# ### Configure EDB -# -# Create an instance of the ``pyedb.Edb`` class. - -# + -# Select EDB version (change it manually if needed, e.g. "2024.2") -edb_version = "2024.2" -print(f"EDB version: {edb_version}") - -edbapp = pyedb.Edb(edbpath=edb_full_path, edbversion=edb_version) -# - - -# ### Generate extended nets -# -# An extended net consists of two nets that are connected -# through a passive component such as a resistor or capacitor. - -all_nets = edbapp.extended_nets.auto_identify_signal(resistor_below=10, inductor_below=1, capacitor_above=1e-9) - -# Review the properties of extended nets. - -# + -diff_p = edbapp.nets["PCIe_Gen4_TX3_CAP_P"] -diff_n = edbapp.nets["PCIe_Gen4_TX3_CAP_N"] - -nets_p = list(diff_p.extended_net.nets.keys()) -nets_n = list(diff_n.extended_net.nets.keys()) - -comp_p = list(diff_p.extended_net.components.keys()) -comp_n = list(diff_n.extended_net.components.keys()) - -rlc_p = list(diff_p.extended_net.rlc.keys()) -rlc_n = list(diff_n.extended_net.rlc.keys()) - -print(comp_p, rlc_p, comp_n, rlc_n, sep="\n") -# - - -# Prepare input data for port creation. - -# + -ports = [] -for net_name, net_obj in diff_p.extended_net.nets.items(): - for comp_name, comp_obj in net_obj.components.items(): - if comp_obj.type not in ["Resistor", "Capacitor", "Inductor"]: - ports.append( - { - "port_name": "{}_{}".format(comp_name, net_name), - "comp_name": comp_name, - "net_name": net_name, - } - ) - -for net_name, net_obj in diff_n.extended_net.nets.items(): - for comp_name, comp_obj in net_obj.components.items(): - if comp_obj.type not in ["Resistor", "Capacitor", "Inductor"]: - ports.append( - { - "port_name": "{}_{}".format(comp_name, net_name), - "comp_name": comp_name, - "net_name": net_name, - } - ) - -print(*ports, sep="\n") -# - - -# ### Create ports -# -# Solder balls are generated automatically. The default port type is coax port. - -for d in ports: - port_name = d["port_name"] - comp_name = d["comp_name"] - net_name = d["net_name"] - edbapp.components.create_port_on_component(component=comp_name, net_list=net_name, port_name=port_name) - -# ### Cutout -# -# Retain only relevant parts of the layout. - -nets = [] -nets.extend(nets_p) -nets.extend(nets_n) -edbapp.cutout(signal_list=nets, reference_list=["GND"], extent_type="Bounding") - -# Set up the model for network analysis in SIwave. - -setup = edbapp.create_siwave_syz_setup("setup1") -setup.add_frequency_sweep( - frequency_sweep=[ - ["linear count", "0", "1kHz", 1], - ["log scale", "1kHz", "0.1GHz", 10], - ["linear scale", "0.1GHz", "10GHz", "0.1GHz"], - ] -) - -# Save and close the EDB. - -edbapp.save() -edbapp.close_edb() - -# ### Launch Hfss3dLayout -# -# The HFSS 3D Layout user interface in AEDT is used to import the EDB and -# run the analysis. AEDT 3D Layout can be used to view the model -# if it is launched in graphical mode. - -h3d = ansys.aedt.core.Hfss3dLayout( - edb_full_path, - specified_version="2024.2", - non_graphical=False, # Set to true for non-graphical mode. - new_desktop_session=True, -) - -# Define the differential pair. - -h3d.set_differential_pair( - positive_terminal="U1_PCIe_Gen4_TX3_CAP_P", - negative_terminal="U1_PCIe_Gen4_TX3_CAP_N", - diff_name="PAIR_U1", -) -h3d.set_differential_pair( - positive_terminal="X1_PCIe_Gen4_TX3_P", - negative_terminal="X1_PCIe_Gen4_TX3_N", - diff_name="PAIR_X1", -) - -# Solve and plot the results. - -h3d.analyze(num_cores=4) - -# Visualze the results. - -h3d.post.create_report("dB(S(PAIR_U1,PAIR_U1))", context="Differential Pairs") - -# Close AEDT. - -h3d.save_project() -print("Project is saved to {}".format(h3d.project_path)) -h3d.release_desktop(True, True) - -# The following cell cleans up the temporary directory and removes all project data. - -temp_dir.cleanup() diff --git a/examples/legacy_pyaedt_integration/_static/connector_example.png b/examples/legacy_pyaedt_integration/_static/connector_example.png deleted file mode 100644 index a1083574c2..0000000000 Binary files a/examples/legacy_pyaedt_integration/_static/connector_example.png and /dev/null differ diff --git a/examples/legacy_pyaedt_integration/_static/edb_example_12_sma_connector_on_board.png b/examples/legacy_pyaedt_integration/_static/edb_example_12_sma_connector_on_board.png deleted file mode 100644 index 1226d2420d..0000000000 Binary files a/examples/legacy_pyaedt_integration/_static/edb_example_12_sma_connector_on_board.png and /dev/null differ diff --git a/examples/legacy_pyaedt_integration/_static/parameterized_design.png b/examples/legacy_pyaedt_integration/_static/parameterized_design.png deleted file mode 100644 index 80bcb84b1a..0000000000 Binary files a/examples/legacy_pyaedt_integration/_static/parameterized_design.png and /dev/null differ diff --git a/examples/legacy_pyaedt_integration/_static/pcb_transition_parameterized.png b/examples/legacy_pyaedt_integration/_static/pcb_transition_parameterized.png deleted file mode 100644 index f75d4a2e67..0000000000 Binary files a/examples/legacy_pyaedt_integration/_static/pcb_transition_parameterized.png and /dev/null differ diff --git a/examples/legacy_pyaedt_integration/index.rst b/examples/legacy_pyaedt_integration/index.rst deleted file mode 100644 index 425a0d466c..0000000000 --- a/examples/legacy_pyaedt_integration/index.rst +++ /dev/null @@ -1,17 +0,0 @@ -AEDT integration -~~~~~~~~~~~~~~~~ -The following examples illustrate the use of the legacy PyEDB API with PyAEDT. - -.. note:: - In the examples, PyAEDT is configured not to display AEDT (`non-graphical=True`). - -.. nbgallery:: - - 03_5G_antenna_example.py - 03_5G_antenna_example_parametrics.py - 04_edb_parametrized_design.py - 09_Configuration.py - 12_edb_sma_connector_on_board.py - 13_edb_create_component.py - 14_edb_create_parametrized_design.py - 15_ac_analysis.py diff --git a/examples/legacy_standalone/00_EDB_Create_VIA.py b/examples/legacy_standalone/00_EDB_Create_VIA.py deleted file mode 100644 index 0d1c63d117..0000000000 --- a/examples/legacy_standalone/00_EDB_Create_VIA.py +++ /dev/null @@ -1,83 +0,0 @@ -# # EDB: geometry creation - -# This example shows how you can use EDB to create a layout. -# ## Final expected project -# -# -# -# ## Import EDB layout object -# Import the EDB layout object and initialize it on version 2023 R2. - -# + -import os -import tempfile - -import pyedb - -temp_dir = tempfile.TemporaryDirectory(suffix=".ansys") -aedb_path = os.path.join(temp_dir.name, "create_via.aedb") -print(f"AEDB file path: {aedb_path}") - -# Select EDB version (change it manually if needed, e.g. "2024.2") -edb_version = "2024.2" -print(f"EDB version: {edb_version}") - -edb = pyedb.Edb(edbpath=aedb_path, edbversion=edb_version) -# - - -# ## Add stackup layers -# Add stackup layers. -# A stackup can be created layer by layer or imported from a CSV file or XML file. - -edb.stackup.add_layer("GND") -edb.stackup.add_layer("Diel", "GND", layer_type="dielectric", thickness="0.1mm", material="FR4_epoxy") -edb.stackup.add_layer("TOP", "Diel", thickness="0.05mm") - -# ## Create signal net and ground planes -# Create a signal net and ground planes. - -points = [[0.0, 0], [100e-3, 0.0]] -edb.modeler.create_trace(points, "TOP", width=1e-3) -points = [[0.0, 1e-3], [0.0, 10e-3], [100e-3, 10e-3], [100e-3, 1e-3], [0.0, 1e-3]] -edb.modeler.create_polygon(points, "TOP") -points = [[0.0, -1e-3], [0.0, -10e-3], [100e-3, -10e-3], [100e-3, -1e-3], [0.0, -1e-3]] -edb.modeler.create_polygon(points, "TOP") - - -# ## Create vias with parametric positions -# Create vias with parametric positions. - -edb.padstacks.create("MyVia") -edb.padstacks.place([5e-3, 5e-3], "MyVia") -edb.padstacks.place([15e-3, 5e-3], "MyVia") -edb.padstacks.place([35e-3, 5e-3], "MyVia") -edb.padstacks.place([45e-3, 5e-3], "MyVia") -edb.padstacks.place([5e-3, -5e-3], "MyVia") -edb.padstacks.place([15e-3, -5e-3], "MyVia") -edb.padstacks.place([35e-3, -5e-3], "MyVia") -edb.padstacks.place([45e-3, -5e-3], "MyVia") - - -# ## Generate geometry plot - -edb.nets.plot(None, color_by_net=True) - -# ## Generate stackup plot - -edb.stackup.plot(plot_definitions="MyVia") - -# ## Save and close EDB -# Save and close EDB. - -if edb: - edb.save_edb() - edb.close_edb() -print("EDB saved correctly to {}. You can import in AEDT.".format(aedb_path)) - -# ### Clean up temporary directory -# -# The following command removes the project and the temporary directory. -# If you'd like to save this project, save it to a folder of your choice -# prior to running the following cell. - -temp_dir.cleanup() diff --git a/examples/legacy_standalone/01_edb_example.py b/examples/legacy_standalone/01_edb_example.py deleted file mode 100644 index a7964a5edb..0000000000 --- a/examples/legacy_standalone/01_edb_example.py +++ /dev/null @@ -1,207 +0,0 @@ -# # EDB: SIwave DC-IR Analysis -# -# This example demonstrates the use of EDB to interact with a PCB -# layout and run DC-IR analysis in SIwave. -# Perform required imports - -# + -import os -import tempfile -import time - -import pyedb -from pyedb.misc.downloads import download_file - -temp_dir = tempfile.TemporaryDirectory(suffix=".ansys") -targetfile = download_file("edb/ANSYS-HSD_V1.aedb", destination=temp_dir.name) - -siwave_file = os.path.join(os.path.dirname(targetfile), "ANSYS-HSD_V1.siw") -print(targetfile) -aedt_file = targetfile[:-4] + "aedt" -# - - -# ## Launch Ansys Electronics Database (EDB) -# -# Instantiate an instance of the `pyedb.Edb` class using SI units. - -# + -if os.path.exists(aedt_file): - os.remove(aedt_file) - -# Select EDB version (change it manually if needed, e.g. "2024.2") -edb_version = "2024.2" -print(f"EDB version: {edb_version}") - -edb = pyedb.Edb(edbpath=targetfile, edbversion=edb_version) -# - - -# ## Identify nets and components -# -# The ``Edb.nets.netlist`` and ``Edb.components.instances`` properties contain information -# about all of the nets and components. The following cell uses this information to print the -# number of nets and components. - -print("Nets {}".format(len(edb.nets.netlist))) -start = time.time() -print("Components {}".format(len(edb.components.instances.keys()))) -print("elapsed time = ", time.time() - start) - -# ## Identify pin positions -# -# This code shows how to obtain all pins for a specific component and -# print the ``[x, y]`` position of each pin. - -pins = edb.components["U2"].pins -count = 0 -for pin in edb.components["U2"].pins.values(): - if count < 10: # Only print the first 10 pin coordinates. - print(pin.position) - elif count == 10: - print("...and many more.") - else: - pass - count += 1 - -# Get all nets connected to a specific component. Print -# the pin and the name of the net that it is connected to. - -connections = edb.components.get_component_net_connection_info("U2") -n_print = 0 # Counter to limit the number of printed lines. -print_max = 15 -for m in range(len(connections["pin_name"])): - ref_des = connections["refdes"][m] - pin_name = connections["pin_name"][m] - net_name = connections["net_name"][m] - if net_name != "" and (n_print < print_max): - print('{}, pin {} -> net "{}"'.format(ref_des, pin_name, net_name)) - n_print += 1 - elif n_print == print_max: - print("...and many more.") - n_print += 1 - -# Compute rats. - -rats = edb.components.get_rats() - -# ## Identify connected nets -# -# The ``get_dcconnected_net_list()`` method retrieves a list of -# all DC-connected power nets. Each group of connected nets is returned -# as a [set](https://docs.python.org/3/tutorial/datastructures.html#sets). -# The first argument to the method is the list of ground nets, which are -# not considered in the search for connected nets. - -GROUND_NETS = ["GND", "GND_DP"] -dc_connected_net_list = edb.nets.get_dcconnected_net_list(GROUND_NETS) -for pnets in dc_connected_net_list: - print(pnets) - -# ## Power Tree -# -# The power tree provides connectivity through all components from the VRM to -# the device. - -VRM = "U1" -OUTPUT_NET = "AVCC_1V3" -powertree_df, component_list_columns, net_group = edb.nets.get_powertree(OUTPUT_NET, GROUND_NETS) - -# Print some information about the power tree. - -print_columns = ["refdes", "pin_name", "component_partname"] -ncol = [component_list_columns.index(c) for c in print_columns] - -# This prints the header. Replace "pin_name" with "pin" to -# make the header align with the values. - -# + -print("\t".join(print_columns).replace("pin_name", "pin")) - -for el in powertree_df: - s = "" - count = 0 - for e in el: - if count in ncol: - s += "{}\t".format(e) - count += 1 - s.rstrip() - print(s) -# - - -# ## Remove unused components -# -# Delete all RLC components that are connected with only one pin. -# The ``Edb.components.delete_single_pin_rlc()`` method -# provides a useful way to -# remove components that are not needed for the simulation. - -edb.components.delete_single_pin_rlc() - -# You can also remove unused components explicitly by name. - -edb.components.delete("C380") - -# Nets can also be removed explicitly. - -edb.nets.delete("PDEN") - -# Print the top and bottom elevation of the stackup obtained using -# the ``Edb.stackup.limits()`` method. - -s = 'Top layer name: "{top}", Elevation: {top_el:.2f} ' -s += 'mm\nBottom layer name: "{bot}", Elevation: {bot_el:2f} mm' -top, top_el, bot, bot_el = edb.stackup.limits() -print(s.format(top=top, top_el=top_el * 1e3, bot=bot, bot_el=bot_el * 1e3)) - -# ## Set up for SIwave DCIR analysis -# -# Create a voltage source and then set up a DCIR analysis. - -edb.siwave.create_voltage_source_on_net("U1", "AVCC_1V3", "U1", "GND", 1.3, 0, "V1") -edb.siwave.create_current_source_on_net("IC2", "NetD3_2", "IC2", "GND", 1.0, 0, "I1") -setup = edb.siwave.add_siwave_dc_analysis("myDCIR_4") -setup.use_dc_custom_settings = True -setup.set_dc_slider = 0 -setup.add_source_terminal_to_ground("V1", 1) - -# ## Solve -# -# Save the modifications and run the analysis in SIwave. - -edb.save_edb() -edb.nets.plot(None, "1_Top", plot_components_on_top=True) - -siw_file = edb.solve_siwave() - -# ## Export results -# -# Export all quantities calculated from the DC-IR analysis. -# The following method runs SIwave in batch mode from the command line. -# Results are written to the edb folder. - -outputs = edb.export_siwave_dc_results( - siw_file, - setup.name, -) - -# Close EDB. After EDB is closed, it can be opened by AEDT. - -edb.close_edb() - -# ## View Layout in SIwave -# -# The SIwave user interface can be visualized and manipulated -# using the SIwave user interface. This command works on Window OS only. - -# + -# siwave = pyedb.Siwave("2024.2") -# siwave.open_project(siwave_file) -# report_file = os.path.join(temp_folder,'Ansys.htm') - -# siwave.export_siwave_report("myDCIR_4", report_file) -# siwave.close_project() -# siwave.quit_application() -# - - -# Clean up the temporary files and directory. - -temp_dir.cleanup() diff --git a/examples/legacy_standalone/02_edb_to_ipc2581.py b/examples/legacy_standalone/02_edb_to_ipc2581.py deleted file mode 100644 index a28a91045e..0000000000 --- a/examples/legacy_standalone/02_edb_to_ipc2581.py +++ /dev/null @@ -1,72 +0,0 @@ -# # EDB: IPC2581 export -# -# This example shows how you can use PyAEDT to export an IPC2581 file. -# -# Perform required imports, which includes importing a section. - -# + -import os -import tempfile - -import pyedb -from pyedb.generic.general_methods import generate_unique_name -from pyedb.misc.downloads import download_file - -# - - -# ## Download the AEDB file and copy it in the temporary folder. - -temp_dir = tempfile.TemporaryDirectory(suffix=".ansys") -targetfile = download_file("edb/ANSYS-HSD_V1.aedb", destination=temp_dir.name) -ipc2581_file_name = os.path.join(temp_dir.name, "Ansys_Hsd.xml") -print(targetfile) - -# ## Launch EDB -# -# Launch the `pyedb.Edb` class, using EDB 2023. -# > Note that length dimensions passed to EDB are in SI units. - -# + -# Select EDB version (change it manually if needed, e.g. "2024.2") -edb_version = "2024.2" -print(f"EDB version: {edb_version}") - -edb = pyedb.Edb(edbpath=targetfile, edbversion=edb_version) -# - - -# ## Parametrize the width of a trace. - -edb.modeler.parametrize_trace_width("A0_N", parameter_name=generate_unique_name("Par"), variable_value="0.4321mm") - -# ## Create a cutout and plot it. - -signal_list = [] -for net in edb.nets.netlist: - if "PCIe" in net: - signal_list.append(net) -power_list = ["GND"] -edb.cutout( - signal_list=signal_list, - reference_list=power_list, - extent_type="ConvexHull", - expansion_size=0.002, - use_round_corner=False, - number_of_threads=4, - remove_single_pin_components=True, - use_pyaedt_extent_computing=True, - extent_defeature=0, -) -edb.nets.plot(None, None, color_by_net=True) - -# ## Export the EDB to an IPC2581 file. - -edb.export_to_ipc2581(ipc2581_file_name, "inch") -print("IPC2581 File has been saved to {}".format(ipc2581_file_name)) - -# ## Close EDB - -edb.close_edb() - -# ## Clean up the temporary directory - -temp_dir.cleanup() diff --git a/examples/legacy_standalone/03_rename_nets_and_ports.py b/examples/legacy_standalone/03_rename_nets_and_ports.py deleted file mode 100644 index 2512e08d3f..0000000000 --- a/examples/legacy_standalone/03_rename_nets_and_ports.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates. -# SPDX-License-Identifier: MIT -# -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - - -# # EDB: Rename nets and ports -# -# This example shows how you can use PyEDB to rename ports and nets. - - -# ## Perform required imports -# Perform required imports, which includes importing a section. - -from pyedb import Edb -from pyedb.generic.general_methods import generate_unique_folder_name -import pyedb.misc.downloads as downloads - -# ## Download ANSYS EDB -# Download ANSYS generic design from public repository. - -temp_folder = generate_unique_folder_name() -targetfile = downloads.download_file("edb/ANSYS-HSD_V1.aedb", destination=temp_folder) - -# ## opening EDB -# Opening EDB with ANSYS release 2024.2 - -EDB_VERSION = "2024.2" -edbapp = Edb(edbpath=targetfile, edbversion=EDB_VERSION) - -# ## Renaming all signal nets -# Using the net name setter to rename. - -for net_name, net in edbapp.nets.signal.items(): - net.name = f"{net_name}_test" - -# ## Creating coaxial port on component U1 and all ddr4_dqs nets -# Selecting all nets from ddr4_dqs and component U1 and create coaxial ports -# On corresponding pins. - -comp_u1 = edbapp.components.instances["U1"] -signal_nets = [net for net in comp_u1.nets if "ddr4_dqs" in net.lower()] -edbapp.hfss.create_coax_port_on_component("U1", net_list=signal_nets) -edbapp.components.set_solder_ball(component="U1", sball_diam="0.3mm", sball_height="0.3mm") - -# ## Renaming all ports -# Renaming all port with _renamed string as suffix example. - -for port_name, port in edbapp.ports.items(): - port.name = f"{port_name}_renamed" - -# ## Saving and closing EDB -# Once the EDB saved and closed, this can be imported in ANSYS AEDT as an HFSS 3D Layout project. - -edbapp.save() -edbapp.close() diff --git a/examples/legacy_standalone/05_Plot_nets.py b/examples/legacy_standalone/05_Plot_nets.py deleted file mode 100644 index 09524e4918..0000000000 --- a/examples/legacy_standalone/05_Plot_nets.py +++ /dev/null @@ -1,65 +0,0 @@ -# # EDB: plot nets with Matplotlib -# -# This example shows how to use the ``Edb`` class to view nets, layers and -# via geometry directly in Python. The methods demonstrated in this example -# rely on -# [matplotlib](https://matplotlib.org/cheatsheets/_images/cheatsheets-1.png). - -# ## Perform required imports -# -# Perform required imports, which includes importing a section. - -# + -import tempfile - -import pyedb -from pyedb.misc.downloads import download_file - -# - - -# ## Download the EDB and copy it into the temporary folder. - -temp_dir = tempfile.TemporaryDirectory(suffix=".ansys") -targetfolder = download_file("edb/ANSYS-HSD_V1.aedb", destination=temp_dir.name) - -# ## Create an instance of the Electronics Database using the `pyedb.Edb` class. -# -# > Note that units are SI. - -# + -# Select EDB version (change it manually if needed, e.g. "2024.2") -edb_version = "2024.2" -print(f"EDB version: {edb_version}") - -edb = pyedb.Edb(edbpath=targetfolder, edbversion=edb_version) -# - - -# Display the nets on a layer. You can display the net geometry directly in Python using -# ``matplotlib`` from the ``pyedb.Edb`` class. - -edb.nets.plot("AVCC_1V3") - -# You can view multiple nets by passing a list containing the net -# names to the ``plot()`` method. - -edb.nets.plot(["GND", "GND_DP", "AVCC_1V3"], color_by_net=True) - -# You can display all copper on a single layer by passing ``None`` -# as the first argument. The second argument is a list -# of layers to plot. In this case, only one -# layer is to be displayed. - -edb.nets.plot(None, ["1_Top"], color_by_net=True, plot_components_on_top=True) - -# Display a side view of the layers and padstack geometry using the -# ``Edb.stackup.plot()`` method. - -edb.stackup.plot(scale_elevation=False, plot_definitions=["c100hn140", "c35"]) - -# Close the EDB. - -edb.close_edb() - -# Remove all files and the temporary directory. - -temp_dir.cleanup() diff --git a/examples/legacy_standalone/06_Advanced_EDB.py b/examples/legacy_standalone/06_Advanced_EDB.py deleted file mode 100644 index fda148d1e3..0000000000 --- a/examples/legacy_standalone/06_Advanced_EDB.py +++ /dev/null @@ -1,173 +0,0 @@ -# # EDB: parametric via creation -# -# This example shows how you can use EDB to create a layout. -# -# First import the required Python packages. - - -import os -import tempfile - -import numpy as np - -import pyedb - -# Create the EDB project. - -temp_dir = tempfile.TemporaryDirectory(suffix=".ansys") -aedb_path = os.path.join(temp_dir.name, "parametric_via.aedb") - -# ## Create stackup -# -# The ``StackupSimple`` class creates a stackup based on few inputs. This stackup -# is used later. -# -# Define a function to create the ground conductor. - - -def create_ground_planes(edb, layers): - plane = edb.modeler.Shape("rectangle", pointA=["-3mm", "-3mm"], pointB=["3mm", "3mm"]) - for i in layers: - edb.modeler.create_polygon(plane, i, net_name="GND") - - -# ## Create the EDB -# -# Create the EDB instance. -# If the path doesn't exist, PyEDB automatically generates a new AEDB folder. - -# + -# Select EDB version (change it manually if needed, e.g. "2024.2") -edb_version = "2024.2" -print(f"EDB version: {edb_version}") - -edb = pyedb.Edb(edbpath=aedb_path, edbversion=edb_version) -# - - -# Insert the stackup layers. - -layout_count = 12 -diel_material_name = "FR4_epoxy" -diel_thickness = "0.15mm" -cond_thickness_outer = "0.05mm" -cond_thickness_inner = "0.017mm" -soldermask_thickness = "0.05mm" -trace_in_layer = "TOP" -trace_out_layer = "L10" -gvia_num = 10 -gvia_angle = 30 -edb.stackup.create_symmetric_stackup( - layer_count=layout_count, - inner_layer_thickness=cond_thickness_inner, - outer_layer_thickness=cond_thickness_outer, - soldermask_thickness=soldermask_thickness, - dielectric_thickness=diel_thickness, - dielectric_material=diel_material_name, -) - -# ## Define parameters -# -# Define parameters to allow changes in the model dimesons. Parameters preceded by -# the ``$`` character have project-wide scope. -# Without the ``$`` prefix, the parameter scope is limited to the design. - -# + -giva_angle_rad = gvia_angle / 180 * np.pi - -edb["$via_hole_size"] = "0.3mm" -edb["$antipaddiam"] = "0.7mm" -edb["$paddiam"] = "0.5mm" -edb.add_design_variable("via_pitch", "1mm", is_parameter=True) -edb.add_design_variable("trace_in_width", "0.2mm", is_parameter=True) -edb.add_design_variable("trace_out_width", "0.1mm", is_parameter=True) -# - - -# ## Define padstacks -# -# Create two padstck definitions, one for the ground via and one for the signal via. - -edb.padstacks.create( - padstackname="SVIA", - holediam="$via_hole_size", - antipaddiam="$antipaddiam", - paddiam="$paddiam", - start_layer=trace_in_layer, - stop_layer=trace_out_layer, -) -edb.padstacks.create(padstackname="GVIA", holediam="0.3mm", antipaddiam="0.7mm", paddiam="0.5mm") - -# Place the signal via. - -edb.padstacks.place([0, 0], "SVIA", net_name="RF") - -# Place the ground vias. - -# + -gvia_num_side = gvia_num / 2 - -if gvia_num_side % 2: - # Even number of ground vias on each side - edb.padstacks.place(["via_pitch", 0], "GVIA", net_name="GND") - edb.padstacks.place(["via_pitch*-1", 0], "GVIA", net_name="GND") - for i in np.arange(1, gvia_num_side / 2): - xloc = "{}*{}".format(np.cos(giva_angle_rad * i), "via_pitch") - yloc = "{}*{}".format(np.sin(giva_angle_rad * i), "via_pitch") - edb.padstacks.place([xloc, yloc], "GVIA", net_name="GND") - edb.padstacks.place([xloc, yloc + "*-1"], "GVIA", net_name="GND") - - edb.padstacks.place([xloc + "*-1", yloc], "GVIA", net_name="GND") - edb.padstacks.place([xloc + "*-1", yloc + "*-1"], "GVIA", net_name="GND") -else: - # Odd number of ground vias on each side - for i in np.arange(0, gvia_num_side / 2): - xloc = "{}*{}".format(np.cos(giva_angle_rad * (i + 0.5)), "via_pitch") - yloc = "{}*{}".format(np.sin(giva_angle_rad * (i + 0.5)), "via_pitch") - edb.padstacks.place([xloc, yloc], "GVIA", net_name="GND") - edb.padstacks.place([xloc, yloc + "*-1"], "GVIA", net_name="GND") - - edb.padstacks.place([xloc + "*-1", yloc], "GVIA", net_name="GND") - edb.padstacks.place([xloc + "*-1", yloc + "*-1"], "GVIA", net_name="GND") -# - - -# Draw the traces - -# + -edb.modeler.create_trace( - [[0, 0], [0, "-3mm"]], - layer_name=trace_in_layer, - net_name="RF", - width="trace_in_width", - start_cap_style="Flat", - end_cap_style="Flat", -) - -edb.modeler.create_trace( - [[0, 0], [0, "3mm"]], - layer_name=trace_out_layer, - net_name="RF", - width="trace_out_width", - start_cap_style="Flat", - end_cap_style="Flat", -) -# - - -# Draw ground conductors - -ground_layers = [i for i in edb.stackup.signal_layers.keys()] -ground_layers.remove(trace_in_layer) -ground_layers.remove(trace_out_layer) -create_ground_planes(edb=edb, layers=ground_layers) - -# Display the layout - -edb.stackup.plot(plot_definitions=["GVIA", "SVIA"]) - -# Save EDB and close the EDB. - -edb.save_edb() -edb.close_edb() -print("aedb Saved in {}".format(aedb_path)) - -# Clean up the temporary directory. - -temp_dir.cleanup() diff --git a/examples/legacy_standalone/08_CPWG.py b/examples/legacy_standalone/08_CPWG.py deleted file mode 100644 index a0d9e88551..0000000000 --- a/examples/legacy_standalone/08_CPWG.py +++ /dev/null @@ -1,192 +0,0 @@ -# # EDB: fully parametrized CPWG design - -# This example shows how you can use HFSS 3D Layout to create a parametric design -# for a CPWG (coplanar waveguide with ground). - - -# ## Perform required imports - -# Perform required imports. Importing the ``Hfss3dlayout`` object initializes it -# on version 2023 R2. - -import os - -import ansys.aedt.core -import numpy as np - -from pyedb import Edb -from pyedb.generic.general_methods import ( - generate_unique_folder_name, - generate_unique_name, -) - -# ## Set non-graphical mode - -# Set non-graphical mode. The default is ``False``. - -non_graphical = False - -# ## Launch EDB - -# + -aedb_path = os.path.join(generate_unique_folder_name(), generate_unique_name("pcb") + ".aedb") -print(aedb_path) - -# Select EDB version (change it manually if needed, e.g. "2024.2") -edb_version = "2024.2" -print(f"EDB version: {edb_version}") -aedt_version = edb_version - -edbapp = Edb(edbpath=aedb_path, edbversion=edb_version) -# - - -# ## Define parameters - -params = { - "$ms_width": "0.4mm", - "$ms_clearance": "0.3mm", - "$ms_length": "20mm", -} -for par_name in params: - edbapp.add_project_variable(par_name, params[par_name]) - - -# ## Create s symmetric stackup - -edbapp.stackup.create_symmetric_stackup(2) -edbapp.stackup.plot() - -# ## Draw planes - -# + -plane_lw_pt = ["0mm", "-3mm"] -plane_up_pt = ["$ms_length", "3mm"] - -top_layer_obj = edbapp.modeler.create_rectangle( - "TOP", net_name="gnd", lower_left_point=plane_lw_pt, upper_right_point=plane_up_pt -) -bot_layer_obj = edbapp.modeler.create_rectangle( - "BOTTOM", net_name="gnd", lower_left_point=plane_lw_pt, upper_right_point=plane_up_pt -) -layer_dict = {"TOP": top_layer_obj, "BOTTOM": bot_layer_obj} -# - - -# ## Draw a trace - -trace_path = [["0", "0"], ["$ms_length", "0"]] -edbapp.modeler.create_trace( - trace_path, - layer_name="TOP", - width="$ms_width", - net_name="sig", - start_cap_style="Flat", - end_cap_style="Flat", -) - -# ## Create a trace to plane clearance - -poly_void = edbapp.modeler.create_trace( - trace_path, - layer_name="TOP", - net_name="gnd", - width="{}+2*{}".format("$ms_width", "$ms_clearance"), - start_cap_style="Flat", - end_cap_style="Flat", -) -edbapp.modeler.add_void(layer_dict["TOP"], poly_void) - -# ## Create a ground via padstack and place ground stitching vias - -# + -edbapp.padstacks.create( - padstackname="GVIA", - holediam="0.3mm", - paddiam="0.5mm", -) - -yloc_u = "$ms_width/2+$ms_clearance+0.25mm" -yloc_l = "-$ms_width/2-$ms_clearance-0.25mm" - -for i in np.arange(1, 20): - edbapp.padstacks.place([str(i) + "mm", yloc_u], "GVIA", net_name="GND") - edbapp.padstacks.place([str(i) + "mm", yloc_l], "GVIA", net_name="GND") -# - - -# ## Save and close EDB - -edbapp.save_edb() -edbapp.close_edb() - -# ## Open EDB in AEDT - -aedt_version = edb_version - -h3d = ansys.aedt.core.Hfss3dLayout( - projectname=aedb_path, - specified_version=aedt_version, - non_graphical=non_graphical, - new_desktop_session=True, -) - -# ## Create wave ports - -h3d.create_edge_port("line_3", 0, iswave=True, wave_vertical_extension=10, wave_horizontal_extension=10) -h3d.create_edge_port("line_3", 2, iswave=True, wave_vertical_extension=10, wave_horizontal_extension=10) - -# ## Edit airbox extents - -h3d.edit_hfss_extents(air_vertical_positive_padding="10mm", air_vertical_negative_padding="1mm") - -# ## Create setup - -setup = h3d.create_setup() -setup["MaxPasses"] = 2 -setup["AdaptiveFrequency"] = "3GHz" -setup["SaveAdaptiveCurrents"] = True -h3d.create_linear_count_sweep( - setupname=setup.name, - unit="GHz", - freqstart=0, - freqstop=5, - num_of_freq_points=1001, - sweepname="sweep1", - sweep_type="Interpolating", - interpolation_tol_percent=1, - interpolation_max_solutions=255, - save_fields=False, - use_q3d_for_dc=False, -) - -# ## Plot layout - -# + -h3d.modeler.edb.nets.plot(None, None, color_by_net=True) - -cp_name = h3d.modeler.clip_plane() -# - - -# ## Solve the active design - -# Uncomment the following code to start the HFSS solver and perform post processing. - -# + -# h3d.analyze() - -# solutions = h3d.get_touchstone_data()[0] -# solutions.log_x = False -# solutions.plot() - -# h3d.post.create_fieldplot_cutplane( -# cp_name, "Mag_E", h3d.nominal_adaptive, intrinsincDict={"Freq": "3GHz", "Phase": "0deg"} -# ) -# - - -# ## Save AEDT - -aedt_path = aedb_path.replace(".aedb", ".aedt") -h3d.logger.info("Your AEDT project is saved to {}".format(aedt_path)) -h3d.save_project() - -# ## Release AEDT - -h3d.release_desktop() diff --git a/examples/legacy_standalone/10_GDS_workflow.py b/examples/legacy_standalone/10_GDS_workflow.py deleted file mode 100644 index 13525ee49b..0000000000 --- a/examples/legacy_standalone/10_GDS_workflow.py +++ /dev/null @@ -1,118 +0,0 @@ -# # EDB: Edit Control File and import gds -# -# This example demonstrates how to import a gds layout for subsequent -# simulation with HFSS. - -# Perform imports. - -# + -import os -import shutil -import tempfile - -import pyedb -from pyedb.dotnet.edb_core.edb_data.control_file import ControlFile -from pyedb.misc.downloads import download_file - -# - - -# ## Fetch Example Data -# -# Download the EDB folder and copy it to a temporary folder. -# The following files are used in this example: -# -# - _sky130_fictious_dtc_exmple_contol_no_map.xml_ -# defines physical information such -# as material properties, stackup layers, and boundary conditions. -# - _dummy_layermap.map_ -# maps properties to stackup layers. - -# + -temp_dir = tempfile.TemporaryDirectory(suffix=".ansys") -control_fn = "sky130_fictitious_dtc_example_control_no_map.xml" -gds_fn = "sky130_fictitious_dtc_example.gds" -layer_map = "dummy_layermap.map" - -local_path = download_file("gds", destination=temp_dir.name) -c_file_in = os.path.join(local_path, control_fn) -c_map = os.path.join(local_path, layer_map) -gds_in = os.path.join(local_path, gds_fn) -gds_out = os.path.join(temp_dir.name, "gds_out.gds") -shutil.copy2(gds_in, gds_out) -# - - -# ## Control file -# -# A Control file is an xml file which purpose if to provide additional information during -# import phase. It can include, materials, stackup, setup, boundaries and settings. -# In this example we will import an existing xml, integrate it with a layer mapping file of gds -# and then adding setup and boundaries. - -c = ControlFile(c_file_in, layer_map=c_map) - -# ## Set up simulation -# -# This code sets up a simulation with HFSS and adds a frequency sweep. - -setup = c.setups.add_setup("Setup1", "1GHz") -setup.add_sweep("Sweep1", "0.01GHz", "5GHz", "0.1GHz") - -# ## Provide additional stackup settings -# -# After import, you can change the stackup settings and add or remove layers or materials. - -c.stackup.units = "um" -c.stackup.dielectrics_base_elevation = -100 -c.stackup.metal_layer_snapping_tolerance = "10nm" -for via in c.stackup.vias: - via.create_via_group = True - via.snap_via_group = True - -# ## Define boundary settings -# -# Boundaries can include ports, components and boundary extent. - -c.boundaries.units = "um" -c.boundaries.add_port("P1", x1=223.7, y1=222.6, layer1="Metal6", x2=223.7, y2=100, layer2="Metal6") -c.boundaries.add_extent() -comp = c.components.add_component("B1", "BGA", "IC", "Flip chip", "Cylinder") -comp.solder_diameter = "65um" -comp.add_pin("1", "81.28", "84.6", "met2") -comp.add_pin("2", "211.28", "84.6", "met2") -comp.add_pin("3", "211.28", "214.6", "met2") -comp.add_pin("4", "81.28", "214.6", "met2") -c.import_options.import_dummy_nets = True - -# ## Write XML file -# -# After all settings are ready, you can write an XML file. - -c.write_xml(os.path.join(temp_dir.name, "output.xml")) - -# ## Open EDB -# -# Import the gds and open the edb. - -# + -# Select EDB version (change it manually if needed, e.g. "2024.2") -edb_version = "2024.2" -print(f"EDB version: {edb_version}") - -edb = pyedb.Edb(gds_out, edbversion=edb_version, technology_file=os.path.join(temp_dir.name, "output.xml")) -# - - -# ## Plot stackup -# -# Plot the stackup. - -edb.stackup.plot(first_layer="met1") - -# ## Close EDB -# -# Close the project. - -edb.close_edb() - -# Clean up the temporary folder. - -temp_dir.cleanup() diff --git a/examples/legacy_standalone/11_post_layout_parameterization.py b/examples/legacy_standalone/11_post_layout_parameterization.py deleted file mode 100644 index eaf8d54fbd..0000000000 --- a/examples/legacy_standalone/11_post_layout_parameterization.py +++ /dev/null @@ -1,93 +0,0 @@ -# # EDB: post-layout parameterization -# -# This example shows you how to parameterize the signal net in post-layout. -# -# Define input parameters. - -signal_net_name = "DDR4_ALERT3" -coplanar_plane_net_name = "1V0" # Specify name of coplanar plane net for adding clearance -layers = ["16_Bottom"] # Specify layers to parameterize - -# Perform required imports. - -# + -import os -import tempfile - -import pyedb -from pyedb.misc.downloads import download_file - -temp_dir = tempfile.TemporaryDirectory(suffix=".ansys") - -# Download and open example layout file in edb format. - -edb_path = download_file("edb/ANSYS-HSD_V1.aedb", destination=temp_dir.name) - -# Select EDB version (change it manually if needed, e.g. "2024.2") -edb_version = "2024.2" -print(f"EDB version: {edb_version}") - -edb = pyedb.Edb(edb_path, edbversion=edb_version) -# - - -# ## Create cutout -# -# The ``Edb.cutout()`` method takes a list of -# signal nets as the first argument and a list of -# reference nets as the second argument. - -edb.cutout([signal_net_name], [coplanar_plane_net_name, "GND"], remove_single_pin_components=True) - -# Retrieve the path segments from the signal net. - -net = edb.nets[signal_net_name] -trace_segments = [] -for p in net.primitives: - if p.layer_name not in layers: - continue - if not p.type == "Path": - continue - trace_segments.append(p) - -# Create and assign delta w variable per layer. - -for p in trace_segments: - vname = f"{p.net_name}_{p.layer_name}_dw" - if vname not in edb.variables: - edb[vname] = "0mm" - new_w = f"{p.width}+{vname}" - p.width = new_w - -# Delete existing clearance. - -for p in trace_segments: - for g in edb.modeler.get_polygons_by_layer(p.layer_name, coplanar_plane_net_name): - for v in g.voids: - if p.is_intersecting(v): - v.delete() - -# Create and assign the clearance variable for each layer. - -for p in trace_segments: - clr = f"{p.net_name}_{p.layer_name}_clr" - if clr not in edb.variables: - edb[clr] = "0.5mm" - path = p.get_center_line() - for g in edb.modeler.get_polygons_by_layer(p.layer_name, coplanar_plane_net_name): - void = edb.modeler.create_trace(path, p.layer_name, f"{p.width}+{clr}*2") - g.add_void(void) - -# Visualize the layout. - -edb.nets.plot(layers=layers[0], size=2000) - -# Save the AEDB file and close EDB. - -save_edb_path = os.path.join(temp_dir.name, "post_layout_parameterization.aedb") -edb.save_edb_as(save_edb_path) -print("Edb is saved to ", save_edb_path) -edb.close_edb() - -# Clean up the temporary folder. - -temp_dir.cleanup() diff --git a/examples/legacy_standalone/_static/diff_via.png b/examples/legacy_standalone/_static/diff_via.png deleted file mode 100644 index d444d1ccbe..0000000000 Binary files a/examples/legacy_standalone/_static/diff_via.png and /dev/null differ diff --git a/examples/legacy_standalone/index.rst b/examples/legacy_standalone/index.rst deleted file mode 100644 index f09e33c442..0000000000 --- a/examples/legacy_standalone/index.rst +++ /dev/null @@ -1,15 +0,0 @@ -Standalone -~~~~~~~~~~ -The following examples illustrate the use of the legacy PyEDB API as a standalone package. - -.. nbgallery:: - - 00_EDB_Create_VIA.py - 01_edb_example.py - 02_edb_to_ipc2581.py - 03_rename_nets_and_ports.py - 05_Plot_nets.py - 06_Advanced_EDB.py - 08_CPWG.py - 10_GDS_workflow.py - 11_post_layout_parameterization.py diff --git a/examples/use_configuration/import_components.py b/examples/use_configuration/import_components.py deleted file mode 100644 index d0fe989c67..0000000000 --- a/examples/use_configuration/import_components.py +++ /dev/null @@ -1,119 +0,0 @@ -# # Import Component Definitions -# This example shows how to import component definitions. It includes -# -# - Download an example board -# - Create a config file with component RLC and solder ball information -# - Apply the config file to the example board - -# ## Import the required packages - -# + -import json -from pathlib import Path -import tempfile - -from IPython.display import display -from ansys.aedt.core.downloads import download_file -import pandas as pd - -from pyedb import Edb - -AEDT_VERSION = "2024.2" - -# - - -# Download the example PCB data. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys").name -file_edb = download_file(source="edb/ANSYS-HSD_V1.aedb", destination=temp_folder) - -# ## Load example layout. - -edbapp = Edb(file_edb, edbversion=AEDT_VERSION) - -# ## Create a config file with component information - -# Keywords -# -# - **reference_designator**. Reference designator of the component. -# - **part_type**. Part type of the component. Supported types are 'resistor', 'inductor', 'capacitor', 'ic', 'io', -# 'other'. -# - **enabled**. Only available for RLC components. -# - **solder_ball_properties**. -# - **shape**. Supported types are 'cylinder', 'spheroid', 'none'. -# - **diameter**. -# - **mid_diameter**. -# - **height**. -# - **port_properties**. -# - **reference_offset**. -# - **reference_size_auto**. -# - **reference_size_x**. -# - **reference_size_y**. -# - **pin_pair_model**. RLC network. Multiple pin pairs are supported. -# - **first_pin**. First pin of the pin pair. -# - **second_pin**. Second pin of the pin pair. -# - **is_parallel**. -# - **resistance**. -# - **resistance_enabled**. -# - **inductance**. -# - **inductance_enabled**. -# - **capacitance**. -# - **capacitance_enabled**. - -cfg = dict() -cfg["components"] = [ - { - "reference_designator": "U1", - "part_type": "io", - "solder_ball_properties": { - "shape": "spheroid", - "diameter": "244um", - "mid_diameter": "400um", - "height": "300um", - }, - "port_properties": { - "reference_offset": "0.1mm", - "reference_size_auto": True, - "reference_size_x": 0, - "reference_size_y": 0, - }, - }, - { - "reference_designator": "C375", - "enabled": False, - "pin_pair_model": [ - { - "first_pin": "1", - "second_pin": "2", - "is_parallel": False, - "resistance": "10ohm", - "resistance_enabled": True, - "inductance": "1nH", - "inductance_enabled": False, - "capacitance": "10nF", - "capacitance_enabled": True, - } - ], - }, -] - -display(pd.DataFrame(data=[cfg["components"][0]["solder_ball_properties"]])) - -display(pd.DataFrame(data=[cfg["components"][0]["port_properties"]])) - -display(pd.DataFrame(data=cfg["components"][1]["pin_pair_model"])) - -cfg_file_path = Path(temp_folder) / "cfg.json" -with open(cfg_file_path, "w") as f: - json.dump(cfg, f, indent=4, ensure_ascii=False) - -# Load config file - -edbapp.configuration.load(cfg_file_path, apply_file=True) - -# ## Save and close Edb -# The temporary folder will be deleted once the execution of this script is finished. Replace **edbapp.save()** with -# **edbapp.save_as("C:/example.aedb")** to keep the example project. - -edbapp.save() -edbapp.close() diff --git a/examples/use_configuration/import_material.py b/examples/use_configuration/import_material.py deleted file mode 100644 index efbd65d08c..0000000000 --- a/examples/use_configuration/import_material.py +++ /dev/null @@ -1,81 +0,0 @@ -# # Import Materials -# This example shows how to import materials. - -# ### Import the required packages - -# + -import json -from pathlib import Path -import tempfile - -from IPython.display import display -from ansys.aedt.core.downloads import download_file -import pandas as pd - -from pyedb import Edb - -AEDT_VERSION = "2024.2" -NG_MODE = False - -# - - -# Download the example PCB data. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") -file_edb = download_file(source="edb/ANSYS-HSD_V1.aedb", destination=temp_folder.name) - -# ## Load example layout. - -edbapp = Edb(file_edb, edbversion=AEDT_VERSION) - -# ## Review materials from layout - -# Get materials from layout in a dictionary. Materials are exported together with stadckup. - -data_cfg = edbapp.configuration.get_data_from_db(stackup=True) - - -df = pd.DataFrame(data=data_cfg["stackup"]["materials"]) -display(df) - -# ## Add a new material - -data_cfg["stackup"]["materials"].append( - {"name": "soldermask", "permittivity": 3.3, "dielectric_loss_tangent": 0.02}, -) - -# ## Edit existing material properties - -data_cfg["stackup"]["materials"][1]["name"] = "fr4_epoxy" -data_cfg["stackup"]["materials"][1]["dielectric_loss_tangent"] = 0.015 - -# ## Review modified materials - -df = pd.DataFrame(data=data_cfg["stackup"]["materials"]) -display(df) - -# ## Write material definition into a json file - -file_cfg = Path(temp_folder.name) / "edb_configuration.json" -with open(file_cfg, "w") as f: - json.dump(data_cfg, f, indent=4, ensure_ascii=False) - - -# ## Load materials from json configuration file - -edbapp.configuration.load(str(file_cfg), apply_file=True) - -# ## Review materials from layout - -edbapp.materials.materials - -# ## Check modified material properties - -edbapp.materials["fr4_epoxy"].loss_tangent - -# ## Save and close Edb -# The temporary folder will be deleted once the execution of this script is finished. Replace **edbapp.save()** with -# **edbapp.save_as("C:/example.aedb")** to keep the example project. - -edbapp.save() -edbapp.close() diff --git a/examples/use_configuration/import_padstack_definitions.py b/examples/use_configuration/import_padstack_definitions.py deleted file mode 100644 index 3ea55a4e4d..0000000000 --- a/examples/use_configuration/import_padstack_definitions.py +++ /dev/null @@ -1,138 +0,0 @@ -# # Import Padstack Definitions -# This example shows how to import padstack definitions. This includes -# -# - Download an example board -# - Create a config file with hole information -# - Create a config file with pad and anti-pad information - -# ## Import the required packages - -# + -import json -from pathlib import Path -import tempfile - -from IPython.display import display -from ansys.aedt.core.downloads import download_file -import pandas as pd - -from pyedb import Edb - -AEDT_VERSION = "2024.2" - -# - - -# Download the example PCB data. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys").name -file_edb = download_file(source="edb/ANSYS-HSD_V1.aedb", destination=temp_folder) - -# ## Load example layout. - -edbapp = Edb(file_edb, edbversion=AEDT_VERSION) - -# ## Create a config file with hole information - -# Keywords -# -# - **name**. Name of the padstack definition. -# - **hole_plating_thickness**. Hole plating thickness. -# - **hole_range**. Supported types are 'through', 'begin_on_upper_pad', 'end_on_lower_pad', 'upper_pad_to_lower_pad'. -# - **hole_parameters**. -# - **shape**. Supported types are 'circle', 'square', 'rectangle'. -# - Other parameters are shape dependent. -# - When shape is 'circle', supported parameter si 'diameter'. -# - When shape is 'square', supported parameter is 'size'. -# - When shape is 'rectangle', supported parameters are 'x_size', 'y_size'. - -cfg = dict() -cfg["padstacks"] = {} -cfg["padstacks"]["definitions"] = [ - { - "name": "v35h15", - "hole_plating_thickness": "25um", - "material": "copper", - "hole_range": "through", - "hole_parameters": { - "shape": "circle", - "diameter": "0.15mm", - }, - } -] - -df = pd.DataFrame(data=cfg["padstacks"]["definitions"]) -display(df) - -cfg_file_path = Path(temp_folder) / "cfg.json" -with open(cfg_file_path, "w") as f: - json.dump(cfg, f, indent=4, ensure_ascii=False) - -# Load config file - -edbapp.configuration.load(cfg_file_path, apply_file=True) - -# ## Create a config file with pad information - -# Keywords -# -# - **name**. Name of the padstack definition. -# - **pad_parameters**. -# - **regular_pad**. List of pad definition per layer. -# - **layer_name**. Name of the layer. -# - **shape**. Supported types are 'circle', 'square', 'rectangle', 'oval', 'bullet'. -# - Other parameters are shape dependent. -# - When shape is 'circle', supported parameter si 'diameter'. -# - When shape is 'square', supported parameter is 'size'. -# - When shape is 'rectangle', supported parameters are 'x_size', 'y_size'. -# - When shape is 'oval', supported parameters are 'x_size', 'y_size', 'corner_radius'. -# - When shape is 'bullet', supported parameters are 'x_size', 'y_size', 'corner_radius'. - -cfg = dict() -cfg["padstacks"] = {} -cfg["padstacks"]["definitions"] = [ - { - "name": "v35h15", - "pad_parameters": { - "regular_pad": [ - { - "layer_name": "1_Top", - "shape": "circle", - "offset_x": "0.1mm", - "offset_y": "0.1mm", - "rotation": "0", - "diameter": "0.5mm", - }, - { - "layer_name": "Inner1(GND1)", - "shape": "square", - "offset_x": "0.1mm", - "offset_y": "0.1mm", - "rotation": "45deg", - "size": "0.5mm", - }, - ], - "anti_pad": [{"layer_name": "1_Top", "shape": "circle", "diameter": "1mm"}], - }, - } -] - -df = pd.DataFrame(data=cfg["padstacks"]["definitions"][0]["pad_parameters"]["regular_pad"]) -display(df) - -df = pd.DataFrame(data=cfg["padstacks"]["definitions"][0]["pad_parameters"]["anti_pad"]) -display(df) - -cfg_file_path = Path(temp_folder) / "cfg.json" -with open(cfg_file_path, "w") as f: - json.dump(cfg, f, indent=4, ensure_ascii=False) - -# Load config file - -edbapp.configuration.load(cfg_file_path, apply_file=True) - -# ## Save and close Edb -# The temporary folder will be deleted once the execution of this script is finished. Replace edbapp.save() with -# edbapp.save_as("C:/example.aedb") to keep the example project. - -edbapp.save() -edbapp.close() diff --git a/examples/use_configuration/import_ports.py b/examples/use_configuration/import_ports.py deleted file mode 100644 index 748faf3a2e..0000000000 --- a/examples/use_configuration/import_ports.py +++ /dev/null @@ -1,161 +0,0 @@ -# # Import Ports -# This example shows how to import ports. In this example, we are going to -# -# - Download an example board -# - Create a configuration file -# - Add a circuit port between two nets -# - Add a circuit port between two pins -# - Add a circuit port between two pin groups -# - Add a circuit port between two coordinates -# - Add a coax port -# - Add a port reference to the nearest pin -# - Add distributed ports -# - Import the configuration file - -# ## Import the required packages - -# + -import json -from pathlib import Path -import tempfile - -from ansys.aedt.core.downloads import download_file - -from pyedb import Edb - -AEDT_VERSION = "2024.2" -NG_MODE = False - -# - - -# Download the example PCB data. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") -file_edb = download_file(source="edb/ANSYS-HSD_V1.aedb", destination=temp_folder.name) - -# ## Load example layout - -edbapp = Edb(file_edb, edbversion=AEDT_VERSION) - -# ## Create an empty dictionary to host all configurations - -cfg = dict() - -# ## Add a circuit port between two nets - -# Keywords -# -# - **name**. Name of the port. -# - **Reference_designator**. Reference designator of the component. -# - **type**. Type of the port. Supported types are 'circuit', 'coax' -# - **positive_terminal**. Positive terminal of the port. Supported types are 'net', 'pin', 'pin_group', 'coordinates' -# - **negative_terminal**. Negative terminal of the port. Supported types are 'net', 'pin', 'pin_group', 'coordinates', -# 'nearest_pin' - -port_1 = { - "name": "port_1", - "reference_designator": "X1", - "type": "circuit", - "positive_terminal": {"net": "PCIe_Gen4_TX2_N"}, - "negative_terminal": {"net": "GND"}, -} - -# ## Add a circuit port between two pins - -port_2 = { - "name": "port_2", - "reference_designator": "C375", - "type": "circuit", - "positive_terminal": {"pin": "1"}, - "negative_terminal": {"pin": "2"}, -} - -# ## Add a circuit port between two pin groups - -pin_groups = [ - {"name": "U9_5V_1", "reference_designator": "U9", "pins": ["32", "33"]}, - {"name": "U9_GND", "reference_designator": "U9", "net": "GND"}, -] - -port_3 = { - "name": "port_3", - "type": "circuit", - "positive_terminal": {"pin_group": "U9_5V_1"}, - "negative_terminal": {"pin_group": "U9_GND"}, -} - -# ## Add a circuit port between two coordinates - -# Keywords -# -# - **layer**. Layer on which the terminal is placed -# - **point**. XY coordinate the terminal is placed -# - **net**. Name of the net the terminal is placed on - -port_4 = { - "name": "port_4", - "type": "circuit", - "positive_terminal": {"coordinates": {"layer": "1_Top", "point": ["104mm", "37mm"], "net": "AVCC_1V3"}}, - "negative_terminal": {"coordinates": {"layer": "Inner6(GND2)", "point": ["104mm", "37mm"], "net": "GND"}}, -} - -# ## Add a coax port - -port_5 = {"name": "port_5", "reference_designator": "U1", "type": "coax", "positive_terminal": {"pin": "AM17"}} - -# ## Add a port reference to the nearest pin - -# Keywords -# -# - **reference_net**. Name of the reference net -# - **search_radius**. Reference pin search radius in meter - -port_6 = { - "name": "port_6", - "reference_designator": "U15", - "type": "circuit", - "positive_terminal": {"pin": "D7"}, - "negative_terminal": {"nearest_pin": {"reference_net": "GND", "search_radius": 5e-3}}, -} - -# ## Add distributed ports - -# Keywords -# -# - **distributed**. Whether to create distributed ports. When set to True, ports are created per pin - -ports_distributed = { - "name": "ports_d", - "reference_designator": "U7", - "type": "circuit", - "distributed": True, - "positive_terminal": {"net": "VDD_DDR"}, - "negative_terminal": {"net": "GND"}, -} - -# ## Add setups in configuration - -cfg["pin_groups"] = pin_groups -cfg["ports"] = [port_1, port_2, port_3, port_4, port_5, port_6, ports_distributed] - -# ## Write configuration into as json file - -file_json = Path(temp_folder.name) / "edb_configuration.json" -with open(file_json, "w") as f: - json.dump(cfg, f, indent=4, ensure_ascii=False) - -# ## Import configuration into example layout - -edbapp.configuration.load(config_file=file_json) -edbapp.configuration.run() - -# ## Review - -edbapp.ports - -# ## Save and close Edb -# The temporary folder will be deleted once the execution of this script is finished. Replace **edbapp.save()** with -# **edbapp.save_as("C:/example.aedb")** to keep the example project. - -edbapp.save() -edbapp.close() diff --git a/examples/use_configuration/import_setup_ac.py b/examples/use_configuration/import_setup_ac.py deleted file mode 100644 index f494ec0cc1..0000000000 --- a/examples/use_configuration/import_setup_ac.py +++ /dev/null @@ -1,142 +0,0 @@ -# # Import Setup AC -# This example shows how to import SIwave, HFSS setups for AC analysis. In this example, we are going to -# -# - Download an example board -# - Create a configuration file -# - add setups -# - Import the configuration file - -# ### Import the required packages - -# + -import json -from pathlib import Path -import tempfile - -from ansys.aedt.core.downloads import download_file - -from pyedb import Edb - -AEDT_VERSION = "2024.2" -NG_MODE = False - -# - - -# Download the example PCB data. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") -file_edb = download_file(source="edb/ANSYS-HSD_V1.aedb", destination=temp_folder.name) - -# ## Load example layout. - -edbapp = Edb(file_edb, edbversion=AEDT_VERSION) - -# ## Create an empty dictionary to host all configurations. - -cfg = dict() - -# ## Create an SIwave SYZ setup - -# Keywords -# -# - **name**. Name of the setup. -# - **type**. Type of the analysis setup. Supported types are 'siwave_ac', 'siwave_dc', 'hfss'. -# - **pi_slider_position**. PI slider position. Supported values are from '0', '1', '2'. 0:speed, 1:balanced, -# 2:accuracy. -# - **freq_sweep**. List of frequency sweeps. -# - **name**. Name of the sweep. -# - **type**. Type of the sweep. Supported types are 'interpolation', 'discrete', 'broadband'. -# - **frequencies**. Frequency distribution. -# - **distribution**. Supported distributions are 'linear_count', 'linear_scale', 'log_scale'. -# - **start**. Start frequency. Example, 1e6, "1MHz". -# - **stop**. Stop frequency. Example, 1e9, "1GHz". -# - **increment**. - -siwave_setup = { - "name": "siwave_1", - "type": "siwave_ac", - "pi_slider_position": 1, - "freq_sweep": [ - { - "name": "Sweep1", - "type": "interpolation", - "frequencies": [{"distribution": "log_scale", "start": 1e6, "stop": 1e9, "increment": 20}], - } - ], -} - -# ## Create a HFSS setup - -# Keywords -# -# - **name**. Name of the setup. -# - **type**. Type of the analysis setup. Supported types are 'siwave_ac', 'siwave_dc', 'hfss'. -# - **f_adapt**. Adaptive frequency. -# - **max_num_passes**. Maximum number of passes. -# - **max_mag_delta_s**. Convergence criteria delta S. -# - **mesh_operations**. Mesh operations. -# - **name**. Name of the mesh operation. -# - **type**. Type of the mesh operation. The supported types are 'base', 'length', 'skin_depth'. -# - **max_length**. Maximum length of elements. -# - **restrict_length**. Whether to restrict length of elements. -# - **refine_inside**. Whether to turn on refine inside objects. -# - **nets_layers_list**. {'layer_name':['net_name_1', 'net_name_2']} -# - **freq_sweep**. List of frequency sweeps. -# - **name**. Name of the sweep. -# - **type**. Type of the sweep. Supported types are 'interpolation', 'discrete', 'broadband'. -# - **frequencies**. Frequency distribution. -# - **distribution**. Supported distributions are 'linear_count', 'linear_scale', 'log_scale'. -# - **start**. Start frequency. Example, 1e6, "1MHz". -# - **stop**. Stop frequency. Example, 1e9, "1GHz". -# - **increment**. - -hfss_setup = { - "name": "hfss_1", - "type": "hfss", - "f_adapt": "5GHz", - "max_num_passes": 10, - "max_mag_delta_s": 0.02, - "mesh_operations": [ - { - "name": "mop_1", - "type": "length", - "max_length": "3mm", - "restrict_length": True, - "refine_inside": False, - "nets_layers_list": {"GND": ["1_Top", "16_Bottom"]}, - } - ], - "freq_sweep": [ - { - "name": "Sweep1", - "type": "interpolation", - "frequencies": [{"distribution": "log_scale", "start": 1e6, "stop": 1e9, "increment": 20}], - } - ], -} - -# ## Add setups in configuration - -cfg["setups"] = [siwave_setup, hfss_setup] - -# ## Write configuration into as json file - -file_json = Path(temp_folder.name) / "edb_configuration.json" -with open(file_json, "w") as f: - json.dump(cfg, f, indent=4, ensure_ascii=False) - -# ## Import configuration into example layout - -edbapp.configuration.load(config_file=file_json) -edbapp.configuration.run() - -# ## Review - -edbapp.setups - -# ## Save and close Edb -# The temporary folder will be deleted once the execution of this script is finished. Replace **edbapp.save()** with -# **edbapp.save_as("C:/example.aedb")** to keep the example project. - -edbapp.save() -edbapp.close() diff --git a/examples/use_configuration/import_sources.py b/examples/use_configuration/import_sources.py deleted file mode 100644 index 7bf6472e1f..0000000000 --- a/examples/use_configuration/import_sources.py +++ /dev/null @@ -1,163 +0,0 @@ -# # Import Sources -# This example shows how to import voltage and current sources. In this example, we are going to -# -# - Download an example board -# - Create a configuration file -# - Add a voltage source between two nets -# - Add a current source between two pins -# - Add a current source between two pin groups -# - Add a current source between two coordinates -# - Add a current source to the nearest pin -# - Add distributed sources -# - Import the configuration file - -# ## Import the required packages - -# + -import json -from pathlib import Path -import tempfile - -from ansys.aedt.core.downloads import download_file - -from pyedb import Edb - -AEDT_VERSION = "2024.2" -NG_MODE = False - -# - - -# Download the example PCB data. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") -file_edb = download_file(source="edb/ANSYS-HSD_V1.aedb", destination=temp_folder.name) - -# ## Load example layout - -edbapp = Edb(file_edb, edbversion=AEDT_VERSION) - -# ## Create an empty dictionary to host all configurations - -cfg = dict() - -# ## Add a voltage source between two nets - -# Keywords -# -# - **name**. Name of the voltage source. -# - **Reference_designator**. Reference designator of the component. -# - **type**. Type of the source. Supported types are 'voltage', 'current' -# - **positive_terminal**. Supported types are 'net', 'pin', 'pin_group', 'coordinates' -# - **negative_terminal**. Supported types are 'net', 'pin', 'pin_group', 'coordinates', -# 'nearest_pin' - -voltage_source = { - "name": "V_SOURCE_5V", - "reference_designator": "U4", - "type": "circuit", - "positive_terminal": {"net": "5V"}, - "negative_terminal": {"net": "GND"}, -} - -# ## Add a current source between two pins - -current_source_1 = { - "name": "I_CURRENT_1A", - "reference_designator": "J5", - "type": "current", - "positive_terminal": {"pin": "15"}, - "negative_terminal": {"pin": "14"}, -} - -# ## Add a current source between two pin groups - -pin_groups = [ - {"name": "IC2_5V", "reference_designator": "IC2", "pins": ["8"]}, - {"name": "IC2_GND", "reference_designator": "IC2", "net": "GND"}, -] - -current_source_2 = { - "name": "CURRENT_SOURCE_2", - "type": "current", - "positive_terminal": {"pin_group": "IC2_5V"}, - "negative_terminal": {"pin_group": "IC2_GND"}, -} - -# ## Add a current source between two coordinates - -# Keywords -# -# - **layer**. Layer on which the terminal is placed -# - **point**. XY coordinate the terminal is placed -# - **net**. Name of the net the terminal is placed on - -current_source_3 = { - "name": "CURRENT_SOURCE_3", - "type": "current", - "positive_terminal": {"coordinates": {"layer": "1_Top", "point": ["116mm", "41mm"], "net": "5V"}}, - "negative_terminal": {"coordinates": {"layer": "Inner1(GND1)", "point": ["116mm", "41mm"], "net": "GND"}}, -} - -# ## Add a current source reference to the nearest pin - -# Keywords -# -# - **reference_net**. Name of the reference net -# - **search_radius**. Reference pin search radius in meter - -current_source_4 = { - "name": "CURRENT_SOURCE_4", - "reference_designator": "J5", - "type": "current", - "positive_terminal": {"pin": "16"}, - "negative_terminal": {"nearest_pin": {"reference_net": "GND", "search_radius": 5e-3}}, -} - -# ## Add distributed current sources - -# Keywords -# -# - **distributed**. Whether to create distributed sources. When set to True, ports are created per pin - -sources_distributed = { - "name": "DISTRIBUTED", - "reference_designator": "U2", - "type": "current", - "distributed": True, - "positive_terminal": {"net": "5V"}, - "negative_terminal": {"net": "GND"}, -} - -# ## Add setups in configuration - -cfg["pin_groups"] = pin_groups -cfg["sources"] = [ - voltage_source, - current_source_1, - current_source_2, - current_source_3, - current_source_4, - sources_distributed, -] - -# ## Write configuration into as json file - -file_json = Path(temp_folder.name) / "edb_configuration.json" -with open(file_json, "w") as f: - json.dump(cfg, f, indent=4, ensure_ascii=False) - -# ## Import configuration into example layout - -edbapp.configuration.load(config_file=file_json) -edbapp.configuration.run() - -# ## Review - -edbapp.siwave.sources - -# ## Save and close Edb -# The temporary folder will be deleted once the execution of this script is finished. Replace **edbapp.save()** with -# **edbapp.save_as("C:/example.aedb")** to keep the example project. - -edbapp.save() -edbapp.close() diff --git a/examples/use_configuration/import_stackup.py b/examples/use_configuration/import_stackup.py deleted file mode 100644 index 446d5f4e8f..0000000000 --- a/examples/use_configuration/import_stackup.py +++ /dev/null @@ -1,83 +0,0 @@ -# # Import Stackup -# This example shows how to import stackup file. - -# ## Import the required packages - -# + -import json -from pathlib import Path -import tempfile - -from IPython.display import display -from ansys.aedt.core.downloads import download_file -import pandas as pd - -from pyedb import Edb - -AEDT_VERSION = "2024.2" -NG_MODE = False - -# - - -# Download the example PCB data. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") -file_edb = download_file(source="edb/ANSYS-HSD_V1.aedb", destination=temp_folder.name) - -# ## Load example layout. - -edbapp = Edb(file_edb, edbversion=AEDT_VERSION) - -# ## Review original stackup definition - -# Get original stackup definition in a dictionary. Alternatively, stackup definition can be exported in a json file by -# edbapp.configuration.export() - -data_cfg = edbapp.configuration.get_data_from_db(stackup=True) - - -df = pd.DataFrame(data=data_cfg["stackup"]["layers"]) -display(df) - -# ## Modify stackup - -# Modify top layer thickness - -data_cfg["stackup"]["layers"][0]["thickness"] = 0.00005 - -# Add a solder mask layer - -data_cfg["stackup"]["layers"].insert( - 0, {"name": "soler_mask", "type": "dielectric", "material": "Megtron4", "fill_material": "", "thickness": 0.00002} -) - -# Review modified stackup - -df = pd.DataFrame(data=data_cfg["stackup"]["layers"]) -display(df.head(3)) - -# Write stackup definition into a json file - -file_cfg = Path(temp_folder.name) / "edb_configuration.json" -with open(file_cfg, "w") as f: - json.dump(data_cfg, f, indent=4, ensure_ascii=False) - - -# ## Load stackup from json configuration file - -edbapp.configuration.load(file_cfg, apply_file=True) - -# Plot stackup - -edbapp.stackup.plot() - -# Check top layer thickness - -edbapp.stackup["1_Top"].thickness - -# ## Save and close Edb -# The temporary folder will be deleted once the execution of this script is finished. Replace **edbapp.save()** with -# **edbapp.save_as("C:/example.aedb")** to keep the example project. - -edbapp.save() -edbapp.close() diff --git a/examples/use_configuration/index.rst b/examples/use_configuration/index.rst index f8378e2376..73783eeed9 100644 --- a/examples/use_configuration/index.rst +++ b/examples/use_configuration/index.rst @@ -7,18 +7,5 @@ End-to-end workflow .. nbgallery:: - pdn_analysis.py serdes.py -Step explanation -------------------------- - -.. nbgallery:: - - import_stackup.py - import_material.py - import_ports.py - import_setup_ac.py - import_padstack_definitions.py - import_components.py - import_sources.py diff --git a/examples/use_configuration/pdn_analysis.py b/examples/use_configuration/pdn_analysis.py deleted file mode 100644 index ef6a44014d..0000000000 --- a/examples/use_configuration/pdn_analysis.py +++ /dev/null @@ -1,178 +0,0 @@ -# # Set up EDB for Power Distribution Network Analysis -# This example shows how to set up the electronics database (EDB) for power integrity analysis from a single -# configuration file. - -# ## Import the required packages - -import json - -# + -import os -import tempfile - -from ansys.aedt.core import Hfss3dLayout -from ansys.aedt.core.downloads import download_file - -from pyedb import Edb - -AEDT_VERSION = "2024.2" -NG_MODE = False - -# - - -# Download the example PCB data. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") -download_file(source="touchstone", name="GRM32_DC0V_25degC_series.s2p", destination=temp_folder.name) -file_edb = download_file(source="edb/ANSYS-HSD_V1.aedb", destination=temp_folder.name) - -# ## Load example layout - -edbapp = Edb(file_edb, edbversion=AEDT_VERSION) - -# ## Create an empty dictionary to host all configurations - -cfg = dict() - -# ## Assign S-parameter model to capactitors. - -# Set S-parameter library path. - -cfg["general"] = {"s_parameter_library": os.path.join(temp_folder.name, "touchstone")} - -# Assign the S-parameter model. -# -# Keywords -# -# - **name**. Name of the S-parameter model in AEDT. -# - **component**_definition. Known as component part number of part name. -# - **file_path**. Touchstone file or full path to the touchstone file. -# - **apply_to_all**. When set to True, assign the S-parameter model to all components share the same -# component_definition. When set to False, Only components in "components" are assigned. -# - **components**. when apply_to_all=False, components in the list are assigned an S-parameter model. -# When apply_to_all=False, components in the list are NOT assigned. -# - **reference_net**. Reference net of the S-parameter model. - -cfg["s_parameters"] = [ - { - "name": "GRM32_DC0V_25degC_series", - "component_definition": "CAPC0603X33X15LL03T05", - "file_path": "GRM32_DC0V_25degC_series.s2p", - "apply_to_all": False, - "components": ["C110", "C206"], - "reference_net": "GND", - } -] - -# ## Define ports -# Create a circuit port between power and ground nets. -# -# Keywords -# -# - **name**. Name of the port. -# - **reference_desinator**. -# - **type**. Type of the port. Supported types are 'ciruict', 'coax'. -# - **positive_terminal**. Positive terminal of the port. Supported types are 'net', 'pin', 'pin_group', 'coordinates'. -# - **negative_terminal**. Positive terminal of the port. Supported types are 'net', 'pin', 'pin_group', 'coordinates'. - -cfg["ports"] = [ - { - "name": "port1", - "reference_designator": "U1", - "type": "circuit", - "positive_terminal": {"net": "1V0"}, - "negative_terminal": {"net": "GND"}, - } -] - -# ## Define SIwave SYZ analysis setup -# -# Keywords -# -# - **name**. Name of the setup. -# - **type**. Type of the analysis setup. Supported types are 'siwave_ac', 'siwave_dc', 'hfss'. -# - **pi_slider_position**. PI slider position. Supported values are from '0', '1', '2'. 0:speed, 1:balanced, -# 2:accuracy. -# - **freq_sweep**. List of frequency sweeps. -# - **name**. Name of the sweep. -# - **type**. Type of the sweep. Supported types are 'interpolation', 'discrete', 'broadband'. -# - **frequencies**. Frequency distribution. -# - **distribution**. Supported distributions are 'linear_count', 'linear_scale', 'log_scale'. -# - **start**. Start frequency. Example, 1e6, "1MHz". -# - **stop**. Stop frequency. Example, 1e9, "1GHz". -# - **increment**. - -cfg["setups"] = [ - { - "name": "siwave_syz", - "type": "siwave_ac", - "pi_slider_position": 1, - "freq_sweep": [ - { - "name": "Sweep1", - "type": "interpolation", - "frequencies": [{"distribution": "log_scale", "start": 1e6, "stop": 1e9, "increment": 20}], - } - ], - } -] - -# ## Define Cutout -# -# Keywords -# -# - **signal_list**. List of nets to be kept after cutout. -# - **reference_list**. List of nets as reference planes. -# - **extent_type**. Supported extend types are 'Conforming', 'ConvexHull', 'Bounding'. -# For optional input arguments, refer to method pyedb.Edb.cutout() - -cfg["operations"] = { - "cutout": { - "signal_list": ["1V0"], - "reference_list": ["GND"], - "extent_type": "ConvexHull", - } -} - -# ## Write configuration into as json file - -file_json = os.path.join(temp_folder.name, "edb_configuration.json") -with open(file_json, "w") as f: - json.dump(cfg, f, indent=4, ensure_ascii=False) - -# ## Import configuration into example layout - -edbapp.configuration.load(config_file=file_json) - -# Apply configuration to EDB. - -edbapp.configuration.run() - -# Save and close EDB. - -edbapp.save() -edbapp.close() - -# The configured EDB file is saved in a temp folder. - -print(temp_folder.name) - -# ## Load edb into HFSS 3D Layout. - -h3d = Hfss3dLayout(edbapp.edbpath, version=AEDT_VERSION, non_graphical=NG_MODE, new_desktop=True) - -# ## Analyze - -h3d.analyze() - -# ## Plot impedance - -solutions = h3d.post.get_solution_data(expressions="Z(port1,port1)") -solutions.plot() - -# ## Shut Down Electronics Desktop - -h3d.close_desktop() - -# All project files are saved in the folder ``temp_file.dir``. If you've run this example as a Jupyter notebook you -# can retrieve those project files. diff --git a/src/pyedb/generic/plot.py b/src/pyedb/generic/plot.py index 5b436f8338..3e7073b1c5 100644 --- a/src/pyedb/generic/plot.py +++ b/src/pyedb/generic/plot.py @@ -14,11 +14,11 @@ from matplotlib.patches import PathPatch from matplotlib.path import Path - # Use matplotlib agg backend (non-interactive) when the CI is running. + # Use matplotlib TkAgg backend (interactive) when the CI is running. if bool(int(os.getenv("PYEDB_CI_NO_DISPLAY", "0"))): # pragma: no cover import matplotlib - matplotlib.use("Agg") + matplotlib.use("TkAgg") import matplotlib.pyplot as plt except ImportError: