xcoll 0.3.5__py3-none-any.whl → 0.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. xcoll/__init__.py +12 -4
  2. xcoll/beam_elements/__init__.py +7 -5
  3. xcoll/beam_elements/absorber.py +41 -7
  4. xcoll/beam_elements/base.py +1161 -244
  5. xcoll/beam_elements/collimators_src/black_absorber.h +118 -0
  6. xcoll/beam_elements/collimators_src/black_crystal.h +111 -0
  7. xcoll/beam_elements/collimators_src/everest_block.h +40 -28
  8. xcoll/beam_elements/collimators_src/everest_collimator.h +129 -50
  9. xcoll/beam_elements/collimators_src/everest_crystal.h +217 -73
  10. xcoll/beam_elements/everest.py +60 -113
  11. xcoll/colldb.py +250 -750
  12. xcoll/general.py +2 -2
  13. xcoll/headers/checks.h +1 -1
  14. xcoll/headers/particle_states.h +2 -2
  15. xcoll/initial_distribution.py +195 -0
  16. xcoll/install.py +177 -0
  17. xcoll/interaction_record/__init__.py +1 -0
  18. xcoll/interaction_record/interaction_record.py +252 -0
  19. xcoll/interaction_record/interaction_record_src/interaction_record.h +98 -0
  20. xcoll/{impacts → interaction_record}/interaction_types.py +11 -4
  21. xcoll/line_tools.py +83 -0
  22. xcoll/lossmap.py +209 -0
  23. xcoll/manager.py +2 -937
  24. xcoll/rf_sweep.py +1 -1
  25. xcoll/scattering_routines/everest/amorphous.h +239 -0
  26. xcoll/scattering_routines/everest/channeling.h +245 -0
  27. xcoll/scattering_routines/everest/crystal_parameters.h +137 -0
  28. xcoll/scattering_routines/everest/everest.h +8 -30
  29. xcoll/scattering_routines/everest/everest.py +13 -10
  30. xcoll/scattering_routines/everest/jaw.h +27 -197
  31. xcoll/scattering_routines/everest/materials.py +2 -0
  32. xcoll/scattering_routines/everest/multiple_coulomb_scattering.h +31 -10
  33. xcoll/scattering_routines/everest/nuclear_interaction.h +86 -0
  34. xcoll/scattering_routines/geometry/__init__.py +6 -0
  35. xcoll/scattering_routines/geometry/collimator_geometry.h +219 -0
  36. xcoll/scattering_routines/geometry/crystal_geometry.h +150 -0
  37. xcoll/scattering_routines/geometry/geometry.py +26 -0
  38. xcoll/scattering_routines/geometry/get_s.h +92 -0
  39. xcoll/scattering_routines/geometry/methods.h +111 -0
  40. xcoll/scattering_routines/geometry/objects.h +154 -0
  41. xcoll/scattering_routines/geometry/rotation.h +23 -0
  42. xcoll/scattering_routines/geometry/segments.h +226 -0
  43. xcoll/scattering_routines/geometry/sort.h +184 -0
  44. {xcoll-0.3.5.dist-info → xcoll-0.4.0.dist-info}/METADATA +1 -1
  45. {xcoll-0.3.5.dist-info → xcoll-0.4.0.dist-info}/RECORD +48 -33
  46. xcoll/beam_elements/collimators_src/absorber.h +0 -141
  47. xcoll/collimator_settings.py +0 -457
  48. xcoll/impacts/__init__.py +0 -1
  49. xcoll/impacts/impacts.py +0 -102
  50. xcoll/impacts/impacts_src/impacts.h +0 -99
  51. xcoll/scattering_routines/everest/crystal.h +0 -1302
  52. xcoll/scattering_routines/everest/scatter.h +0 -169
  53. xcoll/scattering_routines/everest/scatter_crystal.h +0 -260
  54. {xcoll-0.3.5.dist-info → xcoll-0.4.0.dist-info}/LICENSE +0 -0
  55. {xcoll-0.3.5.dist-info → xcoll-0.4.0.dist-info}/NOTICE +0 -0
  56. {xcoll-0.3.5.dist-info → xcoll-0.4.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,154 @@
1
+ // copyright ############################### #
2
+ // This file is part of the Xcoll Package. #
3
+ // Copyright (c) CERN, 2024. #
4
+ // ######################################### #
5
+
6
+ #ifndef XCOLL_GEOM_OBJECTS_H
7
+ #define XCOLL_GEOM_OBJECTS_H
8
+ #include <math.h>
9
+ #include <stdio.h>
10
+ #include <stdint.h>
11
+ #include <stdlib.h>
12
+
13
+
14
+ // Assumption for all objects: the particle at -inf is outside the object (otherwise some comparisons might give wrong results)
15
+
16
+
17
+ // Collimator jaw
18
+ // --------------
19
+
20
+ /*gpufun*/
21
+ Segment* create_jaw(double s_U, double x_U, double s_D, double x_D, double tilt_tan, int8_t side){
22
+ Segment* segments= (Segment*) malloc(3*sizeof(Segment));
23
+ segments[0] = (Segment) create_halfopen_line_segment(s_U, x_U, tilt_tan, side);
24
+ segments[1] = (Segment) create_line_segment(s_U, x_U, s_D, x_D);
25
+ segments[2] = (Segment) create_halfopen_line_segment(s_D, x_D, tilt_tan, side);
26
+ return segments;
27
+ }
28
+
29
+ /*gpufun*/
30
+ void destroy_jaw(Segment* segments){
31
+ free((HalfOpenLineSegment) segments[0]);
32
+ free((LineSegment) segments[1]);
33
+ free((HalfOpenLineSegment) segments[2]);
34
+ free(segments);
35
+ }
36
+
37
+
38
+ // Polygon
39
+ // -------
40
+
41
+ /*gpufun*/
42
+ Segment* create_polygon(double* s_poly, double* x_poly, int8_t num_polys){
43
+ Segment* segments= (Segment*) malloc((unsigned int) num_polys*sizeof(Segment));
44
+ for (int8_t i=0; i<num_polys-1; i++){
45
+ segments[i] = (Segment) create_line_segment(s_poly[i], x_poly[i], s_poly[i+1], x_poly[i+1]);
46
+ }
47
+ segments[num_polys-1] = (Segment) create_line_segment(s_poly[num_polys-1], x_poly[num_polys-1], \
48
+ s_poly[0], x_poly[0]);
49
+ return segments;
50
+ }
51
+
52
+ /*gpufun*/
53
+ void destroy_polygon(Segment* segments, int8_t num_polys){
54
+ for (int8_t i=0; i<num_polys; i++) {
55
+ free((LineSegment) segments[i]);
56
+ }
57
+ free(segments);
58
+ }
59
+
60
+
61
+ // Open polygon
62
+ // ------------
63
+
64
+ /*gpufun*/
65
+ Segment* create_open_polygon(double* s_poly, double* x_poly, int8_t num_polys, double tilt_tan, int8_t side){
66
+ Segment* segments= (Segment*) malloc((num_polys+1)*sizeof(Segment));
67
+ segments[0] = (Segment) create_halfopen_line_segment(s_poly[0], x_poly[0], tilt_tan, side);
68
+ for (int8_t i=1; i<num_polys; i++){
69
+ segments[i] = (Segment) create_line_segment(s_poly[i-1], x_poly[i-1], s_poly[i], x_poly[i]);
70
+ }
71
+ segments[num_polys] = (Segment) create_halfopen_line_segment(s_poly[num_polys-1], x_poly[num_polys-1], \
72
+ tilt_tan, side);
73
+ return segments;
74
+ }
75
+
76
+ /*gpufun*/
77
+ void destroy_open_polygon(Segment* segments, int8_t num_polys){
78
+ free((HalfOpenLineSegment) segments[0]);
79
+ for (int8_t i=1; i<num_polys; i++) {
80
+ free((LineSegment) segments[i]);
81
+ }
82
+ free((HalfOpenLineSegment) segments[num_polys]);
83
+ free(segments);
84
+ }
85
+
86
+
87
+ // Crystal
88
+ // -------
89
+
90
+ // The four corners A, B, C, D are such that AB is the front face, BC the curve furthest from the beam,
91
+ // CD the back face, and DA the curve closest to the beam.
92
+ /*gpufun*/
93
+ Segment* create_crystal(double R, double width, double length, double jaw_U, double tilt_sin, double tilt_cos){
94
+ Segment* segments= (Segment*) malloc(4*sizeof(Segment));
95
+
96
+ // First corner is what defines the crystal position
97
+ double A_s = 0;
98
+ double A_x = jaw_U;
99
+
100
+ // Manipulate R in function of sign
101
+ double sgnR = (R > 0) - (R < 0);
102
+ double R_short = sgnR*(fabs(R) - width);
103
+ double sin_a = length/fabs(R);
104
+ double cos_a = sqrt(1 - length*length/R/R);
105
+ if (fabs(R) < 1.e-12){
106
+ // straight crystal - not yet implemented
107
+ printf("Straight crystal not yet implemented!"); //only_for_context cpu_serial
108
+ fflush(stdout); //only_for_context cpu_serial
109
+ return NULL;
110
+
111
+ } else if (R < 0){
112
+ // This distinction is needed to keep the crystal at the same location when changing the bend direction
113
+ double R_temp = R_short;
114
+ R_short = R;
115
+ R = R_temp;
116
+ }
117
+
118
+ // Bending centre is defined w.r.t. A
119
+ double R_s = A_s - R*tilt_sin;
120
+ double R_x = A_x + R*tilt_cos;
121
+
122
+ // Three remaining corner points of crystal
123
+ double B_s = R_s + R_short*tilt_sin;
124
+ double C_s = R_s + fabs(R_short)*sin_a*tilt_cos + R_short*cos_a*tilt_sin;
125
+ double D_s = R_s + fabs(R)*sin_a*tilt_cos + R*cos_a*tilt_sin;
126
+ double B_x = R_x - R_short*tilt_cos;
127
+ double C_x = R_x - cos_a*tilt_cos*R_short + sin_a*tilt_sin*fabs(R_short);
128
+ double D_x = R_x - cos_a*tilt_cos*R + sin_a*tilt_sin*fabs(R);
129
+ double A_t = atan2(A_x - R_x, A_s - R_s);
130
+ double D_t = atan2(D_x - R_x, D_s - R_s);
131
+ double t1 = MIN(A_t, D_t);
132
+ double t2 = MAX(A_t, D_t);
133
+
134
+ // Fill segments
135
+ segments[0] = (Segment) create_line_segment(A_s, A_x, B_s, B_x);
136
+ segments[1] = (Segment) create_circular_segment(R, R_s, R_x, t1, t2);
137
+ segments[2] = (Segment) create_line_segment(C_s, C_x, D_s, D_x);
138
+ segments[3] = (Segment) create_circular_segment(R_short, R_s, R_x, t1, t2);
139
+
140
+ // printf("R: (%f, %f) A: (%f, %f) B: (%f, %f) C: (%f, %f) D: (%f, %f) t1: %f t2: %f\n", R_s,R_x,A_s,A_x,B_s,B_x,C_s,C_x,D_s,D_x,t1*180/3.141592653589793,t2*180/3.141592653589793); fflush(stdout);
141
+ return segments;
142
+ }
143
+
144
+ /*gpufun*/
145
+ void destroy_crystal(Segment* segments){
146
+ free((LineSegment) segments[0]);
147
+ free((CircularSegment) segments[1]);
148
+ free((LineSegment) segments[2]);
149
+ free((CircularSegment) segments[3]);
150
+ free(segments);
151
+ }
152
+
153
+
154
+ #endif /* XCOLL_GEOM_OBJECTS_H */
@@ -0,0 +1,23 @@
1
+ // copyright ############################### #
2
+ // This file is part of the Xcoll Package. #
3
+ // Copyright (c) CERN, 2024. #
4
+ // ######################################### #
5
+
6
+ #ifndef XCOLL_GEOM_ROT_H
7
+ #define XCOLL_GEOM_ROT_H
8
+ #include <math.h>
9
+ #include <stdio.h>
10
+
11
+
12
+ /*gpufun*/
13
+ double YRotation_single_particle_rotate_only(LocalParticle* part, double s, double angle){
14
+ double x = LocalParticle_get_x(part);
15
+ double rpp = LocalParticle_get_rpp(part);
16
+ double sin_y = sin(angle);
17
+ double cos_y = cos(angle);
18
+ LocalParticle_set_x(part, x*cos_y - s*sin_y);
19
+ LocalParticle_add_to_px(part,-angle/rpp);
20
+ return x*sin_y + s*cos_y; // new s
21
+ }
22
+
23
+ #endif /* XCOLL_GEOM_ROT_H */
@@ -0,0 +1,226 @@
1
+ // copyright ############################### #
2
+ // This file is part of the Xcoll Package. #
3
+ // Copyright (c) CERN, 2024. #
4
+ // ######################################### #
5
+
6
+ #ifndef XCOLL_GEOM_SEGMENTS_H
7
+ #define XCOLL_GEOM_SEGMENTS_H
8
+ #include <math.h>
9
+ #include <stdio.h>
10
+ #include <stdint.h>
11
+ #include <stdlib.h>
12
+
13
+
14
+ // These functions compare a particle trajectory (straight line with slope part_tan going
15
+ // through the point [0, part_x]) with a given segment of specific type.
16
+ // The results are always stored in an array s, and n_hit keeps track of the number of hits.
17
+
18
+
19
+ #define XC_MAX_CROSS_PER_SEGMENT 2 // Update if new segment type allows more crossings
20
+
21
+
22
+ // Function that calculates the crossing with a given segment
23
+ typedef void (*CrossingFunc)(int8_t*, double*, double, double, void*);
24
+
25
+
26
+ // Parent type for all segments
27
+ // ----------------------------
28
+ typedef struct Segment_{
29
+ CrossingFunc crossing;
30
+ } Segment_;
31
+ typedef Segment_* Segment;
32
+
33
+
34
+ // Line segment
35
+ // ------------
36
+
37
+ // Line segment defined by two points (s1, x1), (s2, x2). The function will fill in the segment
38
+ // points in the trajectory equation; if the results have opposite sign, the two points lie on
39
+ // different sides of the trajectory and hence the segment is crossed.
40
+
41
+ typedef struct LineSegment_ {
42
+ CrossingFunc crossing;
43
+ double point1_s;
44
+ double point1_x;
45
+ double point2_s;
46
+ double point2_x;
47
+ } LineSegment_;
48
+ typedef LineSegment_* LineSegment;
49
+
50
+ /*gpufun*/
51
+ void get_s_of_crossing_with_line_segment(int8_t* n_hit, double* s, double part_x, double part_tan, void* self){
52
+ // Get segment data
53
+ LineSegment seg = (LineSegment) self;
54
+ double s_p1 = seg->point1_s;
55
+ double s_p2 = seg->point2_s;
56
+ double x_p1 = seg->point1_x;
57
+ double x_p2 = seg->point2_x;
58
+ // Calculate crossings
59
+ double trajectory_p1 = x_p1 - part_x - s_p1*part_tan;
60
+ double trajectory_p2 = x_p2 - part_x - s_p2*part_tan;
61
+ if (trajectory_p1*trajectory_p2 <= 0){
62
+ // It's a crossing
63
+ if (fabs(s_p2 - s_p1) < 1.e-12){
64
+ s[*n_hit] = s_p1;
65
+ (*n_hit)++;
66
+ } else {
67
+ double poly_tan = (x_p2 - x_p1)/(s_p2 - s_p1);
68
+ if (fabs(poly_tan - part_tan) < 1.e-12){
69
+ s[*n_hit] = s_p1;
70
+ (*n_hit)++;
71
+ } else {
72
+ s[*n_hit] = (part_x - x_p1 + s_p1*poly_tan)/(poly_tan - part_tan);
73
+ (*n_hit)++;
74
+ }
75
+ }
76
+ }
77
+ }
78
+
79
+ /*gpufun*/
80
+ LineSegment create_line_segment(double point1_s, double point1_x, double point2_s, double point2_x){
81
+ LineSegment seg = (LineSegment) malloc(sizeof(LineSegment_));
82
+ seg->crossing = &get_s_of_crossing_with_line_segment;
83
+ seg->point1_s = point1_s;
84
+ seg->point2_s = point2_s;
85
+ seg->point1_x = point1_x;
86
+ seg->point2_x = point2_x;
87
+ return seg;
88
+ }
89
+
90
+
91
+ // Half-open line segment
92
+ // ----------------------
93
+
94
+ // This function works as above, but considers a half-open segment. For this reason,
95
+ // the function needs to know whether this is a positive or negative jaw (representing
96
+ // to which infinite it points), and the overall tilt of the jaw.
97
+ typedef struct HalfOpenLineSegment_ {
98
+ CrossingFunc crossing;
99
+ double point_s;
100
+ double point_x;
101
+ int8_t side;
102
+ // Important: this is the perpendicular angle (hence we will use -1/point_tan)
103
+ // This is done because the case "point_tan == 0" cannot take place in our setup,
104
+ // but "point_tan == inf" can (when the jaws have no tilt).
105
+ double point_tan;
106
+ } HalfOpenLineSegment_;
107
+ typedef HalfOpenLineSegment_* HalfOpenLineSegment;
108
+
109
+ // A half-open segment implies one of its points lies at +-inf.
110
+ // In practice we just add a polygon point at the wall overflow (at 1km for the x-coordinate).
111
+ /*gpufun*/
112
+ void get_s_of_crossing_with_halfopen_line_segment(int8_t* n_hit, double* s, double part_x, double part_tan, void* self){
113
+ // Get segment data
114
+ HalfOpenLineSegment seg = (HalfOpenLineSegment) self;
115
+ double s_p1 = seg->point_s;
116
+ double x_p1 = seg->point_x;
117
+ double x_p2 = 1.e3*seg->side;
118
+ double s_p2;
119
+ if (fabs(seg->point_tan) < 1.e-12){
120
+ s_p2 = s_p1;
121
+ } else {
122
+ s_p2 = -(x_p2 - x_p1 - s_p1/seg->point_tan)*seg->point_tan;
123
+ }
124
+ // Calculate crossings
125
+ double trajectory_p1 = x_p1 - part_x - s_p1*part_tan;
126
+ double trajectory_p2 = x_p2 - part_x - s_p2*part_tan;
127
+ if (trajectory_p1*trajectory_p2 <= 0){
128
+ // It's a crossing
129
+ if (fabs(s_p2 - s_p1) < 1.e-12){
130
+ s[*n_hit] = s_p1;
131
+ (*n_hit)++;
132
+ } else {
133
+ double poly_tan = (x_p2 - x_p1)/(s_p2 - s_p1);
134
+ if (fabs(poly_tan - part_tan) < 1.e-12){
135
+ s[*n_hit] = s_p1;
136
+ (*n_hit)++;
137
+ } else {
138
+ s[*n_hit] = (part_x - x_p1 + s_p1*poly_tan)/(poly_tan - part_tan);
139
+ (*n_hit)++;
140
+ }
141
+ }
142
+ }
143
+ }
144
+
145
+ /*gpufun*/
146
+ HalfOpenLineSegment create_halfopen_line_segment(double point_s, double point_x, double point_tan, int8_t side){
147
+ HalfOpenLineSegment seg = (HalfOpenLineSegment) malloc(sizeof(HalfOpenLineSegment_));
148
+ seg->crossing = &get_s_of_crossing_with_halfopen_line_segment;
149
+ seg->point_s = point_s;
150
+ seg->point_x = point_x;
151
+ seg->side = side;
152
+ seg->point_tan = point_tan;
153
+ return seg;
154
+ }
155
+
156
+
157
+ // Circular arc segment
158
+ // --------------------
159
+
160
+ // This function finds the crossing points between a line defined by a point (s=0, x) and a tangent,
161
+ // and a circular arc segment defined by a radius R, a centre (Rs, Rx), and angles t1 and t2.
162
+ // The results are stored in an array s, and n_hit keeps track of the number of hits.
163
+ typedef struct CircularSegment_ {
164
+ CrossingFunc crossing;
165
+ double R;
166
+ double centre_s;
167
+ double centre_x;
168
+ double point1_angle;
169
+ double point2_angle;
170
+ } CircularSegment_;
171
+ typedef CircularSegment_* CircularSegment;
172
+
173
+ /*gpufun*/
174
+ void get_s_of_crossing_with_circular_segment(int8_t* n_hit, double* s, double part_x, double part_tan, void* self){
175
+ // Get segment data
176
+ CircularSegment seg = (CircularSegment) self;
177
+ double R = seg->R;
178
+ double R_s = seg->centre_s;
179
+ double R_x = seg->centre_x;
180
+ double t1 = seg->point1_angle;
181
+ double t2 = seg->point2_angle;
182
+ // Calculate crossings
183
+ int8_t reversed = 0;
184
+ if (t2 < t1){
185
+ reversed = 1;
186
+ }
187
+ double a = 1 + part_tan*part_tan;
188
+ double bb = R_s - part_tan*(part_x - R_x);
189
+ double c = R_s*R_s + (part_x - R_x)*(part_x - R_x) - R*R;
190
+ double disc = bb*bb - a*c;
191
+ if (disc >= 0){
192
+ for (int8_t i = 0; i < 2; i++) {
193
+ double sgnD = i*2-1; // negative and positive solutions
194
+ double new_s = 1/a*(bb + sgnD*sqrt(bb*bb - a*c));
195
+ double x = part_x + new_s*part_tan;
196
+ double t = atan2(x - R_x, new_s - R_s);
197
+ if (reversed){
198
+ // t2 < t1, so we are looking at the inverted region of angles
199
+ if (t1 >= t || t >= t2){
200
+ s[*n_hit] = new_s;
201
+ (*n_hit)++;
202
+ }
203
+ } else {
204
+ if (t1 <= t && t <= t2){
205
+ s[*n_hit] = new_s;
206
+ (*n_hit)++;
207
+ }
208
+ }
209
+ }
210
+ }
211
+ }
212
+
213
+ /*gpufun*/
214
+ CircularSegment create_circular_segment(double R, double centre_s, double centre_x, double point1_angle, double point2_angle){
215
+ CircularSegment seg = (CircularSegment) malloc(sizeof(CircularSegment_));
216
+ seg->crossing = &get_s_of_crossing_with_circular_segment;
217
+ seg->R = R;
218
+ seg->centre_s = centre_s;
219
+ seg->centre_x = centre_x;
220
+ seg->point1_angle = point1_angle;
221
+ seg->point2_angle = point2_angle;
222
+ return seg;
223
+ }
224
+
225
+
226
+ #endif /* XCOLL_GEOM_SEGMENTS_H */
@@ -0,0 +1,184 @@
1
+ // copyright ############################### #
2
+ // This file is part of the Xcoll Package. #
3
+ // Copyright (c) CERN, 2024. #
4
+ // ######################################### #
5
+
6
+ #ifndef XCOLL_GEOM_SORT_H
7
+ #define XCOLL_GEOM_SORT_H
8
+ #include <math.h>
9
+ #include <stdio.h>
10
+ #include <stdint.h>
11
+ #include <stdlib.h>
12
+
13
+ #pragma GCC diagnostic push
14
+ #pragma GCC diagnostic ignored "-Warray-bounds"
15
+
16
+ #ifdef MAX
17
+ #undef MAX
18
+ #pragma message ("Xcoll geometry: Compiler macro MAX redefined")
19
+ #endif
20
+ #define MAX(x, y) ({const __typeof__ (x) _x = (x); \
21
+ const __typeof__ (y) _y = (y); \
22
+ _x > _y ? _x : _y; })
23
+ #ifdef MIN
24
+ #undef MIN
25
+ #pragma message ("Xcoll geometry: Compiler macro MIN redefined")
26
+ #endif
27
+ #define MIN(x, y) ({const __typeof__ (x) _x = (x); \
28
+ const __typeof__ (y) _y = (y); \
29
+ _x < _y ? _x : _y; })
30
+ #ifdef SWAP
31
+ #error "Xcoll geometry: Compiler macro SWAP already defined!"
32
+ #endif
33
+ #define SWAP(d,x,y) ({const __typeof__(*d) _x = MIN(d[x], d[y]); \
34
+ const __typeof__(*d) _y = MAX(d[x], d[y]); \
35
+ d[x] = _x; d[y] = _y; })
36
+
37
+
38
+ // Fast methods
39
+ // ------------
40
+
41
+ static inline void sort_array_of_2_double(double* d){
42
+ SWAP(d, 0, 1);
43
+ }
44
+
45
+ static inline void sort_array_of_3_double(double* d){
46
+ SWAP(d, 0, 1); SWAP(d, 1, 2); SWAP(d, 0, 1);
47
+ }
48
+
49
+ static inline void sort_array_of_4_double(double* d){
50
+ SWAP(d, 0, 1); SWAP(d, 2, 3); SWAP(d, 0, 2); SWAP(d, 1, 3); SWAP(d, 1, 2);
51
+ }
52
+
53
+ static inline void sort_array_of_5_double(double* d){
54
+ SWAP(d, 0, 1); SWAP(d, 3, 4); SWAP(d, 2, 4); SWAP(d, 2, 3); SWAP(d, 1, 4);
55
+ SWAP(d, 0, 3); SWAP(d, 0, 2); SWAP(d, 1, 3); SWAP(d, 1, 2);
56
+ }
57
+
58
+ static inline void sort_array_of_6_double(double* d){
59
+ SWAP(d, 1, 2); SWAP(d, 4, 5); SWAP(d, 0, 2); SWAP(d, 3, 5); SWAP(d, 0, 1);
60
+ SWAP(d, 3, 4); SWAP(d, 1, 4); SWAP(d, 0, 3); SWAP(d, 2, 5); SWAP(d, 1, 3);
61
+ SWAP(d, 2, 4); SWAP(d, 2, 3);
62
+ }
63
+
64
+ static inline void sort_array_of_7_double(double* d){
65
+ SWAP(d, 1, 2); SWAP(d, 3, 4); SWAP(d, 5, 6); SWAP(d, 0, 2); SWAP(d, 3, 5);
66
+ SWAP(d, 4, 6); SWAP(d, 0, 1); SWAP(d, 4, 5); SWAP(d, 2, 6); SWAP(d, 0, 4);
67
+ SWAP(d, 1, 5); SWAP(d, 0, 3); SWAP(d, 2, 5); SWAP(d, 1, 3); SWAP(d, 2, 4);
68
+ SWAP(d, 2, 3);
69
+ }
70
+
71
+ static inline void sort_array_of_8_double(double* d){
72
+ SWAP(d, 0, 1); SWAP(d, 2, 3); SWAP(d, 4, 5); SWAP(d, 6, 7); SWAP(d, 0, 2);
73
+ SWAP(d, 1, 3); SWAP(d, 4, 6); SWAP(d, 5, 7); SWAP(d, 1, 2); SWAP(d, 5, 6);
74
+ SWAP(d, 0, 4); SWAP(d, 3, 7); SWAP(d, 1, 5); SWAP(d, 2, 6); SWAP(d, 1, 4);
75
+ SWAP(d, 3, 6); SWAP(d, 2, 4); SWAP(d, 3, 5); SWAP(d, 3, 4);
76
+ }
77
+
78
+ static inline void sort_array_of_2_int64(int64_t* d){
79
+ SWAP(d, 0, 1);
80
+ }
81
+
82
+ static inline void sort_array_of_3_int64(int64_t* d){
83
+ SWAP(d, 0, 1); SWAP(d, 1, 2); SWAP(d, 0, 1);
84
+ }
85
+
86
+ static inline void sort_array_of_4_int64(int64_t* d){
87
+ SWAP(d, 0, 1); SWAP(d, 2, 3); SWAP(d, 0, 2); SWAP(d, 1, 3); SWAP(d, 1, 2);
88
+ }
89
+
90
+ static inline void sort_array_of_5_int64(int64_t* d){
91
+ SWAP(d, 0, 1); SWAP(d, 3, 4); SWAP(d, 2, 4); SWAP(d, 2, 3); SWAP(d, 1, 4);
92
+ SWAP(d, 0, 3); SWAP(d, 0, 2); SWAP(d, 1, 3); SWAP(d, 1, 2);
93
+ }
94
+
95
+ static inline void sort_array_of_6_int64(int64_t* d){
96
+ SWAP(d, 1, 2); SWAP(d, 4, 5); SWAP(d, 0, 2); SWAP(d, 3, 5); SWAP(d, 0, 1);
97
+ SWAP(d, 3, 4); SWAP(d, 1, 4); SWAP(d, 0, 3); SWAP(d, 2, 5); SWAP(d, 1, 3);
98
+ SWAP(d, 2, 4); SWAP(d, 2, 3);
99
+ }
100
+
101
+ static inline void sort_array_of_7_int64(int64_t* d){
102
+ SWAP(d, 1, 2); SWAP(d, 3, 4); SWAP(d, 5, 6); SWAP(d, 0, 2); SWAP(d, 3, 5);
103
+ SWAP(d, 4, 6); SWAP(d, 0, 1); SWAP(d, 4, 5); SWAP(d, 2, 6); SWAP(d, 0, 4);
104
+ SWAP(d, 1, 5); SWAP(d, 0, 3); SWAP(d, 2, 5); SWAP(d, 1, 3); SWAP(d, 2, 4);
105
+ SWAP(d, 2, 3);
106
+ }
107
+
108
+ static inline void sort_array_of_8_int64(int64_t* d){
109
+ SWAP(d, 0, 1); SWAP(d, 2, 3); SWAP(d, 4, 5); SWAP(d, 6, 7); SWAP(d, 0, 2);
110
+ SWAP(d, 1, 3); SWAP(d, 4, 6); SWAP(d, 5, 7); SWAP(d, 1, 2); SWAP(d, 5, 6);
111
+ SWAP(d, 0, 4); SWAP(d, 3, 7); SWAP(d, 1, 5); SWAP(d, 2, 6); SWAP(d, 1, 4);
112
+ SWAP(d, 3, 6); SWAP(d, 2, 4); SWAP(d, 3, 5); SWAP(d, 3, 4);
113
+ }
114
+
115
+
116
+ // Generic methods
117
+ // ---------------
118
+
119
+ int cmpfunc_double(const void * a, const void * b) {
120
+ return ( *(double*)a - *(double*)b );
121
+ }
122
+
123
+ static inline void sort_array_of_double(double* arr, int64_t length){
124
+ switch(length){
125
+ case 2:
126
+ sort_array_of_2_double(arr);
127
+ break;
128
+ case 3:
129
+ sort_array_of_3_double(arr);
130
+ break;
131
+ case 4:
132
+ sort_array_of_4_double(arr);
133
+ break;
134
+ case 5:
135
+ sort_array_of_5_double(arr);
136
+ break;
137
+ case 6:
138
+ sort_array_of_6_double(arr);
139
+ break;
140
+ case 7:
141
+ sort_array_of_7_double(arr);
142
+ break;
143
+ case 8:
144
+ sort_array_of_8_double(arr);
145
+ break;
146
+ default:
147
+ qsort(arr, length, sizeof(double), cmpfunc_double);
148
+ }
149
+ }
150
+
151
+ int cmpfunc_int64(const void * a, const void * b) {
152
+ return ( *(int64_t*)a - *(int64_t*)b );
153
+ }
154
+
155
+ static inline void sort_array_of_int64(int64_t* arr, int64_t length){
156
+ switch(length){
157
+ case 2:
158
+ sort_array_of_2_int64(arr);
159
+ break;
160
+ case 3:
161
+ sort_array_of_3_int64(arr);
162
+ break;
163
+ case 4:
164
+ sort_array_of_4_int64(arr);
165
+ break;
166
+ case 5:
167
+ sort_array_of_5_int64(arr);
168
+ break;
169
+ case 6:
170
+ sort_array_of_6_int64(arr);
171
+ break;
172
+ case 7:
173
+ sort_array_of_7_int64(arr);
174
+ break;
175
+ case 8:
176
+ sort_array_of_8_int64(arr);
177
+ break;
178
+ default:
179
+ qsort(arr, length, sizeof(int64_t), cmpfunc_int64);
180
+ }
181
+ }
182
+
183
+ #pragma GCC diagnostic pop
184
+ #endif /* XCOLL_GEOM_SORT_H */
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: xcoll
3
- Version: 0.3.5
3
+ Version: 0.4.0
4
4
  Summary: Xsuite collimation package
5
5
  Home-page: https://github.com/xsuite/xcoll
6
6
  License: Apache 2.0