Skip to content
Merged
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
119 changes: 26 additions & 93 deletions lib/python/picongpu/picmi/lasers/dispersive_pulse_laser.py
Original file line number Diff line number Diff line change
@@ -1,133 +1,66 @@
"""
This file is part of PIConGPU.
Copyright 2025 PIConGPU contributors
Authors: Julian Lenz
Authors: Julian Lenz, Masoud Afshari
License: GPLv3+
"""

import math
import typing

import typeguard

from ...pypicongpu import laser
from ..copy_attributes import default_converts_to
from .base_laser import BaseLaser
from .polarization_type import PolarizationType
from .gaussian_laser import GaussianLaser # inherit standard Gaussian laser fields


@default_converts_to(laser.DispersivePulseLaser)
@typeguard.typechecked
class DispersivePulseLaser(BaseLaser):
class DispersivePulseLaser(GaussianLaser):
"""
Specifies a dispersive Gaussian pulse with dispersion parameters

Parameters
----------
wavelength: float
Laser wavelength [m], defined as :math:`\\lambda_0` in the above formula

duration: float
Duration of the Gaussian pulse [s], defined as :math:`\\tau` in the above formula

propagation_direction: unit vector of length 3 of floats
Direction of propagation [1]
PICMI Dispersive Pulse Laser.

polarization_direction: unit vector of length 3 of floats
Direction of polarization [1]
Extends `GaussianLaser` class with additional dispersion-specific parameters used in PIConGPU.

focal_position: vector of length 3 of floats
Position of the laser focus [m]
All standard Gaussian laser fields are inherited. please refer to class:`GaussianLaser`

centroid_position: vector of length 3 of floats
Position of the laser centroid at time 0 [m]
Additional dispersive parameters (PIConGPU-specific):

a0: float
Normalized vector potential at focus
Specify either a0 or E0 (E0 takes precedence).
- picongpu_spectral_support : float, default=6.0
Width of spectral support (dimensionless).

E0: float
Maximum amplitude of the laser field [V/m]
Specify either a0 or E0 (E0 takes precedence).
- picongpu_sd_si : float, default=0.0
Spatial dispersion coefficient [m*s].

phi0: float
Carrier envelope phase (CEP) [rad]
- picongpu_ad_si : float, default=0.0
Angular dispersion coefficient [rad*s].

spectral_support: float
Width of the spectral support for the discrete Fourier transform [none]
- picongpu_gdd_si : float, default=0.0
Group delay dispersion (GDD) [s^2].

sd_si: float
Spatial dispersion in focus [m*s]

ad_si: float
Angular dispersion in focus [rad*s]

gdd_si: float
Group velocity dispersion in focus [s^2]

tod_si: float
Third order dispersion in focus [s^3]
- picongpu_tod_si : float, default=0.0
Third-order dispersion (TOD) [s^3].
"""

def __init__(
self,
waist,
wavelength,
duration,
propagation_direction,
polarization_direction,
focal_position,
centroid_position,
a0=None,
E0=None,
phi0: float = 0.0,
picongpu_polarization_type=(PolarizationType.LINEAR),
picongpu_spectral_support: float = 6.0,
picongpu_sd_si: float = 0.0,
picongpu_ad_si: float = 0.0,
picongpu_gdd_si: float = 0.0,
picongpu_tod_si: float = 0.0,
# make sure to always place Huygens-surface inside PML-boundaries,
# default is valid for standard PMLs
# @todo create check for insufficient dimension
# @todo create check in simulation for conflict between PMLs and
# Huygens-surfaces
picongpu_huygens_surface_positions: typing.List[typing.List[int]] = [
[16, -16],
[16, -16],
[16, -16],
],
**kw, # all standard GaussianLaser arguments
):
if waist <= 0:
raise ValueError(f"waist must be > 0. You gave {waist=}.")
if wavelength <= 0:
raise ValueError(f"wavelength must be > 0. You gave {wavelength=}.")
if duration <= 0:
raise ValueError(f"laser pulse duration must be > 0. You gave {duration=}.")
# Forbid Laguerre modes and phases
if "picongpu_laguerre_modes" in kw and kw["picongpu_laguerre_modes"] is not None:
raise ValueError("DispersivePulseLaser does not support Laguerre modes.")
if "picongpu_laguerre_phases" in kw and kw["picongpu_laguerre_phases"] is not None:
raise ValueError("DispersivePulseLaser does not support Laguerre phases.")

