Skip to content

Commit 77bead0

Browse files
authored
H3d layout geometries refactor (#1178)
* First Hfss3dLayout Refactoring * First Hfss3dLayout Refactoring * Hfss modeler objects refactoring * Hfss modeler objects refactoring * Hfss modeler objects refactoring * Fixed * Fix Documentation * Fix Documentation * Fix Documentation * Improved Edge Port Method * Improved Edge Port Method * Improved Edge Port Method * Fix Documentation * Fix Codacy * Fix Codacy * Fixed net unit test Co-authored-by: maxcapodi78 <Shark78>
1 parent f452b78 commit 77bead0

File tree

13 files changed

+1595
-1041
lines changed

13 files changed

+1595
-1041
lines changed

_unittest/test_40_3dlayout_edb.py

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,13 @@ def test_01_get_components(self):
3535
assert len(comp) > 0
3636
assert comp["L3A1"].object_units == "mm"
3737
assert comp["L3A1"].angle == "0deg"
38-
assert comp["L3A1"].location[1] == 0.0381
38+
comp["L3A1"].angle = "90deg"
39+
assert comp["L3A1"].angle == "90deg"
40+
comp["L3A1"].angle = "0deg"
41+
assert comp["L3A1"].location[0] == 0.0
42+
comp["L3A1"].location = [1.0, 0.0]
43+
assert comp["L3A1"].location[0] == 1.0
44+
comp["L3A1"].location = [0.0, 0.0]
3945
assert comp["L3A1"].placement_layer == "TOP"
4046
assert comp["L3A1"].part == "A32422-019"
4147
assert comp["L3A1"].part_type == "Inductor"
@@ -52,32 +58,84 @@ def test_01_get_components(self):
5258

5359
def test_02a_get_geometries(self):
5460
line = self.aedtapp.modeler.geometries["line_1983"]
61+
assert line.edges
62+
assert line.points
63+
assert line.points
64+
assert line.is_closed
65+
poly = self.aedtapp.modeler.geometries["poly_208"]
66+
assert poly.edges
67+
assert poly.points
68+
assert poly.bottom_edge_x == 1
69+
assert poly.bottom_edge_y == 7
70+
assert poly.top_edge_x == 13
71+
assert poly.top_edge_y == 18
72+
assert poly.placement_layer == "TOP"
73+
poly.placement_layer = "BOTTOM"
74+
assert poly.placement_layer == "BOTTOM"
75+
poly.placement_layer = "TOP"
76+
assert poly.net_name == "GND"
77+
assert not poly.negative
78+
assert not poly.is_void
79+
assert not poly.lock_position
80+
assert poly.is_closed
5581
assert len(self.aedtapp.modeler.geometries) > 0
82+
rect = self.aedtapp.modeler.rectangles["rect_30091"]
83+
assert rect.point_a
84+
assert rect.point_b
85+
assert rect.two_point_description
86+
assert not rect.center
87+
rect.two_point_description = False
88+
assert rect.center
89+
assert rect.height
90+
rect.two_point_description = True
91+
assert rect.point_a
92+
circle = self.aedtapp.modeler.circles["circle_30092"]
93+
assert circle.center
94+
assert circle.radius
95+
circle.radius = "2.5mm"
96+
assert circle.radius == "2.5mm"
5697

5798
def test_02b_geo_units(self):
5899
assert self.aedtapp.modeler.geometries["line_1983"].object_units == "mm"
59100

60101
def test_02c_geo_layer(self):
61-
assert self.aedtapp.modeler.geometries["line_1983"].get_placement_layer()
102+
assert self.aedtapp.modeler.geometries["line_1983"].placement_layer
62103
assert len(self.aedtapp.modeler.layers.drawing_layers) > 0
63104

64105
def test_02d_geo_lock(self):
65-
assert self.aedtapp.modeler.geometries["line_1983"].set_lock_position(True)
66-
assert self.aedtapp.modeler.geometries["line_1983"].set_lock_position(False)
106+
self.aedtapp.modeler.geometries["line_1983"].lock_position = True
107+
assert self.aedtapp.modeler.geometries["line_1983"].lock_position == True
108+
self.aedtapp.modeler.geometries["line_1983"].lock_position = False
109+
assert self.aedtapp.modeler.geometries["line_1983"].lock_position == False
67110

68111
def test_02e_geo_setter(self):
69-
assert self.aedtapp.modeler.geometries["line_1983"].set_layer("PWR")
70-
assert self.aedtapp.modeler.geometries["line_1983"].set_net_name("VCC")
112+
self.aedtapp.modeler.geometries["line_1983"].layer = "PWR"
113+
assert self.aedtapp.modeler.geometries["line_1983"].layer == "PWR"
114+
self.aedtapp.modeler.geometries["line_1983"].net_name = "VCC"
115+
assert self.aedtapp.modeler.geometries["line_1983"].net_name == "VCC"
71116

72117
def test_03_get_pins(self):
73118
pins = self.aedtapp.modeler.pins
74119
assert len(pins) > 0
75120
assert pins["L3A1-1"].object_units == "mm"
121+
assert pins["L3A1-1"].componentname == "L3A1"
122+
assert pins["L3A1-1"].is_pin
76123
assert pins["L3A1-1"].angle == "180deg"
77124
assert pins["L3A1-1"].location[0] > 0
78125
assert pins["L3A1-1"].start_layer == "TOP"
79126
assert pins["L3A1-1"].stop_layer == "TOP"
80127

128+
def test_03B_get_vias(self):
129+
vias = self.aedtapp.modeler.vias
130+
assert len(vias) > 0
131+
assert vias["via_3795"].object_units == "mm"
132+
assert not vias["via_3795"].is_pin
133+
assert vias["via_3795"].angle == "90deg"
134+
assert vias["via_3795"].location[0] > 0
135+
assert vias["via_3795"].start_layer == "TOP"
136+
assert vias["via_3795"].stop_layer == "BOTTOM"
137+
assert vias["via_3795"].holediam == "10mil"
138+
81139
def test_04_add_mesh_operations(self):
82140
self.aedtapp.create_setup("HFSS")
83141
setup1 = self.aedtapp.mesh.assign_length_mesh("HFSS", "PWR", "GND")
@@ -101,6 +159,7 @@ def test_07_nets(self):
101159
nets = self.aedtapp.modeler.nets
102160
assert nets["GND"].name == "GND"
103161
assert len(nets) > 0
162+
assert len(nets["GND"].components) > 0
104163

105164
def test_08_merge(self):
106165
tol = 1e-12

_unittest/test_41_3dlayout_modeler.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,8 @@ def test_08_objectlist(self):
150150
def test_09_modify_padstack(self):
151151
pad_0 = self.aedtapp.modeler.padstacks["PlanarEMVia"]
152152
assert self.aedtapp.modeler.padstacks["PlanarEMVia"].plating != 55
153-
pad_0.plating = 55
153+
pad_0.plating = "55"
154154
pad_0.update()
155-
self.aedtapp.modeler.init_padstacks()
156155
assert self.aedtapp.modeler.padstacks["PlanarEMVia"].plating == "55"
157156

158157
def test_10_create_padstack(self):
@@ -179,6 +178,9 @@ def test_12_create_line(self):
179178
assert line == "line1"
180179

181180
def test_13a_create_edge_port(self):
181+
port_wave = self.aedtapp.create_edge_port("line1", 3, False, True, 6, 4, "2mm")
182+
assert port_wave
183+
assert self.aedtapp.delete_port(port_wave)
182184
assert self.aedtapp.create_edge_port("line1", 3, False)
183185
assert self.aedtapp.create_edge_port("line1", 0, True)
184186
assert len(self.aedtapp.excitations) > 0

_unittest_ironpython/run_unittests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
if os.name != "posix":
2020
ansysem_install_dir = os.environ.get("ANSYSEM_INSTALL_DIR", "")
2121
if not ansysem_install_dir:
22-
ansysem_install_dir = os.environ["ANSYSEM_ROOT212"]
22+
ansysem_install_dir = os.environ["ANSYSEM_ROOT221"]
2323
sys.path.append(os.path.join(ansysem_install_dir, "PythonFiles", "DesktopPlugin"))
2424
path_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "..")
2525
sys.path.append(path_dir)

