OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
BeamStrippingPhysics.cpp
Go to the documentation of this file.
1 // ------------------------------------------------------------------------
2 //
3 // Class:BeamStrippingPhysics
4 // Defines the beam stripping physics models
5 //
6 // ------------------------------------------------------------------------
7 // Class category: ParticleMatterInteraction
8 // ------------------------------------------------------------------------
9 // $Date: 2018/11 $
10 // $Author: PedroCalvo$
11 //-------------------------------------------------------------------------
12 
14 #include "AbsBeamline/Cyclotron.h"
16 #include "Algorithms/PartData.h"
17 #include "Physics/Physics.h"
19 #include "Structure/LossDataSink.h"
20 #include "Utilities/Options.h"
21 #include "Utilities/Util.h"
22 #include "Utilities/Timer.h"
23 
24 #include "Ippl.h"
25 
26 #include <iostream>
27 #include <fstream>
28 #include <algorithm>
29 #include <math.h>
30 #include <sys/time.h>
31 #include <boost/math/special_functions/chebyshev.hpp>
32 
33 using namespace std;
34 
35 using Physics::kB;
36 using Physics::q_e;
37 using Physics::m_e;
38 using Physics::c;
39 using Physics::m_hm;
40 using Physics::m_p;
41 using Physics::m_h;
42 using Physics::m_h2p;
43 using Physics::E_ryd;
44 
45 namespace {
46  struct InsideTester {
47  virtual ~InsideTester() {}
48 
49  virtual bool checkHit(const Vector_t &R) = 0;
50  virtual double getPressure(const Vector_t &R) = 0;
51  };
52  struct BeamStrippingInsideTester: public InsideTester {
53  explicit BeamStrippingInsideTester(ElementBase * el) {
54  bstp_m = static_cast<BeamStripping*>(el);
55  }
56  virtual bool checkHit(const Vector_t &R) {
57  return bstp_m->checkPoint(R(0), R(1), R(2));
58  }
59  double getPressure(const Vector_t &R) {
60  return bstp_m->checkPressure(R(0)*0.001, R(1)*0.001);
61  }
62  private:
63  BeamStripping *bstp_m;
64  };
65 }
66 
67 
69  ParticleMatterInteractionHandler(name, element),
70  T_m(0.0),
71  dT_m(0.0),
72  mass_m(0.0),
73  charge_m(0.0),
74  pressure_m(0.0),
75  NCS_a(0.0),
76  NCS_b(0.0),
77  NCS_c(0.0),
78  NCS_total(0.0),
79  bunchToMatStat_m(0),
80  stoppedPartStat_m(0),
81  rediffusedStat_m(0),
82  locPartsInMat_m(0)
83 {
84  bstp_m = dynamic_cast<BeamStripping *>(getElement()->removeWrappers());
86  lossDs_m = std::unique_ptr<LossDataSink>(new LossDataSink(element_ref_m->getName(), !Options::asciidump));
87 
88  const gsl_rng_type * T;
89  gsl_rng_env_setup();
90  struct timeval tv; // Seed generation based on time
91  gettimeofday(&tv,0);
92  unsigned long mySeed = tv.tv_sec + tv.tv_usec;
93  T = gsl_rng_default; // Generator setup
94  r_m = gsl_rng_alloc (T);
95  gsl_rng_set(r_m, mySeed);
96 
98 }
99 
100 
102  lossDs_m->save();
103  gsl_rng_free(r_m);
104 }
105 
106 const std::string BeamStrippingPhysics::getType() const {
107  return "BeamStrippingPhysics";
108 }
109 
111  const std::pair<Vector_t, double> &boundingSphere,
112  size_t numParticlesInSimulation) {
113 
114  dT_m = bunch->getdT();
115 
116  double mass = bunch->getM()*1E-9;
117 
118  if (bunch->get_sPos() != 0) {
119  if(abs(mass-m_hm) < 1E-6 ||
120  abs(mass-m_p) < 1E-6 ||
121  abs(mass-m_h2p) < 1E-6 ||
122  abs(mass-m_h) < 1E-6)
123  doPhysics(bunch);
124  else {
125  Inform gmsgALL("OPAL", INFORM_ALL_NODES);
126  gmsgALL << getName() << ": Unsupported type of particle for residual gas interactions!"<< endl;
127  gmsgALL << getName() << "-> Beam Stripping Physics not apply"<< endl;
128  }
129  }
130 }
131 
132 
134  /*
135  Do physics if
136  -- particle in material
137  -- particle not dead (bunch->Bin[i] != -1)
138  Delete particle i: bunch->Bin[i] != -1;
139  */
140 
141  double Eng = 0.0;
142  double gamma = 0.0;
143  double beta = 0.0;
144  double deltas = 0.0;
145  Vector_t extE = Vector_t(0.0, 0.0, 0.0);
146  Vector_t extB = Vector_t(0.0, 0.0, 0.0); //kGauss
147  double E = 0.0;
148  double B = 0.0;
149 
150  bool stop = bstp_m->getStop();
151 
152  InsideTester *tester;
153  tester = new BeamStrippingInsideTester(element_ref_m);
154 
155  Inform gmsgALL("OPAL", INFORM_ALL_NODES);
156 
157  for (size_t i = 0; i < bunch->getLocalNum(); ++i) {
158  if ( (bunch->Bin[i] != -1) && (tester->checkHit(bunch->R[i]))) {
159 
160  bool pdead_GS = false;
161  bool pdead_LS = false;
162  pressure_m = tester->getPressure(bunch->R[i]);
163  mass_m = bunch->M[i];
164  charge_m = bunch->Q[i];
165 
166  Eng = (sqrt(1.0 + dot(bunch->P[i], bunch->P[i])) - 1) * mass_m; //GeV
167  gamma = (Eng + mass_m) / mass_m;
168  beta = sqrt(1.0 - 1.0 / (gamma * gamma));
169  deltas = dT_m * beta * c;
170 
171  crossSection(bunch->R[i], Eng);
172  pdead_GS = gasStripping(deltas);
173 
174  if(abs(mass_m-m_hm) < 1E-6 && charge_m == -q_e) {
175  cycl_m->apply(bunch->R[i]*0.001, bunch->P[i], T_m, extE, extB);
176  B = 0.1 * sqrt(extB[0]*extB[0] + extB[1]*extB[1] + extB[2]*extB[2]); //T
177  E = gamma * beta * c * B;
178  pdead_LS = lorentzStripping(gamma, E);
179  }
180 
181  if (pdead_GS == true || pdead_LS == true) {
182  lossDs_m->addParticle(bunch->R[i]*0.001, bunch->P[i], bunch->ID[i],
183  bunch->getT()*1e9, 0, bunch->bunchNum[i]);
184  if (stop) {
185  bunch->Bin[i] = -1;
187  gmsgALL << level4 << getName() << ": Particle " << bunch->ID[i]
188  << " is deleted by beam stripping" << endl;
189  }
190  else {
191  secondaryParticles(bunch, i, pdead_LS);
192  bunch->updateNumTotal();
193  gmsgALL << level4 << getName()
194  << ": Total number of particles after beam stripping = "
195  << bunch->getTotalNum() << endl;
196  }
197  }
198  }
199  }
200  delete tester;
201 }
202 
203 
204 void BeamStrippingPhysics::crossSection(const Vector_t &R, double Eng){
205 
206  const double temperature = bstp_m->getTemperature(); // K
207 
208  Eng *=1E6; //keV
209  double Emin = 0.0;
210  double Emax = 0.0;
211  double Eth = 0.0;
212  double a1 = 0.0;
213  double a2 = 0.0;
214  double a3 = 0.0;
215  double a4 = 0.0;
216  double a5 = 0.0;
217  double a6 = 0.0;
218  double a7 = 0.0;
219  double a8 = 0.0;
220  double a9 = 0.0;
221  double a10 = 0.0;
222  double a11 = 0.0;
223  double a12 = 0.0;
224 
225  double molecularDensity[3] ={};
226 
227  if (gas_m == "H2") {
228 
229  molecularDensity[0] = 100 * pressure_m / (kB * q_e * temperature);
230 
231  double CS_a = 0.0;
232  double CS_b = 0.0;
233  double CS_c = 0.0;
234  double CS_total = 0.0;
235 
236  if(abs(mass_m-m_hm) < 1E-6 && charge_m == -q_e) {
237  // Single-electron detachment - Hydrogen Production
240  for (int i = 0; i < 9; ++i)
242  CS_a = csChebyshevFitting(Eng*1E3, Emin, Emax);
243 
244  // Double-electron detachment - Proton Production
247  for (int i = 0; i < 9; ++i)
249  CS_b = csChebyshevFitting(Eng*1E3, Emin, Emax);
250  }
251  else if(abs(mass_m-m_p) < 1E-6 && charge_m == q_e) {
252  // Single-electron capture - Hydrogen Production
255  for (int i = 0; i < 9; ++i)
256  a_m[i] = {csCoefSingle_Hplus_Chebyshev[i+2]};
257  CS_a = csChebyshevFitting(Eng*1E3, Emin, Emax);
258 
259  // Double-electron capture - Hminus Production
262  for (int i = 0; i < 9; ++i)
263  a_m[i] = {csCoefDouble_Hplus_Chebyshev[i+2]};
264  CS_b = csChebyshevFitting(Eng*1E3, Emin, Emax);
265  }
266  else if(abs(mass_m-m_h) < 1E-6 && charge_m == 0.0) {
267  // Single-electron detachment - Proton Production
275  CS_a = csAnalyticFunctionTabata(Eng, Eth, a1, a2, 0.0, 0.0, a3, a4) +
276  a5 * csAnalyticFunctionTabata(Eng/a6, Eth/a6, a1, a2, 0.0, 0.0, a3, a4);
277 
278  // Single-electron capture - Hminus Production
292  CS_b = csAnalyticFunctionTabata(Eng, Eth, a1, a2, a3, a4, a5, a6) +
293  csAnalyticFunctionTabata(Eng, Eth, a7, a8, a9, a10, a11, a12);
294  }
295  else if(abs(mass_m-m_h2p) < 1E-6 && charge_m == q_e) {
296  // Proton production
308  CS_a = csAnalyticFunctionTabata(Eng, Eth, a1, a2, 0.0, 0.0, a3, a4) +
309  csAnalyticFunctionTabata(Eng, Eth, a5, a6, 0.0, 0.0, a7, a8) +
310  a9 * csAnalyticFunctionTabata(Eng/a10, Eth/a10, a5, a6, 0.0, 0.0, a7, a8);
311 
312  // Hydrogen production
315  for (int i = 0; i < 9; ++i)
317  CS_b = csChebyshevFitting(Eng*1E3, Emin, Emax);
318 
319  // H3+, H
327  CS_c = csAnalyticFunctionTabata(Eng, Eth, a1, a2, a3, a4, a5, a6);
328  }
329  CS_total = CS_a + CS_b + CS_c;
330  //*gmsg << "* CS_total = " << CS_total << " cm2" << endl;
331 
332  NCS_a = CS_a * 1E-4 * molecularDensity[0];
333  NCS_b = CS_b * 1E-4 * molecularDensity[0];
334  NCS_c = CS_c * 1E-4 * molecularDensity[0];
335  NCS_total = CS_total * 1E-4 * molecularDensity[0];
336  }
337 
338 
339  else if (gas_m == "AIR") {
340 
341  static const double fMolarFraction[3] = {
342  // Nitrogen
343  78.084/100,
344  //Oxygen
345  20.947/100,
346  //Argon
347  0.934/100
348  };
349  double CS_single[3];
350  double CS_double[3];
351  double CS_total[3];
352  double NCS_single[3];
353  double NCS_double[3];
354  double NCS_all[3];
355  double NCS_single_all = 0.0;
356  double NCS_double_all = 0.0;
357  double NCS_total_all = 0.0;
358 
359  for (int i = 0; i < 3; ++i) {
360 
361  molecularDensity[i] = 100 * pressure_m * fMolarFraction[i] / (kB * q_e * temperature);
362 
363  if(abs(mass_m-m_hm) < 1E-6 && charge_m == -q_e) {
364  // Single-electron detachment - Hydrogen Production
365  Eth = csCoefSingle_Hminus[i][0];
366  for (int j = 0; j < 8; ++j)
367  b_m[i][j] = csCoefSingle_Hminus[i][j+1];
368  CS_single[i] = csAnalyticFunctionNakai(Eng, Eth, i);
369 
370  // Double-electron detachment - Proton Production
371  Eth = csCoefDouble_Hminus[i][0];
372  for (int j = 0; j < 8; ++j)
373  b_m[i][j] = csCoefDouble_Hminus[i][j+1];
374  CS_double[i] = csAnalyticFunctionNakai(Eng, Eth, i);
375  }
376  else if(abs(mass_m-m_p) < 1E-6 && charge_m == q_e) {
377  // Single-electron capture - Hydrogen Production
378  Eth = csCoefSingle_Hplus[i][0];
379  for (int j = 0; j < 8; ++j)
380  b_m[i][j] = csCoefSingle_Hplus[i][j+1];
381  CS_single[i] = csAnalyticFunctionNakai(Eng, Eth, i) +
382  b_m[i][6] * csAnalyticFunctionNakai(Eng/b_m[i][7], Eth/b_m[i][7], i);
383 
384  // Double-electron capture - Hminus Production
385  Eth = csCoefDouble_Hplus[i][0];
386  for (int j = 0; j < 8; ++j)
387  b_m[i][j] = csCoefDouble_Hplus[i][j+1];
388  if(b_m[i][7] != 0) {
389  CS_double[i] = csAnalyticFunctionNakai(Eng, Eth, i) +
390  b_m[i][6] * csAnalyticFunctionNakai(Eng/b_m[i][7], Eth/b_m[i][7], i);
391  }
392  else {
393  CS_double[i] = csAnalyticFunctionNakai(Eng, Eth, i);
394  }
395  }
396  else if(abs(mass_m-m_h) < 1E-6 && charge_m == 0.0) {
397  // Single-electron detachment - Proton Production
398  Eth = csCoefSingleLoss_H[i][0];
399  for (int j = 0; j < 8; ++j)
400  b_m[i][j] = csCoefSingleLoss_H[i][j+1];
401  CS_single[i] = csAnalyticFunctionNakai(Eng, Eth, i);
402 
403  // Single-electron capture - Hminus Production
404  Eth = csCoefSingleCapt_H[i][0];
405  for (int j = 0; j < 8; ++j)
406  b_m[i][j] = csCoefSingleCapt_H[i][j+1];
407  if(b_m[i][7] != 0) {
408  CS_double[i] = csAnalyticFunctionNakai(Eng, Eth, i) +
409  b_m[i][6] * csAnalyticFunctionNakai(Eng/b_m[i][7], Eth/b_m[i][7], i);
410  }
411  else {
412  CS_double[i] = csAnalyticFunctionNakai(Eng, Eth, i);
413  }
414  }
415  else {
416  CS_single[i] = {0.0};
417  CS_double[i] = {0.0};
418  }
419  CS_total[i] = CS_single[i] + CS_double[i];
420 
421  NCS_single[i] = CS_single[i] * 1E-4 * molecularDensity[i];
422  NCS_double[i] = CS_double[i] * 1E-4 * molecularDensity[i];
423  NCS_all[i] = CS_total[i] * 1E-4 * molecularDensity[i];
424 
425  NCS_single_all += NCS_single[i];
426  NCS_double_all += NCS_double[i];
427  NCS_total_all += NCS_all[i];
428  }
429  NCS_a = NCS_single_all;
430  NCS_b = NCS_double_all;
431  NCS_total = NCS_total_all;
432  }
433  else {
434  throw GeneralClassicException("BeamStrippingPhysics::crossSection",
435  "Residual gas not found ...");
436  }
437 }
438 
439 
440 double BeamStrippingPhysics::csAnalyticFunctionNakai(double Eng, double Eth, int &i) {
441 
442  const double E_R = E_ryd*1e6 * m_h / m_e; //keV
443  const double sigma_0 = 1E-16;
444  double E1 = 0.0;
445  double f1 = 0.0;
446  double sigma = 0.0; //cm2
447  if(Eng > Eth) {
448  E1 = (Eng-Eth);
449  f1 = sigma_0 * b_m[i][0] * pow((E1/E_R),b_m[i][1]);
450  if(b_m[i][2] != 0.0 && b_m[i][3] != 0.0)
451  sigma = f1 / (1 + pow((E1/b_m[i][2]),(b_m[i][1]+b_m[i][3])) + pow((E1/b_m[i][4]),(b_m[i][1]+b_m[i][5])));
452  else
453  sigma = f1 / (1 + pow((E1/b_m[i][4]),(b_m[i][1]+b_m[i][5])));
454  }
455  return sigma;
456 }
457 
459  double a1, double a2, double a3, double a4, double a5, double a6) {
460 
461  const double sigma_0 = 1E-16;
462  double E1 = 0.0;
463  double f1 = 0.0;
464  double sigma = 0.0; //cm2
465  if(Eng > Eth) {
466  E1 = (Eng-Eth);
467  f1 = sigma_0 * a1 * pow((E1/(E_ryd*1e6)),a2);
468  if(a3 != 0.0 && a4 != 0.0)
469  sigma = f1 / (1 + pow((E1/a3),(a2+a4)) + pow((E1/a5),(a2+a6)));
470  else
471  sigma = f1 / (1 + pow((E1/a5),(a2+a6)));
472  }
473  return sigma;
474 }
475 
476 double BeamStrippingPhysics::csChebyshevFitting(double Eng, double Emin, double Emax) {
477 
478  double sum_aT = 0.0;
479  double sigma = 0.0; //cm2
480  double aT[8] = {0.0};
481  if(Eng > Emin && Eng < Emax) {
482  double X = ((log(Eng)-log(Emin)) - (log(Emax)-log(Eng))) / (log(Emax)- log(Emin));
483  for (int i = 0; i < 8; ++i) {
484  aT[i] = (a_m[i+1] * boost::math::chebyshev_t(i+1, X));
485  sum_aT += aT[i];
486  }
487  sigma = exp(0.5*a_m[0] + sum_aT);
488  }
489  return sigma;
490 }
491 
492 
494 
495  double xi = gsl_rng_uniform(r_m);
496  double fg = 1-exp(-NCS_total*deltas);
497 
498  return (fg >= xi);
499 }
500 
501 bool BeamStrippingPhysics::lorentzStripping(double &gamma, double &E) {
502 
503  double tau = 0.0;
504  double fL = 0.0;
505  double xi = gsl_rng_uniform(r_m);
506 
507 // //Parametrization
508 // const double A1 = 3.073E-6;
509 // const double A2 = 4.414E9;
510 // tau = (A1/E) * exp(A2/E);
511 
512  //Theoretical
513  const double eps0 = 0.75419 * q_e;
514  const double hbar = Physics::h_bar*1E9*q_e;
515  const double me = m_e*1E9*q_e/(c*c);
516  const double p = 0.0126;
517  const double S0 = 0.783;
518  const double a = 2.01407/Physics::a0;
519  const double k0 = sqrt(2 * me * eps0)/hbar;
520  const double N = (sqrt(2 * k0 * (k0+a) * (2*k0+a)))/a;
521  double zT = eps0 / (q_e * E);
522  tau = (4 * me * zT)/(S0 * N * N * hbar * (1+p)*(1+p) * (1-1/(2*k0*zT))) * exp(4*k0*zT/3);
523  fL = 1 - exp( - dT_m / (gamma * tau));
524 
525  return (fL >= xi);
526 }
527 
529 
530  double r = gsl_rng_uniform(r_m);
531 
532  // change the mass_m and charge_m
533  if(abs(mass_m-m_hm) < 1E-6 && charge_m == -q_e) {
534  if (pdead_LS == true) {
535  transformToHydrogen(bunch, i);
536  }
537  else {
538  if(r > NCS_b/NCS_total)
539  transformToHydrogen(bunch, i);
540  else
541  transformToProton(bunch, i);
542  }
543  }
544 
545  else if(abs(mass_m-m_p) < 1E-6 && charge_m == q_e) {
546  if(r > NCS_b/NCS_total)
547  transformToHydrogen(bunch, i);
548  else
549  transformToHminus(bunch, i);
550  }
551 
552  else if(abs(mass_m-m_h) < 1E-6 && charge_m == 0.0) {
553  if(r > NCS_b/NCS_total)
554  transformToProton(bunch, i);
555  else
556  transformToHminus(bunch, i);
557  }
558 
559  else if(abs(mass_m-m_h2p) < 1E-6 && charge_m == q_e) {
560  if(NCS_c>NCS_b && NCS_b>NCS_a){
561  if(r > (NCS_a+NCS_b)/NCS_total)
562  transformToH3plus(bunch, i);
563  else if(r > NCS_a/NCS_total)
564  transformToHydrogen(bunch, i);
565  else
566  transformToProton(bunch, i);
567  }
568  else if(NCS_a>NCS_b && NCS_b>NCS_c) {
569  if(r > (NCS_c+NCS_b)/NCS_total)
570  transformToProton(bunch, i);
571  else if(r > NCS_c/NCS_total)
572  transformToHydrogen(bunch, i);
573  else
574  transformToH3plus(bunch, i);
575  }
576  else if(NCS_a>NCS_b && NCS_c>NCS_a) {
577  if(r > (NCS_a+NCS_b)/NCS_total)
578  transformToH3plus(bunch, i);
579  else if(r > NCS_b/NCS_total)
580  transformToProton(bunch, i);
581  else
582  transformToHydrogen(bunch, i);
583  }
584  else if(NCS_a>NCS_c && NCS_c>NCS_b) {
585  if(r > (NCS_c+NCS_b)/NCS_total)
586  transformToProton(bunch, i);
587  else if(r > NCS_b/NCS_total)
588  transformToH3plus(bunch, i);
589  else
590  transformToHydrogen(bunch, i);
591  }
592  else if(NCS_b>NCS_c && NCS_b>NCS_a && NCS_a>NCS_c) {
593  if(r > (NCS_c+NCS_a)/NCS_total)
594  transformToHydrogen(bunch, i);
595  else if(r > NCS_c/NCS_total)
596  transformToProton(bunch, i);
597  else
598  transformToH3plus(bunch, i);
599  }
600  else {
601  if(r > (NCS_c+NCS_a)/NCS_total)
602  transformToHydrogen(bunch, i);
603  else if(r > NCS_a/NCS_total)
604  transformToH3plus(bunch, i);
605  else
606  transformToProton(bunch, i);
607  }
608  }
609 
610  bunch->PType[i] = ParticleType::SECONDARY;
611 
612  if(bunch->weHaveBins())
613  bunch->Bin[bunch->getLocalNum()-1] = bunch->Bin[i];
614 }
615 
617  Inform gmsgALL("OPAL", INFORM_ALL_NODES);
618  gmsgALL << level4 << getName() << ": Particle " << bunch->ID[i]
619  << " is transformed to proton" << endl;
620  bunch->M[i] = m_p;
621  bunch->Q[i] = q_e;
622 }
624  Inform gmsgALL("OPAL", INFORM_ALL_NODES);
625  gmsgALL << level4 << getName() << ": Particle " << bunch->ID[i]
626  << " is transformed to neutral hydrogen" << endl;
627  bunch->M[i] = m_h;
628  bunch->Q[i] = 0.0;
629 }
631  Inform gmsgALL("OPAL", INFORM_ALL_NODES);
632  gmsgALL << level4 << getName() << ": Particle " << bunch->ID[i]
633  << " is transformed to negative hydrogen ion" << endl;
634  bunch->M[i] = m_hm;
635  bunch->Q[i] = -q_e;
636 }
638  Inform gmsgALL("OPAL", INFORM_ALL_NODES);
639  gmsgALL << level4 << getName() << ": Particle " << bunch->ID[i]
640  << " is transformed to H3+" << endl;
641  bunch->M[i] = Physics::m_h3p;
642  bunch->Q[i] = q_e;
643 }
644 
646 }
647 
649  return locPartsInMat_m != 0;
650 }
651 
653  bool beamstrippingAlive = true;
654  return beamstrippingAlive;
655 }
656 
657 
658 /*
659  Cross sections parameters for interaction with air
660  -- [1] -> Nitrogen
661  -- [2] -> Oxygen
662  -- [3] -> Argon
663 */
664 const double BeamStrippingPhysics::csCoefSingle_Hminus[3][9] = {
665  {7.50E-04, 4.38E+02, 7.28E-01, 8.40E-01, 2.82E-01, 4.10E+01, 1.37E+00, 0.00E+00, 0.00E+00},
666  {-2.00E-04, 3.45E+02, 4.80E-01, 5.30E-02, 8.40E-02, 1.00E+01, 9.67E-01, 0.00E+00, 0.00E+00},
667  {1.70E-3, 2.47E+01, 3.36E-01, 7.00E+01, 5.00E-01, 9.90E+01, 7.80E-01, 0.00E+00, 0.00E+00}
668 };
669 const double BeamStrippingPhysics::csCoefDouble_Hminus[3][9] = {
670  {1.40E-02, 1.77E+00, 4.80E-01, 0.00E+00, 0.00E+00, 1.52E+02, 1.52E+00, 0.00E+00, 0.00E+00},
671  {1.30E-02, 1.90E+00, 6.20E-01, 0.00E+00, 0.00E+00, 5.20E+01, 9.93E-01, 0.00E+00, 0.00E+00},
672  {1.50E-02, 1.97E+00, 8.90E-01, 0.00E+00, 0.00E+00, 5.10E+01, 9.37E-01, 0.00E+00, 0.00E+00}
673 };
674 const double BeamStrippingPhysics::csCoefSingle_Hplus[3][9] = {
675  {2.00E-03, 1.93E+03, 1.64E+00, 1.98E+00, 6.69E-01, 2.19E+01, 4.15E+00, 3.23E-04, 1.00E+01},
676  {-1.50E-03, 3.86E+05, 1.60E+00, 6.93E-02, 3.28E-01, 7.86E+00, 3.92E+00, 3.20E-04, 1.00E+01},
677  {2.18E-03, 1.61E+04, 2.12E+00, 1.16E+00, 4.44E-01, 1.39E+01, 4.07E+00, 2.99E-04, 1.45E+01}
678 };
679 const double BeamStrippingPhysics::csCoefDouble_Hplus[3][9] = {
680  {2.90E-02, 2.90E-01, 1.50E+00, 1.39E+01, 1.65E+00, 3.94E+01, 5.79E+00, 0.00E+00, 0.00E+00},
681  {2.20E-02, 2.64E-01, 1.50E+00, 1.40E+01, 1.70E+00, 4.00E+01, 5.80E+00, 0.00E+00, 0.00E+00},
682  {2.90E-02, 1.40E-01, 1.87E+00, 2.40E+01, 1.60E+00, 3.37E+01, 4.93E+00, 4.50E-01, 2.00E-01}
683 };
684 const double BeamStrippingPhysics::csCoefSingleLoss_H[3][9] = {
685  {1.36E-02, 2.59E+03, 1.78E+00, 2.69E-01, -3.52E-01, 5.60E+00, 8.99E-01, 0.00E+00, 0.00E+00},
686  {1.36E-02, 3.29E+03, 1.85E+00, 2.89E-01, -2.72E-01, 8.20E+00, 1.09E+00, 0.00E+00, 0.00E+00},
687  {1.36E-02, 1.16E+12, 7.40E+00, 5.36E-01, -5.42E-01, 1.23E+00, 7.26E-01, 0.00E+00, 0.00E+00}
688 };
689 const double BeamStrippingPhysics::csCoefSingleCapt_H[3][9] = {
690  {1.48E-02, 1.15E+00, 1.18E+00, 1.15E+01, 1.19E+00, 3.88E+01, 3.38E+00, 1.00E-01, 2.82E-02},
691  {1.13E-02, 3.26E+00, 1.02E+00, 2.99E+00, 4.50E-01, 1.90E+01, 3.42E+00, 0.00E+00, 0.00E+00},
692  {1.50E-02, 1.24E+03, 3.38E+00, 2.46E+00, 5.20E-01, 7.00E+00, 2.56E+00, 9.10E-02, 1.95E-02}
693 };
694 
695 // Cross sections parameters for interaction with hydrogen gas (H2)
697  2.1E-02, 9.73E-03, 2.38E+00, 1.39E-02, -5.51E-01, 7.7E-02, 2.12E+00, 1.97E-06, 2.051E+00, 5.5E+00, 6.62E-01, 2.02E+01, 3.62E+00
698 };
700  2.0E-02, 2.53E-04, 1.728E+00, 2.164E+00, 7.74E-01, 1.639E+00, 1.43E+01, 0, 0
701 };
703  5.0E-03, 6.34E+01, 1.78E+00, 1.38E-03, 4.06E-01, 1.63E-01, 3.27E-01, 1.554E+01, 3.903E+00, 1.735, 1.02E+01
704 };
706  0.00E+00, 6.05E+00, -5.247E-01, 4.088E-03, 2.872E+00, 7.3E-03, 6.99E+00
707 };
709  2.3, 1.7E+07, -73.1505813599, -1.7569509745, -2.0016760826, -0.1902804971, 0.0171353221, 0.1270833164, -0.1523126215, 0, 0
710 };
712  1.00E+03, 1.00E+07, -79.0158996582, -2.1025185585, -1.2407282591, 0.174798578, 0.1062489152, -0.0004342734, -0.0465673618, 0, 0
713 };
715  2.6E+00, 4.00E+06, -82.5164, -6.70755, -6.10977, -2.6281, 0.709759, 0.639033, 0.10298, 0.26124, -0.263817
716 };
718  200, 1.00E+06, -95.8165, -7.17049, -7.48288, -1.93034, 0.761153, 0.556689, -0.0542859, -0.270184, -0.0147
719 };
721  2.00E+03, 1.00E+05, -70.670173645, -0.632612288, -0.6065212488, -0.0915143117, -0.0121710282, 0.0168179292, 0.0104796877, 0, 0
722 };
723 
724 double BeamStrippingPhysics::a_m[9] = {};
725 double BeamStrippingPhysics::b_m[3][9] = {};
bool weHaveBins() const
ParticleAttrib< Vector_t > P
double getT() const
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
constexpr double kB
Boltzman&#39;s constant in eV/K.
Definition: Physics.h:67
Interface for basic beam line object.
Definition: ElementBase.h:128
int checkPoint(const double &x, const double &y, const double &z)
std::unique_ptr< LossDataSink > lossDs_m
Definition: rbendmap.h:8
constexpr double m_hm
The H- rest mass in GeV.
Definition: Physics.h:115
static const double csCoefDouble_Hminus[3][9]
static const double csCoefSingle_Hplus_Chebyshev[11]
void crossSection(const Vector_t &R, double Eng)
#define INFORM_ALL_NODES
Definition: Inform.h:38
void apply(PartBunchBase< double, 3 > *bunch, const std::pair< Vector_t, double > &boundingSphere, size_t numParticlesInSimulation=0)
Definition: rbendmap.h:8
static const double csCoefSingleCapt_H[3][9]
ParticleAttrib< double > Q
virtual ElementBase * removeWrappers()
Return the design element.
Tps< T > exp(const Tps< T > &x)
Exponential.
Definition: TpsMath.h:165
static const double csCoefDouble_Hplus_Chebyshev[11]
static const double csCoefSingle_Hminus[3][9]
double getdT() const
double getM() const
constexpr double m_p
The proton rest mass in GeV.
Definition: Physics.h:97
virtual const std::string getType() const
virtual const std::string & getName() const
Get element name.
Definition: ElementBase.cpp:95
ParticleAttrib< short > bunchNum
bool stillAlive(PartBunchBase< double, 3 > *bunch)
void secondaryParticles(PartBunchBase< double, 3 > *bunch, size_t &i, bool pdead_LS)
Inform & level4(Inform &inf)
Definition: Inform.cpp:48
static const double csCoefSingle_Hplus[3][9]
size_t getTotalNum() const
Tps< T > log(const Tps< T > &x)
Natural logarithm.
Definition: TpsMath.h:182
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition: Vector3D.cpp:118
virtual ElementType getType() const =0
Get element type std::string.
virtual bool apply(const size_t &id, const double &t, Vector_t &E, Vector_t &B)
Definition: Cyclotron.cpp:342
constexpr double m_e
The electron rest mass in GeV.
Definition: Physics.h:85
constexpr double m_h3p
The H3+ rest mass in GeV.
Definition: Physics.h:136
static const double csCoefProtonProduction_H2plus_Tabata[11]
static const double csCoefH3plusProduction_H2plus_Tabata[7]
constexpr double E_ryd
Rydberg&#39;s energy (Rydberg&#39;s constant times hc) in GeV.
Definition: Physics.h:70
double csAnalyticFunctionNakai(double Eng, double Eth, int &i)
ParticleAttrib< short > PType
ParticleIndex_t & ID
bool lorentzStripping(double &gamma, double &E)
static const double csCoefSingleLoss_H[3][9]
ElementBase::ElementType bstpshape_m
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
constexpr double a0
Bohr radius in m.
Definition: Physics.h:73
virtual bool getStop() const
double getTemperature() const
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6
static const double csCoefDouble_Hminus_Chebyshev[11]
void transformToHminus(PartBunchBase< double, 3 > *bunch, size_t &i)
void doPhysics(PartBunchBase< double, 3 > *bunch)
size_t getLocalNum() const
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
static const double csCoefDouble_Hplus[3][9]
void transformToH3plus(PartBunchBase< double, 3 > *bunch, size_t &i)
constexpr double m_h2p
The H2+ rest mass in GeV.
Definition: Physics.h:133
bool asciidump
Definition: Options.cpp:18
constexpr double h_bar
The reduced Planck constant in GeVs.
Definition: Physics.h:61
void transformToProton(PartBunchBase< double, 3 > *bunch, size_t &i)
bool gasStripping(double &deltas)
constexpr double q_e
The elementary charge in As.
Definition: Physics.h:76
constexpr double m_h
The hydrogen atom rest mass in GeV.
Definition: Physics.h:130
static const double csCoefProtonProduction_H_Tabata[9]
const std::string name
virtual std::string getResidualGas() const
ParticleAttrib< int > Bin
static const double csCoefHminusProduction_H_Tabata[13]
ParticleAttrib< double > M
ParticlePos_t & R
BeamStrippingPhysics(const std::string &name, ElementBase *element)
double csChebyshevFitting(double Eng, double Emin, double Emax)
static const double csCoefHydrogenProduction_H2plus_Chebyshev[11]
virtual bool checkHit(const Vector_t &R, const Vector_t &P, double dt)=0
Definition: Inform.h:41
static double b_m[3][9]
static const double csCoefSingle_Hminus_Chebyshev[11]
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
void transformToHydrogen(PartBunchBase< double, 3 > *bunch, size_t &i)
double csAnalyticFunctionTabata(double Eng, double Eth, double a1, double a2, double a3, double a4, double a5, double a6)