self.waist = waist
self.wavelength = wavelength
self.k0 = 2.0 * math.pi / wavelength
self.duration = duration
self.focal_position = focal_position
self.centroid_position = centroid_position
self.propagation_direction = propagation_direction
self.polarization_direction = polarization_direction
self.a0, self.E0 = self._compute_E0_and_a0(self.k0, E0, a0)
self.phi0 = phi0
# Initialize standard Gaussian laser fields
super().__init__(**kw)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is the case handled with Laguerre modes?
It looks like that this code just takes them (as they are part of GaussianLaser), but will not treat them correctly in pypicongpu. I think this is not a valid solution.

Issue with:

  • picongpu_laguerre_modes
  • picongpu_laguerre_phases

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@steindev, you, as the ultimate authority on lasers 😜, what is your opinion?


self.picongpu_polarization_type = picongpu_polarization_type
# Store dispersive extensions
self.picongpu_spectral_support = picongpu_spectral_support
self.picongpu_sd_si = picongpu_sd_si
self.picongpu_ad_si = picongpu_ad_si
self.picongpu_gdd_si = picongpu_gdd_si
self.picongpu_tod_si = picongpu_tod_si
self.picongpu_huygens_surface_positions = picongpu_huygens_surface_positions
self._validate_common_properties()
self.pulse_init = self._compute_pulse_init()

def check(self):
self._validate_common_properties()
assert self._propagation_connects_centroid_and_focus(), (
"propagation_direction must connect centroid_position and focus_position"
)
53 changes: 51 additions & 2 deletions lib/python/picongpu/picmi/lasers/gaussian_laser.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""
This file is part of PIConGPU.
Copyright 2021-2024 PIConGPU contributors
Authors: Hannes Troepgen, Brian Edward Marre, Alexander Debus, Richard Pausch
Authors: Hannes Troepgen, Brian Edward Marre, Alexander Debus, Richard Pausch,
Masoud Afshari
License: GPLv3+
"""

Expand All @@ -20,7 +21,55 @@
@default_converts_to(laser.GaussianLaser)
@typeguard.typechecked
class GaussianLaser(picmistandard.PICMI_GaussianLaser, BaseLaser):
"""PICMI object for Gaussian Laser"""
"""
PICMI object for Gaussian Laser.

Standard Gaussian laser pulse parameters are:

- wavelength : float
Central wavelength of the laser [m].

- waist : float
Spot size (1/e^2 radius) of the laser at focus [m].

- duration : float
Full-width-half-maximum (FWHM) duration of the pulse [s].

- propagation_direction : list[float]
Normalized vector of propagation direction.

- polarization_direction : list[float]
Normalized vector of polarization direction.

- focal_position : list[float]
3D coordinates of the laser focus [m].

- centroid_position : list[float]
3D coordinates of the laser centroid [m].

- a0 : float, optional
Normalized vector potential (dimensionless).

- E0 : float, optional
Peak electric field amplitude [V/m].

- picongpu_polarization_type: Polarization type in PIConGPU (LINEAR or CIRCULAR)

- picongpu_laguerre_modes: Optional magnitudes of Laguerre modes (only relevant for structured beams)

- picongpu_laguerre_phases: Optional phases of Laguerre modes (only relevant for structured beams)

- picongpu_huygens_surface_positions : list[list[int]], default=[[16, -16],[16, -16],[16, -16]]
Positions of the Huygens surface inside the PML. Each entry is a
pair [min, max] indices along x, y, z.

- phi0 : float, optional
Initial phase offset [rad].

Notes:
- Exactly one of ``a0`` or ``E0`` must be provided, the other is
calculated automatically.
"""

def __init__(
self,
Expand Down