pyedb 0.46.0__py3-none-any.whl → 0.48.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyedb might be problematic. Click here for more details.

Files changed (33) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/configuration/cfg_stackup.py +35 -1
  3. pyedb/configuration/configuration.py +13 -13
  4. pyedb/dotnet/database/cell/primitive/primitive.py +8 -1
  5. pyedb/dotnet/database/cell/terminal/terminal.py +22 -4
  6. pyedb/dotnet/database/components.py +22 -3
  7. pyedb/dotnet/database/dotnet/database.py +18 -0
  8. pyedb/dotnet/database/edb_data/padstacks_data.py +20 -0
  9. pyedb/dotnet/database/edb_data/ports.py +14 -0
  10. pyedb/dotnet/database/edb_data/utilities.py +1 -1
  11. pyedb/dotnet/database/geometry/polygon_data.py +1 -1
  12. pyedb/dotnet/database/hfss.py +11 -1
  13. pyedb/dotnet/database/materials.py +78 -0
  14. pyedb/dotnet/database/modeler.py +9 -5
  15. pyedb/dotnet/database/sim_setup_data/data/mesh_operation.py +24 -0
  16. pyedb/dotnet/database/siwave.py +1 -1
  17. pyedb/dotnet/database/utilities/simulation_setup.py +51 -9
  18. pyedb/dotnet/edb.py +67 -8
  19. pyedb/grpc/database/components.py +19 -13
  20. pyedb/grpc/database/hfss.py +3 -3
  21. pyedb/grpc/database/modeler.py +4 -4
  22. pyedb/grpc/database/padstacks.py +3 -1
  23. pyedb/grpc/database/ports/ports.py +4 -0
  24. pyedb/grpc/database/primitive/path.py +2 -2
  25. pyedb/grpc/database/primitive/primitive.py +6 -1
  26. pyedb/grpc/database/source_excitations.py +16 -8
  27. pyedb/grpc/database/terminal/bundle_terminal.py +1 -1
  28. pyedb/grpc/edb.py +125 -32
  29. pyedb/misc/downloads.py +1 -1
  30. {pyedb-0.46.0.dist-info → pyedb-0.48.0.dist-info}/METADATA +1 -1
  31. {pyedb-0.46.0.dist-info → pyedb-0.48.0.dist-info}/RECORD +33 -33
  32. {pyedb-0.46.0.dist-info → pyedb-0.48.0.dist-info}/LICENSE +0 -0
  33. {pyedb-0.46.0.dist-info → pyedb-0.48.0.dist-info}/WHEEL +0 -0
pyedb/__init__.py CHANGED
@@ -44,7 +44,7 @@ deprecation_warning()
44
44
  #
45
45
 
46
46
  pyedb_path = os.path.dirname(__file__)
47
- __version__ = "0.46.0"
47
+ __version__ = "0.48.0"
48
48
  version = __version__
49
49
 
50
50
  #
@@ -24,6 +24,33 @@ from pyedb import Edb
24
24
  from pyedb.configuration.cfg_common import CfgBase
25
25
 
26
26
 
27
+ class CfgMaterialPropertyThermalModifier:
28
+ def __init__(self, **kwargs):
29
+ self.property_name = kwargs["property_name"]
30
+ self.basic_quadratic_c1 = kwargs.get("basic_quadratic_c1", 0)
31
+ self.basic_quadratic_c2 = kwargs.get("basic_quadratic_c2", 0)
32
+ self.basic_quadratic_temperature_reference = kwargs.get("basic_quadratic_temperature_reference", 22)
33
+ self.advanced_quadratic_lower_limit = kwargs.get("advanced_quadratic_lower_limit", -273.15)
34
+ self.advanced_quadratic_upper_limit = kwargs.get("advanced_quadratic_upper_limit", 1000)
35
+
36
+ self.advanced_quadratic_auto_calculate = kwargs.get("advanced_quadratic_auto_calculate", True)
37
+ self.advanced_quadratic_lower_constant = kwargs.get("advanced_quadratic_lower_constant", 1)
38
+ self.advanced_quadratic_upper_constant = kwargs.get("advanced_quadratic_upper_constant", 1)
39
+
40
+ def to_dict(self):
41
+ return {
42
+ "property_name": self.property_name,
43
+ "basic_quadratic_c1": self.basic_quadratic_c1,
44
+ "basic_quadratic_c2": self.basic_quadratic_c2,
45
+ "basic_quadratic_temperature_reference": self.basic_quadratic_temperature_reference,
46
+ "advanced_quadratic_lower_limit": self.advanced_quadratic_lower_limit,
47
+ "advanced_quadratic_upper_limit": self.advanced_quadratic_upper_limit,
48
+ "advanced_quadratic_auto_calculate": self.advanced_quadratic_auto_calculate,
49
+ "advanced_quadratic_lower_constant": self.advanced_quadratic_lower_constant,
50
+ "advanced_quadratic_upper_constant": self.advanced_quadratic_upper_constant,
51
+ }
52
+
53
+
27
54
  class CfgMaterial(CfgBase):
