Bunching Factors¶
Import packages¶
In [1]:
Copied!
%load_ext autoreload
%autoreload 2
%load_ext autoreload
%autoreload 2
In [2]:
Copied!
import numpy as np
from numpy import genfromtxt
import scipy
from scipy import special
from zfel.particles import general_load_bucket
import matplotlib.pyplot as plt
import numpy as np
from numpy import genfromtxt
import scipy
from scipy import special
from zfel.particles import general_load_bucket
import matplotlib.pyplot as plt
Input parameters¶
In [3]:
Copied!
npart = 512 # n-macro-particles per bucket
s_steps = 200#31 # n-sample points along bunch length
z_steps = 200#20 # n-sample points along undulator
energy = 4313.34*1E6 # electron energy [eV]
eSpread = 0#1.0e-4 # relative rms energy spread [ ]
emitN = 1.2e-6 # normalized transverse emittance [m-rad]
currentMax = 3900 # peak current [Ampere]
beta = 26 # mean beta [meter]
unduPeriod = 0.03 # undulator period [meter]
unduK = 3.5 # undulator parameter, K [ ]
unduL = 70#30 # length of undulator [meter]
radWavelength = 1.5e-9 # seed wavelength? [meter], used only in single-freuqency runs
dEdz = 0 # rate of relative energy gain or taper [keV/m], optimal~130
iopt = 5 # 5=SASE, 4=seeded
P0 = 10000*0.0 # small seed input power [W]
constseed = 1 # whether we want to use constant random seed for reproducibility, 1 Yes, 0 No
particle_position=genfromtxt('./data/weird_particle_position.csv', delimiter=',') # or None
# particle information with positions in meter and eta,\
# if we want to load random particle positions and energy, then set None
hist_rule='square-root' # 'square-root' or 'sturges' or 'rice-rule' or 'self-design', number \
# of intervals to generate the histogram of eta value in a bucket
npart = 512 # n-macro-particles per bucket
s_steps = 200#31 # n-sample points along bunch length
z_steps = 200#20 # n-sample points along undulator
energy = 4313.34*1E6 # electron energy [eV]
eSpread = 0#1.0e-4 # relative rms energy spread [ ]
emitN = 1.2e-6 # normalized transverse emittance [m-rad]
currentMax = 3900 # peak current [Ampere]
beta = 26 # mean beta [meter]
unduPeriod = 0.03 # undulator period [meter]
unduK = 3.5 # undulator parameter, K [ ]
unduL = 70#30 # length of undulator [meter]
radWavelength = 1.5e-9 # seed wavelength? [meter], used only in single-freuqency runs
dEdz = 0 # rate of relative energy gain or taper [keV/m], optimal~130
iopt = 5 # 5=SASE, 4=seeded
P0 = 10000*0.0 # small seed input power [W]
constseed = 1 # whether we want to use constant random seed for reproducibility, 1 Yes, 0 No
particle_position=genfromtxt('./data/weird_particle_position.csv', delimiter=',') # or None
# particle information with positions in meter and eta,\
# if we want to load random particle positions and energy, then set None
hist_rule='square-root' # 'square-root' or 'sturges' or 'rice-rule' or 'self-design', number \
# of intervals to generate the histogram of eta value in a bucket
In [4]:
Copied!
particle_position[:,1]
particle_position[:,1]
Out[4]:
array([ 0.005, 0.005, 0.005, ..., -0.005, -0.005, -0.005])
Calculating intermediate parameters and bunching factor¶
In [5]:
Copied!
# whether to use constant random seed for reproducibility
if constseed==1:
np.random.seed(22)
# Some constant values
mc2 = 0.51099906E6#510.99906E-3 # Electron rest mass in eV
c = 2.99792458E8 # light speed in meter
e = 1.60217733E-19 # electron charge in Coulomb
gamma0 = energy/mc2 # central energy of the beam in unit of mc2
resWavelength = unduPeriod*(1+unduK**2/2.0)\
/(2*gamma0**2) # resonant wavelength
coopLength = resWavelength/unduPeriod # cooperation length
gainLength = 1 # rough gain length
#cs0 = bunchLength/coopLength # bunch length in units of cooperation length
z0 = unduL/gainLength # wiggler length in units of gain length
delt = z0/z_steps # integration step in z0 ~ 0.1 gain length
dels = delt # integration step in s0 must be same as in z0
gbar = (resWavelength-radWavelength)\
/(radWavelength) # scaled detune parameter
delg = eSpread # Gaussian energy spread in units of rho
Ns = currentMax*unduL/unduPeriod/z_steps\
*resWavelength/c/e # N electrons per s-slice [ ]
#load buckets
#[thet_init,eta_init]=general_load_bucket(npart,gbar,delg,iopt\
# ,Ns,coopLength,resWavelength,particle_position,s_steps,dels,hist_rule)
#load buckets
data = general_load_bucket(npart,Ns,coopLength,s_steps,dels,
particle_position=particle_position,
hist_rule=hist_rule,gbar=0,delg=None,iopt=None)
thet_init = data['thet_init']
eta_init = data['eta_init']
bunching=np.mean(np.real(np.exp(-1j*thet_init)),axis=1)\
+np.mean(np.imag(np.exp(-1j*thet_init)),axis=1)*1j #bunching factor calculation
bunching.shape
# whether to use constant random seed for reproducibility
if constseed==1:
np.random.seed(22)
# Some constant values
mc2 = 0.51099906E6#510.99906E-3 # Electron rest mass in eV
c = 2.99792458E8 # light speed in meter
e = 1.60217733E-19 # electron charge in Coulomb
gamma0 = energy/mc2 # central energy of the beam in unit of mc2
resWavelength = unduPeriod*(1+unduK**2/2.0)\
/(2*gamma0**2) # resonant wavelength
coopLength = resWavelength/unduPeriod # cooperation length
gainLength = 1 # rough gain length
#cs0 = bunchLength/coopLength # bunch length in units of cooperation length
z0 = unduL/gainLength # wiggler length in units of gain length
delt = z0/z_steps # integration step in z0 ~ 0.1 gain length
dels = delt # integration step in s0 must be same as in z0
gbar = (resWavelength-radWavelength)\
/(radWavelength) # scaled detune parameter
delg = eSpread # Gaussian energy spread in units of rho
Ns = currentMax*unduL/unduPeriod/z_steps\
*resWavelength/c/e # N electrons per s-slice [ ]
#load buckets
#[thet_init,eta_init]=general_load_bucket(npart,gbar,delg,iopt\
# ,Ns,coopLength,resWavelength,particle_position,s_steps,dels,hist_rule)
#load buckets
data = general_load_bucket(npart,Ns,coopLength,s_steps,dels,
particle_position=particle_position,
hist_rule=hist_rule,gbar=0,delg=None,iopt=None)
thet_init = data['thet_init']
eta_init = data['eta_init']
bunching=np.mean(np.real(np.exp(-1j*thet_init)),axis=1)\
+np.mean(np.imag(np.exp(-1j*thet_init)),axis=1)*1j #bunching factor calculation
bunching.shape
Out[5]:
(200,)
Verify whether the initial bunching level is reasonable¶
In [6]:
Copied!
print(np.sqrt(np.mean(np.absolute(bunching)**2)))
print(1/np.sqrt(Ns))
print(np.sqrt(np.mean(np.absolute(bunching)**2)))
print(1/np.sqrt(Ns))
0.0008998043866928952 0.0008389101946493842