4 #include <boost/lexical_cast.hpp>
5 #include <boost/filesystem.hpp>
7 #include "flame/constants.h"
8 #include "flame/moment.h"
9 #include "flame/moment_sup.h"
10 #include "flame/rf_cavity.h"
11 #include "flame/config.h"
13 #define sqr(x) ((x)*(x))
14 #define cube(x) ((x)*(x)*(x))
17 #define defpath DEFPATH
22 std::map<std::string,boost::shared_ptr<Config> > ElementRFCavity::CavConfMap;
26 static double ipow(
double base,
int exp)
43 void EvalGapModel(
const double dis,
const double IonW0,
const Particle &real,
const double IonFy0,
44 const double k,
const double Lambda,
const double Ecen,
45 const double T,
const double S,
const double Tp,
const double Sp,
const double V0,
46 double &IonW_f,
double &IonFy_f);
51 double GetCavPhase(
const int cavi,
const Particle& ref,
const double IonFys,
const double multip,
const std::vector<double>& P);
56 double GetCavPhaseComplex(
const Particle& ref,
const double IonFys,
const double scale,
57 const double multip,
const std::vector<double>& P);
60 void CavDataType::show(std::ostream& strm,
const int k)
const
62 strm << std::scientific << std::setprecision(5)
63 << std::setw(13) << s[k] << std::setw(13) << Elong[k] <<
"\n";
67 void CavDataType::show(std::ostream& strm)
const
69 for (
unsigned int k = 0; k < s.size(); k++)
74 void CavTLMLineType::clear(
void)
76 s.clear(); Elem.clear(); E0.clear();
77 T.clear(); S.clear(); Accel.clear();
81 void CavTLMLineType::set(
const double s,
const std::string &Elem,
const double E0,
82 const double T,
const double S,
const double Accel)
84 this->s.push_back(s); this->Elem.push_back(Elem); this->E0.push_back(E0);
85 this->T.push_back(T); this->S.push_back(S); this->Accel.push_back(Accel);
89 void CavTLMLineType::show(
const int k)
const
91 FLAME_LOG(FINE) << std::fixed << std::setprecision(5)
92 << std::setw(9) << s[k] << std::setw(10) << Elem[k]
93 << std::scientific << std::setprecision(10)
94 << std::setw(18) << T[k] << std::setw(18) << S[k]
95 << std::setw(18) << Accel[k] <<
"\n";
99 void CavTLMLineType::show()
const
101 for (
unsigned int k = 0; k < s.size(); k++)
106 int get_column(
const std::string &str)
110 if (str ==
"CaviMlp_EFocus1")
112 else if (str ==
"CaviMlp_EFocus2")
114 else if (str ==
"CaviMlp_EDipole")
116 else if (str ==
"CaviMlp_EQuad")
118 else if (str ==
"CaviMlp_HMono")
120 else if (str ==
"CaviMlp_HDipole")
122 else if (str ==
"CaviMlp_HQuad")
125 throw std::runtime_error(SB()<<
"get_column: undef. column: " << str);
132 void calTransfac(
const numeric_table& fldmap,
int column_no,
const int gaplabel,
const double IonK,
const bool half,
133 double &Ecenter,
double &T,
double &Tp,
double &S,
double &Sp,
double &V0)
137 double len, dz, eml, em_mom;
138 std::vector<double> z, EM;
143 n = fldmap.table.size1();
145 if(n<=0 || (
size_t)column_no>=fldmap.table.size2())
146 throw std::runtime_error(
"field map size invalid");
151 std::copy(fldmap.table.find1(2, 0, 0),
152 fldmap.table.find1(2, n, 0),
154 std::copy(fldmap.table.find1(2, 0, column_no),
155 fldmap.table.find1(2, n, column_no),
161 if (half) n = (int)round((n-1)/2e0);
163 dz = (z[n-1]-z[0])/(n-1);
168 for (k = n-1; k >= 0; k--)
171 eml = 0e0, em_mom = 0e0;
172 for (k = 0; k < n-1; k++) {
173 eml += (fabs(EM[k])+fabs(EM[k+1]))/2e0*dz;
174 em_mom += (z[k]+z[k+1])/2e0*(fabs(EM[k])+fabs(EM[k+1]))/2e0*dz;
176 Ecenter = em_mom/eml;
178 for (k = 0; k < n; k++)
182 for (k = 0; k < n-1; k++)
183 T += (EM[k]+EM[k+1])/2e0*cos(IonK*(z[k]+z[k+1])/2e0)*dz;
187 for (k = 0; k < n-1; k++)
188 Tp -= ((z[k]+z[k+1])/2e0)*(EM[k]+EM[k+1])/2e0*sin(IonK*(z[k]+z[k+1])/2e0)*dz;
192 for (k = 0; k < n-1; k++)
193 S += (EM[k]+EM[k+1])/2e0*sin(IonK*(z[k]+z[k+1])/2e0)*(z[k+1]-z[k]);
197 for (k = 0; k < n-1; k++) {
198 Sp += (z[k]+z[k+1])/2e0*(EM[k]+EM[k+1])/2e0*cos(IonK*(z[k]+z[k+1])/2e0)*dz;
202 V0 = eml/MeVtoeV/MtoMM;
206 Ecenter = len - Ecenter;
213 double PwrSeries(
const double beta,
214 const double a0,
const double a1,
const double a2,
const double a3,
215 const double a4,
const double a5,
const double a6,
const double a7,
216 const double a8,
const double a9)
222 const double a[] = {a0, a1, a2, a3, a4, a5, a6, a7, a8, a9};
225 for (k = 1; k < n; k++)
226 f += a[k]*pow(beta, k);
232 void ElementRFCavity::TransFacts(
const int cavilabel,
double beta,
const double CaviIonK,
const int gaplabel,
const double EfieldScl,
233 double &Ecen,
double &T,
double &Tp,
double &S,
double &Sp,
double &V0)
const
236 std::ostringstream strm;
240 calTransfac(CavData, 2, gaplabel, CaviIonK,
true, Ecen, T, Tp, S, Sp, V0);
247 if (beta < 0.025 || beta > 0.08) {
248 FLAME_LOG(DEBUG) <<
"*** TransFacts: CaviIonK out of Range " << cavilabel <<
"\n";
249 calTransfac(CavData, 2, gaplabel, CaviIonK,
true, Ecen, T, Tp, S, Sp, V0);
259 S = PwrSeries(beta, -4.109, 399.9, -1.269e4, 1.991e5, -1.569e6, 4.957e6, 0.0, 0.0, 0.0, 0.0);
260 Sp = PwrSeries(beta, 61.98, -1.073e4, 4.841e5, 9.284e6, 8.379e7, -2.926e8, 0.0, 0.0, 0.0, 0.0);
261 V0 = 0.98477*EfieldScl;
265 Ecen = 0.0006384*pow(beta, -1.884) + 86.69;
266 T = PwrSeries(beta, 0.9232, -123.2, 3570, -5.476e4, 4.316e5, -1.377e6, 0.0, 0.0, 0.0, 0.0);
267 Tp = PwrSeries(beta, 1.699, 924.7, -4.062e4, 7.528e5, -6.631e6, 2.277e7, 0.0, 0.0, 0.0, 0.0);
269 Sp = PwrSeries(beta, -1.571, 25.59, 806.6, -2.98e4, 3.385e5, -1.335e6, 0.0, 0.0, 0.0, 0.0);
270 V0 = 0.492385*EfieldScl;
274 Ecen = -0.0006384*pow(beta, -1.884) + 33.31;
275 T = PwrSeries(beta, -0.9232, 123.2, -3570, 5.476e4, -4.316e5, 1.377e6, 0.0, 0.0, 0.0, 0.0);
276 Tp = PwrSeries(beta, -1.699, -924.7, 4.062e4, -7.528e5, 6.631e6, -2.277e7, 0.0, 0.0, 0.0, 0.0);
278 Sp = PwrSeries(beta, -1.571, 25.59, 806.6, -2.98e4, 3.385e5, -1.335e6, 0.0, 0.0, 0.0, 0.0);
279 V0 = 0.492385*EfieldScl;
282 strm <<
"*** GetTransitFac: undef. number of gaps " << gaplabel <<
"\n";
283 throw std::runtime_error(strm.str());
287 if (beta < 0.05 || beta > 0.25) {
288 FLAME_LOG(DEBUG) <<
"*** TransFacts: CaviIonK out of Range " << cavilabel <<
"\n";
289 calTransfac(CavData, 2, gaplabel, CaviIonK,
true, Ecen, T, Tp, S, Sp, V0);
298 S = PwrSeries(beta, -6.811, 343.9, -6385, 6.477e4, -3.914e5, 1.407e6, -2.781e6, 2.326e6, 0.0, 0.0);
299 Sp = PwrSeries(beta, 162.7, -1.631e4, 4.315e5, -5.344e6, 3.691e7, -1.462e8, 3.109e8, -2.755e8, 0.0, 0.0);
300 V0 = 1.967715*EfieldScl;
303 Ecen = 0.0002838*pow(beta, -2.13) + 76.5;
304 T = 0.0009467*pow(beta, -1.855) - 1.002;
305 Tp = PwrSeries(beta, 24.44, -334, 2468, -1.017e4, 2.195e4, -1.928e4, 0.0, 0.0, 0.0, 0.0);
307 Sp = -0.0009751*pow(beta, -1.898) + 0.001568;
308 V0 = 0.9838574*EfieldScl;
311 Ecen = -0.0002838*pow(beta, -2.13) + 73.5;
312 T = -0.0009467*pow(beta, -1.855) + 1.002;
313 Tp = PwrSeries(beta, -24.44, 334, -2468, 1.017e4, -2.195e4, 1.928e4, 0.0, 0.0, 0.0, 0.0);
315 Sp = -0.0009751*pow(beta, -1.898) + 0.001568;
316 V0 = 0.9838574*EfieldScl;
319 strm <<
"*** GetTransitFac: undef. number of gaps " << gaplabel <<
"\n";
320 throw std::runtime_error(strm.str());
324 if (beta < 0.15 || beta > 0.4) {
325 FLAME_LOG(DEBUG) <<
"*** TransFacts: CaviIonK out of Range " << cavilabel <<
"\n";
326 calTransfac(CavData, 2, gaplabel, CaviIonK,
true, Ecen, T, Tp, S, Sp, V0);
335 S = PwrSeries(beta, -4.285, 58.08, -248, 486, -405.6, 76.54, 0.0, 0.0, 0.0, 0.0);
336 Sp = PwrSeries(beta, 888, -2.043e4, 1.854e5, -9.127e5, 2.695e6, -4.791e6, 4.751e6, -2.025e6, 0.0, 0.0);
337 V0 = 2.485036*EfieldScl;
340 Ecen = 0.01163*pow(beta, -2.001) + 91.77;
341 T = 0.02166*pow(beta, -1.618) - 1.022;
342 Tp = PwrSeries(beta, -11.25, 534.7, -3917, 1.313e4, -2.147e4, 1.389e4, 0.0, 0.0, 0.0, 0.0);
344 Sp = PwrSeries(beta, -0.8283, -4.409, 78.77, -343.9, 645.1, -454.4, 0.0, 0.0, 0.0, 0.0);
345 V0 = 1.242518*EfieldScl;
348 Ecen =-0.01163*pow(beta, -2.001) + 58.23;
349 T =-0.02166*pow(beta, -1.618) + 1.022;
350 Tp = PwrSeries(beta, 11.25, -534.7, 3917, -1.313e4, 2.147e4, -1.389e4, 0.0, 0.0, 0.0, 0.0);
352 Sp = PwrSeries(beta, -0.8283, -4.409, 78.77, -343.9, 645.1, -454.4, 0.0, 0.0, 0.0, 0.0);
353 V0 = 1.242518*EfieldScl;
356 strm <<
"*** GetTransitFac: undef. number of gaps " << gaplabel <<
"\n";
357 throw std::runtime_error(strm.str());
361 if (beta < 0.3 || beta > 0.6) {
362 FLAME_LOG(DEBUG) <<
"*** TransFacts: CaviIonK out of Range " << cavilabel <<
"\n";
363 calTransfac(CavData, 2, gaplabel, CaviIonK,
true, Ecen, T, Tp, S, Sp, V0);
372 S = PwrSeries(beta, -4.222, 26.64, -38.49, -17.73, 84.12, -52.93, 0.0, 0.0, 0.0, 0.0);
373 Sp = PwrSeries(beta, -1261, -1.413e4, 5.702e4, -1.111e5, 1.075e5, -4.167e4, 0.0, 0.0 , 0.0, 0.0);
374 V0 = 4.25756986*EfieldScl;
377 Ecen = 0.01219*pow(beta, -2.348) + 137.8;
378 T = 0.04856*pow(beta, -1.68) - 1.018;
379 Tp = PwrSeries(beta, -3.612, 422.8, -1973, 4081, -4109, 1641, 0.0, 0.0, 0.0, 0.0);
381 Sp = -0.03969*pow(beta, -1.775) +0.009034;
382 V0 = 2.12878493*EfieldScl;
385 Ecen = -0.01219*pow(beta, -2.348) + 112.2;
386 T = -0.04856*pow(beta, -1.68) + 1.018;
387 Tp = PwrSeries(beta, 3.612, -422.8, 1973, -4081, 4109, -1641, 0.0, 0.0, 0.0, 0.0);
389 Sp = -0.03969*pow(beta, -1.775) +0.009034;
390 V0 = 2.12878493*EfieldScl;
393 strm <<
"*** GetTransitFac: undef. number of gaps " << gaplabel <<
"\n";
394 throw std::runtime_error(strm.str());
398 strm <<
"*** GetTransitFac: undef. cavity type" <<
"\n";
399 throw std::runtime_error(strm.str());
407 void ElementRFCavity::TransitFacMultipole(
const int cavi,
const std::string &flabel,
const double CaviIonK,
408 double &T,
double &S)
const
410 double Ecen, Tp, Sp, V0;
414 calTransfac(mlptable, get_column(flabel), 0, CaviIonK,
false, Ecen, T, Tp, S, Sp, V0);
418 if (((cavi == 1) && (CaviIonK < 0.025 || CaviIonK > 0.055)) ||
419 ((cavi == 2) && (CaviIonK < 0.006 || CaviIonK > 0.035)) ||
420 ((cavi == 3) && (CaviIonK < 0.01687155 || CaviIonK > 0.0449908)) ||
421 ((cavi == 4) && (CaviIonK < 0.0112477 || CaviIonK > 0.0224954))) {
422 FLAME_LOG(DEBUG) <<
"*** TransitFacMultipole: CaviIonK out of Range" <<
"\n";
423 calTransfac(mlptable, get_column(flabel), 0, CaviIonK,
false, Ecen, T, Tp, S, Sp, V0);
427 if (flabel ==
"CaviMlp_EFocus1") {
430 T = PwrSeries(CaviIonK, 1.256386e+02, -3.108322e+04, 3.354464e+06, -2.089452e+08, 8.280687e+09, -2.165867e+11,
431 3.739846e+12, -4.112154e+13, 2.613462e14, -7.316972e14);
432 S = PwrSeries(CaviIonK, 1.394183e+02, -3.299673e+04, 3.438044e+06, -2.070369e+08, 7.942886e+09, -2.013750e+11,
433 3.374738e+12, -3.605780e+13, 2.229446e+14, -6.079177e+14);
436 T = PwrSeries(CaviIonK, -9.450041e-01, -3.641390e+01, 9.926186e+03, -1.449193e+06, 1.281752e+08, -7.150297e+09,
437 2.534164e+11, -5.535252e+12, 6.794778e+13, -3.586197e+14);
438 S = PwrSeries(CaviIonK, 9.928055e-02, -5.545119e+01, 1.280168e+04, -1.636888e+06, 1.279801e+08, -6.379800e+09,
439 2.036575e+11, -4.029152e+12, 4.496323e+13, -2.161712e+14);
442 T = PwrSeries(CaviIonK, -1.000000e+00, 2.778823e-07, 6.820327e+01, 4.235106e-03, -1.926935e+03, 1.083516e+01,
443 2.996807e+04, 6.108642e+03, -3.864554e+05, 6.094390e+05);
444 S = PwrSeries(CaviIonK, -4.530303e-10, 1.625011e-07, -2.583224e-05, 2.478684e+01, -1.431967e-01, -1.545412e+03,
445 -1.569820e+02, 3.856713e+04, -3.159828e+04, -2.700076e+05);
449 T = PwrSeries(CaviIonK, -1.000000e+00, -2.406447e-07, 9.480040e+01, -7.659927e-03, -4.926996e+03, -3.504383e+01,
450 1.712590e+05, -1.964643e+04, -4.142976e+06, 6.085390e+06);
451 S = PwrSeries(CaviIonK, 3.958048e-11, -2.496811e-08, 7.027794e-06, -8.662787e+01, 1.246098e-01, 9.462491e+03,
452 4.481784e+02, -4.552412e+05, 3.026543e+05, 8.798256e+06);
455 }
else if (flabel ==
"CaviMlp_EFocus2") {
458 T = PwrSeries(CaviIonK, 1.038803e+00, -9.121320e+00, 8.943931e+02, -5.619149e+04, 2.132552e+06, -5.330725e+07,
459 8.799404e+08, -9.246033e+09, 5.612073e+10, -1.499544e+11);
460 S = PwrSeries(CaviIonK, 1.305154e-02, -2.585211e+00, 2.696971e+02, -1.488249e+04, 5.095765e+05, -1.154148e+07,
461 1.714580e+08, -1.604935e+09, 8.570757e+09, -1.983302e+10);
464 T = PwrSeries(CaviIonK, 9.989307e-01, 7.299233e-01, -2.932580e+02, 3.052166e+04, -2.753614e+06, 1.570331e+08,
465 -5.677804e+09, 1.265012e+11, -1.584238e+12, 8.533351e+12);
466 S = PwrSeries(CaviIonK, -3.040839e-03, 2.016667e+00, -4.313590e+02, 5.855139e+04, -4.873584e+06, 2.605444e+08,
467 -8.968899e+09, 1.923697e+11, -2.339920e+12, 1.233014e+13);
470 T = PwrSeries(CaviIonK, 1.000000e+00, -4.410575e-06, -8.884752e+01, -7.927594e-02, 4.663277e+03, -2.515405e+02,
471 -1.797134e+05, -1.904305e+05, 8.999378e+06, -2.951362e+07);
472 S = PwrSeries(CaviIonK, 6.387813e-08, -2.300899e-05, 3.676251e-03, -1.703282e+02, 2.066461e+01, 1.704569e+04,
473 2.316653e+04, -1.328926e+06, 4.853676e+06, 1.132796e+06);
477 T = PwrSeries(CaviIonK, 1.000000e+00, -5.025186e-06, -1.468976e+02, -2.520376e-01,2.048799e+04, -2.224267e+03,
478 -2.532091e+06, -4.613480e+06, 3.611911e+08, -1.891951e+09);
479 S = PwrSeries(CaviIonK, -1.801149e-08, 1.123280e-05, -3.126902e-03, 4.655245e+02, -5.431878e+01, -1.477730e+05,
480 -1.922110e+05, 2.795761e+07, -1.290046e+08, -4.656951e+08);
483 }
else if (flabel ==
"CaviMlp_EDipole") {
486 T = PwrSeries(CaviIonK, -1.005885e+00, 1.526489e+00, -1.047651e+02, 1.125013e+04, -4.669147e+05, 1.255841e+07,
487 -2.237287e+08, 2.535541e+09, -1.656906e+10, 4.758398e+10);
488 S = PwrSeries(CaviIonK, -2.586200e-02, 5.884367e+00, -6.407538e+02, 3.888964e+04, -1.488484e+06, 3.782592e+07,
489 -6.361033e+08, 6.817810e+09, -4.227114e+10, 1.155597e+11);
492 T = PwrSeries(CaviIonK, -9.999028e-01, -6.783669e-02, 1.415756e+02, -2.950990e+03, 2.640980e+05, -1.570742e+07,
493 5.770450e+08, -1.303686e+10, 1.654958e+11, -9.030017e+11);
494 S = PwrSeries(CaviIonK, 2.108581e-04, -3.700608e-01, 2.851611e+01, -3.502994e+03, 2.983061e+05, -1.522679e+07,
495 4.958029e+08, -1.002040e+10, 1.142835e+11, -5.617061e+11);
498 std::ostringstream strm;
499 strm <<
"*** 0.29 HWR and 0.53HWR havr no dipole term\n";
500 throw std::runtime_error(strm.str());
503 }
else if (flabel ==
"CaviMlp_EQuad") {
506 T = PwrSeries(CaviIonK, 1.038941e+00, -9.238897e+00, 9.127945e+02, -5.779110e+04, 2.206120e+06, -5.544764e+07,
507 9.192347e+08, -9.691159e+09, 5.896915e+10, -1.578312e+11);
508 S = PwrSeries(CaviIonK, 1.248096e-01, -2.923507e+01, 3.069331e+03, -1.848380e+05, 7.094882e+06, -1.801113e+08,
509 3.024208e+09, -3.239241e+10, 2.008767e+11, -5.496217e+11);
512 T = PwrSeries(CaviIonK, 1.000003e+00, -1.015639e-03, -1.215634e+02, 1.720764e+01, 3.921401e+03, 2.674841e+05,
513 -1.236263e+07, 3.128128e+08, -4.385795e+09, 2.594631e+10);
514 S = PwrSeries(CaviIonK, -1.756250e-05, 2.603597e-01, -2.551122e+00, -4.840638e+01, -2.870201e+04, 1.552398e+06,
515 -5.135200e+07, 1.075958e+09, -1.277425e+10, 6.540748e+10);
518 T = PwrSeries(CaviIonK, 1.000000e+00, 6.239107e-06, -1.697479e+02, 3.444883e-02, 1.225241e+04, -1.663533e+02,
519 -5.526645e+05, -3.593353e+05, 2.749580e+07, -9.689870e+07);
520 S = PwrSeries(CaviIonK, 2.128708e-07, -7.985618e-05, 1.240259e-02, -3.211339e+02, 7.098731e+01, 3.474652e+04,
521 8.187145e+04, -3.731688e+06, 1.802053e+07, -1.819958e+07);
524 T = PwrSeries(CaviIonK, 9.998746e-01, -2.431292e-05, -5.019138e+02, -1.176338e+00, 1.006054e+05, -9.908805e+03,
525 -1.148028e+07, -1.922707e+07, 1.432258e+09, -7.054482e+09);
526 S = PwrSeries(CaviIonK, 6.003340e-08, -1.482633e-02, 1.037590e-02, -2.235440e+03, 1.790006e+02, 6.456882e+05,
527 6.261020e+05, -1.055477e+08, 4.110502e+08, 2.241301e+09);
530 }
else if (flabel ==
"CaviMlp_HMono") {
533 T = PwrSeries(CaviIonK, 1.703336e+00, -1.671357e+02, 1.697657e+04, -9.843253e+05, 3.518178e+07, -8.043084e+08,
534 1.165760e+10, -1.014721e+11, 4.632851e+11, -7.604796e+11);
535 S = PwrSeries(CaviIonK, 1.452657e+01, -3.409550e+03, 3.524921e+05, -2.106663e+07, 8.022856e+08,
536 -2.019481e+10, 3.360597e+11, -3.565836e+12, 2.189668e+13, -5.930241e+13);
539 T = PwrSeries(CaviIonK, 1.003228e+00, -1.783406e+00, 1.765330e+02, -5.326467e+04, 4.242623e+06, -2.139672e+08,
540 6.970488e+09, -1.411958e+11, 1.617248e+12, -8.000662e+12);
541 S = PwrSeries(CaviIonK, -1.581533e-03, 1.277444e+00, -2.742508e+02, 3.966879e+04, -3.513478e+06, 1.962939e+08,
542 -6.991916e+09, 1.539708e+11, -1.910236e+12, 1.021016e+13);
545 T = PwrSeries(CaviIonK, 9.999990e-01, 3.477993e-04, -2.717994e+02, 4.554376e+00, 3.083481e+04, 8.441315e+03,
546 -2.439843e+06, 1.322379e+06, 1.501750e+08, -6.822135e+08);
547 S = PwrSeries(CaviIonK, 1.709084e-06, -6.240506e-04, 1.013278e-01, -2.649338e+02, 5.944163e+02,
548 4.588900e+04, 7.110518e+05, -2.226574e+07, 1.658524e+08, -3.976459e+08);
551 T = PwrSeries(CaviIonK, 1.000000e+00, -4.358956e-05, -7.923870e+02, -2.472669e+00, 2.241378e+05, -2.539286e+04,
552 -3.385480e+07, -6.375134e+07, 5.652166e+09, -3.355877e+10);
553 S = PwrSeries(CaviIonK, 1.163146e-07, -7.302018e-05, 2.048587e-02, -3.689694e+02, 3.632907e+02, 1.757838e+05,
554 1.327057e+06, -9.520645e+07, 9.406709e+08, -2.139562e+09);
557 }
else if (flabel ==
"CaviMlp_HDipole") {
560 T = PwrSeries(CaviIonK, 6.853803e-01, 7.075414e+01, -7.117391e+03, 3.985674e+05, -1.442888e+07, 3.446369e+08,
561 -5.420826e+09, 5.414689e+10, -3.116216e+11, 7.869717e+11);
562 S = PwrSeries(CaviIonK, 1.021102e+00, -2.441117e+02, 2.575274e+04, -1.569273e+06, 6.090118e+07, -1.562284e+09,
563 2.649289e+10, -2.864139e+11, 1.791634e+12, -4.941947e+12);
566 T = PwrSeries(CaviIonK, 1.014129e+00, -8.016304e+00, 1.631339e+03, -2.561826e+05, 2.115355e+07, -1.118723e+09,
567 3.821029e+10, -8.140248e+11, 9.839613e+12, -5.154137e+13);
568 S = PwrSeries(CaviIonK, -4.688714e-03, 3.299051e+00, -8.101936e+02, 1.163814e+05, -1.017331e+07, 5.607330e+08,
569 -1.967300e+10, 4.261388e+11, -5.194592e+12, 2.725370e+13);
572 std::ostringstream strm;
573 strm <<
"*** 0.29 HWR and 0.53HWR have no dipole term\n";
574 throw std::runtime_error(strm.str());
577 }
else if (flabel ==
"CaviMlp_HQuad") {
580 T = PwrSeries(CaviIonK, -1.997432e+00, 2.439177e+02, -2.613724e+04, 1.627837e+06, -6.429625e+07, 1.676173e+09,
581 -2.885455e+10, 3.163675e+11, -2.005326e+12, 5.600545e+12);
582 S = PwrSeries(CaviIonK, -2.470704e+00, 5.862902e+02, -6.135071e+04, 3.711527e+06, -1.431267e+08, 3.649414e+09,
583 -6.153570e+10, 6.617859e+11, -4.119861e+12, 1.131390e+13);
586 T = PwrSeries(CaviIonK, -1.000925e+00, 5.170302e-01, 9.311761e+01, 1.591517e+04, -1.302247e+06, 6.647808e+07,
587 -2.215417e+09, 4.603390e+10, -5.420873e+11, 2.764042e+12);
588 S = PwrSeries(CaviIonK, 3.119419e-04, -4.540868e-01, 5.433028e+01, -7.571946e+03, 6.792565e+05, -3.728390e+07,
589 1.299263e+09, -2.793705e+10, 3.377097e+11, -1.755126e+12);
592 T = PwrSeries(CaviIonK, -9.999997e-01, -1.049624e-04, 2.445420e+02, -1.288731e+00, -2.401575e+04, -1.972894e+03,
593 1.494708e+06, 2.898145e+05, -8.782506e+07, 3.566907e+08);
594 S = PwrSeries(CaviIonK, -7.925695e-07, 2.884963e-04, -4.667266e-02, 2.950936e+02, -2.712131e+02, -4.260259e+04,
595 -3.199682e+05, 1.103376e+07, -7.304474e+07, 1.479036e+08);
598 T = PwrSeries(CaviIonK, -1.000000e+00, 4.357777e-05, 7.605879e+02, 2.285787e+00, -2.009415e+05, 2.149581e+04,
599 2.773856e+07, 4.886782e+07, -4.127019e+09, 2.299278e+10);
600 S = PwrSeries(CaviIonK, -1.483304e-07, 9.278457e-05, -2.592071e-02, 1.690272e+03, -4.545599e+02, -6.192487e+05,
601 -1.632321e+06, 1.664856e+08, -1.124066e+09, -3.121299e+08);
605 std::ostringstream strm;
606 strm <<
"*** TransitFacMultipole: undef. multipole type " << flabel <<
"\n";
607 throw std::runtime_error(strm.str());
613 double GetCavPhase(
const int cavi,
const Particle& ref,
const double IonFys,
const double multip,
const std::vector<double>& P)
624 Fyc = 4.394*pow(IonEk, -0.4965) - 4.731;
627 Fyc = 5.428*pow(IonEk, -0.5008) + 1.6;
630 Fyc = 22.35*pow(IonEk, -0.5348) + 2.026;
633 Fyc = 41.43*pow(IonEk, -0.5775) + 2.59839;
636 Fyc = 5.428*pow(IonEk, -0.5008) + 1.6;
639 Fyc = P[0]*pow(IonEk,P[1])- P[2];
642 std::ostringstream strm;
643 strm <<
"*** GetCavPhase: undef. cavity type" <<
"\n";
644 throw std::runtime_error(strm.str());
647 return IonFys - Fyc - ref.
phis*multip;
652 double GetCavPhaseComplex(
const Particle& ref,
const double IonFys,
const double scale,
653 const double multip,
const std::vector<double>& P)
656 size_t npoly = P.size()/5;
658 if (P.size()%5 != 0) {
659 throw std::runtime_error(SB()<<
"*** Size of fitting parameter for the synchronous phase must be 5*n.");
665 for (
size_t i=0; i<npoly; i++){
666 Fyc += (P[5*i]*pow(Ek,P[5*i+1]) + P[5*i+2]*log(Ek) + P[5*i+3]*exp(-Ek) + P[5*i+4])
667 *ipow(scale, static_cast<int>(i));
670 return IonFys - Fyc - ref.
phis*multip;
675 void EvalGapModel(
const double dis,
const double IonW0,
const Particle &real,
const double IonFy0,
676 const double k,
const double Lambda,
const double Ecen,
677 const double T,
const double S,
const double Tp,
const double Sp,
const double V0,
678 double &IonW_f,
double &IonFy_f)
680 double Iongamma_f, IonBeta_f, k_f;
682 IonW_f = IonW0 + real.
IonZ*V0*T*cos(IonFy0+k*Ecen)*MeVtoeV - real.
IonZ*V0*S*sin(IonFy0+k*Ecen)*MeVtoeV;
683 Iongamma_f = IonW_f/real.
IonEs;
684 IonBeta_f = sqrt(1e0-1e0/sqr(Iongamma_f));
685 k_f = 2e0*M_PI/(IonBeta_f*Lambda);
687 IonFy_f = IonFy0 + k*Ecen + k_f*(dis-Ecen)
688 + real.
IonZ*V0*k*(Tp*sin(IonFy0+k*Ecen)+Sp*cos(IonFy0+k*Ecen))/(2e0*(IonW0-real.
IonEs)/MeVtoeV);
692 ElementRFCavity::ElementRFCavity(
const Config& c)
695 ElementRFCavity::LoadCavityFile(c);
699 void ElementRFCavity::LoadCavityFile(
const Config& c)
701 fRF = c.
get<
double>(
"f");
702 IonFys = c.
get<
double>(
"phi")*M_PI/180e0;
703 phi_ref = std::numeric_limits<double>::quiet_NaN();
704 cRm = c.
get<
double>(
"Rm", 0.0);
705 forcettfcalc = c.get<
double>(
"forcettfcalc", 0.0)!=0.0;
706 MpoleLevel = get_flag(c,
"MpoleLevel", 2);
707 EmitGrowth = get_flag(c,
"EmitGrowth", 0);
709 if (MpoleLevel != 0 && MpoleLevel != 1 && MpoleLevel != 2)
710 throw std::runtime_error(SB()<<
"Undefined MpoleLevel: " << MpoleLevel);
712 if (EmitGrowth != 0 && EmitGrowth != 1)
713 throw std::runtime_error(SB()<<
"Undefined EmitGrowth: " << EmitGrowth);
715 CavType = c.get<std::string>(
"cavtype");
716 std::string cavfile(c.get<std::string>(
"Eng_Data_Dir", defpath)),
720 if (CavType ==
"0.041QWR") {
722 fldmap +=
"/axisData_41.txt";
723 cavfile +=
"/Multipole41/thinlenlon_41.txt";
724 mlpfile +=
"/Multipole41/CaviMlp_41.txt";
725 }
else if (CavType ==
"0.085QWR") {
727 fldmap +=
"/axisData_85.txt";
728 cavfile +=
"/Multipole85/thinlenlon_85.txt";
729 mlpfile +=
"/Multipole85/CaviMlp_85.txt";
730 }
else if (CavType ==
"0.29HWR") {
732 fldmap +=
"/axisData_29.txt";
733 cavfile +=
"/Multipole29/thinlenlon_29.txt";
734 mlpfile +=
"/Multipole29/CaviMlp_29.txt";
735 }
else if (CavType ==
"0.53HWR") {
737 fldmap +=
"/axisData_53.txt";
738 cavfile +=
"/Multipole53/thinlenlon_53.txt";
739 mlpfile +=
"/Multipole53/CaviMlp_53.txt";
740 }
else if (CavType ==
"Generic") {
741 DataFile = cavfile+
"/"+c.get<std::string>(
"datafile");
744 throw std::runtime_error(SB()<<
"*** InitRFCav: undef. cavity type: " << CavType);
749 numeric_table_cache *cache = numeric_table_cache::get();
752 numeric_table_cache::table_pointer ent = cache->fetch(fldmap);
754 if(CavData.table.size1()==0 || CavData.table.size2()<2)
755 throw std::runtime_error(
"field map needs 2+ columns");
756 }
catch(std::exception& e){
757 throw std::runtime_error(SB()<<
"Error parsing '"<<fldmap<<
"' : "<<e.what());
761 numeric_table_cache::table_pointer ent = cache->fetch(mlpfile);
763 if(mlptable.table.size1()==0 || mlptable.table.size2()<7)
764 throw std::runtime_error(
"CaviMlp needs 7+ columns");
765 }
catch(std::exception& e){
766 throw std::runtime_error(SB()<<
"Error parsing '"<<mlpfile<<
"' : "<<e.what());
770 std::ifstream fstrm(cavfile.c_str());
774 while(std::getline(fstrm, rawline)) {
777 size_t cpos = rawline.find_first_not_of(
" \t");
778 if(cpos==rawline.npos || rawline[cpos]==
'%')
781 cpos = rawline.find_last_not_of(
"\r\n");
782 if(cpos!=rawline.npos)
783 rawline = rawline.substr(0, cpos+1);
785 std::istringstream lstrm(rawline);
787 lstrm >> params.type >> params.name >> params.length >> params.aperature;
788 bool needE0 = params.type!=
"drift" && params.type!=
"AccGap";
794 if(lstrm.fail() && !lstrm.eof()) {
795 throw std::runtime_error(SB()<<
"Error parsing line '"<<line<<
"' in '"<<cavfile<<
"'");
797 lattice.push_back(params);
800 if(fstrm.fail() && !fstrm.eof()) {
801 throw std::runtime_error(SB()<<
"Error, extra chars at end of file (line "<<line<<
") in '"<<cavfile<<
"'");
807 boost::shared_ptr<Config> conf;
808 std::string key(SB()<<DataFile<<
"|"<<boost::filesystem::last_write_time(DataFile));
809 if ( CavConfMap.find(key) == CavConfMap.end() ) {
815 }
catch(std::exception& e){
816 std::cerr<<
"Parse error: "<<e.what()<<
"\n";
819 }
catch(std::exception& e){
820 std::cerr<<
"Error: "<<e.what()<<
"\n";
822 CavConfMap.insert(std::make_pair(key, conf));
825 conf=CavConfMap[key];
828 typedef Config::vector_t elements_t;
829 elements_t Es(conf->get<elements_t>(
"elements"));
830 for(elements_t::iterator it=Es.begin(), end=Es.end(); it!=end; ++it)
833 const std::string& etype(EC.
get<std::string>(
"type"));
834 const double elength(EC.
get<
double>(
"L"));
838 params.length = elength;
839 std::vector<double> attrs;
840 bool notdrift = etype!=
"drift";
843 const double eV0(EC.
get<
double>(
"V0"));
845 EC.
tryGet<std::vector<double> >(
"attr", attrs);
846 for(
int i=0; i<10; i++)
848 params.Tfit.push_back(attrs[i]);
850 for(
int i=0; i<10; i++)
852 params.Sfit.push_back(attrs[i+10]);
855 bool needSynAccTab = params.type==
"AccGap";
857 if(needSynAccTab && SynAccTab.size()==0)
859 for(
int i=0; i<3; i++)
861 SynAccTab.push_back(attrs[i+20]);
864 lattice.push_back(params);
867 std::vector<double> Ez;
868 bool checker = conf->tryGet<std::vector<double> >(
"Ez", Ez);
869 if (!checker)
throw std::runtime_error(SB()<<
"'Ez' is missing in RF cavity file.\n");
870 CavData.readvec(Ez,2);
871 conf->tryGet<
double>(
"Rm",cRm);
874 have_RefNrm = conf->tryGet<
double>(
"RefNorm", RefNrm);
875 have_SynComplex = conf->tryGet<std::vector<double> >(
"SyncFit", SynComplex);
876 have_EkLim = conf->tryGet<std::vector<double> >(
"EnergyLimit", EkLim);
877 have_NrLim = conf->tryGet<std::vector<double> >(
"NormLimit", NrLim);
881 void ElementRFCavity::GetCavMatParams(
const int cavi,
const double beta_tab[],
const double gamma_tab[],
const double CaviIonK[],
882 CavTLMLineType& lineref)
const
885 throw std::runtime_error(
"empty RF cavity lattice");
890 double s=CavData.table(0,0);
891 for(i=0; i<lattice.size(); i++) {
892 const RawParams& P = lattice[i];
894 double E0=0.0, T=0.0, S=0.0, Accel=0.0;
896 if ((P.type !=
"drift") && (P.type !=
"AccGap"))
899 s+=lattice[i].length;
901 if (P.type ==
"drift") {
902 }
else if (P.type ==
"EFocus1") {
905 ElementRFCavity::TransitFacMultipole(cavi,
"CaviMlp_EFocus2", CaviIonK[0], T, S);
910 ElementRFCavity::TransitFacMultipole(cavi,
"CaviMlp_EFocus1", CaviIonK[1], T, S);
912 }
else if (P.type ==
"EFocus2") {
915 ElementRFCavity::TransitFacMultipole(cavi,
"CaviMlp_EFocus1", CaviIonK[0], T, S);
919 ElementRFCavity::TransitFacMultipole(cavi,
"CaviMlp_EFocus2", CaviIonK[1], T, S);
921 }
else if (P.type ==
"EDipole") {
922 if (MpoleLevel >= 1) {
924 ElementRFCavity::TransitFacMultipole(cavi,
"CaviMlp_EDipole", CaviIonK[0], T, S);
929 ElementRFCavity::TransitFacMultipole(cavi,
"CaviMlp_EDipole", CaviIonK[1], T, S);
932 }
else if (P.type ==
"EQuad") {
933 if (MpoleLevel >= 2) {
936 ElementRFCavity::TransitFacMultipole(cavi,
"CaviMlp_EQuad", CaviIonK[0], T, S);
940 ElementRFCavity::TransitFacMultipole(cavi,
"CaviMlp_EQuad", CaviIonK[1], T, S);
943 }
else if (P.type ==
"HMono") {
944 if (MpoleLevel >= 2) {
947 ElementRFCavity::TransitFacMultipole(cavi,
"CaviMlp_HMono", CaviIonK[0], T, S);
951 ElementRFCavity::TransitFacMultipole(cavi,
"CaviMlp_HMono", CaviIonK[1], T, S);
954 }
else if (P.type ==
"HDipole") {
955 if (MpoleLevel >= 1) {
958 ElementRFCavity::TransitFacMultipole(cavi,
"CaviMlp_HDipole", CaviIonK[0], T, S);
962 ElementRFCavity::TransitFacMultipole(cavi,
"CaviMlp_HDipole", CaviIonK[1], T, S);
965 }
else if (P.type ==
"HQuad") {
966 if (MpoleLevel >= 2) {
969 ElementRFCavity::TransitFacMultipole(cavi,
"CaviMlp_HQuad", CaviIonK[0], T, S);
973 ElementRFCavity::TransitFacMultipole(cavi,
"CaviMlp_HQuad", CaviIonK[1], T, S);
976 }
else if (P.type ==
"AccGap") {
979 Accel = (beta_tab[0]*gamma_tab[0])/((beta_tab[1]*gamma_tab[1]));
982 Accel = (beta_tab[1]*gamma_tab[1])/((beta_tab[2]*gamma_tab[2]));
985 std::ostringstream strm;
986 strm <<
"*** GetCavMatParams: undef. multipole element " << P.type <<
"\n";
987 throw std::runtime_error(strm.str());
990 lineref.set(s, P.type, E0, T, S, Accel);
994 if (FLAME_LOG_CHECK(DEBUG)) {
1001 void ElementRFCavity::GenCavMat2(
const int cavi,
const double dis,
const double EfieldScl,
const double TTF_tab[],
1002 const double beta_tab[],
const double gamma_tab[],
const double Lambda,
1003 Particle &real,
const double IonFys[],
const double Rm, state_t::matrix_t &M,
1004 const CavTLMLineType& linetab)
const
1011 double Ecens[2], Ts[2], Ss[2], V0s[2], ks[2], L1, L2, L3;
1012 double beta, gamma, kfac, V0, T, S, kfdx, kfdy, dpy, Accel, IonFy;
1013 state_t::matrix_t Idmat, Mlon_L1, Mlon_K1, Mlon_L2;
1014 state_t::matrix_t Mlon_K2, Mlon_L3, Mlon, Mtrans, Mprob;
1017 const bool logme = FLAME_LOG_CHECK(DEBUG);
1019 const double IonA = 1e0;
1021 using boost::numeric::ublas::prod;
1023 Idmat = boost::numeric::ublas::identity_matrix<double>(PS_Dim);
1025 k_s[0] = 2e0*M_PI/(beta_tab[0]*Lambda);
1026 k_s[1] = 2e0*M_PI/(beta_tab[1]*Lambda);
1027 k_s[2] = 2e0*M_PI/(beta_tab[2]*Lambda);
1033 Ecens[0] = TTF_tab[0];
1036 V0s[0] = TTF_tab[5];
1037 ks[0] = 0.5*(k_s[0]+k_s[1]);
1038 L1 = dis + Ecens[0];
1043 Mlon_L1(4, 5) = -2e0*M_PI/Lambda*(1e0/cube(beta_tab[0]*gamma_tab[0])*MeVtoeV/real.
IonEs*L1);
1045 Mlon_K1(5, 4) = -real.
IonZ*V0s[0]*Ts[0]*sin(IonFys[0]+ks[0]*L1)-real.
IonZ*V0s[0]*Ss[0]*cos(IonFys[0]+ks[0]*L1);
1047 Ecens[1] = TTF_tab[6];
1050 V0s[1] = TTF_tab[11];
1051 ks[1] = 0.5*(k_s[1]+k_s[2]);
1052 L2 = Ecens[1] - Ecens[0];
1057 Mlon_L2(4, 5) = -2e0*M_PI/Lambda*(1e0/cube(beta_tab[1]*gamma_tab[1])*MeVtoeV/real.
IonEs*L2);
1058 Mlon_K2(5, 4) = -real.
IonZ*V0s[1]*Ts[1]*sin(IonFys[1]+ks[1]*Ecens[1])-real.
IonZ*V0s[1]*Ss[1]*cos(IonFys[1]+ks[1]*Ecens[1]);
1060 L3 = dis - Ecens[1];
1063 Mlon_L3(4, 5) = -2e0*M_PI/Lambda*(1e0/cube(beta_tab[2]*gamma_tab[2])*MeVtoeV/real.
IonEs*L3);
1065 Mlon = prod(Mlon_K1, Mlon_L1);
1066 Mlon = prod(Mlon_L2, Mlon);
1067 Mlon = prod(Mlon_K2, Mlon);
1068 Mlon = prod(Mlon_L3, Mlon);
1080 gamma = gamma_tab[0];
1084 V0 = 0e0, T = 0e0, S = 0e0, kfdx = 0e0, kfdy = 0e0, dpy = 0e0;
1086 double s=CavData.table(0,0);
1087 for(n=0; n<lattice.size(); n++) {
1088 const RawParams& P = lattice[n];
1090 s+=lattice[n].length;
1093 printf(
"%9.5f %8s %8s %9.5f %9.5f %9.5f\n",
1094 s, P.type.c_str(), P.name.c_str(), P.length, P.aperature, P.E0);
1097 if (P.type ==
"drift") {
1098 IonFy = IonFy + kfac*P.length;
1100 Mprob(0, 1) = P.length;
1101 Mprob(2, 3) = P.length;
1102 Mtrans = prod(Mprob, Mtrans);
1103 }
else if (P.type ==
"EFocus1") {
1104 V0 = linetab.E0[n]*EfieldScl;
1107 kfdx = real.
IonZ*V0/sqr(beta)/gamma/IonA/AU*(T*cos(IonFy)-S*sin(IonFy))/Rm;
1110 FLAME_LOG(FINE)<<
" X EFocus1 kfdx="<<kfdx<<
"\n"
1111 <<
" Y "<<linetab.E0[n]<<
" "<<EfieldScl<<
" "<<beta
1112 <<
" "<<gamma<<
" "<<IonFy<<
" "<<Rm<<
"\n Z "<<T<<
" "<<S<<
"\n";
1117 Mtrans = prod(Mprob, Mtrans);
1118 }
else if (P.type ==
"EFocus2") {
1119 V0 = linetab.E0[n]*EfieldScl;
1122 kfdx = real.
IonZ*V0/sqr(beta)/gamma/IonA/AU*(T*cos(IonFy)-S*sin(IonFy))/Rm;
1124 if(logme) FLAME_LOG(FINE)<<
" X EFocus2 kfdx="<<kfdx<<
"\n";
1128 Mtrans = prod(Mprob, Mtrans);
1129 }
else if (P.type ==
"EDipole") {
1130 if (MpoleLevel >= 1) {
1131 V0 = linetab.E0[n]*EfieldScl;
1134 dpy = real.
IonZ*V0/sqr(beta)/gamma/IonA/AU*(T*cos(IonFy)-S*sin(IonFy));
1135 if(logme) FLAME_LOG(FINE)<<
" X EDipole dpy="<<dpy<<
"\n";
1138 Mtrans = prod(Mprob, Mtrans);
1140 }
else if (P.type ==
"EQuad") {
1141 if (MpoleLevel >= 2) {
1142 V0 = linetab.E0[n]*EfieldScl;
1145 kfdx = real.
IonZ*V0/sqr(beta)/gamma/IonA/AU*(T*cos(IonFy)-S*sin(IonFy))/Rm;
1147 if(logme) FLAME_LOG(FINE)<<
" X EQuad kfdx="<<kfdx<<
"\n";
1151 Mtrans = prod(Mprob, Mtrans);
1153 }
else if (P.type ==
"HMono") {
1154 if (MpoleLevel >= 2) {
1155 V0 = linetab.E0[n]*EfieldScl;
1158 kfdx = -MU0*C0*real.
IonZ*V0/beta/gamma/IonA/AU*(T*cos(IonFy+M_PI/2e0)-S*sin(IonFy+M_PI/2e0))/Rm;
1160 if(logme) FLAME_LOG(FINE)<<
" X HMono kfdx="<<kfdx<<
"\n";
1164 Mtrans = prod(Mprob, Mtrans);
1166 }
else if (P.type ==
"HDipole") {
1167 if (MpoleLevel >= 1) {
1168 V0 = linetab.E0[n]*EfieldScl;
1171 dpy = -MU0*C0*real.
IonZ*V0/beta/gamma/IonA/AU*(T*cos(IonFy+M_PI/2e0)-S*sin(IonFy+M_PI/2e0));
1172 if(logme) FLAME_LOG(FINE)<<
" X HDipole dpy="<<dpy<<
"\n";
1175 Mtrans = prod(Mprob, Mtrans);
1177 }
else if (P.type ==
"HQuad") {
1178 if (MpoleLevel >= 2) {
1181 beta = (beta_tab[0]+beta_tab[1])/2e0;
1182 gamma = (gamma_tab[0]+gamma_tab[1])/2e0;
1184 beta = (beta_tab[1]+beta_tab[2])/2e0;
1185 gamma = (gamma_tab[1]+gamma_tab[2])/2e0;
1187 V0 = linetab.E0[n]*EfieldScl;
1190 kfdx = -MU0*C0*real.
IonZ*V0/beta/gamma/IonA/AU*(T*cos(IonFy+M_PI/2e0)-S*sin(IonFy+M_PI/2e0))/Rm;
1192 if(logme) FLAME_LOG(FINE)<<
" X HQuad kfdx="<<kfdx<<
"\n";
1196 Mtrans = prod(Mprob, Mtrans);
1198 }
else if (P.type ==
"AccGap") {
1202 beta = beta_tab[seg];
1203 gamma = gamma_tab[seg];
1204 kfac = 2e0*M_PI/(beta*Lambda);
1205 Accel = linetab.Accel[n];
1206 if(logme) FLAME_LOG(FINE)<<
" X AccGap Accel="<<Accel<<
"\n";
1208 Mprob(1, 1) = Accel;
1209 Mprob(3, 3) = Accel;
1210 Mtrans = prod(Mprob, Mtrans);
1212 std::ostringstream strm;
1213 strm <<
"*** GetCavMat: undef. multipole type " << P.type <<
"\n";
1214 throw std::runtime_error(strm.str());
1219 if(logme) FLAME_LOG(FINE)<<
"Elem "<<P.name<<
":"<<P.type<<
"\n Mtrans "<<Mtrans<<
"\nMprob "<<Mprob<<
"\n";
1224 M(4, 4) = Mlon(4, 4);
1225 M(4, 5) = Mlon(4, 5);
1226 M(5, 4) = Mlon(5, 4);
1227 M(5, 5) = Mlon(5, 5);
1231 void ElementRFCavity::GetCavMat(
const int cavi,
const int cavilabel,
const double Rm,
Particle &real,
1232 const double EfieldScl,
const double IonFyi_s,
1233 const double IonEk_s, state_t::matrix_t &M,
1234 CavTLMLineType &linetab)
const
1236 double CaviLambda, Ecen[2], T[2], Tp[2], S[2], Sp[2], V0[2];
1237 double dis, IonW_s[3], IonFy_s[3], gamma_s[3], beta_s[3], CaviIonK_s[3];
1240 CaviLambda = C0/fRF*MtoMM;
1242 IonW_s[0] = IonEk_s + real.
IonEs;
1243 IonFy_s[0] = IonFyi_s;
1244 gamma_s[0] = IonW_s[0]/real.
IonEs;
1245 beta_s[0] = sqrt(1e0-1e0/sqr(gamma_s[0]));
1246 CaviIonK_s[0] = 2e0*M_PI/(beta_s[0]*CaviLambda);
1248 size_t n = CavData.table.size1();
1250 dis = (CavData.table(n-1,0)-CavData.table(0,0))/2e0;
1252 ElementRFCavity::TransFacts(cavilabel, beta_s[0], CaviIonK_s[0], 1, EfieldScl,
1253 Ecen[0], T[0], Tp[0], S[0], Sp[0], V0[0]);
1254 EvalGapModel(dis, IonW_s[0], real, IonFy_s[0], CaviIonK_s[0], CaviLambda,
1255 Ecen[0], T[0], S[0], Tp[0], Sp[0], V0[0], IonW_s[1], IonFy_s[1]);
1256 gamma_s[1] = IonW_s[1]/real.
IonEs;
1257 beta_s[1] = sqrt(1e0-1e0/sqr(gamma_s[1]));
1258 CaviIonK_s[1] = 2e0*M_PI/(beta_s[1]*CaviLambda);
1260 ElementRFCavity::TransFacts(cavilabel, beta_s[1], CaviIonK_s[1], 2, EfieldScl,
1261 Ecen[1], T[1], Tp[1], S[1], Sp[1], V0[1]);
1262 EvalGapModel(dis, IonW_s[1], real, IonFy_s[1], CaviIonK_s[1], CaviLambda,
1263 Ecen[1], T[1], S[1], Tp[1], Sp[1], V0[1], IonW_s[2], IonFy_s[2]);
1264 gamma_s[2] = IonW_s[2]/real.
IonEs;
1265 beta_s[2] = sqrt(1e0-1e0/sqr(gamma_s[2]));
1266 CaviIonK_s[2] = 2e0*M_PI/(beta_s[2]*CaviLambda);
1268 Ecen[0] = Ecen[0] - dis;
1270 double TTF_tab[] = {Ecen[0], T[0], Tp[0], S[0], Sp[0], V0[0], Ecen[1], T[1], Tp[1], S[1], Sp[1], V0[1]};
1271 CaviIonK[0] = (CaviIonK_s[0]+CaviIonK_s[1])/2e0;
1272 CaviIonK[1] = (CaviIonK_s[1]+CaviIonK_s[2])/2e0;
1275 printf(
"\n GetCavMat:\n");
1276 printf(
"CaviIonK: %15.10f %15.10f %15.10f\n", CaviIonK_s[0], CaviIonK_s[1], CaviIonK_s[2]);
1277 printf(
"CaviIonK: %15.10f %15.10f\n", CaviIonK[0], CaviIonK[1]);
1278 printf(
"beta: %15.10f %15.10f %15.10f\n", beta_s[0], beta_s[1], beta_s[2]);
1279 printf(
"gamma: %15.10f %15.10f %15.10f\n", gamma_s[0], gamma_s[1], gamma_s[2]);
1280 printf(
"Ecen: %15.10f %15.10f\n", Ecen[0], Ecen[1]);
1281 printf(
"T: %15.10f %15.10f\n", T[0], T[1]);
1282 printf(
"Tp: %15.10f %15.10f\n", Tp[0], Tp[1]);
1283 printf(
"S: %15.10f %15.10f\n", S[0], S[1]);
1284 printf(
"Sp: %15.10f %15.10f\n", Sp[0], Sp[1]);
1285 printf(
"V0: %15.10f %15.10f\n", V0[0], V0[1]);
1288 ElementRFCavity::GetCavMatParams(cavi, beta_s, gamma_s, CaviIonK, linetab);
1289 ElementRFCavity::GenCavMat2(cavi, dis, EfieldScl, TTF_tab, beta_s, gamma_s, CaviLambda, real, IonFy_s, Rm, M, linetab);
1293 void ElementRFCavity::GetCavMatGeneric(
Particle &real,
const double EfieldScl,
const double IonFyi_s,
1294 const double IonEk_s, state_t::matrix_t &M, CavTLMLineType &linetab)
const
1297 const double IonA = 1e0;
1298 const bool logme = FLAME_LOG_CHECK(DEBUG);
1299 state_t::matrix_t Idmat, Mlon, Mtrans,Mprob,MprobLon;
1300 Idmat = boost::numeric::ublas::identity_matrix<double>(PS_Dim);
1304 double IonW0 = IonEk_s + real.
IonEs;
1305 double gamma0 = IonW0/real.
IonEs;
1306 double beta0 = sqrt(1e0-1e0/sqr(gamma0));
1307 double IonFy0 = IonFyi_s;
1308 double CaviLambda = C0/fRF*MtoMM;
1309 double kfac0 = 2e0*M_PI/(beta0*CaviLambda);
1310 double dis = 0.0, V0 = 0.0, T = 0.0, S = 0.0, kfdx = 0.0, kfdy = 0.0, Accel = 0.0;
1313 double IonW=IonW0,gamma=gamma0,beta=beta0,IonFy=IonFy0,kfac=kfac0;
1317 for(
unsigned n=0; n<lattice.size(); n++) {
1318 const RawParams& P = lattice[n];
1320 dis+=lattice[n].length;
1323 printf(
"%9.5f %8s %8s %9.5f %9.5f %9.5f\n",
1324 dis, P.type.c_str(), P.name.c_str(), P.length, P.aperature, P.E0);
1328 if (P.type ==
"drift") {
1329 IonFy = IonFy + kfac*P.length;
1331 Mprob(0, 1) = P.length;
1332 Mprob(2, 3) = P.length;
1333 Mtrans = prod(Mprob, Mtrans);
1336 MprobLon(4, 5) = -2e0*M_PI/CaviLambda*(1e0/cube(beta*gamma)*MeVtoeV/real.
IonEs*P.length);
1337 Mlon = prod(MprobLon, Mlon);
1339 }
else if (P.type ==
"EFocus") {
1340 V0 = P.E0*EfieldScl;
1341 T = calFitPow(kfac,P.Tfit);
1342 S = calFitPow(kfac,P.Sfit);
1343 kfdx = real.
IonZ*V0/sqr(beta)/gamma/IonA/AU*(T*cos(IonFy)-S*sin(IonFy))/cRm;
1346 FLAME_LOG(FINE)<<
" X EFocus1 kfdx="<<kfdx<<
"\n"
1347 <<
" Y "<<linetab.E0[n]<<
" "<<EfieldScl<<
" "<<beta
1348 <<
" "<<gamma<<
" "<<IonFy<<
" "<<cRm<<
"\n Z "<<T<<
" "<<S<<
"\n";
1353 Mtrans = prod(Mprob, Mtrans);
1355 }
else if (P.type ==
"EDipole") {
1356 if (MpoleLevel >= 1) {
1357 V0 = P.E0*EfieldScl;
1358 T = calFitPow(kfac,P.Tfit);
1359 S = calFitPow(kfac,P.Sfit);
1360 dpy = real.
IonZ*V0/sqr(beta)/gamma/IonA/AU*(T*cos(IonFy)-S*sin(IonFy));
1361 if(logme) FLAME_LOG(FINE)<<
" X EDipole dpy="<<dpy<<
"\n";
1364 Mtrans = prod(Mprob, Mtrans);
1366 }
else if (P.type ==
"EQuad") {
1367 if (MpoleLevel >= 2) {
1368 V0 = P.E0*EfieldScl;
1369 T = calFitPow(kfac,P.Tfit);
1370 S = calFitPow(kfac,P.Sfit);
1371 kfdx = real.
IonZ*V0/sqr(beta)/gamma/IonA/AU*(T*cos(IonFy)-S*sin(IonFy))/cRm;
1373 if(logme) FLAME_LOG(FINE)<<
" X EQuad kfdx="<<kfdx<<
"\n";
1377 Mtrans = prod(Mprob, Mtrans);
1379 }
else if (P.type ==
"HMono") {
1380 if (MpoleLevel >= 2) {
1381 V0 = P.E0*EfieldScl;
1382 T = calFitPow(kfac,P.Tfit);
1383 S = calFitPow(kfac,P.Sfit);
1384 kfdx = -MU0*C0*real.
IonZ*V0/beta/gamma/IonA/AU*(T*cos(IonFy+M_PI/2e0)-S*sin(IonFy+M_PI/2e0))/cRm;
1386 if(logme) FLAME_LOG(FINE)<<
" X HMono kfdx="<<kfdx<<
"\n";
1390 Mtrans = prod(Mprob, Mtrans);
1392 }
else if (P.type ==
"HDipole") {
1393 if (MpoleLevel >= 1) {
1394 V0 = P.E0*EfieldScl;
1395 T = calFitPow(kfac,P.Tfit);
1396 S = calFitPow(kfac,P.Sfit);
1397 dpy = -MU0*C0*real.
IonZ*V0/beta/gamma/IonA/AU*(T*cos(IonFy+M_PI/2e0)-S*sin(IonFy+M_PI/2e0));
1398 if(logme) FLAME_LOG(FINE)<<
" X HDipole dpy="<<dpy<<
"\n";
1401 Mtrans = prod(Mprob, Mtrans);
1403 }
else if (P.type ==
"HQuad") {
1404 if (MpoleLevel >= 2) {
1405 V0 = P.E0*EfieldScl;
1406 T = calFitPow(kfac,P.Tfit);
1407 S = calFitPow(kfac,P.Sfit);
1408 kfdx = -MU0*C0*real.
IonZ*V0/beta/gamma/IonA/AU*(T*cos(IonFy+M_PI/2e0)-S*sin(IonFy+M_PI/2e0))/cRm;
1410 if(logme) FLAME_LOG(FINE)<<
" X HQuad kfdx="<<kfdx<<
"\n";
1414 Mtrans = prod(Mprob, Mtrans);
1416 }
else if (P.type ==
"AccGap") {
1417 V0 = P.E0*EfieldScl;
1418 T = calFitPow(kfac,P.Tfit);
1419 S = calFitPow(kfac,P.Sfit);
1420 IonW=IonW+real.
IonZ*V0*MeVtoeV*T*cos(IonFy)-real.
IonZ*V0*MeVtoeV*S*sin(IonFy);
1421 double gamma_f=IonW/real.
IonEs;
1422 double beta_f=sqrt(1.0-1.0/(gamma_f*gamma_f));
1423 kfac = 2e0*M_PI/(beta_f*CaviLambda);
1424 Accel = (beta*gamma)/((beta_f*gamma_f));
1425 if(logme) FLAME_LOG(FINE)<<
" X AccGap Accel="<<Accel<<
"\n";
1427 Mprob(1, 1) = Accel;
1428 Mprob(3, 3) = Accel;
1429 Mtrans = prod(Mprob, Mtrans);
1431 MprobLon(5, 4) = -real.
IonZ*V0*T*sin(IonFy)-real.
IonZ*V0*S*cos(IonFy);
1432 Mlon = prod(MprobLon, Mlon);
1438 std::ostringstream strm;
1439 strm <<
"*** GetCavMat: undef. multipole type " << P.type <<
"\n";
1440 throw std::runtime_error(strm.str());
1445 if(logme) FLAME_LOG(FINE)<<
"Elem "<<P.name<<
":"<<P.type<<
"\n Mtrans "<<Mtrans<<
"\nMprob "<<Mprob<<
"\n";
1450 M(4, 4) = Mlon(4, 4);
1451 M(4, 5) = Mlon(4, 5);
1452 M(5, 4) = Mlon(5, 4);
1453 M(5, 5) = Mlon(5, 5);
1456 double ElementRFCavity::calFitPow(
double kfac,
const std::vector<double>& Tfit)
const
1458 int order=Tfit.size();
1460 for (
int ii=0; ii<order; ii++)
1462 res=res+Tfit[ii]*ipow(kfac,order-ii-1);
1467 void ElementRFCavity::GetCavBoost(
const numeric_table &CavData,
Particle &state,
const double IonFy0,
1468 const double EfieldScl,
double &IonFy)
const
1470 size_t n = CavData.table.size1();
1474 const bool logme = FLAME_LOG_CHECK(DEBUG);
1476 const double dis = CavData.table(n-1, 0) - CavData.table(0, 0),
1478 CaviLambda = C0/fRF*MtoMM;
1481 FLAME_LOG(DEBUG)<<__FUNCTION__
1482 <<
" IonFy0="<<IonFy0
1484 <<
" EfieldScl="<<EfieldScl
1490 double CaviIonK = 2e0*M_PI*fRF/(state.beta*C0*MtoMM);
1491 for (
size_t k = 0; k < n-1; k++) {
1492 double IonFylast = IonFy;
1493 IonFy += CaviIonK*dz;
1494 state.IonW += state.IonZ*EfieldScl*(CavData.table(k,1)+CavData.table(k+1,1))/2e0
1495 *cos((IonFylast+IonFy)/2e0)*dz/MtoMM;
1496 double IonGamma = state.IonW/state.IonEs;
1497 double IonBeta = sqrt(1e0-1e0/sqr(IonGamma));
1498 if ((state.IonW-state.IonEs) < 0e0) {
1499 state.IonW = state.IonEs;
1504 CaviIonK = 2e0*M_PI/(IonBeta*CaviLambda);
1505 if(logme) FLAME_LOG(DEBUG)<<
" "<<k<<
" CaviIonK="<<CaviIonK<<
" IonW="<<state.IonW<<
"\n";
1510 void ElementRFCavity::PropagateLongRFCav(
Particle &ref,
double& phi_ref)
const
1512 double multip, EfieldScl, caviFy, IonFy_i, IonFy_o;
1513 double fsync = conf().get<
double>(
"syncflag", 1.0);
1516 EfieldScl = conf().get<
double>(
"scl_fac");
1518 if (cavi == 0 && have_EkLim) {
1519 if (ref.
IonEk/MeVtoeV < EkLim[0] || ref.
IonEk/MeVtoeV > EkLim[1])
1520 FLAME_LOG(WARN)<<
"Warning: RF cavity incident energy (" << ref.
IonEk/MeVtoeV
1521 <<
" [MeV]) is out of range (" << EkLim[0] <<
" ~ " << EkLim[1] <<
").\n";
1525 if (cavi == 0 && have_RefNrm && have_SynComplex && fsync == 1.0) {
1527 double NormScl = EfieldScl*ref.
IonZ/RefNrm;
1529 if (NormScl < NrLim[0] || NormScl > NrLim[1])
1530 FLAME_LOG(WARN)<<
"Warning: RF cavity normalized scale (" << NormScl
1531 <<
") is out of range (" << NrLim[0] <<
" ~ " << NrLim[1] <<
").\n";
1533 caviFy = GetCavPhaseComplex(ref, IonFys, NormScl, multip, SynComplex);
1536 caviFy = GetCavPhase(cavi, ref, IonFys, multip, SynAccTab);
1539 caviFy = conf().get<
double>(
"phi")*M_PI/180e0;
1542 IonFy_i = multip*ref.
phis + caviFy;
1544 FLAME_LOG(DEBUG)<<
"RF long phase"
1546 <<
" multip="<<multip
1547 <<
" phis="<<ref.
phis
1548 <<
" IonFy_i="<<IonFy_i
1549 <<
" EfieldScl="<<EfieldScl
1554 GetCavBoost(CavData, ref, IonFy_i, EfieldScl, IonFy_o);
1558 ref.
phis += (IonFy_o-IonFy_i)/multip;
1562 void ElementRFCavity::calRFcaviEmitGrowth(
const state_t::matrix_t &matIn,
Particle &state,
const int n,
const double betaf,
const double gamaf,
1563 const double aveX2i,
const double cenX,
const double aveY2i,
const double cenY,
1564 state_t::matrix_t &matOut)
1568 double ionLamda, E0TL, DeltaPhi, kpX, fDeltaPhi, f2DeltaPhi, gPhisDeltaPhi, deltaAveXp2f, XpIncreaseFactor;
1569 double kpY, deltaAveYp2f, YpIncreaseFactor, kpZ, ionK, aveZ2i, deltaAveZp2, longiTransFactor, ZpIncreaseFactor;
1573 ionLamda = C0/fRF*MtoMM;
1576 const double accIonW = last_real_out[n].IonW -last_real_in[n].IonW,
1577 ave_beta = (last_real_out[n].beta +last_real_in[n].beta)/2.0,
1578 ave_gamma = (last_real_out[n].gamma+last_real_in[n].gamma)/2.0;
1580 E0TL = accIonW/cos(IonFys)/state.
IonZ;
1583 if (cos(IonFys) > -0.0001 && cos(IonFys) < 0.0001) E0TL = 0e0;
1584 DeltaPhi = sqrt(matIn(4, 4));
1586 kpX = -M_PI*fabs(state.
IonZ)*E0TL/state.
IonEs/sqr(ave_beta*ave_gamma)/betaf/gamaf/ionLamda;
1587 fDeltaPhi = 15e0/sqr(DeltaPhi)*(3e0/sqr(DeltaPhi)*(sin(DeltaPhi)/DeltaPhi-cos(DeltaPhi))-(sin(DeltaPhi)/DeltaPhi));
1588 f2DeltaPhi = 15e0/sqr(2e0*DeltaPhi)*(3e0/sqr(2e0*DeltaPhi)
1589 *(sin(2e0*DeltaPhi)/(2e0*DeltaPhi)-cos(2e0*DeltaPhi))-(sin(2e0*DeltaPhi)/(2e0*DeltaPhi)));
1590 gPhisDeltaPhi = 0.5e0*(1+(sqr(sin(IonFys))-sqr(cos(IonFys)))*f2DeltaPhi);
1591 deltaAveXp2f = kpX*kpX*(gPhisDeltaPhi-sqr(sin(IonFys)*fDeltaPhi))*(aveX2i+cenX*cenX);
1592 XpIncreaseFactor = 1e0;
1594 if (deltaAveXp2f+matIn(1, 1) > 0e0) XpIncreaseFactor = sqrt((deltaAveXp2f+matIn(1, 1))/matIn(1, 1));
1597 kpY = -M_PI*fabs(state.
IonZ)*E0TL/state.
IonEs/sqr(ave_beta*ave_gamma)/betaf/gamaf/ionLamda;
1598 deltaAveYp2f = sqr(kpY)*(gPhisDeltaPhi-sqr(sin(IonFys)*fDeltaPhi))*(aveY2i+sqr(cenY));
1599 YpIncreaseFactor = 1.0;
1600 if (deltaAveYp2f+matIn(3, 3)>0) {
1601 YpIncreaseFactor = sqrt((deltaAveYp2f+matIn(3, 3))/matIn(3, 3));
1604 kpZ = -2e0*kpX*sqr(ave_gamma);
1606 ionK = 2e0*M_PI/(ave_beta*ionLamda);
1607 aveZ2i = sqr(DeltaPhi)/sqr(ionK);
1608 deltaAveZp2 = sqr(kpZ*DeltaPhi)*aveZ2i*(sqr(cos(IonFys))/8e0+DeltaPhi*sin(IonFys)/576e0);
1609 longiTransFactor = 1e0/(ave_gamma-1e0)/state.
IonEs*MeVtoeV;
1610 ZpIncreaseFactor = 1e0;
1611 if (deltaAveZp2+matIn(5, 5)*sqr(longiTransFactor) > 0e0)
1612 ZpIncreaseFactor = sqrt((deltaAveZp2+matIn(5, 5)*sqr(longiTransFactor))/(matIn(5, 5)*sqr(longiTransFactor)));
1614 for (k = 0; k < PS_Dim; k++) {
1615 matOut(1, k) *= XpIncreaseFactor;
1616 matOut(k, 1) *= XpIncreaseFactor;
1617 matOut(3, k) *= YpIncreaseFactor;
1618 matOut(k, 3) *= YpIncreaseFactor;
1619 matOut(5, k) *= ZpIncreaseFactor;
1620 matOut(k, 5) *= ZpIncreaseFactor;
1625 void ElementRFCavity::InitRFCav(
Particle &real, state_t::matrix_t &M, CavTLMLineType &linetab)
1628 double Rm, multip, IonFy_i, Ek_i, EfieldScl, IonFy_o;
1630 FLAME_LOG(DEBUG)<<
"RF recompute start "<<real<<
"\n";
1635 }
else if (cavi== 2) {
1638 }
else if (cavi== 3) {
1641 }
else if (cavi== 4) {
1644 }
else if (cavi== 5) {
1648 }
else if (cavi == 0) {
1653 throw std::logic_error(SB()<<
"*** InitRFCav: undef. cavity type: after ctor");
1658 IonFy_i = multip*real.
phis + phi_ref;
1662 EfieldScl = conf().get<
double>(
"scl_fac");
1663 ElementRFCavity::GetCavBoost(CavData, real, IonFy_i, EfieldScl, IonFy_o);
1667 real.
phis += (IonFy_o-IonFy_i)/multip;
1669 FLAME_LOG(DEBUG)<<
"RF recompute before "<<real
1671 <<
" cavilabel="<<cavilabel
1673 <<
" EfieldScl="<<EfieldScl
1674 <<
" IonFy_i="<<IonFy_i
1681 GetCavMat(cavi, cavilabel, Rm, real, EfieldScl, IonFy_i, Ek_i, M, linetab);
1685 GetCavMatGeneric(real, EfieldScl, IonFy_i, Ek_i, M, linetab);
1691 for (
int i=0; i < state_t::maxsize; i++){
1697 FLAME_LOG(DEBUG)<<
"RF recompute after "<<real<<
"\n"
Config * parse_file(const char *fname, const bool have_lattice=true)
Open and parse a file.
double IonW
Total energy. (dependent)
Interface to lattice file parser.
double IonEk
Kinetic energy.
double phis
Absolute synchrotron phase [rad].
double SampleFreq
Sampling frequency [Hz].
Associative configuration container.
bool tryGet(const std::string &name, T &val) const
detail::RT< T >::type get(const std::string &name) const