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_cirs_relative_directions_to_enu_directions.h"
7 #include "convert/oskar_convert_cirs_relative_directions_to_enu_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_CIRS_REL_DIR_TO_ENU_DIR(convert_cirs_relative_directions_to_enu_directions_float,float)15 OSKAR_CONVERT_CIRS_REL_DIR_TO_ENU_DIR(convert_cirs_relative_directions_to_enu_directions_float, float)
16 OSKAR_CONVERT_CIRS_REL_DIR_TO_ENU_DIR(convert_cirs_relative_directions_to_enu_directions_double, double)
17 
18 void oskar_convert_cirs_relative_directions_to_enu_directions(
19         int at_origin,
20         int bypass,
21         int offset_in,
22         int num_points,
23         const oskar_Mem* l,
24         const oskar_Mem* m,
25         const oskar_Mem* n,
26         double ra0_rad,
27         double dec0_rad,
28         double lon_rad,
29         double lat_rad,
30         double era_rad,
31         double pm_x_rad,
32         double pm_y_rad,
33         double diurnal_aberration,
34         int offset_out,
35         oskar_Mem* x,
36         oskar_Mem* y,
37         oskar_Mem* z,
38         int* status)
39 {
40     if (*status) return;
41     const int type = oskar_mem_type(x);
42     const int location = oskar_mem_location(x);
43     const double ha0_rad = era_rad + lon_rad - ra0_rad;
44     const double sin_ha0  = sin(ha0_rad);
45     const double cos_ha0  = cos(ha0_rad);
46     const double sin_dec0 = sin(dec0_rad);
47     const double cos_dec0 = cos(dec0_rad);
48     const double sin_lon  = sin(lon_rad);
49     const double cos_lon  = cos(lon_rad);
50     const double sin_lat  = sin(lat_rad);
51     const double cos_lat  = cos(lat_rad);
52     const double local_pm_x = pm_x_rad * cos_lon - pm_y_rad * sin_lon;
53     const double local_pm_y = pm_x_rad * sin_lon + pm_y_rad * cos_lon;
54     const float sin_ha0_f  = (float) sin_ha0;
55     const float cos_ha0_f  = (float) cos_ha0;
56     const float sin_dec0_f = (float) sin_dec0;
57     const float cos_dec0_f = (float) cos_dec0;
58     const float sin_lat_f  = (float) sin_lat;
59     const float cos_lat_f  = (float) cos_lat;
60     const float local_pm_x_f = (float) local_pm_x;
61     const float local_pm_y_f = (float) local_pm_y;
62     const float diurnal_aberration_f = (float) diurnal_aberration;
63     if (type != OSKAR_SINGLE && type != OSKAR_DOUBLE)
64     {
65         *status = OSKAR_ERR_BAD_DATA_TYPE;
66         return;
67     }
68     if (type != oskar_mem_type(y) || type != oskar_mem_type(z) ||
69             type != oskar_mem_type(l) || type != oskar_mem_type(m) ||
70             type != oskar_mem_type(n))
71     {
72         *status = OSKAR_ERR_TYPE_MISMATCH;
73         return;
74     }
75     if (location != oskar_mem_location(y) ||
76             location != oskar_mem_location(z) ||
77             location != oskar_mem_location(l) ||
78             location != oskar_mem_location(m) ||
79             location != oskar_mem_location(n))
80     {
81         *status = OSKAR_ERR_LOCATION_MISMATCH;
82         return;
83     }
84     if (location == OSKAR_CPU)
85     {
86         if (type == OSKAR_SINGLE)
87         {
88             convert_cirs_relative_directions_to_enu_directions_float(
89                     at_origin, bypass, offset_in, num_points,
90                     (!at_origin ? oskar_mem_float_const(l, status) : 0),
91                     (!at_origin ? oskar_mem_float_const(m, status) : 0),
92                     (!at_origin ? oskar_mem_float_const(n, status) : 0),
93                     sin_ha0_f, cos_ha0_f, sin_dec0_f, cos_dec0_f,
94                     sin_lat_f, cos_lat_f, local_pm_x_f, local_pm_y_f,
95                     diurnal_aberration_f, offset_out,
96                     oskar_mem_float(x, status),
97                     oskar_mem_float(y, status),
98                     oskar_mem_float(z, status));
99         }
100         else if (type == OSKAR_DOUBLE)
101         {
102             convert_cirs_relative_directions_to_enu_directions_double(
103                     at_origin, bypass, offset_in, num_points,
104                     (!at_origin ? oskar_mem_double_const(l, status) : 0),
105                     (!at_origin ? oskar_mem_double_const(m, status) : 0),
106                     (!at_origin ? oskar_mem_double_const(n, status) : 0),
107                     sin_ha0, cos_ha0, sin_dec0, cos_dec0,
108                     sin_lat, cos_lat, local_pm_x, local_pm_y,
109                     diurnal_aberration, offset_out,
110                     oskar_mem_double(x, status),
111                     oskar_mem_double(y, status),
112                     oskar_mem_double(z, 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         const void* np = 0;
125         if (type == OSKAR_SINGLE)
126         {
127             k = "convert_cirs_relative_directions_to_enu_directions_float";
128         }
129         else if (type == OSKAR_DOUBLE)
130         {
131             k = "convert_cirs_relative_directions_to_enu_directions_double";
132         }
133         else
134         {
135             *status = OSKAR_ERR_BAD_DATA_TYPE;
136             return;
137         }
138         if (num_points <= 32)
139         {
140             local_size[0] = 32;
141         }
142         else if (num_points <= 64)
143         {
144             local_size[0] = 64;
145         }
146         oskar_device_check_local_size(location, 0, local_size);
147         global_size[0] = oskar_device_global_size(
148                 (size_t) num_points, local_size[0]);
149         const oskar_Arg args[] = {
150                 {INT_SZ, &at_origin},
151                 {INT_SZ, &bypass},
152                 {INT_SZ, &offset_in},
153                 {INT_SZ, &num_points},
154                 {PTR_SZ, (!at_origin ? oskar_mem_buffer_const(l) : &np)},
155                 {PTR_SZ, (!at_origin ? oskar_mem_buffer_const(m) : &np)},
156                 {PTR_SZ, (!at_origin ? oskar_mem_buffer_const(n) : &np)},
157                 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
158                         (const void*)&sin_ha0 : (const void*)&sin_ha0_f},
159                 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
160                         (const void*)&cos_ha0 : (const void*)&cos_ha0_f},
161                 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
162                         (const void*)&sin_dec0 : (const void*)&sin_dec0_f},
163                 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
164                         (const void*)&cos_dec0 : (const void*)&cos_dec0_f},
165                 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
166                         (const void*)&sin_lat : (const void*)&sin_lat_f},
167                 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
168                         (const void*)&cos_lat : (const void*)&cos_lat_f},
169                 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
170                         (const void*)&local_pm_x : (const void*)&local_pm_x_f},
171                 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
172                         (const void*)&local_pm_y : (const void*)&local_pm_y_f},
173                 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
174                         (const void*)&diurnal_aberration :
175                         (const void*)&diurnal_aberration_f},
176                 {INT_SZ, &offset_out},
177                 {PTR_SZ, oskar_mem_buffer(x)},
178                 {PTR_SZ, oskar_mem_buffer(y)},
179                 {PTR_SZ, oskar_mem_buffer(z)}
180         };
181         oskar_device_launch_kernel(k, location, 1, local_size, global_size,
182                 sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status);
183     }
184 }
185 
186 #ifdef __cplusplus
187 }
188 #endif
189