FLAME  devel
 All Classes Functions Variables Typedefs Enumerations Pages
chg_stripper.cpp
1 #include "flame/constants.h"
2 #include "flame/moment.h"
3 #include "flame/moment_sup.h"
4 #include "flame/chg_stripper.h"
5 
6 #define sqr(x) ((x)*(x))
7 #define cube(x) ((x)*(x)*(x))
8 
9 static
10 double Gaussian(double in, const double Q_ave, const double d)
11 {
12  // Gaussian distribution.
13  return 1e0/sqrt(2e0*M_PI)/d*exp(-0.5e0*sqr(in-Q_ave)/sqr(d));
14 }
15 
16 
17 static
18 void StripperCharge(const double beta, double &Q_ave, double &d)
19 {
20  // Baron's formula for carbon foil.
21  double Q_ave1, Y;
22 
23  Q_ave1 = Stripper_IonProton*(1e0-exp(-83.275*(beta/pow(Stripper_IonProton, 0.447))));
24  Q_ave = Q_ave1*(1e0-exp(-12.905+0.2124*Stripper_IonProton-0.00122*sqr(Stripper_IonProton)));
25  Y = Q_ave1/Stripper_IonProton;
26  d = sqrt(Q_ave1*(0.07535+0.19*Y-0.2654*sqr(Y)));
27 }
28 
29 
30 static
31 void ChargeStripper(const double beta, const std::vector<double>& ChgState, std::vector<double>& chargeAmount_Baron)
32 {
33  unsigned k;
34  double Q_ave, d;
35 
36  StripperCharge(beta, Q_ave, d);
37  for (k = 0; k < ChgState.size(); k++)
38  chargeAmount_Baron.push_back(Gaussian(ChgState[k]*Stripper_IonMass, Q_ave, d));
39 }
40 
41 
42 static
43 void Stripper_Propagate_ref(Particle &ref)
44 {
45 
46  // Change reference particle charge state.
47  ref.IonZ = Stripper_IonZ;
48 
49 // ChargeStripper(ref.beta, ChgState, chargeAmount_Baron);
50 
51  // Evaluate change in reference particle energy due to stripper model energy straggling.
52  ref.IonEk = (ref.IonEk-Stripper_Para[2])*Stripper_E0Para[1] + Stripper_E0Para[0];
53 
54  ref.recalc();
55 }
56 
57 void Stripper_GetMat(const Config &conf,
58  MomentState &ST)
59 {
60  unsigned k, n;
61  double tmptotCharge, Fy_abs_recomb, Ek_recomb, stdEkFoilVariation, ZpAfStr, growthRate;
62  double stdXYp, XpAfStr, growthRateXp, YpAfStr, growthRateYp, s;
63  Particle ref;
64  state_t *StatePtr = &ST;
65  MomentState::matrix_t tmpmat;
66  std::vector<double> chargeAmount_Baron;
67 
68  // Evaluate beam parameter recombination.
69 
70  //std::cout<<"In "<<__FUNCTION__<<"\n";
71 
72  tmptotCharge = 0e0;
73  Fy_abs_recomb = 0e0;
74  Ek_recomb = 0e0;
75  tmpmat = boost::numeric::ublas::zero_matrix<double>(PS_Dim);
76  for (k = 0; k < ST.size(); k++) {
77  const double Q = ST.real[k].IonQ;
78  tmptotCharge += Q;
79  Fy_abs_recomb += Q*StatePtr->real[k].phis;
80  Ek_recomb += Q*StatePtr->real[k].IonEk;
81  tmpmat +=
82  Q*(StatePtr->moment1[k]+outer_prod(StatePtr->moment0[k]-ST.moment0_env, StatePtr->moment0[k]-ST.moment0_env));
83  }
84 
85  Fy_abs_recomb /= tmptotCharge;
86  Ek_recomb /= tmptotCharge;
87 
88  // Stripper model energy straggling.
89  Ek_recomb = (Ek_recomb-Stripper_Para[2])*Stripper_E0Para[1] + Stripper_E0Para[0];
90  tmpmat /= tmptotCharge;
91 
92  // Estimate Zp stripper caused envelope increase.
93  stdEkFoilVariation = sqrt(1e0/3e0)*Stripper_Para[1]/100e0*Stripper_Para[0]*Stripper_E0Para[2];
94  ZpAfStr = tmpmat(5, 5) + sqr(Stripper_E1Para) + sqr(stdEkFoilVariation);
95  growthRate = sqrt(ZpAfStr/tmpmat(5, 5));
96 
97  for (k = 0; k < 6; k++) {
98  tmpmat(k, 5) = tmpmat(k, 5)*growthRate;
99  // This trick allows two times growthRate for <Zp, Zp>.
100  tmpmat(5, k) = tmpmat(5, k)*growthRate;
101  }
102 
103  // Estimate Xp, Yp stripper caused envelope increase.
104  stdXYp = sqrt(Stripper_upara/sqr(Stripper_lambda))*1e-3;// mrad to rad
105  XpAfStr = tmpmat(1, 1) + sqr(stdXYp);
106  growthRateXp = sqrt(XpAfStr/tmpmat(1, 1));
107  YpAfStr = tmpmat(3, 3) + sqr(stdXYp);
108  growthRateYp = sqrt(YpAfStr/tmpmat(3, 3));
109 
110  for (k = 0; k < 6; k++) {
111  tmpmat(k, 1) = tmpmat(k, 1)*growthRateXp;
112  // This trick allows two times growthRate for <Zp, Zp>.
113  tmpmat(1, k) = tmpmat(1, k)*growthRateXp;
114  tmpmat(k, 3) = tmpmat(k, 3)*growthRateYp;
115  tmpmat(3, k) = tmpmat(3, k)*growthRateYp;
116  }
117 
118  // Get new charge states.
119  const std::vector<double>& ChgState = conf.get<std::vector<double> >("IonChargeStates");
120  const std::vector<double>& NChg = conf.get<std::vector<double> >("NCharge");
121  n = ChgState.size();
122  assert(NChg.size()==n);
123 
124  // Propagate reference particle.
125  ref = ST.ref;
126  Stripper_Propagate_ref(ref);
127 
128  s = StatePtr->pos;
129 
130  ST.real.resize(n);
131  ST.moment0.resize(n);
132  ST.moment1.resize(n);
133 
134  // Length is zero.
135  StatePtr->pos = s;
136 
137  StatePtr->ref = ref;
138 
139  ChargeStripper(StatePtr->real[0].beta, ChgState, chargeAmount_Baron);
140 
141  for (k = 0; k < n; k++) {
142  StatePtr->real[k].IonZ = ChgState[k];
143  StatePtr->real[k].IonQ = chargeAmount_Baron[k];
144  StatePtr->real[k].IonEs = ref.IonEs;
145  StatePtr->real[k].IonEk = Ek_recomb;
146  StatePtr->real[k].recalc();
147  StatePtr->real[k].phis = Fy_abs_recomb;
148  StatePtr->moment0[k] = ST.moment0_env;
149  StatePtr->moment1[k] = tmpmat;
150  }
151 
152  ST.calc_rms();
153 }
154 
155 void ElementStripper::advance(StateBase &s)
156 {
157  state_t& ST = static_cast<state_t&>(s);
158 
159  ST.recalc();
160  ST.calc_rms(); // paranoia in case someone (python) has made moment0_env inconsistent
161 
162  Stripper_GetMat(conf(), ST);
163 }
double IonEk
Kinetic energy.
Definition: moment.h:24
double IonZ
Charge state.
Definition: moment.h:24
The abstract base class for all simulation state objects.
Definition: base.h:28
void recalc()
Definition: moment.h:46
Associative configuration container.
Definition: config.h:66
double pos
absolute longitudinal position at end of Element
Definition: base.h:36
size_t size() const
of charge states
Definition: moment.h:123
detail::RT< T >::type get(const std::string &name) const
Definition: config.h:123