28
55
  def __init__(self, **kwargs):
29
56
  self.name = kwargs.get("name", None)
@@ -37,6 +64,10 @@ class CfgMaterial(CfgBase):
37
64
  self.specific_heat = kwargs.get("specific_heat", None)
38
65
  self.thermal_conductivity = kwargs.get("thermal_conductivity", None)
39
66
 
67
+ self.thermal_modifier = [
68
+ CfgMaterialPropertyThermalModifier(**i) for i in kwargs.get("thermal_modifier", {}) if i is not None
69
+ ]
70
+
40
71
 
41
72
  class CfgLayer(CfgBase):
42
73
  def __init__(self, **kwargs):
@@ -131,12 +162,15 @@ class CfgStackup:
131
162
  attrs = mat_in_cfg.get_attributes()
132
163
  mat = self._pedb.materials.add_material(**attrs)
133
164
 
165
+ for i in attrs.get("thermal_modifier", []):
166
+ mat.set_thermal_modifier(**i.to_dict())
167
+
134
168
  def get_materials_from_db(self):
135
169
  materials = []
136
170
  for name, p in self._pedb.materials.materials.items():
137
171
  mat = {}
138
172
  for p_name in CfgMaterial().__dict__:
139
- mat[p_name] = getattr(p, p_name)
173
+ mat[p_name] = getattr(p, p_name, None)
140
174
  materials.append(mat)
141
175
  return materials
142
176
 
@@ -572,17 +572,17 @@ class Configuration:
572
572
  """
573
573
  return self.api.export(
574
574
  file_path,
575
- stackup=True,
576
- package_definitions=False,
577
- setups=True,
578
- sources=True,
579
- ports=True,
580
- nets=True,
581
- pin_groups=True,
582
- operations=True,
583
- components=True,
584
- boundaries=True,
585
- s_parameters=True,
586
- padstacks=True,
587
- general=True,
575
+ stackup=stackup,
576
+ package_definitions=package_definitions,
577
+ setups=setups,
578
+ sources=sources,
579
+ ports=ports,
580
+ nets=nets,
581
+ pin_groups=pin_groups,
582
+ operations=operations,
583
+ components=components,
584
+ boundaries=boundaries,
585
+ s_parameters=s_parameters,
586
+ padstacks=padstacks,
587
+ general=general,
588
588
  )
@@ -51,7 +51,9 @@ class Primitive(Connectable):
51
51
  "invalid": bondwire_type.Invalid,
52
52
  "apd": bondwire_type.ApdBondwire,
53
53
  "jedec_4": bondwire_type.Jedec4Bondwire,
54
+ "jedec4": bondwire_type.Jedec4Bondwire,
54
55
  "jedec_5": bondwire_type.Jedec5Bondwire,
56
+ "jedec5": bondwire_type.Jedec5Bondwire,
55
57
  "num_of_bondwire_type": bondwire_type.NumOfBondwireType,
56
58
  }
57
59
  bondwire_cross_section_type = self._pedb._edb.Cell.Primitive.BondwireCrossSectionType
@@ -261,7 +263,12 @@ class Primitive(Connectable):
261
263
 
262
264
  """
263
265
  bbox = self.polygon_data._edb_object.GetBBox()
