Skip to content

Commit

Permalink
add laser wakefield example
Browse files Browse the repository at this point in the history
  • Loading branch information
BrianMarre committed Aug 3, 2024
1 parent 78d1c61 commit cfe0bf5
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 19 deletions.
36 changes: 19 additions & 17 deletions docs/source/usage/picmi/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,25 @@ After you have installed the dependencies you must include the PIConGPU PICMI im
.. note::
Above, we used ``$PICSRC`` as a short hand for the path to picongpu's source code directory, provided from your shell environment if a pre-configured profile is used.

After you have installed all PICMI dependencies, simply create a user script, see :ref:`here <example_PICMI_setup>`, and generate a picongpu setup, see :ref:`generating a PIConGPU setup with PICMI <generating_setups_with_PICMI>`.
After you have installed all PICMI dependencies, simply create a user script, see the :ref:`warm plasma <example_PICMI_setup_warm_plasma>` and :ref:`laser wakefield <example_PICMI_setup_lwfa>` examples, and generate a picongpu setup, see :ref:`generating a PIConGPU setup with PICMI <generating_setups_with_PICMI>`.

Example User Script for a warm plasma setup:
--------------------------------------
.. _example_PICMI_setup:
.. _example_PICMI_setup_warm_plasma:

.. literalinclude:: ../../../../share/picongpu/pypicongpu/examples/warm_plasma/main.py
:language: python

Creates a directory ``generated_input``, where you can run ``pic-build`` and subsequently ``tbg``.
Creates a directory ``warm_plasma``, where you can run ``pic-build`` and subsequently ``tbg``.

Example User Script for a laser wakefield setup:
--------------------------------------
.. _example_PICMI_setup_lwfa:

.. literalinclude:: ../../../../share/picongpu/pypicongpu/examples/laser_wakefield/main.py
:language: python

Creates a directory ``LWFA``, where you can run ``pic-build`` and subsequently ``tbg``.

Generation of PIConGPU setups with PICMI
----------------------------------------
Expand Down Expand Up @@ -188,24 +197,17 @@ Parameters/Methods prefixed with ``picongpu_`` are PIConGPU-exclusive.

If neither is set a warning is printed prompting for either of the options above.

- **Interaction**
Configuration of the PIC-algorithm extensions, example of use as follows:

.. code:: python
Ionization:
^^^^^^^^^^^
The PIConGPU PICMI interface currently supports the configuration of ionization only through a picongpu specific PICMI extension, not the in the PICMI standard defined interface, due to the lack of standardization of ionization algorithm names in the PICMI standard.

from picongpu import picmi
from picongpu.interaction.ionization.fieldionization import ADK, ADKVariant
from picongpu.interaction import Interaction
Use the **Interaction** interface

e = picmi.Species(name="e", particle_type="electron")
nitrogen = picmi.Species(name="nitrogen", particle_type="N", charge_state=2)

ADK_ionization = ADK(ADK_variant = ADKVariant.LinearPolarization, ion_species = nitrogen, ionization_electron_species=e)
interaction = Interaction(ground_state_ionizaion_model_list=[ADK_Ionization])
- **Interaction**
picongpu specific configuration of PIC-algorithm extensions.

sim = picmi.simulation(picongpu_interaction=interaction)
sim.add_species(e, ...)
sim.add_species(nitrogen, ...)
- ``__init__(ground_state_ionizaion_model_list= <list of ionization models>)``

Output
^^^^^^
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
LWFA
202 changes: 202 additions & 0 deletions share/picongpu/pypicongpu/examples/laser_wakefield/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
"""
This file is part of PIConGPU.
Copyright 2024 PIConGPU contributors
Authors: Masoud Afshari, Brian Edward Marre
License: GPLv3+
"""

from picongpu import picmi
from picongpu import pypicongpu
import numpy as np

"""
@file PICMI user script reproducing the PIConGPU LWFA example
This Python script is example PICMI user script reproducing the LaserWakefield example setup, based on 8.cfg.
"""


# generation modifiers
ENABLE_IONS = True
ENABLE_IONIZATION = True
ADD_CUSTOM_INPUT = True
OUTPUT_DIRECTORY_PATH = "LWFA"

