{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Strap Reactance Frequency Fit" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The antenna straps having a given length, their reactance is non zero. Let's look to the strap reactances from the realistic antenna model in vacuum and facing the water tank (aka the \"aquarium\"):" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib widget" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import skrf as rf\n", "from tqdm.notebook import tqdm\n", "\n", "# WEST ICRH Antenna package\n", "import sys; sys.path.append('..')\n", "from west_ic_antenna import WestIcrhAntenna\n", "\n", "# styling the figures \n", "rf.stylely()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# HFSS simulation of the antenna front-face radiating in WEST empty chamber (vacuum)\n", "file_vacuum = '../west_ic_antenna/data/Sparameters/front_faces/WEST_ICRH_antenna_front_face_curved_30to70MHz.s4p'\n", "ntw_vacuum = rf.Network(file_vacuum)\n", "\n", "# HFSS simulation of the antenna front-face direclty facing the water tank\n", "file_aquarium = '../west_ic_antenna/data/Sparameters/front_faces/aquarium/HFSS/Epsr_55MHz/WEST_ICRH_front_face_with_aquarium_Daq00cm.s4p'\n", "ntw_aquarium = rf.Network(file_aquarium)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's plot the front-face resistance R_s ($X_s=\\Im(Z)$) and reactance ($X_s=\\Im(Z)$) of each port for each cases:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(2, 1, sharex=True)\n", "# real parts\n", "[ntw_vacuum.plot_z_re(m=idx, n=idx, ax=ax[0], ls='--', color=f'C{idx}',\n", " label=f'vacuum - port {idx}') for idx in range(4)]\n", "[ntw_aquarium.plot_z_re(m=idx, n=idx, ax=ax[0], color=f'C{idx}',\n", " label=f'aquarium - port {idx}') for idx in range(4)]\n", "ax[0].set_title('Real part of the front-face port impedances')\n", "# imag parts\n", "[ntw_vacuum.plot_z_im(m=idx, n=idx, ax=ax[1], ls='--', color=f'C{idx}',\n", " label=f'vacuum - port {idx}') for idx in range(4)]\n", "[ntw_aquarium.plot_z_im(m=idx, n=idx, ax=ax[1], color=f'C{idx}',\n", " label=f'aquarium - port {idx}') for idx in range(4)]\n", "ax[1].set_title('Imaginary part of the front-face port impedances')\n", "fig.tight_layout()\n", "[a.legend(ncol=2) for a in ax]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As one can see, while the resistance of the front-face's ports obviously depend of the coupling conditions, while the reactance is almost independant of the coupling conditions and only depends of the frequency. \n", "\n", "Hence, one can fit the strap reactance with frequency only:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from numpy import polyfit, polyval" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# polynomial fit of the strap reactance\n", "coeffs = polyfit(ntw_vacuum.frequency.f/1e6, \n", " ntw_vacuum.z_im[:,0,0], \n", " deg=3)\n", "print(coeffs)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The strap reactance can be approximated by the following formula:\n", "\n", "$$\n", "X_s(f_{\\mathrm{MHz}}) \n", "= \n", "1.66\\times 10^{-4} f_{\\mathrm{MHz}}^3 \n", "-1.53\\times 10^{-2} f_{\\mathrm{MHz}}^2 \n", "+ 1.04 f_{\\mathrm{MHz}}\n", "-7.77\n", "$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def Xs(f_MHz):\n", " \"\"\"\n", " Strap Reactance [Ohm] for a given frequency in MHz\n", " \"\"\"\n", " return 1.66e-04*f_MHz**3 -1.53e-02*f_MHz**2 + 1.04*f_MHz -7.77" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots()\n", "ntw_vacuum.plot_z_im(m=0, n=0, ax=ax, lw=2, label='simulation')\n", "ax.plot(ntw_vacuum.frequency.f, Xs(ntw_vacuum.frequency.f/1e6), \n", " lw=2, ls='--', label='fit')\n", "ax.set_xlim(30e6, 70e6)\n", "ax.legend()\n", "ax.grid(True)\n", "ax.set_title('Strap Reactance $X_s$')\n", "ax.set_ylabel('$X_s$ [$\\Omega$]')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from IPython.core.display import HTML\n", "def _set_css_style(css_file_path):\n", " \"\"\"\n", " Read the custom CSS file and load it into Jupyter\n", " Pass the file path to the CSS file\n", " \"\"\"\n", " styles = open(css_file_path, \"r\").read()\n", " s = '' % styles\n", " return HTML(s)\n", "\n", "_set_css_style('custom.css')" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.7" } }, "nbformat": 4, "nbformat_minor": 4 }