Source code for albums.physics.coupled_bunch

# -*- coding: utf-8 -*-
"""
HOM-driven longitudinal dipole coupled-bunch instability:
- Growth-rate estimate using Bosch [1] resonant approximation,
compared against approxmiate the Landau-damping threshold from
rf potential decomposition.

References
----------
[1] Bosch, R. A., K. J. Kleman, and J. J. Bisognano. "Robinson instabilities
    with a higher-harmonic cavity." Physical Review Special Topics-Accelerators
    and Beams 4.7 (2001): 074401.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

import numpy as np

from albums.physics.potential import form_factors

if TYPE_CHECKING:  # pragma: no cover - hints only
    from mbtrack2 import Synchrotron


[docs]def dipole_coupled_bunch_growth_rate( ring: Synchrotron, I0: float, f_HOM: float, Z_HOM: float, bunch_length: float, omega_r: float, ) -> float: """Resonant dipole coupled-bunch growth rate. Eq. (22) in [1].""" from_factor = form_factors(f_HOM, 1, bunch_length) return (I0 * ring.eta() * 2 * np.pi * f_HOM * Z_HOM * from_factor**2) / ( 2 * ring.E0 * ring.T0 * omega_r )
[docs]def dipole_coupled_bunch( ring: Synchrotron, I0: float, f_HOM: float | np.ndarray, Z_HOM: float | np.ndarray, bunch_length: float, omega_r: float, landau: np.ndarray, ) -> bool: """HOM-driven dipole coupled-bunch instability test. Uses the resonant dipole_coupled_bunch_growth_rate for each HOM in the supplied list. The instability is flagged only if the HOM growth rate exceeds both radiation damping and the dipole Landau threshold. Parameters ---------- ring : Synchrotron Ring parameters. I0 : float Beam current in A. f_HOM, Z_HOM : float or array-like HOM resonant frequency in [Hz] and shunt impedance in [Ohm]. bunch_length : float RMS bunch length in [s]. omega_r : float Synchrotron angular frequency. landau : numpy.ndarray Landau thresholds from landau_threshold; only the dipole entry landau[0] is used. Returns ------- bool True if HOM-driven coupled-bunch unstable. Raises ------ ValueError If f_HOM and Z_HOM have mismatched lengths. References ---------- Eq. (22) in [1]. """ HOM = False if isinstance(f_HOM, (int, float)): f_HOM = [f_HOM] if isinstance(Z_HOM, (int, float)): Z_HOM = [Z_HOM] if len(f_HOM) != len(Z_HOM): raise ValueError("f_HOM and Z_HOM must have the same length.") else: N = len(f_HOM) for i in range(N): gr_HOM = dipole_coupled_bunch_growth_rate( ring, I0, f_HOM[i], Z_HOM[i], bunch_length, omega_r ) gr = gr_HOM - 1 / ring.tau[2] if gr > 0: if gr_HOM > landau[0]: HOM = True break return HOM