1 | function orbit = findorbit6(RING,varargin); |
---|
2 | %FINDORBIT6 finds closed orbit in the full 6-d phase space |
---|
3 | % by numerically solving for a fixed point of the one turn |
---|
4 | % map M calculated with RINGPASS |
---|
5 | % |
---|
6 | % (X, PX, Y, PY, DP, CT2 ) = M (X, PX, Y, PY, DP, CT1) |
---|
7 | % |
---|
8 | % with constraint % CT2 - CT1 = C*HarmNumber(1/Frf - 1/Frf0) |
---|
9 | % |
---|
10 | % IMPORTANT!!! FINDORBIT6 is a realistic simulation |
---|
11 | % 1. The Frf frequency in the RF cavities (may be different from Frf0) |
---|
12 | % imposes the synchronous condition |
---|
13 | % CT2 - CT1 = C*HarmNumber(1/Frf - 1/Frf0) |
---|
14 | % 2. The algorithm numerically calculates |
---|
15 | % 6-by-6 Jacobian matrix J6. In order for (J-E) matrix |
---|
16 | % to be non-singular it is NECESSARY to use a realistic |
---|
17 | % PassMethod for cavities with non-zero momentum kick |
---|
18 | % (such as ThinCavityPass). |
---|
19 | % 3. FINDORBIT6 can find orbits with radiation. |
---|
20 | % In order for the solution to exist the cavity must supply |
---|
21 | % adequate energy compensation. |
---|
22 | % In the simplest case of a single cavity, it must have |
---|
23 | % 'Voltage' field set so that Voltage > Erad - energy loss per turn |
---|
24 | % 4. FINDORBIT6 starts the search from [ 0 0 0 0 0 0 ]', unless |
---|
25 | % the third argument is specified: FINDORBIT6(RING,REFPTS,GUESS) |
---|
26 | % There exist a family of solutions that correspond to different RF buckets |
---|
27 | % They differ in the 6-th coordinate by C*Nb/Frf. Nb = 1 .. HarmNum-1 |
---|
28 | % 5. The value of the 6-th coordinate found at the cavity gives |
---|
29 | % the equilibrium RF phase. If there is no radiation the phase is 0; |
---|
30 | % |
---|
31 | % FINDORBIT6(RING) is 6x1 vector - fixed point at the |
---|
32 | % entrance of the 1-st element of the RING (x,px,y,py,dp,ct) |
---|
33 | % |
---|
34 | % FINDORBIT6(RING,REFPTS) is 6-by-Length(REFPTS) |
---|
35 | % array of column vectors - fixed points (x,px,y,py,dp,ct) |
---|
36 | % at the entrance of each element indexed REFPTS array. |
---|
37 | % REFPTS is an array of increasing indexes that select elements |
---|
38 | % from the range 1 to length(RING)+1. |
---|
39 | % See further explanation of REFPTS in the 'help' for FINDSPO |
---|
40 | % |
---|
41 | % FINDORBIT6(RING,REFPTS,GUESS) - same as above but the search |
---|
42 | % for the fixed point starts at the initial condition GUESS |
---|
43 | % GUESS must be a 6-by-1 vector; |
---|
44 | % |
---|
45 | % [ORBIT, FIXEDPOINT] = FINDORBIT6( ... ) |
---|
46 | % The optional second return parameter is |
---|
47 | % a 6-by-1 vector of initial conditions |
---|
48 | % on the close orbit at the entrance to the RING. |
---|
49 | % |
---|
50 | % See also FINDORBIT, FINDORBIT4, FINDSYNCORBIT. |
---|
51 | |
---|
52 | if ~iscell(RING) |
---|
53 | error('First argument must be a cell array'); |
---|
54 | end |
---|
55 | |
---|
56 | |
---|
57 | L0 = findspos(RING,length(RING)+1); % design length [m] |
---|
58 | C0 = 299792458; % speed of light [m/s] |
---|
59 | T0 = L0/C0; |
---|
60 | |
---|
61 | CavityLocation = findcells(RING,'Frequency'); |
---|
62 | Frf = RING{CavityLocation(1)}.Frequency; |
---|
63 | |
---|
64 | if ~isfield(RING{CavityLocation(1)},'HarmNumber') |
---|
65 | error('FINDORBIT6 needs the HarmNumber field to be defined in RF cavity elements'); |
---|
66 | end |
---|
67 | HarmNumber = RING{CavityLocation(1)}.HarmNumber; |
---|
68 | theta = [0 0 0 0 0 C0*(HarmNumber/Frf - T0)]'; |
---|
69 | |
---|
70 | |
---|
71 | d = 1e-6; % step size for numerical differentiation |
---|
72 | max_iterations = 20; |
---|
73 | |
---|
74 | if nargin==3 |
---|
75 | if isnumeric(varargin{2}) & all(eq(size(varargin{2}),[6,1])) |
---|
76 | Ri=varargin{2}; |
---|
77 | else |
---|
78 | error('The last argument GUESS must be a 6-by-1 vector'); |
---|
79 | end |
---|
80 | else |
---|
81 | Ri = zeros(6,1); |
---|
82 | end |
---|
83 | D = d*eye(6); |
---|
84 | |
---|
85 | RMATi= [Ri Ri Ri Ri Ri Ri Ri] + [D, zeros(6,1)]; |
---|
86 | RMATf = linepass(RING,RMATi); |
---|
87 | J6 = (RMATf(:,1:6)-RMATf(:,7)*ones(1,6))/d; |
---|
88 | Rf = RMATf(:,7); |
---|
89 | % Replace matrix inversion with \ |
---|
90 | % B = inv(eye(6)-J6); |
---|
91 | % Ri_next = Ri + B*(Rf-Ri-theta); |
---|
92 | Ri_next = Ri + (eye(6)-J6)\(Rf-Ri-theta); |
---|
93 | change = norm(Ri_next - Ri); |
---|
94 | Ri = Ri_next; |
---|
95 | |
---|
96 | itercount = 1; |
---|
97 | |
---|
98 | |
---|
99 | while (change>eps) & (itercount < max_iterations) |
---|
100 | RMATi= [Ri Ri Ri Ri Ri Ri Ri] + [D, zeros(6,1)]; |
---|
101 | RMATf = linepass(RING,RMATi,'reuse'); |
---|
102 | J6 = (RMATf(:,1:6)-RMATf(:,7)*ones(1,6))/d; |
---|
103 | Rf = RMATf(:,7); |
---|
104 | % Replace matrix inversion with \ |
---|
105 | % B = inv(eye(6)-J6); |
---|
106 | % Ri_next = Ri + B*(Rf-Ri-theta); |
---|
107 | Ri_next = Ri + (eye(6)-J6)\(Rf-Ri-theta); |
---|
108 | change = norm(Ri_next - Ri); |
---|
109 | Ri = Ri_next; |
---|
110 | itercount = itercount+1; |
---|
111 | end; |
---|
112 | |
---|
113 | if itercount == max_iterations |
---|
114 | warning('Maximum number of iterations reached. Possible non-convergence') |
---|
115 | end |
---|
116 | if(nargin==1)|(varargin{1}==(length(RING)+1)) |
---|
117 | % return only the fixed point at the entrance of RING{1} |
---|
118 | orbit=Ri; |
---|
119 | else % 2-nd input argument - vector of reference points alog the Ring |
---|
120 | % is supplied - return orbit |
---|
121 | orbit = linepass(RING,Ri,varargin{1},'reuse'); |
---|
122 | end |
---|
123 | |
---|
124 | if nargout==2 |
---|
125 | varargout{1}=Ri; |
---|
126 | end |
---|