2 #include <boost/lexical_cast.hpp>
3 #include <boost/filesystem.hpp>
4 #include <boost/numeric/ublas/lu.hpp>
6 #include "flame/constants.h"
7 #include "flame/moment.h"
9 #define sqr(x) ((x)*(x))
10 #define cube(x) ((x)*(x)*(x))
13 #define defpath DEFPATH
18 std::map<std::string,boost::shared_ptr<Config> > CurveMap;
22 void inverse(MomentElementBase::value_t& out,
const MomentElementBase::value_t& in)
24 using boost::numeric::ublas::permutation_matrix;
25 using boost::numeric::ublas::lu_factorize;
26 using boost::numeric::ublas::lu_substitute;
27 using boost::numeric::ublas::identity_matrix;
29 MomentElementBase::value_t scratch(in);
30 permutation_matrix<size_t> pm(scratch.size1());
31 if(lu_factorize(scratch, pm)!=0)
32 throw std::runtime_error(
"Failed to invert matrix");
33 out.assign(identity_matrix<double>(scratch.size1()));
35 lu_substitute(scratch, pm, out);
38 void RotMat(
const double dx,
const double dy,
39 const double theta_x,
const double theta_y,
const double theta_z,
40 typename MomentElementBase::value_t &R)
44 MomentState::matrix_t T = boost::numeric::ublas::identity_matrix<double>(state_t::maxsize);
46 R = boost::numeric::ublas::identity_matrix<double>(state_t::maxsize);
50 double m11 = cos(-theta_y)*cos(theta_z),
51 m12 = sin(theta_x)*sin(-theta_y)*cos(theta_z) + cos(theta_x)*sin(theta_z),
52 m13 = -cos(theta_x)*sin(-theta_y)*cos(theta_z) + sin(theta_x)*sin(theta_z),
54 m21 = -cos(-theta_y)*sin(theta_z),
55 m22 = -sin(theta_x)*sin(-theta_y)*sin(theta_z) + cos(theta_x)*cos(theta_z),
56 m23 = cos(theta_x)*sin(-theta_y)*sin(theta_z) + sin(theta_x)*cos(theta_z),
59 m32 = -sin(theta_x)*cos(-theta_y),
60 m33 = cos(theta_x)*cos(-theta_y);
62 R(0, 0) = m11, R(0, 2) = m12, R(0, 4) = m13;
63 R(2, 0) = m21, R(2, 2) = m22, R(2, 4) = m23;
64 R(4, 0) = m31, R(4, 2) = m32, R(4, 4) = m33;
66 R(1, 1) = m11, R(1, 3) = m12, R(1, 5) = m13;
67 R(3, 1) = m21, R(3, 3) = m22, R(3, 5) = m23;
68 R(5, 1) = m31, R(5, 3) = m32, R(5, 5) = m33;
70 T(0, 6) = -dx, T(2, 6) = -dy;
76 void GetQuadMatrix(
const double L,
const double K,
const unsigned ind,
typename MomentElementBase::value_t &M)
91 M(ind, ind) = M(ind+1, ind+1) = cs;
93 M(ind, ind+1) = sn/sqrtK;
97 M(ind+1, ind) = -sqrtK*sn;
107 M(ind, ind) = M(ind+1, ind+1) = cs;
109 M(ind, ind+1) = sn/sqrtK;
113 M(ind+1, ind) = sqrtK*sn;
119 void GetSextMatrix(
const double L,
const double K3,
double Dx,
double Dy,
120 const double D2x,
const double D2y,
const double D2xy,
const bool thinlens,
const bool dstkick,
typename MomentElementBase::value_t &M)
124 double sqrtK, psi, cs, sn, ch, sh,
125 dr = sqrt(sqr(Dx)+sqr(Dx));
131 MomentState::matrix_t T = boost::numeric::ublas::identity_matrix<double>(state_t::maxsize);
132 MomentState::matrix_t P = boost::numeric::ublas::identity_matrix<double>(state_t::maxsize);
133 MomentState::matrix_t scratch;
135 T(state_t::PS_X, state_t::PS_PX) = L/2e0;
136 T(state_t::PS_Y, state_t::PS_PY) = L/2e0;
138 P(state_t::PS_PX, state_t::PS_X) = -K3*L*Dx;
139 P(state_t::PS_PX, state_t::PS_Y) = K3*L*Dy;
141 P(state_t::PS_PY, state_t::PS_X) = K3*L*Dy;
142 P(state_t::PS_PY, state_t::PS_Y) = K3*L*Dx;
151 sqrtK = sqrt(fabs(K3)*dr);
155 Dx *= copysign(1e0,K3);
156 Dy *= copysign(1e0,K3);
165 M(state_t::PS_X, state_t::PS_X) = M(state_t::PS_PX, state_t::PS_PX) = ((dr+Dx)*cs+(dr-Dx)*ch)/(2e0*dr);
166 M(state_t::PS_X, state_t::PS_PX) = ((dr+Dx)*sn+(dr-Dx)*sh)/(2e0*sqrtK*dr);
167 M(state_t::PS_X, state_t::PS_Y) = M(state_t::PS_PX, state_t::PS_PY) =
168 M(state_t::PS_Y, state_t::PS_X) = M(state_t::PS_PY, state_t::PS_PX) = Dy*(-cs+ch)/(2e0*dr);
169 M(state_t::PS_X, state_t::PS_PY) = Dy*(-sn+sh)/(2e0*sqrtK*dr);
171 M(state_t::PS_PX, state_t::PS_X) = sqrtK*(-(dr+Dx)*sn+(dr-Dx)*sh)/(2e0*dr);
172 M(state_t::PS_PX, state_t::PS_Y) = M(state_t::PS_PY, state_t::PS_X) = Dy*sqrtK*(sn+sh)/(2e0*dr);
174 M(state_t::PS_Y, state_t::PS_PX) = Dy*(-sn+sh)/(2e0*sqrtK*dr);
175 M(state_t::PS_Y, state_t::PS_Y) = M(state_t::PS_PY, state_t::PS_PY) = ((dr-Dx)*cs+(dr+Dx)*ch)/(2e0*dr);
176 M(state_t::PS_Y, state_t::PS_PY) = ((dr-Dx)*sn+(dr+Dx)*sh)/(2e0*sqrtK*dr);
178 M(state_t::PS_PY, state_t::PS_Y) = sqrtK*(-(dr-Dx)*sn+(dr+Dx)*sh)/(2e0*dr);
181 M(state_t::PS_X, state_t::PS_PX) = L;
182 M(state_t::PS_Y, state_t::PS_PY) = L;
187 M(state_t::PS_PX, 6) = -K3*L*(D2x-D2y);
188 M(state_t::PS_PY, 6) = 2e0*K3*L*D2xy;
192 void GetEdgeMatrix(
const double rho,
const double phi,
const double dphi,
const double qmrel,
typename MomentElementBase::value_t &M)
196 M = boost::numeric::ublas::identity_matrix<double>(state_t::maxsize);
198 M(state_t::PS_PX, state_t::PS_X) = (tan(phi+dphi)/rho)*(1+qmrel);
199 M(state_t::PS_PY, state_t::PS_Y) = -(tan(phi-dphi)/rho)*(1+qmrel);
203 void GetEEdgeMatrix(
const double fringe_x,
const double fringe_y,
const double kappa,
typename MomentElementBase::value_t &M)
208 M = boost::numeric::ublas::identity_matrix<double>(state_t::maxsize);
210 M(state_t::PS_PX, state_t::PS_X) = fringe_x;
211 M(state_t::PS_PX, state_t::PS_PX) = sqrt(1e0+kappa);
212 M(state_t::PS_PY, state_t::PS_Y) = fringe_y;
213 M(state_t::PS_PS, state_t::PS_PS) = 1e0+kappa;
217 void GetSBendMatrix(
const double L,
const double phi,
const double phi1,
const double phi2,
const double K,
218 const double IonEs,
const double ref_gamma,
const double qmrel,
219 const double dphi1,
const double dphi2,
const unsigned EFcorrection,
220 const double dip_beta,
const double dip_gamma,
const double d,
const double dip_IonK,
typename MomentElementBase::value_t &M)
224 MomentState::matrix_t edge1, edge2, R;
227 Kx = K + 1e0/sqr(rho),
233 GetQuadMatrix(L, Kx, (
unsigned)state_t::PS_X, M);
235 GetQuadMatrix(L, Ky, (
unsigned)state_t::PS_Y, M);
239 dx = sqr(L)/(2e0*rho);
241 }
else if (Kx > 0e0) {
242 dx = (1e0-cos(sqrt(Kx)*L))/(rho*Kx);
243 sx = sin(sqrt(Kx)*L)/(rho*sqrt(Kx));
245 dx = (1e0-cosh(sqrt(-Kx)*L))/(rho*Kx);
246 sx = sin(sqrt(-Kx)*L)/(rho*sqrt(-Kx));
249 M(state_t::PS_X, state_t::PS_PS) = dx/(sqr(dip_beta)*dip_gamma*IonEs/MeVtoeV);
250 M(state_t::PS_PX, state_t::PS_PS) = sx/(sqr(dip_beta)*dip_gamma*IonEs/MeVtoeV);
252 M(state_t::PS_S, state_t::PS_X) = sx*dip_IonK;
253 M(state_t::PS_S, state_t::PS_PX) = dx*dip_IonK;
255 M(state_t::PS_S, state_t::PS_PS) =
256 ((L/rho-sx)/(Kx*rho)-L/sqr(ref_gamma))*dip_IonK
257 /(sqr(dip_beta)*dip_gamma*IonEs/MeVtoeV);
260 M(state_t::PS_S, 6) = ((L/rho-sx)/(Kx*rho)*d-L/sqr(ref_gamma)*(d+qmrel))*dip_IonK;
261 M(state_t::PS_X, 6) = dx*d;
262 M(state_t::PS_PX, 6) = sx*d;
266 GetEdgeMatrix(rho, phi1, dphi1, qmrel, edge1);
267 GetEdgeMatrix(rho, phi2, dphi2, qmrel, edge2);
269 GetEdgeMatrix(rho, phi1, dphi1, 0e0, edge1);
270 GetEdgeMatrix(rho, phi2, dphi2, 0e0, edge2);
282 void GetSolMatrix(
const double L,
const double K,
typename MomentElementBase::value_t &M)
286 double C = ::cos(K*L),
289 M(state_t::PS_X, state_t::PS_X)
290 = M(state_t::PS_PX, state_t::PS_PX)
291 = M(state_t::PS_Y, state_t::PS_Y)
292 = M(state_t::PS_PY, state_t::PS_PY)
296 M(state_t::PS_X, state_t::PS_PX) = S*C/K;
298 M(state_t::PS_X, state_t::PS_PX) = L;
299 M(state_t::PS_X, state_t::PS_Y) = S*C;
301 M(state_t::PS_X, state_t::PS_PY) = sqr(S)/K;
303 M(state_t::PS_X, state_t::PS_PY) = 0e0;
305 M(state_t::PS_PX, state_t::PS_X) = -K*S*C;
306 M(state_t::PS_PX, state_t::PS_Y) = -K*sqr(S);
307 M(state_t::PS_PX, state_t::PS_PY) = S*C;
309 M(state_t::PS_Y, state_t::PS_X) = -S*C;
311 M(state_t::PS_Y, state_t::PS_PX) = -sqr(S)/K;
313 M(state_t::PS_Y, state_t::PS_PX) = 0e0;
315 M(state_t::PS_Y, state_t::PS_PY) = S*C/K;
317 M(state_t::PS_Y, state_t::PS_PY) = L;
319 M(state_t::PS_PY, state_t::PS_X) = K*sqr(S);
320 M(state_t::PS_PY, state_t::PS_PX) = -S*C;
321 M(state_t::PS_PY, state_t::PS_Y) = -K*S*C;
329 void GetEBendMatrix(
const double L,
const double phi,
const double fringe_x,
const double fringe_y,
const double kappa,
330 const double Kx,
const double Ky,
const double IonEs,
const double real_gamma,
const double eta0,
const double h,
331 const double delta_K,
const double delta_KZ,
const double SampleIonK,
typename MomentElementBase::value_t &M)
335 MomentState::matrix_t edge;
338 scl = (real_gamma - 1e0)*IonEs/MeVtoeV,
343 GetQuadMatrix(L, Kx, (
unsigned)state_t::PS_X, M);
345 GetQuadMatrix(L, Ky, (
unsigned)state_t::PS_Y, M);
351 }
else if (Kx > 0e0) {
352 dx = (1e0-cos(sqrt(Kx)*L))/(rho*Kx);
353 sx = sin(sqrt(Kx)*L)/sqrt(Kx);
355 dx = (1e0-cosh(sqrt(-Kx)*L))/(rho*Kx);
356 sx = sin(sqrt(Kx)*L)/sqrt(Kx);
359 double Nk = (sqr(1e0+2e0*eta0)+h)/(2e0*(1e0+eta0)*(1e0+2e0*eta0)),
360 Nt = 1e0 + h/sqr(1e0+2e0*eta0),
361 CorT = -real_gamma/(1e0+real_gamma),
364 tzp = (-L/(2e0*(1e0+eta0)*(1e0+2e0*eta0))+((L-sx)/Kx/sqr(rho))*Nk*Nt)*CorT;
366 M(state_t::PS_X, state_t::PS_PS) = dx*Nk/scl;
367 M(state_t::PS_PX, state_t::PS_PS) = sx/rho*Nk/scl;
369 M(state_t::PS_S, state_t::PS_X) = -tx*SampleIonK;
370 M(state_t::PS_S, state_t::PS_PX) = -txp*SampleIonK;
372 M(state_t::PS_S, state_t::PS_PS) = -tzp*SampleIonK/scl;
375 double Nkz = (1e0+2e0*eta0-h)/(2e0*(1e0+eta0)*(1e0+2e0*eta0));
377 M(state_t::PS_X, 6) = dx*(Nk*delta_K+Nkz*delta_KZ);
378 M(state_t::PS_PX, 6) = sx/rho*(Nk*delta_K+Nkz*delta_KZ);
381 GetEEdgeMatrix(fringe_x, fringe_y ,kappa, edge);
391 void GetCurveData(
const Config &c,
const unsigned ncurve, std::vector<double> &Scales,
392 std::vector<std::vector<double> > &Curves)
394 boost::shared_ptr<Config> conf;
396 std::string filename;
397 std::vector<double> range;
398 bool checker = c.
tryGet<std::string>(
"CurveFile", filename),
399 rngchecker = c.
tryGet<std::vector<double> >(
"use_range", range);
402 std::string CurveFile = c.
get<std::string>(
"Eng_Data_Dir", defpath);
403 CurveFile +=
"/" + filename;
404 std::string key(SB()<<CurveFile<<
"|"<<boost::filesystem::last_write_time(CurveFile));
405 if ( CurveMap.find(key) == CurveMap.end() ) {
410 conf.reset(P.
parse_file(CurveFile.c_str(),
false));
411 }
catch(std::exception& e){
412 throw std::runtime_error(SB()<<
"Parse error: "<<e.what()<<
"\n");
415 }
catch(std::exception& e){
416 throw std::runtime_error(SB()<<
"Error: "<<e.what()<<
"\n");
418 CurveMap.insert(std::make_pair(key, conf));
425 size_t prev_size = 0;
426 for (
unsigned n=0; n<ncurve; n++) {
427 std::string num(boost::lexical_cast<std::string>(n));
428 std::vector<double> cv;
431 cvchecker = conf->tryGet<std::vector<double> >(
"curve"+num, cv);
433 cvchecker = c.
tryGet<std::vector<double> >(
"curve"+num, cv);
435 if (!cvchecker)
throw std::runtime_error(SB()<<
"'curve" << num <<
"' is missing in lattice file.\n");
439 if (range.size() != 2)
440 throw std::runtime_error(SB()<<
"Size of 'use_range' must be 2.\n");
441 start =
static_cast<unsigned>(range[0]);
442 end =
static_cast<unsigned>(range[1]);
444 if (start > cv.size() or end > cv.size())
445 throw std::runtime_error(SB()<<
"'use_range' is out of curve size.\n");
447 std::vector<double> part(cv.begin()+start, cv.begin()+end);
448 Curves.push_back(part);
450 Curves.push_back(cv);
453 if (n != 0 and prev_size != cv.size())
454 throw std::runtime_error(SB()<<
"Size of 'curve" << n <<
"' (" << cv.size() <<
") and 'curve" << n-1 <<
455 "' (" << prev_size <<
") are inconsistent. All curves must have the same size.\n");
456 prev_size = cv.size();
458 Scales.push_back(c.
get<
double>(
"scl_fac"+num, 0.0));
Config * parse_file(const char *fname, const bool have_lattice=true)
Open and parse a file.
Interface to lattice file parser.
Associative configuration container.
bool tryGet(const std::string &name, T &val) const
detail::RT< T >::type get(const std::string &name) const