pyedb 0.13.dev0__py3-none-any.whl → 0.14.1__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 (75) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/configuration/cfg_common.py +0 -5
  3. pyedb/configuration/cfg_components.py +0 -2
  4. pyedb/configuration/cfg_operations.py +0 -2
  5. pyedb/configuration/cfg_package_definition.py +0 -2
  6. pyedb/configuration/cfg_ports_sources.py +14 -11
  7. pyedb/configuration/cfg_stackup.py +0 -7
  8. pyedb/configuration/configuration.py +0 -6
  9. pyedb/dotnet/application/Variables.py +4 -40
  10. pyedb/dotnet/edb.py +27 -82
  11. pyedb/dotnet/edb_core/{edb_data/components_data.py → cell/hierarchy/component.py} +13 -133
  12. pyedb/dotnet/edb_core/cell/hierarchy/model.py +0 -3
  13. pyedb/dotnet/edb_core/cell/hierarchy/netlist_model.py +30 -0
  14. pyedb/dotnet/edb_core/cell/hierarchy/pin_pair_model.py +105 -0
  15. pyedb/dotnet/edb_core/cell/hierarchy/s_parameter_model.py +34 -0
  16. pyedb/dotnet/edb_core/cell/hierarchy/spice_model.py +34 -0
  17. pyedb/dotnet/edb_core/cell/layout.py +137 -0
  18. pyedb/dotnet/edb_core/cell/layout_obj.py +2 -4
  19. pyedb/dotnet/edb_core/cell/primitive.py +199 -1
  20. pyedb/dotnet/edb_core/cell/terminal/bundle_terminal.py +52 -0
  21. pyedb/dotnet/edb_core/cell/terminal/edge_terminal.py +50 -0
  22. pyedb/dotnet/edb_core/cell/terminal/padstack_instance_terminal.py +88 -0
  23. pyedb/dotnet/edb_core/cell/terminal/pingroup_terminal.py +59 -0
  24. pyedb/dotnet/edb_core/cell/terminal/point_terminal.py +73 -0
  25. pyedb/dotnet/edb_core/{edb_data/terminals.py → cell/terminal/terminal.py} +33 -242
  26. pyedb/dotnet/edb_core/components.py +10 -56
  27. pyedb/dotnet/edb_core/definition/component_def.py +1 -8
  28. pyedb/dotnet/edb_core/definition/component_model.py +0 -2
  29. pyedb/dotnet/edb_core/definition/definitions.py +0 -2
  30. pyedb/dotnet/edb_core/definition/package_def.py +7 -5
  31. pyedb/dotnet/edb_core/edb_data/control_file.py +0 -3
  32. pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py +0 -5
  33. pyedb/dotnet/edb_core/edb_data/hfss_pi_simulation_setup_data.py +4 -9
  34. pyedb/dotnet/edb_core/edb_data/layer_data.py +0 -7
  35. pyedb/dotnet/edb_core/edb_data/nets_data.py +2 -5
  36. pyedb/dotnet/edb_core/edb_data/padstacks_data.py +11 -29
  37. pyedb/dotnet/edb_core/edb_data/ports.py +4 -4
  38. pyedb/dotnet/edb_core/edb_data/primitives_data.py +3 -26
  39. pyedb/dotnet/edb_core/edb_data/raptor_x_simulation_setup_data.py +13 -20
  40. pyedb/dotnet/edb_core/edb_data/simulation_configuration.py +3 -11
  41. pyedb/dotnet/edb_core/edb_data/sources.py +12 -17
  42. pyedb/dotnet/edb_core/general.py +1 -6
  43. pyedb/dotnet/edb_core/geometry/polygon_data.py +0 -3
  44. pyedb/dotnet/edb_core/hfss.py +1 -33
  45. pyedb/dotnet/edb_core/layout.py +0 -35
  46. pyedb/dotnet/edb_core/layout_validation.py +1 -3
  47. pyedb/dotnet/edb_core/materials.py +1 -22
  48. pyedb/dotnet/edb_core/net_class.py +0 -8
  49. pyedb/dotnet/edb_core/nets.py +4 -29
  50. pyedb/dotnet/edb_core/padstack.py +76 -30
  51. pyedb/dotnet/edb_core/sim_setup_data/data/adaptive_frequency_data.py +72 -0
  52. pyedb/dotnet/edb_core/sim_setup_data/data/mesh_operation.py +287 -0
  53. pyedb/dotnet/edb_core/{edb_data/hfss_simulation_setup_data.py → sim_setup_data/data/settings.py} +174 -878
  54. pyedb/dotnet/edb_core/sim_setup_data/data/sweep_data.py +509 -0
  55. pyedb/dotnet/edb_core/sim_setup_data/io/__init__.py +0 -0
  56. pyedb/dotnet/edb_core/{edb_data/siwave_simulation_setup_data.py → sim_setup_data/io/siwave.py} +0 -341
  57. pyedb/dotnet/edb_core/siwave.py +5 -33
  58. pyedb/dotnet/edb_core/stackup.py +4 -51
  59. pyedb/dotnet/edb_core/utilities/simulation_setup.py +613 -366
  60. pyedb/generic/data_handlers.py +1 -9
  61. pyedb/generic/general_methods.py +3 -53
  62. pyedb/generic/plot.py +1 -2
  63. pyedb/ipc2581/ecad/cad_data/layer_feature.py +1 -7
  64. pyedb/ipc2581/ecad/cad_data/package.py +1 -4
  65. pyedb/ipc2581/ecad/cad_data/path.py +1 -3
  66. pyedb/ipc2581/ecad/cad_data/polygon.py +1 -6
  67. pyedb/ipc2581/ecad/cad_data/step.py +1 -10
  68. pyedb/ipc2581/ipc2581.py +8 -15
  69. pyedb/modeler/geometry_operators.py +164 -67
  70. pyedb/siwave.py +25 -32
  71. {pyedb-0.13.dev0.dist-info → pyedb-0.14.1.dist-info}/METADATA +2 -2
  72. {pyedb-0.13.dev0.dist-info → pyedb-0.14.1.dist-info}/RECORD +75 -61
  73. /pyedb/dotnet/edb_core/cell/{__init__.py → terminal/__init__.py} +0 -0
  74. {pyedb-0.13.dev0.dist-info → pyedb-0.14.1.dist-info}/LICENSE +0 -0
  75. {pyedb-0.13.dev0.dist-info → pyedb-0.14.1.dist-info}/WHEEL +0 -0
