source: MML/trunk/machine/SOLEIL/common/k2amp.m @ 4

Last change on this file since 4 was 4, checked in by zhangj, 10 years ago

Initial import--MML version from SOLEIL@2013

File size: 4.5 KB
Line 
1function Amps = k2amp(Family, Field, k, DeviceList, Energy, C, K2AmpScaleFactor)
2%K2AMP - Converts simulator values to amperes
3%  Amps = k2amp(Family, Field, k, DeviceList, Energy, Coefficients, K2AmpScaleFactor)
4%       or
5%  Amps = k2amp(Family, Field, k, DeviceList, Energy, MagnetCoreType, K2AmpScaleFactor)
6%
7%  Calculates the current [amperes] from the coefficients (or MagnetCoreType), "K-value", energy, and linear scale factor
8%
9%  INPUTS
10%  1. Family - Family name
11%  2. Field - Sub-field (like 'Setpoint')
12%  3. K - "K-value" in AT convention
13%          For dipole:      K = B / Brho
14%          For quadrupole:  K = B'/ Brho
15%          For sextupole:   K = B"/ Brho / 2
16%  4. DeviceList - Device list (Amps and DeviceList must have the same number of rows)
17%  5. Energy - Energy in GeV {Default: getenergy}
18%              If Energy is a vector, each output column will correspond to that energy.
19%              Energy can be anything getenergy accepts, like 'Model' or 'Online'.
20%              (Note: If Energy is a vector, then Amps can only have 1 column)
21%  6. Coefficients - A Coefficients vector or a MagnetCoreType string (coefficient found from magnetcoefficents.m) can be used
22%  k and Coefficients must have equal number of rows or one must only have
23%  one row
24%  7. K2AmpScaleFactor - linearly scales the output current:  Amps =
25%  K2AmpScaleFactor .* Amps
26%
27%  NOTES
28%  1. If energy is not an input or empty, then the energy is obtained from getenergy.
29%  2. Family and Field inputs are not used but there automatically part of the physics2hw call.
30%
31% See Also amp2k, magnetcoefficients
32
33% ALGORITHM
34%
35% p = root(-k*Brho  + (c0 + c1*I + ... + cn*I^n))
36% I = root(p) closest to linear solution rlin
37% Linear solution is
38% rlin = (k*Brho - c0)/c1
39
40%
41% M. Yoon 4/8/03
42% Adapted by Laurent S. Nadolski
43% Closest solution to linear takes into account the offset term
44
45
46if nargin < 4
47    error('At least 4 inputs required');
48end
49
50if nargin < 6
51    C = [];
52end
53if isempty(C)
54    %[CC, Leff, MagnetName] = magnetcoefficients(Family);
55    C = getfamilydata(Family, Field, 'HW2PhysicsParams', DeviceList);
56    C = C{1};
57end
58
59if nargin < 5
60    Energy = [];
61end
62if isempty(Energy)
63    Energy = getenergy;
64elseif ischar(Energy)
65    Energy = getenergy(Energy);
66end
67
68
69% If k is a row vector make it a column vector
70k = k(:);
71
72
73brho = getbrho(Energy);
74
75
76% Compute roots for the expansion:  0 = -BLeff + c0*I + c1*I^2 ...
77% For dipole:      BLeff = B  * Leff
78% For quadrupole:  BLeff = B' * Leff
79% For sextupole:   BLeff = B" * Leff
80
81%polynom = (C(8)+C(7)*Amps+C(6)*Amps^2+C(5)*Amps^3+C(4)*Amps^4+C(3)*Amps^5+C(2)*Amps^6+C(1)*Amps^7)
82%polynom = (c0+c1*Amps+c2*Amps^2+c3*Amps^3+c4*Amps^4+c5*Amps^5+c6*Amps^6+c7*Amps^7)
83
84
85if isstr(C)
86    TableLookUpFlag = 1;
87    MagnetCoreType = C;
88    [C, Leff, MagnetName] = magnetcoefficients(MagnetCoreType, k(1), 'k');
89    fprintf('k2amp: Warning magnetcoeeficient called\n');
90    k0 = k(1);
91else
92    TableLookUpFlag = 0;
93end
94
95if any(size(C,1) ~= length(k))
96    if length(k) == 1
97        k = ones(size(C,1),1) * k;
98    elseif size(C,1) == 1
99        % Ok as is
100        %C = ones(size(k,1),1) * C;
101    else
102        error('k and Coefficients must have equal number of rows or one must only have one row');
103    end
104end
105
106for j = 1:length(k)
107    % For piecewise tables, get a new polynomial
108    if TableLookUpFlag
109        if k(j) ~= k0;
110            [C, Leff, MagnetName] = magnetcoefficients(MagnetCoreType, k(j), 'k');
111            fprintf('k2amp: Warning magnetcoeeficient called\n');
112            k0 = k(j);
113        end
114    end
115
116   
117   
118    % Solve for roots based on polynomial coefficient (coefficients already divided by Leff)
119    % p = [C(1) C(2) C(3) C(4) C(5) C(6) C(7) C(8) C(9)-k(j)*brho];
120   
121    if size(C,1) == 1
122        p = [C(1:end-1) C(end)-k(j)*brho];
123        r1inear = (k(j)*brho-C(end))/C(end-1);
124    else
125        p = [C(j,1:end-1) C(j,end)-k(j)*brho];
126        r1inear = (k(j)*brho-C(end))/C(j,end-1);
127    end
128   
129    r = roots(p);   
130       
131    % Choose the closest solution to the linear one
132    Amps(j,1) = Inf;
133    FitError = Inf;
134    for i = 1:length(r)
135        if isreal(r(i))
136            %if r(i)>0 & abs(r(i)) < Amps(j,1)  % Smallest, positive
137                       
138            % Closest to linear method
139            if abs(r(i)-r1inear) < abs(Amps(j,1)-r1inear)
140                Amps(j,1) = r(i);
141            end
142        end
143    end
144   
145    if isinf(Amps(j,1))
146        error(sprintf('Solution for k=%.3f not found (all roots are complex)', k(j)));
147    end
148end
149
150% Scale solution if required
151if nargin >= 7
152    Amps = Amps .* K2AmpScaleFactor;
153end
Note: See TracBrowser for help on using the repository browser.