xcoll 0.3.6__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.
- xcoll/__init__.py +12 -4
- xcoll/beam_elements/__init__.py +7 -5
- xcoll/beam_elements/absorber.py +41 -7
- xcoll/beam_elements/base.py +1161 -244
- xcoll/beam_elements/collimators_src/black_absorber.h +118 -0
- xcoll/beam_elements/collimators_src/black_crystal.h +111 -0
- xcoll/beam_elements/collimators_src/everest_block.h +40 -28
- xcoll/beam_elements/collimators_src/everest_collimator.h +129 -50
- xcoll/beam_elements/collimators_src/everest_crystal.h +217 -73
- xcoll/beam_elements/everest.py +60 -113
- xcoll/colldb.py +250 -750
- xcoll/general.py +2 -2
- xcoll/headers/checks.h +1 -1
- xcoll/headers/particle_states.h +2 -2
- xcoll/initial_distribution.py +195 -0
- xcoll/install.py +177 -0
- xcoll/interaction_record/__init__.py +1 -0
- xcoll/interaction_record/interaction_record.py +252 -0
- xcoll/interaction_record/interaction_record_src/interaction_record.h +98 -0
- xcoll/{impacts → interaction_record}/interaction_types.py +11 -4
- xcoll/line_tools.py +83 -0
- xcoll/lossmap.py +209 -0
- xcoll/manager.py +2 -937
- xcoll/rf_sweep.py +1 -1
- xcoll/scattering_routines/everest/amorphous.h +239 -0
- xcoll/scattering_routines/everest/channeling.h +245 -0
- xcoll/scattering_routines/everest/crystal_parameters.h +137 -0
- xcoll/scattering_routines/everest/everest.h +8 -30
- xcoll/scattering_routines/everest/everest.py +13 -10
- xcoll/scattering_routines/everest/jaw.h +27 -197
- xcoll/scattering_routines/everest/materials.py +2 -0
- xcoll/scattering_routines/everest/multiple_coulomb_scattering.h +31 -10
- xcoll/scattering_routines/everest/nuclear_interaction.h +86 -0
- xcoll/scattering_routines/geometry/__init__.py +6 -0
- xcoll/scattering_routines/geometry/collimator_geometry.h +219 -0
- xcoll/scattering_routines/geometry/crystal_geometry.h +150 -0
- xcoll/scattering_routines/geometry/geometry.py +26 -0
- xcoll/scattering_routines/geometry/get_s.h +92 -0
- xcoll/scattering_routines/geometry/methods.h +111 -0
- xcoll/scattering_routines/geometry/objects.h +154 -0
- xcoll/scattering_routines/geometry/rotation.h +23 -0
- xcoll/scattering_routines/geometry/segments.h +226 -0
- xcoll/scattering_routines/geometry/sort.h +184 -0
- {xcoll-0.3.6.dist-info → xcoll-0.4.0.dist-info}/METADATA +1 -1
- {xcoll-0.3.6.dist-info → xcoll-0.4.0.dist-info}/RECORD +48 -33
- xcoll/beam_elements/collimators_src/absorber.h +0 -141
- xcoll/collimator_settings.py +0 -457
- xcoll/impacts/__init__.py +0 -1
- xcoll/impacts/impacts.py +0 -102
- xcoll/impacts/impacts_src/impacts.h +0 -99
- xcoll/scattering_routines/everest/crystal.h +0 -1302
- xcoll/scattering_routines/everest/scatter.h +0 -169
- xcoll/scattering_routines/everest/scatter_crystal.h +0 -260
- {xcoll-0.3.6.dist-info → xcoll-0.4.0.dist-info}/LICENSE +0 -0
- {xcoll-0.3.6.dist-info → xcoll-0.4.0.dist-info}/NOTICE +0 -0
- {xcoll-0.3.6.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 */
|