doc/source/API/Primitives.rst

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,9 @@ It contains all getter and setter to simplify object manipulation.
125125
Object3d.FacePrimitive
126126
Object3d.EdgePrimitive
127127
Object3d.VertexPrimitive
128-
Object3d.Point
129128
Primitives.PolylineSegment
130129
Primitives.Polyline
130+
Object3d.Padstack
131131

132132
.. code:: python
133133
@@ -202,12 +202,15 @@ It contains all getter and setter to simplify object manipulation.
202202
:toctree: _autosummary
203203
:nosignatures:
204204

205-
Object3d.Objec3DLayout
206-
Object3d.Components3DLayout
207-
Object3d.Nets3DLayout
208-
Object3d.Pins3DLayout
209-
Object3d.Geometries3DLayout
210-
Object3d.Padstack
205+
object3dlayout.Components3DLayout
206+
object3dlayout.Nets3DLayout
207+
object3dlayout.Pins3DLayout
208+
object3dlayout.Line3dLayout
209+
object3dlayout.Polygons3DLayout
210+
object3dlayout.Circle3dLayout
211+
object3dlayout.Rect3dLayout
212+
object3dlayout.Points3dLayout
213+
object3dlayout.Point
211214

212215
.. code:: python
213216

pyaedt/application/Analysis3DLayout.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ def __init__(
9393
self._oboundary = self._odesign.GetModule("Excitations")
9494
self.logger.info("Analysis Loaded")
9595
self._modeler = Modeler3DLayout(self)
96-
self._modeler.init_padstacks()
9796
self.logger.info("Modeler Loaded")
9897
self._mesh = Mesh3d(self)
9998
self._post = PostProcessor(self)

pyaedt/application/AnalysisNexxim.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ def __init__(
5454
)
5555

5656
self._modeler = ModelerNexxim(self)
57-
self._modeler.layout.init_padstacks()
5857
self._post = CircuitPostProcessor(self)
5958

6059
@pyaedt_function_handler()

pyaedt/hfss3dlayout.py

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,16 @@ def __enter__(self):
124124
return self
125125

126126
@pyaedt_function_handler()
127-
def create_edge_port(self, primivitivename, edgenumber, iscircuit=True):
127+
def create_edge_port(
128+
self,
129+
primivitivename,
130+
edgenumber,
131+
iscircuit=False,
132+
iswave=False,
133+
wave_horizontal_extension=5,
134+
wave_vertical_extension=3,
135+
wave_launcher="1mm",
136+
):
128137
"""Create an edge port.
129138
130139
Parameters
@@ -135,10 +144,18 @@ def create_edge_port(self, primivitivename, edgenumber, iscircuit=True):
135144
Edge number to create the edge port on.
136145
iscircuit : bool, optional
137146
Whether the edge port is a circuit port. The default is ``False``.
147+
iswave : bool, optional
148+
Whether the edge port is a circuit port. The default is ``False``.
149+
wave_horizontal_extension : float, optional
150+
Horizontal port extension factor. Default is `5`.
151+
wave_vertical_extension : float, optional
152+
Vertical port extension factor. Default is `5`.
153+
wave_launcher : str, optional
154+
Pec Launcher size with units. Default is `"1mm"`.
138155
139156
Returns
140157
-------
141-
type
158+
str
142159
Name of the port when successful, ``False`` when failed.
143160
144161
References
@@ -161,6 +178,31 @@ def create_edge_port(self, primivitivename, edgenumber, iscircuit=True):
161178
listnew = self.port_list
162179
a = [i for i in listnew if i not in listp]
163180
if len(a) > 0:
181+
if iswave:
182+
self.modeler.change_property(
183+
property_object="Excitations:{}".format(a[0]),
184+
property_name="HFSS Type",
185+
property_value="Wave",
186+
property_tab="EM Design",
187+
)
188+
self.modeler.change_property(
189+
property_object="Excitations:{}".format(a[0]),
190+
property_name="Horizontal Extent Factor",
191+
property_value=str(wave_horizontal_extension),
192+
property_tab="EM Design",
193+
)
194+
self.modeler.change_property(
195+
property_object="Excitations:{}".format(a[0]),
196+
property_name="Vertical Extent Factor",
197+
property_value=str(wave_vertical_extension),
198+
property_tab="EM Design",
199+
)
200+
self.modeler.change_property(
201+
property_object="Excitations:{}".format(a[0]),
202+
property_name="PEC Launch Width",
203+
property_value=str(wave_launcher),
204+
property_tab="EM Design",
205+
)
164206
return a[0]
165207
else:
166208
return False

pyaedt/modeler/Model3DLayout.py

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
from pyaedt.generic.general_methods import is_ironpython
1313
from pyaedt.generic.general_methods import pyaedt_function_handler
1414
from pyaedt.modeler.Modeler import Modeler
15-
from pyaedt.modeler.Object3d import ComponentsSubCircuit3DLayout
16-
from pyaedt.modeler.Primitives3DLayout import Geometries3DLayout
15+
from pyaedt.modeler.object3dlayout import ComponentsSubCircuit3DLayout
1716
from pyaedt.modeler.Primitives3DLayout import Primitives3DLayout
1817
from pyaedt.modules.LayerStackup import Layers
1918

@@ -387,6 +386,7 @@ def colinear_heal(self, selection, tolerance=0.1):
387386
self.arg_with_dim(tolerance),
388387
]
389388
)
389+
390390
return True
391391

392392
@pyaedt_function_handler()
@@ -434,14 +434,13 @@ def expand(self, object_to_expand, size=1, expand_type="ROUND", replace_original
434434
pos = [poly[0].GetX(), poly[0].GetY()]
435435
geom_names = self.oeditor.FindObjectsByPoint(self.oeditor.Point().Set(pos[0], pos[1]), layer)
436436
self.oeditor.Expand(self.arg_with_dim(size), expand_type, replace_original, ["NAME:elements", object_to_expand])
437+
self._init_prims()
437438
if not replace_original:
438439
new_geom_names = [
439440
i
440441
for i in self.oeditor.FindObjectsByPoint(self.oeditor.Point().Set(pos[0], pos[1]), layer)
441442
if i not in geom_names
442443
]
443-
if self.is_outside_desktop:
444-
self._geometries[new_geom_names[0]] = Geometries3DLayout(self, new_geom_names[0])
445444
return new_geom_names[0]
446445
return object_to_expand
447446

@@ -565,13 +564,7 @@ def subtract(self, blank, tool):
565564
vArg1.append(tool)
566565
if self.oeditor is not None:
567566
self.oeditor.Subtract(vArg1)
568-
if isinstance(tool, list):
569-
for el in tool:
570-
if self.is_outside_desktop:
571-
self._geometries.pop(el)
572-
else:
573-
if self.is_outside_desktop:
574-
self._geometries.pop(tool)
567+
self._init_prims()
575568
return True
576569

577570
@pyaedt_function_handler()
@@ -598,10 +591,7 @@ def unite(self, objectlists):
598591
for el in objectlists:
599592
vArg1.append(el)
600593
self.oeditor.Unite(vArg1)
601-
for el in objectlists:
602-
if not self.oeditor.FindObjects("Name", el):
603-
if self.is_outside_desktop:
604-
self._geometries.pop(el)
594+
self._init_prims()
605595
return True
606596
else:
607597
self.logger.error("Input list must contain at least two elements.")
@@ -631,10 +621,7 @@ def intersect(self, objectlists):
631621
for el in objectlists:
632622
vArg1.append(el)
633623
self.oeditor.Intersect(vArg1)
634-
for el in objectlists:
635-
if not self.oeditor.FindObjects("Name", el):
636-
if self.is_outside_desktop:
637-
self._geometries.pop(el)
624+
self._init_prims()
638625
return True
639626
else:
640627
self.logger.error("Input list must contain at least two elements.")
@@ -668,6 +655,7 @@ def duplicate(self, objectlists, count, direction_vector):
668655
self.oeditor.Duplicate(
669656
["NAME:options", "count:=", count], ["NAME:elements", ",".join(objectlists)], direction_vector
670657
)
658+
self._init_prims()
671659
return True
672660

673661
@pyaedt_function_handler()
@@ -799,7 +787,7 @@ def set_spice_model(self, component_name, model_path, model_name=None, subcircui
799787
pinNames.remove(pinNames[0])
800788
pinNames.remove(pinNames[0])
801789
break
802-
componentPins = [i.GetName() for i in self.edb.core_components.get_pin_from_component(component_name)]
790+
componentPins = self.components[component_name].pins
803791
componentPins.reverse()
804792
if not pin_map:
805793
pin_map = []

0 commit comments

Comments
 (0)