264
- return [bbox.Item1.X.ToDouble(), bbox.Item1.Y.ToDouble(), bbox.Item2.X.ToDouble(), bbox.Item2.Y.ToDouble()]
266
+ return [
267
+ round(bbox.Item1.X.ToDouble(), 6),
268
+ round(bbox.Item1.Y.ToDouble(), 6),
269
+ round(bbox.Item2.X.ToDouble(), 6),
270
+ round(bbox.Item2.Y.ToDouble(), 6),
271
+ ]
265
272
 
266
273
  def convert_to_polygon(self):
267
274
  """Convert path to polygon.
@@ -21,6 +21,7 @@
21
21
  # SOFTWARE.
22
22
 
23
23
  import re
24
+ import warnings
24
25
 
25
26
  from pyedb.dotnet.database.cell.connectable import Connectable
26
27
  from pyedb.dotnet.database.edb_data.padstacks_data import EDBPadstackInstance
@@ -196,18 +197,35 @@ class Terminal(Connectable):
196
197
  return self._edb_object.IsReferenceTerminal()
197
198
 
198
199
  @property
199
- def ref_terminal(self):
200
- """Get reference terminal."""
201
-
200
+ def reference_terminal(self):
201
+ """Adding grpc compatibility."""
202
202
  edb_terminal = self._edb_object.GetReferenceTerminal()
203
203
  if not edb_terminal.IsNull():
204
204
  return self._pedb.terminals[edb_terminal.GetName()]
205
205
  else:
206
206
  return None
207
207
 
208
+ @reference_terminal.setter
209
+ def reference_terminal(self, value):
210
+ self._edb_object.SetReferenceTerminal(value._edb_object)
211
+
212
+ @property
213
+ def ref_terminal(self):
214
+ """Get reference terminal.
215
+
216
+ .deprecated:: pyedb 0.47.0
217
+ Use: attribute:`reference_terminal` instead.
218
+
219
+ """
220
+ warnings.warn(
221
+ "`ref_terminal` is deprecated, use `reference_terminal` instead.",
222
+ DeprecationWarning,
223
+ )
224
+ return self.reference_terminal
225
+
208
226
  @ref_terminal.setter
209
227
  def ref_terminal(self, value):
210
- self._edb_object.SetReferenceTerminal(value._edb_object)
228
+ self.reference_terminal = value
211
229
 
212
230
  @property
213
231
  def reference_object(self): # pragma : no cover
@@ -947,6 +947,25 @@ class Components(object):
947
947
  >>> port_type=SourceType.CoaxPort, do_pingroup=False, refnet="GND")
948
948
 
949
949
  """
950
+ # Adding grpc compatibility
951
+ if not isinstance(port_type, int):
952
+ if port_type == "circuit_port":
953
+ port_type = SourceType.CircPort
954
+ elif port_type == "coaxial_port":
955
+ port_type = SourceType.CoaxPort
956
+ elif port_type == "lumped_port":
957
+ port_type = SourceType.LumpedPort
958
+ elif port_type == "rlc":
959
+ port_type = SourceType.Rlc
960
+ elif port_type == "current_source":
961
+ port_type = SourceType.Isource
962
+ elif port_type == "voltage_source":
963
+ port_type = SourceType.Vsource
964
+ elif port_type == "dc_terminal":
965
+ port_type = SourceType.DcTerminal
966
+ else:
967
+ self._pedb.logger.error(f"Port type {port_type} seems to be for grpc version but is not compatible.")
968
+ return False
950
969
  if isinstance(component, str):
951
970
  component = self.instances[component].edbcomponent
952
971
 
@@ -1576,7 +1595,9 @@ class Components(object):
1576
1595
  >>> edbapp.components.create(pins, "A1New")
1577
1596
 
