{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Laser Pulse in Time Only (numpy only)\n", "\n", "In this example we look at the special case where one is only interested in defining and manipulating the temporal profile of the laser pulse. In this case, having a full 3D or quasi-3D profile is an inefficient use of resources. For this purpose, we have defined the transverse laser profile `PlaneWaveProfile` which allows one to treat the transverse profile as a 1 pixel plane wave.\n", "\n", "This tutorial assumes that CuPy is not installed so that it will not run on GPU and the NumPy backend will be used. This allows us to use `import numpy as np` instead of `from lasy.backend import xp` and work with the output from LASY directly without copying it to the CPU explicitly for plotting." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Generate a Gaussian Profile in Time with a Plane Wave Transverse Profile\n", "\n", "One key difference you might notice to the traditional definition of the laser pulse is that we do not use the laser energy to scale the amplitude of the electric field, but in this case we use the peak power of the laser pulse" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "from scipy.constants import c\n", "\n", "from lasy.laser import Laser\n", "from lasy.profiles import CombinedLongitudinalTransverseProfile\n", "from lasy.profiles.longitudinal import GaussianLongitudinalProfile\n", "from lasy.profiles.transverse import PlaneWaveProfile\n", "from lasy.utils.laser_utils import get_duration, get_laser_fluence, get_laser_power\n", "\n", "# Physical Parameters\n", "tau = 30e-15\n", "wavelength = 800e-9\n", "t_peak = 0.0\n", "pol = (1, 0)\n", "peak_power = 1e12 # W\n", "\n", "long_prof = GaussianLongitudinalProfile(wavelength, tau, t_peak)\n", "tran_prof = PlaneWaveProfile()\n", "profile = CombinedLongitudinalTransverseProfile(\n", " wavelength, pol, long_prof, tran_prof, peak_power=peak_power\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Define the Computational Grid\n", "\n", "Here we should note the the `lo` and `hi` variables have been passed as `None` for the transverse axes as it is a plane wave. Additionally, the number of points along the transverse dimensions is 1 in each direction." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Computational Grid\n", "dim = \"xyt\"\n", "lo = (None, None, -5 * tau)\n", "hi = (None, None, 5 * tau)\n", "npoints = (1, 1, 1000)\n", "\n", "laser = Laser(dim, lo, hi, npoints, profile)\n", "\n", "laser.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Visualizing and Analyzing the Pulse\n", "\n", "We see that the standard `laser.show()` command works here and we indeed get a plane wave.\n", "\n", "One can also extract the laser power and use this to visualize the pule." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "power = get_laser_power(laser.dim, laser.grid)\n", "\n", "plt.figure()\n", "plt.plot(laser.grid.axes[-1] * 1e15, power / 1e12)\n", "plt.xlim(laser.grid.axes[-1][0] * 1e15, laser.grid.axes[-1][-1] * 1e15)\n", "plt.ylim(0, None)\n", "plt.xlabel(\"Time (fs)\")\n", "plt.ylabel(\"Instantaneous Power (TW)\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Adding Optics\n", "\n", "Optics can be added in the usual way to manipulate the laser pulse.\n", "Additionally, standard `laser_utils` functions work out of the box\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tau0_meas = get_duration(laser.grid, laser.dim)\n", "fluence0_meas = get_laser_fluence(laser.grid)\n", "\n", "from lasy.optical_elements import PolynomialSpectralPhase\n", "\n", "omega0 = 2 * np.pi * c / wavelength\n", "gdd = 500e-30\n", "tod = 15000e-45\n", "dazzler = PolynomialSpectralPhase(omega0, gdd=gdd, tod=tod)\n", "\n", "laser.apply_optics(dazzler)\n", "\n", "tau1_meas = get_duration(laser.grid, laser.dim)\n", "fluence1_meas = get_laser_fluence(laser.grid)\n", "\n", "\n", "print(\"Initial Pulse Duration = %.2f fs\" % (tau0_meas * 1e15))\n", "print(\"Final Pulse Duration = %.2f fs\" % (tau1_meas * 1e15))\n", "print(\"Initial Pulse Fluence = %.2e mJ/cm2\" % (fluence0_meas / 10))\n", "print(\"Final Pulse Fluence = %.2e mJ/cm2\" % (fluence1_meas / 10))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "power1 = get_laser_power(laser.dim, laser.grid)\n", "\n", "plt.figure()\n", "plt.plot(laser.grid.axes[-1] * 1e15, power / 1e12, label=\"Initial Laser\")\n", "plt.plot(laser.grid.axes[-1] * 1e15, power1 / 1e12, label=\"Final Laser\")\n", "plt.xlim(laser.grid.axes[-1][0] * 1e15, laser.grid.axes[-1][-1] * 1e15)\n", "plt.ylim(\n", " 0,\n", ")\n", "plt.xlabel(\"Time (fs)\")\n", "plt.ylabel(\"Instantaneous Power (TW)\")\n", "plt.legend()" ] } ], "metadata": { "kernelspec": { "display_name": "splice2025", "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.9" } }, "nbformat": 4, "nbformat_minor": 2 }