Intra-Beam Scattering

Analytical Growth Rates

The following example illustrates how to obtain growth rates from Intra-Beam Scattering in Xsuite. The functionality is exposed through the TwissTable and can make use of two different formalism, Nagaitsev and Bjorken-Mtingwa. The former provides a computationally efficient approach but does not account for vertical dispersion, while the latter accounts for it but is slower.

See also: xtrack.twiss.TwissTable.get_ibs_growth_rates()

import json

import xtrack as xt

##########################
# Load xt.Line from file #
##########################

fname_line_particles = "../../../xtrack/test_data/lhc_no_bb/" \
                       "line_and_particle.json"

with open(fname_line_particles, "r") as fid:
    input_data = json.load(fid)

line = xt.Line.from_json(fname_line_particles)
line.particle_ref = xt.Particles.from_dict(input_data["particle"])
tw = line.twiss(method="4d")

#####################
# Define parameters #
#####################

# Line is for LHC protons at top energy
bunch_intensity: int = int(1.8e11)
nemitt_x: float = 1.8e-6
nemitt_y: float = 1.8e-6
sigma_delta: float = 4.71e-5
bunch_length: float = 3.75e-2

###################################
# Get growth rates with Nagaitsev #
###################################

nag_growth_rates = tw.get_ibs_growth_rates(
    formalism="nagaitsev",
    total_beam_intensity=bunch_intensity,
    nemitt_x=nemitt_x,
    nemitt_y=nemitt_y,
    sigma_delta=sigma_delta,
    bunch_length=bunch_length,
    bunched=True,
)

#########################################
# Get growth rates with Bjorken-Mtingwa #
#########################################

bm_growth_rates = tw.get_ibs_growth_rates(
    formalism="bjorken-mtingwa",  # also accepts "b&m"
    total_beam_intensity=bunch_intensity,
    nemitt_x=nemitt_x,
    nemitt_y=nemitt_y,
    sigma_delta=sigma_delta,
    bunch_length=bunch_length,
    bunched=True,
)

##########################################################
# Compare: we expect Nagaitsev to be wrong in horizontal #
##########################################################

print()
print("Computed from normalized emittances:")
print("------------------------------------")
print(f"Nagaitsev:       {nag_growth_rates}")
print(f"Bjorken-Mtingwa: {bm_growth_rates}")

# Computed from normalized emittances:
# ------------------------------------
# Nagaitsev:       IBSGrowthRates(Tx=6.24e-05, Ty=-2.27e-09, Tz=0.00031)
# Bjorken-Mtingwa: IBSGrowthRates(Tx=6.21e-05, Ty=1.1e-06, Tz=0.00031)

# Complete source: xfields/examples/005_ibs/001_growth_rates_from_parameters_with_vdisp.py

IBS Kicks for Tracking

When trying to study the interplay of IBS effects with others such as space charge, e-cloud, beamb-beam etc. analytical growth rates are not enough and tracking becomes necessary. In Xfields beam elements are provided to model IBS tracking, which apply momenta kicks to particles. Two kick elements are available:

  • IBSAnalyticalKick (from R. Bruce) for kicks based on analytical growth rates;

  • IBSKineticKick (from P. Zenkevich) for kicks based on diffusion and friction terms from the kinetic theory of gases.

The following example illustrates how to create a kick element, inserting and configuring it for tracking. Refer to the Reference manual for the full list of parameters and their explanation, and to the Physics guide for full information.

See also: xtrack.Line.configure_intrabeam_scattering()

import xfields as xf
import xobjects as xo
import xpart as xp
import xtrack as xt

context = xo.ContextCpu(omp_num_threads="auto")

##########################
# Load xt.Line from file #
##########################

# This is SPS line with proton as particle ref
fname_line_particles = "../../../xtrack/test_data/sps_w_spacecharge/"\
                       "line_no_spacecharge_and_particle.json"
line: xt.Line = xt.Line.from_json(fname_line_particles)
line.build_tracker(_context=context)

#######################################
# Create and Install IBS Kick Element #
#######################################

# For the analytical kick formalism: kicks are computed based
# on the analytical growth rates (so it needs a formalism)
# ibs_kick = xf.IBSAnalyticalKick(formalism="nagaitsev", num_slices=50)

# For the kinetic formalism: kicks are computed based on the
# friction and diffusion terms of the kinetic theory of gases
ibs_kick = xf.IBSKineticKick(num_slices=50)

# By default the element is off until configuration. Let's install
# the kick at the end of the line and configure it. This internally
# provides the necessary information to the element
line.configure_intrabeam_scattering(
    element=ibs_kick, name="ibskick", index=-1, update_every=50
)

############################################
# Define parameters and Generate Particles #
############################################

# Line is for SPS protons at injection
bunch_intensity: int = int(3.5e8)
nemitt_x: float = 2.5e-6
nemitt_y: float = 2.5e-6
sigma_delta: float = 9.56e-4
bunch_length: float = 8.98e-2

particles = xp.generate_matched_gaussian_bunch(
    num_particles=10_000,
    total_intensity_particles=bunch_intensity,
    nemitt_x=nemitt_x,
    nemitt_y=nemitt_y,
    sigma_z=bunch_length,
    line=line,
    _context=context,
)

##############################################
# Track now applies an IBS kick at each turn #
##############################################

line.track(particles, num_turns=100, with_progress=5)

# Complete source: xfields/examples/005_ibs/003_tracking_with_kicks.py