Beam

There are two ways to define the initial distribution of beam particles in the six-dimensional phase space. The first way is to specify all necessary parameters for each beam macroparticle. The second way is to define the macroscopic beam parameters and let the code to create macroparticles.

Warning

This section will updated in the future.

Loading an external beam

It is possible to generate an arbitrary beam distribution by setting initial parameters for each beam macroparticle. For this, information about the macroparticles should be written to the file beamfile.npz by a user script (the file name can be any).

This file contains information about beam macroparticles. The state of each macroparticle is defined by 8 values in cylindrical geometry and 9 values in 3D geometry:

  • Longitudinal position, 'xi'.

  • Transverse position, 'r' (cylindrical geometry) or 'x' and 'y' (3d geometry).

  • Longitudinal momentum, 'p_z'.

  • Transverse momentum, 'p_r' (cylindrical geometry) or 'p_x' (3d geometry).

  • Angular momentum 'M' (cylindrical geometry) or third momentum component 'p_y' (3d geometry).

  • Absolute value of the charge to mass ratio, compared to electron, 'q_m'.

  • Charge carried by the macro-particle, 'q'. The charge unit is \(\Delta\xi mc^2/(2 e)\).

  • Identifier of the macro-particle, 'id' (int).

As follows from the data format, the actual beam charge depends on the dimensionless longitudinal grid step xi-step ( \(\Delta\xi\) ). Also see Units. Using a beam generated for some xi-step in a run with different xi-step requires scaling the parameter q.

The beam file can be written in the following way:

import numpy as np

...

np.savez('beamfile.npz', # xi, y, x ... are some previously computed arrays
         'xi' = xi[:],
         'x' = x[:],
         'y' = y[:],
         ...
         )

...

This file can be loaded as follows:

sim = Simulation(...)
sim.load_beamfile('path/to/beamfile.npz') # here we load the file
sim.step()

Beam generator

The beam can be generated by lcode. To do this, you need to collect all necessary parameters in a Python dictionary (dict) and pass it into Simulation at startup.

The beam consists of consecutive segments. The main dictionary contains both shared parameters for all segments and separate dictionaries that contain parameters specific to individual segments. A segment is a beam piece of variable length \(l_s\). The segments follow one by one starting from the beginning of the simulation window (at \(\xi=0\)). If a parameter is not explicitly defined in the segment description, then it is assigned the default value. Default parameters for all segments can be overwritten with a special dict called ‘default’. It is always assumed that the beam has cylindrical symmetry.

This structure looks as follows:

seg1 = {'length': 2, 'ampl': 2, 'energy': 2000}
seg2 = {'length': 3, 'ampl': 0}
seg3 = {'length': 1, 'ampl': 0.1, 'radius': 2}
new_defaults = {'xishape': 'l'}
beams = {'current': 0.1, # shared segment parameters
         'default': new_defaults, # set new default parameters
         'seg1': seg1, # individual segment parameters
         'seg2': seg2,
         'seg3': seg3,
         }

This beam is a combination of three segments with base current \(I_b = 0.1\). The longitudinal profile is constant for all segments.

  • The first segment has current 0.2, length 2, and longitudinal momentum of particles \(2000 m_e c\).

  • The second segment of length 3 has no beam particles.

  • The third segment has a current of 0.01 and a radius of 2.

Shared segment parameters

  • 'current': 0.05 (float)

    Base beam current (in units of \(mc^3/e \approx 17\) kA), \(I_{b0}\). Negative - for negatively charged particles.

  • 'particles_in_layer': 2000 (int)

    Number of beam particles in the layer, \(N_b\). A beam layer which has the current \(I_{b0}\) and length \(\Delta \xi\) contains \(N_b\) macroparticles. Beam layers with lower currents have proportionally fewer macroparticles.

  • 'rng_seed': 1 (int)

    Initial seed for random number generator.

