6 #include <boost/lexical_cast.hpp> 
    8 #include <boost/numeric/ublas/vector_proxy.hpp> 
    9 #include <boost/numeric/ublas/matrix_proxy.hpp> 
   11 #include "flame/constants.h" 
   13 #include "flame/moment.h" 
   14 #include "flame/moment_sup.h" 
   15 #include "flame/rf_cavity.h" 
   16 #include "flame/chg_stripper.h" 
   18 #include "flame/h5loader.h" 
   20 #define sqr(x)  ((x)*(x)) 
   21 #define cube(x) ((x)*(x)*(x)) 
   23 namespace ub = boost::numeric::ublas;
 
   30 template<
typename ARR>
 
   31 bool load_storage(ARR& to, 
const Config& conf, 
const std::string& name, 
bool T=
true)
 
   34         const std::vector<double>& val(conf.
get<std::vector<double> >(name));
 
   35         if(to.size()!=val.size()) {
 
   36             throw std::invalid_argument(SB()<<
"Array "<<name<<
" must have "<<to.size()<<
" elements, not "<<val.size());
 
   38         std::copy(val.begin(), val.end(), to.begin());
 
   41     }
catch(std::exception&){
 
   43             throw std::invalid_argument(name+
" not defined or has wrong type (must be vector)");
 
   52 std::ostream& operator<<(std::ostream& strm, 
const Particle& P)
 
   55       <<
"IonZ="<<std::scientific << std::setprecision(10)<<P.
IonZ 
   69 MomentState::MomentState(
const Config& c)
 
   73     ,moment0_env(maxsize, 0e0)
 
   74     ,moment0_rms(maxsize, 0e0)
 
   75     ,moment1_env(boost::numeric::ublas::identity_matrix<double>(maxsize))
 
   83     double icstate_f = 0.0;
 
   84     bool have_cstate = c.
tryGet<
double>(
"cstate", icstate_f);
 
   85     size_t icstate = (size_t)icstate_f;
 
   87     std::string vectorname(c.
get<std::string>(
"vector_variable", 
"moment0"));
 
   88     std::string matrixname(c.
get<std::string>(
"matrix_variable", 
"initial"));
 
   90     std::vector<double> ics, nchg;
 
   91     bool have_ics = c.
tryGet<std::vector<double> >(
"IonChargeStates", ics);
 
   93     ref.IonEs      = c.
get<
double>(
"IonEs", 0e0),
 
   94     ref.IonEk      = c.
get<
double>(
"IonEk", 0e0);
 
   98         ref.IonZ = c.
get<
double>(
"IonZ", 0e0);
 
   99         ref.IonQ = c.
get<
double>(
"IonQ", 1e0);
 
  101         ics.push_back(ref.IonZ);
 
  102         nchg.push_back(ref.IonQ);
 
  106             throw std::invalid_argument(
"IonChargeStates w/ length 0");
 
  107         if(icstate>=ics.size())
 
  108             throw std::invalid_argument(
"IonChargeStates[cstate] is out of bounds");
 
  110         nchg = c.
get<std::vector<double> >(
"NCharge");
 
  111         if(nchg.size()!=ics.size())
 
  112             throw std::invalid_argument(
"NCharge[] and IonChargeStates[] must have equal length");
 
  126     if(!have_cstate && !have_ics) {
 
  128     } 
else if(!have_cstate && have_ics) {
 
  132     } 
else if(have_cstate && have_ics) {
 
  136         ics[0]  = ics[icstate];
 
  137         nchg[0] = nchg[icstate];
 
  142         throw std::invalid_argument(
"MomentState: must define IonChargeStates and NCharge when cstate is set");
 
  146         real.resize(ics.size());
 
  147         moment0.resize(ics.size());
 
  148         moment1.resize(ics.size());
 
  150         for(
size_t i=0; i<ics.size(); i++) {
 
  151             std::string num(boost::lexical_cast<std::string>(icstate+i));
 
  153             moment0[i].resize(maxsize);
 
  154             moment1[i].resize(maxsize, maxsize);
 
  155             moment1[i] = boost::numeric::ublas::identity_matrix<double>(maxsize);
 
  157             load_storage(moment0[i].data(), c, vectorname+num);
 
  158             load_storage(moment1[i].data(), c, matrixname+num);
 
  162             real[i].IonZ = ics[i];
 
  163             real[i].IonQ = nchg[i];
 
  165             real[i].phis      = moment0[i][PS_S];
 
  166             real[i].IonEk    += moment0[i][PS_PS]*MeVtoeV;
 
  176         moment0[0].resize(maxsize);
 
  177         moment1[0].resize(maxsize, maxsize);
 
  179         load_storage(moment0[0].data(), c, vectorname, 
false);
 
  180         load_storage(moment1[0].data(), c, matrixname, 
false);
 
  186 MomentState::~MomentState() {}
 
  188 void MomentState::calc_rms()
 
  190     assert(real.size()>0);
 
  191     assert(moment0_env.size()==maxsize);
 
  192     assert(moment0_rms.size()==maxsize);
 
  193     assert(moment1_env.size1()==maxsize);
 
  194     assert(moment1_env.size2()==maxsize);
 
  197     for(
size_t n=0; n<real.size(); n++) {
 
  198         totQ += real[n].IonQ;
 
  200             noalias(moment0_env)  = moment0[n]*real[n].IonQ;
 
  202             noalias(moment0_env) += moment0[n]*real[n].IonQ;
 
  207     moment1_env = ub::zero_matrix<double>(state_t::maxsize);
 
  208     boost::numeric::ublas::slice S(0, 1, 6);
 
  209     for(
size_t n=0; n<real.size(); n++) {
 
  210         const double Q = real[n].IonQ;
 
  211         state_t::vector_t m0diff(moment0[n]-moment0_env);
 
  213         ub::project(moment1_env, S, S) += ub::project(Q*(moment1[n]+ub::outer_prod(m0diff, m0diff)), S, S);
 
  217     for(
size_t j=0; j<maxsize; j++) {
 
  218         moment0_rms[j] = sqrt(moment1_env(j,j));
 
  222 MomentState::MomentState(
const MomentState& o, clone_tag t)
 
  228     ,moment0_env(o.moment0_env)
 
  229     ,moment0_rms(o.moment0_rms)
 
  230     ,moment1_env(o.moment1_env)
 
  237         throw std::invalid_argument(
"Can't assign State: incompatible types");
 
  240     moment0 = O->moment0;
 
  241     moment1 = O->moment1;
 
  242     moment0_env = O->moment0_env;
 
  243     moment0_rms = O->moment0_rms;
 
  244     moment1_env = O->moment1_env;
 
  251         strm<<
"State: empty";
 
  256         strm<<
"State: moment0 mean="<<moment0_env;
 
  259         strm << std::scientific << std::setprecision(8)
 
  260              << 
"\nState:\n  energy [eV] =\n" << std::setw(20) << real[0].IonEk << 
"\n  moment0 mean =\n    ";
 
  261         for (
size_t k = 0; k < MomentState::maxsize; k++)
 
  262             strm << std::scientific << std::setprecision(10) << std::setw(18) << moment0_env(k) << 
",";
 
  263         strm << std::scientific << std::setprecision(10)
 
  264              << 
"\n  moment0 rms =\n    ";
 
  265         for (
size_t k = 0; k < MomentState::maxsize; k++)
 
  266             strm << std::scientific << std::setprecision(10) << std::setw(18) << moment0_rms(k) << 
",";
 
  267         strm << 
"\n  moment1 mean =\n";
 
  268         for (
size_t j = 0; j < MomentState::maxsize; j++) {
 
  270             for (
size_t k = 0; k < MomentState::maxsize; k++) {
 
  271                 strm << std::scientific << std::setprecision(10) << std::setw(18) << moment1_env(j, k) << 
",";
 
  273             if (j < MomentState::maxsize-1) strm << 
"\n";
 
  277         strm<< 
"\n  Reference state:\n    "<<ref<<
"\n";
 
  278         for(
size_t k=0; k<
size(); k++) {
 
  279             strm<<
"  Charge state "<<k<<
"\n" 
  281                   "    moment0 "<<moment0[k]<<
"\n";
 
  284                   "    moment1 "<<moment1[k]<<
"\n";
 
  292         Info.
name = 
"moment1_env";
 
  293         Info.
ptr = &moment1_env(0,0);
 
  294         Info.type = ArrayInfo::Double;
 
  296         Info.
dim[0] = moment1_env.size1();
 
  297         Info.
dim[1] = moment1_env.size2();
 
  298         Info.
stride[0] = 
sizeof(double)*moment1_env.size2();
 
  299         Info.
stride[1] = 
sizeof(double);
 
  301     } 
else if(idx==I++) {
 
  309         static_assert(
sizeof(moment1[0])>=
sizeof(
double)*maxsize*maxsize,
 
  310                       "storage assumption violated");
 
  311         Info.
name = 
"moment1";
 
  312         Info.
ptr = &moment1[0](0,0);
 
  313         Info.type = ArrayInfo::Double;
 
  315         Info.
dim[0] = moment1[0].size1();
 
  316         Info.
dim[1] = moment1[0].size2();
 
  317         Info.
dim[2] = moment1.size();
 
  318         Info.
stride[0] = 
sizeof(double)*moment1_env.size2();
 
  319         Info.
stride[1] = 
sizeof(double);
 
  320         Info.
stride[2] = 
sizeof(moment1[0]);
 
  322     } 
else if(idx==I++) {
 
  323         Info.
name = 
"moment0_env";
 
  324         Info.
ptr = &moment0_env(0);
 
  325         Info.type = ArrayInfo::Double;
 
  327         Info.
dim[0] = moment0_env.size();
 
  328         Info.
stride[0] = 
sizeof(double);
 
  330     } 
else if(idx==I++) {
 
  331         Info.
name = 
"moment0_rms";
 
  332         Info.
ptr = &moment0_rms(0);
 
  333         Info.type = ArrayInfo::Double;
 
  335         Info.
dim[0] = moment0_rms.size();
 
  336         Info.
stride[0] = 
sizeof(double);
 
  338     } 
else if(idx==I++) {
 
  340         static_assert(
sizeof(moment0[0])>=
sizeof(
double)*maxsize,
 
  341                 "storage assumption violated");
 
  342         Info.
name = 
"moment0";
 
  343         Info.
ptr = &moment0[0][0];
 
  344         Info.type = ArrayInfo::Double;
 
  346         Info.
dim[0] = moment0[0].size();
 
  347         Info.
dim[1] = moment0.size();
 
  348         Info.
stride[0] = 
sizeof(double);
 
  349         Info.
stride[1] = 
sizeof(moment0[0]);
 
  351     } 
else if(idx==I++) {
 
  352         Info.
name = 
"ref_IonZ";
 
  354         Info.type = ArrayInfo::Double;
 
  357     } 
else if(idx==I++) {
 
  358         Info.
name = 
"ref_IonQ";
 
  360         Info.type = ArrayInfo::Double;
 
  363     } 
else if(idx==I++) {
 
  364         Info.
name = 
"ref_IonEs";
 
  366         Info.type = ArrayInfo::Double;
 
  369     } 
else if(idx==I++) {
 
  370         Info.
name = 
"ref_IonW";
 
  372         Info.type = ArrayInfo::Double;
 
  375     } 
else if(idx==I++) {
 
  376         Info.
name = 
"ref_gamma";
 
  378         Info.type = ArrayInfo::Double;
 
  381     } 
else if(idx==I++) {
 
  382         Info.
name = 
"ref_beta";
 
  384         Info.type = ArrayInfo::Double;
 
  387     } 
else if(idx==I++) {
 
  388         Info.
name = 
"ref_bg";
 
  390         Info.type = ArrayInfo::Double;
 
  393     } 
else if(idx==I++) {
 
  394         Info.
name = 
"ref_SampleIonK";
 
  396         Info.type = ArrayInfo::Double;
 
  399     } 
else if(idx==I++) {
 
  400         Info.
name = 
"ref_phis";
 
  402         Info.type = ArrayInfo::Double;
 
  405     } 
else if(idx==I++) {
 
  406         Info.
name = 
"ref_IonEk";
 
  408         Info.type = ArrayInfo::Double;
 
  411     } 
else if(idx==I++) {
 
  413         Info.
ptr  = &real[0].IonZ;
 
  414         Info.type = ArrayInfo::Double;
 
  416         Info.
dim   [0] = real.size();
 
  417         Info.
stride[0] = 
sizeof(real[0]);
 
  420     } 
else if(idx==I++) {
 
  422         Info.
ptr  = &real[0].IonEs;
 
  423         Info.type = ArrayInfo::Double;
 
  425         Info.
dim   [0] = real.size();
 
  426         Info.
stride[0] = 
sizeof(real[0]);
 
  428     } 
else if(idx==I++) {
 
  430         Info.
ptr  = &real[0].IonW;
 
  431         Info.type = ArrayInfo::Double;
 
  433         Info.
dim   [0] = real.size();
 
  434         Info.
stride[0] = 
sizeof(real[0]);
 
  436     } 
else if(idx==I++) {
 
  438         Info.
ptr  = &real[0].gamma;
 
  439         Info.type = ArrayInfo::Double;
 
  441         Info.
dim   [0] = real.size();
 
  442         Info.
stride[0] = 
sizeof(real[0]);
 
  444     } 
else if(idx==I++) {
 
  446         Info.
ptr  = &real[0].beta;
 
  447         Info.type = ArrayInfo::Double;
 
  449         Info.
dim   [0] = real.size();
 
  450         Info.
stride[0] = 
sizeof(real[0]);
 
  452     } 
else if(idx==I++) {
 
  454         Info.
ptr  = &real[0].bg;
 
  455         Info.type = ArrayInfo::Double;
 
  457         Info.
dim   [0] = real.size();
 
  458         Info.
stride[0] = 
sizeof(real[0]);
 
  460     } 
else if(idx==I++) {
 
  461         Info.
name = 
"SampleIonK";
 
  462         Info.
ptr  = &real[0].SampleIonK;
 
  463         Info.type = ArrayInfo::Double;
 
  465         Info.
dim   [0] = real.size();
 
  466         Info.
stride[0] = 
sizeof(real[0]);
 
  468     } 
else if(idx==I++) {
 
  470         Info.
ptr  = &real[0].phis;
 
  471         Info.type = ArrayInfo::Double;
 
  473         Info.
dim   [0] = real.size();
 
  474         Info.
stride[0] = 
sizeof(real[0]);
 
  476     } 
else if(idx==I++) {
 
  478         Info.
ptr  = &real[0].IonEk;
 
  479         Info.type = ArrayInfo::Double;
 
  481         Info.
dim   [0] = real.size();
 
  482         Info.
stride[0] = 
sizeof(real[0]);
 
  484     } 
else if(idx==I++) {
 
  486         Info.
ptr  = &real[0].IonQ;
 
  487         Info.type = ArrayInfo::Double;
 
  489         Info.
dim   [0] = real.size();
 
  490         Info.
stride[0] = 
sizeof(real[0]);
 
  497 MomentElementBase::MomentElementBase(
const Config& c)
 
  499     ,dx   (c.get<double>(
"dx",    0e0)*MtoMM)
 
  500     ,dy   (c.get<double>(
"dy",    0e0)*MtoMM)
 
  501     ,pitch(c.get<double>(
"pitch", 0e0))
 
  502     ,yaw  (c.get<double>(
"yaw",   0e0))
 
  503     ,roll (c.get<double>(
"roll",  0e0))
 
  504     ,skipcache(c.get<double>(
"skipcache", 0.0)!=0.0)
 
  509 MomentElementBase::~MomentElementBase() {}
 
  514     last_real_in = O->last_real_in;
 
  515     last_real_out= O->last_real_out;
 
  516     last_ref_in  = O->last_ref_in;
 
  517     last_ref_out = O->last_ref_out;
 
  519     misalign = O->misalign;
 
  520     misalign_inv = O->misalign_inv;
 
  532     using namespace boost::numeric::ublas;
 
  541 void MomentElementBase::get_misalign(
const state_t &ST, 
const Particle &real, value_t &M, value_t &IM)
 const 
  544               scl     = boost::numeric::ublas::identity_matrix<double>(state_t::maxsize),
 
  550     scl(state_t::PS_S, state_t::PS_S)   /= -real.
SampleIonK;
 
  551     scl(state_t::PS_PS, state_t::PS_PS) /= sqr(real.
beta)*real.
gamma*ST.ref.
IonEs/MeVtoeV;
 
  553     inverse(scl_inv, scl);
 
  556     T(state_t::PS_S,  6) = -
length/2e0*MtoMM;
 
  557     T(state_t::PS_PS, 6) = 1e0;
 
  560     RotMat(
dx, dy, pitch, yaw, roll, R);
 
  565     M = prod(scl_inv, M);
 
  570     T(state_t::PS_S,  6) = 
length/2e0*MtoMM;
 
  571     T(state_t::PS_PS, 6) = 1e0;
 
  575     IM = prod(R_inv, IM);
 
  576     IM = prod(T_inv, IM);
 
  577     IM = prod(scl_inv, IM);
 
  583     using namespace boost::numeric::ublas;
 
  592         last_ref_in = ST.ref;
 
  593         last_real_in = ST.real;
 
  600         for(
size_t k=0; k<last_real_in.size(); k++)
 
  601             ST.real[k].phis  += ST.real[k].SampleIonK*
length*MtoMM;
 
  604         last_ref_out = ST.ref;
 
  605         last_real_out = ST.real;
 
  607         ST.ref = last_ref_out;
 
  608         assert(last_real_out.size()==ST.real.size()); 
 
  609         std::copy(last_real_out.begin(),
 
  616     for(
size_t k=0; k<last_real_in.size(); k++) {
 
  618         ST.moment0[k] = prod(
transfer[k], ST.moment0[k]);
 
  620         scratch  = prod(
transfer[k], ST.moment1[k]);
 
  621         ST.moment1[k] = prod(scratch, trans(
transfer[k]));
 
  630             && last_real_in.size()==ST.
size()
 
  631             && last_ref_in==ST.ref
 
  632             && std::equal(last_real_in.begin(),
 
  639     transfer.resize(ST.real.size(), boost::numeric::ublas::identity_matrix<double>(state_t::maxsize));
 
  640     misalign.resize(ST.real.size(), boost::numeric::ublas::identity_matrix<double>(state_t::maxsize));
 
  641     misalign_inv.resize(ST.real.size(), boost::numeric::ublas::identity_matrix<double>(state_t::maxsize));
 
  648     for(
size_t k=0; k<last_real_in.size(); k++) {
 
  649         transfer[k] = boost::numeric::ublas::identity_matrix<double>(state_t::maxsize);
 
  657     typedef ElementSource            self_t;
 
  659     typedef typename base_t::state_t 
state_t;
 
  661     ElementSource(
const Config& c): base_t(c), istate(c) {}
 
  665         state_t& ST = 
static_cast<state_t&
>(s);
 
  670     virtual void show(std::ostream& strm, 
int level)
 const 
  673         strm<<
"Initial: "<<istate.moment0_env<<
"\n";
 
  679     virtual ~ElementSource() {}
 
  681     virtual const char* 
type_name()
 const {
return "source";}
 
  684         base_t::assign(other);
 
  685         const self_t* O=
static_cast<const self_t*
>(other);
 
  693     typedef ElementMark            self_t;
 
  695     typedef typename base_t::state_t state_t;
 
  698     virtual ~ElementMark() {}
 
  699     virtual const char* 
type_name()
 const {
return "marker";}
 
  707     typedef ElementBPM               self_t;
 
  709     typedef typename base_t::state_t state_t;
 
  712     virtual ~ElementBPM() {}
 
  713     virtual const char* 
type_name()
 const {
return "bpm";}
 
  721     typedef ElementDrift             self_t;
 
  723     typedef typename base_t::state_t state_t;
 
  725     ElementDrift(
const Config& c) : base_t(c) {}
 
  726     virtual ~ElementDrift() {}
 
  727     virtual const char* 
type_name()
 const {
return "drift";}
 
  735         const double L = 
length*MtoMM; 
 
  737         for(
size_t i=0; i<last_real_in.size(); i++) {
 
  738             transfer[i] = boost::numeric::ublas::identity_matrix<double>(state_t::maxsize);
 
  739             transfer[i](state_t::PS_X, state_t::PS_PX) = L;
 
  740             transfer[i](state_t::PS_Y, state_t::PS_PY) = L;
 
  741             transfer[i](state_t::PS_S, state_t::PS_PS) =
 
  742                 -2e0*M_PI/(SampleLambda*ST.real[i].IonEs/MeVtoeV*cube(ST.real[i].bg))*L;
 
  750     typedef ElementOrbTrim           self_t;
 
  752     typedef typename base_t::state_t state_t;
 
  754     ElementOrbTrim(
const Config& c) : base_t(c) {
length = 0e0;}
 
  755     virtual ~ElementOrbTrim() {}
 
  756     virtual const char* 
type_name()
 const {
return "orbtrim";}
 
  763         double theta_x = 
conf().
get<
double>(
"theta_x", 0e0),
 
  764                theta_y = 
conf().
get<
double>(
"theta_y", 0e0);
 
  766         for(
size_t i=0; i<last_real_in.size(); i++) {
 
  767             transfer[i] = boost::numeric::ublas::identity_matrix<double>(state_t::maxsize);
 
  768             transfer[i](state_t::PS_PX, 6) = theta_x*ST.real[i].IonZ/ST.ref.
IonZ;
 
  769             transfer[i](state_t::PS_PY, 6) = theta_y*ST.real[i].IonZ/ST.ref.
IonZ;
 
  771             get_misalign(ST, ST.real[i], misalign[i], misalign_inv[i]);
 
  773             noalias(scratch)  = prod(
transfer[i], misalign[i]);
 
  774             noalias(
transfer[i]) = prod(misalign_inv[i], scratch);
 
  784     typedef ElementSBend             self_t;
 
  786     typedef typename base_t::state_t state_t;
 
  788     unsigned HdipoleFitMode;
 
  790     ElementSBend(
const Config& c) : base_t(c), HdipoleFitMode(0) {
 
  792         std::istringstream strm(c.
get<std::string>(
"HdipoleFitMode", 
"1"));
 
  793         strm>>HdipoleFitMode;
 
  794         if(!strm.eof() && strm.fail())
 
  795             throw std::runtime_error(
"HdipoleFitMode must be an integer");
 
  797     virtual ~ElementSBend() {}
 
  798     virtual const char* 
type_name()
 const {
return "sbend";}
 
  801         base_t::assign(other);
 
  802         const self_t* O=
static_cast<const self_t*
>(other);
 
  803         HdipoleFitMode = O->HdipoleFitMode;
 
  808         state_t&  ST = 
static_cast<state_t&
>(s);
 
  809         using namespace boost::numeric::ublas;
 
  816             last_ref_in = ST.ref;
 
  817             last_real_in = ST.real;
 
  823             last_ref_out = ST.ref;
 
  824             last_real_out = ST.real;
 
  826             ST.ref = last_ref_out;
 
  827             assert(last_real_out.size()==ST.real.size()); 
 
  828             std::copy(last_real_out.begin(),
 
  837         for(
size_t i=0; i<last_real_in.size(); i++) {
 
  838             double phis_temp = ST.moment0[i][state_t::PS_S];
 
  840             ST.moment0[i]          = prod(
transfer[i], ST.moment0[i]);
 
  842             noalias(scratch)       = prod(
transfer[i], ST.moment1[i]);
 
  843             noalias(ST.moment1[i]) = prod(scratch, trans(
transfer[i]));
 
  845             double dphis_temp = ST.moment0[i][state_t::PS_S] - phis_temp;
 
  847             if (HdipoleFitMode != 1) {
 
  860                 ST.real[i].phis  += ST.real[i].SampleIonK*
length*MtoMM + dphis_temp;
 
  862                 ST.real[i].phis  += ST.real[i].SampleIonK*
length*MtoMM + dphis_temp;
 
  872         double L     = 
conf().
get<
double>(
"L")*MtoMM,
 
  873                phi   = 
conf().
get<
double>(
"phi")*M_PI/180e0,
 
  874                phi1  = 
conf().
get<
double>(
"phi1")*M_PI/180e0,
 
  875                phi2  = 
conf().
get<
double>(
"phi2")*M_PI/180e0,
 
  876                K     = 
conf().
get<
double>(
"K", 0e0)/sqr(MtoMM);
 
  878         for(
size_t i=0; i<last_real_in.size(); i++) {
 
  879             double qmrel = (ST.real[i].IonZ-ST.ref.
IonZ)/ST.ref.
IonZ;
 
  881             transfer[i] = boost::numeric::ublas::identity_matrix<double>(state_t::maxsize);
 
  883             if (HdipoleFitMode != 1) {
 
  884                 double dip_bg    = 
conf().
get<
double>(
"bg"),
 
  886                        dip_Ek    = (sqrt(sqr(dip_bg)+1e0)-1e0)*ST.ref.
IonEs,
 
  887                        dip_gamma = (dip_Ek+ST.ref.
IonEs)/ST.ref.
IonEs,
 
  888                        dip_beta  = sqrt(1e0-1e0/sqr(dip_gamma)),
 
  889                        d         = (ST.ref.
gamma-dip_gamma)/(sqr(dip_beta)*dip_gamma) - qmrel,
 
  890                        dip_IonK  = 2e0*M_PI/(dip_beta*SampleLambda);
 
  892                 GetSBendMatrix(L, phi, phi1, phi2, K, ST.ref.
IonEs, ST.ref.
gamma, qmrel,
 
  893                                dip_beta, dip_gamma, d, dip_IonK, 
transfer[i]);
 
  895                 GetSBendMatrix(L, phi, phi1, phi2, K, ST.ref.
IonEs, ST.ref.
gamma, qmrel,
 
  898             get_misalign(ST, ST.real[i], misalign[i], misalign_inv[i]);
 
  900             noalias(scratch)     = prod(
transfer[i], misalign[i]);
 
  901             noalias(
transfer[i]) = prod(misalign_inv[i], scratch);
 
  909     typedef ElementQuad              self_t;
 
  911     typedef typename base_t::state_t state_t;
 
  913     ElementQuad(
const Config& c) : base_t(c) {}
 
  914     virtual ~ElementQuad() {}
 
  915     virtual const char* 
type_name()
 const {
return "quadrupole";}
 
  921         const double B2= 
conf().
get<
double>(
"B2"),
 
  922                      L = 
conf().
get<
double>(
"L")*MtoMM;
 
  924         for(
size_t i=0; i<last_real_in.size(); i++) {
 
  926             transfer[i] = boost::numeric::ublas::identity_matrix<double>(state_t::maxsize);
 
  928             double Brho = ST.real[i].beta*(ST.real[i].IonEk+ST.real[i].IonEs)/(C0*ST.real[i].IonZ),
 
  929                    K = B2/Brho/sqr(MtoMM);
 
  932             GetQuadMatrix(L,  K, (
unsigned)state_t::PS_X, 
transfer[i]);
 
  934             GetQuadMatrix(L, -K, (
unsigned)state_t::PS_Y, 
transfer[i]);
 
  938             transfer[i](state_t::PS_S, state_t::PS_PS) =
 
  939                     -2e0*M_PI/(SampleLambda*ST.real[i].IonEs/MeVtoeV*cube(ST.real[i].bg))*L;
 
  941             get_misalign(ST, ST.real[i], misalign[i], misalign_inv[i]);
 
  943             noalias(scratch)     = prod(
transfer[i], misalign[i]);
 
  944             noalias(
transfer[i]) = prod(misalign_inv[i], scratch);
 
  952     typedef ElementSolenoid          self_t;
 
  954     typedef typename base_t::state_t state_t;
 
  956     ElementSolenoid(
const Config& c) : base_t(c) {}
 
  957     virtual ~ElementSolenoid() {}
 
  958     virtual const char* 
type_name()
 const {
return "solenoid";}
 
  964         const double B = 
conf().
get<
double>(
"B"),
 
  965                      L = 
conf().
get<
double>(
"L")*MtoMM;      
 
  967         for(
size_t i=0; i<last_real_in.size(); i++) {
 
  969             transfer[i] = boost::numeric::ublas::identity_matrix<double>(state_t::maxsize);
 
  971             double Brho = ST.real[i].beta*(ST.real[i].IonEk+ST.real[i].IonEs)/(C0*ST.real[i].IonZ),
 
  972                    K    = B/(2e0*Brho)/MtoMM;
 
  976             transfer[i](state_t::PS_S, state_t::PS_PS) =
 
  977                     -2e0*M_PI/(SampleLambda*ST.real[i].IonEs/MeVtoeV*cube(ST.real[i].bg))*L;
 
  979             get_misalign(ST, ST.real[i], misalign[i], misalign_inv[i]);
 
  981             noalias(scratch)     = prod(
transfer[i], misalign[i]);
 
  982             noalias(
transfer[i]) = prod(misalign_inv[i], scratch);
 
  990     typedef ElementEDipole           self_t;
 
  992     typedef typename base_t::state_t state_t;
 
  994     ElementEDipole(
const Config& c) : base_t(c) {}
 
  995     virtual ~ElementEDipole() {}
 
  996     virtual const char* 
type_name()
 const {
return "edipole";}
 
 1006         bool   ver         = 
conf().
get<
double>(
"ver") == 1.0;
 
 1007         double L           = 
conf().
get<
double>(
"L")*MtoMM,
 
 1008                phi         = 
conf().
get<
double>(
"phi")*M_PI/180e0,
 
 1010                fringe_x    = 
conf().
get<
double>(
"fringe_x", 0e0)/MtoMM,
 
 1011                fringe_y    = 
conf().
get<
double>(
"fringe_y", 0e0)/MtoMM,
 
 1012                kappa       = 
conf().
get<
double>(
"asym_fac", 0e0),
 
 1014                spher       = 
conf().
get<
double>(
"spher"),
 
 1018                Ky          = spher/sqr(rho),
 
 1019                dip_beta    = 
conf().
get<
double>(
"beta"),
 
 1020                dip_gamma   = 1e0/sqrt(1e0-sqr(dip_beta));
 
 1022         for(
size_t i=0; i<last_real_in.size(); i++) {
 
 1023             double eta0        = (ST.real[i].gamma-1e0)/2e0,
 
 1024                    Kx          = (1e0-spher+sqr(1e0+2e0*eta0))/sqr(rho),
 
 1025                    delta_KZ    = ST.real[i].IonZ/ST.ref.
IonZ - 1e0,
 
 1026                    SampleIonK  = 2e0*M_PI/(ST.real[i].beta*SampleLambda);
 
 1028             transfer[i] = boost::numeric::ublas::identity_matrix<double>(state_t::maxsize);
 
 1030             GetEBendMatrix(L, phi, fringe_x, fringe_y, kappa, Kx, Ky, ST.ref.
IonEs, ST.ref.
beta, ST.real[i].gamma,
 
 1031                            eta0, h, dip_beta, dip_gamma, delta_KZ, SampleIonK, 
transfer[i]);
 
 1036                 R = boost::numeric::ublas::identity_matrix<double>(state_t::maxsize);
 
 1037                 R(state_t::PS_X,  state_t::PS_X)   =  0e0;
 
 1038                 R(state_t::PS_PX, state_t::PS_PX)  =  0e0;
 
 1039                 R(state_t::PS_Y,  state_t::PS_Y)   =  0e0;
 
 1040                 R(state_t::PS_PY, state_t::PS_PY)  =  0e0;
 
 1041                 R(state_t::PS_X,  state_t::PS_Y)   = -1e0;
 
 1042                 R(state_t::PS_PX, state_t::PS_PY)  = -1e0;
 
 1043                 R(state_t::PS_Y,  state_t::PS_X)   =  1e0;
 
 1044                 R(state_t::PS_PY,  state_t::PS_PX) =  1e0;
 
 1046                 noalias(scratch)     = prod(R, 
transfer[i]);
 
 1047                 noalias(
transfer[i]) = prod(scratch, trans(R));
 
 1051             get_misalign(ST, ST.real[i], misalign[i], misalign_inv[i]);
 
 1053             noalias(scratch)     = prod(
transfer[i], misalign[i]);
 
 1054             noalias(
transfer[i]) = prod(misalign_inv[i], scratch);
 
 1062     typedef ElementEQuad             self_t;
 
 1064     typedef typename base_t::state_t state_t;
 
 1066     ElementEQuad(
const Config& c) : base_t(c) {}
 
 1067     virtual ~ElementEQuad() {}
 
 1068     virtual const char* 
type_name()
 const {
return "equad";}
 
 1074         const double V0   = 
conf().
get<
double>(
"V"),
 
 1075                      R    = 
conf().
get<
double>(
"radius"),
 
 1076                      L    = 
conf().
get<
double>(
"L")*MtoMM;
 
 1078         for(
size_t i=0; i<last_real_in.size(); i++) {
 
 1081             transfer[i] = boost::numeric::ublas::identity_matrix<double>(state_t::maxsize);
 
 1083             double Brho = ST.real[i].beta*(ST.real[i].IonEk+ST.real[i].IonEs)/(C0*ST.real[i].IonZ),
 
 1084                    K    = 2e0*V0/(C0*ST.real[i].beta*sqr(R))/Brho/sqr(MtoMM);
 
 1087             GetQuadMatrix(L,  K, (
unsigned)state_t::PS_X, 
transfer[i]);
 
 1089             GetQuadMatrix(L, -K, (
unsigned)state_t::PS_Y, 
transfer[i]);
 
 1093             transfer[i](state_t::PS_S, state_t::PS_PS) =
 
 1094                     -2e0*M_PI/(SampleLambda*ST.real[i].IonEs/MeVtoeV*cube(ST.real[i].bg))*L;
 
 1096             get_misalign(ST, ST.real[i], misalign[i], misalign_inv[i]);
 
 1098             noalias(scratch)     = prod(
transfer[i], misalign[i]);
 
 1099             noalias(
transfer[i]) = prod(misalign_inv[i], scratch);
 
 1106 void registerMoment()
 
 1108     Machine::registerState<MomentState>(
"MomentMatrix");
 
 1110     Machine::registerElement<ElementSource                 >(
"MomentMatrix", 
"source");
 
 1112     Machine::registerElement<ElementMark                   >(
"MomentMatrix", 
"marker");
 
 1114     Machine::registerElement<ElementBPM                    >(
"MomentMatrix", 
"bpm");
 
 1116     Machine::registerElement<ElementDrift                  >(
"MomentMatrix", 
"drift");
 
 1118     Machine::registerElement<ElementOrbTrim                >(
"MomentMatrix", 
"orbtrim");
 
 1120     Machine::registerElement<ElementSBend                  >(
"MomentMatrix", 
"sbend");
 
 1122     Machine::registerElement<ElementQuad                   >(
"MomentMatrix", 
"quadrupole");
 
 1124     Machine::registerElement<ElementSolenoid               >(
"MomentMatrix", 
"solenoid");
 
 1126     Machine::registerElement<ElementRFCavity               >(
"MomentMatrix", 
"rfcavity");
 
 1128     Machine::registerElement<ElementStripper               >(
"MomentMatrix", 
"stripper");
 
 1130     Machine::registerElement<ElementEDipole                >(
"MomentMatrix", 
"edipole");
 
 1132     Machine::registerElement<ElementEQuad                  >(
"MomentMatrix", 
"equad");
 
double gamma
Gamma for ion. (dependent) 
 
virtual bool check_cache(const state_t &S) const 
 
virtual bool getArray(unsigned idx, ArrayInfo &Info)
Introspect named parameter of the derived class. 
 
Base class for all simulated elements. 
 
double length
Longitudual length of this element (added to StateBase::pos) 
 
double IonW
Total energy. (dependent) 
 
double IonEk
Kinetic energy. 
 
virtual void show(std::ostream &strm, int level) const 
 
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]. 
 
virtual void assign(const ElementVoid *other)=0
 
Associative configuration container. 
 
virtual void recompute_matrix(state_t &ST)
recalculate 'transfer' taking into consideration the provided input state 
 
Used with StateBase::getArray() to describe a single parameter. 
 
virtual void assign(const StateBase &other)=0
 
double pos
absolute longitudinal position at end of Element 
 
virtual void assign(const ElementVoid *other)=0
 
virtual void assign(const StateBase &other)
 
size_t dim[maxdims]
Array dimensions in elements. 
 
const Config & conf() const 
The Config used to construct this element. 
 
double dx
constituents of misalign 
 
bool skipcache
If set, check_cache() will always return false. 
 
size_t size() const 
of charge states
 
size_t stride[maxdims]
Array strides in bytes. 
 
std::vector< value_t > transfer
final transfer matricies 
 
double beta
Beta for ion. (dependent) 
 
double bg
Beta*gamma. (dependent) 
 
virtual void show(std::ostream &strm, int level) const 
 
bool tryGet(const std::string &name, T &val) const 
 
virtual bool getArray(unsigned index, ArrayInfo &Info)
Introspect named parameter of the derived class. 
 
detail::RT< T >::type get(const std::string &name) const 
 
double SampleIonK
Sample rate; different RF Cavity due to RF frequenies. (dependent) 
 
virtual void show(std::ostream &, int level) const 
 
void resize_cache(const state_t &ST)
 
const char * name
The parameter name. 
 
An Element which propagates the statistical moments of a bunch.