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