numberCells = np.array([192, 2048, 192])
cellSize = np.array([0.1772e-6, 0.4430e-7, 0.1772e-6]) # unit: meter)

# Define the simulation grid based on grid.param
grid = picmi.Cartesian3DGrid(
picongpu_n_gpus=[2, 4, 1],
number_of_cells=numberCells.tolist(),
lower_bound=[0, 0, 0],
upper_bound=(numberCells * cellSize).tolist(),
lower_boundary_conditions=["open", "open", "open"],
upper_boundary_conditions=["open", "open", "open"],
)

gaussianProfile = picmi.distribution.GaussianDistribution(
density=1.0e25,
center_front=8.0e-5,
sigma_front=8.0e-5,
center_rear=10.0e-5,
sigma_rear=8.0e-5,
factor=-1.0,
power=4.0,
vacuum_cells_front=50,
)

# for particle type see https://github.com/openPMD/openPMD-standard/blob/upcoming-2.0.0/EXT_SpeciesType.md
electrons = picmi.Species(particle_type="electron", name="electron", initial_distribution=gaussianProfile)

hydrogen_ionization = picmi.Species(
particle_type="H", name="hydrogen", charge_state=0, initial_distribution=gaussianProfile
)

hydrogen_fully_ionized = picmi.Species(
particle_type="H", name="hydrogen", picongpu_fixed_charge=True, initial_distribution=gaussianProfile
)

solver = picmi.ElectromagneticSolver(
grid=grid,
method="Yee",
)

laser = picmi.GaussianLaser(
wavelength=0.8e-6,
waist=5.0e-6 / 1.17741,
duration=5.0e-15,
propagation_direction=[0.0, 1.0, 0.0],
polarization_direction=[1.0, 0.0, 0.0],
focal_position=[float(numberCells[0] * cellSize[0] / 2.0), 4.62e-5, float(numberCells[2] * cellSize[2] / 2.0)],
centroid_position=[float(numberCells[0] * cellSize[0] / 2.0), 0.0, float(numberCells[2] * cellSize[2] / 2.0)],
picongpu_polarization_type=pypicongpu.laser.GaussianLaser.PolarizationType.CIRCULAR,
a0=8.0,
picongpu_phase=0.0,
)

randomLayout = picmi.PseudoRandomLayout(n_macroparticles_per_cell=2)

# Initialize particles based on speciesInitialization.param
# simulation schema : https://github.com/BrianMarre/picongpu/blob/2ddcdab4c1aca70e1fc0ba02dbda8bd5e29d98eb/share/picongpu/pypicongpu/schema/simulation.Simulation.json

if not ENABLE_IONIZATION:
hydrogen = hydrogen_fully_ionized
interaction = None
else:
hydrogen = hydrogen_ionization
adk_ionization_model = picmi.ADK(
ADK_variant=picmi.ADKVariant.CircularPolarization,
ion_species=hydrogen_ionization,
ionization_electron_species=electrons,
ionization_current=None,
)

bsi_effectiveZ_ionization_model = picmi.BSI(
BSI_extensions=[picmi.BSIExtension.EffectiveZ],
ion_species=hydrogen_ionization,
ionization_electron_species=electrons,
ionization_current=None,
)

interaction = picmi.Interaction(
ground_state_ionization_model_list=[adk_ionization_model, bsi_effectiveZ_ionization_model]
)

sim = picmi.Simulation(
solver=solver,
max_steps=4000,
time_step_size=1.39e-16,
picongpu_moving_window_move_point=0.9,
picongpu_interaction=interaction,
)

sim.add_species(electrons, layout=randomLayout)

if ENABLE_IONS:
sim.add_species(hydrogen, layout=randomLayout)

sim.add_laser(laser, None)

# additional non standardized custom user input
# only active if custom templates are used

# for generating setup with custom input see standard implementation,
# see https://picongpu.readthedocs.io/en/latest/usage/picmi/custom_template.html
if ADD_CUSTOM_INPUT:
min_weight_input = pypicongpu.customuserinput.CustomUserInput()
min_weight_input.addToCustomInput({"minimum_weight": 10.0}, "minimum_weight")
sim.picongpu_add_custom_user_input(min_weight_input)

