pyedb
Advanced tools
| # Copyright (C) 2023 - 2026 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. | ||
| from ansys.edb.core.simulation_setup.hfss_pi_simulation_settings import ( | ||
| HFSSPIGeneralSettings as CoreHFSSPIGeneralSettings, | ||
| HFSSPIModelType as CoreHFSSPIModelType, | ||
| HFSSPISimulationPreference as CoreHFSSPISimulationPreference, | ||
| SurfaceRoughnessModel as CoreSurfaceRoughnessModel, | ||
| ) | ||
| _mapping_model_type = { | ||
| "pcb": CoreHFSSPIModelType.PCB, | ||
| "rdl": CoreHFSSPIModelType.RDL, | ||
| "package": CoreHFSSPIModelType, | ||
| } | ||
| _mapping_simulation_preference = { | ||
| "balanced": CoreHFSSPISimulationPreference.BALANCED, | ||
| "accuracy": CoreHFSSPISimulationPreference.ACCURACY, | ||
| } | ||
| _mapping_surface_roughness = { | ||
| "exponential": CoreSurfaceRoughnessModel.EXPONENTIAL, | ||
| "hammerstad": CoreSurfaceRoughnessModel.HAMMERSTAD, | ||
| "": CoreSurfaceRoughnessModel.NONE, | ||
| } | ||
| class HFSSPIGeneralSettings: | ||
| """PyEDB HFSS PI general settings class.""" | ||
| def __init__(self, pedb, core: "CoreHFSSPIGeneralSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def include_enhanced_bondwire_modeling(self) -> bool: | ||
| """Flag indicating whether to include enhanced bondwire modeling. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if include enhanced bondwire modeling is enabled, False otherwise. | ||
| """ | ||
| return self.core.include_enhanced_bondwire_modeling | ||
| @include_enhanced_bondwire_modeling.setter | ||
| def include_enhanced_bondwire_modeling(self, value: bool): | ||
| self.core.include_enhanced_bondwire_modeling = value | ||
| @property | ||
| def min_plane_area_to_mesh(self) -> str: | ||
| """(General Mode Only) The minimum plane area to mesh. | ||
| Returns | ||
| ------- | ||
| str | ||
| Minimum plane area to mesh as a string with units (e.g., "0.1mm2"). | ||
| """ | ||
| return self.core.min_plane_area_to_mesh | ||
| @min_plane_area_to_mesh.setter | ||
| def min_plane_area_to_mesh(self, value: str): | ||
| self.core.min_plane_area_to_mesh = value | ||
| @property | ||
| def min_void_area_to_mesh(self) -> str: | ||
| """(General Mode Only) The minimum void area to mesh. | ||
| Returns | ||
| ------- | ||
| str | ||
| Minimum void area to mesh as a string with units (e.g., "0.1mm2"). | ||
| """ | ||
| return self.core.min_void_area_to_mesh | ||
| @min_void_area_to_mesh.setter | ||
| def min_void_area_to_mesh(self, value: str): | ||
| self.core.min_void_area_to_mesh = value | ||
| @property | ||
| def model_type(self) -> str: | ||
| """Get the model type. | ||
| Returns | ||
| ------- | ||
| str | ||
| The model type. | ||
| """ | ||
| for key, val in _mapping_model_type.items(): | ||
| if val == self.core.model_type: | ||
| return key | ||
| return "unknown" # Fallback in case of an unmapped type | ||
| @model_type.setter | ||
| def model_type(self, value: str): | ||
| if value.lower() in _mapping_model_type: | ||
| self.core.model_type = _mapping_model_type[value.lower()] | ||
| else: | ||
| raise ValueError(f"Invalid model type: {value}. Valid options are: {list(_mapping_model_type.keys())}") | ||
| @property | ||
| def perform_erc(self) -> bool: | ||
| """(General Mode Only) Flag indicating whether to perform error checking while generating the solver input file. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if perform ERC is enabled, False otherwise. | ||
| """ | ||
| return self.core.perform_erc | ||
| @perform_erc.setter | ||
| def perform_erc(self, value: bool): | ||
| self.core.perform_erc = value | ||
| @property | ||
| def rms_surface_roughness(self) -> str: | ||
| """The RMS surface roughness. | ||
| Returns | ||
| ------- | ||
| str | ||
| RMS surface roughness as a string with units (e.g., "0.5um"). | ||
| """ | ||
| return self.core.rms_surface_roughness | ||
| @rms_surface_roughness.setter | ||
| def rms_surface_roughness(self, value: str): | ||
| self.core.rms_surface_roughness = value | ||
| @property | ||
| def simulation_preference(self) -> str: | ||
| """Get the simulation preference. | ||
| Returns | ||
| ------- | ||
| str | ||
| The simulation preference. | ||
| """ | ||
| for key, val in _mapping_simulation_preference.items(): | ||
| if val == self.core.simulation_preference: | ||
| return key | ||
| return "unknown" # Fallback in case of an unmapped type | ||
| @simulation_preference.setter | ||
| def simulation_preference(self, value: str): | ||
| if value.lower() in _mapping_simulation_preference: | ||
| self.core.simulation_preference = _mapping_simulation_preference[value.lower()] | ||
| else: | ||
| raise ValueError( | ||
| f"Invalid simulation preference: {value}. " | ||
| f"Valid options are: {list(_mapping_simulation_preference.keys())}" | ||
| ) | ||
| @property | ||
| def snap_length_threshold(self) -> str: | ||
| """(General Mode Only) The snap length threshold. | ||
| Returns | ||
| ------- | ||
| str | ||
| Snap length threshold as a string with units (e.g., "0.1mm"). | ||
| """ | ||
| return self.core.snap_length_threshold | ||
| @snap_length_threshold.setter | ||
| def snap_length_threshold(self, value: str): | ||
| self.core.snap_length_threshold = value | ||
| @property | ||
| def surface_roughness_model(self) -> str: | ||
| """Get the surface roughness model. | ||
| Returns | ||
| ------- | ||
| str | ||
| The surface roughness model. | ||
| """ | ||
| for key, val in _mapping_surface_roughness.items(): | ||
| if val == self.core.surface_roughness_model: | ||
| return key | ||
| return "unknown" # Fallback in case of an unmapped type | ||
| @surface_roughness_model.setter | ||
| def surface_roughness_model(self, value: str): | ||
| if value.lower() in _mapping_surface_roughness: | ||
| self.core.surface_roughness_model = _mapping_surface_roughness[value.lower()] | ||
| else: | ||
| raise ValueError( | ||
| f"Invalid surface roughness model: {value}. " | ||
| f"Valid options are: {list(_mapping_surface_roughness.keys())}" | ||
| ) |
| # Copyright (C) 2023 - 2026 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. | ||
| from ansys.edb.core.simulation_setup.hfss_pi_simulation_settings import ( | ||
| HFSSPINetProcessingSettings as CoreHFSSPINetProcessingSettings, | ||
| ) | ||
| class HFSSPINetProcessingSettings: | ||
| """PyEDB HFSS PI net processing settings class.""" | ||
| def __init__(self, pedb, core: "CoreHFSSPINetProcessingSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def auto_select_nets_for_simulation(self) -> bool: | ||
| """Flag indicating whether to automatically select nets for simulation. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if auto select nets for simulation is enabled, False otherwise. | ||
| """ | ||
| return self.core.auto_select_nets_for_simulation | ||
| @auto_select_nets_for_simulation.setter | ||
| def auto_select_nets_for_simulation(self, value: bool): | ||
| self.core.auto_select_nets_for_simulation = value | ||
| @property | ||
| def ignore_dummy_nets_for_selected_nets(self) -> bool: | ||
| """Flag indicating whether to ignore dummy nets for selected nets. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if ignore dummy nets for selected nets is enabled, False otherwise. | ||
| """ | ||
| return self.core.ignore_dummy_nets_for_selected_nets | ||
| @ignore_dummy_nets_for_selected_nets.setter | ||
| def ignore_dummy_nets_for_selected_nets(self, value: bool): | ||
| self.core.ignore_dummy_nets_for_selected_nets = value | ||
| @property | ||
| def include_nets(self) -> list[str]: | ||
| """List of nets to include in the simulation. | ||
| Returns | ||
| ------- | ||
| list[str] | ||
| List of net names to include. | ||
| """ | ||
| return self.core.include_nets | ||
| @include_nets.setter | ||
| def include_nets(self, value: list[str]): | ||
| self.core.include_nets = value |
| # Copyright (C) 2023 - 2026 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. | ||
| from ansys.edb.core.simulation_setup.hfss_pi_simulation_settings import ( | ||
| HFSSPIPowerGroundNetsSettings as CoreHFSSPIPowerGroundNetsSettings, | ||
| ) | ||
| class HFSSPIPowerGroundNetsSettings: | ||
| """PyEDB HFSS PI Power/Ground Nets settings class.""" | ||
| def __init__(self, pedb, core: "CoreHFSSPIPowerGroundNetsSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def auto_detect_ignore_small_holes_min_diameter(self) -> bool: | ||
| """Flag indicating whether to automatically detect a diameter that holes smaller than the diameter | ||
| will be ignored. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if auto-detect ignore small holes minimum diameter is enabled, False otherwise. | ||
| """ | ||
| return self.core.auto_detect_ignore_small_holes_min_diameter | ||
| @auto_detect_ignore_small_holes_min_diameter.setter | ||
| def auto_detect_ignore_small_holes_min_diameter(self, value: bool): | ||
| self.core.auto_detect_ignore_small_holes_min_diameter = value | ||
| @property | ||
| def ignore_small_holes_min_diameter(self) -> str: | ||
| """Diameter that holes smaller than the diameter will be ignored. | ||
| Returns | ||
| ------- | ||
| str | ||
| Minimum diameter for holes to be ignored. | ||
| """ | ||
| return self.core.ignore_small_holes_min_diameter | ||
| @ignore_small_holes_min_diameter.setter | ||
| def ignore_small_holes_min_diameter(self, value: str): | ||
| self.core.ignore_small_holes_min_diameter = value | ||
| @property | ||
| def improved_loss_model(self) -> str: | ||
| """Improved loss model setting. | ||
| Returns | ||
| ------- | ||
| str | ||
| Improved loss model setting. Values are `level_1`, `level_2`, `level_3`. | ||
| """ | ||
| return self.core.improved_loss_model.name.lower() | ||
| @improved_loss_model.setter | ||
| def improved_loss_model(self, value: str): | ||
| model = self.core.improved_loss_model | ||
| enum_value = model.__class__[value.upper()] | ||
| self.core.improved_loss_model = enum_value |
| # Copyright (C) 2023 - 2026 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. | ||
| from ansys.edb.core.simulation_setup.hfss_pi_simulation_settings import ( | ||
| HFSSPISignalNetsSettings as CoreHFSSPISignalNetsSettings, | ||
| ) | ||
| class HFSSPISignalNetsSettings: | ||
| """PyEDB HFSS PI signal nets settings class.""" | ||
| def __init__(self, pedb, core: "CoreHFSSPISignalNetsSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def conductor_modeling(self) -> str: | ||
| """Get the conductor modeling method. | ||
| Returns | ||
| ------- | ||
| str | ||
| The conductor modeling method. Accepted values are 'mesh_inside' and 'impedance_boundary'. | ||
| """ | ||
| return self.core.conductor_modeling.name.lower() | ||
| @conductor_modeling.setter | ||
| def conductor_modeling(self, value: str): | ||
| """Set the conductor modeling method. | ||
| Parameters | ||
| ---------- | ||
| value : str | ||
| The conductor modeling method. | ||
| """ | ||
| model = self.core.conductor_modeling | ||
| if not value.lower() in ["mesh_inside", "impedance_boundary"]: | ||
| raise ValueError( | ||
| "Invalid conductor modeling method. Accepted values are 'mesh_inside' and 'impedance_boundary'." | ||
| ) | ||
| model.name = value.upper() | ||
| self.core.conductor_modeling = model | ||
| @property | ||
| def error_tolerance(self) -> str: | ||
| """Get the error tolerance. | ||
| Returns | ||
| ------- | ||
| str | ||
| The error tolerance. Values are `et_0_0`, `et_0_02`, `et_0_04`, `et_0_06`, `et_0_08`, `et_0_1` | ||
| `et_0_2`, `et_0_5`, `et_1_0`. | ||
| """ | ||
| return self.core.error_tolerance.name.lower() | ||
| @error_tolerance.setter | ||
| def error_tolerance(self, value: str): | ||
| """Set the error tolerance. | ||
| Parameters | ||
| ---------- | ||
| value : str | ||
| The error tolerance. Values are `et_0_0`, `et_0_02`, `et_0_04`, `et_0_06`, `et_0_08`, `et_0_1` | ||
| `et_0_2`, `et_0_5`, `et_1_0`. | ||
| """ | ||
| tolerance = self.core.error_tolerance | ||
| valid_values = ["et_0_0", "et_0_02", "et_0_04", "et_0_06", "et_0_08", "et_0_1", "et_0_2", "et_0_5", "et_1_0"] | ||
| if not value.lower() in valid_values: | ||
| raise ValueError(f"Invalid error tolerance. Accepted values are {valid_values}.") | ||
| tolerance.name = value.upper() | ||
| self.core.error_tolerance = tolerance | ||
| @property | ||
| def include_improved_dielectric_fill_refinement(self) -> bool: | ||
| """Get the flag for improved dielectric fill refinement. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if improved dielectric fill refinement is included, False otherwise. | ||
| """ | ||
| return self.core.include_improved_dielectric_fill_refinement | ||
| @include_improved_dielectric_fill_refinement.setter | ||
| def include_improved_dielectric_fill_refinement(self, value: bool): | ||
| self.core.include_improved_dielectric_fill_refinement = value | ||
| @property | ||
| def include_improved_loss_handling(self) -> bool: | ||
| """Get the flag for improved loss handling. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if improved loss handling is included, False otherwise. | ||
| """ | ||
| return self.core.include_improved_loss_handling | ||
| @include_improved_loss_handling.setter | ||
| def include_improved_loss_handling(self, value: bool): | ||
| self.core.include_improved_loss_handling = value |
| # Copyright (C) 2023 - 2026 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. | ||
| from ansys.edb.core.simulation_setup.hfss_pi_simulation_settings import ( | ||
| HFSSPISimulationSettings as CoreHFSSPISimulationSettings, | ||
| ) | ||
| from pyedb.grpc.database.simulation_setup.hfss_pi_general_settings import HFSSPIGeneralSettings | ||
| from pyedb.grpc.database.simulation_setup.hfss_pi_net_processing_settings import HFSSPINetProcessingSettings | ||
| from pyedb.grpc.database.simulation_setup.hfss_pi_power_ground_nets_settings import HFSSPIPowerGroundNetsSettings | ||
| from pyedb.grpc.database.simulation_setup.hfss_pi_signal_nets_settings import HFSSPISignalNetsSettings | ||
| class HFSSPISimulationSettings: | ||
| """PyEDB HFSS PI simulation setup class.""" | ||
| def __init__(self, pedb, core: "CoreHFSSPISimulationSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def enabled(self) -> bool: | ||
| """Get or set the enabled status of the HFSS PI simulation setup. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if the simulation setup is enabled, False otherwise. | ||
| """ | ||
| return self.core.enabled | ||
| @enabled.setter | ||
| def enabled(self, value: bool): | ||
| self.core.enabled = value | ||
| @property | ||
| def general(self) -> HFSSPIGeneralSettings: | ||
| """Get the HFSS PI general simulation settings. | ||
| Returns | ||
| ------- | ||
| HFSSPIGeneralSettings | ||
| The HFSS PI general simulation settings object. | ||
| """ | ||
| return HFSSPIGeneralSettings(self._pedb, self.core.general) | ||
| @property | ||
| def net_processing(self) -> HFSSPINetProcessingSettings: | ||
| """Get the HFSS PI net processing simulation settings. | ||
| Returns | ||
| ------- | ||
| HFSSPINetProcessingSettings | ||
| The HFSS PI net processing simulation settings object. | ||
| """ | ||
| return HFSSPINetProcessingSettings(self._pedb, self.core.net_processing) | ||
| @property | ||
| def power_ground_nets(self) -> HFSSPIPowerGroundNetsSettings: | ||
| """Get the HFSS PI power and ground nets simulation settings. | ||
| Returns | ||
| ------- | ||
| HFSSPIPowerGroundNetsSettings | ||
| The HFSS PI power and ground nets simulation settings object. | ||
| """ | ||
| return HFSSPIPowerGroundNetsSettings(self._pedb, self.core.power_ground_nets) | ||
| @property | ||
| def signal_nets(self) -> HFSSPISignalNetsSettings: | ||
| """Get the HFSS PI signal nets simulation settings. | ||
| Returns | ||
| ------- | ||
| HFSSPISignalNetsSettings | ||
| The HFSS PI signal nets simulation settings object. | ||
| """ | ||
| return HFSSPISignalNetsSettings(self._pedb, self.core.signal_nets) |
| # Copyright (C) 2023 - 2026 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. | ||
| from typing import TYPE_CHECKING | ||
| from ansys.edb.core.simulation_setup.hfss_pi_simulation_setup import HFSSPISimulationSetup as CoreHFSSPISimulationSetup | ||
| from pyedb.grpc.database.simulation_setup.hfss_pi_simulation_settings import HFSSPISimulationSettings | ||
| from pyedb.grpc.database.simulation_setup.simulation_setup import SimulationSetup | ||
| if TYPE_CHECKING: | ||
| from pyedb.grpc.edb import Edb | ||
| class HFSSPISimulationSetup(SimulationSetup): | ||
| """HFSS PI simulation setup class.""" | ||
| def __init__(self, pedb, core: "CoreHFSSPISimulationSetup"): | ||
| super().__init__(pedb, core) | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @classmethod | ||
| def create(cls, edb: "Edb", name: str = "HFSS_PI") -> "HFSSPISimulationSetup": | ||
| """Create a HFSS PI simulation setup. | ||
| Parameters | ||
| ---------- | ||
| edb : Edb | ||
| An EDB instance. | ||
| name : str | ||
| Name of the simulation setup. | ||
| Returns | ||
| ------- | ||
| HFSSPISimulationSetup | ||
| The HFSS PI simulation setup object. | ||
| """ | ||
| core_setup = CoreHFSSPISimulationSetup.create(edb.active_cell, name) | ||
| return cls(edb, core_setup) | ||
| @property | ||
| def settings(self) -> HFSSPISimulationSettings: | ||
| """Get the HFSS PI simulation settings. | ||
| Returns | ||
| ------- | ||
| HFSSPISimulationSettings | ||
| The HFSS PI simulation settings object. | ||
| """ | ||
| return HFSSPISimulationSettings(self._pedb, self.core.settings) |
| # Copyright (C) 2023 - 2026 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, | ||
| # FITNE SS 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. | ||
| from ansys.edb.core.simulation_setup.mesh_operation import LengthMeshOperation as CoreLengthMeshOperation | ||
| class LengthMeshOperation: | ||
| """PyEDB Length Mesh Operation class.""" | ||
| def __init__( | ||
| self, | ||
| core=None, | ||
| name="", | ||
| net_layer_info=None, | ||
| enabled=True, | ||
| refine_inside=False, | ||
| mesh_region="", | ||
| solve_inside=False, | ||
| max_length: str = "1mm", | ||
| restrict_max_length: bool = True, | ||
| max_elements: str = "1000", | ||
| restrict_max_elements: bool = False, | ||
| ): | ||
| if not core: | ||
| self.core = self.create( | ||
| name=name, | ||
| net_layer_info=net_layer_info, | ||
| enabled=enabled, | ||
| refine_inside=refine_inside, | ||
| mesh_region=mesh_region, | ||
| solve_inside=solve_inside, | ||
| max_length=max_length, | ||
| restrict_max_length=restrict_max_length, | ||
| max_elements=max_elements, | ||
| restrict_max_elements=restrict_max_elements, | ||
| ) | ||
| else: | ||
| self.core = core | ||
| @classmethod | ||
| def create( | ||
| cls, | ||
| name: str = "", | ||
| net_layer_info: tuple[str, str, bool] = None, | ||
| enabled: bool = True, | ||
| refine_inside: bool = False, | ||
| mesh_region: str = "", | ||
| solve_inside: bool = False, | ||
| max_length: str = "1mm", | ||
| restrict_max_length: bool = True, | ||
| max_elements: str = "1000", | ||
| restrict_max_elements: bool = False, | ||
| ) -> "LengthMeshOperation": | ||
| """Create a Length Mesh Operation. | ||
| Parameters | ||
| ---------- | ||
| name : str | ||
| Name of the mesh operation. | ||
| net_layer_info : tuple[str, str, bool] | ||
| A tuple containing the net name, layer name, and a boolean indicating whether to include | ||
| child layers. | ||
| enabled : bool | ||
| Whether the mesh operation is enabled. | ||
| refine_inside : bool | ||
| Whether to refine the mesh inside the specified region. | ||
| mesh_region : str | ||
| The name of the mesh region. | ||
| solve_inside : bool | ||
| Whether to solve inside the specified region. | ||
| max_length : str | ||
| The maximum length for the mesh operation. | ||
| restrict_max_length : bool | ||
| Whether to restrict the maximum length. | ||
| max_elements : str | ||
| The maximum number of elements for the mesh operation. | ||
| restrict_max_elements : bool | ||
| Whether to restrict the maximum number of elements. | ||
| Returns | ||
| ------- | ||
| LengthMeshOperation : LengthMeshOperation | ||
| The Length Mesh Operation object. | ||
| """ | ||
| core_op = CoreLengthMeshOperation( | ||
| name=name, | ||
| net_layer_info=net_layer_info, | ||
| enabled=enabled, | ||
| refine_inside=refine_inside, | ||
| mesh_region=mesh_region, | ||
| solve_inside=solve_inside, | ||
| max_length=max_length, | ||
| restrict_max_length=restrict_max_length, | ||
| max_elements=max_elements, | ||
| restrict_max_elements=restrict_max_elements, | ||
| ) | ||
| return cls(core=core_op) | ||
| @property | ||
| def name(self) -> str: | ||
| """Get the name of the mesh operation. | ||
| Returns | ||
| ------- | ||
| str | ||
| Name of the mesh operation. | ||
| """ | ||
| return self.core.name | ||
| @name.setter | ||
| def name(self, value: str): | ||
| self.core.name = value | ||
| @property | ||
| def enabled(self) -> bool: | ||
| """Get the enabled status of the mesh operation. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if the mesh operation is enabled, False otherwise. | ||
| """ | ||
| return self.core.enabled | ||
| @enabled.setter | ||
| def enabled(self, value: bool): | ||
| self.core.enabled = value | ||
| @property | ||
| def mesh_region(self) -> str: | ||
| """Get the mesh region name. | ||
| Returns | ||
| ------- | ||
| str | ||
| Name of the mesh region. | ||
| """ | ||
| return self.core.mesh_region | ||
| @mesh_region.setter | ||
| def mesh_region(self, value: str): | ||
| self.core.mesh_region = value | ||
| @property | ||
| def net_layer_info(self) -> list[tuple[str, str, bool]]: | ||
| """Get the net layer information list. | ||
| Returns | ||
| ------- | ||
| list[tuple(str, str, bool)] | ||
| List of net layer information for the mesh operation. | ||
| """ | ||
| return list(self.core.net_layer_info) | ||
| @net_layer_info.setter | ||
| def net_layer_info(self, value: list[tuple[str, str, bool]]): | ||
| self.core.net_layer_info.clear() | ||
| for info in value: | ||
| self.core.net_layer_info.append(info) | ||
| @property | ||
| def refine_inside(self) -> bool: | ||
| """Get the refine inside status of the mesh operation. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if refining inside is enabled, False otherwise. | ||
| """ | ||
| return self.core.refine_inside | ||
| @refine_inside.setter | ||
| def refine_inside(self, value: bool): | ||
| self.core.refine_inside = value | ||
| @property | ||
| def solve_inside(self) -> bool: | ||
| """Get the solve inside status of the mesh operation. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if solving inside is enabled, False otherwise. | ||
| """ | ||
| return self.core.solve_inside | ||
| @solve_inside.setter | ||
| def solve_inside(self, value: bool): | ||
| self.core.solve_inside = value | ||
| @property | ||
| def max_length(self) -> float: | ||
| """Get the length for the length mesh operation. | ||
| Returns | ||
| ------- | ||
| float | ||
| The length value. | ||
| """ | ||
| return self.core.max_length | ||
| @max_length.setter | ||
| def max_length(self, value: float): | ||
| """Set the length for the length mesh operation. | ||
| Parameters | ||
| ---------- | ||
| value : float | ||
| The length value to set. | ||
| """ | ||
| self.core.max_length = value | ||
| @property | ||
| def restrict_max_length(self) -> bool: | ||
| """Get the restrict max length status of the mesh operation. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if restricting max length is enabled, False otherwise. | ||
| """ | ||
| return self.core.restrict_max_length | ||
| @restrict_max_length.setter | ||
| def restrict_max_length(self, value: bool): | ||
| self.core.restrict_max_length = value | ||
| @property | ||
| def max_elements(self) -> str: | ||
| """Get the maximum number of elements for the length mesh operation. | ||
| Returns | ||
| ------- | ||
| str | ||
| The maximum number of elements. | ||
| """ | ||
| return self.core.max_elements | ||
| @max_elements.setter | ||
| def max_elements(self, value: str): | ||
| self.core.max_elements = value | ||
| @property | ||
| def restrict_max_elements(self) -> bool: | ||
| """Get the restrict max elements status of the mesh operation. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if restricting max elements is enabled, False otherwise. | ||
| """ | ||
| return self.core.restrict_max_elements | ||
| @restrict_max_elements.setter | ||
| def restrict_max_elements(self, value: bool): | ||
| self.core.restrict_max_elements = value |
| # Copyright (C) 2023 - 2026 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, | ||
| # FITNE SS 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. | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.q3d_simulation_settings import Q3DACRLSettings as CoreQ3DACRLSettings | ||
| class Q3DACRLSettings: | ||
| """Q3D ACRL settings class.""" | ||
| def __init__(self, pedb, core: "CoreQ3DACRLSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def max_passes(self) -> int: | ||
| """Maximum number of mesh refinement cycles to perform. | ||
| Returns | ||
| ------- | ||
| int | ||
| Maximum number of passes. | ||
| """ | ||
| return self.core.max_passes | ||
| @max_passes.setter | ||
| def max_passes(self, value: int): | ||
| self.core.max_passes = value | ||
| @property | ||
| def max_refine_per_pass(self) -> float: | ||
| """Maximum percentage of elements to refine per pass. | ||
| Returns | ||
| ------- | ||
| float | ||
| Maximum percentage of elements to refine per pass. | ||
| """ | ||
| return self.core.max_refine_per_pass | ||
| @max_refine_per_pass.setter | ||
| def max_refine_per_pass(self, value: float): | ||
| self.core.max_refine_per_pass = value | ||
| @property | ||
| def min_converged_passes(self) -> int: | ||
| """Minimum number of converged passes required. | ||
| Returns | ||
| ------- | ||
| int | ||
| Minimum number of converged passes. | ||
| """ | ||
| return self.core.min_converged_passes | ||
| @min_converged_passes.setter | ||
| def min_converged_passes(self, value: int): | ||
| self.core.min_converged_passes = value | ||
| @property | ||
| def min_passes(self) -> int: | ||
| """Minimum number of passes required. | ||
| Returns | ||
| ------- | ||
| int | ||
| Minimum number of passes. | ||
| """ | ||
| return self.core.min_passes | ||
| @min_passes.setter | ||
| def min_passes(self, value: int): | ||
| self.core.min_passes = value | ||
| @property | ||
| def percent_error(self) -> float: | ||
| """Target percent error for convergence. | ||
| Returns | ||
| ------- | ||
| float | ||
| Target percent error. | ||
| """ | ||
| return self.core.percent_error | ||
| @percent_error.setter | ||
| def percent_error(self, value: float): | ||
| self.core.percent_error = value |
| # Copyright (C) 2023 - 2026 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, | ||
| # FITNE SS 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. | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.q3d_simulation_settings import ( | ||
| Q3DAdvancedMeshingSettings as CoreQ3DAdvancedMeshingSettings, | ||
| ) | ||
| class Q3DAdvancedMeshingSettings: | ||
| """Q3D advanced meshing settings class.""" | ||
| def __init__(self, pedb, core: "CoreQ3DAdvancedMeshingSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def arc_step_size(self) -> float: | ||
| """Arc step size in micrometers. | ||
| Returns | ||
| ------- | ||
| float | ||
| Arc step size in micrometers. | ||
| """ | ||
| return self._pedb.value(self.core.arc_step_size) | ||
| @arc_step_size.setter | ||
| def arc_step_size(self, value: float): | ||
| self.core.arc_step_size = str(self._pedb.value(value)) | ||
| @property | ||
| def arc_to_chord_error(self) -> float: | ||
| """Arc to chord error in micrometers. | ||
| Returns | ||
| ------- | ||
| float | ||
| Arc to chord error in micrometers. | ||
| """ | ||
| return self._pedb.value(self.core.arc_to_chord_error) | ||
| @arc_to_chord_error.setter | ||
| def arc_to_chord_error(self, value: float): | ||
| self.core.arc_to_chord_error = str(self._pedb.value(value)) | ||
| @property | ||
| def circle_start_azimuth(self) -> float: | ||
| """Circle start azimuth in degrees. | ||
| Returns | ||
| ------- | ||
| float | ||
| Circle start azimuth in degrees. | ||
| """ | ||
| return self._pedb.value(self.core.circle_start_azimuth) | ||
| @circle_start_azimuth.setter | ||
| def circle_start_azimuth(self, value: float): | ||
| self.core.circle_start_azimuth = str(self._pedb.value(value)) | ||
| @property | ||
| def layer_alignment(self) -> str: | ||
| """Snapping tolerance for hierarchical layer alignment. | ||
| Returns | ||
| ------- | ||
| float | ||
| Snapping tolerance for hierarchical layer alignment. | ||
| """ | ||
| return self.core.layer_alignment | ||
| @layer_alignment.setter | ||
| def layer_alignment(self, value: str): | ||
| self.core.layer_alignment = str(value) | ||
| @property | ||
| def max_num_arc_points(self) -> int: | ||
| """Maximum number of points used to approximate arcs. | ||
| Returns | ||
| ------- | ||
| int | ||
| Maximum number of arc points. | ||
| """ | ||
| return self.core.max_num_arc_points | ||
| @max_num_arc_points.setter | ||
| def max_num_arc_points(self, value: int): | ||
| self.core.max_num_arc_points = value | ||
| @property | ||
| def use_arc_chord_error_approx(self) -> bool: | ||
| """Flag indicating if arc to chord error approximation is used. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if arc to chord error approximation is used, False otherwise. | ||
| """ | ||
| return self.core.use_arc_chord_error_approx | ||
| @use_arc_chord_error_approx.setter | ||
| def use_arc_chord_error_approx(self, value: bool): | ||
| self.core.use_arc_chord_error_approx = value |
| # Copyright (C) 2023 - 2026 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, | ||
| # FITNE SS 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. | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.q3d_simulation_settings import Q3DAdvancedSettings as CoreQ3DAdvancedSettings | ||
| class Q3DAdvancedSettings: | ||
| """Q3D advanced simulation settings. | ||
| Parameters | ||
| ---------- | ||
| pedb : :class:`Edb < pyedb.grpc.edb.Edb>` | ||
| Inherited object. | ||
| """ | ||
| def __init__(self, pedb, core: "CoreQ3DAdvancedSettings"): | ||
| self._pedb = pedb | ||
| self.core = core | ||
| @property | ||
| def defeature_absolute_length(self) -> float: | ||
| """Absolute length used as tolerance when defeaturing polygons. | ||
| Returns | ||
| ------- | ||
| float | ||
| Defeature absolute length value. | ||
| """ | ||
| return self._pedb.value(self.core.defeature_absolute_length) | ||
| @defeature_absolute_length.setter | ||
| def defeature_absolute_length(self, value: float): | ||
| self.core.defeature_absolute_length = str(self._pedb.edb_value(value)) | ||
| @property | ||
| def defeature_ratio(self) -> float: | ||
| """Extent ratio used as tolerance when defeaturing polygons. | ||
| Returns | ||
| ------- | ||
| float | ||
| Defeature ratio value. | ||
| """ | ||
| return self.core.defeature_ratio | ||
| @defeature_ratio.setter | ||
| def defeature_ratio(self, value: float): | ||
| self.core.defeature_ratio = value | ||
| @property | ||
| def healing_option(self) -> int: | ||
| """Healing option. | ||
| Returns | ||
| ------- | ||
| int | ||
| Healing option value. | ||
| """ | ||
| return self.core.healing_option | ||
| @healing_option.setter | ||
| def healing_option(self, value: int): | ||
| self.core.healing_option = value | ||
| @property | ||
| def ic_mode_auto_resolution(self) -> bool: | ||
| """Flag indicating if model resolution is automatically calculated for IC designs. | ||
| Returns | ||
| ------- | ||
| bool | ||
| IC mode auto resolution value. | ||
| """ | ||
| return self.core.ic_mode_auto_resolution | ||
| @ic_mode_auto_resolution.setter | ||
| def ic_mode_auto_resolution(self, value: bool): | ||
| self.core.ic_mode_auto_resolution = value | ||
| @property | ||
| def ic_mode_length(self) -> float: | ||
| """Model resolution to use when manually setting the model resolution of IC designs. | ||
| Returns | ||
| ------- | ||
| float | ||
| IC mode length value. | ||
| """ | ||
| return self._pedb.value(self.core.ic_mode_length) | ||
| @ic_mode_length.setter | ||
| def ic_mode_length(self, value: float): | ||
| self.core.ic_mode_length = str(self._pedb.edb_value(value)) | ||
| @property | ||
| def max_passes(self) -> int: | ||
| """Maximum number of mesh refinement cycles to perform. | ||
| Returns | ||
| ------- | ||
| int | ||
| Max passes value. | ||
| """ | ||
| return self.core.max_passes | ||
| @max_passes.setter | ||
| def max_passes(self, value: int): | ||
| self.core.max_passes = value | ||
| @property | ||
| def max_refine_per_pass(self) -> float: | ||
| """How many tetrahedra are added at each iteration of the adaptive refinement process. | ||
| Returns | ||
| ------- | ||
| float | ||
| Max refine per pass value. | ||
| """ | ||
| return self.core.max_refine_per_pass | ||
| @max_refine_per_pass.setter | ||
| def max_refine_per_pass(self, value: float): | ||
| self.core.max_refine_per_pass = value | ||
| @property | ||
| def mesh_for_via_plating(self) -> bool: | ||
| """Flag indicating whether to mesh the via plating. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Mesh for via plating value. | ||
| """ | ||
| return self.core.mesh_for_via_plating | ||
| @mesh_for_via_plating.setter | ||
| def mesh_for_via_plating(self, value: bool): | ||
| self.core.mesh_for_via_plating = value | ||
| @property | ||
| def min_converged_passes(self) -> int: | ||
| """Minimum number of converged passes before stopping the adaptive refinement process. | ||
| Returns | ||
| ------- | ||
| int | ||
| Min converged passes value. | ||
| """ | ||
| return self.core.min_converged_passes | ||
| @min_converged_passes.setter | ||
| def min_converged_passes(self, value: int): | ||
| self.core.min_converged_passes = value | ||
| @property | ||
| def min_passes(self) -> int: | ||
| """Minimum number of mesh refinement cycles to perform. | ||
| Returns | ||
| ------- | ||
| int | ||
| Min passes value. | ||
| """ | ||
| return self.core.min_passes | ||
| @min_passes.setter | ||
| def min_passes(self, value: int): | ||
| self.core.min_passes = value | ||
| @property | ||
| def num_via_density(self) -> float: | ||
| """Spacing between vias. | ||
| Returns | ||
| ------- | ||
| float | ||
| Num via density value. | ||
| """ | ||
| return self.core.num_via_density | ||
| @num_via_density.setter | ||
| def num_via_density(self, value: float): | ||
| self.core.num_via_density = value | ||
| @property | ||
| def num_via_sides(self) -> int: | ||
| """Number of sides to use when meshing vias. | ||
| Returns | ||
| ------- | ||
| int | ||
| Num via sides value. | ||
| """ | ||
| return self.core.num_via_sides | ||
| @num_via_sides.setter | ||
| def num_via_sides(self, value: int): | ||
| self.core.num_via_sides = value | ||
| @property | ||
| def percent_error(self) -> float: | ||
| """Target percent error for adaptive mesh refinement. | ||
| Returns | ||
| ------- | ||
| float | ||
| Percent error value. | ||
| """ | ||
| return self.core.percent_error | ||
| @percent_error.setter | ||
| def percent_error(self, value: float): | ||
| self.core.percent_error = value | ||
| @property | ||
| def remove_floating_geometry(self) -> bool: | ||
| """Flag indicating if a geometry not connected to any other geometry is removed. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Remove floating geometry value. | ||
| """ | ||
| return self.core.remove_floating_geometry | ||
| @remove_floating_geometry.setter | ||
| def remove_floating_geometry(self, value: bool): | ||
| self.core.remove_floating_geometry = value | ||
| @property | ||
| def small_void_area(self) -> float: | ||
| """Voids with an area smaller than this value are ignored during simulation. | ||
| Returns | ||
| ------- | ||
| float | ||
| Small void area value. | ||
| """ | ||
| return self.core.small_void_area | ||
| @small_void_area.setter | ||
| def small_void_area(self, value: float): | ||
| self.core.small_void_area = self._pedb.edb_value(value) | ||
| @property | ||
| def union_polygons(self) -> bool: | ||
| """Flag indicating if polygons are united before meshing. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Union polygons value. | ||
| """ | ||
| return self.core.union_polygons | ||
| @union_polygons.setter | ||
| def union_polygons(self, value: bool): | ||
| self.core.union_polygons = value | ||
| @property | ||
| def use_defeature(self) -> bool: | ||
| """Flag indicating if defeaturing is used when meshing. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Use defeature value. | ||
| """ | ||
| return self.core.use_defeature | ||
| @use_defeature.setter | ||
| def use_defeature(self, value: bool): | ||
| self.core.use_defeature = value | ||
| @property | ||
| def use_defeature_absolute_length(self) -> bool: | ||
| """Flag indicating if absolute length or extent ratio is used when defeaturing polygons. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Use defeature absolute length value. | ||
| """ | ||
| return self.core.use_defeature_absolute_length | ||
| @use_defeature_absolute_length.setter | ||
| def use_defeature_absolute_length(self, value: bool): | ||
| self.core.use_defeature_absolute_length = value | ||
| @property | ||
| def via_material(self) -> str: | ||
| """Material used for vias. | ||
| Returns | ||
| ------- | ||
| str | ||
| Via material value. | ||
| """ | ||
| return self.core.via_material | ||
| @via_material.setter | ||
| def via_material(self, value: str): | ||
| self.core.via_material = value |
| # Copyright (C) 2023 - 2026 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, | ||
| # FITNE SS 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. | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.q3d_simulation_settings import Q3DCGSettings as CoreQ3DCGSettings | ||
| from ansys.edb.core.simulation_setup.q3d_simulation_settings import ( | ||
| Q3DSolutionOrder as CoreQ3DSolutionOrder, | ||
| SolverType as CoreSolverType, | ||
| ) | ||
| _mapping_solution_order = { | ||
| "normal": CoreQ3DSolutionOrder.NORMAL, | ||
| "high": CoreQ3DSolutionOrder.HIGH, | ||
| "higher": CoreQ3DSolutionOrder.HIGHER, | ||
| "highest": CoreQ3DSolutionOrder.HIGHEST, | ||
| "num_solution_order": CoreQ3DSolutionOrder.NUM_SOLUTION_ORDER, | ||
| } | ||
| _mapping_solver_type = { | ||
| "direct": CoreSolverType.DIRECT_SOLVER, | ||
| "iterative": CoreSolverType.ITERATIVE_SOLVER, | ||
| "auto": CoreSolverType.AUTO_SOLVER, | ||
| } | ||
| class Q3DCGSettings: | ||
| """Q3D CG settings class.""" | ||
| def __init__(self, pedb, core: "CoreQ3DCGSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def auto_incr_sol_order(self) -> bool: | ||
| """Get auto increment solution order setting. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Auto increment solution order setting. | ||
| """ | ||
| return self.core.auto_incr_sol_order | ||
| @auto_incr_sol_order.setter | ||
| def auto_incr_sol_order(self, value: bool): | ||
| self.core.auto_incr_sol_order = value | ||
| @property | ||
| def compression_tol(self) -> float: | ||
| """Get compression tolerance. | ||
| Returns | ||
| ------- | ||
| float | ||
| Compression tolerance. | ||
| """ | ||
| return self._pedb.value(self.core.compression_tol) | ||
| @compression_tol.setter | ||
| def compression_tol(self, value: float): | ||
| self.core.compression_tol = value | ||
| @property | ||
| def max_passes(self) -> int: | ||
| """Maximum number of passes. | ||
| Returns | ||
| ------- | ||
| int | ||
| Maximum number of passes. | ||
| """ | ||
| return self.core.max_passes | ||
| @max_passes.setter | ||
| def max_passes(self, value: int): | ||
| self.core.max_passes = value | ||
| @property | ||
| def max_refine_per_pass(self) -> float: | ||
| """Maximum refinement per pass. | ||
| Returns | ||
| ------- | ||
| float | ||
| Maximum refinement per pass. | ||
| """ | ||
| return self._pedb.value(self.core.max_refine_per_pass) | ||
| @max_refine_per_pass.setter | ||
| def max_refine_per_pass(self, value: float): | ||
| self.core.max_refine_per_pass = value | ||
| @property | ||
| def min_converged_passes(self) -> int: | ||
| """Minimum number of converged passes. | ||
| Returns | ||
| ------- | ||
| int | ||
| Minimum number of converged passes. | ||
| """ | ||
| return self.core.min_converged_passes | ||
| @min_converged_passes.setter | ||
| def min_converged_passes(self, value: int): | ||
| self.core.min_converged_passes = value | ||
| @property | ||
| def min_passes(self) -> int: | ||
| """Minimum number of passes. | ||
| Returns | ||
| """ | ||
| return self.core.min_passes | ||
| @min_passes.setter | ||
| def min_passes(self, value: int): | ||
| self.core.min_passes = value | ||
| @property | ||
| def percent_error(self) -> float: | ||
| """Percent error during conduction adaptive passes. | ||
| Returns | ||
| ------- | ||
| float | ||
| Percent error during conduction adaptive passes. | ||
| """ | ||
| return self.core.percent_error | ||
| @percent_error.setter | ||
| def percent_error(self, value: float): | ||
| self.core.percent_error = value | ||
| @property | ||
| def solution_order(self) -> str: | ||
| """Get solution order. | ||
| Returns | ||
| ------- | ||
| str | ||
| Solution order. | ||
| """ | ||
| reverse_mapping = {v: k for k, v in _mapping_solution_order.items()} | ||
| return reverse_mapping[self.core.solution_order] | ||
| @solution_order.setter | ||
| def solution_order(self, value: str): | ||
| if not (value in _mapping_solution_order.keys()): | ||
| raise ValueError( | ||
| f"Invalid solution order: {value}. Valid options are: {list(_mapping_solution_order.keys())}" | ||
| ) | ||
| self.core.solution_order = _mapping_solution_order[value] | ||
| @property | ||
| def solver_type(self) -> str: | ||
| """Get solver type. | ||
| Returns | ||
| ------- | ||
| str | ||
| Solver type. | ||
| """ | ||
| reverse_mapping = {v: k for k, v in _mapping_solver_type.items()} | ||
| return reverse_mapping[self.core.solver_type] | ||
| @solver_type.setter | ||
| def solver_type(self, value: str): | ||
| if not (value in _mapping_solver_type.keys()): | ||
| raise ValueError(f"Invalid solver type: {value}. Valid options are: {list(_mapping_solver_type.keys())}") | ||
| self.core.solver_type = _mapping_solver_type[value] |
| # Copyright (C) 2023 - 2026 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. | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.q3d_simulation_settings import Q3DDCRLSettings as CoreQ3DDCRLSettings | ||
| from ansys.edb.core.simulation_setup.q3d_simulation_settings import Q3DSolutionOrder as CoreQ3DSolutionOrder | ||
| _mapping_solution_order = { | ||
| "normal": CoreQ3DSolutionOrder.NORMAL, | ||
| "high": CoreQ3DSolutionOrder.HIGH, | ||
| "higher": CoreQ3DSolutionOrder.HIGHER, | ||
| "highest": CoreQ3DSolutionOrder.HIGHEST, | ||
| "num_solution_order": CoreQ3DSolutionOrder.NUM_SOLUTION_ORDER, | ||
| } | ||
| class Q3DDCRLSettings: | ||
| def __init__(self, pedb, core: "CoreQ3DDCRLSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def max_passes(self) -> int: | ||
| """Maximum number of passes. | ||
| Returns | ||
| ------- | ||
| int | ||
| Maximum number of passes. | ||
| """ | ||
| return self.core.max_passes | ||
| @max_passes.setter | ||
| def max_passes(self, value: int): | ||
| self.core.max_passes = value | ||
| @property | ||
| def max_refine_per_pass(self) -> float: | ||
| """Maximum refinement per pass. | ||
| Returns | ||
| ------- | ||
| float | ||
| Maximum refinement per pass. | ||
| """ | ||
| return self.core.max_refine_per_pass | ||
| @max_refine_per_pass.setter | ||
| def max_refine_per_pass(self, value: float): | ||
| self.core.max_refine_per_pass = value | ||
| @property | ||
| def min_converged_passes(self) -> int: | ||
| """Minimum number of converged passes. | ||
| Returns | ||
| ------- | ||
| int | ||
| Minimum number of converged passes. | ||
| """ | ||
| return self.core.min_converged_passes | ||
| @min_converged_passes.setter | ||
| def min_converged_passes(self, value: int): | ||
| self.core.min_converged_passes = value | ||
| @property | ||
| def min_passes(self) -> int: | ||
| """Minimum number of passes. | ||
| Returns | ||
| ------- | ||
| int | ||
| Minimum number of passes. | ||
| """ | ||
| return self.core.min_passes | ||
| @min_passes.setter | ||
| def min_passes(self, value: int): | ||
| self.core.min_passes = value | ||
| @property | ||
| def percent_error(self) -> float: | ||
| """Percent error. | ||
| Returns | ||
| ------- | ||
| float | ||
| Percent error. | ||
| """ | ||
| return self.core.percent_error | ||
| @percent_error.setter | ||
| def percent_error(self, value: float): | ||
| self.core.percent_error = value | ||
| @property | ||
| def solution_order(self) -> str: | ||
| """Solution order. | ||
| Returns | ||
| ------- | ||
| str | ||
| Solution order. | ||
| """ | ||
| reverse_mapping = {v: k for k, v in _mapping_solution_order.items()} | ||
| return reverse_mapping.get(self.core.solution_order, "normal") | ||
| @solution_order.setter | ||
| def solution_order(self, value: str): | ||
| if value.lower() in _mapping_solution_order: | ||
| self.core.solution_order = _mapping_solution_order[value.lower()] | ||
| else: | ||
| self.core.solution_order = CoreQ3DSolutionOrder.NORMAL |
| # Copyright (C) 2023 - 2026 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, | ||
| # FITNE SS 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. | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.q3d_simulation_settings import Q3DGeneralSettings as CoreQ3DGeneralSettings | ||
| class Q3DGeneralSettings: | ||
| def __init__(self, pedb, core: "CoreQ3DGeneralSettings"): | ||
| """Q3D general settings class.""" | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def do_ac(self) -> bool: | ||
| """Whether to perform AC analysis. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if AC analysis is to be performed, False otherwise. | ||
| """ | ||
| return self.core.do_ac | ||
| @do_ac.setter | ||
| def do_ac(self, value: bool): | ||
| self.core.do_ac = value | ||
| @property | ||
| def do_cg(self) -> bool: | ||
| """Whether to perform CG analysis. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if CG analysis is to be performed, False otherwise. | ||
| """ | ||
| return self.core.do_cg | ||
| @do_cg.setter | ||
| def do_cg(self, value: bool): | ||
| self.core.do_cg = value | ||
| @property | ||
| def do_dc(self) -> bool: | ||
| """Whether to perform DC analysis. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if DC analysis is to be performed, False otherwise. | ||
| """ | ||
| return self.core.do_dc | ||
| @do_dc.setter | ||
| def do_dc(self, value: bool): | ||
| self.core.do_dc = value | ||
| @property | ||
| def do_dc_res_only(self) -> bool: | ||
| """Whether to perform DC resistance only analysis. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if DC resistance only analysis is to be performed, False otherwise. | ||
| """ | ||
| return self.core.do_dc_res_only | ||
| @do_dc_res_only.setter | ||
| def do_dc_res_only(self, value: bool): | ||
| self.core.do_dc_res_only = value | ||
| @property | ||
| def save_fields(self) -> bool: | ||
| """Whether to save fields. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if fields are to be saved, False otherwise. | ||
| """ | ||
| return self.core.save_fields | ||
| @save_fields.setter | ||
| def save_fields(self, value: bool): | ||
| self.core.save_fields = value | ||
| @property | ||
| def solution_frequency(self) -> float: | ||
| """Solution frequency in Hz. | ||
| Returns | ||
| ------- | ||
| float | ||
| Solution frequency in Hz. | ||
| """ | ||
| return self._pedb.value(self.core.solution_frequency) | ||
| @solution_frequency.setter | ||
| def solution_frequency(self, value: float): | ||
| self.core.solution_frequency = str(self._pedb.value(value)) |
| # Copyright (C) 2023 - 2026 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, | ||
| # FITNE SS 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. | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.q3d_simulation_settings import ( | ||
| Q3DSimulationSettings as CoreQ3DSimulationSettings, | ||
| ) | ||
| from pyedb.grpc.database.simulation_setup.q3d_acrl_settings import Q3DACRLSettings | ||
| from pyedb.grpc.database.simulation_setup.q3d_advanced_meshing_settings import Q3DAdvancedMeshingSettings | ||
| from pyedb.grpc.database.simulation_setup.q3d_advanced_settings import Q3DAdvancedSettings | ||
| from pyedb.grpc.database.simulation_setup.q3d_cg_settings import Q3DCGSettings | ||
| from pyedb.grpc.database.simulation_setup.q3d_dcrl_settings import Q3DDCRLSettings | ||
| from pyedb.grpc.database.simulation_setup.q3d_general_settings import Q3DGeneralSettings | ||
| class Q3DSimulationSettings: | ||
| """Q3D simulation settings class.""" | ||
| def __init__(self, pedb, core: "CoreQ3DSimulationSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def acrl(self) -> Q3DACRLSettings: | ||
| """ACRL settings class. | ||
| Returns | ||
| ------- | ||
| :class:`Q3DACRLSettings <pyedb.grpc.database.simulation_setup. | ||
| q3d_acrl_settings.Q3DACRLSettings>` | ||
| """ | ||
| return Q3DACRLSettings(self._pedb, self.core.acrl) | ||
| @property | ||
| def advanced(self) -> Q3DAdvancedSettings: | ||
| """Advanced settings class. | ||
| Returns | ||
| ------- | ||
| :class:`Q3DAdvancedSettings <pyedb.grpc.database.simulation_setup. | ||
| q3d_advanced_settings.Q3DAdvancedSettings>` | ||
| """ | ||
| return Q3DAdvancedSettings(self._pedb, self.core.advanced) | ||
| @property | ||
| def advanced_meshing(self) -> Q3DAdvancedMeshingSettings: | ||
| """Advanced meshing settings class. | ||
| Returns | ||
| ------- | ||
| :class:`Q3DAdvancedMeshingSettings <pyedb.grpc.database.simulation_setup. | ||
| q3d_advanced_meshing_settings.Q3DAdvancedMeshingSettings>` | ||
| """ | ||
| return Q3DAdvancedMeshingSettings(self._pedb, self.core.advanced_meshing) | ||
| @property | ||
| def cg(self) -> Q3DCGSettings: | ||
| """CG settings class. | ||
| Returns | ||
| ------- | ||
| :class:`Q3DCGSettings <pyedb.grpc.database.simulation_setup. | ||
| q3d_cg_settings.Q3DCGSettings>` | ||
| """ | ||
| return Q3DCGSettings(self._pedb, self.core.cg) | ||
| @property | ||
| def dcrl(self) -> Q3DDCRLSettings: | ||
| """DCRL settings class. | ||
| Returns | ||
| ------- | ||
| :class:`Q3DDCRLSettings <pyedb.grpc.database.simulation_setup. | ||
| q3d_dcrl_settings.Q3DDCRLSettings>` | ||
| """ | ||
| return Q3DDCRLSettings(self._pedb, self.core.dcrl) | ||
| @property | ||
| def enabled(self) -> bool: | ||
| """Enabled flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Enabled flag. | ||
| """ | ||
| return self.core.enabled | ||
| @enabled.setter | ||
| def enabled(self, value: bool): | ||
| self.core.enabled = value | ||
| @property | ||
| def general(self) -> Q3DGeneralSettings: | ||
| """General settings class. | ||
| Returns | ||
| ------- | ||
| :class:`Q3DGeneralSettings <pyedb.grpc.database.simulation_setup. | ||
| q3d_general_settings.Q3DGeneralSettings>` | ||
| """ | ||
| return Q3DGeneralSettings(self._pedb, self.core.general) |
| # Copyright (C) 2023 - 2026 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. | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from pyedb.grpc.edb import Edb | ||
| from ansys.edb.core.simulation_setup.q3d_simulation_setup import Q3DSimulationSetup as CoreQ3DSimulationSetup | ||
| from pyedb.grpc.database.simulation_setup.q3d_simulation_settings import Q3DSimulationSettings | ||
| from pyedb.grpc.database.simulation_setup.simulation_setup import SimulationSetup | ||
| from pyedb.grpc.database.simulation_setup.sweep_data import SweepData | ||
| class Q3DSimulationSetup(SimulationSetup): | ||
| """Q3D simulation setup management. | ||
| Parameters | ||
| ---------- | ||
| pedb : :class:`Edb` | ||
| Inherited object. | ||
| """ | ||
| def __init__(self, pedb, core: "GrpcQ3DSimulationSetup"): | ||
| super().__init__(pedb, core) | ||
| self.core: CoreQ3DSimulationSetup = core | ||
| self._pedb = pedb | ||
| @classmethod | ||
| def create(cls, edb: "Edb", name: str = "Q3D_setup") -> "Q3DSimulationSetup": | ||
| """Create a Q3D simulation setup. | ||
| Parameters | ||
| ---------- | ||
| edb : Edb | ||
| Inherited object. | ||
| name : str, optional | ||
| Name of the simulation setup, by default "Q3D_setup". | ||
| Returns | ||
| ------- | ||
| Q3DSimulationSetup | ||
| The Q3D simulation setup object. | ||
| """ | ||
| core = CoreQ3DSimulationSetup.create(edb.active_cell, name) | ||
| return cls(edb, core) | ||
| @property | ||
| def settings(self) -> Q3DSimulationSettings: | ||
| """Q3D simulation settings. | ||
| Returns | ||
| ------- | ||
| Q3DSimulationSettings | ||
| The Q3D simulation settings object. | ||
| """ | ||
| return Q3DSimulationSettings(self._pedb, self.core.settings) | ||
| @property | ||
| def sweep_data(self) -> list[SweepData]: | ||
| """Get sweep data. | ||
| Returns | ||
| ------- | ||
| list[SweepData] | ||
| List of sweep data objects. | ||
| """ | ||
| return [SweepData(self._pedb, sd) for sd in self.core.sweep_data] |
| # Copyright (C) 2023 - 2026 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. | ||
| from typing import TYPE_CHECKING, Union | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.simulation_setup import SimulationSetup as CoreSimulationSetup | ||
| from ansys.edb.core.simulation_setup.simulation_setup import SimulationSetupType as CoreSimulationSetupType | ||
| from pyedb.grpc.database.simulation_setup.sweep_data import SweepData | ||
| _mapping_simulation_types = { | ||
| CoreSimulationSetupType.HFSS: "hfss", | ||
| CoreSimulationSetupType.SI_WAVE: "siwave", | ||
| CoreSimulationSetupType.SI_WAVE_DCIR: "siwave_dcir", | ||
| CoreSimulationSetupType.HFSS_PI: "hfss_pi", | ||
| CoreSimulationSetupType.RAPTOR_X: "raptor_x", | ||
| CoreSimulationSetupType.Q3D_SIM: "q3d", | ||
| } | ||
| class SimulationSetup: | ||
| def __init__(self, pedb, core: "CoreSimulationSetup"): | ||
| """PyEDB Simulation Setup base class.""" | ||
| self.core = core | ||
| self._pedb = pedb | ||
| def cast(self): | ||
| """Cast a core SimulationSetup to PyEDB SimulationSetup.""" | ||
| return self.core.cast() | ||
| @property | ||
| def id(self) -> int: | ||
| """Unique ID of the EDB object. | ||
| Returns | ||
| ------- | ||
| int | ||
| Simulation setup ID. | ||
| """ | ||
| return self.core.id | ||
| @property | ||
| def is_null(self) -> bool: | ||
| """Check if the simulation setup is null. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if the simulation setup is null, False otherwise. | ||
| """ | ||
| return self.core.is_null | ||
| @property | ||
| def name(self) -> str: | ||
| """Get or set the name of the simulation setup. | ||
| Returns | ||
| ------- | ||
| str | ||
| Simulation setup name. | ||
| """ | ||
| return self.core.name | ||
| @name.setter | ||
| def name(self, value: str): | ||
| self.core.name = value | ||
| @property | ||
| def position(self) -> int: | ||
| """Get or set the position of the simulation setup. | ||
| Returns | ||
| ------- | ||
| int | ||
| Simulation setup position. | ||
| """ | ||
| return self.core.position | ||
| @position.setter | ||
| def position(self, value: int): | ||
| self.core.position = value | ||
| @property | ||
| def sweep_data(self) -> list[SweepData]: | ||
| """Get the sweep data associated with the simulation setup. | ||
| Returns | ||
| ------- | ||
| list[SweepData] | ||
| List of sweep data objects. | ||
| """ | ||
| return [SweepData(self._pedb, core=sweep) for sweep in self.core.sweep_data] | ||
| @sweep_data.setter | ||
| def sweep_data(self, sweeps: list[SweepData]): | ||
| self.core.sweep_data = [sweep.core for sweep in sweeps] | ||
| def _normalize_distribution(self, distribution: str) -> str: | ||
| """Normalize user-provided distribution string to internal code. | ||
| Parameters | ||
| ---------- | ||
| distribution : str | ||
| User-specified distribution. | ||
| Returns | ||
| ------- | ||
| str | ||
| One of: "LIN", "LINC", "ESTP", "DEC", "OCT". | ||
| """ | ||
| if not distribution: | ||
| return "LIN" | ||
| d = distribution.lower().strip() | ||
| if d in ("linear", "linear scale"): | ||
| return "LIN" | ||
| if d in ("linear_count", "linear count"): | ||
| return "LINC" | ||
| if d == "exponential": | ||
| return "ESTP" | ||
| if d in ("decade_count", "decade count", "log scale", "log_scale"): | ||
| return "DEC" | ||
| if d in ("octave_count", "octave count"): | ||
| return "OCT" | ||
| # already an internal code? | ||
| if d.upper() in ("LIN", "LINC", "ESTP", "DEC", "OCT"): | ||
| return d.upper() | ||
| return "LIN" | ||
| def _build_sweep_from_params( | ||
| self, name: str, distribution: str, start_freq, stop_freq, step, discrete: bool | ||
| ) -> SweepData: | ||
| """Construct a SweepData object from normalized parameters.""" | ||
| start_freq_val = self._pedb.number_with_units(start_freq, "Hz") | ||
| stop_freq_val = self._pedb.number_with_units(stop_freq, "Hz") | ||
| step_val = str(step) | ||
| sweep = SweepData( | ||
| self._pedb, name=name, distribution=distribution, start_f=start_freq_val, end_f=stop_freq_val, step=step_val | ||
| ) | ||
| if discrete: | ||
| # Use the string-based setter to avoid direct enum access | ||
| sweep.type = "discrete" | ||
| return sweep | ||
| def _add_sweeps_from_frequency_set(self, frequency_set, name, init_sweep_count, discrete): | ||
| """Handle the legacy frequency_set format. | ||
| This function creates SweepData entries from the provided frequency_set and | ||
| appends them to the existing core.sweep_data. | ||
| """ | ||
| new_sweeps = [] | ||
| for sweep_item in frequency_set: | ||
| # detect distribution token and map to internal code | ||
| if "linear_scale" in sweep_item: | ||
| distribution = "LIN" | ||
| elif "linear_count" in sweep_item: | ||
| distribution = "LINC" | ||
| elif "exponential" in sweep_item: | ||
| distribution = "ESTP" | ||
| elif "log_scale" in sweep_item: | ||
| distribution = "DEC" | ||
| elif "octave_count" in sweep_item: | ||
| distribution = "OCT" | ||
| else: | ||
| distribution = "LIN" | ||
| start_freq = self._pedb.number_with_units(sweep_item[1], "Hz") | ||
| stop_freq = self._pedb.number_with_units(sweep_item[2], "Hz") | ||
| step = str(sweep_item[3]) | ||
| if not name: | ||
| name = f"sweep_{init_sweep_count + 1}" | ||
| new_sweeps.append( | ||
| SweepData( | ||
| self._pedb, name=name, distribution=distribution, start_f=start_freq, end_f=stop_freq, step=step | ||
| ) | ||
| ) | ||
| if discrete: | ||
| # Use the string-based setter | ||
| new_sweeps[-1].type = "discrete" | ||
| # append existing core sweep data (preserve previous entries) | ||
| for s in self.core.sweep_data: | ||
| new_sweeps.append(s) | ||
| self.core.sweep_data = new_sweeps | ||
| def _add_single_sweep(self, sweep: SweepData) -> Union[SweepData, None]: | ||
| """Insert a single sweep into core.sweep_data preserving existing sweeps. | ||
| Returns the newly added SweepData on success, None otherwise. | ||
| """ | ||
| init_count = len(self.sweep_data) | ||
| # Prepend the new sweep keeping previous ones | ||
| sweep_list = [sweep] | ||
| for s in self.sweep_data: | ||
| sweep_list.append(s) | ||
| sweep_data = [sw.core for sw in sweep_list] | ||
| self.core.sweep_data = sweep_data | ||
| if len(self.sweep_data) == init_count + 1: | ||
| return self.sweep_data[-1] | ||
| return None | ||
| def add_sweep( | ||
| self, | ||
| name=None, | ||
| distribution="linear", | ||
| start_freq="0GHz", | ||
| stop_freq="20GHz", | ||
| step="10MHz", | ||
| discrete=False, | ||
| frequency_set=None, | ||
| ) -> Union[SweepData, None]: | ||
| """Add a HFSS frequency sweep. | ||
| This method was refactored to reduce complexity. The behaviour is compatible | ||
| with the previous implementation: it accepts either a legacy `frequency_set` | ||
| or single-sweep parameters. | ||
| Returns | ||
| ------- | ||
| SweepData | None | ||
| The newly added sweep when single sweep parameters are used, or None when | ||
| `frequency_set` is provided (legacy multi-sweep behavior). | ||
| """ | ||
| # Legacy batch mode | ||
| if frequency_set: | ||
| self._add_sweeps_from_frequency_set(frequency_set, name, len(self.sweep_data), discrete) | ||
| return None | ||
| # Single-sweep mode delegated to helper to reduce complexity | ||
| distribution_code = self._normalize_distribution(distribution) | ||
| if not name: | ||
| name = f"sweep_{len(self.sweep_data) + 1}" | ||
| sweep = self._build_sweep_from_params(name, distribution_code, start_freq, stop_freq, step, discrete) | ||
| result = self._add_single_sweep(sweep) | ||
| if result: | ||
| return result | ||
| self._pedb.logger.error("Failed to add frequency sweep data") | ||
| return None | ||
| def clear_sweeps(self): | ||
| """Clear all frequency sweeps from the simulation setup.""" | ||
| self.core.sweep_data = [] | ||
| @property | ||
| def setup_type(self) -> str: | ||
| """Get the type of the simulation setup. | ||
| Returns | ||
| ------- | ||
| str | ||
| Simulation setup type. | ||
| """ | ||
| return _mapping_simulation_types[self.core.type] |
| # Copyright (C) 2023 - 2026 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. | ||
| from ansys.edb.core.simulation_setup.siwave_simulation_settings import ( | ||
| SIWaveAdvancedSettings as CoreSIWaveAdvancedSettings, | ||
| ) | ||
| class SIWaveAdvancedSettings: | ||
| """SIWave advanced settings class.""" | ||
| def __init__(self, pedb, core: "CoreSIWaveAdvancedSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def ac_dc_merge_mode(self) -> int: | ||
| """AC/DC merge mode. | ||
| Returns | ||
| ------- | ||
| int | ||
| AC/DC merge mode. | ||
| """ | ||
| return self.core.ac_dc_merge_mode | ||
| @ac_dc_merge_mode.setter | ||
| def ac_dc_merge_mode(self, value: int): | ||
| self.core.ac_dc_merge_mode = value | ||
| @property | ||
| def cross_talk_threshold(self) -> float: | ||
| """Cross talk threshold. | ||
| Returns | ||
| ------- | ||
| float | ||
| Cross talk threshold. | ||
| """ | ||
| return self._pedb.value(self.core.cross_talk_threshold) | ||
| @cross_talk_threshold.setter | ||
| def cross_talk_threshold(self, value: float): | ||
| self.core.cross_talk_threshold = str(self._pedb.value(value)) | ||
| @property | ||
| def ignore_non_functional_pads(self) -> bool: | ||
| """Ignore non-functional pads flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Ignore non-functional pads flag. | ||
| """ | ||
| return self.core.ignore_non_functional_pads | ||
| @ignore_non_functional_pads.setter | ||
| def ignore_non_functional_pads(self, value: bool): | ||
| self.core.ignore_non_functional_pads = value | ||
| @property | ||
| def include_co_plane_coupling(self) -> bool: | ||
| """Include co-plane coupling flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Include co-plane coupling flag. | ||
| """ | ||
| return self.core.include_co_plane_coupling | ||
| @include_co_plane_coupling.setter | ||
| def include_co_plane_coupling(self, value: bool): | ||
| self.core.include_co_plane_coupling = value | ||
| @property | ||
| def include_fringe_plane_coupling(self) -> bool: | ||
| """Include fringe plane coupling flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Include fringe plane coupling flag. | ||
| """ | ||
| return self.core.include_fringe_plane_coupling | ||
| @include_fringe_plane_coupling.setter | ||
| def include_fringe_plane_coupling(self, value: bool): | ||
| self.core.include_fringe_plane_coupling = value | ||
| @property | ||
| def include_inf_gnd(self) -> bool: | ||
| """Include infinite ground flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Include infinite ground flag. | ||
| """ | ||
| return self.core.include_inf_gnd | ||
| @include_inf_gnd.setter | ||
| def include_inf_gnd(self, value: bool): | ||
| self.core.include_inf_gnd = value | ||
| @property | ||
| def include_inter_plane_coupling(self) -> bool: | ||
| """Include inter-plane coupling flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Include inter-plane coupling flag. | ||
| """ | ||
| return self.core.include_inter_plane_coupling | ||
| @include_inter_plane_coupling.setter | ||
| def include_inter_plane_coupling(self, value: bool): | ||
| self.core.include_inter_plane_coupling = value | ||
| @property | ||
| def include_split_plane_coupling(self) -> bool: | ||
| """Include split plane coupling flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Include split plane coupling flag. | ||
| """ | ||
| return self.core.include_split_plane_coupling | ||
| @include_split_plane_coupling.setter | ||
| def include_split_plane_coupling(self, value: bool): | ||
| self.core.include_split_plane_coupling = value | ||
| @property | ||
| def include_trace_plane_coupling(self) -> bool: | ||
| """Include trace-plane coupling flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Include trace-plane coupling flag. | ||
| """ | ||
| return self.core.include_trace_plane_coupling | ||
| @include_trace_plane_coupling.setter | ||
| def include_trace_plane_coupling(self, value: bool): | ||
| self.core.include_trace_plane_coupling = value | ||
| @property | ||
| def include_vi_sources(self) -> bool: | ||
| """Include VI sources flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Include VI sources flag. | ||
| """ | ||
| return self.core.include_vi_sources | ||
| @include_vi_sources.setter | ||
| def include_vi_sources(self, value: bool): | ||
| self.core.include_vi_sources = value | ||
| @property | ||
| def inf_gnd_location(self) -> float: | ||
| """Infinite ground location. | ||
| Returns | ||
| ------- | ||
| float | ||
| Infinite ground location. | ||
| """ | ||
| return self._pedb.value(self.core.inf_gnd_location) | ||
| @inf_gnd_location.setter | ||
| def inf_gnd_location(self, value: float): | ||
| self.core.inf_gnd_location = str(self._pedb.value(value)) | ||
| @property | ||
| def max_coupled_lines(self) -> int: | ||
| """Maximum coupled lines. | ||
| Returns | ||
| ------- | ||
| int | ||
| Maximum coupled lines. | ||
| """ | ||
| return self.core.max_coupled_lines | ||
| @max_coupled_lines.setter | ||
| def max_coupled_lines(self, value: int): | ||
| self.core.max_coupled_lines = value | ||
| @property | ||
| def mesh_automatic(self) -> bool: | ||
| """Automatic mesh flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Automatic mesh flag. | ||
| """ | ||
| return self.core.mesh_automatic | ||
| @mesh_automatic.setter | ||
| def mesh_automatic(self, value: bool): | ||
| self.core.mesh_automatic = value | ||
| @property | ||
| def mesh_frequency(self) -> float: | ||
| """Mesh frequency. | ||
| Returns | ||
| ------- | ||
| float | ||
| Mesh frequency. | ||
| """ | ||
| return self._pedb.value(self.core.mesh_frequency) | ||
| @mesh_frequency.setter | ||
| def mesh_frequency(self, value: float): | ||
| self.core.mesh_frequency = str(self._pedb.value(value)) | ||
| @property | ||
| def min_pad_area_to_mesh(self) -> float: | ||
| """Minimum pad area to mesh. | ||
| Returns | ||
| ------- | ||
| float | ||
| Minimum pad area to mesh. | ||
| """ | ||
| return self._pedb.value(self.core.min_pad_area_to_mesh) | ||
| @min_pad_area_to_mesh.setter | ||
| def min_pad_area_to_mesh(self, value: float): | ||
| self.core.min_pad_area_to_mesh = str(self._pedb.value(value)) | ||
| @property | ||
| def min_plane_area_to_mesh(self) -> float: | ||
| """Minimum plane area to mesh. | ||
| Returns | ||
| ------- | ||
| float | ||
| Minimum plane area to mesh. | ||
| """ | ||
| return self._pedb.value(self.core.min_plane_area_to_mesh) | ||
| @min_plane_area_to_mesh.setter | ||
| def min_plane_area_to_mesh(self, value: float): | ||
| self.core.min_plane_area_to_mesh = str(self._pedb.value(value)) | ||
| @property | ||
| def min_void_area(self) -> str: | ||
| """Minimum void area. | ||
| Returns | ||
| ------- | ||
| float | ||
| Minimum void area. | ||
| """ | ||
| return self.core.min_void_area | ||
| @min_void_area.setter | ||
| def min_void_area(self, value: str): | ||
| self.core.min_void_area = str(self._pedb.value(value)) | ||
| @property | ||
| def perform_erc(self) -> bool: | ||
| """Perform ERC flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Perform ERC flag. | ||
| """ | ||
| return self.core.perform_erc | ||
| @perform_erc.setter | ||
| def perform_erc(self, value: bool): | ||
| self.core.perform_erc = value | ||
| @property | ||
| def return_current_distribution(self) -> bool: | ||
| """Return current distribution flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Return current distribution flag. | ||
| """ | ||
| return self.core.return_current_distribution | ||
| @return_current_distribution.setter | ||
| def return_current_distribution(self, value: bool): | ||
| self.core.return_current_distribution = value | ||
| @property | ||
| def snap_length_threshold(self) -> float: | ||
| """Snap length threshold. | ||
| Returns | ||
| ------- | ||
| float | ||
| Snap length threshold. | ||
| """ | ||
| return self._pedb.value(self.core.snap_length_threshold) | ||
| @snap_length_threshold.setter | ||
| def snap_length_threshold(self, value: float): | ||
| self.core.snap_length_threshold = str(self._pedb.value(value)) |
| # Copyright (C) 2023 - 2026 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. | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.siwave_simulation_settings import ( | ||
| SIWaveDCAdvancedSettings as CoreSIWaveDCAdvancedSettings, | ||
| ) | ||
| class SIWaveDCAdvancedSettings: | ||
| """Siwave DC Advanced simulation settings class.""" | ||
| def __init__(self, pedb, core: "CoreSIWaveDCAdvancedSettings"): | ||
| self._pedb = pedb | ||
| self.core = core | ||
| @property | ||
| def dc_min_plane_area_to_mesh(self) -> str: | ||
| """Minimum plane area to mesh. | ||
| Returns | ||
| ------- | ||
| float | ||
| Minimum plane area to mesh value. | ||
| """ | ||
| return self.core.dc_min_plane_area_to_mesh | ||
| @dc_min_plane_area_to_mesh.setter | ||
| def dc_min_plane_area_to_mesh(self, value: str): | ||
| self.core.dc_min_plane_area_to_mesh = value | ||
| @property | ||
| def dc_min_void_area_to_mesh(self) -> str: | ||
| """Minimum void area to mesh. | ||
| Returns | ||
| ------- | ||
| str | ||
| Minimum void area to mesh value. | ||
| """ | ||
| return self.core.dc_min_void_area_to_mesh | ||
| @dc_min_void_area_to_mesh.setter | ||
| def dc_min_void_area_to_mesh(self, value: str): | ||
| self.core.dc_min_void_area_to_mesh = value | ||
| @property | ||
| def energy_error(self) -> float: | ||
| """Energy error. | ||
| Returns | ||
| ------- | ||
| float | ||
| Energy error value. | ||
| """ | ||
| return self.core.energy_error | ||
| @energy_error.setter | ||
| def energy_error(self, value: float): | ||
| self.core.energy_error = value | ||
| @property | ||
| def max_init_mesh_edge_length(self) -> str: | ||
| """Maximum initial mesh edge length. | ||
| Returns | ||
| ------- | ||
| str | ||
| Maximum initial mesh edge length value. | ||
| """ | ||
| return self.core.max_init_mesh_edge_length | ||
| @max_init_mesh_edge_length.setter | ||
| def max_init_mesh_edge_length(self, value: str): | ||
| self.core.max_init_mesh_edge_length = value | ||
| @property | ||
| def max_num_passes(self) -> int: | ||
| """Maximum number of passes. | ||
| Returns | ||
| ------- | ||
| int | ||
| Maximum number of passes value. | ||
| """ | ||
| return self.core.max_num_passes | ||
| @max_num_passes.setter | ||
| def max_num_passes(self, value: int): | ||
| self.core.max_num_passes = value | ||
| @property | ||
| def mesh_bws(self) -> bool: | ||
| """Mesh BWS. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Mesh BWS value. | ||
| """ | ||
| return self.core.mesh_bws | ||
| @mesh_bws.setter | ||
| def mesh_bws(self, value: bool): | ||
| self.core.mesh_bws = value | ||
| @property | ||
| def mesh_vias(self) -> bool: | ||
| """Mesh vias. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Mesh vias value. | ||
| """ | ||
| return self.core.mesh_vias | ||
| @mesh_vias.setter | ||
| def mesh_vias(self, value: bool): | ||
| self.core.mesh_vias = value | ||
| @property | ||
| def min_num_passes(self) -> int: | ||
| """Minimum number of passes. | ||
| Returns | ||
| ------- | ||
| int | ||
| Minimum number of passes value. | ||
| """ | ||
| return self.core.min_num_passes | ||
| @min_num_passes.setter | ||
| def min_num_passes(self, value: int): | ||
| self.core.min_num_passes = value | ||
| @property | ||
| def num_bw_sides(self) -> int: | ||
| """Number of BWS sides. | ||
| Returns | ||
| ------- | ||
| int | ||
| Number of BWS sides value. | ||
| """ | ||
| return self.core.num_bw_sides | ||
| @num_bw_sides.setter | ||
| def num_bw_sides(self, value: int): | ||
| self.core.num_bw_sides = value | ||
| @property | ||
| def num_via_sides(self) -> int: | ||
| """Number of via sides. | ||
| Returns | ||
| ------- | ||
| int | ||
| Number of via sides value. | ||
| """ | ||
| return self.core.num_via_sides | ||
| @num_via_sides.setter | ||
| def num_via_sides(self, value: int): | ||
| self.core.num_via_sides = value | ||
| @property | ||
| def percent_local_refinement(self) -> float: | ||
| """Percentage of local refinement. | ||
| Returns | ||
| ------- | ||
| float | ||
| Percentage of local refinement value. | ||
| """ | ||
| return self.core.percent_local_refinement | ||
| @percent_local_refinement.setter | ||
| def percent_local_refinement(self, value: float): | ||
| self.core.percent_local_refinement = value | ||
| @property | ||
| def perform_adaptive_refinement(self) -> bool: | ||
| """Perform adaptive refinement. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Perform adaptive refinement value. | ||
| """ | ||
| return self.core.perform_adaptive_refinement | ||
| @perform_adaptive_refinement.setter | ||
| def perform_adaptive_refinement(self, value: bool): | ||
| self.core.perform_adaptive_refinement = value | ||
| @property | ||
| def refine_bws(self) -> bool: | ||
| """Refine BWS. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Refine BWS value. | ||
| """ | ||
| return self.core.refine_bws | ||
| @refine_bws.setter | ||
| def refine_bws(self, value: bool): | ||
| self.core.refine_bws = value | ||
| @property | ||
| def refine_vias(self) -> bool: | ||
| """Refine vias. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Refine vias value. | ||
| """ | ||
| return self.core.refine_vias | ||
| @refine_vias.setter | ||
| def refine_vias(self, value: bool): | ||
| self.core.refine_vias = value |
| # Copyright (C) 2023 - 2026 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. | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.siwave_simulation_settings import SIWaveDCSettings as CoreSIWaveDCSettings | ||
| class SIWaveDCSettings: | ||
| def __init__(self, pedb, core: "CoreSIWaveDCSettings"): | ||
| """PyEDB SIWave simulation settings class.""" | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def compute_inductance(self) -> bool: | ||
| """Compute inductance flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if compute inductance is enabled, False otherwise. | ||
| """ | ||
| return self.core.compute_inductance | ||
| @compute_inductance.setter | ||
| def compute_inductance(self, value: bool): | ||
| """Set compute inductance flag. | ||
| Parameters | ||
| ---------- | ||
| value : bool | ||
| True to enable compute inductance, False to disable. | ||
| """ | ||
| self.core.compute_inductance = value | ||
| @property | ||
| def contact_radius(self) -> str: | ||
| """Contact radius value. | ||
| Returns | ||
| ------- | ||
| str | ||
| Contact radius. | ||
| """ | ||
| return self.core.contact_radius | ||
| @contact_radius.setter | ||
| def contact_radius(self, value: str): | ||
| self.core.contact_radius = value | ||
| @property | ||
| def dc_slider_pos(self) -> int: | ||
| """DC slider position. | ||
| Returns | ||
| ------- | ||
| int | ||
| DC slider position. | ||
| """ | ||
| return self.core.dc_slider_pos | ||
| @dc_slider_pos.setter | ||
| def dc_slider_pos(self, value: int): | ||
| self.core.dc_slider_pos = value | ||
| @property | ||
| def plot_jv(self) -> bool: | ||
| """Plot JV flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if plot JV is enabled, False otherwise. | ||
| """ | ||
| return self.core.plot_jv | ||
| @plot_jv.setter | ||
| def plot_jv(self, value: bool): | ||
| self.core.plot_jv = value | ||
| @property | ||
| def use_dc_custom_settings(self) -> bool: | ||
| """Use DC custom settings flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if DC custom settings are used, False otherwise. | ||
| """ | ||
| return self.core.use_dc_custom_settings | ||
| @use_dc_custom_settings.setter | ||
| def use_dc_custom_settings(self, value: bool): | ||
| self.core.use_dc_custom_settings = value | ||
| @property | ||
| def export_dc_thermal_data(self) -> bool: | ||
| """Export DC thermal data flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if export DC thermal data is enabled, False otherwise. | ||
| """ | ||
| return self.core.export_dc_thermal_data | ||
| @export_dc_thermal_data.setter | ||
| def export_dc_thermal_data(self, value: bool): | ||
| self.core.export_dc_thermal_data = value | ||
| @property | ||
| def import_thermal_data(self) -> bool: | ||
| """Import thermal data flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if import thermal data is enabled, False otherwise. | ||
| """ | ||
| return self.core.import_thermal_data | ||
| @import_thermal_data.setter | ||
| def import_thermal_data(self, value: bool): | ||
| self.core.import_thermal_data = value | ||
| @property | ||
| def dc_report_show_active_devices(self) -> bool: | ||
| """DC report show active devices flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if DC report show active devices is enabled, False otherwise. | ||
| """ | ||
| return self.core.dc_report_show_active_devices | ||
| @dc_report_show_active_devices.setter | ||
| def dc_report_show_active_devices(self, value: bool): | ||
| self.core.dc_report_show_active_devices = value | ||
| @property | ||
| def per_pin_use_pin_format(self) -> bool: | ||
| """Per pin use pin format flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if per pin use pin format is enabled, False otherwise. | ||
| """ | ||
| return self.core.per_pin_use_pin_format | ||
| @per_pin_use_pin_format.setter | ||
| def per_pin_use_pin_format(self, value: bool): | ||
| self.core.per_pin_use_pin_format = value | ||
| @property | ||
| def use_loop_res_for_per_pin(self) -> bool: | ||
| """Use loop resistance for per pin flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if use loop resistance for per pin is enabled, False otherwise. | ||
| """ | ||
| return self.core.use_loop_res_for_per_pin | ||
| @use_loop_res_for_per_pin.setter | ||
| def use_loop_res_for_per_pin(self, value: bool): | ||
| self.core.use_loop_res_for_per_pin = value | ||
| @property | ||
| def dc_report_config_file(self) -> str: | ||
| """DC report configuration file. | ||
| Returns | ||
| ------- | ||
| str | ||
| DC report configuration file. | ||
| """ | ||
| return self.core.dc_report_config_file | ||
| @dc_report_config_file.setter | ||
| def dc_report_config_file(self, value: str): | ||
| self.core.dc_report_config_file = value | ||
| @property | ||
| def full_dc_report_path(self) -> str: | ||
| """Full DC report path. | ||
| Returns | ||
| ------- | ||
| str | ||
| Full DC report path. | ||
| """ | ||
| return self.core.full_dc_report_path | ||
| @full_dc_report_path.setter | ||
| def full_dc_report_path(self, value: str): | ||
| self.core.full_dc_report_path = value | ||
| @property | ||
| def icepak_temp_file(self) -> str: | ||
| """Icepak temperature file. | ||
| Returns | ||
| ------- | ||
| str | ||
| Icepak temperature file. | ||
| """ | ||
| return self.core.icepak_temp_file | ||
| @icepak_temp_file.setter | ||
| def icepak_temp_file(self, value: str): | ||
| self.core.icepak_temp_file = value | ||
| @property | ||
| def per_pin_res_path(self) -> bool: | ||
| """Per pin resistance path. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if per pin resistance path is enabled, False otherwise. | ||
| """ | ||
| return self.core.per_pin_res_path | ||
| @per_pin_res_path.setter | ||
| def per_pin_res_path(self, value: bool): | ||
| self.core.per_pin_res_path = value | ||
| @property | ||
| def via_report_path(self) -> str: | ||
| """Via report path. | ||
| Returns | ||
| ------- | ||
| str | ||
| Via report path. | ||
| """ | ||
| return self.core.via_report_path | ||
| @via_report_path.setter | ||
| def via_report_path(self, value: str): | ||
| self.core.via_report_path = value | ||
| @property | ||
| def source_terms_to_ground(self) -> dict[str, int]: | ||
| """Source terms to ground mapping. | ||
| Returns | ||
| ------- | ||
| dict[str, int] | ||
| Source terms to ground mapping. | ||
| """ | ||
| return self.core.source_terms_to_ground | ||
| @source_terms_to_ground.setter | ||
| def source_terms_to_ground(self, value: dict[str, int]): | ||
| self.core.source_terms_to_ground = value |
| # Copyright (C) 2023 - 2026 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. | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.siwave_simulation_settings import ( | ||
| SIWaveGeneralSettings as CoreSIWaveGeneralSettings, | ||
| ) | ||
| class SIWaveGeneralSettings: | ||
| def __init__(self, pedb, core: "CoreSIWaveGeneralSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def pi_slider_pos(self) -> int: | ||
| """Position of the PI slider. | ||
| Returns | ||
| ------- | ||
| int | ||
| Position value. | ||
| """ | ||
| return self.core.pi_slider_pos | ||
| @pi_slider_pos.setter | ||
| def pi_slider_pos(self, value: int): | ||
| self.core.pi_slider_pos = value | ||
| @property | ||
| def si_slider_pos(self) -> int: | ||
| """Position of the SI slider. | ||
| Returns | ||
| ------- | ||
| int | ||
| Position value. | ||
| """ | ||
| return self.core.si_slider_pos | ||
| @si_slider_pos.setter | ||
| def si_slider_pos(self, value: int): | ||
| self.core.si_slider_pos = value | ||
| @property | ||
| def use_custom_settings(self) -> bool: | ||
| """Flag to indicate if custom settings are used. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if custom settings are used, False otherwise. | ||
| """ | ||
| return self.core.use_custom_settings | ||
| @use_custom_settings.setter | ||
| def use_custom_settings(self, value: bool): | ||
| self.core.use_custom_settings = value | ||
| @property | ||
| def use_si_settings(self) -> bool: | ||
| """Flag to indicate if SI settings are used. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if SI settings are used, False otherwise. | ||
| """ | ||
| return self.core.use_si_settings | ||
| @use_si_settings.setter | ||
| def use_si_settings(self, value: bool): | ||
| self.core.use_si_settings = value |
| # Copyright (C) 2023 - 2026 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. | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.siwave_simulation_settings import ( | ||
| SIWaveSParameterSettings as CoreSIWaveSParameterSettings, | ||
| ) | ||
| from ansys.edb.core.simulation_setup.siwave_simulation_settings import ( | ||
| SParamDCBehavior as CoreSParamDCBehavior, | ||
| SParamExtrapolation as CoreSParamExtrapolation, | ||
| SParamInterpolation as CoreSParamInterpolation, | ||
| ) | ||
| _mapping_dc_behavior = { | ||
| "zero": CoreSParamDCBehavior.ZERO_DC, | ||
| "same": CoreSParamDCBehavior.SAME_DC, | ||
| "linear": CoreSParamDCBehavior.LINEAR_DC, | ||
| "constant": CoreSParamDCBehavior.CONSTANT_DC, | ||
| "one_port_capacitor": CoreSParamDCBehavior.ONE_PORT_CAPACITOR_DC, | ||
| "open": CoreSParamDCBehavior.OPEN_DC, | ||
| } | ||
| _mapping_s_parameter_extrapolation = { | ||
| "zero": CoreSParamExtrapolation.ZERO_EX, | ||
| "same": CoreSParamExtrapolation.SAME_EX, | ||
| "linear": CoreSParamExtrapolation.LINEAR_EX, | ||
| "constant": CoreSParamExtrapolation.CONSTANT_EX, | ||
| } | ||
| _mapping_s_parameter_interpolation = { | ||
| "point": CoreSParamInterpolation.POINT_IN, | ||
| "linear": CoreSParamInterpolation.LINEAR_IN, | ||
| "step": CoreSParamInterpolation.STEP_IN, | ||
| } | ||
| class SIWaveSParameterSettings: | ||
| """SIWave S-Parameter simulation settings class.""" | ||
| def __init__(self, pedb, core: "CoreSIWaveSParameterSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def dc_behavior(self) -> str: | ||
| """Get or set the DC behavior for S-Parameter simulation. | ||
| Returns | ||
| ------- | ||
| str | ||
| The DC behavior as a string. | ||
| """ | ||
| reverse_mapping = {v: k for k, v in _mapping_dc_behavior.items()} | ||
| return reverse_mapping[self.core.dc_behavior] | ||
| @dc_behavior.setter | ||
| def dc_behavior(self, value: str): | ||
| if value not in _mapping_dc_behavior: | ||
| raise ValueError(f"Invalid DC behavior: {value}. Valid options are: {list(_mapping_dc_behavior.keys())}") | ||
| self.core.dc_behavior = _mapping_dc_behavior[value] | ||
| @property | ||
| def extrapolation(self) -> str: | ||
| """Get or set the S-Parameter extrapolation method. | ||
| Returns | ||
| ------- | ||
| str | ||
| The S-Parameter extrapolation method as a string. | ||
| """ | ||
| reverse_mapping = {v: k for k, v in _mapping_s_parameter_extrapolation.items()} | ||
| return reverse_mapping[self.core.extrapolation] | ||
| @extrapolation.setter | ||
| def extrapolation(self, value: str): | ||
| if value not in _mapping_s_parameter_extrapolation: | ||
| raise ValueError( | ||
| f"Invalid S-Parameter extrapolation: {value}. Valid options are: " | ||
| f"{list(_mapping_s_parameter_extrapolation.keys())}" | ||
| ) | ||
| self.core.extrapolation = _mapping_s_parameter_extrapolation[value] | ||
| @property | ||
| def interpolation(self) -> str: | ||
| """Get or set the S-Parameter interpolation method. | ||
| Returns | ||
| ------- | ||
| str | ||
| The S-Parameter interpolation method as a string. | ||
| """ | ||
| reverse_mapping = {v: k for k, v in _mapping_s_parameter_interpolation.items()} | ||
| return reverse_mapping[self.core.interpolation] | ||
| @interpolation.setter | ||
| def interpolation(self, value: str): | ||
| if value not in _mapping_s_parameter_interpolation: | ||
| raise ValueError( | ||
| f"Invalid S-Parameter interpolation: {value}. Valid options are: " | ||
| f"{list(_mapping_s_parameter_interpolation.keys())}" | ||
| ) | ||
| self.core.interpolation = _mapping_s_parameter_interpolation[value] | ||
| @property | ||
| def use_state_space(self) -> bool: | ||
| """Get or set whether to use state space representation. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if state space representation is used, False otherwise. | ||
| """ | ||
| return self.core.use_state_space | ||
| @use_state_space.setter | ||
| def use_state_space(self, value: bool): | ||
| self.core.use_state_space = value |
| # Copyright (C) 2023 - 2026 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. | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.siwave_simulation_settings import ( | ||
| SIWaveSimulationSettings as CoreSIWaveSimulationSettings, | ||
| ) | ||
| from pyedb.grpc.database.simulation_setup.siwave_advanced_settings import SIWaveAdvancedSettings | ||
| from pyedb.grpc.database.simulation_setup.siwave_dc_advanced import SIWaveDCAdvancedSettings | ||
| from pyedb.grpc.database.simulation_setup.siwave_dc_settings import SIWaveDCSettings | ||
| from pyedb.grpc.database.simulation_setup.siwave_general_settings import SIWaveGeneralSettings | ||
| from pyedb.grpc.database.simulation_setup.siwave_s_parameter_settings import SIWaveSParameterSettings | ||
| class SIWaveSimulationSettings: | ||
| def __init__(self, pedb, core: "CoreSIWaveSimulationSettings"): | ||
| """PyEDB SIWave simulation settings class.""" | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def advanced(self) -> SIWaveAdvancedSettings: | ||
| """Advanced settings class. | ||
| Returns | ||
| ------- | ||
| :class:`SIWaveAdvancedSettings <pyedb.grpc.database.simulation_setup. | ||
| siwave_advanced_settings.SIWaveAdvancedSettings>` | ||
| """ | ||
| return SIWaveAdvancedSettings(self._pedb, self.core.advanced) | ||
| @property | ||
| def dc(self) -> SIWaveDCSettings: | ||
| """DC settings class. | ||
| Returns | ||
| ------- | ||
| :class:`SIWaveDCSettings <pyedb.grpc.database.simulation_setup. | ||
| siwave_dc_settings.SIWaveDCSettings>` | ||
| """ | ||
| return SIWaveDCSettings(self._pedb, self.core.dc) | ||
| @property | ||
| def dc_advanced(self) -> SIWaveDCAdvancedSettings: | ||
| """DC advanced settings class. | ||
| Returns | ||
| ------- | ||
| :class:`SIWaveDCAdvancedSettings <pyedb.grpc.database.simulation_setup. | ||
| siwave_dc_advanced.SIWaveDCAdvancedSettings>` | ||
| """ | ||
| return SIWaveDCAdvancedSettings(self._pedb, self.core.dc_advanced) | ||
| @property | ||
| def enabled(self) -> bool: | ||
| """Enabled status of the SIWave simulation. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if enabled, False otherwise. | ||
| """ | ||
| return self.core.enabled | ||
| @enabled.setter | ||
| def enabled(self, value: bool): | ||
| self.core.enabled = value | ||
| @property | ||
| def general(self) -> SIWaveGeneralSettings: | ||
| """General settings class. | ||
| Returns | ||
| ------- | ||
| :class:`SIWaveGeneralSettings <pyedb.grpc.database.simulation_setup. | ||
| siwave_general_settings.SIWaveGeneralSettings>` | ||
| """ | ||
| return SIWaveGeneralSettings(self._pedb, self.core.general) | ||
| @property | ||
| def s_parameter(self) -> SIWaveSParameterSettings: | ||
| """S-Parameter settings class. | ||
| Returns | ||
| ------- | ||
| :class:`SIWaveSParameterSettings <pyedb.grpc.database.simulation_setup. | ||
| siwave_s_parameter_settings.SIWaveSParameterSettings>` | ||
| """ | ||
| return SIWaveSParameterSettings(self._pedb, self.core.s_parameter) |
| # Copyright (C) 2023 - 2026 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. | ||
| from ansys.edb.core.simulation_setup.mesh_operation import SkinDepthMeshOperation as CoreSkinDepthMeshOperation | ||
| class SkinDepthMeshOperation: | ||
| """PyEDB Length Mesh Operation class.""" | ||
| def __init__( | ||
| self, | ||
| core=None, | ||
| name="", | ||
| net_layer_info=None, | ||
| enabled=True, | ||
| refine_inside=False, | ||
| mesh_region="", | ||
| solve_inside=False, | ||
| skin_depth: str = "1um", | ||
| surface_triangle_length: str = "1mm", | ||
| num_layers: str = "2", | ||
| max_elements: str = "1000", | ||
| restrict_max_elements: bool = False, | ||
| ): | ||
| if not core: | ||
| self.core = self.create( | ||
| name=name, | ||
| net_layer_info=net_layer_info, | ||
| enabled=enabled, | ||
| refine_inside=refine_inside, | ||
| mesh_region=mesh_region, | ||
| solve_inside=solve_inside, | ||
| skin_depth=skin_depth, | ||
| surface_triangle_length=surface_triangle_length, | ||
| num_layers=num_layers, | ||
| max_elements=max_elements, | ||
| restrict_max_elements=restrict_max_elements, | ||
| ) | ||
| else: | ||
| self.core = core | ||
| @classmethod | ||
| def create( | ||
| cls, | ||
| name: str = "", | ||
| net_layer_info: tuple[str, str, bool] = None, | ||
| enabled: bool = True, | ||
| refine_inside: bool = False, | ||
| mesh_region: str = "", | ||
| solve_inside: bool = False, | ||
| skin_depth: str = "1um", | ||
| surface_triangle_length: str = "1mm", | ||
| num_layers: str = "2", | ||
| max_elements: str = "1000", | ||
| restrict_max_elements: bool = False, | ||
| ) -> "SkinDepthMeshOperation": | ||
| """Create a Length Mesh Operation. | ||
| Parameters | ||
| ---------- | ||
| name : str | ||
| Name of the mesh operation. | ||
| net_layer_info : tuple[str, str, bool] | ||
| A tuple containing the net name, layer name, and a boolean indicating whether to include | ||
| child layers. | ||
| enabled : bool | ||
| Whether the mesh operation is enabled. | ||
| refine_inside : bool | ||
| Whether to refine the mesh inside the specified region. | ||
| mesh_region : str | ||
| The name of the mesh region. | ||
| solve_inside : bool | ||
| Whether to solve inside the specified region. | ||
| skin_depth : str | ||
| The skin_depth value. | ||
| surface_triangle_length : str | ||
| The surface triangle length value. | ||
| num_layers: int | ||
| Number of layers for the skin depth mesh operation. | ||
| max_elements : int | ||
| Maximum number of elements for the mesh operation. | ||
| restrict_max_elements : bool | ||
| Whether to restrict the maximum number of elements. | ||
| Returns | ||
| ------- | ||
| LengthMeshOperation : LengthMeshOperation | ||
| The Length Mesh Operation object. | ||
| """ | ||
| core_op = CoreSkinDepthMeshOperation( | ||
| name=name, | ||
| net_layer_info=net_layer_info, | ||
| enabled=enabled, | ||
| refine_inside=refine_inside, | ||
| mesh_region=mesh_region, | ||
| solve_inside=solve_inside, | ||
| skin_depth=skin_depth, | ||
| surface_triangle_length=surface_triangle_length, | ||
| num_layers=num_layers, | ||
| max_elements=max_elements, | ||
| restrict_max_elements=restrict_max_elements, | ||
| ) | ||
| return cls(core=core_op) | ||
| @property | ||
| def name(self) -> str: | ||
| """Get the name of the mesh operation. | ||
| Returns | ||
| ------- | ||
| str | ||
| Name of the mesh operation. | ||
| """ | ||
| return self.core.name | ||
| @name.setter | ||
| def name(self, value: str): | ||
| self.core.name = value | ||
| @property | ||
| def enabled(self) -> bool: | ||
| """Get the enabled status of the mesh operation. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if the mesh operation is enabled, False otherwise. | ||
| """ | ||
| return self.core.enabled | ||
| @enabled.setter | ||
| def enabled(self, value: bool): | ||
| self.core.enabled = value | ||
| @property | ||
| def mesh_region(self) -> str: | ||
| """Get the mesh region name. | ||
| Returns | ||
| ------- | ||
| str | ||
| Name of the mesh region. | ||
| """ | ||
| return self.core.mesh_region | ||
| @mesh_region.setter | ||
| def mesh_region(self, value: str): | ||
| self.core.mesh_region = value | ||
| @property | ||
| def net_layer_info(self) -> list[tuple[str, str, bool]]: | ||
| """Get the net layer information list. | ||
| Returns | ||
| ------- | ||
| list[tuple(str, str, bool)] | ||
| List of net layer information for the mesh operation. | ||
| """ | ||
| return list(self.core.net_layer_info) | ||
| @net_layer_info.setter | ||
| def net_layer_info(self, value: list[tuple[str, str, bool]]): | ||
| self.core.net_layer_info.clear() | ||
| for info in value: | ||
| self.core.net_layer_info.append(info) | ||
| @property | ||
| def refine_inside(self) -> bool: | ||
| """Get the refine inside status of the mesh operation. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if refining inside is enabled, False otherwise. | ||
| """ | ||
| return self.core.refine_inside | ||
| @refine_inside.setter | ||
| def refine_inside(self, value: bool): | ||
| self.core.refine_inside = value | ||
| @property | ||
| def solve_inside(self) -> bool: | ||
| """Get the solve inside status of the mesh operation. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if solving inside is enabled, False otherwise. | ||
| """ | ||
| return self.core.solve_inside | ||
| @solve_inside.setter | ||
| def solve_inside(self, value: bool): | ||
| self.core.solve_inside = value | ||
| @property | ||
| def skin_depth(self) -> str: | ||
| """Get the skin depth value. | ||
| Returns | ||
| ------- | ||
| str | ||
| Skin depth value. | ||
| """ | ||
| return self.core.skin_depth | ||
| @skin_depth.setter | ||
| def skin_depth(self, value: str): | ||
| self.core.skin_depth = value | ||
| @property | ||
| def surface_triangle_length(self) -> str: | ||
| """Get the surface triangle length value. | ||
| Returns | ||
| ------- | ||
| str | ||
| Surface triangle length value. | ||
| """ | ||
| return self.core.surface_triangle_length | ||
| @surface_triangle_length.setter | ||
| def surface_triangle_length(self, value: str): | ||
| self.core.surface_triangle_length = value | ||
| @property | ||
| def num_layers(self) -> str: | ||
| """Get the number of layers for the skin depth mesh operation. | ||
| Returns | ||
| ------- | ||
| int | ||
| Number of layers. | ||
| """ | ||
| return self.core.num_layers | ||
| @num_layers.setter | ||
| def num_layers(self, value: str): | ||
| self.core.num_layers = value | ||
| @property | ||
| def max_elements(self) -> str: | ||
| """Get the maximum number of elements for the mesh operation. | ||
| Returns | ||
| ------- | ||
| int | ||
| Maximum number of elements. | ||
| """ | ||
| return self.core.max_elements | ||
| @max_elements.setter | ||
| def max_elements(self, value: str): | ||
| self.core.max_elements = value | ||
| @property | ||
| def restrict_max_elements(self) -> bool: | ||
| """Get the restrict maximum elements status of the mesh operation. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if restricting maximum elements is enabled, False otherwise. | ||
| """ | ||
| return self.core.restrict_max_elements | ||
| @restrict_max_elements.setter | ||
| def restrict_max_elements(self, value: bool): | ||
| self.core.restrict_max_elements = value |
| # Copyright (C) 2023 - 2026 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. | ||
| from typing import Union, cast | ||
| from ansys.edb.core.database import ProductIdType as CoreProductIdType | ||
| from pyedb.generic.general_methods import generate_unique_name | ||
| from pyedb.grpc.database.simulation_setup.hfss_simulation_setup import HfssSimulationSetup | ||
| from pyedb.grpc.database.simulation_setup.q3d_simulation_setup import Q3DSimulationSetup | ||
| from pyedb.grpc.database.simulation_setup.raptor_x_simulation_setup import RaptorXSimulationSetup | ||
| from pyedb.grpc.database.simulation_setup.simulation_setup import SimulationSetup as BaseSimulationSetup | ||
| from pyedb.grpc.database.simulation_setup.siwave_cpa_simulation_setup import SIWaveCPASimulationSetup | ||
| from pyedb.grpc.database.simulation_setup.siwave_dcir_simulation_setup import SIWaveDCIRSimulationSetup | ||
| from pyedb.grpc.database.simulation_setup.siwave_simulation_setup import SiwaveSimulationSetup | ||
| from pyedb.misc.decorators import deprecate_argument_name | ||
| from pyedb.siwave_core.product_properties import SIwaveProperties | ||
| class SimulationSetups: | ||
| """Simulation setups container class.""" | ||
| def __init__(self, pedb): | ||
| self._pedb = pedb | ||
| self._hfss_setups: dict[str, HfssSimulationSetup] = {} | ||
| self._siwave_setups: dict[str, SiwaveSimulationSetup] = {} | ||
| self._siwave_dcir_setups: dict[str, SIWaveDCIRSimulationSetup] = {} | ||
| self._raptorx_setups: dict[str, RaptorXSimulationSetup] = {} | ||
| self._q3d_setups: dict[str, Q3DSimulationSetup] = {} | ||
| self._siwave_cpa_setup: dict[str, SIWaveCPASimulationSetup] = {} | ||
| @property | ||
| def hfss(self) -> dict[str, HfssSimulationSetup]: | ||
| """HFSS simulation setups. | ||
| Returns | ||
| ------- | ||
| List[:class:`HFSSSimulationSetup <pyedb.grpc.database.simulation_setup. | ||
| hfss_simulation_setup.HFSSSimulationSetup>`] | ||
| """ | ||
| self._hfss_setups = { | ||
| setup.name: HfssSimulationSetup(self._pedb, setup) | ||
| for setup in self._pedb.active_cell.simulation_setups | ||
| if setup.type.name.lower() == "hfss" | ||
| } | ||
| return self._hfss_setups | ||
| @property | ||
| def siwave(self) -> dict[str, SiwaveSimulationSetup]: | ||
| """SIWave simulation setups. | ||
| Returns | ||
| ------- | ||
| List[:class:`SIWaveSimulationSetup <pyedb.grpc.database.simulation_setup. | ||
| siwave_simulation_setup.SIWaveSimulationSetup>`] | ||
| """ | ||
| self._siwave_setups = { | ||
| setup.name: SiwaveSimulationSetup(self._pedb, setup) | ||
| for setup in self._pedb.active_cell.simulation_setups | ||
| if setup.type.name.lower() == "si_wave" | ||
| } | ||
| return self._siwave_setups | ||
| @property | ||
| def siwave_dcir(self) -> dict[str, SIWaveDCIRSimulationSetup]: | ||
| """SIWave DCIR simulation setups. | ||
| Returns | ||
| ------- | ||
| List[:class:`SIWaveDCIRSimulationSetup <pyedb.grpc.database.simulation_setup. | ||
| siwave_dcir_simulation_setup.SIWaveDCIRSimulationSetup>`] | ||
| """ | ||
| self._siwave_dcir_setups = { | ||
| setup.name: SIWaveDCIRSimulationSetup(self._pedb, setup) | ||
| for setup in self._pedb.active_cell.simulation_setups | ||
| if setup.type.name.lower() == "si_wave_dcir" | ||
| } | ||
| return self._siwave_dcir_setups | ||
| @property | ||
| def siwave_cpa(self) -> dict[str, SIWaveCPASimulationSetup]: | ||
| """SIWave CPA simulation setups. | ||
| Returns | ||
| ------- | ||
| List[:class:`SIWaveCPASimulationSetup <pyedb.grpc.database.simulation_setup. | ||
| siwave_cpa_simulation_setup.SIWaveCPASimulationSetup>`] | ||
| """ | ||
| # cpa setup is not a real simulation setup type in EDB. | ||
| # It is created through product interface (ProductProperty). | ||
| # THe setup is unique per design, and is created when imported inside SIwave, | ||
| # THe setup does not reside itself inside simulation setups collection. | ||
| # check if cpa name exists | ||
| cpa_setup_name = self._pedb.active_cell.get_product_property( | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_SIM_NAME | ||
| ).value | ||
| if cpa_setup_name: | ||
| if cpa_setup_name not in self._siwave_cpa_setup: | ||
| # instantiate the cpa setup | ||
| self._siwave_cpa_setup[cpa_setup_name] = SIWaveCPASimulationSetup(self._pedb, cpa_setup_name) | ||
| return self._siwave_cpa_setup | ||
| @property | ||
| def raptorx(self) -> dict[str, RaptorXSimulationSetup]: | ||
| """RaptorX simulation setups. | ||
| Returns | ||
| ------- | ||
| List[:class:`RaptorXSimulationSetup <pyedb.grpc.database.simulation_setup. | ||
| raptor_x_simulation_setup.RaptorXSimulationSetup>`] | ||
| """ | ||
| if self._raptorx_setups is None: | ||
| self._raptorx_setups = { | ||
| setup.name: RaptorXSimulationSetup(self._pedb, setup) | ||
| for setup in self._pedb.active_cell.simulation_setups | ||
| if setup.type.name.lower() == "raptor_x" | ||
| } | ||
| return self._raptorx_setups | ||
| @property | ||
| def q3d(self) -> dict[str, Q3DSimulationSetup]: | ||
| """Q3D simulation setups. | ||
| Returns | ||
| ------- | ||
| List[:class:`Q3DSimulationSetup <pyedb.grpc.database.simulation_setup. | ||
| q3d_simulation_setup.Q3DSimulationSetup>`] | ||
| """ | ||
| if self._q3d_setups is None: | ||
| self._q3d_setups = { | ||
| setup.name: Q3DSimulationSetup(self._pedb, setup) | ||
| for setup in self._pedb.active_cell.simulation_setups | ||
| if setup.type == "q3d_sim" | ||
| } | ||
| return self._q3d_setups | ||
| @property | ||
| def setups(self) -> dict[str, object]: | ||
| """All simulation setups. | ||
| Returns | ||
| ------- | ||
| dict[str:setup name, :class:`SimulationSetup <pyedb.grpc.database.simulation_setup. | ||
| simulation_setup.SimulationSetup>`] | ||
| """ | ||
| # Merge all per-solver dicts into a single mapping | ||
| return {**self.hfss, **self.siwave, **self.siwave_dcir, **self.siwave_cpa, **self.raptorx, **self.q3d} | ||
| def create( | ||
| self, | ||
| name=None, | ||
| solver="hfss", | ||
| distribution="linear", | ||
| start_freq=0, | ||
| stop_freq=20e9, | ||
| step_freq=1e6, | ||
| discrete_sweep=False, | ||
| sweep_name: str = "frequency_sweep", | ||
| **kwargs, | ||
| ) -> Union[BaseSimulationSetup, None]: | ||
| """Add HFSS analysis setup. | ||
| Parameters | ||
| ---------- | ||
| name : str, optional | ||
| Setup name (auto-generated if None). | ||
| solver : str, optional | ||
| Simulation setup type ("hfss", "siwave", "siwave_dcir", "raptorx", "q3d"). | ||
| distribution : str, optional | ||
| Sweep distribution type ("linear", "linear_count", "decade_count", "octave_count", "exponential"). | ||
| start_freq : float, str, optional | ||
| Starting frequency (Hz). | ||
| stop_freq : float, str, optional | ||
| Stopping frequency (Hz). | ||
| step_freq : float, str, int, optional | ||
| Frequency step (Hz) or count depending on distribution. | ||
| discrete_sweep : bool, optional | ||
| Use discrete sweep. | ||
| sweep_name : str, optional | ||
| Name of the frequency sweep. | ||
| Returns | ||
| ------- | ||
| HfssSimulationSetup | ||
| Created setup object. | ||
| Examples | ||
| -------- | ||
| .. code:: python | ||
| from pyedb import Edb | ||
| edb = Edb("my_aedb") | ||
| hfss_setup = edb.simulation_setups.create( | ||
| name="MySetup", | ||
| solver="hfss", | ||
| distribution="linear_count", | ||
| start_freq=1e9, | ||
| stop_freq=10e9, | ||
| step_freq=100, | ||
| discrete_sweep=False, | ||
| sweep_name="MyFrequencySweep", | ||
| ) | ||
| """ | ||
| if not name: | ||
| name = generate_unique_name(f"{solver}_setup") | ||
| if name in self._pedb.setups: | ||
| self._pedb.logger.error(f"Simulation setup {name} already defined.") | ||
| return None | ||
| if solver.lower() == "hfss": | ||
| setup = HfssSimulationSetup.create(self._pedb, name) | ||
| self._pedb.logger.info(f"HFSS setup {name} created.") | ||
| elif solver.lower() == "siwave": | ||
| setup = SiwaveSimulationSetup.create(self._pedb, name) | ||
| self._pedb.logger.info(f"SIWave setup {name} created.") | ||
| elif solver.lower() == "siwave_dcir": | ||
| setup = SIWaveDCIRSimulationSetup.create(self._pedb, name) | ||
| self._pedb.logger.info(f"SIWave DCIR setup {name} created.") | ||
| elif solver.lower() == "raptor_x": | ||
| setup = RaptorXSimulationSetup.create(self._pedb, name) | ||
| self._pedb.logger.info(f"RaptorX setup {name} created.") | ||
| elif solver.lower() == "q3d": | ||
| setup = Q3DSimulationSetup.create(self._pedb, name) | ||
| self._pedb.logger.info(f"Q3D setup {name} created.") | ||
| else: | ||
| setup = HfssSimulationSetup.create(self._pedb, name) | ||
| self._pedb.logger.info(f"HFSS setup {name} created.") | ||
| if not setup.is_null: | ||
| if start_freq and stop_freq and step_freq: | ||
| setup.add_sweep( | ||
| name=sweep_name, | ||
| distribution=distribution, | ||
| start_freq=start_freq, | ||
| stop_freq=stop_freq, | ||
| step=step_freq, | ||
| discrete=discrete_sweep, | ||
| frequency_set=None, | ||
| ) | ||
| self._pedb.logger.info(f"Frequency sweep {sweep_name} added to simulation setup {name}.") | ||
| for k, v in kwargs.items(): | ||
| setattr(setup, k, v) | ||
| return setup | ||
| @deprecate_argument_name({"freq_step": "step_freq"}) | ||
| def create_hfss_setup( | ||
| self, | ||
| name=None, | ||
| distribution="linear", | ||
| start_freq: float = None, | ||
| stop_freq: float = None, | ||
| step_freq: float = None, | ||
| discrete_sweep=False, | ||
| sweep_name: str = "frequency_sweep", | ||
| **kwargs, | ||
| ) -> HfssSimulationSetup: | ||
| """Add HFSS analysis setup. | ||
| Parameters | ||
| ---------- | ||
| name : str, optional | ||
| Setup name (auto-generated if None). | ||
| distribution : str, optional | ||
| Sweep distribution type ("linear", "linear_count", "decade_count", "octave_count", "exponential"). | ||
| start_freq : float, str, optional | ||
| Starting frequency (Hz). | ||
| stop_freq : float, str, optional | ||
| Stopping frequency (Hz). | ||
| step_freq : float, str, int, optional | ||
| Frequency step (Hz) or count depending on distribution. | ||
| discrete_sweep : bool, optional | ||
| Use discrete sweep. | ||
| sweep_name : str, optional | ||
| Name of the frequency sweep. | ||
| Returns | ||
| ------- | ||
| HfssSimulationSetup | ||
| Created setup object. | ||
| """ | ||
| result = self.create( | ||
| name=name, | ||
| solver="hfss", | ||
| distribution=distribution, | ||
| start_freq=start_freq, | ||
| stop_freq=stop_freq, | ||
| step_freq=step_freq, | ||
| discrete_sweep=discrete_sweep, | ||
| sweep_name=sweep_name, | ||
| **kwargs, | ||
| ) | ||
| return cast(HfssSimulationSetup, result) # casting only for IDE type checking purposes | ||
| def create_siwave_setup( | ||
| self, | ||
| name=None, | ||
| distribution="linear", | ||
| start_freq: float = None, | ||
| stop_freq: float = None, | ||
| step_freq: float = None, | ||
| discrete_sweep=False, | ||
| sweep_name: str = "frequency_sweep", | ||
| **kwargs, | ||
| ) -> SiwaveSimulationSetup: | ||
| """Add SIWave analysis setup. | ||
| Parameters | ||
| ---------- | ||
| name : str, optional | ||
| Setup name (auto-generated if None). | ||
| distribution : str, optional | ||
| Sweep distribution type ("linear", "linear_count", "decade_count", "octave_count", "exponential"). | ||
| start_freq : float, str, optional | ||
| Starting frequency (Hz). | ||
| stop_freq : float, str, optional | ||
| Stopping frequency (Hz). | ||
| step_freq : float, str, int, optional | ||
| Frequency step (Hz) or count depending on distribution. | ||
| discrete_sweep : bool, optional | ||
| Use discrete sweep. | ||
| sweep_name : str, optional | ||
| Name of the frequency sweep. | ||
| Returns | ||
| ------- | ||
| SIWaveSimulationSetup | ||
| Created setup object. | ||
| """ | ||
| result = self.create( | ||
| name=name, | ||
| solver="siwave", | ||
| distribution=distribution, | ||
| start_freq=start_freq, | ||
| stop_freq=stop_freq, | ||
| step_freq=step_freq, | ||
| discrete_sweep=discrete_sweep, | ||
| sweep_name=sweep_name, | ||
| **kwargs, | ||
| ) | ||
| return cast(SiwaveSimulationSetup, result) # casting only for IDE type checking purposes | ||
| def create_siwave_dcir_setup(self, name=None, **kwargs) -> SIWaveDCIRSimulationSetup: | ||
| """Add SIWave DCIR analysis setup. | ||
| Parameters | ||
| ---------- | ||
| name : str, optional | ||
| Setup name (auto-generated if None). | ||
| Returns | ||
| ------- | ||
| SIWaveDCIRSimulationSetup | ||
| Created setup object. | ||
| """ | ||
| result = self.create(name=name, solver="siwave_dcir", **kwargs) | ||
| return cast(SIWaveDCIRSimulationSetup, result) # casting only for IDE type checking purposes | ||
| def create_siwave_cpa_setup(self, name=None, siwave_cpa_config=None, **kwargs) -> SIWaveCPASimulationSetup: | ||
| """Add SIWave CPA analysis setup. | ||
| Parameters | ||
| ---------- | ||
| name : str, optional | ||
| Setup name (auto-generated if None). | ||
| Returns | ||
| ------- | ||
| SIWaveCPASimulationSetup | ||
| Created setup object. | ||
| """ | ||
| if not name: | ||
| name = generate_unique_name("siwave_cpa_setup") | ||
| if name in self.siwave_cpa: | ||
| self._pedb.logger.error(f"SIWave CPA simulation setup {name} already defined.") | ||
| return self.siwave_cpa[name] | ||
| # Create the CPA setup through product property interface | ||
| cpa_setup = SIWaveCPASimulationSetup.create(self._pedb, name, siwave_cpa_config) | ||
| self._pedb.logger.info(f"SIWave CPA setup {name} created.") | ||
| # Store the created setup in the internal dictionary | ||
| self._siwave_cpa_setup[name] = cpa_setup | ||
| return cpa_setup | ||
| def create_raptor_x_setup( | ||
| self, | ||
| name=None, | ||
| distribution="linear", | ||
| start_freq: float = None, | ||
| stop_freq: float = None, | ||
| step_freq: float = None, | ||
| discrete_sweep=False, | ||
| sweep_name: str = "frequency_sweep", | ||
| **kwargs, | ||
| ) -> RaptorXSimulationSetup: | ||
| """Add RaptorX analysis setup | ||
| Parameters | ||
| ---------- | ||
| name : str, optional | ||
| Setup name (auto-generated if None). | ||
| distribution : str, optional | ||
| Sweep distribution type ("linear", "linear_count", "decade_count", "octave_count", "exponential"). | ||
| start_freq : float, str, optional | ||
| Starting frequency (Hz). | ||
| stop_freq : float, str, optional | ||
| Stopping frequency (Hz). | ||
| step_freq : float, str, int, optional | ||
| Frequency step (Hz) or count depending on distribution. | ||
| discrete_sweep : bool, optional | ||
| Use discrete sweep. | ||
| sweep_name : str, optional | ||
| Name of the frequency sweep. | ||
| Returns | ||
| ------- | ||
| RaptorXSimulationSetup | ||
| Created setup object. | ||
| """ | ||
| result = self.create( | ||
| name=name, | ||
| solver="raptor_x", | ||
| distribution=distribution, | ||
| start_freq=start_freq, | ||
| stop_freq=stop_freq, | ||
| step_freq=step_freq, | ||
| discrete_sweep=discrete_sweep, | ||
| sweep_name=sweep_name, | ||
| **kwargs, | ||
| ) | ||
| return cast(RaptorXSimulationSetup, result) # casting only for IDE type checking purposes | ||
| def create_q3d_setup( | ||
| self, | ||
| name=None, | ||
| distribution="linear", | ||
| start_freq: float = None, | ||
| stop_freq: float = None, | ||
| step_freq: float = None, | ||
| discrete_sweep=False, | ||
| sweep_name: str = "frequency_sweep", | ||
| **kwargs, | ||
| ) -> Q3DSimulationSetup: | ||
| """Add Q3D analysis setup | ||
| Parameters | ||
| ---------- | ||
| name : str, optional | ||
| Setup name (auto-generated if None). | ||
| distribution : str, optional | ||
| Sweep distribution type ("linear", "linear_count", "decade_count", "octave_count", "exponential"). | ||
| start_freq : float, str, optional | ||
| Starting frequency (Hz). | ||
| stop_freq : float, str, optional | ||
| Stopping frequency (Hz). | ||
| step_freq : float, str, int, optional | ||
| Frequency step (Hz) or count depending on distribution. | ||
| discrete_sweep : bool, optional | ||
| Use discrete sweep. | ||
| sweep_name : str, optional | ||
| Name of the frequency sweep. | ||
| Returns | ||
| ------- | ||
| Q3DSimulationSetup | ||
| Created setup object. | ||
| """ | ||
| result = self.create( | ||
| name=name, | ||
| solver="q3d", | ||
| distribution=distribution, | ||
| start_freq=start_freq, | ||
| stop_freq=stop_freq, | ||
| step_freq=step_freq, | ||
| discrete_sweep=discrete_sweep, | ||
| sweep_name=sweep_name, | ||
| **kwargs, | ||
| ) | ||
| return cast(Q3DSimulationSetup, result) # casting only for IDE type checking purposes |
| # Copyright (C) 2023 - 2026 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. | ||
| from ansys.edb.core.utility.value import Value as CoreValue | ||
| class PortPostProcessingProp: | ||
| """Port post-processing properties. | ||
| This class wraps the gRPC port post-processing properties, providing access to | ||
| deembedding length, renormalization impedance, voltage magnitude and phase, | ||
| and flags for deembedding and renormalization. | ||
| Parameters | ||
| ---------- | ||
| core : GrpcPortPostProcessing | ||
| The underlying gRPC port post-processing object. | ||
| """ | ||
| def __init__(self, core): | ||
| self.core = core | ||
| @property | ||
| def deembed_length(self): | ||
| """Deembedding length. | ||
| Returns | ||
| ------- | ||
| float | ||
| The deembedding length value. | ||
| """ | ||
| return self.core.deembed_length.value | ||
| @deembed_length.setter | ||
| def deembed_length(self, value): | ||
| self.core.deembed_length = CoreValue(value) | ||
| @property | ||
| def renormalization_impedance(self): | ||
| """Renormalization impedance. | ||
| Returns | ||
| ------- | ||
| float | ||
| The renormalization impedance value. | ||
| """ | ||
| return self.core.renormalization_impedance.value | ||
| @renormalization_impedance.setter | ||
| def renormalization_impedance(self, value): | ||
| self.core.renormalization_impedance = CoreValue(value) | ||
| @property | ||
| def voltage_magnitude(self): | ||
| """Voltage magnitude. | ||
| Returns | ||
| ------- | ||
| float | ||
| The voltage magnitude value. | ||
| """ | ||
| return self.core.voltage_magnitude.value | ||
| @voltage_magnitude.setter | ||
| def voltage_magnitude(self, value): | ||
| self.core.voltage_magnitude = CoreValue(value) | ||
| @property | ||
| def voltage_phase(self): | ||
| """Voltage phase. | ||
| Returns | ||
| ------- | ||
| float | ||
| The voltage phase value. | ||
| """ | ||
| return self.core.voltage_phase.value | ||
| @voltage_phase.setter | ||
| def voltage_phase(self, value): | ||
| self.core.voltage_phase = CoreValue(value) | ||
| @property | ||
| def do_deembed(self): | ||
| """Whether to perform deembedding. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if deembedding is enabled, False otherwise. | ||
| """ | ||
| return self.core.do_deembed | ||
| @do_deembed.setter | ||
| def do_deembed(self, value: bool): | ||
| self.core.do_deembed = value | ||
| @property | ||
| def do_renormalize(self): | ||
| """Whether to perform renormalization. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if renormalization is enabled, False otherwise. | ||
| """ | ||
| return self.core.do_renormalize | ||
| @do_renormalize.setter | ||
| def do_renormalize(self, value: bool): | ||
| self.core.do_renormalize = value |
| # Copyright (C) 2023 - 2026 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. |
| # Copyright (C) 2023 - 2026 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. | ||
| from pathlib import Path | ||
| from typing import Optional | ||
| from pydantic import BaseModel, Field | ||
| import xmltodict | ||
| from pyedb.xml_parser.xml_stackup import XmlStackup | ||
| # ---------- Nets ---------- | ||
| class XmlNet(BaseModel): | ||
| name: str = Field(alias="@Name") | ||
| pins_become_ports: Optional[bool] = Field(None, alias="@PinsBecomePorts") | ||
| model_config = dict(populate_by_name=True) | ||
| # ---------- Import Options ---------- | ||
| class XmlImportOptions(BaseModel): | ||
| enable_default_component_values: Optional[bool] = Field(None, alias="EnableDefaultComponentValues") | ||
| flatten: Optional[bool] = Field(None, alias="Flatten") | ||
| model_config = dict(populate_by_name=True) | ||
| # ---------- Control root ---------- | ||
| class XmlParser(BaseModel): | ||
| stackup: Optional[XmlStackup] = Field(default=None, alias="Stackup") | ||
| import_options: Optional[XmlImportOptions] = Field(default=None, alias="ImportOptions") | ||
| nets: Optional[dict] = Field(default=None, alias="Nets") | ||
| schema_version: Optional[str] = Field(default=None, alias="schemaVersion") | ||
| model_config = dict(populate_by_name=True) | ||
| def add_stackup(self): | ||
| self.stackup = XmlStackup() | ||
| return self.stackup | ||
| @classmethod | ||
| def load_xml_file(cls, path: str | Path) -> "XmlParser": | ||
| with open(path, "r", encoding="utf-8") as f: | ||
| xml_data = f.read() | ||
| data_dict = xmltodict.parse(xml_data) | ||
| control_dict = list(data_dict.values())[0] | ||
| return cls.model_validate(control_dict) | ||
| def to_xml(self, root_name="c:Control", pretty=True) -> str: | ||
| root = self.model_dump(by_alias=True, exclude_none=True) | ||
| # Ensure the desired root tag attributes exist | ||
| root["@xmlns:c"] = "http://www.ansys.com/control" | ||
| root.setdefault("@schemaVersion", "1.0") | ||
| stackup = root.get("Stackup") | ||
| stackup.setdefault("@schemaVersion", "1.0") | ||
| d = {root_name: root} | ||
| return xmltodict.unparse(d, pretty=pretty) | ||
| def to_xml_file(self, file_path: str | Path): | ||
| xml_out = self.to_xml() | ||
| with open(file_path, "w", encoding="utf-8") as f: | ||
| f.write(xml_out) | ||
| return str(file_path) | ||
| def to_dict(self): | ||
| return {"stackup": self.stackup.to_dict()} |
| # Copyright (C) 2023 - 2026 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. | ||
| from pydantic import BaseModel, Field | ||
| # ---------- Materials ---------- | ||
| class XmlMaterialProperty(BaseModel): | ||
| value: float | None = Field(None, alias="Double") | ||
| model_config = dict(populate_by_name=True) | ||
| class XmlMaterial(BaseModel): | ||
| name: str = Field(alias="@Name") | ||
| permittivity: XmlMaterialProperty | None = Field(None, alias="Permittivity") | ||
| permeability: XmlMaterialProperty | None = Field(None, alias="Permeability") | ||
| conductivity: XmlMaterialProperty | None = Field(None, alias="Conductivity") | ||
| dielectric_loss_tangent: XmlMaterialProperty | None = Field(None, alias="DielectricLossTangent") | ||
| magnetic_loss_tangent: XmlMaterialProperty | None = Field(None, alias="MagneticLossTangent") | ||
| model_config = dict(populate_by_name=True) | ||
| # ---------- Layers ---------- | ||
| class XmlLayer(BaseModel): | ||
| color: str | None = Field(None, alias="@Color") | ||
| gdsii_via: bool | None = Field(None, alias="@GDSIIVia") | ||
| material: str | None = Field(None, alias="@Material") | ||
| fill_material: str | None = Field(None, alias="@FillMaterial") | ||
| name: str = Field(alias="@Name") | ||
| negative: bool | None = Field(None, alias="@Negative") | ||
| thickness: float | str | None = Field(None, alias="@Thickness") | ||
| type: str | None = Field(None, alias="@Type") | ||
| model_config = dict(populate_by_name=True) | ||
| # ---------- Stackup ---------- | ||
| class XmlMaterials(BaseModel): | ||
| material: list[XmlMaterial] | None = Field(list(), alias="Material") | ||
| model_config = dict(populate_by_name=True) | ||
| def add_material(self, name, **kwargs) -> XmlMaterial: | ||
| mat = XmlMaterial( | ||
| **{"name": name}, | ||
| **{p_name: XmlMaterialProperty(**{"value": p_value}) for p_name, p_value in kwargs.items()}, | ||
| ) | ||
| self.material.append(mat) | ||
| return mat | ||
| class XmlLayers(BaseModel): | ||
| length_unit: str | None = Field(None, alias="@LengthUnit") | ||
| layer: list[XmlLayer] | None = Field(list(), alias="Layer") | ||
| model_config = dict(populate_by_name=True) | ||
| def add_layer(self, **kwargs) -> XmlLayer: | ||
| layer = XmlLayer(**kwargs) | ||
| self.layer.append(layer) | ||
| return layer | ||
| class XmlStackup(BaseModel): | ||
| materials: XmlMaterials | None = Field(None, alias="Materials") | ||
| layers: XmlLayers | None = Field(None, alias="Layers") | ||
| schema_version: str | None = Field(None, alias="schemaVersion") | ||
| model_config = dict(populate_by_name=True) | ||
| def add_materials(self): | ||
| self.materials = XmlMaterials() | ||
| return self.materials | ||
| def add_layers(self): | ||
| self.layers = XmlLayers(length_unit="mm") | ||
| return self.layers | ||
| def import_from_cfg_stackup(self, cfg_stackup): | ||
| self.add_materials() | ||
| for mat in cfg_stackup.materials: | ||
| mat_kwargs = {} | ||
| for key, value in mat.model_dump(exclude_none=True).items(): | ||
| if key != "name": | ||
| mat_kwargs[key] = value | ||
| self.materials.add_material(name=mat.name, **mat_kwargs) | ||
| self.add_layers() | ||
| for layer in cfg_stackup.layers: | ||
| layer_kwargs = {} | ||
| for key, value in layer.model_dump(exclude_none=True).items(): | ||
| layer_kwargs[key] = value | ||
| self.layers.add_layer(**layer_kwargs) | ||
| def to_dict(self): | ||
| layer_data = [] | ||
| unit = self.layers.length_unit | ||
| for lay in self.layers.layer: | ||
| layer_dict = lay.model_dump(exclude_none=True) | ||
| if not str(lay.thickness)[-1].isalpha(): | ||
| layer_dict["thickness"] = f"{layer_dict['thickness']}{unit}" | ||
| layer_dict["type"] = "signal" if layer_dict["type"].lower() == "conductor" else layer_dict["type"].lower() | ||
| layer_data.append(layer_dict) | ||
| material_data = [] | ||
| for mat in self.materials.material: | ||
| _mat = {} | ||
| for key, value in mat.model_dump(exclude_none=True).items(): | ||
| if isinstance(getattr(mat, key), XmlMaterialProperty): | ||
| value = getattr(mat, key).value | ||
| _mat[key] = value | ||
| material_data.append(_mat) | ||
| return { | ||
| "layers": layer_data, | ||
| "materials": material_data, | ||
| } |
+1
-1
| Metadata-Version: 2.4 | ||
| Name: pyedb | ||
| Version: 0.67.3 | ||
| Version: 0.68.0 | ||
| Summary: Higher-Level Pythonic Ansys Electronics Data Base | ||
@@ -5,0 +5,0 @@ Author-email: "ANSYS, Inc." <pyansys.core@ansys.com> |
@@ -62,3 +62,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| pyedb_path = os.path.dirname(__file__) | ||
| __version__ = "0.67.3" | ||
| __version__ = "0.68.0" | ||
| version = __version__ | ||
@@ -65,0 +65,0 @@ |
@@ -82,5 +82,6 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| class CfgAutoMeshOperation(BaseModel): | ||
| trace_ratio_seeding: float | ||
| signal_via_side_number: int | ||
| power_ground_via_side_number: int | ||
| enabled: bool = False | ||
| trace_ratio_seeding: float = 3 | ||
| signal_via_side_number: int = 12 | ||
| power_ground_via_side_number: int = 6 | ||
@@ -106,3 +107,3 @@ class CfgMeshOperation(BaseModel): | ||
| auto_mesh_operation: CfgAutoMeshOperation | None = None | ||
| auto_mesh_operation: CfgAutoMeshOperation | None = CfgAutoMeshOperation() | ||
| mesh_operations: list[CfgMeshOperation] | None = list() | ||
@@ -109,0 +110,0 @@ |
@@ -205,4 +205,6 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| if setup.auto_mesh_operation: | ||
| edb_setup.auto_mesh_operation(**dict(setup.auto_mesh_operation)) | ||
| if setup.auto_mesh_operation.enabled: | ||
| args = dict(setup.auto_mesh_operation) | ||
| args.pop("enabled") | ||
| edb_setup.auto_mesh_operation(**args) | ||
@@ -209,0 +211,0 @@ for mp in setup.mesh_operations: |
@@ -47,2 +47,12 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| # Backwards-compatible re-exports (decorators were moved to pyedb.misc.decorators) | ||
| from pyedb.misc.decorators import deprecate_argument_name, execution_timer | ||
| __all__ = [ | ||
| "installed_ansys_em_versions", | ||
| "get_filename_without_extension", | ||
| "deprecate_argument_name", | ||
| "execution_timer", | ||
| ] | ||
| from pyedb.generic.constants import CSS4_COLORS | ||
@@ -49,0 +59,0 @@ from pyedb.generic.settings import settings |
@@ -24,5 +24,5 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| GRPC_GENERAL_WARNING = ( | ||
| "Your ANSYS AEDT version is eligible to gRPC version." | ||
| "You might consider switching to that version for better user experience." | ||
| "This version of the Ansys Electronics Database (EDB) is compatible with the gRPC" | ||
| "interface. You can enable gRPC by passing ``grpc=True`` when instantiating the Edb object." | ||
| "For more information please check this link: https://edb.docs.pyansys.com/version/dev/grpc_api/index.html" | ||
| ) |
@@ -25,3 +25,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.definition.component_def import ComponentDef as GrpcComponentDef | ||
| from ansys.edb.core.definition.component_def import ComponentDef as CoreComponentDef | ||
@@ -106,6 +106,6 @@ from pyedb.grpc.database.definition.component_pin import ComponentPin | ||
| """ | ||
| from ansys.edb.core.hierarchy.component_group import ComponentGroup as GrpcComponent | ||
| from ansys.edb.core.hierarchy.component_group import ComponentGroup as CoreComponent | ||
| comp_list = [ | ||
| Component(self._pedb, l) for l in GrpcComponent.find_by_def(self._pedb.active_layout.core, self.part_name) | ||
| Component(self._pedb, l) for l in CoreComponent.find_by_def(self._pedb.active_layout.core, self.part_name) | ||
| ] | ||
@@ -152,3 +152,3 @@ return {comp.refdes: comp for comp in comp_list} | ||
| """ | ||
| core_comp_def = GrpcComponentDef.find(edb.db, name) | ||
| core_comp_def = CoreComponentDef.find(edb.db, name) | ||
| if not core_comp_def.is_null: | ||
@@ -175,3 +175,3 @@ return ComponentDef(edb, core_comp_def) | ||
| """ | ||
| component_def = GrpcComponentDef.create(edb.db, name, fp) | ||
| component_def = CoreComponentDef.create(edb.db, name, fp) | ||
| return ComponentDef(edb, component_def) | ||
@@ -294,3 +294,3 @@ | ||
| from ansys.edb.core.definition.component_model import ( | ||
| NPortComponentModel as GrpcNPortComponentModel, | ||
| NPortComponentModel as CoreNPortComponentModel, | ||
| ) | ||
@@ -303,3 +303,3 @@ | ||
| raise RuntimeError(f"Model {name} already defined for component definition {self.name}") | ||
| n_port_model = GrpcNPortComponentModel.create(name=name) | ||
| n_port_model = CoreNPortComponentModel.create(name=name) | ||
| n_port_model.reference_file = fpath | ||
@@ -306,0 +306,0 @@ self.core.add_component_model(n_port_model) |
@@ -26,4 +26,4 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.definition.component_model import ( | ||
| ComponentModel as GrpcComponentModel, | ||
| NPortComponentModel as GrpcNPortComponentModel, | ||
| ComponentModel as CoreComponentModel, | ||
| NPortComponentModel as CoreNPortComponentModel, | ||
| ) | ||
@@ -36,3 +36,3 @@ | ||
| def __init__(self, core): | ||
| self.core = GrpcComponentModel(core.msg) | ||
| self.core = CoreComponentModel(core.msg) | ||
@@ -80,3 +80,3 @@ @property | ||
| def __init__(self, core): | ||
| self.core = GrpcComponentModel(core.msg) | ||
| self.core = CoreComponentModel(core.msg) | ||
@@ -98,3 +98,3 @@ @classmethod | ||
| """ | ||
| return cls(GrpcNPortComponentModel.create(name)) | ||
| return cls(CoreNPortComponentModel.create(name)) | ||
@@ -116,3 +116,3 @@ @classmethod | ||
| """ | ||
| core_nport_model = GrpcNPortComponentModel.find_by_id(component_definition.core, id) | ||
| core_nport_model = CoreNPortComponentModel.find_by_id(component_definition.core, id) | ||
| if not core_nport_model.is_null: | ||
@@ -138,3 +138,3 @@ return cls(core_nport_model) | ||
| """ | ||
| core_nport_model = GrpcNPortComponentModel.find_by_name(component_definition.core, name) | ||
| core_nport_model = CoreNPortComponentModel.find_by_name(component_definition.core, name) | ||
| if not core_nport_model.is_null: | ||
@@ -141,0 +141,0 @@ return cls(core_nport_model) |
@@ -23,3 +23,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.definition.component_pin import ComponentPin as GrpcComponentPin | ||
| from ansys.edb.core.definition.component_pin import ComponentPin as CoreComponentPin | ||
@@ -49,3 +49,3 @@ | ||
| """ | ||
| edb_obj = GrpcComponentPin.create(component_def.core, name) | ||
| edb_obj = CoreComponentPin.create(component_def.core, name) | ||
| return cls(edb_obj) | ||
@@ -52,0 +52,0 @@ |
@@ -32,12 +32,12 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.definition.debye_model import DebyeModel as GrpcDebyeModel | ||
| from ansys.edb.core.definition.debye_model import DebyeModel as CoreDebyeModel | ||
| from ansys.edb.core.definition.djordjecvic_sarkar_model import ( | ||
| DjordjecvicSarkarModel as GrpcDjordjecvicSarkarModel, | ||
| DjordjecvicSarkarModel as CoreDjordjecvicSarkarModel, | ||
| ) | ||
| from ansys.edb.core.definition.material_def import ( | ||
| MaterialDef as GrpcMaterialDef, | ||
| MaterialProperty as GrpcMaterialProperty, | ||
| MaterialDef as CoreMaterialDef, | ||
| MaterialProperty as CoreMaterialProperty, | ||
| ) | ||
| from ansys.edb.core.definition.multipole_debye_model import ( | ||
| MultipoleDebyeModel as GrpcMultipoleDebyeModel, | ||
| MultipoleDebyeModel as CoreMultipoleDebyeModel, | ||
| ) | ||
@@ -166,7 +166,7 @@ from pydantic import BaseModel, confloat | ||
| if self.core.dielectric_material_model.type.name.lower() == "debye": | ||
| self.__dielectric_model = GrpcDebyeModel(self.core.dielectric_material_model.msg) | ||
| self.__dielectric_model = CoreDebyeModel(self.core.dielectric_material_model.msg) | ||
| elif self.core.dielectric_material_model.type.name.lower() == "multipole_debye": | ||
| self.__dielectric_model = GrpcMultipoleDebyeModel(self.core.dielectric_material_model.msg) | ||
| self.__dielectric_model = CoreMultipoleDebyeModel(self.core.dielectric_material_model.msg) | ||
| elif self.core.dielectric_material_model.type.name.lower() == "djordjecvic_sarkar": | ||
| self.__dielectric_model = GrpcDjordjecvicSarkarModel(self.core.dielectric_material_model.msg) | ||
| self.__dielectric_model = CoreDjordjecvicSarkarModel(self.core.dielectric_material_model.msg) | ||
| return self.__dielectric_model | ||
@@ -186,3 +186,3 @@ except: | ||
| try: | ||
| return Value(self.core.get_property(GrpcMaterialProperty.CONDUCTIVITY)) | ||
| return Value(self.core.get_property(CoreMaterialProperty.CONDUCTIVITY)) | ||
| except: | ||
@@ -200,3 +200,3 @@ return 0.0 | ||
| else: | ||
| self.core.set_property(GrpcMaterialProperty.CONDUCTIVITY, Value(value)) | ||
| self.core.set_property(CoreMaterialProperty.CONDUCTIVITY, Value(value)) | ||
@@ -316,3 +316,3 @@ @property | ||
| try: | ||
| return Value(self.core.get_property(GrpcMaterialProperty.PERMITTIVITY)) | ||
| return Value(self.core.get_property(CoreMaterialProperty.PERMITTIVITY)) | ||
| except: | ||
@@ -324,3 +324,3 @@ return 0.0 | ||
| """Set material permittivity.""" | ||
| self.core.set_property(GrpcMaterialProperty.PERMITTIVITY, Value(value)) | ||
| self.core.set_property(CoreMaterialProperty.PERMITTIVITY, Value(value)) | ||
@@ -338,3 +338,3 @@ @property | ||
| try: | ||
| return Value(self.core.get_property(GrpcMaterialProperty.PERMEABILITY)) | ||
| return Value(self.core.get_property(CoreMaterialProperty.PERMEABILITY)) | ||
| except: | ||
@@ -346,3 +346,3 @@ return 0.0 | ||
| """Set material permeability.""" | ||
| self.core.set_property(GrpcMaterialProperty.PERMEABILITY, Value(value)) | ||
| self.core.set_property(CoreMaterialProperty.PERMEABILITY, Value(value)) | ||
@@ -377,3 +377,3 @@ @property | ||
| try: | ||
| return Value(self.core.get_property(GrpcMaterialProperty.DIELECTRIC_LOSS_TANGENT)) | ||
| return Value(self.core.get_property(CoreMaterialProperty.DIELECTRIC_LOSS_TANGENT)) | ||
| except: | ||
@@ -395,3 +395,3 @@ return 0.0 | ||
| """Set material loss tangent.""" | ||
| self.core.set_property(GrpcMaterialProperty.DIELECTRIC_LOSS_TANGENT, Value(value)) | ||
| self.core.set_property(CoreMaterialProperty.DIELECTRIC_LOSS_TANGENT, Value(value)) | ||
@@ -408,3 +408,3 @@ @property | ||
| try: | ||
| return Value(self.core.get_property(GrpcMaterialProperty.MAGNETIC_LOSS_TANGENT)) | ||
| return Value(self.core.get_property(CoreMaterialProperty.MAGNETIC_LOSS_TANGENT)) | ||
| except: | ||
@@ -416,3 +416,3 @@ return 0.0 | ||
| """Set material magnetic loss tangent.""" | ||
| self.core.set_property(GrpcMaterialProperty.MAGNETIC_LOSS_TANGENT, Value(value)) | ||
| self.core.set_property(CoreMaterialProperty.MAGNETIC_LOSS_TANGENT, Value(value)) | ||
@@ -430,3 +430,3 @@ @property | ||
| try: | ||
| return Value(self.core.get_property(GrpcMaterialProperty.THERMAL_CONDUCTIVITY)) | ||
| return Value(self.core.get_property(CoreMaterialProperty.THERMAL_CONDUCTIVITY)) | ||
| except: | ||
@@ -438,3 +438,3 @@ return 0.0 | ||
| """Set material thermal conductivity.""" | ||
| self.core.set_property(GrpcMaterialProperty.THERMAL_CONDUCTIVITY, Value(value)) | ||
| self.core.set_property(CoreMaterialProperty.THERMAL_CONDUCTIVITY, Value(value)) | ||
@@ -452,3 +452,3 @@ @property | ||
| try: | ||
| return Value(self.core.get_property(GrpcMaterialProperty.MASS_DENSITY)) | ||
| return Value(self.core.get_property(CoreMaterialProperty.MASS_DENSITY)) | ||
| except: | ||
@@ -460,3 +460,3 @@ return 0.0 | ||
| """Set material mass density.""" | ||
| self.core.set_property(GrpcMaterialProperty.MASS_DENSITY, Value(value)) | ||
| self.core.set_property(CoreMaterialProperty.MASS_DENSITY, Value(value)) | ||
@@ -474,3 +474,3 @@ @property | ||
| try: | ||
| return Value(self.core.get_property(GrpcMaterialProperty.YOUNGS_MODULUS)) | ||
| return Value(self.core.get_property(CoreMaterialProperty.YOUNGS_MODULUS)) | ||
| except: | ||
@@ -482,3 +482,3 @@ return 0.0 | ||
| """Set material young modulus.""" | ||
| self.core.set_property(GrpcMaterialProperty.YOUNGS_MODULUS, Value(value)) | ||
| self.core.set_property(CoreMaterialProperty.YOUNGS_MODULUS, Value(value)) | ||
@@ -495,3 +495,3 @@ @property | ||
| try: | ||
| return Value(self.core.get_property(GrpcMaterialProperty.SPECIFIC_HEAT)) | ||
| return Value(self.core.get_property(CoreMaterialProperty.SPECIFIC_HEAT)) | ||
| except: | ||
@@ -503,3 +503,3 @@ return 0.0 | ||
| """Set material specific heat.""" | ||
| self.core.set_property(GrpcMaterialProperty.SPECIFIC_HEAT, Value(value)) | ||
| self.core.set_property(CoreMaterialProperty.SPECIFIC_HEAT, Value(value)) | ||
@@ -516,3 +516,3 @@ @property | ||
| try: | ||
| return Value(self.core.get_property(GrpcMaterialProperty.POISSONS_RATIO)) | ||
| return Value(self.core.get_property(CoreMaterialProperty.POISSONS_RATIO)) | ||
| except: | ||
@@ -524,3 +524,3 @@ return 0.0 | ||
| """Set material poisson ratio.""" | ||
| self.core.set_property(GrpcMaterialProperty.POISSONS_RATIO, Value(value)) | ||
| self.core.set_property(CoreMaterialProperty.POISSONS_RATIO, Value(value)) | ||
@@ -538,3 +538,3 @@ @property | ||
| try: | ||
| return Value(self.core.get_property(GrpcMaterialProperty.THERMAL_EXPANSION_COEFFICIENT)) | ||
| return Value(self.core.get_property(CoreMaterialProperty.THERMAL_EXPANSION_COEFFICIENT)) | ||
| except: | ||
@@ -546,15 +546,15 @@ return 0.0 | ||
| """Set material thermal coefficient.""" | ||
| self.core.set_property(GrpcMaterialProperty.THERMAL_EXPANSION_COEFFICIENT, Value(value)) | ||
| self.core.set_property(CoreMaterialProperty.THERMAL_EXPANSION_COEFFICIENT, Value(value)) | ||
| def set_debye_model(self): | ||
| """Set Debye model on current material.""" | ||
| self.core.dielectric_material_model.__set__(self, GrpcDebyeModel.create()) | ||
| self.core.dielectric_material_model.__set__(self, CoreDebyeModel.create()) | ||
| def set_multipole_debye_model(self): | ||
| """Set multi-pole debeye model on current material.""" | ||
| self.core.dielectric_material_model.__set__(self, GrpcMultipoleDebyeModel.create()) | ||
| self.core.dielectric_material_model.__set__(self, CoreMultipoleDebyeModel.create()) | ||
| def set_djordjecvic_sarkar_model(self): | ||
| """Set Djordjecvic-Sarkar model on current material.""" | ||
| self.core.dielectric_material_model = GrpcDjordjecvicSarkarModel.create() | ||
| self.core.dielectric_material_model = CoreDjordjecvicSarkarModel.create() | ||
@@ -582,3 +582,3 @@ def to_dict(self): | ||
| if not self.__dielectric_model: | ||
| self.__dielectric_model = GrpcDjordjecvicSarkarModel.create() | ||
| self.__dielectric_model = CoreDjordjecvicSarkarModel.create() | ||
| for attribute in DC_ATTRIBUTES: | ||
@@ -693,3 +693,3 @@ if attribute in input_dict: | ||
| material_def = GrpcMaterialDef.create(self.__edb.active_db, name) | ||
| material_def = CoreMaterialDef.create(self.__edb.active_db, name) | ||
| material = Material(self.__edb, material_def) | ||
@@ -792,3 +792,3 @@ # Apply default values to the material | ||
| material_model = GrpcDjordjecvicSarkarModel.create() | ||
| material_model = CoreDjordjecvicSarkarModel.create() | ||
| material_model.relative_permittivity_at_frequency = permittivity_at_frequency | ||
@@ -861,3 +861,3 @@ material_model.loss_tangent_at_frequency = loss_tangent_at_frequency | ||
| raise ValueError(f"Material names are case-insensitive and {name.lower()} already exists.") | ||
| material_model = GrpcDebyeModel.create() | ||
| material_model = CoreDebyeModel.create() | ||
| material_model.frequency_range = (lower_freqency, higher_frequency) | ||
@@ -925,3 +925,3 @@ material_model.loss_tangent_at_high_low_frequency = (loss_tangent_low, loss_tangent_high) | ||
| loss_tangents = [float(i) for i in loss_tangents] | ||
| material_model = GrpcMultipoleDebyeModel.create() | ||
| material_model = CoreMultipoleDebyeModel.create() | ||
| material_model.set_parameters(frequencies, permittivities, loss_tangents) | ||
@@ -953,8 +953,8 @@ try: | ||
| """ | ||
| if GrpcMaterialDef.find_by_name(self.__edb.active_db, name).is_null: | ||
| if CoreMaterialDef.find_by_name(self.__edb.active_db, name).is_null: | ||
| if name.lower() in (material.lower() for material in self.materials): | ||
| raise ValueError(f"Material names are case-insensitive and {name.lower()} already exists.") | ||
| GrpcMaterialDef.create(self.__edb.active_db, name) | ||
| CoreMaterialDef.create(self.__edb.active_db, name) | ||
| material_def = GrpcMaterialDef.find_by_name(self.__edb.active_db, name) | ||
| material_def = CoreMaterialDef.find_by_name(self.__edb.active_db, name) | ||
| material_def.dielectric_material_model = material_model | ||
@@ -986,3 +986,3 @@ material = Material(self.__edb, material_def) | ||
| material = self.materials[material_name] | ||
| material_def = GrpcMaterialDef.create(self.__edb.active_db, new_material_name) | ||
| material_def = CoreMaterialDef.create(self.__edb.active_db, new_material_name) | ||
| material_dict = material.to_dict() | ||
@@ -1018,3 +1018,3 @@ new_material = Material(self.__edb, material_def) | ||
| """ | ||
| material_def = GrpcMaterialDef.find_by_name(self.__edb.active_db, material_name) | ||
| material_def = CoreMaterialDef.find_by_name(self.__edb.active_db, material_name) | ||
| if material_def.is_null: | ||
@@ -1079,14 +1079,14 @@ raise ValueError(f"Cannot find material {material_name}.") | ||
| property_name_to_id = { | ||
| "Permittivity": GrpcMaterialProperty.PERMITTIVITY, | ||
| "Permeability": GrpcMaterialProperty.PERMEABILITY, | ||
| "Conductivity": GrpcMaterialProperty.CONDUCTIVITY, | ||
| "DielectricLossTangent": GrpcMaterialProperty.DIELECTRIC_LOSS_TANGENT, | ||
| "MagneticLossTangent": GrpcMaterialProperty.MAGNETIC_LOSS_TANGENT, | ||
| "ThermalConductivity": GrpcMaterialProperty.THERMAL_CONDUCTIVITY, | ||
| "MassDensity": GrpcMaterialProperty.MASS_DENSITY, | ||
| "SpecificHeat": GrpcMaterialProperty.SPECIFIC_HEAT, | ||
| "YoungsModulus": GrpcMaterialProperty.YOUNGS_MODULUS, | ||
| "PoissonsRatio": GrpcMaterialProperty.POISSONS_RATIO, | ||
| "ThermalExpansionCoefficient": GrpcMaterialProperty.THERMAL_EXPANSION_COEFFICIENT, | ||
| "InvalidProperty": GrpcMaterialProperty.INVALID_PROPERTY, | ||
| "Permittivity": CoreMaterialProperty.PERMITTIVITY, | ||
| "Permeability": CoreMaterialProperty.PERMEABILITY, | ||
| "Conductivity": CoreMaterialProperty.CONDUCTIVITY, | ||
| "DielectricLossTangent": CoreMaterialProperty.DIELECTRIC_LOSS_TANGENT, | ||
| "MagneticLossTangent": CoreMaterialProperty.MAGNETIC_LOSS_TANGENT, | ||
| "ThermalConductivity": CoreMaterialProperty.THERMAL_CONDUCTIVITY, | ||
| "MassDensity": CoreMaterialProperty.MASS_DENSITY, | ||
| "SpecificHeat": CoreMaterialProperty.SPECIFIC_HEAT, | ||
| "YoungsModulus": CoreMaterialProperty.YOUNGS_MODULUS, | ||
| "PoissonsRatio": CoreMaterialProperty.POISSONS_RATIO, | ||
| "ThermalExpansionCoefficient": CoreMaterialProperty.THERMAL_EXPANSION_COEFFICIENT, | ||
| "InvalidProperty": CoreMaterialProperty.INVALID_PROPERTY, | ||
| } | ||
@@ -1093,0 +1093,0 @@ |
@@ -25,3 +25,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.definition.component_model import ( | ||
| NPortComponentModel as GrpcNPortComponentModel, | ||
| NPortComponentModel as CoreNPortComponentModel, | ||
| ) | ||
@@ -47,5 +47,5 @@ | ||
| raise ValueError("Name must be provided to create NPortComponentModel.") | ||
| grpc_nport_component_model = GrpcNPortComponentModel.create(name=name) | ||
| grpc_nport_component_model = CoreNPortComponentModel.create(name=name) | ||
| if grpc_nport_component_model.is_null: | ||
| raise ValueError("Failed to create NPortComponentModel.") | ||
| return cls(grpc_nport_component_model) |
@@ -23,4 +23,4 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.definition.package_def import PackageDef as GrpcPackageDef | ||
| from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData | ||
| from ansys.edb.core.definition.package_def import PackageDef as CorePackageDef | ||
| from ansys.edb.core.geometry.polygon_data import PolygonData as CorePolygonData | ||
@@ -52,6 +52,7 @@ from pyedb.generic.settings import settings | ||
| if name: | ||
| edb_object = GrpcPackageDef.create(db=pedb.active_db, name=name) | ||
| self.core = CorePackageDef.create(db=pedb.active_db, name=name) | ||
| else: | ||
| raise AttributeError("Name must be provided to create and instantiate a PackageDef object.") | ||
| self.core = core | ||
| else: | ||
| self.core = core | ||
| self._pedb = pedb | ||
@@ -75,3 +76,3 @@ self._heat_sink = None | ||
| """ | ||
| self.core = GrpcPackageDef.create(self._pedb.active_db, name) | ||
| self.core = CorePackageDef.create(self._pedb.active_db, name) | ||
| if component_part_name: | ||
@@ -91,3 +92,3 @@ x_pt1, y_pt1, x_pt2, y_pt2 = list( | ||
| ) | ||
| polygon_data = GrpcPolygonData(points=bbox) | ||
| polygon_data = CorePolygonData(points=bbox) | ||
| self.exterior_boundary = polygon_data | ||
@@ -104,3 +105,3 @@ | ||
| @property | ||
| def exterior_boundary(self) -> GrpcPolygonData: | ||
| def exterior_boundary(self) -> CorePolygonData: | ||
| """Get the exterior boundary of a package definition. | ||
@@ -113,3 +114,3 @@ | ||
| """ | ||
| return GrpcPolygonData(self.core.exterior_boundary.points) | ||
| return CorePolygonData(self.core.exterior_boundary.points) | ||
@@ -239,3 +240,3 @@ @exterior_boundary.setter | ||
| """ | ||
| grpc_package = GrpcPackageDef.create(edb.active_db, name) | ||
| grpc_package = CorePackageDef.create(edb.active_db, name) | ||
| if grpc_package.is_null: | ||
@@ -242,0 +243,0 @@ raise RuntimeError(f"Failed to create package {name}") |
@@ -26,12 +26,12 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.definition.padstack_def import PadstackDef as GrpcPadstackDef | ||
| from ansys.edb.core.definition.padstack_def import PadstackDef as CorePadstackDef | ||
| from ansys.edb.core.definition.padstack_def_data import ( | ||
| PadGeometryType as GrpcPadGeometryType, | ||
| PadstackHoleRange as GrpcPadstackHoleRange, | ||
| PadType as GrpcPadType, | ||
| PadGeometryType as CorePadGeometryType, | ||
| PadstackHoleRange as CorePadstackHoleRange, | ||
| PadType as CorePadType, | ||
| ) | ||
| import ansys.edb.core.geometry.polygon_data | ||
| from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData | ||
| from ansys.edb.core.hierarchy.structure3d import MeshClosure as GrpcMeshClosure, Structure3D as GrpcStructure3D | ||
| from ansys.edb.core.primitive.circle import Circle as GrpcCircle | ||
| from ansys.edb.core.geometry.polygon_data import PolygonData as CorePolygonData | ||
| from ansys.edb.core.hierarchy.structure3d import MeshClosure as CoreMeshClosure, Structure3D as CoreStructure3D | ||
| from ansys.edb.core.primitive.circle import Circle as CoreCircle | ||
@@ -81,5 +81,5 @@ from pyedb.generic.general_methods import generate_unique_name | ||
| def _pad_parameter_value(self): | ||
| p_val = self._edb_padstack.get_pad_parameters(self.layer_name, GrpcPadType.REGULAR_PAD) | ||
| p_val = self._edb_padstack.get_pad_parameters(self.layer_name, CorePadType.REGULAR_PAD) | ||
| if isinstance(p_val[0], ansys.edb.core.geometry.polygon_data.PolygonData): | ||
| p_val = [GrpcPadGeometryType.PADGEOMTYPE_POLYGON] + [i for i in p_val] | ||
| p_val = [CorePadGeometryType.PADGEOMTYPE_POLYGON] + [i for i in p_val] | ||
| return p_val | ||
@@ -123,7 +123,7 @@ | ||
| if value.lower() == "circle": | ||
| self._update_pad_parameters_parameters(geom_type=GrpcPadGeometryType.PADGEOMTYPE_CIRCLE) | ||
| self._update_pad_parameters_parameters(geom_type=CorePadGeometryType.PADGEOMTYPE_CIRCLE) | ||
| elif value.lower() == "rectangle": | ||
| self._update_pad_parameters_parameters(geom_type=GrpcPadGeometryType.PADGEOMTYPE_RECTANGLE) | ||
| self._update_pad_parameters_parameters(geom_type=CorePadGeometryType.PADGEOMTYPE_RECTANGLE) | ||
| elif value.lower() == "polygon": | ||
| self._update_pad_parameters_parameters(geom_type=GrpcPadGeometryType.PADGEOMTYPE_POLYGON) | ||
| self._update_pad_parameters_parameters(geom_type=CorePadGeometryType.PADGEOMTYPE_POLYGON) | ||
| else: | ||
@@ -163,3 +163,3 @@ raise ValueError( | ||
| @property | ||
| def polygon_data(self) -> GrpcPolygonData: | ||
| def polygon_data(self) -> CorePolygonData: | ||
| """Parameters. | ||
@@ -235,6 +235,6 @@ | ||
| if pad_type is None: | ||
| pad_type = GrpcPadType.REGULAR_PAD | ||
| pad_type = CorePadType.REGULAR_PAD | ||
| if geom_type is None: | ||
| geom_type = self.geometry_type | ||
| for k in GrpcPadGeometryType: | ||
| for k in CorePadGeometryType: | ||
| if k.value == geom_type: | ||
@@ -297,3 +297,3 @@ geom_type = k | ||
| """Create a new padstack definition.""" | ||
| padstack_def = GrpcPadstackDef.create(edb.db, name) | ||
| padstack_def = CorePadstackDef.create(edb.db, name) | ||
| return cls(edb, padstack_def) | ||
@@ -449,3 +449,3 @@ | ||
| hole_offset_y = hole_parameter[3] | ||
| if not isinstance(geometry_type, GrpcPolygonData): | ||
| if not isinstance(geometry_type, CorePolygonData): | ||
| hole_rotation = hole_parameter[4] | ||
@@ -574,3 +574,3 @@ self.core.data.set_hole_parameters( | ||
| try: | ||
| self._pad_by_layer[layer] = PadProperties(self.core.data, layer, GrpcPadType.REGULAR_PAD, self) | ||
| self._pad_by_layer[layer] = PadProperties(self.core.data, layer, CorePadType.REGULAR_PAD, self) | ||
| except: | ||
@@ -592,3 +592,3 @@ self._pad_by_layer[layer] = None | ||
| try: | ||
| self._pad_by_layer[layer] = PadProperties(self.core.data, layer, GrpcPadType.ANTI_PAD, self) | ||
| self._pad_by_layer[layer] = PadProperties(self.core.data, layer, CorePadType.ANTI_PAD, self) | ||
| except: | ||
@@ -610,3 +610,3 @@ self._antipad_by_layer[layer] = None | ||
| try: | ||
| self._pad_by_layer[layer] = PadProperties(self.core.data, layer, GrpcPadType.THERMAL_PAD, self) | ||
| self._pad_by_layer[layer] = PadProperties(self.core.data, layer, CorePadType.THERMAL_PAD, self) | ||
| except: | ||
@@ -696,11 +696,11 @@ self._thermalpad_by_layer[layer] = None | ||
| if value == "through": | ||
| self.core.data.hole_range = GrpcPadstackHoleRange.THROUGH | ||
| self.core.data.hole_range = CorePadstackHoleRange.THROUGH | ||
| elif value == "begin_on_upper_pad": | ||
| self.core.data.hole_range = GrpcPadstackHoleRange.BEGIN_ON_UPPER_PAD | ||
| self.core.data.hole_range = CorePadstackHoleRange.BEGIN_ON_UPPER_PAD | ||
| elif value == "end_on_lower_pad": | ||
| self.core.data.hole_range = GrpcPadstackHoleRange.END_ON_LOWER_PAD | ||
| self.core.data.hole_range = CorePadstackHoleRange.END_ON_LOWER_PAD | ||
| elif value == "upper_pad_to_lower_pad": | ||
| self.core.data.hole_range = GrpcPadstackHoleRange.UPPER_PAD_TO_LOWER_PAD | ||
| self.core.data.hole_range = CorePadstackHoleRange.UPPER_PAD_TO_LOWER_PAD | ||
| else: # pragma no cover | ||
| self.core.data.hole_range = GrpcPadstackHoleRange.UNKNOWN_RANGE | ||
| self.core.data.hole_range = CorePadstackHoleRange.UNKNOWN_RANGE | ||
@@ -730,3 +730,3 @@ def convert_to_3d_microvias( | ||
| if isinstance(self.core.data.get_hole_parameters()[0], GrpcPolygonData): | ||
| if isinstance(self.core.data.get_hole_parameters()[0], CorePolygonData): | ||
| self._pedb.logger.error("Microvias cannot be applied on vias using hole shape polygon") | ||
@@ -818,3 +818,3 @@ return False | ||
| ) | ||
| s3d = GrpcStructure3D.create( | ||
| s3d = CoreStructure3D.create( | ||
| layout.core, generate_unique_name("via3d_" + via.aedt_name.replace("via_", ""), n=3) | ||
@@ -830,3 +830,3 @@ ) | ||
| s3d.set_material(self.core.data.material.value) | ||
| s3d.mesh_closure = GrpcMeshClosure.ENDS_CLOSED | ||
| s3d.mesh_closure = CoreMeshClosure.ENDS_CLOSED | ||
| started = True | ||
@@ -873,3 +873,3 @@ i += 1 | ||
| included = [start, stop] | ||
| new_padstack_definition = GrpcPadstackDef.create(self._pedb.db, new_padstack_name) | ||
| new_padstack_definition = CorePadstackDef.create(self._pedb.db, new_padstack_name) | ||
| new_padstack_definition.data.add_layers(included) | ||
@@ -880,3 +880,3 @@ for layer in included: | ||
| layer=layer, | ||
| pad_type=GrpcPadType.REGULAR_PAD, | ||
| pad_type=CorePadType.REGULAR_PAD, | ||
| offset_x=Value(pl.offset_x, self._pedb.db), | ||
@@ -893,3 +893,3 @@ offset_y=Value(pl.offset_y, self._pedb.db), | ||
| layer=layer, | ||
| pad_type=GrpcPadType.ANTI_PAD, | ||
| pad_type=CorePadType.ANTI_PAD, | ||
| offset_x=Value(pl.offset_x, self._pedb.db), | ||
@@ -906,3 +906,3 @@ offset_y=Value(pl.offset_y, self._pedb.db), | ||
| layer=layer, | ||
| pad_type=GrpcPadType.THERMAL_PAD, | ||
| pad_type=CorePadType.THERMAL_PAD, | ||
| offset_x=Value(pl.offset_x, self._pedb.db), | ||
@@ -909,0 +909,0 @@ offset_y=Value(pl.offset_y, self._pedb.db), |
@@ -24,5 +24,5 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.definition.bondwire_def import ( | ||
| ApdBondwireDef as GrpcApdBondwireDef, | ||
| Jedec4BondwireDef as GrpcJedec4BondwireDef, | ||
| Jedec5BondwireDef as GrpcJedec5BondwireDef, | ||
| ApdBondwireDef as CoreApdBondwireDef, | ||
| Jedec4BondwireDef as CoreJedec4BondwireDef, | ||
| Jedec5BondwireDef as CoreJedec5BondwireDef, | ||
| ) | ||
@@ -105,3 +105,3 @@ | ||
| """ | ||
| grpc_bondwire_def = GrpcJedec4BondwireDef.create(edb._db, name) | ||
| grpc_bondwire_def = CoreJedec4BondwireDef.create(edb._db, name) | ||
| return cls(edb, grpc_bondwire_def) | ||
@@ -125,5 +125,5 @@ | ||
| """ | ||
| grpc_bondwire_def = GrpcJedec4BondwireDef.find_by_name(edb._db, name) | ||
| if grpc_bondwire_def: | ||
| return Jedec4BondwireDef(edb, grpc_bondwire_def) | ||
| core_bondwire_def = CoreJedec4BondwireDef.find_by_name(edb._db, name) | ||
| if core_bondwire_def: | ||
| return Jedec4BondwireDef(edb, core_bondwire_def) | ||
| return None | ||
@@ -156,4 +156,4 @@ | ||
| """ | ||
| grpc_bondwire_def = GrpcJedec5BondwireDef.create(edb._db, name) | ||
| return cls(edb, grpc_bondwire_def) | ||
| core_bondwire_def = CoreJedec5BondwireDef.create(edb._db, name) | ||
| return cls(edb, core_bondwire_def) | ||
@@ -176,3 +176,3 @@ @staticmethod | ||
| """ | ||
| grpc_bondwire_def = GrpcJedec5BondwireDef.find_by_name(edb._db, name) | ||
| grpc_bondwire_def = CoreJedec5BondwireDef.find_by_name(edb._db, name) | ||
| if grpc_bondwire_def: | ||
@@ -207,3 +207,3 @@ return Jedec5BondwireDef(edb, grpc_bondwire_def) | ||
| """ | ||
| grpc_bondwire_def = GrpcApdBondwireDef.create(edb._db, name) | ||
| grpc_bondwire_def = CoreApdBondwireDef.create(edb._db, name) | ||
| return cls(edb, grpc_bondwire_def) | ||
@@ -227,5 +227,5 @@ | ||
| """ | ||
| grpc_bondwire_def = GrpcApdBondwireDef.find_by_name(edb._db, name) | ||
| grpc_bondwire_def = CoreApdBondwireDef.find_by_name(edb._db, name) | ||
| if grpc_bondwire_def: | ||
| return ApdBondwireDef(edb, grpc_bondwire_def) | ||
| return None |
@@ -26,3 +26,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData | ||
| from ansys.edb.core.geometry.polygon_data import PolygonData as CorePolygonData | ||
@@ -246,8 +246,8 @@ from pyedb.grpc.database.definition.component_def import ComponentDef | ||
| if not boundary_points and not definition.is_null: | ||
| package_def.exterior_boundary = GrpcPolygonData( | ||
| package_def.exterior_boundary = CorePolygonData( | ||
| points=list(definition.components.values())[0].bounding_box # type: ignore[arg-type] | ||
| ) | ||
| if boundary_points: | ||
| package_def.exterior_boundary = GrpcPolygonData(points=boundary_points) # type: ignore[arg-type] | ||
| package_def.exterior_boundary = CorePolygonData(points=boundary_points) # type: ignore[arg-type] | ||
| return package_def | ||
| return False |
@@ -24,3 +24,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.geometry.arc_data import ArcData as GrpcArcData | ||
| from ansys.edb.core.geometry.arc_data import ArcData as CoreArcData | ||
@@ -27,0 +27,0 @@ from pyedb.grpc.database.utility.value import Value |
@@ -23,3 +23,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.geometry.point3d_data import Point3DData as GrpcPoint3DData | ||
| from ansys.edb.core.geometry.point3d_data import Point3DData as CorePoint3DData | ||
@@ -33,3 +33,3 @@ from pyedb.grpc.database.utility.value import Value | ||
| def __init__(self, x, y, z): | ||
| self.core = GrpcPoint3DData.__init__(x, y, z) | ||
| self.core = CorePoint3DData.__init__(x, y, z) | ||
@@ -36,0 +36,0 @@ @property |
@@ -23,5 +23,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.geometry.point_data import PointData as GrpcPointData | ||
| class PointData: | ||
@@ -28,0 +26,0 @@ """Class managing :class:`Point Data <ansys.edb.core.geometry.point_data.PointData>`""" |
@@ -24,4 +24,4 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.geometry.point_data import PointData as GrpcPointData | ||
| from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData | ||
| from ansys.edb.core.geometry.point_data import PointData as CorePointData | ||
| from ansys.edb.core.geometry.polygon_data import PolygonData as CorePolygonData | ||
@@ -167,7 +167,7 @@ from pyedb.grpc.database.geometry.arc_data import ArcData | ||
| for pt in points: | ||
| list_of_point_data.append(GrpcPointData(pt)) | ||
| return cls(GrpcPolygonData(points=list_of_point_data, closed=closed)) | ||
| list_of_point_data.append(CorePointData(pt)) | ||
| return cls(CorePolygonData(points=list_of_point_data, closed=closed)) | ||
| @classmethod | ||
| def create_from_bounding_box(cls, points) -> GrpcPolygonData: | ||
| def create_from_bounding_box(cls, points) -> CorePolygonData: | ||
| """Create PolygonData from point list. | ||
@@ -180,3 +180,3 @@ | ||
| """ | ||
| return cls(GrpcPolygonData(points=points)) | ||
| return cls(CorePolygonData(points=points)) | ||
@@ -183,0 +183,0 @@ def has_self_intersections(self, tolerance=1e-12) -> bool: |
@@ -31,5 +31,4 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData | ||
| from ansys.edb.core.geometry.polygon_data import PolygonData as CorePolygonData | ||
| from pyedb.generic.general_methods import generate_unique_name | ||
| from pyedb.grpc.database.simulation_setup.hfss_simulation_setup import ( | ||
@@ -956,3 +955,3 @@ HfssSimulationSetup, | ||
| tuple_list.append(lobj_bbox) | ||
| _bbox = GrpcPolygonData.bbox_of_polygons(tuple_list) | ||
| _bbox = CorePolygonData.bbox_of_polygons(tuple_list) | ||
| layout_bbox = [ | ||
@@ -1150,4 +1149,4 @@ round(_bbox[0].x.value, digit_resolution), | ||
| dim = 0.30 * max(abs(ur[0] - ll[0]), abs(ur[1] - ll[1])) | ||
| terms_bbox.append(GrpcPolygonData([ll[0] - dim, ll[1] - dim, ur[0] + dim, ur[1] + dim])) | ||
| return GrpcPolygonData.bbox_of_polygons(terms_bbox) | ||
| terms_bbox.append(CorePolygonData([ll[0] - dim, ll[1] - dim, ur[0] + dim, ur[1] + dim])) | ||
| return CorePolygonData.bbox_of_polygons(terms_bbox) | ||
@@ -1235,87 +1234,20 @@ def get_ports_number(self): | ||
| distribution="linear", | ||
| start_freq=0, | ||
| stop_freq=20e9, | ||
| step_freq=1e6, | ||
| start_freq=None, | ||
| stop_freq=None, | ||
| step_freq=None, | ||
| discrete_sweep=False, | ||
| ) -> Optional[HfssSimulationSetup]: | ||
| """Add HFSS analysis setup. | ||
| """ | ||
| .. deprecated pyedb 0.67.0 | ||
| Parameters | ||
| ---------- | ||
| name : str, optional | ||
| Setup name (auto-generated if None). | ||
| distribution : str, optional | ||
| Sweep distribution type ("linear", "linear_count", "decade_count", "octave_count", "exponential"). | ||
| start_freq : float, str, optional | ||
| Starting frequency (Hz). | ||
| stop_freq : float, str, optional | ||
| Stopping frequency (Hz). | ||
| step_freq : float, str, int, optional | ||
| Frequency step (Hz) or count depending on distribution. | ||
| discrete_sweep : bool, optional | ||
| Use discrete sweep. | ||
| Add HFSS analysis setup (deprecated). | ||
| use :func:`create_simulation_setup` instead. | ||
| Returns | ||
| ------- | ||
| HfssSimulationSetup | ||
| Created setup object. | ||
| """ | ||
| warnings.warn("add_setup is deprecated use create_simulation_setup instead", DeprecationWarning) | ||
| Examples | ||
| -------- | ||
| >>> from pyedb import Edb | ||
| >>> edb = Edb("my_aedb") | ||
| >>> hfss_setup = edb.hfss.add_setup( | ||
| ... name="MySetup", | ||
| ... distribution="linear_count", | ||
| ... start_freq=1e9, | ||
| ... stop_freq=10e9, | ||
| ... step_freq=100, | ||
| ... ) | ||
| """ | ||
| from ansys.edb.core.simulation_setup.hfss_simulation_setup import ( | ||
| HfssSimulationSetup as GrpcHfssSimulationSetup, | ||
| return self._pedb.simulation_setups.create_hfss_setup( | ||
| name, distribution, start_freq, stop_freq, step_freq, discrete_sweep | ||
| ) | ||
| from ansys.edb.core.simulation_setup.simulation_setup import ( | ||
| Distribution as GrpcDistribution, | ||
| FrequencyData as GrpcFrequencyData, | ||
| SweepData as GrpcSweepData, | ||
| ) | ||
| if not name: | ||
| name = generate_unique_name("HFSS_pyedb") | ||
| if name in self._pedb.setups: | ||
| self._pedb.logger.error(f"HFSS setup {name} already defined.") | ||
| return None | ||
| setup = GrpcHfssSimulationSetup.create(self._pedb.active_cell, name) | ||
| start_freq = self._pedb.number_with_units(start_freq, "Hz") | ||
| stop_freq = self._pedb.number_with_units(stop_freq, "Hz") | ||
| if distribution.lower() == "linear": | ||
| distribution = "LIN" | ||
| elif distribution.lower() == "linear_count": | ||
| distribution = "LINC" | ||
| elif distribution.lower() == "exponential": | ||
| distribution = "ESTP" | ||
| elif distribution.lower() == "decade_count": | ||
| distribution = "DEC" | ||
| elif distribution.lower() == "octave_count": | ||
| distribution = "OCT" | ||
| else: | ||
| distribution = "LIN" | ||
| sweep_name = f"sweep_{len(setup.sweep_data) + 1}" | ||
| sweep_data = [ | ||
| GrpcSweepData( | ||
| name=sweep_name, | ||
| frequency_data=GrpcFrequencyData( | ||
| distribution=GrpcDistribution[distribution], start_f=start_freq, end_f=stop_freq, step=step_freq | ||
| ), | ||
| ) | ||
| ] | ||
| if discrete_sweep: | ||
| sweep_data[0].type = sweep_data[0].type.DISCRETE_SWEEP | ||
| for sweep in setup.sweep_data: | ||
| sweep_data.append(sweep) | ||
| # TODO check bug #441 status | ||
| # setup.sweep_data = sweep_data | ||
| return HfssSimulationSetup(self._pedb, setup) | ||
| def generate_auto_hfss_regions(self): | ||
@@ -1322,0 +1254,0 @@ """Generate auto HFSS regions. |
@@ -29,21 +29,21 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.definition.component_model import ( | ||
| NPortComponentModel as GrpcNPortComponentModel, | ||
| NPortComponentModel as CoreNPortComponentModel, | ||
| ) | ||
| from ansys.edb.core.definition.die_property import DieOrientation as GrpcDieOrientation, DieType as GrpcDieType | ||
| from ansys.edb.core.definition.die_property import DieOrientation as CoreDieOrientation, DieType as CoreDieType | ||
| from ansys.edb.core.definition.solder_ball_property import SolderballShape | ||
| from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData | ||
| from ansys.edb.core.hierarchy.component_group import ComponentType as GrpcComponentType | ||
| from ansys.edb.core.hierarchy.netlist_model import NetlistModel as GrpcNetlistModel | ||
| from ansys.edb.core.hierarchy.pin_pair_model import PinPairModel as GrpcPinPairModel | ||
| from ansys.edb.core.geometry.polygon_data import PolygonData as CorePolygonData | ||
| from ansys.edb.core.hierarchy.component_group import ComponentType as CoreComponentType | ||
| from ansys.edb.core.hierarchy.netlist_model import NetlistModel as CoreNetlistModel | ||
| from ansys.edb.core.hierarchy.pin_pair_model import PinPairModel as CorePinPairModel | ||
| from ansys.edb.core.hierarchy.sparameter_model import ( | ||
| SParameterModel as GrpcSParameterModel, | ||
| SParameterModel as CoreSParameterModel, | ||
| ) | ||
| from ansys.edb.core.hierarchy.spice_model import SPICEModel as GrpcSPICEModel | ||
| from ansys.edb.core.hierarchy.spice_model import SPICEModel as CoreSPICEModel | ||
| from ansys.edb.core.primitive.padstack_instance import ( | ||
| PadstackInstance as GrpcPadstackInstance, | ||
| PadstackInstance as CorePadstackInstance, | ||
| ) | ||
| from ansys.edb.core.terminal.padstack_instance_terminal import ( | ||
| PadstackInstanceTerminal as GrpcPadstackInstanceTerminal, | ||
| PadstackInstanceTerminal as CorePadstackInstanceTerminal, | ||
| ) | ||
| from ansys.edb.core.utility.rlc import Rlc as GrpcRlc | ||
| from ansys.edb.core.utility.rlc import Rlc as CoreRlc | ||
| import numpy as np | ||
@@ -63,9 +63,9 @@ | ||
| component_type_mapping = { | ||
| GrpcComponentType.OTHER: "other", | ||
| GrpcComponentType.RESISTOR: "resistor", | ||
| GrpcComponentType.INDUCTOR: "inductor", | ||
| GrpcComponentType.CAPACITOR: "capacitor", | ||
| GrpcComponentType.IC: "ic", | ||
| GrpcComponentType.IO: "io", | ||
| GrpcComponentType.INVALID: "invalid", | ||
| CoreComponentType.OTHER: "other", | ||
| CoreComponentType.RESISTOR: "resistor", | ||
| CoreComponentType.INDUCTOR: "inductor", | ||
| CoreComponentType.CAPACITOR: "capacitor", | ||
| CoreComponentType.IC: "ic", | ||
| CoreComponentType.IO: "io", | ||
| CoreComponentType.INVALID: "invalid", | ||
| } | ||
@@ -123,3 +123,3 @@ | ||
| if value in reverse_mapping: | ||
| self.core.component_type = GrpcComponentType(reverse_mapping[value]) | ||
| self.core.component_type = CoreComponentType(reverse_mapping[value]) | ||
| else: | ||
@@ -230,6 +230,6 @@ self._pedb.logger.error(f"Invalid component type: {value}") | ||
| self._pedb.logger.warning(f"Spice model defined on component {self.name}, replacing model by ") | ||
| rlc = GrpcRlc() | ||
| rlc = CoreRlc() | ||
| pins = list(self.pins.keys()) | ||
| pin_pair = (pins[0], pins[1]) | ||
| rlc_model = PinPairModel(self._pedb, GrpcPinPairModel.create()) | ||
| rlc_model = PinPairModel(self._pedb, CorePinPairModel.create()) | ||
| rlc_model.core.set_rlc(pin_pair, rlc) | ||
@@ -303,5 +303,5 @@ component_property = self.component_property | ||
| if isinstance(self.component_property.model, GrpcSPICEModel): | ||
| if isinstance(self.component_property.model, CoreSPICEModel): | ||
| return SpiceModel(edb_object=self.component_property.model.msg) | ||
| elif isinstance(self.component_property.model, GrpcSParameterModel): | ||
| elif isinstance(self.component_property.model, CoreSParameterModel): | ||
| return SparamModel(edb_object=self.component_property.model.msg) | ||
@@ -340,3 +340,3 @@ else: | ||
| self._package_def = GrpcPackageDef.create(self._pedb.db, name=value) | ||
| self._package_def.exterior_boundary = GrpcPolygonData(points=self.bounding_box) | ||
| self._package_def.exterior_boundary = CorePolygonData(points=self.bounding_box) | ||
| comp_prop = self.core.component_property | ||
@@ -494,3 +494,3 @@ comp_prop.package_def = self._package_def | ||
| @property | ||
| def netlist_model(self) -> GrpcNetlistModel: | ||
| def netlist_model(self) -> CoreNetlistModel: | ||
| """Assigned netlist model. | ||
@@ -505,3 +505,3 @@ | ||
| else: | ||
| return GrpcNetlistModel(self._edb_model) | ||
| return CoreNetlistModel(self._edb_model) | ||
@@ -733,3 +733,3 @@ @property | ||
| _rlc = [] | ||
| model = PinPairModel(self._pedb, GrpcPinPairModel.create()) | ||
| model = PinPairModel(self._pedb, CorePinPairModel.create()) | ||
| for rlc in self._rlc: | ||
@@ -764,3 +764,3 @@ rlc.r_enabled = True | ||
| _rlc = [] | ||
| model = PinPairModel(self._pedb, GrpcPinPairModel.create()) | ||
| model = PinPairModel(self._pedb, CorePinPairModel.create()) | ||
| for rlc in self._rlc: | ||
@@ -795,3 +795,3 @@ rlc.c_enabled = True | ||
| _rlc = [] | ||
| model = PinPairModel(self._pedb, GrpcPinPairModel.create()) | ||
| model = PinPairModel(self._pedb, CorePinPairModel.create()) | ||
| for rlc in self._rlc: | ||
@@ -935,6 +935,6 @@ rlc.l_enabled = True | ||
| for connectable in self.core.members: | ||
| if isinstance(connectable, GrpcPadstackInstanceTerminal): | ||
| if isinstance(connectable, CorePadstackInstanceTerminal): | ||
| if connectable.padstack_instance.is_layout_pin: | ||
| _pins[connectable.name] = PadstackInstanceTerminal(self._pedb, connectable) | ||
| if isinstance(connectable, GrpcPadstackInstance): | ||
| if isinstance(connectable, CorePadstackInstance): | ||
| if connectable.is_layout_pin: | ||
@@ -1224,3 +1224,3 @@ _pins[connectable.name] = PadstackInstance(self._pedb, connectable) | ||
| def assign_s_param_model(self, file_path, name=None, reference_net=None) -> GrpcNPortComponentModel: | ||
| def assign_s_param_model(self, file_path, name=None, reference_net=None) -> CoreNPortComponentModel: | ||
| """Assign S-parameter to this component. | ||
@@ -1255,9 +1255,9 @@ | ||
| reference_net = "GND" | ||
| n_port_model = GrpcNPortComponentModel.find_by_name(self.core.component_def, name) | ||
| n_port_model = CoreNPortComponentModel.find_by_name(self.core.component_def, name) | ||
| if n_port_model.is_null: | ||
| n_port_model = GrpcNPortComponentModel.create(name=name) | ||
| n_port_model = CoreNPortComponentModel.create(name=name) | ||
| n_port_model.reference_file = file_path | ||
| self.component_definition.core.add_component_model(n_port_model) | ||
| model = GrpcSParameterModel.create(name=name, ref_net=reference_net) | ||
| model = CoreSParameterModel.create(name=name, ref_net=reference_net) | ||
| return self._set_model(model) | ||
@@ -1293,3 +1293,3 @@ | ||
| if not model.is_null: | ||
| s_param_model = GrpcSParameterModel.create(name=name, ref_net="GND") | ||
| s_param_model = CoreSParameterModel.create(name=name, ref_net="GND") | ||
| if reference_net: | ||
@@ -1334,3 +1334,3 @@ s_param_model.reference_net = reference_net | ||
| # pin_pair = GrpcPinPair(pin_names[idx], pin_names[idx + 1]) | ||
| rlc = GrpcRlc( | ||
| rlc = CoreRlc( | ||
| r=res, | ||
@@ -1412,5 +1412,5 @@ r_enabled=r_enabled, | ||
| if value.lower() == "chip_up": | ||
| die_property.die_orientation = GrpcDieOrientation.CHIP_UP | ||
| die_property.die_orientation = CoreDieOrientation.CHIP_UP | ||
| elif value.lower() == "chip_down": | ||
| die_property.die_orientation = GrpcDieOrientation.CHIP_DOWN | ||
| die_property.die_orientation = CoreDieOrientation.CHIP_DOWN | ||
| else: | ||
@@ -1438,7 +1438,7 @@ return | ||
| if value.lower() == "none": | ||
| die_property.die_type = GrpcDieType.NONE | ||
| die_property.die_type = CoreDieType.NONE | ||
| elif value.lower() == "flipchip": | ||
| die_property.die_type = GrpcDieType.FLIPCHIP | ||
| die_property.die_type = CoreDieType.FLIPCHIP | ||
| elif value.lower() == "wirebond": | ||
| die_property.die_type = GrpcDieType.WIREBOND | ||
| die_property.die_type = CoreDieType.WIREBOND | ||
| else: | ||
@@ -1445,0 +1445,0 @@ return |
@@ -23,6 +23,6 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.hierarchy.model import Model as GrpcModel | ||
| from ansys.edb.core.hierarchy.model import Model as CoreModel | ||
| class Model(GrpcModel): | ||
| class Model(CoreModel): | ||
| """Manages model :class:`Model <ansys.edb.core.hierarchy.model.Model>`.""" | ||
@@ -29,0 +29,0 @@ |
@@ -23,6 +23,6 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.hierarchy.netlist_model import NetlistModel as GrpcNetlistModel | ||
| from ansys.edb.core.hierarchy.netlist_model import NetlistModel as CoreNetlistModel | ||
| class NetlistModel(GrpcNetlistModel): | ||
| class NetlistModel(CoreNetlistModel): | ||
| """Manage :class:`NetlistModel <ansys.edb.core.hierarchy.netlist_model.NetlistModel>`.""" | ||
@@ -29,0 +29,0 @@ |
@@ -25,3 +25,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| # from ansys.edb.core.hierarchy.pin_pair_model import PinPairModel | ||
| from ansys.edb.core.hierarchy.pin_pair_model import PinPairModel as GrpcPinPairModel | ||
| from ansys.edb.core.hierarchy.pin_pair_model import PinPairModel as CorePinPairModel | ||
@@ -28,0 +28,0 @@ from pyedb.grpc.database.utility.value import Value |
@@ -33,4 +33,4 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.hierarchy.pin_group import PinGroup as GrpcPinGroup | ||
| from ansys.edb.core.terminal.terminal import BoundaryType as GrpcBoundaryType | ||
| from ansys.edb.core.hierarchy.pin_group import PinGroup as CorePinGroup | ||
| from ansys.edb.core.terminal.terminal import BoundaryType as CoreBoundaryType | ||
@@ -72,3 +72,3 @@ from pyedb.generic.general_methods import generate_unique_name | ||
| raise TypeError("padstack_instances must be list of PadstackInstance") | ||
| pin_group = GrpcPinGroup.create(layout.core, name, [inst.core for inst in padstack_instances]) | ||
| pin_group = CorePinGroup.create(layout.core, name, [inst.core for inst in padstack_instances]) | ||
| return cls(layout._pedb, pin_group) | ||
@@ -206,3 +206,3 @@ | ||
| """ | ||
| return GrpcPinGroup.unique_name(layout.core, base_name) | ||
| return CorePinGroup.unique_name(layout.core, base_name) | ||
@@ -264,3 +264,3 @@ def create_terminal(self, name=None) -> PinGroupTerminal: | ||
| terminal = self.create_terminal() | ||
| terminal.boundary_type = GrpcBoundaryType.CURRENT_SOURCE | ||
| terminal.boundary_type = CoreBoundaryType.CURRENT_SOURCE | ||
| terminal.source_amplitude = Value(magnitude) | ||
@@ -290,3 +290,3 @@ terminal.source_phase = Value(phase) | ||
| terminal = self.create_terminal() | ||
| terminal.boundary_type = GrpcBoundaryType.VOLTAGE_SOURCE | ||
| terminal.boundary_type = CoreBoundaryType.VOLTAGE_SOURCE | ||
| terminal.source_amplitude = Value(magnitude) | ||
@@ -312,3 +312,3 @@ terminal.source_phase = Value(phase) | ||
| terminal = self.create_terminal() | ||
| terminal.boundary_type = GrpcBoundaryType.VOLTAGE_PROBE | ||
| terminal.boundary_type = CoreBoundaryType.VOLTAGE_PROBE | ||
| terminal.impedance = Value(impedance) | ||
@@ -315,0 +315,0 @@ return terminal |
@@ -23,7 +23,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.hierarchy.sparameter_model import ( | ||
| SParameterModel as GrpcSParameterModel, | ||
| ) | ||
| class SparamModel: # pragma: no cover | ||
@@ -30,0 +26,0 @@ """Manage :class:`SParameterModel <ansys.edb.core.hierarchy.sparameter_model.SParameterModel>`""" |
@@ -23,3 +23,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.hierarchy.spice_model import SPICEModel as GrpcSpiceModel | ||
| from ansys.edb.core.hierarchy.spice_model import SPICEModel as CoreSpiceModel | ||
@@ -36,3 +36,3 @@ | ||
| sub_circuit = name | ||
| edb_object = GrpcSpiceModel.create(name=name, path=file_path, sub_circuit=sub_circuit) | ||
| edb_object = CoreSpiceModel.create(name=name, path=file_path, sub_circuit=sub_circuit) | ||
| self.core = edb_object | ||
@@ -39,0 +39,0 @@ |
@@ -27,3 +27,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| class ConnObj(LayoutObj): | ||
| def __init__(self, pedb, edb_object): | ||
| super().__init__(pedb, edb_object) | ||
| def __init__(self, pedb, core): | ||
| super().__init__(pedb, core) |
@@ -31,22 +31,22 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.layer.layer import Layer as GrpcLayer, LayerType as GrpcLayerType | ||
| from ansys.edb.core.layer.layer import Layer as GrpcLayer, LayerType as CoreLayerType | ||
| layer_type_mapping = { | ||
| "conducting": GrpcLayerType.CONDUCTING_LAYER, | ||
| "air_lines": GrpcLayerType.AIRLINES_LAYER, | ||
| "errors": GrpcLayerType.ERRORS_LAYER, | ||
| "symbol": GrpcLayerType.SYMBOL_LAYER, | ||
| "measure": GrpcLayerType.MEASURE_LAYER, | ||
| "assembly": GrpcLayerType.ASSEMBLY_LAYER, | ||
| "silkscreen": GrpcLayerType.SILKSCREEN_LAYER, | ||
| "solder_mask": GrpcLayerType.SOLDER_MASK_LAYER, | ||
| "solder_paste": GrpcLayerType.SOLDER_PASTE_LAYER, | ||
| "glue": GrpcLayerType.GLUE_LAYER, | ||
| "wirebond": GrpcLayerType.WIREBOND_LAYER, | ||
| "user": GrpcLayerType.USER_LAYER, | ||
| "siwave_hfss_solver_regions": GrpcLayerType.SIWAVE_HFSS_SOLVER_REGIONS, | ||
| "postprocessing": GrpcLayerType.POST_PROCESSING_LAYER, | ||
| "outline": GrpcLayerType.OUTLINE_LAYER, | ||
| "layer_types_count": GrpcLayerType.LAYER_TYPES_COUNT, | ||
| "undefined_layer_type": GrpcLayerType.UNDEFINED_LAYER_TYPE, | ||
| "conducting": CoreLayerType.CONDUCTING_LAYER, | ||
| "air_lines": CoreLayerType.AIRLINES_LAYER, | ||
| "errors": CoreLayerType.ERRORS_LAYER, | ||
| "symbol": CoreLayerType.SYMBOL_LAYER, | ||
| "measure": CoreLayerType.MEASURE_LAYER, | ||
| "assembly": CoreLayerType.ASSEMBLY_LAYER, | ||
| "silkscreen": CoreLayerType.SILKSCREEN_LAYER, | ||
| "solder_mask": CoreLayerType.SOLDER_MASK_LAYER, | ||
| "solder_paste": CoreLayerType.SOLDER_PASTE_LAYER, | ||
| "glue": CoreLayerType.GLUE_LAYER, | ||
| "wirebond": CoreLayerType.WIREBOND_LAYER, | ||
| "user": CoreLayerType.USER_LAYER, | ||
| "siwave_hfss_solver_regions": CoreLayerType.SIWAVE_HFSS_SOLVER_REGIONS, | ||
| "postprocessing": CoreLayerType.POST_PROCESSING_LAYER, | ||
| "outline": CoreLayerType.OUTLINE_LAYER, | ||
| "layer_types_count": CoreLayerType.LAYER_TYPES_COUNT, | ||
| "undefined_layer_type": CoreLayerType.UNDEFINED_LAYER_TYPE, | ||
| } | ||
@@ -53,0 +53,0 @@ |
@@ -27,5 +27,5 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.layer.layer import LayerType as GrpcLayerType | ||
| from ansys.edb.core.layer.stackup_layer import RoughnessRegion as GrpcRoughnessRegion, StackupLayer as GrpcStackupLayer | ||
| from ansys.edb.core.utility.value import Value as GrpcValue | ||
| from ansys.edb.core.layer.layer import LayerType as CoreLayerType | ||
| from ansys.edb.core.layer.stackup_layer import RoughnessRegion as CoreRoughnessRegion, StackupLayer as CoreStackupLayer | ||
| from ansys.edb.core.utility.value import Value as CoreValue | ||
@@ -37,5 +37,5 @@ if TYPE_CHECKING: | ||
| _mapping_layer_type = { | ||
| "signal": GrpcLayerType.SIGNAL_LAYER, | ||
| "dielectric": GrpcLayerType.DIELECTRIC_LAYER, | ||
| "wirebond": GrpcLayerType.WIREBOND_LAYER, | ||
| "signal": CoreLayerType.SIGNAL_LAYER, | ||
| "dielectric": CoreLayerType.DIELECTRIC_LAYER, | ||
| "wirebond": CoreLayerType.WIREBOND_LAYER, | ||
| } | ||
@@ -52,10 +52,10 @@ | ||
| return { | ||
| "conducting_layer": GrpcLayerType.CONDUCTING_LAYER, | ||
| "silkscreen_layer": GrpcLayerType.SILKSCREEN_LAYER, | ||
| "solder_mask_layer": GrpcLayerType.SOLDER_MASK_LAYER, | ||
| "solder_paste_layer": GrpcLayerType.SOLDER_PASTE_LAYER, | ||
| "glue_layer": GrpcLayerType.GLUE_LAYER, | ||
| "wirebond_layer": GrpcLayerType.WIREBOND_LAYER, | ||
| "user_layer": GrpcLayerType.USER_LAYER, | ||
| "siwave_hfss_solver_regions": GrpcLayerType.SIWAVE_HFSS_SOLVER_REGIONS, | ||
| "conducting_layer": CoreLayerType.CONDUCTING_LAYER, | ||
| "silkscreen_layer": CoreLayerType.SILKSCREEN_LAYER, | ||
| "solder_mask_layer": CoreLayerType.SOLDER_MASK_LAYER, | ||
| "solder_paste_layer": CoreLayerType.SOLDER_PASTE_LAYER, | ||
| "glue_layer": CoreLayerType.GLUE_LAYER, | ||
| "wirebond_layer": CoreLayerType.WIREBOND_LAYER, | ||
| "user_layer": CoreLayerType.USER_LAYER, | ||
| "siwave_hfss_solver_regions": CoreLayerType.SIWAVE_HFSS_SOLVER_REGIONS, | ||
| } | ||
@@ -73,3 +73,3 @@ | ||
| ) -> StackupLayer: | ||
| layer = GrpcStackupLayer.create( | ||
| layer = CoreStackupLayer.create( | ||
| name=name, | ||
@@ -177,3 +177,3 @@ layer_type=_mapping_layer_type[layer_type], | ||
| layer_type = self._stackup_layer_mapping[layer_type] | ||
| self._edb_object = GrpcStackupLayer.create( | ||
| self._edb_object = CoreStackupLayer.create( | ||
| self._name, | ||
@@ -404,3 +404,3 @@ layer_type, | ||
| return 0.0 | ||
| top_roughness_model = self.core.get_roughness_model(GrpcRoughnessRegion.TOP) | ||
| top_roughness_model = self.core.get_roughness_model(CoreRoughnessRegion.TOP) | ||
| if len(top_roughness_model) == 2: | ||
@@ -426,3 +426,3 @@ return Value(top_roughness_model[0], self._pedb.active_cell) | ||
| return 0.0 | ||
| top_roughness_model = self.core.get_roughness_model(GrpcRoughnessRegion.TOP) | ||
| top_roughness_model = self.core.get_roughness_model(CoreRoughnessRegion.TOP) | ||
| if len(top_roughness_model) == 2: | ||
@@ -448,3 +448,3 @@ return Value(top_roughness_model[1], self._pedb.active_cell) | ||
| return 0.0 | ||
| bottom_roughness_model = self.core.get_roughness_model(GrpcRoughnessRegion.BOTTOM) | ||
| bottom_roughness_model = self.core.get_roughness_model(CoreRoughnessRegion.BOTTOM) | ||
| if len(bottom_roughness_model) == 2: | ||
@@ -470,3 +470,3 @@ return Value(bottom_roughness_model[0], self._pedb.active_cell) | ||
| return 0.0 | ||
| bottom_roughness_model = self.core.get_roughness_model(GrpcRoughnessRegion.BOTTOM) | ||
| bottom_roughness_model = self.core.get_roughness_model(CoreRoughnessRegion.BOTTOM) | ||
| if len(bottom_roughness_model) == 2: | ||
@@ -493,3 +493,3 @@ return Value(bottom_roughness_model[1], self._pedb.active_cell) | ||
| return 0.0 | ||
| side_roughness_model = self.core.get_roughness_model(GrpcRoughnessRegion.SIDE) | ||
| side_roughness_model = self.core.get_roughness_model(CoreRoughnessRegion.SIDE) | ||
| if len(side_roughness_model) == 2: | ||
@@ -514,3 +514,3 @@ return Value(side_roughness_model[0], self._pedb.active_cell) | ||
| return 0.0 | ||
| side_roughness_model = self.core.get_roughness_model(GrpcRoughnessRegion.SIDE) | ||
| side_roughness_model = self.core.get_roughness_model(CoreRoughnessRegion.SIDE) | ||
| if len(side_roughness_model) == 2: | ||
@@ -535,4 +535,4 @@ return Value(side_roughness_model[1], self._pedb.active_cell) | ||
| return 0.0 | ||
| top_roughness = self.core.get_roughness_model(GrpcRoughnessRegion.TOP) | ||
| if isinstance(top_roughness, GrpcValue): | ||
| top_roughness = self.core.get_roughness_model(CoreRoughnessRegion.TOP) | ||
| if isinstance(top_roughness, CoreValue): | ||
| return top_roughness.value | ||
@@ -556,4 +556,4 @@ return 0.0 | ||
| return 0.0 | ||
| bottom_roughness = self.core.get_roughness_model(GrpcRoughnessRegion.BOTTOM) | ||
| if isinstance(bottom_roughness, GrpcValue): | ||
| bottom_roughness = self.core.get_roughness_model(CoreRoughnessRegion.BOTTOM) | ||
| if isinstance(bottom_roughness, CoreValue): | ||
| return bottom_roughness.value | ||
@@ -577,4 +577,4 @@ return 0.0 | ||
| return 0.0 | ||
| bottom_roughness = self.core.get_roughness_model(GrpcRoughnessRegion.SIDE) | ||
| if isinstance(bottom_roughness, GrpcValue): | ||
| bottom_roughness = self.core.get_roughness_model(CoreRoughnessRegion.SIDE) | ||
| if isinstance(bottom_roughness, CoreValue): | ||
| return bottom_roughness.value | ||
@@ -664,9 +664,9 @@ return 0.0 | ||
| if apply_on_surface == "all": | ||
| regions = [GrpcRoughnessRegion.TOP, GrpcRoughnessRegion.BOTTOM, GrpcRoughnessRegion.SIDE] | ||
| regions = [CoreRoughnessRegion.TOP, CoreRoughnessRegion.BOTTOM, CoreRoughnessRegion.SIDE] | ||
| elif apply_on_surface == "top": | ||
| regions = [GrpcRoughnessRegion.TOP] | ||
| regions = [CoreRoughnessRegion.TOP] | ||
| elif apply_on_surface == "bottom": | ||
| regions = [GrpcRoughnessRegion.BOTTOM] | ||
| regions = [CoreRoughnessRegion.BOTTOM] | ||
| elif apply_on_surface == "side": | ||
| regions = [GrpcRoughnessRegion.SIDE] | ||
| regions = [CoreRoughnessRegion.SIDE] | ||
| self.core.roughness_enabled = True | ||
@@ -680,5 +680,5 @@ for r in regions: | ||
| if [ | ||
| self.core.get_roughness_model(GrpcRoughnessRegion.TOP), | ||
| self.core.get_roughness_model(GrpcRoughnessRegion.BOTTOM), | ||
| self.core.get_roughness_model(GrpcRoughnessRegion.SIDE), | ||
| self.core.get_roughness_model(CoreRoughnessRegion.TOP), | ||
| self.core.get_roughness_model(CoreRoughnessRegion.BOTTOM), | ||
| self.core.get_roughness_model(CoreRoughnessRegion.SIDE), | ||
| ]: | ||
@@ -685,0 +685,0 @@ return True |
@@ -26,3 +26,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.database import ProductIdType as GrpcProductIdType | ||
| from ansys.edb.core.database import ProductIdType as CoreProductIdType | ||
@@ -32,5 +32,3 @@ from pyedb.generic.general_methods import generate_unique_name | ||
| # from pyedb.grpc.database.primitive.primitive import Primitive | ||
| class LayoutValidation: | ||
@@ -395,3 +393,3 @@ """Manages all layout validation capabilities""" | ||
| for obj in pds: | ||
| name = obj.core.get_product_property(GrpcProductIdType.DESIGNER, 11) | ||
| name = obj.core.get_product_property(CoreProductIdType.DESIGNER, 11) | ||
| name = str(name).strip("'") | ||
@@ -402,8 +400,8 @@ if name == "": | ||
| if not obj.component: | ||
| obj.set_product_property(GrpcProductIdType.DESIGNER, 11, f"Via{via_count}") | ||
| obj.set_product_property(CoreProductIdType.DESIGNER, 11, f"Via{via_count}") | ||
| via_count = via_count + 1 | ||
| else: | ||
| obj.set_product_property( | ||
| GrpcProductIdType.DESIGNER, 11, f"{obj.component.name}-{obj.component_pin}" | ||
| CoreProductIdType.DESIGNER, 11, f"{obj.component.name}-{obj.component_pin}" | ||
| ) | ||
| self._pedb.logger.info(f"Found {counts}/{len(pds)} padstacks have no name.") |
@@ -23,5 +23,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.layout.cell import Cell as GrpcCell | ||
| class Cell: | ||
@@ -28,0 +26,0 @@ """Manage :class:`Cell <ansys.edb.core.layout.cell.Cell>`""" |
@@ -30,3 +30,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.layout.voltage_regulator import ( | ||
| VoltageRegulator as GrpcVoltageRegulator, | ||
| VoltageRegulator as CoreVoltageRegulator, | ||
| ) | ||
@@ -33,0 +33,0 @@ |
@@ -32,3 +32,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.net.differential_pair import ( | ||
| DifferentialPair as GrpcDifferentialPair, | ||
| DifferentialPair as CoreDifferentialPair, | ||
| ) | ||
@@ -75,3 +75,3 @@ | ||
| return False | ||
| GrpcDifferentialPair.create(layout=self._pedb.layout.core, name=name, pos_net=net_p, neg_net=net_n) | ||
| CoreDifferentialPair.create(layout=self._pedb.layout.core, name=name, pos_net=net_p, neg_net=net_n) | ||
| return self.items[name] | ||
@@ -127,3 +127,3 @@ | ||
| class DifferentialPair(GrpcDifferentialPair): | ||
| class DifferentialPair(CoreDifferentialPair): | ||
| """Manages EDB functionalities for a primitive. | ||
@@ -130,0 +130,0 @@ It inherits EDB object properties. |
@@ -29,3 +29,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from pyedb.grpc.database.net.net import Net | ||
| from ansys.edb.core.net.extended_net import ExtendedNet as GrpcExtendedNet | ||
| from ansys.edb.core.net.extended_net import ExtendedNet as CoreExtendedNet | ||
@@ -295,3 +295,3 @@ | ||
| """ | ||
| core_extended_net = GrpcExtendedNet.create(layout.core, name) | ||
| core_extended_net = CoreExtendedNet.create(layout.core, name) | ||
| return cls(layout._pedb, core_extended_net) | ||
@@ -298,0 +298,0 @@ |
@@ -30,4 +30,4 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance | ||
| from ansys.edb.core.net.net import Net as GrpcNet | ||
| from ansys.edb.core.primitive.primitive import PrimitiveType as GrpcPrimitiveType | ||
| from ansys.edb.core.net.net import Net as CoreNet | ||
| from ansys.edb.core.primitive.primitive import PrimitiveType as CorePrimitiveType | ||
@@ -148,11 +148,11 @@ from pyedb.grpc.database.primitive.bondwire import Bondwire | ||
| for primitive in primitives: | ||
| if primitive.primitive_type == GrpcPrimitiveType.PATH: | ||
| if primitive.primitive_type == CorePrimitiveType.PATH: | ||
| self.__primitives.append(Path(self._pedb, primitive)) | ||
| elif primitive.primitive_type == GrpcPrimitiveType.POLYGON: | ||
| elif primitive.primitive_type == CorePrimitiveType.POLYGON: | ||
| self.__primitives.append(Polygon(self._pedb, primitive)) | ||
| elif primitive.primitive_type == GrpcPrimitiveType.CIRCLE: | ||
| elif primitive.primitive_type == CorePrimitiveType.CIRCLE: | ||
| self.__primitives.append(Circle(self._pedb, primitive)) | ||
| elif primitive.primitive_type == GrpcPrimitiveType.RECTANGLE: | ||
| elif primitive.primitive_type == CorePrimitiveType.RECTANGLE: | ||
| self.__primitives.append(Rectangle(self._pedb, primitive)) | ||
| elif primitive.primitive_type == GrpcPrimitiveType.BONDWIRE: | ||
| elif primitive.primitive_type == CorePrimitiveType.BONDWIRE: | ||
| self.__primitives.append(Bondwire(self._pedb, primitive)) | ||
@@ -212,3 +212,3 @@ return self.__primitives | ||
| """ | ||
| return cls(layout._pedb, GrpcNet.create(layout=layout.core, name=name)) | ||
| return cls(layout._pedb, CoreNet.create(layout=layout.core, name=name)) | ||
@@ -320,3 +320,3 @@ def find_dc_short(self, fix=False) -> list[list[str, str]]: | ||
| """ | ||
| net = GrpcNet.find_by_name(layout.core, name) | ||
| net = CoreNet.find_by_name(layout.core, name) | ||
| return Net(layout._pedb, net) |
@@ -28,3 +28,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.net.net_class import NetClass as GrpcNetClass | ||
| from ansys.edb.core.net.net_class import NetClass as CoreNetClass | ||
@@ -972,3 +972,3 @@ from pyedb.common.nets import CommonNets | ||
| return False | ||
| grpc_net_class = GrpcNetClass.create(self._pedb.active_layout.core, name) | ||
| grpc_net_class = CoreNetClass.create(self._pedb.active_layout.core, name) | ||
| if isinstance(net, str): | ||
@@ -975,0 +975,0 @@ net = [net] |
@@ -24,5 +24,5 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.primitive.bondwire import ( | ||
| Bondwire as GrpcBondWire, | ||
| BondwireCrossSectionType as GrpcBondwireCrossSectionType, | ||
| BondwireType as GrpcBondWireType, | ||
| Bondwire as CoreBondWire, | ||
| BondwireCrossSectionType as CoreBondwireCrossSectionType, | ||
| BondwireType as CoreBondWireType, | ||
| ) | ||
@@ -104,13 +104,13 @@ | ||
| if bondwire_type == "jedec4": | ||
| bondwire_type = GrpcBondWireType.JEDEC4 | ||
| bondwire_type = CoreBondWireType.JEDEC4 | ||
| elif bondwire_type == "jedec5": | ||
| bondwire_type = GrpcBondWireType.JEDEC5 | ||
| bondwire_type = CoreBondWireType.JEDEC5 | ||
| elif bondwire_type == "apd": | ||
| bondwire_type = GrpcBondWireType.APD | ||
| bondwire_type = CoreBondWireType.APD | ||
| else: | ||
| bondwire_type = GrpcBondWireType.JEDEC4 | ||
| bondwire_type = CoreBondWireType.JEDEC4 | ||
| if material not in layout._pedb.materials.materials: | ||
| layout._pedb.materials.add_conductor_material(material) | ||
| layout._pedb.logger("Material {material} not found. Added to the material library.") | ||
| core_bondwire = GrpcBondWire.create( | ||
| core_bondwire = CoreBondWire.create( | ||
| layout=layout.core, | ||
@@ -168,6 +168,6 @@ bondwire_type=bondwire_type, | ||
| mapping = { | ||
| "apd": GrpcBondWireType.APD, | ||
| "jedec4": GrpcBondWireType.JEDEC4, | ||
| "jedec5": GrpcBondWireType.JEDEC5, | ||
| "num_of_type": GrpcBondWireType.NUM_OF_TYPE, | ||
| "apd": CoreBondWireType.APD, | ||
| "jedec4": CoreBondWireType.JEDEC4, | ||
| "jedec5": CoreBondWireType.JEDEC5, | ||
| "num_of_type": CoreBondWireType.NUM_OF_TYPE, | ||
| } | ||
@@ -190,3 +190,3 @@ self.core.type = mapping[bondwire_type] | ||
| def cross_section_type(self, cross_section_type): | ||
| mapping = {"round": GrpcBondwireCrossSectionType.ROUND, "rectangle": GrpcBondwireCrossSectionType.RECTANGLE} | ||
| mapping = {"round": CoreBondwireCrossSectionType.ROUND, "rectangle": CoreBondwireCrossSectionType.RECTANGLE} | ||
| self.core.cross_section_type = mapping[cross_section_type] | ||
@@ -193,0 +193,0 @@ |
@@ -26,3 +26,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.primitive.circle import Circle as GrpcCircle | ||
| from ansys.edb.core.primitive.circle import Circle as CoreCircle | ||
@@ -58,3 +58,3 @@ from pyedb.grpc.database.layers.layer import Layer | ||
| raise ValueError("Center x and y values must be provided to create a circle.") | ||
| edb_object = GrpcCircle.create( | ||
| edb_object = CoreCircle.create( | ||
| layout=layout.core, | ||
@@ -61,0 +61,0 @@ layer=layer, |
@@ -31,12 +31,12 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from pyedb.grpc.database.layers.stackup_layer import StackupLayer | ||
| from ansys.edb.core.database import ProductIdType as GrpcProductIdType | ||
| from ansys.edb.core.geometry.point_data import PointData as GrpcPointData | ||
| from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData | ||
| from ansys.edb.core.hierarchy.pin_group import PinGroup as GrpcPinGroup | ||
| from ansys.edb.core.hierarchy.structure3d import MeshClosure as GrpcMeshClosure, Structure3D as GrpcStructure3D | ||
| from ansys.edb.core.database import ProductIdType as CoreProductIdType | ||
| from ansys.edb.core.geometry.point_data import PointData as CorePointData | ||
| from ansys.edb.core.geometry.polygon_data import PolygonData as CorePolygonData | ||
| from ansys.edb.core.hierarchy.pin_group import PinGroup as CorePinGroup | ||
| from ansys.edb.core.hierarchy.structure3d import MeshClosure as CoreMeshClosure, Structure3D as CoreStructure3D | ||
| from ansys.edb.core.primitive.padstack_instance import ( | ||
| PadstackInstance as GrpcPadstackInstance, | ||
| PadstackInstance as CorePadstackInstance, | ||
| ) | ||
| from ansys.edb.core.terminal.pin_group_terminal import ( | ||
| PinGroupTerminal as GrpcPinGroupTerminal, | ||
| PinGroupTerminal as CorePinGroupTerminal, | ||
| ) | ||
@@ -138,3 +138,3 @@ | ||
| padstack_def = layout._pedb.padstacks.definitions[padstack_definition].core | ||
| inst = GrpcPadstackInstance.create( | ||
| inst = CorePadstackInstance.create( | ||
| layout=layout.core, | ||
@@ -260,3 +260,3 @@ net=net.core, | ||
| """ | ||
| side_value = self.core.get_product_property(GrpcProductIdType.HFSS_3D_LAYOUT, 21) | ||
| side_value = self.core.get_product_property(CoreProductIdType.HFSS_3D_LAYOUT, 21) | ||
| if side_value: | ||
@@ -282,3 +282,3 @@ return int(re.search(r"(?m)^\s*sid=(\d+)", side_value).group(1)) | ||
| prop_string = f"$begin ''\n\tsid={value}\n\tmat='copper'\n\tvs='Wirebond'\n$end ''\n" | ||
| self.core.set_product_property(GrpcProductIdType.HFSS_3D_LAYOUT, 21, prop_string) | ||
| self.core.set_product_property(CoreProductIdType.HFSS_3D_LAYOUT, 21, prop_string) | ||
| else: | ||
@@ -463,6 +463,6 @@ raise ValueError("Number of sides must be an integer between 3 and 64") | ||
| if isinstance(reference, list): | ||
| pg = GrpcPinGroup.create( | ||
| pg = CorePinGroup.create( | ||
| self.core.layout, name=f"pingroup_{self.name}_ref", padstack_instances=reference | ||
| ) | ||
| negative_terminal = GrpcPinGroupTerminal.create( | ||
| negative_terminal = CorePinGroupTerminal.create( | ||
| layout=self.core.layout, | ||
@@ -612,3 +612,3 @@ name=f"pingroup_term{self.name}_ref)", | ||
| """ | ||
| int_val = 1 if polygon_data.is_inside(GrpcPointData(self.position)) else 0 | ||
| int_val = 1 if polygon_data.is_inside(CorePointData(self.position)) else 0 | ||
| if int_val == 0: | ||
@@ -625,3 +625,3 @@ if include_partial: | ||
| ] | ||
| int_val = polygon_data.intersection_type(GrpcPolygonData(inst_bbox)).value | ||
| int_val = polygon_data.intersection_type(CorePolygonData(inst_bbox)).value | ||
| if int_val == 0: # fully outside | ||
@@ -772,3 +772,3 @@ return False | ||
| if self.component: | ||
| out2 = self.component.core.transform.transform_point(GrpcPointData(position[:2])) | ||
| out2 = self.component.core.transform.transform_point(CorePointData(position[:2])) | ||
| self._position = [Value(out2[0]), Value(out2[1])] | ||
@@ -787,3 +787,3 @@ else: | ||
| pos.append(v) | ||
| point_data = GrpcPointData(pos[0], pos[1]) | ||
| point_data = CorePointData(pos[0], pos[1]) | ||
| self.core.set_position_and_rotation( | ||
@@ -823,3 +823,3 @@ x=point_data.x, y=point_data.y, rotation=Value(self.rotation, self._pedb.active_cell) | ||
| # changing aedt_name too | ||
| self.core.set_product_property(GrpcProductIdType.DESIGNER, 11, value) | ||
| self.core.set_product_property(CoreProductIdType.DESIGNER, 11, value) | ||
@@ -1039,3 +1039,3 @@ @property | ||
| name = self.core.get_product_property(GrpcProductIdType.DESIGNER, 11) | ||
| name = self.core.get_product_property(CoreProductIdType.DESIGNER, 11) | ||
| return str(name).strip("'") | ||
@@ -1045,3 +1045,3 @@ | ||
| def aedt_name(self, value): | ||
| self.core.set_product_property(GrpcProductIdType.DESIGNER, 11, value) | ||
| self.core.set_product_property(CoreProductIdType.DESIGNER, 11, value) | ||
@@ -1132,3 +1132,3 @@ def split(self) -> list: | ||
| s3d = GrpcStructure3D.create( | ||
| s3d = CoreStructure3D.create( | ||
| layout.core, generate_unique_name("via3d_" + self.aedt_name.replace("via_", ""), n=3) | ||
@@ -1139,3 +1139,3 @@ ) | ||
| s3d.set_material(self.definition.material) | ||
| s3d.mesh_closure = GrpcMeshClosure.ENDS_CLOSED | ||
| s3d.mesh_closure = CoreMeshClosure.ENDS_CLOSED | ||
| hole_override_enabled = True | ||
@@ -1275,3 +1275,3 @@ hole_override_diam = 0 | ||
| y_pos = Value(self.position[1]) | ||
| point_data = GrpcPointData([x_pos, y_pos]) | ||
| point_data = CorePointData([x_pos, y_pos]) | ||
@@ -1542,4 +1542,4 @@ voids = [] | ||
| # return False | ||
| rect = [GrpcPointData(pt) for pt in rect] | ||
| path = GrpcPolygonData(rect) | ||
| rect = [CorePointData(pt) for pt in rect] | ||
| path = CorePolygonData(rect) | ||
| new_rect = [] | ||
@@ -1546,0 +1546,0 @@ for point in path.points: |
@@ -28,7 +28,7 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData | ||
| from ansys.edb.core.geometry.polygon_data import PolygonData as CorePolygonData | ||
| from ansys.edb.core.primitive.path import ( | ||
| Path as GrpcPath, | ||
| PathCornerType as GrpcPathCornerType, | ||
| PathEndCapType as GrpcPathEndCapType, | ||
| Path as CorePath, | ||
| PathCornerType as CorePathCornerType, | ||
| PathEndCapType as CorePathEndCapType, | ||
| ) | ||
@@ -91,6 +91,6 @@ | ||
| width: float = 100e-6, | ||
| end_cap1: Union[str, GrpcPathEndCapType] = "flat", | ||
| end_cap2: Union[str, GrpcPathEndCapType] = "flat", | ||
| corner_style: Union[str, GrpcPathCornerType] = "sharp", | ||
| points: Union[list, GrpcPolygonData] = None, | ||
| end_cap1: Union[str, CorePathEndCapType] = "flat", | ||
| end_cap2: Union[str, CorePathEndCapType] = "flat", | ||
| corner_style: Union[str, CorePathCornerType] = "sharp", | ||
| points: Union[list, CorePolygonData] = None, | ||
| ): | ||
@@ -143,11 +143,11 @@ """ | ||
| end_cap_mapping = { | ||
| "flat": GrpcPathEndCapType.FLAT, | ||
| "round": GrpcPathEndCapType.ROUND, | ||
| "extended": GrpcPathEndCapType.EXTENDED, | ||
| "clipped": GrpcPathEndCapType.CLIPPED, | ||
| "flat": CorePathEndCapType.FLAT, | ||
| "round": CorePathEndCapType.ROUND, | ||
| "extended": CorePathEndCapType.EXTENDED, | ||
| "clipped": CorePathEndCapType.CLIPPED, | ||
| } | ||
| corner_style_mapping = { | ||
| "round": GrpcPathCornerType.ROUND, | ||
| "mitter": GrpcPathCornerType.MITER, | ||
| "sharp": GrpcPathCornerType.SHARP, | ||
| "round": CorePathCornerType.ROUND, | ||
| "mitter": CorePathCornerType.MITER, | ||
| "sharp": CorePathCornerType.SHARP, | ||
| } | ||
@@ -163,4 +163,4 @@ if isinstance(end_cap1, str): | ||
| if isinstance(points, list): | ||
| points = GrpcPolygonData(points=points) | ||
| _path = GrpcPath.create( | ||
| points = CorePolygonData(points=points) | ||
| _path = CorePath.create( | ||
| layout=layout.core, | ||
@@ -207,3 +207,3 @@ layer=layer, | ||
| points.append([x, y]) | ||
| points = GrpcPolygonData(points=points) | ||
| points = CorePolygonData(points=points) | ||
| self.core.center_line = points | ||
@@ -224,8 +224,8 @@ return True | ||
| mapping = { | ||
| "round": GrpcPathCornerType.ROUND, | ||
| "mitter": GrpcPathCornerType.MITER, | ||
| "sharp": GrpcPathCornerType.SHARP, | ||
| "round": CorePathCornerType.ROUND, | ||
| "mitter": CorePathCornerType.MITER, | ||
| "sharp": CorePathCornerType.SHARP, | ||
| } | ||
| cloned_path = GrpcPath.create( | ||
| cloned_path = CorePath.create( | ||
| layout=self._pedb.active_layout.core, | ||
@@ -238,3 +238,3 @@ layer=self.layer, | ||
| corner_style=mapping[self.corner_style], | ||
| points=GrpcPolygonData(self.center_line), | ||
| points=CorePolygonData(self.center_line), | ||
| ) | ||
@@ -449,5 +449,5 @@ if not cloned_path.is_null: | ||
| mapping = { | ||
| "round": GrpcPathCornerType.ROUND, | ||
| "mitter": GrpcPathCornerType.MITER, | ||
| "sharp": GrpcPathCornerType.SHARP, | ||
| "round": CorePathCornerType.ROUND, | ||
| "mitter": CorePathCornerType.MITER, | ||
| "sharp": CorePathCornerType.SHARP, | ||
| } | ||
@@ -472,5 +472,5 @@ self.corner_style = mapping[corner_type] | ||
| mapping = { | ||
| "flat": GrpcPathEndCapType.FLAT, | ||
| "round": GrpcPathEndCapType.ROUND, | ||
| "extended": GrpcPathEndCapType.EXTENDED, | ||
| "flat": CorePathEndCapType.FLAT, | ||
| "round": CorePathEndCapType.ROUND, | ||
| "extended": CorePathEndCapType.EXTENDED, | ||
| } | ||
@@ -495,6 +495,6 @@ self.core.set_end_cap_style(mapping[end_cap_style], self.core.get_end_cap_style()[1].value) | ||
| mapping = { | ||
| "flat": GrpcPathEndCapType.FLAT, | ||
| "round": GrpcPathEndCapType.ROUND, | ||
| "extended": GrpcPathEndCapType.EXTENDED, | ||
| "flat": CorePathEndCapType.FLAT, | ||
| "round": CorePathEndCapType.ROUND, | ||
| "extended": CorePathEndCapType.EXTENDED, | ||
| } | ||
| self.core.set_end_cap_style(self.core.get_end_cap_style()[0].value, mapping[end_cap_style]) |
@@ -27,5 +27,5 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.geometry.point_data import PointData as GrpcPointData | ||
| from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData | ||
| from ansys.edb.core.primitive.polygon import Polygon as GrpcPolygon | ||
| from ansys.edb.core.geometry.point_data import PointData as CorePointData | ||
| from ansys.edb.core.geometry.polygon_data import PolygonData as CorePolygonData | ||
| from ansys.edb.core.primitive.polygon import Polygon as CorePolygon | ||
@@ -148,3 +148,3 @@ from pyedb.grpc.database.geometry.polygon_data import PolygonData | ||
| if isinstance(polygon_data, list): | ||
| polygon_data = GrpcPolygonData(polygon_data) | ||
| polygon_data = CorePolygonData(polygon_data) | ||
| if isinstance(polygon_data, PolygonData): | ||
@@ -156,3 +156,3 @@ polygon_data = polygon_data.core | ||
| net = net.core | ||
| edb_object = GrpcPolygon.create(layout=layout.core, layer=layer, net=net, polygon_data=polygon_data) | ||
| edb_object = CorePolygon.create(layout=layout.core, layer=layer, net=net, polygon_data=polygon_data) | ||
| new_polygon = cls(layout._pedb, edb_object) | ||
@@ -289,3 +289,3 @@ # keep modeler cache in sync | ||
| elif isinstance(center, list) and len(center) == 2: | ||
| center = GrpcPointData([Value(center[0]), Value(center[1])]) | ||
| center = CorePointData([Value(center[0]), Value(center[1])]) | ||
| self.polygon_data = PolygonData(self.polygon_data.core.scale(factor, center)) | ||
@@ -365,7 +365,7 @@ return True | ||
| """ | ||
| int_val = 1 if self.polygon_data.core.is_inside(GrpcPointData(point_data)) else 0 | ||
| int_val = 1 if self.polygon_data.core.is_inside(CorePointData(point_data)) else 0 | ||
| if int_val == 0: | ||
| return False | ||
| else: | ||
| int_val = self.polygon_data.core.intersection_type(GrpcPolygonData(point_data)) | ||
| int_val = self.polygon_data.core.intersection_type(CorePolygonData(point_data)) | ||
| # Intersection type: | ||
@@ -372,0 +372,0 @@ # 0 = objects do not intersect |
@@ -26,6 +26,6 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.database import ProductIdType as GrpcProductIdType | ||
| from ansys.edb.core.geometry.point_data import PointData as GrpcPointData | ||
| from ansys.edb.core.layer.layer import LayerType as GrpcLayerType | ||
| from ansys.edb.core.primitive.circle import Circle as GrpcCircle | ||
| from ansys.edb.core.database import ProductIdType as CoreProductIdType | ||
| from ansys.edb.core.geometry.point_data import PointData as CorePointData | ||
| from ansys.edb.core.layer.layer import LayerType as CoreLayerType | ||
| from ansys.edb.core.primitive.circle import Circle as CoreCircle | ||
@@ -38,19 +38,19 @@ from pyedb.grpc.database.geometry.polygon_data import PolygonData | ||
| layer_type_mapping = { | ||
| "conducting": GrpcLayerType.CONDUCTING_LAYER, | ||
| "air_lines": GrpcLayerType.AIRLINES_LAYER, | ||
| "errors": GrpcLayerType.ERRORS_LAYER, | ||
| "symbol": GrpcLayerType.SYMBOL_LAYER, | ||
| "measure": GrpcLayerType.MEASURE_LAYER, | ||
| "assembly": GrpcLayerType.ASSEMBLY_LAYER, | ||
| "silkscreen": GrpcLayerType.SILKSCREEN_LAYER, | ||
| "solder_mask": GrpcLayerType.SOLDER_MASK_LAYER, | ||
| "solder_paste": GrpcLayerType.SOLDER_PASTE_LAYER, | ||
| "glue": GrpcLayerType.GLUE_LAYER, | ||
| "wirebond": GrpcLayerType.WIREBOND_LAYER, | ||
| "user": GrpcLayerType.USER_LAYER, | ||
| "siwave_hfss_solver_regions": GrpcLayerType.SIWAVE_HFSS_SOLVER_REGIONS, | ||
| "postprocessing": GrpcLayerType.POST_PROCESSING_LAYER, | ||
| "outline": GrpcLayerType.OUTLINE_LAYER, | ||
| "layer_types_count": GrpcLayerType.LAYER_TYPES_COUNT, | ||
| "undefined_layer_type": GrpcLayerType.UNDEFINED_LAYER_TYPE, | ||
| "conducting": CoreLayerType.CONDUCTING_LAYER, | ||
| "air_lines": CoreLayerType.AIRLINES_LAYER, | ||
| "errors": CoreLayerType.ERRORS_LAYER, | ||
| "symbol": CoreLayerType.SYMBOL_LAYER, | ||
| "measure": CoreLayerType.MEASURE_LAYER, | ||
| "assembly": CoreLayerType.ASSEMBLY_LAYER, | ||
| "silkscreen": CoreLayerType.SILKSCREEN_LAYER, | ||
| "solder_mask": CoreLayerType.SOLDER_MASK_LAYER, | ||
| "solder_paste": CoreLayerType.SOLDER_PASTE_LAYER, | ||
| "glue": CoreLayerType.GLUE_LAYER, | ||
| "wirebond": CoreLayerType.WIREBOND_LAYER, | ||
| "user": CoreLayerType.USER_LAYER, | ||
| "siwave_hfss_solver_regions": CoreLayerType.SIWAVE_HFSS_SOLVER_REGIONS, | ||
| "postprocessing": CoreLayerType.POST_PROCESSING_LAYER, | ||
| "outline": CoreLayerType.OUTLINE_LAYER, | ||
| "layer_types_count": CoreLayerType.LAYER_TYPES_COUNT, | ||
| "undefined_layer_type": CoreLayerType.UNDEFINED_LAYER_TYPE, | ||
| } | ||
@@ -261,3 +261,3 @@ | ||
| try: | ||
| name = self.core.get_product_property(GrpcProductIdType.DESIGNER, 1) | ||
| name = self.core.get_product_property(CoreProductIdType.DESIGNER, 1) | ||
| name = name.strip("'") | ||
@@ -283,3 +283,3 @@ except: | ||
| def aedt_name(self, value): | ||
| self.core.set_product_property(GrpcProductIdType.DESIGNER, 1, value) | ||
| self.core.set_product_property(CoreProductIdType.DESIGNER, 1, value) | ||
@@ -444,3 +444,3 @@ def get_connected_objects(self): | ||
| if isinstance(point, (list, tuple)): | ||
| point = GrpcPointData(point) | ||
| point = CorePointData(point) | ||
@@ -546,3 +546,3 @@ p0 = self.core.cast().polygon_data.closest_point(point) | ||
| elif isinstance(center, list) and len(center) == 2: | ||
| center = GrpcPointData([Value(center[0]), Value(center[1])]) | ||
| center = CorePointData([Value(center[0]), Value(center[1])]) | ||
| else: | ||
@@ -627,3 +627,3 @@ self._pedb.logger.error(f"Failed to evaluate center on primitive {self.id}") | ||
| else: | ||
| if isinstance(prim, GrpcCircle): | ||
| if isinstance(prim, CoreCircle): | ||
| primi_polys.append(prim.polygon_data) | ||
@@ -742,3 +742,3 @@ else: | ||
| if isinstance(point, GrpcPointData): | ||
| if isinstance(point, CorePointData): | ||
| point = [Value(point.x), Value(point.y)] | ||
@@ -946,3 +946,3 @@ dist = 1e12 | ||
| elif isinstance(center, list) and len(center) == 2: | ||
| center = GrpcPointData(center) | ||
| center = CorePointData(center) | ||
| polygon_data.scale(factor, center) | ||
@@ -949,0 +949,0 @@ self.core.cast().polygon_data = polygon_data |
@@ -27,4 +27,4 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.primitive.rectangle import ( | ||
| Rectangle as GrpcRectangle, | ||
| RectangleRepresentationType as GrpcRectangleRepresentationType, | ||
| Rectangle as CoreRectangle, | ||
| RectangleRepresentationType as CoreRectangleRepresentationType, | ||
| ) | ||
@@ -46,4 +46,4 @@ | ||
| self._mapping_representation_type = { | ||
| "center_width_height": GrpcRectangleRepresentationType.CENTER_WIDTH_HEIGHT, | ||
| "lower_left_upper_right": GrpcRectangleRepresentationType.LOWER_LEFT_UPPER_RIGHT, | ||
| "center_width_height": CoreRectangleRepresentationType.CENTER_WIDTH_HEIGHT, | ||
| "lower_left_upper_right": CoreRectangleRepresentationType.LOWER_LEFT_UPPER_RIGHT, | ||
| } | ||
@@ -65,3 +65,3 @@ | ||
| if not value in self._mapping_representation_type: | ||
| self.core.representation_type = GrpcRectangleRepresentationType.INVALID_RECT_TYPE | ||
| self.core.representation_type = CoreRectangleRepresentationType.INVALID_RECT_TYPE | ||
| else: | ||
@@ -141,7 +141,7 @@ self.core.representation_type = self._mapping_representation_type[value] | ||
| rep_type_mapping = { | ||
| "center_width_height": GrpcRectangleRepresentationType.CENTER_WIDTH_HEIGHT, | ||
| "lower_left_upper_right": GrpcRectangleRepresentationType.LOWER_LEFT_UPPER_RIGHT, | ||
| "center_width_height": CoreRectangleRepresentationType.CENTER_WIDTH_HEIGHT, | ||
| "lower_left_upper_right": CoreRectangleRepresentationType.LOWER_LEFT_UPPER_RIGHT, | ||
| } | ||
| rep_type = rep_type_mapping.get(rep_type, GrpcRectangleRepresentationType.INVALID_RECT_TYPE) | ||
| edb_object = GrpcRectangle.create( | ||
| rep_type = rep_type_mapping.get(rep_type, CoreRectangleRepresentationType.INVALID_RECT_TYPE) | ||
| edb_object = CoreRectangle.create( | ||
| layout=layout.core, | ||
@@ -148,0 +148,0 @@ layer=layer, |
@@ -23,12 +23,89 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from typing import TYPE_CHECKING | ||
| from ansys.edb.core.simulation_setup.adaptive_solutions import ( | ||
| AdaptiveFrequency as GrpcAdaptiveFrequency, | ||
| ) | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.adaptive_solutions import ( | ||
| AdaptiveFrequency as CoreAdaptiveFrequency, | ||
| ) | ||
| from ansys.edb.core.utility.value import Value as CoreValue | ||
| class AdaptiveFrequency(GrpcAdaptiveFrequency): | ||
| """EDB-core Adaptive Frequency class.""" | ||
| class AdaptiveFrequency: | ||
| """PyEDB Adaptive Frequency class.""" | ||
| def __init__(self, adaptive_frequency): | ||
| super().__init__(adaptive_frequency) | ||
| def __init__(self, core: "CoreAdaptiveFrequency"): | ||
| self.core = core | ||
| @property | ||
| def adaptive_frequency(self) -> float: | ||
| """Get the adaptive frequency value. | ||
| Returns | ||
| ------- | ||
| float | ||
| Adaptive frequency value. | ||
| """ | ||
| return CoreValue(self.core.adaptive_frequency).value | ||
| @adaptive_frequency.setter | ||
| def adaptive_frequency(self, value: float): | ||
| """Set the adaptive frequency value. | ||
| Parameters | ||
| ---------- | ||
| value : float | ||
| Adaptive frequency value. | ||
| """ | ||
| self.core.adaptive_frequency = str(CoreValue(value)) | ||
| @property | ||
| def max_delta(self): | ||
| """Get the maximum delta value. | ||
| Returns | ||
| ------- | ||
| float | ||
| Maximum delta value. | ||
| """ | ||
| return float(self.core.max_delta) | ||
| @max_delta.setter | ||
| def max_delta(self, value: float): | ||
| """Set the maximum delta value. | ||
| Parameters | ||
| ---------- | ||
| value : float | ||
| Maximum delta value. | ||
| """ | ||
| self.core.max_delta = str(value) | ||
| @property | ||
| def output_variables(self) -> dict[str, str]: | ||
| """Map of output variable names to maximum delta S.""" | ||
| return self.core.output_variables | ||
| def add_output_variable(self, variable_name: str, max_delta_s: float): | ||
| """Add an output variable with its maximum delta S. | ||
| Parameters | ||
| ---------- | ||
| variable_name : str | ||
| Name of the output variable. | ||
| max_delta_s : float | ||
| Maximum delta S for the output variable. | ||
| """ | ||
| output_dict = self.output_variables | ||
| output_dict[variable_name] = str(max_delta_s) | ||
| self.output_variables = output_dict | ||
| @output_variables.setter | ||
| def output_variables(self, value: dict[str, str]): | ||
| """Set the output variables map. | ||
| Parameters | ||
| ---------- | ||
| value : dict[str, str] | ||
| Map of output variable names to maximum delta S. | ||
| """ | ||
| self.core.output_variables = value |
@@ -23,11 +23,124 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.simulation_setup.hfss_simulation_settings import ( | ||
| HFSSAdvancedMeshingSettings as GrpcHFSSAdvancedMeshingSettings, | ||
| ) | ||
| from typing import TYPE_CHECKING | ||
| import warnings | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.hfss_simulation_settings import ( | ||
| HFSSAdvancedMeshingSettings as CoreHFSSAdvancedMeshingSettings, | ||
| ) | ||
| class HFSSAdvancedMeshingSettings(GrpcHFSSAdvancedMeshingSettings): | ||
| def __init__(self, pedb, core): | ||
| """EDB-core HFSS advanced meshing settings class.""" | ||
| super().__init__(core) | ||
| class HFSSAdvancedMeshingSettings: | ||
| def __init__(self, pedb, core: "CoreHFSSAdvancedMeshingSettings"): | ||
| """PyEDB HFSS advanced meshing settings class.""" | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def arc_step_size(self) -> str: | ||
| """Get or set the arc step size. | ||
| Returns | ||
| ------- | ||
| float | ||
| Arc step size. | ||
| """ | ||
| return self.core.arc_step_size | ||
| @arc_step_size.setter | ||
| def arc_step_size(self, value: str): | ||
| self.core.arc_step_size = value | ||
| @property | ||
| def arc_to_chord_error(self) -> str: | ||
| """Get or set the arc to chord error. | ||
| Returns | ||
| ------- | ||
| float | ||
| Arc to chord error. | ||
| """ | ||
| return self.core.arc_to_chord_error | ||
| @arc_to_chord_error.setter | ||
| def arc_to_chord_error(self, value: str): | ||
| self.core.arc_to_chord_error = value | ||
| @property | ||
| def circle_start_azimuth(self) -> str: | ||
| """Get or set the circle start azimuth. | ||
| Returns | ||
| ------- | ||
| float | ||
| Circle start azimuth. | ||
| """ | ||
| return self.core.circle_start_azimuth | ||
| @circle_start_azimuth.setter | ||
| def circle_start_azimuth(self, value: str): | ||
| self.core.circle_start_azimuth = value | ||
| @property | ||
| def layer_snap_tol(self) -> str: | ||
| """Get or set the layer snap tolerance. | ||
| Returns | ||
| ------- | ||
| str | ||
| Layer snap tolerance. | ||
| """ | ||
| return self.core.layer_snap_tol | ||
| @layer_snap_tol.setter | ||
| def layer_snap_tol(self, value: str): | ||
| self.core.layer_snap_tol = str(value) | ||
| @property | ||
| def max_arc_points(self) -> int: | ||
| """Get or set the maximum number of arc points. | ||
| .. deprecated:: 0.77.3 | ||
| Use :attr:`max_num_arc_points` instead. | ||
| """ | ||
| warnings.warn( | ||
| "The 'max_arc_points' property is deprecated and will be removed in future releases.", DeprecationWarning | ||
| ) | ||
| return self.max_num_arc_points | ||
| @max_arc_points.setter | ||
| def max_arc_points(self, value: int): | ||
| warnings.warn( | ||
| "The 'max_arc_points' property is deprecated and will be removed in future releases.", DeprecationWarning | ||
| ) | ||
| self.max_num_arc_points = value | ||
| @property | ||
| def max_num_arc_points(self) -> int: | ||
| """Get or set the maximum number of arc points. | ||
| Returns | ||
| ------- | ||
| int | ||
| Maximum number of arc points. | ||
| """ | ||
| return self.core.max_num_arc_points | ||
| @max_num_arc_points.setter | ||
| def max_num_arc_points(self, value: int): | ||
| self.core.max_num_arc_points = value | ||
| @property | ||
| def use_arc_chord_error_approx(self) -> bool: | ||
| """Get or set whether to use arc chord error approximation. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if using arc chord error approximation, False otherwise. | ||
| """ | ||
| return self.core.use_arc_chord_error_approx | ||
| @use_arc_chord_error_approx.setter | ||
| def use_arc_chord_error_approx(self, value: bool): | ||
| self.core.use_arc_chord_error_approx = value |
@@ -23,26 +23,353 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from typing import TYPE_CHECKING | ||
| import warnings | ||
| from ansys.edb.core.simulation_setup.hfss_simulation_settings import ( | ||
| HFSSAdvancedSettings as GrpcHFSSAdvancedSettings, | ||
| ) | ||
| from ansys.edb.core.simulation_setup.simulation_settings import ViaStyle as GrpcViaStyle | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.hfss_simulation_settings import ( | ||
| HFSSAdvancedSettings as CoreHFSSAdvancedSettings, | ||
| ) | ||
| from ansys.edb.core.simulation_setup.simulation_settings import ViaStyle as CoreViaStyle | ||
| class HFSSAdvancedSettings(GrpcHFSSAdvancedSettings): | ||
| def __init__(self, pedb, core): | ||
| super().__init__(core) | ||
| class HFSSAdvancedSettings: | ||
| def __init__(self, pedb, core: "CoreHFSSAdvancedSettings"): | ||
| """PyEDB HFSS advanced settings class.""" | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def via_model_type(self) -> str: | ||
| """Via model. | ||
| def defeature_abs_length(self) -> float: | ||
| """Absolute length used as tolerance when defeaturing polygons. | ||
| .. deprecated:: 0.77.3 | ||
| Use :attr:`defeature_absolute_length` instead. | ||
| """ | ||
| warnings.warn( | ||
| "The 'defeature_abs_length' property is deprecated. Please use 'defeature_absolute_length' instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| return self.defeature_absolute_length | ||
| @defeature_abs_length.setter | ||
| def defeature_abs_length(self, value): | ||
| warnings.warn( | ||
| "The 'defeature_abs_length' property is deprecated. Please use 'defeature_absolute_length' instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| self.defeature_absolute_length = value | ||
| @property | ||
| def defeature_absolute_length(self) -> str: | ||
| """Absolute length used as tolerance when defeaturing polygons. | ||
| Returns | ||
| ------- | ||
| str | ||
| Length value. | ||
| """ | ||
| return self.core.defeature_absolute_length | ||
| @defeature_absolute_length.setter | ||
| def defeature_absolute_length(self, value): | ||
| self.core.defeature_absolute_length = str(value) | ||
| @property | ||
| def defeature_ratio(self) -> float: | ||
| """Extent ratio used as tolerance when defeaturing polygons. | ||
| Returns | ||
| ------- | ||
| float | ||
| Ratio value. | ||
| """ | ||
| return self.core.defeature_ratio | ||
| @defeature_ratio.setter | ||
| def defeature_ratio(self, value: float): | ||
| self.core.defeature_ratio = value | ||
| @property | ||
| def healing_option(self) -> int: | ||
| """Enable/disable healing of mis-aligned points and edges. | ||
| Returns | ||
| ------- | ||
| int | ||
| Healing option value. | ||
| """ | ||
| return self.core.healing_option | ||
| @healing_option.setter | ||
| def healing_option(self, value: int): | ||
| self.core.healing_option = value | ||
| @property | ||
| def ic_mode_auto_resolution(self) -> bool: | ||
| """Flag indicating if model resolution is automatically calculated for IC designs.. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if IC mode auto resolution is enabled, False otherwise. | ||
| """ | ||
| return self.core.ic_mode_auto_resolution | ||
| @ic_mode_auto_resolution.setter | ||
| def ic_mode_auto_resolution(self, value: bool): | ||
| self.core.ic_mode_auto_resolution = value | ||
| @property | ||
| def mesh_for_via_plating(self) -> bool: | ||
| """Flag indicating if meshing for via plating is enabled. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if meshing for via plating is enabled, False otherwise. | ||
| """ | ||
| return self.core.mesh_for_via_plating | ||
| @mesh_for_via_plating.setter | ||
| def mesh_for_via_plating(self, value: bool): | ||
| self.core.mesh_for_via_plating = value | ||
| @property | ||
| def model_type(self) -> str: | ||
| """HFSS model type. | ||
| Returns | ||
| ------- | ||
| str | ||
| Model type name. | ||
| """ | ||
| return self.via_model_type.name | ||
| if self.core.model_type.value == 0: | ||
| return "general" | ||
| else: | ||
| return "ic" | ||
| @property | ||
| def via_density(self) -> float: | ||
| """Density of vias. | ||
| .. deprecated:: 0.77.3 | ||
| Use :attr:`num_via_density` instead. | ||
| """ | ||
| return self.num_via_density | ||
| @via_density.setter | ||
| def via_density(self, value: float): | ||
| warnings.warn( | ||
| "The 'via_density' property is deprecated. Please use 'num_via_density' instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| self.num_via_density = value | ||
| @property | ||
| def num_via_density(self) -> float: | ||
| """Spacing between vias. | ||
| Returns | ||
| ------- | ||
| int | ||
| Spacing value. | ||
| """ | ||
| return self.core.num_via_density | ||
| @num_via_density.setter | ||
| def num_via_density(self, value: float): | ||
| self.core.num_via_density = value | ||
| @property | ||
| def via_num_sides(self) -> int: | ||
| """Number of sides a via is considered to have. | ||
| .. deprecated:: 0.77.3 | ||
| Use :attr:`num_via_sides` instead. | ||
| """ | ||
| return self.num_via_sides | ||
| @via_num_sides.setter | ||
| def via_num_sides(self, value: int): | ||
| warnings.warn( | ||
| "The 'via_num_sides' property is deprecated. Please use 'num_via_sides' instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| self.num_via_sides = value | ||
| @property | ||
| def num_via_sides(self) -> int: | ||
| """Number of sides a via is considered to have. | ||
| Returns | ||
| ------- | ||
| int | ||
| Number of via sides value. | ||
| """ | ||
| return self.core.num_via_sides | ||
| @num_via_sides.setter | ||
| def num_via_sides(self, value: int): | ||
| self.core.num_via_sides = value | ||
| @property | ||
| def remove_floating_geometry(self) -> bool: | ||
| """Flag indicating if a geometry not connected to any other geometry is removed. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if floating geometry is removed, False otherwise. | ||
| """ | ||
| return self.core.remove_floating_geometry | ||
| @remove_floating_geometry.setter | ||
| def remove_floating_geometry(self, value: bool): | ||
| self.core.remove_floating_geometry = value | ||
| @property | ||
| def small_void_area(self) -> float: | ||
| """Voids with an area smaller than this value are ignored during simulation. | ||
| Returns | ||
| ------- | ||
| float | ||
| Small void area value. | ||
| """ | ||
| return self.core.small_void_area | ||
| @small_void_area.setter | ||
| def small_void_area(self, value: float): | ||
| self.core.small_void_area = value | ||
| @property | ||
| def union_polygons(self) -> bool: | ||
| """Flag indicating if polygons are unioned. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if polygons are unioned, False otherwise. | ||
| """ | ||
| return self.core.union_polygons | ||
| @union_polygons.setter | ||
| def union_polygons(self, value: bool): | ||
| self.core.union_polygons = value | ||
| @property | ||
| def use_defeature(self) -> bool: | ||
| """Flag indicating if defeaturing is used. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if defeaturing is used, False otherwise. | ||
| """ | ||
| return self.core.use_defeature | ||
| @use_defeature.setter | ||
| def use_defeature(self, value: bool): | ||
| self.core.use_defeature = value | ||
| @property | ||
| def use_defeature_abs_length(self) -> bool: | ||
| """Flag indicating if absolute length defeaturing is used. | ||
| .. deprecated:: 0.77.3 | ||
| Use :attr:`use_defeature_absolute_length` instead. | ||
| """ | ||
| warnings.warn( | ||
| "The 'use_defeature_abs_length' property is deprecated. " | ||
| "Please use 'use_defeature_absolute_length' instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| return self.use_defeature_absolute_length | ||
| @use_defeature_abs_length.setter | ||
| def use_defeature_abs_length(self, value: bool): | ||
| warnings.warn( | ||
| "The 'use_defeature_abs_length' property is deprecated. " | ||
| "Please use 'use_defeature_absolute_length' instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| self.use_defeature_absolute_length = value | ||
| @property | ||
| def use_defeature_absolute_length(self) -> bool: | ||
| """Flag indicating if absolute length or extent ratio is used when defeaturing polygons. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if absolute length defeaturing is used, False otherwise. | ||
| """ | ||
| return self.core.use_defeature_absolute_length | ||
| @use_defeature_absolute_length.setter | ||
| def use_defeature_absolute_length(self, value: bool): | ||
| self.core.use_defeature_absolute_length = value | ||
| @property | ||
| def via_material(self) -> str: | ||
| """Default via material. | ||
| Returns | ||
| ------- | ||
| str | ||
| Via material name. | ||
| """ | ||
| return self.core.via_material | ||
| @via_material.setter | ||
| def via_material(self, value: str): | ||
| self.core.via_material = value | ||
| @property | ||
| def via_style(self) -> str: | ||
| """Via style. | ||
| .. deprecated:: 0.77.3 | ||
| Use :attr:`via_model_type` instead. | ||
| """ | ||
| return self.via_model_type | ||
| @via_style.setter | ||
| def via_style(self, value): | ||
| warnings.warn( | ||
| "The 'via_style' property is deprecated. Please use 'via_model_type' instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| self.via_model_type = value | ||
| @property | ||
| def via_model_type(self) -> str: | ||
| """Via model type. | ||
| Returns | ||
| ------- | ||
| str | ||
| Via model type name. | ||
| """ | ||
| return self.core.via_model_type.name.lower() | ||
| @via_model_type.setter | ||
@@ -52,10 +379,10 @@ def via_model_type(self, value): | ||
| if value.upper() == "WIREBOND": | ||
| self.via_model_type = GrpcViaStyle.WIREBOND | ||
| self.core.via_model_type = CoreViaStyle.WIREBOND | ||
| elif value.lower() == "RIBBON": | ||
| self.via_model_type = GrpcViaStyle.RIBBON | ||
| self.core.via_model_type = CoreViaStyle.RIBBON | ||
| elif value.lower() == "MESH": | ||
| self.via_model_type = GrpcViaStyle.MESH | ||
| self.core.via_model_type = CoreViaStyle.MESH | ||
| elif value.lower() == "FIELD": | ||
| self.via_model_type = GrpcViaStyle.FIELD | ||
| self.core.ia_model_type = CoreViaStyle.FIELD | ||
| elif value.lower() == "NUM_VIA_STYLE": | ||
| self.via_model_type = GrpcViaStyle.NUM_VIA_STYLE | ||
| self.core.via_model_type = CoreViaStyle.NUM_VIA_STYLE |
@@ -23,14 +23,185 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from typing import TYPE_CHECKING | ||
| import warnings | ||
| from ansys.edb.core.simulation_setup.hfss_simulation_settings import ( | ||
| HFSSDCRSettings as GrpcHFSSDCRSettings, | ||
| ) | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.hfss_simulation_settings import ( | ||
| HFSSDCRSettings as CoreHFSSDCRSettings, | ||
| ) | ||
| class HFSSDCRSettings(GrpcHFSSDCRSettings): | ||
| """PyEDB-core HFSS DC settings class.""" | ||
| class HFSSDCRSettings: | ||
| """PyEDB HFSS DC settings class.""" | ||
| def __init__(self, pedb, core): | ||
| super().__init__(core) | ||
| self._core = core | ||
| def __init__(self, pedb, core: "CoreHFSSDCRSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def conduction_max_passes(self) -> int: | ||
| """Maximum number of conduction adaptive passes. | ||
| ... deprecated:: 0.77.3 | ||
| Use :attr:`max_passes <pyedb.grpc.database.simulation_setup.hfss_dcr_settings.HFSSDCRSettings.max_passes>` | ||
| nstead. | ||
| """ | ||
| warnings.warn("`conduction_max_passes` is deprecated. Use `max_passes` instead.", DeprecationWarning) | ||
| return self.max_passes | ||
| @conduction_max_passes.setter | ||
| def conduction_max_passes(self, value: int): | ||
| """Set maximum number of conduction adaptive passes. | ||
| ... deprecated:: 0.77.3 | ||
| Use :attr:`max_passes <pyedb.grpc.database.simulation_setup.hfss_dcr_settings.HFSSDCRSettings.max_passes>` | ||
| instead. | ||
| """ | ||
| warnings.warn("`conduction_max_passes` is deprecated. Use `max_passes` instead.", DeprecationWarning) | ||
| self.max_passes = value | ||
| @property | ||
| def max_passes(self) -> int: | ||
| """Maximum number of conduction adaptive passes.""" | ||
| return self.core.max_passes | ||
| @max_passes.setter | ||
| def max_passes(self, value: int): | ||
| """Set maximum number of conduction adaptive passes.""" | ||
| self.core.max_passes = value | ||
| @property | ||
| def conduction_min_converged_passes(self) -> int: | ||
| """Minimum number of converged conduction adaptive passes. | ||
| ... deprecated:: 0.77.3 | ||
| Use :attr:`min_converged_passes | ||
| <pyedb.grpc.database.simulation_setup.hfss_dcr_settings.HFSSDCRSettings.min_converged_passes>` | ||
| instead. | ||
| """ | ||
| warnings.warn( | ||
| "`conduction_min_converged_passes` is deprecated. Use `min_converged_passes` instead.", DeprecationWarning | ||
| ) | ||
| return self.min_converged_passes | ||
| @conduction_min_converged_passes.setter | ||
| def conduction_min_converged_passes(self, value: int): | ||
| """Set minimum number of converged conduction adaptive passes. | ||
| ... deprecated:: 0.77.3 | ||
| Use :attr:`min_converged_passes | ||
| <pyedb.grpc.database.simulation_setup.hfss_dcr_settings.HFSSDCRSettings.min_converged_passes>` | ||
| instead. | ||
| """ | ||
| warnings.warn( | ||
| "`conduction_min_converged_passes` is deprecated. Use `min_converged_passes` instead.", DeprecationWarning | ||
| ) | ||
| self.min_converged_passes = value | ||
| @property | ||
| def min_converged_passes(self) -> int: | ||
| """Minimum number of converged conduction adaptive passes.""" | ||
| return self.core.min_converged_passes | ||
| @min_converged_passes.setter | ||
| def min_converged_passes(self, value: int): | ||
| """Set minimum number of converged conduction adaptive passes.""" | ||
| self.core.min_converged_passes = value | ||
| @property | ||
| def conduction_min_passes(self) -> int: | ||
| """Minimum number of conduction adaptive passes. | ||
| ... deprecated:: 0.77.3 | ||
| Use :attr:`min_passes <pyedb.grpc.database.simulation_setup.hfss_dcr_settings.HFSSDCRSettings.min_passes>` | ||
| instead. | ||
| """ | ||
| warnings.warn("`conduction_min_passes` is deprecated. Use `min_passes` instead.", DeprecationWarning) | ||
| return self.min_passes | ||
| @conduction_min_passes.setter | ||
| def conduction_min_passes(self, value: int): | ||
| """Set minimum number of conduction adaptive passes. | ||
| ... deprecated:: 0.77.3 | ||
| Use :attr:`min_passes | ||
| <pyedb.grpc.database.simulation_setup.hfss_dcr_settings.HFSSDCRSettings.min_passes>` | ||
| instead. | ||
| """ | ||
| warnings.warn("`conduction_min_passes` is deprecated. Use `min_passes` instead.", DeprecationWarning) | ||
| self.min_passes = value | ||
| @property | ||
| def min_passes(self) -> int: | ||
| """Minimum number of conduction adaptive passes.""" | ||
| return self.core.min_passes | ||
| @min_passes.setter | ||
| def min_passes(self, value: int): | ||
| """Set minimum number of conduction adaptive passes.""" | ||
| self.core.min_passes = value | ||
| @property | ||
| def conduction_per_error(self) -> float: | ||
| """Conduction adaptive percent error. | ||
| ... deprecated:: 0.77.3 | ||
| Use :attr:`percent_error <pyedb.grpc.database.simulation_setup.hfss_dcr_settings.HFSSDCRSettings.percent_error>` | ||
| instead. | ||
| """ | ||
| warnings.warn("`conduction_percent_error` is deprecated. Use `percent_error` instead.", DeprecationWarning) | ||
| return self.percent_error | ||
| @conduction_per_error.setter | ||
| def conduction_per_error(self, value: float): | ||
| """Set conduction adaptive percent error. | ||
| ... deprecated:: 0.77.3 | ||
| Use :attr:`percent_error <pyedb.grpc.database.simulation_setup.hfss_dcr_settings.HFSSDCRSettings.percent_error>` | ||
| instead. | ||
| """ | ||
| warnings.warn("`conduction_percent_error` is deprecated. Use `percent_error` instead.", DeprecationWarning) | ||
| self.percent_error = value | ||
| @property | ||
| def percent_error(self) -> float: | ||
| """Conduction adaptive percent error.""" | ||
| return self.core.percent_error | ||
| @percent_error.setter | ||
| def percent_error(self, value: float): | ||
| """Set conduction adaptive percent error.""" | ||
| self.core.percent_error = value | ||
| @property | ||
| def conduction_per_refine(self) -> float: | ||
| """Conduction adaptive percent refinement per pass. | ||
| ... deprecated:: 0.77.3 | ||
| Use :attr: | ||
| `percent_refinement_per_pass | ||
| <pyedb.grpc.database.simulation_setup.hfss_dcr_settings.HFSSDCRSettings.percent_refinement_per_pass>` | ||
| instead. | ||
| """ | ||
| return self.percent_refinement_per_pass | ||
| @conduction_per_refine.setter | ||
| def conduction_per_refine(self, value: float): | ||
| """Set conduction adaptive percent refinement per pass. | ||
| ... deprecated:: 0.77.3 | ||
| Use :attr: | ||
| `percent_refinement_per_pass | ||
| <pyedb.grpc.database.simulation_setup.hfss_dcr_settings.HFSSDCRSettings.percent_refinement_per_pass>` | ||
| instead. | ||
| """ | ||
| self.percent_refinement_per_pass = value | ||
| @property | ||
| def percent_refinement_per_pass(self) -> float: | ||
| """Conduction adaptive percent refinement per pass.""" | ||
| return self.core.percent_refinement_per_pass | ||
| @percent_refinement_per_pass.setter | ||
| def percent_refinement_per_pass(self, value: float): | ||
| """Set conduction adaptive percent refinement per pass.""" | ||
| self.core.percent_refinement_per_pass = value |
@@ -23,17 +23,526 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from typing import TYPE_CHECKING | ||
| import warnings | ||
| from ansys.edb.core.simulation_setup.hfss_simulation_settings import ( | ||
| AdaptType as GrpcAdaptType, | ||
| HFSSGeneralSettings as GrpcHFSSGeneralSettings, | ||
| ) | ||
| from ansys.edb.core.simulation_setup.hfss_simulation_settings import AdaptType as CoreAdaptType | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.hfss_simulation_settings import ( | ||
| HFSSGeneralSettings as CoreHFSSGeneralSettings, | ||
| ) | ||
| class HFSSGeneralSettings(GrpcHFSSGeneralSettings): | ||
| """PyEDB-core HFSS general settings class.""" | ||
| class BroadbandAdaptiveSolution: | ||
| def __init__(self, pedb, core): | ||
| super().__init__(core) | ||
| self._pedb = pedb | ||
| self.core = core | ||
| @property | ||
| def high_frequency(self) -> str: | ||
| """High frequency for broadband adaptive solution. | ||
| Returns | ||
| ------- | ||
| float | ||
| High frequency value in Hz. | ||
| """ | ||
| return self.core.high_frequency | ||
| @high_frequency.setter | ||
| def high_frequency(self, value): | ||
| self.core.high_frequency = str(value) | ||
| @property | ||
| def low_frequency(self) -> str: | ||
| """Low frequency for broadband adaptive solution. | ||
| Returns | ||
| ------- | ||
| float | ||
| Low frequency value in Hz. | ||
| """ | ||
| return self.core.low_frequency | ||
| @low_frequency.setter | ||
| def low_frequency(self, value): | ||
| self.core.low_frequency = str(value) | ||
| @property | ||
| def max_delta(self) -> str: | ||
| """Maximum delta for broadband adaptive solution. | ||
| Returns | ||
| ------- | ||
| float | ||
| Maximum delta value. | ||
| """ | ||
| return self.core.max_delta | ||
| @max_delta.setter | ||
| def max_delta(self, value): | ||
| self.core.max_delta = str(value) | ||
| @property | ||
| def max_num_passes(self) -> int: | ||
| """Maximum number of passes for broadband adaptive solution. | ||
| Returns | ||
| ------- | ||
| int | ||
| Maximum number of passes. | ||
| """ | ||
| return self.core.max_num_passes | ||
| @max_num_passes.setter | ||
| def max_num_passes(self, value): | ||
| self.core.max_num_passes = value | ||
| class AdaptiveFrequency: | ||
| def __init__(self, pedb, core): | ||
| """Represents an adaptive frequency.""" | ||
| self._pedb = pedb | ||
| self.core = core | ||
| @property | ||
| def adaptive_frequency(self) -> str: | ||
| """Adaptive frequency value. | ||
| Returns | ||
| ------- | ||
| float | ||
| Adaptive frequency in Hz. | ||
| """ | ||
| return self.core.adaptive_frequency | ||
| @adaptive_frequency.setter | ||
| def adaptive_frequency(self, value): | ||
| self.core.adaptive_frequency = str(value) | ||
| @property | ||
| def max_delta(self) -> str: | ||
| """Maximum delta for the adaptive frequency. | ||
| Returns | ||
| ------- | ||
| float | ||
| Maximum delta value. | ||
| """ | ||
| return self.core.max_delta | ||
| @max_delta.setter | ||
| def max_delta(self, value): | ||
| self.core.max_delta = str(value) | ||
| @property | ||
| def output_variables(self) -> dict[str, float]: | ||
| """Map of output variable names to maximum delta S. | ||
| Returns | ||
| ------- | ||
| dict[str, float] | ||
| Dictionary of output variable names and delta S value. | ||
| """ | ||
| return {var_name: self._pedb.value(value) for var_name, value in self.core.output_variables.items()} | ||
| def add_output_variable(self, name: str, delta_s: float): | ||
| """Add an output variable for the adaptive frequency. | ||
| Parameters | ||
| ---------- | ||
| name : str | ||
| Name of the output variable. | ||
| delta_s : float | ||
| Delta S value. | ||
| """ | ||
| variables = self.output_variables | ||
| variables[name] = delta_s | ||
| self.core.output_variables = variables | ||
| def delete_output_variable(self, name: str) -> bool: | ||
| """Delete an output variable from the adaptive frequency. | ||
| Parameters | ||
| ---------- | ||
| name : str | ||
| Name of the output variable to delete. | ||
| Returns | ||
| ------- | ||
| bool | ||
| """ | ||
| variables = self.output_variables | ||
| if name in variables: | ||
| del variables[name] | ||
| self.core.output_variables = variables | ||
| return True # | ||
| else: | ||
| self._pedb.logger.warning(f"Output variable '{name}' not found.") | ||
| return False | ||
| class MultiFrequencyAdaptiveSolution: | ||
| def __init__(self, pedb, core): | ||
| self._pedb = pedb | ||
| self.core = core | ||
| @property | ||
| def adaptive_frequencies(self) -> list[AdaptiveFrequency]: | ||
| return [AdaptiveFrequency(self._pedb, freq) for freq in self.core.adaptive_frequencies] | ||
| @property | ||
| def max_passes(self) -> int: | ||
| """Maximum number of passes for multi-frequency adaptive solution. | ||
| Returns | ||
| ------- | ||
| int | ||
| Maximum number of passes. | ||
| """ | ||
| return self.core.max_passes | ||
| @max_passes.setter | ||
| def max_passes(self, value): | ||
| self.core.max_passes = value | ||
| class MatrixConvergenceDataEntry: | ||
| def __init__(self, pedb, core): | ||
| self._pedb = pedb | ||
| self.core = core | ||
| @property | ||
| def mag_limit(self) -> float: | ||
| """Magnitude limit for the matrix convergence data entry. | ||
| Returns | ||
| ------- | ||
| float | ||
| Magnitude limit value. | ||
| """ | ||
| return self._pedb.value(self.core.mag_limit) | ||
| @mag_limit.setter | ||
| def mag_limit(self, value): | ||
| self.core.mag_limit = self._pedb.value(value) | ||
| @property | ||
| def phase_limit(self) -> float: | ||
| """Phase limit for the matrix convergence data entry. | ||
| Returns | ||
| ------- | ||
| float | ||
| Phase limit value. | ||
| """ | ||
| return self._pedb.value(self.core.phase_limit) | ||
| @phase_limit.setter | ||
| def phase_limit(self, value): | ||
| self.core.phase_limit = self._pedb.value(value) | ||
| @property | ||
| def port_1_name(self) -> str: | ||
| """Name of the first port. | ||
| Returns | ||
| ------- | ||
| str | ||
| First port name. | ||
| """ | ||
| return self.core.port_1_name | ||
| @port_1_name.setter | ||
| def port_1_name(self, value): | ||
| self.core.port_1_name = value | ||
| @property | ||
| def port_2_name(self) -> str: | ||
| """Name of the second port. | ||
| Returns | ||
| ------- | ||
| str | ||
| Second port name. | ||
| """ | ||
| return self.core.port_2_name | ||
| @port_2_name.setter | ||
| def port_2_name(self, value): | ||
| self.core.port_2_name = value | ||
| class MatrixConvergenceData: | ||
| def __init__(self, pedb, core): | ||
| self._pedb = pedb | ||
| self.core = core | ||
| @property | ||
| def all_constant(self) -> bool: | ||
| """Indicates whether all matrix convergence data entries are constant. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if all entries are constant, False otherwise. | ||
| """ | ||
| return self.core.all_constant | ||
| @all_constant.setter | ||
| def all_constant(self, value: bool): | ||
| self.core.all_constant = value | ||
| @property | ||
| def all_diag_constant(self) -> bool: | ||
| """Indicates whether all diagonal matrix convergence data entries are constant. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if all diagonal entries are constant, False otherwise. | ||
| """ | ||
| return self.core.all_diag_constant | ||
| @all_diag_constant.setter | ||
| def all_diag_constant(self, value: bool): | ||
| self.core.all_diag_constant = value | ||
| @property | ||
| def all_off_diag_constant(self) -> bool: | ||
| """Indicates whether all off-diagonal matrix convergence data entries are constant. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if all off-diagonal entries are constant, False otherwise. | ||
| """ | ||
| return self.core.all_off_diag_constant | ||
| @all_off_diag_constant.setter | ||
| def all_off_diag_constant(self, value: bool): | ||
| self.core.all_off_diag_constant = value | ||
| @property | ||
| def entry_list(self) -> list[MatrixConvergenceDataEntry]: | ||
| """List of matrix convergence data entries. | ||
| Returns | ||
| ------- | ||
| list[MatrixConvergenceDataEntry] | ||
| List of matrix convergence data entries. | ||
| """ | ||
| return [MatrixConvergenceDataEntry(self._pedb, entry) for entry in self.core.entry_list] | ||
| @property | ||
| def mag_min_threshold(self) -> float: | ||
| """Magnitude minimum threshold for matrix convergence data. | ||
| Returns | ||
| ------- | ||
| float | ||
| Magnitude minimum threshold value. | ||
| """ | ||
| return self._pedb.value(self.core.mag_min_threshold) | ||
| @mag_min_threshold.setter | ||
| def mag_min_threshold(self, value): | ||
| self.core.mag_min_threshold = self._pedb.value(value) | ||
| def add_entry(self, port_name_1, port_name_2, mag_limit, phase_limit): | ||
| """Add a matrix convergence data entry. | ||
| Parameters | ||
| ---------- | ||
| port_name_1 : str | ||
| Name of the first port. | ||
| port_name_2 : str | ||
| Name of the second port. | ||
| mag_limit : float | ||
| Magnitude limit. | ||
| phase_limit : float | ||
| Phase limit. | ||
| """ | ||
| self.core.add_entry(port_name_1, port_name_2, mag_limit, phase_limit) | ||
| def set_all_constant(self, mag_limit, phase_limit, port_names): | ||
| """Set all matrix convergence data entries to constant values. | ||
| Parameters | ||
| ---------- | ||
| mag_limit : float | ||
| Magnitude limit. | ||
| phase_limit : float | ||
| Phase limit. | ||
| port_names : list[str] | ||
| List of port names. | ||
| """ | ||
| self.core.set_all_constant(mag_limit, phase_limit, port_names) | ||
| def set_all_diag_constant(self, mag_limit, phase_limit, port_names, clear_entries): | ||
| """Set all diagonal matrix convergence data entries to constant values. | ||
| Parameters | ||
| ---------- | ||
| mag_limit : float | ||
| Magnitude limit. | ||
| phase_limit : float | ||
| Phase limit. | ||
| port_names : list[str] | ||
| List of port names. | ||
| clear_entries : bool | ||
| Whether to clear existing entries. | ||
| """ | ||
| self.core.set_all_diag_constant(mag_limit, phase_limit, port_names, clear_entries) | ||
| def set_all_off_diag_constant(self, mag_limit, phase_limit, port_names, clear_entries): | ||
| """Set all off-diagonal matrix convergence data entries to constant values. | ||
| Parameters | ||
| ---------- | ||
| mag_limit : float | ||
| Magnitude limit. | ||
| phase_limit : float | ||
| Phase limit. | ||
| port_names : list[str] | ||
| List of port names. | ||
| clear_entries : bool | ||
| Whether to clear existing entries. | ||
| """ | ||
| self.core.set_all_off_diag_constant(mag_limit, phase_limit, port_names, clear_entries) | ||
| class SingleFrequencyAdaptiveSolution: | ||
| def __init__(self, pedb, core): | ||
| self._pedb = pedb | ||
| self.core = core | ||
| @property | ||
| def adaptive_frequency(self) -> float: | ||
| """Adaptive frequency for single frequency adaptive solution. | ||
| Returns | ||
| ------- | ||
| float | ||
| Adaptive frequency in Hz. | ||
| """ | ||
| return self.core.adaptive_frequency | ||
| @adaptive_frequency.setter | ||
| def adaptive_frequency(self, value): | ||
| self.core.adaptive_frequency = str(self._pedb.value(value)) | ||
| @property | ||
| def max_delta(self) -> float: | ||
| """Maximum delta for single frequency adaptive solution. | ||
| Returns | ||
| ------- | ||
| float | ||
| Maximum delta value. | ||
| """ | ||
| return self.core.max_delta | ||
| @max_delta.setter | ||
| def max_delta(self, value): | ||
| self.core.max_delta = str(value) | ||
| @property | ||
| def max_passes(self) -> int: | ||
| """Maximum number of passes for single frequency adaptive solution. | ||
| Returns | ||
| ------- | ||
| int | ||
| Maximum number of passes. | ||
| """ | ||
| return self.core.max_passes | ||
| @max_passes.setter | ||
| def max_passes(self, value): | ||
| self.core.max_passes = value | ||
| @property | ||
| def mx_conv_data(self) -> MatrixConvergenceData: | ||
| """Matrix convergence data for single frequency adaptive solution. | ||
| Returns | ||
| ------- | ||
| :class:`MatrixConvergenceData | ||
| <pyedb.grpc.database.simulation_setup.hfss_general_settings.MatrixConvergenceData>` | ||
| Matrix convergence data object. | ||
| """ | ||
| return MatrixConvergenceData(self._pedb, self.core.mx_conv_data) | ||
| @property | ||
| def use_mx_conv_data(self) -> bool: | ||
| """Indicates whether to use matrix convergence data. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if matrix convergence data is used, False otherwise. | ||
| """ | ||
| return self.core.use_mx_conv_data | ||
| @use_mx_conv_data.setter | ||
| def use_mx_conv_data(self, value: bool): | ||
| self.core.use_mx_conv_data = value | ||
| class HFSSGeneralSettings: | ||
| """PyEDB-core HFSS general settings class.""" | ||
| def __init__(self, pedb, core: "CoreHFSSGeneralSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def adapt_type(self) -> str: | ||
| """Adaptation type. | ||
| ..deprecated:: 0.67.0 | ||
| This property is deprecated and will be removed in future versions. | ||
| Attribute added for dotnet compatibility. | ||
| Use :attr:`adaptive_solution_type` instead. | ||
| """ | ||
| warnings.warn( | ||
| "The 'adapt_type' property is deprecated and will be removed in future versions. " | ||
| "Use 'adaptive_solution_type' instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| # The underlying core.adaptive_solution_type may be an enum (with .name) | ||
| # or already a string. Handle both robustly. | ||
| val = self.core.adaptive_solution_type | ||
| # If core returns an enum-like object with .name, use it. | ||
| try: | ||
| return val.name.lower() | ||
| except Exception: | ||
| return str(val).lower() | ||
| @property | ||
| def adaptive_solution_type(self) -> str: | ||
@@ -45,6 +554,7 @@ """Adaptive solution type. | ||
| str | ||
| Adaptive solution type name. | ||
| Adaptive solution type name. Returned values are `single`, `multi_frequencies`, `broad_band`, | ||
| or `num_adapt_type`. | ||
| """ | ||
| return self.adaptive_solution_type.name | ||
| return self.core.adaptive_solution_type.name.lower() | ||
@@ -55,8 +565,194 @@ @adaptive_solution_type.setter | ||
| if value.lower() == "single": | ||
| self.adaptive_solution_type = GrpcAdaptType.SINGLE | ||
| self.core.adaptive_solution_type = CoreAdaptType.SINGLE | ||
| elif value.lower() == "multi_frequencies": | ||
| self.adaptive_solution_type = GrpcAdaptType.MULTI_FREQUENCIES | ||
| self.core.adaptive_solution_type = CoreAdaptType.MULTI_FREQUENCIES | ||
| elif value.lower() == "broad_band": | ||
| self.adaptive_solution_type = GrpcAdaptType.BROADBAND | ||
| self.core.adaptive_solution_type = CoreAdaptType.BROADBAND | ||
| elif value.lower() == "num_adapt_type": | ||
| self.adaptive_solution_type = GrpcAdaptType.NUM_ADAPT_TYPE | ||
| self.core.adaptive_solution_type = CoreAdaptType.NUM_ADAPT_TYPE | ||
| @property | ||
| def broadband_adaptive_solution(self) -> BroadbandAdaptiveSolution: | ||
| """Settings for a broadband adaptive solution. | ||
| Returns | ||
| ------- | ||
| :class:`HFSSBroadbandAdaptiveSolution | ||
| <pyedb.grpc.database.simulation_setup.hfss_simulation_settings.HFSSBroadbandAdaptiveSolution>` | ||
| Broadband adaptive solution settings object. | ||
| """ | ||
| return BroadbandAdaptiveSolution(self._pedb, self.core.broadband_adaptive_solution) | ||
| @property | ||
| def mesh_region_name(self) -> str: | ||
| """Name of the mesh region to use. | ||
| Returns | ||
| ------- | ||
| str | ||
| Mesh region name. | ||
| """ | ||
| return self.core.mesh_region_name | ||
| @mesh_region_name.setter | ||
| def mesh_region_name(self, value): | ||
| self.core.mesh_region_name = value | ||
| @property | ||
| def multi_frequency_adaptive_solution(self) -> MultiFrequencyAdaptiveSolution: | ||
| return MultiFrequencyAdaptiveSolution(self._pedb, self.core) | ||
| @property | ||
| def save_fields(self) -> bool: | ||
| """Indicates whether to save fields. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if fields are to be saved, False otherwise. | ||
| """ | ||
| return self.core.save_fields | ||
| @save_fields.setter | ||
| def save_fields(self, value: bool): | ||
| self.core.save_fields = value | ||
| @property | ||
| def save_rad_field_only(self) -> bool: | ||
| """Indicates whether to save radiation field only. | ||
| .. deprecated:: 0.67.0 | ||
| This property is deprecated and will be removed in future versions. | ||
| Use :attr:`save_rad_fields_only` instead. | ||
| """ | ||
| warnings.warn( | ||
| "The 'save_rad_field_only' property is deprecated and will be removed in future versions. " | ||
| "Use 'save_rad_fields_only' instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| return self.save_rad_fields_only | ||
| @save_rad_field_only.setter | ||
| def save_rad_field_only(self, value: bool): | ||
| warnings.warn( | ||
| "The 'save_rad_field_only' property is deprecated and will be removed in future versions. " | ||
| "Use 'save_rad_fields_only' instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| self.save_rad_fields_only = value | ||
| @property | ||
| def save_rad_fields_only(self) -> bool: | ||
| """Indicates whether to save radiation fields only. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if only radiation fields are to be saved, False otherwise. | ||
| """ | ||
| return self.core.save_rad_fields_only | ||
| @save_rad_fields_only.setter | ||
| def save_rad_fields_only(self, value: bool): | ||
| self.core.save_rad_fields_only = value | ||
| @property | ||
| def single_frequency_adaptive_solution(self): | ||
| return SingleFrequencyAdaptiveSolution(self._pedb, self.core.single_frequency_adaptive_solution) | ||
| @property | ||
| def use_mesh_region(self) -> bool: | ||
| """Indicates whether to use a mesh region. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if a mesh region is used, False otherwise. | ||
| """ | ||
| return self.core.use_mesh_region | ||
| @use_mesh_region.setter | ||
| def use_mesh_region(self, value: bool): | ||
| self.core.use_mesh_region = value | ||
| @property | ||
| def use_parallel_refinement(self) -> bool: | ||
| """Indicates whether to use parallel refinement. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if parallel refinement is used, False otherwise. | ||
| """ | ||
| return self.core.use_parallel_refinement | ||
| @use_parallel_refinement.setter | ||
| def use_parallel_refinement(self, value: bool): | ||
| self.core.use_parallel_refinement = value | ||
| @property | ||
| def max_refine_per_pass(self) -> float: | ||
| """Maximum refinement per pass. | ||
| .. deprecated:: 0.67.0 | ||
| This property is deprecated and will be removed in future versions. | ||
| use settings.options.max_refinement_per_pass instead. | ||
| """ | ||
| warnings.warn( | ||
| "Use of 'max_refine_per_pass' is deprecated and will be removed in future versions." | ||
| "Use 'settings.options.max_refinement_per_pass' instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| return self._pedb.settings.options.max_refinement_per_pass | ||
| @max_refine_per_pass.setter | ||
| def max_refine_per_pass(self, value: float): | ||
| self._pedb.settings.options.max_refinement_per_pass = value | ||
| @property | ||
| def min_passes(self) -> int: | ||
| """Minimum number of passes. | ||
| .. deprecated:: 0.67.0 | ||
| This property is deprecated and will be removed in future versions. | ||
| use settings.options.min_passes instead. | ||
| """ | ||
| warnings.warn( | ||
| "Use of 'min_passes' is deprecated and will be removed in future versions." | ||
| "Use 'settings.options.min_passes' instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| return self._pedb.settings.options.min_passes | ||
| @min_passes.setter | ||
| def min_passes(self, value: int): | ||
| self._pedb.settings.options.min_passes = value | ||
| @property | ||
| def use_max_refinement(self) -> bool: | ||
| """Indicates whether to use maximum refinement. | ||
| .. deprecated:: 0.67.0 | ||
| This property is deprecated and will be removed in future versions. | ||
| use settings.options.use_max_refinement instead. | ||
| """ | ||
| warnings.warn( | ||
| "Use of 'use_max_refinement' is deprecated and will be removed in future versions." | ||
| "Use 'settings.options.use_max_refinement' instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| return self._pedb.settings.options.use_max_refinement | ||
| @use_max_refinement.setter | ||
| def use_max_refinement(self, value: bool): | ||
| self._pedb.settings.options.use_max_refinement = value |
@@ -23,18 +23,136 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.hfss_simulation_settings import ( | ||
| BasisFunctionOrder as CoreBasisFunctionOrder, | ||
| HFSSSettingsOptions as CoreHFSSSettingsOptions, | ||
| SolverType as CoreSolverType, | ||
| ) | ||
| from ansys.edb.core.simulation_setup.hfss_simulation_settings import ( | ||
| BasisFunctionOrder as GrpcBasisFunctionOrder, | ||
| HFSSSettingsOptions as GrpcHFSSSettingsOptions, | ||
| SolverType as GrpcSolverType, | ||
| BasisFunctionOrder as CoreBasisFunctionOrder, | ||
| SolverType as CoreSolverType, | ||
| ) | ||
| class HFSSSettingsOptions(GrpcHFSSSettingsOptions): | ||
| class HFSSSettingsOptions: | ||
| """PyEDB-core HFSS settings options class.""" | ||
| def __init__(self, _pedb, core): | ||
| super().__init__(core) | ||
| def __init__(self, _pedb, core: "CoreHFSSSettingsOptions"): | ||
| self.core = core | ||
| self._pedb = _pedb | ||
| @property | ||
| def do_lambda_refine(self) -> bool: | ||
| """Flag to enable/disable lambda refinement. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if lambda refinement is enabled, False otherwise. | ||
| """ | ||
| return self.core.do_lambda_refine | ||
| @do_lambda_refine.setter | ||
| def do_lambda_refine(self, value: bool): | ||
| self.core.do_lambda_refine = value | ||
| @property | ||
| def enhanced_low_frequency_accuracy(self) -> bool: | ||
| """Flag to enable/disable enhanced low frequency accuracy. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if enhanced low frequency accuracy is enabled, False otherwise. | ||
| """ | ||
| return self.core.enhanced_low_frequency_accuracy | ||
| @enhanced_low_frequency_accuracy.setter | ||
| def enhanced_low_frequency_accuracy(self, value: bool): | ||
| self.core.enhanced_low_frequency_accuracy = value | ||
| @property | ||
| def lambda_target(self) -> float: | ||
| """Lambda target value. | ||
| Returns | ||
| ------- | ||
| float | ||
| Lambda target value. | ||
| """ | ||
| return self.core.lambda_target | ||
| @lambda_target.setter | ||
| def lambda_target(self, value: float): | ||
| self.core.lambda_target = value | ||
| @property | ||
| def max_refinement_per_pass(self) -> int: | ||
| """Maximum refinement per pass. | ||
| Returns | ||
| ------- | ||
| int | ||
| Maximum refinement per pass. | ||
| """ | ||
| return self.core.max_refinement_per_pass | ||
| @max_refinement_per_pass.setter | ||
| def max_refinement_per_pass(self, value: int): | ||
| self.core.max_refinement_per_pass = value | ||
| @property | ||
| def mesh_size_factor(self) -> float: | ||
| """Mesh size factor. | ||
| Returns | ||
| ------- | ||
| float | ||
| Mesh size factor. | ||
| """ | ||
| return self.core.mesh_size_factor | ||
| @mesh_size_factor.setter | ||
| def mesh_size_factor(self, value: float): | ||
| self.core.mesh_size_factor = value | ||
| @property | ||
| def min_converged_passes(self) -> int: | ||
| """Minimum converged passes. | ||
| Returns | ||
| ------- | ||
| int | ||
| Minimum converged passes. | ||
| """ | ||
| return self.core.min_converged_passes | ||
| @min_converged_passes.setter | ||
| def min_converged_passes(self, value: int): | ||
| self.core.min_converged_passes = value | ||
| @property | ||
| def min_passes(self) -> int: | ||
| """Minimum passes. | ||
| Returns | ||
| ------- | ||
| int | ||
| Minimum passes. | ||
| """ | ||
| return self.core.min_passes | ||
| @min_passes.setter | ||
| def min_passes(self, value: int): | ||
| self.core.min_passes = value | ||
| @property | ||
| def order_basis(self) -> str: | ||
@@ -49,28 +167,92 @@ """Order basis name. | ||
| """ | ||
| return self.order_basis.name | ||
| return self.core.order_basis.name.lower().split("_")[0] | ||
| @order_basis.setter | ||
| def order_basis(self, value): | ||
| if value == "ZERO_ORDER": | ||
| self.order_basis = GrpcBasisFunctionOrder.ZERO_ORDER | ||
| elif value == "FIRST_ORDER": | ||
| self.order_basis = GrpcBasisFunctionOrder.FIRST_ORDER | ||
| elif value == "SECOND_ORDER": | ||
| self.order_basis = GrpcBasisFunctionOrder.SECOND_ORDER | ||
| elif value == "MIXED_ORDER": | ||
| self.order_basis = GrpcBasisFunctionOrder.MIXED_ORDER | ||
| if value.upper() == "ZERO": | ||
| self.core.order_basis = CoreBasisFunctionOrder.ZERO_ORDER | ||
| elif value.upper() == "FIRST": | ||
| self.core.order_basis = CoreBasisFunctionOrder.FIRST_ORDER | ||
| elif value.upper() == "MIXED": | ||
| self.core.order_basis = CoreBasisFunctionOrder.MIXED_ORDER | ||
| elif value.upper() == "SECOND": | ||
| self.core.order_basis = CoreBasisFunctionOrder.SECOND_ORDER | ||
| @property | ||
| def relative_residual(self) -> float: | ||
| """Relative residual value that the HFSS iterative solver is to use. | ||
| Returns | ||
| ------- | ||
| float | ||
| Relative residual value. | ||
| """ | ||
| return self.core.relative_residual | ||
| @relative_residual.setter | ||
| def relative_residual(self, value: float): | ||
| self.core.relative_residual = value | ||
| @property | ||
| def solver_type(self): | ||
| return self.solver_type.name() | ||
| return self.core.solver_type.name.lower() | ||
| @solver_type.setter | ||
| def solver_type(self, value): | ||
| if value == "AUTO_SOLVER": | ||
| self.solver_type = GrpcSolverType.AUTO_SOLVER | ||
| elif value == "DIRECT_SOLVER": | ||
| self.solver_type = GrpcSolverType.DIRECT_SOLVER | ||
| elif value == "ITERATIVE_SOLVER": | ||
| self.solver_type = GrpcSolverType.ITERATIVE_SOLVER | ||
| elif value == "NUM_SOLVER_TYPES": | ||
| self.solver_type = GrpcSolverType.NUM_SOLVER_TYPES | ||
| if value.upper() == "AUTO_SOLVER": | ||
| self.core.solver_type = CoreSolverType.AUTO_SOLVER | ||
| elif value.upper() == "DIRECT_SOLVER": | ||
| self.core.solver_type = CoreSolverType.DIRECT_SOLVER | ||
| elif value.upper() == "ITERATIVE_SOLVER": | ||
| self.core.solver_type = CoreSolverType.ITERATIVE_SOLVER | ||
| elif value.upper() == "NUM_SOLVER_TYPES": | ||
| self.core.solver_type = CoreSolverType.NUM_SOLVER_TYPES | ||
| @property | ||
| def use_default_lambda_value(self) -> bool: | ||
| """Flag to indicate whether to use the default lambda value. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if using the default lambda value, False otherwise. | ||
| """ | ||
| return self.core.use_default_lambda_value | ||
| @use_default_lambda_value.setter | ||
| def use_default_lambda_value(self, value: float): | ||
| self.core.use_default_lambda_value = value | ||
| @property | ||
| def use_max_refinement(self) -> float: | ||
| """Flag to indicate whether to use maximum refinement. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if using maximum refinement, False otherwise. | ||
| """ | ||
| return self.core.use_max_refinement | ||
| @use_max_refinement.setter | ||
| def use_max_refinement(self, value: bool): | ||
| self.core.use_max_refinement = value | ||
| @property | ||
| def use_shell_elements(self) -> bool: | ||
| """Flag to indicate whether to use shell elements. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if using shell elements, False otherwise. | ||
| """ | ||
| return self.core.use_shell_elements | ||
| @use_shell_elements.setter | ||
| def use_shell_elements(self, value: bool): | ||
| self.core.use_shell_elements = value |
@@ -23,6 +23,9 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from typing import TYPE_CHECKING | ||
| import warnings | ||
| from ansys.edb.core.simulation_setup.hfss_simulation_settings import ( | ||
| HFSSSimulationSettings as GrpcHFSSSimulationSettings, | ||
| ) | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.hfss_simulation_settings import ( | ||
| HFSSSimulationSettings as CoreHFSSSimulationSettings, | ||
| ) | ||
@@ -45,8 +48,7 @@ from pyedb.grpc.database.simulation_setup.hfss_advanced_meshing_settings import ( | ||
| class HFSSSimulationSettings(GrpcHFSSSimulationSettings): | ||
| class HFSSSimulationSettings: | ||
| """PyEDB-core HFSS simulation settings class.""" | ||
| def __init__(self, pedb, core): | ||
| super().__init__(core) | ||
| self._edb_object = core | ||
| def __init__(self, pedb, core: "CoreHFSSSimulationSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
@@ -64,3 +66,3 @@ | ||
| """ | ||
| return HFSSAdvancedSettings(self._pedb, self.advanced) | ||
| return HFSSAdvancedSettings(self._pedb, self.core.advanced) | ||
@@ -77,3 +79,3 @@ @property | ||
| """ | ||
| return HFSSAdvancedMeshingSettings(self._pedb, self.advanced_meshing) | ||
| return HFSSAdvancedMeshingSettings(self._pedb, self.core.advanced_meshing) | ||
@@ -89,3 +91,3 @@ @property | ||
| """ | ||
| return HFSSDCRSettings(self._pedb, self.dcr) | ||
| return HFSSDCRSettings(self._pedb, self.core.dcr) | ||
@@ -101,3 +103,3 @@ @property | ||
| """ | ||
| return HFSSGeneralSettings(self._pedb, self.general) | ||
| return HFSSGeneralSettings(self._pedb, self.core.general) | ||
@@ -113,3 +115,3 @@ @property | ||
| """ | ||
| return HFSSSettingsOptions(self._pedb, self.options) | ||
| return HFSSSettingsOptions(self._pedb, self.core.options) | ||
@@ -125,2 +127,59 @@ @property | ||
| """ | ||
| return HFSSSolverSettings(self._pedb, self.solver) | ||
| return HFSSSolverSettings(self._pedb, self.core.solver) | ||
| @property | ||
| def enhanced_low_frequency_accuracy(self) -> bool: | ||
| """Enhanced low frequency accuracy flag. | ||
| .. deprecated:: 0.67.0 | ||
| This property is deprecated. Please use :attr:`options.enhanced_low_frequency_accuracy` | ||
| instead. | ||
| This attribute was added for dotnet compatibility and will be removed in future releases. | ||
| """ | ||
| warnings.warn( | ||
| "The 'enhanced_low_frequency_accuracy' property is deprecated and will be removed in future releases. ", | ||
| DeprecationWarning, | ||
| ) | ||
| return self.options.enhanced_low_frequency_accuracy | ||
| @enhanced_low_frequency_accuracy.setter | ||
| def enhanced_low_frequency_accuracy(self, value: bool): | ||
| self.options.enhanced_low_frequency_accuracy = value | ||
| @property | ||
| def relative_residual(self) -> float: | ||
| """Relative residual value. | ||
| .. deprecated:: 0.67.0 | ||
| This property is deprecated. Please use :attr:`options.relative_residual` | ||
| instead. | ||
| This attribute was added for dotnet compatibility and will be removed in future releases. | ||
| """ | ||
| warnings.warn( | ||
| "The 'relative_residual' property is deprecated and will be removed in future releases.", | ||
| DeprecationWarning, | ||
| ) | ||
| return self.options.relative_residual | ||
| @relative_residual.setter | ||
| def relative_residual(self, value: float): | ||
| self.options.relative_residual = value | ||
| @property | ||
| def use_shell_elements(self) -> bool: | ||
| """Use shell elements flag. | ||
| .. deprecated:: 0.67.0 | ||
| This property is deprecated. Please use :attr:`options.use_shell_elements` | ||
| instead. | ||
| This attribute was added for dotnet compatibility and will be removed in future releases. | ||
| """ | ||
| warnings.warn( | ||
| "The 'use_shell_elements' property is deprecated and will be removed in future releases. ", | ||
| DeprecationWarning, | ||
| ) | ||
| return self.options.use_shell_elements | ||
| @use_shell_elements.setter | ||
| def use_shell_elements(self, value: bool): | ||
| self.options.use_shell_elements = value |
@@ -24,35 +24,237 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.simulation_setup.adaptive_solutions import ( | ||
| AdaptiveFrequency as GrpcAdaptiveFrequency, | ||
| ) | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from pyedb.grpc.edb import Edb | ||
| from typing import Union | ||
| import warnings | ||
| from ansys.edb.core.simulation_setup.adaptive_solutions import AdaptiveFrequency as CoreAdaptiveFrequency | ||
| from ansys.edb.core.simulation_setup.hfss_simulation_settings import ( | ||
| AdaptType as GrpcAdaptType, | ||
| AdaptType as CoreAdaptType, | ||
| ) | ||
| from ansys.edb.core.simulation_setup.hfss_simulation_setup import ( | ||
| HfssSimulationSetup as GrpcHfssSimulationSetup, | ||
| HfssSimulationSetup as CoreHfssSimulationSetup, | ||
| ) | ||
| from ansys.edb.core.simulation_setup.mesh_operation import LengthMeshOperation as GrpcLengthMeshOperation | ||
| from pyedb.generic.general_methods import generate_unique_name | ||
| from pyedb.grpc.database.simulation_setup.hfss_general_settings import HFSSGeneralSettings | ||
| from pyedb.grpc.database.simulation_setup.hfss_simulation_settings import HFSSSimulationSettings | ||
| from pyedb.grpc.database.simulation_setup.length_mesh_operation import LengthMeshOperation | ||
| from pyedb.grpc.database.simulation_setup.simulation_setup import SimulationSetup | ||
| from pyedb.grpc.database.simulation_setup.skin_depth_mesh_operation import SkinDepthMeshOperation | ||
| from pyedb.grpc.database.simulation_setup.sweep_data import SweepData | ||
| class HfssSimulationSetup(GrpcHfssSimulationSetup): | ||
| class HfssSimulationSetup(SimulationSetup): | ||
| """HFSS simulation setup class.""" | ||
| def __init__(self, pedb, core, name: str = None): | ||
| super().__init__(core.msg) | ||
| def __init__(self, pedb, core: "CoreHfssSimulationSetup", name: str = None): | ||
| super().__init__(pedb, core) | ||
| self.core = core | ||
| self._pedb = pedb | ||
| self._name = name | ||
| self._mesh_operations: list[Union[LengthMeshOperation, SkinDepthMeshOperation]] = [] | ||
| @classmethod | ||
| def create(cls, edb: "Edb", name: str = None): | ||
| """Create a new HFSS simulation setup. | ||
| Parameters | ||
| ---------- | ||
| edb : pyedb.Edb | ||
| The EDB instance to which the simulation setup will be added. | ||
| name : str, optional | ||
| Name of the simulation setup. | ||
| Returns | ||
| ------- | ||
| :class:`HfssSimulationSetup <pyedb.grpc.database.simulation_setup.hfss_simulation_setup.HfssSimulationSetup>` | ||
| """ | ||
| if not name: | ||
| name = generate_unique_name("HFSS_Setup") | ||
| core = CoreHfssSimulationSetup.create(edb.active_cell, name) | ||
| return cls(pedb=edb, core=core, name=name) | ||
| @property | ||
| def mesh_operations(self) -> list[Union[LengthMeshOperation, SkinDepthMeshOperation]]: | ||
| """List of HFSS mesh operations.""" | ||
| from ansys.edb.core.simulation_setup.mesh_operation import ( | ||
| LengthMeshOperation as GrpcLengthMeshOperation, | ||
| SkinDepthMeshOperation as GrpcSkinDepthMeshOperation, | ||
| ) | ||
| self._mesh_operations = [] | ||
| for mesh_operation in self.core.mesh_operations: | ||
| if isinstance(mesh_operation, GrpcLengthMeshOperation): | ||
| self._mesh_operations.append(LengthMeshOperation(core=mesh_operation)) | ||
| elif isinstance(mesh_operation, GrpcSkinDepthMeshOperation): | ||
| self._mesh_operations.append(SkinDepthMeshOperation(core=mesh_operation)) | ||
| return self._mesh_operations | ||
| @mesh_operations.setter | ||
| def mesh_operations(self, mesh_operations: list[Union[LengthMeshOperation, SkinDepthMeshOperation]]): | ||
| self.core.mesh_operations = [mesh_operation.core for mesh_operation in mesh_operations] | ||
| @property | ||
| def defeature_settings(self): | ||
| """HFSS defeature settings class. | ||
| .. deprecated:: 0.67.2 | ||
| Use :attr:`settings | ||
| <pyedb.grpc.database.simulation_setup.hfss_simulation_setup.HfssSimulationSetup.settings.advanced>" | ||
| instead. | ||
| """ | ||
| warnings.warn( | ||
| "The 'defeature_settings' property is deprecated. Use 'settings.advanced' property instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| return self.settings.advanced | ||
| @property | ||
| def via_settings(self): | ||
| """HFSS via settings class. | ||
| .. deprecated:: 0.67.2 | ||
| Use :attr:`settings | ||
| <pyedb.grpc.database.simulation_setup.hfss_simulation_setup.HfssSimulationSetup.settings.advanced>` | ||
| instead. | ||
| """ | ||
| warnings.warn( | ||
| "The 'via_settings' property is deprecated. Use 'settings.advanced' property instead.", DeprecationWarning | ||
| ) | ||
| return self.settings.advanced | ||
| @property | ||
| def advanced_mesh_settings(self): | ||
| """HFSS advanced meshing settings class. | ||
| .. deprecated:: 0.67.2 | ||
| Use :attr:`settings | ||
| <pyedb.grpc.database.simulation_setup.hfss_simulation_setup.HfssSimulationSetup.settings.advanced_meshing>` | ||
| instead. | ||
| """ | ||
| warnings.warn( | ||
| "The 'advanced_mesh_settings' property is deprecated. Use 'settings.advanced_meshing' property instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| return self.settings.advanced_meshing | ||
| @property | ||
| def hfss_solver_settings(self): | ||
| """Legacy compatibility to settings properties.""" | ||
| return self.settings.options | ||
| """Legacy compatibility to settings properties. | ||
| .. deprecated:: 0.67.2 | ||
| Use :attr:`settings <pyedb.grpc.database.simulation_setup.hfss_simulation_setup.HfssSimulationSetup.settings>` | ||
| instead. | ||
| #""" | ||
| warnings.warn( | ||
| "The 'hfss_solver_settings' property is deprecated. Use 'settings' property instead.", DeprecationWarning | ||
| ) | ||
| return self.settings | ||
| @property | ||
| def settings(self) -> HFSSSimulationSettings: | ||
| """HFSS simulation settings class. | ||
| Returns | ||
| ------- | ||
| :class:`HFSSSimulationSettings | ||
| <pyedb.grpc.database.simulation_setup.hfss_simulation_settings.HFSSSimulationSettings>` | ||
| """ | ||
| return HFSSSimulationSettings(self, self.core.settings) | ||
| @property | ||
| def adaptive_settings(self): | ||
| """Legacy compatibility to general settings.""" | ||
| return self.settings.general | ||
| """Legacy compatibility to general settings. | ||
| .. deprecated:: 0.67.2 | ||
| use :attr:`general_settings | ||
| <pyedb.grpc.database.simulation_setup.hfss_simulation_setup.HfssSimulationSetup.settings.general>` | ||
| instead. | ||
| """ | ||
| warnings.warn( | ||
| "The 'adaptive_settings' property is deprecated. Use 'settings.general' property instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| return HFSSGeneralSettings(self, self.core.settings.general) | ||
| @property | ||
| def curve_approx_settings(self): | ||
| """Legacy compatibility to advanced meshing settings. | ||
| .. deprecated:: 0.67.2 | ||
| use :attr:`advanced_mesh_settings | ||
| <pyedb.grpc.database.simulation_setup.hfss_simulation_setup.HfssSimulationSetup.settings.advanced_meshing>` | ||
| instead. | ||
| """ | ||
| warnings.warn( | ||
| "The 'curve_approx_settings' property is deprecated. Use 'settings.advanced_meshing' property instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| return self.settings.advanced_meshing | ||
| @property | ||
| def dcr_settings(self): | ||
| """HFSS DCR settings class. | ||
| .. deprecated:: 0.67.2 | ||
| use :attr:`dcr | ||
| <pyedb.grpc.database.simulation_setup.hfss_simulation_setup.HfssSimulationSetup.settings.dcr>` | ||
| instead. | ||
| """ | ||
| warnings.warn( | ||
| "The 'dcr_settings' property is deprecated. Use 'settings.dcr' property instead.", DeprecationWarning | ||
| ) | ||
| return self.settings.dcr | ||
| @property | ||
| def hfss_port_settings(self): | ||
| """HFSS port settings class. | ||
| .. deprecated:: 0.67.2 | ||
| use :attr:`settings | ||
| <pyedb.grpc.database.simulation_setup.hfss_simulation_setup.HfssSimulationSetup.settings>` | ||
| instead. | ||
| """ | ||
| warnings.warn( | ||
| "The 'hfss_port_settings' property is deprecated. Use 'settings' property instead.", DeprecationWarning | ||
| ) | ||
| return self.settings.solver | ||
| @property | ||
| def sweep_data(self) -> list[SweepData]: | ||
| """List of HFSS sweep data. | ||
| Returns | ||
| ------- | ||
| list[:class:`SweepData <pyedb.grpc.database.simulation_setup.sweep_data.SweepData>`] | ||
| List of sweep data. | ||
| """ | ||
| return [SweepData(self, core=sweep) for sweep in self.core.sweep_data] | ||
| @sweep_data.setter | ||
| def sweep_data(self, value: list[SweepData]): | ||
| """Set the HFSS sweep data list. | ||
| Accepts a list of SweepData wrapper objects or raw core sweep objects. The underlying | ||
| core.sweep_data is updated with core objects extracted from the wrappers. | ||
| """ | ||
| # Normalize incoming values to core objects | ||
| core_list = [] | ||
| for item in value: | ||
| # If a wrapper with .core attribute is provided, use that; otherwise assume it's already a core object | ||
| core_list.append(item.core if hasattr(item, "core") else item) | ||
| self.core.sweep_data = core_list | ||
| def set_solution_single_frequency(self, frequency="5GHz", max_num_passes=10, max_delta_s=0.02) -> bool: | ||
@@ -74,12 +276,9 @@ """Set HFSS single frequency solution. | ||
| """ | ||
| try: | ||
| self.settings.general.adaptive_solution_type = GrpcAdaptType.SINGLE | ||
| sfs = self.settings.general.single_frequency_adaptive_solution | ||
| sfs.adaptive_frequency = frequency | ||
| sfs.max_passes = max_num_passes | ||
| sfs.max_delta = str(max_delta_s) | ||
| self.settings.general.single_frequency_adaptive_solution = sfs | ||
| return True | ||
| except: | ||
| return False | ||
| self.core.settings.general.adaptive_solution_type = CoreAdaptType.SINGLE | ||
| sfs = self.core.settings.general.single_frequency_adaptive_solution | ||
| sfs.adaptive_frequency = frequency | ||
| sfs.max_passes = max_num_passes | ||
| sfs.max_delta = str(max_delta_s) | ||
| self.core.settings.general.single_frequency_adaptive_solution = sfs | ||
| return True | ||
@@ -101,18 +300,15 @@ def set_solution_multi_frequencies(self, frequencies="5GHz", max_delta_s=0.02) -> bool: | ||
| """ | ||
| try: | ||
| self.settings.general.adaptive_solution_type = GrpcAdaptType.MULTI_FREQUENCIES | ||
| if not isinstance(frequencies, list): | ||
| frequencies = [frequencies] | ||
| if not isinstance(max_delta_s, list): | ||
| max_delta_s = [max_delta_s] | ||
| if len(max_delta_s) < len(frequencies): | ||
| for _ in frequencies[len(max_delta_s) :]: | ||
| max_delta_s.append(max_delta_s[-1]) | ||
| adapt_frequencies = [ | ||
| GrpcAdaptiveFrequency(frequencies[ind], str(max_delta_s[ind])) for ind in range(len(frequencies)) | ||
| ] | ||
| self.settings.general.multi_frequency_adaptive_solution.adaptive_frequencies = adapt_frequencies | ||
| return True | ||
| except: | ||
| return False | ||
| self.settings.general.adaptive_solution_type = "multi_frequencies" | ||
| if not isinstance(frequencies, list): | ||
| frequencies = [frequencies] | ||
| if not isinstance(max_delta_s, list): | ||
| max_delta_s = [max_delta_s] | ||
| if len(max_delta_s) < len(frequencies): | ||
| for _ in frequencies[len(max_delta_s) :]: | ||
| max_delta_s.append(max_delta_s[-1]) | ||
| adapt_frequencies = [ | ||
| CoreAdaptiveFrequency(frequencies[ind], str(max_delta_s[ind])) for ind in range(len(frequencies)) | ||
| ] | ||
| self.core.settings.general.multi_frequency_adaptive_solution.adaptive_frequencies = adapt_frequencies | ||
| return True | ||
@@ -139,9 +335,9 @@ def set_solution_broadband(self, low_frequency="1GHz", high_frequency="10GHz", max_delta_s=0.02, max_num_passes=10): | ||
| try: | ||
| self.settings.general.adaptive_solution_type = GrpcAdaptType.BROADBAND | ||
| self.settings.general.adaptive_solution_type = "broad_band" | ||
| bfs = self.settings.general.broadband_adaptive_solution | ||
| bfs.low_frequency = low_frequency | ||
| bfs.high_frequency = high_frequency | ||
| bfs.max_delta = str(max_delta_s) | ||
| bfs.max_delta = max_delta_s | ||
| bfs.max_num_passes = max_num_passes | ||
| self.settings.general.broadband_adaptive_solution = bfs | ||
| self.core.settings.general.broadband_adaptive_solution = bfs | ||
| return True | ||
@@ -169,4 +365,4 @@ except: | ||
| adapt_frequencies = self.settings.general.multi_frequency_adaptive_solution.adaptive_frequencies | ||
| adapt_frequencies.append(GrpcAdaptiveFrequency(frequency, str(max_delta_s))) | ||
| self.settings.general.multi_frequency_adaptive_solution.adaptive_frequencies = adapt_frequencies | ||
| adapt_frequencies.append(CoreAdaptiveFrequency(frequency, str(max_delta_s))) | ||
| self.core.settings.general.multi_frequency_adaptive_solution.adaptive_frequencies = adapt_frequencies | ||
| return True | ||
@@ -238,3 +434,4 @@ except: | ||
| mesh_ops = self.mesh_operations | ||
| mesh_ops.append(mop) | ||
| # Wrap the core mesh operation with the MeshOperation wrapper before appending | ||
| mesh_ops.append(LengthMeshOperation(core=mop)) | ||
| self.mesh_operations = mesh_ops | ||
@@ -308,116 +505,6 @@ return mop | ||
| mesh_ops = self.mesh_operations | ||
| mesh_ops.append(mesh_operation) | ||
| mesh_ops.append(SkinDepthMeshOperation(mesh_operation)) | ||
| self.mesh_operations = mesh_ops | ||
| return mesh_operation | ||
| def add_sweep( | ||
| self, | ||
| name=None, | ||
| distribution="linear", | ||
| start_freq="0GHz", | ||
| stop_freq="20GHz", | ||
| step="10MHz", | ||
| discrete=False, | ||
| frequency_set=None, | ||
| ): | ||
| """Add a HFSS frequency sweep. | ||
| Parameters | ||
| ---------- | ||
| name : str, optional | ||
| Sweep name. | ||
| distribution : str, optional | ||
| Type of the sweep. The default is `"linear"`. Options are: | ||
| - `"linear"` | ||
| - `"linear_count"` | ||
| - `"decade_count"` | ||
| - `"octave_count"` | ||
| - `"exponential"` | ||
| start_freq : str, float, optional | ||
| Starting frequency. The default is ``1``. | ||
| stop_freq : str, float, optional | ||
| Stopping frequency. The default is ``1e9``. | ||
| step : str, float, int, optional | ||
| Frequency step. The default is ``1e6``. or used for `"decade_count"`, "linear_count"`, "octave_count"` | ||
| distribution. Must be integer in that case. | ||
| discrete : bool, optional | ||
| Whether the sweep is discrete. The default is ``False``. | ||
| frequency_set : List, optional | ||
| Frequency set is a list adding one or more frequency sweeps. If ``frequency_set`` is provided, the other | ||
| arguments are ignored except ``discrete``. Default value is ``None``. | ||
| example of frequency_set : [['linear_scale', '50MHz', '200MHz', '10MHz']]. | ||
| Returns | ||
| ------- | ||
| bool | ||
| """ | ||
| init_sweep_count = len(self.sweep_data) | ||
| if frequency_set: | ||
| for sweep in frequency_set: | ||
| if "linear_scale" in sweep: | ||
| distribution = "LIN" | ||
| elif "linear_count" in sweep: | ||
| distribution = "LINC" | ||
| elif "exponential" in sweep: | ||
| distribution = "ESTP" | ||
| elif "log_scale" in sweep: | ||
| distribution = "DEC" | ||
| elif "octave_count" in sweep: | ||
| distribution = "OCT" | ||
| else: | ||
| distribution = "LIN" | ||
| start_freq = self._pedb.number_with_units(sweep[1], "Hz") | ||
| stop_freq = self._pedb.number_with_units(sweep[2], "Hz") | ||
| step = str(sweep[3]) | ||
| if not name: | ||
| name = f"sweep_{init_sweep_count + 1}" | ||
| sweep_data = [ | ||
| SweepData( | ||
| self._pedb, name=name, distribution=distribution, start_f=start_freq, end_f=stop_freq, step=step | ||
| ) | ||
| ] | ||
| if discrete: | ||
| sweep_data[0].type = sweep_data[0].type.DISCRETE_SWEEP | ||
| for sweep in self.sweep_data: | ||
| sweep_data.append(sweep) | ||
| self.sweep_data = sweep_data | ||
| else: | ||
| start_freq = self._pedb.number_with_units(start_freq, "Hz") | ||
| stop_freq = self._pedb.number_with_units(stop_freq, "Hz") | ||
| step = str(step) | ||
| if not distribution in ["LIN", "LINC", "ESTP", "DEC", "OCT"]: | ||
| if distribution.lower() == "linear" or distribution.lower() == "linear scale": | ||
| distribution = "LIN" | ||
| elif distribution.lower() == "linear_count" or distribution.lower() == "linear count": | ||
| distribution = "LINC" | ||
| elif distribution.lower() == "exponential": | ||
| distribution = "ESTP" | ||
| elif ( | ||
| distribution.lower() == "decade_count" | ||
| or distribution.lower() == "decade count" | ||
| or distribution.lower() | ||
| ) == "log scale": | ||
| distribution = "DEC" | ||
| elif distribution.lower() == "octave_count" or distribution.lower() == "octave count": | ||
| distribution = "OCT" | ||
| else: | ||
| distribution = "LIN" | ||
| if not name: | ||
| name = f"sweep_{init_sweep_count + 1}" | ||
| sweep_data = [ | ||
| SweepData( | ||
| self._pedb, name=name, distribution=distribution, start_f=start_freq, end_f=stop_freq, step=step | ||
| ) | ||
| ] | ||
| if discrete: | ||
| sweep_data[0].type = sweep_data[0].type.DISCRETE_SWEEP | ||
| for sweep in self.sweep_data: | ||
| sweep_data.append(sweep) | ||
| self.sweep_data = sweep_data | ||
| if len(self.sweep_data) == init_sweep_count + 1: | ||
| return self.sweep_data[-1] | ||
| else: | ||
| self._pedb.logger.error("Failed to add frequency sweep data") | ||
| return False | ||
| def auto_mesh_operation( | ||
@@ -480,3 +567,3 @@ self, | ||
| raise ValueError("No terminals found to seed the mesh operation.") | ||
| meshop = GrpcLengthMeshOperation(name=f"{self.name}_AutoMeshOp") | ||
| meshop = LengthMeshOperation.create(name=f"{self.name}_AutoMeshOp") | ||
| layer_info = [] | ||
@@ -483,0 +570,0 @@ smallest_width = 1e3 |
@@ -23,13 +23,130 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from typing import TYPE_CHECKING | ||
| import warnings | ||
| from ansys.edb.core.simulation_setup.hfss_simulation_settings import ( | ||
| HFSSSolverSettings as GrpcHFSSSolverSettings, | ||
| ) | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.hfss_simulation_settings import ( | ||
| HFSSSolverSettings as CoreHFSSSolverSettings, | ||
| ) | ||
| class HFSSSolverSettings(GrpcHFSSSolverSettings): | ||
| class HFSSSolverSettings: | ||
| """HFSS solver settings class.""" | ||
| def __init__(self, pedb, core): | ||
| super().__init__(core) | ||
| def __init__(self, pedb, core: "CoreHFSSSolverSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def enable_intra_plane_coupling(self) -> bool: | ||
| """Flag indicating if intra-plane coupling of power/ground nets is enabled to enhance accuracy..""" | ||
| return self.core.enable_intra_plane_coupling | ||
| @enable_intra_plane_coupling.setter | ||
| def enable_intra_plane_coupling(self, value: bool): | ||
| self.core.enable_intra_plane_coupling = value | ||
| @property | ||
| def max_delta_z0(self) -> float: | ||
| """Maximum percent change in characteristic impedance of ports between adaptive passes.""" | ||
| return self.core.max_delta_z0 | ||
| @max_delta_z0.setter | ||
| def max_delta_z0(self, value: float): | ||
| self.core.max_delta_z0 = value | ||
| @property | ||
| def max_triangles_wave_port(self) -> int: | ||
| """Maximum number of triangles to use for meshing wave-ports.""" | ||
| warnings.warn( | ||
| "max_triangles_wave_port is deprecated. Use max_triangles_for_wave_port instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| return self.core.max_triangles_for_wave_port | ||
| @max_triangles_wave_port.setter | ||
| def max_triangles_wave_port(self, value: int): | ||
| warnings.warn( | ||
| "max_triangles_wave_port is deprecated. Use max_triangles_for_wave_port instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| self.core.max_triangles_for_wave_port = value | ||
| @property | ||
| def max_triangles_for_wave_port(self) -> int: | ||
| """Maximum number of triangles to use for meshing wave-ports.""" | ||
| return self.core.max_triangles_for_wave_port | ||
| @max_triangles_for_wave_port.setter | ||
| def max_triangles_for_wave_port(self, value: int): | ||
| self.core.max_triangles_for_wave_port = value | ||
| @property | ||
| def min_triangles_wave_port(self) -> int: | ||
| """Minimum number of triangles to use for meshing wave-ports.""" | ||
| warnings.warn( | ||
| "min_triangles_wave_port is deprecated. Use min_triangles_for_wave_port instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| return self.core.min_triangles_for_wave_port | ||
| @min_triangles_wave_port.setter | ||
| def min_triangles_wave_port(self, value: int): | ||
| warnings.warn( | ||
| "min_triangles_wave_port is deprecated. Use min_triangles_for_wave_port instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| self.core.min_triangles_for_wave_port = value | ||
| @property | ||
| def min_triangles_for_wave_port(self) -> int: | ||
| """Minimum number of triangles to use for meshing wave-ports.""" | ||
| return self.core.min_triangles_for_wave_port | ||
| @min_triangles_for_wave_port.setter | ||
| def min_triangles_for_wave_port(self, value: int): | ||
| self.core.min_triangles_for_wave_port = value | ||
| @property | ||
| def enable_set_triangles_wave_port(self) -> bool: | ||
| """Flag indicating if the minimum and maximum triangle values for wave-ports are used.""" | ||
| warnings.warn( | ||
| "enable_set_triangles_wave_port is deprecated. Use set_triangles_for_wave_port instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| return self.core.set_triangles_for_wave_port | ||
| @enable_set_triangles_wave_port.setter | ||
| def enable_set_triangles_wave_port(self, value: bool): | ||
| warnings.warn( | ||
| "enable_set_triangles_wave_port is deprecated. Use set_triangles_for_wave_port instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| self.core.set_triangles_for_wave_port = value | ||
| @property | ||
| def set_triangles_for_wave_port(self) -> bool: | ||
| """Flag indicating ifthe minimum and maximum triangle values for wave-ports are used.""" | ||
| return self.core.set_triangles_for_wave_port | ||
| @set_triangles_for_wave_port.setter | ||
| def set_triangles_for_wave_port(self, value: bool): | ||
| self.core.set_triangles_for_wave_port = value | ||
| @property | ||
| def thin_dielectric_layer_threshold(self) -> float: | ||
| """Value below which dielectric layers are merged with adjacent dielectric layers.""" | ||
| return self._pedb.value(self.core.thin_dielectric_layer_threshold) | ||
| @thin_dielectric_layer_threshold.setter | ||
| def thin_dielectric_layer_threshold(self, value: float): | ||
| self.core.thin_dielectric_layer_threshold = str(self._pedb.value(value)) | ||
| @property | ||
| def thin_signal_layer_threshold(self) -> float: | ||
| """Value below which signal layers are merged with adjacent signal layers.""" | ||
| return self._pedb.value(self.core.thin_signal_layer_threshold) | ||
| @thin_signal_layer_threshold.setter | ||
| def thin_signal_layer_threshold(self, value: float): | ||
| self.core.thin_signal_layer_threshold = str(self._pedb.value(value)) |
@@ -17,3 +17,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| # FITNE SS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
@@ -24,13 +24,244 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| from typing import TYPE_CHECKING | ||
| from ansys.edb.core.simulation_setup.raptor_x_simulation_settings import ( | ||
| RaptorXAdvancedSettings as GrpcRaptorXAdvancedSettings, | ||
| ) | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.raptor_x_simulation_settings import ( | ||
| RaptorXAdvancedSettings as CoreRaptorXAdvancedSettings, | ||
| ) | ||
| class RaptorXAdvancedSettings(GrpcRaptorXAdvancedSettings): | ||
| class RaptorXAdvancedSettings: | ||
| """Raptor X advanced settings class.""" | ||
| def __init__(self, pedb, core): | ||
| super().__init__(core) | ||
| def __init__(self, pedb, core: "CoreRaptorXAdvancedSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def advanced_options(self) -> dict[str, list[str]]: | ||
| """Get advanced options as a dictionary.""" | ||
| return self.core.advanced_options | ||
| @property | ||
| def auto_removal_sliver_poly(self) -> float: | ||
| """Automatic sliver polygon removal tolerance.""" | ||
| return self.core.auto_removal_sliver_poly | ||
| @auto_removal_sliver_poly.setter | ||
| def auto_removal_sliver_poly(self, value: float): | ||
| """Set automatic sliver polygon removal tolerance.""" | ||
| self.core.auto_removal_sliver_poly = value | ||
| @property | ||
| def cells_per_wavelength(self) -> int: | ||
| """Number of cells that fit under each wavelength.""" | ||
| return self.core.cells_per_wavelength | ||
| @cells_per_wavelength.setter | ||
| def cells_per_wavelength(self, value: int): | ||
| """Set number of cells that fit under each wavelength.""" | ||
| self.core.cells_per_wavelength = value | ||
| @property | ||
| def edge_mesh(self) -> float: | ||
| """Thickness and width of the exterior conductor filament.""" | ||
| return self._pedb.value(self.core.edge_mesh) | ||
| @edge_mesh.setter | ||
| def edge_mesh(self, value: float): | ||
| """Set thickness and width of the exterior conductor filament.""" | ||
| self.core.edge_mesh = str(self._pedb.value(value)) | ||
| @property | ||
| def eliminate_slit_per_holes(self) -> float: | ||
| """Threshold for strain or thermal relief slits and hole polygon areas.""" | ||
| return self.core.eliminate_slit_per_holes | ||
| @eliminate_slit_per_holes.setter | ||
| def eliminate_slit_per_holes(self, value: float): | ||
| """Set threshold for strain or thermal relief slits and hole polygon areas.""" | ||
| self.core.eliminate_slit_per_holes = value | ||
| @property | ||
| def mesh_frequency(self) -> float: | ||
| """Frequency at which the mesh is generated.""" | ||
| return self._pedb.value(self.core.mesh_frequency) | ||
| @mesh_frequency.setter | ||
| def mesh_frequency(self, value: float): | ||
| """Set frequency at which the mesh is generated.""" | ||
| self.core.mesh_frequency = str(self._pedb.value(value)) | ||
| @property | ||
| def net_settings_options(self) -> dict[str, list[str]]: | ||
| """Get net settings options as a dictionary.""" | ||
| return self.core.net_settings_options | ||
| @net_settings_options.setter | ||
| def net_settings_options(self, value: dict[str, list[str]]): | ||
| """Set net settings options as a dictionary.""" | ||
| self.core.net_settings_options = value | ||
| @property | ||
| def override_shrink_factor(self) -> float: | ||
| """Override shrink factor for polygon edges.""" | ||
| return self.core.override_shrink_factor | ||
| @override_shrink_factor.setter | ||
| def override_shrink_factor(self, value: float): | ||
| self.core.override_shrink_factor = value | ||
| @property | ||
| def plane_projection_factor(self) -> float: | ||
| """Plane projection factor for reducing the mesh complexity of large metal planes.""" | ||
| return self.core.plane_projection_factor | ||
| @plane_projection_factor.setter | ||
| def plane_projection_factor(self, value: float): | ||
| self.core.plane_projection_factor = value | ||
| @property | ||
| def use_accelerate_via_extraction(self) -> bool: | ||
| """Flag indicating if neighboring vias are simplified/merged.""" | ||
| return self.core.use_accelerate_via_extraction | ||
| @use_accelerate_via_extraction.setter | ||
| def use_accelerate_via_extraction(self, value: bool): | ||
| self.core.use_accelerate_via_extraction = value | ||
| @property | ||
| def use_auto_removal_sliver_poly(self) -> bool: | ||
| """Flag indicating if slight misaligned overlapping polygons are to be automatically aligned.""" | ||
| return self.core.use_auto_removal_sliver_poly | ||
| @use_auto_removal_sliver_poly.setter | ||
| def use_auto_removal_sliver_poly(self, value: bool): | ||
| self.core.use_auto_removal_sliver_poly = value | ||
| @property | ||
| def use_cells_per_wavelength(self) -> bool: | ||
| """Flag indicating if cells per wavelength are used.""" | ||
| return self.core.use_cells_per_wavelength | ||
| @use_cells_per_wavelength.setter | ||
| def use_cells_per_wavelength(self, value: bool): | ||
| self.core.use_cells_per_wavelength = value | ||
| @property | ||
| def use_edge_mesh(self) -> bool: | ||
| """Flag indicating if edge mesh is used.""" | ||
| return self.core.use_edge_mesh | ||
| @use_edge_mesh.setter | ||
| def use_edge_mesh(self, value: bool): | ||
| self.core.use_edge_mesh = value | ||
| @property | ||
| def use_eliminate_slit_per_holes(self) -> bool: | ||
| """Flag indicating if elimination of slits and holes is used.""" | ||
| return self.core.use_eliminate_slit_per_holes | ||
| @use_eliminate_slit_per_holes.setter | ||
| def use_eliminate_slit_per_holes(self, value: bool): | ||
| self.core.use_eliminate_slit_per_holes = value | ||
| @property | ||
| def use_enable_advanced_cap_effects(self) -> bool: | ||
| """Flag indicating if capacitance-related effects such as conformal dielectrics are applied.""" | ||
| return self.core.use_enable_advanced_cap_effects | ||
| @use_enable_advanced_cap_effects.setter | ||
| def use_enable_advanced_cap_effects(self, value: bool): | ||
| self.core.use_enable_advanced_cap_effects = value | ||
| @property | ||
| def use_enable_etch_transform(self) -> bool: | ||
| """Flag indicating if layout is "pre-distorted" based on foundry rules.""" | ||
| return self.core.use_enable_etch_transform | ||
| @use_enable_etch_transform.setter | ||
| def use_enable_etch_transform(self, value: bool): | ||
| self.core.use_enable_etch_transform = value | ||
| @property | ||
| def defuse_enable_hybrid_extraction(self) -> bool: | ||
| """Flag indicating if the modeler is to split the layout into two parts in an attempt to decrease | ||
| the complexity.""" | ||
| return self.core.defuse_enable_hybrid_extraction | ||
| @defuse_enable_hybrid_extraction.setter | ||
| def defuse_enable_hybrid_extraction(self, value: bool): | ||
| self.core.defuse_enable_hybrid_extraction = value | ||
| @property | ||
| def use_enable_substrate_network_extraction(self) -> bool: | ||
| """Flag indicating if modeling of substrate coupling effects is enabled using equivalent distributed RC | ||
| networks.""" | ||
| return self.core.use_enable_substrate_network_extraction | ||
| @use_enable_substrate_network_extraction.setter | ||
| def use_enable_substrate_network_extraction(self, value: bool): | ||
| self.core.use_enable_substrate_network_extraction = value | ||
| @property | ||
| def use_extract_floating_metals_dummy(self) -> bool: | ||
| """Flag indicating if floating metals are modeled as dummy fills.""" | ||
| return self.core.use_extract_floating_metals_dummy | ||
| @use_extract_floating_metals_dummy.setter | ||
| def use_extract_floating_metals_dummy(self, value: bool): | ||
| self.core.use_extract_floating_metals_dummy = value | ||
| @property | ||
| def use_extract_floating_metals_floating(self) -> bool: | ||
| """Flag indicating if floating metals are modeled as floating nets.""" | ||
| return self.core.use_extract_floating_metals_floating | ||
| @use_extract_floating_metals_floating.setter | ||
| def use_extract_floating_metals_floating(self, value: bool): | ||
| self.core.use_extract_floating_metals_floating = value | ||
| @property | ||
| def use_lde(self) -> bool: | ||
| """Flag indicating if variations in resistivity are taken into account.""" | ||
| return self.core.use_lde | ||
| @use_lde.setter | ||
| def use_lde(self, value: bool): | ||
| self.core.use_lde = value | ||
| @property | ||
| def use_mesh_frequency(self) -> bool: | ||
| """Flag indicating if mesh frequency is used.""" | ||
| return self.core.use_mesh_frequency | ||
| @use_mesh_frequency.setter | ||
| def use_mesh_frequency(self, value: bool): | ||
| self.core.use_mesh_frequency = value | ||
| @property | ||
| def use_override_shrink_factor(self) -> bool: | ||
| """Flag indicating if override shrink factor is used.""" | ||
| return self.core.use_override_shrink_factor | ||
| @use_override_shrink_factor.setter | ||
| def use_override_shrink_factor(self, value: bool): | ||
| self.core.use_override_shrink_factor = value | ||
| @property | ||
| def use_plane_projection_factor(self) -> bool: | ||
| """Flag indicating if plane projection factor is used.""" | ||
| return self.core.use_plane_projection_factor | ||
| @use_plane_projection_factor.setter | ||
| def use_plane_projection_factor(self, value: bool): | ||
| self.core.use_plane_projection_factor = value | ||
| @property | ||
| def use_relaxed_z_axis(self) -> bool: | ||
| """Flag indicating if simplified meshing is used along the z axis.""" | ||
| return self.core.use_relaxed_z_axis | ||
| @use_relaxed_z_axis.setter | ||
| def use_relaxed_z_axis(self, value: bool): | ||
| self.core.use_relaxed_z_axis = value |
@@ -17,3 +17,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| # FITNE SS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
@@ -24,12 +24,95 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| from ansys.edb.core.simulation_setup.raptor_x_simulation_settings import ( | ||
| RaptorXGeneralSettings as GrpcRaptorXGeneralSettings, | ||
| ) | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.raptor_x_simulation_settings import ( | ||
| RaptorXGeneralSettings as CoreRaptorXGeneralSettings, | ||
| ) | ||
| class RaptorXGeneralSettings(GrpcRaptorXGeneralSettings): | ||
| class RaptorXGeneralSettings: | ||
| """Raptor X general settings class.""" | ||
| def __init__(self, pedb, core): | ||
| super().__init__(core) | ||
| def __init__(self, pedb, core: "CoreRaptorXGeneralSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def global_temperature(self) -> float: | ||
| """Simulation temperature in degrees Celsius. | ||
| Returns | ||
| ------- | ||
| float | ||
| Global temperature in Kelvin. | ||
| """ | ||
| return self._pedb.value(self.core.global_temperature) | ||
| @global_temperature.setter | ||
| def global_temperature(self, value: float): | ||
| """Set simulation temperature in degrees Celsius. | ||
| Parameters | ||
| ---------- | ||
| value : float | ||
| Global temperature in Kelvin. | ||
| """ | ||
| self.core.global_temperature = self._pedb.value(value) | ||
| @property | ||
| def max_frequency(self) -> float: | ||
| """Maximum frequency for the simulation in Hz. | ||
| Returns | ||
| ------- | ||
| float | ||
| Maximum frequency in Hz. | ||
| """ | ||
| return self._pedb.value(self.core.max_frequency) | ||
| @max_frequency.setter | ||
| def max_frequency(self, value: float): | ||
| """Set maximum frequency for the simulation in Hz. | ||
| Parameters | ||
| ---------- | ||
| value : float | ||
| Maximum frequency in Hz. | ||
| """ | ||
| self.core.max_frequency = str(self._pedb.value(value)) | ||
| @property | ||
| def netlist_export_spectre(self) -> bool: | ||
| """Flag indicating if the netlist is exported in Spectre format.""" | ||
| return self.core.netlist_export_spectre | ||
| @netlist_export_spectre.setter | ||
| def netlist_export_spectre(self, value: bool): | ||
| self.core.netlist_export_spectre = value | ||
| @property | ||
| def save_netlist(self) -> bool: | ||
| """Flag indicating if the netlist is saved.""" | ||
| return self.core.save_netlist | ||
| @save_netlist.setter | ||
| def save_netlist(self, value: bool): | ||
| self.core.save_netlist = value | ||
| @property | ||
| def save_rfm(self) -> bool: | ||
| """Flag indicating if the RFM file is saved.""" | ||
| return self.core.save_rfm | ||
| @save_rfm.setter | ||
| def save_rfm(self, value: bool): | ||
| self.core.save_rfm = value | ||
| @property | ||
| def use_gold_em_solver(self) -> bool: | ||
| """Flag indicating if the Gold EM solver is used.""" | ||
| return self.core.use_gold_em_solver | ||
| @use_gold_em_solver.setter | ||
| def use_gold_em_solver(self, value: bool): | ||
| self.core.use_gold_em_solver = value |
@@ -17,3 +17,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| # FITNE SS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
@@ -24,6 +24,9 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| from ansys.edb.core.simulation_setup.raptor_x_simulation_setup import ( | ||
| RaptorXSimulationSettings as GrpcRaptorXSimulationSettings, | ||
| ) | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.raptor_x_simulation_setup import ( | ||
| RaptorXSimulationSettings as CoreRaptorXSimulationSettings, | ||
| ) | ||
| from pyedb.grpc.database.simulation_setup.raptor_x_advanced_settings import ( | ||
@@ -37,7 +40,7 @@ RaptorXAdvancedSettings, | ||
| class RaptorXSimulationSettings(GrpcRaptorXSimulationSettings): | ||
| class RaptorXSimulationSettings: | ||
| """Raptor X simulation settings class.""" | ||
| def __init__(self, pedb, core): | ||
| super().__init__(core) | ||
| def __init__(self, pedb, core: "CoreRaptorXSimulationSettings"): | ||
| self.core = core | ||
| self._pedb = pedb | ||
@@ -55,3 +58,3 @@ | ||
| """ | ||
| return RaptorXAdvancedSettings(self._pedb, self.advanced) | ||
| return RaptorXAdvancedSettings(self._pedb, self.core.advanced) | ||
@@ -68,2 +71,18 @@ @property | ||
| """ | ||
| RaptorXGeneralSettings(self._pedb, self.general) | ||
| return RaptorXGeneralSettings(self._pedb, self.core.general) | ||
| @property | ||
| def enabled(self) -> bool: | ||
| """Enabled flag. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Enabled flag. | ||
| """ | ||
| return self.core.enabled | ||
| @enabled.setter | ||
| def enabled(self, value: bool): | ||
| self.core.enabled = value |
@@ -17,3 +17,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| # FITNE SS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
@@ -24,104 +24,76 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| import warnings | ||
| from typing import TYPE_CHECKING | ||
| from ansys.edb.core.simulation_setup.raptor_x_simulation_setup import ( | ||
| RaptorXSimulationSetup as GrpcRaptorXSimulationSetup, | ||
| RaptorXSimulationSetup as CoreRaptorXSimulationSetup, | ||
| ) | ||
| from pyedb.grpc.database.simulation_setup.simulation_setup import SimulationSetup | ||
| if TYPE_CHECKING: | ||
| from pyedb.grpc.edb import Edb | ||
| from pyedb.grpc.database.simulation_setup.raptor_x_simulation_settings import RaptorXSimulationSettings | ||
| from pyedb.grpc.database.simulation_setup.sweep_data import SweepData | ||
| class RaptorXSimulationSetup(GrpcRaptorXSimulationSetup): | ||
| class RaptorXSimulationSetup(SimulationSetup): | ||
| """RaptorX simulation setup.""" | ||
| def __init__(self, pedb, core): | ||
| super().__init__(core.msg) | ||
| def __init__(self, pedb, core: "CoreRaptorXSimulationSetup"): | ||
| super().__init__(pedb, core) | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @property | ||
| def frequency_sweeps(self): | ||
| """Returns Frequency sweeps | ||
| . deprecated:: use sweep_data instead | ||
| @classmethod | ||
| def create(cls, edb: "Edb", name: str = "RaptorX_Simulation_Setup"): | ||
| """Create RaptorX simulation setup. | ||
| Parameters | ||
| ---------- | ||
| edb : PyEDB Edb object | ||
| PyEDB Edb object. | ||
| name : str | ||
| Name of the simulation setup. | ||
| Returns | ||
| ------- | ||
| RaptorXSimulationSetup | ||
| RaptorX simulation setup object. | ||
| """ | ||
| warnings.warn( | ||
| "`frequency_sweeps` is deprecated use `sweep_data` instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| return self.sweep_data | ||
| core = CoreRaptorXSimulationSetup.create(edb.active_cell, name) | ||
| return cls(edb, core) | ||
| def add_frequency_sweep( | ||
| self, name=None, distribution="linear", start_freq="0GHz", stop_freq="20GHz", step="10MHz", discrete=False | ||
| ): | ||
| """Add frequency sweep. | ||
| @property | ||
| def settings(self) -> RaptorXSimulationSettings: | ||
| """RaptorX simulation settings. | ||
| . deprecated:: pyedb 0.31.0 | ||
| Use :func:`add sweep` instead. | ||
| Returns | ||
| ------- | ||
| RaptorXSimulationSettings | ||
| RaptorX simulation settings object. | ||
| """ | ||
| warnings.warn( | ||
| "`add_frequency_sweep` is deprecated use `add_sweep` instead.", | ||
| DeprecationWarning, | ||
| ) | ||
| return self.add_sweep(name, distribution, start_freq, stop_freq, step, discrete) | ||
| return RaptorXSimulationSettings(self._pedb, self.core.settings) | ||
| def add_sweep( | ||
| self, name=None, distribution="linear", start_freq="0GHz", stop_freq="20GHz", step="10MHz", discrete=False | ||
| ) -> bool: | ||
| """Add a HFSS frequency sweep. | ||
| @property | ||
| def sweep_data(self) -> list[SweepData]: | ||
| """Returns Frequency sweeps. | ||
| Parameters | ||
| ---------- | ||
| name : str, optional | ||
| Sweep name. | ||
| distribution : str, optional | ||
| Type of the sweep. The default is `"linear"`. Options are: | ||
| - `"linear"` | ||
| - `"linear_count"` | ||
| - `"decade_count"` | ||
| - `"octave_count"` | ||
| - `"exponential"` | ||
| start_freq : str, float, optional | ||
| Starting frequency. The default is ``1``. | ||
| stop_freq : str, float, optional | ||
| Stopping frequency. The default is ``1e9``. | ||
| step : str, float, int, optional | ||
| Frequency step. The default is ``1e6``. or used for `"decade_count"`, "linear_count"`, "octave_count"` | ||
| distribution. Must be integer in that case. | ||
| discrete : bool, optional | ||
| Whether the sweep is discrete. The default is ``False``. | ||
| Returns | ||
| ------- | ||
| bool | ||
| list[SweepData] | ||
| List of SweepData objects. | ||
| """ | ||
| init_sweep_count = len(self.sweep_data) | ||
| start_freq = self._pedb.number_with_units(start_freq, "Hz") | ||
| stop_freq = self._pedb.number_with_units(stop_freq, "Hz") | ||
| step = str(step) | ||
| if distribution.lower() == "linear": | ||
| distribution = "LIN" | ||
| elif distribution.lower() == "linear_count": | ||
| distribution = "LINC" | ||
| elif distribution.lower() == "exponential": | ||
| distribution = "ESTP" | ||
| elif distribution.lower() == "decade_count": | ||
| distribution = "DEC" | ||
| elif distribution.lower() == "octave_count": | ||
| distribution = "OCT" | ||
| else: | ||
| distribution = "LIN" | ||
| if not name: | ||
| name = f"sweep_{init_sweep_count + 1}" | ||
| sweep_data = [ | ||
| SweepData(self._pedb, name=name, distribution=distribution, start_f=start_freq, end_f=stop_freq, step=step) | ||
| ] | ||
| if discrete: | ||
| sweep_data[0].type = sweep_data[0].type.DISCRETE_SWEEP | ||
| for sweep in self.sweep_data: | ||
| sweep_data.append(sweep) | ||
| self.sweep_data = sweep_data | ||
| if len(self.sweep_data) == init_sweep_count + 1: | ||
| return True | ||
| else: | ||
| self._pedb.logger.error("Failed to add frequency sweep data") | ||
| return False | ||
| sweeps = [] | ||
| for sweep in self.core.sweep_data: | ||
| sweeps.append(SweepData(self._pedb, core=sweep)) | ||
| return sweeps | ||
| @sweep_data.setter | ||
| def sweep_data(self, value: list[SweepData]): | ||
| sweep_data = [sweep.core for sweep in value] | ||
| self.core.sweep_data = sweep_data |
@@ -23,5 +23,10 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.database import ProductIdType as GrpcProductIdType | ||
| from ansys.edb.core.utility.value import Value as GrpcValue | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from pyedb.grpc.edb import Edb | ||
| from ansys.edb.core.database import ProductIdType as CoreProductIdType | ||
| from ansys.edb.core.utility.value import Value as CoreValue | ||
| from pyedb.generic.general_methods import generate_unique_name | ||
| from pyedb.siwave_core.cpa.simulation_setup_data_model import SIwaveCpaSetup, Vrm | ||
@@ -84,3 +89,3 @@ from pyedb.siwave_core.product_properties import SIwaveProperties | ||
| return self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_DIE_NAME | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_DIE_NAME | ||
| ).value | ||
@@ -97,3 +102,3 @@ | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_DIE_NAME, value | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_DIE_NAME, value | ||
| ) | ||
@@ -111,3 +116,3 @@ | ||
| pg_mode = self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_PIN_GROUPING_MODE | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_PIN_GROUPING_MODE | ||
| ).value | ||
@@ -136,3 +141,3 @@ return mode_mapping[int(pg_mode.split(":")[1])] if pg_mode else "perpin" | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_PIN_GROUPING_MODE, self.die_name + ":" + str(value) | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_PIN_GROUPING_MODE, self.die_name + ":" + str(value) | ||
| ) | ||
@@ -149,3 +154,3 @@ | ||
| cmp_exposure = self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_COMPONENT_EXPOSURE_CONFIG | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_COMPONENT_EXPOSURE_CONFIG | ||
| ).value | ||
@@ -177,3 +182,3 @@ cmp_dict = {} | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_COMPONENT_EXPOSURE_CONFIG, channel_comp_exposure | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_COMPONENT_EXPOSURE_CONFIG, channel_comp_exposure | ||
| ) | ||
@@ -193,3 +198,3 @@ | ||
| vrm = self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_VRM_SETUP | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_VRM_SETUP | ||
| ).value | ||
@@ -239,3 +244,3 @@ vrm_list = [] | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_VRM_SETUP, vrm_str | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_VRM_SETUP, vrm_str | ||
| ) | ||
@@ -354,3 +359,3 @@ | ||
| mode = self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_EXTRACTION_MODE | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_EXTRACTION_MODE | ||
| ).value | ||
@@ -365,7 +370,7 @@ if mode == "1": | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_EXTRACTION_MODE, "1" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_EXTRACTION_MODE, "1" | ||
| ) | ||
| else: | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_EXTRACTION_MODE, "0" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_EXTRACTION_MODE, "0" | ||
| ) | ||
@@ -382,3 +387,3 @@ | ||
| refine = self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_CUSTOM_REFINEMENT | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_CUSTOM_REFINEMENT | ||
| ).value | ||
@@ -393,7 +398,7 @@ if refine == "1": | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_CUSTOM_REFINEMENT, "1" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_CUSTOM_REFINEMENT, "1" | ||
| ) | ||
| else: | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_CUSTOM_REFINEMENT, "0" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_CUSTOM_REFINEMENT, "0" | ||
| ) | ||
@@ -410,3 +415,3 @@ | ||
| return self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_EXTRACTION_FREQUENCY | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_EXTRACTION_FREQUENCY | ||
| ).value | ||
@@ -416,5 +421,5 @@ | ||
| def extraction_frequency(self, value): | ||
| freq = str(GrpcValue(value)) | ||
| freq = str(CoreValue(value)) | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_EXTRACTION_FREQUENCY, freq | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_EXTRACTION_FREQUENCY, freq | ||
| ) | ||
@@ -431,3 +436,3 @@ | ||
| compute = self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_COMPUTE_CAPACITANCE | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_COMPUTE_CAPACITANCE | ||
| ).value | ||
@@ -442,7 +447,7 @@ if compute == "1": | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_COMPUTE_CAPACITANCE, "1" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_COMPUTE_CAPACITANCE, "1" | ||
| ) | ||
| else: | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_COMPUTE_CAPACITANCE, "0" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_COMPUTE_CAPACITANCE, "0" | ||
| ) | ||
@@ -459,3 +464,3 @@ | ||
| compute = self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_COMPUTE_DC_PARAMS | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_COMPUTE_DC_PARAMS | ||
| ).value | ||
@@ -470,7 +475,7 @@ if compute == "1": | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_COMPUTE_DC_PARAMS, "1" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_COMPUTE_DC_PARAMS, "1" | ||
| ) | ||
| else: | ||
| self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_COMPUTE_DC_PARAMS, "0" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_COMPUTE_DC_PARAMS, "0" | ||
| ) | ||
@@ -487,3 +492,3 @@ | ||
| _res = self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_DC_PARAMS_COMPUTE_RL | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_DC_PARAMS_COMPUTE_RL | ||
| ).value | ||
@@ -498,7 +503,7 @@ if _res == "1": | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_DC_PARAMS_COMPUTE_RL, "1" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_DC_PARAMS_COMPUTE_RL, "1" | ||
| ) | ||
| else: | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_DC_PARAMS_COMPUTE_RL, "0" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_DC_PARAMS_COMPUTE_RL, "0" | ||
| ) | ||
@@ -515,3 +520,3 @@ | ||
| _res = self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_DC_PARAMS_COMPUTE_CG | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_DC_PARAMS_COMPUTE_CG | ||
| ).value | ||
@@ -526,7 +531,7 @@ if _res == "1": | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_DC_PARAMS_COMPUTE_CG, "1" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_DC_PARAMS_COMPUTE_CG, "1" | ||
| ) | ||
| else: | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_DC_PARAMS_COMPUTE_CG, "0" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_DC_PARAMS_COMPUTE_CG, "0" | ||
| ) | ||
@@ -543,3 +548,3 @@ | ||
| _res = self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_AC_PARAMS_COMPUTE_RL | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_AC_PARAMS_COMPUTE_RL | ||
| ).value | ||
@@ -554,7 +559,7 @@ if _res == "1": | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_AC_PARAMS_COMPUTE_RL, "1" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_AC_PARAMS_COMPUTE_RL, "1" | ||
| ) | ||
| else: | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_AC_PARAMS_COMPUTE_RL, "0" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_AC_PARAMS_COMPUTE_RL, "0" | ||
| ) | ||
@@ -571,3 +576,3 @@ | ||
| _res = self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_GROUND_PG_NETS_FOR_SI | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_GROUND_PG_NETS_FOR_SI | ||
| ).value | ||
@@ -582,7 +587,7 @@ if _res == "1": | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_GROUND_PG_NETS_FOR_SI, "1" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_GROUND_PG_NETS_FOR_SI, "1" | ||
| ) | ||
| else: | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_GROUND_PG_NETS_FOR_SI, "0" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_GROUND_PG_NETS_FOR_SI, "0" | ||
| ) | ||
@@ -599,3 +604,3 @@ | ||
| _res = self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_SMALL_HOLE_DIAMETER | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_SMALL_HOLE_DIAMETER | ||
| ).value | ||
@@ -611,7 +616,7 @@ if _res == "-1": | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_SMALL_HOLE_DIAMETER, "-1" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_SMALL_HOLE_DIAMETER, "-1" | ||
| ) | ||
| else: | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_SMALL_HOLE_DIAMETER, str(GrpcValue(value)) | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_SMALL_HOLE_DIAMETER, str(CoreValue(value)) | ||
| ) | ||
@@ -628,3 +633,3 @@ | ||
| return self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_MODEL_TYPE | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_MODEL_TYPE | ||
| ).value | ||
@@ -635,3 +640,3 @@ | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_MODEL_TYPE, value.lower() | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_MODEL_TYPE, value.lower() | ||
| ) | ||
@@ -649,3 +654,3 @@ | ||
| self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_CG_MAX_PASSES | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_CG_MAX_PASSES | ||
| ).value | ||
@@ -657,3 +662,3 @@ ) | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_CG_MAX_PASSES, str(int(value)) | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_CG_MAX_PASSES, str(int(value)) | ||
| ) | ||
@@ -671,3 +676,3 @@ | ||
| self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_CG_PERCENT_ERROR | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_CG_PERCENT_ERROR | ||
| ).value | ||
@@ -679,3 +684,3 @@ ) | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_CG_PERCENT_ERROR, str(float(value)) | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_CG_PERCENT_ERROR, str(float(value)) | ||
| ) | ||
@@ -693,3 +698,3 @@ | ||
| self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_CG_PERCENT_REFINEMENT_PER_PASS | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_CG_PERCENT_REFINEMENT_PER_PASS | ||
| ).value | ||
@@ -701,3 +706,3 @@ ) | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, | ||
| CoreProductIdType.SIWAVE, | ||
| SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_CG_PERCENT_REFINEMENT_PER_PASS, | ||
@@ -718,3 +723,3 @@ str(float(value)), | ||
| self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_RL_MAX_PASSES | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_RL_MAX_PASSES | ||
| ).value | ||
@@ -727,3 +732,3 @@ ) | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_RL_MAX_PASSES, str(float(value)) | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_RL_MAX_PASSES, str(float(value)) | ||
| ) | ||
@@ -741,3 +746,3 @@ | ||
| self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_RL_PERCENT_ERROR | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_RL_PERCENT_ERROR | ||
| ).value | ||
@@ -749,3 +754,3 @@ ) | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_RL_PERCENT_ERROR, str(float(value)) | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_RL_PERCENT_ERROR, str(float(value)) | ||
| ) | ||
@@ -763,3 +768,3 @@ | ||
| self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_RL_PERCENT_REFINEMENT_PER_PASS | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_RL_PERCENT_REFINEMENT_PER_PASS | ||
| ).value | ||
@@ -771,3 +776,3 @@ ) | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, | ||
| CoreProductIdType.SIWAVE, | ||
| SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_RL_PERCENT_REFINEMENT_PER_PASS, | ||
@@ -786,3 +791,3 @@ str(float(value)), | ||
| _res = self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_RETURN_PATH_NET_FOR_LOOP_PARAMS | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_RETURN_PATH_NET_FOR_LOOP_PARAMS | ||
| ).value | ||
@@ -797,7 +802,7 @@ if _res == "1": | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_RETURN_PATH_NET_FOR_LOOP_PARAMS, "1" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_RETURN_PATH_NET_FOR_LOOP_PARAMS, "1" | ||
| ) | ||
| else: | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_RETURN_PATH_NET_FOR_LOOP_PARAMS, "0" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_RETURN_PATH_NET_FOR_LOOP_PARAMS, "0" | ||
| ) | ||
@@ -836,3 +841,3 @@ | ||
| not self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, | ||
| CoreProductIdType.SIWAVE, | ||
| SIwaveProperties.CPA_SIM_NAME, | ||
@@ -842,3 +847,3 @@ ) | ||
| ): | ||
| self._pedb.active_cell.set_product_property(GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_SIM_NAME, name) | ||
| self._pedb.active_cell.set_product_property(CoreProductIdType.SIWAVE, SIwaveProperties.CPA_SIM_NAME, name) | ||
@@ -854,2 +859,26 @@ def __init_values(self): | ||
| @classmethod | ||
| def create(cls, edb: "Edb", name=None, siwave_cpa_setup_class=None) -> "SIWaveCPASimulationSetup": | ||
| """Creates a new SIWaveCPASimulationSetup instance. | ||
| Parameters: | ||
| ----------- | ||
| edb (pyedb.Edb): The EDB object representing the active design. | ||
| name (str, optional): The name of the simulation setup. If not provided, a unique name will be generated. | ||
| siwave_cpa_setup_class (SIwaveCpaSetup, optional): An optional configuration object to initialize the setup. | ||
| #Returns: | ||
| -------- | ||
| SIWaveCPASimulationSetup: A new instance of SIWaveCPASimulationSetup. | ||
| """ | ||
| if not name: | ||
| if not siwave_cpa_setup_class: | ||
| name = generate_unique_name("cpa_setup") | ||
| else: | ||
| name = siwave_cpa_setup_class.name | ||
| cpa_setup = SIWaveCPASimulationSetup(edb, name=name, siwave_cpa_setup_class=siwave_cpa_setup_class) | ||
| if siwave_cpa_setup_class: | ||
| cpa_setup._apply_cfg_object(siwave_cpa_setup_class) | ||
| return cpa_setup | ||
| def _apply_cfg_object(self, siwave_cpa_setup_class): | ||
@@ -881,3 +910,3 @@ """ | ||
| return self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_SIM_NAME | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_SIM_NAME | ||
| ).value | ||
@@ -887,3 +916,3 @@ | ||
| def name(self, value): | ||
| self._pedb.active_cell.set_product_property(GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_SIM_NAME, value) | ||
| self._pedb.active_cell.set_product_property(CoreProductIdType.SIWAVE, SIwaveProperties.CPA_SIM_NAME, value) | ||
@@ -899,3 +928,3 @@ @property | ||
| cpa_mode = self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_SETUP | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_SETUP | ||
| ).value | ||
@@ -910,7 +939,7 @@ if cpa_mode == "1": | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_SETUP, "1" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_SETUP, "1" | ||
| ) | ||
| else: | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_SETUP, "0" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_CHANNEL_SETUP, "0" | ||
| ) | ||
@@ -927,3 +956,3 @@ | ||
| mod_type = self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_ESD_R_MODEL | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_ESD_R_MODEL | ||
| ).value | ||
@@ -938,5 +967,5 @@ if mod_type == "0": | ||
| if value == "rlcg": | ||
| self._pedb.active_cell.set_product_property(GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_ESD_R_MODEL, "0") | ||
| self._pedb.active_cell.set_product_property(CoreProductIdType.SIWAVE, SIwaveProperties.CPA_ESD_R_MODEL, "0") | ||
| elif value == "esd_r": | ||
| self._pedb.active_cell.set_product_property(GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_ESD_R_MODEL, "1") | ||
| self._pedb.active_cell.set_product_property(CoreProductIdType.SIWAVE, SIwaveProperties.CPA_ESD_R_MODEL, "1") | ||
@@ -954,3 +983,3 @@ @property | ||
| self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_USE_Q3D_SOLVER | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_USE_Q3D_SOLVER | ||
| ).value | ||
@@ -964,7 +993,7 @@ ) | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_USE_Q3D_SOLVER, "1" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_USE_Q3D_SOLVER, "1" | ||
| ) | ||
| else: | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_USE_Q3D_SOLVER, "0" | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_USE_Q3D_SOLVER, "0" | ||
| ) | ||
@@ -981,3 +1010,3 @@ | ||
| return self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_NET_PROCESSING_MODE | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_NET_PROCESSING_MODE | ||
| ).value | ||
@@ -988,3 +1017,3 @@ | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_NET_PROCESSING_MODE, str(value) | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_NET_PROCESSING_MODE, str(value) | ||
| ) | ||
@@ -1031,3 +1060,3 @@ | ||
| nets = self._pedb.active_cell.get_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_NETS_TO_PROCESS | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_NETS_TO_PROCESS | ||
| ).value | ||
@@ -1041,5 +1070,5 @@ return nets.split("*") | ||
| self._pedb.active_cell.set_product_property( | ||
| GrpcProductIdType.SIWAVE, SIwaveProperties.CPA_NETS_TO_PROCESS, nets | ||
| CoreProductIdType.SIWAVE, SIwaveProperties.CPA_NETS_TO_PROCESS, nets | ||
| ) | ||
| else: | ||
| raise TypeError("nets_to_process must be a list of strings.") |
@@ -24,12 +24,66 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| import warnings | ||
| from ansys.edb.core.simulation_setup.siwave_dcir_simulation_setup import ( | ||
| SIWaveDCIRSimulationSetup as Grpcsiwave_dcir_simulation_setup, | ||
| SIWaveDCIRSimulationSetup as CoreSIWaveDCIRSimulationSetup, | ||
| ) | ||
| import pyedb | ||
| from pyedb.grpc.database.simulation_setup.simulation_setup import SimulationSetup | ||
| from pyedb.grpc.database.simulation_setup.siwave_dc_settings import SIWaveDCSettings | ||
| from pyedb.grpc.database.simulation_setup.siwave_simulation_settings import SIWaveSimulationSettings | ||
| class SIWaveDCIRSimulationSetup(Grpcsiwave_dcir_simulation_setup): | ||
| class SIWaveDCIRSimulationSetup(SimulationSetup): | ||
| """Siwave Dcir simulation setup class.""" | ||
| def __init__(self, pedb, core): | ||
| super().__init__(core.msg) | ||
| def __init__(self, pedb, core: "CoreSIWaveDCIRSimulationSetup"): | ||
| super().__init__(pedb, core) | ||
| self.core = core | ||
| self._pedb = pedb | ||
| @classmethod | ||
| def create(cls, edb: "pyedb.Edb", name: str = "Siwave_DCIR"): | ||
| """Create a SIWave DCIR simulation setup. | ||
| Parameters | ||
| ---------- | ||
| edb : Edb object | ||
| An EDB instance. | ||
| name : str | ||
| Name of the simulation setup. | ||
| Returns | ||
| ------- | ||
| SIWaveDCIRSimulationSetup | ||
| The SIWave DCIR simulation setup object. | ||
| """ | ||
| core_setup = CoreSIWaveDCIRSimulationSetup.create(edb.active_cell, name=name) | ||
| return cls(edb, core_setup) | ||
| @property | ||
| def dc_ir_settings(self): | ||
| """SIWave DCIR simulation settings. | ||
| ... deprecated:: 0.77.3 | ||
| Use :attr:`settings.dc | ||
| <pyedb.grpc.database.simulation_setup.siwave_dcir_simulation_setup.SIWaveDCIRSimulationSetup.settings>` | ||
| instead. | ||
| """ | ||
| warnings.warn("`dc_ir_settings` is deprecated. Use `settings.dc` instead.", DeprecationWarning) | ||
| return SIWaveDCSettings(self._pedb, self.core.settings) | ||
| @property | ||
| def settings(self) -> SIWaveSimulationSettings: | ||
| """SIWave DCIR simulation settings. | ||
| Returns | ||
| ------- | ||
| SIWaveSimulationSettings | ||
| The SIWave DCIR simulation settings object. | ||
| """ | ||
| return SIWaveSimulationSettings(self._pedb, self.core.settings) |
@@ -17,3 +17,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| # FITNE SS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
@@ -24,21 +24,52 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| from ansys.edb.core.simulation_setup.simulation_setup import ( | ||
| SimulationSetupType as GrpcSimulationSetupType, | ||
| ) | ||
| from ansys.edb.core.simulation_setup.siwave_simulation_setup import ( | ||
| SIWaveSimulationSetup as GrpcSIWaveSimulationSetup, | ||
| ) | ||
| from typing import TYPE_CHECKING | ||
| from pyedb.grpc.database.simulation_setup.sweep_data import SweepData | ||
| from ansys.edb.core.simulation_setup.siwave_simulation_setup import SIWaveSimulationSetup as CoreSIWaveSimulationSetup | ||
| from pyedb.grpc.database.simulation_setup.simulation_setup import SimulationSetup | ||
| from pyedb.grpc.database.simulation_setup.siwave_advanced_settings import SIWaveAdvancedSettings | ||
| from pyedb.grpc.database.simulation_setup.siwave_dc_advanced import SIWaveDCAdvancedSettings | ||
| from pyedb.grpc.database.simulation_setup.siwave_dc_settings import SIWaveDCSettings | ||
| from pyedb.grpc.database.simulation_setup.siwave_simulation_settings import SIWaveSimulationSettings | ||
| class SiwaveSimulationSetup(GrpcSIWaveSimulationSetup): | ||
| if TYPE_CHECKING: | ||
| from pyedb.grpc.edb import Edb | ||
| class SiwaveSimulationSetup(SimulationSetup): | ||
| """SIwave simulation setup class.""" | ||
| def __init__(self, pedb, core=None): | ||
| super().__init__(core.msg if core else None) | ||
| def __init__(self, pedb, core: "CoreSIWaveSimulationSetup"): | ||
| super().__init__(pedb, core) | ||
| # give static analyzers a concrete type for core | ||
| self.core: CoreSIWaveSimulationSetup = core | ||
| self._pedb = pedb | ||
| @classmethod | ||
| def create(cls, edb: "Edb", name: str = "siwave_setup") -> "SiwaveSimulationSetup": | ||
| """Create a SIWave simulation setup object. | ||
| Parameters | ||
| ---------- | ||
| edb : :class:`Edb` | ||
| Inherited object. | ||
| name : str, optional | ||
| Name of the simulation setup. The default is "siwave_setup". | ||
| Returns | ||
| ------- | ||
| SiwaveSimulationSetup | ||
| The SIWave simulation setup object. | ||
| """ | ||
| core = CoreSIWaveSimulationSetup.create(edb.active_cell, name) | ||
| return cls(edb, core) | ||
| @property | ||
| def advanced_settings(self): | ||
| def settings(self) -> SIWaveSimulationSettings: | ||
| """Setup simulation settings.""" | ||
| return SIWaveSimulationSettings(self._pedb, self.core.settings) | ||
| @property | ||
| def advanced_settings(self) -> SIWaveAdvancedSettings: | ||
| """Setup advanced settings.""" | ||
@@ -48,3 +79,3 @@ return self.settings.advanced | ||
| @property | ||
| def dc_settings(self): | ||
| def dc_settings(self) -> SIWaveDCSettings: | ||
| """Setup dc settings.""" | ||
@@ -54,129 +85,4 @@ return self.settings.dc | ||
| @property | ||
| def dc_advanced_settings(self): | ||
| def dc_advanced_settings(self) -> SIWaveDCAdvancedSettings: | ||
| """Setup dc settings.""" | ||
| return self.settings.dc_advanced | ||
| @property | ||
| def type(self) -> str: | ||
| """Simulation setup type. | ||
| Returns | ||
| ------- | ||
| str | ||
| Simulation type. | ||
| """ | ||
| return super().type.name | ||
| @type.setter | ||
| def type(self, value): | ||
| if value.upper() == "SI_WAVE": | ||
| super(SiwaveSimulationSetup, self.__class__).type.__set__(self, GrpcSimulationSetupType.SI_WAVE) | ||
| elif value.upper() == "SI_WAVE_DCIR": | ||
| super(SiwaveSimulationSetup, self.__class__).type.__set__(self, GrpcSimulationSetupType.SI_WAVE_DCIR) | ||
| def add_sweep( | ||
| self, | ||
| name=None, | ||
| distribution="linear", | ||
| start_freq="0GHz", | ||
| stop_freq="20GHz", | ||
| step="10MHz", | ||
| discrete=False, | ||
| frequency_set=None, | ||
| ) -> bool: | ||
| """Add a HFSS frequency sweep. | ||
| Parameters | ||
| ---------- | ||
| name : str, optional | ||
| Sweep name. | ||
| distribution : str, optional | ||
| Type of the sweep. The default is `"linear"`. Options are: | ||
| - `"linear"` | ||
| - `"linear_count"` | ||
| - `"decade_count"` | ||
| - `"octave_count"` | ||
| - `"exponential"` | ||
| start_freq : str, float, optional | ||
| Starting frequency. The default is ``1``. | ||
| stop_freq : str, float, optional | ||
| Stopping frequency. The default is ``1e9``. | ||
| step : str, float, int, optional | ||
| Frequency step. The default is ``1e6``. or used for `"decade_count"`, "linear_count"`, "octave_count"` | ||
| distribution. Must be integer in that case. | ||
| discrete : bool, optional | ||
| Whether the sweep is discrete. The default is ``False``. | ||
| frequency_set : List, optional | ||
| Frequency set is a list adding one or more frequency sweeps. If ``frequency_set`` is provided, the other | ||
| arguments are ignored except ``discrete``. Default value is ``None``. | ||
| example of frequency_set : [['linear_scale', '50MHz', '200MHz', '10MHz']]. | ||
| Returns | ||
| ------- | ||
| bool | ||
| """ | ||
| init_sweep_count = len(self.sweep_data) | ||
| if frequency_set: | ||
| for sweep in frequency_set: | ||
| if "linear_scale" in sweep: | ||
| distribution = "LIN" | ||
| elif "linear_count" in sweep: | ||
| distribution = "LINC" | ||
| elif "exponential" in sweep: | ||
| distribution = "ESTP" | ||
| elif "log_scale" in sweep: | ||
| distribution = "DEC" | ||
| elif "octave_count" in sweep: | ||
| distribution = "OCT" | ||
| else: | ||
| distribution = "LIN" | ||
| start_freq = self._pedb.number_with_units(sweep[1], "Hz") | ||
| stop_freq = self._pedb.number_with_units(sweep[2], "Hz") | ||
| step = str(sweep[3]) | ||
| if not name: | ||
| name = f"sweep_{init_sweep_count + 1}" | ||
| sweep_data = [ | ||
| SweepData( | ||
| self._pedb, name=name, distribution=distribution, start_f=start_freq, end_f=stop_freq, step=step | ||
| ) | ||
| ] | ||
| if discrete: | ||
| sweep_data[0].type = sweep_data[0].type.DISCRETE_SWEEP | ||
| for sweep in self.sweep_data: | ||
| sweep_data.append(sweep) | ||
| self.sweep_data = sweep_data | ||
| return sweep_data[0] | ||
| else: | ||
| start_freq = self._pedb.number_with_units(start_freq, "Hz") | ||
| stop_freq = self._pedb.number_with_units(stop_freq, "Hz") | ||
| step = str(step) | ||
| if distribution.lower() == "linear": | ||
| distribution = "LIN" | ||
| elif distribution.lower() == "linear_count": | ||
| distribution = "LINC" | ||
| elif distribution.lower() == "exponential": | ||
| distribution = "ESTP" | ||
| elif distribution.lower() == "decade_count": | ||
| distribution = "DEC" | ||
| elif distribution.lower() == "octave_count": | ||
| distribution = "OCT" | ||
| else: | ||
| distribution = "LIN" | ||
| if not name: | ||
| name = f"sweep_{init_sweep_count + 1}" | ||
| sweep_data = [ | ||
| SweepData( | ||
| self._pedb, name=name, distribution=distribution, start_f=start_freq, end_f=stop_freq, step=step | ||
| ) | ||
| ] | ||
| if discrete: | ||
| sweep_data[0].type = sweep_data[0].type.DISCRETE_SWEEP | ||
| for sweep in self.sweep_data: | ||
| sweep_data.append(sweep) | ||
| self.sweep_data = sweep_data | ||
| if len(self.sweep_data) == init_sweep_count + 1: | ||
| return sweep_data[0] | ||
| else: | ||
| self._pedb.logger.error("Failed to add frequency sweep data") | ||
| return False |
@@ -23,20 +23,348 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from typing import TYPE_CHECKING | ||
| if TYPE_CHECKING: | ||
| from ansys.edb.core.simulation_setup.simulation_setup import SweepData as CoreSweepData | ||
| from ansys.edb.core.simulation_setup.simulation_setup import ( | ||
| Distribution as GrpcDistribution, | ||
| FrequencyData as GrpcFrequencyData, | ||
| SweepData as GrpcSweepData, | ||
| Distribution as CoreDistribution, | ||
| FreqSweepType as CoreSweepType, | ||
| FrequencyData as CoreFrequencyData, | ||
| SweepData as CoreSweepData, | ||
| ) | ||
| _mapping_distribution = { | ||
| "lin": CoreDistribution.LIN, | ||
| "dec": CoreDistribution.DEC, | ||
| "estp": CoreDistribution.ESTP, | ||
| "linc": CoreDistribution.LINC, | ||
| "oct": CoreDistribution.OCT, | ||
| "LIN": CoreDistribution.LIN, | ||
| "DEC": CoreDistribution.DEC, | ||
| "ESTP": CoreDistribution.ESTP, | ||
| "LINC": CoreDistribution.LINC, | ||
| "OCT": CoreDistribution.OCT, | ||
| } | ||
| class SweepData(GrpcSweepData): | ||
| """Frequency sweep data class.""" | ||
| _mapping_sweep_type = { | ||
| "interpolating": CoreSweepType.INTERPOLATING_SWEEP, | ||
| "discrete": CoreSweepType.DISCRETE_SWEEP, | ||
| "broadband": CoreSweepType.BROADBAND_SWEEP, | ||
| "INTERPOLATING": CoreSweepType.INTERPOLATING_SWEEP, | ||
| "DISCRETE": CoreSweepType.DISCRETE_SWEEP, | ||
| "BROADBAND": CoreSweepType.BROADBAND_SWEEP, | ||
| } | ||
| def __init__(self, pedb, name, distribution, start_f, end_f, step, core=None): | ||
| super().__init__( | ||
| name=name, | ||
| frequency_data=GrpcFrequencyData( | ||
| distribution=GrpcDistribution[distribution], start_f=start_f, end_f=end_f, step=step | ||
| ), | ||
| ) | ||
| self._edb_object = core | ||
| class FrequencyData: | ||
| def __init__(self, core: "CoreFrequencyData"): | ||
| self._core = core | ||
| @property | ||
| def distribution(self) -> str: | ||
| """Get the distribution type of the frequency data. | ||
| Returns | ||
| ------- | ||
| str | ||
| Distribution type. Values are: "lin", "dec", "estp", "linc", "oct". | ||
| """ | ||
| return self._core.distribution.name.lower() | ||
| @distribution.setter | ||
| def distribution(self, value: str): | ||
| if value not in _mapping_distribution: | ||
| raise ValueError( | ||
| f"Unsupported distribution type: {value}. Supported types are: {list(_mapping_distribution.keys())}" | ||
| ) | ||
| self._core.distribution = _mapping_distribution[value] | ||
| @property | ||
| def start_frequency(self) -> str: | ||
| """Get the start frequency in Hz. | ||
| Returns | ||
| ------- | ||
| str | ||
| Start frequency in Hz. | ||
| """ | ||
| return self._core.start_f | ||
| @start_frequency.setter | ||
| def start_frequency(self, value: float): | ||
| self._core.start_f = str(value) | ||
| @property | ||
| def end_frequency(self) -> str: | ||
| """Get the end frequency in Hz. | ||
| Returns | ||
| ------- | ||
| str | ||
| End frequency in Hz. | ||
| """ | ||
| return self._core.end_f | ||
| @end_frequency.setter | ||
| def end_frequency(self, value: float): | ||
| self._core.end_f = str(value) | ||
| @property | ||
| def step(self) -> str: | ||
| """Get the frequency step in Hz. | ||
| Returns | ||
| ------- | ||
| str | ||
| Frequency step in Hz. | ||
| """ | ||
| return self._core.step | ||
| @step.setter | ||
| def step(self, value: float): | ||
| self._core.step = str(value) | ||
| class SweepData: | ||
| """Frequency sweep data class. | ||
| PARAMETERS | ||
| ---------- | ||
| pedb : Pedb | ||
| Parent EDB object. | ||
| name : str, default: “” | ||
| Name of the sweep data. | ||
| distribution : str, default: “lin” | ||
| Distribution type of the frequency sweep. Supported types are: "lin", "dec", "estp", "linc", "oct". | ||
| start_f : float, default: 0.0 | ||
| Start frequency of the sweep in Hz. | ||
| end_f : float, default: 10e9 | ||
| End frequency of the sweep in Hz. | ||
| step : float, default: 10e6 | ||
| Frequency step of the sweep in Hz. | ||
| """ | ||
| def __init__( | ||
| self, | ||
| pedb, | ||
| name="sweep_data", | ||
| distribution="lin", | ||
| start_f=0.0, | ||
| end_f=10e9, | ||
| step=10e6, | ||
| core: "GrpcSweepData" = None, | ||
| ): | ||
| self._pedb = pedb | ||
| if core: | ||
| self.core = core | ||
| else: | ||
| if distribution not in _mapping_distribution: | ||
| raise ValueError( | ||
| f"Unsupported distribution type: {distribution}. " | ||
| f"Supported types are: {list(_mapping_distribution.keys())}" | ||
| ) | ||
| distribution = _mapping_distribution[distribution] | ||
| self.core = CoreSweepData( | ||
| name=name, | ||
| frequency_data=CoreFrequencyData( | ||
| distribution=distribution, | ||
| start_f=str(self._pedb.value(start_f)), | ||
| end_f=str(self._pedb.value(end_f)), | ||
| step=str(self._pedb.value(step)), | ||
| ), | ||
| ) | ||
| @property | ||
| def name(self) -> str: | ||
| """Get the name of the frequency sweep data.""" | ||
| return self.core.name | ||
| @name.setter | ||
| def name(self, value: str): | ||
| """Set the name of the frequency sweep data.""" | ||
| self.core.name = value | ||
| @property | ||
| def frequency_data(self) -> CoreFrequencyData: | ||
| """Get the frequency data of the sweep. | ||
| Returns | ||
| ------- | ||
| GrpcFrequencyData | ||
| Frequency data object. | ||
| """ | ||
| return FrequencyData(self.core.frequency_data) | ||
| @property | ||
| def enabled(self) -> bool: | ||
| """Get the enabled status of the frequency sweep. | ||
| Returns | ||
| ------- | ||
| bool | ||
| Enabled status. | ||
| """ | ||
| return self.core.enabled | ||
| @enabled.setter | ||
| def enabled(self, value: bool): | ||
| self.core.enabled = value | ||
| @property | ||
| def type(self) -> str: | ||
| """Get the type of the frequency sweep. | ||
| Returns | ||
| ------- | ||
| str | ||
| Frequency sweep type. Values are: "interpolating", "discrete", "broadband". | ||
| """ | ||
| return self.core.type.name.lower().split("_")[0] | ||
| @type.setter | ||
| def type(self, value: str): | ||
| if value not in _mapping_sweep_type: | ||
| raise ValueError( | ||
| f"Unsupported sweep type: {value}. Supported types are: {list(_mapping_sweep_type.keys())}" | ||
| ) | ||
| self.core.type = _mapping_sweep_type[value] | ||
| @property | ||
| def use_q3d_for_dc(self) -> bool: | ||
| """Get the flag indicating if Q3D is used for DC bias. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if Q3D is used for DC bias, False otherwise. | ||
| """ | ||
| return self.core.use_q3d_for_dc | ||
| @use_q3d_for_dc.setter | ||
| def use_q3d_for_dc(self, value: bool): | ||
| self.core.use_q3d_for_dc = value | ||
| @property | ||
| def save_fields(self) -> bool: | ||
| """Get the flag indicating if fields are saved during the sweep. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if fields are saved, False otherwise. | ||
| """ | ||
| return self.core.save_fields | ||
| @save_fields.setter | ||
| def save_fields(self, value: bool): | ||
| self.core.save_fields = value | ||
| @property | ||
| def save_rad_fields_only(self) -> bool: | ||
| """Get the flag indicating if only radiation fields are saved. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if only radiation fields are saved, False otherwise. | ||
| """ | ||
| return self.core.save_rad_fields_only | ||
| @save_rad_fields_only.setter | ||
| def save_rad_fields_only(self, value: bool): | ||
| self.core.save_rad_fields_only = value | ||
| @property | ||
| def compute_dc_point(self) -> bool: | ||
| """Get the flag indicating if DC point is computed. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if DC point is computed, False otherwise. | ||
| """ | ||
| return self.core.compute_dc_point | ||
| @compute_dc_point.setter | ||
| def compute_dc_point(self, value: bool): | ||
| self.core.compute_dc_point = value | ||
| @property | ||
| def siwave_with_3dddm(self) -> bool: | ||
| """Get the flag indicating if SIwave with 3D-DDM is used. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if SIwave with 3D-DDM is used, False otherwise. | ||
| """ | ||
| return self.core.siwave_with_3dddm | ||
| @siwave_with_3dddm.setter | ||
| def siwave_with_3dddm(self, value: bool): | ||
| self.core.siwave_with_3dddm = value | ||
| @property | ||
| def use_hfss_solver_regions(self) -> bool: | ||
| """Get the flag indicating if HFSS solver regions are used. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if HFSS solver regions are used, False otherwise. | ||
| """ | ||
| return self.core.use_hfss_solver_regions | ||
| @use_hfss_solver_regions.setter | ||
| def use_hfss_solver_regions(self, value: bool): | ||
| self.core.use_hfss_solver_regions = value | ||
| @property | ||
| def frequency_string(self) -> str: | ||
| """Get the frequency sweep string. | ||
| Returns | ||
| ------- | ||
| str | ||
| Frequency sweep string. | ||
| """ | ||
| return self.core.frequency_string.strip() | ||
| @property | ||
| def enforce_causality(self) -> bool: | ||
| """Get the flag indicating if causality is enforced. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if causality is enforced, False otherwise. | ||
| """ | ||
| return self.core.interpolation_data.enforce_causality | ||
| @enforce_causality.setter | ||
| def enforce_causality(self, value: bool): | ||
| self.core.interpolation_data.enforce_causality = value | ||
| @property | ||
| def enforce_passivity(self) -> bool: | ||
| """Get the flag indicating if passivity is enforced. | ||
| Returns | ||
| ------- | ||
| bool | ||
| True if passivity is enforced, False otherwise. | ||
| """ | ||
| return self.core.interpolation_data.enforce_passivity | ||
| @enforce_passivity.setter | ||
| def enforce_passivity(self, value: bool): | ||
| self.core.interpolation_data.enforce_passivity = value | ||
| @property | ||
| def interpolation_data(self): | ||
| """Get the interpolation data points. | ||
| Returns | ||
| ------- | ||
| list[float] | ||
| List of interpolation data points in Hz. | ||
| """ | ||
| return self.core.interpolation_data |
@@ -29,11 +29,9 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| import os | ||
| from typing import Any, Dict, Optional, Union | ||
| from typing import TYPE_CHECKING, Any, Dict, Optional, Union, cast | ||
| if TYPE_CHECKING: | ||
| from pyedb.grpc.database.simulation_setup.siwave_simulation_setup import SiwaveSimulationSetup | ||
| import warnings | ||
| from ansys.edb.core.database import ProductIdType as GrpcProductIdType | ||
| from ansys.edb.core.simulation_setup.simulation_setup import ( | ||
| Distribution as GrpcDistribution, | ||
| FrequencyData as GrpcFrequencyData, | ||
| SweepData as GrpcSweepData, | ||
| ) | ||
| from ansys.edb.core.database import ProductIdType as CoreProductIdType | ||
@@ -536,3 +534,3 @@ from pyedb.grpc.database.simulation_setup.siwave_cpa_simulation_setup import ( | ||
| touchstone_file_path: str = "", | ||
| ) -> bool: | ||
| ) -> str: | ||
| """Create an executable file. | ||
@@ -556,4 +554,4 @@ | ||
| ------- | ||
| bool | ||
| ``True`` if file was created, ``False`` otherwise. | ||
| str | ||
| Path to the created exec file. | ||
@@ -572,3 +570,5 @@ Examples | ||
| workdir = os.path.dirname(self._pedb.edbpath) | ||
| file_name = os.path.join(workdir, os.path.splitext(os.path.basename(self._pedb.edbpath))[0] + ".exec") | ||
| file_name: str = cast( | ||
| str, os.path.join(workdir, os.path.splitext(os.path.basename(self._pedb.edbpath))[0] + ".exec") | ||
| ) | ||
| if os.path.isfile(file_name): | ||
@@ -593,15 +593,17 @@ os.remove(file_name) | ||
| return file_name | ||
| return str(file_name) | ||
| def add_cpa_analysis(self, name=None, siwave_cpa_setup_class=None): | ||
| if not name: | ||
| from pyedb.generic.general_methods import generate_unique_name | ||
| """Add a SIwave CPA analysis to EDB. | ||
| if not siwave_cpa_setup_class: | ||
| name = generate_unique_name("cpa_setup") | ||
| else: | ||
| name = siwave_cpa_setup_class.name | ||
| cpa_setup = SIWaveCPASimulationSetup(self._pedb, name=name, siwave_cpa_setup_class=siwave_cpa_setup_class) | ||
| return cpa_setup | ||
| .. deprecated:: pyedb 0.77.3 | ||
| Use :func:`pyedb.grpc.database.simulation_setup.siwave_cpa_simulation_setup.SiwaveCPASimulationSetup.create` | ||
| instead. | ||
| """ | ||
| warnings.warn( | ||
| "`add_cpa_analysis` is deprecated. Use `SiwaveCPASimulationSetup.create` instead.", DeprecationWarning | ||
| ) | ||
| return self._pedb.simulation_setups.create_siwave_cpa_setup(name, siwave_cpa_config=siwave_cpa_setup_class) | ||
| def add_siwave_syz_analysis( | ||
@@ -615,3 +617,3 @@ self, | ||
| discrete_sweep: bool = False, | ||
| ) -> Any: | ||
| ) -> "SiwaveSimulationSetup": | ||
| """Add a SIwave AC analysis to EDB. | ||
@@ -659,33 +661,11 @@ | ||
| """ | ||
| setup = self._pedb.create_siwave_syz_setup() | ||
| start_freq = self._pedb.number_with_units(start_freq, "Hz") | ||
| stop_freq = self._pedb.number_with_units(stop_freq, "Hz") | ||
| setup.settings.general.si_slider_pos = accuracy_level | ||
| if distribution.lower() == "linear": | ||
| distribution = "LIN" | ||
| elif distribution.lower() == "linear_count": | ||
| distribution = "LINC" | ||
| elif distribution.lower() == "exponential": | ||
| distribution = "ESTP" | ||
| elif distribution.lower() == "decade_count": | ||
| distribution = "DEC" | ||
| elif distribution.lower() == "octave_count": | ||
| distribution = "OCT" | ||
| else: | ||
| distribution = "LIN" | ||
| sweep_name = f"sweep_{len(setup.sweep_data) + 1}" | ||
| sweep_data = [ | ||
| GrpcSweepData( | ||
| name=sweep_name, | ||
| frequency_data=GrpcFrequencyData( | ||
| distribution=GrpcDistribution[distribution], start_f=start_freq, end_f=stop_freq, step=step_freq | ||
| ), | ||
| ) | ||
| ] | ||
| if discrete_sweep: | ||
| sweep_data[0].type = sweep_data[0].type.DISCRETE_SWEEP | ||
| for sweep in setup.sweep_data: | ||
| sweep_data.append(sweep) | ||
| setup.sweep_data = sweep_data | ||
| setup = self._pedb.simulation_setups.create_siwave_setup( | ||
| distribution=distribution, | ||
| start_freq=start_freq, | ||
| stop_freq=stop_freq, | ||
| step_freq=step_freq, | ||
| discrete_sweep=discrete_sweep, | ||
| ) | ||
| self.create_exec_file(add_ac=True) | ||
| setup.settings.accuracy_level = accuracy_level | ||
| return setup | ||
@@ -1050,3 +1030,3 @@ | ||
| """ | ||
| return self._pedb.active_cell.get_product_property(GrpcProductIdType.SIWAVE, 422).value | ||
| return self._pedb.active_cell.get_product_property(CoreProductIdType.SIWAVE, 422).value | ||
@@ -1056,3 +1036,3 @@ @icepak_use_minimal_comp_defaults.setter | ||
| value = "True" if bool(value) else "" | ||
| self._pedb.active_cell.set_product_property(GrpcProductIdType.SIWAVE, 422, value) | ||
| self._pedb.active_cell.set_product_property(CoreProductIdType.SIWAVE, 422, value) | ||
@@ -1062,6 +1042,6 @@ @property | ||
| """Icepak component file path.""" | ||
| return self._pedb.active_cell.get_product_property(GrpcProductIdType.SIWAVE, 420).value | ||
| return self._pedb.active_cell.get_product_property(CoreProductIdType.SIWAVE, 420).value | ||
| @icepak_component_file.setter | ||
| def icepak_component_file(self, value): | ||
| self._pedb.active_cell.set_product_property(GrpcProductIdType.SIWAVE, 420, value) | ||
| self._pedb.active_cell.set_product_property(CoreProductIdType.SIWAVE, 420, value) |
@@ -31,9 +31,8 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from pyedb.grpc.database.ports.ports import WavePort | ||
| from ansys.edb.core.terminal.bundle_terminal import BundleTerminal as GrpcBundleTerminal | ||
| from ansys.edb.core.terminal.bundle_terminal import BundleTerminal as CoreBundleTerminal | ||
| from ansys.edb.core.terminal.terminal import ( | ||
| HfssPIType as GrpcHfssPIType, | ||
| SourceTermToGroundType as GrpcSourceTermToGroundType, | ||
| HfssPIType as CoreHfssPIType, | ||
| SourceTermToGroundType as CoreSourceTermToGroundType, | ||
| ) | ||
| from pyedb.grpc.database.layers.layer import Layer | ||
| from pyedb.grpc.database.terminal.terminal import Terminal | ||
@@ -55,3 +54,3 @@ from pyedb.grpc.database.utility.rlc import Rlc | ||
| def __init__(self, pedb, core): | ||
| if isinstance(core, GrpcBundleTerminal): | ||
| if isinstance(core, CoreBundleTerminal): | ||
| super().__init__(pedb, core.terminals[0]) | ||
@@ -90,3 +89,3 @@ self.core = core | ||
| terminals = [term.core for term in terminals] | ||
| grpc_term = GrpcBundleTerminal.create(terminals=terminals) | ||
| grpc_term = CoreBundleTerminal.create(terminals=terminals) | ||
| bundle_terminal = cls(pedb, grpc_term) | ||
@@ -154,11 +153,11 @@ bundle_terminal.name = name | ||
| if value.upper() == "DEFAULT": | ||
| self.core.hfss_pi_type = GrpcHfssPIType.DEFAULT | ||
| self.core.hfss_pi_type = CoreHfssPIType.DEFAULT | ||
| elif value.upper() == "COAXIAL_OPEN": | ||
| self.core.hfss_pi_type = GrpcHfssPIType.COAXIAL_OPEN | ||
| self.core.hfss_pi_type = CoreHfssPIType.COAXIAL_OPEN | ||
| elif value.upper() == "COAXIAL_SHORTENED": | ||
| self.core.hfss_pi_type = GrpcHfssPIType.COAXIAL_SHORTENED | ||
| self.core.hfss_pi_type = CoreHfssPIType.COAXIAL_SHORTENED | ||
| elif value.upper() == "GAP": | ||
| self.core.hfss_pi_type = GrpcHfssPIType.GAP | ||
| self.core.hfss_pi_type = CoreHfssPIType.GAP | ||
| elif value.upper() == "LUMPED": | ||
| self.core.hfss_pi_type = GrpcHfssPIType.LUMPED | ||
| self.core.hfss_pi_type = CoreHfssPIType.LUMPED | ||
@@ -189,7 +188,7 @@ @property | ||
| if value.upper() == "NO_GROUND": | ||
| self.core.term_to_ground = GrpcSourceTermToGroundType.NO_GROUND | ||
| self.core.term_to_ground = CoreSourceTermToGroundType.NO_GROUND | ||
| elif value.upper() == "NEGATIVE": | ||
| self.core.term_to_ground = GrpcSourceTermToGroundType.NEGATIVE | ||
| self.core.term_to_ground = CoreSourceTermToGroundType.NEGATIVE | ||
| elif value.upper() == "POSITIVE": | ||
| self.core.term_to_ground = GrpcSourceTermToGroundType.POSITIVE | ||
| self.core.term_to_ground = CoreSourceTermToGroundType.POSITIVE | ||
@@ -196,0 +195,0 @@ @property |
@@ -26,3 +26,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.terminal.edge_terminal import EdgeTerminal as GrpcEdgeTerminal | ||
| from ansys.edb.core.terminal.edge_terminal import EdgeTerminal as CoreEdgeTerminal | ||
@@ -65,3 +65,3 @@ from pyedb.grpc.database.terminal.bundle_terminal import BundleTerminal | ||
| raise Exception("Net must be specified to create an Edge Terminal.") | ||
| grpc_edge_terminal = GrpcEdgeTerminal.create( | ||
| grpc_edge_terminal = CoreEdgeTerminal.create( | ||
| layout.core, | ||
@@ -68,0 +68,0 @@ name, |
@@ -27,6 +27,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.terminal.padstack_instance_terminal import ( | ||
| PadstackInstanceTerminal as GrpcPadstackInstanceTerminal, | ||
| ) | ||
| from ansys.edb.core.terminal.terminal import BoundaryType as GrpcBoundaryType | ||
| from ansys.edb.core.terminal.padstack_instance_terminal import PadstackInstanceTerminal as CorePadstackInstanceTerminal | ||
@@ -39,3 +36,2 @@ if TYPE_CHECKING: | ||
| from pyedb.grpc.database.utility.value import Value | ||
| from pyedb.misc.decorators import deprecated_property | ||
@@ -71,3 +67,3 @@ | ||
| net = padstack_instance.net | ||
| edb_terminal_inst = GrpcPadstackInstanceTerminal.create( | ||
| edb_terminal_inst = CorePadstackInstanceTerminal.create( | ||
| layout=layout.core, | ||
@@ -74,0 +70,0 @@ name=name, |
@@ -30,11 +30,11 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.terminal.pin_group_terminal import ( | ||
| PinGroupTerminal as GrpcPinGroupTerminal, | ||
| PinGroupTerminal as CorePinGroupTerminal, | ||
| ) | ||
| from ansys.edb.core.terminal.terminal import BoundaryType as GrpcBoundaryType | ||
| from ansys.edb.core.terminal.terminal import BoundaryType as CoreBoundaryType | ||
| boundary_type_mapping = { | ||
| "voltage_source": GrpcBoundaryType.VOLTAGE_SOURCE, | ||
| "current_source": GrpcBoundaryType.CURRENT_SOURCE, | ||
| "port": GrpcBoundaryType.PORT, | ||
| "voltage_probe": GrpcBoundaryType.VOLTAGE_PROBE, | ||
| "voltage_source": CoreBoundaryType.VOLTAGE_SOURCE, | ||
| "current_source": CoreBoundaryType.CURRENT_SOURCE, | ||
| "port": CoreBoundaryType.PORT, | ||
| "voltage_probe": CoreBoundaryType.VOLTAGE_PROBE, | ||
| } | ||
@@ -113,3 +113,3 @@ from pyedb.grpc.database.terminal.terminal import Terminal | ||
| """ | ||
| term = GrpcPinGroupTerminal.create(layout.core, name, pin_group.core, net.core, is_ref) | ||
| term = CorePinGroupTerminal.create(layout.core, name, pin_group.core, net.core, is_ref) | ||
| return cls(layout._pedb, term) |
@@ -23,20 +23,16 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from typing import TYPE_CHECKING | ||
| from ansys.edb.core.geometry.point_data import PointData as CorePointData | ||
| from ansys.edb.core.terminal.point_terminal import PointTerminal as CorePointTerminal | ||
| from ansys.edb.core.terminal.terminal import BoundaryType as CoreBoundaryType | ||
| from ansys.edb.core.geometry.point_data import PointData as GrpcPointData | ||
| from ansys.edb.core.terminal.point_terminal import PointTerminal as GrpcPointTerminal | ||
| from ansys.edb.core.terminal.terminal import BoundaryType as GrpcBoundaryType | ||
| if TYPE_CHECKING: | ||
| from pyedb.grpc.database.layers.stackup_layer import StackupLayer | ||
| from pyedb.grpc.database.utility.value import Value | ||
| mapping_boundary_type = { | ||
| "port": GrpcBoundaryType.PORT, | ||
| "dc_terminal": GrpcBoundaryType.DC_TERMINAL, | ||
| "voltage_probe": GrpcBoundaryType.VOLTAGE_PROBE, | ||
| "voltage_source": GrpcBoundaryType.VOLTAGE_SOURCE, | ||
| "current_source": GrpcBoundaryType.CURRENT_SOURCE, | ||
| "rlc": GrpcBoundaryType.RLC, | ||
| "pec": GrpcBoundaryType.PEC, | ||
| "port": CoreBoundaryType.PORT, | ||
| "dc_terminal": CoreBoundaryType.DC_TERMINAL, | ||
| "voltage_probe": CoreBoundaryType.VOLTAGE_PROBE, | ||
| "voltage_source": CoreBoundaryType.VOLTAGE_SOURCE, | ||
| "current_source": CoreBoundaryType.CURRENT_SOURCE, | ||
| "rlc": CoreBoundaryType.RLC, | ||
| "pec": CoreBoundaryType.PEC, | ||
| } | ||
@@ -78,3 +74,3 @@ from pyedb.grpc.database.terminal.terminal import Terminal | ||
| if isinstance(point, list): | ||
| point = GrpcPointData([Value(i) for i in point]) | ||
| point = CorePointData([Value(i) for i in point]) | ||
| if isinstance(net, str): | ||
@@ -84,3 +80,3 @@ net = layout._pedb.nets[net] | ||
| layer = layout._pedb.stackup.layers[layer] | ||
| core_terminal = GrpcPointTerminal.create( | ||
| core_terminal = CorePointTerminal.create( | ||
| layout=layout.core, net=net.core, layer=layer.core, name=name, point=point | ||
@@ -129,3 +125,3 @@ ) | ||
| value = [Value(i) for i in value] | ||
| self.core.point = GrpcPointData(value) | ||
| self.core.point = CorePointData(value) | ||
@@ -132,0 +128,0 @@ @property |
@@ -33,26 +33,27 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.terminal.edge_terminal import EdgeType as GrpcEdgeType | ||
| from ansys.edb.core.terminal.edge_terminal import EdgeType as CoreEdgeType | ||
| from ansys.edb.core.terminal.terminal import ( | ||
| BoundaryType as GrpcBoundaryType, | ||
| TerminalType as GrpcTerminalType, | ||
| BoundaryType as CoreBoundaryType, | ||
| TerminalType as CoreTerminalType, | ||
| ) | ||
| from pyedb.grpc.database.primitive.primitive import Primitive | ||
| from pyedb.grpc.database.utility.port_post_processing_prop import PortPostProcessingProp | ||
| from pyedb.grpc.database.utility.value import Value | ||
| mapping_boundary_type = { | ||
| "port": GrpcBoundaryType.PORT, | ||
| "dc_terminal": GrpcBoundaryType.DC_TERMINAL, | ||
| "voltage_probe": GrpcBoundaryType.VOLTAGE_PROBE, | ||
| "voltage_source": GrpcBoundaryType.VOLTAGE_SOURCE, | ||
| "current_source": GrpcBoundaryType.CURRENT_SOURCE, | ||
| "rlc": GrpcBoundaryType.RLC, | ||
| "pec": GrpcBoundaryType.PEC, | ||
| "portboundary": GrpcBoundaryType.PORT, | ||
| "kdcterminal": GrpcBoundaryType.DC_TERMINAL, | ||
| "kvoltageprobe": GrpcBoundaryType.VOLTAGE_PROBE, | ||
| "kvoltagesource": GrpcBoundaryType.VOLTAGE_SOURCE, | ||
| "kcurrentsource": GrpcBoundaryType.CURRENT_SOURCE, | ||
| "rlcboundary": GrpcBoundaryType.RLC, | ||
| "pecboundary": GrpcBoundaryType.PEC, | ||
| "port": CoreBoundaryType.PORT, | ||
| "dc_terminal": CoreBoundaryType.DC_TERMINAL, | ||
| "voltage_probe": CoreBoundaryType.VOLTAGE_PROBE, | ||
| "voltage_source": CoreBoundaryType.VOLTAGE_SOURCE, | ||
| "current_source": CoreBoundaryType.CURRENT_SOURCE, | ||
| "rlc": CoreBoundaryType.RLC, | ||
| "pec": CoreBoundaryType.PEC, | ||
| "portboundary": CoreBoundaryType.PORT, | ||
| "kdcterminal": CoreBoundaryType.DC_TERMINAL, | ||
| "kvoltageprobe": CoreBoundaryType.VOLTAGE_PROBE, | ||
| "kvoltagesource": CoreBoundaryType.VOLTAGE_SOURCE, | ||
| "kcurrentsource": CoreBoundaryType.CURRENT_SOURCE, | ||
| "rlcboundary": CoreBoundaryType.RLC, | ||
| "pecboundary": CoreBoundaryType.PEC, | ||
| } | ||
@@ -68,11 +69,15 @@ | ||
| self._terminal_type_mapping = { | ||
| "edge": GrpcTerminalType.EDGE, | ||
| "point": GrpcTerminalType.POINT, | ||
| "terminal_instance": GrpcTerminalType.TERM_INST, | ||
| "padstack_instance": GrpcTerminalType.PADSTACK_INST, | ||
| "bundle": GrpcTerminalType.BUNDLE, | ||
| "pin_group": GrpcTerminalType.PIN_GROUP, | ||
| "edge": CoreTerminalType.EDGE, | ||
| "point": CoreTerminalType.POINT, | ||
| "terminal_instance": CoreTerminalType.TERM_INST, | ||
| "padstack_instance": CoreTerminalType.PADSTACK_INST, | ||
| "bundle": CoreTerminalType.BUNDLE, | ||
| "pin_group": CoreTerminalType.PIN_GROUP, | ||
| } | ||
| @property | ||
| def port_post_processing_prop(self): | ||
| return PortPostProcessingProp(self.core.port_post_processing_prop) | ||
| @property | ||
| def _hfss_port_property(self): | ||
@@ -139,9 +144,24 @@ """HFSS port property.""" | ||
| """ | ||
| return self.core.port_post_processing_prop.do_renormalize | ||
| return self.port_post_processing_prop.do_renormalize | ||
| @do_renormalize.setter | ||
| def do_renormalize(self, value): | ||
| self.core.port_post_processing_prop.do_renormalize = value | ||
| self.port_post_processing_prop.do_renormalize = value | ||
| @property | ||
| def renormalization_impedance(self) -> float: | ||
| """Get the renormalization impedance value. | ||
| Returns | ||
| ------- | ||
| float | ||
| """ | ||
| return self.port_post_processing_prop.renormalization_impedance | ||
| @renormalization_impedance.setter | ||
| def renormalization_impedance(self, value): | ||
| self.port_post_processing_prop.renormalization_impedance = value | ||
| @property | ||
| def net_name(self) -> str: | ||
@@ -196,3 +216,3 @@ """Net name. | ||
| value = mapping_boundary_type.get(value.lower(), None) | ||
| if not isinstance(value, GrpcBoundaryType): | ||
| if not isinstance(value, CoreBoundaryType): | ||
| raise ValueError("Value must be a string or BoundaryType enum.") | ||
@@ -291,3 +311,3 @@ self.core.boundary_type = value | ||
| edge_type = edges[0].type | ||
| if edge_type == GrpcEdgeType.PADSTACK: | ||
| if edge_type == CoreEdgeType.PADSTACK: | ||
| self._reference_object = self.get_pad_edge_terminal_reference_pin() | ||
@@ -357,18 +377,18 @@ else: | ||
| refTerm = self.core.reference_terminal | ||
| if self.core.type == GrpcTerminalType.PIN_GROUP: | ||
| padStackInstance = self.core.pin_group.pins[0] | ||
| pingroup = refTerm.pin_group | ||
| refPinList = pingroup.pins | ||
| return self._get_closest_pin(padStackInstance, refPinList, gnd_net_name_preference) | ||
| elif self.core.type == GrpcTerminalType.PADSTACK_INST: | ||
| _, padStackInstance, _ = self.core.get_parameters() | ||
| if refTerm.type == GrpcTerminalType.PIN_GROUP: | ||
| pingroup = refTerm.pin_group | ||
| refPinList = pingroup.pins | ||
| return self._get_closest_pin(padStackInstance, refPinList, gnd_net_name_preference) | ||
| ref_term = self.core.reference_terminal | ||
| if self.core.type == CoreTerminalType.PIN_GROUP: | ||
| padstack_instance = self.core.pin_group.pins[0] | ||
| pingroup = ref_term.pin_group | ||
| ref_pins = pingroup.pins | ||
| return self._get_closest_pin(padstack_instance, ref_pins, gnd_net_name_preference) | ||
| elif self.core.type == CoreTerminalType.PADSTACK_INST: | ||
| _, padstack_instance, _ = self.core.get_parameters() | ||
| if ref_term.type == CoreTerminalType.PIN_GROUP: | ||
| pingroup = ref_term.pin_group | ||
| ref_pins = pingroup.pins | ||
| return self._get_closest_pin(padstack_instance, ref_pins, gnd_net_name_preference) | ||
| else: | ||
| try: | ||
| _, refTermPSI, _ = refTerm.get_parameters() | ||
| return PadstackInstance(self._pedb, refTermPSI) | ||
| _, ref_term_psi, _ = ref_term.get_parameters() | ||
| return PadstackInstance(self._pedb, ref_term_psi) | ||
| except AttributeError: | ||
@@ -390,3 +410,2 @@ return False | ||
| _, _, point_data = edges[0].get_parameters() | ||
| # shape_pd = self._pedb.core.geometry.point_data(X, Y) | ||
| layer_name = ref_layer.name | ||
@@ -414,7 +433,5 @@ for primitive in self._pedb.layout.primitives: | ||
| _, point_data, layer = ref_term.get_parameters() | ||
| # shape_pd = self._pedb.core.geometry.point_data(X, Y) | ||
| layer_name = layer.name | ||
| for primitive in self._pedb.layout.primitives: | ||
| if primitive.layer.name == layer_name: | ||
| prim_shape_data = primitive.GetPolygonData() | ||
| if primitive.polygon_data.point_in_polygon(point_data): | ||
@@ -421,0 +438,0 @@ return Primitive(self._pedb, primitive) |
@@ -24,5 +24,5 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.utility.heat_sink import ( | ||
| HeatSinkFinOrientation as GrpcHeatSinkFinOrientation, | ||
| HeatSinkFinOrientation as CoreHeatSinkFinOrientation, | ||
| ) | ||
| from ansys.edb.core.utility.value import Value as GrpcValue | ||
| from ansys.edb.core.utility.value import Value as CoreValue | ||
@@ -43,5 +43,5 @@ | ||
| self._fin_orientation_type = { | ||
| "x_oriented": GrpcHeatSinkFinOrientation.X_ORIENTED, | ||
| "y_oriented": GrpcHeatSinkFinOrientation.Y_ORIENTED, | ||
| "other_oriented": GrpcHeatSinkFinOrientation.OTHER_ORIENTED, | ||
| "x_oriented": CoreHeatSinkFinOrientation.X_ORIENTED, | ||
| "y_oriented": CoreHeatSinkFinOrientation.Y_ORIENTED, | ||
| "other_oriented": CoreHeatSinkFinOrientation.OTHER_ORIENTED, | ||
| } | ||
@@ -62,3 +62,3 @@ | ||
| def fin_base_height(self, value): | ||
| self._edb_object.fin_base_height = GrpcValue(value) | ||
| self._edb_object.fin_base_height = CoreValue(value) | ||
@@ -79,3 +79,3 @@ @property | ||
| def fin_height(self, value): | ||
| self._edb_object.fin_height = GrpcValue(value) | ||
| self._edb_object.fin_height = CoreValue(value) | ||
@@ -111,3 +111,3 @@ @property | ||
| def fin_spacing(self, value): | ||
| self._edb_object.fin_spacing = GrpcValue(value) | ||
| self._edb_object.fin_spacing = CoreValue(value) | ||
@@ -128,2 +128,2 @@ @property | ||
| def fin_thickness(self, value): | ||
| self._edb_object.fin_thickness = GrpcValue(value) | ||
| self._edb_object.fin_thickness = CoreValue(value) |
@@ -24,7 +24,6 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.utility.hfss_extent_info import ( | ||
| HfssExtentInfo as GrpcHfssExtentInfo, | ||
| HFSSExtentInfoType as GrpcHfssExtentInfoType, | ||
| OpenRegionType as GrpcOpenRegionType, | ||
| HFSSExtentInfoType as CoreHfssExtentInfoType, | ||
| OpenRegionType as CoreOpenRegionType, | ||
| ) | ||
| from ansys.edb.core.utility.value import Value as GrpcValue | ||
| from ansys.edb.core.utility.value import Value as CoreValue | ||
@@ -45,10 +44,10 @@ | ||
| self.extent_type_mapping = { | ||
| "bounding_box": GrpcHfssExtentInfoType.BOUNDING_BOX, | ||
| "conforming": GrpcHfssExtentInfoType.CONFORMING, | ||
| "convex_hull": GrpcHfssExtentInfoType.CONVEX_HUL, | ||
| "polygon": GrpcHfssExtentInfoType.POLYGON, | ||
| "bounding_box": CoreHfssExtentInfoType.BOUNDING_BOX, | ||
| "conforming": CoreHfssExtentInfoType.CONFORMING, | ||
| "convex_hull": CoreHfssExtentInfoType.CONVEX_HUL, | ||
| "polygon": CoreHfssExtentInfoType.POLYGON, | ||
| } | ||
| self._open_region_type = { | ||
| "radiation": GrpcOpenRegionType.RADIATION, | ||
| "pml": GrpcOpenRegionType.PML, | ||
| "radiation": CoreOpenRegionType.RADIATION, | ||
| "pml": CoreOpenRegionType.PML, | ||
| } | ||
@@ -75,3 +74,3 @@ self.hfss_extent_type = self.core.extent_type | ||
| hfss_extent = self.core | ||
| hfss_extent.airbox_horizontal = (GrpcValue(size).value, is_multiple) | ||
| hfss_extent.airbox_horizontal = (CoreValue(size).value, is_multiple) | ||
| self._update_hfss_extent_info(hfss_extent) | ||
@@ -95,3 +94,3 @@ | ||
| hfss_exent = self.core | ||
| hfss_exent.airbox_vertical_positive = (GrpcValue(size).value, is_multiple) | ||
| hfss_exent.airbox_vertical_positive = (CoreValue(size).value, is_multiple) | ||
| self._update_hfss_extent_info(hfss_exent) | ||
@@ -115,3 +114,3 @@ | ||
| hfss_extent = self.core | ||
| hfss_extent.airbox_vertical_negative = (GrpcValue(size).value, is_multiple) | ||
| hfss_extent.airbox_vertical_negative = (CoreValue(size).value, is_multiple) | ||
| self._update_hfss_extent_info(hfss_extent) | ||
@@ -280,3 +279,3 @@ | ||
| hfss_extent = self.core | ||
| hfss_extent.operating_frequency = GrpcValue(value) | ||
| hfss_extent.operating_frequency = CoreValue(value) | ||
| self._update_hfss_extent_info(hfss_extent) | ||
@@ -302,3 +301,3 @@ | ||
| hfss_extent = self.core | ||
| hfss_extent.radiation_level = GrpcValue(value) | ||
| hfss_extent.radiation_level = CoreValue(value) | ||
| self._update_hfss_extent_info(hfss_extent) | ||
@@ -305,0 +304,0 @@ |
@@ -32,4 +32,4 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.utility.layer_map import ( | ||
| LayerMap as GrpcLayerMap, | ||
| LayerMapUniqueDirection as GrpcLayerMapUniqueDirection, | ||
| LayerMap as CoreLayerMap, | ||
| LayerMapUniqueDirection as CoreLayerMapUniqueDirection, | ||
| ) | ||
@@ -57,7 +57,7 @@ | ||
| mapping = { | ||
| "two_way": GrpcLayerMapUniqueDirection.TWOWAY_UNIQUE, | ||
| "forward": GrpcLayerMapUniqueDirection.FORWARD_UNIQUE, | ||
| "backward": GrpcLayerMapUniqueDirection.BACKWARD_UNIQUE, | ||
| "two_way": CoreLayerMapUniqueDirection.TWOWAY_UNIQUE, | ||
| "forward": CoreLayerMapUniqueDirection.FORWARD_UNIQUE, | ||
| "backward": CoreLayerMapUniqueDirection.BACKWARD_UNIQUE, | ||
| } | ||
| core_layer_map = GrpcLayerMap.create(mapping[direction]) | ||
| core_layer_map = CoreLayerMap.create(mapping[direction]) | ||
| return cls(core_layer_map) | ||
@@ -64,0 +64,0 @@ |
@@ -24,7 +24,7 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| from ansys.edb.core.utility.rlc import Rlc as GrpcRlc | ||
| from ansys.edb.core.utility.value import Value as GrpcValue | ||
| from ansys.edb.core.utility.rlc import Rlc as CoreRlc | ||
| from ansys.edb.core.utility.value import Value as CoreValue | ||
| class Rlc(GrpcRlc): | ||
| class Rlc(CoreRlc): | ||
| def __init__(self, pedb, core): | ||
@@ -49,3 +49,3 @@ super().__init__(core) | ||
| def r(self, value): | ||
| self.r = GrpcValue(value) | ||
| self.r = CoreValue(value) | ||
@@ -66,3 +66,3 @@ @property | ||
| def l(self, value): | ||
| self.l = GrpcValue(value) | ||
| self.l = CoreValue(value) | ||
@@ -83,2 +83,2 @@ @property | ||
| def c(self, value): | ||
| self.c = GrpcValue(value) | ||
| self.c = CoreValue(value) |
@@ -17,3 +17,3 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| # FITNE SS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
@@ -24,3 +24,3 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| from ansys.edb.core.utility.value import Value as GrpcValue | ||
| from ansys.edb.core.utility.value import Value as CoreValue | ||
@@ -63,3 +63,3 @@ | ||
| else: | ||
| return f"LIN {GrpcValue(start).value} {GrpcValue(stop).value} {GrpcValue(step).value}" | ||
| return f"LIN {CoreValue(start).value} {CoreValue(stop).value} {CoreValue(step).value}" | ||
| elif sweep_type.lower() == "linear_count": | ||
@@ -69,3 +69,3 @@ if isinstance(start, str) and isinstance(stop, str) and isinstance(count, int): | ||
| else: | ||
| return f"LINC {GrpcValue(start).value} {GrpcValue(stop).value} {int(GrpcValue(count).value)}" | ||
| return f"LINC {CoreValue(start).value} {CoreValue(stop).value} {int(CoreValue(count).value)}" | ||
| elif sweep_type.lower() == "exponential": | ||
@@ -75,3 +75,3 @@ if isinstance(start, str) and isinstance(stop, str) and isinstance(count, int): | ||
| else: | ||
| return f"ESTP {GrpcValue(start).value} {GrpcValue(stop).value} {int(GrpcValue(count).value)}" | ||
| return f"ESTP {CoreValue(start).value} {CoreValue(stop).value} {int(CoreValue(count).value)}" | ||
| elif sweep_type.lower() == "decade_count": | ||
@@ -81,3 +81,3 @@ if isinstance(start, str) and isinstance(stop, str) and isinstance(decade_number, int): | ||
| else: | ||
| return f"DEC {GrpcValue(start).value} {GrpcValue(stop).value} {int(GrpcValue(decade_number).value)}" | ||
| return f"DEC {CoreValue(start).value} {CoreValue(stop).value} {int(CoreValue(decade_number).value)}" | ||
| elif sweep_type.lower() == "octave_count": | ||
@@ -87,4 +87,4 @@ if isinstance(start, str) and isinstance(stop, str) and isinstance(octave_number, int): | ||
| else: | ||
| return f"OCT {GrpcValue(start).value} {GrpcValue(stop).value} {int(GrpcValue(octave_number).value)}" | ||
| return f"OCT {CoreValue(start).value} {CoreValue(stop).value} {int(CoreValue(octave_number).value)}" | ||
| else: | ||
| return "" |
@@ -24,10 +24,10 @@ # Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates. | ||
| import ansys.edb.core.utility.value | ||
| from ansys.edb.core.utility.value import Value as GrpcValue | ||
| from ansys.edb.core.utility.value import Value as CoreValue | ||
| class Value(float, GrpcValue): | ||
| class Value(float, CoreValue): | ||
| """Class defining Edb Value properties.""" | ||
| def __new__(cls, val, owner=None) -> float: | ||
| core = GrpcValue(val, owner) | ||
| core = CoreValue(val, owner) | ||
| inst = super().__new__(cls, core.value) | ||
@@ -34,0 +34,0 @@ inst._edb_object = core |
| # Copyright (C) 2023 - 2026 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, | ||
| # FITNE SS 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. | ||
| from ansys.edb.core.simulation_setup.mesh_operation import ( | ||
| MeshOperation as GrpcMeshOperation, | ||
| ) | ||
| class MeshOperation(GrpcMeshOperation): | ||
| """Mesh operation class.""" | ||
| def __init__(self, pedb, core): | ||
| super().__init__(core) | ||
| self._pedb = pedb |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
4381434
5.22%301
9.85%103625
5.8%