Download this example
Download this example as a Jupyter Notebook or as a Python script.
Eigenmode filter#
This example illustrates and efficient approach to calculate eigenmode frequencies over a wide bandwidth for open structures using HFSS.
The model is comprised of a metal chassis and a simple PCB inside the enclosure.

HFSS relies on specification of a lower frequency limit for the search5 range. The number of desired modes must also be specified.
If performance is to be determined over a wide bandwith, the large number of modes can increase compute time. An iterative search that limits the number of modes being sought for each iteration improves time and memory requirements.
Keywords: HFSS, Eigenmode, resonance.
Prerequisites#
Perform imports#
[1]:
from pathlib import Path
import tempfile
import time
import numpy as np
import ansys.aedt.core
from ansys.aedt.core.examples.downloads import download_file
from ansys.aedt.core.generic.settings import settings
Define constants#
Constants help ensure consistency and avoid repetition throughout the example.
[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")
Model Preparation#
The model used in this example will be downloaded from the example-data GitHub repository.
[4]:
project_path = download_file(
"eigenmode", "emi_PCB_house.aedt", temp_folder.name
)
[5]:
hfss = ansys.aedt.core.Hfss(
project=project_path,
version=AEDT_VERSION,
non_graphical=NG_MODE,
new_desktop=False,
)
hfss.desktop_class.logger.log_on_stdout = False
PyAEDT INFO: Parsing C:\Users\ansys\AppData\Local\Temp\tmpqc_tynu9.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.26.dev0.
PyAEDT INFO: Initializing Desktop session.
PyAEDT INFO: AEDT version 2025.2.
PyAEDT INFO: File C:\Users\ansys\AppData\Local\Temp\tmpqc_tynu9.ansys\eigenmode\emi_PCB_house.aedt correctly loaded. Elapsed time: 0m 0sec
PyAEDT INFO: New AEDT session is starting on gRPC port 61233.
PyAEDT INFO: Starting new AEDT gRPC session on port 61233.
PyAEDT INFO: Launching AEDT server with gRPC transport mode: wnua
PyAEDT INFO: Electronics Desktop started on gRPC port 61233 after 10.8 seconds.
PyAEDT INFO: AEDT installation Path C:\Program Files\ANSYS Inc\v252\AnsysEM
PyAEDT INFO: Connected to AEDT gRPC session on port 61233.
PyAEDT WARNING: Service Pack is not detected. PyAEDT is currently connecting in Insecure Mode.
PyAEDT WARNING: Please download and install latest Service Pack to use connect to AEDT in Secure Mode.
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
The function find_resonance() creates a solution setup, runs an analysis and returns the Q-factor and frequency values of num_modes resonant modes.
This function will then be called inside a while loop that filters all physical resonant modes over a wide bandwidth to retain only those modes having a quality factor greater than the user-defined limit.
The workflow used to retrieve solution data from HFSS is comprised of the following steps and corresponding method calls: | Step | Description | Method | |—|---|—| | 1. | Retrieve a list of all availablesolution “categories”.| hfss.post.avilable_report_quantities() | | 2. | Retrieve a SolutionData object to provide an interface to the solution data. | hfss.post.get_solution_data() | | 3. | Retrieve the data | get_expression_data()|
These steps mirror the reporter UI in the Electronics Desktop:

[6]:
def find_resonance(num_modes):
# 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 quantity names for the quality factor values.
q_solution_names = hfss.post.available_report_quantities(
quantities_category="Eigen Q"
)
# Get the quantity names for the frequency.
f_solution_names = hfss.post.available_report_quantities(
quantities_category="Eigen Modes"
)
# Store a list of [q_factor, frequency] pairs
data = []
get_solution = lambda quantity: hfss.post.get_solution_data(expressions=quantity, report_category="Eigenmode")
get_data = lambda solution: float(solution.get_expression_data()[1][0])
for q_name, f_name in zip(q_solution_names, f_solution_names):
eigen_q_value = get_solution(q_name)
eigen_f_value = get_solution(f_name)
data.append([get_data(eigen_q_value), get_data(eigen_f_value)])
return np.array(data)
fmin: The minimum frequency for the global search in GHz.fmax: The maximum frequency for the global search (GHz). When a mode is found having a frequency greater than or equal to this value, the iterations end.limit: The lower bound on quality factor. Modes having a lower quality factor are assumed to be non-physical and are removed from the results.
[7]:
fmin = 1 # Minimum frequency in search range (GHz)
fmax = 2 # Maximum frequency in search range
limit = 10 # Q-factor threshold (low Q modes will be ignored)
next_fmin = fmin # Current lowest frequency in the iterative search
setup_nr = 1 # Current iteration in the search loop.
valid_modes = None
while next_fmin < fmax:
modes = find_resonance(6) # Limit the search to 6 modes per iteration.
next_fmin = modes[-1][1] / 1E9
setup_nr += 1
cont_res = len(modes)
valid_modes = [q for q in modes if q[0] > limit]
count = 1
if valid_modes:
for mode in valid_modes:
print(f"Mode {count}: Q= {mode[0]}, f= {mode[1]/1e9:.3f} GHz")
count += 1
else:
print("No valid modes found.")
Time to initialize solution data:0.013181447982788086
Time to initialize solution data:0.015189409255981445
Time to initialize solution data:0.026732683181762695
Time to initialize solution data:0.026732683181762695
Time to initialize solution data:0.015685558319091797
Time to initialize solution data:0.015685558319091797
Time to initialize solution data:0.015851736068725586
Time to initialize solution data:0.015851736068725586
Time to initialize solution data:0.0
Time to initialize solution data:0.015760183334350586
Time to initialize solution data:0.015851736068725586
Time to initialize solution data:0.015851736068725586
Time to initialize solution data:0.01596975326538086
Time to initialize solution data:0.01596975326538086
Time to initialize solution data:0.015129566192626953
Time to initialize solution data:0.015129566192626953
Time to initialize solution data:0.008220672607421875
Time to initialize solution data:0.008220672607421875
Time to initialize solution data:0.016325950622558594
Time to initialize solution data:0.016325950622558594
Time to initialize solution data:0.015758752822875977
Time to initialize solution data:0.024831533432006836
Time to initialize solution data:0.016034841537475586
Time to initialize solution data:0.016034841537475586
Time to initialize solution data:0.02293539047241211
Time to initialize solution data:0.02293539047241211
Time to initialize solution data:0.015287637710571289
Time to initialize solution data:0.015287637710571289
Time to initialize solution data:0.011821985244750977
Time to initialize solution data:0.016309738159179688
Time to initialize solution data:0.01654958724975586
Time to initialize solution data:0.01654958724975586
Time to initialize solution data:0.0
Time to initialize solution data:0.015101194381713867
Time to initialize solution data:0.008069515228271484
Time to initialize solution data:0.008069515228271484
Time to initialize solution data:0.0
Time to initialize solution data:0.016034603118896484
Time to initialize solution data:0.015146493911743164
Time to initialize solution data:0.015146493911743164
Time to initialize solution data:0.015371561050415039
Time to initialize solution data:0.015371561050415039
Time to initialize solution data:0.006299734115600586
Time to initialize solution data:0.006299734115600586
Time to initialize solution data:0.016459226608276367
Time to initialize solution data:0.016459226608276367
Time to initialize solution data:0.010711908340454102
Time to initialize solution data:0.016349077224731445
Mode 1: Q= 395.5699044962927, f= 1.853 GHz
Mode 2: Q= 456.2650870701165, f= 2.261 GHz
Display the model.
[8]:
hfss.modeler.fit_all()
hfss.plot(
show=False,
output_file=Path(hfss.working_directory) / "Image.jpg",
plot_air_objects=False,
)
[8]:
Class: ansys.aedt.core.visualization.plot.pyvista.ModelPlotter
Finish#
Save the project#
[9]:
hfss.save_project()
hfss.release_desktop()
# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory.
time.sleep(3)
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.
[10]:
temp_folder.cleanup()
Download this example
Download this example as a Jupyter Notebook or as a Python script.