1578
1597
  """
1579
- pins = [p._edb_object for p in pins]
1598
+ _pins = [p._edb_object for p in pins if isinstance(p, EDBPadstackInstance)]
1599
+ if _pins:
1600
+ pins = _pins
1580
1601
  if not component_name:
1581
1602
  component_name = generate_unique_name("Comp_")
1582
1603
  if component_part_name:
@@ -1589,8 +1610,6 @@ class Components(object):
1589
1610
  self._active_layout, component_name, compdef.GetName()
1590
1611
  )
1591
1612
 
1592
- if isinstance(pins[0], EDBPadstackInstance):
1593
- pins = [i._edb_object for i in pins]
1594
1613
  hosting_component_location = pins[0].GetComponent().GetTransform()
1595
1614
  for pin in pins:
1596
1615
  pin.SetIsLayoutPin(True)
@@ -484,6 +484,24 @@ class CellClassDotNet:
484
484
 
485
485
  return PrimitiveDotNet(self._app)
486
486
 
487
+ @property
488
+ def simulation_setups(self):
489
+ return self._app.setups
490
+
491
+ def get_all_variable_names(self):
492
+ """Method added for compatibility with grpc.
493
+
494
+ Returns
495
+ -------
496
+ List[Str]
497
+ List of variables name.
498
+
499
+ """
500
+ return list(self._app.variable_exists("")[1].GetAllVariableNames())
501
+
502
+ def get_variable_value(self, variable_name):
503
+ return self._app.variables[variable_name]
504
+
487
505
 
488
506
  class UtilityDotNet:
489
507
  """Utility Edb class."""
@@ -1261,6 +1261,8 @@ class EDBPadstackInstance(Primitive):
1261
1261
  """
1262
1262
  terminal = self.create_terminal(name)
1263
1263
  if reference:
1264
+ if isinstance(reference, tuple):
1265
+ reference = reference[1]
1264
1266
  ref_terminal = reference.create_terminal(terminal.name + "_ref")
1265
1267
  if reference._edb_object.ToString() == "PinGroup":
1266
1268
  is_circuit_port = True
@@ -1463,6 +1465,19 @@ class EDBPadstackInstance(Primitive):
1463
1465
  else:
1464
1466
  return self._edb_padstackinstance.SetBackDrillParameters(layer, val, False)
1465
1467
 
1468
+ @property
1469
+ def backdrill_type(self):
1470
+ """Adding grpc compatibility. DotNet is supporting only layer drill type with adding stub length."""
1471
+ return "layer_drill"
1472
+
1473
+ def get_back_drill_by_layer(self):
1474
+ params = self.backdrill_parameters["from_bottom"]
1475
+ return (
1476
+ params["drill_to_layer"],
1477
+ round(self._pedb.edb_value(params["stub_length"]).ToDouble(), 6),
1478
+ round(self._pedb.edb_value(params["diameter"]).ToDouble(), 6),
1479
+ )
1480
+
1466
1481
  @property
1467
1482
  def backdrill_bottom(self):
1468
1483
  """Backdrill layer from bottom.
@@ -1539,6 +1554,11 @@ class EDBPadstackInstance(Primitive):
1539
1554
  False,
1540
1555
  )
1541
1556
 
1557
+ def set_back_drill_by_layer(self, drill_to_layer, diameter, offset):
1558
+ """Method added to bring compatibility with grpc."""
1559
+
1560
+ self.set_backdrill_bottom(drill_depth=drill_to_layer.name, drill_diameter=diameter, offset=offset)
1561
+
1542
1562
  def set_backdrill_bottom(self, drill_depth, drill_diameter, offset=0.0):
1543
1563
  """Set backdrill from bottom.
1544
1564
 
@@ -54,6 +54,16 @@ class GapPort(EdgeTerminal):
54
54
  """Magnitude."""
55
55
  return self._edb_object.GetSourceAmplitude().ToDouble()
56
56
 
57
+ @property
58
+ def source_amplitude(self):
59
+ """Property added for grpc compatibility"""
60
+ return self.magnitude
61
+
62
+ @property
63
+ def source_phase(self):
64
+ """Property added for grpc compatibility"""
65
+ return self.phase
66
+
57
67
  @property
58
68
  def phase(self):
59
69
  """Phase."""
@@ -77,6 +87,10 @@ class GapPort(EdgeTerminal):
77
87
  self._edb_object.GetPortPostProcessingProp().RenormalizionZ0.ToComplex().Item2,
78
88
  )
79
89
 
90
+ @property
91
+ def renormalization_impedance(self):
92
+ return self.renormalize_z0[0]
93
+
80
94
 
81
95
  class CircuitPort(GapPort):
