Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce an RF frequency shift input to specify off-momentum computation #501

Merged
merged 4 commits into from
Oct 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions atmat/atphysics/LinearOptics/atlinopt4.m
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@
% corresponding to a frequency shift. The resulting deltap/p is returned
% in the 5th component of the ClosedOrbit field.
%
% [...] = ATLINOPT4(...,'df',DF)
% Analyses the off-momentum lattice by specifying the RF frequency shift.
% The resulting deltap/p is returned in the 5th component of the ClosedOrbit field.
%
% [...] = ATLINOPT4(...,'orbit',ORBITIN)
% Do not search for closed orbit. Instead ORBITIN,a 6x1 vector
% of initial conditions is used: [x0; px0; y0; py0; DP; 0].
Expand All @@ -80,7 +84,7 @@
% [3] Brian W. Montague Report LEP Note 165, CERN, 1979
% [4] D.Sagan, D.Rubin Phys.Rev.Spec.Top.-Accelerators and beams, vol.2 (1999)
%
% See also atlinopt atlinopt2 atlinopt6 tunechrom
% See also atlinopt2 atlinopt6 tunechrom

% [...] = ATLINOPT4(...,'coupled',flag)
% Private keyword for computation without coupling (used for atlinopt2)
Expand All @@ -94,9 +98,9 @@
[get_chrom,varargs]=getflag(varargin,'get_chrom');
[get_w,varargs]=getflag(varargs,'get_w');
[twiss_in,varargs]=getoption(varargs,'twiss_in',[]);
[dp,varargs]=getoption(varargs,'dp',0.0);
[dpargs,varargs]=getoption(varargs,{'orbit','dct','df'});
[orbitin,varargs]=getoption(varargs,'orbit',[]);
[ct,varargs]=getoption(varargs,'ct',NaN);
[dp,varargs]=getoption(varargs,'dp',0);
[coupled,varargs]=getoption(varargs,'coupled',true);
[mkey,varargs]=getoption(varargs,'mkey','M');
[DPStep,varargs]=getoption(varargs,'DPStep');
Expand All @@ -116,7 +120,7 @@
end

if isempty(twiss_in) % Circular machine
[orbit,orbitin]=findorbit(ring,refpts,'dp',dp,'ct',ct,'orbit',orbitin,'XYStep',XYStep);
[orbit,orbitin]=findorbit4(ring,dp,refpts,dpargs{:},'XYStep',XYStep);
dp=orbitin(5);
[orbitP,o1P]=findorbit4(ring,dp+0.5*DPStep,refpts,orbitin,'XYStep',XYStep);
[orbitM,o1M]=findorbit4(ring,dp-0.5*DPStep,refpts,orbitin,'XYStep',XYStep);
Expand Down Expand Up @@ -198,7 +202,7 @@
'gamma',gamma, 'C',CL, 'A',AL, 'B',BL,...
'beta',num2cell([BX,BY],2),...
'alpha',num2cell([AX,AY],2),...
'mu',num2cell([MX,MY],2));
'mu',num2cell([MX,MY],2))';

if get_w
% Calculate optics for DP +/- DDP
Expand Down
9 changes: 6 additions & 3 deletions atmat/atphysics/LinearOptics/atlinopt6.m
Original file line number Diff line number Diff line change
Expand Up @@ -67,23 +67,26 @@
% Specify off-momentum
%
% [...] = ATLINOPT6(...,'dct',DCT)
% Specify path lengthening
% Specify the path lengthening
%
% [...] = ATLINOPT6(...,'df',DF)
% Specify the RF frequency deviation
%
% REFERENCES
% [1] Etienne Forest, Phys. Rev. E 58, 2481 – Published 1 August 1998
% [2] Andrzej Wolski, Phys. Rev. ST Accel. Beams 9, 024001 –
% Published 3 February 2006
% [3] Brian W. Montague Report LEP Note 165, CERN, 1979
%
% See also atlinopt atlinopt2 atlinopt4 tunechrom
% See also atlinopt2 atlinopt4 tunechrom

[ringdata,elemdata]=wrapper6d(ring,@xlinopt6,varargin{:});

function [ringdata,elemdata] = xlinopt6(ring, is6d, varargin)
clight = PhysConstant.speed_of_light_in_vacuum.value; % m/s
[get_chrom, varargs]=getflag(varargin, 'get_chrom');
[get_w, varargs]=getflag(varargs, 'get_w');
[dpargs,varargs]=getoption(varargs,{'orbit','dp','dct'});
[dpargs,varargs]=getoption(varargs,{'orbit','dp','dct','df'});
[twiss_in,varargs]=getoption(varargs,'twiss_in',[]);
[DPStep,~]=getoption(varargs,'DPStep');
[cavargs,varargs]=getoption(varargs,{'cavpts'});
Expand Down
35 changes: 18 additions & 17 deletions atmat/atphysics/LinearOptics/findm44.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function [M44, varargout] = findm44(LATTICE,dp,varargin)
function [M44, varargout] = findm44(LATTICE,varargin)
%FINDM44 numerically finds the 4x4 transfer matrix of an accelerator lattice
% for a particle with relative momentum deviation DP
%
Expand All @@ -8,12 +8,12 @@
% (cavities , magnets with radiation, ...)
% 2.have any time dependence (localized impedance, fast kickers, ...)
%
% M44 = FINDM44(LATTICE,DP) finds the full one-turn
% M44 = FINDM44(LATTICE) finds the full one-turn
% matrix at the entrance of the first element
% !!! With this syntax FINDM44 assumes that the LATTICE
% is a ring and first finds the closed orbit
%
% [M44,T] = FINDM44(LATTICE,DP,REFPTS) also returns
% [M44,T] = FINDM44(LATTICE,REFPTS) also returns
% 4x4 transfer matrixes between entrance of
% the first element and each element indexed by REFPTS.
% T is 4x4xlength(REFPTS) 3 dimensional array
Expand All @@ -32,7 +32,17 @@
% it is also the entrance of the first element
% after 1 turn: T(:,:,end) = M
%
% [...] = FINDM44(...,'orbit',ORBITIN)
% [...] = FINDM44(RING,...,'dp',DP)
% [...] = FINDM44(RING,DP,REFPTS,...) (Deprecated syntax)
% Computes for the off-momentum DP
%
% [...] = FINDM44(RING,...,'dct',DCT)
% Computes for the path lenghening specified by CT.
%
% [...] = FINDM44(RING,...,'df',DF)
% Computes for a deviation of RF frequency DF
%
% [...] = FINDM44(RING,...,'orbit',ORBITIN)
% [...] = FINDM44(RING,DP,REFPTS,ORBITIN) (Deprecated syntax)
% Do not search for closed orbit. Instead ORBITIN,a 6x1 vector
% of initial conditions is used: [x0; px0; y0; py0; DP; 0].
Expand All @@ -44,11 +54,6 @@
% Same as above except that matrices returned in T are full 1-turn
% matrices at the entrance of each element indexed by REFPTS.
%
% [...] = FINDM44(...,'ct',CT)
% Instead of computing the linear optics for the specified DP/P,
% computes for the path lenghening specified by CT.
% The DP argument is ignored.
%
% [M44,T,orbit] = FINDM44(...)
% In addition returns the closed orbit at the entrance of each element
% indexed by REFPTS.
Expand All @@ -62,10 +67,6 @@
% --------------------------------------
% 2*delta
%
% with optimal differentiation step delta given by !!!! DO LATER
% The relative error in the derivative computed this way
% is !!!!!!!!!!!!!!!!! DO LATER
% Reference: Numerical Recipes.

if ~iscell(LATTICE)
error('First argument must be a cell array');
Expand All @@ -74,7 +75,9 @@
[fullflag,varargs]=getflag(varargin,'full');
[XYStep,varargs]=getoption(varargs,'XYStep');
[orbitin,varargs]=getoption(varargs,'orbit',[]);
[ct,varargs]=getoption(varargs,'ct',NaN);
varargs=getdparg(varargs);
[dp,varargs]=getoption(varargs,'dp',0.0);
[dpargs,varargs]=getoption(varargs,{'dct','df'});
[refpts,orbitin,varargs]=getargs(varargs,[],orbitin,'check',@(x) ~(ischar(x) || isstring(x))); %#ok<ASGLU>

if islogical(refpts)
Expand All @@ -90,10 +93,8 @@
dp=orbitin(5);
end
orbitin = [orbitin(1:4);dp;0];
elseif isnan(ct)
[~,orbitin] = findorbit4(LATTICE,dp);
else
[~,orbitin]=findsyncorbit(LATTICE,ct);
[~,orbitin]=findorbit4(LATTICE,'dp',dp,dpargs{:});
end

refs=setelems(refpts,NE+1); % Add end-of-lattice
Expand Down
23 changes: 15 additions & 8 deletions atmat/atphysics/LongitudinalDynamics/atsetcavity.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,20 @@
% Set the cavity frequency to the nominal value according to
% circumference and harmonic number
%
%NEWRING=ATSETCAVITY(RING,...,'Frequency','nominal','dp',dp)
%NEWRING=ATSETCAVITY(RING,...,'Frequency','nominal','dp',DP)
% Set the cavity frequency to the nominal value for the specified dp
%
%NEWRING=ATSETCAVITY(RING,...,'Frequency','nominal','dct',dct)
%NEWRING=ATSETCAVITY(RING,...,'Frequency','nominal','dct',DCT)
% Set the cavity frequency to the nominal value for the specified dct
%
%NEWRING=ATSETCAVITY(RING,...,'Frequency','nominal','df',DF)
% Set the cavity frequency to the nominal value + df
%
%NEWRING=ATSETCAVITY(RING,...,'Voltage',VOLTAGE,...)
% Set the total voltage (all cells) [V]
% The voltage of each cavity is VOLTAGE / N_CAVITIES / PERIODICITY
%
%NEWRING=ATSETCAVITY(RING,...,'HarmNumber',h,...)
%NEWRING=ATSETCAVITY(RING,...,'HarmNumber',H,...)
% Set the harmonic number
%
%NEWRING=ATSETCAVITY(RING,...,'TimeLag',TIMELAG,...)
Expand Down Expand Up @@ -61,7 +64,7 @@
% on radflag says whether or not we want radiation on, which affects
% synchronous phase.
%
% See also atSetCavityPhase, atsetRFcavity, atradon, atradoff, atgetU0
% See also atSetCavityPhase, atsetRFcavity, atenable_6d, atdisable_6d, atgetU0

% Speed of light
CLIGHT=PhysConstant.speed_of_light_in_vacuum.value;
Expand All @@ -74,6 +77,7 @@
[timelag,varargs]=getoption(varargs, 'TimeLag', []);
[dp,varargs]=getoption(varargs,'dp',NaN);
[dct,varargs]=getoption(varargs,'dct',NaN);
[df,varargs]=getoption(varargs,'df',NaN);

if isempty(cavpts)
[ncells,cell_h,beta0,cavpts]=atGetRingProperties(ring,'Periodicity','cell_harmnumber','beta','cavpts');
Expand All @@ -96,7 +100,10 @@
lcell=findspos(ring,length(ring)+1);
frev=beta0*CLIGHT/lcell;
if (ischar(frequency) || isstring(frequency)) && strcmp(frequency, 'nominal')
if isfinite(dct)
hh=props_harmnumber(harmcell,cell_h);
if isfinite(df)
frev = frev + df/hh;
elseif isfinite(dct)
frev=frev * lcell/(lcell+dct);
elseif isfinite(dp)
% Find the path lengthening for dp
Expand All @@ -106,7 +113,7 @@
dct=orbitout(6);
frev=frev * lcell/(lcell+dct);
end
frequency = frev * props_harmnumber(harmcell,cell_h);
frequency = hh * frev;
else
harmcell=round(frequency/frev);
end
Expand Down Expand Up @@ -138,9 +145,9 @@
if radflag
U0=atgetU0(ring);
timelag= (lcell/(2*pi*harmcell))*asin(U0/vring);
ring=atradon(ring); % set radiation on. nothing if radiation is already on
ring=atenable_6d(ring); % set radiation on. nothing if radiation is already on
else
ring=atradoff(ring,'RFCavityPass'); % set radiation off. nothing if radiation is already off
ring=atdisable_6d(ring,'cavipass',''); % set radiation off. nothing if radiation is already off
timelag=0;
end
ring=atsetfieldvalues(ring, cavpts, 'TimeLag', timelag);
Expand Down
127 changes: 68 additions & 59 deletions atmat/atphysics/Orbit/findorbit.m
Original file line number Diff line number Diff line change
@@ -1,59 +1,68 @@
function [orbs,orbitin] = findorbit(ring,varargin)
%FINDORBIT find the closed orbit
%
%Depending on the lattice, FINDORBIT will:
% - use findorbit6 if radiation is ON,
% - use findsyncorbit if radiation is OFF and ct is specified,
% - use findorbit4 otherwise
%
%[ORBIT,FIXEDPOINT]=FINDORBIT(RING,REFPTS)
%
% ORBIT: 6xNrefs, closed orbit at the selected reference points
% FIXEDPOINT: 6x1 closed orbit at the entrance of the lattice
%
%[...]=FINDORBIT(RING,...,'dp',DP) Specify the momentum deviation when
% radiation is OFF (default: 0)
%
%[...]=FINDORBIT(RING,...,'dct',DCT) Specify the path lengthening when
% radiation is OFF (default: 0)
%
%[...]=FINDORBIT(RING,...,'orbit',ORBIT) Specify the orbit at the entrance
% of the ring, if known. FINDORBIT will then transfer it to the reference points
%
%[...]=FINDORBIT(RING,...,'guess',GUESS) The search will start with GUESS as
% initial conditions
%
%For other keywords, see the underlying functions.
%
% See also FINDORBIT4, FINDSYNCORBIT, FINDORBIT6.

