1 /*
2 * Copyright (c) 2014-2021, The OSKAR Developers.
3 * See the LICENSE file at the top-level directory of this distribution.
4 */
5
6 #include "convert/define_convert_enu_directions_to_cirs_relative_directions.h"
7 #include "convert/oskar_convert_enu_directions_to_cirs_relative_directions.h"
8 #include "utility/oskar_device.h"
9 #include "utility/oskar_kernel_macros.h"
10
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14
OSKAR_CONVERT_ENU_DIR_TO_CIRS_REL_DIR(convert_enu_directions_to_cirs_relative_directions_float,float)15 OSKAR_CONVERT_ENU_DIR_TO_CIRS_REL_DIR(convert_enu_directions_to_cirs_relative_directions_float, float)
16 OSKAR_CONVERT_ENU_DIR_TO_CIRS_REL_DIR(convert_enu_directions_to_cirs_relative_directions_double, double)
17
18 void oskar_convert_enu_directions_to_cirs_relative_directions(
19 int offset_in,
20 int num_points,
21 const oskar_Mem* x,
22 const oskar_Mem* y,
23 const oskar_Mem* z,
24 double ra0_rad,
25 double dec0_rad,
26 double lon_rad,
27 double lat_rad,
28 double era_rad,
29 double pm_x_rad,
30 double pm_y_rad,
31 double diurnal_aberration,
32 int offset_out,
33 oskar_Mem* l,
34 oskar_Mem* m,
35 oskar_Mem* n,
36 int* status)
37 {
38 if (*status) return;
39 const int type = oskar_mem_type(x);
40 const int location = oskar_mem_location(x);
41 const double ha0_rad = era_rad + lon_rad - ra0_rad;
42 const double sin_ha0 = sin(ha0_rad);
43 const double cos_ha0 = cos(ha0_rad);
44 const double sin_dec0 = sin(dec0_rad);
45 const double cos_dec0 = cos(dec0_rad);
46 const double sin_lon = sin(lon_rad);
47 const double cos_lon = cos(lon_rad);
48 const double sin_lat = sin(lat_rad);
49 const double cos_lat = cos(lat_rad);
50 const double local_pm_x = pm_x_rad * cos_lon - pm_y_rad * sin_lon;
51 const double local_pm_y = pm_x_rad * sin_lon + pm_y_rad * cos_lon;
52 const float sin_ha0_f = (float) sin_ha0;
53 const float cos_ha0_f = (float) cos_ha0;
54 const float sin_dec0_f = (float) sin_dec0;
55 const float cos_dec0_f = (float) cos_dec0;
56 const float sin_lat_f = (float) sin_lat;
57 const float cos_lat_f = (float) cos_lat;
58 const float local_pm_x_f = (float) local_pm_x;
59 const float local_pm_y_f = (float) local_pm_y;
60 const float diurnal_aberration_f = (float) diurnal_aberration;
61 if (type != OSKAR_SINGLE && type != OSKAR_DOUBLE)
62 {
63 *status = OSKAR_ERR_BAD_DATA_TYPE;
64 return;
65 }
66 if (type != oskar_mem_type(y) || type != oskar_mem_type(z) ||
67 type != oskar_mem_type(l) || type != oskar_mem_type(m) ||
68 type != oskar_mem_type(n))
69 {
70 *status = OSKAR_ERR_TYPE_MISMATCH;
71 return;
72 }
73 if (location != oskar_mem_location(y) ||
74 location != oskar_mem_location(z) ||
75 location != oskar_mem_location(l) ||
76 location != oskar_mem_location(m) ||
77 location != oskar_mem_location(n))
78 {
79 *status = OSKAR_ERR_LOCATION_MISMATCH;
80 return;
81 }
82 if (location == OSKAR_CPU)
83 {
84 if (type == OSKAR_SINGLE)
85 {
86 convert_enu_directions_to_cirs_relative_directions_float(
87 offset_in, num_points,
88 oskar_mem_float_const(x, status),
89 oskar_mem_float_const(y, status),
90 oskar_mem_float_const(z, status),
91 sin_ha0_f, cos_ha0_f, sin_dec0_f, cos_dec0_f,
92 sin_lat_f, cos_lat_f,
93 local_pm_x_f, local_pm_y_f, diurnal_aberration_f,
94 offset_out,
95 oskar_mem_float(l, status),
96 oskar_mem_float(m, status),
97 oskar_mem_float(n, status));
98 }
99 else if (type == OSKAR_DOUBLE)
100 {
101 convert_enu_directions_to_cirs_relative_directions_double(
102 offset_in, num_points,
103 oskar_mem_double_const(x, status),
104 oskar_mem_double_const(y, status),
105 oskar_mem_double_const(z, status),
106 sin_ha0, cos_ha0, sin_dec0, cos_dec0,
107 sin_lat, cos_lat,
108 local_pm_x, local_pm_y, diurnal_aberration,
109 offset_out,
110 oskar_mem_double(l, status),
111 oskar_mem_double(m, status),
112 oskar_mem_double(n, status));
113 }
114 else
115 {
116 *status = OSKAR_ERR_BAD_DATA_TYPE;
117 }
118 }
119 else
120 {
121 size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1};
122 const int is_dbl = (type == OSKAR_DOUBLE);
123 const char* k = 0;
124 if (type == OSKAR_SINGLE)
125 {
126 k = "convert_enu_directions_to_cirs_relative_directions_float";
127 }
128 else if (type == OSKAR_DOUBLE)
129 {
130 k = "convert_enu_directions_to_cirs_relative_directions_double";
131 }
132 else
133 {
134 *status = OSKAR_ERR_BAD_DATA_TYPE;
135 return;
136 }
137 oskar_device_check_local_size(location, 0, local_size);
138 global_size[0] = oskar_device_global_size(
139 (size_t) num_points, local_size[0]);
140 const oskar_Arg args[] = {
141 {INT_SZ, &offset_in},
142 {INT_SZ, &num_points},
143 {PTR_SZ, oskar_mem_buffer_const(x)},
144 {PTR_SZ, oskar_mem_buffer_const(y)},
145 {PTR_SZ, oskar_mem_buffer_const(z)},
146 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
147 (const void*)&sin_ha0 : (const void*)&sin_ha0_f},
148 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
149 (const void*)&cos_ha0 : (const void*)&cos_ha0_f},
150 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
151 (const void*)&sin_dec0 : (const void*)&sin_dec0_f},
152 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
153 (const void*)&cos_dec0 : (const void*)&cos_dec0_f},
154 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
155 (const void*)&sin_lat : (const void*)&sin_lat_f},
156 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
157 (const void*)&cos_lat : (const void*)&cos_lat_f},
158 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
159 (const void*)&local_pm_x : (const void*)&local_pm_x_f},
160 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
161 (const void*)&local_pm_y : (const void*)&local_pm_y_f},
162 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
163 (const void*)&diurnal_aberration :
164 (const void*)&diurnal_aberration_f},
165 {INT_SZ, &offset_out},
166 {PTR_SZ, oskar_mem_buffer(l)},
167 {PTR_SZ, oskar_mem_buffer(m)},
168 {PTR_SZ, oskar_mem_buffer(n)}
169 };
170 oskar_device_launch_kernel(k, location, 1, local_size, global_size,
171 sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status);
172 }
173 }
174
175 #ifdef __cplusplus
176 }
177 #endif
178