|
1 | | -function [M66, varargout] = findm66(LATTICE, varargin) |
| 1 | +function varargout = findm66(LATTICE, varargin) |
2 | 2 | %FINDM66 numerically finds the 6x6 transfer matrix of an accelerator lattice |
3 | 3 | % by differentiation of LINEPASS near the closed orbit |
4 | 4 | % FINDM66 uses FINDORBIT6 to search for the closed orbit in 6-d |
|
7 | 7 | % M66 = FINDM66(RING) finds the full one-turn 6-by-6 |
8 | 8 | % matrix at the entrance of the first element |
9 | 9 | % |
| 10 | +%[...]=FINDM66(RING,...,'dp',DP) Specify the momentum deviation when |
| 11 | +% radiation is OFF (default: 0) |
| 12 | +% |
| 13 | +%[...]=FINDM66(RING,...,'dct',DCT) Specify the path lengthening when |
| 14 | +% radiation is OFF (default: 0) |
| 15 | +% |
| 16 | +%[...]=FINDM66(RING,...,'df',DF) Specify the RF frequency deviation |
| 17 | +% radiation is OFF (default: 0) |
| 18 | +% |
| 19 | +%[...]=FINDM66(RING,...,'orbit',ORBIT) Specify the orbit at the entrance |
| 20 | +% of the ring, if known. |
| 21 | +% |
10 | 22 | % [M66,T] = FINDM66(RING,REFPTS) in addition to M finds |
11 | 23 | % 6-by-6 transfer matrixes between entrances of |
12 | 24 | % the first element and each element indexed by REFPTS. |
|
37 | 49 | if ~iscell(LATTICE) |
38 | 50 | error('First argument must be a cell array'); |
39 | 51 | end |
40 | | -NE = length(LATTICE); |
41 | | -[XYStep,varargs]=getoption(varargin,'XYStep'); % Step size for numerical differentiation %1.e-8 |
42 | | -[DPStep,varargs]=getoption(varargs,'DPStep'); % Step size for numerical differentiation %1.e-6 |
43 | | -[orbitin,varargs]=getoption(varargs,'orbit',[]); |
44 | | -[refpts,orbitin,varargs]=getargs(varargs,[],orbitin,'check',@(x) ~(ischar(x) || isstring(x))); %#ok<ASGLU> |
| 52 | +[varargout{1:nargout}] = frequency_control(@xfindm66,LATTICE,varargin{:}); |
45 | 53 |
|
46 | | -if islogical(refpts) |
47 | | - refpts(end+1:NE+1)=false; |
48 | | -elseif isnumeric(refpts) |
49 | | - refpts=setelems(false(1,NE+1),refpts); |
50 | | -else |
51 | | - error('REFPTS must be numeric or logical'); |
52 | | -end |
| 54 | + function [M66, varargout] = xfindm66(LATTICE, varargin) |
| 55 | + NE = length(LATTICE); |
| 56 | + [XYStep,varargs]=getoption(varargin,'XYStep'); % Step size for numerical differentiation %1.e-8 |
| 57 | + [DPStep,varargs]=getoption(varargs,'DPStep'); % Step size for numerical differentiation %1.e-6 |
| 58 | + [orbitin,varargs]=getoption(varargs,'orbit',[]); |
| 59 | + [dpargs,varargs]=getoption(varargs,{'dp','dct','df'}); |
| 60 | + [is_6d,varargs]=getoption(varargs,'is_6d',[]); % Always set by frequency_control |
| 61 | + [refpts,orbitin,varargs]=getargs(varargs,[],orbitin,'check',@(x) ~(ischar(x) || isstring(x))); %#ok<ASGLU> |
53 | 62 |
|
54 | | -if isempty(orbitin) |
55 | | - if check_radiation(LATTICE) |
56 | | - orbitin = findorbit6(LATTICE,'XYStep',XYStep,'DPStep',DPStep); |
57 | | - else |
58 | | - [~, orbitin] = findorbit4(LATTICE,0.0,'XYStep',XYStep); |
59 | | - end |
60 | | -end |
| 63 | + if islogical(refpts) |
| 64 | + refpts(end+1:NE+1)=false; |
| 65 | + elseif isnumeric(refpts) |
| 66 | + refpts=setelems(false(1,NE+1),refpts); |
| 67 | + else |
| 68 | + error('REFPTS must be numeric or logical'); |
| 69 | + end |
61 | 70 |
|
62 | | -refs=setelems(refpts,NE+1); |
63 | | -reqs=refpts(refs); |
| 71 | + if isempty(orbitin) |
| 72 | + [~, orbitin] = findorbit(LATTICE,'XYStep',XYStep,'DPStep',DPStep,'is_6d',is_6d,dpargs{:}); |
| 73 | + end |
64 | 74 |
|
65 | | -% Build a diagonal matrix of initial conditions |
66 | | -%scaling=2*XYStep*[1 0.1 1 0.1 1 1]; |
67 | | -scaling=XYStep*[1 1 1 1 0 0] + DPStep*[0 0 0 0 1 1]; |
68 | | -D6 = 0.5*diag(scaling); |
69 | | -% Add to the orbit_in. First 12 columns for derivative |
70 | | -% 13-th column is for closed orbit |
71 | | -RIN = orbitin + [D6 -D6 zeros(6,1)]; |
72 | | -ROUT = linepass(LATTICE,RIN,refs); |
73 | | -TMAT3 = reshape(ROUT,6,13,[]); |
74 | | -M66 = (TMAT3(:,1:6,end)-TMAT3(:,7:12,end))./scaling; |
| 75 | + refs=setelems(refpts,NE+1); |
| 76 | + reqs=refpts(refs); |
75 | 77 |
|
76 | | -if nargout >= 2 % Calculate matrices at all REFPTS. |
77 | | - varargout{1} = (TMAT3(:,1:6,reqs)-TMAT3(:,7:12,reqs))./scaling; |
78 | | - % Return closed orbit if requested |
79 | | - if nargout >= 3 |
80 | | - varargout{2}=squeeze(TMAT3(:,13,reqs)); |
81 | | - end |
82 | | -end |
| 78 | + % Build a diagonal matrix of initial conditions |
| 79 | + %scaling=2*XYStep*[1 0.1 1 0.1 1 1]; |
| 80 | + scaling=XYStep*[1 1 1 1 0 0] + DPStep*[0 0 0 0 1 1]; |
| 81 | + D6 = 0.5*diag(scaling); |
| 82 | + % Add to the orbit_in. First 12 columns for derivative |
| 83 | + % 13-th column is for closed orbit |
| 84 | + RIN = orbitin + [D6 -D6 zeros(6,1)]; |
| 85 | + ROUT = linepass(LATTICE,RIN,refs); |
| 86 | + TMAT3 = reshape(ROUT,6,13,[]); |
| 87 | + M66 = (TMAT3(:,1:6,end)-TMAT3(:,7:12,end))./scaling; |
83 | 88 |
|
84 | | - function mask=setelems(mask,idx) |
85 | | - mask(idx)=true; |
86 | | - end |
| 89 | + if nargout >= 2 % Calculate matrices at all REFPTS. |
| 90 | + varargout{1} = (TMAT3(:,1:6,reqs)-TMAT3(:,7:12,reqs))./scaling; |
| 91 | + % Return closed orbit if requested |
| 92 | + if nargout >= 3 |
| 93 | + varargout{2}=squeeze(TMAT3(:,13,reqs)); |
| 94 | + end |
| 95 | + end |
| 96 | + |
| 97 | + function mask=setelems(mask,idx) |
| 98 | + mask(idx)=true; |
| 99 | + end |
87 | 100 |
|
| 101 | + end |
88 | 102 | end |
0 commit comments