[orbitin,varargs]=getoption(varargin,'orbit',[]);
[refpts,varargs]=getargs(varargs,[],'check',@(arg) isnumeric(arg) || islogical(arg));
[dp,varargs]=getoption(varargs,'dp',NaN);
[dct,varargs]=getoption(varargs,'dct',NaN);
if isempty(orbitin)
if check_radiation(ring) % Radiation ON: 6D orbit
if isfinite(dp) || isfinite(dct)
warning('AT:linopt','In 6D, "dp" and "dct" are ignored');
end
orbitin=xorbit_6(ring,varargs{:});
elseif isfinite(dct)
orbitin=xorbit_ct(ring,dct,varargs{:});
else
orbitin=xorbit_dp(ring,dp,varargs{:});
end
args={'KeepLattice'};
else
args={};
end

if islogical(refpts)
refpts=find(refpts);
end
if isempty(refpts)
% return only the fixed point at the entrance of RING{1}
orbs=orbitin;
else
orbs=linepass(ring,orbitin,refpts,args{:});
end
end
function [orbs,orbitin] = findorbit(ring,varargin)
%FINDORBIT find the closed orbit
%
%Depending on the lattice, FINDORBIT will:
% - use findorbit6 if radiation is ON,
% - use findsyncorbit if radiation is OFF and ct is specified,
% - use findorbit4 otherwise
%
%[ORBIT,FIXEDPOINT]=FINDORBIT(RING,REFPTS)
%
% ORBIT: 6xNrefs, closed orbit at the selected reference points
% FIXEDPOINT: 6x1 closed orbit at the entrance of the lattice
%
%[...]=FINDORBIT(RING,...,'dp',DP) Specify the momentum deviation when
% radiation is OFF (default: 0)
%
%[...]=FINDORBIT(RING,...,'dct',DCT) Specify the path lengthening when
% radiation is OFF (default: 0)
%
%[...]=FINDORBIT(RING,...,'df',DF) Specify the RF frequency deviation
% radiation is OFF (default: 0)
%
%[...]=FINDORBIT(RING,...,'orbit',ORBIT) Specify the orbit at the entrance
% of the ring, if known. FINDORBIT will then transfer it to the reference points
%
%[...]=FINDORBIT(RING,...,'guess',GUESS) The search will start with GUESS as
% initial conditions
%
%For other keywords, see the underlying functions.
%
% See also FINDORBIT4, FINDSYNCORBIT, FINDORBIT6.

[orbitin,varargs]=getoption(varargin,'orbit',[]);
[refpts,varargs]=getargs(varargs,[],'check',@(arg) isnumeric(arg) || islogical(arg));
[dp,varargs]=getoption(varargs,'dp',NaN);
[dct,varargs]=getoption(varargs,'dct',NaN);
[df,varargs]=getoption(varargs,'df',NaN);
if isempty(orbitin)
if check_6d(ring) % Radiation ON: 6D orbit
if isfinite(dp) || isfinite(dct) || isfinite(df)
warning('AT:linopt','In 6D, "dp", "dct" and "df" are ignored');
end
orbitin=xorbit_6(ring,varargs{:});
elseif isfinite(df)
[cell_l,cell_frev,cell_h]=atGetRingProperties(ring,'cell_length',...
'cell_harmnumber','cell_revolution_frequency');
dct=-cell_l*df/(cell_frev*cell_h+df);
orbitin=xorbit_ct(ring,dct,varargs{:});
elseif isfinite(dct)
orbitin=xorbit_ct(ring,dct,varargs{:});
else
orbitin=xorbit_dp(ring,dp,varargs{:});
end
args={'KeepLattice'};
else
args={};
end

if islogical(refpts)
refpts=find(refpts);
end
if isempty(refpts)
% return only the fixed point at the entrance of RING{1}
orbs=orbitin;
else
orbs=linepass(ring,orbitin,refpts,args{:});
end
end
Loading