6 #include <boost/numeric/ublas/matrix.hpp>
12 #define PS_Dim MomentState::maxsize // Set to 7; to include orbit.
15 #define defpath DEFPATH
24 std::vector<double> s,
27 void RdData(std::istream &inf);
28 void show(std::ostream&,
const int)
const;
29 void show(std::ostream&)
const;
33 class CavTLMLineType {
35 std::vector<double> s;
36 std::vector<std::string> Elem;
37 std::vector<double> E0,
43 void set(
const double,
const std::string &,
const double,
44 const double,
const double,
const double);
45 void show(
const int)
const;
52 typedef ElementRFCavity self_t;
54 typedef typename base_t::state_t
state_t;
57 std::string name, type;
58 double length, aperature, E0;
60 std::vector<double> Tfit, Sfit;
62 std::vector<RawParams> lattice;
71 std::vector<double> SynAccTab;
80 std::vector<double> SynComplex,
84 double calFitPow(
double kfac,
const std::vector<double>& Tfit)
const;
85 static std::map<std::string,boost::shared_ptr<Config> > CavConfMap;
87 std::vector<CavTLMLineType> CavTLMLineTab;
98 ElementRFCavity(
const Config& c);
100 void LoadCavityFile(
const Config& c);
102 void GetCavMatParams(
const int cavi,
103 const double beta_tab[],
const double gamma_tab[],
const double IonK[],
104 CavTLMLineType& lineref)
const;
106 void GetCavMat(
const int cavi,
const int cavilabel,
const double Rm,
Particle &real,
107 const double EfieldScl,
const double IonFyi_s,
108 const double IonEk_s, state_t::matrix_t &M,
109 CavTLMLineType &linetab)
const;
111 void GetCavMatGeneric(
Particle &real,
const double EfieldScl,
const double IonFyi_s,
112 const double IonEk_s, state_t::matrix_t &M, CavTLMLineType &linetab)
const;
114 void GenCavMat2(
const int cavi,
const double dis,
const double EfieldScl,
const double TTF_tab[],
115 const double beta_tab[],
const double gamma_tab[],
const double Lambda,
116 Particle &real,
const double IonFys[],
const double Rm, state_t::matrix_t &M,
117 const CavTLMLineType& linetab)
const;
119 void PropagateLongRFCav(
Particle &ref,
double &phi_ref)
const;
121 void calRFcaviEmitGrowth(
const state_t::matrix_t &matIn,
Particle &state,
const int n,
122 const double betaf,
const double gamaf,
123 const double aveX2i,
const double cenX,
const double aveY2i,
const double cenY,
124 state_t::matrix_t &matOut);
126 void InitRFCav(
Particle &real, state_t::matrix_t &M, CavTLMLineType &linetab);
129 const double EfieldScl,
double &IonFy)
const;
131 void TransFacts(
const int cavilabel,
double beta,
const double CaviIonK,
const int gaplabel,
const double EfieldScl,
132 double &Ecen,
double &T,
double &Tp,
double &S,
double &Sp,
double &V0)
const;
134 void TransitFacMultipole(
const int cavi,
const std::string &flabel,
const double CaviIonK,
135 double &T,
double &S)
const;
137 virtual ~ElementRFCavity() {}
141 const self_t* O=
static_cast<const self_t*
>(other);
143 lattice = O->lattice;
144 mlptable = O->mlptable;
145 CavData = O->CavData;
146 CavTLMLineTab = O->CavTLMLineTab;
149 phi_ref = O->phi_ref;
150 MpoleLevel = O->MpoleLevel;
151 EmitGrowth = O->EmitGrowth;
154 forcettfcalc = O->forcettfcalc;
160 using namespace boost::numeric::ublas;
162 double x0[2], x2[2], s0[2];
167 if(!check_cache(ST) && !ST.
retreat) {
168 last_ref_in = ST.ref;
169 last_real_in = ST.real;
173 std::string newtype = conf().get<std::string>(
"cavtype");
174 if (CavType != newtype){
177 LoadCavityFile(conf());
178 }
else if (CavType ==
"Generic") {
179 std::string newfile = conf().get<std::string>(
"Eng_Data_Dir", defpath);
180 newfile +=
"/" + conf().get<std::string>(
"datafile");
181 if (DataFile != newfile) {
184 LoadCavityFile(conf());
188 recompute_matrix(ST);
190 for(
size_t i=0; i<last_real_in.size(); i++)
191 get_misalign(ST, ST.real[i], misalign[i], misalign_inv[i]);
195 last_ref_out = ST.ref;
196 last_real_out = ST.real;
198 if (!check_backward(ST))
199 throw std::runtime_error(SB()<<
200 "Backward propagation error at " << ST.
next_elem <<
": beam state does not match to the previous propagation.");
202 ST.ref.
phis -= (last_ref_out.phis - last_ref_in.phis);
203 ST.ref.
IonEk = last_ref_in.IonEk;
204 for(
size_t k=0; k<last_real_in.size(); k++) {
205 ST.real[k].phis -= (last_real_out[k].phis - last_real_in[k].phis);
206 ST.real[k].IonEk = last_real_in[k].IonEk;
207 get_misalign(ST, ST.real[k], misalign[k], misalign_inv[k]);
213 ST.ref = last_ref_out;
214 assert(last_real_out.size()==ST.real.size());
215 std::copy(last_real_out.begin(),
224 for(
size_t i=0; i<last_real_in.size(); i++) {
225 ST.moment0[i] = prod(misalign[i], ST.moment0[i]);
228 x0[0] = ST.moment0[i][state_t::PS_X];
229 x0[1] = ST.moment0[i][state_t::PS_Y];
230 x2[0] = ST.moment1[i](0, 0);
231 x2[1] = ST.moment1[i](2, 2);
234 transfer[i](state_t::PS_S, 6) = 0.0;
235 transfer[i](state_t::PS_PS, 6) = 0.0;
237 ST.moment0[i] = prod(transfer[i], ST.moment0[i]);
240 s0[0] = (ST.real[i].phis - ST.ref.
phis);
241 s0[1] = (ST.real[i].IonEk - ST.ref.
IonEk)/MeVtoeV;
242 transfer[i](state_t::PS_S, 6) = - ST.moment0[i][state_t::PS_S] + s0[0];
243 transfer[i](state_t::PS_PS, 6) = - ST.moment0[i][state_t::PS_PS] + s0[1];
246 ST.moment0[i][state_t::PS_S] = s0[0];
247 ST.moment0[i][state_t::PS_PS] = s0[1];
249 ST.moment0[i] = prod(misalign_inv[i], ST.moment0[i]);
251 scratch = prod(misalign[i], ST.moment1[i]);
252 ST.moment1[i] = prod(scratch, trans(misalign[i]));
254 scratch = prod(transfer[i], ST.moment1[i]);
255 ST.moment1[i] = prod(scratch, trans(transfer[i]));
258 calRFcaviEmitGrowth(ST.moment1[i], ST.ref, i, ST.real[i].beta, ST.real[i].gamma, x2[0], x0[0], x2[1], x0[1], scratch);
259 ST.moment1[i] = scratch;
262 scratch = prod(misalign_inv[i], ST.moment1[i]);
263 ST.moment1[i] = prod(scratch, trans(misalign_inv[i]));
265 scratch = prod(transfer[i], misalign[i]);
266 scratch = prod(misalign_inv[i], scratch);
267 ST.transmat[i] = scratch;
272 value_t invmat = boost::numeric::ublas::identity_matrix<double>(state_t::maxsize);
273 for(
size_t i=0; i<last_real_in.size(); i++) {
274 scratch = prod(transfer[i], misalign[i]);
275 scratch = prod(misalign_inv[i], scratch);
277 inverse(invmat, scratch);
279 ST.moment0[i] = prod(invmat, ST.moment0[i]);
281 scratch = prod(invmat, ST.moment1[i]);
282 ST.moment1[i] = prod(scratch, trans(invmat));
283 ST.transmat[i] = invmat;
288 ST.last_caviphi0 = fmod(phi_ref*180e0/M_PI, 360e0);
296 CavTLMLineTab.resize(last_real_in.size());
298 PropagateLongRFCav(ST.ref, phi_ref);
300 for(
size_t i=0; i<last_real_in.size(); i++) {
302 transfer[i] = boost::numeric::ublas::identity_matrix<double>(state_t::maxsize);
303 transfer[i](state_t::PS_X, state_t::PS_PX) = length;
304 transfer[i](state_t::PS_Y, state_t::PS_PY) = length;
307 double SampleIonK = ST.real[i].SampleIonK;
309 InitRFCav(ST.real[i], transfer[i], CavTLMLineTab[i]);
312 ST.real[i].SampleIonK = SampleIonK;
316 virtual const char*
type_name()
const {
return "rfcavity";}
bool retreat
retreat (backward) simulation flag
Base class for all simulated elements.
double IonEk
Kinetic energy.
virtual const char * type_name() const =0
The abstract base class for all simulation state objects.
virtual void advance(StateBase &s)
Propogate the given State through this Element.
double phis
Absolute synchrotron phase [rad].
Associative configuration container.
virtual void recompute_matrix(state_t &ST)
recalculate 'transfer' taking into consideration the provided input state
double pos
absolute longitudinal position at end of Element
virtual void assign(const ElementVoid *other)=0
std::vector< value_t > transfer
final transfer matricies
An Element which propagates the statistical moments of a bunch.