diff --git a/doc/source/conf.py b/doc/source/conf.py index d6d9c1465e..077f22cdde 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -367,6 +367,7 @@ def setup(app): "examples/use_configuration/import_setup_ac": "_static/thumbnails/101_getting_started.png", "examples/use_configuration/import_padstack_definitions": "_static/thumbnails/101_getting_started.png", "examples/use_configuration/import_components": "_static/thumbnails/101_getting_started.png", + "examples/use_configuration/import_sources": "_static/thumbnails/101_getting_started.png", } nbsphinx_custom_formats = { diff --git a/examples/use_configuration/import_ports.py b/examples/use_configuration/import_ports.py index d625c87c46..9bcf7f8697 100644 --- a/examples/use_configuration/import_ports.py +++ b/examples/use_configuration/import_ports.py @@ -8,7 +8,7 @@ # - 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 neareast pin +# - Add a port reference to the nearest pin # - Add distributed ports # - Import the configuration file @@ -48,7 +48,7 @@ # - **name**. Name of the port. # - **Reference_designator**. Reference designator of the component. # - **type**. Type of the port. Supported types are 'circuit', 'coax' -# - **positve_terminal**. Positive terminal of the port. Supported types are 'net', 'pin', 'pin_group', 'coordinates' +# - **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' diff --git a/examples/use_configuration/import_sources.py b/examples/use_configuration/import_sources.py new file mode 100644 index 0000000000..7bf6472e1f --- /dev/null +++ b/examples/use_configuration/import_sources.py @@ -0,0 +1,163 @@ +# # 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/index.rst b/examples/use_configuration/index.rst index e9257852d6..8012729af7 100644 --- a/examples/use_configuration/index.rst +++ b/examples/use_configuration/index.rst @@ -20,3 +20,4 @@ Step explanation import_setup_ac.py import_padstack_definitions.py import_components.py + import_sources.py diff --git a/pyproject.toml b/pyproject.toml index 46be5d9856..b00daae875 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,11 +59,11 @@ doc = [ "pypandoc>=1.10.0,<1.15", # NOTE: Remove recommonmark once examples are reworked. "recommonmark", - "Sphinx>=7.1.0,<8.1", + "Sphinx>=7.1.0,<8.2", "sphinx-autobuild==2021.3.14; python_version == '3.8'", "sphinx-autobuild==2024.10.3; python_version > '3.8'", "sphinx-copybutton>=0.5.0,<0.6", - "sphinx-gallery>=0.14.0,<0.18", + "sphinx-gallery>=0.14.0,<0.19", "sphinx_design>=0.4.0,<0.7", ] full = [ diff --git a/src/pyedb/__init__.py b/src/pyedb/__init__.py index a03101cc88..b8cb9e1325 100644 --- a/src/pyedb/__init__.py +++ b/src/pyedb/__init__.py @@ -70,7 +70,7 @@ def custom_show_warning(message, category, filename, lineno, file=None, line=Non # pyedb_path = os.path.dirname(__file__) -__version__ = "0.30.dev0" +__version__ = "0.32.dev0" version = __version__ # diff --git a/src/pyedb/configuration/cfg_operations.py b/src/pyedb/configuration/cfg_operations.py index 19e7c0f12e..9d7701ce10 100644 --- a/src/pyedb/configuration/cfg_operations.py +++ b/src/pyedb/configuration/cfg_operations.py @@ -60,10 +60,11 @@ def get_data_from_db(self): net_names = [] for name, obj in self._pedb.nets.nets.items(): - if obj.primitives[0].layer.name == "pyedb_cutout": - continue - if len(obj.primitives) > 0: - net_names.append(name) + if obj.primitives: + if obj.primitives[0].layer.name == "pyedb_cutout": + continue + else: + net_names.append(name) self.reference_list = [] self.signal_list = net_names diff --git a/src/pyedb/dotnet/edb_core/layout_validation.py b/src/pyedb/dotnet/edb_core/layout_validation.py index 866a0adb3b..cfd6fb86ac 100644 --- a/src/pyedb/dotnet/edb_core/layout_validation.py +++ b/src/pyedb/dotnet/edb_core/layout_validation.py @@ -332,9 +332,7 @@ def padstacks_no_name(self, fix=False): counts += 1 if fix: if not obj.component: - obj._edb_object.SetProductProperty( - self._pedb.edb_api.ProductId.Designer, 11, f"via_{via_count}" - ) + obj._edb_object.SetProductProperty(self._pedb.edb_api.ProductId.Designer, 11, f"Via{via_count}") via_count = via_count + 1 else: obj._edb_object.SetProductProperty( diff --git a/src/pyedb/dotnet/edb_core/materials.py b/src/pyedb/dotnet/edb_core/materials.py index 94de6c53e9..9ebf884a33 100644 --- a/src/pyedb/dotnet/edb_core/materials.py +++ b/src/pyedb/dotnet/edb_core/materials.py @@ -69,6 +69,7 @@ "dc_conductivity", "dc_permittivity", ] +PERMEABILITY_DEFAULT_VALUE = 1 def get_line_float_value(line): @@ -507,6 +508,9 @@ def add_material(self, name: str, **kwargs): material_def = self.__edb_definition.MaterialDef.Create(self.__edb.active_db, name) material = Material(self.__edb, material_def) + # Apply default values to the material + if "permeability" not in kwargs: + kwargs["permeability"] = PERMEABILITY_DEFAULT_VALUE attributes_input_dict = {key: val for (key, val) in kwargs.items() if key in ATTRIBUTES + DC_ATTRIBUTES} if "loss_tangent" in kwargs: # pragma: no cover warnings.warn( diff --git a/tests/legacy/system/test_edb_materials.py b/tests/legacy/system/test_edb_materials.py index 1b084274a1..fc6ab5d18a 100644 --- a/tests/legacy/system/test_edb_materials.py +++ b/tests/legacy/system/test_edb_materials.py @@ -27,7 +27,12 @@ import pytest -from pyedb.dotnet.edb_core.materials import Material, MaterialProperties, Materials +from pyedb.dotnet.edb_core.materials import ( + PERMEABILITY_DEFAULT_VALUE, + Material, + MaterialProperties, + Materials, +) from tests.conftest import local_path pytestmark = [pytest.mark.system, pytest.mark.legacy] @@ -171,7 +176,9 @@ def test_materials_add_material(self): material = materials.add_material(MATERIAL_NAME, permittivity=12) assert material - material.name == materials[MATERIAL_NAME].name + assert material.name == materials[MATERIAL_NAME].name + # Check default values + assert material.permeability == PERMEABILITY_DEFAULT_VALUE with pytest.raises(ValueError): materials.add_material(MATERIAL_NAME, permittivity=12) @@ -181,7 +188,9 @@ def test_materials_add_conductor_material(self): material = materials.add_conductor_material(MATERIAL_NAME, 12, permittivity=12) assert material - _ = materials[MATERIAL_NAME] + assert material.name == materials[MATERIAL_NAME].name + # Check default values + assert material.permeability == PERMEABILITY_DEFAULT_VALUE with pytest.raises(ValueError): materials.add_conductor_material(MATERIAL_NAME, 12, permittivity=12) @@ -191,7 +200,9 @@ def test_materials_add_dielectric_material(self): material = materials.add_dielectric_material(MATERIAL_NAME, 12, 12, conductivity=12) assert material - _ = materials[MATERIAL_NAME] + assert material.name == materials[MATERIAL_NAME].name + # Check default values + assert material.permeability == PERMEABILITY_DEFAULT_VALUE with pytest.raises(ValueError): materials.add_dielectric_material(MATERIAL_NAME, 12, 12, conductivity=12) @@ -203,7 +214,9 @@ def test_materials_add_djordjevicsarkar_dielectric(self): MATERIAL_NAME, 4.3, 0.02, 9, dc_conductivity=1e-12, dc_permittivity=5, conductivity=0 ) assert material - _ = materials[MATERIAL_NAME] + assert material.name == materials[MATERIAL_NAME].name + # Check default values + assert material.permeability == PERMEABILITY_DEFAULT_VALUE with pytest.raises(ValueError): materials.add_djordjevicsarkar_dielectric( MATERIAL_NAME, 4.3, 0.02, 9, dc_conductivity=1e-12, dc_permittivity=5, conductivity=0 @@ -215,7 +228,9 @@ def test_materials_add_debye_material(self): material = materials.add_debye_material(MATERIAL_NAME, 6, 4, 0.02, 0.05, 1e9, 10e9, conductivity=0) assert material - _ = materials[MATERIAL_NAME] + assert material.name == materials[MATERIAL_NAME].name + # Check default values + assert material.permeability == PERMEABILITY_DEFAULT_VALUE with pytest.raises(ValueError): materials.add_debye_material(MATERIAL_NAME, 6, 4, 0.02, 0.05, 1e9, 10e9, conductivity=0) @@ -230,7 +245,9 @@ def test_materials_add_multipole_debye_material(self): MATERIAL_NAME, frequencies, relative_permitivities, loss_tangents, conductivity=0 ) assert material - _ = materials[MATERIAL_NAME] + assert material.name == materials[MATERIAL_NAME].name + # Check default values + assert material.permeability == PERMEABILITY_DEFAULT_VALUE with pytest.raises(ValueError): materials.add_multipole_debye_material( MATERIAL_NAME, frequencies, relative_permitivities, loss_tangents, conductivity=0