Download this example

Download this example as a Jupyter Notebook or as a Python script.


Eigenmode filter#

This example shows how to use PyAEDT to automate the Eigenmode solver in HFSS. Eigenmode analysis can be applied to open radiating structures using an absorbing boundary condition. This type of analysis is useful for determining the resonant frequency of a geometry or an antenna, and it can be used to refine the mesh at the resonance, even when the resonant frequency of the antenna is not known.

The challenge posed by this method is to identify and filter the non-physical modes resulting from reflection from boundaries of the main domain. Because the Eigenmode solver sorts by frequency and does not filter on the quality factor, these virtual modes are present when the Eigenmode approach is applied to nominally open structures.

When looking for resonant modes over a wide frequency range for nominally enclosed structures, several iterations may be required because the minimum frequency is determined manually. Simulations re-run until the complete frequency range is covered and all important physical modes are calculated.

The following script finds the physical modes of a model in a wide frequency range by automating the solution setup. During each simulation, a user-defined number of modes is simulated, and the modes with a Q higher than a user-defined value are filtered. The next simulation automatically continues to find modes having a frequency higher than the last mode of the previous analysis. This continues until the maximum frequency in the desired range is achieved.

Keywords: HFSS, Eigenmode, resonance.

Perform imports and define constants#

Perform required imports.

[1]:
import os
import tempfile
import time

import ansys.aedt.core
from ansys.aedt.core.examples.downloads import download_file

Define constants.

[2]:
AEDT_VERSION = "2025.2"
NUM_CORES = 4
NG_MODE = False  # Open AEDT UI when it is launched.

Create temporary directory#

Create a temporary directory where downloaded data or dumped data can be stored. If you’d like to retrieve the project data for subsequent use, the temporary folder name is given by temp_folder.name.

[3]:
temp_folder = tempfile.TemporaryDirectory(suffix=".ansys")

Download 3D component#

Download the 3D component that is needed to run the example.

[4]:
project_path = download_file(
    "eigenmode", "emi_PCB_house.aedt", temp_folder.name
)

Launch AEDT#

[5]:
d = ansys.aedt.core.launch_desktop(
    AEDT_VERSION,
    non_graphical=NG_MODE,
    new_desktop=True,
)
PyAEDT INFO: Python version 3.10.11 (tags/v3.10.11:7d4cc5a, Apr  5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)].
PyAEDT INFO: PyAEDT version 0.23.dev0.
PyAEDT INFO: Initializing new Desktop session.
PyAEDT INFO: Log on console is enabled.
PyAEDT INFO: Log on file C:\Users\ansys\AppData\Local\Temp\pyaedt_ansys_61a1dec5-db6e-43fc-ac85-93976a8aabd3.log is enabled.
PyAEDT INFO: Log on AEDT is disabled.
PyAEDT INFO: Debug logger is disabled. PyAEDT methods will not be logged.
PyAEDT INFO: Launching PyAEDT with gRPC plugin.
PyAEDT INFO: New AEDT session is starting on gRPC port 54939.
PyAEDT INFO: Electronics Desktop started on gRPC port: 54939 after 11.482747077941895 seconds.
PyAEDT INFO: AEDT installation Path C:\Program Files\ANSYS Inc\v252\AnsysEM
PyAEDT INFO: Ansoft.ElectronicsDesktop.2025.2 version started with process ID 8468.

Launch HFSS#

Create an HFSS design.

[6]:
hfss = ansys.aedt.core.Hfss(
    version=AEDT_VERSION, project=project_path, non_graphical=NG_MODE
)
PyAEDT INFO: Parsing C:\Users\ansys\AppData\Local\Temp\tmpm8cv2xn4.ansys\eigenmode\emi_PCB_house.aedt.
PyAEDT INFO: Python version 3.10.11 (tags/v3.10.11:7d4cc5a, Apr  5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)].
PyAEDT INFO: PyAEDT version 0.23.dev0.
PyAEDT INFO: Returning found Desktop session with PID 8468!
PyAEDT INFO: File C:\Users\ansys\AppData\Local\Temp\tmpm8cv2xn4.ansys\eigenmode\emi_PCB_house.aedt correctly loaded. Elapsed time: 0m 0sec
PyAEDT INFO: Project emi_PCB_house has been opened.
PyAEDT INFO: Active Design set to with_chassis_em
PyAEDT INFO: Active Design set to with_chassis_em
PyAEDT INFO: Aedt Objects correctly read

