17#ifdef YAC_NETCDF_ENABLED
25 int * nbr_vertices_per_cell);
33 double * temp_vertex_lat,
34 int * temp_nbr_vertices,
38 int * nbr_cells,
int ** num_vertices_per_cell,
39 int ** cell_to_vertex,
double ** x_vertices,
40 double ** y_vertices,
double ** x_cells,
53 double * temp_vertex_lon;
54 double * temp_vertex_lat;
55 int nbr_vertices_per_cell;
56 int temp_nbr_vertices;
59 nbr_cells, &nbr_vertices_per_cell);
61 temp_nbr_vertices = *nbr_cells * nbr_vertices_per_cell;
63 int * old_to_new_id =
xmalloc(temp_nbr_vertices *
sizeof(*old_to_new_id));
66 &temp_nbr_vertices, old_to_new_id);
68 *nbr_vertices = temp_nbr_vertices;
70 *x_vertices =
xrealloc(temp_vertex_lon,
71 temp_nbr_vertices *
sizeof(**x_vertices));
72 *y_vertices =
xrealloc(temp_vertex_lat,
73 temp_nbr_vertices *
sizeof(**y_vertices));
75 *num_vertices_per_cell =
xmalloc(*nbr_cells *
sizeof(**num_vertices_per_cell));
76 for (
int i = 0; i < *nbr_cells; ++i)
77 (*num_vertices_per_cell)[i] = nbr_vertices_per_cell;
79 *cell_to_vertex =
xmalloc(*nbr_cells * nbr_vertices_per_cell *
80 sizeof(**cell_to_vertex));
83 for (
int i = 0, k = 0; i < *nbr_cells; ++i)
84 for (
int j = 0; j < nbr_vertices_per_cell; ++j, ++k)
85 (*cell_to_vertex)[k] = old_to_new_id[k];
87 int new_size_cell_to_vertex = 0;
90 for (
int i = 0; i < *nbr_cells; ++i) {
91 (*cell_to_vertex)[new_size_cell_to_vertex++] =
92 (*cell_to_vertex)[i * nbr_vertices_per_cell];
93 for (
int j = 1; j < nbr_vertices_per_cell; ++j)
94 if ((*cell_to_vertex)[i * nbr_vertices_per_cell + j] !=
95 (*cell_to_vertex)[i * nbr_vertices_per_cell + j - 1])
96 (*cell_to_vertex)[new_size_cell_to_vertex++] =
97 (*cell_to_vertex)[i * nbr_vertices_per_cell + j];
99 (*num_vertices_per_cell)[i]--;
102 *cell_to_vertex =
xrealloc(*cell_to_vertex, new_size_cell_to_vertex *
103 sizeof(**cell_to_vertex));
112 size_t temp_nbr_cells;
120 char const * filename) {
127 double * x_vertices = NULL;
128 double * y_vertices = NULL;
129 double * x_cells = NULL;
130 double * y_cells = NULL;
134 &x_vertices, &y_vertices,
153 char const * filename,
char const * gridname) {
167 int * nbr_vertices_per_cell) {
175 int glon_dimids[NC_MAX_VAR_DIMS];
176 int glat_dimids[NC_MAX_VAR_DIMS];
189 nc_inq_var (ncid, glon_id, 0, &glon_type, &glon_ndims, glon_dimids, &nbr_atts));
192 nc_inq_var (ncid, glat_id, 0, &glat_type, &glat_ndims, glat_dimids, &nbr_atts));
196 glon_type == glat_type,
197 "ERROR(get_fesom_vertices): lon and lat datatypes do not match");
199 glon_ndims == 2 && glat_ndims == 2,
200 "ERROR(get_fesom_vertices): unsupported number of dimensions for lon or lat");
204 size_t dimlen_lat[2];
205 size_t dimlen_lon[2];
207 for (
int i = 0; i < 2; ++i) {
211 dimlen_lon[i] == dimlen_lat[i],
212 "ERROR(get_fesom_vertices): mismatching dimension size for lon and lat");
215 nbr_vertices = dimlen_lon[0] * dimlen_lon[1];
216 *nbr_cells = dimlen_lon[0];
217 *nbr_vertices_per_cell = dimlen_lon[1];
222 *vertex_lon = (
double * )
xmalloc ( nbr_vertices *
sizeof (
double ) );
223 *vertex_lat = (
double * )
xmalloc ( nbr_vertices *
sizeof (
double ) );
228 for (
size_t i = 0; i < nbr_vertices; ++i) {
239 size_t *nbr_cells ) {
247 int glon_dimids[NC_MAX_VAR_DIMS];
248 int glat_dimids[NC_MAX_VAR_DIMS];
259 nc_inq_var (ncid, glon_id, 0, &glon_type, &glon_ndims, glon_dimids, &nbr_atts));
261 nc_inq_var (ncid, glat_id, 0, &glat_type, &glat_ndims, glat_dimids, &nbr_atts));
265 glon_type == glat_type,
266 "ERROR(get_fesom_cell_center): lon and lat datatypes do not match");
268 glon_ndims == 1 && glat_ndims == 1,
269 "ERROR(get_fesom_cell_center): unsupported number of dimensions for lon or lat");
279 dimlen_lon == dimlen_lat,
280 "ERROR(get_fesom_cell_center): mismatching dimension size for lon and lat");
282 *nbr_cells = dimlen_lon;
286 *cell_lon = (
double * )
xmalloc ( *nbr_cells *
sizeof ( **cell_lon ) );
287 *cell_lat = (
double * )
xmalloc ( *nbr_cells *
sizeof ( **cell_lat ) );
292 for (
size_t i = 0; i < *nbr_cells; ++i) {
313 int lon_diff = fabs(a_->
p.
lon - b_->
p.
lon) > 1e-9;
314 int lat_diff = fabs(a_->
p.
lat - b_->
p.
lat) > 1e-9;
318 if (a_->
p.
lon > b_->
p.
lon)
return -1;
321 }
else if (lat_diff) {
323 if (a_->
p.
lat > b_->
p.
lat)
return -1;
330 double * temp_vertex_lat,
331 int * temp_nbr_vertices,
332 int * old_to_new_id) {
335 xmalloc(*temp_nbr_vertices *
sizeof(*sort_array));
337 for (
int i = 0;
i < *temp_nbr_vertices; ++
i) {
339 double curr_lon, curr_lat;
341 curr_lon = ((
double*)temp_vertex_lon)[
i];
342 curr_lat = ((
double*)temp_vertex_lat)[
i];
344 while (curr_lon < 0.0) curr_lon += 360.0;
345 while (curr_lon >= 360) curr_lon -= 360.0;
347 sort_array[
i].
p.
lon = curr_lon;
348 sort_array[
i].
p.
lat = curr_lat;
353 yac_mergesort(sort_array, *temp_nbr_vertices,
sizeof(*sort_array),
356 old_to_new_id[sort_array[0].
i] = 1;
358 int last_unique_idx = sort_array[0].
i;
360 for (
int i = 1;
i < *temp_nbr_vertices; ++
i) {
364 old_to_new_id[sort_array[
i].
i] = 1;
365 last_unique_idx = sort_array[
i].i;
369 old_to_new_id[sort_array[
i].
i] = -last_unique_idx;
375 size_t new_nbr_vertices = 0;
377 for (
int i = 0;
i < *temp_nbr_vertices; ++
i) {
379 if (old_to_new_id[
i] == 1) {
381 temp_vertex_lon[new_nbr_vertices] = temp_vertex_lon[
i];
382 temp_vertex_lat[new_nbr_vertices] = temp_vertex_lat[
i];
384 old_to_new_id[
i] = new_nbr_vertices;
390 for (
int i = 0;
i < *temp_nbr_vertices; ++
i)
391 if (old_to_new_id[
i] <= 0)
392 old_to_new_id[
i] = old_to_new_id[-old_to_new_id[
i]];
394 *temp_nbr_vertices = new_nbr_vertices;
400 char
const * filename) {
404 "ERROR(yac_read_fesom_basic_grid_data): "
405 "YAC is built without the NetCDF support");
409 (
size_t[]){0,0}, (
int[]){0,0}, NULL, NULL);
413 char const * filename,
char const * gridname) {
418 "ERROR(yac_read_fesom_basic_grid): "
419 "YAC is built without the NetCDF support");
425 int * nbr_cells,
int ** num_vertices_per_cell,
426 int ** cell_to_vertex,
double ** x_vertices,
427 double ** y_vertices,
double ** x_cells,
433 UNUSED(num_vertices_per_cell);
440 "ERROR(yac_read_fesom_grid_information): "
441 "YAC is built without the NetCDF support");
struct yac_basic_grid * yac_basic_grid_new(char const *name, struct yac_basic_grid_data grid_data)
struct yac_basic_grid_data yac_generate_basic_grid_data_reg_2d(size_t nbr_vertices[2], int cyclic[2], double *lon_vertices, double *lat_vertices)
struct yac_basic_grid_data yac_generate_basic_grid_data_unstruct(size_t nbr_vertices, size_t nbr_cells, int *num_vertices_per_cell, double *x_vertices, double *y_vertices, int *cell_to_vertex)
void yac_nc_inq_varid(int ncid, char const *name, int *varidp)
void yac_nc_open(const char *path, int omode, int *ncidp)
#define YAC_HANDLE_ERROR(exp)
void yac_mergesort(void *base, size_t num, size_t size, int(*compar)(const void *, const void *))
#define xrealloc(ptr, size)
static int compare_point_with_index(const void *a, const void *b)
static void remove_duplicated_vertices(double *temp_vertex_lon, double *temp_vertex_lat, int *temp_nbr_vertices, int *old_to_new_id)
void yac_read_fesom_grid_information(const char *filename, int *nbr_vertices, int *nbr_cells, int **num_vertices_per_cell, int **cell_to_vertex, double **x_vertices, double **y_vertices, double **x_cells, double **y_cells)
static void get_fesom_cell_center(int ncid, double **cell_lon, double **cell_lat, size_t *nbr_cells)
struct yac_basic_grid * yac_read_fesom_basic_grid(char const *filename, char const *gridname)
static void get_fesom_vertices(int ncid, double **vertex_lon, double **vertex_lat, int *nbr_cells, int *nbr_vertices_per_cell)
struct yac_basic_grid_data yac_read_fesom_basic_grid_data(char const *filename)
struct point_with_index::@66 p
int * num_vertices_per_cell
#define YAC_ASSERT(exp, msg)