Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/source/tutorials/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ Additionally, a set of static (automatically tested) examples can be found below
1d_temporal_laser.ipynb
2d_spatial_laser.ipynb
nonlinear_propagation_split_step.ipynb
user_defined_longitudinal_profile.ipynb
collins_propagator.ipynb
168 changes: 168 additions & 0 deletions docs/source/tutorials/user_defined_longitudinal_profile.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "e1ed0812-0917-4bb6-b872-3fda185ceb7c",
"metadata": {},
"source": [
"# Laser Pulse with user-defined longitudinal profile\n",
"\n",
"In this example we show how to define a custom longitudinal profile based on an analytical expression (in this case a \"flat-top\" profile that rises smoothly from zero to one as a squared cosine, stays constant for some time, and then goes smoothly to zero as a squared cosine)."
]
},
{
"cell_type": "markdown",
"id": "f6a4ee6a-1135-412a-9317-1f5dd3edcb66",
"metadata": {},
"source": [
"## Define a derived class of LongitudinalProfile: MyOwnLongitudinalProfile\n",
"First, we define a new class `MyOwnLongitudinalProfile`, inheriting the `LongitudinalProfile` class. We need to implement the `__init__` method to record the parameters of the custom profile, and the `evaluate` method that should return the envelope as a function of the time."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cb439136-ebc4-4c90-a363-322b224120d0",
"metadata": {},
"outputs": [],
"source": [
"from lasy.profiles.longitudinal import LongitudinalProfile\n",
"\n",
"\n",
"# User-defined profile\n",
"class MyOwnLongitudinalProfile(LongitudinalProfile):\n",
" r\"\"\"\n",
" Derived class for the analytic longitudinal flat-top profile of a laser pulse.\n",
"\n",
" Derived class for the analytic longitudinal flat-top profile of a laser pulse,\n",
" i.e., a longitudinal profile that rises smoothly from zero to one (as a squared cosine),\n",
" stays constant for some time and then goes down smoothly to zero (as a squared cosine).\n",
"\n",
" Parameters\n",
" ----------\n",
" wavelength : float (in meter)\n",
" The main laser wavelength :math:`\\lambda_0` of the laser.\n",
" t_start : float (in seconds)\n",
" The starting time of the pulse,\n",
" t_rise : float (in seconds)\n",
" The rise time of the pulse envelope,\n",
" t_flat : float (in seconds)\n",
" The duration of the flat part of the pulse envelope,\n",
" t_down : float (in seconds)\n",
" The duration of the decreasing part of the pulse envelope,\n",
" cep_phase : float (in radian), optional\n",
" The Carrier Enveloppe Phase (CEP)\n",
"\n",
" \"\"\"\n",
"\n",
" def __init__(self, wavelength, t_start, t_rise, t_flat, t_down, cep_phase):\n",
" super().__init__(wavelength)\n",
" self.t_start = t_start\n",
" self.t_rise = t_rise\n",
" self.t_flat = t_flat\n",
" self.t_down = t_down\n",
" self.cep_phase = cep_phase\n",
"\n",
" def evaluate(self, t):\n",
" \"\"\"\n",
" Return the longitudinal envelope.\n",
"\n",
" Parameters\n",
" ----------\n",
" t : ndarrays of floats\n",
" Define points on which to evaluate the envelope\n",
"\n",
" Returns\n",
" -------\n",
" envelope : ndarray of complex numbers\n",
" Contains the value of the longitudinal envelope at the\n",
" specified points. This array has the same shape as the array t.\n",
" \"\"\"\n",
" t1 = self.t_start\n",
" t2 = t1 + self.t_rise\n",
" t3 = t2 + self.t_flat\n",
" t4 = t3 + self.t_down\n",
" tcep = 0.5 * (t3 + t2)\n",
"\n",
" envelope = (\n",
" (t >= t1) * (t < t2) * np.cos(0.5 * np.pi * (t - t2) / (t2 - t1)) ** 2\n",
" + (t >= t2) * (t < t3)\n",
" + (t >= t3) * (t < t4) * np.cos(0.5 * np.pi * (t - t3) / (t3 - t4)) ** 2\n",
" ) * np.exp(+1.0j * (self.cep_phase + self.omega0 * tcep))\n",
"\n",
" return envelope"
]
},
{
"cell_type": "markdown",
"id": "dace1e17-5f9a-4a8b-b424-f6c26badc706",
"metadata": {},
"source": [
"## Use MyOwnLongitudinalProfile as a regular longitudinal profile\n",
"The new class `MyOwnLongitudinalProfile` can be used just like any other longitudinal profile"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5d1fb72e-b052-4ab0-95de-af974bc7fe54",
"metadata": {},
"outputs": [],
"source": [
"wavelength = 800e-6\n",
"t_start = 0\n",
"t_rise = 20e-15\n",
"t_flat = 20e-15\n",
"t_down = 10e-15\n",
"cep_phase = 0\n",
"longitudinal_profile = MyOwnLongitudinalProfile(\n",
" wavelength, t_start, t_rise, t_flat, t_down, cep_phase\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "38f2ee28-2d60-488d-8e42-7f3444e41e93",
"metadata": {},
"outputs": [],
"source": [
"# test the custom longitudinal profile\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"\n",
"times = np.linspace(0.0, 55e-15, 300)\n",
"plt.plot(times, np.abs(longitudinal_profile.evaluate(times)))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "60f9d7b6-dd76-4041-9edf-aec39132646f",
"metadata": {},
"outputs": [],
"source": []
}
],
"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.13.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading