diff --git a/collective_effects/__init__.py b/collective_effects/__init__.py index 50123bb7163425ebe74e564e981faa67474b4e2d..bdea55f7291697a9d610b142d34d1f23d82ade5b 100644 --- a/collective_effects/__init__.py +++ b/collective_effects/__init__.py @@ -7,7 +7,7 @@ Created on Tue Jan 14 12:25:30 2020 from mbtrack2.collective_effects.instabilities import mbi_threshold, cbi_threshold from mbtrack2.collective_effects.resistive_wall import skin_depth, CircularResistiveWall -from mbtrack2.collective_effects.resonator import Resonator +from mbtrack2.collective_effects.resonator import Resonator, PureInductive, PureResistive from mbtrack2.collective_effects.tapers import StupakovRectangularTaper, StupakovCircularTaper from mbtrack2.collective_effects.wakefield import ComplexData, Impedance, WakeFunction, WakeField from mbtrack2.collective_effects.utilities import read_CST, read_IW2D, spectral_density diff --git a/collective_effects/resonator.py b/collective_effects/resonator.py index c6a083d86542067dd1e8916ab7bcfb3ee6592d79..f11948ee3abe5b923d4d5f66bbcf2e483b64df09 100644 --- a/collective_effects/resonator.py +++ b/collective_effects/resonator.py @@ -12,7 +12,7 @@ from mbtrack2.collective_effects.wakefield import (WakeField, Impedance, WakeFunction) class Resonator(WakeField): - def __init__(self, Rs, fr, Q, plane, n_wake=1e4, n_imp=1e4, imp_freq_lim=50e9): + def __init__(self, Rs, fr, Q, plane, n_wake=1e6, n_imp=1e6, imp_freq_lim=100e9): """ Resonator model WakeField element which computes the impedance and the wake function in both longitudinal and transverse case. @@ -28,11 +28,11 @@ class Resonator(WakeField): plane : str Plane on which the resonator is used: "long", "x" or "y". n_wake : int or float, optional - Number of points used in the wake function. The default is 1e4. + Number of points used in the wake function. n_imp : int or float, optional - Number of points used in the impedance. The default is 1e4. + Number of points used in the impedance. imp_freq_lim : float, optional - Maximum frequency used in the impedance. The default is 50e9. + Maximum frequency used in the impedance. References ---------- @@ -117,4 +117,76 @@ class Resonator(WakeField): else: return (self.wr * self.Rs / self.Q_p * np.exp(-1 * t * self.wr / 2 / self.Q_p) * - np.sinh(self.wr_p * t) ) \ No newline at end of file + np.sinh(self.wr_p * t) ) + +class PureInductive(WakeField): + """ + Pure inductive Wakefield element which computes associated longitudinal + impedance and wake function. + + Parameters + ---------- + L : float + Inductance value in [Ohm/Hz]. + n_wake : int or float, optional + Number of points used in the wake function. + n_imp : int or float, optional + Number of points used in the impedance. + imp_freq_lim : float, optional + Maximum frequency used in the impedance. + nout, trim : see Impedance.to_wakefunction + """ + def __init__(self, L, n_wake=1e6, n_imp=1e6, imp_freq_lim=1e11, nout=None, + trim=False): + self.L = L + self.n_wake = int(n_wake) + self.n_imp = int(n_imp) + self.imp_freq_lim = imp_freq_lim + + freq = np.linspace(start=1, stop=self.imp_freq_lim, num=self.n_imp) + imp = Impedance(variable=freq, + function=self.long_impedance(freq), + impedance_type="long") + super().append_to_model(imp) + + wf = imp.to_wakefunction(nout=nout, trim=trim) + super().append_to_model(wf) + + def long_impedance(self, f): + return 1j*self.L*f + +class PureResistive(WakeField): + """ + Pure resistive Wakefield element which computes associated longitudinal + impedance and wake function. + + Parameters + ---------- + R : float + Resistance value in [Ohm]. + n_wake : int or float, optional + Number of points used in the wake function. + n_imp : int or float, optional + Number of points used in the impedance. + imp_freq_lim : float, optional + Maximum frequency used in the impedance. + nout, trim : see Impedance.to_wakefunction + """ + def __init__(self, R, n_wake=1e6, n_imp=1e6, imp_freq_lim=1e11, nout=None, + trim=False): + self.R = R + self.n_wake = int(n_wake) + self.n_imp = int(n_imp) + self.imp_freq_lim = imp_freq_lim + + freq = np.linspace(start=1, stop=self.imp_freq_lim, num=self.n_imp) + imp = Impedance(variable=freq, + function=self.long_impedance(freq), + impedance_type="long") + super().append_to_model(imp) + + wf = imp.to_wakefunction(nout=nout, trim=trim) + super().append_to_model(wf) + + def long_impedance(self, f): + return self.R \ No newline at end of file diff --git a/collective_effects/wakefield.py b/collective_effects/wakefield.py index 01fa913dfcaa94a85d881bfb0557f464764782fa..ee372cb5f06023070b4671336860de968e886eab 100644 --- a/collective_effects/wakefield.py +++ b/collective_effects/wakefield.py @@ -569,13 +569,14 @@ class Impedance(ComplexData): def to_wakefunction(self, nout=None, trim=False): """ Return a WakeFunction object from the impedance data. + The impedance data is assumed to be sampled equally. Parameters ---------- - nout : int, optional + nout : int or float, optional Length of the transformed axis of the output. If None, it is taken to be 2*(n-1) where n is the length of the input. If nout > n, the - input is padded with zeros. If nout < n, the inpu it cropped. + input is padded with zeros. If nout < n, the input it cropped. Note that, for any nout value, nout//2+1 input points are required. trim : bool or float, optional If True, the pseudo wake function is trimmed at time=0 and is forced @@ -597,6 +598,8 @@ class Impedance(ComplexData): if nout is None: nout = len(Z) + else: + nout = int(nout) time_array = sc.fft.fftfreq(nout, sampling) Wlong_raw = sc.fft.irfft(np.array(Z), n=nout, axis=0) * nout * fs