Individual segment parameters

  • 'length': 5.01 (float)

    Length of the segment, \(l_s\).

  • 'ampl': 1 (float)

    Maximum current for this segment (\(I_a\)) in units of \(I_{b0}\).

  • 'xishape: 'cos' (‘c’|’h’|’b’|’g’|’l’|’t’|’T’)

    Dependence of the beam current on the longitudinal coordinate, \(I_b(\xi)\). In the following variants, the formulae are applicable in the interval \(l_s > \delta \xi > 0\), where \(\delta \xi = \xi_s-\xi\), and the segment starts at \(\xi_s \leq 0\).

    • 'c' or 'cos' - shifted cosine shape:

      \(I_b(\xi) = 0.5\, I_a I_{b0} (1 - \cos (2\pi \delta \xi/l_s))\).

    • 'h' or 'half-cos' - rising half-period of the shifted cosine:

      \(I_b(\xi) = 0.5 \, I_a I_{b0} (1 - \cos (\pi \delta \xi/l_s))\).

    • 'b' - Decreasing half-period of the shifted cosine:

      \(I_b(\xi) = 0.5\, I_a I_{b0} (1 + \cos (\pi \delta \xi/l_s))\).

    • 'g' or 'gaussian' - decreasing part of Gaussian function with \(\sigma_z = l_s/6\):

      \(I_b(\xi) = 0.5\, I_a I_{b0} \exp (-18 \,\delta \xi^2/l_s^2)\).

    • 'l' - constant current:

      \(I_b(\xi) = I_a I_{b0}\).

    • 't' - linear rise of the current:

      \(I_b(\xi) = I_a I_{b0} \, \delta \xi/l_s\).

    • 'T' - linear decrease of the current:

      \(I_b(\xi) = I_a I_{b0} (1 - \delta \xi/l_s)\).

  • 'radius': 1 (float)

    Radius of the beam segment, \(\sigma_r\).

  • 'energy': 1000 (float)

    Basic longitudinal momentum of beam particles, \(p_{b0}\).

  • 'xshift': 0 (float)

    Transverse displacement of the segment along x-axis (used in 3d geometry only), \(x_0\).

  • 'yshift': 0 (float)

    Transverse displacement of the segment along y-axis (used in 3d geometry only), \(y_0\).

  • 'rshape': 'g' (‘g’)

    Initial distribution of beam particles in the transverse phase space. At present only Gaussian distribution is possible.

    For 3D geometry:

    \begin{gather} f_\perp (x_b,y_b,p_{bx},p_{by}) = \frac{1}{(2\pi)^2 \sigma_r^2 \alpha_b^2 p_{b0}^2} \exp \left( -\frac{(x_b-x_0)^2 + (y_b-y_0)^2}{2 \sigma_r^2} - \frac{p_{bx}^2+p_{by}^2}{2 \alpha_b^2 p_{b0}^2} \right), \end{gather}

    where \(\alpha_b\) is the angular spread of the beam slice, and the distances (\(x_0\), \(y_0\), \(x_b\), \(y_b\)) are measured from the central axis.

    For cylindrical geometry:

    \begin{gather} f_\perp (r_b,p_{br},p_{b\varphi}) = \frac{r_b}{2\pi \sigma_r^2 \alpha_b^2 p_{b0}^2} \exp \left( -\frac{r_b^2}{2 \sigma_r^2} - \frac{p_{br}^2+p_{b\varphi}^2}{2 \alpha_b^2 p_{b0}^2} \right). \end{gather}

    The beam current \(I_b(\xi)\) and the beam density on the axis \(\rho_{b0}(r=0)\) or \(\rho_{b0}(x_0, y_0)\) are related as

    \[I_b(\xi) = \frac{\rho_{b0} \sigma_r^2}{2}.\]
  • 'angspread': 1e-5 (float)

    Maximum angular spread in the segment, \(\alpha_0\).

  • 'angshape': 'l' (‘c’|’h’|’b’|’g’|’l’|’t’|’T’)

    Dependence of the angular spread on the longitudinal coordinate, \(\alpha_b(\xi)\).

    In the following variants, the formulae are applicable in the interval \(l_s > \delta \xi > 0\), where \(\delta \xi = \xi_s-\xi\), and the segment starts at \(\xi_s \leq 0\).

    • 'c' or 'cos' - shifted cosine shape:

      \(\alpha_b(\xi) = 0.5\, \alpha_0 (1 - \cos (2\pi \delta \xi/l_s))\).

    • 'h' or 'half-cos' - rising half-period of the shifted cosine:

      \(\alpha_b(\xi) = 0.5 \, \alpha_0 (1 - \cos (\pi \delta \xi/l_s))\).

    • 'b' - decreasing half-period of the shifted cosine:

      \(\alpha_b(\xi) = 0.5\, \alpha_0 (1 + \cos (\pi \delta \xi/l_s))\).

    • 'g' or 'gaussian' - decreasing part of Gaussian function with \(\sigma_z = l_s/6\):

      \(\alpha_b(\xi) = 0.5\, \alpha_0 \exp (-18 \,\delta \xi^2/l_s^2)\).

    • 'l' - constant:

      \(\alpha_b(\xi) = \alpha_0\).

    • 't' - linear rise:

      \(\alpha_b(\xi) = \alpha_0 \, \delta \xi/l_s\).

    • 'T' - linear decrease:

      \(\alpha_b(\xi) = \alpha_0 (1 - \delta \xi/l_s)\).

  • 'espread': 0 (float)

    Auxiliary value of the longitudinal momentum, \(p_a\).

  • 'eshape': 'm' (‘m’|’u’|’l’|’g’|’N’)

    Longitudinal momentum distribution of beam particles, \(f_\parallel (p_{bz})\).

    Available options:

    • 'm' or 'monoenergetic' - monoenergetic:

    \[f_\parallel (p_{bz}) = \delta (p_{bz}-p_{b0}).\]
    • 'u' or 'uniform' - uniform over the interval:

    \begin{gather} f_\parallel (p_{bz}) = (p_{b0}-p_a)^{-1} \qquad &\text{if} \quad p_{b0} > p_{bz} > p_a, \\ f_\parallel (p_{bz}) = 0 \qquad &otherwise. \end{gather}
    • 'l' or 'linear' - linear energy growth from \(p_a\) to \(p_{b0}\):

    \[f_\parallel (p_{bz}) = \delta \bigl(p_{bz}-p_{b0}\, \delta \xi/l_s - p_a (1-\delta \xi/l_s)\bigr).\]
    • 'g' or 'gaussian' - Gaussian distribution:

    \[f_\parallel (p_{bz}) = \frac{\exp(-(p_{bz}-p_{b0})^2/(2 p_a^2))}{\sqrt{2 \pi} p_a}.\]
    • 'N' - monoenergetic fractions (\(N = 2 \ldots 9\)):

    \[f_\parallel (p_{bz}) = \sum_{i=0}^{N-1} \delta (p_{bz}-p_i), \qquad p_i = p_a + \frac{i}{N-1} (p_{b0}-p_a).\]
  • 'mass_charge_ratio': 1 (float)

    Absolute value of mass to charge ratio, compared to the electron.