YetAnotherCoupler 3.5.2
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
53 return -1;
54#else
55
56 int is_degree = 0;
57 nc_type att_type;
58 size_t att_len;
59 int status = nc_inq_att(ncid, varid, "units", &att_type, &att_len);
60 // if the status is not "attribute not found"
61 if (status != NC_ENOTATT) {
62 YAC_HANDLE_ERROR(status);
63 // if the attribute is not a string or too long
65 (att_type == NC_CHAR) && (att_len <= 8),
66 "ERROR(yac_check_coord_units): invalid units type or len")
67 char units[8];
68 memset(units, 0, 8 * sizeof(units[0]));
69 YAC_HANDLE_ERROR(nc_get_att_text(ncid, varid, "units", units));
70 is_degree = !strcmp(units, "degree");
72 is_degree || !strcmp(units, "radian"),
73 "ERROR(yac_check_coord_units): unsupported units type")
74 }
75 return is_degree;
76#endif
77}
78
79#ifdef YAC_NETCDF_ENABLED
80static double * read_coord(int ncid, int varid, size_t varlen) {
81
82 int is_degree = yac_check_coord_units(ncid, varid);
83
84 double * coord = xmalloc(varlen * sizeof(*coord));
85 YAC_HANDLE_ERROR(nc_get_var_double (ncid, varid, coord));
86
87 // convert to radiant if necessary
88 if (is_degree) for (size_t i = 0; i < varlen; ++i) coord[i] *= YAC_RAD;
89
90 return coord;
91}
92#endif
93
95 int ncid, char const * lon_name, char const * lat_name,
96 double ** lon, double ** lat, size_t * len) {
97
98#ifndef YAC_NETCDF_ENABLED
99
100 UNUSED(ncid);
101 UNUSED(lon_name);
102 UNUSED(lat_name);
103 UNUSED(lon);
104 UNUSED(lat);
105 UNUSED(len);
106 die("ERROR(yac_read_coords): YAC is built without the NetCDF support");
107#else
108
109 int vlonid, vlatid;
110 yac_nc_inq_varid(ncid, lon_name, &vlonid);
111 yac_nc_inq_varid(ncid, lat_name, &vlatid);
112
113 size_t varlen = (*len = check_dimension(ncid, (int[]){vlonid, vlatid}));
114 *lon = read_coord(ncid, vlonid, varlen);
115 *lat = read_coord(ncid, vlatid, varlen);
116#endif
117}
#define UNUSED(x)
Definition core.h:73
#define YAC_RAD
Definition geometry.h:30
void yac_nc_inq_varid(int ncid, char const *name, int *varidp)
Definition io_utils.c:411
#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:94
static double * read_coord(int ncid, int varid, size_t varlen)
Definition read_grid.c:80
#define die(msg)
Definition yac_assert.h:12
#define YAC_ASSERT(exp, msg)
Definition yac_assert.h:16