{ "cells": [ { "cell_type": "markdown", "id": "296a0e27", "metadata": {}, "source": [ "# Eigenmode filter\n", "\n", "This example shows how to use PyAEDT to automate the Eigenmode solver in HFSS.\n", "Eigenmode analysis can be applied to open radiating structures\n", "using an absorbing boundary condition. This type of analysis is useful for\n", "determining the resonant frequency of a geometry or an antenna, and it can be used to refine\n", "the mesh at the resonance, even when the resonant frequency of the antenna is not known.\n", "\n", "The challenge posed by this method is to identify and filter the non-physical modes\n", "resulting from reflection from boundaries of the main domain.\n", "Because the Eigenmode solver sorts by frequency and does not filter on the\n", "quality factor, these virtual modes are present when the Eigenmode approach is\n", "applied to nominally open structures.\n", "\n", "When looking for resonant modes over a wide frequency range for nominally\n", "enclosed structures, several iterations may be required because the minimum frequency\n", "is determined manually. Simulations re-run until the complete frequency range is covered\n", "and all important physical modes are calculated.\n", "\n", "The following script finds the physical modes of a model in a wide frequency\n", "range by automating the solution setup.\n", "During each simulation, a user-defined number of modes is simulated, and the modes\n", "with a Q higher than a user-defined value are filtered.\n", "The next simulation automatically continues to find modes having a frequency higher\n", "than the last mode of the previous analysis.\n", "This continues until the maximum frequency in the desired range is achieved.\n", "\n", "Keywords: **HFSS**, **Eigenmode**, **resonance**." ] }, { "cell_type": "markdown", "id": "9b2f0d74", "metadata": {}, "source": [ "## Perform imports and define constants\n", "\n", "Perform required imports." ] }, { "cell_type": "code", "execution_count": null, "id": "528f4769", "metadata": {}, "outputs": [], "source": [ "import os\n", "import tempfile\n", "import time" ] }, { "cell_type": "code", "execution_count": null, "id": "b74ae4ba", "metadata": {}, "outputs": [], "source": [ "import ansys.aedt.core" ] }, { "cell_type": "markdown", "id": "82481087", "metadata": {}, "source": [ "Define constants." ] }, { "cell_type": "code", "execution_count": null, "id": "1c9f70a6", "metadata": {}, "outputs": [], "source": [ "AEDT_VERSION = \"2024.2\"\n", "NUM_CORES = 4\n", "NG_MODE = False # Open AEDT UI when it is launched." ] }, { "cell_type": "markdown", "id": "83ea63bf", "metadata": {}, "source": [ "## Create temporary directory\n", "\n", "Create a temporary directory where downloaded data or\n", "dumped data can be stored.\n", "If you'd like to retrieve the project data for subsequent use,\n", "the temporary folder name is given by ``temp_folder.name``." ] }, { "cell_type": "code", "execution_count": null, "id": "cfd03dd1", "metadata": {}, "outputs": [], "source": [ "temp_folder = tempfile.TemporaryDirectory(suffix=\".ansys\")" ] }, { "cell_type": "markdown", "id": "89b9c14e", "metadata": {}, "source": [ "## Download 3D component\n", "Download the 3D component that is needed to run the example." ] }, { "cell_type": "code", "execution_count": null, "id": "859289a2", "metadata": {}, "outputs": [], "source": [ "project_path = ansys.aedt.core.downloads.download_file(\n", " \"eigenmode\", \"emi_PCB_house.aedt\", temp_folder.name\n", ")" ] }, { "cell_type": "markdown", "id": "f7faa1ea", "metadata": {}, "source": [ "## Launch AEDT" ] }, { "cell_type": "code", "execution_count": null, "id": "0e5f766c", "metadata": {}, "outputs": [], "source": [ "d = ansys.aedt.core.launch_desktop(\n", " AEDT_VERSION,\n", " non_graphical=NG_MODE,\n", " new_desktop=True,\n", ")" ] }, { "cell_type": "markdown", "id": "0c7a3522", "metadata": {}, "source": [ "## Launch HFSS\n", "\n", "Create an HFSS design." ] }, { "cell_type": "code", "execution_count": null, "id": "be2dcd11", "metadata": {}, "outputs": [], "source": [ "hfss = ansys.aedt.core.Hfss(\n", " version=AEDT_VERSION, project=project_path, non_graphical=NG_MODE\n", ")" ] }, { "cell_type": "markdown", "id": "531beaac", "metadata": {}, "source": [ "## Input parameters for Eigenmode solver\n", "\n", "The geometry and material should be already set. The analyses are generated by the code.\n", "The ``num_modes`` parameter is the number of modes during each analysis. The maximum\n", "allowed number is 20. Entering a number higher than 10 might result in a long simulation\n", "time as the Eigenmode solver must converge on modes. The ``fmin`` parameter is the lowest\n", "frequency of interest. The ``fmax`` parameter is the highest frequency of interest.\n", "The ``limit`` parameter determines which modes are ignored." ] }, { "cell_type": "code", "execution_count": null, "id": "f99b24a3", "metadata": {}, "outputs": [], "source": [ "num_modes = 6\n", "fmin = 1\n", "fmax = 2\n", "next_fmin = fmin\n", "setup_nr = 1\n", "limit = 10\n", "resonance = {}" ] }, { "cell_type": "markdown", "id": "ce19eac7", "metadata": { "lines_to_next_cell": 2 }, "source": [ "## Find modes\n", "\n", "The following cell defines a function that can be used to create and solve an Eigenmode setup.\n", "After solving the model, information about each mode is saved for subsequent processing." ] }, { "cell_type": "code", "execution_count": null, "id": "0717a1ac", "metadata": { "lines_to_next_cell": 2 }, "outputs": [], "source": [ "def find_resonance():\n", " # Setup creation\n", " next_min_freq = f\"{next_fmin} GHz\"\n", " setup_name = f\"em_setup{setup_nr}\"\n", " setup = hfss.create_setup(setup_name)\n", " setup.props[\"MinimumFrequency\"] = next_min_freq\n", " setup.props[\"NumModes\"] = num_modes\n", " setup.props[\"ConvergeOnRealFreq\"] = True\n", " setup.props[\"MaximumPasses\"] = 10\n", " setup.props[\"MinimumPasses\"] = 3\n", " setup.props[\"MaxDeltaFreq\"] = 5\n", "\n", " # Analyze the Eigenmode setup\n", " hfss.analyze_setup(setup_name, cores=NUM_CORES, use_auto_settings=True)\n", "\n", " # Get the Q and real frequency of each mode\n", " eigen_q_quantities = hfss.post.available_report_quantities(\n", " quantities_category=\"Eigen Q\"\n", " )\n", " eigen_mode_quantities = hfss.post.available_report_quantities()\n", " data = {}\n", " for i, expression in enumerate(eigen_mode_quantities):\n", " eigen_q_value = hfss.post.get_solution_data(\n", " expressions=eigen_q_quantities[i],\n", " setup_sweep_name=f\"{setup_name} : LastAdaptive\",\n", " report_category=\"Eigenmode\",\n", " )\n", " eigen_mode_value = hfss.post.get_solution_data(\n", " expressions=expression,\n", " setup_sweep_name=f\"{setup_name} : LastAdaptive\",\n", " report_category=\"Eigenmode\",\n", " )\n", " data[i] = [eigen_q_value.data_real()[0], eigen_mode_value.data_real()[0]]\n", "\n", " print(data)\n", " return data" ] }, { "cell_type": "markdown", "id": "2735ed51", "metadata": { "lines_to_next_cell": 2 }, "source": [ "## Automate Eigenmode solution\n", "\n", "Running the next cell calls the resonance function and saves\n", "only those modes with a Q higher than the defined\n", "limit. The ``find_resonance()`` function is called until the complete\n", "frequency range is covered.\n", "When the automation ends, the physical modes in the whole frequency\n", "range are reported." ] }, { "cell_type": "code", "execution_count": null, "id": "ed0359de", "metadata": {}, "outputs": [], "source": [ "while next_fmin < fmax:\n", " output = find_resonance()\n", " next_fmin = output[len(output) - 1][1] / 1e9\n", " setup_nr += 1\n", " cont_res = len(resonance)\n", " for q in output:\n", " if output[q][0] > limit:\n", " resonance[cont_res] = output[q]\n", " cont_res += 1\n", "\n", "resonance_frequencies = [f\"{resonance[i][1] / 1e9:.5} GHz\" for i in resonance]\n", "print(str(resonance_frequencies))" ] }, { "cell_type": "markdown", "id": "eeb7dcd8", "metadata": {}, "source": [ "Plot the model." ] }, { "cell_type": "code", "execution_count": null, "id": "2013d4f1", "metadata": {}, "outputs": [], "source": [ "hfss.modeler.fit_all()\n", "hfss.plot(\n", " show=False,\n", " output_file=os.path.join(hfss.working_directory, \"Image.jpg\"),\n", " plot_air_objects=False,\n", ")" ] }, { "cell_type": "markdown", "id": "8293e5ec", "metadata": {}, "source": [ "## Release AEDT" ] }, { "cell_type": "code", "execution_count": null, "id": "ad4b5b22", "metadata": {}, "outputs": [], "source": [ "hfss.save_project()\n", "d.release_desktop()\n", "# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory.\n", "time.sleep(3)" ] }, { "cell_type": "markdown", "id": "1ee25b29", "metadata": {}, "source": [ "## Clean up\n", "\n", "All project files are saved in the folder ``temp_folder.name``.\n", "If you've run this example as a Jupyter notebook, you\n", "can retrieve those project files. The following cell removes\n", "all temporary files, including the project folder." ] }, { "cell_type": "code", "execution_count": null, "id": "c7f5622b", "metadata": {}, "outputs": [], "source": [ "temp_folder.cleanup()" ] } ], "metadata": { "jupytext": { "cell_metadata_filter": "-all", "main_language": "python", "notebook_metadata_filter": "-all" } }, "nbformat": 4, "nbformat_minor": 5 }