@@ -35,7 +35,7 @@ from pyedb.dotnet.edb_core.edb_data.padstacks_data import (
35
35
  EDBPadstackInstance,
36
36
  )
37
37
  from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
38
- from pyedb.generic.general_methods import generate_unique_name, pyedb_function_handler
38
+ from pyedb.generic.general_methods import generate_unique_name
39
39
  from pyedb.modeler.geometry_operators import GeometryOperators
40
40
 
41
41
 
@@ -49,7 +49,6 @@ class EdbPadstacks(object):
49
49
  >>> edb_padstacks = edbapp.padstacks
50
50
  """
51
51
 
52
- @pyedb_function_handler()
53
52
  def __getitem__(self, name):
54
53
  """Get a padstack definition or instance from the Edb project.
55
54
 
@@ -59,7 +58,7 @@ class EdbPadstacks(object):
59
58
 
60
59
  Returns
61
60
  -------
62
- :class:`pyedb.dotnet.edb_core.edb_data.components_data.EDBComponent`
61
+ :class:`pyedb.dotnet.edb_core.cell.hierarchy.component.EDBComponent`
63
62
 
64
63
  """
65
64
  if name in self.instances:
@@ -109,7 +108,6 @@ class EdbPadstacks(object):
109
108
  """ """
110
109
  return self._pedb.stackup.stackup_layers
111
110
 
112
- @pyedb_function_handler()
113
111
  def int_to_pad_type(self, val=0):
114
112
  """Convert an integer to an EDB.PadGeometryType.
