Skip to content
Snippets Groups Projects
Commit a6efc774 authored by Vadim Gubaidulin's avatar Vadim Gubaidulin
Browse files

- added Chebyshev, Legendre and Sacherer (Sinusoidal)

 modes to effective impedance computation
 -  for transverse plane modes, the frequency sampling should be
 with fractional part of the transverse tune.
 Otherwise code does not work for single bunch case (M=1)
 - added head_tail_form_factor(), a function that computes only
  the denominator of the effective impedance.
  To be used to compute tune shifts in low intensity approximation
  - added tune_shift_from_effective_impedance() to implement it
  in the future
  - some autorefactoring
parent 290fc097
Branches
Tags
No related merge requests found
...@@ -10,6 +10,7 @@ from scipy.interpolate import interp1d ...@@ -10,6 +10,7 @@ from scipy.interpolate import interp1d
from mbtrack2.impedance.wakefield import Impedance from mbtrack2.impedance.wakefield import Impedance
from mbtrack2.utilities.spectrum import spectral_density from mbtrack2.utilities.spectrum import spectral_density
def effective_impedance(ring, imp, m, mu, sigma, M, tuneS, xi=None, def effective_impedance(ring, imp, m, mu, sigma, M, tuneS, xi=None,
mode="Hermite"): mode="Hermite"):
""" """
...@@ -56,19 +57,18 @@ def effective_impedance(ring, imp, m, mu, sigma, M, tuneS, xi=None, ...@@ -56,19 +57,18 @@ def effective_impedance(ring, imp, m, mu, sigma, M, tuneS, xi=None,
if fmin > 0: if fmin > 0:
double_sided_impedance(imp) double_sided_impedance(imp)
if mode == "Hermite": if mode in ["Hermite", "Legendre", "Sinusoidal", "Sacherer", "Chebyshev"]:
def h(f): def h(f):
return spectral_density(frequency=f, sigma=sigma, m=m, return spectral_density(frequency=f, sigma=sigma, m=m,
mode="Hermite") mode=mode)
else: else:
raise NotImplementedError("Not implemanted yet.") raise NotImplementedError("Not implemanted yet.")
if imp.component_type == "long":
pmax = fmax/(ring.f0 * M) - 1 pmax = fmax/(ring.f0 * M) - 1
pmin = fmin/(ring.f0 * M) + 1 pmin = fmin/(ring.f0 * M) + 1
p = np.arange(pmin, pmax+1) p = np.arange(pmin, pmax+1)
if imp.component_type == "long":
fp = ring.f0*(p*M + mu + m*tuneS) fp = ring.f0*(p*M + mu + m*tuneS)
fp = fp[np.nonzero(fp)] # Avoid division by 0 fp = fp[np.nonzero(fp)] # Avoid division by 0
num = np.sum(imp(fp) * h(fp) / (fp*2*np.pi)) num = np.sum(imp(fp) * h(fp) / (fp*2*np.pi))
...@@ -77,13 +77,16 @@ def effective_impedance(ring, imp, m, mu, sigma, M, tuneS, xi=None, ...@@ -77,13 +77,16 @@ def effective_impedance(ring, imp, m, mu, sigma, M, tuneS, xi=None,
elif imp.component_type == "xdip" or imp.component_type == "ydip": elif imp.component_type == "xdip" or imp.component_type == "ydip":
if imp.component_type == "xdip": if imp.component_type == "xdip":
tuneXY = ring.tune[0] tuneXY = ring.tune[0]-np.floor(ring.tune[0])
if xi is None: if xi is None:
xi = ring.chro[0] xi = ring.chro[0]
elif imp.component_type == "ydip": elif imp.component_type == "ydip":
tuneXY = ring.tune[1] tuneXY = ring.tune[1]-np.floor(ring.tune[1])
if xi is None: if xi is None:
xi = ring.chro[1] xi = ring.chro[1]
pmax = fmax/(ring.f0 * M) - 1
pmin = fmin/(ring.f0 * M) + 1
p = np.arange(pmin, pmax+1)
fp = ring.f0*(p*M + mu + tuneXY + m*tuneS) fp = ring.f0*(p*M + mu + tuneXY + m*tuneS)
f_xi = xi/ring.eta*ring.f0 f_xi = xi/ring.eta*ring.f0
num = np.sum(imp(fp) * h(fp - f_xi)) num = np.sum(imp(fp) * h(fp - f_xi))
...@@ -96,6 +99,55 @@ def effective_impedance(ring, imp, m, mu, sigma, M, tuneS, xi=None, ...@@ -96,6 +99,55 @@ def effective_impedance(ring, imp, m, mu, sigma, M, tuneS, xi=None,
return Zeff return Zeff
def head_tail_form_factor(ring, imp, m, sigma, tuneS, xi=None, mode="Hermite", mu=0):
M = 1
if not isinstance(imp, Impedance):
raise TypeError("{} should be an Impedance object.".format(imp))
fmin = imp.data.index.min()
fmax = imp.data.index.max()
if fmin > 0:
double_sided_impedance(imp)
if mode in ["Hermite", "Legendre", "Sinusoidal", "Sacherer", "Chebyshev"]:
def h(f):
return spectral_density(frequency=f, sigma=sigma, m=m,
mode=mode)
else:
raise NotImplementedError("Not implemanted yet.")
pmax = np.floor(fmax/(ring.f0 * M))
pmin = np.ceil(fmin/(ring.f0 * M))
p = np.arange(pmin, pmax+1)
if imp.component_type == "long":
fp = ring.f0*(p*M + mu + m*tuneS)
fp = fp[np.nonzero(fp)] # Avoid division by 0
den = np.sum(h(fp))
elif imp.component_type == "xdip" or imp.component_type == "ydip":
if imp.component_type == "xdip":
tuneXY = ring.tune[0]-np.floor(ring.tune[0])
if xi is None:
xi = ring.chro[0]
elif imp.component_type == "ydip":
tuneXY = ring.tune[1]-np.floor(ring.tune[0])
if xi is None:
xi = ring.chro[1]
fp = ring.f0*(p*M + mu + tuneXY + m*tuneS)
f_xi = xi/ring.eta*ring.f0
den = np.sum(h(fp - f_xi))
else:
raise TypeError("Effective impedance is only defined for long, xdip"
" and ydip impedance type.")
return den
def tune_shift_from_effective_impedance(Zeff):
pass
def yokoya_elliptic(x_radius, y_radius): def yokoya_elliptic(x_radius, y_radius):
""" """
Compute Yokoya factors for an elliptic beam pipe. Compute Yokoya factors for an elliptic beam pipe.
...@@ -154,6 +206,7 @@ def yokoya_elliptic(x_radius , y_radius): ...@@ -154,6 +206,7 @@ def yokoya_elliptic(x_radius , y_radius):
return (yoklong, yokxdip, yokydip, yokxquad, yokyquad) return (yoklong, yokxdip, yokydip, yokxquad, yokyquad)
def beam_loss_factor(impedance, frequency, spectrum, ring): def beam_loss_factor(impedance, frequency, spectrum, ring):
""" """
Compute "beam" loss factor using the beam spectrum, uses a sum instead of Compute "beam" loss factor using the beam spectrum, uses a sum instead of
...@@ -198,6 +251,7 @@ def beam_loss_factor(impedance, frequency, spectrum, ring): ...@@ -198,6 +251,7 @@ def beam_loss_factor(impedance, frequency, spectrum, ring):
return kloss_beam return kloss_beam
def double_sided_impedance(impedance): def double_sided_impedance(impedance):
""" """
Add negative frequency points to single sided impedance spectrum following Add negative frequency points to single sided impedance spectrum following
...@@ -236,4 +290,3 @@ def double_sided_impedance(impedance): ...@@ -236,4 +290,3 @@ def double_sided_impedance(impedance):
all_data = impedance.data.append(negative_data) all_data = impedance.data.append(negative_data)
all_data = all_data.sort_index() all_data = all_data.sort_index()
impedance.data = all_data impedance.data = all_data
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment