diff --git a/atpy/core/beamline.pyx b/atpy/core/beamline.pyx index 7ef17bb..341a8df 100644 --- a/atpy/core/beamline.pyx +++ b/atpy/core/beamline.pyx @@ -64,8 +64,6 @@ cdef class BeamLine: if self.pyline.expand[0].name !="START": self.pyline.expand.insert(0,Marker("START") ) self.pyline.reverse.insert(0, False) - (self.pyline.expand[0]).eids=[0] - self.elems_index["START"]=[0] length0=len(self.pyline.expand)-1 self.lat=new CppBeamLine(name, self.stat.stat.particle, self.stat.stat.energy,length0,self.stat.stat) # self.elems_index["START"]=[0] @@ -84,9 +82,6 @@ cdef class BeamLine: for index,value in enumerate(self.pyline.expand ): # 在CppBeamLine中有默认起始Marker元素 "START" position=index - if index==0: continue - # print(index," __cinit__:0",value.name) - # self.lat.append(value.elem ,self.pyline.reverse[index ] ) if value.name not in self.elems_index.keys(): (value).eids=[position] self.elems_index[value.name] = [position ] @@ -110,6 +105,7 @@ cdef class BeamLine: cdef size_t index,position cdef Parser parser=Parser(self.elems_index ) for index,value in enumerate(self.pyline.expand ): + # 在CppBeamLine中有默认起始Marker元素 "START" if index==0: continue lat.append(value.elem ,self.pyline.reverse[index ] ) parser._set_database(lat ) @@ -137,6 +133,9 @@ cdef class BeamLine: def set_parallel(self, int nkernel=-1): """ set_parallel(self, Py_ssize_t nkernel=None) + set threads of parallel + params: + nkernel: (default: -1, max_threads of machine ) """ cdef Py_ssize_t i,num_thread = openmp.omp_get_max_threads() @@ -166,6 +165,10 @@ cdef class BeamLine: self.update_parser(self.parser_pool[i], self.parser) def update_parser(self,Parser parser1, Parser parser0): + """ + update_parser(self,Parser parser1, Parser parser0) + update the parser1 from parser0, usually called internally. + """ len0 = len(parser0.tokens) len1 = len(parser1.tokens) if len1>len0: @@ -179,6 +182,10 @@ cdef class BeamLine: def set_worker(self,Py_ssize_t index=0): + """ + set_worker(self,Py_ssize_t index=0) + change the default worker, index <= nkernel ,then the old default worker will stored to the index worker + """ cdef: CppBeamLine* lat0 = self.lat Parser parser0= self.parser @@ -237,6 +244,9 @@ cdef class BeamLine: def _save(self): + """ + internal funcction + """ cdef: CppBeamLine* lat=NULL bytes name @@ -247,6 +257,9 @@ cdef class BeamLine: lat.save((self.pyline.elems[name.decode("utf8")]).elem ) def save(self): + """ + save the value of internal to the python objects + """ self._save() @@ -278,6 +291,7 @@ cdef class BeamLine: string name double value=0,summary=0,cell=0 Constraints* pconstraint=&lat.constraints + double *tmp_ptr = NULL # print("_update_constraints") computeRDTs = lat.stat.computedrivingterms lat.stat.computedrivingterms=False @@ -307,6 +321,8 @@ cdef class BeamLine: lat.compute_large_off_momentum_tunes(lat.stat.monitor_dp) if lat.constraints.time_consuming_terms[OFF_MOMENTUM_SUM_TERMS ] : lat.compute_off_momentum_sum_square(lat.stat.monitor_dp) + if lat.constraints.time_consuming_terms[DA_TRACKING_TERMS ] : + lat.get_DA_area( tmp_ptr ) #更新ID表和约束 lat.TwissPropagate() for name in lat.id_table.id_table: @@ -326,6 +342,7 @@ cdef class BeamLine: size_t i double value=0,summary=0 Optima* poptima=&lat.optima + double *tmp_ptr = NULL # print("_update_optima") computeRDTs = lat.stat.computedrivingterms @@ -347,6 +364,8 @@ cdef class BeamLine: lat.compute_large_off_momentum_tunes(lat.stat.monitor_dp) if poptima.time_consuming_terms[OFF_MOMENTUM_SUM_TERMS ] and not lat.constraints.time_consuming_terms[OFF_MOMENTUM_SUM_TERMS ] : lat.compute_off_momentum_sum_square(lat.stat.monitor_dp) + if poptima.time_consuming_terms[DA_TRACKING_TERMS ] and not lat.constraints.time_consuming_terms[DA_TRACKING_TERMS ] : + lat.get_DA_area( tmp_ptr ) for i in range(poptima.num_optima): @@ -374,6 +393,14 @@ cdef class BeamLine: def evolution(self,double[:,:] variables, double[:,:] objectives, double[:,:] CV ): + """ + evolution(self,double[:,:] variables, double[:,:] objectives, double[:,:] CV ) + variables: MxN array corresponing to the VAR of parser + objectives: MxL array corresponing to the CONSTRAINT of parser + CV: MxP array corresponing to the OPTIMIZE of parser + returns: + CV, objectives + """ cdef: int i,j,i_cv_best,i_objv_best, num_variables= variables.shape[1], num_optima = objectives.shape[1], num_constraints=CV.shape[1], num_pop = variables.shape[0] double cv_tmp,value,objv_value @@ -402,8 +429,15 @@ cdef class BeamLine: def __call__(self,double[:] X): + """ + X: 1-d array of N elements corresponing to the VAR of parser + return: + CV, objectives + CV: 1-d array of P elements corresponing to the OPTIMIZE of parser + objectives: 1-d array L elements corresponing to the CONSTRAINT of parser + """ cdef: - int i,i_cv_best,i_objv_best, num_variables= X.shape[1] + int i,i_cv_best,i_objv_best, num_variables= X.shape[0] double cv_tmp,value,objv_value CppBeamLine* lat=NULL lat=self.lat @@ -439,6 +473,10 @@ cdef class BeamLine: lat.TwissPropagate() def findclosedorbit(self, double dp): + """ + dp: off-momentum Delta_p/p_0 + find the closed orbit with 4-D track + """ cdef double[::1] r=np.array([0,0,0,0,0,dp],dtype="float") self.lat.findClosedOrbit( &r[0] ) @@ -452,6 +490,11 @@ cdef class BeamLine: self.lat.compute_off_momentum_RDTs() def correctchrom(self, dQx=None, dQy=None): + """ + correctchrom(self, dQx=None, dQy=None) + correct 1st order chromaticity to (dQx,dQy) use the knob set by CHROM in parser + if dQx, dQy is None, the chromaticity is corrected to the value set by AIM_DQX, AIM_DQY + """ cdef: CppBeamLine* lat=self.lat if lat.chrom_corrector.iscorr1 or lat.chrom_corrector.iscorr2: @@ -464,6 +507,17 @@ cdef class BeamLine: def compute_off_momentum_twiss(self, list dp_range, double dp_step=1e-4, bint local_twiss=True): + """ + compute_off_momentum_twiss(self, list dp_range, double dp_step=1e-4, bint local_twiss=True) + dp_range: (min dp, max dp) + dp_step : the step of dp to compute the off-momentum twiss functions at the end of beamline + local_twiss : whether to calculate the twiss functions of local elements + returns: + dps, twiss_mat + dps: 1-d array of N dp elements to calculate off-momentum twisses + twiss_mat: NxNUM_TWS array of the twisses function + """ + cdef: CppBeamLine* lat=self.lat size_t i @@ -488,8 +542,15 @@ cdef class BeamLine: def track(self, double[:,::1] beam0, int start_pos=0, int end_pos=-1, int nturn0=1,int nturn1=1): """ - track(self, double[:,:] beam, start_pos=0, end_pos=-1, nturn0=1,nturn1=1): - return : N x [X ,PX ,Y ,PY ,Z ,DP ,LOSS , LOSSTURN ,LOSSPOS ] + track(self, double[:,::1] beam0, int start_pos=0, int end_pos=-1, int nturn0=1,int nturn1=1) + track(self, double[:,:] beam, start_pos=0, end_pos=-1, nturn0=1,nturn1=1) + beam: Nx7([X ,PX ,Y ,PY ,Z ,DP ,LOSS) array, loss is zero if particle is not lost + start_pos: int,the start element to track beams + end_pos: int, the end element to end the tracking + nturn0: int, the nturn0-th turn to start tracking + nturn1: int, the nturn1-th turn to end the tracking + return + N x [X ,PX ,Y ,PY ,Z ,DP ,LOSS , LOSSTURN ,LOSSPOS ] """ cdef: int nbegin, nend, nturn_begin, nturn_end, num_col=beam0.shape[1] , num_particles=beam0.shape[0] @@ -560,6 +621,7 @@ cdef class BeamLine: value=lat.id_table.id_dict[name].value print(f"{index:<4}:{name.decode('utf8'):25}{value:>30.e6}") print(60*"=") + elif token=="VAR": num_indep_vars=lat.vars.num_independent_vars num_dep_vars=lat.vars.num_dependent_vars @@ -569,7 +631,8 @@ cdef class BeamLine: name=lat.vars.ordered_independ_var_names[index] lb=(lat.vars.independent_vars[name]).lb ub=(lat.vars.independent_vars[name]).ub - print(f"{index:<4}:{name.decode('utf8'):25}{lb:15.6}{ub:15.6}") + step=(lat.vars.independent_vars[name]).step + print(f"{index:<4}:NAME={name.decode('utf8'):25}, LOWER={lb:13.6}, UPPER={ub:13.6}, STEP={step:13.6};") for index in range(num_dep_vars): name=lat.vars.ordered_depend_var_names[index] print(f"{index+num_indep_vars:<4}:{name.decode('utf8'):36}{'CoVar':20}") @@ -594,6 +657,12 @@ cdef class BeamLine: def export(self,str filename, str filetype="atpy"): + """ + export(self,str filename, str filetype="atpy") + export the lattice to the form of other simulation programs ( some detail of the transformation may be not correct) + filename: names of file to store the output lattice + filetype: str, one of the ["atpy","elegant", "opa","sad","madx"] + """ cdef: CppBeamLine* lat=NULL lat=self.lat @@ -688,7 +757,8 @@ cdef class BeamLine: def optics(self, start=0, stop=None,step=0.01,key=None,*,bint at_s=False): """ - + optics(self, start=0, stop=None,step=0.01,key=None,*,bint at_s=False) + return the twiss function at given steps, usually for ploting """ cdef: double tmp_tws[TWS_NUM] @@ -815,6 +885,10 @@ cdef class BeamLine: return res def get_DA_area(self): + """ + get_DA_area + get DA bounds with the form numpy.array([x_list,y_list]) + """ cdef double[:,::1] area_datas=np.zeros((2,self.lat.stat.track_lines) ) self.lat.get_DA_area( &area_datas[0,0] ) return np.array(area_datas.base ) diff --git a/atpy/core/elements.pyx b/atpy/core/elements.pyx index 23d417d..ea01d46 100644 --- a/atpy/core/elements.pyx +++ b/atpy/core/elements.pyx @@ -4,6 +4,10 @@ import re from .interface.constants import rcParams # from constants import KWD_INDEX, INDEX_KWD, TWS_INDEX, LOC_INDEX, GLB_INDEX, ELEM_INDEX, DEFAULT_ELEM_KARGS +# export_hash ={ +# "elegant":{L:"L", ANGLE:"ANGLE", K1:"K1", K2:"K2",K3:"K3", E1:"e1", E2:"e2",NSLICE:"N_SLICES" }, + +# } def generate_tuners(ring, names): @@ -53,6 +57,8 @@ cdef class Line: # lines=args[::-1] if reverse else args for index,arg in enumerate(args): if isinstance(arg,Element): + if arg.name in ("START","END") and (index != 0 and index != len(args)-1): + raise ValueError(f"START and END are reserved for the first and last Marker element, but {index}-th used the {arg.name}!") # self.unit_cell.append(arg) self.line.append(arg) self.elems[arg.name]=arg @@ -60,6 +66,8 @@ cdef class Line: self.expand.append(arg) self.reverse.append(False) elif isinstance(arg,Line): + # when a line is used by BeamLine, START and END will be inserted. to reuse the line, delete these two Elements + arg.renew() self.elems={**self.elems,**arg.elems} self.ordered_lines+=arg.ordered_lines self.line.append(arg ) @@ -75,11 +83,24 @@ cdef class Line: self.ordered_lines.append(self) + def renew(self): + """ + remove the START and END Marker inserted by BeamLine + """ + if self.expand[0].name == "START": + self.expand.pop(0) + self.reverse.pop(0) + if self.expand[-1].name == "END": + self.expand.pop(-1) + self.reverse.pop(-1) + + def __rmul__(self,int other): cdef Line newline=Line.__new__(self.__class__ ) cdef list reverse,expand newline.name=f"{other}*{self.name}" + self.renew() if other<0: reverse=-other*[not value for value in self.reverse[::-1] ] expand=-other*self.expand[::-1] @@ -106,6 +127,7 @@ cdef class Line: def __neg__(self): cdef Line newline=Line.__new__(self.__class__ ) newline.name=f"-{self.name}" + self.renew() newline.reverse=[not value for value in self.reverse[::-1] ] newline.expand =self.expand[::-1] newline.ordered_lines=self.ordered_lines @@ -476,4 +498,4 @@ cdef class Wiggler(Line): seq= int(m)*[Dipole(f"{name}{i:0>2}",l=l_slice,angle=Ais[i],e1=e1s[i],e2=e2s[i]) for i in range(nslices) ] super(Wiggler, self).__init__(name,*seq ) - pass \ No newline at end of file + pass diff --git a/atpy/core/interface/constants.pxd b/atpy/core/interface/constants.pxd index 8702a5e..d26e224 100644 --- a/atpy/core/interface/constants.pxd +++ b/atpy/core/interface/constants.pxd @@ -86,7 +86,8 @@ cdef extern from "physics/utils/cppconstants.h": LOCAL_NUX ,LOCAL_NUY, S ,GX ,GY ,GZ ,THETAX ,THETAY , THETAZ ,DX ,DY ,DZ ,ROTATE1 ,ROTATE2 , - ROTATE3 ,AX ,AY , + ROTATE3 ,AX ,AY ,WX1 ,WY1 ,WX2 , + WY2 , LOC_NUM @@ -110,7 +111,9 @@ cdef extern from "physics/utils/cppconstants.h": H22000, H11110, H00220, H31000, H40000, H20110, H11200, H20020, H20200, H00310, H00400, DA , DA_SIGMA , - DETAX , DETAPX, DBETAX, DBETAY, DALPHAX, DALPHAY, DDETAX, DDBETAX, DDBETAY, WX, WY, + DETAX , DETAPX, DBETAX, DBETAY, DALPHAX, DALPHAY, + # DDETAX, DDBETAX, DDBETAY, + WX, WY, LOW_QX ,LOW_QY, HIGH_QX ,HIGH_QY, SUM_SQR_QX, SUM_SQR_QY, INV_TAU, GLB_NUM diff --git a/atpy/core/interface/cppast.pxd b/atpy/core/interface/cppast.pxd index cfa061f..3451f99 100644 --- a/atpy/core/interface/cppast.pxd +++ b/atpy/core/interface/cppast.pxd @@ -6,7 +6,7 @@ cdef extern from "../utils/cppast.h"nogil: cdef enum: ADD, SUB, MUL, DIV, POW, MOD, FLOOR, ABS, SQRT, SIN, COS, SINH, COSH, - EXP, DIM, MAX, MIN, + EXP, DIM, MAX, MIN, MAXABS, MINABS, SUM, NUMBER, PROPERTY, ID, REFER, DOT, SLICE, COMMA, DELAY, ASSIGN, diff --git a/atpy/core/parser/lexer.pyx b/atpy/core/parser/lexer.pyx index 901669b..a051afb 100644 --- a/atpy/core/parser/lexer.pyx +++ b/atpy/core/parser/lexer.pyx @@ -46,7 +46,7 @@ cdef class Lexer: local = LOC_INDEX.keys() glbs = GLB_INDEX.keys() - funs = ["ABS", "MIN", "MAX", "SQRT", "DIM", "SIN", "COS", "SINH", "COSH", "EXP"] + funs = ["ABS", "MIN", "MAX","MINABS", "MAXABS", "SQRT", "DIM", "SIN", "COS", "SINH", "COSH", "EXP"] operators= ["+","-","*", "/", "//", "%", "**" ] bracket = ["(", ")" ] sign = [",","@","."] diff --git a/atpy/core/parser/parser.pyx b/atpy/core/parser/parser.pyx index fccaf79..dd872ae 100644 --- a/atpy/core/parser/parser.pyx +++ b/atpy/core/parser/parser.pyx @@ -2,7 +2,7 @@ import re import warnings value2enum={"+":ADD, "-": SUB, "*": MUL, "/":DIV, "**":POW, "%":MOD, "//":FLOOR, - "ABS":ABS, "SQRT":SQRT, "DIM":DIM, "MAX":MAX, "MIN":MIN, + "ABS":ABS, "SQRT":SQRT, "DIM":DIM, "MAX":MAX, "MIN":MIN, "MAXABS":MAXABS, "MINABS":MINABS, "NUMBER":NUMBER, "TWS":TWS, "KWD":KWD, "LOC":LOC, "GLB":GLB, "DELAY":DELAY } @@ -106,7 +106,7 @@ cdef class Parser: # 定义语法分析器的类 node =NULL self.eat("(") - if func in ("MIN", "MAX"): + if func in ("MIN", "MAX", "MINABS", "MAXABS"): for i in range(2): position=self.position() positions.append( position ) diff --git a/atpy/core/physics/beamline/cppbeamline.backup b/atpy/core/physics/beamline/cppbeamline.backup deleted file mode 100644 index 82b625a..0000000 --- a/atpy/core/physics/beamline/cppbeamline.backup +++ /dev/null @@ -1,1776 +0,0 @@ -#ifndef _CPPBEAMLINE_CPP_ -#define _CPPBEAMLINE_CPP_ - -#include "omp.h" -#include -#include -#include -#include "cppbeamline.h" -#include "twiss.h" - -using Eigen::Matrix; -using Eigen::MatrixXd; -using Eigen::EigenSolver; -using Eigen::Map; -using Eigen::Dynamic; -using Eigen::RowMajor; -typedef Matrix Matrix6d; - -double touschekF(double x){ - // condition x > 0 is not checked in the function, be careful - double Eular=0.5772; - double logx, logx2, logx3, logx4, value; - - if(x<0.0013 ){ - return log(Eular/x)-1.5; - } - else if(x<10){ - logx=log(x); - logx2=sqr(logx); - logx3=logx*logx2; - logx4=sqr(logx2); - - value=-3.10811-2.19156*logx - 0.615641*logx2 -0.160444*logx3 - 0.0460054*logx4 -0.0105172*logx*logx4 - - 1.31192e-3*logx2*logx4 -6.3898e-5*logx3*logx4; - return exp(value ); - } - else{ - return 1e-16; - } -} - -void deallocate(CppBeamLine* line){ - if(line !=nullptr){ - delete line; - } -} - - -CppBeamLine::CppBeamLine(){ - // elems_position["START"]={0}; - // elems.resize(0); - // elems.emplace_back(new CppMarker("START") ); - - nelems=0; - length=0; - CppElement* tmp_elem=new CppMarker("START"); - this->append(tmp_elem,false); - delete tmp_elem; - // elems["START"]->position.emplace_back(0); - stat.Trx=10; - stat.Try=10; - stat.totalslice=0; - stat.multipoleslice=0; - fill(globals, globals+GLB_NUM,0.0); - - // rdtcache.mult_slice=0; - // rdtcache.sext_slice=0; - -} - -CppBeamLine::CppBeamLine(const string name0, const size_t particle, const double energy,const size_t length0, Status stat0){ - name=name0; - stat=stat0; - stat.Trx=10; - stat.Try=10; - stat.totalslice=1; - stat.multipoleslice=0; - // cout<<"here in CppBeamLine::CppBeamLine(const string name0"<append(tmp_elem,false); - delete tmp_elem; - // this->append(elems["START"],false); - // elems["START"]->position.emplace_back(0); -} - - -CppBeamLine::CppBeamLine(const CppBeamLine& bline) -{ - name=bline.name; - stat=bline.stat; - factory=bline.factory; - stat.Trx=10; - stat.Try=10; - // globals[ENERGY]=bline.globals[ENERGY]; - // globals[MASS0]= bline.globals[MASS0]; - // globals[GAMMA]= bline.globals[GAMMA]; - // memcpy(globals, bline.globals, GLB_NUM*__SIZEOF_DOUBLE__ ); - length=0; - nelems=0; - line.resize(bline.line.size() ); - for(auto iter:bline.line){ - this->append(iter->elem,iter->reverse); - // cout<<"CppBeamLine::CppBeamLine(&):"<< (iter)->elem<name) ){ - *elem=**(elems[elem->name].begin() ); - return 0; - } - else{ - return -1; - } -} - - - -int CppBeamLine::display(const int disflag, const bool detail){ - - vector twiss={ COORD, BETAX, ALPHAX,GAMMAX, BETAY, ALPHAY,GAMMAX, ETAX, ETAPX, NUX, NUY,DCHROMX,DCHROMY};//,CHROMX,CHROMY }; - if(disflag!=DVTs){ - cout<< std::setw(6)<< std::left <<"No."<< std::setw(14)<< std::left << "Name"; - } - cout.precision(8); - switch (disflag) - { - case KWD: - /* code */ - for(size_t i=0;idisplay(disflag,detail); - } - return 0; -} - - - -int CppBeamLine::insert(CppElement* elem0,const int pos,const bool reverse){ - // 需要调整component中position参数 - if(fabs(pos)>length){ - throw std::out_of_range("insert position is out of range in function: CppBeamLine::insert!") ; - } - length+=1; - if(0==elems.count(elem0->name)){ - // CppElement* tmp_elem= - nelems+=1; - elems[elem0->name ].emplace_back( factory.CreateElement(elem0) ); - elems_position[elem0->name]={length}; - elems[elem0->name ].back()->position={length}; - } - else if(stat.expand){ - nelems+=1; - elems[elem0->name].emplace_back( factory.CreateElement(elem0) ); - elems_position[elem0->name].emplace_back(length); - elems[elem0->name ].back()->position={length}; - } - else{ - elems_position[elem0->name].emplace_back(length); - elems[elem0->name ].back()->position.emplace_back(length); - } - if(pos>0){ - line.insert(line.begin()+pos,new CppComponent(elems[elem0->name ].back(), reverse,pos) ); - } - else{ - - line.insert(line.end()+pos,new CppComponent(elems[elem0->name ].back(), reverse,pos) ); - } - - components[ elem0->name ].emplace_back(line.back() ); - - stat.totalslice+=elem0->nslice; - if(elem0->kind==QUADRUPOLE || elem0->kind==SEXTUPOLE || (stat.combineddipole && elem0->kind==DIPOLE)|| - elem0->kind==EXACTDRIFT || elem0->kind==OCTUPOLE ){ - stat.multipoleslice+=elem0->nslice; - rdtcache.mult_slice+=elem0->nslice; - if(elem0->kind==SEXTUPOLE)rdtcache.sext_slice+=elem0->nslice; - rdtcache.mult_position.push_back(length); - } - - return 0; - -} - - -int CppBeamLine::append(CppElement* elem0,const bool reverse){ - // cout<<"here in CppBeamLine:append:"<name<keywords[0])<line.size() ){ - cout<<"CppBeamLine::append: Input components are more than expected!"<name<name)){ - // cout<<"here in CppBeamLine:append:"<<0<<"length: "<name]->position.resize(0); - tmp0=factory.CreateElement(elem0); - elems[elem0->name].emplace_back( tmp0 ); - // cout<<"here in CppBeamLine:append:"<<1<name ].back(), (bool)reverse, length ) ; - // cout<<"here in CppBeamLine:append:"<<2<name]={length}; - elems[elem0->name ].back()->position={length}; - - } - else if(stat.expand){ - // cout<<1<name].emplace_back( tmp0 ); - // cout<<"CppBeamLine::append,elem0 address:"<< tmp0<name ].back(), reverse, length ) ; - elems_position[elem0->name].emplace_back(length); - elems[elem0->name ].back()->position={length}; - - // elems.emplace_back(factory.CreateElement(elem0) ); - // line.emplace_back( elems.back(),reverse,length ); - - // elems.back()->position={length}; - - } - else{ - - // elems[elem0->name].emplace_back( factory.CreateElement(elem0) ); - line[length]=new CppComponent( elems[ elem0->name ].back(), reverse, length ) ; - elems_position[elem0->name].emplace_back(length); - elems[elem0->name ].back()->position.emplace_back(length); - } - // cout<<"CppBeamLine::append,elem0 address:"<< elems[elem0->name ].back()<name ].emplace_back(line.back() ); - // line.emplace_back( elems[elem0->name],reverse,length ); - // elems[elem0->name]->position.emplace_back(length); - - // cout<<"CppBeamLine::append: "<<1<nslice; - if(elem0->kind==QUADRUPOLE || elem0->kind==SEXTUPOLE || (stat.combineddipole && elem0->kind==DIPOLE) || - elem0->kind==EXACTDRIFT || elem0->kind==OCTUPOLE) { - stat.multipoleslice+=elem0->nslice; - rdtcache.mult_slice+=elem0->nslice; - if(elem0->kind==SEXTUPOLE)rdtcache.sext_slice+=elem0->nslice; - rdtcache.mult_position.push_back(length); - } - - // cout<<"here in CppBeamLine:append:"<<7<tws(0,1)<position; - if(iter->local[S] >=coordinate)break; - } - return pos; -} - - - -int CppBeamLine::get_optics_at_s(double coordinate, double* twsout){ - size_t pos; - int i_th=0; - size_t i; - double delta_len=0, elem_len=0, len_rate; - double* twsin=nullptr; - double tmp_glbs[GLB_NUM ]; - memcpy(tmp_glbs, globals, EMITX*__SIZEOF_DOUBLE__ ); - pos=get_position_at_s(coordinate); - elem_len = line[pos]->elem->values[L]; - if(0==pos || fabs(elem_len)<1e-15 ){ - memcpy(twsout, &line[pos]->tws[0], TWS_NUM*__SIZEOF_DOUBLE__); - } - else{ - - delta_len=coordinate-line[pos-1]->local[S]; - len_rate=delta_len/elem_len; - twsin= &line[pos-1]->tws[-1] ; - // 设置LHxxxxx离切片中最近的值 - for(i=LH00111;itws(-1,i) ; - } - - // i_th=round(delta_len/elem_len*line[pos]->elem->values[NSLICE ] )-1; - // if(i_th>0){ - // memcpy(twsout,&line[pos]->tws[i_th ], TWS_NUM*__SIZEOF_DOUBLE__); - // } - // else{ - // memcpy(twsout,twsin, TWS_NUM*__SIZEOF_DOUBLE__); - // } - line[pos]->elem->linearoptics(twsin, delta_len/elem_len, &stat,line[pos]->reverse, twsout, tmp_glbs ); - twsin=nullptr; - } - return 0; -} - - -int CppBeamLine::computeGlobalProperties(){ - double gamma0=globals[GAMMA], energy0=globals[ENERGY]; - double *RI= &globals[0],time0, circumference, Jx ; - double c_light=2.99792458e8 ; - double C_gamma=8.85e-5; - // cout<<"CppBeamLine::computeGlobalProperties: RI5"<local[S]; - circumference=globals[CIRCUMFERENCE]; - time0=circumference/c_light; - // #energy loss U0 [keV] - globals[U0] = 1e6*C_gamma*0.5*INV_PI*pow(energy0*1e-9,4)*RI[RI2]; - // #momentum compaction factor - globals[ALPHAC] = RI[RI1]/globals[CIRCUMFERENCE ]; - // #damping factor D Jx=1-D,Jy=1,Jz=2+D - globals[DAMP_FACTOR] = RI[RI4]/RI[RI2]; - globals[JX] =1-globals[DAMP_FACTOR]; - globals[JY] =1; - globals[JZ] =2+globals[DAMP_FACTOR]; - // #square of Energy dispersion - globals[ESPREAD] = sqrt(Cq*gamma0*gamma0*RI[RI3]/(2*RI[RI2] + RI[RI4]) ); - if(fabs(RI[RI3])>1e-15){ - // #spin polarization I[6]:I3a in S.Y. Lee's book - globals[SPIN] = -1.6/sqrt(3)*RI[RI3A]/RI[RI3]; - } - Jx=globals[JX]; - //Damping time ms (eV->keV s->ms) - globals[TAUY] = 2*energy0*time0/globals[U0] ; - globals[TAUX] = globals[TAUY]/Jx ; - globals[TAUZ] = globals[TAUY]/(3-Jx) ; - globals[QX]=line[length]->tws(-1,NUX); - globals[QY]=line[length]->tws(-1,NUY); - // globals[H11001]=line[length]->tws(-1,CHROMX); - // globals[H00111]=line[length]->tws(-1,CHROMY); - RI=nullptr; - return 0; -} - - -int CppBeamLine::initialoptics(){ - // 初始化起点光学函数 - memcpy(line[0]->local+R11, EYE66, sizeof(EYE66)); - // fill(&(line[0]->tws[0] ) , &(line[0]->tws[0] )+TWS_NUM, 1E10); - - // if(ordered_changed_position.size()>0){ - // for(size_t index:ordered_changed_position){ - // line[index]->update_TransferMatrix(line[index-1]->local ,&stat ); - // } - // } - // else{ - // for(int i=1;i<=length;i++){ - // line[i]->update_TransferMatrix(line[i-1]->local ,&stat ); - // } - // } - // if(stat.period || stat.transfermatrix){ - // for(int i=1;icompute_TransferMatrix(line[i-1]->local ,&stat ); - // } - // } - line[0]->local[CODDP]=stat.dp0; - findClosedOrbit(line[0]->local+CODX); - if(stat.period){ - line[0]->tws=0.0; - int nslice=line[length]->elem->nslice; - double Trx= line[length]->local[R11]+line[length]->local[R22]; - double Try= line[length]->local[R33]+line[length]->local[R44]; - stat.Trx=Trx; - stat.Try=Try; - if(fabs( Trx)<2 && fabs(Try)<2 ){ - double* local=line[length]->local; - double cosmux = 0.5*Trx; - double cosmuy = 0.5*Try; - double cscmux = local[R12]/( fabs(local[R12])*sqrt(1-cosmux*cosmux) ); //1/sin(mux); - double cscmuy = local[R34]/( fabs(local[R34])*sqrt(1-cosmuy*cosmuy) ); //1/sin(muy); - // 重设初始点LHxxxxx为0 - fill(&(line[0]->tws[0] ) , &(line[0]->tws[0] )+TWS_NUM, 0.0); - - line[0]->tws(0,BETAX ) = local[R12]*cscmux; - line[0]->tws(0,ALPHAX) = 0.5*(local[R11]-local[R22])*cscmux; - line[0]->tws(0,GAMMAX) = -local[R21]*cscmux; - line[0]->tws(0,BETAY ) = local[R34]*cscmuy; - line[0]->tws(0,ALPHAY) = 0.5*(local[R33]-local[R44])*cscmuy; - line[0]->tws(0,GAMMAY) = -local[R43]*cscmuy; - line[0]->tws(0,ETAX ) = 0.5*(local[R16]*(1.0-local[R22]) + local[R12]*local[R26])/(1.0-cosmux); - line[0]->tws(0,ETAPX ) = 0.5*(local[R26]*(1.0-local[R11]) + local[R21]*local[R16])/(1.0-cosmux); - local=nullptr; - } - else{ - fill(&(line[0]->tws[0] ) , &(line[0]->tws[0] )+TWS_NUM, 1E10); - } - } - else{ - line[0]->tws(0,GAMMAX) = (1+sqr(line[0]->tws(0,ALPHAX) ))/line[0]->tws(0,BETAX) ; - line[0]->tws(0,GAMMAY) = (1+sqr(line[0]->tws(0,ALPHAY) ))/line[0]->tws(0,BETAY) ; - } - return 0; -} - - -int CppBeamLine::TwissPropagate(){ - int kind; - // avoid integrate twice - fill(globals+RI1,globals+RI5+1, 0.0); - for(int i=1;i<=length;i++){ - kind=line[i]->elem->kind; - line[i]->linearoptics(&(line[i-1]->tws[-1] ) ,&stat, globals); - if(QUADRUPOLE==kind || DIPOLE==kind ){ - globals[NATURE_CHROMX]+=line[i]->tws(-1,DCHROMX); - globals[NATURE_CHROMY]+=line[i]->tws(-1,DCHROMY); - } - else if(SEXTUPOLE==kind){ - globals[TOTAL_K2L]+=fabs(line[i]->elem->values[K2]*line[i]->elem->values[L]); - } - line[i]->get_geometry(line[i-1]->local ,&stat); - } -} - - -int CppBeamLine::calculate(){ - double nux=0,nuy=0; - size_t kind=0; - // 考虑设置一些状态参数,当某些量改变时,状态值为true即需要重新分配空间, - // 如insert函数、四六极铁切片数改变等 - // - // - // - // - if(stat.computedrivingterms){ - if(rdtcache.cache.size()!=stat.multipoleslice){ - rdtcache.cache.resize(stat.multipoleslice); //分配四极铁六极铁切片内存空间,用于DrivingTerms计算 - cout<<"calculate: cache size : "<elem->kind; - line[i]->linearoptics(&(line[i-1]->tws[-1] ) ,&stat, globals); - if(QUADRUPOLE==kind || DIPOLE==kind ){ - globals[NATURE_CHROMX]+=line[i]->tws(-1,DCHROMX); - globals[NATURE_CHROMY]+=line[i]->tws(-1,DCHROMY); - } - else if(SEXTUPOLE==kind){ - globals[TOTAL_K2L]+=fabs(line[i]->elem->values[K2]*line[i]->elem->values[L]); - } - line[i]->get_geometry(line[i-1]->local ,&stat); - } - } - } - else{ - // nonlinearonly=True, - if(fabs(stat.Trx)>2 || fabs(stat.Trx)>2){ - if(stat.printout) cout<<"fabs(stat.Trx)>2 || fabs(stat.Trx)>2 || !stat.computedrivingterms"<2.0 || fabs(stat.Trx)>2.0 ){ - // 在非周期解或者不稳定时,退出 - cout<<"period is "<<(stat.period?"True":"False")<<", Trx: "<elem->kind; - line[i]->linearoptics(&(line[i-1]->tws[-1] ) ,&stat, globals); - if(QUADRUPOLE==kind || DIPOLE==kind ){ - globals[NATURE_CHROMX]+=line[i]->tws(-1,DCHROMX); - globals[NATURE_CHROMY]+=line[i]->tws(-1,DCHROMY); - } - else if(SEXTUPOLE==kind){ - globals[TOTAL_K2L]+=fabs(line[i]->elem->values[K2]*line[i]->elem->values[L]); - } - line[i]->get_geometry(line[i-1]->local ,&stat); - } - } - else{ - //已获得稳定周期解和光学函数,仅计算非线性元件一阶色品 - // for(int i=1;i<=length;i++){ - // line[i]->linearoptics(&(line[i-1]->tws[-1] ) ,&stat, globals); - // line[i]->get_geometry(line[i-1]->local ,&stat); - // } - globals[TOTAL_K2L]=0; - for(int i=1;i<=length;i++){ - if(line[i]->elem->kind==SEXTUPOLE){ - line[i]->linearoptics(&(line[i-1]->tws[-1] ) ,&stat, globals); - globals[TOTAL_K2L]+=fabs(line[i]->elem->values[K2]*line[i]->elem->values[L]); - } - } - for(size_t i=1;i<=length;i++){ - line[i]->get_chromaticities(&(line[i-1]->tws[-1] ) ,&stat); - } - } - } - computeGlobalProperties(); - compute_theory_touscheklifetime_part(); - // 色品计算,三阶驱动项计算 - if(stat.computedrivingterms && !stat.fast_2nd_order_RDTs && stat.period && fabs(stat.Trx)<2 && fabs(stat.Try)<2 ){ - if(stat.printout) cout<<"calculate: computmdrivingTerms_period: "< beams; - // double nux=0, nuy=0, tmp_nux=0, tmp_nuy=0; - double cosmux,cosmuy; - double tws1[TWS_NUM]={0}; - double tws2[TWS_NUM]={0}; - - double *pbeam0=beams.data(); - double *tmp_local=&line[0]->local[0]; - - beams.setIdentity(6,6); - beams*=precision; - for(int i=0;i<6;++i){ - for(int j=0;j<6;++j){ - pbeam0[6*i+j]+=line[0]->local[CODX+j]; - } - } - - double tmpnux=0,tmpnuy=0,nux=0,nuy=0,localnux=0,localnuy=0; - // if(stat.printout) cout<elem->track(pbeam0+6*i, &stat, line[j]->reverse); - for(size_t k=0;k<6;k++){ - line[j]->local[R11+6*k+i]=(pbeam0[6*i+k] - line[j]->local[CODX+k] )/precision; - } - } - propagate_twiss(tws2, tws1, &line[j]->local[R11]); - - // tmp_local=&line[j]->local[0]; - // tmp_tws[BETAX]= sqr(tmp_local[R11])*tws0[BETAX] - 2*tmp_local[R11]*tmp_local[R12]*tws0[ALPHAX] + sqr(tmp_local[R12])*tws0[GAMMAX] ; - // tmp_tws[ALPHAX]= -tmp_local[R11]*tmp_local[R21]*tws0[BETAX] - (1+2*tmp_local[R21]*tmp_local[R12])*tws0[ALPHAX] -tmp_local[R12]*tmp_local[R22]*tws0[GAMMAX] ; - - // tmp_tws[BETAY]= sqr(tmp_local[R33])*tws0[BETAY] - 2*tmp_local[R33]*tmp_local[R34]*tws0[ALPHAY] + sqr(tmp_local[R34])*tws0[GAMMAY] ; - // tmp_tws[ALPHAY]= -tmp_local[R33]*tmp_local[R43]*tws0[BETAY] - (1+2*tmp_local[R43]*tmp_local[R34])*tws0[ALPHAY] -tmp_local[R34]*tmp_local[R44]*tws0[GAMMAY] ; - - - // cosmux = (tws0[BETAX]*tmp_local[R11] - tws0[ALPHAX]*tmp_local[R12] )/sqrt(tws0[BETAX]*tmp_tws[BETAX]); - // cosmuy = (tws0[BETAY]*tmp_local[R33] - tws0[ALPHAY]*tmp_local[R34] )/sqrt(tws0[BETAY]*tmp_tws[BETAY]); - // if(fabs(cosmux-1)elem->kind ){ - if(line[j]->elem->values[DNUX]<0 || (line[j]->elem->values[DNUX]== 0.0 && tmpnux < nux) ) localnux-=1.0; - if(line[j]->elem->values[DNUY]<0 || (line[j]->elem->values[DNUY]== 0.0 && tmpnuy < nuy) ) localnuy-=1.0; - } - - // if(stat.printout) cout<local[LOCAL_NUX]=localnux; - line[j]->local[LOCAL_NUY]=localnuy; - - - // tmp_nux=(tmp_local[R12]<0? PIx2-acos(cosmux):acos(cosmux) )/PIx2; - // tmp_nuy=(tmp_local[R34]<0? PIx2-acos(cosmuy):acos(cosmuy) )/PIx2; - - // if (tmp_nuxelem->kind ){ - // if(line[j]->elem->values[DNUX]<0 ) tmp_tws[NUX]-=1.0; - // if(line[j]->elem->values[DNUY]<0 ) tmp_tws[NUY]-=1.0; - // } - // nux=tmp_nux; - // nuy=tmp_nuy; - - // // if(stat.printout) cout<<"tmp_nux: "<local[LOCAL_NUX]=tmp_tws[NUX]; - // line[j]->local[LOCAL_NUY]=tmp_tws[NUY]; - } - if(stat.printout){ - cout<<"tmp_nux: "<,6,6,RowMajor> eigenvector; - Matrix solv; - - size_t MaxIter=40; - double resume=1e10, convergence=1e-30, precision=fmin(3e-8,dp*1e-7); - double dt=0; - Matrix eye67; - Matrix beam0; - Matrix beams; - - double mux; - double muy; - - Matrix lf, eye66; - Matrix m44, eye44; - Matrix trsfmat; - Matrix xco, dco,d,tol; - Matrix b; - // double *pbeam0=beam0.data(); - double *pbeam0=beams.data(); - beam0.fill(0); - xco.fill(0); - b.fill(0); - dco.fill(0); - eye67.setIdentity(6,7); - eye44.setIdentity(4,4); - // when dp=0,precision==0,then reset precision to a small number - if(abs(precision)<1e-15){ - precision=1e-8; - } - - eye67*=precision; - - trsfmat.fill(0); - lf.fill(0); - tol.array()+=1e-30; - lf(5,4)=1e-12; - xco(5,0)=dp; - for(size_t it=0;itlocal+CODX,pbeam0+6*i,6*__SIZEOF_DOUBLE__); - line[j]->elem->track(pbeam0+6*i, &stat, line[j]->reverse); - } - } - // if(it<3) cout<<"after track"<(0,0)=trsfmat.block<4,4>(0,0); - b.head(4)=(beams.col(6)-xco).head(4); - - // if( b.array().abs().sum()local+CODX, xco.data(), 6*sizeof(double)); - for(size_t i=0;i<7;i++){ - beams.col(i)=eye67.col(i)+xco; - } - for(size_t j=1;jelem->track(pbeam0+6*i, &stat, line[j]->reverse); - } - for(size_t i=0;i<6;i++){ - trsfmat.col(i)=(beams.col(i)-beams.col(6))/precision; - } - memcpy(line[j]->local+R11, trsfmat.data(), 36*__SIZEOF_DOUBLE__); - memcpy(line[j]->local+CODX, pbeam0+36, 6*sizeof(double)); - // memcpy(line[j]->local+CODX, line[j-1]->local+CODX, 6*sizeof(double)); - - // line[j]->elem->track(line[j]->local+CODX, &stat, line[j]->reverse); - } - - - // memcpy(line[length]->local+R11, trsfmat.data(), 36*__SIZEOF_DOUBLE__); - } - else{ - if(stat.printout)cout<<"findcod: Closed orbit not found!"<tws(-1,CHROMX) ; - dQy0=line[length]->tws(-1,CHROMY); - if(chrom_corrector.iscorr1){ - for(size_t it=0;itelem->values[L]; - len_2=len*len; - len_3=len*len_2; - len_4=len*len_3; - // beta=0.5*(line[pos-1 ]->tws(-1,BETAX) + line[pos ]->tws(-1,BETAX) ); - // eta =0.5*(line[pos-1 ]->tws(-1,ETAX ) + line[pos ]->tws(-1,ETAX) ); - betax= line[pos-1 ]->tws(-1,BETAX) ; - eta = line[pos-1 ]->tws(-1,ETAX ) ; - etap = line[pos-1 ]->tws(-1,ETAPX ) ; - betay=line[pos-1 ]->tws(-1,BETAY); - // coeffx1+= chrom_corrector.coeff1[it]*eta*beta*len; - - // if(fabs(line[pos]->elem->values[K2])<1e-10 ){ - - alphax= line[pos-1 ]->tws(-1,ALPHAX) ; - alphay= line[pos-1 ]->tws(-1,ALPHAY) ; - gammax= line[pos-1 ]->tws(-1,GAMMAX) ; - gammay= line[pos-1 ]->tws(-1,GAMMAY) ; - coeffx1 += chrom_corrector.coeff1[it]*(0.25*etap*gammax*len_4 + (eta*gammax -2*etap*alphax )/3*len_3 + - 0.5*(etap*betax -2*eta*alphax )*len_2 + eta*betax*len ); - coeffy1 += chrom_corrector.coeff1[it]*(0.25*etap*gammay*len_4 + (eta*gammay -2*etap*alphay )/3*len_3 + - 0.5*(etap*betay -2*eta*alphay )*len_2 + eta*betay*len ); - // } - // else() - - // coeffx1+= line[pos-1 ]->tws(-1,DCHROMY)/line[pos-1 ]->elem->values[K2]*; - // chrom_corrector.coeff1[it]*eta*betax*len; - - // beta=0.5*(line[pos-1 ]->tws(-1,BETAY) + line[pos ]->tws(-1,BETAY) ); - // eta =0.5*(line[pos-1 ]->tws(-1,ETAX ) + line[pos ]->tws(-1,ETAX) ); - // coeffy1+= chrom_corrector.coeff1[it]*eta*betay*len; - - // coeffy1+= chrom_corrector.coeff1[it]*eta*beta*len; - } - dqx=4*PI*(chrom_corrector.aim_dQx-dQx0 ); - - } - if(chrom_corrector.iscorr2){ - for(size_t it=0;itelem->values[L]; - len_2=len*len; - len_3=len*len_2; - len_4=len*len_3; - betax= line[pos-1 ]->tws(-1,BETAX) ; - eta = line[pos-1 ]->tws(-1,ETAX ) ; - etap = line[pos-1 ]->tws(-1,ETAPX ) ; - betay=line[pos-1 ]->tws(-1,BETAY); - alphax= line[pos-1 ]->tws(-1,ALPHAX) ; - alphay= line[pos-1 ]->tws(-1,ALPHAY) ; - gammax= line[pos-1 ]->tws(-1,GAMMAX) ; - gammay= line[pos-1 ]->tws(-1,GAMMAY) ; - coeffx2 += chrom_corrector.coeff2[it]*(0.25*etap*gammax*len_4 + (eta*gammax -2*etap*alphax )/3*len_3 + - 0.5*(etap*betax -2*eta*alphax )*len_2 + eta*betax*len ); - coeffy2 += chrom_corrector.coeff2[it]*(0.25*etap*gammay*len_4 + (eta*gammay -2*etap*alphay )/3*len_3 + - 0.5*(etap*betay -2*eta*alphay )*len_2 + eta*betay*len ); - // len=line[pos ]->elem->values[L]; - // beta=0.5*(line[pos-1 ]->tws(-1,BETAX) + line[pos ]->tws(-1,BETAX) ); - // eta =0.5*(line[pos-1 ]->tws(-1,ETAX ) + line[pos ]->tws(-1,ETAX) ); - // coeffx2+= chrom_corrector.coeff2[it]*eta*beta*len; - - // beta=0.5*(line[pos-1 ]->tws(-1,BETAY) + line[pos ]->tws(-1,BETAY) ); - // eta =0.5*(line[pos-1 ]->tws(-1,ETAX ) + line[pos ]->tws(-1,ETAX) ); - // coeffy2+= chrom_corrector.coeff2[it]*eta*beta*len; - } - dqy=4*PI*(chrom_corrector.aim_dQy-dQy0 ); - - } - if(chrom_corrector.iscorr1 && chrom_corrector.iscorr2){ - d0= -coeffx1*coeffy2+coeffx2*coeffy1; - d1= -(dqx*coeffy2+dqy*coeffx2); - d2= (coeffx1*dqy+coeffy1*dqx); - if (abs(d0)<1e-10 ){ - k1=1e6; - k2=1e6; - } - else{ - k1=d1/d0; - k2=d2/d0; - } - for(size_t it=0;itelem->values[K2]+=k1*chrom_corrector.unique_coeff1[it] ; - } - for(size_t it=0;itelem->values[K2]+=k2*chrom_corrector.unique_coeff2[it] ; - } - } - else if(chrom_corrector.iscorr1 && !chrom_corrector.iscorr2){ - if(abs(coeffx1)<1e-30 ) coeffx1=1e-10; - k1=dqx/coeffx1; - for(size_t it=0;itelem->values[K2]+=k1*chrom_corrector.unique_coeff1[it] ; - } - } - else if(!chrom_corrector.iscorr1 && chrom_corrector.iscorr2){ - if(abs(coeffy2)<1e-30 ) coeffy2=1e-10; - k2= -dqy/coeffy2; - for(size_t it=0;itelem->values[K2]+=k2*chrom_corrector.unique_coeff2[it] ; - } - } - return 0; - -} - -int CppBeamLine::compute_off_momentum_twiss(double* tws, double dp, bool local_twiss=true){ - Status stat0=stat; - double dp0=stat.dp0; - double Trx,Try; - int result, result2; - double OneTurnTransferMatrixCache[6][6]; - double tws0[TWS_NUM]={0.0}; - double tws1[TWS_NUM]={0.0},tws2[TWS_NUM]={0.0}; - double cosmux=0, sinmux=0, cosmuy=0, sinmuy=0; - double *tmpM= &line[length]->local[0]; - - - fill(tws,tws+TWS_NUM,0.0); - - memcpy(OneTurnTransferMatrixCache, &line[length]->local[R11], 36*__SIZEOF_DOUBLE__ ); - memcpy(tws1, &line[0]->tws[0], TWS_NUM*__SIZEOF_DOUBLE__ ); - tws1[TWSMODE]=1; - memcpy(tws0, &line[length]->tws[0], TWS_NUM*__SIZEOF_DOUBLE__ ); - - - if(stat.period){ - tws0[NUX]=(line[length]->local[R12]>0? acos(0.5*stat.Trx):PIx2-acos(0.5*stat.Trx) )/PIx2; - tws0[NUY]=(line[length]->local[R34]>0? acos(0.5*stat.Try):PIx2-acos(0.5*stat.Try) )/PIx2; - } - else{ - tws0[NUX]= fmod( line[length]->tws(-1,NUX), 1.0); - tws0[NUY]= fmod( line[length]->tws(-1,NUY), 1.0); - } - - stat.computedrivingterms=false; - - fill(line[0]->local+CODX,line[0]->local+CODDP+1,0); - - line[0]->local[CODDP]=dp; - result=findClosedOrbit(line[0]->local+CODX ); - - if(!stat.period ){ - propagate_twiss(&tws2[0], tws1, &tmpM[R11]); - memcpy(tws,tws2,__SIZEOF_DOUBLE__*36 ); - // tws[BETAX] = tws2[BETAX] = sqr(tmpM[R11])*tws1[BETAX] - 2.0*tmpM[R11]*tmpM[R12]*tws1[ALPHAX] + sqr(tmpM[R12])*tws1[GAMMAX]; - // tws[ALPHAX]= -tmpM[R11]*tmpM[R21]*tws1[BETAX] + (1+2.0*tmpM[R12]*tmpM[R21])*tws1[ALPHAX] - tmpM[R12]*tmpM[R22]*tws1[GAMMAX]; - // // tws2[GAMMAX]= sqr(tmpM[R21])*tws1[BETAX] - 2.0*tmpM[R21]*tmpM[R22]*tws1[ALPHAX] + sqr(tmpM[R22])*tws1[GAMMAX]; - - // tws[BETAY] = tws2[BETAY] = sqr(tmpM[R33])*tws1[BETAY] - 2.0*tmpM[R33]*tmpM[R34]*tws1[ALPHAY] + sqr(tmpM[R34])*tws1[GAMMAY]; - // tws[ALPHAY]= -tmpM[R33]*tmpM[R43]*tws1[BETAY] + (1+2.0*tmpM[R34]*tmpM[R43])*tws1[ALPHAY] - tmpM[R34]*tmpM[R44]*tws1[GAMMAY]; - // // tws2[GAMMAY]= sqr(tmpM[R43])*tws1[BETAY] - 2.0*tmpM[R43]*tmpM[R44]*tws1[ALPHAY] + sqr(tmpM[R44])*tws1[GAMMAY]; - // cosmux=sqrt(tws1[BETAX]/tws2[BETAX] )*tmpM[R11]-tws1[ALPHAX]*tmpM[R12]/sqrt(tws1[BETAX]*tws2[BETAX] ); - // sinmux=tmpM[R12]/sqrt(tws1[BETAX]*tws2[BETAX] ); - // cosmuy=sqrt(tws1[BETAY]/tws2[BETAY] )*tmpM[R33]-tws1[ALPHAY]*tmpM[R34]/sqrt(tws1[BETAY]*tws2[BETAY] ); - // sinmuy=tmpM[R34]/sqrt(tws1[BETAY]*tws2[BETAY] ); - - // if(isnan(cosmux) ) cosmux=1e10; - // if(isnan(cosmuy) ) cosmuy=1e10; - - // if(fabs(cosmux-1)0? acos( cosmux ):PIx2-acos(cosmux) )/PIx2; - // tws[NUY]=( sinmuy>0? acos( cosmuy ):PIx2-acos(cosmuy) )/PIx2; - // tws[ETAX] = tmpM[R11]*line[0]->tws(0,ETAX) + tmpM[R12]*line[0]->tws(0,ETAPX) + tmpM[R16] ; - // tws[ETAPX]= tmpM[R21]*line[0]->tws(0,ETAX) + tmpM[R22]*line[0]->tws(0,ETAPX) + tmpM[R26] ; - - if(!(isnan(tws[NUX] ) || isnan(tws[NUY] )) ){ - if(local_twiss){ - compute_off_momentum_local_twiss(tws1); - tws[NUX]=line[length]->local[LOCAL_NUX]; - tws[NUY]=line[length]->local[LOCAL_NUY]; - } - } - else{ - tws[NUX]=1e10; - tws[NUY]=1e10; - return -1; - } - // if(isnan(tws[NUX] ) ){ tws[NUX]=1e10*fdim(fabs(cosmux),1); line[length]->local[LOCAL_NUX]=tws[NUX] ; } - // if(isnan(tws[NUY] ) ){ tws[NUY]=1e10*fdim(fabs(cosmuy),1); line[length]->local[LOCAL_NUY]=tws[NUY] ; } - if(stat.printout ){ - cout<<"nux: "<local[R11],tws ); - if(result2<0){ - if(result2 == -1){ - if(stat.printout)cout<<"Failed to decouple periodic transfer matrix. The linear matrix is unstable. "<tws[0], TWS_NUM*__SIZEOF_DOUBLE__); - // memcpy( line[length]->tws[-1],tws,); - // double tmpnux=0,tmpnuy=0,nux=0,nuy=0,localnux=0,localnuy=0; - // for(int i=1;ilocal[R11]); - // tmpnux=tws2[NUX]; - // tmpnuy=tws2[NUY]; - // if(isnan(tmpnux) || isnan(tmpnuy) ) break; - // if (tmpnuxelem->kind ){ - // if(line[i]->elem->values[DNUX]<0 || (line[i]->elem->values[DNUX]== 0.0 && tmpnux < nux) ) localnux-=1.0; - // if(line[i]->elem->values[DNUY]<0 || (line[i]->elem->values[DNUY]== 0.0 && tmpnuy < nuy) ) localnuy-=1.0; - // } - - // // if(stat.printout) cout<local[LOCAL_NUX]=localnux; - // line[i]->local[LOCAL_NUY]=localnuy; - // } - - if(local_twiss){ - compute_off_momentum_local_twiss(tws); - tws[NUX]=line[length]->local[LOCAL_NUX]; - tws[NUY]=line[length]->local[LOCAL_NUY]; - } - // tws[NUX]=line[length]->local[LOCAL_NUX]; - // tws[NUY]=line[length]->local[LOCAL_NUY]; - - } - if(stat.printout){ - cout<<"TWS[NUX]: "<local[LOCAL_NUX]=tws[NUX] ; } - if(isnan(tws[NUY] ) ){ tws[NUY]=1e10; line[length]->local[LOCAL_NUY]=tws[NUY] ; } - - - if(stat.printout) cout<<"Delta: "<local[CODDP]<<", nux: "<local+CODX,line[0]->local+CODDP+1,0); - line[0]->local[CODDP]=stat.dp0; - // findClosedOrbit(line[0]->local+CODX ); - for(int j=1;j<=length;j++){ - fill(line[j]->local+CODX,line[j]->local+CODDP+1,0); - // line[j]->update_TransferMatrix(line[j-1]->local, &stat); - } - - memcpy( &line[length]->local[R11],OneTurnTransferMatrixCache, 36*__SIZEOF_DOUBLE__ ); - return 0; - -} - - -int CppBeamLine::compute_large_off_momentum_tunes(double dp){ - double tws1[TWS_NUM]={0}; - double int_nux0=floor(line[length]->tws(0,NUX) ); - double int_nuy0=floor(line[length]->tws(0,NUY) ); - - if(stat.printout) cout<<"int_nux: "<tws(0,NUX) ); - double int_nuy0=floor(line[length]->tws(0,NUY) ); - double nux_bounds[2], nuy_bounds[2]; - double sum_sqr_qx=0,sum_sqr_qy=0, dpi=0, ddp; - int dprange[]={4,3,3,2,2,2,1,1,1,1 }; - int cnt=0, iloop=0; - int ngrid=10, ndiv=20; - nux_bounds[0]=0.5*floor(line[length]->tws(0,NUX)/0.5 ); - nux_bounds[1]=nux_bounds[0]+0.5; - nuy_bounds[0]=0.5*floor(line[length]->tws(0,NUY)/0.5 ); - nuy_bounds[1]=nuy_bounds[0]+0.5; - - ddp=abs(dp)/(ndiv); - dpi=0; - cnt=0; - for(iloop=0;iloopnux_bounds[1] || tws1[NUY]nuy_bounds[1] ) { - break; - } - cnt+=dprange[iloop]; - sum_sqr_qx+=dprange[iloop]*sqr(tws1[NUX]-int_nux0) ; - sum_sqr_qy+=dprange[iloop]*sqr(tws1[NUY]-int_nuy0) ; - if(stat.printout){ - cout<<"compute_off_momentum_sum_square::nux: "<nux_bounds[1] || tws1[NUY]nuy_bounds[1] ) { - break; - } - cnt+=dprange[iloop]; - sum_sqr_qx+=dprange[iloop]*sqr(tws1[NUX]-int_nux0) ; - sum_sqr_qy+=dprange[iloop]*sqr(tws1[NUY]-int_nuy0) ; - if(stat.printout){ - cout<<"compute_off_momentum_sum_square::nux: "<tws(-1,BETAX); - etaxi = line[iloop]->tws(-1,ETAX); - if(max_betax < betaxi){ - max_betax = betaxi; - max_betax_index=iloop; - } - if(max_etax < etaxi ){ - max_etax = etaxi; - max_etax_index=iloop; - } - } - } - else{ - max_betax=stat.max_betax; - max_etax=stat.max_etax; - max_betax_index=-1; - max_etax_index=-1; - } - - for(iloop=0;iloopelem->kind ) continue; - h0 = 0.5*(line[iloop]->tws(0,H0)+line[iloop]->tws(-1,H0) ) ; - - betaxi = 0.5*(line[iloop]->tws(0,BETAX)+ line[iloop]->tws(-1,BETAX) ) ; - betayi = 0.5*(line[iloop]->tws(0,BETAY)+ line[iloop]->tws(-1,BETAY) ) ; - etaxi = 0.5*(line[iloop]->tws(0,ETAX)+ line[iloop]->tws(-1,ETAX) ) ; - - sigma_xi=sqrt(betaxi*emitx +sqr(e_spread*etaxi) ); - sigma_yi=sqrt(betayi*emitx*couple ); - sigma_xpi= emitx/sigma_xi*sqrt(1+ h0*sqr(e_spread)/emitx ); - if(max_betax_index<0 || max_etax_index<0 ){ - - ax1=line[0 ]->local[AX ]; - delta_p_accept = ax1/(sqrt(h0*max_betax) + max_etax ); - } - else{ - ax1=line[max_betax_index ]->local[AX ]; - ax2=line[max_etax_index ]->local[AX ]; - delta_p_accept=fmin( ax1/(sqrt(h0*max_betax)+ line[max_betax_index]->tws(-1,ETAX) ) - ,ax2/(sqrt(h0*line[max_etax_index]->tws(-1,BETAX))+ max_etax ) ) ; - } - delta_p_accept=fmin(stat.rf_dp, delta_p_accept); - - zetai = sqr(delta_p_accept)/sqr(gamma*sigma_xpi ); - - if(stat.printout ){ - cout<<"delta_p: "<elem->values.at(L) ; - } - - globals[INV_TAU ]= inv_tau*sqr(2.81e-15)*2.99792458e8*stat.NP/(8*PI*gamma*gamma*gamma*globals[CIRCUMFERENCE ] ) ; - return 0; -} - - -int CppBeamLine::computeSecondOrderChromaticities(const double dp){ - Status stat0=stat; - double dp0=stat.dp0; - double Trx,Try; - int result; - double OneTurnTransferMatrixCache[6][6]; - double tws1[TWS_NUM],tws2[TWS_NUM]; - double cosmux=0, sinmux=0, cosmuy=0, sinmuy=0; - Matrix nux, nuy,etax, etapx, betax, betay ,alphax, alphay ,coeff_nux,coeff_nuy ; - Matrix fit_mat_x, fit_mat_y ; - double *tmpM= &line[length]->local[0]; - double i=0; - i=-3.0; - nux.fill(0); - nuy.fill(0); - fit_mat_x.fill(0); - fit_mat_y.fill(0); - memcpy(OneTurnTransferMatrixCache, &line[length]->local[R11], 36*__SIZEOF_DOUBLE__ ); - memcpy(tws1, &line[0]->tws[0], TWS_NUM*__SIZEOF_DOUBLE__ ); - if(stat.period){ - nux[2]=(line[length]->local[R12]>0? acos(0.5*stat.Trx):PIx2-acos(0.5*stat.Trx) )/PIx2; - nuy[2]=(line[length]->local[R34]>0? acos(0.5*stat.Try):PIx2-acos(0.5*stat.Try) )/PIx2; - } - else{ - nux[2]= fmod( line[length]->tws(-1,NUX), 1.0); - nuy[2]= fmod( line[length]->tws(-1,NUY), 1.0); - } - if(stat.printout) cout<tws(-1,BETAX); - alphax[2]= line[length]->tws(-1,ALPHAX); - betay[2]= line[length]->tws(-1,BETAY); - alphay[2]= line[length]->tws(-1,ALPHAY); - etax[2] = line[length]->tws(-1,ETAX); - etapx[2]= line[length]->tws(-1,ETAPX); - - stat.computedrivingterms=false; - if(stat.printout) cout<<"dp: "<local+CODX,line[0]->local+CODDP+1,0); - - line[0]->local[CODDP]=dp0+i*dp; - - for(size_t k=1;k<5;++k){ - fit_mat_x(j,k)=pow(line[0]->local[CODDP],k); - fit_mat_y(j,k)=pow(line[0]->local[CODDP],k); - } - - result=findClosedOrbit(line[0]->local+CODX ); - if(!stat.period ){ - betax[j] = tws2[BETAX] = sqr(tmpM[R11])*tws1[BETAX] - 2.0*tmpM[R11]*tmpM[R12]*tws1[ALPHAX] + sqr(tmpM[R12])*tws1[GAMMAX]; - alphax[j]= tws2[ALPHAX]= -tmpM[R11]*tmpM[R21]*tws1[BETAX] + (1+2.0*tmpM[R12]*tmpM[R21])*tws1[ALPHAX] - tmpM[R12]*tmpM[R22]*tws1[GAMMAX]; - // tws2[GAMMAX]= sqr(tmpM[R21])*tws1[BETAX] - 2.0*tmpM[R21]*tmpM[R22]*tws1[ALPHAX] + sqr(tmpM[R22])*tws1[GAMMAX]; - - betay[j] = tws2[BETAY] = sqr(tmpM[R33])*tws1[BETAY] - 2.0*tmpM[R33]*tmpM[R34]*tws1[ALPHAY] + sqr(tmpM[R34])*tws1[GAMMAY]; - alphay[j]= tws2[ALPHAY]= -tmpM[R33]*tmpM[R43]*tws1[BETAY] + (1+2.0*tmpM[R34]*tmpM[R43])*tws1[ALPHAY] - tmpM[R34]*tmpM[R44]*tws1[GAMMAY]; - // tws2[GAMMAY]= sqr(tmpM[R43])*tws1[BETAY] - 2.0*tmpM[R43]*tmpM[R44]*tws1[ALPHAY] + sqr(tmpM[R44])*tws1[GAMMAY]; - cosmux=sqrt(tws1[BETAX]/tws2[BETAX] )*tmpM[R11]-tws1[ALPHAX]*tmpM[R12]/sqrt(tws1[BETAX]*tws2[BETAX] ); - sinmux=tmpM[R12]/sqrt(tws1[BETAX]*tws2[BETAX] ); - cosmuy=sqrt(tws1[BETAY]/tws2[BETAY] )*tmpM[R33]-tws1[ALPHAY]*tmpM[R34]/sqrt(tws1[BETAY]*tws2[BETAY] ); - sinmuy=tmpM[R34]/sqrt(tws1[BETAY]*tws2[BETAY] ); - nux[j]=( sinmux>0? acos( cosmux ):PIx2-acos(cosmux) )/PIx2; - nuy[j]=( sinmuy>0? acos( cosmuy ):PIx2-acos(cosmuy) )/PIx2; - etax[j] = tmpM[R11]*line[0]->tws(0,ETAX) + tmpM[R12]*line[0]->tws(0,ETAPX) + tmpM[R16] ; - etapx[j]= tmpM[R21]*line[0]->tws(0,ETAX) + tmpM[R22]*line[0]->tws(0,ETAPX) + tmpM[R26] ; - - if(isnan(nux[j] ) ) nux[j]=10*i; - if(isnan(nuy[j] ) ) nuy[j]=10*i; - if(stat.printout ){ - cout<local[R11]+line[length]->local[R22]; - Try=line[length]->local[R33]+line[length]->local[R44]; - // cout<<"Trx: "<0? acos(0.5*Trx):PIx2-acos(0.5*Trx) )/PIx2; - nuy[j]=(tmpM[R34]>0? acos(0.5*Try):PIx2-acos(0.5*Try) )/PIx2; - sinmux = sin(PIx2*nux[j] ); //1/sin(mux); - sinmuy = sin(PIx2*nuy[j] ); //1/sin(muy); - - betax[j]= tmpM[R12]/sinmux; - betay[j]= tmpM[R34]/sinmuy; - alphax[j]= (cosmux - tmpM[R22])/sinmux; - alphay[j]= (cosmuy - tmpM[R44])/sinmuy; - etax[j] = 0.5*(tmpM[R16]*(1.0-tmpM[R22]) + tmpM[R12]*tmpM[R26])/(1.0-cosmux); - etapx[j]= 0.5*(tmpM[R26]*(1.0-tmpM[R11]) + tmpM[R21]*tmpM[R16])/(1.0-cosmux); - } - else if(fabs( Trx)<2 && fabs(Try)>=2 ){ - - cosmux = 0.5*Trx; - nux[j]=(tmpM[R12]>0? acos(0.5*Trx):PIx2-acos(0.5*Trx) )/PIx2; - sinmux = sin(PIx2*nux[j] ); //1/sin(mux); - - betax[j]= tmpM[R12]/sinmux; - alphax[j]= (cosmux - tmpM[R22])/sinmux; - etax[j] = 0.5*(tmpM[R16]*(1.0-tmpM[R22]) + tmpM[R12]*tmpM[R26])/(1.0-cosmux); - etapx[j]= 0.5*(tmpM[R26]*(1.0-tmpM[R11]) + tmpM[R21]*tmpM[R16])/(1.0-cosmux); - nuy[j]=1e4*fdim(fabs(Try), 2); - } - else if(fabs( Trx)>=2 && fabs(Try)<2 ){ - nux[j]=1e4*fdim(fabs(Trx), 2); - cosmuy = 0.5*Try; - nuy[j]=(tmpM[R34]>0? acos(0.5*Try):PIx2-acos(0.5*Try) )/PIx2; - sinmuy = sin(PIx2*nuy[j] ); //1/sin(muy); - - betay[j]= tmpM[R34]/sinmuy; - alphay[j]= (cosmuy - tmpM[R44])/sinmuy; - } - else{ - nux[j]=1e4*fdim(fabs(Trx), 2); - nuy[j]=1e4*fdim(fabs(Try), 2); - } - } - if(nux[j]-nux[2]>0.5 ){ // nux0~0.0x, nux[j]~0.9x - nux[j]-=1; - } - else if(nux[2]-nux[j]>0.5){ //nux0~0.9x, nux[j]~0.0x - nux[j]+=1; - } - if(nuy[j]-nuy[2]>0.5 ){ // nuy~0.0x, nuyj]~0.9x - nuy[j]-=1; - } - else if(nuy[2]-nuy[j]>0.5){ //nuy~0.9x, nuyj]~0.0x - nuy[j]+=1; - } - if(stat.printout) cout<<"Delta: "<local[CODDP]<<", nux: "<local+CODX,line[0]->local+CODDP+1,0); - line[0]->local[CODDP]=stat.dp0; - // findClosedOrbit(line[0]->local+CODX ); - for(int j=1;j<=length;j++){ - fill(line[j]->local+CODX,line[j]->local+CODDP+1,0); - // line[j]->update_TransferMatrix(line[j-1]->local, &stat); - } - // calculate(); - - // cout<<"TransferMatrix after calculate: "<local[R11+6*m+n]; - // } - // cout<local[R11],OneTurnTransferMatrixCache, 36*__SIZEOF_DOUBLE__ ); - if(stat.second_order_chrom || stat.third_order_chrom){ - globals[DQX]=0.5*(nux[3]-nux[1])/dp; - globals[DQY]=0.5*(nuy[3]-nuy[1])/dp; - - // globals[DQX] = 0.33333333*(nux[3]+nux[2]-2.0*nux[1])/dp; - // globals[DQY] = 0.33333333*(nuy[3]+nuy[2]-2.0*nuy[1])/dp; - - globals[D2QX]=(nux[1]+nux[3]-2*nux[2])/(2*dp*dp); - globals[D2QY]=(nuy[1]+nuy[3]-2*nuy[2])/(2*dp*dp); - globals[DETAX]=(etax[3] - etax[1])/dp ; - globals[DETAPX]=(etapx[3] - etapx[1])/dp ; - globals[DBETAX]=(betax[3] - betax[1])/dp ; - globals[DBETAY]=(betay[3] - betay[1])/dp ; - globals[DALPHAX]=(alphax[3] - alphax[1])/dp ; - globals[DALPHAY]=(alphay[3] - alphay[1])/dp ; - globals[DDBETAX]=(betax[1]+betax[3]-2*betax[2])/(2*dp*dp); - globals[DDBETAY]=(betay[1]+betay[3]-2*betay[2])/(2*dp*dp); - globals[DDETAX]=(etax[1]+etax[3]-2*etax[2])/(2*dp*dp); - - double A1X,B1X, A1Y,B1Y; - A1X= globals[DALPHAX]- alphax[2]*globals[DBETAX]/betax[2] ; - B1X= globals[DBETAX]/betax[2] ; - - A1Y= globals[DALPHAY]- alphay[2]*globals[DBETAY]/betay[2] ; - B1Y= globals[DBETAY]/betay[2] ; - - globals[WX]=sqrt( sqr(A1X) + sqr(B1X) ); - globals[WY]=sqrt( sqr(A1Y) + sqr(B1Y) ); - } - if(stat.third_order_chrom){ - Matrix tmp_fit_mat; - tmp_fit_mat=fit_mat_x.transpose(); - coeff_nux= (tmp_fit_mat*fit_mat_x).householderQr().solve(tmp_fit_mat*nux); - tmp_fit_mat=fit_mat_y.transpose(); - coeff_nuy= (tmp_fit_mat*fit_mat_y).householderQr().solve(tmp_fit_mat*nuy); - if(stat.printout){ - cout< nturn_end){ - throw std::invalid_argument("nturn_begin should no more than nturn_end!"); - } - if (0==nbegin && nend == length){/*绝大多数情况粒子从头到尾*/ } - else{ - if(nbegin0){ - if(nend>length) throw std::invalid_argument("nend should no more than length of beamline!"); - stat_no=1; - nturn0=nturn_begin+1; - nturn1=nturn_end-1; - } - else if(nbeginlength) throw std::invalid_argument("nend should no more than length of beamline!"); - stat_no=2; - first_end_pos=nend; - nturn0=nturn_begin+1; - } - else if(nbegin >nend){ - if(nbegin>length) throw std::invalid_argument("nbegin should no more than length of beamline!"); - stat_no=3; - nturn0=nturn_begin+1; - } - for(j=nbegin;jtrack(beams,&stat); - if(beams[LOSS]) break; - } - if(beams[LOSS]){ - beams[LOSSTURN]=nturn_begin; - return 0; - } - } - // 多圈,从头到尾的跟踪 - for( k=nturn0;ktrack(beams, &stat); - if(beams[LOSS]){ - if(jtrack(beams,&stat); - if(beams[LOSS]){ - beams[LOSSTURN]=nturn_end; - return 0; - } - } - break; - default: - break; - } - beams[LOSSTURN]=nturn_end+1; - return 0; -} - -double CppBeamLine::get_DA_area(double* area_datas){ - - size_t npara=stat.npara, max_machine_thread=1; - double s=0; - int alive_cnt[100]={0.0}; // maximum track lines is 100 - size_t nline=stat.track_lines, n_step=nline-1, track_turns=stat.track_turns; // - matrix beams(nline,TRK_NUM,0); // - vector max_radiuses(nline,0); // - size_t j=0,k=0; - int i=0; - - if(stat.npara<1) npara=1; - max_machine_thread=omp_get_num_procs() ; - if(stat.npara>2*max_machine_thread ){ - std::cout<<"Warning: Parallel number is too big, npara="<tws(-1,BETAX), betay1=line[0]->tws(-1,BETAY); - double cos_theta=cos(i*PI/n_step), sin_theta=sin(i*PI/n_step) ; - double mincoup=stat.mincouple ; - double p_k=0,q_k=0,n_k=0, a2_yk=1, a2_xk=1, xo_k=0, xo_begin=0; - double betax_k=0, betay_k=0; - double min_sqrt_A=1e10; - double max_radius=1; - double inv_couple=1/(1+mincoup); - double commax1=sqrt(betax1*1*inv_couple),commay1=sqrt(betay1*mincoup*inv_couple) ; - double sigmax = commax1*sqrt(globals[EMITX]), sigmay = commay1*sqrt(globals[EMITX]); - double ytol=1e-8; - for(j=1;jlocal[AX],2); - a2_yk=pow(line[j]->local[AY],2); - betax_k=line[j]->tws(-1,BETAX); - betay_k=line[j]->tws(-1,BETAY); - xo_k=line[j]->local[CODX]; - n_k=a2_yk*betax_k*(1-mincoup)+a2_xk*betay_k*mincoup; - p_k=a2_yk*fabs(xo_k)*sqrt((1-mincoup)*betax_k )/n_k; - q_k=a2_yk*(pow(xo_k,2)- a2_xk)/n_k; - min_sqrt_A=fmin(min_sqrt_A, -p_k+sqrt(pow(p_k,2)-q_k) ); - } - xo_begin=line[0]->local[CODX]; - max_radius=min_sqrt_A; - // r_step=0.1*max_radius; - omp_set_num_threads(npara); -#pragma omp parallel for - for(i=0;i=0.0 && alive_cnt[i] <5 ){ // - fill(&beams[i], &beams[i]+TRK_NUM,0); - beams(i,DP)=stat.dp0; - x=r*cos_theta*sigmax+xo_begin; - y=r*sin_theta*sigmay; - beams(i,X)=x; - beams(i,Y)=y+ ytol; - track(&beams[i],0,length,1,track_turns ); - if( !beams(i,LOSS) ){ - r-=1; - alive_cnt[i]+=1; - if(stat.printout){ cout<0){ - // r_prev=max_radiuses[i-1]; - // } - // else{ - // r_prev=max_radiuses[i]; - // } - // if(ir_local_max){ - // max_radiuses[i]=r_local_max; - // r=r_local_max; - // } - ave_r+=r; - sum_r2_i+=r*r; - if(i>0){ - normal_area+=0.5*sin(PI/n_step)*max_radiuses[i]*max_radiuses[i-1]; - } - area_datas[i]= r*cos(i*PI/n_step)*sigmax+ xo_begin ; - area_datas[nline+i]= r*sin(i*PI/n_step)*sigmay+ytol ; - } - ave_r/=nline; - sigma_r=sqrt(sum_r2_i/nline - ave_r*ave_r); - // normal_area-=0.5*n_step*PI/nline*sigma_r*sigma_r; - globals[DA]=normal_area; - globals[DA_SIGMA]=sigma_r; - return normal_area; -} - -// int CppBeamLine::paralleltrack(int np, int nturn, double* beams){ -// int npara=1, max_machine_thread=1; -// double s=0; -// if(stat.npara<1) npara=1; -// max_machine_thread=omp_get_num_procs() ; -// if(stat.npara>2*max_machine_thread ){ -// std::cout<<"Warning: Parallel number is too big, npara="<track(beams+i*TRK_NUM,&stat); -// if(beams[i*TRK_NUM+LOSS])break; -// } -// if(beams[i*TRK_NUM+LOSS]){ -// beams[i+TRK_NUM+LOSSTURN]=k+1; -// break; -// } -// memcpy(trackdata.data+(4*nturn*i+4*k) ,beams+(i*TRK_NUM), 4*sizeof(double) ); -// } -// } -// } -// else{ -// #pragma omp parallel for -// for(int i=0;itrack(beams+i*TRK_NUM,&stat); -// if(beams[i*TRK_NUM+LOSS])break; -// } -// if(beams[i*TRK_NUM+LOSS]){ -// beams[i+TRK_NUM+LOSSTURN]=k+1; -// break; -// } -// } -// } -// } -// return 0; -// } - - -#endif \ No newline at end of file diff --git a/atpy/core/physics/beamline/cppbeamline.cpp b/atpy/core/physics/beamline/cppbeamline.cpp index 1a673de..33a6f98 100644 --- a/atpy/core/physics/beamline/cppbeamline.cpp +++ b/atpy/core/physics/beamline/cppbeamline.cpp @@ -1141,15 +1141,6 @@ int CppBeamLine::compute_off_momentum_twiss(double* tws, double dp, bool local_t tws1[TWSMODE]=1; // memcpy(tws0, &line[length]->tws[0], TWS_NUM*__SIZEOF_DOUBLE__ ); - - // if(stat.period){ - // tws0[NUX]=(line[length]->local[R12]>0? acos(0.5*stat.Trx):PIx2-acos(0.5*stat.Trx) )/PIx2; - // tws0[NUY]=(line[length]->local[R34]>0? acos(0.5*stat.Try):PIx2-acos(0.5*stat.Try) )/PIx2; - // } - // else{ - // tws0[NUX]= fmod( line[length]->tws(-1,NUX), 1.0); - // tws0[NUY]= fmod( line[length]->tws(-1,NUY), 1.0); - // } // must recovery at the end fill(line[0]->local+CODX,line[0]->local+CODDP+1,0); @@ -1316,19 +1307,6 @@ int CppBeamLine::compute_off_momentum_sum_square(double dp){ prev_nux = tws1[NUX]; prev_nuy = tws1[NUY]; - // if(tws1[NUX]>1e8 && tws1[NUY]>1e8 ) break; - // if(tws1[NUX]nux_bounds[1] ) { - // sum_sqr_qx+= tws1[NUX]>9.99e5 ? tws1[NUX] : 1e4*dprange[iloop]*sqr(tws1[NUX]-int_nux0) ; - // } - // else{ - // sum_sqr_qx+=dprange[iloop]*sqr(tws1[NUX]-int_nux0) ; - // } - // if(tws1[NUY]nuy_bounds[1] ) { - // sum_sqr_qy+= tws1[NUY]>9.99e5 ? tws1[NUY] : 1e4*dprange[iloop]*sqr(tws1[NUY]-int_nuy0) ; - // } - // else{ - // sum_sqr_qy+=dprange[iloop]*sqr(tws1[NUY]-int_nuy0) ; - // } cnt+=dprange[iloop]; if(stat.printout){ cout<<"compute_off_momentum_sum_square::nux: "<elem->values.at(L) ; } @@ -1499,14 +1473,6 @@ int CppBeamLine::computeSecondOrderChromaticities(const double dp){ memcpy(OneTurnTransferMatrixCache, &line[ref_pt]->local[R11], 36*__SIZEOF_DOUBLE__ ); memcpy(tws1, &line[0]->tws[0], TWS_NUM*__SIZEOF_DOUBLE__ ); - // if(stat.period){ - // nux[2]=(line[ref_pt]->local[R12]>0? acos(0.5*stat.Trx):PIx2-acos(0.5*stat.Trx) )/PIx2; - // nuy[2]=(line[ref_pt]->local[R34]>0? acos(0.5*stat.Try):PIx2-acos(0.5*stat.Try) )/PIx2; - // } - // else{ - // nux[2]= fmod( line[ref_pt]->tws(-1,NUX), 1.0); - // nuy[2]= fmod( line[ref_pt]->tws(-1,NUY), 1.0); - // } nux[2]= line[ref_pt]->tws(-1,NUX); nuy[2]= line[ref_pt]->tws(-1,NUY); @@ -1601,9 +1567,6 @@ int CppBeamLine::computeSecondOrderChromaticities(const double dp){ globals[DBETAY]=(betay[3] - betay[1])/dp ; globals[DALPHAX]=(alphax[3] - alphax[1])/dp ; globals[DALPHAY]=(alphay[3] - alphay[1])/dp ; - globals[DDBETAX]=(betax[1]+betax[3]-2*betax[2])/(2*dp*dp); - globals[DDBETAY]=(betay[1]+betay[3]-2*betay[2])/(2*dp*dp); - globals[DDETAX]=(etax[1]+etax[3]-2*etax[2])/(2*dp*dp); double A1X,B1X, A1Y,B1Y; A1X= globals[DALPHAX]- alphax[2]*globals[DBETAX]/betax[2] ; @@ -1638,8 +1601,6 @@ int CppBeamLine::computeSecondOrderChromaticities(const double dp){ } - - int CppBeamLine::track(double* beams, size_t nbegin, size_t nend, size_t nturn_begin, size_t nturn_end ){ size_t nturn0=nturn_begin, nturn1=nturn_end; size_t stat_no=0, first_end_pos=length; @@ -1669,7 +1630,10 @@ int CppBeamLine::track(double* beams, size_t nbegin, size_t nend, size_t nturn_b } for(j=nbegin;jtrack(beams,&stat); - if(beams[LOSS]) break; + if(beams[LOSS]){ + beams[LOSSPOS] = j; + break; + } } if(beams[LOSS]){ beams[LOSSTURN]=nturn_begin; @@ -1687,6 +1651,7 @@ int CppBeamLine::track(double* beams, size_t nbegin, size_t nend, size_t nturn_b else{ beams[LOSSTURN]=k; } + beams[LOSSPOS] = j; return 0; } } @@ -1702,6 +1667,7 @@ int CppBeamLine::track(double* beams, size_t nbegin, size_t nend, size_t nturn_b line[j]->track(beams,&stat); if(beams[LOSS]){ beams[LOSSTURN]=nturn_end; + beams[LOSSPOS] = j; return 0; } } @@ -1710,6 +1676,7 @@ int CppBeamLine::track(double* beams, size_t nbegin, size_t nend, size_t nturn_b break; } beams[LOSSTURN]=nturn_end+1; + beams[LOSSPOS] = -1; return 0; } @@ -1717,6 +1684,7 @@ double CppBeamLine::get_DA_area(double* area_datas){ size_t npara=stat.npara, max_machine_thread=1; double s=0; + double c_area_datas[100][2]={0}; int alive_cnt[100]={0}; // maximum track lines is 100 size_t nline=stat.track_lines, n_step=nline-1, track_turns=stat.track_turns; // matrix beams(nline,TRK_NUM,0); // @@ -1792,21 +1760,26 @@ double CppBeamLine::get_DA_area(double* area_datas){ } } double normal_area=0, sigma_r=0, ave_r=0, sum_r2_i=0; - double r=0, r_prev=0, r_next=0, r_local_max=0; + double r=0, r_prev=0, r_next=0, r_local_max=0, r_min=1e10; + for(i=0;i0){ normal_area+=0.5*sin(PI/n_step)*max_radiuses[i]*max_radiuses[i-1]; } - area_datas[i]= r*cos(i*PI/n_step)*sigmax+ xo_begin ; - area_datas[nline+i]= r*sin(i*PI/n_step)*sigmay+ytol ; + if(area_datas != nullptr ){ + area_datas[i]= r*cos(i*PI/n_step)*sigmax+ xo_begin ; + area_datas[nline+i]= r*sin(i*PI/n_step)*sigmay+ytol ; + } } ave_r/=nline; sigma_r=sqrt(sum_r2_i/nline - ave_r*ave_r); // normal_area-=0.5*n_step*PI/nline*sigma_r*sigma_r; - globals[DA]=normal_area; + // globals[DA]=normal_area; + globals[DA]=r_min*r_min; globals[DA_SIGMA]=sigma_r; return normal_area; } @@ -1857,4 +1830,4 @@ double CppBeamLine::get_DA_area(double* area_datas){ // } -#endif \ No newline at end of file +#endif diff --git a/atpy/core/physics/beamline/cppdrivingterms2.cpp b/atpy/core/physics/beamline/cppdrivingterms2.cpp index d27f535..10773bc 100644 --- a/atpy/core/physics/beamline/cppdrivingterms2.cpp +++ b/atpy/core/physics/beamline/cppdrivingterms2.cpp @@ -1,4 +1,4 @@ -#ifndef _CPPDRIVINGTERMS2_CPP_ +#ifndef _CPPDRIVINGTERMS2_CPP_ #define _CPPDRIVINGTERMS2_CPP_ @@ -13,19 +13,6 @@ -// int SIGN(double x){ -// if (x==0){ -// return 0; -// } -// else if(x>0) -// { -// return 1; -// } -// else -// { -// return -1; -// } -// }; // 只适合周期结构中对称右半部分、且仅仅dnux_dJx, dnux_nJy, dnuy_dJx完成,其他的还需继续 @@ -86,7 +73,7 @@ void computmdrivingTerms_nonperiod(vector& bline, vectorposition, slice_pos=-1,nslice=bline[mult_pos[0] ]->elem->nslice, sext_slice_cnt=0 ; + int comp_pos_index=-1, comp_pos=bline[mult_pos[0] ]->position, slice_pos=-1,nslice=bline[mult_pos[0] ]->elem->nslice, sext_slice_cnt=0 ; for(size_t i=0;i& bline, vectorname=name; values[L]=l; values[ANGLE]=angle; @@ -385,7 +385,7 @@ int CppDipole::track(double* rin, const Status* stat, const bool reverse){ double len = values[L]; double pnorm=1/(1+dp); double angle=values[ANGLE]; - double rhoinv=angle/values[L],Gx=rhoinv; + double rhoinv=angle/values[L],h=rhoinv,Gx=rhoinv; double Fx=(rhoinv*rhoinv+values[K1])*pnorm; double Fy=-values[K1]*pnorm; @@ -440,21 +440,42 @@ int CppDipole::track(double* rin, const Status* stat, const bool reverse){ Sy=len; } + // 扇形磁铁区域 + double xpr = rin[1]*pnorm; + double ypr = rin[3]*pnorm; + double delta = rin[5]; + double ByError = 0.0; rin[0] = Cx*x + pnorm*Sx*px + pnorm*Gx*Dx*dp; rin[1] = -Fx*Sx/pnorm*x + Cx*px + Gx*Sx*dp; rin[2] = Cy*y + pnorm*Sy*py; rin[3] = -Fy*Sy/pnorm*y + Cy*py; // rin[4] = ; // rin[5] = ; + /* from AT */ + double M12 = Sx, M21=-Fx*Sx, M34 = Sy, M43=-Fy*Sy; + + rin[4]-= xpr*xpr*(len+Cx*M12)/4; + if (Fx==0.0) { + /* Do nothing */ + } + else + { + double off_err = (delta*pnorm-ByError); + rin[4]-= (len-Cx*M12)*(x*x*Fx+off_err*off_err*h*h/Fx + -2*x*h*off_err)/4; + rin[4]-= M12*M21*( x*xpr - xpr*off_err*h/Fx)/2; + rin[4]-= h*x*M12 + xpr*(1-Cx)*h/Fx + off_err*(len-M12)*h*h/Fx; + } + rin[4]-= ((len-Cy*M34)*y*y*Fy + ypr*ypr*(len+Cy*M34))/4; + rin[4]-= M34*M43*x*xpr/2; + if (0.0!=edge2) { tge2=tan(edge2); rin[1]+= rhoinv*tge2*rin[0]; rin[3]-= rhoinv*tge2*rin[2]; } - - // rin[0]=x; rin[1]=xp; rin[2]=y; rin[3]=yp; rin[4]=z; rin[5]=dp; return 0; } diff --git a/atpy/core/physics/elements/cppdrift.cpp b/atpy/core/physics/elements/cppdrift.cpp index 90c39c1..2a744cd 100644 --- a/atpy/core/physics/elements/cppdrift.cpp +++ b/atpy/core/physics/elements/cppdrift.cpp @@ -34,7 +34,7 @@ int CppDrift::track(double* rin, const Status* stat, const bool reverse){ // rin[0]+=length*rin[1]/sqrt(sqr(1/pnorm)-sqr(px)-sqr(py)); // rin[2]+=length*rin[3]/sqrt(sqr(1/pnorm)-sqr(px)-sqr(py)); // rin[4]+=length*pnorm*0.5*(rin[1]*rin[1]+rin[3]*rin[3]); - rin[4]+=(1+rin[5])*Lpnorm - length; + rin[4]-=(1+rin[5])*Lpnorm - length; return 0; } diff --git a/atpy/core/physics/elements/cppoctupole.cpp b/atpy/core/physics/elements/cppoctupole.cpp index 6e9bac3..abdaee3 100644 --- a/atpy/core/physics/elements/cppoctupole.cpp +++ b/atpy/core/physics/elements/cppoctupole.cpp @@ -161,7 +161,7 @@ int CppOctupole::_drift_track(double* rin, const double len,const Status* stat){ double pnorm=1/(1+rin[5]); rin[0]=rin[0]+len*rin[1]*pnorm; rin[2]=rin[2]+len*rin[3]*pnorm; - rin[4]+=len*pnorm*0.5*(rin[1]*rin[1]+rin[3]*rin[3]); + rin[4]-=len*pnorm*0.5*(rin[1]*rin[1]+rin[3]*rin[3]); return 0; } diff --git a/atpy/core/physics/elements/cppquadrupole.cpp b/atpy/core/physics/elements/cppquadrupole.cpp index 7f7a7f7..1391147 100644 --- a/atpy/core/physics/elements/cppquadrupole.cpp +++ b/atpy/core/physics/elements/cppquadrupole.cpp @@ -181,10 +181,20 @@ int CppQuadrupole::track(double* rin, const Status* stat, const bool reverse){ Sy=len; } + double xpr = rin[1]*pnorm; + double ypr = rin[3]*pnorm; + double delta = rin[5]; + rin[0] = Cx*x + pnorm*Sx*px ; rin[1] = -Fx*Sx/pnorm*x + Cx*px ; rin[2] = Cy*y + pnorm*Sy*py; rin[3] = -Fy*Sy/pnorm*y + Cy*py; + + double M12 = Sx, M21=-Fx*Sx, M34 = Sy, M43=-Fy*Sy; + + rin[4]-= abs(Fx)*(x*x*(len-Cx*M12)-y*y*(len-Cy*M34))/4; + rin[4]-= (xpr*xpr*(len+Cx*M12)+ypr*ypr*(len+Cy*M34))/4; + rin[4]-= (x*xpr*M12*M21 + y*ypr*M34*M43)/2; return 0; } diff --git a/atpy/core/physics/elements/cppsextupole.cpp b/atpy/core/physics/elements/cppsextupole.cpp index 4a3f81c..084524e 100644 --- a/atpy/core/physics/elements/cppsextupole.cpp +++ b/atpy/core/physics/elements/cppsextupole.cpp @@ -251,7 +251,7 @@ int CppSextupole::drift(double* rin, const double len,const Status* stat) // cout<<" CppSextupole::drift:rin[5]: "< LOCAL_DICT= {{R11, "R11"}, {R12, "R12"}, {R13, "R13"}, { {LOCAL_NUX, "local_nux"}, {LOCAL_NUY, "local_nuy"}, {S, "s"}, {GX, "Gx"}, {GY, "Gy"}, {GZ, "Gz"}, {THETAX, "thetax"}, {THETAY, "thetay"}, {THETAZ, "thetaz"}, {DX, "Dx"}, {DY, "Dy"}, {DZ, "Dz"}, {ROTATE1, "rotate1"}, {ROTATE2, "rotate2"}, - {ROTATE3, "rotate3"}, {AX, "Ax"}, {AY, "Ay"}, + {ROTATE3, "rotate3"}, {AX, "Ax"}, {AY, "Ay"}, {WX1, "Wx1"}, {WY1, "Wy1"}, {WX2, "Wx2"}, {WY2, "Wy2"}, // {LOC_NUM,"loc_num"} }; //# GLOBAL PARAMETER CODE # @@ -294,7 +295,8 @@ enum GlobalToken: uint16_t H31000, H40000, H20110, H11200, H20020, H20200, H00310, H00400, DA , DA_SIGMA , DETAX , DETAPX, DBETAX, DBETAY, DALPHAX, DALPHAY, - DDETAX, DDBETAX, DDBETAY, WX, WY, + // DDETAX, DDBETAX, DDBETAY, + WX, WY, LOW_QX ,LOW_QY, HIGH_QX ,HIGH_QY, SUM_SQR_QX, SUM_SQR_QY, INV_TAU, GLB_NUM @@ -316,7 +318,8 @@ const map GLOBALS_DICT= {{MASS0,"mass0"},{GAMMA,"gamma"},{ENERGY,"en {H31000,"H31000"}, {H40000,"H40000"}, {H20110,"H20110"}, {H11200,"H11200"}, {H20020,"H20020"}, {H20200,"H20200"}, {H00310,"H00310"}, {H00400,"H00400"}, {DA, "DA"}, {DA_SIGMA, "DA_SIGMA"}, {DETAX, "detax"} , {DETAPX, "detapx"}, {DBETAX, "dbetax"}, {DBETAY, "dbetay"}, {DALPHAX, "dalphax"}, {DALPHAY, "dalphay"}, - {DDETAX, "ddetax"}, {DDBETAX, "ddbetax"}, {DDBETAY, "ddbetay"}, {WX, "Wx"}, {WY, "Wy"}, + // {DDETAX, "ddetax"}, {DDBETAX, "ddbetax"}, {DDBETAY, "ddbetay"}, + {WX, "Wx"}, {WY, "Wy"}, {LOW_QX, "low_Qx"} ,{LOW_QY, "low_Qy"}, {HIGH_QX, "high_Qx"} ,{HIGH_QY, "high_Qy"}, {SUM_SQR_QX, "sum_sqr_Qx"}, {SUM_SQR_QY, "sum_sqr_Qy"}, {INV_TAU, "inv_tau"}, // { GLB_NUM, "glb_num"} @@ -345,4 +348,4 @@ enum { EQUIV }; -#endif \ No newline at end of file +#endif diff --git a/atpy/core/physics/utils/cppstructures.h b/atpy/core/physics/utils/cppstructures.h index 7abf385..c833e30 100644 --- a/atpy/core/physics/utils/cppstructures.h +++ b/atpy/core/physics/utils/cppstructures.h @@ -67,13 +67,13 @@ const Status STAT0={ // totalslice ,multipoleslice ,Trx ,Try ,dp0 , 0, 0, 10, 10, 0, // dp ,expand ,particle ,energy ,second_order_chrom , - 0, false,ELECTRON,2E9,false, + 4e-4, false,ELECTRON,2E9,false, // third_order_chrom ,nperiods ,printout ,transfermatrix ,mincouple , false,1,false,true,0.005, // track_lines ,track_turns ,monitor_dp, larger_monitor_dp ,fast_2nd_order_RDTs 13,100,0.01,true,1.0, false, // max_betax, max_etax, NP, rf_dp, rdt_fluctuation, local_twiss, off_momentum_rdts, off_rdts_observer, max_da_range - 0,0,50000000000, 0.02, false, false, false, 0.01, 50, -1 + 1e-6,1e-6,50000000000, 0.02, false, false, false, 0.01, 50, -1 }; /* diff --git a/atpy/utils/report.py b/atpy/utils/report.py index e23ba2f..66e3eea 100644 --- a/atpy/utils/report.py +++ b/atpy/utils/report.py @@ -82,4 +82,8 @@ def export_vars(ring,file_type="atpy"): vars_elem = [elem.str(file_type) for name,elem in ordered_elems ] for elem in vars_elem:print(elem,end="") - return vars_elem \ No newline at end of file + return vars_elem + +def twiss2dict(RING, name="END", terms=["betax","alphax","betay","alphay", "etax","etapx" ] ): + index,datas = RING[name, terms] + return { term:data for term,data in zip(terms,datas) } diff --git a/readme.md b/readme.md index 4673423..a6dbf6d 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,8 @@ -# atpy-cpp +# atpy This package is for accelerator design and optimization, working on python as a library. The core code is written in C++14, wrapped by cython. ## Install -This package depends on cmake, gcc/msvc(support c++14), cython, pymoo -1. Install Visual Studio Code, then, install the extensions of cmake and cmake tools, and build the c++ library with cmake extension. +This package depends on cmake, gcc/msvc(support c++14, linux better), cython, pymoo, matplotlib, numpy and Eigen +Pre-work: install msvc by Visual Studio 2022 生成工具(select ‘使用C++的桌面开发’ ), install +1. Install Visual Studio Code, then, install the extensions of cmake and cmake tools, and build the c++ library with cmake extension. (select your compiler, select the release mode, build the c++ project) 2. run `python setup.py bdist_wheel` in the directory, the the python package will be compiled. 3. install this package as a python library `pip install ./dist/atpy.xxx.xxx.whl`, where xxx.xxx is some information about your platform. diff --git a/user_manual/ATPY_User_Manual.ipynb b/user_manual/ATPY_User_Manual.ipynb index 0ca8df7..b2a6a6e 100644 --- a/user_manual/ATPY_User_Manual.ipynb +++ b/user_manual/ATPY_User_Manual.ipynb @@ -8,6 +8,156 @@ "# ATPY User Muanual" ] }, + { + "cell_type": "markdown", + "id": "e84f4f21", + "metadata": {}, + "source": [ + "ATPY(Accelerator Tools on PYthon)是以C++实现内核、cython作为接口、python下调用的加速器模拟工具包,主要包含以下功能:\n", + "\n", + "1. 快速计算工具\n" + ] + }, + { + "cell_type": "markdown", + "id": "a7ba6a84", + "metadata": {}, + "source": [ + "## features introduction\n", + "### parameters\n", + "#### local parameters\n", + "- element parameters(see by run `print(list(kwd_index.keys()))`)\n", + "- linear optics(twiss functions)(see by run `print(list(tws_index.keys()))`)\n", + "- resernance driving terms fluctuation(lhijmnp,where i,j,m,n,p is number)\n", + "- geometry parameters (see by run `print(list(loc_index.keys()))` )\n", + "- transfer matrix (Rij, where i,j is number between 1~6)and closed orbit(CODx,CODpx, CODy,CODpy, CODz,CODpz)\n", + "- misaligment parameters(todo)(Dx,Dy,Dz, rotate1,rotate2,rotate3)\n", + "- local Montague functions(todo)(Wx1,Wy1, Wx2, Wy2)\n", + "#### global parameters(see by run `print(list(glb_index.keys()))` )\n", + "- beam parameters, like radiation integrals(RI1~RI5), emittance, damping time, nature chromaticity, circumference,etc.\n", + "- chromaticity, 1~4 order chromaticity(dQx,dQy, d2Qx,d2Qy,d3Qx,d3Qy,d4Qx,d4Qy), by numeric defferential\n", + "- resonance driving terms\n", + "- dynmaic aperture(DA)\n", + "- 1st order Motague function (Wx,Wy) \n", + "- tune at $\\pm monitor\\_dp$ (low_Qx,low_Qy,high_Qx,high_Qy)\n", + "- $\\delta_p$ range for stable lattice(scan between $\\pm rf_dp$ ), and the rms of the valid tunes(sum_sqr_Qx, sum_sqr_Qy),\n" + ] + }, + { + "cell_type": "markdown", + "id": "fa6be033", + "metadata": {}, + "source": [ + "#### Status flags(see by run `print(default_status )`)\n", + "```\n", + "misaligment :False, (if True, misalignment will considered, but not implemented yet, so keep it False)\n", + "radiation :False, (if True, radiation will considered, but not implemented yet, so keep it False)\n", + "fluctuation :False, (if True, quantum excitation will considered, but not implemented yet, so keep it False)\n", + "fringe :False,(if True, fringe will considered, but not implemented yet, so keep it False)\n", + "edge :False,(if True, edge will considered, but this flag is not used yet, so keep it False)\n", + "lossmap :False, (if True, lossmap will considered. However, lossmap is always considered, so no matter it is False or True)\n", + "fma :False, (if True, fma will considered, but not implemented yet, so keep it False)\n", + "slice :True, (if True, slice will considered, but slice is always considered, so no matter it is False or True)\n", + "combineddipole :False, (if combined dipole is used, set combineddipole to be True)\n", + "computedrivingterms :False,\n", + "leaderordertermonly :False, (if True, only leader order terms will be considered in RDTs, but now deprecated, all RDTs calculated)\n", + "nonlineartermonly :False, (if True, only non-linear terms change in linear optics,then linear optics only change at non-linear element, may be deprecated later )\n", + "linear :True, (if True, the optics is linear optics, otherwise, it is non-linear optics, actually, linear optics is always considered)\n", + "period :True, (**if True, the lattice is periodic, otherwise, it is non-periodic**)\n", + "npara :1, (number of thread in calculate global parameter DA)\n", + "totalslice :0, (total number of slices, don't set it, it's calculated)\n", + "multipoleslice :0, (number of slices for multipoles, don't set it, it's calculated)\n", + "Trx :10.0, (horizontal trace of the transfer matrix, calculated)\n", + "Try :10.0, (vertical trace of the transfer matrix, calculated)\n", + "dp0 :0.0, (the working dp/p, 0 for on-momentum)\n", + "dp :4e-4, (the dp/p step used in numerical differentiation)\n", + "expand :False, (if True, the lattice is expanded, then every component has its independent element with the same name, parameters are copied)\n", + "particle :0, (the particle type, 0 for the electron particle, actually only electron is supported now.)\n", + "energy :2000000000.0, (the energy of the particle, in eV)\n", + "second_order_chrom :False, (if True, the 2nd order chromaticity is calculated)\n", + "third_order_chrom :False, (if True, the 2nd-4th order chromaticity is calculated)\n", + "nperiods :1, (the number of periods, used to calculate RDTs, but not used now)\n", + "printout :False, (if True, some log will be printed, then the calculation will be slow for the output stream)\n", + "transfermatrix :True, (if True, the transfer matrix will be calculated, however, transfer matrix is always calculated now)\n", + "mincouple :0.005, (the minimum coupling factor)\n", + "track_lines :13, (the number of lines to track in DA calculation)\n", + "track_turns :100, (the number of turns to track in DA calculation)\n", + "monitor_dp :0.01, (the dp/p where to monitor the tunes)\n", + "lazy_compute :True, (if True, the objective will not be computed if the constraints are not satisfied)\n", + "larger_monitor_dp :1.0, (the larger_monitor_dp*monitor_dp where to monitor the tunes)\n", + "fast_2nd_order_RDTs :False, (if True, the RDTs will be computed in a faster way)\n", + "max_betax :1e-6, (a given maximum betax function to estimate touschek lifetime)\n", + "max_etax :1e-6, (a given maximum etax function to estimate touschek lifetime)\n", + "NP :50000000000, (the number of particles in a bunch to estimate touschek lifetime)\n", + "rf_dp :0.02, ( the $\\delta_p$ range to calculate the tune of stable lattice)\n", + "rdt_fluctuation :False, (if True, RDTs fluctuation will considered, the global RDTs Hijmnp will be use to stored the mean of the lhijmnp along the lattice )\n", + "local_twiss :False, (if True, the local twiss parameters will be computed in the rf_dp)\n", + "off_momentum_rdts :False, (if True, the off-momentum RDTs will be computed)\n", + "off_rdts_observer :0.01, (the observer dp/p for the off-momentum RDTs)\n", + "max_da_range :50, (the maximum range for the DA calculation, max_da_range*$sigma_{x,y} $ )\n", + "chrom_refpt :-1 (the reference point for the chromaticity calculation)\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c96a5c8e", + "metadata": {}, + "outputs": [], + "source": [ + "#### status flags(see by run `print(default_status )`)\n", + "stat_dict= { 'misaligment': \"False, (if True, misalignment will considered, but not implemented yet, so keep it False)\",\n", + " 'radiation': \"False, (if True, radiation will considered, but not implemented yet, so keep it False)\",\n", + " 'fluctuation': \"False, (if True, quantum excitation will considered, but not implemented yet, so keep it False)\",\n", + " 'fringe': \"False,(if True, fringe will considered, but not implemented yet, so keep it False)\",\n", + " 'edge': \"False,(if True, edge will considered, but this flag is not used yet, so keep it False)\",\n", + " 'lossmap': \"False, (if True, lossmap will considered. However, lossmap is always considered, so no matter it is False or True)\",\n", + " 'fma': \"False, (if True, fma will considered, but not implemented yet, so keep it False)\",\n", + " 'slice': \"True, (if True, slice will considered, but slice is always considered, so no matter it is False or True)\",\n", + " 'combineddipole': \"False, (if combined dipole is used, set combineddipole to be True)\",\n", + " 'computedrivingterms': \"False,\",\n", + " 'leaderordertermonly': \"False, (if True, only leader order terms will be considered in RDTs, but now deprecated, all RDTs calculated)\",\n", + " 'nonlineartermonly': \"False, (if True, only non-linear terms change in linear optics,then linear optics only change at non-linear element, may be deprecated later )\",\n", + " 'linear': \"True, (if True, the optics is linear optics, otherwise, it is non-linear optics, actually, linear optics is always considered)\",\n", + " 'period': \"True, (**if True, the lattice is periodic, otherwise, it is non-periodic**)\",\n", + " 'npara': \"1, (number of thread in calculate global parameter DA)\",\n", + " 'totalslice': \"0, (total number of slices, don't set it, it's calculated)\",\n", + " 'multipoleslice': \"0, (number of slices for multipoles, don't set it, it's calculated)\",\n", + " 'Trx': \"10.0, (horizontal trace of the transfer matrix, calculated)\",\n", + " 'Try': \"10.0, (vertical trace of the transfer matrix, calculated)\",\n", + " 'dp0': \"0.0, (the working dp/p, 0 for on-momentum)\",\n", + " 'dp': \"4e-4, (the dp/p step used in numerical differentiation)\",\n", + " 'expand': \"False, (if True, the lattice is expanded, then every component has its independent element with the same name, parameters are copied)\",\n", + " 'particle': \"0, (the particle type, 0 for the electron particle, actually only electron is supported now.)\",\n", + " 'energy': \"2000000000.0, (the energy of the particle, in eV)\",\n", + " 'second_order_chrom': \"False, (if True, the 2nd order chromaticity is calculated)\",\n", + " 'third_order_chrom': \"False, (if True, the 2nd-4th order chromaticity is calculated)\",\n", + " 'nperiods': \"1, (the number of periods, used to calculate RDTs, but not used now)\",\n", + " 'printout': \"False, (if True, some log will be printed, then the calculation will be slow for the output stream)\",\n", + " 'transfermatrix': \"True, (if True, the transfer matrix will be calculated, however, transfer matrix is always calculated now)\",\n", + " 'mincouple': \"0.005, (the minimum coupling factor)\",\n", + " 'track_lines': \"13, (the number of lines to track in DA calculation)\",\n", + " 'track_turns': \"100, (the number of turns to track in DA calculation)\",\n", + " 'monitor_dp': \"0.01, (the dp/p where to monitor the tunes)\",\n", + " 'lazy_compute': \"True, (if True, the objective will not be computed if the constraints are not satisfied)\",\n", + " 'larger_monitor_dp': \"1.0, (the larger_monitor_dp*monitor_dp where to monitor the tunes)\",\n", + " 'fast_2nd_order_RDTs': \"False, (if True, the RDTs will be computed in a faster way)\",\n", + " 'max_betax': \"1e-6, (a given maximum betax function to estimate touschek lifetime)\",\n", + " 'max_etax': \"1e-6, (a given maximum etax function to estimate touschek lifetime)\",\n", + " 'NP': \"50000000000, (the number of particles in a bunch to estimate touschek lifetime)\",\n", + " 'rf_dp': \"0.02, ( the $\\delta_p$ range to calculate the tune of stable lattice)\",\n", + " 'rdt_fluctuation': \"False, (if True, RDTs fluctuation will considered, the global RDTs Hijmnp will be use to stored the mean of the lhijmnp along the lattice )\",\n", + " 'local_twiss': \"False, (if True, the local twiss parameters will be computed in the rf_dp)\",\n", + " 'off_momentum_rdts': \"False, (if True, the off-momentum RDTs will be computed)\",\n", + " 'off_rdts_observer': \"0.01, (the observer dp/p for the off-momentum RDTs)\",\n", + " 'max_da_range': \"50, (the maximum range for the DA calculation, max_da_range*$sigma_{x,y} $ )\",\n", + " 'chrom_refpt': \"-1 (the reference point for the chromaticity calculation)\"\n", + "}\n", + "for key,value in stat_dict.items():\n", + " print(f\"{key:<20} :{value}\")" + ] + }, { "cell_type": "markdown", "id": "49923033", @@ -18,7 +168,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "68a15599", "metadata": { "ExecuteTime": { @@ -34,7 +184,13 @@ "# Marker,Drift,ExactDrift, Dipole, Quadrupole, Sextupole, Octupole, Tuning\n", "# Line BeamLine\n", "# Status\n", - "# tws_index, kwd_index, loc_index, glb_index\n" + "# tws_index, kwd_index, loc_index, glb_index\n", + "from atpy import *\n", + "print(list(kwd_index.keys()))\n", + "print(list(tws_index.keys()))\n", + "print(list(loc_index.keys()))\n", + "print(list(glb_index.keys()))\n", + "print(default_status)" ] }, { @@ -47,7 +203,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "fec4be14", "metadata": { "ExecuteTime": { @@ -58,11 +214,11 @@ }, "outputs": [], "source": [ - "#-*- for folding -*-\n", + "#-*- direct definition -*-\n", "from atpy import*\n", "FM = Marker(\"FM\",)\n", "F1 = Marker(\"F1\",)\n", - "LSB2 = Drift(\"LSB2\",l=1.95227266)\n", + "LSB2 = Drift(\"LSB2\",l=1.95227266) \n", "LSB1 = Drift(\"LSB1\",l=1.46167866)\n", "LSX = Drift(\"LSX\",l=0.40000000)\n", "LSA2 = Drift(\"LSA2\",l=2.55416484)\n", @@ -77,32 +233,23 @@ "QSA1 = Quadrupole(\"QSA1\",l=0.30000000, k1=-1.70081304)\n", "QF = Quadrupole(\"QF\",l=0.30000000, k1=1.53040414)\n", "QD = Quadrupole(\"QD\",l=0.30000000, k1=-1.52453199)\n", - "SF = Sextupole(\"SF\",l=0.20000000, k2=33.88427102)\n", + "SF = Sextupole(\"SF\",l=0.20000000, k2=33.88427102) # l could be 0, which is thin lens, so is octupole\n", "SD = Sextupole(\"SD\",l=0.20000000, k2=-62.31467841)\n", - "SF1 = Sextupole(\"SF1\",l=0.20000000, k2=33.88427102)\n", - "SD1 = Sextupole(\"SD1\",l=0.20000000, k2=-62.31467841)\n", - "SF2 = Sextupole(\"SF2\",l=0.20000000, k2=33.88427102)\n", - "SD2 = Sextupole(\"SD2\",l=0.20000000, k2=-62.31467841)\n", + "TUNE01 = Tuning(\"TUNE01\",dnux=0.00000000, dnuy=0.00000000,\n", + " betax1=10,alphax1=0,betay1=1,alphay1=0,etax1=0,etapx1=0,\n", + " betax2=10,alphax2=0,betay2=1,alphay2=0,etax2=0,etapx2=0 ) # define a phase trombone, usuualy betax1=betax,betay1=betay2, ..., dnux, dnuy is tuned \n", + "# define line\n", "SUPP = Line(\"SUPP\",LSA1, QSA1, LSA2, QSA2, LSX, B1, LSX, QSA3, LSB1, QSA4, LSB2, QSA5, FM)\n", + "SUPP2 = Line(\"SUPP2\",QF, SUPP)\n", "FREEFODO = Line(\"FREEFODO\",F1, QF, LSX, DTUNE0, B1, DTUNE0, LSX, QD, LSX, DTUNE0, B1, DTUNE0, LSX)\n", - "\n", - "FODOX1 = Line(\"FODOX1\",F1, QF, LX03, SF1, LX03, DTUNE0, B1, DTUNE0, LSX, QD, LSX, DTUNE0, B1, DTUNE0, LSX)\n", - "FODOXY1 = Line(\"FODOXY1\",F1, QF, LX03, SF1, LX03, DTUNE0, B1, DTUNE0, LSX, QD, LX03, SD1, LX03, DTUNE0, B1, DTUNE0, LSX)\n", - "FODOY1 = Line(\"FODOY1\",F1, QF, LSX, DTUNE0, B1, DTUNE0, LSX, QD, LX03, SD1, LX03, DTUNE0, B1, DTUNE0, LSX)\n", - "FODOX2 = Line(\"FODOX2\",F1, QF, LX03, SF2, LX03, DTUNE0, B1, DTUNE0, LSX, QD, LSX, DTUNE0, B1, DTUNE0, LSX)\n", - "FODOXY2 = Line(\"FODOXY2\",F1, QF, LX03, SF2, LX03, DTUNE0, B1, DTUNE0, LSX, QD, LX03, SD2, LX03, DTUNE0, B1, DTUNE0, LSX)\n", - "FODOY2 = Line(\"FODOY2\",F1, QF, LSX, DTUNE0, B1, DTUNE0, LSX, QD, LX03, SD2, LX03, DTUNE0, B1, DTUNE0, LSX)\n", - "\n", - "FIVEFODO1 = Line(\"FIVEFODO1\",FODOX1, FREEFODO, FODOXY1, FREEFODO, FODOY1)\n", - "FIVEFODO2 = Line(\"FIVEFODO2\",FODOX2, FREEFODO, FODOXY2, FREEFODO, FODOY2)\n", - "ARC = Line(\"ARC\",-SUPP, FIVEFODO1,FIVEFODO2, FIVEFODO1,FIVEFODO2,FIVEFODO1,FIVEFODO2, QF, SUPP)\n", - "\n", - "\n", + "FODOXY = Line(\"FODOXY\",F1, QF, LX03, SF, LX03, DTUNE0, B1, DTUNE0, LSX, QD, LX03, SD, LX03, DTUNE0, B1, DTUNE0, LSX)\n", + "ARC = Line(\"ARC\",-SUPP, 5*FODOXY, SUPP2)\n", + "# model the lattice\n", "stat=Status( second_order_chrom=True, track_lines=9, monitor_dp=0.02, \n", " fast_2nd_order_RDTs=True, max_betax=277.56, max_etax=0.592, third_order_chrom=True, dp=0.00035, rf_dp=0.017, npara=5, \n", " computedrivingterms=True, period= True, track_turns=500 )\n", "tws0={'betax': 6.000000e-02, 'betay': 6.000000e-04}\n", - "RING=BeamLine(\"RING\",stat,FREEFODO,**tws0)" + "RING=BeamLine(\"RING\",stat,FODOXY,**tws0)" ] }, { @@ -115,7 +262,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "id": "c2833756", "metadata": { "ExecuteTime": { @@ -133,41 +280,29 @@ " from atpy import*\n", " FM = Marker()\n", " F1 = Marker()\n", - " LSB2 = Drift(l=1.95227266)\n", - " LSB1 = Drift(l=1.46167866)\n", + " LSB2 = Drift(l=1.95227266*2)\n", + " LSB1 = Drift(l=1.46167866*2)\n", " LSX = Drift(l=0.40000000)\n", - " LSA2 = Drift(l=2.55416484)\n", - " LSA1 = Drift(l=2.84837711)\n", + " LSA2 = Drift(l=2.55416484*2)\n", + " LSA1 = Drift(l=2.84837711*2)\n", " LX03 = Drift(l=0.10000000)\n", " DTUNE0 = Drift(l=0.78648950)\n", " B1 = Dipole(l=0.50670849, angle=0.03378057, k1=0.00000000, e1=0.50000000, e2=0.50000000)\n", - " QSA5 = Quadrupole(l=0.30000000, k1=-0.84186052)\n", - " QSA4 = Quadrupole(l=0.30000000, k1=1.49711117)\n", - " QSA3 = Quadrupole(l=0.30000000, k1=-1.65566620)\n", - " QSA2 = Quadrupole(l=0.30000000, k1=1.63095422)\n", - " QSA1 = Quadrupole(l=0.30000000, k1=-1.70081304)\n", + " QSA4 = Quadrupole(l=0.30000000, k1=1.49711117*2)\n", + " QSA5 = Quadrupole(l=0.30000000, k1=-0.84186052*2)\n", + " QSA3 = Quadrupole(l=0.30000000, k1=-1.65566620*2)\n", + " QSA2 = Quadrupole(l=0.30000000, k1=1.63095422*2)\n", + " QSA1 = Quadrupole(l=0.30000000, k1=-1.70081304*2)\n", " QF = Quadrupole(l=0.30000000, k1=1.53040414)\n", " QD = Quadrupole(l=0.30000000, k1=-1.52453199)\n", " SF = Sextupole(l=0.20000000, k2=33.88427102)\n", " SD = Sextupole(l=0.20000000, k2=-62.31467841)\n", - " SF1 = Sextupole(l=0.20000000, k2=33.88427102)\n", - " SD1 = Sextupole(l=0.20000000, k2=-62.31467841)\n", - " SF2 = Sextupole(l=0.20000000, k2=33.88427102)\n", - " SD2 = Sextupole(l=0.20000000, k2=-62.31467841)\n", " SUPP = Line(LSA1, QSA1, LSA2, QSA2, LSX, B1, LSX, QSA3, LSB1, QSA4, LSB2, QSA5, FM)\n", + " SUPP2 = Line(QF, SUPP)\n", " FREEFODO = Line(F1, QF, LSX, DTUNE0, B1, DTUNE0, LSX, QD, LSX, DTUNE0, B1, DTUNE0, LSX)\n", " FODOXY = Line(F1, QF, LX03, SF, LX03, DTUNE0, B1, DTUNE0, LSX, QD, LX03, SD, LX03, DTUNE0, B1, DTUNE0, LSX)\n", " \n", - " FODOX1 = Line(F1, QF, LX03, SF1, LX03, DTUNE0, B1, DTUNE0, LSX, QD, LSX, DTUNE0, B1, DTUNE0, LSX)\n", - " FODOXY1 = Line(F1, QF, LX03, SF1, LX03, DTUNE0, B1, DTUNE0, LSX, QD, LX03, SD1, LX03, DTUNE0, B1, DTUNE0, LSX)\n", - " FODOY1 = Line(F1, QF, LSX, DTUNE0, B1, DTUNE0, LSX, QD, LX03, SD1, LX03, DTUNE0, B1, DTUNE0, LSX)\n", - " FODOX2 = Line(F1, QF, LX03, SF2, LX03, DTUNE0, B1, DTUNE0, LSX, QD, LSX, DTUNE0, B1, DTUNE0, LSX)\n", - " FODOXY2 = Line(F1, QF, LX03, SF2, LX03, DTUNE0, B1, DTUNE0, LSX, QD, LX03, SD2, LX03, DTUNE0, B1, DTUNE0, LSX)\n", - " FODOY2 = Line(F1, QF, LSX, DTUNE0, B1, DTUNE0, LSX, QD, LX03, SD2, LX03, DTUNE0, B1, DTUNE0, LSX)\n", - " \n", - " FIVEFODO1 = Line(FODOX1, FREEFODO, FODOXY1, FREEFODO, FODOY1)\n", - " FIVEFODO2 = Line(FODOX2, FREEFODO, FODOXY2, FREEFODO, FODOY2)\n", - " ARC = Line(-SUPP, FIVEFODO1,FIVEFODO2, FIVEFODO1,FIVEFODO2,FIVEFODO1,FIVEFODO2, QF, SUPP)\n", + " ARC = Line(-SUPP, 5*FODOXY, SUPP2)\n", "\"\"\"\n", "\n", "from atpy import*\n", @@ -176,23 +311,88 @@ "# import the \n", "from atpy.tools.translate import*\n", "\n", + "stat=Status( second_order_chrom=True, track_lines=9, monitor_dp=0.02, \n", + " fast_2nd_order_RDTs=True, max_betax=277.56, max_etax=0.592, third_order_chrom=True, dp=0.00035, rf_dp=0.017, npara=5, \n", + " computedrivingterms=True, period= True, track_turns=500 )\n", + "\n", "tws0=dict(betax=10.34965253, alphax=-2.38935827, betay=1.963445526, alphay=0.5242721964 ,etax=0.2846300877, etapx= 0.06610030865)\n", "RING=BeamLine(\"RING\",stat,FODOXY,**tws0)" ] }, { - "cell_type": "code", - "execution_count": 34, - "id": "2818cb38", - "metadata": { - "ExecuteTime": { - "end_time": "2024-03-31T02:52:26.331987Z", - "start_time": "2024-03-31T02:52:26.315956Z" - } - }, - "outputs": [], + "cell_type": "markdown", + "id": "d567a7aa", + "metadata": {}, "source": [ - "RING?" + "## Interface" + ] + }, + { + "cell_type": "markdown", + "id": "056d87f0", + "metadata": {}, + "source": [ + "### getitem\n", + "```python\n", + "# getvaluie of Element\n", + "print(QF[\"all\"]) # one of the element parameters\n", + "# getvaluie of BeamLine\n", + "## 1 str argument\n", + "RING[\"VAR\"] # return \n", + "RING[\"CONSTRAINT\"] # return \n", + "RING[\"OPTIMIZE\"] # return \n", + "RING[\"ID\"] # return self define variables\n", + "RING[\"KWD\"] # return all the keyword name and its index\n", + "RING[\"TWS\"] # return all the twiss function name and its index\n", + "RING[\"LOC\"] # return all the local variables name and its index\n", + "RING[\"GLB\"] # return all the global variables name and its index\n", + "RING[\"STAT\"] # return current status dict\n", + "RING[\"QF\"] # return element by the given name\n", + "RING[\"emitx\"] # return the value of the global variable by the given name\n", + "## 1 int argument\n", + "RING[-1] # return the last element\n", + "## 1 slice argument\n", + "RING[:] # return all the elements\n", + "## 1 list argument\n", + "RING[[1,3,5,7]] # return the element list of the given indexes\n", + "RING[list(glb_index.keys())] # return the global list of the given names\n", + "### 2 arguments\n", + "RING[position, terms ] # position (position of elements): int/:/list of int/list of str\n", + " # terms(name of the gloabl variables ): str/list of str, the str could be the name of keywords, twiss function, and the local variables \n", + " # return: \n", + " # 1. if position refers to one position and terms refers to one name, return the value of the element, is a number ;\n", + " # 2. if position refers to one position and terms refers to a list of names, return the position list and the values of the element, list1,list2 ;\n", + " # 3. if position refers to a list of positions and terms refers to one name, return the position list and the value of the elements, list1,list2 ;\n", + " # 4. if position refers to a list of positions and terms refers to a list of names, return the position list and the values of the elements, list1, list2 ;\n", + "\n", + "\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "189b83e1", + "metadata": {}, + "source": [ + "### setitem\n", + "\n", + "```python\n", + "## 1 str argument\n", + "RING[\"dp\"]=0.00035 # set a filed of status\n", + "RING[\"VAR\"]=[[lb1,ub1],\n", + " [lb2,ub2],\n", + " [lb3,ub3],\n", + " ...\n", + " [lbn,ubn]] # reset the bounds of the variables\n", + "## 1 list argument\n", + "RING[[\"dp\",\"rf_dp\"]]=[0.00035, 0.02]# set several filed of status\n", + "## 2 argument\n", + "RING[position, terms ] = value # position (position of elements): int/:/list of int/list of str\n", + " # terms(name of the gloabl variables ): str/list of str, the str could be the name of keywords, twiss function, and the local variables \n", + " # value: float/array or list of float with the same shape of the second value in return of RING[position, terms ] \n", + "RING.parse(string) # return any values by parsing the string\n", + "\n", + "```" ] }, { @@ -224,7 +424,83 @@ "display(self,str token,bint detail=False)\n", "export(self,str filename, str filetype=\"atpy\")\n", "str(self,str filetype=\"atpy\")\n", - "```" + "```\n" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "2b209a1c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "__call__\n", + "__class__\n", + "__delattr__\n", + "__delitem__\n", + "__dir__\n", + "__eq__\n", + "__format__\n", + "__ge__\n", + "__getattribute__\n", + "__getitem__\n", + "__gt__\n", + "__hash__\n", + "__init__\n", + "__init_subclass__\n", + "__le__\n", + "__lt__\n", + "__ne__\n", + "__new__\n", + "__reduce__\n", + "__reduce_ex__\n", + "__repr__\n", + "__setattr__\n", + "__setitem__\n", + "__setstate__\n", + "__sizeof__\n", + "__str__\n", + "__subclasshook__\n", + "_save\n", + "calc\n", + "compute_large_off_momentum_tunes\n", + "compute_off_momentum_RDTs\n", + "compute_off_momentum_twiss\n", + "correctchrom\n", + "display\n", + "eval\n", + "evolution\n", + "export\n", + "findclosedorbit\n", + "get_DA_area\n", + "highorderchromaticity\n", + "optics\n", + "parse\n", + "save\n", + "set_parallel\n", + "set_worker\n", + "str\n", + "track\n", + "update_parser\n", + "Help on cython_function_or_method in module atpy.core.beamline:\n", + "\n", + "set_worker(self, index=0)\n", + " set_worker(self,Py_ssize_t index=0)\n", + " change the default worker, index <= nkernel ,then the old default worker will stored to the index worker\n", + "\n" + ] + } + ], + "source": [ + "# -*- find the method of BeamLine -*- \n", + "names= dir(BeamLine)\n", + "for name in names:\n", + "\tif callable(getattr(BeamLine,name) ):\n", + "\t\tprint(name)\n", + "help(BeamLine.set_worker)" ] }, { @@ -232,12 +508,37 @@ "id": "cc8aac35", "metadata": {}, "source": [ - "## match or optimize" + "## match or optimize\n", + " **most of the optimization and matching is done with BeamLine.parse()(more complex opertion can be done with python script)**\n", + "1. set variables\n", + "\t1. VAR,NAME= **QF[0].k1**, LOWER=**0**, UPPER=**4**,STEP=**1e-6** ; #set one variable\n", + "\t2. VAR,NAME= **\\$Q.+\\$** **[0].k1**, LOWER=**0**, UPPER=**4**,STEP=**1e-6** ; # set many varibales which names match the **Q.+**\n", + "\t3. VAR,**QF[0].l** := **2/QF[0].k1**; # binding parameters to other variables\n", + "\t4. Variable includes:\n", + "\t\t* twiss functions(only initial twiss is work with non-period lattice, not work with period latttice )\n", + "\t\t* local parameters(only initial local parameters work )\n", + "\t\t* all parameters of elements \n", + "\n", + "2. set constraint and optimization objectives\n", + "\t1. CONSTRAINT,EXPR:= **DIM(ABS(END[0].nuy-0.25),1E-4)**;\n", + "\t2. OPTIMIZE,EXPR:= **DIM(ABS(END[0].nux-0.25),1E-8)**;\n", + "\t3. the expr consists of below exprerssions:\n", + "\t\t* twiss function, local parameters (END[0].betax)\n", + "\t\t* global parameters (emitx,circumference,dQx,d2Qx)\n", + "\t\t* self defined variables ( X1:=END[0].betax/END[0].betay-3 )\n", + "\t\t* operator(+,-,*,/,**,%,//)\n", + "\t\t* functions\n", + "\t\t\t+ 1 argument: ABS(arg), SQRT(abs) ( all the expression consists of paramters, functions, operators can be argument of the functions)\n", + "\t\t\t+ 2 arguments: DIM(arg1,arg2) ( all the expression consists of paramters, functions, operators can be argument of the functions)\n", + "\t\t\t+ 3 arguments range functions: MAX(position1, position2, local/twiss), MIN(position1, position2, local/twiss), MAXABS(position1, position2, local/twiss), MINABS(position1, position2, local/twiss) \n", + "3. set chromaticity correction (set a pair of knob to correct the chromaticity to the aim value)\n", + "\t1. CHROM,AIM_DQX=**0**,KNOB=**SF**;\n", + "\t2. CHROM,AIM_DQY=**0**,KNOB=**SD**;" ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "id": "33ee1ccd", "metadata": { "ExecuteTime": { @@ -249,40 +550,17 @@ 1 ] }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "VAR total: 2 CoVar: 0\n", - "============================================================\n", - "0 :QF[0].k1 0.0 2.5\n", - "1 :QD[0].k1 -2.5 0.0\n", - "============================================================\n", - "CONSTRAINT total: 1\n", - "============================================================\n", - "0 :DIM(ABS(END[0].R11+END[0].R22),2)+DIM(ABS(END[0].R33+END[0].R44),2)\n", - "============================================================\n", - "OPTIMIZE total: 2\n", - "============================================================\n", - "0 :DIM(ABS(END[0].nux-0.25),1E-8) MINIMIZE\n", - "1 :DIM(ABS(END[0].nuy-0.25),1E-8) MINIMIZE\n", - "============================================================\n" - ] - } - ], + "outputs": [], "source": [ "#-*- for folding -*-\n", "token=\"\"\"\n", " VAR,NAME=QF[0].k1, LOWER=0, UPPER=4,STEP=1e-6 ;\n", " VAR,NAME=QD[0].k1, LOWER=-4, UPPER=0,STEP=1e-6 ;\n", " \n", - " # CONSTRAINT,EXPR:= DIM(ABS(END[0].nux-0.25),1E-4);\n", - " \n", - " # CONSTRAINT,EXPR:= DIM(ABS(END[0].nuy-0.25),1E-4);\n", + " CONSTRAINT,EXPR:= DIM(ABS(END[0].nux-0.25),1E-4);\n", + " CONSTRAINT,EXPR:= DIM(ABS(END[0].nuy-0.25),1E-4);\n", " \n", " OPTIMIZE,EXPR:= DIM(ABS(END[0].nux-0.25),1E-8);\n", - " \n", " OPTIMIZE,EXPR:= DIM(ABS(END[0].nuy-0.25),1E-8);\n", " \n", " CHROM,AIM_DQX=0,KNOB=SF;\n", @@ -314,7 +592,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "id": "0b5df0fd", "metadata": { "ExecuteTime": { @@ -323,166 +601,78 @@ }, "collapsed": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "===================================================================================================================\n", - "n_gen | n_eval | cv (min) | cv (avg) | n_nds | eps | indicator | obj (min) | obj (avg) \n", - "===================================================================================================================\n", - " 1 | 100 | 0.00000E+00 | 1.263802675 | 2 | - | - | 0.008164683 | 5.20000E+09\n", - " 2 | 200 | 0.00000E+00 | 0.093409117 | 5 | 0.060272863 | ideal | 0.002318872 | 2.90000E+09\n", - " 3 | 300 | 0.00000E+00 | 0.00000E+00 | 4 | 0.057350456 | ideal | 2.61958E-06 | 0.074087190\n", - " 4 | 400 | 0.00000E+00 | 0.00000E+00 | 7 | 0.073237054 | f | 2.61958E-06 | 0.053980813\n", - " 5 | 500 | 0.00000E+00 | 0.00000E+00 | 11 | 0.039045014 | ideal | 2.61958E-06 | 0.041632312\n", - " 6 | 600 | 0.00000E+00 | 0.00000E+00 | 9 | 0.054079124 | f | 2.61958E-06 | 0.035001443\n", - " 7 | 700 | 0.00000E+00 | 0.00000E+00 | 8 | 0.004143746 | ideal | 2.61958E-06 | 0.032142811\n", - " 8 | 800 | 0.00000E+00 | 0.00000E+00 | 9 | 0.005881833 | ideal | 2.61958E-06 | 0.030249652\n", - " 9 | 900 | 0.00000E+00 | 0.00000E+00 | 15 | 0.029750367 | f | 2.61958E-06 | 0.026380715\n", - " 10 | 1000 | 0.00000E+00 | 0.00000E+00 | 11 | 0.012744564 | f | 2.61958E-06 | 0.024046756\n", - " 11 | 1100 | 0.00000E+00 | 0.00000E+00 | 8 | 0.014205649 | f | 2.61958E-06 | 0.023841221\n", - " 12 | 1200 | 0.00000E+00 | 0.00000E+00 | 5 | 0.004657087 | f | 2.61958E-06 | 0.021686091\n", - " 13 | 1300 | 0.00000E+00 | 0.00000E+00 | 6 | 0.004388574 | f | 2.61958E-06 | 0.020975159\n", - " 14 | 1400 | 0.00000E+00 | 0.00000E+00 | 7 | 0.010277058 | f | 2.61958E-06 | 0.019543543\n", - " 15 | 1500 | 0.00000E+00 | 0.00000E+00 | 7 | 0.00000E+00 | f | 2.61958E-06 | 0.018541082\n", - " 16 | 1600 | 0.00000E+00 | 0.00000E+00 | 8 | 1.712976026 | nadir | 2.06698E-06 | 0.015682026\n", - " 17 | 1700 | 0.00000E+00 | 0.00000E+00 | 7 | 0.001695477 | f | 2.06698E-06 | 0.015163615\n", - " 18 | 1800 | 0.00000E+00 | 0.00000E+00 | 7 | 0.00000E+00 | f | 2.06698E-06 | 0.014398217\n", - " 19 | 1900 | 0.00000E+00 | 0.00000E+00 | 7 | 0.00000E+00 | f | 2.06698E-06 | 0.012771185\n", - " 20 | 2000 | 0.00000E+00 | 0.00000E+00 | 9 | 6.35482E+01 | nadir | 1.30363E-06 | 0.012438156\n", - " 21 | 2100 | 0.00000E+00 | 0.00000E+00 | 10 | 0.000015944 | f | 1.30363E-06 | 0.011547381\n", - " 22 | 2200 | 0.00000E+00 | 0.00000E+00 | 10 | 0.00000E+00 | f | 1.30363E-06 | 0.011214675\n", - " 23 | 2300 | 0.00000E+00 | 0.00000E+00 | 10 | 0.00000E+00 | f | 1.30363E-06 | 0.010990192\n", - " 24 | 2400 | 0.00000E+00 | 0.00000E+00 | 12 | 0.009358188 | f | 1.30363E-06 | 0.009440949\n", - " 25 | 2500 | 0.00000E+00 | 0.00000E+00 | 15 | 0.001742199 | f | 1.30363E-06 | 0.008745836\n", - " 26 | 2600 | 0.00000E+00 | 0.00000E+00 | 16 | 0.007338578 | f | 1.30363E-06 | 0.007559581\n", - " 27 | 2700 | 0.00000E+00 | 0.00000E+00 | 19 | 0.012822404 | f | 1.30363E-06 | 0.006507616\n", - " 28 | 2800 | 0.00000E+00 | 0.00000E+00 | 11 | 0.017897540 | f | 1.30363E-06 | 0.006459725\n", - " 29 | 2900 | 0.00000E+00 | 0.00000E+00 | 9 | 0.017967390 | f | 1.30363E-06 | 0.006345937\n", - " 30 | 3000 | 0.00000E+00 | 0.00000E+00 | 9 | 0.00000E+00 | f | 1.30363E-06 | 0.005657054\n", - " 31 | 3100 | 0.00000E+00 | 0.00000E+00 | 9 | 0.00000E+00 | f | 1.30363E-06 | 0.005558588\n", - " 32 | 3200 | 0.00000E+00 | 0.00000E+00 | 12 | 0.011939510 | f | 1.30363E-06 | 0.005458297\n", - " 33 | 3300 | 0.00000E+00 | 0.00000E+00 | 12 | 0.001753931 | f | 1.30363E-06 | 0.004779408\n", - " 34 | 3400 | 0.00000E+00 | 0.00000E+00 | 13 | 0.000025245 | f | 1.30363E-06 | 0.004214007\n", - " 35 | 3500 | 0.00000E+00 | 0.00000E+00 | 14 | 0.004518414 | f | 1.30363E-06 | 0.004069964\n", - " 36 | 3600 | 0.00000E+00 | 0.00000E+00 | 14 | 0.000120860 | f | 1.30363E-06 | 0.004135090\n", - " 37 | 3700 | 0.00000E+00 | 0.00000E+00 | 13 | 0.002291231 | f | 1.30363E-06 | 0.003625245\n", - " 38 | 3800 | 0.00000E+00 | 0.00000E+00 | 14 | 0.000129197 | f | 1.30363E-06 | 0.003642723\n", - " 39 | 3900 | 0.00000E+00 | 0.00000E+00 | 16 | 0.000464947 | f | 1.30363E-06 | 0.003383266\n", - " 40 | 4000 | 0.00000E+00 | 0.00000E+00 | 17 | 0.000168901 | f | 1.30363E-06 | 0.003424688\n", - " 41 | 4100 | 0.00000E+00 | 0.00000E+00 | 18 | 0.002005320 | f | 1.30363E-06 | 0.003290341\n", - " 42 | 4200 | 0.00000E+00 | 0.00000E+00 | 14 | 0.003674509 | f | 1.30363E-06 | 0.003310437\n", - " 43 | 4300 | 0.00000E+00 | 0.00000E+00 | 14 | 0.000715253 | f | 1.30363E-06 | 0.003040879\n", - " 44 | 4400 | 0.00000E+00 | 0.00000E+00 | 15 | 0.000475635 | f | 1.30363E-06 | 0.003021962\n", - " 45 | 4500 | 0.00000E+00 | 0.00000E+00 | 13 | 0.001821922 | f | 1.30363E-06 | 0.003101188\n", - " 46 | 4600 | 0.00000E+00 | 0.00000E+00 | 13 | 0.00000E+00 | f | 1.30363E-06 | 0.002809349\n", - " 47 | 4700 | 0.00000E+00 | 0.00000E+00 | 13 | 0.00000E+00 | f | 1.30363E-06 | 0.002917960\n", - " 48 | 4800 | 0.00000E+00 | 0.00000E+00 | 14 | 0.000156549 | f | 1.30363E-06 | 0.002989476\n", - " 49 | 4900 | 0.00000E+00 | 0.00000E+00 | 13 | 2.653548853 | nadir | 3.32857E-07 | 0.002878592\n", - " 50 | 5000 | 0.00000E+00 | 0.00000E+00 | 14 | 0.000432328 | f | 3.32857E-07 | 0.002672013\n", - " 51 | 5100 | 0.00000E+00 | 0.00000E+00 | 16 | 0.001986216 | f | 3.32857E-07 | 0.002544866\n", - " 52 | 5200 | 0.00000E+00 | 0.00000E+00 | 17 | 0.007337582 | f | 3.32857E-07 | 0.002451850\n", - " 53 | 5300 | 0.00000E+00 | 0.00000E+00 | 12 | 0.002710355 | f | 3.32857E-07 | 0.002318304\n", - " 54 | 5400 | 0.00000E+00 | 0.00000E+00 | 13 | 0.000138722 | f | 3.32857E-07 | 0.002314903\n", - " 55 | 5500 | 0.00000E+00 | 0.00000E+00 | 13 | 0.000605860 | f | 3.32857E-07 | 0.001683433\n", - " 56 | 5600 | 0.00000E+00 | 0.00000E+00 | 13 | 0.00000E+00 | f | 3.32857E-07 | 0.001557465\n", - " 57 | 5700 | 0.00000E+00 | 0.00000E+00 | 13 | 0.003623928 | f | 3.32857E-07 | 0.001391984\n", - " 58 | 5800 | 0.00000E+00 | 0.00000E+00 | 14 | 0.000503822 | f | 3.32857E-07 | 0.001307942\n", - " 59 | 5900 | 0.00000E+00 | 0.00000E+00 | 14 | 0.00000E+00 | f | 3.32857E-07 | 0.001304002\n", - " 60 | 6000 | 0.00000E+00 | 0.00000E+00 | 14 | 0.000509325 | f | 3.32857E-07 | 0.001238105\n", - " 61 | 6100 | 0.00000E+00 | 0.00000E+00 | 17 | 0.726149090 | nadir | 3.13276E-07 | 0.001257502\n", - " 62 | 6200 | 0.00000E+00 | 0.00000E+00 | 18 | 0.015955677 | nadir | 2.43430E-07 | 0.001217879\n", - " 63 | 6300 | 0.00000E+00 | 0.00000E+00 | 18 | 0.00000E+00 | f | 2.43430E-07 | 0.001165631\n", - " 64 | 6400 | 0.00000E+00 | 0.00000E+00 | 19 | 0.002892976 | f | 2.43430E-07 | 0.001026500\n", - " 65 | 6500 | 0.00000E+00 | 0.00000E+00 | 18 | 0.000185457 | f | 2.43430E-07 | 0.001033792\n", - " 66 | 6600 | 0.00000E+00 | 0.00000E+00 | 19 | 0.000018079 | f | 2.43430E-07 | 0.001029220\n", - " 67 | 6700 | 0.00000E+00 | 0.00000E+00 | 20 | 0.012352826 | f | 2.43430E-07 | 0.001007269\n", - " 68 | 6800 | 0.00000E+00 | 0.00000E+00 | 20 | 0.00000E+00 | f | 2.43430E-07 | 0.000996451\n", - " 69 | 6900 | 0.00000E+00 | 0.00000E+00 | 21 | 0.000144901 | f | 2.43430E-07 | 0.000972400\n", - " 70 | 7000 | 0.00000E+00 | 0.00000E+00 | 18 | 0.000878906 | f | 2.43430E-07 | 0.001026582\n", - " 71 | 7100 | 0.00000E+00 | 0.00000E+00 | 19 | 0.012493125 | f | 2.43430E-07 | 0.001027920\n", - " 72 | 7200 | 0.00000E+00 | 0.00000E+00 | 18 | 0.020117683 | nadir | 8.92883E-08 | 0.000938433\n", - " 73 | 7300 | 0.00000E+00 | 0.00000E+00 | 17 | 0.000155775 | f | 8.92883E-08 | 0.000919315\n", - " 74 | 7400 | 0.00000E+00 | 0.00000E+00 | 18 | 0.000049583 | f | 8.92883E-08 | 0.000878588\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " 75 | 7500 | 0.00000E+00 | 0.00000E+00 | 14 | 0.000711318 | f | 8.92883E-08 | 0.000860683\n", - " 76 | 7600 | 0.00000E+00 | 0.00000E+00 | 15 | 0.001485161 | f | 8.92883E-08 | 0.000847273\n", - " 77 | 7700 | 0.00000E+00 | 0.00000E+00 | 16 | 0.000075893 | f | 8.92883E-08 | 0.000848108\n", - " 78 | 7800 | 0.00000E+00 | 0.00000E+00 | 16 | 0.000250360 | f | 8.92883E-08 | 0.000832434\n", - " 79 | 7900 | 0.00000E+00 | 0.00000E+00 | 16 | 0.001188930 | f | 8.92883E-08 | 0.000727910\n", - " 80 | 8000 | 0.00000E+00 | 0.00000E+00 | 16 | 0.00000E+00 | f | 8.92883E-08 | 0.000670877\n", - " 81 | 8100 | 0.00000E+00 | 0.00000E+00 | 16 | 0.00000E+00 | f | 8.92883E-08 | 0.000662236\n", - " 82 | 8200 | 0.00000E+00 | 0.00000E+00 | 16 | 0.232606982 | nadir | 8.92883E-08 | 0.000739160\n", - " 83 | 8300 | 0.00000E+00 | 0.00000E+00 | 14 | 0.000422578 | f | 8.92883E-08 | 0.000735516\n", - " 84 | 8400 | 0.00000E+00 | 0.00000E+00 | 13 | 0.000072824 | f | 8.92883E-08 | 0.000726078\n", - " 85 | 8500 | 0.00000E+00 | 0.00000E+00 | 13 | 0.00000E+00 | f | 8.92883E-08 | 0.000719618\n", - " 86 | 8600 | 0.00000E+00 | 0.00000E+00 | 13 | 0.00000E+00 | f | 8.92883E-08 | 0.000717787\n", - " 87 | 8700 | 0.00000E+00 | 0.00000E+00 | 14 | 0.000011436 | f | 8.92883E-08 | 0.000714228\n", - " 88 | 8800 | 0.00000E+00 | 0.00000E+00 | 14 | 0.000246568 | f | 8.92883E-08 | 0.000653403\n", - " 89 | 8900 | 0.00000E+00 | 0.00000E+00 | 14 | 0.000316417 | f | 8.92883E-08 | 0.000638536\n", - " 90 | 9000 | 0.00000E+00 | 0.00000E+00 | 15 | 0.000429723 | f | 8.92883E-08 | 0.000712430\n", - " 91 | 9100 | 0.00000E+00 | 0.00000E+00 | 15 | 0.00000E+00 | f | 8.92883E-08 | 0.000703728\n", - " 92 | 9200 | 0.00000E+00 | 0.00000E+00 | 16 | 0.000080028 | f | 8.92883E-08 | 0.000709190\n", - " 93 | 9300 | 0.00000E+00 | 0.00000E+00 | 16 | 0.00000E+00 | f | 8.92883E-08 | 0.000627395\n", - " 94 | 9400 | 0.00000E+00 | 0.00000E+00 | 12 | 0.000567007 | f | 8.92883E-08 | 0.000666323\n", - " 95 | 9500 | 0.00000E+00 | 0.00000E+00 | 11 | 0.000231692 | f | 8.92883E-08 | 0.000665621\n", - " 96 | 9600 | 0.00000E+00 | 0.00000E+00 | 12 | 0.000083663 | f | 8.92883E-08 | 0.000672643\n", - " 97 | 9700 | 0.00000E+00 | 0.00000E+00 | 12 | 0.00000E+00 | f | 8.92883E-08 | 0.000665769\n", - " 98 | 9800 | 0.00000E+00 | 0.00000E+00 | 13 | 0.000071426 | f | 8.92883E-08 | 0.000662963\n", - " 99 | 9900 | 0.00000E+00 | 0.00000E+00 | 13 | 0.00000E+00 | f | 8.92883E-08 | 0.000654181\n", - " 100 | 10000 | 0.00000E+00 | 0.00000E+00 | 13 | 0.00000E+00 | f | 8.92883E-08 | 0.000634240\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "#-*- for folding -*-\n", "# multi-objective optimization\n", "res1,plot=optimize(RING)\n", "plot.show()\n", - "# nelder-mead optimize usually used for match, need initial value\n", + "# # nelder-mead optimize usually used for match, need initial value\n", "res = match(RING)" ] }, { "cell_type": "code", - "execution_count": 32, - "id": "64d558ca", - "metadata": { - "ExecuteTime": { - "end_time": "2024-03-31T02:50:07.082841Z", - "start_time": "2024-03-31T02:50:07.065841Z" - } - }, + "execution_count": null, + "id": "bb337bf2", + "metadata": {}, + "outputs": [], + "source": [ + "RING.save()\n", + "stat[\"period\"]=False\n", + "# stat[\"period\"]=False\n", + "tws = twiss2dict(RING) \n", + "RING2 = BeamLine(\"RING2\",stat, SUPP2, **tws)\n", + "token2 = \"\"\"VAR, NAME=$QS.*$[0].k1,LOWER=-2.64,UPPER=2.64,STEP=1e-6;\n", + " VAR, NAME=$LS.*$[0].l,LOWER=0.1,UPPER=4,STEP=1e-2;\n", + " CONSTRAINT, EXPR:=DIM(ABS(END[0].alphax),0.01)/1e-2 + DIM(ABS(END[0].alphay),0.01)/1e-2;\n", + " CONSTRAINT, EXPR:=DIM(ABS(B1[0].etax),0.001)/1e-3 +DIM(ABS(B1[0].etapx),0.001)/1e-3;\n", + " CONSTRAINT, EXPR:=DIM(2*END[0].betay,END[0].betax) +DIM(MAX(START[0],END[0], betax),30)/30 + +DIM(MAX(START[0],END[0], betay),30)/30 + DIM(circumference,10);\n", + "\n", + " OPTIMIZE, EXPR:=DIM(ABS(END[0].alphax),1e-8)/1e-8 + DIM(ABS(END[0].alphay),1e-8)/1e-8;\n", + " OPTIMIZE, EXPR:=DIM(ABS(B1[0].etax),1E-8)/1e-8 +DIM(ABS(B1[0].etapx),1E-8)/1e-8;\n", + "\"\"\"\n", + "RING2.parse(token2)\n", + "RING2.display(\"VAR\")\n", + "RING2.display(\"CONSTRAINT\")\n", + "RING2.display(\"OPTIMIZE\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "417cfeea", + "metadata": {}, "outputs": [], - "source": [] + "source": [ + "#-*- matching SUPP -*-\n", + "# multi-objective optimization\n", + "res1,plot=optimize(RING2,npop=2000)\n", + "values,lbs,ubs,_ = RING2[\"VAR\"]\n", + "bounds=[]\n", + "for value,lb,ub in zip(values,lbs,ubs):\n", + " bounds.append([max(lb,value-0.2),min(ub,value+0.2)])\n", + "# RING2[\"VAR\"]=bounds\n", + "RING2.display(\"VAR\")\n", + "# res = match(RING2, convergence=1e-10 )" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b4fe9ac9", + "metadata": {}, + "outputs": [], + "source": [ + "# useful functions in utils/report.py\n", + "export_vars(RING)\n", + "save_lattice(RING)\n", + "nonlinear_parameters(RING)\n", + "summary(RING )\n", + "display(RING)\n", + "twiss2dict(RING, name=\"END\")\n", + "layout_datas(RING)\n" + ] }, { "cell_type": "markdown", @@ -494,7 +684,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "id": "ea8142ee", "metadata": { "ExecuteTime": { @@ -502,48 +692,14 @@ "start_time": "2024-03-31T02:36:32.000433Z" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "circumference : 6.35937\n", - "energy : 2e+09\n", - "emitx : 3.37949e-09\n", - "U0 : 1.01505\n", - "alphac : 0.00208567\n", - "e_spread : 0.000442241\n", - "Qx : 0.247276\n", - "Qy : 0.25\n", - "taux : 83.584\n", - "tauy : 83.592\n", - "tauz : 41.798\n", - "dQx : 0.0\n", - "dQy : 0.0\n", - "d2Qx : 0.0\n", - "d2Qy : 0.0\n", - "nature_chromx : -0.626678\n", - "nature_chromy : -0.629882\n", - "RI1 : 0.0132636\n", - "RI2 : 0.00450408\n", - "RI3 : 0.000300272\n", - "RI4 : -4.28359e-07\n", - "RI5 : 2.59466e-06\n", - "spin : -0.92376\n", - "damp_factor : -9.51048e-05\n", - "Jx : 1.0001\n", - "Jy : 1.0\n", - "Jz : 1.9999\n" - ] - } - ], + "outputs": [], "source": [ "result1 = summary(RING,main=False)" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "id": "555e69e4", "metadata": { "ExecuteTime": { @@ -551,41 +707,22 @@ "start_time": "2024-03-31T02:36:35.058039Z" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "No. Name : s l betax alphax betay alphay etax etapx nux nuy\n", - "0 START : 0.0 nan 10.35038 -2.371824 1.968676 0.522018 0.2895522 0.06674815 0.0 0.0\n", - "1 F1 : 0.0 nan 10.35038 -2.371824 1.968676 0.522018 0.2895522 0.06674815 0.0 0.0\n", - "2 QF : 0.3 0.3 10.35038 2.371824 1.968676 -0.522018 0.2895522 -0.06674815 0.00450921 0.02491118\n", - "3 LX03 : 0.4 0.1 9.882419 2.307811 2.079543 -0.5866555 0.2828774 -0.06674815 0.006082894 0.0327803\n", - "4 SF : 0.6 0.2 8.984899 2.179786 2.34006 -0.7159305 0.2695278 -0.06674815 0.009461165 0.04722969\n", - "5 LX03 : 0.7 0.1 8.555343 2.115773 2.48971 -0.780568 0.262853 -0.06674815 0.01127649 0.05382533\n", - "6 DTUNE0 : 1.48649 0.7864895 5.623236 1.612321 4.117352 -1.288935 0.2103562 -0.06674815 0.02936223 0.09332535\n", - "7 B1 : 1.993198 0.5067085 4.153886 1.288025 5.584097 -1.604066 0.1850985 -0.03296437 0.04607597 0.1101755\n", - "8 DTUNE0 : 2.779687 0.7864895 2.523809 0.7845732 8.503053 -2.107307 0.1591723 -0.03296437 0.08512623 0.1283808\n", - "9 LSX : 3.179687 0.4 1.99857 0.5285229 10.29128 -2.36325 0.1459866 -0.03296437 0.1136243 0.1351883\n", - "10 QD : 3.479687 0.3 1.99857 -0.5285229 10.29128 2.36325 0.1459866 0.03296437 0.138161 0.1397232\n", - "11 LX03 : 3.579687 0.1 2.110676 -0.5925355 9.825024 2.299264 0.149283 0.03296437 0.1459132 0.141306\n", - "12 SD : 3.779687 0.2 2.373295 -0.7205606 8.930913 2.171292 0.1558759 0.03296437 0.1601543 0.1447044\n", - "13 LX03 : 3.879687 0.1 2.523809 -0.7845732 8.503053 2.107307 0.1591723 0.03296437 0.1666591 0.1465308\n", - "14 DTUNE0 : 4.666177 0.7864895 4.153886 -1.288025 5.584097 1.604066 0.1850985 0.03296437 0.2057094 0.164736\n", - "15 B1 : 5.172885 0.5067085 5.623236 -1.612321 4.117352 1.288935 0.2103562 0.06674815 0.2224231 0.1815862\n", - "16 DTUNE0 : 5.959375 0.7864895 8.555343 -2.115773 2.48971 0.780568 0.262853 0.06674815 0.2405089 0.2210862\n", - "17 LSX : 6.359375 0.4 10.35038 -2.371824 1.968676 0.522018 0.2895522 0.06674815 0.2472761 0.2500003\n", - "18 END : 6.359375 nan 10.35038 -2.371824 1.968676 0.522018 0.2895522 0.06674815 0.2472761 0.2500003\n" - ] - } - ], + "outputs": [], "source": [ "display(RING)" ] }, + { + "cell_type": "markdown", + "id": "6e3235fa", + "metadata": {}, + "source": [ + "### graphics " + ] + }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "id": "5028e062", "metadata": { "ExecuteTime": { @@ -593,20 +730,7 @@ "start_time": "2024-03-31T02:39:49.357087Z" } }, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "opti=OpticsPlot(RING )\n", "opti.draw([\"betax\",\"betay\",\"etax\",\"H0\"],dpi=100 )" @@ -614,7 +738,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 48, "id": "52478b9a", "metadata": { "ExecuteTime": { @@ -625,9 +749,9 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ - "
" + "
" ] }, "metadata": { @@ -638,29 +762,77 @@ ], "source": [ "layout= Layout()\n", - "# [elem_type,x,y,theta,angle,length]\n", - "kinds= [ elem[\"kind\"] for elem in RING[:] ]\n", - "datas= RING[:,[\"Gx\",\"Gy\",\"thetax\",\"angle\",\"l\"] ][1].tolist()\n", - "datas= [ [kind] + datas[i] for i, kind in enumerate(kinds)]\n", + "# list of [elem_type,x,y,theta,angle,length]\n", + "datas=layout_datas(RING)\n", "layout.add_beamline(datas)\n", - "# datas" + "RING[0,\"thetax\"]=3.1415926/2\n", + "RING.calc()\n", + "datas=layout_datas(RING)\n", + "layout.add_beamline(datas)" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "af79188b", + "cell_type": "markdown", + "id": "c9948f54", "metadata": {}, - "outputs": [], - "source": [] + "source": [ + "## Todo\n", + "1. matching with linear solve like MADX JACOBIAN method (see MADX matchjc.f90)\n", + "2. misalignment calculation\n", + "3. FMA calculation\n", + "4. tracking with radiation \n", + "5. etc." + ] }, { "cell_type": "code", "execution_count": null, - "id": "772a25df", + "id": "b7af6ed9", "metadata": {}, "outputs": [], - "source": [] + "source": [ + "# -*- JACOBIAN linear solve -*-\n", + "values,lbs0,ubs0,_ = RING2[\"VAR\"]\n", + "best_value = np.array(values )\n", + "best_G = np.array(RING2[\"CONSTRAINT\"])\n", + "best_F = np.array(RING2[\"OPTIMIZE\"])\n", + "best_conv = np.sum(best_G**2)+np.sum(best_F**2)\n", + "\n", + "for j in range(100):\n", + " values,lbs0,ubs0,_ = RING2[\"VAR\"]\n", + " # conv = np.sum(G**2)+np.sum(F**2)\n", + " # if conv<1e-10: break\n", + " # if best_conv > conv: \n", + " # best_value = np.array(values )\n", + " # best_G = G\n", + " # best_F = F\n", + "\n", + " X=np.array([values for i in range(len(values)+1) ] )\n", + "\n", + " delta = 1e-6\n", + " for i in range(len(values)):\n", + " X[i,i]+=delta\n", + "\n", + " cv = RING2[\"CONSTRAINT\"] \n", + " f = RING2[\"OPTIMIZE\"]\n", + " \n", + " G = np.array([cv for i in range(len(values)+1) ] )\n", + " F = np.array([f for i in range(len(values)+1) ] )\n", + " RING2.evolution(X,F,G )\n", + " F1 = np.concatenate((1e20*G,F),axis=1)\n", + "\n", + " F1[:-1] -= F1[-1]\n", + " F1[:-1] /= delta\n", + " A = F1[:-1].copy().transpose()\n", + " print(\"j : \",j)\n", + " print(A)\n", + " delta_X = np.linalg.lstsq( A, -F1[-1].copy() )\n", + " # delta_X\n", + " cv,obj=RING2(delta_X[0]+np.array(values))\n", + " print(\"cv : \",cv)\n", + " print(\"obj : \",obj)\n", + " if np.sum(cv**2)+np.sum(obj**2)<1e-10: break" + ] } ], "metadata": {