1 #include "flame/constants.h"
2 #include "flame/moment.h"
3 #include "flame/moment_sup.h"
4 #include "flame/chg_stripper.h"
6 #define sqr(x) ((x)*(x))
7 #define cube(x) ((x)*(x)*(x))
10 double Gaussian(
double in,
const double Q_ave,
const double d)
13 return 1e0/sqrt(2e0*M_PI)/d*exp(-0.5e0*sqr(in-Q_ave)/sqr(d));
17 void ElementStripper::StripperCharge(
const double beta,
double &Q_ave,
double &d)
22 Q_ave1 = Stripper_IonProton*(1e0-exp(-83.275*(beta/pow(Stripper_IonProton, 0.447))));
23 Q_ave = Q_ave1*(1e0-exp(-12.905+0.2124*Stripper_IonProton-0.00122*sqr(Stripper_IonProton)));
24 Y = Q_ave1/Stripper_IonProton;
25 d = sqrt(Q_ave1*(0.07535+0.19*Y-0.2654*sqr(Y)));
29 void ElementStripper::ChargeStripper(
const double beta,
const std::vector<double>& ChgState, std::vector<double>& chargeAmount_Baron)
34 StripperCharge(beta, Q_ave, d);
35 for (k = 0; k < ChgState.size(); k++)
36 chargeAmount_Baron.push_back(Gaussian(ChgState[k]*Stripper_IonMass, Q_ave, d));
40 void ElementStripper::Stripper_Propagate_ref(
Particle &ref)
44 ref.
IonZ = Stripper_IonZ;
49 ref.
IonEk = (ref.
IonEk-Stripper_Para[2])*Stripper_E0Para[1] + Stripper_E0Para[0];
54 void ElementStripper::Stripper_GetMat(
const Config &conf,
58 double tmptotCharge, Fy_abs_recomb, Ek_recomb, stdEkFoilVariation, ZpAfStr, growthRate;
59 double stdXYp, XpAfStr, growthRateXp, YpAfStr, growthRateYp, s;
62 MomentState::matrix_t tmpmat;
63 std::vector<double> chargeAmount_Set;
68 const std::vector<double>& ChgState = conf.
get<std::vector<double> >(
"IonChargeStates");
69 const std::vector<double>& NChg = conf.
get<std::vector<double> >(
"NCharge");
70 const std::string chrgmdl = conf.
get<std::string>(
"charge_model",
"baron");
72 if(chrgmdl==
"off" && ChgState.size()!=NChg.size())
73 throw std::runtime_error(
"charge stripper requires that IonChargeStates[] and NCharge[] have the same length");
74 if(chrgmdl!=
"off" && chrgmdl!=
"baron")
75 throw std::runtime_error(
"charge_model key word unknown, only \"baron\" and \"off\" supported by now");
77 Stripper_IonZ = conf.
get<
double>(
"Stripper_IonZ", Stripper_IonZ_default);
78 Stripper_IonMass = conf.
get<
double>(
"Stripper_IonMass", Stripper_IonMass_default);
79 Stripper_IonProton = conf.
get<
double>(
"Stripper_IonProton", Stripper_IonProton_default);
80 Stripper_E1Para = conf.
get<
double>(
"Stripper_E1Para", Stripper_E1Para_default);
81 Stripper_lambda = conf.
get<
double>(
"Stripper_lambda", Stripper_lambda_default);
82 Stripper_upara = conf.
get<
double>(
"Stripper_upara", Stripper_upara_default);
84 const std::vector<double> p1_default(Stripper_Para_default, Stripper_Para_default+3),
85 p2_default(Stripper_E0Para_default, Stripper_E0Para_default+3);
87 Stripper_Para = conf.
get<std::vector<double> >(
"Stripper_Para", p1_default);
88 Stripper_E0Para = conf.
get<std::vector<double> >(
"Stripper_E0Para", p2_default);
93 if (ChgState.size()!=NChg.size())
94 throw std::runtime_error(
"charge stripper requires that IonChargeStates[] and NCharge[] have the same length");
96 for (k = 0; k < n; k++) chargeAmount_Set.push_back(NChg[k]);
99 ChargeStripper(StatePtr->real[0].beta, ChgState, chargeAmount_Set);
107 tmpmat = boost::numeric::ublas::zero_matrix<double>(PS_Dim);
108 for (k = 0; k < ST.
size(); k++) {
109 const double Q = ST.real[k].IonQ;
111 Fy_abs_recomb += Q*StatePtr->real[k].phis;
112 Ek_recomb += Q*StatePtr->real[k].IonEk;
114 Q*(StatePtr->moment1[k]+outer_prod(StatePtr->moment0[k]-ST.moment0_env, StatePtr->moment0[k]-ST.moment0_env));
117 Fy_abs_recomb /= tmptotCharge;
118 Ek_recomb /= tmptotCharge;
121 Ek_recomb = (Ek_recomb-Stripper_Para[2])*Stripper_E0Para[1] + Stripper_E0Para[0];
122 tmpmat /= tmptotCharge;
125 stdEkFoilVariation = sqrt(1e0/3e0)*Stripper_Para[1]/100e0*Stripper_Para[0]*Stripper_E0Para[2];
126 ZpAfStr = tmpmat(5, 5) + sqr(Stripper_E1Para) + sqr(stdEkFoilVariation);
127 if (tmpmat(5, 5) != 0e0) {
128 growthRate = sqrt(ZpAfStr/tmpmat(5, 5));
133 for (k = 0; k < 6; k++) {
134 tmpmat(k, 5) = tmpmat(k, 5)*growthRate;
136 tmpmat(5, k) = tmpmat(5, k)*growthRate;
140 stdXYp = sqrt(Stripper_upara/sqr(Stripper_lambda))*1e-3;
141 XpAfStr = tmpmat(1, 1) + sqr(stdXYp);
142 growthRateXp = sqrt(XpAfStr/tmpmat(1, 1));
143 YpAfStr = tmpmat(3, 3) + sqr(stdXYp);
144 growthRateYp = sqrt(YpAfStr/tmpmat(3, 3));
146 for (k = 0; k < 6; k++) {
147 tmpmat(k, 1) = tmpmat(k, 1)*growthRateXp;
149 tmpmat(1, k) = tmpmat(1, k)*growthRateXp;
150 tmpmat(k, 3) = tmpmat(k, 3)*growthRateYp;
151 tmpmat(3, k) = tmpmat(3, k)*growthRateYp;
159 Stripper_Propagate_ref(ref);
164 ST.moment0.resize(n);
165 ST.moment1.resize(n);
166 ST.transmat.resize(n);
174 for (k = 0; k < n; k++) {
175 StatePtr->real[k].IonZ = ChgState[k];
176 StatePtr->real[k].IonQ = chargeAmount_Set[k];
177 StatePtr->real[k].SampleFreq = ref.
SampleFreq;
178 StatePtr->real[k].IonEs = ref.
IonEs;
179 StatePtr->real[k].IonEk = Ek_recomb;
180 StatePtr->real[k].recalc();
181 StatePtr->real[k].phis = Fy_abs_recomb;
182 StatePtr->moment0[k] = ST.moment0_env;
183 StatePtr->moment1[k] = tmpmat;
184 StatePtr->transmat[k] = boost::numeric::ublas::identity_matrix<double>(PS_Dim);
190 void ElementStripper::advance(
StateBase &s)
197 if(ST.
retreat)
throw std::runtime_error(SB()<<
198 "Backward propagation error: Backward propagation does not support charge stripper.");
201 Stripper_GetMat(conf(), ST);
bool retreat
retreat (backward) simulation flag
double IonEk
Kinetic energy.
The abstract base class for all simulation state objects.
double SampleFreq
Sampling frequency [Hz].
Associative configuration container.
double pos
absolute longitudinal position at end of Element
size_t size() const
of charge states
detail::RT< T >::type get(const std::string &name) const