115
113
 
@@ -136,7 +134,6 @@ class EdbPadstacks(object):
136
134
  else:
137
135
  return val
138
136
 
139
- @pyedb_function_handler()
140
137
  def int_to_geometry_type(self, val=0):
141
138
  """Convert an integer to an EDB.PadGeometryType.
142
139
 
@@ -329,7 +326,6 @@ class EdbPadstacks(object):
329
326
 
330
327
  return PadType
331
328
 
332
- @pyedb_function_handler()
333
329
  def create_circular_padstack(
334
330
  self,
335
331
  padstackname=None,
@@ -431,7 +427,6 @@ class EdbPadstacks(object):
431
427
  )
432
428
  PadStack.SetData(new_PadStackData)
433
429
 
434
- @pyedb_function_handler()
435
430
  def delete_padstack_instances(self, net_names): # pragma: no cover
436
431
  """Delete padstack instances by net names.
437
432
 
@@ -459,7 +454,6 @@ class EdbPadstacks(object):
459
454
  return False
460
455
  return True
461
456
 
462
- @pyedb_function_handler()
463
457
  def set_solderball(self, padstackInst, sballLayer_name, isTopPlaced=True, ballDiam=100e-6):
464
458
  """Set solderball for the given PadstackInstance.
465
459
 
@@ -502,7 +496,6 @@ class EdbPadstacks(object):
502
496
 
503
497
  return False
504
498
 
505
- @pyedb_function_handler()
506
499
  def create_coax_port(self, padstackinstance, use_dot_separator=True, name=None):
507
500
  """Create HFSS 3Dlayout coaxial lumped port on a pastack
508
501
  Requires to have solder ball defined before calling this method.
@@ -564,11 +557,9 @@ class EdbPadstacks(object):
564
557
  return port_name
565
558
  return ""
566
559
 
567
- @pyedb_function_handler()
568
560
  def _port_exist(self, port_name):
569
561
  return any(port for port in list(self._pedb.excitations.keys()) if port == port_name)
570
562
 
571
- @pyedb_function_handler()
572
563
  def get_pinlist_from_component_and_net(self, refdes=None, netname=None):
573
564
  """Retrieve pins given a component's reference designator and net name.
574
565
 
@@ -605,7 +596,6 @@ class EdbPadstacks(object):
605
596
 
606
597
  return pinlist
607
598
 
608
- @pyedb_function_handler()
609
599
  def get_pad_parameters(self, pin, layername, pad_type=0):
610
600
  """Get Padstack Parameters from Pin or Padstack Definition.
611
601
 
@@ -661,7 +651,6 @@ class EdbPadstacks(object):
661
651
  return geometry_type, parameters, offset_x, offset_y, rotation
662
652
  return 0, [0], 0, 0, 0
663
653
 
664
- @pyedb_function_handler()
665
654
  def set_all_antipad_value(self, value):
666
655
  """Set all anti-pads from all pad-stack definition to the given value.
667
656
 
@@ -710,7 +699,6 @@ class EdbPadstacks(object):
710
699
  padstack.edb_padstack.SetData(cloned_padstack_data)
711
700
  return all_succeed
712
701
 
713
- @pyedb_function_handler()
714
702
  def check_and_fix_via_plating(self, minimum_value_to_replace=0.0, default_plating_ratio=0.2):
715
703
  """Check for minimum via plating ration value, values found below the minimum one are replaced by default
716
704
  plating ratio.
@@ -736,7 +724,6 @@ class EdbPadstacks(object):
736
724
  )
737
725
  return True
738
726
 
739
- @pyedb_function_handler()
740
727
  def get_via_instance_from_net(self, net_list=None):
