Skip to content

Commit 2dff0a6

Browse files
committed
add M66Rad passmethod
1 parent 9b0784f commit 2dff0a6

File tree

3 files changed

+104
-6
lines changed

3 files changed

+104
-6
lines changed

atintegrators/Matrix66RadPass.c

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#include "atelem.c"
2+
#include "atlalib.c"
3+
4+
struct elem
5+
{
6+
double *M66;
7+
/* optional fields */
8+
double *R1;
9+
double *R2;
10+
double *T1;
11+
double *T2;
12+
};
13+
14+
void Matrix66RadPass(double *r, const double *M,
15+
const double *T1, const double *T2,
16+
const double *R1, const double *R2, int num_particles)
17+
{
18+
double *r6;
19+
int c;
20+
for (c = 0; c<num_particles; c++) { /*Loop over particles */
21+
r6 = r+c*6;
22+
if (!atIsNaN(r6[0])) {
23+
if (T1 != NULL) ATaddvv(r6, T1);
24+
if (R1 != NULL) ATmultmv(r6, R1);
25+
ATmultmv(r6, M);
26+
if (R2 != NULL) ATmultmv(r6, R2);
27+
if (T2 != NULL) ATaddvv(r6, T2);
28+
}
29+
}
30+
}
31+
32+
#if defined(MATLAB_MEX_FILE) || defined(PYAT)
33+
ExportMode struct elem *trackFunction(const atElem *ElemData,struct elem *Elem,
34+
double *r_in, int num_particles, struct parameters *Param)
35+
{
36+
if (!Elem) {
37+
double *M66;
38+
double *R1, *R2, *T1, *T2;
39+
M66=atGetDoubleArray(ElemData,"M66Rad"); check_error();
40+
/*optional fields*/
41+
R1=atGetOptionalDoubleArray(ElemData,"R1"); check_error();
42+
R2=atGetOptionalDoubleArray(ElemData,"R2"); check_error();
43+
T1=atGetOptionalDoubleArray(ElemData,"T1"); check_error();
44+
T2=atGetOptionalDoubleArray(ElemData,"T2"); check_error();
45+
Elem = (struct elem*)atMalloc(sizeof(struct elem));
46+
Elem->M66=M66;
47+
/*optional fields*/
48+
Elem->R1=R1;
49+
Elem->R2=R2;
50+
Elem->T1=T1;
51+
Elem->T2=T2;
52+
}
53+
Matrix66RadPass(r_in, Elem->M66, Elem->T1, Elem->T2, Elem->R1, Elem->R2, num_particles);
54+
return Elem;
55+
}
56+
MODULE_DEF(Matrix66RadPass) /* Dummy module initialisation */
57+
58+
#endif /*defined(MATLAB_MEX_FILE) || defined(PYAT)*/
59+
60+
#if defined(MATLAB_MEX_FILE)
61+
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
62+
{
63+
if (nrhs >= 2) {
64+
double *r_in;
65+
const mxArray *ElemData = prhs[0];
66+
int num_particles = mxGetN(prhs[1]);
67+
double *M66, *R1, *R2, *T1, *T2;
68+
M66=atGetDoubleArray(ElemData,"M66Rad"); check_error();
69+
/*optional fields*/
70+
R1=atGetOptionalDoubleArray(ElemData,"R1"); check_error();
71+
R2=atGetOptionalDoubleArray(ElemData,"R2"); check_error();
72+
T1=atGetOptionalDoubleArray(ElemData,"T1"); check_error();
73+
T2=atGetOptionalDoubleArray(ElemData,"T2"); check_error();
74+
75+
/* ALLOCATE memory for the output array of the same size as the input */
76+
plhs[0] = mxDuplicateArray(prhs[1]);
77+
r_in = mxGetDoubles(plhs[0]);
78+
Matrix66RadPass(r_in, M66, T1, T2, R1, R2, num_particles);
79+
}
80+
else if (nrhs == 0) {
81+
/* list of required fields */
82+
plhs[0] = mxCreateCellMatrix(1,1);
83+
mxSetCell(plhs[0],0,mxCreateString("M66Rad"));
84+
if (nlhs>1) {
85+
/* list of optional fields */
86+
plhs[1] = mxCreateCellMatrix(4,1);
87+
mxSetCell(plhs[1], 0,mxCreateString("T1"));
88+
mxSetCell(plhs[1], 1,mxCreateString("T2"));
89+
mxSetCell(plhs[1], 2,mxCreateString("R1"));
90+
mxSetCell(plhs[1], 3,mxCreateString("R2"));
91+
}
92+
}
93+
else {
94+
mexErrMsgIdAndTxt("AT:WrongArg","Needs 0 or 2 arguments");
95+
}
96+
}
97+
#endif /*MATLAB_MEX_FILE*/

pyat/at/lattice/elements/basic_elements.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -443,25 +443,30 @@ def set_longt_motion(self, enable, new_pass=None, **kwargs):
443443
return super().set_longt_motion(enable, new_pass=new_pass, **kwargs)
444444

445445

446-
class M66(Element):
446+
class M66(Radiative, Element):
447447
"""Linear (6, 6) transfer matrix."""
448448

449449
_BUILD_ATTRIBUTES = [*Element._BUILD_ATTRIBUTES, "M66"]
450450
_conversions = dict(Element._conversions, M66=_array66)
451451
_file_classname = "Matrix66"
452452

453-
def __init__(self, family_name: str, m66=None, **kwargs):
453+
def __init__(self, family_name: str, m66=None, m66rad=None, **kwargs):
454454
"""
455455
Args:
456456
family_name: Name of the element
457457
m66: Transfer matrix. Default: Identity matrix.
458+
m66rad: Transfer matrix including radiation. Default: Identity matrix.
459+
458460
459461
Default PassMethod: ``Matrix66Pass``
460462
"""
461463
if m66 is None:
462464
m66 = np.identity(6)
465+
if m66rad is None:
466+
m66rad = np.identity(6)
463467
kwargs.setdefault("PassMethod", "Matrix66Pass")
464468
kwargs.setdefault("M66", m66)
469+
kwargs.setdefault("M66Rad", m66rad)
465470
super().__init__(family_name, **kwargs)
466471

467472

pyat/at/physics/matrix.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,6 @@ def find_m66(ring: Lattice, refpts: Refpts = None,
109109
:py:func:`find_m66` finds the 6x6 transfer matrix of an accelerator
110110
lattice by differentiation of trajectories near the closed orbit.
111111
112-
:py:func:`find_m66` uses :py:func:`.find_orbit6` to search for the closed
113-
orbit in 6-D. In order for this to work the ring **MUST** have a ``Cavity``
114-
element
115-
116112
Parameters:
117113
ring: Lattice description
118114
refpts: Observation points

0 commit comments

Comments
 (0)