82
96
  """Manages gap port properties.
@@ -69,7 +69,7 @@ class EDBStatistics(object):
69
69
 
70
70
  @property
71
71
  def stackup_thickness(self):
72
- return self._stackup_thickness
72
+ return round(self._stackup_thickness, 6)
73
73
 
74
74
  @stackup_thickness.setter
75
75
  def stackup_thickness(self, value):
@@ -82,7 +82,7 @@ class PolygonData:
82
82
  list[list[float]]
83
83
  """
84
84
  return [
85
- [self._pedb.edb_value(i.X).ToDouble(), self._pedb.edb_value(i.Y).ToDouble()]
85
+ (self._pedb.edb_value(i.X).ToDouble(), self._pedb.edb_value(i.Y).ToDouble())
86
86
  for i in list(self._edb_object.Points)
87
87
  ]
88
88
 
@@ -429,7 +429,7 @@ class EdbHfss(object):
429
429
  source_name,
430
430
  )
431
431
 
432
- def create_coax_port_on_component(self, ref_des_list, net_list):
432
+ def create_coax_port_on_component(self, ref_des_list, net_list, delete_existing_terminal=False):
433
433
  """Create a coaxial port on a component or component list on a net or net list.
434
434
  The name of the new coaxial port is automatically assigned.
435
435
 
@@ -441,6 +441,10 @@ class EdbHfss(object):
441
441
  net_list : list, str
442
442
  List of one or more nets.
443
443
 
444
+ delete_existing_terminal : bool
445
+ Only active with grpc version. This argument is added only to ensure compatibility between DotNet and grpc.
446
+
447
+
444
448
  Returns
445
449
  -------
446
450
  bool
@@ -448,6 +452,8 @@ class EdbHfss(object):
448
452
 
449
453
  """
450
454
  coax = []
455
+ if delete_existing_terminal:
456
+ self._pedb.logger.warning(f"flag delete_existing_terminal is set to True but is only supported with grpc.")
451
457
  if not isinstance(ref_des_list, list):
452
458
  ref_des_list = [ref_des_list]
453
459
  if not isinstance(net_list, list):
@@ -1234,6 +1240,10 @@ class EdbHfss(object):
1234
1240
  self._layout.cell.SetHFSSExtentInfo(hfss_extent) # returns void
1235
1241
  return True
1236
1242
 
1243
+ def add_setup(self, name=None):
1244
+ """Adding method for grpc compatibility"""
1245
+ return self._pedb.create_hfss_setup(name=name)
1246
+
1237
1247
  def configure_hfss_analysis_setup(self, simulation_setup=None):
