FLAME  devel
 All Classes Functions Variables Typedefs Enumerations Pages
rf_cavity.h
1 #ifndef RF_CAVITY_H
2 #define RF_CAVITY_H
3 
4 #endif // RF_CAVITY_H
5 
6 #include <boost/numeric/ublas/matrix.hpp>
7 
8 #include "moment.h"
9 #include "util.h"
10 
11 // Phase space dimension; including vector for orbit/1st moment.
12 #define PS_Dim MomentState::maxsize // Set to 7; to include orbit.
13 
14 #ifdef DEFPATH
15  #define defpath DEFPATH
16 #else
17  #define defpath "."
18 #endif
19 
20 
21 class CavDataType {
22 // Cavity on-axis longitudinal electric field vs. s.
23 public:
24  std::vector<double> s, // s coordinate [m]
25  Elong; // Longitudinal Electric field [V/m].
26 
27  void RdData(std::istream &inf);
28  void show(std::ostream&, const int) const;
29  void show(std::ostream&) const;
30 };
31 
32 
33 class CavTLMLineType {
34 public:
35  std::vector<double> s; // Longitudinal position [m].
36  std::vector<std::string> Elem;
37  std::vector<double> E0,
38  T,
39  S,
40  Accel;
41 
42  void clear(void);
43  void set(const double, const std::string &, const double,
44  const double, const double, const double);
45  void show(const int) const;
46  void show() const;
47 };
48 
49 struct ElementRFCavity : public MomentElementBase
50 {
51  // Transport matrix for an RF Cavity.
52  typedef ElementRFCavity self_t;
53  typedef MomentElementBase base_t;
54  typedef typename base_t::state_t state_t;
55 
56  struct RawParams {
57  std::string name, type;
58  double length, aperature, E0;
59  // vector Tfit and Sfit always have ten elements
60  std::vector<double> Tfit, Sfit;
61  };
62  std::vector<RawParams> lattice; // from thinlenlon_*.txt
63 
64  numeric_table mlptable, // from CaviMlp_*.txt
65  CavData; // from axisData_*.txt
66 
67  std::string CavType,
68  DataPath,
69  DataFile;
70 
71  std::vector<double> SynAccTab;
72 
73  bool have_RefNrm,
74  have_SynComplex,
75  have_EkLim,
76  have_NrLim;
77 
78  double RefNrm; // Reference scale factor q0*1.0/m0
79 
80  std::vector<double> SynComplex, // Fitting model coefficients
81  EkLim, // Limits for incident energy
82  NrLim; // Limits for normalization factor q*scl/m
83 
84  double calFitPow(double kfac, const std::vector<double>& Tfit) const;
85  static std::map<std::string,boost::shared_ptr<Config> > CavConfMap;
86 
87  std::vector<CavTLMLineType> CavTLMLineTab; // from lattice, for each charge state
88  double fRF, // RF frequency [Hz]
89  IonFys, // Synchrotron phase [rad].
90  phi_ref,
91  cRm;
92  int cavi;
93  bool forcettfcalc;
94 
95  unsigned MpoleLevel,
96  EmitGrowth;
97 
98  ElementRFCavity(const Config& c);
99 
100  void LoadCavityFile(const Config& c);
101 
102  void GetCavMatParams(const int cavi,
103  const double beta_tab[], const double gamma_tab[], const double IonK[],
104  CavTLMLineType& lineref) const;
105 
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;
110 
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;
113 
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;
118 
119  void PropagateLongRFCav(Particle &ref, double &phi_ref) const;
120 
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);
125 
126  void InitRFCav(Particle &real, state_t::matrix_t &M, CavTLMLineType &linetab);
127 
128  void GetCavBoost(const numeric_table &CavData, Particle &state, const double IonFy0,
129  const double EfieldScl, double &IonFy) const;
130 
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;
133 
134  void TransitFacMultipole(const int cavi, const std::string &flabel, const double CaviIonK,
135  double &T, double &S) const;
136 
137  virtual ~ElementRFCavity() {}
138 
139  virtual void assign(const ElementVoid *other) {
140  base_t::assign(other);
141  const self_t* O=static_cast<const self_t*>(other);
142  // *all* member variables must be assigned here or reconfigure() will result in inconsistancy
143  lattice = O->lattice;
144  mlptable = O->mlptable;
145  CavData = O->CavData;
146  CavTLMLineTab = O->CavTLMLineTab;
147  fRF = O->fRF;
148  IonFys = O->IonFys;
149  phi_ref = O->phi_ref;
150  MpoleLevel = O->MpoleLevel;
151  EmitGrowth = O->EmitGrowth;
152  cRm = O->cRm;
153  cavi = O->cavi;
154  forcettfcalc = O->forcettfcalc;
155  }
156 
157  virtual void advance(StateBase& s)
158  {
159  state_t& ST = static_cast<state_t&>(s);
160  using namespace boost::numeric::ublas;
161 
162  double x0[2], x2[2], s0[2];
163 
164  // IonEk is Es + E_state; the latter is set by user.
165  ST.recalc();
166 
167  if(!check_cache(ST) && !ST.retreat) {
168  last_ref_in = ST.ref;
169  last_real_in = ST.real;
170  resize_cache(ST);
171  // need to re-calculate energy dependent terms
172 
173  std::string newtype = conf().get<std::string>("cavtype");
174  if (CavType != newtype){
175  lattice.clear();
176  SynAccTab.clear();
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) {
182  lattice.clear();
183  SynAccTab.clear();
184  LoadCavityFile(conf());
185  }
186  }
187 
188  recompute_matrix(ST); // updates transfer and last_Kenergy_out
189 
190  for(size_t i=0; i<last_real_in.size(); i++)
191  get_misalign(ST, ST.real[i], misalign[i], misalign_inv[i]);
192 
193  ST.recalc();
194 
195  last_ref_out = ST.ref;
196  last_real_out = ST.real;
197  } else if(ST.retreat){
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.");
201 
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]);
208  }
209 
210  ST.recalc();
211 
212  } else {
213  ST.ref = last_ref_out;
214  assert(last_real_out.size()==ST.real.size()); // should be true if check_cache() -> true
215  std::copy(last_real_out.begin(),
216  last_real_out.end(),
217  ST.real.begin());
218  }
219  // note that calRFcaviEmitGrowth() assumes real[] isn't changed after this point
220 
221  if(!ST.retreat){
222  // Forward propagation
223  ST.pos += length;
224  for(size_t i=0; i<last_real_in.size(); i++) {
225  ST.moment0[i] = prod(misalign[i], ST.moment0[i]);
226 
227  // Inconsistency in TLM; orbit at entrace should be used to evaluate emittance growth.
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);
232 
233  // reset extra parameters in transfer matrix
234  transfer[i](state_t::PS_S, 6) = 0.0;
235  transfer[i](state_t::PS_PS, 6) = 0.0;
236 
237  ST.moment0[i] = prod(transfer[i], ST.moment0[i]);
238 
239  // combine new z and zp centroid to transfer matrix for backward propagation
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];
244 
245  // insert new z and zp centroid
246  ST.moment0[i][state_t::PS_S] = s0[0];
247  ST.moment0[i][state_t::PS_PS] = s0[1];
248 
249  ST.moment0[i] = prod(misalign_inv[i], ST.moment0[i]);
250 
251  scratch = prod(misalign[i], ST.moment1[i]);
252  ST.moment1[i] = prod(scratch, trans(misalign[i]));
253 
254  scratch = prod(transfer[i], ST.moment1[i]);
255  ST.moment1[i] = prod(scratch, trans(transfer[i]));
256 
257  if (EmitGrowth) {
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;
260  }
261 
262  scratch = prod(misalign_inv[i], ST.moment1[i]);
263  ST.moment1[i] = prod(scratch, trans(misalign_inv[i]));
264 
265  scratch = prod(transfer[i], misalign[i]);
266  scratch = prod(misalign_inv[i], scratch);
267  ST.transmat[i] = scratch;
268  }
269  } else {
270  // Backward propagation
271  ST.pos -= length;
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);
276 
277  inverse(invmat, scratch);
278 
279  ST.moment0[i] = prod(invmat, ST.moment0[i]);
280 
281  scratch = prod(invmat, ST.moment1[i]);
282  ST.moment1[i] = prod(scratch, trans(invmat));
283  ST.transmat[i] = invmat;
284  }
285 
286  }
287 
288  ST.last_caviphi0 = fmod(phi_ref*180e0/M_PI, 360e0); // driven phase [degree]
289  ST.calc_rms();
290  }
291 
292  virtual void recompute_matrix(state_t& ST)
293  {
294  // Re-initialize transport matrix. and update ST.ref and ST.real[]
295 
296  CavTLMLineTab.resize(last_real_in.size());
297 
298  PropagateLongRFCav(ST.ref, phi_ref);
299 
300  for(size_t i=0; i<last_real_in.size(); i++) {
301  // TODO: 'transfer' is overwritten in InitRFCav()?
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;
305 
306  // J.B. Bug in TLM.
307  double SampleIonK = ST.real[i].SampleIonK;
308 
309  InitRFCav(ST.real[i], transfer[i], CavTLMLineTab[i]);
310 
311  // J.B. Bug in TLM.
312  ST.real[i].SampleIonK = SampleIonK;
313  }
314  }
315 
316  virtual const char* type_name() const {return "rfcavity";}
317 };
318 
bool retreat
retreat (backward) simulation flag
Definition: base.h:39
Base class for all simulated elements.
Definition: base.h:165
double IonEk
Kinetic energy.
Definition: moment.h:22
virtual const char * type_name() const =0
size_t next_elem
Definition: base.h:35
The abstract base class for all simulation state objects.
Definition: base.h:29
virtual void advance(StateBase &s)
Propogate the given State through this Element.
Definition: moment.cpp:658
double phis
Absolute synchrotron phase [rad].
Definition: moment.h:22
Associative configuration container.
Definition: config.h:66
virtual void recompute_matrix(state_t &ST)
recalculate &#39;transfer&#39; taking into consideration the provided input state
Definition: moment.cpp:760
double pos
absolute longitudinal position at end of Element
Definition: base.h:37
virtual void assign(const ElementVoid *other)=0
Definition: moment.cpp:563
std::vector< value_t > transfer
final transfer matricies
Definition: moment.h:181
An Element which propagates the statistical moments of a bunch.
Definition: moment.h:146