Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update beamloading #906

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions atintegrators/BeamLoadingCavityPass.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct elem
double Rshunt;
double Beta;
double phis;
double detune_angle;
double *vbunch;
double *vbeam_phasor;
double *vbeam;
Expand Down Expand Up @@ -82,6 +83,7 @@ void BeamLoadingCavityPass(double *r_in,int num_particles,int nbunch,
double *vbeamk = Elem->vbeam;
double *vcavk = Elem->vcav;
double *vgenk = Elem->vgen;
double detune_angle = Elem->detune_angle;
double tot_current=0.0;
int i;
size_t sz = nslice*nbunch*sizeof(double) + num_particles*sizeof(int);
Expand All @@ -103,7 +105,7 @@ void BeamLoadingCavityPass(double *r_in,int num_particles,int nbunch,
psi = vgenk[1];
}
/*Track RF cavity is always done. */
trackRFCavity(r_in,le,vgen/energy,rffreq,harmn,tlag,-psi,nturn,circumference/C0,num_particles);
trackRFCavity(r_in,le,vgen/energy,rffreq,harmn,tlag,-psi+detune_angle,nturn,circumference/C0,num_particles);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't you want detune_angle to have the same sign as psi?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. The Vgen[1] is psi, and for a main cavity in electron machines the optimum is at -ve psi, which is -ve detuning in frequency due to the -ve gradient. It is the opposite for harmonic cavities.

I prefer to keep it as an absolute delta, which is the most logical.


/*Only allocate memory if current is > 0*/
if(tot_current>0){
Expand Down Expand Up @@ -139,7 +141,7 @@ void BeamLoadingCavityPass(double *r_in,int num_particles,int nbunch,
}
}
if(cavitymode==1){
update_vgen(vbeamk,vcavk,vgenk,phasegain,voltgain);
update_vgen(vbeamk,vcavk,vgenk,phasegain,voltgain,detune_angle);
}
if(buffersize>0){
write_buffer(vbeamk, vbeam_buffer, 2, buffersize);
Expand Down Expand Up @@ -167,7 +169,7 @@ ExportMode struct elem *trackFunction(const atElem *ElemData,struct elem *Elem,
double *vbeam_buffer;
double *vbunch_buffer;
double *z_cuts;
double Energy, Frequency, TimeLag, Length;
double Energy, Frequency, TimeLag, Length, detune_angle;
double qfactor,rshunt,beta;
double *vbunch;
double *vbeam_phasor;
Expand Down Expand Up @@ -204,7 +206,8 @@ ExportMode struct elem *trackFunction(const atElem *ElemData,struct elem *Elem,
/*optional attributes*/
Energy=atGetOptionalDouble(ElemData,"Energy",Param->energy); check_error();
z_cuts=atGetOptionalDoubleArray(ElemData,"ZCuts"); check_error();

detune_angle=atGetOptionalDouble(ElemData,"detune_angle", 0); check_error();

int dimsth[] = {Param->nbunch*nslice*nturns, 4};
atCheckArrayDims(ElemData,"_turnhistory", 2, dimsth); check_error();
int dimsvb[] = {Param->nbunch, 2};
Expand Down Expand Up @@ -238,6 +241,7 @@ ExportMode struct elem *trackFunction(const atElem *ElemData,struct elem *Elem,
Elem->vgen_buffer = vgen_buffer;
Elem->vbeam_buffer = vbeam_buffer;
Elem->vbunch_buffer = vbunch_buffer;
Elem->detune_angle = detune_angle;
}
energy = atEnergy(Param->energy, Elem->Energy);

Expand Down Expand Up @@ -283,7 +287,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
double normfact, phasegain, voltgain;
double *turnhistory;
double *z_cuts;
double Energy, Frequency, TimeLag, Length;
double Energy, Frequency, TimeLag, Length, detune_angle;
double qfactor,rshunt,beta;
double *vbunch;
double *vbeam_phasor;
Expand Down Expand Up @@ -322,7 +326,8 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
/*optional attributes*/
Energy=atGetOptionalDouble(ElemData,"Energy",0.0); check_error();
z_cuts=atGetOptionalDoubleArray(ElemData,"ZCuts"); check_error();

detune_angle=atGetOptionalDouble(ElemData,"detune_angle",0.0); check_error();

Elem = (struct elem*)atMalloc(sizeof(struct elem));
Elem->Length=Length;
Elem->blmode=blmode;
Expand Down Expand Up @@ -350,6 +355,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Elem->vgen_buffer = vgen_buffer;
Elem->vbeam_buffer = vbeam_buffer;
Elem->vbunch_buffer = vbunch_buffer;
Elem->detune_angle = detune_angle;
if (nrhs > 2) atProperties(prhs[2], &Energy, &rest_energy, &charge);

if (mxGetM(prhs[1]) != 6) mexErrMsgIdAndTxt("AT:WrongArg","Second argument must be a 6 x N matrix");
Expand Down Expand Up @@ -390,9 +396,10 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
mxSetCell(plhs[0],23,mxCreateString("_buffersize"));
if(nlhs>1) /* optional fields */
{
plhs[1] = mxCreateCellMatrix(2,1);
plhs[1] = mxCreateCellMatrix(3,1);
mxSetCell(plhs[1],0,mxCreateString("TimeLag"));
mxSetCell(plhs[0],1,mxCreateString("ZCuts"));
mxSetCell(plhs[1],1,mxCreateString("ZCuts"));
mxSetCell(plhs[1],2,mxCreateString("detune_angle"));
}
}
else
Expand Down
4 changes: 2 additions & 2 deletions atintegrators/atimplib.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,15 +451,15 @@ static void compute_kicks_phasor(int nslice, int nbunch, int nturns, double *tur
};


static void update_vgen(double *vbeam,double *vcav,double *vgen,double voltgain,double phasegain){
static void update_vgen(double *vbeam,double *vcav,double *vgen,double voltgain,double phasegain,double detune_angle){
double vbeamr = vbeam[0]*cos(vbeam[1]);
double vbeami = vbeam[0]*sin(vbeam[1]);
double vcavr = vcav[0]*cos(vcav[1]);
double vcavi = vcav[0]*sin(vcav[1]);
double vgenr = vcavr - vbeamr;
double vgeni = vcavi - vbeami;
double vga = sqrt(vgenr*vgenr+vgeni*vgeni);
double vgp = atan2(vgeni,vgenr)-vcav[1];
double vgp = atan2(vgeni,vgenr)-vcav[1]+detune_angle;
vgen[0] += (vga-vgen[0])*voltgain;
vgen[1] += (vgp-vgen[1])*phasegain;
}
2 changes: 1 addition & 1 deletion atmat/atmexall.m
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ function atmexall(varargin)
compile(compargs, pmeth);
catch errcomp
if fail
rethrow(err);
rethrow(errcomp);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this to be fixed in another PR then? Maybe you should start with this?

else
fprintf(2, 'Could not compile %s:\n%s\n', pmeth, errcomp.message);
end
Expand Down
6 changes: 4 additions & 2 deletions pyat/at/collective/beam_loading.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ def __init__(self, family_name: str, length: float, voltage: float,
cavitymode (CavityMode): Is cavity ACTIVE (default) or PASSIVE
buffersize (int): Size of the history buffer for vbeam, vgen, vbunch
(default 0)
detune_angle: Fixed detuning from optimal tuning angle. [rad]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should you describe the sign convention here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may want to add this in the docstring of add_beamloading function as well no?


Returns:
bl_elem (Element): beam loading element
"""
Expand All @@ -165,9 +167,9 @@ def __init__(self, family_name: str, length: float, voltage: float,
raise TypeError('cavitymode has to be an ' +
'instance of CavityMode')
zcuts = kwargs.pop('ZCuts', None)
phil = kwargs.pop('phil', 0)
energy = ring.energy
harmonic_number = numpy.round(frequency*ring.circumference/clight)
self.detune_angle = kwargs.pop('detune_angle', 0)
self.Rshunt = rshunt
self.Qfactor = qfactor
self.NormFact = kwargs.pop('NormFact', 1.0)
Expand Down Expand Up @@ -199,7 +201,7 @@ def __init__(self, family_name: str, length: float, voltage: float,
self._vbeam = numpy.zeros(2)
self._vgen = numpy.zeros(2)
self._vcav = numpy.array([self.Voltage,
numpy.pi/2-self._phis-phil])
numpy.pi/2-self._phis])
self.clear_history(ring=ring)

def is_compatible(self, other):
Expand Down