1238
1248
  """
1239
1249
  Configure HFSS analysis setup.
@@ -116,6 +116,22 @@ class Material(object):
116
116
  self.__material_def = material_def
117
117
  self.__dc_model = material_def.GetDielectricMaterialModel()
118
118
 
119
+ self._pedb = edb
120
+ self._edb_object = material_def
121
+ definition = self.__edb_definition
122
+ self.material_property_id_mapping = {
123
+ "conductivity": definition.MaterialPropertyId.Conductivity,
124
+ "permittivity": definition.MaterialPropertyId.Permittivity,
125
+ "dielectric_loss_tangent": definition.MaterialPropertyId.DielectricLossTangent,
126
+ "magnetic_loss_tangent": definition.MaterialPropertyId.MagneticLossTangent,
127
+ "mass_density": definition.MaterialPropertyId.MassDensity,
128
+ "permeability": definition.MaterialPropertyId.Permeability,
129
+ "poisson_ratio": definition.MaterialPropertyId.PoissonsRatio,
130
+ "specific_heat": definition.MaterialPropertyId.SpecificHeat,
131
+ "thermal_conductivity": definition.MaterialPropertyId.ThermalConductivity,
132
+ "thermal_expansion_coefficient": definition.MaterialPropertyId.ThermalExpansionCoefficient,
133
+ }
134
+
119
135
  @property
120
136
  def name(self):
121
137
  """Material name."""
@@ -442,6 +458,68 @@ class Material(object):
442
458
  # # Trigger get value on the property
443
459
  # _ = getattr(self, name)
444
460
 
461
+ def set_thermal_modifier(
462
+ self,
463
+ property_name: str,
464
+ basic_quadratic_temperature_reference: float = 21,
465
+ basic_quadratic_c1: float = 0.1,
466
+ basic_quadratic_c2: float = 0.1,
467
+ advanced_quadratic_lower_limit: float = -270,
468
+ advanced_quadratic_upper_limit: float = 1001,
469
+ advanced_quadratic_auto_calculate: bool = False,
470
+ advanced_quadratic_lower_constant: float = 1.1,
471
+ advanced_quadratic_upper_constant: float = 1.1,
472
+ ):
473
+ """Sets the material property thermal modifier of a given material property.
474
+
475
+ Parameters
476
+ ----------
477
+ property_name : str
478
+ Name of the property to modify.
479
+ basic_quadratic_temperature_reference : float, optional
480
+ The TempRef value in the quadratic model.
481
+ basic_quadratic_c1 : float, optional
482
+ The C1 value in the quadratic model.
483
+ basic_quadratic_c2 : float, optional
484
+ The C2 value in the quadratic model.
485
+ advanced_quadratic_lower_limit : float, optional
486
+ The lower temperature limit where the quadratic model is valid.
487
+ advanced_quadratic_upper_limit : float, optional
488
+ The upper temperature limit where the quadratic model is valid.
489
+ advanced_quadratic_auto_calculate : bool, optional
490
+ The flag indicating whether or the LowerConstantThermalModifierVal and UpperConstantThermalModifierVal
491
+ values should be auto calculated.
492
+ advanced_quadratic_lower_constant : float, optional
493
+ The constant thermal modifier value for temperatures lower than LowerConstantThermalModifierVal.
494
+ advanced_quadratic_upper_constant : float, optional
495
+ The constant thermal modifier value for temperatures greater than UpperConstantThermalModifierVal.
496
+
497
+ Returns
498
+ -------
499
+
500
+ """
501
+ _edb = self._pedb._edb
502
+ basic = _edb.Utility.BasicQuadraticParams(
503
+ _edb.Utility.Value(basic_quadratic_temperature_reference),
504
+ _edb.Utility.Value(basic_quadratic_c1),
505
+ _edb.Utility.Value(basic_quadratic_c2),
506
+ )
507
+ advanced = _edb.Utility.AdvancedQuadraticParams(
508
+ _edb.Utility.Value(advanced_quadratic_lower_limit),
509
+ _edb.Utility.Value(advanced_quadratic_upper_limit),
510
+ advanced_quadratic_auto_calculate,
511
+ _edb.Utility.Value(advanced_quadratic_lower_constant),
512
+ _edb.Utility.Value(advanced_quadratic_upper_constant),
513
+ )
514
+
515
+ thermal_modifier = _edb.Definition.MaterialPropertyThermalModifier(basic, advanced)
516
+ if not self.__material_def.SetThermalModifier(
517
+ self.material_property_id_mapping[property_name], thermal_modifier
518
+ ):
519
+ raise ValueError(f"Fail to set thermal modifier for property {property_name}")
520
+ else:
521
+ return True
522
+
445
523
 
446
524
  class Materials(object):
447
525
  """Manages EDB methods for material management accessible from `Edb.materials` property."""
@@ -1317,7 +1317,7 @@ class Modeler(object):
1317
1317
  stat_model.num_resistors = len(self._pedb.components.resistors)
1318
1318
  stat_model.num_inductors = len(self._pedb.components.inductors)
1319
1319
  bbox = self._pedb._hfss.get_layout_bounding_box(self._active_layout)
1320
- stat_model._layout_size = bbox[2] - bbox[0], bbox[3] - bbox[1]
1320
+ stat_model._layout_size = round(bbox[2] - bbox[0], 6), round(bbox[3] - bbox[1], 6)
1321
1321
  stat_model.num_discrete_components = (
1322
1322
  len(self._pedb.components.Others) + len(self._pedb.components.ICs) + len(self._pedb.components.IOs)
1323
1323
  )
@@ -1328,7 +1328,7 @@ class Modeler(object):
1328
1328
  stat_model.num_traces = len(self._pedb.modeler.paths)
1329
1329
  stat_model.num_polygons = len(self._pedb.modeler.polygons)
1330
1330
  stat_model.num_vias = len(self._pedb.padstacks.instances)
1331
- stat_model.stackup_thickness = self._pedb.stackup.get_layout_thickness()
1331
+ stat_model.stackup_thickness = round(self._pedb.stackup.get_layout_thickness(), 6)
1332
1332
  if evaluate_area:
1333
1333
  outline_surface = stat_model.layout_size[0] * stat_model.layout_size[1]
1334
1334
  if net_list:
@@ -1343,8 +1343,8 @@ class Modeler(object):
1343
1343
  surface += prim.length * prim.width
1344
1344
  if prim.type == "Polygon":
1345
1345
  surface += prim.polygon_data._edb_object.Area()
1346
- stat_model.occupying_surface[layer] = surface
1347
- stat_model.occupying_ratio[layer] = surface / outline_surface
1346
+ stat_model.occupying_surface[layer] = round(surface, 6)
1347
+ stat_model.occupying_ratio[layer] = round(surface / outline_surface, 6)
1348
1348
  return stat_model
1349
1349
 
1350
1350
  def create_bondwire(
@@ -1361,6 +1361,7 @@ class Modeler(object):
1361
1361
  end_y,
1362
1362
  net,
1363
1363
  bondwire_type="jedec4",
1364
+ start_cell_instance_name=None,
1364
1365
  ):
1365
1366
  """Create a bondwire object.