741
728
  """Get the list for EDB vias from a net name list.
742
729
 
@@ -767,7 +754,6 @@ class EdbPadstacks(object):
767
754
  via_list.append(lobj)
768
755
  return via_list
769
756
 
770
- @pyedb_function_handler()
771
757
  def create_padstack(
772
758
  self,
773
759
  padstackname=None,
@@ -850,7 +836,6 @@ class EdbPadstacks(object):
850
836
  pad_rotation=pad_rotation,
851
837
  )
852
838
 
853
- @pyedb_function_handler()
854
839
  def create(
855
840
  self,
856
841
  padstackname=None,
@@ -958,7 +943,7 @@ class EdbPadstacks(object):
958
943
  else:
959
944
  return False
960
945
  elif isinstance(polygon_hole, PolygonDataDotNet):
961
- hole_param = polygon_hole
946
+ hole_param = polygon_hole.edb_api
962
947
  else:
963
948
  return False
964
949
  padstackData.SetPolygonalHoleParameters(hole_param, value0, value0, value0)
@@ -1077,7 +1062,6 @@ class EdbPadstacks(object):
1077
1062
  self._logger.info("Padstack %s create correctly", padstackname)
1078
1063
  return padstackname
1079
1064
 
1080
- @pyedb_function_handler()
1081
1065
  def _get_pin_layer_range(self, pin):
1082
1066
  res, fromlayer, tolayer = pin.GetLayerRange()
1083
1067
  if res:
@@ -1085,7 +1069,6 @@ class EdbPadstacks(object):
1085
1069
  else:
1086
1070
  return False
1087
1071
 
1088
- @pyedb_function_handler()
1089
1072
  def duplicate_padstack(self, target_padstack_name, new_padstack_name=""):
1090
1073
  """Duplicate a padstack.
1091
1074
 
@@ -1107,7 +1090,6 @@ class EdbPadstacks(object):
1107
1090
  warnings.warn("Use :func:`create` method instead.", DeprecationWarning)
1108
1091
  return self.duplicate(target_padstack_name=target_padstack_name, new_padstack_name=new_padstack_name)
1109
1092
 
1110
- @pyedb_function_handler()
1111
1093
  def duplicate(self, target_padstack_name, new_padstack_name=""):
1112
1094
  """Duplicate a padstack.
1113
1095
 
@@ -1134,7 +1116,6 @@ class EdbPadstacks(object):
1134
1116
 
1135
1117
  return new_padstack_name
1136
1118
 
1137
- @pyedb_function_handler()
1138
1119
  def place(
1139
1120
  self,
1140
1121
  position,
@@ -1221,7 +1202,6 @@ class EdbPadstacks(object):
1221
1202
  else:
1222
1203
  return False
1223
1204
 
1224
- @pyedb_function_handler()
1225
1205
  def place_padstack(
1226
1206
  self,
1227
1207
  position,
@@ -1276,7 +1256,6 @@ class EdbPadstacks(object):
1276
1256
  is_pin=is_pin,
1277
1257
  )
1278
1258
 
1279
- @pyedb_function_handler()
1280
1259
  def remove_pads_from_padstack(self, padstack_name, layer_name=None):
1281
1260
  """Remove the Pad from a padstack on a specific layer by setting it as a 0 thickness circle.
1282
1261
 
@@ -1309,7 +1288,6 @@ class EdbPadstacks(object):
1309
1288
  self.definitions[padstack_name].edb_padstack.SetData(newPadstackDefinitionData)
1310
1289
  return True
1311
1290
 
