From db6bc752540a2dbbfcd1d8456399a063f1a07d97 Mon Sep 17 00:00:00 2001 From: PrometheusPi Date: Fri, 8 Aug 2025 14:03:45 +0200 Subject: [PATCH 1/6] add todo for future non +y propagation direction --- lib/python/picongpu/picmi/gaussian_laser.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/python/picongpu/picmi/gaussian_laser.py b/lib/python/picongpu/picmi/gaussian_laser.py index f8778a32e4..3be74f22b8 100644 --- a/lib/python/picongpu/picmi/gaussian_laser.py +++ b/lib/python/picongpu/picmi/gaussian_laser.py @@ -127,6 +127,8 @@ def get_as_pypicongpu(self) -> laser.GaussianLaser: it using a huygens surface in the box, centroid_y <= 0" # @todo implement check that laser field strength sufficiently small # at simulation box boundary + # @todo extend this to other propagation directions than +y + # check polarization vector normalization From dacb20a63e6d99268f13729e37fcf87ce7486c3a Mon Sep 17 00:00:00 2001 From: PrometheusPi Date: Fri, 8 Aug 2025 14:09:30 +0200 Subject: [PATCH 2/6] remove magic number from pulse init time shift --- lib/python/picongpu/picmi/gaussian_laser.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/python/picongpu/picmi/gaussian_laser.py b/lib/python/picongpu/picmi/gaussian_laser.py index 3be74f22b8..4418cc36f5 100644 --- a/lib/python/picongpu/picmi/gaussian_laser.py +++ b/lib/python/picongpu/picmi/gaussian_laser.py @@ -150,11 +150,10 @@ def get_as_pypicongpu(self) -> laser.GaussianLaser: pypicongpu_laser.phase = self.picongpu_phase pypicongpu_laser.E0 = self.E0 - pypicongpu_laser.pulse_init = max( - -2 * self.centroid_position[1] / (self.propagation_direction[1] * constants.c) / self.duration, - 15, - ) - # unit: duration + pypicongpu_laser.pulse_init = (-2.0 * self.centroid_position[1] + / (self.propagation_direction[1] * constants.c) + / self.duration) # unit: multiple of laser pulse duration + # @todo extend this to other propagation directions than +y pypicongpu_laser.polarization_type = self.picongpu_polarization_type pypicongpu_laser.polarization_direction = self.polarization_direction From 44f6cc29c36da7d94536d0210445d945c8c40387 Mon Sep 17 00:00:00 2001 From: PrometheusPi Date: Fri, 8 Aug 2025 14:16:23 +0200 Subject: [PATCH 3/6] update lwfa example --- share/picongpu/pypicongpu/examples/laser_wakefield/main.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/share/picongpu/pypicongpu/examples/laser_wakefield/main.py b/share/picongpu/pypicongpu/examples/laser_wakefield/main.py index 4047ea0232..c97402dce5 100644 --- a/share/picongpu/pypicongpu/examples/laser_wakefield/main.py +++ b/share/picongpu/pypicongpu/examples/laser_wakefield/main.py @@ -51,10 +51,12 @@ solver = picmi.ElectromagneticSolver(grid=grid, method="Yee") +laser_duration = 5.0e-15 +pulse_init = 15. laser = picmi.GaussianLaser( wavelength=0.8e-6, waist=5.0e-6 / 1.17741, - duration=5.0e-15, + duration=laser_duration, propagation_direction=[0.0, 1.0, 0.0], polarization_direction=[1.0, 0.0, 0.0], focal_position=[ @@ -64,7 +66,7 @@ ], centroid_position=[ float(numberCells[0] * cellSize[0] / 2.0), - 0.0, + -0.5 * pulse_init * laser_duration, float(numberCells[2] * cellSize[2] / 2.0), ], picongpu_polarization_type=pypicongpu.laser.GaussianLaser.PolarizationType.CIRCULAR, From 1b9ee727d1995d885adb9e65fc08cb1b4eab615b Mon Sep 17 00:00:00 2001 From: PrometheusPi Date: Fri, 8 Aug 2025 14:34:51 +0200 Subject: [PATCH 4/6] add warning if laser init is too short --- lib/python/picongpu/picmi/gaussian_laser.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/python/picongpu/picmi/gaussian_laser.py b/lib/python/picongpu/picmi/gaussian_laser.py index 4418cc36f5..55e2e4d68a 100644 --- a/lib/python/picongpu/picmi/gaussian_laser.py +++ b/lib/python/picongpu/picmi/gaussian_laser.py @@ -13,6 +13,7 @@ import typeguard import typing +import logging @typeguard.typechecked @@ -154,6 +155,10 @@ def get_as_pypicongpu(self) -> laser.GaussianLaser: / (self.propagation_direction[1] * constants.c) / self.duration) # unit: multiple of laser pulse duration # @todo extend this to other propagation directions than +y + if pypicongpu_laser.pulse_init < 3.: + logging.warning("set centroid_position and propagation_direction indicate that laser " + + "initalization might be too short.\n" + + f"Details: laser.pulse_init = {pypicongpu_laser.pulse_init} < 3") pypicongpu_laser.polarization_type = self.picongpu_polarization_type pypicongpu_laser.polarization_direction = self.polarization_direction From 77a0d354c90a00a383515122943c58a46a367417 Mon Sep 17 00:00:00 2001 From: PrometheusPi Date: Fri, 8 Aug 2025 14:37:19 +0200 Subject: [PATCH 5/6] update author list --- lib/python/picongpu/picmi/gaussian_laser.py | 2 +- share/picongpu/pypicongpu/examples/laser_wakefield/main.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/picongpu/picmi/gaussian_laser.py b/lib/python/picongpu/picmi/gaussian_laser.py index 55e2e4d68a..3283812996 100644 --- a/lib/python/picongpu/picmi/gaussian_laser.py +++ b/lib/python/picongpu/picmi/gaussian_laser.py @@ -1,7 +1,7 @@ """ This file is part of PIConGPU. Copyright 2021-2024 PIConGPU contributors -Authors: Hannes Troepgen, Brian Edward Marre, Alexander Debus +Authors: Hannes Troepgen, Brian Edward Marre, Alexander Debus, Richard Pausch License: GPLv3+ """ diff --git a/share/picongpu/pypicongpu/examples/laser_wakefield/main.py b/share/picongpu/pypicongpu/examples/laser_wakefield/main.py index c97402dce5..76ec5e6d0a 100644 --- a/share/picongpu/pypicongpu/examples/laser_wakefield/main.py +++ b/share/picongpu/pypicongpu/examples/laser_wakefield/main.py @@ -1,7 +1,7 @@ """ This file is part of PIConGPU. Copyright 2024 PIConGPU contributors -Authors: Masoud Afshari, Brian Edward Marre +Authors: Masoud Afshari, Brian Edward Marre, Richard Pausch License: GPLv3+ """ From 66c31c06fc453ccfdc5df838295abffb3615b28c Mon Sep 17 00:00:00 2001 From: BrianMarre Date: Fri, 8 Aug 2025 15:39:34 +0200 Subject: [PATCH 6/6] code refactor suggestion --- lib/python/picongpu/picmi/gaussian_laser.py | 61 ++++++++++--------- .../examples/laser_wakefield/main.py | 2 +- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/lib/python/picongpu/picmi/gaussian_laser.py b/lib/python/picongpu/picmi/gaussian_laser.py index 3283812996..72de3f9ae6 100644 --- a/lib/python/picongpu/picmi/gaussian_laser.py +++ b/lib/python/picongpu/picmi/gaussian_laser.py @@ -88,21 +88,15 @@ def __init__( **kw, ) - def get_as_pypicongpu(self) -> laser.GaussianLaser: - util.unsupported("laser name", self.name) - util.unsupported("laser zeta", self.zeta) - util.unsupported("laser beta", self.beta) - util.unsupported("laser phi2", self.phi2) - # unsupported: fill_in (do not warn, b/c we don't know if it has been - # set explicitly, and always warning is bad) - + def check(self) -> None: + # polarization direction is normalized assert self.testRelativeError( 1, self.scalarProduct(self.polarization_direction, self.polarization_direction), 1e-9, ), "the polarization direction vector must be normalized" - # check for excessive phase values to avoid numerical precision errors + # phase values not excessive to avoid numerical precision errors assert abs(self.picongpu_phase) <= 2 * math.pi, "abs(phase) must be < 2*pi" # check that initialising from y_min-plane only is sensible @@ -111,38 +105,41 @@ def get_as_pypicongpu(self) -> laser.GaussianLaser: ), "laser propagation parallel to the y-plane or pointing outside \ from the inside of the simulation box is not supported by this \ laser in PIConGPU" + + # propagation direction is normalized assert self.testRelativeError( 1, - ( - self.propagation_direction[0] ** 2 - + self.propagation_direction[1] ** 2 - + self.propagation_direction[2] ** 2 - ), + self.scalarProduct(self.propagation_direction, self.propagation_direction), 1e-9, ), "propagation vector must be normalized" - # check centroid outside box + # centroid outside box assert self.centroid_position[1] <= 0, "the laser maximum must be \ outside of the \ simulation box, otherwise it is impossible to correctly initialize\ it using a huygens surface in the box, centroid_y <= 0" + # @todo implement check that laser field strength sufficiently small # at simulation box boundary # @todo extend this to other propagation directions than +y - - # check polarization vector normalization - + # polarization vector normalization assert self.testRelativeError( 1, - ( - self.propagation_direction[0] ** 2 - + self.propagation_direction[1] ** 2 - + self.propagation_direction[2] ** 2 - ), + self.scalarProduct(self.propagation_direction, self.propagation_direction), 1e-9, ), "polarization vector must be normalized" + def get_as_pypicongpu(self) -> laser.GaussianLaser: + util.unsupported("laser name", self.name) + util.unsupported("laser zeta", self.zeta) + util.unsupported("laser beta", self.beta) + util.unsupported("laser phi2", self.phi2) + # unsupported: fill_in (do not warn, b/c we don't know if it has been + # set explicitly, and always warning is bad) + + self.check() + pypicongpu_laser = laser.GaussianLaser() pypicongpu_laser.wavelength = self.wavelength pypicongpu_laser.waist = self.waist @@ -151,14 +148,18 @@ def get_as_pypicongpu(self) -> laser.GaussianLaser: pypicongpu_laser.phase = self.picongpu_phase pypicongpu_laser.E0 = self.E0 - pypicongpu_laser.pulse_init = (-2.0 * self.centroid_position[1] - / (self.propagation_direction[1] * constants.c) - / self.duration) # unit: multiple of laser pulse duration + # unit: multiple of laser pulse duration + pypicongpu_laser.pulse_init = ( + -2.0 * self.centroid_position[1] / (self.propagation_direction[1] * constants.c) / self.duration + ) + # @todo extend this to other propagation directions than +y - if pypicongpu_laser.pulse_init < 3.: - logging.warning("set centroid_position and propagation_direction indicate that laser " - + "initalization might be too short.\n" - + f"Details: laser.pulse_init = {pypicongpu_laser.pulse_init} < 3") + if pypicongpu_laser.pulse_init < 3.0: + logging.warning( + "set centroid_position and propagation_direction indicate that laser " + + "initalization might be too short.\n" + + f"Details: laser.pulse_init = {pypicongpu_laser.pulse_init} < 3" + ) pypicongpu_laser.polarization_type = self.picongpu_polarization_type pypicongpu_laser.polarization_direction = self.polarization_direction diff --git a/share/picongpu/pypicongpu/examples/laser_wakefield/main.py b/share/picongpu/pypicongpu/examples/laser_wakefield/main.py index 76ec5e6d0a..bc8c62b437 100644 --- a/share/picongpu/pypicongpu/examples/laser_wakefield/main.py +++ b/share/picongpu/pypicongpu/examples/laser_wakefield/main.py @@ -52,7 +52,7 @@ solver = picmi.ElectromagneticSolver(grid=grid, method="Yee") laser_duration = 5.0e-15 -pulse_init = 15. +pulse_init = 15.0 laser = picmi.GaussianLaser( wavelength=0.8e-6, waist=5.0e-6 / 1.17741,