# -*- coding: utf-8 -*-
"""
Equilibrium-derived closed-form quantities: RF potential well, bunch length,
form factors, incoherent (Robinson) frequency and the Landau-damping threshold.
These are the low-level quantities shared by the Stage-1 solvers
(albums.equilibrium) and by nearly every Stage-2 theory.
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 scipy.integrate import quad
if TYPE_CHECKING: # pragma: no cover - hints only
from mbtrack2 import CavityResonator, Synchrotron
[docs]def potential_decomposition(
ring: Synchrotron, cavity_list: list[CavityResonator]
) -> tuple[float, float, float]:
"""Taylor coefficients of the RF potential well about the synchronous point.
Parameters
----------
ring : Synchrotron
Ring parameters.
cavity_list : list of CavityResonator
Solved cavities.
Returns
-------
a, b, c : float
Quadratic, cubic and quartic potential-well coefficients.
References
----------
Eq. (4)-(6) in [1].
"""
a_sum = b_sum = c_sum = 0
for cavity in cavity_list:
a_sum += cavity.m * cavity.Vc * np.sin(cavity.theta)
b_sum += cavity.m**2 * cavity.Vc * np.cos(cavity.theta)
c_sum += cavity.m**3 * cavity.Vc * np.sin(cavity.theta)
a = ring.ac * ring.omega1 / (2 * ring.E0 * ring.T0) * a_sum
b = ring.ac * ring.omega1**2 / (6 * ring.E0 * ring.T0) * b_sum
c = -ring.ac * ring.omega1**3 / (24 * ring.E0 * ring.T0) * c_sum
return (a, b, c)
[docs]def bunch_length(
ring: Synchrotron, a: float, b: float, c: float, tau_boundary: float
) -> float:
"""RMS bunch length from the potential-well distribution.
Integrates the Boltzmann distribution of the quartic potential well over
[-tau_boundary, tau_boundary] and returns its standard deviation.
Parameters
----------
ring : Synchrotron
Ring parameters.
a, b, c : float
Potential-well coefficients from potential_decomposition.
tau_boundary : float
Integration half-width in [s].
Returns
-------
float
RMS bunch length in [s].
References
----------
Eq. (8) in [1].
"""
U0 = ring.ac**2 * ring.sigma_delta**2 / 2
def U(tau):
return a * tau**2 + b * tau**3 + c * tau**4
def numerator(tau):
return tau**2 * np.exp(-U(tau) / (2 * U0))
def denominator(tau):
return np.exp(-U(tau) / (2.0 * U0))
num = quad(numerator, -tau_boundary, tau_boundary)[0]
den = quad(denominator, -tau_boundary, tau_boundary)[0]
return np.sqrt(num / den)
[docs]def robinson_frequency(
ring: Synchrotron, cavity_list: list[CavityResonator], F: np.ndarray
) -> float:
"""Incoherent synchrotron (Robinson) angular frequency omega_r.
Parameters
----------
ring : Synchrotron
Ring parameters.
cavity_list : list of CavityResonator
Solved cavities.
F : numpy.ndarray
Amplitude form factor per cavity.
Returns
-------
float
Synchrotron angular frequency in [rad/s].
References
----------
Eq. (10) in [1].
"""
sum_val = 0
for i, cavity in enumerate(cavity_list):
sum_val += cavity.m * F[i] * cavity.Vc * np.sin(cavity.theta)
omega2 = ring.ac * ring.omega1 / (ring.E0 * ring.T0) * sum_val
return np.sqrt(omega2)
[docs]def landau_threshold(
ring: Synchrotron, omega_r: float, c: float, b: float
) -> np.ndarray:
"""Landau-damping frequency-spread threshold for modes mu = 1..4.
Parameters
----------
ring : Synchrotron
Ring parameters.
omega_r : float
Synchrotron angular frequency from robinson_frequency.
c, b : float
Quartic and cubic potential-well coefficients from
potential_decomposition.
Returns
-------
numpy.ndarray
Shape (4, 1) thresholds for the dipole, quadrupole, sextupole and
octupole modes.
References
----------
Eq. (19) in [1].
"""
dipole_landau = (
0.78
* ring.ac**2
* ring.sigma_delta**2
/ omega_r
* np.abs(3 * c / omega_r**2 - (3 * b / omega_r**2) ** 2)
)
out = np.zeros((4, 1))
out[0] = dipole_landau
out[1] = 2.24 / 0.78 * dipole_landau
out[2] = 4.12 / 0.78 * dipole_landau
out[3] = 6.36 / 0.78 * dipole_landau
return out