Input parameters for Eigenmode solver#

The geometry and material should be already set. The analyses are generated by the code. The num_modes parameter is the number of modes during each analysis. The maximum allowed number is 20. Entering a number higher than 10 might result in a long simulation time as the Eigenmode solver must converge on modes. The fmin parameter is the lowest frequency of interest. The fmax parameter is the highest frequency of interest. The limit parameter determines which modes are ignored.

[7]:
num_modes = 6
fmin = 1
fmax = 2
next_fmin = fmin
setup_nr = 1
limit = 10
resonance = {}

Find modes#

The following cell defines a function that can be used to create and solve an Eigenmode setup. After solving the model, information about each mode is saved for subsequent processing.

[8]:
def find_resonance():
    # Setup creation
    next_min_freq = f"{next_fmin} GHz"
    setup_name = f"em_setup{setup_nr}"
    setup = hfss.create_setup(setup_name)
    setup.props["MinimumFrequency"] = next_min_freq
    setup.props["NumModes"] = num_modes
    setup.props["ConvergeOnRealFreq"] = True
    setup.props["MaximumPasses"] = 10
    setup.props["MinimumPasses"] = 3
    setup.props["MaxDeltaFreq"] = 5

    # Analyze the Eigenmode setup
    hfss.analyze_setup(setup_name, cores=NUM_CORES, use_auto_settings=True)

    # Get the Q and real frequency of each mode
    eigen_q_quantities = hfss.post.available_report_quantities(
        quantities_category="Eigen Q"
    )
    eigen_mode_quantities = hfss.post.available_report_quantities()
    data = {}
    for i, expression in enumerate(eigen_mode_quantities):
        eigen_q_value = hfss.post.get_solution_data(
            expressions=eigen_q_quantities[i],
            setup_sweep_name=f"{setup_name} : LastAdaptive",
            report_category="Eigenmode",
        )
        eigen_mode_value = hfss.post.get_solution_data(
            expressions=expression,
            setup_sweep_name=f"{setup_name} : LastAdaptive",
            report_category="Eigenmode",
        )
        data[i] = [eigen_q_value.data_real()[0], eigen_mode_value.data_real()[0]]

    print(data)
    return data

Automate Eigenmode solution#

Running the next cell calls the resonance function and saves only those modes with a Q higher than the defined limit. The find_resonance() function is called until the complete frequency range is covered. When the automation ends, the physical modes in the whole frequency range are reported.

[9]:
while next_fmin < fmax:
    output = find_resonance()
    next_fmin = output[len(output) - 1][1] / 1e9
    setup_nr += 1
    cont_res = len(resonance)
    for q in output:
        if output[q][0] > limit:
            resonance[cont_res] = output[q]
            cont_res += 1

