YAC 3.21.0
Yet Another Coupler
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, "coordinate array has more than one dimension")
27 }
28
29 int dimids[2];
30 for (int i = 0; i < 2; ++i)
31 YAC_HANDLE_ERROR(nc_inq_vardimid(ncid, varids[i], &(dimids[i])));
32
34 dimids[0] == dimids[1],
35 "lon lat coordinate arrays have differing dimensions")
36
37 size_t dimlen;
38 YAC_HANDLE_ERROR(nc_inq_dimlen(ncid, dimids[0], &dimlen));
39 return dimlen;
40}
41#endif
42
43int yac_check_coord_units(int ncid, int varid) {
44
45#ifndef YAC_NETCDF_ENABLED
46
47 UNUSED(ncid);
48 UNUSED(varid);
49 die("ERROR(yac_check_coord_units): YAC is built without the NetCDF support");
50
51 return -1;
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), "invalid units type or len")
64 char units[8];
65 memset(units, 0, 8 * sizeof(units[0]));
66 YAC_HANDLE_ERROR(nc_get_att_text(ncid, varid, "units", units));
67 is_degree = !strcmp(units, "degree");
69 is_degree || !strcmp(units, "radian"), "unsupported units type")
70 }
71 return is_degree;
72#endif
73}
74
75#ifdef YAC_NETCDF_ENABLED
76static double * read_coord(int ncid, int varid, size_t varlen) {
77
78 int is_degree = yac_check_coord_units(ncid, varid);
79
80 double * coord = xmalloc(varlen * sizeof(*coord));
81 YAC_HANDLE_ERROR(nc_get_var_double (ncid, varid, coord));
82
83 // convert to radiant if necessary
84 if (is_degree) for (size_t i = 0; i < varlen; ++i) coord[i] *= YAC_RAD;
85
86 return coord;
87}
88#endif
89
91 int ncid, char const * lon_name, char const * lat_name,
92 double ** lon, double ** lat, size_t * len) {
93
94#ifndef YAC_NETCDF_ENABLED
95
96 UNUSED(ncid);
97 UNUSED(lon_name);
98 UNUSED(lat_name);
99 UNUSED(lon);
100 UNUSED(lat);
101 UNUSED(len);
102 die("ERROR(yac_read_coords): YAC is built without the NetCDF support");
103#else
104
105 int vlonid, vlatid;
106 yac_nc_inq_varid(ncid, lon_name, &vlonid);
107 yac_nc_inq_varid(ncid, lat_name, &vlatid);
108
109 size_t varlen = (*len = check_dimension(ncid, (int[]){vlonid, vlatid}));
110 *lon = read_coord(ncid, vlonid, varlen);
111 *lat = read_coord(ncid, vlatid, varlen);
112#endif
113}
#define YAC_ASSERT(exp, msg)
#define UNUSED(x)
Definition core.h:72
#define YAC_RAD
void yac_nc_inq_varid(int ncid, char const *name, int *varidp)
Definition io_utils.c:369
#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:43
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:90
static double * read_coord(int ncid, int varid, size_t varlen)
Definition read_grid.c:76
#define YAC_HANDLE_ERROR(exp)
Definition toy_output.c:13
#define die(msg)
Definition yac_assert.h:14