1312
- @pyedb_function_handler()
1313
1291
  def set_pad_property(
1314
1292
  self,
1315
1293
  padstack_name,
@@ -1411,7 +1389,6 @@ class EdbPadstacks(object):
1411
1389
  self.definitions[padstack_name].edb_padstack.SetData(new_padstack_def)
1412
1390
  return True
1413
1391
 
1414
- @pyedb_function_handler()
1415
1392
  def get_instances(
1416
1393
  self,
1417
1394
  name=None,
@@ -1467,7 +1444,6 @@ class EdbPadstacks(object):
1467
1444
  instances = [inst for inst in instances if inst.pin_number in component_pin]
1468
1445
  return instances
1469
1446
 
1470
- @pyedb_function_handler()
1471
1447
  def get_padstack_instance_by_net_name(self, net_name):
1472
1448
  """Get a list of padstack instances by net name.
1473
1449
 
@@ -1484,7 +1460,6 @@ class EdbPadstacks(object):
1484
1460
  warnings.warn("Use new property :func:`get_padstack_instance` instead.", DeprecationWarning)
1485
1461
  return self.get_instances(net_name=net_name)
1486
1462
 
1487
- @pyedb_function_handler()
1488
1463
  def get_reference_pins(
1489
1464
  self, positive_pin, reference_net="gnd", search_radius=5e-3, max_limit=0, component_only=True
1490
1465
  ):
@@ -1542,7 +1517,6 @@ class EdbPadstacks(object):
1542
1517
  pinlist = [pin[1] for pin in sorted(pin_dict.items())[:max_limit]]
1543
1518
  return pinlist
1544
1519
 
1545
- @pyedb_function_handler()
1546
1520
  def get_padstack_instances_rtree_index(self, nets=None):
1547
1521
  """Returns padstack instances Rtree index.
1548
1522
 
@@ -1568,7 +1542,6 @@ class EdbPadstacks(object):
1568
1542
  padstack_instances_index.insert(inst.id, inst.position)
1569
1543
  return padstack_instances_index
1570
1544
 
1571
- @pyedb_function_handler()
1572
1545
  def get_padstack_instances_intersecting_bounding_box(self, bounding_box, nets=None):
1573
1546
  """Returns the list of padstack instances ID intersecting a given bounding box and nets.
1574
1547
 
@@ -1592,3 +1565,76 @@ class EdbPadstacks(object):
1592
1565
  if isinstance(bounding_box, list):
1593
1566
  bounding_box = tuple(bounding_box)
1594
1567
  return list(index.intersection(bounding_box))
1568
+
1569
+ def merge_via_along_lines(self, net_name="GND", distance_threshold=5e-3, minimum_via_number=6):
1570
+ """Replace padstack instances along lines into a single polygon.
1571
+
1572
+ Detect all padstack instances that are placed along lines and replace them by a single polygon based one
1573
+ forming a wall shape. This method is designed to simplify meshing on via fence usually added to shield RF traces
1574
+ on PCB.
1575
+
1576
+ Parameters
1577
+ ----------
1578
+ net_name : str
1579
+ Net name used for detected padstack instances. Default value is ``"GND"``.
1580
+
1581
+ distance_threshold : float, None, optional
1582
+ If two points in a line are separated by a distance larger than `distance_threshold`,
1583
+ the line is divided in two parts. Default is ``5e-3`` (5mm), in which case the control is not performed.
1584
+
1585
+ minimum_via_number : int, optional
1586
+ The minimum number of points that a line must contain. Default is ``6``.
1587
+
1588
+ Returns
1589
+ -------
1590
+ bool
1591
+ ``True`` when succeeded ``False`` when failed. <
1592
+
1593
+ """
1594
+ _def = list(
1595
+ set([inst.padstack_definition for inst in list(self.instances.values()) if inst.net_name == net_name])
1596
+ )
1597
+ if not _def:
1598
+ self._logger.error(f"No padstack definition found for net {net_name}")
1599
+ return False
1600
+ _instances_to_delete = []
1601
+ padstack_instances = []
1602
+ for pdstk_def in _def:
1603
+ padstack_instances.append(
1604
+ [inst for inst in self.definitions[pdstk_def].instances if inst.net_name == net_name]
1605
+ )
1606
+ for pdstk_series in padstack_instances:
1607
+ instances_location = [inst.position for inst in pdstk_series]
1608
+ lines, line_indexes = GeometryOperators.find_points_along_lines(
1609
+ points=instances_location,
1610
+ minimum_number_of_points=minimum_via_number,
1611
+ distance_threshold=distance_threshold,
1612
+ )
1613
+ for line in line_indexes:
1614
+ [_instances_to_delete.append(pdstk_series[ind]) for ind in line]
1615
+ start_point = pdstk_series[line[0]]
1616
+ stop_point = pdstk_series[line[-1]]
1617
+ padstack_def = start_point.padstack_definition
1618
+ trace_width = self.definitions[padstack_def].pad_by_layer[stop_point.start_layer].parameters_values[0]
1619
+ trace = self._pedb.modeler.create_trace(
1620
+ path_list=[start_point.position, stop_point.position],
1621
+ layer_name=start_point.start_layer,
1622
+ width=trace_width,
1623
+ )
1624
+ polygon_data = trace.polygon_data
1625
+ trace.delete()
1626
+ new_padstack_def = generate_unique_name(padstack_def)
1627
+ if not self.create(
1628
+ padstackname=new_padstack_def,
1629
+ pad_shape="Polygon",
1630
+ antipad_shape="Polygon",
1631
+ pad_polygon=polygon_data,
1632
+ antipad_polygon=polygon_data,
1633
+ polygon_hole=polygon_data,
1634
+ ):
1635
+ self._logger.error(f"Failed to create padstack definition {new_padstack_def}")
1636
+ if not self.place(position=[0, 0], definition_name=new_padstack_def, net_name=net_name):
1637
+ self._logger.error(f"Failed to place padstack instance {new_padstack_def}")
1638
+ for inst in _instances_to_delete:
1639
+ inst.delete()
1640
+ return True
@@ -0,0 +1,72 @@
1
+ # Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
2
+ # SPDX-License-Identifier: MIT
3
+ #
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+
24
+ class AdaptiveFrequencyData(object):
25
+ """Manages EDB methods for adaptive frequency data."""
26
+
27
+ def __init__(self, adaptive_frequency_data):
28
+ self._adaptive_frequency_data = adaptive_frequency_data
29
+
30
+ @property
31
+ def adaptive_frequency(self):
32
+ """Adaptive frequency for the setup.
33
+
34
+ Returns
35
+ -------
36
+ str
37
+ Frequency with units.
38
+ """
39
+ return self._adaptive_frequency_data.AdaptiveFrequency
40
+
41
+ @adaptive_frequency.setter
42
+ def adaptive_frequency(self, value):
43
+ self._adaptive_frequency_data.AdaptiveFrequency = value
44
+
45
+ @property
46
+ def max_delta(self):
47
+ """Maximum change of S-parameters between two consecutive passes, which serves as
48
+ a stopping criterion.
49
+
50
+ Returns
51
+ -------
52
+ str
53
+ """
54
+ return self._adaptive_frequency_data.MaxDelta
55
+
56
+ @max_delta.setter
57
+ def max_delta(self, value):
58
+ self._adaptive_frequency_data.MaxDelta = str(value)
59
+
60
+ @property
61
+ def max_passes(self):
62
+ """Maximum allowed number of mesh refinement cycles.
63
+
64
+ Returns
65
+ -------
66
+ int
67
+ """
68
+ return self._adaptive_frequency_data.MaxPasses
69
+
70
+ @max_passes.setter
71
+ def max_passes(self, value):
72
+ self._adaptive_frequency_data.MaxPasses = value
@@ -0,0 +1,287 @@
1
+ # Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
2
+ # SPDX-License-Identifier: MIT
3
+ #
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ from System import Tuple
24
+
25
+ from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
26
+
27
+
28
+ class MeshOperation(object):
29
+ """Mesh Operation Class."""
30
+
31
+ def __init__(self, parent, mesh_operation):
32
+ self._parent = parent
33
+ self.mesh_operation = mesh_operation
34
+ self._mesh_op_mapping = {
35
+ "kMeshSetupBase": mesh_operation.TMeshOpType.kMeshSetupBase,
36
+ "kMeshSetupLength": mesh_operation.TMeshOpType.kMeshSetupLength,
37
+ "kMeshSetupSkinDepth": mesh_operation.TMeshOpType.kMeshSetupSkinDepth,
38
+ "kNumMeshOpTypes": mesh_operation.TMeshOpType.kNumMeshOpTypes,
39
+ }
40
+
41
+ @property
42
+ def enabled(self):
43
+ """Whether if mesh operation is enabled.
44
+
45
+ Returns
46
+ -------
47
+ bool
48
+ ``True`` if mesh operation is used, ``False`` otherwise.
49
+ """
50
+ return self.mesh_operation.Enabled
51
+
52
+ @property
53
+ def mesh_operation_type(self):
54
+ """Mesh operation type.
55
+ Options:
56
+ 0- ``kMeshSetupBase``
57
+ 1- ``kMeshSetupLength``
58
+ 2- ``kMeshSetupSkinDepth``
59
+ 3- ``kNumMeshOpTypes``.
60
+
61
+ Returns
62
+ -------
63
+ int
64
+ """
65
+ return self.mesh_operation.MeshOpType.ToString()
66
+
67
+ @property
68
+ def mesh_region(self):
69
+ """Mesh region name.
70
+
71
+ Returns
72
+ -------
73
+ str
74
+ Name of the mesh region.
75
+ """
76
+ return self.mesh_operation.MeshRegion
77
+
78
+ @property
79
+ def name(self):
80
+ """Mesh operation name.
81
+
82
+ Returns
83
+ -------
84
+ str
85
+ """
86
+ return self.mesh_operation.Name
87
+
88
+ @property
89
+ def nets_layers_list(self):
90
+ """List of nets and layers.
91
+
92
+ Returns
93
+ -------
94
+ list
95
+ List of lists with three elements. Each list must contain:
96
+ 1- net name
97
+ 2- layer name
98
+ 3- bool.
99
+ Third element is represents whether if the mesh operation is enabled or disabled.
100
+
101
+ """
102
+ return self.mesh_operation.NetsLayersList
103
+
104
+ @nets_layers_list.setter
105
+ def nets_layers_list(self, values):
106
+ temp = []
107
+ for net, layers in values.items():
108
+ for layer in layers:
109
+ temp.append(Tuple[str, str, bool](net, layer, True))
110
+ self.mesh_operation.NetsLayersList = convert_py_list_to_net_list(temp)
111
+
112
+ @property
113
+ def refine_inside(self):
114
+ """Whether to turn on refine inside objects.
115
+
116
+ Returns
117
+ -------
118
+ bool
119
+ ``True`` if refine inside objects is used, ``False`` otherwise.
120
+
121
+ """
122
+ return self.mesh_operation.RefineInside
123
+
124
+ @enabled.setter
125
+ def enabled(self, value):
126
+ self.mesh_operation.Enabled = value
127
+ self._parent._update_setup()
128
+
129
+ @mesh_region.setter
130
+ def mesh_region(self, value):
131
+ self.mesh_operation.MeshRegion = value
132
+ self._parent._update_setup()
133
+
134
+ @name.setter
135
+ def name(self, value):
136
+ self.mesh_operation.Name = value
137
+ self._parent._update_setup()
138
+
139
+ @refine_inside.setter
140
+ def refine_inside(self, value):
141
+ self.mesh_operation.RefineInside = value
142
+ self._parent._update_setup()
143
+
144
+ @property
145
+ def max_elements(self):
146
+ """Maximum number of elements.
147
+
148
+ Returns
149
+ -------
150
+ str
151
+ """
152
+ return self.mesh_operation.MaxElems
153
+
154
+ @property
155
+ def restrict_max_elements(self):
156
+ """Whether to restrict maximum number of elements.
157
+
158
+ Returns
159
+ -------
160
+ bool
161
+ """
162
+ return self.mesh_operation.RestrictMaxElem
163
+
164
+ @max_elements.setter
165
+ def max_elements(self, value):
166
+ self.mesh_operation.MaxElems = str(value)
167
+ self._parent._update_setup()
168
+
169
+ @restrict_max_elements.setter
170
+ def restrict_max_elements(self, value):
171
+ """Whether to restrict maximum number of elements.
172
+
173
+ Returns
174
+ -------
175
+ bool
176
+ """
177
+ self.mesh_operation.RestrictMaxElem = value
178
+ self._parent._update_setup()
179
+
180
+
181
+ class MeshOperationLength(MeshOperation, object):
182
+ """Mesh operation Length class.
183
+ This class is accessible from Hfss Setup in EDB and add_length_mesh_operation method.
184
+
185
+ Examples
186
+ --------
187
+ >>> mop = edbapp.setups["setup1a"].add_length_mesh_operation({"GND": ["TOP", "BOTTOM"]})
188
+ >>> mop.max_elements = 3000
189
+ """
190
+
191
+ def __init__(self, parent, mesh_operation):
192
+ MeshOperation.__init__(self, parent, mesh_operation)
193
+
194
+ @property
195
+ def max_length(self):
196
+ """Maximum length of elements.
197
+
198
+ Returns
199
+ -------
200
+ str
201
+ """
202
+ return self.mesh_operation.MaxLength
203
+
204
+ @property
205
+ def restrict_length(self):
206
+ """Whether to restrict length of elements.
207
+
208
+ Returns
209
+ -------
210
+ bool
211
+ """
212
+ return self.mesh_operation.RestrictLength
213
+
214
+ @max_length.setter
215
+ def max_length(self, value):
216
+ self.mesh_operation.MaxLength = value
217
+ self._parent._update_setup()
218
+
219
+ @restrict_length.setter
220
+ def restrict_length(self, value):
221
+ """Whether to restrict length of elements.
222
+
223
+ Returns
224
+ -------
225
+ bool
226
+ """
227
+ self.mesh_operation.RestrictLength = value
228
+ self._parent._update_setup()
229
+
230
+
231
+ class MeshOperationSkinDepth(MeshOperation, object):
232
+ """Mesh operation Skin Depth class.
233
+ This class is accessible from Hfss Setup in EDB and assign_skin_depth_mesh_operation method.
234
+
235
+ Examples
236
+ --------
237
+ >>> mop = edbapp.setups["setup1a"].add_skin_depth_mesh_operation({"GND": ["TOP", "BOTTOM"]})
238
+ >>> mop.max_elements = 3000
239
+ """
240
+
241
+ def __init__(self, parent, mesh_operation):
242
+ MeshOperation.__init__(self, parent, mesh_operation)
243
+
244
+ @property
245
+ def skin_depth(self):
246
+ """Skin depth value.
247
+
248
+ Returns
249
+ -------
250
+ str
251
+ """
252
+ return self.mesh_operation.SkinDepth
253
+
254
+ @skin_depth.setter
255
+ def skin_depth(self, value):
256
+ self.mesh_operation.SkinDepth = value
257
+ self._parent._update_setup()
258
+
259
+ @property
260
+ def surface_triangle_length(self):
261
+ """Surface triangle length value.
262
+
263
+ Returns
264
+ -------
265
+ str
266
+ """
267
+ return self.mesh_operation.SurfTriLength
268
+
269
+ @surface_triangle_length.setter
270
+ def surface_triangle_length(self, value):
271
+ self.mesh_operation.SurfTriLength = value
272
+ self._parent._update_setup()
273
+
274
+ @property
275
+ def number_of_layer_elements(self):
276
+ """Number of layer elements.
277
+
278
+ Returns
279
+ -------
280
+ str
281
+ """
282
+ return self.mesh_operation.NumLayers
283
+
284
+ @number_of_layer_elements.setter
285
+ def number_of_layer_elements(self, value):
286
+ self.mesh_operation.NumLayers = str(value)
287
+ self._parent._update_setup()