Skip to content

Commit 2c557ba

Browse files
FEAT: Toggle net type in Q3D (#6237)
Co-authored-by: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com>
1 parent e02376c commit 2c557ba

3 files changed

Lines changed: 136 additions & 22 deletions

File tree

doc/changelog.d/6237.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Toggle net type in q3d

src/ansys/aedt/core/q3d.py

Lines changed: 83 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,15 +1399,21 @@ def net_sources(self, net_name):
13991399
>>> net = q3d.net_sources("Net1")
14001400
"""
14011401
sources = []
1402-
net_id = -1
1403-
for i in self.boundaries:
1404-
if i.type == "SignalNet" and i.name == net_name and i.props.get("ID", None) is not None: # pragma: no cover
1405-
net_id = i.props.get("ID", None)
1406-
break
1407-
for i in self.boundaries:
1408-
if i.type == "Source":
1409-
if i.props.get("Net", None) == net_name or i.props.get("Net", None) == net_id:
1410-
sources.append(i.name)
1402+
1403+
# Try to find the matching net from SignalNet boundaries
1404+
net = next((i for i in self.boundaries_by_type.get("SignalNet", []) if i.name == net_name), None)
1405+
1406+
# Get net_id and net_sources_sinks if the net was found
1407+
net_id = net.props.get("ID") if net and net.props.get("ID") is not None else -1 # pragma: no cover
1408+
net_sources_sinks = net.children if net else {}
1409+
1410+
for boundary in self.boundaries:
1411+
if boundary.type == "Source" and (
1412+
boundary.props.get("Net") == net_name
1413+
or boundary.props.get("Net") == net_id
1414+
or boundary.name in net_sources_sinks
1415+
):
1416+
sources.append(boundary.name)
14111417

14121418
return sources
14131419

@@ -1432,14 +1438,21 @@ def net_sinks(self, net_name):
14321438
>>> net = q3d.net_sinks("Net1")
14331439
"""
14341440
sinks = []
1435-
net_id = -1
1436-
for i in self.boundaries:
1437-
if i.type == "SignalNet" and i.name == net_name and i.props.get("ID", None) is not None:
1438-
net_id = i.props.get("ID", None) # pragma: no cover
1439-
break # pragma: no cover
1440-
for i in self.boundaries:
1441-
if i.type == "Sink" and any(map(lambda val: i.props.get("Net", None) == val, [net_name, net_id])):
1442-
sinks.append(i.name)
1441+
1442+
# Try to find the matching net from SignalNet boundaries
1443+
net = next((i for i in self.boundaries_by_type.get("SignalNet", []) if i.name == net_name), None)
1444+
1445+
# Get net_id and net_sources_sinks if the net was found
1446+
net_id = net.props.get("ID") if net and net.props.get("ID") is not None else -1 # pragma: no cover
1447+
net_sources_sinks = net.children if net else {}
1448+
1449+
for boundary in self.boundaries:
1450+
if boundary.type == "Sink" and (
1451+
boundary.props.get("Net") == net_name
1452+
or boundary.props.get("Net") == net_id
1453+
or boundary.name in net_sources_sinks
1454+
):
1455+
sinks.append(boundary.name)
14431456
return sinks
14441457

14451458
@pyaedt_function_handler()
@@ -1479,6 +1492,57 @@ def auto_identify_nets(self):
14791492
self.logger.info("No new nets identified")
14801493
return True
14811494

1495+
@pyaedt_function_handler()
1496+
def toggle_net(self, net_name, net_type="Signal"):
1497+
"""Toggle net type.
1498+
1499+
Parameters
1500+
----------
1501+
net_name : str or :class:`ansys.aedt.core.modules.boundary.common.BoundaryObject`, optional
1502+
Name of the net. The default is ```None``, in which case the
1503+
default name is used.
1504+
net_type : str, bool
1505+
Type of net to create. Options are ``"Signal"``, ``"Ground"`` and ``"Floating"``.
1506+
The default is ``"Signal"``.
1507+
1508+
Returns
1509+
-------
1510+
:class:`ansys.aedt.core.modules.boundary.common.BoundaryObject`
1511+
Net object.
1512+
1513+
References
1514+
----------
1515+
>>> oModule.ToggleNet
1516+
1517+
Examples
1518+
--------
1519+
>>> from ansys.aedt.core import Q3d
1520+
>>> q3d = Q3d()
1521+
>>> box = q3d.modeler.create_box([30, 30, 30], [10, 10, 10], name="mybox")
1522+
>>> aedtapp.auto_identify_nets()
1523+
>>> net = aedtapp.nets[0]
1524+
>>> new_net = aedtapp.toggle_net(net, "Floating")
1525+
"""
1526+
if isinstance(net_name, BoundaryObject):
1527+
net_name = net_name.name
1528+
1529+
if net_name not in self.nets:
1530+
raise ValueError(f"{net_name} is not a valid net name.")
1531+
1532+
type_bound = {"ground": "GroundNet", "floating": "FloatingNet"}.get(net_type.lower(), "SignalNet")
1533+
1534+
# Delete from list of design excitations
1535+
if net_name in self._boundaries:
1536+
self._boundaries.pop(net_name)
1537+
1538+
# Toggle
1539+
self.oboundary.ToggleNet(net_name, type_bound)
1540+
1541+
# Update boundaries
1542+
_ = self.boundaries
1543+
1544+
return self._boundaries[net_name]
1545+
14821546
@pyaedt_function_handler(objects="assignment")
14831547
def assign_net(self, assignment, net_name=None, net_type="Signal"):
14841548
"""Assign a net to a list of objects.
@@ -1517,11 +1581,8 @@ def assign_net(self, assignment, net_name=None, net_type="Signal"):
15171581
if not net_name:
15181582
net_name = generate_unique_name("Net")
15191583
props = dict({"Objects": assignment})
1520-
type_bound = "SignalNet"
1521-
if net_type.lower() == "ground":
1522-
type_bound = "GroundNet"
1523-
elif net_type.lower() == "floating":
1524-
type_bound = "FloatingNet"
1584+
1585+
type_bound = {"ground": "GroundNet", "floating": "FloatingNet"}.get(net_type.lower(), "SignalNet")
15251586

15261587
return self._create_boundary(net_name, props, type_bound)
15271588

tests/system/solvers/test_31_Q3D.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,30 @@ def test_06c_auto_identify(self, aedtapp):
178178
aedtapp.modeler.create_box([20, 5, 0], [1, 1, 20], material="brass")
179179

180180
assert aedtapp.auto_identify_nets()
181+
assert len(aedtapp.nets) == 2
181182
assert aedtapp.delete_all_nets()
183+
assert len(aedtapp.nets) == 0
182184
assert aedtapp.auto_identify_nets()
185+
nets = aedtapp.nets
186+
187+
net1 = aedtapp.design_excitations[nets[0]]
188+
net2 = aedtapp.design_excitations[nets[1]]
189+
190+
new_net1 = aedtapp.toggle_net(net1, "Floating")
191+
assert new_net1.type == "FloatingNet"
192+
net1_1 = aedtapp.design_excitations[nets[0]]
193+
assert net1_1.type == "FloatingNet"
194+
net1_2 = aedtapp.excitation_objects[nets[0]]
195+
assert net1_2.type == "FloatingNet"
196+
assert "FloatingNet" in list(aedtapp.boundaries_by_type.keys())
197+
198+
new_net2 = aedtapp.toggle_net(net2.name, "Ground")
199+
assert new_net2.type == "GroundNet"
200+
net2_1 = aedtapp.design_excitations[nets[1]]
201+
assert net2_1.type == "GroundNet"
202+
net2_2 = aedtapp.excitation_objects[nets[1]]
203+
assert net2_2.type == "GroundNet"
204+
assert "GroundNet" in list(aedtapp.boundaries_by_type.keys())
183205

184206
def test_07_create_source_sinks(self, aedtapp):
185207
udp = aedtapp.modeler.Position(0, 0, 0)
@@ -565,3 +587,33 @@ def test_21_mutual_coupling(self, coupling):
565587

566588
assert not coupling.get_mutual_coupling("ac2", "a1", "a3", "a1")
567589
assert not coupling.get_mutual_coupling("a1", "a2", "b2", "b1", calculation="ACL2")
590+
591+
def test_toggle_net_with_sources(self, add_app):
592+
app = add_app(application=Q3d, design_name="toggle_net")
593+
udp = app.modeler.Position(0, 0, 0)
594+
coax_dimension = 30
595+
app.modeler.create_cylinder(app.PLANE.XY, udp, 3, coax_dimension, 0, name="MyCylinder", material="brass")
596+
597+
_ = app.source("MyCylinder", direction=0, name="Source1")
598+
_ = app.sink("MyCylinder", direction=3, name="Sink1")
599+
app.auto_identify_nets()
600+
net = app.nets[0]
601+
assert len(app.excitation_objects) == 3
602+
assert "SignalNet" in app.excitations_by_type
603+
sources = app.net_sources(net)
604+
sinks = app.net_sinks(net)
605+
606+
with pytest.raises(ValueError):
607+
app.toggle_net(net_name="invented")
608+
609+
new_net = app.toggle_net(net, "Ground")
610+
assert new_net.type == "GroundNet"
611+
assert len(app.excitation_objects) == 1
612+
assert len(app.boundaries) == 1
613+
new_sources = app.net_sources(net)
614+
new_sinks = app.net_sinks(net)
615+
616+
assert len(sources) != len(new_sources)
617+
assert len(sinks) != len(new_sinks)
618+
assert "GroundNet" in app.excitations_by_type
619+
assert "SignalNet" not in app.excitations_by_type

0 commit comments

Comments
 (0)