1366
1367
 
@@ -1390,13 +1391,16 @@ class Modeler(object):
1390
1391
  Y value of end point.
1391
1392
  net : str or :class:`Net <ansys.edb.net.Net>` or None
1392
1393
  Net of the Bondwire.
1394
+ start_cell_instance_name : None
1395
+ Added for grpc compatibility.
1393
1396
 
1394
1397
  Returns
1395
1398
  -------
1396
1399
  :class:`pyedb.dotnet.database.dotnet.primitive.BondwireDotNet`
1397
1400
  Bondwire object created.
1398
1401
  """
1399
-
1402
+ if start_cell_instance_name:
1403
+ self._pedb.logger.warning(f"start_cell_instance_name {start_cell_instance_name} is only valid with grpc.")
1400
1404
  return Bondwire(
1401
1405
  pedb=self._pedb,
1402
1406
  bondwire_type=bondwire_type,
@@ -47,6 +47,20 @@ class MeshOperation(object):
47
47
  "kNumMeshOpTypes": self._edb_object.TMeshOpType.kNumMeshOpTypes,
48
48
  }
49
49
 
50
+ @property
51
+ def net_layer_info(self):
52
+ """Adding property for grpc compatibility.
53
+
54
+ Returns
55
+ -------
56
+ The tuple is in this form: (net_name, layer_name, is_sheet)``.
57
+ """
58
+ layer_inf = []
59
+ for net_name, mesh_op in self.nets_layers_list.items():
60
+ for layer in mesh_op:
61
+ layer_inf.append((net_name, layer, True))
62
+ return layer_inf
63
+
50
64
  @property
51
65
  def enabled(self):
52
66
  """Whether if mesh operation is enabled.
@@ -220,6 +234,11 @@ class LengthMeshOperation(MeshOperation, object):
220
234
  """
221
235
  return self._edb_object.MaxLength
222
236
 
237
+ @property
238
+ def restrict_max_length(self):
239
+ """Adding property for grpc compatibility."""
240
+ return self.restrict_length
241
+
223
242
  @property
224
243
  def restrict_length(self):
225
244
  """Whether to restrict length of elements.
@@ -286,6 +305,11 @@ class SkinDepthMeshOperation(MeshOperation, object):
286
305
  def surface_triangle_length(self, value):
287
306
  self._edb_object.SurfTriLength = value
288
307
 
308
+ @property
309
+ def number_of_layers(self):
310
+ """Adding property for grpc compatibility."""
311
+ return self.number_of_layer_elements
312
+
289
313
  @property
290
314
  def number_of_layer_elements(self):
