Skip to content

Commit 6319629

Browse files
FIX: Adding close desktop function (#6052)
Co-authored-by: pyansys-ci-bot <[email protected]>
1 parent b3713a2 commit 6319629

File tree

5 files changed

+167
-8
lines changed

5 files changed

+167
-8
lines changed

doc/changelog.d/6052.fixed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Adding close desktop function

src/ansys/aedt/core/filtersolutions.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424

2525
import warnings
2626

27+
from ansys.aedt.core import Circuit
28+
from ansys.aedt.core import Hfss
29+
from ansys.aedt.core import Hfss3dLayout
2730
from ansys.aedt.core import settings
2831
import ansys.aedt.core.filtersolutions_core
2932
from ansys.aedt.core.filtersolutions_core.attributes import Attributes
@@ -96,6 +99,32 @@ def _cleanup_resources(self):
9699
self.geometry = None
97100
self.radial = None
98101

102+
def _create_design(self, desktop_version, desktop_process_id):
103+
"""Create a new design in AEDT.
104+
This method is called to create an ``AEDT`` object when the design is exported to ``AEDT``.
105+
106+
Parameters
107+
----------
108+
desktop_version : str
109+
Version of AEDT in ``xxxx.x`` format.
110+
111+
desktop_process_id : int
112+
Process ID of the AEDT instance.
113+
114+
Returns
115+
-------
116+
:class:``AEDT`` design object
117+
"""
118+
if isinstance(FilterDesignBase._active_design, LumpedDesign):
119+
return Circuit(version=desktop_version, aedt_process_id=desktop_process_id)
120+
elif isinstance(FilterDesignBase._active_design, DistributedDesign):
121+
if getattr(self, "insert_hfss_3dl_design", True):
122+
return Hfss3dLayout(version=desktop_version, aedt_process_id=desktop_process_id)
123+
elif getattr(self, "insert_hfss_design", True):
124+
return Hfss(version=desktop_version, aedt_process_id=desktop_process_id)
125+
elif getattr(self, "insert_circuit_design", True):
126+
return Circuit(version=desktop_version, aedt_process_id=desktop_process_id)
127+
99128

100129
class LumpedDesign(FilterDesignBase):
101130
"""Provides the `FilterSolutions` application interface for lumped filter designs.

src/ansys/aedt/core/filtersolutions_core/export_to_aedt.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,9 @@ def _define_export_to_desktop_dll_functions(self):
275275
self._dll.getOptimizeAfterExport.argtype = POINTER(c_bool)
276276
self._dll.getOptimizeAfterExport.restype = c_int
277277

278+
self._dll.exportDesign.argtypes = [c_int, c_int, c_char_p, POINTER(c_int)]
279+
self._dll.exportDesign.restype = c_int
280+
278281
self._dll.loadLibraryPartsConf.argtype = c_char_p
279282
self._dll.loadLibraryPartsConf.restype = c_int
280283

@@ -861,6 +864,13 @@ def export_design(self, export_format=None, export_creation_mode=None, export_pa
861864
When exporting to ``AEDT``, the design can either be appended to an existing project or overwrite it.
862865
When generating a Python script, the script is created and saved to the specified file location.
863866
867+
Returns the design object for an exported design when ``export_format``
868+
is set to ``ExportFormat.DIRECT_TO_AEDT``.
869+
870+
The returned object type is one of ``Circuit``, ``Hfss``, or ``Hfss3dLayout``.
871+
872+
Returns ``None`` if ``export_format`` is set to ``ExportFormat.PYTHON_SCRIPT``.
873+
864874
Parameters
865875
----------
866876
export_format : `ExportFormat`
@@ -872,21 +882,35 @@ def export_design(self, export_format=None, export_creation_mode=None, export_pa
872882
export_path : str
873883
The export path for Python script.
874884
The default is ``None``.
885+
886+
Returns
887+
-------
888+
:class: ``AEDT`` design object
875889
"""
890+
891+
desktop_version = getattr(self._dll_interface, "_version")
876892
if export_format is None:
877893
export_format = ExportFormat.DIRECT_TO_AEDT
878894
if export_creation_mode is None:
879895
export_creation_mode = ExportCreationMode.OVERWRITE
880896
if not export_path:
881-
export_path = ""
897+
export_path_bytes = b""
882898
else:
883899
directory_path = os.path.dirname(export_path)
884900
# Check if the directory path exists, if not, create it to ensure the export path is valid
885901
if not os.path.exists(directory_path):
886902
os.makedirs(directory_path)
887-
export_path_bytes = bytes(export_path, "ascii")
888-
status = self._dll.exportDesign(export_format.value, export_creation_mode.value, export_path_bytes)
903+
export_path_bytes = bytes(export_path, "ascii")
904+
desktop_process_id = c_int()
905+
status = self._dll.exportDesign(
906+
export_format.value, export_creation_mode.value, export_path_bytes, byref(desktop_process_id)
907+
)
889908
self._dll_interface.raise_error(status)
909+
if export_format == ExportFormat.DIRECT_TO_AEDT:
910+
design = ansys.aedt.core.filtersolutions.FilterDesignBase._create_design(
911+
self, desktop_version, desktop_process_id.value
912+
)
913+
return design
890914

891915
def load_library_parts_config(self, load_library_parts_config_string):
892916
self._dll_interface.set_string(self._dll.loadLibraryPartsConf, load_library_parts_config_string)
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates.
4+
# SPDX-License-Identifier: MIT
5+
#
6+
#
7+
# Permission is hereby granted, free of charge, to any person obtaining a copy
8+
# of this software and associated documentation files (the "Software"), to deal
9+
# in the Software without restriction, including without limitation the rights
10+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
# copies of the Software, and to permit persons to whom the Software is
12+
# furnished to do so, subject to the following conditions:
13+
#
14+
# The above copyright notice and this permission notice shall be included in all
15+
# copies or substantial portions of the Software.
16+
#
17+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
# SOFTWARE.
24+
25+
from ansys.aedt.core import Circuit
26+
from ansys.aedt.core import Hfss
27+
from ansys.aedt.core import Hfss3dLayout
28+
from ansys.aedt.core.generic.settings import is_linux
29+
import pytest
30+
31+
from tests.system.solvers.conftest import config
32+
33+
34+
@pytest.mark.skipif(is_linux, reason="FilterSolutions API is not supported on Linux.")
35+
@pytest.mark.skipif(config["desktopVersion"] < "2025.2", reason="Skipped on versions earlier than 2025.1")
36+
class TestClass:
37+
def test_lumped_exported_desktop(self, lumped_design):
38+
schem_name = lumped_design.export_to_aedt.schematic_name
39+
schem_name_length = len(schem_name)
40+
circuit = lumped_design.export_to_aedt.export_design()
41+
assert isinstance(circuit, Circuit)
42+
assert circuit.project_name.split()[0][:schem_name_length] == schem_name
43+
assert circuit.design_name == schem_name
44+
assert next(iter(circuit.setup_sweeps_names)) == "FS_Advanced Setup"
45+
variables = circuit.variable_manager.variables
46+
assert variables["C1"].value == pytest.approx(1.967e-12)
47+
assert variables["L2"].value == pytest.approx(1.288e-8)
48+
assert variables["C3"].value == pytest.approx(6.366e-12)
49+
50+
def test_distributed_circuit_exported_desktop(self, distributed_design):
51+
schem_name = distributed_design.export_to_aedt.schematic_name
52+
schem_name_length = len(schem_name)
53+
distributed_design.export_to_aedt.insert_circuit_design = True
54+
circuit = distributed_design.export_to_aedt.export_design()
55+
assert isinstance(circuit, Circuit)
56+
assert circuit.project_name.split()[0][:schem_name_length] == schem_name
57+
assert circuit.design_name == schem_name
58+
assert next(iter(circuit.setup_sweeps_names)) == "FS_Advanced Setup"
59+
variables = circuit.variable_manager.variables
60+
assert variables["W1"].value == pytest.approx(5.08e-3)
61+
assert variables["W2"].value == pytest.approx(3.175e-4)
62+
assert variables["W3"].value == pytest.approx(5.08e-3)
63+
assert variables["S1"].value == pytest.approx(3.362e-3)
64+
assert variables["S2"].value == pytest.approx(2.172e-2)
65+
assert variables["S3"].value == pytest.approx(1.008e-2)
66+
67+
def test_distributed_hfss3dl_exported_desktop(self, distributed_design):
68+
schem_name = distributed_design.export_to_aedt.schematic_name
69+
schem_name_length = len(schem_name)
70+
distributed_design.export_to_aedt.insert_hfss_3dl_design = True
71+
hfss3dl = distributed_design.export_to_aedt.export_design()
72+
assert isinstance(hfss3dl, Hfss3dLayout)
73+
assert hfss3dl.project_name.split()[0][:schem_name_length] == schem_name
74+
assert hfss3dl.design_name == schem_name
75+
assert next(iter(hfss3dl.setup_sweeps_names)) == "FS_Advanced Setup"
76+
variables = hfss3dl.variable_manager.variables
77+
assert variables["Win"].value == pytest.approx(1.234e-3)
78+
assert variables["W1"].value == pytest.approx(5.08e-3)
79+
assert variables["W2"].value == pytest.approx(3.175e-4)
80+
assert variables["W3"].value == pytest.approx(5.08e-3)
81+
assert variables["S1"].value == pytest.approx(3.36225452227e-3)
82+
assert variables["S2"].value == pytest.approx(2.17231965814e-2)
83+
assert variables["S3"].value == pytest.approx(1.00773795179e-2)
84+
85+
def test_distributed_hfss_exported_desktop(self, distributed_design):
86+
schem_name = distributed_design.export_to_aedt.schematic_name
87+
schem_name_length = len(schem_name)
88+
distributed_design.export_to_aedt.insert_hfss_design = True
89+
hfss = distributed_design.export_to_aedt.export_design()
90+
assert isinstance(hfss, Hfss)
91+
assert hfss.project_name.split()[0][:schem_name_length] == schem_name
92+
assert hfss.design_name == schem_name
93+
assert next(iter(hfss.setup_sweeps_names)) == "FS_Advanced_Setup"
94+
variables = hfss.variable_manager.variables
95+
assert variables["Win"].value == pytest.approx(1.234e-3)
96+
assert variables["W1"].value == pytest.approx(5.08e-3)
97+
assert variables["W2"].value == pytest.approx(3.175e-4)
98+
assert variables["W3"].value == pytest.approx(5.08e-3)
99+
assert variables["S1"].value == pytest.approx(3.36225452227e-3)
100+
assert variables["S2"].value == pytest.approx(2.17231965814e-2)
101+
assert variables["S3"].value == pytest.approx(1.00773795179e-2)

tests/system/solvers/test_45_FilterSolutions/test_export_to_aedt/test_export_to_aedt.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -436,16 +436,20 @@ def test_export_design(self, lumped_design):
436436
assert info.value.args[0] == "Python export path is not specified"
437437
else:
438438
assert info.value.args[0] == "Python export path is not specified."
439-
export_path = resource_path("test_exported_design.py")
439+
design_export_path = resource_path("test_exported_design.py")
440440
lumped_design.export_to_aedt.export_design(
441441
export_format=ExportFormat.PYTHON_SCRIPT,
442442
export_creation_mode=ExportCreationMode.OVERWRITE,
443-
export_path=export_path,
443+
export_path=design_export_path,
444444
)
445-
assert os.path.exists(export_path)
446-
directory_path = os.path.dirname(export_path)
445+
assert os.path.exists(design_export_path)
446+
directory_path = os.path.dirname(design_export_path)
447447
assert os.path.exists(directory_path)
448-
os.remove(export_path)
448+
try:
449+
with open(design_export_path, "a"):
450+
os.remove(design_export_path)
451+
except (OSError, PermissionError):
452+
return
449453

450454
def test_load_library_parts_config(self, lumped_design):
451455
lumped_design.export_to_aedt.load_library_parts_config(resource_path("library_parts.cfg"))

0 commit comments

Comments
 (0)