Skip to content

Restructure BeamIonElement

Hey @GUBAIDULIN,

As you know there are a few things that I would like to improve for the BeamIonElement class:

  • Mandatory monitor which records every turn and every bunch
  • Should be able to track through an already built up ion cloud
  • Should be able to deal with changing bunch charge
  • Global lack of modularity

Possible directions on where to go to solve this issue:

  • Each mp has its own charge value (so store for each mp a 7 dimensions array with 6 coordinates + charge)
  • Allow for a mode without ion generation
  • split BeamIonElement.track call to allow for more modularity (so being able to choose when monitor is called, when ions are generated, ...)

I wanted to exchange first to see if you see any blocking point with these ideas or what would you suggest to solve this.

Two concrete examples of things that the code should handle:

Tracking with pre-set could -> currently not ok

from mbtrack2 import IonParticles

new_ion_particles = IonParticles(
    mp_number=1000,
    ion_element_length=ring.L,
    ring=ring,
)

new_ion_particles.generate_as_a_distribution(beam[0])
beam_ion.ion_beam += new_ion_particles
beam_ion.ion_beam.charge = 1e-9

#%%

beam_ion.track(beam)
print(beam_ion.ion_beam.charge)
print(beam_ion.ion_beam.charge_per_mp)

>> 2.2246133759865426e-12
>> 1.0070680742356462e-15

Tracking with aperture -> currently not ok

beam = Beam(ring)
filling = np.zeros((ring.h,))
filling[:n_bunch] = total_charge/ring.T0/n_bunch
beam.init_beam(filling, mp_per_bunch=mp_num, track_alive=True, mpi=mpi)

print(beam.current)

beam_ion.track(beam)
print(beam_ion.ion_beam.charge)
print(beam_ion.ion_beam.charge_per_mp)

aperture = ElipticalAperture(X_radius, Y_radius)

for bunch in beam:
    bunch["x"] += X_radius

aperture.track(beam)
print(beam.current)

beam_ion.track(beam)
print(beam_ion.ion_beam.charge)
print(beam_ion.ion_beam.charge_per_mp)