function [orbit, varargout] = findsyncorbit(RING,dCT,varargin); %FINDSYNCORBIT finds closed orbit, synchronous with the RF cavity % and momentum deviation dP (first 5 components of the phase space vector) % by numerically solving for a fixed point % of the one turn map M calculated with LINEPASS % % (X, PX, Y, PY, dP2, CT2 ) = M (X, PX, Y, PY, dP1, CT1) % % under constraints CT2 - CT1 = dCT = C(1/Frev - 1/Frev0) and dP2 = dP1 , where % Frev0 = Frf0/HarmNumber is the design revolution frequency % Frev = (Frf0 + dFrf)/HarmNumber is the imposed revolution frequency % % IMPORTANT!!! FINDSYNCORBIT imposes a constraint (CT2 - CT1) and % dP2 = dP1 but no constraint on the value of dP1, dP2 % The algorithm assumes time-independent fixed-momentum ring % to reduce the dimensionality of the problem. % To impose this artificial constraint in FINDSYNCORBIT % PassMethod used for any element SHOULD NOT % 1. change the longitudinal momentum dP (cavities , magnets with radiation) % 2. have any time dependence (localized impedance, fast kickers etc). % % % FINDSYNCORBIT(RING,dCT) is 5x1 vector - fixed point at the % entrance of the 1-st element of the RING (x,px,y,py,dP) % % FINDSYNCORBIT(RING,dCT,REFPTS) is 5-by-Length(REFPTS) % array of column vectors - fixed points (x,px,y,py,dP) % at the entrance of each element indexed in REFPTS array. % REFPTS is an array of increasing indexes that select elements % from the range 1 to length(RING)+1. % See further explanation of REFPTS in the 'help' for FINDSPOS % % FINDSYNCORBIT(RING,dCT,REFPTS,GUESS) - same as above but the search % for the fixed point starts at the initial condition GUESS % Otherwise the search starts from [0 0 0 0 0 0]'. % GUESS must be a 6-by-1 vector; % % [ORBIT, FIXEDPOINT] = FINDSYNCORBIT( ... ) % The optional second return parameter is % a 6-by-1 vector of initial conditions % on the close orbit at the entrance to the RING. % % See also FINDORBIT, FINDORBIT4, FINDORBIT6. % if ~iscell(RING) error('First argument must be a cell array'); end d = 1e-9; % step size for numerical differentiation max_iterations = 20; J = zeros(5); if nargin==4 if isnumeric(varargin{2}) & all(eq(size(varargin{2}),[6,1])) Ri=varargin{2}; else error('The last argument GUESS must be a 6-by-1 vector'); end else Ri = zeros(6,1); end D5 = d*eye(5); %B5 = zeros(5,5); RMATi = zeros(6,6); theta5 = [0 0 0 0 dCT]'; %Fist iteration RMATi= Ri*ones(1,6) + [D5 zeros(5,1); zeros(1,6)]; RMATf = linepass(RING,RMATi); Rf = RMATf(:,6); % compute the transverse part of the Jacobian J5 = [RMATf([1:4,6],1:5)-RMATf([1:4,6],6)*ones(1,5)]/d; % Replace matrix inversion with \ %B5 = inv(diag([1 1 1 1 0]) - J5); % Ri_next = Ri + [B5* (Rf([1:4,6])-[Ri(1:4);0]-theta5) ; 0]; Ri_next = Ri + [(diag([1 1 1 1 0]) - J5)\(Rf([1:4,6])-[Ri(1:4);0]-theta5) ; 0]; change = norm(Ri_next - Ri); Ri = Ri_next; itercount = 1; while (change>eps) & (itercount < max_iterations) RMATi= Ri*ones(1,6) + [D5 zeros(5,1); zeros(1,6)]; RMATf = linepass(RING,RMATi,'reuse'); Rf = RMATf(:,6); % compute the transverse part of the Jacobian J5 = [RMATf([1:4,6],1:5)-RMATf([1:4,6],6)*ones(1,5)]/d; % Replace matrix inversion with \ %B5 = inv(diag([1 1 1 1 0]) - J5); %Ri_next = Ri + [B5*(Rf([1:4,6])-[Ri(1:4);0]-theta5); 0]; Ri_next = Ri + [(diag([1 1 1 1 0]) - J5)\(Rf([1:4,6])-[Ri(1:4);0]-theta5); 0]; change = norm(Ri_next - Ri); Ri = Ri_next; itercount = itercount+1; end; if(nargin<3) | (varargin{1}==(length(RING)+1)) % return only the fixed point at the entrance of RING{1} orbit=Ri(1:5,1); else % 3-rd input argument - vector of reference points along the Ring % is supplied - return orbit orb6 = linepass(RING,Ri,varargin{1},'reuse'); orbit = orb6(1:5,:); end if nargout==2 varargout{1}=Ri; end