{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# This file is part of nannos\n# License: GPLv3\n%matplotlib notebook" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n# Geometry tools\n\nDefining patterns using shapely, or built in functions.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\nimport numpy as np\nimport shapely.geometry as sg\n\nimport nannos as nn\n\nN = 2**10\nlattice = nn.Lattice([[1, 0], [0, 1]], N)\nepsilon = lattice.ones()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A split ring resonator\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "t = 0.1\nl_out = 0.8\nl_arm = 0.45\ngap = 0.05\n\ns_out = (1 - l_out) / 2\ns_in = s_out + t\nl_in = l_out - 2 * t\n\nsq_out = sg.Polygon(\n [\n (s_out, s_out),\n (s_out + l_out, s_out),\n (s_out + l_out, s_out + l_out),\n (s_out, s_out + l_out),\n ]\n)\n\nsq_in = sg.Polygon(\n [\n (s_in, s_in),\n (s_in + l_in, s_in),\n (s_in + l_in, s_in + l_in),\n (s_in, s_in + l_in),\n ]\n)\nring = sq_out.difference(sq_in)\n\ng = sg.Polygon(\n [\n (0.5 - gap / 2, s_out),\n (0.5 + gap / 2, s_out),\n (0.5 + gap / 2, s_out + t),\n (0.5 - gap / 2, s_out + t),\n ]\n)\nsrr = ring.difference(g)\n\n\na = 0.5 - gap / 2\nb = s_out + t\narm_left = sg.Polygon(\n [\n (a - t, b),\n (a - t, b + l_arm),\n (a, b + l_arm),\n (a, b),\n ]\n)\na = 0.5 + gap / 2\narm_right = sg.Polygon(\n [\n (a, b),\n (a, b + l_arm),\n (a + t, b + l_arm),\n (a + t, b),\n ]\n)\n\nsrr = srr.union(arm_left).union(arm_right)\nmask = lattice.geometry_mask(srr)\nepsilon[mask] = 6\n\nlayer = lattice.Layer(epsilon=epsilon)\nplt.figure()\nims = layer.plot()\nplt.colorbar(ims[0])\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Various patterns\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "epsilon = lattice.ones()\n\ncircle = sg.Point(0.4, 0.4).buffer(0.3)\nmask = lattice.geometry_mask(circle)\n\nepsilon[mask] = 2\ncircle1 = sg.Point(0.8, 0.8).buffer(0.1)\nmask1 = lattice.geometry_mask(circle1)\nepsilon[mask1] = 3\n\n\ncircle3 = sg.Point(0.3, 0.3).buffer(0.2)\ndiff = circle.difference(circle3)\nmask2 = lattice.geometry_mask(diff)\nepsilon[mask2] = 4\n\n\ncircle4 = sg.Point(0.3, 0.7).buffer(0.15)\nunion = diff.union(circle4)\nmask3 = lattice.geometry_mask(union)\nepsilon[mask3] = 5\n\npolygon = sg.Polygon([(0.7, 0.1), (0.9, 0.1), (0.9, 0.4)])\nmask4 = lattice.geometry_mask(polygon)\nepsilon[mask4] = 6\n\ncenters = [(0.1, 0.8), (0.5, 0.9), (0.8, 0.5)]\nradii = [0.03, 0.08, 0.04]\n\nfor i, (c, r) in enumerate(zip(centers, radii)):\n circle = sg.Point(c).buffer(r)\n mask = lattice.geometry_mask(circle)\n epsilon[mask] = 7 + i\n\n\nlayer = lattice.Layer(epsilon=epsilon)\nplt.figure()\nims = layer.plot()\nplt.colorbar(ims[0])\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A crescent using built in nannos geometry and boolean logic\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "epsilon = lattice.ones()\n\ncircle0 = lattice.circle(center=(0.5, 0.7), radius=0.4)\ncircle1 = lattice.circle(center=(0.5, 0.5), radius=0.4)\ndiff = (circle0 ^ circle1) & circle1\nepsilon[diff] = 4\n\n\nlayer = lattice.Layer(epsilon=epsilon)\nplt.figure()\nims = layer.plot(cmap=\"Reds\")\nplt.colorbar(ims[0])\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Read an image file\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "im = plt.imread(\"../doc/_assets/nannos.png\")\nim = np.rot90(im, axes=(1, 0))\n\ns = np.shape(im)[:2]\n\nN = np.max(s)\nM = int(0.2 * N)\nN += M\nim_bin = im[:, :, -1]\nim_bin[im_bin < 0.5] = 0\nim_bin[im_bin >= 0.5] = 1\nim_bin = np.array(im_bin, dtype=bool)\nim_pat = np.zeros((N, N), dtype=bool)\nn0 = M // 2\nim_pat[n0 : n0 + s[0], n0 : n0 + s[1]] = im_bin" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define a simulation\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "lattice = nn.Lattice([[1.0, 0], [0, 1.0]], discretization=N)\nsup = lattice.Layer(\"Superstrate\", epsilon=1)\nsub = lattice.Layer(\"Substrate\", epsilon=2, thickness=0.2)\nepsilon = lattice.ones()\nepsilon[im_pat] = 3\nms = lattice.Layer(\"Metasurface\", thickness=0.1, epsilon=epsilon)\npw = nn.PlaneWave(wavelength=1.2, angles=(0, 0, 0))\nsim = nn.Simulation([sup, ms, sub], pw, nh=100)\nR, T = sim.diffraction_efficiencies()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Plot unit cell\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "p = sim.plot_structure(cmap=\"Blues\")\ncpos = [\n (1.1192477879430005, -1.2748586620193856, -0.9994028480242046),\n (0.5184051413665429, 0.39573269350113394, 0.47559144020172595),\n (-0.03201639930679419, 0.6550248171539488, -0.7549287642472394),\n]\np.show(cpos=cpos)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Get and plot the electric field\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "E = sim.get_field_grid(\"Metasurface\", field=\"E\", component=\"all\")\nEnorm2 = np.sum(np.abs(E) ** 2, axis=0) ** 0.5\nplt.figure()\nplt.pcolormesh(*lattice.grid, Enorm2[:, :, 0], cmap=\"inferno\")\nplt.colorbar()\nms.plot(alpha=0.1, cmap=\"Greys\")\nplt.axis(\"off\")\nplt.tight_layout()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import nannos.utils.jupyter\n%nannos_version_table" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.12.5" } }, "nbformat": 4, "nbformat_minor": 0 }