Skip to content

Commit 2fff7dc

Browse files
Merge branch 'main' into refacto/maxwell_examples
2 parents 9bdae5b + 5e5ab9d commit 2fff7dc

24 files changed

+709
-630
lines changed

doc/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ help:
2323
@echo "Removing vtk to avoid conflicts with vtk-osmesa needed for CI/CD"; \
2424
pip uninstall --yes vtk; \
2525
@echo "Installing vtk-osmesa"; \
26-
pip install --extra-index-url https://wheels.vtk.org vtk-osmesa==9.2.20230527.dev0; \
26+
pip install --extra-index-url https://wheels.vtk.org vtk-osmesa; \
2727
fi
2828
@if [ "${ON_CI}" = "True" ] && [ "$$is_pypandoc_binary_installed" != "yes" ]; then \
2929
@echo "Removing pypandoc to avoid conflicts with pypandoc-binary needed for CI/CD"; \

doc/make.bat

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ if NOT "%is_vtk_osmesa_installed%" == "vtk-osmesa" if "%ON_CI%" == "true" (
2222
@ECHO ON
2323
echo "Installing vtk-osmesa"
2424
@ECHO OFF
25-
pip install --extra-index-url https://wheels.vtk.org vtk-osmesa==9.2.20230527.dev0)
25+
pip install --extra-index-url https://wheels.vtk.org vtk-osmesa)
2626
for /f %%i in ('pip freeze ^| findstr /c:"pypandoc_binary"') do set is_pypandoc_binary_installed=%%i
2727
if NOT "%is_pypandoc_binary_installed%" == "pypandoc_binary" if "%ON_CI%" == "true" (
2828
@ECHO ON

doc/source/conf.py

+2-31
Original file line numberDiff line numberDiff line change
@@ -64,33 +64,6 @@ def run(self):
6464
return [addnodes.desc_name(text=member_name), addnodes.desc_content("", literal)]
6565

6666

67-
# Sphinx builder specific events hook
68-
69-
70-
def check_example_error(app: Sphinx, pagename: str, templatename:str , context:dict[str, Any], doctree: document):
71-
"""Log an error if the execution of an example as a notebook triggered an error.
72-
73-
Since the documentation build might not stop if the execution of a notebook triggered
74-
an error, we use a flag to log that an error is spotted in the html page context.
75-
"""
76-
# Check if the HTML contains an error message
77-
if pagename.startswith("examples") and not pagename.endswith("/index"):
78-
if any(
79-
map(
80-
lambda msg: msg in context["body"],
81-
[
82-
"UsageError",
83-
"NameError",
84-
"DeadKernelError",
85-
"NotebookError",
86-
"CellExecutionError",
87-
],
88-
)
89-
):
90-
logger.error(f"An error was detected in file {pagename}")
91-
app.builder.config.html_context["build_error"] = True
92-
93-
9467
# Sphinx generic event hooks
9568

9669

@@ -227,8 +200,8 @@ def check_build_finished_without_error(app: Sphinx, exception: None | Exception)
227200
exception : None or Exception
228201
Exception raised during the build process.
229202
"""
230-
if app.builder.config.html_context.get("build_error", False):
231-
logger.info("Build failed due to an error in html-page-context")
203+
if exception is not None:
204+
logger.error("Build failed due to an error.")
232205
exit(1)
233206

234207
def remove_doctree(app: Sphinx, exception: None | Exception):
@@ -261,8 +234,6 @@ def setup(app):
261234
Sphinx instance containing all the configuration for the documentation build.
262235
"""
263236
app.add_directive("pprint", PrettyPrintDirective)
264-
# Builder specific hook
265-
app.connect("html-page-context", check_example_error)
266237
# Builder inited hooks
267238
app.connect("builder-inited", copy_examples)
268239
app.connect("builder-inited", check_pandoc_installed)

examples/02-HFSS/Array.py

+42-37
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,25 @@
88
# Keywords: **HFSS**, **antenna array**, **far field**.
99

1010

11-
# ## Perform required imports
12-
#
13-
# Perform required imports.
11+
# ## Preparation
12+
# Import the required packages
1413

1514
import os
1615
import tempfile
16+
import time
17+
1718
import pyaedt
18-
from pyaedt.modules.solutions import FfdSolutionData
19+
from pyaedt.generic.farfield_visualization import FfdSolutionData
1920

20-
# Set constant values
21+
# Define constants.
2122

2223
AEDT_VERSION = "2024.1"
2324
NUM_CORES = 4
24-
25-
# ## Set non-graphical mode
26-
#
27-
# Set non-graphical mode.
28-
# You can set ``non_graphical`` either to ``True`` or ``False``.
29-
30-
non_graphical = False
25+
NG_MODE = False # Open Electronics UI when the application is launched.
3126

3227
# ## Create temporary directory
3328

34-
temp_dir = tempfile.TemporaryDirectory(suffix="_ansys")
29+
temp_dir = tempfile.TemporaryDirectory(suffix=".ansys")
3530

3631
# ## Download 3D component
3732
# Download the 3D component that is needed to run the example.
@@ -42,22 +37,26 @@
4237
#
4338
# Launch HFSS and open the project.
4439

45-
project_name = pyaedt.generate_unique_project_name(rootname=temp_dir.name, project_name="array")
40+
# +
41+
project_name = os.path.join(temp_dir.name, "array.aedt")
4642
hfss = pyaedt.Hfss(
4743
project=project_name,
4844
version=AEDT_VERSION,
4945
design="Array_Simple",
50-
non_graphical=non_graphical,
46+
non_graphical=NG_MODE,
5147
new_desktop=True,
5248
)
5349

5450
print("Project name " + project_name)
51+
# -
5552

5653
# ## Read array definition from JSON file
5754
#
5855
# Read JSON file.
5956

60-
dict_in = pyaedt.general_methods.read_json(os.path.join(example_path, "array_simple.json"))
57+
dict_in = pyaedt.general_methods.read_json(
58+
os.path.join(example_path, "array_simple.json")
59+
)
6160

6261
# ## 3D Component definition
6362
#
@@ -91,81 +90,87 @@
9190
setup = hfss.create_setup()
9291
setup.props["Frequency"] = "5GHz"
9392
setup.props["MaximumPasses"] = 3
94-
95-
hfss.analyze(num_cores=NUM_CORES)
93+
hfss.analyze(cores=NUM_CORES)
9694

9795

9896
# ## Get far field data
9997
#
10098
# Get far field data. After the simulation completes, the far
10199
# field data is generated port by port and stored in a data class.
102100

103-
ffdata = hfss.get_antenna_ffd_solution_data(
104-
sphere_name="Infinite Sphere1", setup_name=hfss.nominal_adaptive, frequencies=[5e9]
105-
)
101+
ffdata = hfss.get_antenna_data(setup=hfss.nominal_adaptive, sphere="Infinite Sphere1")
106102

107103
# ## Generate contour plot
108104
#
109105
# Generate a contour plot. You can define the Theta scan and Phi scan.
110106

111-
ffdata.plot_farfield_contour(
112-
farfield_quantity="RealizedGain", title="Contour at {}Hz".format(ffdata.frequency)
107+
ffdata.farfield_data.plot_contour(
108+
quantity="RealizedGain",
109+
title="Contour at {}Hz".format(ffdata.farfield_data.frequency),
113110
)
114111

115112
# ## Release AEDT
116113
#
117114
# Release AEDT.
118115
# Far field post-processing can be performed without AEDT because the data is stored.
119116

120-
eep_file = ffdata.eep_files
121-
frequencies = ffdata.frequencies
117+
metadata_file = ffdata.metadata_file
122118
working_directory = hfss.working_directory
123119

120+
hfss.save_project()
124121
hfss.release_desktop()
122+
# Wait 3 seconds to allow Electronics Desktop to shut down before cleaning the temporary directory.
123+
time.sleep(3)
125124

126125
# ## Load far field data
127126
#
128127
# Load far field data stored.
129128

130-
ffdata = FfdSolutionData(frequencies=frequencies[0], eep_files=eep_file[0])
129+
ffdata = FfdSolutionData(input_file=metadata_file)
131130

132131
# ## Generate contour plot
133132
#
134133
# Generate a contour plot. You can define the Theta scan
135134
# and Phi scan.
136135

137-
ffdata.plot_farfield_contour(
138-
farfield_quantity="RealizedGain", title="Contour at {}Hz".format(ffdata.frequency)
136+
ffdata.plot_contour(
137+
quantity="RealizedGain", title="Contour at {}Hz".format(ffdata.frequency)
139138
)
140139

141140
# ## Generate 2D cutout plots
142141
#
143142
# Generate 2D cutout plots. You can define the Theta scan
144143
# and Phi scan.
145144

146-
ffdata.plot_2d_cut(
145+
ffdata.plot_cut(
146+
quantity="RealizedGain",
147147
primary_sweep="theta",
148148
secondary_sweep_value=[-180, -75, 75],
149-
farfield_quantity="RealizedGain",
150149
title="Azimuth at {}Hz".format(ffdata.frequency),
151150
quantity_format="dB10",
152151
)
153152

154-
ffdata.plot_2d_cut(
153+
ffdata.plot_cut(
154+
quantity="RealizedGain",
155155
primary_sweep="phi",
156156
secondary_sweep_value=30,
157-
farfield_quantity="RealizedGain",
158157
title="Elevation",
159158
quantity_format="dB10",
160159
)
161160

162-
# ## Generate 3D polar plots in Matplotlib
161+
# ## Generate 3D plot
163162
#
164-
# Generate 3D polar plots in Matplotlib. You can define
165-
# the Theta scan and Phi scan.
163+
# Generate 3D plots. You can define the Theta scan and Phi scan.
166164

167-
ffdata.polar_plot_3d(farfield_quantity="RealizedGain")
165+
# ffdata.plot_3d(quantity='RealizedGain',
166+
# output_file=os.path.join(working_directory, "Image.jpg"),
167+
# show=False)
168168

169-
# ## Clean temporary directory
169+
# ## Cleanup
170+
#
171+
# All project files are saved in the folder ``temp_dir.name``.
172+
# If you've run this example as a Jupyter notebook you
173+
# can retrieve those project files. The following cell
174+
# removes all temporary files, including the project folder.
170175

171176
temp_dir.cleanup()

examples/02-HFSS/Create_3d_Component_and_use_it.py

+43-20
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,35 @@
99
#
1010
# Keywords: **HFSS**, **3D Component**.
1111

12-
# ## Perform required imports
13-
#
14-
# Perform required imports.
12+
# ## Preparation
13+
# Import the required packages
1514

1615
import os
1716
import tempfile
17+
import time
1818

1919
from pyaedt import Hfss
20-
from pyaedt.generic.general_methods import generate_unique_name
2120

22-
# Set constant values
21+
# ## Project setup
22+
#
23+
# Define constants
2324

2425
AEDT_VERSION = "2024.1"
26+
NG_MODE = False # Open Electronics UI when the application is launched.
2527

26-
# ## Create temporary directory
28+
# Create temporary directory
2729

28-
temp_dir = tempfile.TemporaryDirectory(suffix="_ansys")
30+
temp_dir = tempfile.TemporaryDirectory(suffix=".ansys")
2931

30-
# ## Launch AEDT
31-
#
32-
# Launch AEDT, create an HFSS design, and save the project.
32+
# Create an HFSS object.
3333

34-
hfss = Hfss(version=AEDT_VERSION, new_desktop=True, close_on_exit=True)
35-
hfss.save_project(os.path.join(temp_dir.name, generate_unique_name("example") + ".aedt"))
34+
hfss = Hfss(
35+
version=AEDT_VERSION,
36+
new_desktop=True,
37+
close_on_exit=True,
38+
non_graphical=NG_MODE,
39+
)
40+
hfss.save_project(os.path.join(temp_dir.name, "example.aedt"))
3641

3742
# ## Variable definition
3843
#
@@ -49,15 +54,23 @@
4954

5055
# +
5156
substrate = hfss.modeler.create_box(
52-
["-width", "-width", "-thick"], ["2*width", "2*width", "thick"], matname="FR4_epoxy", name="sub"
57+
["-width", "-width", "-thick"],
58+
["2*width", "2*width", "thick"],
59+
matname="FR4_epoxy",
60+
name="sub",
5361
)
5462

5563
patch = hfss.modeler.create_rectangle(
5664
"XY", ["-width/2", "-width/2", "0mm"], ["width", "width"], name="patch1"
5765
)
5866

5967
via1 = hfss.modeler.create_cylinder(
60-
2, ["-width/8", "-width/4", "-thick"], "0.01mm", "thick", matname="copper", name="via_inner"
68+
2,
69+
["-width/8", "-width/4", "-thick"],
70+
"0.01mm",
71+
"thick",
72+
matname="copper",
73+
name="via_inner",
6174
)
6275

6376
via_outer = hfss.modeler.create_cylinder(
@@ -84,7 +97,9 @@
8497

8598
# +
8699
side_face = [
87-
i for i in via_outer.faces if i.id not in [via_outer.top_face_z.id, via_outer.bottom_face_z.id]
100+
i
101+
for i in via_outer.faces
102+
if i.id not in [via_outer.top_face_z.id, via_outer.bottom_face_z.id]
88103
]
89104

90105
hfss.assign_perfecte_to_sheets(side_face)
@@ -106,14 +121,14 @@
106121
# Multiple options are available to partially select objects, cs, boundaries and mesh operations.
107122
# Furthermore, encrypted 3d comp can be created too.
108123

109-
component_path = os.path.join(temp_dir.name, generate_unique_name("component_test") + ".aedbcomp")
124+
component_path = os.path.join(temp_dir.name, "component_test.aedbcomp")
110125
hfss.modeler.create_3dcomponent(component_path, "patch_antenna")
111126

112127
# ## Multiple project management
113128
#
114129
# PyAEDT allows to control multiple projects, design and solution type at the same time.
115130

116-
new_project = os.path.join(temp_dir.name, generate_unique_name("new_project") + ".aedt")
131+
new_project = os.path.join(temp_dir.name, "new_project.aedt")
117132
hfss2 = Hfss(project=new_project, design="new_design")
118133

119134
# ## Insert 3D component
@@ -137,7 +152,7 @@
137152
# They can be the same or linked to different files.
138153

139154
hfss2.modeler.create_coordinate_system(origin=[20, 20, 10], name="Second_antenna")
140-
ant2 = hfss2.modeler.insert_3d_component(component_path, targetCS="Second_antenna")
155+
ant2 = hfss2.modeler.insert_3d_component(component_path, coordinate_system="Second_antenna")
141156

142157
# ## Move 3D components
143158
#
@@ -165,14 +180,22 @@
165180
hfss2.modeler.fit_all()
166181
hfss2.plot(
167182
show=False,
168-
export_path=os.path.join(hfss.working_directory, "Image.jpg"),
183+
output_file=os.path.join(hfss.working_directory, "Image.jpg"),
169184
plot_air_objects=True,
170185
)
171186

172187
# ## Release AEDT
173188

189+
hfss2.save_project()
174190
hfss2.release_desktop()
191+
# Wait 3 seconds to allow Electronics Desktop to shut down before cleaning the temporary directory.
192+
time.sleep(3)
175193

176-
# ## Clean temporary directory
194+
# ## Cleanup
195+
#
196+
# All project files are saved in the folder ``temp_dir.name``.
197+
# If you've run this example as a Jupyter notebook you
198+
# can retrieve those project files. The following cell removes
199+
# all temporary files, including the project folder.
177200

178201
temp_dir.cleanup()

0 commit comments

Comments
 (0)