291
315
  """Number of layer elements.
@@ -401,7 +401,7 @@ class EdbSiwave(object):
401
401
  voltage_source.positive_node.component_node = pos_pin.GetComponent()
402
402
  voltage_source.positive_node.node_pins = pos_pin
403
403
  voltage_source.negative_node.component_node = neg_pin.GetComponent()
404
- voltage_source.negative_node.node_pins = pos_pin
404
+ voltage_source.negative_node.node_pins = neg_pin
405
405
  return self._create_terminal_on_pins(voltage_source)
406
406
 
407
407
  def create_current_source_on_pin(self, pos_pin, neg_pin, current_value=0.1, phase_value=0, source_name=""):
@@ -109,6 +109,11 @@ class SimulationSetup(object):
109
109
  warnings.warn("Use new property :func:`sim_setup_info` instead.", DeprecationWarning)
110
110
  return self.sim_setup_info._edb_object
111
111
 
112
+ @property
113
+ def is_null(self):
114
+ """Adding this property for compatibility with grpc."""
115
+ return self._edb_object.IsNull()
116
+
112
117
  def get_simulation_settings(self):
113
118
  sim_settings = self.sim_setup_info.simulation_settings
114
119
  properties = {}
@@ -237,13 +242,43 @@ class SimulationSetup(object):
237
242
  """List of frequency sweeps."""
238
243
  return {i.name: i for i in self.sim_setup_info.sweep_data_list}
239
244
 
240
- def add_sweep(self, name: str = None, frequency_set: list = None, sweep_type: str = "interpolation", **kwargs):
245
+ @property
246
+ def sweep_data(self):
247
+ """Adding property for compatibility with grpc."""
248
+ return list(self.sweeps.values())
249
+
250
+ @sweep_data.setter
251
+ def sweep_data(self, sweep_data):
252
+ for sweep in self.sweep_data:
253
+ self.delete_frequency_sweep(sweep)
254
+ for sweep in sweep_data:
255
+ self._add_frequency_sweep(sweep)
256
+
257
+ def add_sweep(
258
+ self,
259
+ name: str = None,
260
+ distribution: str = None,
261
+ start_freq: str = None,
262
+ stop_freq: str = None,
263
+ step=None,
264
+ frequency_set: list = None,
265
+ sweep_type: str = "interpolation",
266
+ **kwargs,
267
+ ):
241
268
  """Add frequency sweep.
242
269
 
243
270
  Parameters
244
271
  ----------
245
272
  name : str, optional
246
273
  Name of the frequency sweep. The default is ``None``.
274
+ distribution : str, optional
275
+ Added for grpc compatibility.
276
+ start_freq : str, optional
277
+ Added for rpc compatibility.
278
+ stop_freq : str, optional
279
+ Added for grpc compatibility.
280
+ step : optional
281
+ Added for grpc compatibility.
247
282
  frequency_set : list, optional
248
283
  List of frequency points. The default is ``None``.
249
284
  sweep_type : str, optional
@@ -261,21 +296,28 @@ class SimulationSetup(object):
261
296
  raise ValueError("Sweep {} already exists.".format(name))
262
297
 
263
298
  sweep_data = SweepData(self._pedb, name=name, sim_setup=self)
264
- for k, v in kwargs.items():
265
- if k in dir(sweep_data):
266
- setattr(sweep_data, k, v)
267
- sweep_data.type = sweep_type
299
+ # adding grpc compatibility
300
+ if distribution and start_freq and stop_freq and step:
301
+ if distribution == "linear":
302
+ distribution = "linear_scale" # to be compatible with grpc
303
+ frequency_set = [[distribution, start_freq, stop_freq, step]]
268
304
 
269
305
  if frequency_set in [None, []]:
270
- sweep_type = "linear_scale"
306
+ distribution = "linear_scale"
271
307
  start, stop, increment = "50MHz", "5GHz", "50MHz"
272
- frequency_set = [[sweep_type, start, stop, increment]]
308
+ frequency_set = [[distribution, start, stop, increment]]
273
309
  elif not isinstance(frequency_set[0], list):
274
310
  frequency_set = [frequency_set]
275
311
 
276
312
  for fs in frequency_set:
277
- sweep_type, start, stop, increment = fs
278
- sweep_data.add(sweep_type, start, stop, increment)
313
+ distribution, start, stop, increment = fs
314
+ sweep_data.add(distribution, start, stop, increment)
315
+
316
+ for k, v in kwargs.items():
317
+ if k in dir(sweep_data):
318
+ setattr(sweep_data, k, v)
319
+ sweep_data.type = sweep_type
320
+
279
321
  return sweep_data
280
322
 
281
323
  def delete(self):