pyedb 0.13.dev0__py3-none-any.whl → 0.15.dev0__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.
- pyedb/__init__.py +1 -1
- pyedb/configuration/cfg_common.py +0 -5
- pyedb/configuration/cfg_components.py +0 -2
- pyedb/configuration/cfg_operations.py +0 -2
- pyedb/configuration/cfg_package_definition.py +0 -2
- pyedb/configuration/cfg_ports_sources.py +14 -11
- pyedb/configuration/cfg_stackup.py +0 -7
- pyedb/configuration/configuration.py +0 -6
- pyedb/dotnet/application/Variables.py +4 -40
- pyedb/dotnet/edb.py +27 -82
- pyedb/dotnet/edb_core/{edb_data/components_data.py → cell/hierarchy/component.py} +13 -133
- pyedb/dotnet/edb_core/cell/hierarchy/model.py +0 -3
- pyedb/dotnet/edb_core/cell/hierarchy/netlist_model.py +30 -0
- pyedb/dotnet/edb_core/cell/hierarchy/pin_pair_model.py +105 -0
- pyedb/dotnet/edb_core/cell/hierarchy/s_parameter_model.py +34 -0
- pyedb/dotnet/edb_core/cell/hierarchy/spice_model.py +34 -0
- pyedb/dotnet/edb_core/cell/layout.py +137 -0
- pyedb/dotnet/edb_core/cell/layout_obj.py +2 -4
- pyedb/dotnet/edb_core/cell/primitive.py +199 -1
- pyedb/dotnet/edb_core/cell/terminal/bundle_terminal.py +52 -0
- pyedb/dotnet/edb_core/cell/terminal/edge_terminal.py +50 -0
- pyedb/dotnet/edb_core/cell/terminal/padstack_instance_terminal.py +88 -0
- pyedb/dotnet/edb_core/cell/terminal/pingroup_terminal.py +59 -0
- pyedb/dotnet/edb_core/cell/terminal/point_terminal.py +73 -0
- pyedb/dotnet/edb_core/{edb_data/terminals.py → cell/terminal/terminal.py} +33 -242
- pyedb/dotnet/edb_core/components.py +10 -56
- pyedb/dotnet/edb_core/definition/component_def.py +1 -8
- pyedb/dotnet/edb_core/definition/component_model.py +0 -2
- pyedb/dotnet/edb_core/definition/definitions.py +0 -2
- pyedb/dotnet/edb_core/definition/package_def.py +7 -5
- pyedb/dotnet/edb_core/edb_data/control_file.py +0 -3
- pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py +0 -5
- pyedb/dotnet/edb_core/edb_data/hfss_pi_simulation_setup_data.py +4 -9
- pyedb/dotnet/edb_core/edb_data/layer_data.py +0 -7
- pyedb/dotnet/edb_core/edb_data/nets_data.py +2 -5
- pyedb/dotnet/edb_core/edb_data/padstacks_data.py +11 -29
- pyedb/dotnet/edb_core/edb_data/ports.py +4 -4
- pyedb/dotnet/edb_core/edb_data/primitives_data.py +3 -26
- pyedb/dotnet/edb_core/edb_data/raptor_x_simulation_setup_data.py +13 -20
- pyedb/dotnet/edb_core/edb_data/simulation_configuration.py +3 -11
- pyedb/dotnet/edb_core/edb_data/sources.py +12 -17
- pyedb/dotnet/edb_core/general.py +1 -6
- pyedb/dotnet/edb_core/geometry/polygon_data.py +0 -3
- pyedb/dotnet/edb_core/hfss.py +1 -33
- pyedb/dotnet/edb_core/layout.py +0 -35
- pyedb/dotnet/edb_core/layout_validation.py +1 -3
- pyedb/dotnet/edb_core/materials.py +1 -22
- pyedb/dotnet/edb_core/net_class.py +0 -8
- pyedb/dotnet/edb_core/nets.py +4 -29
- pyedb/dotnet/edb_core/padstack.py +76 -30
- pyedb/dotnet/edb_core/sim_setup_data/data/adaptive_frequency_data.py +72 -0
- pyedb/dotnet/edb_core/sim_setup_data/data/mesh_operation.py +287 -0
- pyedb/dotnet/edb_core/{edb_data/hfss_simulation_setup_data.py → sim_setup_data/data/settings.py} +174 -878
- pyedb/dotnet/edb_core/sim_setup_data/data/sweep_data.py +509 -0
- pyedb/dotnet/edb_core/sim_setup_data/io/__init__.py +0 -0
- pyedb/dotnet/edb_core/{edb_data/siwave_simulation_setup_data.py → sim_setup_data/io/siwave.py} +0 -341
- pyedb/dotnet/edb_core/siwave.py +5 -33
- pyedb/dotnet/edb_core/stackup.py +4 -51
- pyedb/dotnet/edb_core/utilities/simulation_setup.py +613 -366
- pyedb/generic/data_handlers.py +1 -9
- pyedb/generic/general_methods.py +3 -53
- pyedb/generic/plot.py +1 -2
- pyedb/ipc2581/ecad/cad_data/layer_feature.py +1 -7
- pyedb/ipc2581/ecad/cad_data/package.py +1 -4
- pyedb/ipc2581/ecad/cad_data/path.py +1 -3
- pyedb/ipc2581/ecad/cad_data/polygon.py +1 -6
- pyedb/ipc2581/ecad/cad_data/step.py +1 -10
- pyedb/ipc2581/ipc2581.py +8 -15
- pyedb/modeler/geometry_operators.py +164 -67
- pyedb/siwave.py +25 -32
- {pyedb-0.13.dev0.dist-info → pyedb-0.15.dev0.dist-info}/METADATA +2 -2
- {pyedb-0.13.dev0.dist-info → pyedb-0.15.dev0.dist-info}/RECORD +75 -61
- /pyedb/dotnet/edb_core/cell/{__init__.py → terminal/__init__.py} +0 -0
- {pyedb-0.13.dev0.dist-info → pyedb-0.15.dev0.dist-info}/LICENSE +0 -0
- {pyedb-0.13.dev0.dist-info → pyedb-0.15.dev0.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
|
|
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.
|
|
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()
|