33 {
34
36
38
40
41 FILE *out;
42
44
45 static float u[16], v[16], w[16];
46
48
49
53
54
55 if (argc < 4 && argc % 2 != 0)
57 ("Give parameters: <ctl> <subgrid.tab> <met0> <met1> [ <met0> <met1> ... ]");
58
59
61
62
64
65
66 for (int i = 3; i < argc - 1; i += 2) {
67
68
69 if (!
read_met(argv[i], &ctl, clim, met0))
70 ERRMSG(
"Cannot open file!");
71 if (!
read_met(argv[i + 1], &ctl, clim, met1))
72 ERRMSG(
"Cannot open file!");
73
74
75 for (
int ix = 0; ix < met0->
nx - 1; ix++)
76 for (
int iy = 0; iy < met0->
ny - 1; iy++)
77 for (
int iz = 0; iz < met0->
np - 1; iz++) {
78
79
80 u[0] = met0->
u[ix][iy][iz];
81 u[1] = met0->
u[ix + 1][iy][iz];
82 u[2] = met0->
u[ix][iy + 1][iz];
83 u[3] = met0->
u[ix + 1][iy + 1][iz];
84 u[4] = met0->
u[ix][iy][iz + 1];
85 u[5] = met0->
u[ix + 1][iy][iz + 1];
86 u[6] = met0->
u[ix][iy + 1][iz + 1];
87 u[7] = met0->
u[ix + 1][iy + 1][iz + 1];
88
89 v[0] = met0->
v[ix][iy][iz];
90 v[1] = met0->
v[ix + 1][iy][iz];
91 v[2] = met0->
v[ix][iy + 1][iz];
92 v[3] = met0->
v[ix + 1][iy + 1][iz];
93 v[4] = met0->
v[ix][iy][iz + 1];
94 v[5] = met0->
v[ix + 1][iy][iz + 1];
95 v[6] = met0->
v[ix][iy + 1][iz + 1];
96 v[7] = met0->
v[ix + 1][iy + 1][iz + 1];
97
98 w[0] = (float) (1e3 *
DP2DZ(met0->
w[ix][iy][iz], met0->
p[iz]));
99 w[1] = (float) (1e3 *
DP2DZ(met0->
w[ix + 1][iy][iz], met0->
p[iz]));
100 w[2] = (float) (1e3 *
DP2DZ(met0->
w[ix][iy + 1][iz], met0->
p[iz]));
101 w[3] =
102 (float) (1e3 *
DP2DZ(met0->
w[ix + 1][iy + 1][iz], met0->
p[iz]));
103 w[4] =
104 (float) (1e3 *
DP2DZ(met0->
w[ix][iy][iz + 1], met0->
p[iz + 1]));
105 w[5] =
106 (float) (1e3 *
107 DP2DZ(met0->
w[ix + 1][iy][iz + 1], met0->
p[iz + 1]));
108 w[6] =
109 (float) (1e3 *
110 DP2DZ(met0->
w[ix][iy + 1][iz + 1], met0->
p[iz + 1]));
111 w[7] =
112 (float) (1e3 *
113 DP2DZ(met0->
w[ix + 1][iy + 1][iz + 1], met0->
p[iz + 1]));
114
115
116 u[8] = met1->
u[ix][iy][iz];
117 u[9] = met1->
u[ix + 1][iy][iz];
118 u[10] = met1->
u[ix][iy + 1][iz];
119 u[11] = met1->
u[ix + 1][iy + 1][iz];
120 u[12] = met1->
u[ix][iy][iz + 1];
121 u[13] = met1->
u[ix + 1][iy][iz + 1];
122 u[14] = met1->
u[ix][iy + 1][iz + 1];
123 u[15] = met1->
u[ix + 1][iy + 1][iz + 1];
124
125 v[8] = met1->
v[ix][iy][iz];
126 v[9] = met1->
v[ix + 1][iy][iz];
127 v[10] = met1->
v[ix][iy + 1][iz];
128 v[11] = met1->
v[ix + 1][iy + 1][iz];
129 v[12] = met1->
v[ix][iy][iz + 1];
130 v[13] = met1->
v[ix + 1][iy][iz + 1];
131 v[14] = met1->
v[ix][iy + 1][iz + 1];
132 v[15] = met1->
v[ix + 1][iy + 1][iz + 1];
133
134 w[8] = (float) (1e3 *
DP2DZ(met1->
w[ix][iy][iz], met1->
p[iz]));
135 w[9] = (float) (1e3 *
DP2DZ(met1->
w[ix + 1][iy][iz], met1->
p[iz]));
136 w[10] = (float) (1e3 *
DP2DZ(met1->
w[ix][iy + 1][iz], met1->
p[iz]));
137 w[11] =
138 (float) (1e3 *
DP2DZ(met1->
w[ix + 1][iy + 1][iz], met1->
p[iz]));
139 w[12] =
140 (float) (1e3 *
DP2DZ(met1->
w[ix][iy][iz + 1], met1->
p[iz + 1]));
141 w[13] =
142 (float) (1e3 *
143 DP2DZ(met1->
w[ix + 1][iy][iz + 1], met1->
p[iz + 1]));
144 w[14] =
145 (float) (1e3 *
146 DP2DZ(met1->
w[ix][iy + 1][iz + 1], met1->
p[iz + 1]));
147 w[15] =
148 (float) (1e3 *
149 DP2DZ(met1->
w[ix + 1][iy + 1][iz + 1], met1->
p[iz + 1]));
150
151
152 usig[iz][iy] +=
stddev(u, 16);
153 vsig[iz][iy] +=
stddev(v, 16);
154 wsig[iz][iy] +=
stddev(w, 16);
155 n[iz][iy]++;
156
157
158 if (met0->
p[iz] > met0->
ps[ix][iy]
159 || met1->
p[iz] > met1->
ps[ix][iy]) {
160 usig[iz][iy] = NAN;
161 vsig[iz][iy] = NAN;
162 wsig[iz][iy] = NAN;
163 n[iz][iy] = 0;
164 }
165 }
166 }
167
168
169 LOG(1,
"Write subgrid data file: %s", argv[2]);
170 if (!(out = fopen(argv[2], "w")))
171 ERRMSG(
"Cannot create file!");
172
173
174 fprintf(out,
175 "# $1 = time [s]\n"
176 "# $2 = altitude [km]\n"
177 "# $3 = longitude [deg]\n"
178 "# $4 = latitude [deg]\n"
179 "# $5 = zonal wind standard deviation [m/s]\n"
180 "# $6 = meridional wind standard deviation [m/s]\n"
181 "# $7 = vertical velocity standard deviation [m/s]\n"
182 "# $8 = number of data points\n");
183
184
185 for (
int iy = 0; iy < met0->
ny - 1; iy++) {
186 fprintf(out, "\n");
187 for (
int iz = 0; iz < met0->
np - 1; iz++)
188 fprintf(out, "%.2f %g %g %g %g %g %g %d\n",
190 0.5 * (
Z(met0->
p[iz]) +
Z(met1->
p[iz + 1])),
191 0.0, 0.5 * (met0->
lat[iy] + met1->
lat[iy + 1]),
192 usig[iz][iy] / n[iz][iy], vsig[iz][iy] / n[iz][iy],
193 wsig[iz][iy] / n[iz][iy], n[iz][iy]);
194 }
195
196
197 fclose(out);
198
199
200 free(clim);
201 free(met0);
202 free(met1);
203
204 return EXIT_SUCCESS;
205}
float stddev(const float *data, const int n)
Calculates the standard deviation of a set of data.
void read_ctl(const char *filename, int argc, char *argv[], ctl_t *ctl)
Reads control parameters from a configuration file and populates the given structure.
int read_met(const char *filename, ctl_t *ctl, clim_t *clim, met_t *met)
Reads meteorological data from a file, supporting multiple formats and MPI broadcasting.
void read_clim(const ctl_t *ctl, clim_t *clim)
Reads various climatological data and populates the given climatology structure.
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
#define EY
Maximum number of latitudes for meteo data.
#define Z(p)
Convert pressure to altitude.
#define DP2DZ(dp, p)
Convert a pressure difference to a height difference in the vertical direction.
#define ALLOC(ptr, type, n)
Allocate memory for a pointer with error handling.
#define LOG(level,...)
Print a log message with a specified logging level.
#define EP
Maximum number of pressure levels for meteo data.
float w[EX][EY][EP]
Vertical velocity [hPa/s].
int nx
Number of longitudes.
int ny
Number of latitudes.
float ps[EX][EY]
Surface pressure [hPa].
int np
Number of pressure levels.
float u[EX][EY][EP]
Zonal wind [m/s].
float v[EX][EY][EP]
Meridional wind [m/s].
double lat[EY]
Latitude [deg].
double p[EP]
Pressure levels [hPa].