@@ -682,7 +682,8 @@ class LinearMap(LongitudinalOneTurnMap):
682682 \eta_0 := 1 / gamma_{tr}^2 - 1 / gamma^2
683683 '''
684684
685- def __init__ (self , alpha_array , circumference , Q_s , D_x = 0 , D_y = 0 ,* args , ** kwargs ):
685+ def __init__ (self , alpha_array , circumference , Q_s , D_x = 0 , D_y = 0 ,
686+ * args , ** kwargs ):
686687 '''Q_s is the synchrotron tune.
687688 D_x, D_y are the dispersions in horizontal and vertical direction.
688689
@@ -759,3 +760,35 @@ def track_without_dispersion(self, beam):
759760
760761 beam .z = z0 * cosdQ_s - longfac * dp0 * sindQ_s
761762 beam .dp = dp0 * cosdQ_s + z0 / longfac * sindQ_s
763+
764+ class RFBox (Drift ):
765+ '''Represents longitudinal square well potential.
766+
767+ Particles drift freely along z within the interval (z_left, z_right)
768+ according to their momentum. When they hit the box boundary they are
769+ reflected with their momentum inverted.
770+
771+ NB: dispersion subtraction not implemented yet!
772+ '''
773+ def __init__ (self , z_left , z_right , alpha_array , length , shrinkage_p_increment = 0 ):
774+ self .z_left = z_left
775+ self .z_right = z_right
776+ super (RFBox , self ).__init__ (alpha_array , length , shrinkage_p_increment )
777+
778+ def track (self , beam ):
779+ super (RFBox , self ).track (beam )
780+ self .reflect (beam )
781+
782+ def reflect (self , beam ):
783+ while pm .any ((beam .z < self .z_left ) + (beam .z > self .z_right )):
784+ left_distance = beam .z - self .z_left
785+ # reflect
786+ beam .z [:] = self .z_left + pm .abs (left_distance )
787+ # invert momentum
788+ beam .dp += - 2 * beam .dp * (left_distance < 0 )
789+
790+ right_distance = beam .z - self .z_right
791+ # reflect
792+ beam .z [:] = self .z_right - pm .abs (right_distance )
793+ # invert momentum
794+ beam .dp += - 2 * beam .dp * (right_distance > 0 )
0 commit comments