output_configuration = pypicongpu.customuserinput.CustomUserInput()
output_configuration.addToCustomInput(
{
"png_plugin_data_list": "['Ex', 'Ey', 'Ez', 'Bx', 'By', 'Bz', 'Jx', 'Jy', 'Jz']",
"png_plugin_SCALE_IMAGE": 1.0,
"png_plugin_SCALE_TO_CELLSIZE": True,
"png_plugin_WHITE_BOX_PER_GPU": False,
"png_plugin_EM_FIELD_SCALE_CHANNEL1": 7,
"png_plugin_EM_FIELD_SCALE_CHANNEL2": -1,
"png_plugin_EM_FIELD_SCALE_CHANNEL3": -1,
"png_plugin_CUSTOM_NORMALIZATION_SI": "5.0e12 / constants.c, 5.0e12, 15.0",
"png_plugin_PRE_PARTICLE_DENS_OPACITY": 0.25,
"png_plugin_PRE_CHANNEL1_OPACITY": 1.0,
"png_plugin_PRE_CHANNEL2_OPACITY": 1.0,
"png_plugin_PRE_CHANNEL3_OPACITY": 1.0,
"png_plugin_preParticleDensCol": "colorScales::grayInv",
"png_plugin_preChannel1Col": "colorScales::green",
"png_plugin_preChannel2Col": "colorScales::none",
"png_plugin_preChannel3Col": "colorScales::none",
"png_plugin_preChannel1": "field_E.x() * field_E.x();",
"png_plugin_preChannel2": "field_E.y()",
"png_plugin_preChannel3": "-1.0_X * field_E.y()",
"png_plugin_period": 100,
"png_plugin_axis": "yx",
"png_plugin_slicePoint": 0.5,
"png_plugin_species_name": "electron",
"png_plugin_folder_name": "pngElectronsYX",
},
"png plugin configuration",
)

output_configuration.addToCustomInput(
{
"energy_histogram_species_name": "electron",
"energy_histogram_period": 100,
"energy_histogram_bin_count": 1024,
"energy_histogram_min_energy": 0.0,
"energy_histogram_maxEnergy": 1000.0,
"energy_histogram_filter": "all",
},
"energy histogram plugin configuration",
)

output_configuration.addToCustomInput(
{
"phase_space_species_name": "electron",
"phase_space_period": 100,
"phase_space_space": "y",
"phase_space_momentum": "py",
"phase_space_min": -1.0,
"phase_space_max": 1.0,
"phase_space_filter": "all",
},
"phase space plugin configuration",
)

output_configuration.addToCustomInput(
{"opnePMD_period": 100, "opnePMD_file": "simData", "opnePMD_extension": "bp"}, "openPMD plugin configuration"
)

output_configuration.addToCustomInput(
{"checkpoint_period": 100, "checkpoint_backend": "openPMD", "checkpoint_restart_backend": "openPMD"},
"checkpoint configuration",
)

output_configuration.addToCustomInput(
{"macro_particle_count_period": 100, "macro_particle_count_species_name": "electron"},
"macro particle count plugin configuration",
)
sim.picongpu_add_custom_user_input(output_configuration)

sim.write_input_file(OUTPUT_DIRECTORY_PATH)
2 changes: 1 addition & 1 deletion share/picongpu/pypicongpu/examples/warm_plasma/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
generated_input
warm_plasma
11 changes: 10 additions & 1 deletion share/picongpu/pypicongpu/examples/warm_plasma/main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
"""
This file is part of PIConGPU.
Copyright 2021-2024 PIConGPU contributors
Authors: Hannes Troepgen
License: GPLv3+
"""

from picongpu import picmi

OUTPUT_DIRECTORY_PATH = "warm_plasma"

boundary_conditions = ["periodic", "periodic", "periodic"]
grid = picmi.Cartesian3DGrid(
# note: [x] * 3 == [x, x, x]
Expand Down Expand Up @@ -36,4 +45,4 @@
layout = picmi.PseudoRandomLayout(n_macroparticles_per_cell=25)
sim.add_species(electron, layout)

sim.write_input_file("generated_input")
sim.write_input_file(OUTPUT_DIRECTORY_PATH)

0 comments on commit cfe0bf5

Please sign in to comment.