resonance_frequencies = [f"{resonance[i][1] / 1e9:.5} GHz" for i in resonance]
print(str(resonance_frequencies))
PyAEDT INFO: Key Desktop/ActiveDSOConfigurations/HFSS correctly changed.
PyAEDT INFO: Solving design setup em_setup1
PyAEDT INFO: Design setup em_setup1 solved correctly in 0.0h 0.0m 50.0s
PyAEDT INFO: Key Desktop/ActiveDSOConfigurations/HFSS correctly changed.
PyAEDT INFO: PostProcessor class has been initialized! Elapsed time: 0m 0sec
PyAEDT INFO: PostProcessor class has been initialized! Elapsed time: 0m 0sec
PyAEDT INFO: Post class has been initialized! Elapsed time: 0m 0sec
PyAEDT INFO: Modeler class has been initialized! Elapsed time: 0m 1sec
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.014768600463867188
Time to initialize solution data:0.017768383026123047
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.01521754264831543
Time to initialize solution data:0.017811298370361328
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.014737367630004883
Time to initialize solution data:0.017737865447998047
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.01563572883605957
Time to initialize solution data:0.017635345458984375
C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\ansys\aedt\core\visualization\post\solution_data.py:733: UserWarning: Method `data_real` is deprecated. Use :func:`get_expression_data` property instead.
  warnings.warn("Method `data_real` is deprecated. Use :func:`get_expression_data` property instead.")
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.015010356903076172
Time to initialize solution data:0.017632007598876953
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.015033960342407227
Time to initialize solution data:0.017658233642578125
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.014571666717529297
Time to initialize solution data:0.017567873001098633
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.015209436416625977
Time to initialize solution data:0.018210172653198242
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.014743804931640625
Time to initialize solution data:0.017743349075317383
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.014547109603881836
Time to initialize solution data:0.0175473690032959
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.015574932098388672
Time to initialize solution data:0.018535375595092773
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.0146026611328125
Time to initialize solution data:0.017139911651611328
{0: [np.float64(103.06513375267946), np.float64(1355332420.34131)], 1: [np.float64(1.268215348193083), np.float64(1478857801.41881)], 2: [np.float64(0.8228778159574546), np.float64(1652467480.64678)], 3: [np.float64(0.6640591553693461), np.float64(1763970332.723)], 4: [np.float64(0.6766419577602678), np.float64(1765237546.4026)], 5: [np.float64(1.0259629202437963), np.float64(1821171387.40162)]}
PyAEDT INFO: Key Desktop/ActiveDSOConfigurations/HFSS correctly changed.
PyAEDT INFO: Solving design setup em_setup2
PyAEDT INFO: Design setup em_setup2 solved correctly in 0.0h 0.0m 54.0s
PyAEDT INFO: Key Desktop/ActiveDSOConfigurations/HFSS correctly changed.
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.014512062072753906
Time to initialize solution data:0.01752161979675293
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.015047788619995117
Time to initialize solution data:0.0176849365234375
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.015595436096191406
Time to initialize solution data:0.017592430114746094
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.014585733413696289
Time to initialize solution data:0.01758742332458496
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.014592409133911133
Time to initialize solution data:0.016588687896728516
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.014252901077270508
Time to initialize solution data:0.01725029945373535
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.014534235000610352
Time to initialize solution data:0.017027854919433594
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.01455831527709961
Time to initialize solution data:0.017556190490722656
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.014619827270507812
Time to initialize solution data:0.017629623413085938
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.014010190963745117
Time to initialize solution data:0.016569137573242188
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.014841079711914062
Time to initialize solution data:0.017840862274169922
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.014620780944824219
Time to initialize solution data:0.017151594161987305
{0: [np.float64(395.5699044962927), np.float64(1852676825.77992)], 1: [np.float64(0.7436448304796339), np.float64(2139379547.71637)], 2: [np.float64(456.2650870701165), np.float64(2261283109.83606)], 3: [np.float64(1.0908953023807333), np.float64(2347859232.9468)], 4: [np.float64(1.595326208776568), np.float64(2367242846.88747)], 5: [np.float64(1.8314043723259759), np.float64(2515365380.39913)]}
['1.3553 GHz', '1.8527 GHz', '2.2613 GHz']

Plot the model.

[10]:
hfss.modeler.fit_all()
hfss.plot(
    show=False,
    output_file=os.path.join(hfss.working_directory, "Image.jpg"),
    plot_air_objects=False,
)
PyAEDT INFO: Parsing design objects. This operation can take time
PyAEDT INFO: Refreshing bodies from Object Info
PyAEDT INFO: Bodies Info Refreshed Elapsed time: 0m 0sec
PyAEDT INFO: 3D Modeler objects parsed. Elapsed time: 0m 0sec
[10]:
<ansys.aedt.core.visualization.plot.pyvista.ModelPlotter at 0x28cb736e980>

Release AEDT#

[11]:
hfss.save_project()
d.release_desktop()
# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory.
time.sleep(3)
PyAEDT INFO: Project emi_PCB_house Saved correctly
PyAEDT INFO: Desktop has been released and closed.

Clean up#

All project files are saved in the folder temp_folder.name. If you’ve run this example as a Jupyter notebook, you can retrieve those project files. The following cell removes all temporary files, including the project folder.

[12]:
temp_folder.cleanup()

Download this example

Download this example as a Jupyter Notebook or as a Python script.