{ "cells": [ { "cell_type": "markdown", "id": "a6db8a2c", "metadata": {}, "source": [ "# Component antenna array" ] }, { "cell_type": "markdown", "id": "8110a4a3", "metadata": {}, "source": [ "This example shows how to create an antenna array using 3D components for the unit\n", "cell definition. You will see how to set\n", "up the analysis, generates the EM solution, and post-process the solution data\n", "using Matplotlib and\n", "PyVista. This example runs only on Windows using CPython.\n", "\n", "Keywords: **HFSS**, **antenna array**, **3D components**, **far field**." ] }, { "cell_type": "markdown", "id": "66dd9a93", "metadata": {}, "source": [ "## Prerequisites\n", "\n", "### Perform imports" ] }, { "cell_type": "code", "execution_count": null, "id": "96f0959e", "metadata": {}, "outputs": [], "source": [ "import os\n", "import tempfile\n", "import time\n", "\n", "from ansys.aedt.core import Hfss\n", "from ansys.aedt.core.visualization.advanced.farfield_visualization import \\\n", " FfdSolutionData\n", "from ansys.aedt.core.examples.downloads import download_3dcomponent\n", "from ansys.aedt.core.generic import file_utils" ] }, { "cell_type": "markdown", "id": "b67d3e0c", "metadata": {}, "source": [ "### Define constants\n", "Constants help ensure consistency and avoid repetition throughout the example." ] }, { "cell_type": "code", "execution_count": null, "id": "3cef30f3", "metadata": {}, "outputs": [], "source": [ "AEDT_VERSION = \"2025.1\"\n", "NUM_CORES = 4\n", "NG_MODE = False # Open AEDT UI when it is launched." ] }, { "cell_type": "markdown", "id": "ae287739", "metadata": {}, "source": [ "### Create temporary directory\n", "\n", "Create a temporary working directory.\n", "The name of the working folder is stored in ``temp_folder.name``.\n", "\n", "> **Note:** The final cell in the notebook cleans up the temporary folder. If you want to\n", "> retrieve the AEDT project and data, do so before executing the final cell in the notebook.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "7e80c10f", "metadata": {}, "outputs": [], "source": [ "temp_folder = tempfile.TemporaryDirectory(suffix=\".ansys\")" ] }, { "cell_type": "markdown", "id": "87779006", "metadata": {}, "source": [ "### Download 3D component\n", "Download the 3D component that will be used to define\n", "the unit cell in the antenna array." ] }, { "cell_type": "code", "execution_count": null, "id": "9ee48084", "metadata": {}, "outputs": [], "source": [ "path_to_3dcomp = download_3dcomponent(local_path=temp_folder.name)" ] }, { "cell_type": "markdown", "id": "7f8253a4", "metadata": {}, "source": [ "### Launch HFSS\n", "\n", "The following cell creates a new ``Hfss`` object. Electronics desktop is launched and\n", "a new HFSS design is inserted into the project." ] }, { "cell_type": "code", "execution_count": null, "id": "28c8a0a6", "metadata": {}, "outputs": [], "source": [ "project_name = os.path.join(temp_folder.name, \"array.aedt\")\n", "hfss = Hfss(\n", " project=project_name,\n", " version=AEDT_VERSION,\n", " design=\"Array_Simple\",\n", " non_graphical=NG_MODE,\n", " new_desktop=False, # Set to `False` to connect to an existing AEDT session.\n", ")\n", "\n", "print(\"Project name \" + project_name)" ] }, { "cell_type": "markdown", "id": "8e575eb8", "metadata": {}, "source": [ "### Read array definition\n", "\n", "Read array definition from the JSON file." ] }, { "cell_type": "code", "execution_count": null, "id": "25b79779", "metadata": {}, "outputs": [], "source": [ "array_definition = file_utils.read_json(\n", " os.path.join(path_to_3dcomp, \"array_simple.json\")\n", ")" ] }, { "cell_type": "markdown", "id": "771fa322", "metadata": {}, "source": [ "### Add the 3D component definition\n", "\n", "The JSON file links the unit cell to the 3D component\n", "named \"Circ_Patch_5GHz1\".\n", "This can be seen by examining ``array_definition[\"cells\"]``. The following\n", "code prints the row and column indices of the array elements along with the name\n", "of the 3D component for each element.\n", "\n", "> **Note:** The ``array_definition[\"cells\"]`` is of type ``dict`` and the key\n", "> is builta as a string from the _(row, column)_ indices of the array element. For example:\n", "> the key for the element in the first row and 2nd column is ``\"(1,2)\"``." ] }, { "cell_type": "code", "execution_count": null, "id": "3e2599aa", "metadata": {}, "outputs": [], "source": [ "print(\"Element\\t\\tName\")\n", "print(\"--------\\t-------------\")\n", "for cell in array_definition[\"cells\"]:\n", " cell_name = array_definition[\"cells\"][cell][\"name\"]\n", " print(f\"{cell}\\t\\t'{cell_name}'.\")" ] }, { "cell_type": "markdown", "id": "23f61165", "metadata": {}, "source": [ "Each unit cell is defined by a 3D Component. The 3D component may be added\n", "to the HFSS design using the method\n", "[Hfss.modeler.insert_3d_component()](https://aedt.docs.pyansys.com/version/stable/API/_autosummary/ansys.aedt.core.modeler.modeler_3d.Modeler3D.insert_3d_component.html)\n", "or it can be added as a key to the ``array_definition`` as shown below." ] }, { "cell_type": "code", "execution_count": null, "id": "9fedc07c", "metadata": {}, "outputs": [], "source": [ "array_definition[\"Circ_Patch_5GHz1\"] = os.path.join(path_to_3dcomp, \"Circ_Patch_5GHz.a3dcomp\")" ] }, { "cell_type": "markdown", "id": "f977c98e", "metadata": {}, "source": [ "Note that the 3D component name is identical to the value for each element\n", "in the ``\"cells\"`` dictionary. For example,\n", "``array_definition[\"cells\"][0][0][\"name\"]" ] }, { "cell_type": "markdown", "id": "3b9fc626", "metadata": {}, "source": [ "### Create the 3D component array in HFSS\n", "\n", "The array is now generated in HFSS from the information in\n", "``array_definition``.\n", "If a 3D component is not available in the design, it is loaded\n", "into the dictionary from the path that you specify. The following\n", "code edits the dictionary to point to the location of the ``A3DCOMP`` file." ] }, { "cell_type": "code", "execution_count": null, "id": "f23b5320", "metadata": {}, "outputs": [], "source": [ "array = hfss.add_3d_component_array_from_json(array_definition, name=\"circ_patch_array\")" ] }, { "cell_type": "markdown", "id": "3ee2672d", "metadata": {}, "source": [ "### Modify cells\n", "\n", "Make the center element passive and rotate the corner elements." ] }, { "cell_type": "code", "execution_count": null, "id": "62e31440", "metadata": {}, "outputs": [], "source": [ "array.cells[1][1].is_active = False\n", "array.cells[0][0].rotation = 90\n", "array.cells[0][2].rotation = 90\n", "array.cells[2][0].rotation = 90\n", "array.cells[2][2].rotation = 90" ] }, { "cell_type": "markdown", "id": "a08cd135", "metadata": {}, "source": [ "### Set up simulation and run analysis\n", "\n", "Set up a simulation and analyze it." ] }, { "cell_type": "code", "execution_count": null, "id": "e0eac131", "metadata": { "lines_to_next_cell": 2 }, "outputs": [], "source": [ "setup = hfss.create_setup()\n", "setup.props[\"Frequency\"] = \"5GHz\"\n", "setup.props[\"MaximumPasses\"] = 3\n", "hfss.analyze(cores=NUM_CORES)" ] }, { "cell_type": "markdown", "id": "0c1f8e03", "metadata": {}, "source": [ "## Postprocess\n", "\n", "### Retrieve far-field data\n", "\n", "Get far-field data. After the simulation completes, the far\n", "field data is generated port by port and stored in a data class." ] }, { "cell_type": "code", "execution_count": null, "id": "39aba108", "metadata": {}, "outputs": [], "source": [ "ffdata = hfss.get_antenna_data(setup=hfss.nominal_adaptive, sphere=\"Infinite Sphere1\")" ] }, { "cell_type": "markdown", "id": "2f2fe86e", "metadata": {}, "source": [ "### Generate contour plot\n", "\n", "Generate a contour plot. You can define the Theta scan and Phi scan." ] }, { "cell_type": "code", "execution_count": null, "id": "c6c71491", "metadata": {}, "outputs": [], "source": [ "ffdata.farfield_data.plot_contour(\n", " quantity=\"RealizedGain\",\n", " title=f\"Contour at {ffdata.farfield_data.frequency * 1E-9:0.1f} GHz\"\n", ")" ] }, { "cell_type": "markdown", "id": "8a4acb61", "metadata": {}, "source": [ "### Save the project and data\n", "\n", "Farfield data can be accessed from disk after the solution has been generated\n", "using the ``metadata_file`` property of ``ffdata``." ] }, { "cell_type": "code", "execution_count": null, "id": "82498299", "metadata": {}, "outputs": [], "source": [ "metadata_file = ffdata.metadata_file\n", "working_directory = hfss.working_directory\n", "\n", "hfss.save_project()\n", "hfss.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": "1de20c4f", "metadata": {}, "source": [ "### Load far field data\n", "\n", "An instance of the ``FfdSolutionData`` class\n", "can be instantiated from the metadata file. Embedded element\n", "patters are linked through the metadata file." ] }, { "cell_type": "code", "execution_count": null, "id": "2cb59d9b", "metadata": {}, "outputs": [], "source": [ "ffdata = FfdSolutionData(input_file=metadata_file)" ] }, { "cell_type": "markdown", "id": "ad130e0d", "metadata": {}, "source": [ "## Generate contour plot\n", "\n", "Generate a contour plot. You can define the Theta scan\n", "and Phi scan." ] }, { "cell_type": "code", "execution_count": null, "id": "23a17d5e", "metadata": {}, "outputs": [], "source": [ "ffdata.plot_contour(\n", " quantity=\"RealizedGain\", title=f\"Contour at {ffdata.frequency * 1e-9:.1f} GHz\"\n", ")" ] }, { "cell_type": "markdown", "id": "3ace4a0d", "metadata": {}, "source": [ "### Generate 2D cutout plots\n", "\n", "Generate 2D cutout plots. You can define the Theta scan\n", "and Phi scan." ] }, { "cell_type": "code", "execution_count": null, "id": "e9b2e26a", "metadata": {}, "outputs": [], "source": [ "ffdata.plot_cut(\n", " quantity=\"RealizedGain\",\n", " primary_sweep=\"theta\",\n", " secondary_sweep_value=[-180, -75, 75],\n", " title=f\"Azimuth at {ffdata.frequency * 1E-9:.1f} GHz\",\n", " quantity_format=\"dB10\",\n", ")\n", "\n", "ffdata.plot_cut(\n", " quantity=\"RealizedGain\",\n", " primary_sweep=\"phi\",\n", " secondary_sweep_value=30,\n", " title=\"Elevation\",\n", " quantity_format=\"dB10\",\n", ")" ] }, { "cell_type": "markdown", "id": "2f579848", "metadata": {}, "source": [ "### Generate 3D plot\n", "\n", "Generate 3D plots. You can define the Theta scan and Phi scan." ] }, { "cell_type": "code", "execution_count": null, "id": "4a1a3792", "metadata": {}, "outputs": [], "source": [ "ffdata.plot_3d(\n", " quantity=\"RealizedGain\",\n", " output_file=os.path.join(working_directory, \"Image.jpg\"),\n", " show=False,\n", ")" ] }, { "cell_type": "markdown", "id": "0a1c9d32", "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\n", "removes all temporary files, including the project folder." ] }, { "cell_type": "code", "execution_count": null, "id": "e21108cc", "metadata": {}, "outputs": [], "source": [ "temp_folder.cleanup()" ] } ], "metadata": { "jupytext": { "cell_metadata_filter": "-all", "main_language": "python", "notebook_metadata_filter": "-all" } }, "nbformat": 4, "nbformat_minor": 5 }