transfer_matrices module
Define every element longitudinal transfer matrix.
Units are taken exactly as in TraceWin, i.e. first line is z (m) and second
line is dp/p.
Todo
Send beta as argument to avoid recomputing it each time
Todo
electric field interpolated twice: a first time for acceleration, and a second time to iterate itg_field. Maybe this could be done only once.
Todo
Integrate my doc with demonstration of transfer matrix for field map form.
- z_drift(gamma_in, delta_s, omega_0_bunch, n_steps=1)[source]
Calculate the transfer matrix of a drift.
- z_field_map_rk4(gamma_in, d_z, n_steps, omega0_rf, delta_phi_norm, delta_gamma_norm, complex_e_func, real_e_func)[source]
Calculate the transfer matrix of
FieldMapusing Runge-Kutta.We slice the field map in a serie of drift-thin acceleration gap-drift. We pre-compute some constants to speed up the calculation:
- Parameters:
gamma_in (
float) – Lorentz factor at entry of field map.d_z (
float) – Size of the integration step in \(\mathrm{m}\).n_steps (
int) – Number of integration steps.omega0_rf (
float) – RF pulsation in \(\mathrm{rad/s}\).delta_phi_norm (
float) –Constant to speed up calculation.
\[\Delta\phi_\mathrm{norm} = \frac{\omega_0 \Delta z}{c}\]delta_gamma_norm (
float) –Constant to speed up calculation.
\[\Delta\gamma_\mathrm{norm} = \frac{q_\mathrm{adim} \Delta z} {E_\mathrm{rest}}\]complex_e_func (
Callable[[float|tuple[float,float] |tuple[float,float,float],float],complex]) – Takes in the z-position of the particle and the phase, return the complex field component at this phase and position.real_e_func (
Callable[[float|tuple[float,float] |tuple[float,float,float],float],float]) – Takes in the z-position of the particle and the phase, return the real field component at this phase and position.
- Return type:
tuple[ndarray[tuple[Any,...],dtype[double]],ndarray[tuple[Any,...],dtype[double]],complex]- Returns:
NDArray[np.float64] – \(2\times 2 \times n\) matrix, holding the \(2\times2\) longitudinal transfer matrix of every field map slice along the field map.
NDArray[np.float64] – \(2\times n\) array, holding Lorentz factor and phase of the synchronous particle along the linac.
complex – Complex integral of the field experienced by the synchronous particle when crossing the cavity.
- z_thin_lense(scaled_e_middle, gamma_in, gamma_out, gamma_middle, half_dz, omega0_rf)[source]
Compute propagation in a slice of field map using thin lense approximation.
Thin lense approximation: drift-acceleration-drift. The transfer matrix of the thin accelerating gap is:
\[\begin{split}\begin{bmatrix} k_3 & 1 \\ k_1 & k_2 \\ \end{bmatrix}\end{split}\]Where:
\[\begin{split}\left\{ \begin{aligned} k_1 &= \Im(\widetilde{E}_\mathrm{scaled}^\mathrm{norm}) \frac{\omega_0}{\beta_m c} \\ k_2 &= 1 - (2 - \beta_m^2)\Re(\widetilde{E}_\mathrm{scaled}^\mathrm{norm}) \\ k_3 &= \frac{1 - \Re(\widetilde{E}_\mathrm{scaled}^\mathrm{norm})}{k_2} \end{aligned} \right.\end{split}\]\(\widetilde{E}_\mathrm{scaled}^\mathrm{norm}\) is proportional to the complex electric field at the middle of the accelerating gap:
\[\widetilde{E}_\mathrm{scaled}^\mathrm{norm} = \frac{\Delta\gamma_\mathrm{norm}}{\gamma_m\beta_m^2} \widetilde{E}(z + \frac{\Delta z}{2}, \phi_m)\]Quantities with a \(m\) subscript are taken at the middle of the accelerating gap. \(i\) are in the first drift, \(i+1\) in the second.
Note
In TraceWin documentation:
\(k_1\) and \(k_2\) are called \(K_1\) and \(K_2\). They miss a \(\Delta z\) term.
Our complex electric field \(\widetilde{E}\) would be written:
\[\widetilde{E} = E_0 \sin{ \left( \frac{Kz}{\beta_c} \right) } \left[ \cos{(\omega t_s + \varphi_0)} + j\sin{(\omega t_s + \varphi_0)} \right]\]
- Parameters:
scaled_e_middle (
complex) –Complex electric field in the accelerating gap multiplied by \(\Delta\gamma_\mathrm{norm}\):
\[\widetilde{E}_\mathrm{scaled} = \Delta\gamma_\mathrm{norm} \widetilde{E}_z\left( z + \Delta z, \phi_m \right)\]where
\[\Delta\gamma_\mathrm{norm} = \frac{q_\mathrm{adim} \Delta z} {E_\mathrm{rest}}\]In the routine, we define:
\[\widetilde{E}_\mathrm{scaled}^\mathrm{norm} = \frac{ \widetilde{E}_\mathrm{scaled} }{ \gamma_m \beta_m^2 }\]gamma_in (
float) – gamma at entrance of first drift.gamma_out (
float) – gamma at exit of first drift.gamma_middle (
float) – gamma at the thin acceleration drift.half_dz (
float) – Half a spatial step in \(\mathrm{m}\).omega0_rf (
float) – Pulsation of the cavity.omega_0_bunch – Pulsation of the beam.
- Return type:
- Returns:
Transfer matrix of the thin lense.
- z_bend(gamma_in, delta_s, factor_1, factor_2, factor_3, omega_0_bunch)[source]
Compute the longitudinal transfer matrix of a bend.
factor_1is:\[\frac{-h^2\Delta s}{k_x^2}\]factor_2is:\[\frac{h^2 \sin{(k_x\Delta s)}}{k_x^3}\]factor_3is:\[\Delta s \left(1 - \frac{h^2}{k_x^2}\right)\]
- z_superposed_field_maps_rk4(gamma_in, d_z, n_steps, omega0_rf, delta_phi_norm, delta_gamma_norm, complex_e_func, real_e_func)[source]
Calculate the transfer matrix of superposed FIELD_MAP using RK.
- Parameters:
gamma_in (
float)d_z (
float)n_steps (
int)omega0_rf (
float)delta_phi_norm (
float)delta_gamma_norm (
float)complex_e_func (
Callable[[float|tuple[float,float] |tuple[float,float,float],float],complex])real_e_func (
Callable[[float|tuple[float,float] |tuple[float,float,float],float],float])
- Return type:
tuple[ndarray[tuple[Any,...],dtype[double]],ndarray[tuple[Any,...],dtype[double]],complex]
- z_field_map_leapfrog(d_z, gamma_in, n_steps, omega0_rf, k_e, phi_0_rel, e_spat, q_adim, inv_e_rest_mev, gamma_init, omega_0_bunch, **kwargs)[source]
Calculate the transfer matrix of a
FIELD_MAPusing leapfrog.Todo
clean, fix, separate leapfrog integration in dedicated module
This method is less precise than RK4. However, it is much faster.
Classic leapfrog method: speed(i+0.5) = speed(i-0.5) + accel(i) * dt pos(i+1) = pos(i) + speed(i+0.5) * dt
Here, dt is not fixed but dz. z(i+1) += dz t(i+1) = t(i) + dz / (c beta(i+1/2)) (time and space variables are on whole steps) beta calculated from W(i+1/2) = W(i-1/2) + qE(i)dz (speed/energy is on half steps)