diff --git a/AdvancedGaussianSources.ipynb b/AdvancedGaussianSources.ipynb
new file mode 100644
index 00000000..428fe15b
--- /dev/null
+++ b/AdvancedGaussianSources.ipynb
@@ -0,0 +1,1816 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "6b6287fd-21a5-4276-a199-b040bb171541",
+ "metadata": {},
+ "source": [
+ "# Advanced Gaussian sources\n",
+ "\n",
+ "Tidy3D natively offers sources like ModeSource, PlaneWave, GaussianBeam, etc. However, due to the python and open-source nature of Tidy3D, we can easily define arbitrary sources such as vortex beams. In this notebook, we demonstrate how to create these advanced sources in a way that is easily usable in multiple scenarios.\n",
+ "
\n",
+ "It can often be tedious to create easily usable customized simulation objects from scratch, as there are various details to consider. For instance, if one wants to create an easily-usable beam source from scratch, one must create functionality to automatically interpret the source plane into field coordinates, handle conversion for polar and azimuthal angles, handle different direction specifications, etc. This all becomes very complicated to build, so there is often a tradeoff between ease of construction and ease of use.\n",
+ "
\n",
+ "Fortunately, we can take advantage of the fact that Tidy3D's [Python frontend](https://github.com/flexcompute/tidy3d/tree/981c0ebb22ba4dd317818ebc3729edb1e0005f2f) is open source is open source to create complex Gaussian sources without needing to consider any of these extraneous functionalities. Namely, we use the Tidy3D [BeamProfile](https://github.com/flexcompute/tidy3d/blob/develop/tidy3d/components/beam.py) class to handle all extra usability considerations, so we only need to define the scalar field profile for the propagation direction. The BeamProfile object will then automatically create, interpolate, and rotate the field amplitudes according to the geometry of the source plane and specified angles.\n",
+ "
\n",
+ "This is just one way in which we can take advantage of the open source nature of Tidy3D, and these principles can be applied to any base object class that Tidy3D provides."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "0e1ed43f-e352-4b82-a2e8-c1d3fe23e7de",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Standard python imports\n",
+ "import matplotlib.pyplot as plt\n",
+ "import numpy as np\n",
+ "\n",
+ "# Tidy3D import\n",
+ "import tidy3d as td\n",
+ "from tidy3d import web"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4b12ff8b-18e5-41a8-a62b-5165050f14b9",
+ "metadata": {},
+ "source": [
+ "If we look at how Tidy3D's GaussianBeam uses the abstract BeamProfile class, we see that the BeamProfile class already handles polarization angles, propagation angles, sourcetimes, direction, and can interpret user-defined source plane geometry. Thus we need only define the extra parameters our advanced Gaussian sources need on top of these. With each source, we will demonstrate its use after defining it as an object."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c1e27425-c9f0-47f5-84e1-77003ed6eb19",
+ "metadata": {},
+ "source": [
+ "## Hermite-Gaussian source\n",
+ "\n",
+ "Here we show how to create a Hermite-Gaussian mode in Tidy3D using our [CustomFieldSource](https://docs.flexcompute.com/projects/tidy3d/en/latest/api/_autosummary/tidy3d.CustomFieldSource.html) object. We then validate the field profile change along the propagation direction.
\n",
+ "In cartesian coordinates, where $x$ is the propagation direction, the mode has field profile\n",
+ "\n",
+ "
16:42:01 EDT Created task 'HGM test' with task_id \n", + " 'fdve-cec2fdd6-bb37-4688-be8e-2fe5d141cd30' and task_type 'FDTD'. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m16:42:01 EDT\u001b[0m\u001b[2;36m \u001b[0mCreated task \u001b[32m'HGM test'\u001b[0m with task_id \n", + "\u001b[2;36m \u001b[0m\u001b[32m'fdve-cec2fdd6-bb37-4688-be8e-2fe5d141cd30'\u001b[0m and task_type \u001b[32m'FDTD'\u001b[0m. \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
View task using web UI at \n", + " 'https://tidy3d.simulation.cloud/workbench?taskId=fdve-cec2fdd6-bb3\n", + " 7-4688-be8e-2fe5d141cd30'. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0mView task using web UI at \n", + "\u001b[2;36m \u001b[0m\u001b]8;id=276143;https://tidy3d.simulation.cloud/workbench?taskId=fdve-cec2fdd6-bb37-4688-be8e-2fe5d141cd30\u001b\\\u001b[32m'https://tidy3d.simulation.cloud/workbench?\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=672000;https://tidy3d.simulation.cloud/workbench?taskId=fdve-cec2fdd6-bb37-4688-be8e-2fe5d141cd30\u001b\\\u001b[32mtaskId\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=276143;https://tidy3d.simulation.cloud/workbench?taskId=fdve-cec2fdd6-bb37-4688-be8e-2fe5d141cd30\u001b\\\u001b[32m=\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=210805;https://tidy3d.simulation.cloud/workbench?taskId=fdve-cec2fdd6-bb37-4688-be8e-2fe5d141cd30\u001b\\\u001b[32mfdve\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=276143;https://tidy3d.simulation.cloud/workbench?taskId=fdve-cec2fdd6-bb37-4688-be8e-2fe5d141cd30\u001b\\\u001b[32m-cec2fdd6-bb3\u001b[0m\u001b]8;;\u001b\\\n", + "\u001b[2;36m \u001b[0m\u001b]8;id=276143;https://tidy3d.simulation.cloud/workbench?taskId=fdve-cec2fdd6-bb37-4688-be8e-2fe5d141cd30\u001b\\\u001b[32m7-4688-be8e-2fe5d141cd30'\u001b[0m\u001b]8;;\u001b\\. \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Task folder: 'default'. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0mTask folder: \u001b]8;id=405008;https://tidy3d.simulation.cloud/folders/ee7143f0-3861-47de-ae8f-8f55df7232f1\u001b\\\u001b[32m'default'\u001b[0m\u001b]8;;\u001b\\. \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "43e426ca17fb4143991fdce94b96e69a", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n", + "\n" + ], + "text/plain": [ + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
16:42:05 EDT Maximum FlexCredit cost: 0.025. Minimum cost depends on task \n", + " execution details. Use 'web.real_cost(task_id)' to get the billed \n", + " FlexCredit cost after a simulation run. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m16:42:05 EDT\u001b[0m\u001b[2;36m \u001b[0mMaximum FlexCredit cost: \u001b[1;36m0.025\u001b[0m. Minimum cost depends on task \n", + "\u001b[2;36m \u001b[0mexecution details. Use \u001b[32m'web.real_cost\u001b[0m\u001b[32m(\u001b[0m\u001b[32mtask_id\u001b[0m\u001b[32m)\u001b[0m\u001b[32m'\u001b[0m to get the billed \n", + "\u001b[2;36m \u001b[0mFlexCredit cost after a simulation run. \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
16:42:06 EDT status = success \n",
+ "\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m16:42:06 EDT\u001b[0m\u001b[2;36m \u001b[0mstatus = success \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "07d747945c1d4fdbbe7f7a26aacd9fb8",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Output()"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n", + "\n" + ], + "text/plain": [ + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
16:42:07 EDT loading simulation from simulation_data.hdf5 \n",
+ "\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m16:42:07 EDT\u001b[0m\u001b[2;36m \u001b[0mloading simulation from simulation_data.hdf5 \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "hgm_sim_data = web.run(simulation=HGM_test_sim, task_name=\"HGM test\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "23e278a7-fe24-4b06-9b87-d0cab75b499a",
+ "metadata": {},
+ "source": [
+ "Display field in propagation direction:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "58e9385b-a077-4044-9cec-763236d28a51",
+ "metadata": {
+ "editable": true,
+ "slideshow": {
+ "slide_type": ""
+ },
+ "tags": []
+ },
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "1d6efaa1ea2c48aa83955629851d003c",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "interactive(children=(FloatSlider(value=0.05000000000000018, description='Ey', max=5.0, min=0.0500000000000001…"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import ipywidgets as widgets\n",
+ "\n",
+ "component = \"Ey\"\n",
+ "\n",
+ "field_slider = widgets.FloatSlider(\n",
+ " value=0,\n",
+ " min=field_monitor_xs[0],\n",
+ " max=field_monitor_xs[-1],\n",
+ " step=None,\n",
+ " description=component,\n",
+ " disabled=False,\n",
+ " continuous_update=True,\n",
+ " orientation=\"horizontal\",\n",
+ " readout=True,\n",
+ " readout_format=\".3f\",\n",
+ ")\n",
+ "\n",
+ "\n",
+ "def update_plot(x):\n",
+ " if x not in field_monitor_xs:\n",
+ " x = min(field_monitor_xs, key=lambda ll: abs(ll - x))\n",
+ " hgm_sim_data.plot_field(str(x), component, f=freq0)\n",
+ " plt.show()\n",
+ "\n",
+ "\n",
+ "widgets.interactive(update_plot, x=field_slider)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7211088d-c600-47aa-9ee3-67abb636a2b0",
+ "metadata": {},
+ "source": [
+ "## Laguerre-Gaussian source\n",
+ "\n",
+ "Here we show how to create an Orbital Angular Momentum (OAM) beam in Tidy3D using our [CustomFieldSource](https://docs.flexcompute.com/projects/tidy3d/en/latest/api/_autosummary/tidy3d.CustomFieldSource.html) object. We then validate the field profile change along the propagation direction.16:42:08 EDT Created task 'OAM test' with task_id \n", + " 'fdve-e94f138b-e65b-4759-9108-50be8b9aef30' and task_type 'FDTD'. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m16:42:08 EDT\u001b[0m\u001b[2;36m \u001b[0mCreated task \u001b[32m'OAM test'\u001b[0m with task_id \n", + "\u001b[2;36m \u001b[0m\u001b[32m'fdve-e94f138b-e65b-4759-9108-50be8b9aef30'\u001b[0m and task_type \u001b[32m'FDTD'\u001b[0m. \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
View task using web UI at \n", + " 'https://tidy3d.simulation.cloud/workbench?taskId=fdve-e94f138b-e65\n", + " b-4759-9108-50be8b9aef30'. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0mView task using web UI at \n", + "\u001b[2;36m \u001b[0m\u001b]8;id=943547;https://tidy3d.simulation.cloud/workbench?taskId=fdve-e94f138b-e65b-4759-9108-50be8b9aef30\u001b\\\u001b[32m'https://tidy3d.simulation.cloud/workbench?\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=890386;https://tidy3d.simulation.cloud/workbench?taskId=fdve-e94f138b-e65b-4759-9108-50be8b9aef30\u001b\\\u001b[32mtaskId\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=943547;https://tidy3d.simulation.cloud/workbench?taskId=fdve-e94f138b-e65b-4759-9108-50be8b9aef30\u001b\\\u001b[32m=\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=13105;https://tidy3d.simulation.cloud/workbench?taskId=fdve-e94f138b-e65b-4759-9108-50be8b9aef30\u001b\\\u001b[32mfdve\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=943547;https://tidy3d.simulation.cloud/workbench?taskId=fdve-e94f138b-e65b-4759-9108-50be8b9aef30\u001b\\\u001b[32m-e94f138b-e65\u001b[0m\u001b]8;;\u001b\\\n", + "\u001b[2;36m \u001b[0m\u001b]8;id=943547;https://tidy3d.simulation.cloud/workbench?taskId=fdve-e94f138b-e65b-4759-9108-50be8b9aef30\u001b\\\u001b[32mb-4759-9108-50be8b9aef30'\u001b[0m\u001b]8;;\u001b\\. \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Task folder: 'default'. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0mTask folder: \u001b]8;id=421943;https://tidy3d.simulation.cloud/folders/ee7143f0-3861-47de-ae8f-8f55df7232f1\u001b\\\u001b[32m'default'\u001b[0m\u001b]8;;\u001b\\. \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d0b9f4948dc84d9b947e8b6d0256dec6", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n", + "\n" + ], + "text/plain": [ + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
16:42:10 EDT Maximum FlexCredit cost: 0.025. Minimum cost depends on task \n", + " execution details. Use 'web.real_cost(task_id)' to get the billed \n", + " FlexCredit cost after a simulation run. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m16:42:10 EDT\u001b[0m\u001b[2;36m \u001b[0mMaximum FlexCredit cost: \u001b[1;36m0.025\u001b[0m. Minimum cost depends on task \n", + "\u001b[2;36m \u001b[0mexecution details. Use \u001b[32m'web.real_cost\u001b[0m\u001b[32m(\u001b[0m\u001b[32mtask_id\u001b[0m\u001b[32m)\u001b[0m\u001b[32m'\u001b[0m to get the billed \n", + "\u001b[2;36m \u001b[0mFlexCredit cost after a simulation run. \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
16:42:11 EDT status = success \n",
+ "\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m16:42:11 EDT\u001b[0m\u001b[2;36m \u001b[0mstatus = success \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "4b5cf604668f48b380e3eb0d284768c8",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Output()"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n", + "\n" + ], + "text/plain": [ + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
16:42:12 EDT loading simulation from simulation_data.hdf5 \n",
+ "\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m16:42:12 EDT\u001b[0m\u001b[2;36m \u001b[0mloading simulation from simulation_data.hdf5 \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "oam_sim_data = web.run(simulation=OAM_test_sim, task_name=\"OAM test\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a704cc24-2d21-4638-ad86-bc5e87a562e0",
+ "metadata": {},
+ "source": [
+ "Display field in propagation direction:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "23c71226-2795-4e70-9555-7c240f51966b",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "c1ccdcab2c494289beca5b600ed322e3",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "interactive(children=(FloatSlider(value=0.05000000000000018, description='E', max=5.0, min=0.05000000000000018…"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import ipywidgets as widgets\n",
+ "\n",
+ "component = \"E\"\n",
+ "\n",
+ "field_slider = widgets.FloatSlider(\n",
+ " value=0,\n",
+ " min=field_monitor_xs[0],\n",
+ " max=field_monitor_xs[-1],\n",
+ " step=None,\n",
+ " description=component,\n",
+ " disabled=False,\n",
+ " continuous_update=True,\n",
+ " orientation=\"horizontal\",\n",
+ " readout=True,\n",
+ " readout_format=\".3f\",\n",
+ ")\n",
+ "\n",
+ "\n",
+ "def update_plot(x):\n",
+ " if x not in field_monitor_xs:\n",
+ " x = min(field_monitor_xs, key=lambda ll: abs(ll - x))\n",
+ " oam_sim_data.plot_field(str(x), component, f=freq0, val=\"abs^2\")\n",
+ " plt.show()\n",
+ "\n",
+ "\n",
+ "widgets.interactive(update_plot, x=field_slider)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "96eb9edb-7266-466a-b858-ad24566ad4df",
+ "metadata": {},
+ "source": [
+ "## Bessel beam source\n",
+ "\n",
+ "Here we show how to create an Bessel beam in Tidy3D using our [CustomFieldSource](https://docs.flexcompute.com/projects/tidy3d/en/latest/api/_autosummary/tidy3d.CustomFieldSource.html) object. We then validate the field amplitude change along the propagation direction.16:42:13 EDT Created task 'Bessel test' with task_id \n", + " 'fdve-61433498-7c0d-4f97-8a04-b2c5b6d9d5b3' and task_type 'FDTD'. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m16:42:13 EDT\u001b[0m\u001b[2;36m \u001b[0mCreated task \u001b[32m'Bessel test'\u001b[0m with task_id \n", + "\u001b[2;36m \u001b[0m\u001b[32m'fdve-61433498-7c0d-4f97-8a04-b2c5b6d9d5b3'\u001b[0m and task_type \u001b[32m'FDTD'\u001b[0m. \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
View task using web UI at \n", + " 'https://tidy3d.simulation.cloud/workbench?taskId=fdve-61433498-7c0\n", + " d-4f97-8a04-b2c5b6d9d5b3'. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0mView task using web UI at \n", + "\u001b[2;36m \u001b[0m\u001b]8;id=408566;https://tidy3d.simulation.cloud/workbench?taskId=fdve-61433498-7c0d-4f97-8a04-b2c5b6d9d5b3\u001b\\\u001b[32m'https://tidy3d.simulation.cloud/workbench?\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=426938;https://tidy3d.simulation.cloud/workbench?taskId=fdve-61433498-7c0d-4f97-8a04-b2c5b6d9d5b3\u001b\\\u001b[32mtaskId\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=408566;https://tidy3d.simulation.cloud/workbench?taskId=fdve-61433498-7c0d-4f97-8a04-b2c5b6d9d5b3\u001b\\\u001b[32m=\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=610512;https://tidy3d.simulation.cloud/workbench?taskId=fdve-61433498-7c0d-4f97-8a04-b2c5b6d9d5b3\u001b\\\u001b[32mfdve\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=408566;https://tidy3d.simulation.cloud/workbench?taskId=fdve-61433498-7c0d-4f97-8a04-b2c5b6d9d5b3\u001b\\\u001b[32m-61433498-7c0\u001b[0m\u001b]8;;\u001b\\\n", + "\u001b[2;36m \u001b[0m\u001b]8;id=408566;https://tidy3d.simulation.cloud/workbench?taskId=fdve-61433498-7c0d-4f97-8a04-b2c5b6d9d5b3\u001b\\\u001b[32md-4f97-8a04-b2c5b6d9d5b3'\u001b[0m\u001b]8;;\u001b\\. \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Task folder: 'default'. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0mTask folder: \u001b]8;id=509299;https://tidy3d.simulation.cloud/folders/ee7143f0-3861-47de-ae8f-8f55df7232f1\u001b\\\u001b[32m'default'\u001b[0m\u001b]8;;\u001b\\. \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b22604121f374ac19a8c6ada66273cbc", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n", + "\n" + ], + "text/plain": [ + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
16:42:15 EDT Maximum FlexCredit cost: 0.025. Minimum cost depends on task \n", + " execution details. Use 'web.real_cost(task_id)' to get the billed \n", + " FlexCredit cost after a simulation run. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m16:42:15 EDT\u001b[0m\u001b[2;36m \u001b[0mMaximum FlexCredit cost: \u001b[1;36m0.025\u001b[0m. Minimum cost depends on task \n", + "\u001b[2;36m \u001b[0mexecution details. Use \u001b[32m'web.real_cost\u001b[0m\u001b[32m(\u001b[0m\u001b[32mtask_id\u001b[0m\u001b[32m)\u001b[0m\u001b[32m'\u001b[0m to get the billed \n", + "\u001b[2;36m \u001b[0mFlexCredit cost after a simulation run. \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
16:42:16 EDT status = success \n",
+ "\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m16:42:16 EDT\u001b[0m\u001b[2;36m \u001b[0mstatus = success \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "662ca8877d1842b690c558fbed0cd9d0",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Output()"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n", + "\n" + ], + "text/plain": [ + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
16:42:17 EDT loading simulation from simulation_data.hdf5 \n",
+ "\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m16:42:17 EDT\u001b[0m\u001b[2;36m \u001b[0mloading simulation from simulation_data.hdf5 \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "bessel_sim_data = web.run(simulation=Bessel_test_sim, task_name=\"Bessel test\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3867781d-4279-4422-915e-cfbe9a9eeb6a",
+ "metadata": {},
+ "source": [
+ "Display field amplitude in propagation direction:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "id": "8e2f90a0-cf5d-42c5-a053-4bfc08c6c3d5",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "f9e45307f48444ba880bc20372fb3902",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "interactive(children=(FloatSlider(value=0.05000000000000018, description='E', max=5.0, min=0.05000000000000018…"
+ ]
+ },
+ "execution_count": 16,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import ipywidgets as widgets\n",
+ "\n",
+ "component = \"E\"\n",
+ "\n",
+ "field_slider = widgets.FloatSlider(\n",
+ " value=0,\n",
+ " min=field_monitor_xs[0],\n",
+ " max=field_monitor_xs[-1],\n",
+ " step=None,\n",
+ " description=component,\n",
+ " disabled=False,\n",
+ " continuous_update=True,\n",
+ " orientation=\"horizontal\",\n",
+ " readout=True,\n",
+ " readout_format=\".3f\",\n",
+ ")\n",
+ "\n",
+ "\n",
+ "def update_plot(x):\n",
+ " if x not in field_monitor_xs:\n",
+ " x = min(field_monitor_xs, key=lambda ll: abs(ll - x))\n",
+ " bessel_sim_data.plot_field(str(x), component, val=\"abs\", f=freq0)\n",
+ " plt.show()\n",
+ "\n",
+ "\n",
+ "widgets.interactive(update_plot, x=field_slider)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "83f68037-14d4-44d9-8878-0471febe3428",
+ "metadata": {},
+ "source": [
+ "## Hyper-geometric Gaussian source\n",
+ "\n",
+ "Here we show how to create a Hyper-geometric Gaussian (HGG) beam in Tidy3D using our [CustomFieldSource](https://docs.flexcompute.com/projects/tidy3d/en/latest/api/_autosummary/tidy3d.CustomFieldSource.html) object. We then validate the field profile change along the propagation direction.16:42:18 EDT Created task 'HGG test' with task_id \n", + " 'fdve-e32c350e-4dcf-480a-9665-38865b9cda11' and task_type 'FDTD'. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m16:42:18 EDT\u001b[0m\u001b[2;36m \u001b[0mCreated task \u001b[32m'HGG test'\u001b[0m with task_id \n", + "\u001b[2;36m \u001b[0m\u001b[32m'fdve-e32c350e-4dcf-480a-9665-38865b9cda11'\u001b[0m and task_type \u001b[32m'FDTD'\u001b[0m. \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
View task using web UI at \n", + " 'https://tidy3d.simulation.cloud/workbench?taskId=fdve-e32c350e-4dc\n", + " f-480a-9665-38865b9cda11'. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0mView task using web UI at \n", + "\u001b[2;36m \u001b[0m\u001b]8;id=62986;https://tidy3d.simulation.cloud/workbench?taskId=fdve-e32c350e-4dcf-480a-9665-38865b9cda11\u001b\\\u001b[32m'https://tidy3d.simulation.cloud/workbench?\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=894741;https://tidy3d.simulation.cloud/workbench?taskId=fdve-e32c350e-4dcf-480a-9665-38865b9cda11\u001b\\\u001b[32mtaskId\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=62986;https://tidy3d.simulation.cloud/workbench?taskId=fdve-e32c350e-4dcf-480a-9665-38865b9cda11\u001b\\\u001b[32m=\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=322785;https://tidy3d.simulation.cloud/workbench?taskId=fdve-e32c350e-4dcf-480a-9665-38865b9cda11\u001b\\\u001b[32mfdve\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=62986;https://tidy3d.simulation.cloud/workbench?taskId=fdve-e32c350e-4dcf-480a-9665-38865b9cda11\u001b\\\u001b[32m-e32c350e-4dc\u001b[0m\u001b]8;;\u001b\\\n", + "\u001b[2;36m \u001b[0m\u001b]8;id=62986;https://tidy3d.simulation.cloud/workbench?taskId=fdve-e32c350e-4dcf-480a-9665-38865b9cda11\u001b\\\u001b[32mf-480a-9665-38865b9cda11'\u001b[0m\u001b]8;;\u001b\\. \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Task folder: 'default'. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0mTask folder: \u001b]8;id=234063;https://tidy3d.simulation.cloud/folders/ee7143f0-3861-47de-ae8f-8f55df7232f1\u001b\\\u001b[32m'default'\u001b[0m\u001b]8;;\u001b\\. \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "546ccc90437045bb81c7a373e20aa2d6", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n", + "\n" + ], + "text/plain": [ + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
16:42:20 EDT Maximum FlexCredit cost: 0.025. Minimum cost depends on task \n", + " execution details. Use 'web.real_cost(task_id)' to get the billed \n", + " FlexCredit cost after a simulation run. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m16:42:20 EDT\u001b[0m\u001b[2;36m \u001b[0mMaximum FlexCredit cost: \u001b[1;36m0.025\u001b[0m. Minimum cost depends on task \n", + "\u001b[2;36m \u001b[0mexecution details. Use \u001b[32m'web.real_cost\u001b[0m\u001b[32m(\u001b[0m\u001b[32mtask_id\u001b[0m\u001b[32m)\u001b[0m\u001b[32m'\u001b[0m to get the billed \n", + "\u001b[2;36m \u001b[0mFlexCredit cost after a simulation run. \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
16:42:21 EDT status = queued \n",
+ "\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m16:42:21 EDT\u001b[0m\u001b[2;36m \u001b[0mstatus = queued \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "To cancel the simulation, use 'web.abort(task_id)' or \n", + " 'web.delete(task_id)' or abort/delete the task in the web UI. \n", + " Terminating the Python script will not stop the job running on the \n", + " cloud. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0mTo cancel the simulation, use \u001b[32m'web.abort\u001b[0m\u001b[32m(\u001b[0m\u001b[32mtask_id\u001b[0m\u001b[32m)\u001b[0m\u001b[32m'\u001b[0m or \n", + "\u001b[2;36m \u001b[0m\u001b[32m'web.delete\u001b[0m\u001b[32m(\u001b[0m\u001b[32mtask_id\u001b[0m\u001b[32m)\u001b[0m\u001b[32m'\u001b[0m or abort/delete the task in the web UI. \n", + "\u001b[2;36m \u001b[0mTerminating the Python script will not stop the job running on the \n", + "\u001b[2;36m \u001b[0mcloud. \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "30f9462ceee9414493f4130680656acf", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
16:42:30 EDT starting up solver \n",
+ "\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m16:42:30 EDT\u001b[0m\u001b[2;36m \u001b[0mstarting up solver \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " running solver \n",
+ "\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0mrunning solver \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "46424f9850814e8aaf6c468e55943e59",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Output()"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "16:42:32 EDT early shutoff detected at 92%, exiting. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m16:42:32 EDT\u001b[0m\u001b[2;36m \u001b[0mearly shutoff detected at \u001b[1;36m92\u001b[0m%, exiting. \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n", + "\n" + ], + "text/plain": [ + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
status = postprocess \n",
+ "\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0mstatus = postprocess \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "c4b25fe24b154abc953a8740aed7e36f",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Output()"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "16:42:40 EDT status = success \n",
+ "\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m16:42:40 EDT\u001b[0m\u001b[2;36m \u001b[0mstatus = success \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "16:42:42 EDT View simulation result at \n", + " 'https://tidy3d.simulation.cloud/workbench?taskId=fdve-e32c350e-4dc\n", + " f-480a-9665-38865b9cda11'. \n", + "\n" + ], + "text/plain": [ + "\u001b[2;36m16:42:42 EDT\u001b[0m\u001b[2;36m \u001b[0mView simulation result at \n", + "\u001b[2;36m \u001b[0m\u001b]8;id=707453;https://tidy3d.simulation.cloud/workbench?taskId=fdve-e32c350e-4dcf-480a-9665-38865b9cda11\u001b\\\u001b[4;34m'https://tidy3d.simulation.cloud/workbench?\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=518924;https://tidy3d.simulation.cloud/workbench?taskId=fdve-e32c350e-4dcf-480a-9665-38865b9cda11\u001b\\\u001b[4;34mtaskId\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=707453;https://tidy3d.simulation.cloud/workbench?taskId=fdve-e32c350e-4dcf-480a-9665-38865b9cda11\u001b\\\u001b[4;34m=\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=745755;https://tidy3d.simulation.cloud/workbench?taskId=fdve-e32c350e-4dcf-480a-9665-38865b9cda11\u001b\\\u001b[4;34mfdve\u001b[0m\u001b]8;;\u001b\\\u001b]8;id=707453;https://tidy3d.simulation.cloud/workbench?taskId=fdve-e32c350e-4dcf-480a-9665-38865b9cda11\u001b\\\u001b[4;34m-e32c350e-4dc\u001b[0m\u001b]8;;\u001b\\\n", + "\u001b[2;36m \u001b[0m\u001b]8;id=707453;https://tidy3d.simulation.cloud/workbench?taskId=fdve-e32c350e-4dcf-480a-9665-38865b9cda11\u001b\\\u001b[4;34mf-480a-9665-38865b9cda11'\u001b[0m\u001b]8;;\u001b\\\u001b[4;34m.\u001b[0m \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "ed75d43054124131b48f3322dc9a1d6a", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n", + "\n" + ], + "text/plain": [ + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
16:42:51 EDT loading simulation from simulation_data.hdf5 \n",
+ "\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m16:42:51 EDT\u001b[0m\u001b[2;36m \u001b[0mloading simulation from simulation_data.hdf5 \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "hgg_sim_data = web.run(simulation=HGG_test_sim, task_name=\"HGG test\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "40b05fb4-59ac-447b-8b47-d1999861c568",
+ "metadata": {},
+ "source": [
+ "Display field in propagation direction:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "id": "496022b9-fc6b-4560-a34f-40697f7d49f5",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "92341339c3d64cca8fc6cf0f43df4854",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "interactive(children=(FloatSlider(value=0.05000000000000018, description='Ey', max=5.0, min=0.0500000000000001…"
+ ]
+ },
+ "execution_count": 21,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import ipywidgets as widgets\n",
+ "\n",
+ "component = \"Ey\"\n",
+ "\n",
+ "field_slider = widgets.FloatSlider(\n",
+ " value=0,\n",
+ " min=field_monitor_xs[0],\n",
+ " max=field_monitor_xs[-1],\n",
+ " step=None,\n",
+ " description=component,\n",
+ " disabled=False,\n",
+ " continuous_update=True,\n",
+ " orientation=\"horizontal\",\n",
+ " readout=True,\n",
+ " readout_format=\".3f\",\n",
+ ")\n",
+ "\n",
+ "\n",
+ "def update_plot(x):\n",
+ " if x not in field_monitor_xs:\n",
+ " x = min(field_monitor_xs, key=lambda ll: abs(ll - x))\n",
+ " hgg_sim_data.plot_field(str(x), component, f=freq0)\n",
+ " plt.show()\n",
+ "\n",
+ "\n",
+ "widgets.interactive(update_plot, x=field_slider)"
+ ]
+ }
+ ],
+ "metadata": {
+ "description": "This notebook creates advanced gaussian beams that can be used by the interested user. In order to make these custom sources easy to use in multiple settings, we use Tidy3D's open-source BeamProfile object to build these sources. This also demonstrates how to take advantage of Tidy3D's open-source nature to save much complication.",
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "keywords": "gaussian, source, field, open-source, angular, hyper-geometric, bessel, hermite",
+ "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.8"
+ },
+ "title": "Creating advanced Gaussian sources using Tidy3D's open-source BeamProfile object"
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/features/sources.rst b/docs/features/sources.rst
index b5c4d298..f76c7332 100644
--- a/docs/features/sources.rst
+++ b/docs/features/sources.rst
@@ -12,3 +12,4 @@ Sources are a fundamental component for input power in electromagnetic simulatio
../../TFSF
../../CustomFieldSource
../../BroadbandPlaneWaveWithConstantObliqueIncidentAngle
+ ../../AdvancedGaussianSources