YetAnotherCoupler 3.2.0_a
Loading...
Searching...
No Matches
read_grid.c
Go to the documentation of this file.
1// Copyright (c) 2024 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#ifdef HAVE_CONFIG_H
6#include "config.h"
7#endif
8
9#ifdef YAC_NETCDF_ENABLED
10#include <netcdf.h>
11#endif
12
13#include <string.h>
14
15#include "geometry.h"
16#include "utils_common.h"
17#include "io_utils.h"
18
19#ifdef YAC_NETCDF_ENABLED
20static size_t check_dimension(int ncid, int varids[2]) {
21
22 for (int i = 0; i < 2; ++i) {
23 int ndims;
24 YAC_HANDLE_ERROR(nc_inq_varndims(ncid, varids[i], &ndims));
26 ndims == 1,
27 "ERROR(check_dimension): coordinate array has more than one dimension")
28 }
29
30 int dimids[2];
31 for (int i = 0; i < 2; ++i)
32 YAC_HANDLE_ERROR(nc_inq_vardimid(ncid, varids[i], &(dimids[i])));
33
35 dimids[0] == dimids[1],
36 "ERROR(check_dimension): "
37 "lon lat coordinate arrays have differing dimensions")
38
39 size_t dimlen;
40 YAC_HANDLE_ERROR(nc_inq_dimlen(ncid, dimids[0], &dimlen));
41 return dimlen;
42}
43#endif
44
45int yac_check_coord_units(int ncid, int varid) {
46
47#ifndef YAC_NETCDF_ENABLED
48
49 UNUSED(ncid);
50 UNUSED(varid);
51 die("ERROR(yac_check_coord_units): YAC is built without the NetCDF support");
52#else
53
54 int is_degree = 0;
55 nc_type att_type;
56 size_t att_len;
57 int status = nc_inq_att(ncid, varid, "units", &att_type, &att_len);
58 // if the status is not "attribute not found"
59 if (status != NC_ENOTATT) {
60 YAC_HANDLE_ERROR(status);
61 // if the attribute is not a string or too long
63 (att_type == NC_CHAR) && (att_len <= 8),
64 "ERROR(yac_check_coord_units): invalid units type or len")
65 char units[8];
66 memset(units, 0, 8 * sizeof(units[0]));
67 YAC_HANDLE_ERROR(nc_get_att_text(ncid, varid, "units", units));
68 is_degree = !strcmp(units, "degree");
70 is_degree || !strcmp(units, "radian"),
71 "ERROR(yac_check_coord_units): unsupported units type")
72 }
73 return is_degree;
74#endif
75}
76
77#ifdef YAC_NETCDF_ENABLED
78static double * read_coord(int ncid, int varid, size_t varlen) {
79
80 int is_degree = yac_check_coord_units(ncid, varid);
81
82 double * coord = xmalloc(varlen * sizeof(*coord));
83 YAC_HANDLE_ERROR(nc_get_var_double (ncid, varid, coord));
84
85 // convert to radiant if necessary
86 if (is_degree) for (size_t i = 0; i < varlen; ++i) coord[i] *= YAC_RAD;
87
88 return coord;
89}
90#endif
91
93 int ncid, char const * lon_name, char const * lat_name,
94 double ** lon, double ** lat, size_t * len) {
95
96#ifndef YAC_NETCDF_ENABLED
97
98 UNUSED(ncid);
99 UNUSED(lon_name);
100 UNUSED(lat_name);
101 UNUSED(lon);
102 UNUSED(lat);
103 UNUSED(len);
104 die("ERROR(yac_read_coords): YAC is built without the NetCDF support");
105#else
106
107 int vlonid, vlatid;
108 yac_nc_inq_varid(ncid, lon_name, &vlonid);
109 yac_nc_inq_varid(ncid, lat_name, &vlatid);
110
111 size_t varlen = (*len = check_dimension(ncid, (int[]){vlonid, vlatid}));
112 *lon = read_coord(ncid, vlonid, varlen);
113 *lat = read_coord(ncid, vlatid, varlen);
114#endif
115}
#define UNUSED(x)
Definition core.h:71
#define YAC_RAD
Definition geometry.h:30
void yac_nc_inq_varid(int ncid, char const *name, int *varidp)
Definition io_utils.c:403
#define YAC_HANDLE_ERROR(exp)
Definition io_utils.h:30
#define xmalloc(size)
Definition ppm_xfuncs.h:66
static size_t check_dimension(int ncid, int varids[2])
Definition read_grid.c:20
int yac_check_coord_units(int ncid, int varid)
Definition read_grid.c:45
void yac_read_coords(int ncid, char const *lon_name, char const *lat_name, double **lon, double **lat, size_t *len)
Definition read_grid.c:92
static double * read_coord(int ncid, int varid, size_t varlen)
Definition read_grid.c:78
#define die(msg)
Definition yac_assert.h:12
#define YAC_ASSERT(exp, msg)
Definition yac_assert.h:15