35static uint64_t rng_ctr;
39static curandGenerator_t rng_curand;
49#define CHUNK_SIZE 2147483647
52 MPI_Bcast(&N, 1, MPI_UINT64_T, 0, MPI_COMM_WORLD);
55 const size_t num_chunks = (N + CHUNK_SIZE - 1) / CHUNK_SIZE;
58 for (
size_t i = 0; i < num_chunks; i++) {
61 const size_t start = i * CHUNK_SIZE;
62 const size_t end = (start + CHUNK_SIZE > N) ? N : start + CHUNK_SIZE;
63 const size_t chunk_size = end - start;
66 MPI_Bcast((
char *) data + start, (
int) chunk_size, MPI_BYTE, 0,
80 const double radius =
NORM(x);
82 *lat =
RAD2DEG(asin(x[2] / radius));
83 *lon =
RAD2DEG(atan2(x[1], x[0]));
98 const double sza_thresh =
DEG2RAD(85.), cos_sza_thresh = cos(sza_thresh);
101 const double oh =
clim_zm(&clim->
oh, t, lat, p);
106 if (sza <= sza_thresh)
121 const double sza_thresh =
DEG2RAD(85.), cos_sza_thresh = cos(sza_thresh);
124 for (
int it = 0; it < clim->
oh.
ntime; it++)
125 for (
int iz = 0; iz < clim->
oh.
np; iz++)
126 for (
int iy = 0; iy < clim->
oh.
nlat; iy++) {
133 for (
double lon = -180; lon < 180; lon += 1.0) {
135 if (sza <= sza_thresh)
143 clim->
oh.
vmr[it][iz][iy] /= (sum / (double) n);
158 if (p < photo->p[photo->
np - 1])
159 p_help = photo->
p[photo->
np - 1];
160 else if (p > photo->
p[0])
161 p_help = photo->
p[0];
164 double sza_help = sza;
165 if (sza < photo->sza[0])
166 sza_help = photo->
sza[0];
167 else if (sza > photo->
sza[photo->
nsza - 1])
168 sza_help = photo->
sza[photo->
nsza - 1];
171 double o3c_help = o3c;
172 if (o3c < photo->o3c[0])
173 o3c_help = photo->
o3c[0];
174 else if (o3c > photo->
o3c[photo->
no3c - 1])
175 o3c_help = photo->
o3c[photo->
no3c - 1];
183 double aux00 =
LIN(photo->
p[ip], rate[ip][isza][io3c],
184 photo->
p[ip + 1], rate[ip + 1][isza][io3c], p_help);
185 double aux01 =
LIN(photo->
p[ip], rate[ip][isza][io3c + 1],
186 photo->
p[ip + 1], rate[ip + 1][isza][io3c + 1], p_help);
187 double aux10 =
LIN(photo->
p[ip], rate[ip][isza + 1][io3c],
188 photo->
p[ip + 1], rate[ip + 1][isza + 1][io3c], p_help);
189 double aux11 =
LIN(photo->
p[ip], rate[ip][isza + 1][io3c + 1],
190 photo->
p[ip + 1], rate[ip + 1][isza + 1][io3c + 1],
192 aux00 =
LIN(photo->
o3c[io3c], aux00, photo->
o3c[io3c + 1], aux01, o3c_help);
193 aux11 =
LIN(photo->
o3c[io3c], aux10, photo->
o3c[io3c + 1], aux11, o3c_help);
194 aux00 =
LIN(photo->
sza[isza], aux00, photo->
sza[isza + 1], aux11, sza_help);
195 return MAX(aux00, 0.0);
206 double sec =
FMOD(t, 365.25 * 86400.);
208 sec += 365.25 * 86400.;
216 clim->
tropo[isec][ilat],
218 clim->
tropo[isec][ilat + 1], lat);
220 clim->
tropo[isec + 1][ilat],
222 clim->
tropo[isec + 1][ilat + 1], lat);
232 LOG(1,
"Initialize tropopause data...");
236 double tropo_time[12] = {
237 1209600.00, 3888000.00, 6393600.00,
238 9072000.00, 11664000.00, 14342400.00,
239 16934400.00, 19612800.00, 22291200.00,
240 24883200.00, 27561600.00, 30153600.00
246 double tropo_lat[73] = {
247 -90, -87.5, -85, -82.5, -80, -77.5, -75, -72.5, -70, -67.5,
248 -65, -62.5, -60, -57.5, -55, -52.5, -50, -47.5, -45, -42.5,
249 -40, -37.5, -35, -32.5, -30, -27.5, -25, -22.5, -20, -17.5,
250 -15, -12.5, -10, -7.5, -5, -2.5, 0, 2.5, 5, 7.5, 10, 12.5,
251 15, 17.5, 20, 22.5, 25, 27.5, 30, 32.5, 35, 37.5, 40, 42.5,
252 45, 47.5, 50, 52.5, 55, 57.5, 60, 62.5, 65, 67.5, 70, 72.5,
253 75, 77.5, 80, 82.5, 85, 87.5, 90
258 double tropo[12][73] = {
259 {324.1, 325.6, 325, 324.3, 322.5, 319.7, 314, 307.2, 301.8, 299.6,
260 297.1, 292.2, 285.6, 276.1, 264, 248.9, 231.9, 213.5, 194.4,
261 175.3, 157, 140.4, 126.7, 116.3, 109.5, 105.4, 103, 101.4, 100.4,
262 99.69, 99.19, 98.84, 98.56, 98.39, 98.39, 98.42, 98.44, 98.54,
263 98.68, 98.81, 98.89, 98.96, 99.12, 99.65, 101.4, 105.4, 113.5, 128,
264 152.1, 184.7, 214, 234.1, 247.3, 255.8, 262.6, 267.7, 271.7, 275,
265 277.2, 279, 280.1, 280.4, 280.6, 280.1, 279.3, 278.3, 276.8, 275.8,
266 275.3, 275.6, 275.4, 274.1, 273.5},
267 {337.3, 338.7, 337.8, 336.4, 333, 328.8, 321.1, 312.6, 306.6, 303.7,
268 300.2, 293.8, 285.4, 273.8, 259.6, 242.7, 224.4, 205.2, 186, 167.5,
269 150.3, 135, 122.8, 113.9, 108.2, 104.7, 102.5, 101.1, 100.2, 99.42,
270 98.88, 98.52, 98.25, 98.09, 98.07, 98.1, 98.12, 98.2, 98.25, 98.27,
271 98.26, 98.27, 98.36, 98.79, 100.2, 104.2, 113.7, 131.2, 159.5, 193,
272 220.4, 238.1, 250.2, 258.1, 264.7, 269.7, 273.7, 277.3, 280.2, 282.8,
273 284.9, 286.5, 288.1, 288.8, 289, 288.5, 287.2, 286.3, 286.1, 287.2,
274 287.5, 286.2, 285.8},
275 {335, 336, 335.7, 335.1, 332.3, 328.1, 320.6, 311.8, 305.1, 301.9,
276 297.6, 290, 280.4, 268.3, 254.6, 239.6, 223.9, 207.9, 192.2, 176.9,
277 161.7, 146.4, 132.2, 120.6, 112.3, 107.2, 104.3, 102.4, 101.3,
278 100.4, 99.86, 99.47, 99.16, 98.97, 98.94, 98.97, 99, 99.09, 99.2,
279 99.31, 99.35, 99.41, 99.51, 99.86, 101.1, 104.9, 114.3, 131, 156.8,
280 186.3, 209.3, 224.6, 236.8, 246.3, 254.9, 262.3, 268.8, 274.8,
281 279.9, 284.6, 288.6, 291.6, 294.9, 297.5, 299.8, 301.8, 303.1,
282 304.3, 304.9, 306, 306.6, 306.2, 306},
283 {306.2, 306.7, 305.7, 307.1, 307.3, 306.4, 301.8, 296.2, 292.4,
284 290.3, 287.1, 280.9, 273.4, 264.3, 254.1, 242.8, 231, 219, 207.2,
285 195.5, 183.3, 169.7, 154.7, 138.7, 124.1, 113.6, 107.8, 104.7,
286 102.8, 101.7, 100.9, 100.4, 100, 99.79, 99.7, 99.66, 99.68, 99.79,
287 99.94, 100.2, 100.5, 100.9, 101.4, 102.1, 103.4, 107, 115.2, 129.1,
288 148.7, 171, 190.8, 205.6, 218.4, 229.4, 239.6, 248.6, 256.5,
289 263.7, 270.3, 276.6, 282.6, 288.1, 294.5, 300.4, 306.3, 311.4,
290 315.1, 318.3, 320.3, 322.2, 322.8, 321.5, 321.1},
291 {266.5, 264.9, 260.8, 261, 262, 263, 261.3, 259.7, 259.2, 259.8,
292 260.1, 258.6, 256.7, 253.6, 249.5, 243.9, 237.4, 230, 222.1, 213.9,
293 205, 194.4, 180.4, 161.8, 140.7, 122.9, 112.1, 106.7, 104.1, 102.7,
294 101.8, 101.4, 101.1, 101, 101, 101, 101.1, 101.2, 101.5, 101.9,
295 102.4, 103, 103.8, 104.9, 106.8, 110.1, 115.6, 124, 135.2, 148.9,
296 165.2, 181.3, 198, 211.8, 223.5, 233.8, 242.9, 251.5, 259, 266.2,
297 273.1, 279.2, 286.2, 292.8, 299.6, 306, 311.1, 315.5, 318.8, 322.6,
298 325.3, 325.8, 325.8},
299 {220.1, 218.1, 210.8, 207.2, 207.6, 210.5, 211.4, 213.5, 217.3,
300 222.4, 227.9, 232.8, 237.4, 240.8, 242.8, 243, 241.5, 238.6, 234.2,
301 228.5, 221, 210.7, 195.1, 172.9, 147.8, 127.6, 115.6, 109.9, 107.1,
302 105.7, 105, 104.8, 104.8, 104.9, 105, 105.1, 105.3, 105.5, 105.8,
303 106.4, 107, 107.6, 108.1, 108.8, 110, 111.8, 114.2, 117.4, 121.6,
304 127.9, 137.3, 151.2, 169.5, 189, 205.8, 218.9, 229.1, 237.8, 245,
305 251.5, 257.1, 262.3, 268.2, 274, 280.4, 286.7, 292.4, 297.9, 302.9,
306 308.5, 312.2, 313.1, 313.3},
307 {187.4, 184.5, 173.3, 166.1, 165.4, 167.8, 169.6, 173.6, 179.6,
308 187.9, 198.9, 210, 220.5, 229.2, 235.7, 239.9, 241.8, 241.6, 239.6,
309 235.8, 229.4, 218.6, 200.9, 175.9, 149.4, 129.4, 118.3, 113.1,
310 110.8, 109.7, 109.3, 109.4, 109.7, 110, 110.2, 110.4, 110.5, 110.7,
311 111, 111.4, 111.8, 112.1, 112.3, 112.7, 113.2, 113.9, 115, 116.4,
312 117.9, 120.4, 124.1, 130.9, 142.2, 159.6, 179.6, 198.5, 212.9,
313 224.2, 232.7, 239.1, 243.8, 247.7, 252.4, 257.3, 263.2, 269.5,
314 275.4, 281.1, 286.3, 292, 296.3, 298.2, 298.8},
315 {166, 166.4, 155.7, 148.3, 147.1, 149, 152.1, 157, 163.6, 172.4,
316 185.3, 199.2, 212.6, 224, 233.2, 239.6, 243.3, 244.6, 243.6, 240.3,
317 233.9, 222.6, 203.7, 177, 149.5, 129.7, 119, 114, 111.7, 110.7,
318 110.3, 110.3, 110.6, 110.9, 111.1, 111.3, 111.5, 111.6, 111.9,
319 112.2, 112.5, 112.6, 112.8, 113, 113.4, 114, 115.1, 116.5, 118.3,
320 120.9, 124.4, 130.2, 139.4, 154.6, 173.8, 193.1, 208.1, 220.4,
321 230.1, 238.2, 244.7, 249.5, 254.5, 259.3, 264.5, 269.4, 273.7,
322 278.2, 282.6, 287.4, 290.9, 292.5, 293},
323 {171.9, 172.8, 166.2, 162.3, 161.4, 162.5, 165.2, 169.6, 175.3,
324 183.1, 193.8, 205.9, 218.3, 229.6, 238.5, 244.3, 246.9, 246.7,
325 243.8, 238.4, 230.2, 217.9, 199.6, 174.9, 148.9, 129.8, 119.5,
326 114.8, 112.3, 110.9, 110.3, 110.1, 110.2, 110.3, 110.4, 110.5,
327 110.6, 110.8, 111, 111.4, 111.8, 112, 112.2, 112.4, 112.9, 113.6,
328 114.7, 116.3, 118.4, 121.9, 127.1, 136.1, 149.8, 168.4, 186.9,
329 203.3, 217, 229.1, 238.7, 247, 254, 259.3, 264.3, 268.3, 272.5,
330 276.6, 280.4, 284.4, 288.4, 293.3, 297.2, 298.7, 299.1},
331 {191.6, 192.2, 189, 188.1, 190.2, 193.7, 197.8, 202.9, 208.5,
332 215.6, 224.2, 233.1, 241.2, 247.3, 250.8, 251.3, 248.9, 244.2,
333 237.3, 228.4, 217.2, 202.9, 184.5, 162.5, 140.7, 124.8, 116.2,
334 111.8, 109.4, 107.9, 107, 106.7, 106.6, 106.6, 106.7, 106.7,
335 106.8, 107, 107.4, 108, 108.7, 109.3, 109.8, 110.4, 111.2,
336 112.4, 114.2, 116.9, 121.1, 127.9, 139.3, 155.2, 173.6, 190.7,
337 206.1, 220.1, 232.3, 243, 251.8, 259.2, 265.7, 270.6, 275.3,
338 279.3, 283.3, 286.9, 289.7, 292.8, 296.1, 300.5, 303.9, 304.8,
340 {241.5, 239.6, 236.8, 237.4, 239.4, 242.3, 244.2, 246.4, 249.2,
341 253.6, 258.6, 262.7, 264.8, 264.2, 260.6, 254.1, 245.5, 235.3,
342 223.9, 211.7, 198.3, 183.1, 165.6, 147.1, 130.5, 118.7, 111.9,
343 108.1, 105.8, 104.3, 103.4, 102.8, 102.5, 102.4, 102.5, 102.5,
344 102.5, 102.7, 103.1, 103.8, 104.6, 105.4, 106.1, 107, 108.2,
345 109.9, 112.8, 117.5, 126, 140.4, 161, 181.9, 201.2, 216.8, 230.4,
346 241.8, 251.4, 259.9, 266.9, 272.8, 277.4, 280.4, 282.9, 284.6,
347 286.1, 287.4, 288.3, 289.5, 290.9, 294.2, 296.9, 297.5, 297.6},
348 {301.2, 300.3, 296.6, 295.4, 295, 294.3, 291.2, 287.4, 284.9, 284.7,
349 284.1, 281.5, 277.1, 270.4, 261.7, 250.6, 237.6, 223.1, 207.9, 192,
350 175.8, 158.8, 142.1, 127.6, 116.8, 109.9, 106, 103.6, 102.1, 101.1,
351 100.4, 99.96, 99.6, 99.37, 99.32, 99.32, 99.31, 99.46, 99.77, 100.2,
352 100.7, 101.3, 101.8, 102.7, 104.1, 106.8, 111.9, 121, 136.7, 160,
353 186.9, 209.9, 228.1, 241.2, 251.5, 259.5, 265.7, 270.9, 274.8, 278,
354 280.3, 281.8, 283, 283.3, 283.7, 283.8, 283, 282.2, 281.2, 281.4,
357 memcpy(clim->
tropo, tropo,
sizeof(clim->
tropo));
360 double tropomin = 1e99, tropomax = -1e99;
362 for (
int iy = 0; iy < clim->
tropo_nlat; iy++) {
363 tropomin =
MIN(tropomin, clim->
tropo[it][iy]);
364 tropomax =
MAX(tropomax, clim->
tropo[it][iy]);
369 LOG(2,
"Time steps: %.2f, %.2f ... %.2f s",
373 LOG(2,
"Latitudes: %g, %g ... %g deg",
376 LOG(2,
"Tropopause altitude range: %g ... %g hPa",
Z(tropomax),
378 LOG(2,
"Tropopause pressure range: %g ... %g hPa", tropomin, tropomax);
388 if (t <= ts->time[0])
395 ts->
time[idx + 1], ts->
vmr[idx + 1], t);
408 double sec =
FMOD(t, 365.25 * 86400.);
410 sec += 365.25 * 86400.;
414 if (p < zm->p[zm->
np - 1])
415 p_help = zm->
p[zm->
np - 1];
416 else if (p > zm->
p[0])
420 double lat_help = lat;
421 if (lat < zm->lat[0])
422 lat_help = zm->
lat[0];
423 else if (lat > zm->
lat[zm->
nlat - 1])
424 lat_help = zm->
lat[zm->
nlat - 1];
432 double aux00 =
LIN(zm->
p[ip], zm->
vmr[isec][ip][ilat],
433 zm->
p[ip + 1], zm->
vmr[isec][ip + 1][ilat], p_help);
434 double aux01 =
LIN(zm->
p[ip], zm->
vmr[isec][ip][ilat + 1],
435 zm->
p[ip + 1], zm->
vmr[isec][ip + 1][ilat + 1], p_help);
436 double aux10 =
LIN(zm->
p[ip], zm->
vmr[isec + 1][ip][ilat],
437 zm->
p[ip + 1], zm->
vmr[isec + 1][ip + 1][ilat], p_help);
438 double aux11 =
LIN(zm->
p[ip], zm->
vmr[isec + 1][ip][ilat + 1],
439 zm->
p[ip + 1], zm->
vmr[isec + 1][ip + 1][ilat + 1],
441 aux00 =
LIN(zm->
lat[ilat], aux00, zm->
lat[ilat + 1], aux01, lat_help);
442 aux11 =
LIN(zm->
lat[ilat], aux10, zm->
lat[ilat + 1], aux11, lat_help);
443 aux00 =
LIN(zm->
time[isec], aux00, zm->
time[isec + 1], aux11, sec);
445 return MAX(aux00, 0.0);
458 const int decompress,
462 const size_t nxy = nx * ny;
463 double lon[
EX], lat[
EY];
464 for (
size_t ix = 0; ix < nx; ix++)
465 lon[ix] = 360. * (
double) ix / ((double) nx - 1.);
466 for (
size_t iy = 0; iy < ny; iy++)
467 lat[iy] = -(180. * (
double) iy / ((double) ny - 1.) - 90.);
470 const char domain[] =
"[0.0, 360.0]x[-90.0, 90.0]";
471 const int Nd0_x = 48;
472 const int Nd0_y = 24;
473 const int max_level_grid = 6;
474 cms_param_t *cms_param
475 = cms_set_parameters(nx, ny, max_level_grid, Nd0_x, Nd0_y, domain);
478 double cr = 0, t_coars = 0, t_eval = 0;
484 for (
size_t ip = 0; ip < np; ip++) {
487 cms_module_t *cms_ptr = cms_init(cms_param);
492 cms_sol = cms_read_zstd_sol(cms_ptr, inout);
494 cms_sol = cms_read_sol(cms_ptr, inout);
497#pragma omp parallel for default(shared)
498 for (
size_t ix = 0; ix < nx; ix++)
499 for (
size_t iy = 0; iy < ny; iy++) {
501 const double x[] = { lon[ix], lat[iy] };
502 cms_eval(cms_ptr, cms_sol, x, &val);
503 array[
ARRAY_3D(ix, iy, ny, ip, np)] = (float) val;
507 cr += cms_compression_rate(cms_ptr, cms_sol) / (double) np;
510 cms_delete_sol(cms_sol);
511 cms_delete_module(cms_ptr);
515 LOG(2,
"Read 3-D variable: %s (cms, RATIO= %g)", varname, cr);
522 cms_module_t *cms_ptr[
EP];
523 cms_sol_t *cms_sol[
EP];
527 ? (size_t) omp_get_max_threads()
529 for (
size_t ip0 = 0; ip0 < np; ip0 += dip) {
532 double t0 = omp_get_wtime();
535#pragma omp parallel for default(shared)
536 for (
size_t ip = ip0; ip <
MIN(ip0 + dip, np); ip++) {
540 ALLOC(tmp_arr,
float,
544 for (
size_t ix = 0; ix < nx; ++ix)
545 for (
size_t iy = 0; iy < ny; ++iy)
547 array[
ARRAY_3D(ix, iy, ny, ip, np)];
550 double c_thresh_test;
551 if (strcasecmp(varname,
"Z") == 0)
553 else if (strcasecmp(varname,
"T") == 0)
555 else if (strcasecmp(varname,
"U") == 0)
557 else if (strcasecmp(varname,
"V") == 0)
559 else if (strcasecmp(varname,
"W") == 0)
561 else if (strcasecmp(varname,
"PV") == 0)
563 else if (strcasecmp(varname,
"H2O") == 0)
565 else if (strcasecmp(varname,
"O3") == 0)
567 else if (strcasecmp(varname,
"LWC") == 0)
569 else if (strcasecmp(varname,
"RWC") == 0)
571 else if (strcasecmp(varname,
"IWC") == 0)
573 else if (strcasecmp(varname,
"SWC") == 0)
575 else if (strcasecmp(varname,
"CC") == 0)
578 ERRMSG(
"Variable name unknown!");
581 cms_ptr[ip] = cms_init(cms_param);
585 cms_read_arr_new(cms_ptr[ip], tmp_arr, lon, lat,
586 nx, ny, c_thresh_test);
590 cms_ptr[ip] = cms_init(cms_param);
593 cms_sol[ip] = cms_read_arr(cms_ptr[ip], tmp_arr, lon, lat, nx, ny);
596 if (strcasecmp(varname,
"Z") == 0)
598 else if (strcasecmp(varname,
"T") == 0)
600 else if (strcasecmp(varname,
"U") == 0)
602 else if (strcasecmp(varname,
"V") == 0)
604 else if (strcasecmp(varname,
"W") == 0)
606 else if (strcasecmp(varname,
"PV") == 0)
608 else if (strcasecmp(varname,
"H2O") == 0)
610 else if (strcasecmp(varname,
"O3") == 0)
612 else if (strcasecmp(varname,
"LWC") == 0)
614 else if (strcasecmp(varname,
"RWC") == 0)
616 else if (strcasecmp(varname,
"IWC") == 0)
618 else if (strcasecmp(varname,
"SWC") == 0)
620 else if (strcasecmp(varname,
"CC") == 0)
623 ERRMSG(
"Variable name unknown!");
626 cms_coarsening(cms_ptr[ip], cms_sol[ip],
635 t_coars += (omp_get_wtime() - t0);
638 for (
size_t ip = ip0; ip <
MIN(ip0 + dip, np); ip++) {
641 double *tmp_cms, *tmp_org, *tmp_diff;
642 ALLOC(tmp_cms,
double,
644 ALLOC(tmp_org,
double,
646 ALLOC(tmp_diff,
double,
650 t0 = omp_get_wtime();
653#pragma omp parallel for default(shared)
654 for (
size_t ix = 0; ix < nx; ix++)
655 for (
size_t iy = 0; iy < ny; iy++) {
656 const size_t idx =
ARRAY_2D(ix, iy, ny);
657 const double x[] = { lon[ix], lat[iy] };
658 cms_eval(cms_ptr[ip], cms_sol[ip], x, &tmp_cms[idx]);
659 tmp_org[idx] = array[
ARRAY_3D(ix, iy, ny, ip, np)];
660 tmp_diff[idx] = tmp_cms[idx] - tmp_org[idx];
664 t_eval += (omp_get_wtime() - t0);
668 "cmultiscale: var= %s / lev= %lu / ratio= %g / rho= %g"
669 " / mean= %g / sd= %g / min= %g / max= %g", varname, ip,
670 cms_compression_rate(cms_ptr[ip], cms_sol[ip]),
671 gsl_stats_correlation(tmp_cms, 1, tmp_org, 1, nxy),
672 gsl_stats_mean(tmp_diff, 1, nxy), gsl_stats_sd(tmp_diff, 1, nxy),
673 gsl_stats_min(tmp_diff, 1, nxy), gsl_stats_max(tmp_diff, 1, nxy));
676 cr += cms_compression_rate(cms_ptr[ip], cms_sol[ip]) / (double) np;
680 cms_save_zstd_sol(cms_sol[ip], inout, 3);
682 cms_save_sol(cms_sol[ip], inout);
685 cms_delete_sol(cms_sol[ip]);
686 cms_delete_module(cms_ptr[ip]);
694 LOG(2,
"Write 3-D variable: %s"
695 " (cms, RATIO= %g, T_COARS= %g s, T_EVAL= %g s)",
696 varname, cr, t_coars, t_eval);
700 cms_delete_param(cms_param);
711 const int decompress,
714 double min[
EP], max[
EP], off[
EP], scl[
EP];
716 unsigned short *sarray;
719 ALLOC(sarray,
unsigned short,
726 LOG(2,
"Read 3-D variable: %s (pck, RATIO= %g)",
727 varname, (
double)
sizeof(
float) / (
double)
sizeof(
unsigned short));
736 FREAD(sarray,
unsigned short,
741#pragma omp parallel for default(shared)
742 for (
size_t ixy = 0; ixy < nxy; ixy++)
743 for (
size_t iz = 0; iz < nz; iz++)
745 = (
float) (sarray[ixy * nz + iz] * scl[iz] + off[iz]);
752 LOG(2,
"Write 3-D variable: %s (pck, RATIO= %g)",
753 varname, (
double)
sizeof(
float) / (
double)
sizeof(
unsigned short));
756 for (
size_t iz = 0; iz < nz; iz++) {
760 for (
size_t ixy = 1; ixy < nxy; ixy++)
761 for (
size_t iz = 0; iz < nz; iz++) {
762 if (array[ixy * nz + iz] < min[iz])
763 min[iz] = array[ixy * nz + iz];
764 if (array[ixy * nz + iz] > max[iz])
765 max[iz] = array[ixy * nz + iz];
769 for (
size_t iz = 0; iz < nz; iz++) {
770 scl[iz] = (max[iz] - min[iz]) / 65533.;
775#pragma omp parallel for default(shared)
776 for (
size_t ixy = 0; ixy < nxy; ixy++)
777 for (
size_t iz = 0; iz < nz; iz++)
779 sarray[ixy * nz + iz] = (
unsigned short)
780 ((array[ixy * nz + iz] - off[iz]) / scl[iz] + .5);
782 sarray[ixy * nz + iz] = 0;
791 FWRITE(sarray,
unsigned short,
810 const double tolerance,
811 const int decompress,
815 const zfp_type type = zfp_type_float;
817 zfp_field_3d(array, type, (uint) nx, (uint) ny, (uint) nz);
820 zfp_stream *zfp = zfp_stream_open(NULL);
824 double actual_tol = 0;
826 actual_prec = (int) zfp_stream_set_precision(zfp, (uint) precision);
827 else if (tolerance > 0)
828 actual_tol = zfp_stream_set_accuracy(zfp, tolerance);
830 ERRMSG(
"Set precision or tolerance!");
833 const size_t bufsize = zfp_stream_maximum_size(zfp, field);
834 void *buffer = malloc(bufsize);
837 bitstream *stream = stream_open(buffer, bufsize);
838 zfp_stream_set_bit_stream(zfp, stream);
839 zfp_stream_rewind(zfp);
844 FREAD(&zfpsize,
size_t,
847 if (fread(buffer, 1, zfpsize, inout) != zfpsize)
848 ERRMSG(
"Error while reading zfp data!");
849 if (!zfp_decompress(zfp, field)) {
850 ERRMSG(
"Decompression failed!");
852 LOG(2,
"Read 3-D variable: %s "
853 "(zfp, PREC= %d, TOL= %g, RATIO= %g)",
854 varname, actual_prec, actual_tol,
855 ((
double) (nx * ny * nz)) / (
double) zfpsize);
860 zfpsize = zfp_compress(zfp, field);
862 ERRMSG(
"Compression failed!");
867 if (fwrite(buffer, 1, zfpsize, inout) != zfpsize)
868 ERRMSG(
"Error while writing zfp data!");
870 LOG(2,
"Write 3-D variable: %s "
871 "(zfp, PREC= %d, TOL= %g, RATIO= %g)",
872 varname, actual_prec, actual_tol,
873 ((
double) (nx * ny * nz)) / (
double) zfpsize);
877 zfp_field_free(field);
878 zfp_stream_close(zfp);
879 stream_close(stream);
891 const int decompress,
896 const size_t uncomprLen = n *
sizeof(float);
897 size_t comprLen = ZSTD_compressBound(uncomprLen);
901 char *compr = (
char *) calloc((uint) comprLen, 1);
902 char *uncompr = (
char *) array;
906 FREAD(&comprLen,
size_t,
909 if (fread(compr, 1, comprLen, inout) != comprLen)
910 ERRMSG(
"Error while reading zstd data!");
911 compsize = ZSTD_decompress(uncompr, uncomprLen, compr, comprLen);
912 if (ZSTD_isError(compsize)) {
913 ERRMSG(
"Decompression failed!");
915 LOG(2,
"Read 3-D variable: %s (zstd, RATIO= %g)",
916 varname, ((
double) uncomprLen) / (
double) comprLen)
921 compsize = ZSTD_compress(compr, comprLen, uncompr, uncomprLen, level);
922 if (ZSTD_isError(compsize)) {
923 ERRMSG(
"Compression failed!");
928 if (fwrite(compr, 1, compsize, inout) != compsize)
929 ERRMSG(
"Error while writing zstd data!");
931 LOG(2,
"Write 3-D variable: %s (zstd, RATIO= %g)",
932 varname, ((
double) uncomprLen) / (
double) compsize);
949 d0[12] = { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 },
950 d0l[12] = { 1, 32, 61, 92, 122, 153, 183, 214, 245, 275, 306, 336 };
953 if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
954 *doy = d0l[mon - 1] + day - 1;
956 *doy = d0[mon - 1] + day - 1;
968 d0[12] = { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 },
969 d0l[12] = { 1, 32, 61, 92, 122, 153, 183, 214, 245, 275, 306, 336 };
974 if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) {
975 for (i = 11; i > 0; i--)
979 *day = doy - d0l[i] + 1;
981 for (i = 11; i > 0; i--)
985 *day = doy - d0[i] + 1;
1000 ERRMSG(
"Too many data points!");
1003 gsl_fft_complex_wavetable *wavetable =
1004 gsl_fft_complex_wavetable_alloc((
size_t) n);
1005 gsl_fft_complex_workspace *workspace =
1006 gsl_fft_complex_workspace_alloc((
size_t) n);
1009 for (
int i = 0; i < n; i++) {
1010 data[2 * i] = fcReal[i];
1011 data[2 * i + 1] = fcImag[i];
1015 gsl_fft_complex_forward(data, 1, (
size_t) n, wavetable, workspace);
1018 for (
int i = 0; i < n; i++) {
1019 fcReal[i] = data[2 * i];
1020 fcImag[i] = data[2 * i + 1];
1024 gsl_fft_complex_wavetable_free(wavetable);
1025 gsl_fft_complex_workspace_free(workspace);
1036 const double radius = z +
RE;
1037 const double latrad =
DEG2RAD(lat);
1038 const double lonrad =
DEG2RAD(lon);
1039 const double coslat = cos(latrad);
1041 x[0] = radius * coslat * cos(lonrad);
1042 x[1] = radius * coslat * sin(lonrad);
1043 x[2] = radius * sin(latrad);
1052 const char *metbase,
1053 const double dt_met,
1060 int year, mon, day, hour, min, sec;
1064 t6 = floor(t / dt_met) * dt_met;
1066 t6 = ceil(t / dt_met) * dt_met;
1069 jsec2time(t6, &year, &mon, &day, &hour, &min, &sec, &r);
1074 sprintf(filename,
"%s_YYYY_MM_DD_HH.nc", metbase);
1076 sprintf(filename,
"%s_YYYY_MM_DD_HH.bin", metbase);
1078 sprintf(filename,
"%s_YYYY_MM_DD_HH.pck", metbase);
1080 sprintf(filename,
"%s_YYYY_MM_DD_HH.zfp", metbase);
1082 sprintf(filename,
"%s_YYYY_MM_DD_HH.zstd", metbase);
1084 sprintf(filename,
"%s_YYYY_MM_DD_HH.cms", metbase);
1085 sprintf(repl,
"%d", year);
1087 sprintf(repl,
"%02d", mon);
1089 sprintf(repl,
"%02d", day);
1091 sprintf(repl,
"%02d", hour);
1097 sprintf(filename,
"%s_YYMMDDHH.nc", metbase);
1098 sprintf(repl,
"%d", year);
1100 sprintf(repl,
"%02d", year % 100);
1102 sprintf(repl,
"%02d", mon);
1104 sprintf(repl,
"%02d", day);
1106 sprintf(repl,
"%02d", hour);
1121 for (
int i = 0; i < 3; i++) {
1125 if (!(ch = strstr(orig, search)))
1127 strncpy(buffer, orig, (
size_t) (ch - orig));
1128 buffer[ch - orig] = 0;
1129 sprintf(buffer + (ch - orig),
"%s%s", repl, ch + strlen(search));
1131 strcpy(orig, buffer);
1138 const int met_tropo,
1158#pragma omp parallel for default(shared) private(ci,cw)
1159 for (
int ix = 0; ix < nx; ix++)
1160 for (
int iy = 0; iy < ny; iy++) {
1162 &pt[iy * nx + ix], ci, cw, 1);
1164 &ps[iy * nx + ix], ci, cw, 0);
1166 &zs[iy * nx + ix], ci, cw, 0);
1168 lats[iy], &zt[iy * nx + ix], ci, cw, 1);
1170 lats[iy], &tt[iy * nx + ix], ci, cw, 0);
1172 lats[iy], &qt[iy * nx + ix], ci, cw, 0);
1174 lats[iy], &o3t[iy * nx + ix], ci, cw, 0);
1191 *lon2 =
FMOD(lon, 360.);
1192 if (*lon2 < lons[0])
1194 else if (*lon2 > lons[nlon - 1])
1199 if (lats[0] < lats[nlat - 1])
1200 *lat2 =
MIN(
MAX(*lat2, lats[0]), lats[nlat - 1]);
1202 *lat2 =
MIN(
MAX(*lat2, lats[nlat - 1]), lats[0]);
1209 float heights0[
EX][
EY][
EP],
1210 float array0[
EX][
EY][
EP],
1212 float heights1[
EX][
EY][
EP],
1213 float array1[
EX][
EY][
EP],
1215 const double height,
1241 int k_max = ind[0][0];
1242 for (
int i = 0; i < 2; i++)
1243 for (
int j = 0; j < 4; j++) {
1244 if (ci[2] > ind[i][j])
1246 if (k_max < ind[i][j])
1252 cw[0] = (lon2 - met0->
lon[ci[0]]) /
1253 (met0->
lon[ci[0] + 1] - met0->
lon[ci[0]]);
1254 cw[1] = (lat2 - met0->
lat[ci[1]]) /
1255 (met0->
lat[ci[1] + 1] - met0->
lat[ci[1]]);
1258 double height00 = cw[3] * (heights1[ci[0]][ci[1]][ci[2]]
1259 - heights0[ci[0]][ci[1]][ci[2]])
1260 + heights0[ci[0]][ci[1]][ci[2]];
1261 double height01 = cw[3] * (heights1[ci[0]][ci[1] + 1][ci[2]]
1262 - heights0[ci[0]][ci[1] + 1][ci[2]])
1263 + heights0[ci[0]][ci[1] + 1][ci[2]];
1264 double height10 = cw[3] * (heights1[ci[0] + 1][ci[1]][ci[2]]
1265 - heights0[ci[0] + 1][ci[1]][ci[2]])
1266 + heights0[ci[0] + 1][ci[1]][ci[2]];
1267 double height11 = cw[3] * (heights1[ci[0] + 1][ci[1] + 1][ci[2]]
1268 - heights0[ci[0] + 1][ci[1] + 1][ci[2]])
1269 + heights0[ci[0] + 1][ci[1] + 1][ci[2]];
1272 double height0 = cw[1] * (height01 - height00) + height00;
1273 double height1 = cw[1] * (height11 - height10) + height10;
1276 double height_bot = cw[0] * (height1 - height0) + height0;
1279 height00 = cw[3] * (heights1[ci[0]][ci[1]][ci[2] + 1]
1280 - heights0[ci[0]][ci[1]][ci[2] + 1])
1281 + heights0[ci[0]][ci[1]][ci[2] + 1];
1282 height01 = cw[3] * (heights1[ci[0]][ci[1] + 1][ci[2] + 1]
1283 - heights0[ci[0]][ci[1] + 1][ci[2] + 1])
1284 + heights0[ci[0]][ci[1] + 1][ci[2] + 1];
1285 height10 = cw[3] * (heights1[ci[0] + 1][ci[1]][ci[2] + 1]
1286 - heights0[ci[0] + 1][ci[1]][ci[2] + 1])
1287 + heights0[ci[0] + 1][ci[1]][ci[2] + 1];
1288 height11 = cw[3] * (heights1[ci[0] + 1][ci[1] + 1][ci[2] + 1]
1289 - heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1])
1290 + heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1];
1293 height0 = cw[1] * (height01 - height00) + height00;
1294 height1 = cw[1] * (height11 - height10) + height10;
1297 double height_top = cw[0] * (height1 - height0) + height0;
1300 while (((heights0[0][0][0] > heights0[0][0][1]) &&
1301 ((height_bot <= height) || (height_top > height))
1302 && (height_bot >= height) && (ci[2] < k_max))
1304 ((heights0[0][0][0] < heights0[0][0][1]) &&
1305 ((height_bot >= height) || (height_top < height))
1306 && (height_bot <= height) && (ci[2] < k_max))
1310 height_bot = height_top;
1313 height00 = cw[3] * (heights1[ci[0]][ci[1]][ci[2] + 1]
1314 - heights0[ci[0]][ci[1]][ci[2] + 1])
1315 + heights0[ci[0]][ci[1]][ci[2] + 1];
1316 height01 = cw[3] * (heights1[ci[0]][ci[1] + 1][ci[2] + 1]
1317 - heights0[ci[0]][ci[1] + 1][ci[2] + 1])
1318 + heights0[ci[0]][ci[1] + 1][ci[2] + 1];
1319 height10 = cw[3] * (heights1[ci[0] + 1][ci[1]][ci[2] + 1]
1320 - heights0[ci[0] + 1][ci[1]][ci[2] + 1])
1321 + heights0[ci[0] + 1][ci[1]][ci[2] + 1];
1322 height11 = cw[3] * (heights1[ci[0] + 1][ci[1] + 1][ci[2] + 1]
1323 - heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1])
1324 + heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1];
1327 height0 = cw[1] * (height01 - height00) + height00;
1328 height1 = cw[1] * (height11 - height10) + height10;
1331 height_top = cw[0] * (height1 - height0) + height0;
1335 cw[2] = (height - height_bot)
1336 / (height_top - height_bot);
1340 double array000 = cw[3] * (array1[ci[0]][ci[1]][ci[2]]
1341 - array0[ci[0]][ci[1]][ci[2]])
1342 + array0[ci[0]][ci[1]][ci[2]];
1343 double array100 = cw[3] * (array1[ci[0] + 1][ci[1]][ci[2]]
1344 - array0[ci[0] + 1][ci[1]][ci[2]])
1345 + array0[ci[0] + 1][ci[1]][ci[2]];
1346 double array010 = cw[3] * (array1[ci[0]][ci[1] + 1][ci[2]]
1347 - array0[ci[0]][ci[1] + 1][ci[2]])
1348 + array0[ci[0]][ci[1] + 1][ci[2]];
1349 double array110 = cw[3] * (array1[ci[0] + 1][ci[1] + 1][ci[2]]
1350 - array0[ci[0] + 1][ci[1] + 1][ci[2]])
1351 + array0[ci[0] + 1][ci[1] + 1][ci[2]];
1352 double array001 = cw[3] * (array1[ci[0]][ci[1]][ci[2] + 1]
1353 - array0[ci[0]][ci[1]][ci[2] + 1])
1354 + array0[ci[0]][ci[1]][ci[2] + 1];
1355 double array101 = cw[3] * (array1[ci[0] + 1][ci[1]][ci[2] + 1]
1356 - array0[ci[0] + 1][ci[1]][ci[2] + 1])
1357 + array0[ci[0] + 1][ci[1]][ci[2] + 1];
1358 double array011 = cw[3] * (array1[ci[0]][ci[1] + 1][ci[2] + 1]
1359 - array0[ci[0]][ci[1] + 1][ci[2] + 1])
1360 + array0[ci[0]][ci[1] + 1][ci[2] + 1];
1361 double array111 = cw[3] * (array1[ci[0] + 1][ci[1] + 1][ci[2] + 1]
1362 - array0[ci[0] + 1][ci[1] + 1][ci[2] + 1])
1363 + array0[ci[0] + 1][ci[1] + 1][ci[2] + 1];
1365 double array00 = cw[0] * (array100 - array000) + array000;
1366 double array10 = cw[0] * (array110 - array010) + array010;
1367 double array01 = cw[0] * (array101 - array001) + array001;
1368 double array11 = cw[0] * (array111 - array011) + array011;
1370 double aux0 = cw[1] * (array10 - array00) + array00;
1371 double aux1 = cw[1] * (array11 - array01) + array01;
1374 *var = cw[2] * (aux1 - aux0) + aux0;
1404 cw[0] = (met->
p[ci[0] + 1] - p)
1405 / (met->
p[ci[0] + 1] - met->
p[ci[0]]);
1406 cw[1] = (met->
lon[ci[1] + 1] - lon2)
1407 / (met->
lon[ci[1] + 1] - met->
lon[ci[1]]);
1408 cw[2] = (met->
lat[ci[2] + 1] - lat2)
1409 / (met->
lat[ci[2] + 1] - met->
lat[ci[2]]);
1414 cw[0] * (array[ci[1]][ci[2]][ci[0]] - array[ci[1]][ci[2]][ci[0] + 1])
1415 + array[ci[1]][ci[2]][ci[0] + 1];
1417 cw[0] * (array[ci[1]][ci[2] + 1][ci[0]] -
1418 array[ci[1]][ci[2] + 1][ci[0] + 1])
1419 + array[ci[1]][ci[2] + 1][ci[0] + 1];
1421 cw[0] * (array[ci[1] + 1][ci[2]][ci[0]] -
1422 array[ci[1] + 1][ci[2]][ci[0] + 1])
1423 + array[ci[1] + 1][ci[2]][ci[0] + 1];
1425 cw[0] * (array[ci[1] + 1][ci[2] + 1][ci[0]] -
1426 array[ci[1] + 1][ci[2] + 1][ci[0] + 1])
1427 + array[ci[1] + 1][ci[2] + 1][ci[0] + 1];
1430 aux00 = cw[2] * (aux00 - aux01) + aux01;
1431 aux11 = cw[2] * (aux10 - aux11) + aux11;
1432 *var = cw[1] * (aux00 - aux11) + aux11;
1458 if (z >= zs[ix][iy][iz + 1])
1459 aux00 = array[ix][iy][iz + 1];
1460 else if (z <= zs[ix][iy][iz])
1461 aux00 = array[ix][iy][iz];
1463 aux00 =
LIN(zs[ix][iy][iz], array[ix][iy][iz],
1464 zs[ix][iy][iz + 1], array[ix][iy][iz + 1], z);
1468 if (z >= zs[ix][iy + 1][iz + 1])
1469 aux01 = array[ix][iy + 1][iz + 1];
1470 else if (z <= zs[ix][iy + 1][iz])
1471 aux01 = array[ix][iy + 1][iz];
1473 aux01 =
LIN(zs[ix][iy + 1][iz], array[ix][iy + 1][iz],
1474 zs[ix][iy + 1][iz + 1], array[ix][iy + 1][iz + 1], z);
1478 if (z >= zs[ix + 1][iy][iz + 1])
1479 aux10 = array[ix + 1][iy][iz + 1];
1480 else if (z <= zs[ix + 1][iy][iz])
1481 aux10 = array[ix + 1][iy][iz];
1483 aux10 =
LIN(zs[ix + 1][iy][iz], array[ix + 1][iy][iz],
1484 zs[ix + 1][iy][iz + 1], array[ix + 1][iy][iz + 1], z);
1488 if (z >= zs[ix + 1][iy + 1][iz + 1])
1489 aux11 = array[ix + 1][iy + 1][iz + 1];
1490 else if (z <= zs[ix + 1][iy + 1][iz])
1491 aux11 = array[ix + 1][iy + 1][iz];
1493 aux11 =
LIN(zs[ix + 1][iy + 1][iz], array[ix + 1][iy + 1][iz],
1494 zs[ix + 1][iy + 1][iz + 1], array[ix + 1][iy + 1][iz + 1], z);
1497 double aux0 =
LIN(met->
lat[iy], aux00, met->
lat[iy + 1], aux01, lat2);
1498 double aux1 =
LIN(met->
lat[iy], aux10, met->
lat[iy + 1], aux11, lat2);
1499 *var =
LIN(met->
lon[ix], aux0, met->
lon[ix + 1], aux1, lon2);
1506 float array[
EX][
EY],
1527 cw[1] = (met->
lon[ci[1] + 1] - lon2)
1528 / (met->
lon[ci[1] + 1] - met->
lon[ci[1]]);
1529 cw[2] = (met->
lat[ci[2] + 1] - lat2)
1530 / (met->
lat[ci[2] + 1] - met->
lat[ci[2]]);
1534 double aux00 = array[ci[1]][ci[2]];
1535 double aux01 = array[ci[1]][ci[2] + 1];
1536 double aux10 = array[ci[1] + 1][ci[2]];
1537 double aux11 = array[ci[1] + 1][ci[2] + 1];
1540 if (isfinite(aux00) && isfinite(aux01)
1541 && isfinite(aux10) && isfinite(aux11)) {
1542 aux00 = cw[2] * (aux00 - aux01) + aux01;
1543 aux11 = cw[2] * (aux10 - aux11) + aux11;
1544 *var = cw[1] * (aux00 - aux11) + aux11;
1564 float array0[
EX][
EY][
EP],
1566 float array1[
EX][
EY][
EP],
1583 const double wt = (met1->
time - ts) / (met1->
time - met0->
time);
1586 *var = wt * (var0 - var1) + var1;
1594 float array0[
EX][
EY][
EP],
1597 float array1[
EX][
EY][
EP],
1611 *var =
LIN(met0->
time, var0, met1->
time, var1, ts);
1618 float array0[
EX][
EY],
1620 float array1[
EX][
EY],
1636 const double wt = (met1->
time - ts) / (met1->
time - met0->
time);
1639 if (isfinite(var0) && isfinite(var1))
1640 *var = wt * (var0 - var1) + var1;
1651 float array0[
EX][
EY],
1653 float array1[
EX][
EY],
1654 const double lons[
EX],
1655 const double lats[
EY],
1665 double aux0, aux1, aux00, aux01, aux10, aux11, mean = 0;
1674 const int ix =
locate_reg(lons, (
int) nlon, lon2);
1675 const int iy =
locate_irr(lats, (
int) nlat, lat2);
1679 for (
int dx = 0; dx < 2; dx++)
1680 for (
int dy = 0; dy < 2; dy++) {
1681 if (isfinite(array0[ix + dx][iy + dy])) {
1682 mean += array0[ix + dx][iy + dy];
1683 *sigma +=
SQR(array0[ix + dx][iy + dy]);
1686 if (isfinite(array1[ix + dx][iy + dy])) {
1687 mean += array1[ix + dx][iy + dy];
1688 *sigma +=
SQR(array1[ix + dx][iy + dy]);
1693 *sigma = sqrt(
MAX(*sigma / n -
SQR(mean / n), 0.0));
1696 if (method == 1 && isfinite(array0[ix][iy])
1697 && isfinite(array0[ix][iy + 1])
1698 && isfinite(array0[ix + 1][iy])
1699 && isfinite(array0[ix + 1][iy + 1])
1700 && isfinite(array1[ix][iy])
1701 && isfinite(array1[ix][iy + 1])
1702 && isfinite(array1[ix + 1][iy])
1703 && isfinite(array1[ix + 1][iy + 1])) {
1705 aux00 =
LIN(lons[ix], array0[ix][iy],
1706 lons[ix + 1], array0[ix + 1][iy], lon2);
1707 aux01 =
LIN(lons[ix], array0[ix][iy + 1],
1708 lons[ix + 1], array0[ix + 1][iy + 1], lon2);
1709 aux0 =
LIN(lats[iy], aux00, lats[iy + 1], aux01, lat2);
1711 aux10 =
LIN(lons[ix], array1[ix][iy],
1712 lons[ix + 1], array1[ix + 1][iy], lon2);
1713 aux11 =
LIN(lons[ix], array1[ix][iy + 1],
1714 lons[ix + 1], array1[ix + 1][iy + 1], lon2);
1715 aux1 =
LIN(lats[iy], aux10, lats[iy + 1], aux11, lat2);
1717 *var =
LIN(time0, aux0, time1, aux1, time);
1722 aux00 =
NN(lons[ix], array0[ix][iy],
1723 lons[ix + 1], array0[ix + 1][iy], lon2);
1724 aux01 =
NN(lons[ix], array0[ix][iy + 1],
1725 lons[ix + 1], array0[ix + 1][iy + 1], lon2);
1726 aux0 =
NN(lats[iy], aux00, lats[iy + 1], aux01, lat2);
1728 aux10 =
NN(lons[ix], array1[ix][iy],
1729 lons[ix + 1], array1[ix + 1][iy], lon2);
1730 aux11 =
NN(lons[ix], array1[ix][iy + 1],
1731 lons[ix + 1], array1[ix + 1][iy + 1], lon2);
1732 aux1 =
NN(lats[iy], aux10, lats[iy + 1], aux11, lat2);
1734 *var =
NN(time0, aux0, time1, aux1, time);
1759 const time_t jsec0 = (time_t) jsec + timegm(&t0);
1760 t1 = gmtime(&jsec0);
1762 *year = t1->tm_year + 1900;
1763 *mon = t1->tm_mon + 1;
1765 *hour = t1->tm_hour;
1768 *remain = jsec - floor(jsec);
1774 const double kz[
EP],
1775 const double kw[
EP],
1784 const double z =
Z(p);
1789 else if (z > kz[nk - 1])
1793 return LIN(kz[idx], kw[idx], kz[idx + 1], kw[idx + 1], z);
1810 const double a =
RA *
SQR(t), r =
SH(h2o) / (1. -
SH(h2o));
1824 const double press[138] = {
1825 0.0200, 0.0310, 0.0467, 0.0683, 0.0975, 0.1361, 0.1861, 0.2499,
1826 0.3299, 0.4288, 0.5496, 0.6952, 0.8690, 1.0742, 1.3143, 1.5928, 1.9134,
1827 2.2797, 2.6954, 3.1642, 3.6898, 4.2759, 4.9262, 5.6441, 6.4334, 7.2974,
1828 8.2397, 9.2634, 10.3720, 11.5685, 12.8561, 14.2377, 15.7162, 17.2945,
1829 18.9752, 20.7610, 22.6543, 24.6577, 26.7735, 29.0039, 31.3512, 33.8174,
1830 36.4047, 39.1149, 41.9493, 44.9082, 47.9915, 51.1990, 54.5299, 57.9834,
1831 61.5607, 65.2695, 69.1187, 73.1187, 77.2810, 81.6182, 86.1450, 90.8774,
1832 95.8280, 101.0047, 106.4153, 112.0681, 117.9714, 124.1337, 130.5637,
1833 137.2703, 144.2624, 151.5493, 159.1403, 167.0450, 175.2731, 183.8344,
1834 192.7389, 201.9969, 211.6186, 221.6146, 231.9954, 242.7719, 253.9549,
1835 265.5556, 277.5852, 290.0548, 302.9762, 316.3607, 330.2202, 344.5663,
1836 359.4111, 374.7666, 390.6450, 407.0583, 424.0190, 441.5395, 459.6321,
1837 478.3096, 497.5845, 517.4198, 537.7195, 558.3430, 579.1926, 600.1668,
1838 621.1624, 642.0764, 662.8084, 683.2620, 703.3467, 722.9795, 742.0855,
1839 760.5996, 778.4661, 795.6396, 812.0847, 827.7756, 842.6959, 856.8376,
1840 870.2004, 882.7910, 894.6222, 905.7116, 916.0815, 925.7571, 934.7666,
1841 943.1399, 950.9082, 958.1037, 964.7584, 970.9046, 976.5737, 981.7968,
1842 986.6036, 991.0230, 995.0824, 998.8081, 1002.2250, 1005.3562, 1008.2239,
1843 1010.8487, 1013.2500, 1044.45
1846 for (
int ip = 0; ip < ctl->
met_np; ip++)
1853 const double press[92] = {
1854 0.0200, 0.0398, 0.0739, 0.1291, 0.2141, 0.3395, 0.5175, 0.7617,
1855 1.0872, 1.5099, 2.0464, 2.7136, 3.5282, 4.5069, 5.6652, 7.0181,
1856 8.5795, 10.3617, 12.3759, 14.6316, 17.1371, 19.8987, 22.9216, 26.2090,
1857 29.7630, 33.5843, 37.6720, 42.0242, 46.6378, 51.5086, 56.6316, 61.9984,
1858 67.5973, 73.4150, 79.4434, 85.7016, 92.2162, 99.0182, 106.1445,
1860 121.5502, 129.9403, 138.8558, 148.3260, 158.3816, 169.0545, 180.3786,
1861 192.3889, 205.1222, 218.6172, 232.9140, 248.0547, 264.0833, 281.0456,
1862 298.9895, 317.9651, 338.0245, 359.2221, 381.6144, 405.2606, 430.2069,
1863 456.4813, 483.8505, 512.0662, 540.8577, 569.9401, 599.0310, 627.9668,
1864 656.6129, 684.8491, 712.5573, 739.5739, 765.7697, 791.0376, 815.2774,
1865 838.3507, 860.1516, 880.6080, 899.6602, 917.2205, 933.2247, 947.6584,
1866 960.5245, 971.8169, 981.5301, 989.7322, 996.8732, 1002.8013,
1867 1007.4431, 1010.8487, 1013.2500, 1044.45
1870 for (
int ip = 0; ip < ctl->
met_np; ip++)
1877 const double press[60] = {
1878 0.01, 0.1361, 0.2499, 0.4288, 0.6952, 1.0742,
1879 2.2797, 3.1642, 4.2759, 7.2974, 9.2634, 11.5685, 14.2377, 20.761,
1880 24.6577, 33.8174, 39.1149, 51.199, 57.9834, 73.1187, 81.6182,
1881 90.8774, 101.005, 112.068, 124.134, 137.27, 151.549, 167.045, 183.834,
1882 201.997, 221.615, 242.772, 265.556, 290.055, 316.361, 344.566, 374.767,
1883 407.058, 441.539, 478.31, 517.42, 558.343, 600.167, 683.262, 722.979,
1884 760.6, 795.64, 827.776, 856.838, 882.791, 905.712, 925.757, 943.14,
1885 958.104, 972.495, 986.886, 1001.28, 1015.67, 1030.06, 1044.45
1888 for (
int ip = 0; ip < ctl->
met_np; ip++)
1895 const double press[147] = {
1896 0.0200, 0.0310, 0.0467, 0.0683, 0.0975, 0.1361, 0.1861, 0.2499,
1897 0.3299, 0.4288, 0.5496, 0.6952, 0.8690, 1.0742, 1.3143, 1.5928, 1.9134,
1898 2.2797, 2.6954, 3.1642, 3.6898, 4.2759, 4.9262, 5.6441, 6.4334, 7.2974,
1899 8.2397, 9.2634, 10.3720, 11.5685, 12.8561, 14.2377, 15.7162, 17.2945,
1900 18.9752, 20.7610, 22.6543, 24.6577, 26.7735, 29.0039, 31.3512, 33.8174,
1901 36.4047, 39.1149, 41.9493, 44.9082, 47.9915, 51.1990, 54.5299, 57.9834,
1902 61.5607, 65.2695, 69.1187, 73.1187, 77.2810, 81.6182, 86.1450, 90.8774,
1903 95.8280, 101.0047, 106.4153, 112.0681, 117.9714, 124.1337, 130.5637,
1904 137.2703, 144.2624, 151.5493, 159.1403, 167.0450, 175.2731, 183.8344,
1905 192.7389, 201.9969, 211.6186, 221.6146, 231.9954, 242.7719, 253.9549,
1906 265.5556, 277.5852, 290.0548, 302.9762, 316.3607, 330.2202, 344.5663,
1907 359.4111, 374.7666, 390.6450, 407.0583, 424.0190, 441.5395, 459.6321,
1908 478.3096, 497.5845, 517.4198, 537.7195, 558.3430, 579.1926, 600.1668,
1909 621.1624, 642.0764, 662.8084, 683.2620, 703.3467, 722.9795, 742.0855,
1910 760.5996, 778.4661, 795.6396, 812.0847, 827.7756, 842.6959, 856.8376,
1911 870.2004, 882.7910, 894.6222, 905.7116, 916.0815, 925.7571, 934.7666,
1912 943.1399, 950.9082, 958.1037, 964.7584, 970.9046, 976.5737, 981.7968,
1913 986.6036, 991.0230, 995.0824, 998.8081, 1002.2250, 1005.3562, 1008.2239,
1914 1010.8487, 1013.25, 1016.37, 1019.49, 1022.61, 1025.73, 1028.85,
1916 1035.09, 1038.21, 1041.33, 1044.45
1919 for (
int ip = 0; ip < ctl->
met_np; ip++)
1926 const double press[101] = {
1927 0.0200, 0.0398, 0.0739, 0.1291, 0.2141, 0.3395, 0.5175, 0.7617,
1928 1.0872, 1.5099, 2.0464, 2.7136, 3.5282, 4.5069, 5.6652, 7.0181,
1929 8.5795, 10.3617, 12.3759, 14.6316, 17.1371, 19.8987, 22.9216, 26.2090,
1930 29.7630, 33.5843, 37.6720, 42.0242, 46.6378, 51.5086, 56.6316, 61.9984,
1931 67.5973, 73.4150, 79.4434, 85.7016, 92.2162, 99.0182, 106.1445,
1933 121.5502, 129.9403, 138.8558, 148.3260, 158.3816, 169.0545, 180.3786,
1934 192.3889, 205.1222, 218.6172, 232.9140, 248.0547, 264.0833, 281.0456,
1935 298.9895, 317.9651, 338.0245, 359.2221, 381.6144, 405.2606, 430.2069,
1936 456.4813, 483.8505, 512.0662, 540.8577, 569.9401, 599.0310, 627.9668,
1937 656.6129, 684.8491, 712.5573, 739.5739, 765.7697, 791.0376, 815.2774,
1938 838.3507, 860.1516, 880.6080, 899.6602, 917.2205, 933.2247, 947.6584,
1939 960.5245, 971.8169, 981.5301, 989.7322, 996.8732, 1002.8013,
1940 1007.4431, 1010.8487, 1013.25, 1016.37, 1019.49, 1022.61, 1025.73,
1942 1035.09, 1038.21, 1041.33, 1044.45
1945 for (
int ip = 0; ip < ctl->
met_np; ip++)
1952 const double press[62] = {
1953 0.01, 0.1361, 0.2499, 0.4288, 0.6952, 1.0742,
1954 2.2797, 3.1642, 4.2759, 7.2974, 9.2634, 11.5685, 14.2377, 20.761,
1955 24.6577, 33.8174, 39.1149, 51.199, 57.9834, 73.1187, 81.6182,
1956 90.8774, 101.005, 112.068, 124.134, 137.27, 151.549, 167.045, 183.834,
1957 201.997, 221.615, 242.772, 265.556, 290.055, 316.361, 344.566, 374.767,
1958 407.058, 441.539, 478.31, 517.42, 558.343, 600.167, 683.262, 722.979,
1959 760.6, 795.64, 827.776, 856.838, 882.791, 905.712, 925.757, 943.14,
1960 958.104, 972.495, 986.886, 1001.28, 1015.67, 1030.06, 1034.86, 1039.65,
1964 for (
int ip = 0; ip < ctl->
met_np; ip++)
1971 const double press[137] = {
1972 0.01, 0.02, 0.031, 0.0467, 0.0683, 0.0975, 0.1361, 0.1861,
1973 0.2499, 0.3299, 0.4288, 0.5496, 0.6952, 0.869, 1.0742,
1974 1.3143, 1.5928, 1.9134, 2.2797, 2.6954, 3.1642, 3.6898,
1975 4.2759, 4.9262, 5.6441, 6.4334, 7.2974, 8.2397, 9.2634,
1976 10.372, 11.5685, 12.8561, 14.2377, 15.7162, 17.2945, 18.9752,
1977 20.761, 22.6543, 24.6577, 26.7735, 29.0039, 31.3512, 33.8174,
1978 36.4047, 39.1149, 41.9493, 44.9082, 47.9915, 51.199, 54.5299,
1979 57.9834, 61.5607, 65.2695, 69.1187, 73.1187, 77.281, 81.6182,
1980 86.145, 90.8774, 95.828, 101.005, 106.415, 112.068, 117.971,
1981 124.134, 130.564, 137.27, 144.262, 151.549, 159.14, 167.045,
1982 175.273, 183.834, 192.739, 201.997, 211.619, 221.615, 231.995,
1983 242.772, 253.955, 265.556, 277.585, 290.055, 302.976, 316.361,
1984 330.22, 344.566, 359.411, 374.767, 390.645, 407.058, 424.019,
1985 441.539, 459.632, 478.31, 497.584, 517.42, 537.72, 558.343,
1986 579.193, 600.167, 621.162, 642.076, 662.808, 683.262, 703.347,
1987 722.979, 742.086, 760.6, 778.466, 795.64, 812.085, 827.776,
1988 842.696, 856.838, 870.2, 882.791, 894.622, 905.712, 916.081,
1989 925.757, 934.767, 943.14, 950.908, 958.104, 965.299, 972.495,
1990 979.69, 986.886, 994.081, 1001.28, 1008.47, 1015.67, 1022.86,
1991 1030.06, 1037.25, 1044.45
1994 for (
int ip = 0; ip < ctl->
met_np; ip++)
2001 const double press[59] = {
2002 0.1, 0.2, 0.3843, 0.6365, 0.9564, 1.3448, 1.8058, 2.3478,
2003 2.985, 3.7397, 4.6462, 5.7565, 7.1322, 8.8366, 10.9483,
2004 13.5647, 16.8064, 20.8227, 25.7989, 31.9642, 39.6029, 49.0671,
2005 60.1802, 73.0663, 87.7274, 104.229, 122.614, 142.902, 165.089,
2006 189.147, 215.025, 242.652, 272.059, 303.217, 336.044, 370.407,
2007 406.133, 443.009, 480.791, 519.209, 557.973, 596.777, 635.306,
2008 673.24, 710.263, 746.063, 780.346, 812.83, 843.263, 871.42,
2009 897.112, 920.189, 940.551, 958.148, 975.744, 993.341, 1010.94,
2013 for (
int ip = 0; ip < ctl->
met_np; ip++)
2017 ERRMSG(
"Use 0 for l137, 1 for l91, 2 for l60 or values between 3 and 7.");
2021 ERRMSG(
"Recompile with larger NP to use this pressure level definition.");
2034 int i = (ihi + ilo) >> 1;
2036 if (xx[i] < xx[i + 1])
2037 while (ihi > ilo + 1) {
2038 i = (ihi + ilo) >> 1;
2044 while (ihi > ilo + 1) {
2045 i = (ihi + ilo) >> 1;
2065 int i = (ihi + ilo) >> 1;
2067 if (x >= xx[ig] && x < xx[ig + 1])
2070 if (xx[i] < xx[i + 1])
2071 while (ihi > ilo + 1) {
2072 i = (ihi + ilo) >> 1;
2078 while (ihi > ilo + 1) {
2079 i = (ihi + ilo) >> 1;
2097 const int i = (int) ((x - xx[0]) / (xx[1] - xx[0]));
2111 float profiles[
EX][
EY][
EP],
2113 const int lon_ap_ind,
2114 const int lat_ap_ind,
2115 const double height_ap,
2121 np, height_ap, ind[0]);
2123 np, height_ap, ind[1]);
2125 np, height_ap, ind[2]);
2144 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2148 double dts, u[4], um = 0, v[4], vm = 0, w[4], wm = 0,
2152 for (
int i = 0; i < ctl->
advect; i++) {
2157 x[0] = atm->
lon[ip];
2158 x[1] = atm->
lat[ip];
2161 dts = (i == 3 ? 1.0 : 0.5) * cache->
dt[ip];
2162 x[0] = atm->
lon[ip] +
DX2DEG(dts * u[i - 1] / 1000., atm->
lat[ip]);
2163 x[1] = atm->
lat[ip] +
DY2DEG(dts * v[i - 1] / 1000.);
2164 x[2] = atm->
p[ip] + dts * w[i - 1];
2166 const double tm = atm->
time[ip] + dts;
2171 tm, x[2], x[0], x[1], &u[i], ci, cw, 1);
2173 tm, x[2], x[0], x[1], &v[i], ci, cw, 0);
2175 tm, x[2], x[0], x[1], &w[i], ci, cw, 0);
2181 met1, met1->
pl, met1->
ul,
2182 tm, x[2], x[0], x[1], &u[i]);
2184 met1, met1->
pl, met1->
vl,
2185 tm, x[2], x[0], x[1], &v[i]);
2187 met1, met1->
pl, met1->
wl,
2188 tm, x[2], x[0], x[1], &w[i]);
2194 k = (i == 0 ? 0.0 : 1.0);
2195 else if (ctl->
advect == 4)
2196 k = (i == 0 || i == 3 ? 1.0 / 6.0 : 2.0 / 6.0);
2203 atm->
time[ip] += cache->
dt[ip];
2204 atm->
lon[ip] +=
DX2DEG(cache->
dt[ip] * um / 1000.,
2205 (ctl->
advect == 2 ? x[1] : atm->
lat[ip]));
2206 atm->
lat[ip] +=
DY2DEG(cache->
dt[ip] * vm / 1000.);
2207 atm->
p[ip] += cache->
dt[ip] * wm;
2215 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2221 atm->
lon[ip], atm->
lat[ip],
2225 double dts, u[4], um = 0, v[4], vm = 0, zeta_dot[4],
2226 zeta_dotm = 0, x[3] = { 0, 0, 0 };
2229 for (
int i = 0; i < ctl->
advect; i++) {
2234 x[0] = atm->
lon[ip];
2235 x[1] = atm->
lat[ip];
2238 dts = (i == 3 ? 1.0 : 0.5) * cache->
dt[ip];
2239 x[0] = atm->
lon[ip] +
DX2DEG(dts * u[i - 1] / 1000., atm->
lat[ip]);
2240 x[1] = atm->
lat[ip] +
DY2DEG(dts * v[i - 1] / 1000.);
2241 x[2] = atm->
q[ctl->
qnt_zeta][ip] + dts * zeta_dot[i - 1];
2243 const double tm = atm->
time[ip] + dts;
2247 met1->
ul, tm, x[2], x[0], x[1], &u[i], ci, cw, 1);
2249 met1->
vl, tm, x[2], x[0], x[1], &v[i], ci, cw, 0);
2252 x[1], &zeta_dot[i], ci, cw, 0);
2257 k = (i == 0 ? 0.0 : 1.0);
2258 else if (ctl->
advect == 4)
2259 k = (i == 0 || i == 3 ? 1.0 / 6.0 : 2.0 / 6.0);
2262 zeta_dotm += k * zeta_dot[i];
2266 atm->
time[ip] += cache->
dt[ip];
2267 atm->
lon[ip] +=
DX2DEG(cache->
dt[ip] * um / 1000.,
2268 (ctl->
advect == 2 ? x[1] : atm->
lat[ip]));
2269 atm->
lat[ip] +=
DY2DEG(cache->
dt[ip] * vm / 1000.);
2270 atm->
q[ctl->
qnt_zeta][ip] += cache->
dt[ip] * zeta_dotm;
2276 atm->
lat[ip], &atm->
p[ip], ci, cw, 1);
2295 SELECT_TIMER(
"MODULE_ADVECT_INIT",
"PHYSICS", NVTX_GPU);
2304 atm->
lon[ip], atm->
lat[ip], &atm->
p[ip], ci, cw, 1);
2319 SELECT_TIMER(
"MODULE_BOUND_COND",
"PHYSICS", NVTX_GPU);
2329 "acc data present(ctl,cache,clim,met0,met1,atm)") {
2365 if (atm->
p[ip] < pbl)
2417 ERRMSG(
"Molar mass is not defined!");
2423 const int np = atm->
np;
2427 const int ngrid = nx * ny * nz;
2429 double *restrict
const z = (
double *) malloc((
size_t) nz *
sizeof(double));
2430 double *restrict
const press =
2431 (
double *) malloc((
size_t) nz *
sizeof(double));
2432 double *restrict
const mass =
2433 (
double *) calloc((
size_t) ngrid,
sizeof(double));
2434 double *restrict
const area =
2435 (
double *) malloc((
size_t) ny *
sizeof(double));
2436 double *restrict
const lon =
2437 (
double *) malloc((
size_t) nx *
sizeof(double));
2438 double *restrict
const lat =
2439 (
double *) malloc((
size_t) ny *
sizeof(double));
2441 int *restrict
const ixs = (
int *) malloc((
size_t) np *
sizeof(int));
2442 int *restrict
const iys = (
int *) malloc((
size_t) np *
sizeof(int));
2443 int *restrict
const izs = (
int *) malloc((
size_t) np *
sizeof(int));
2452#pragma acc enter data create(ixs[0:np],iys[0:np],izs[0:np],z[0:nz],press[0:nz],mass[0:ngrid],area[0:ny],lon[0:nx],lat[0:ny])
2453#pragma acc data present(ctl,met0,met1,atm,ixs,iys,izs,z,press,mass,area,lon,lat)
2454#pragma acc parallel loop independent gang vector
2456#pragma omp parallel for default(shared)
2458 for (
int iz = 0; iz < nz; iz++) {
2460 press[iz] =
P(z[iz]);
2464 const double t0 = tt - 0.5 * ctl->
dt_mod;
2465 const double t1 = tt + 0.5 * ctl->
dt_mod;
2469#pragma acc parallel loop independent gang vector
2471#pragma omp parallel for default(shared)
2473 for (
int ip = 0; ip < np; ip++) {
2477 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
2478 || ixs[ip] < 0 || ixs[ip] >= nx
2479 || iys[ip] < 0 || iys[ip] >= ny || izs[ip] < 0 || izs[ip] >= nz)
2485#pragma acc parallel loop independent gang vector
2487#pragma omp parallel for default(shared)
2489 for (
int ix = 0; ix < nx; ix++)
2492#pragma acc parallel loop independent gang vector
2494#pragma omp parallel for default(shared)
2496 for (
int iy = 0; iy < ny; iy++) {
2498 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat[iy]));
2503#pragma acc parallel loop independent gang vector
2505 for (
int ip = 0; ip < np; ip++)
2508#pragma acc atomic update
2510 mass[
ARRAY_3D(ixs[ip], iys[ip], ny, izs[ip], nz)]
2511 += atm->
q[ctl->
qnt_m][ip];
2515#pragma acc parallel loop independent gang vector
2517#pragma omp parallel for default(shared)
2519 for (
int ip = 0; ip < np; ip++)
2526 lon[ixs[ip]], lat[iys[ip]], &temp, ci, cw, 1);
2529 const double m = mass[
ARRAY_3D(ixs[ip], iys[ip], ny, izs[ip], nz)];
2533 / (
RHO(press[izs[ip]], temp) * area[iys[ip]] * dz * 1e9);
2536#pragma acc exit data delete(ixs,iys,izs,z,press,mass,area,lon,lat)
2564 ERRMSG(
"Molar mass is not defined!");
2567 SELECT_TIMER(
"MODULE_CHEM_GRID_ENS",
"PHYSICS", NVTX_GPU);
2570 const int np = atm->
np;
2574 const int ngrid = nx * ny * nz;
2576 double *restrict
const z = (
double *) malloc((
size_t) nz *
sizeof(double));
2577 double *restrict
const press =
2578 (
double *) malloc((
size_t) nz *
sizeof(double));
2579 double *restrict
const mass =
2580 (
double *) calloc((
size_t) ngrid * (size_t) ctl->
nens,
sizeof(
double));
2581 double *restrict
const area =
2582 (
double *) malloc((
size_t) ny *
sizeof(double));
2583 double *restrict
const lon =
2584 (
double *) malloc((
size_t) nx *
sizeof(double));
2585 double *restrict
const lat =
2586 (
double *) malloc((
size_t) ny *
sizeof(double));
2588 int *restrict
const ixs = (
int *) malloc((
size_t) np *
sizeof(int));
2589 int *restrict
const iys = (
int *) malloc((
size_t) np *
sizeof(int));
2590 int *restrict
const izs = (
int *) malloc((
size_t) np *
sizeof(int));
2599#pragma acc enter data create(ixs[0:np],iys[0:np],izs[0:np],z[0:nz],press[0:nz],mass[0:ngrid],area[0:ny],lon[0:nx],lat[0:ny])
2600#pragma acc data present(ctl,met0,met1,atm,ixs,iys,izs,z,press,mass,area,lon,lat)
2601#pragma acc parallel loop independent gang vector
2603#pragma omp parallel for default(shared)
2605 for (
int iz = 0; iz < nz; iz++) {
2607 press[iz] =
P(z[iz]);
2611 const double t0 = tt - 0.5 * ctl->
dt_mod;
2612 const double t1 = tt + 0.5 * ctl->
dt_mod;
2616#pragma acc parallel loop independent gang vector
2618#pragma omp parallel for default(shared)
2620 for (
int ip = 0; ip < np; ip++) {
2624 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
2625 || ixs[ip] < 0 || ixs[ip] >= nx
2626 || iys[ip] < 0 || iys[ip] >= ny || izs[ip] < 0 || izs[ip] >= nz)
2632#pragma acc parallel loop independent gang vector
2634#pragma omp parallel for default(shared)
2636 for (
int ix = 0; ix < nx; ix++)
2639#pragma acc parallel loop independent gang vector
2641#pragma omp parallel for default(shared)
2643 for (
int iy = 0; iy < ny; iy++) {
2645 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat[iy]));
2650#pragma acc parallel loop independent gang vector
2652 for (
int ip = 0; ip < np; ip++)
2654 const int ens = (int) atm->
q[ctl->
qnt_ens][ip];
2656#pragma acc atomic update
2658 mass[ens * ngrid +
ARRAY_3D(ixs[ip], iys[ip], ny, izs[ip], nz)]
2659 += atm->
q[ctl->
qnt_m][ip];
2664#pragma acc parallel loop independent gang vector
2666#pragma omp parallel for default(shared)
2668 for (
int ip = 0; ip < np; ip++)
2675 lon[ixs[ip]], lat[iys[ip]], &temp, ci, cw, 1);
2678 int ens = (int) atm->
q[ctl->
qnt_ens][ip];
2680 mass[ens * ngrid +
ARRAY_3D(ixs[ip], iys[ip], ny, izs[ip], nz)];
2684 / (
RHO(press[izs[ip]], temp) * area[iys[ip]] * dz * 1e9);
2687#pragma acc exit data delete(ixs,iys,izs,z,press,mass,area,lon,lat)
2717 "acc data present(ctl,cache,clim,met0,met1,atm)") {
2734 atm->
lon[ip], atm->
lat[ip], atm->
p[ip]));
2736 atm->
lat[ip], atm->
p[ip]));
2738 atm->
lat[ip], atm->
p[ip]));
2740 atm->
lat[ip], atm->
p[ip]));
2754 SELECT_TIMER(
"MODULE_CONVECTION",
"PHYSICS", NVTX_GPU);
2760 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2768 double pbot = ps, ptop = ps;
2785 double cape, cin, pel;
2791 if (isfinite(cape) && cape >= ctl->
conv_cape
2793 ptop = GSL_MIN(ptop, pel);
2797 if (ptop != pbot && atm->
p[ip] >= ptop) {
2802 pbot, atm->
lon[ip], atm->
lat[ip], &tbot, ci, cw, 1);
2804 atm->
lon[ip], atm->
lat[ip], &ttop, ci, cw, 1);
2805 const double rhobot = pbot / tbot;
2806 const double rhotop = ptop / ttop;
2809 const double rho = rhobot + (rhotop - rhobot) * cache->
rs[ip];
2812 atm->
p[ip] =
LIN(rhobot, pbot, rhotop, ptop, rho);
2830 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
2833 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,clim,atm)") {
2842 const double aux = exp(-cache->
dt[ip] / tdec);
2843 if (ctl->
qnt_m >= 0) {
2846 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
2847 atm->
q[ctl->
qnt_m][ip] *= aux;
2872 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2880 float umean = 0, usig = 0, vmean = 0, vsig = 0, wmean = 0, wsig = 0;
2881 for (
int i = 0; i < 2; i++)
2882 for (
int j = 0; j < 2; j++)
2883 for (
int k = 0; k < 2; k++) {
2884 umean += met0->
u[ix + i][iy + j][iz + k];
2885 usig +=
SQR(met0->
u[ix + i][iy + j][iz + k]);
2886 vmean += met0->
v[ix + i][iy + j][iz + k];
2887 vsig +=
SQR(met0->
v[ix + i][iy + j][iz + k]);
2888 wmean += met0->
w[ix + i][iy + j][iz + k];
2889 wsig +=
SQR(met0->
w[ix + i][iy + j][iz + k]);
2891 umean += met1->
u[ix + i][iy + j][iz + k];
2892 usig +=
SQR(met1->
u[ix + i][iy + j][iz + k]);
2893 vmean += met1->
v[ix + i][iy + j][iz + k];
2894 vsig +=
SQR(met1->
v[ix + i][iy + j][iz + k]);
2895 wmean += met1->
w[ix + i][iy + j][iz + k];
2896 wsig +=
SQR(met1->
w[ix + i][iy + j][iz + k]);
2898 usig = usig / 16.f -
SQR(umean / 16.f);
2899 usig = (usig > 0 ? sqrtf(usig) : 0);
2900 vsig = vsig / 16.f -
SQR(vmean / 16.f);
2901 vsig = (vsig > 0 ? sqrtf(vsig) : 0);
2902 wsig = wsig / 16.f -
SQR(wmean / 16.f);
2903 wsig = (wsig > 0 ? sqrtf(wsig) : 0);
2906 const double r = 1 - 2 * fabs(cache->
dt[ip]) / ctl->
dt_met;
2907 const double r2 = sqrt(1 - r * r);
2911 cache->
uvwp[ip][0] =
2912 (float) (r * cache->
uvwp[ip][0] +
2917 cache->
uvwp[ip][1] =
2918 (float) (r * cache->
uvwp[ip][1] +
2925 cache->
uvwp[ip][2] =
2926 (float) (r * cache->
uvwp[ip][2] +
2928 atm->
p[ip] += cache->
uvwp[ip][2] * cache->
dt[ip];
2949 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2951 double dsigw_dz = 0.0, sig_u = 0.25, sig_w = 0.1,
2952 tau_u = 300., tau_w = 100.;
2961 if (atm->
p[ip] >= pbl) {
2964 const double p =
MIN(atm->
p[ip], ps);
2965 const double zs =
Z(ps);
2966 const double z = 1e3 * (
Z(p) - zs);
2967 const double zi = 1e3 * (
Z(pbl) - zs);
2968 const double zratio = z / zi;
2971 double ess, nss, h2o, t;
2976 const double rho =
RHO(p,
TVIRT(t, h2o));
2977 const double tau = sqrt(
SQR(ess) +
SQR(nss));
2978 const double ustar = sqrt(tau / rho);
2988 sig_u = 1e-2 + 2.0 * ustar * (1.0 - zratio);
2989 sig_w = 1e-2 + 1.3 * ustar * (1.0 - zratio);
2992 dsigw_dz = -1.3 * ustar / zi;
2995 tau_u = 0.07 * zi / sig_u * sqrt(zratio);
2996 tau_w = 0.1 * zi / sig_w * pow(zratio, 0.8);
3003 const double wstar =
3004 pow(
G0 /
THETAVIRT(p, t, h2o) * shf / (rho *
CPD) * zi, 1. / 3.);
3008 + sqrt(0.4 *
SQR(wstar) + (5.0 - 4.0 * zratio) *
SQR(ustar));
3009 sig_w = 1e-2 + sqrt(1.2 *
SQR(wstar) * (1.0 - 0.9 * zratio)
3010 * pow(zratio, 2.0 / 3.0)
3011 + (1.8 - 1.4 * zratio) *
SQR(ustar));
3014 dsigw_dz = 0.5 / sig_w / zi * (-1.4 *
SQR(ustar) +
SQR(wstar)
3016 pow(
MAX(zratio, 1e-3), -1.0 / 3.0)
3017 - 1.8 * pow(zratio, 2.0 / 3.0)));
3020 const double C0 = 3.0;
3022 (1.5 - 1.2 * pow(zratio, 1.0 / 3.0)) *
SQR(wstar) * wstar / zi
3023 +
SQR(ustar) * ustar * (1.0 - 0.8 * zratio) / (
KARMAN * z);
3024 tau_u = 2 *
SQR(sig_u) / (C0 * eps);
3025 tau_w = 2 *
SQR(sig_w) / (C0 * eps);
3030 sig_u =
MAX(sig_u, 0.25);
3031 sig_w =
MAX(sig_w, 0.1);
3032 tau_u =
MAX(tau_u, 300.);
3033 tau_w =
MAX(tau_w, 100.);
3036 const double ru = exp(-fabs(cache->
dt[ip]) / tau_u);
3037 const double ru2 = sqrt(1.0 -
SQR(ru));
3039 = (float) (cache->
uvwp[ip][0] * ru + ru2 * cache->
rs[3 * ip]);
3041 = (float) (cache->
uvwp[ip][1] * ru + ru2 * cache->
rs[3 * ip + 1]);
3043 const double rw = exp(-fabs(cache->
dt[ip]) / tau_w);
3044 const double rw2 = sqrt(1.0 -
SQR(rw));
3046 = (float) (cache->
uvwp[ip][2] * rw + rw2 * cache->
rs[3 * ip + 2]
3047 + sig_w * dsigw_dz * cache->
dt[ip]);
3054 DZ2DP(cache->
uvwp[ip][2] * cache->
dt[ip] / 1000., atm->
p[ip]);
3076 "acc data present(ctl,cache,clim,met0,met1,atm)") {
3085 const double wpbl =
pbl_weight(ctl, atm, ip, pbl, ps);
3086 const double wtrop =
tropo_weight(clim, atm, ip) * (1.0 - wpbl);
3087 const double wstrat = 1.0 - wpbl - wtrop;
3097 const double sigma = sqrt(2.0 * dx * fabs(cache->
dt[ip])) / 1000.;
3099 atm->
lat[ip] +=
DY2DEG(cache->
rs[3 * ip + 1] * sigma);
3104 const double sigma = sqrt(2.0 * dz * fabs(cache->
dt[ip])) / 1000.;
3105 atm->
p[ip] +=
DZ2DP(cache->
rs[3 * ip + 2] * sigma, atm->
p[ip]);
3124 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
3127 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
3139 const double dz = 1000. * (
Z(ps - ctl->
dry_depo_dp) -
Z(ps));
3159 const double aux = exp(-cache->
dt[ip] * v_dep / dz);
3160 if (ctl->
qnt_m >= 0) {
3163 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
3164 atm->
q[ctl->
qnt_m][ip] *= aux;
3188 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
3191 const double a = 3.12541941e-06;
3192 const double b = -5.72532259e-01;
3193 const double low = pow(1. / a, 1. / b);
3197 "acc data present(ctl,cache,ctl,met0,met1,atm)") {
3204 if (!(lwc > 0 || rwc > 0))
3215 const double k = 9.1e7 * exp(-29700. /
RI * (1. / t - 1. / 298.15));
3218 const double H_SO2 =
3219 1.3e-2 * exp(2900. * (1. / t - 1. / 298.15)) *
RI * t;
3220 const double K_1S = 1.23e-2 * exp(2.01e3 * (1. / t - 1. / 298.15));
3223 const double H_h2o2 =
3224 8.3e2 * exp(7600. * (1. / t - 1. / 298.15)) *
RI * t;
3230 cor = atm->
q[ctl->
qnt_Cx][ip] >
3231 low ? a * pow(atm->
q[ctl->
qnt_Cx][ip], b) : 1;
3233 const double h2o2 = H_h2o2
3235 * M * cor * 1000. /
AVO;
3238 const double rho_air = atm->
p[ip] / (
RI * t) *
MA / 10.;
3239 const double CWC = (lwc + rwc) * rho_air / 1e3;
3242 const double rate_coef = k * K_1S * h2o2 * H_SO2 * CWC;
3243 const double aux = exp(-cache->
dt[ip] * rate_coef);
3244 if (ctl->
qnt_m >= 0) {
3247 atm->
q[ctl->
qnt_m][ip] *= aux;
3268 SELECT_TIMER(
"MODULE_ISOSURF_INIT",
"PHYSICS", NVTX_GPU);
3279 PARTICLE_LOOP(0, atm->
np, 0,
"acc data present(cache,met0,met1,atm)") {
3282 cache->
iso_var[ip] = atm->
p[ip] / t;
3288 PARTICLE_LOOP(0, atm->
np, 0,
"acc data present(cache,met0,met1,atm)") {
3299 LOG(1,
"Read balloon pressure data: %s", ctl->
balloon);
3303 if (!(in = fopen(ctl->
balloon,
"r")))
3304 ERRMSG(
"Cannot open file!");
3308 while (fgets(line,
LEN, in))
3309 if (sscanf(line,
"%lg %lg", &(cache->
iso_ts[cache->
iso_n]),
3312 ERRMSG(
"Too many data points!");
3315 if (cache->
iso_n < 1)
3316 ERRMSG(
"Could not read any data!");
3339 PARTICLE_LOOP(0, atm->
np, 0,
"acc data present(ctl,cache,met0,met1,atm)") {
3352 atm->
p[ip] = cache->
iso_var[ip] * t;
3358 atm->
p[ip] = 1000. * pow(cache->
iso_var[ip] / t, -1. / 0.286);
3364 atm->
p[ip] = cache->
iso_ps[0];
3391 const int nvar = NVAR, nfix = NFIX, nreact = NREACT;
3392 double rtol[1] = { 1.0e-3 };
3393 double atol[1] = { 1.0 };
3397#pragma acc data copy(rtol,atol,nvar,nfix,nreact)
3400 "acc data present(ctl,cache,clim,met0,met1,atm) ") {
3403 double var[nvar], fix[nfix], rconst[nreact];
3404 for (
int i = 0; i < nvar; i++)
3406 for (
int i = 0; i < nfix; i++)
3408 for (
int i = 0; i < nreact; i++)
3410 kpp_chem_initialize(ctl, clim, met0, met1, atm, var, fix, rconst, ip);
3415 for (
int i = 0; i < 20; i++) {
3422 Rosenbrock(var, fix, rconst, 0, ctl->
dt_kpp,
3423 atol, rtol, &FunTemplate, &JacTemplate, rpar, ipar);
3426 kpp_chem_output2atm(atm, ctl, met0, met1, var, ip);
3447 ERRMSG(
"Need T_ice and T_NAT to calculate T_STS!");
3451 "acc data present(ctl,cache,clim,met0,met1,atm)") {
3453 double ps, ts, zs, us, vs, ess, nss, shf, lsm, sst, pbl, pt, pct, pcb,
3454 cl, plcl, plfc, pel, cape, cin, o3c, pv, t, tt, u, v, w, h2o, h2ot,
3455 o3, lwc, rwc, iwc, swc, cc, z, zt;
3503 atm->
lon[ip], atm->
lat[ip], atm->
p[ip]));
3505 atm->
lat[ip], atm->
p[ip]));
3507 atm->
lat[ip], atm->
p[ip]));
3509 atm->
lat[ip], atm->
p[ip]));
3510 SET_ATM(qnt_vh, sqrt(u * u + v * v));
3529 atm->
lat[ip], atm->
p[ip])));
3547 const int np = atm->
np;
3548 int *restrict
const ixs = (
int *) malloc((
size_t) np *
sizeof(int));
3549 int *restrict
const iys = (
int *) malloc((
size_t) np *
sizeof(int));
3550 int *restrict
const izs = (
int *) malloc((
size_t) np *
sizeof(int));
3558 const double t0 = t - 0.5 * ctl->
dt_mod;
3559 const double t1 = t + 0.5 * ctl->
dt_mod;
3563#pragma acc enter data create(ixs[0:np],iys[0:np],izs[0:np])
3564#pragma acc data present(ctl,clim,atm,ixs,iys,izs)
3565#pragma acc parallel loop independent gang vector
3567#pragma omp parallel for default(shared)
3569 for (
int ip = 0; ip < np; ip++) {
3572 izs[ip] = (int) ((
Z(atm->
p[ip]) - ctl->
mixing_z0) / dz);
3573 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
3574 || ixs[ip] < 0 || ixs[ip] >= ctl->
mixing_nx
3575 || iys[ip] < 0 || iys[ip] >= ctl->
mixing_ny
3576 || izs[ip] < 0 || izs[ip] >= ctl->
mixing_nz)
3581 if (ctl->
nens > 0) {
3582 if (ctl->
qnt_m >= 0)
3617 if (ctl->
qnt_m >= 0)
3655#pragma acc exit data delete(ixs,iys,izs)
3671 const int qnt_idx) {
3674 const int np = atm->
np;
3676 double *restrict
const cmean =
3677 (
double *) malloc((
size_t) ngrid *
sizeof(double));
3678 int *restrict
const count = (
int *) malloc((
size_t) ngrid *
sizeof(int));
3682#pragma acc enter data create(cmean[0:ngrid],count[0:ngrid])
3683#pragma acc data present(ctl,clim,atm,ixs,iys,izs,cmean,count)
3684#pragma acc parallel loop independent gang vector
3689#pragma omp parallel for
3691 for (
int i = 0; i < ngrid; i++) {
3698#pragma acc parallel loop independent gang vector
3700 for (
int ip = 0; ip < np; ip++)
3705#pragma acc atomic update
3707 cmean[idx] += atm->
q[qnt_idx][ip];
3709#pragma acc atomic update
3714#pragma acc parallel loop independent gang vector
3719#pragma omp parallel for
3721 for (
int i = 0; i < ngrid; i++)
3723 cmean[i] /= count[i];
3727#pragma acc parallel loop independent gang vector
3729#pragma omp parallel for
3731 for (
int ip = 0; ip < np; ip++)
3735 double mixparam = 1.0;
3742 atm->
q[qnt_idx][ip] +=
3745 - atm->
q[qnt_idx][ip]) * mixparam;
3750#pragma acc exit data delete(cmean,count)
3765 const int qnt_idx) {
3768 const int np = atm->
np;
3770 double *restrict
const cmean =
3771 (
double *) malloc((
size_t) ngrid * (size_t) ctl->
nens *
sizeof(
double));
3772 int *restrict
const count =
3773 (
int *) malloc((
size_t) ngrid * (size_t) ctl->
nens *
sizeof(
int));
3777#pragma acc enter data create(cmean[0:ngrid],count[0:ngrid])
3778#pragma acc data present(ctl,clim,atm,ixs,iys,izs,cmean,count)
3779#pragma acc parallel loop independent gang vector
3784#pragma omp parallel for
3786 for (
int i = 0; i < ngrid * ctl->
nens; i++) {
3793#pragma acc parallel loop independent gang vector
3795 for (
int ip = 0; ip < np; ip++)
3797 const int ens = (int) atm->
q[ctl->
qnt_ens][ip];
3798 const int idx = ens * ngrid +
ARRAY_3D
3801#pragma acc atomic update
3803 cmean[idx] += atm->
q[qnt_idx][ip];
3805#pragma acc atomic update
3810#pragma acc parallel loop independent gang vector
3815#pragma omp parallel for
3817 for (
int i = 0; i < ngrid * ctl->
nens; i++)
3819 cmean[i] /= count[i];
3823#pragma acc parallel loop independent gang vector
3825#pragma omp parallel for
3827 for (
int ip = 0; ip < np; ip++)
3830 int ens = (int) atm->
q[ctl->
qnt_ens][ip];
3832 double mixparam = 1.0;
3839 atm->
q[qnt_idx][ip] +=
3843 - atm->
q[qnt_idx][ip]) * mixparam;
3848#pragma acc exit data delete(cmean,count)
3869 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
3872 const double a = 4.71572206e-08;
3873 const double b = -8.28782867e-01;
3874 const double low = pow(1. / a, 1. / b);
3878 "acc data present(ctl,cache,clim,met0,met1,atm)") {
3904 0 ? pow(298. / t, ctl->
oh_chem[1]) : 1.);
3907 0 ? pow(298. / t, ctl->
oh_chem[3]) : 1.);
3908 const double c = log10(k0 * M / ki);
3909 k = k0 * M / (1. + k0 * M / ki) * pow(0.6, 1. / (1. + c * c));
3918 low ? a * pow(atm->
q[ctl->
qnt_Cx][ip], b) : 1;
3921 const double rate_coef =
3923 atm->
lat[ip], atm->
p[ip]) * M * cor;
3924 const double aux = exp(-cache->
dt[ip] * rate_coef);
3925 if (ctl->
qnt_m >= 0) {
3928 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
3929 atm->
q[ctl->
qnt_m][ip] *= aux;
3950 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(cache,met0,met1,atm)") {
3961 while (atm->
lat[ip] < -90 || atm->
lat[ip] > 90) {
3962 if (atm->
lat[ip] > 90) {
3963 atm->
lat[ip] = 180 - atm->
lat[ip];
3964 atm->
lon[ip] += 180;
3966 if (atm->
lat[ip] < -90) {
3967 atm->
lat[ip] = -180 - atm->
lat[ip];
3968 atm->
lon[ip] += 180;
3973 while (atm->
lon[ip] < -180)
3974 atm->
lon[ip] += 360;
3975 while (atm->
lon[ip] >= 180)
3976 atm->
lon[ip] -= 360;
3979 if (atm->
p[ip] < met0->
p[met0->
np - 1]) {
3980 atm->
p[ip] = met0->
p[met0->
np - 1];
3981 }
else if (atm->
p[ip] > 300.) {
3983 if (atm->
p[ip] > ps)
3995 gsl_rng_env_setup();
3996 if (omp_get_max_threads() >
NTHREADS)
3997 ERRMSG(
"Too many threads!");
3998 for (
int i = 0; i <
NTHREADS; i++) {
3999 rng[i] = gsl_rng_alloc(gsl_rng_default);
4000 gsl_rng_set(rng[i], gsl_rng_default_seed
4001 + (
long unsigned) (ntask *
NTHREADS + i));
4006 if (curandCreateGenerator(&rng_curand, CURAND_RNG_PSEUDO_DEFAULT) !=
4007 CURAND_STATUS_SUCCESS)
4008 ERRMSG(
"Cannot create random number generator!");
4009 if (curandSetPseudoRandomGeneratorSeed(rng_curand, ntask) !=
4010 CURAND_STATUS_SUCCESS)
4011 ERRMSG(
"Cannot set seed for random number generator!");
4014 (cudaStream_t) acc_get_cuda_stream(acc_async_sync)) !=
4015 CURAND_STATUS_SUCCESS)
4016 ERRMSG(
"Cannot set stream for random number generator!");
4033#pragma omp parallel for default(shared)
4034 for (
size_t i = 0; i < n; ++i)
4035 rs[i] = gsl_rng_uniform(rng[omp_get_thread_num()]);
4039 else if (method == 1) {
4040#pragma omp parallel for default(shared)
4041 for (
size_t i = 0; i < n; ++i)
4042 rs[i] = gsl_ran_gaussian_ziggurat(rng[omp_get_thread_num()], 1.0);
4048#pragma acc update device(rs[:n])
4056 const uint64_t key = 0xc8e4fd154ce32f6d;
4060#pragma acc data present(rs)
4061#pragma acc parallel loop independent gang vector
4063#pragma omp parallel for default(shared)
4065 for (
size_t i = 0; i < n + 1; ++i) {
4066 uint64_t r, t, x, y, z;
4067 y = x = (rng_ctr + i) * key;
4070 x = (x >> 32) | (x << 32);
4072 x = (x >> 32) | (x << 32);
4074 x = (x >> 32) | (x << 32);
4076 x = (x >> 32) | (x << 32);
4077 r = t ^ ((x * x + y) >> 32);
4078 rs[i] = (double) r / (
double) UINT64_MAX;
4085#pragma acc parallel loop independent gang vector
4087#pragma omp parallel for default(shared)
4089 for (
size_t i = 0; i < n; i += 2) {
4090 const double r = sqrt(-2.0 * log(rs[i]));
4091 const double phi = 2.0 * M_PI * rs[i + 1];
4092 rs[i] = r * cosf((
float) phi);
4093 rs[i + 1] = r * sinf((
float) phi);
4101#pragma acc host_data use_device(rs)
4106 if (curandGenerateUniformDouble(rng_curand, rs, (n < 4 ? 4 : n)) !=
4107 CURAND_STATUS_SUCCESS)
4108 ERRMSG(
"Cannot create random numbers!");
4112 else if (method == 1) {
4113 if (curandGenerateNormalDouble
4114 (rng_curand, rs, (n < 4 ? 4 : n), 0.0,
4115 1.0) != CURAND_STATUS_SUCCESS)
4116 ERRMSG(
"Cannot create random numbers!");
4120 ERRMSG(
"MPTRAC was compiled without cuRAND!");
4138 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
4146 const double v_s =
sedi(atm->
p[ip], t, atm->
q[ctl->
qnt_rp][ip],
4150 atm->
p[ip] +=
DZ2DP(v_s * cache->
dt[ip] / 1000., atm->
p[ip]);
4165 const int np = atm->
np;
4166 double *restrict
const a = (
double *) malloc((
size_t) np *
sizeof(double));
4167 int *restrict
const p = (
int *) malloc((
size_t) np *
sizeof(int));
4170#pragma acc enter data create(a[0:np],p[0:np])
4171#pragma acc data present(ctl,met0,atm,a,p)
4176#pragma acc parallel loop independent gang vector
4178#pragma omp parallel for default(shared)
4180 for (
int ip = 0; ip < np; ip++) {
4190#pragma acc host_data use_device(a,p)
4195 ERRMSG(
"MPTRAC was compiled without Thrust library!");
4203 for (
int iq = 0; iq < ctl->
nq; iq++)
4208#pragma acc exit data delete(a,p)
4222 double *restrict
const help =
4223 (
double *) malloc((
size_t) np *
sizeof(double));
4227#pragma acc enter data create(help[0:np])
4228#pragma acc data present(a,p,help)
4229#pragma acc parallel loop independent gang vector
4231#pragma omp parallel for default(shared)
4233 for (
int ip = 0; ip < np; ip++)
4234 help[ip] = a[p[ip]];
4236#pragma acc parallel loop independent gang vector
4238#pragma omp parallel for default(shared)
4240 for (
int ip = 0; ip < np; ip++)
4245#pragma acc exit data delete(help)
4262 const double latmin = gsl_stats_min(met0->
lat, 1, (
size_t) met0->
ny),
4263 latmax = gsl_stats_max(met0->
lat, 1, (
size_t) met0->
ny);
4266 (fabs(met0->
lon[met0->
nx - 1] - met0->
lon[0] - 360.0) >= 0.01);
4269 PARTICLE_LOOP(0, atm->
np, 0,
"acc data present(ctl,cache,met0,atm)") {
4275 cache->
dt[ip] = t - atm->
time[ip];
4277 cache->
dt[ip] = 0.0;
4280 if (local && (atm->
lon[ip] <= met0->
lon[0]
4281 || atm->
lon[ip] >= met0->
lon[met0->
nx - 1]
4282 || atm->
lat[ip] <= latmin || atm->
lat[ip] >= latmax))
4283 cache->
dt[ip] = 0.0;
4294 SELECT_TIMER(
"MODULE_TIMESTEPS_INIT",
"PHYSICS", NVTX_GPU);
4298 ctl->
t_start = gsl_stats_min(atm->
time, 1, (
size_t) atm->
np);
4300 ctl->
t_stop = gsl_stats_max(atm->
time, 1, (
size_t) atm->
np);
4302 ctl->
t_start = gsl_stats_max(atm->
time, 1, (
size_t) atm->
np);
4304 ctl->
t_stop = gsl_stats_min(atm->
time, 1, (
size_t) atm->
np);
4309 ERRMSG(
"Nothing to do! Check T_STOP and DIRECTION!");
4329 SELECT_TIMER(
"MODULE_TRACER_CHEM",
"PHYSICS", NVTX_GPU);
4333 "acc data present(ctl,cache,clim,met0,met1,atm)") {
4356 const double K_o1d =
ARRHENIUS(3.30e-10, 0, t) * o1d * M;
4358 atm->
p[ip], sza, o3c);
4359 atm->
q[ctl->
qnt_Cccl4][ip] *= exp(-cache->
dt[ip] * (K_hv + K_o1d));
4364 const double K_o1d =
ARRHENIUS(2.30e-10, 0, t) * o1d * M;
4366 atm->
p[ip], sza, o3c);
4367 atm->
q[ctl->
qnt_Cccl3f][ip] *= exp(-cache->
dt[ip] * (K_hv + K_o1d));
4372 const double K_o1d =
ARRHENIUS(1.40e-10, -25, t) * o1d * M;
4374 atm->
p[ip], sza, o3c);
4375 atm->
q[ctl->
qnt_Cccl2f2][ip] *= exp(-cache->
dt[ip] * (K_hv + K_o1d));
4380 const double K_o1d =
ARRHENIUS(1.19e-10, -20, t) * o1d * M;
4382 atm->
p[ip], sza, o3c);
4383 atm->
q[ctl->
qnt_Cn2o][ip] *= exp(-cache->
dt[ip] * (K_hv + K_o1d));
4402 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
4405 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
4411 if (!isfinite(pct) || atm->
p[ip] <= pct)
4427 double lwc, rwc, iwc, swc;
4432 const int inside = (lwc > 0 || rwc > 0 || iwc > 0 || swc > 0);
4446 else if (t <= 238.15)
4466 const double K_1 = 1.23e-2 * exp(2.01e3 * (1. / t - 1. / 298.15));
4467 const double K_2 = 6e-8 * exp(1.12e3 * (1. / t - 1. / 298.15));
4468 h *= (1. + K_1 / H_ion + K_1 * K_2 /
SQR(H_ion));
4472 const double dz = 1e3 * (
Z(pct) -
Z(pcb));
4475 lambda = h *
RI * t * Is / 3.6e6 / dz * eta;
4501 const double dz = 1e3 * (
Z(pct) -
Z(pcb));
4504 lambda = h *
RI * t * Is / 3.6e6 / dz * eta;
4509 const double aux = exp(-cache->
dt[ip] * lambda);
4510 if (ctl->
qnt_m >= 0) {
4513 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
4514 atm->
q[ctl->
qnt_m][ip] *= aux;
4538 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
4540 if (acc_get_num_devices(acc_device_nvidia) <= 0)
4541 ERRMSG(
"Not running on a GPU device!");
4542 acc_set_device_num(rank % acc_get_num_devices(acc_device_nvidia),
4544 acc_device_t device_type = acc_get_device_type();
4545 acc_init(device_type);
4559 SELECT_TIMER(
"CREATE_DATA_REGION",
"MEMORY", NVTX_GPU);
4560 ctl_t *ctlup = *ctl;
4563 met_t *met0up = *met0;
4564 met_t *met1up = *met1;
4565 atm_t *atmup = *atm;
4566#pragma acc enter data create(ctlup[:1],cacheup[:1],climup[:1],met0up[:1],met1up[:1],atmup[:1])
4582 SELECT_TIMER(
"DELETE_DATA_REGION",
"MEMORY", NVTX_GPU);
4583#pragma acc exit data delete (ctl,cache,clim,met0,met1,atm)
4609 char cachefile[
LEN], cmd[2 *
LEN], filename[
LEN];
4615 if (t == ctl->
t_start || !init) {
4622 ERRMSG(
"Cannot open file!");
4627 ERRMSG(
"Cannot open file!");
4637 sprintf(cmd,
"cat %s > /dev/null &", cachefile);
4638 LOG(1,
"Caching: %s", cachefile);
4639 if (system(cmd) != 0)
4640 WARN(
"Caching command failed!");
4645 if (t > (*met1)->time) {
4655 ERRMSG(
"Cannot open file!");
4665 sprintf(cmd,
"cat %s > /dev/null &", cachefile);
4666 LOG(1,
"Caching: %s", cachefile);
4667 if (system(cmd) != 0)
4668 WARN(
"Caching command failed!");
4673 if (t < (*met0)->time) {
4683 ERRMSG(
"Cannot open file!");
4693 sprintf(cmd,
"cat %s > /dev/null &", cachefile);
4694 LOG(1,
"Caching: %s", cachefile);
4695 if (system(cmd) != 0)
4696 WARN(
"Caching command failed!");
4701 if ((*met0)->nx != 0 && (*met1)->nx != 0) {
4702 if ((*met0)->nx != (*met1)->nx
4703 || (*met0)->ny != (*met1)->ny || (*met0)->np != (*met1)->np)
4704 ERRMSG(
"Meteo grid dimensions do not match!");
4705 for (
int ix = 0; ix < (*met0)->nx; ix++)
4706 if (fabs((*met0)->lon[ix] - (*met1)->lon[ix]) > 0.001)
4707 ERRMSG(
"Meteo grid longitudes do not match!");
4708 for (
int iy = 0; iy < (*met0)->ny; iy++)
4709 if (fabs((*met0)->lat[iy] - (*met1)->lat[iy]) > 0.001)
4710 ERRMSG(
"Meteo grid latitudes do not match!");
4711 for (
int ip = 0; ip < (*met0)->np; ip++)
4712 if (fabs((*met0)->p[ip] - (*met1)->p[ip]) > 0.001)
4713 ERRMSG(
"Meteo grid pressure levels do not match!");
4739 const char *filename,
4752 LOG(1,
"Read atmospheric data: %s", filename);
4772 ERRMSG(
"Atmospheric data type not supported!");
4780 ERRMSG(
"Can not read any data!");
4784 LOG(2,
"Number of particles: %d", atm->
np);
4785 gsl_stats_minmax(&mini, &maxi, atm->
time, 1, (
size_t) atm->
np);
4786 LOG(2,
"Time range: %.2f ... %.2f s", mini, maxi);
4787 gsl_stats_minmax(&mini, &maxi, atm->
p, 1, (
size_t) atm->
np);
4788 LOG(2,
"Altitude range: %g ... %g km",
Z(maxi),
Z(mini));
4789 LOG(2,
"Pressure range: %g ... %g hPa", maxi, mini);
4790 gsl_stats_minmax(&mini, &maxi, atm->
lon, 1, (
size_t) atm->
np);
4791 LOG(2,
"Longitude range: %g ... %g deg", mini, maxi);
4792 gsl_stats_minmax(&mini, &maxi, atm->
lat, 1, (
size_t) atm->
np);
4793 LOG(2,
"Latitude range: %g ... %g deg", mini, maxi);
4794 for (
int iq = 0; iq < ctl->
nq; iq++) {
4796 sprintf(msg,
"Quantity %s range: %s ... %s %s",
4799 gsl_stats_minmax(&mini, &maxi, atm->
q[iq], 1, (
size_t) atm->
np);
4800 LOG(2, msg, mini, maxi);
4870 const char *filename,
4879 LOG(1,
"\nMassive-Parallel Trajectory Calculations (MPTRAC)\n"
4880 "(executable: %s | version: %s | compiled: %s, %s)\n",
4881 argv[0], VERSION, __DATE__, __TIME__);
4977 ctl->
nq = (int)
scan_ctl(filename, argc, argv,
"NQ", -1,
"0", NULL);
4979 ERRMSG(
"Too many quantities!");
4980 for (
int iq = 0; iq < ctl->
nq; iq++) {
4986 scan_ctl(filename, argc, argv,
"QNT_FORMAT", iq,
"%g",
4988 if (strcasecmp(ctl->
qnt_name[iq],
"aoa") == 0)
4992 SET_QNT(qnt_idx,
"idx",
"particle index",
"-")
4993 SET_QNT(qnt_ens,
"ens",
"ensemble index",
"-")
4994 SET_QNT(qnt_stat,
"stat",
"station flag",
"-")
4995 SET_QNT(qnt_m,
"m",
"mass",
"kg")
4996 SET_QNT(qnt_vmr,
"vmr",
"volume mixing ratio",
"ppv")
4997 SET_QNT(qnt_rp,
"rp",
"particle radius",
"microns")
4998 SET_QNT(qnt_rhop,
"rhop",
"particle density",
"kg/m^3")
4999 SET_QNT(qnt_ps,
"ps",
"surface pressure",
"hPa")
5000 SET_QNT(qnt_ts,
"ts",
"surface temperature",
"K")
5001 SET_QNT(qnt_zs,
"zs",
"surface height",
"km")
5002 SET_QNT(qnt_us,
"us",
"surface zonal wind",
"m/s")
5003 SET_QNT(qnt_vs,
"vs",
"surface meridional wind",
"m/s")
5004 SET_QNT(qnt_ess,
"ess",
"eastward turbulent surface stress",
"N/m^2")
5005 SET_QNT(qnt_nss,
"nss",
"northward turbulent surface stress",
"N/m^2")
5006 SET_QNT(qnt_shf,
"shf",
"surface sensible heat flux",
"W/m^2")
5007 SET_QNT(qnt_lsm,
"lsm",
"land-sea mask",
"1")
5008 SET_QNT(qnt_sst,
"sst",
"sea surface temperature",
"K")
5009 SET_QNT(qnt_pbl,
"pbl",
"planetary boundary layer",
"hPa")
5010 SET_QNT(qnt_pt,
"pt",
"tropopause pressure",
"hPa")
5011 SET_QNT(qnt_tt,
"tt",
"tropopause temperature",
"K")
5012 SET_QNT(qnt_zt,
"zt",
"tropopause geopotential height",
"km")
5013 SET_QNT(qnt_h2ot,
"h2ot",
"tropopause water vapor",
"ppv")
5014 SET_QNT(qnt_zg,
"zg",
"geopotential height",
"km")
5015 SET_QNT(qnt_p,
"p",
"pressure",
"hPa")
5016 SET_QNT(qnt_t,
"t",
"temperature",
"K")
5017 SET_QNT(qnt_rho,
"rho",
"air density",
"kg/m^3")
5018 SET_QNT(qnt_u,
"u",
"zonal wind",
"m/s")
5019 SET_QNT(qnt_v,
"v",
"meridional wind",
"m/s")
5020 SET_QNT(qnt_w,
"w",
"vertical velocity",
"hPa/s")
5021 SET_QNT(qnt_h2o,
"h2o",
"water vapor",
"ppv")
5022 SET_QNT(qnt_o3,
"o3",
"ozone",
"ppv")
5023 SET_QNT(qnt_lwc,
"lwc",
"cloud liquid water content",
"kg/kg")
5024 SET_QNT(qnt_rwc,
"rwc",
"cloud rain water content",
"kg/kg")
5025 SET_QNT(qnt_iwc,
"iwc",
"cloud ice water content",
"kg/kg")
5026 SET_QNT(qnt_swc,
"swc",
"cloud snow water content",
"kg/kg")
5027 SET_QNT(qnt_cc,
"cc",
"cloud cover",
"1")
5028 SET_QNT(qnt_pct,
"pct",
"cloud top pressure",
"hPa")
5029 SET_QNT(qnt_pcb,
"pcb",
"cloud bottom pressure",
"hPa")
5030 SET_QNT(qnt_cl,
"cl",
"total column cloud water",
"kg/m^2")
5031 SET_QNT(qnt_plcl,
"plcl",
"lifted condensation level",
"hPa")
5032 SET_QNT(qnt_plfc,
"plfc",
"level of free convection",
"hPa")
5033 SET_QNT(qnt_pel,
"pel",
"equilibrium level",
"hPa")
5034 SET_QNT(qnt_cape,
"cape",
"convective available potential energy",
5036 SET_QNT(qnt_cin,
"cin",
"convective inhibition",
"J/kg")
5037 SET_QNT(qnt_o3c,
"o3c",
"total column ozone",
"DU")
5038 SET_QNT(qnt_hno3,
"hno3",
"nitric acid",
"ppv")
5039 SET_QNT(qnt_oh,
"oh",
"hydroxyl radical",
"ppv")
5040 SET_QNT(qnt_h2o2,
"h2o2",
"hydrogen peroxide",
"ppv")
5041 SET_QNT(qnt_ho2,
"ho2",
"hydroperoxyl radical",
"ppv")
5042 SET_QNT(qnt_o1d,
"o1d",
"atomic oxygen",
"ppv")
5043 SET_QNT(qnt_mloss_oh,
"mloss_oh",
"mass loss due to OH chemistry",
"kg")
5044 SET_QNT(qnt_mloss_h2o2,
"mloss_h2o2",
5045 "mass loss due to H2O2 chemistry",
"kg")
5046 SET_QNT(qnt_mloss_kpp,
"mloss_kpp",
"mass loss due to kpp chemistry",
5048 SET_QNT(qnt_mloss_wet,
"mloss_wet",
"mass loss due to wet deposition",
5050 SET_QNT(qnt_mloss_dry,
"mloss_dry",
"mass loss due to dry deposition",
5052 SET_QNT(qnt_mloss_decay,
"mloss_decay",
5053 "mass loss due to exponential decay",
"kg")
5054 SET_QNT(qnt_loss_rate,
"loss_rate",
"total loss rate",
"s^-1")
5055 SET_QNT(qnt_psat,
"psat",
"saturation pressure over water",
"hPa")
5056 SET_QNT(qnt_psice,
"psice",
"saturation pressure over ice",
"hPa")
5057 SET_QNT(qnt_pw,
"pw",
"partial water vapor pressure",
"hPa")
5058 SET_QNT(qnt_sh,
"sh",
"specific humidity",
"kg/kg")
5059 SET_QNT(qnt_rh,
"rh",
"relative humidity",
"%%")
5060 SET_QNT(qnt_rhice,
"rhice",
"relative humidity over ice",
"%%")
5061 SET_QNT(qnt_theta,
"theta",
"potential temperature",
"K")
5062 SET_QNT(qnt_zeta,
"zeta",
"zeta coordinate",
"K")
5063 SET_QNT(qnt_zeta_d,
"zeta_d",
"diagnosed zeta coordinate",
"K")
5064 SET_QNT(qnt_tvirt,
"tvirt",
"virtual temperature",
"K")
5065 SET_QNT(qnt_lapse,
"lapse",
"temperature lapse rate",
"K/km")
5066 SET_QNT(qnt_vh,
"vh",
"horizontal velocity",
"m/s")
5067 SET_QNT(qnt_vz,
"vz",
"vertical velocity",
"m/s")
5068 SET_QNT(qnt_pv,
"pv",
"potential vorticity",
"PVU")
5069 SET_QNT(qnt_tdew,
"tdew",
"dew point temperature",
"K")
5070 SET_QNT(qnt_tice,
"tice",
"frost point temperature",
"K")
5071 SET_QNT(qnt_tsts,
"tsts",
"STS existence temperature",
"K")
5072 SET_QNT(qnt_tnat,
"tnat",
"NAT existence temperature",
"K")
5073 SET_QNT(qnt_Cx,
"Cx",
"Trace species x volume mixing ratio",
"ppv")
5074 SET_QNT(qnt_Ch2o,
"Ch2o",
"H2O volume mixing ratio",
"ppv")
5075 SET_QNT(qnt_Co3,
"Co3",
"O3 volume mixing ratio",
"ppv")
5076 SET_QNT(qnt_Cco,
"Cco",
"CO volume mixing ratio",
"ppv")
5077 SET_QNT(qnt_Coh,
"Coh",
"HO volume mixing ratio",
"ppv")
5078 SET_QNT(qnt_Ch,
"Ch",
"H radical volume mixing ratio",
"ppv")
5079 SET_QNT(qnt_Cho2,
"Cho2",
"HO2 volume mixing ratio",
"ppv")
5080 SET_QNT(qnt_Ch2o2,
"Ch2o2",
"H2O2 volume mixing ratio",
"ppv")
5081 SET_QNT(qnt_Co1d,
"Co1d",
"O(1D) volume mixing ratio",
"ppv")
5082 SET_QNT(qnt_Co3p,
"Co3p",
"O(3P) radical volume mixing ratio",
"ppv")
5083 SET_QNT(qnt_Cccl4,
"Cccl4",
"CCl4 (CFC-10) volume mixing ratio",
"ppv")
5084 SET_QNT(qnt_Cccl3f,
"Cccl3f",
"CCl3F (CFC-11) volume mixing ratio",
5086 SET_QNT(qnt_Cccl2f2,
"Cccl2f2",
"CCl2F2 (CFC-12) volume mixing ratio",
5088 SET_QNT(qnt_Cn2o,
"Cn2o",
"N2O volume mixing ratio",
"ppv")
5089 SET_QNT(qnt_Csf6,
"Csf6",
"SF6 volume mixing ratio",
"ppv")
5090 SET_QNT(qnt_aoa,
"aoa",
"age of air",
"s")
5096 (int)
scan_ctl(filename, argc, argv,
"ADVECT_VERT_COORD", -1,
"0", NULL);
5098 ERRMSG(
"Set ADVECT_VERT_COORD to 0, 1, or 2!");
5100 (int)
scan_ctl(filename, argc, argv,
"MET_VERT_COORD", -1,
"0", NULL);
5102 ERRMSG(
"Set MET_VERT_COORD to 0, 1, 2, 3, or 4!");
5104 ERRMSG(
"Please add zeta to your quantities for diabatic calculations!");
5107 (
"Using ADVECT_VERT_COORD = 2 requires meteo data on model levels!");
5111 (int)
scan_ctl(filename, argc, argv,
"DIRECTION", -1,
"1", NULL);
5113 ERRMSG(
"Set DIRECTION to -1 or 1!");
5114 ctl->
t_stop =
scan_ctl(filename, argc, argv,
"T_STOP", -1,
"1e100", NULL);
5115 ctl->
dt_mod =
scan_ctl(filename, argc, argv,
"DT_MOD", -1,
"180", NULL);
5119 ctl->
dt_met =
scan_ctl(filename, argc, argv,
"DT_MET", -1,
"3600", NULL);
5121 (int)
scan_ctl(filename, argc, argv,
"MET_CONVENTION", -1,
"0", NULL);
5123 (int)
scan_ctl(filename, argc, argv,
"MET_TYPE", -1,
"0", NULL);
5126 (
"Please use meteo files in netcdf format for diabatic calculations.");
5128 (int)
scan_ctl(filename, argc, argv,
"MET_CLAMS", -1,
"0", NULL);
5130 (int)
scan_ctl(filename, argc, argv,
"MET_NC_SCALE", -1,
"1", NULL);
5132 (int)
scan_ctl(filename, argc, argv,
"MET_NC_LEVEL", -1,
"0", NULL);
5134 (int)
scan_ctl(filename, argc, argv,
"MET_NC_QUANT", -1,
"0", NULL);
5136 (int)
scan_ctl(filename, argc, argv,
"MET_ZSTD_LEVEL", -1,
"0", NULL);
5138 (int)
scan_ctl(filename, argc, argv,
"MET_ZFP_PREC", -1,
"8", NULL);
5140 scan_ctl(filename, argc, argv,
"MET_ZFP_TOL_T", -1,
"5.0", NULL);
5142 scan_ctl(filename, argc, argv,
"MET_ZFP_TOL_Z", -1,
"0.5", NULL);
5144 (int)
scan_ctl(filename, argc, argv,
"MET_CMS_BATCH", -1,
"-1", NULL);
5146 (int)
scan_ctl(filename, argc, argv,
"MET_CMS_ZSTD", -1,
"1", NULL);
5148 (int)
scan_ctl(filename, argc, argv,
"MET_CMS_HEUR", -1,
"1", NULL);
5150 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_Z", -1,
"1.0", NULL);
5152 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_T", -1,
"0.05", NULL);
5154 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_U", -1,
"0.05", NULL);
5156 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_V", -1,
"0.05", NULL);
5158 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_W", -1,
"1.0", NULL);
5160 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_PV", -1,
"1.0", NULL);
5162 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_H2O", -1,
"1.0", NULL);
5164 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_O3", -1,
"1.0", NULL);
5166 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_LWC", -1,
"1.0", NULL);
5168 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_RWC", -1,
"1.0", NULL);
5170 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_IWC", -1,
"1.0", NULL);
5172 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_SWC", -1,
"1.0", NULL);
5174 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_CC", -1,
"1.0", NULL);
5175 ctl->
met_dx = (int)
scan_ctl(filename, argc, argv,
"MET_DX", -1,
"1", NULL);
5176 ctl->
met_dy = (int)
scan_ctl(filename, argc, argv,
"MET_DY", -1,
"1", NULL);
5177 ctl->
met_dp = (int)
scan_ctl(filename, argc, argv,
"MET_DP", -1,
"1", NULL);
5179 ERRMSG(
"MET_DX, MET_DY, and MET_DP need to be greater than zero!");
5180 ctl->
met_sx = (int)
scan_ctl(filename, argc, argv,
"MET_SX", -1,
"1", NULL);
5181 ctl->
met_sy = (int)
scan_ctl(filename, argc, argv,
"MET_SY", -1,
"1", NULL);
5182 ctl->
met_sp = (int)
scan_ctl(filename, argc, argv,
"MET_SP", -1,
"1", NULL);
5184 ERRMSG(
"MET_SX, MET_SY, and MET_SP need to be greater than zero!");
5186 scan_ctl(filename, argc, argv,
"MET_DETREND", -1,
"-999", NULL);
5187 ctl->
met_np = (int)
scan_ctl(filename, argc, argv,
"MET_NP", -1,
"0", NULL);
5189 ERRMSG(
"Too many pressure levels!");
5191 (int)
scan_ctl(filename, argc, argv,
"MET_PRESS_LEVEL_DEF", -1,
"-1",
5197 for (
int ip = 0; ip < ctl->
met_np; ip++)
5199 scan_ctl(filename, argc, argv,
"MET_P", ip,
"", NULL);
5203 (int)
scan_ctl(filename, argc, argv,
"MET_NLEV", -1,
"0", NULL);
5205 ERRMSG(
"Too many model levels!");
5206 for (
int ip = 0; ip < ctl->
met_nlev; ip++) {
5208 scan_ctl(filename, argc, argv,
"MET_LEV_HYAM", ip,
"", NULL);
5210 scan_ctl(filename, argc, argv,
"MET_LEV_HYBM", ip,
"", NULL);
5213 (int)
scan_ctl(filename, argc, argv,
"MET_GEOPOT_SX", -1,
"-1", NULL);
5215 (int)
scan_ctl(filename, argc, argv,
"MET_GEOPOT_SY", -1,
"-1", NULL);
5217 (int)
scan_ctl(filename, argc, argv,
"MET_RELHUM", -1,
"0", NULL);
5219 (int)
scan_ctl(filename, argc, argv,
"MET_CAPE", -1,
"1", NULL);
5221 ERRMSG(
"Set MET_CAPE to 0 or 1!");
5223 (int)
scan_ctl(filename, argc, argv,
"MET_PBL", -1,
"3", NULL);
5225 ERRMSG(
"Set MET_PBL to 0 ... 3!");
5227 scan_ctl(filename, argc, argv,
"MET_PBL_MIN", -1,
"0.1", NULL);
5229 scan_ctl(filename, argc, argv,
"MET_PBL_MAX", -1,
"5.0", NULL);
5231 (int)
scan_ctl(filename, argc, argv,
"MET_TROPO", -1,
"3", NULL);
5233 ERRMSG(
"Set MET_TROPO to 0 ... 5!");
5235 scan_ctl(filename, argc, argv,
"MET_TROPO_PV", -1,
"3.5", NULL);
5237 scan_ctl(filename, argc, argv,
"MET_TROPO_THETA", -1,
"380", NULL);
5239 (int)
scan_ctl(filename, argc, argv,
"MET_TROPO_SPLINE", -1,
"1", NULL);
5241 scan_ctl(filename, argc, argv,
"MET_DT_OUT", -1,
"0.1", NULL);
5243 (int)
scan_ctl(filename, argc, argv,
"MET_CACHE", -1,
"0", NULL);
5245 (int)
scan_ctl(filename, argc, argv,
"MET_MPI_SHARE", -1,
"0", NULL);
5248 ctl->
sort_dt =
scan_ctl(filename, argc, argv,
"SORT_DT", -1,
"-999", NULL);
5252 (int)
scan_ctl(filename, argc, argv,
"ISOSURF", -1,
"0", NULL);
5257 (int)
scan_ctl(filename, argc, argv,
"RNG_TYPE", -1,
"1", NULL);
5259 ERRMSG(
"Set RNG_TYPE to 0, 1, or 2!");
5262 ctl->
advect = (int)
scan_ctl(filename, argc, argv,
"ADVECT", -1,
"2", NULL);
5266 ERRMSG(
"Set ADVECT to 0, 1, 2, or 4!");
5270 = (int)
scan_ctl(filename, argc, argv,
"DIFFUSION", -1,
"0", NULL);
5272 ERRMSG(
"Set DIFFUSION to 0, 1 or 2!");
5274 scan_ctl(filename, argc, argv,
"TURB_DX_PBL", -1,
"50", NULL);
5276 scan_ctl(filename, argc, argv,
"TURB_DX_TROP", -1,
"50", NULL);
5278 scan_ctl(filename, argc, argv,
"TURB_DX_STRAT", -1,
"0", NULL);
5280 scan_ctl(filename, argc, argv,
"TURB_DZ_PBL", -1,
"0", NULL);
5282 scan_ctl(filename, argc, argv,
"TURB_DZ_TROP", -1,
"0", NULL);
5284 scan_ctl(filename, argc, argv,
"TURB_DZ_STRAT", -1,
"0.1", NULL);
5286 scan_ctl(filename, argc, argv,
"TURB_MESOX", -1,
"0.16", NULL);
5288 scan_ctl(filename, argc, argv,
"TURB_MESOZ", -1,
"0.16", NULL);
5292 = (int)
scan_ctl(filename, argc, argv,
"CONV_MIX_PBL", -1,
"0", NULL);
5294 =
scan_ctl(filename, argc, argv,
"CONV_PBL_TRANS", -1,
"0", NULL);
5296 =
scan_ctl(filename, argc, argv,
"CONV_CAPE", -1,
"-999", NULL);
5298 =
scan_ctl(filename, argc, argv,
"CONV_CIN", -1,
"-999", NULL);
5299 ctl->
conv_dt =
scan_ctl(filename, argc, argv,
"CONV_DT", -1,
"-999", NULL);
5303 scan_ctl(filename, argc, argv,
"BOUND_MASS", -1,
"-999", NULL);
5305 scan_ctl(filename, argc, argv,
"BOUND_MASS_TREND", -1,
"0", NULL);
5307 scan_ctl(filename, argc, argv,
"BOUND_VMR", -1,
"-999", NULL);
5309 scan_ctl(filename, argc, argv,
"BOUND_VMR_TREND", -1,
"0", NULL);
5311 scan_ctl(filename, argc, argv,
"BOUND_LAT0", -1,
"-999", NULL);
5313 scan_ctl(filename, argc, argv,
"BOUND_LAT1", -1,
"-999", NULL);
5315 scan_ctl(filename, argc, argv,
"BOUND_P0", -1,
"-999", NULL);
5317 scan_ctl(filename, argc, argv,
"BOUND_P1", -1,
"-999", NULL);
5319 scan_ctl(filename, argc, argv,
"BOUND_DPS", -1,
"-999", NULL);
5321 scan_ctl(filename, argc, argv,
"BOUND_DZS", -1,
"-999", NULL);
5323 scan_ctl(filename, argc, argv,
"BOUND_ZETAS", -1,
"-999", NULL);
5325 (int)
scan_ctl(filename, argc, argv,
"BOUND_PBL", -1,
"0", NULL);
5329 if (strcasecmp(ctl->
species,
"CF2Cl2") == 0) {
5333 }
else if (strcasecmp(ctl->
species,
"CFCl3") == 0) {
5337 }
else if (strcasecmp(ctl->
species,
"CH4") == 0) {
5344 }
else if (strcasecmp(ctl->
species,
"CO") == 0) {
5353 }
else if (strcasecmp(ctl->
species,
"CO2") == 0) {
5357 }
else if (strcasecmp(ctl->
species,
"H2O") == 0) {
5359 }
else if (strcasecmp(ctl->
species,
"N2O") == 0) {
5363 }
else if (strcasecmp(ctl->
species,
"NH3") == 0) {
5370 }
else if (strcasecmp(ctl->
species,
"HNO3") == 0) {
5374 }
else if (strcasecmp(ctl->
species,
"NO") == 0) {
5383 }
else if (strcasecmp(ctl->
species,
"NO2") == 0) {
5392 }
else if (strcasecmp(ctl->
species,
"O3") == 0) {
5399 }
else if (strcasecmp(ctl->
species,
"SF6") == 0) {
5403 }
else if (strcasecmp(ctl->
species,
"SO2") == 0) {
5416 sprintf(defstr,
"%g", ctl->
molmass);
5417 ctl->
molmass =
scan_ctl(filename, argc, argv,
"MOLMASS", -1, defstr, NULL);
5422 (int)
scan_ctl(filename, argc, argv,
"OH_CHEM_REACTION", -1, defstr,
5424 for (
int ip = 0; ip < 4; ip++) {
5425 sprintf(defstr,
"%g", ctl->
oh_chem[ip]);
5427 scan_ctl(filename, argc, argv,
"OH_CHEM", ip, defstr, NULL);
5430 scan_ctl(filename, argc, argv,
"OH_CHEM_BETA", -1,
"0", NULL);
5434 (int)
scan_ctl(filename, argc, argv,
"H2O2_CHEM_REACTION", -1,
"0", NULL);
5438 (int)
scan_ctl(filename, argc, argv,
"KPP_CHEM", -1,
"0", NULL);
5439 ctl->
dt_kpp =
scan_ctl(filename, argc, argv,
"DT_KPP", -1,
"1800", NULL);
5443 (int)
scan_ctl(filename, argc, argv,
"TRACER_CHEM", -1,
"0", NULL);
5446 for (
int ip = 0; ip < 2; ip++) {
5449 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_H", ip, defstr, NULL);
5451 for (
int ip = 0; ip < 1; ip++) {
5454 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_H", ip, defstr, NULL);
5457 scan_ctl(filename, argc, argv,
"WET_DEPO_SO2_PH", -1,
"0", NULL);
5459 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_A", -1,
"0", NULL);
5461 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_B", -1,
"0", NULL);
5463 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_A", -1,
"0", NULL);
5465 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_B", -1,
"0", NULL);
5467 scan_ctl(filename, argc, argv,
"WET_DEPO_PRE", 0,
"0.5", NULL);
5469 scan_ctl(filename, argc, argv,
"WET_DEPO_PRE", 1,
"0.36", NULL);
5471 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_RET_RATIO", -1,
"1", NULL);
5473 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_RET_RATIO", -1,
"1", NULL);
5477 scan_ctl(filename, argc, argv,
"DRY_DEPO_VDEP", -1,
"0", NULL);
5479 scan_ctl(filename, argc, argv,
"DRY_DEPO_DP", -1,
"30", NULL);
5482 scan_ctl(filename, argc, argv,
"CLIM_PHOTO", -1,
5483 "../../data/clams_photolysis_rates.nc", ctl->
clim_photo);
5484 scan_ctl(filename, argc, argv,
"CLIM_HNO3_FILENAME", -1,
5486 scan_ctl(filename, argc, argv,
"CLIM_OH_FILENAME", -1,
5488 scan_ctl(filename, argc, argv,
"CLIM_H2O2_FILENAME", -1,
5490 scan_ctl(filename, argc, argv,
"CLIM_HO2_FILENAME", -1,
5492 scan_ctl(filename, argc, argv,
"CLIM_O1D_FILENAME", -1,
5494 scan_ctl(filename, argc, argv,
"CLIM_CCL4_TIMESERIES", -1,
5496 scan_ctl(filename, argc, argv,
"CLIM_CCL3F_TIMESERIES", -1,
5498 scan_ctl(filename, argc, argv,
"CLIM_CCL2F2_TIMESERIES", -1,
5500 scan_ctl(filename, argc, argv,
"CLIM_N2O_TIMESERIES", -1,
5502 scan_ctl(filename, argc, argv,
"CLIM_SF6_TIMESERIES", -1,
5507 scan_ctl(filename, argc, argv,
"MIXING_DT", -1,
"3600.", NULL);
5509 scan_ctl(filename, argc, argv,
"MIXING_TROP", -1,
"-999", NULL);
5511 scan_ctl(filename, argc, argv,
"MIXING_STRAT", -1,
"-999", NULL);
5513 scan_ctl(filename, argc, argv,
"MIXING_Z0", -1,
"-5", NULL);
5515 scan_ctl(filename, argc, argv,
"MIXING_Z1", -1,
"85", NULL);
5517 (int)
scan_ctl(filename, argc, argv,
"MIXING_NZ", -1,
"90", NULL);
5519 scan_ctl(filename, argc, argv,
"MIXING_LON0", -1,
"-180", NULL);
5521 scan_ctl(filename, argc, argv,
"MIXING_LON1", -1,
"180", NULL);
5523 (int)
scan_ctl(filename, argc, argv,
"MIXING_NX", -1,
"360", NULL);
5525 scan_ctl(filename, argc, argv,
"MIXING_LAT0", -1,
"-90", NULL);
5527 scan_ctl(filename, argc, argv,
"MIXING_LAT1", -1,
"90", NULL);
5529 (int)
scan_ctl(filename, argc, argv,
"MIXING_NY", -1,
"180", NULL);
5533 scan_ctl(filename, argc, argv,
"CHEMGRID_Z0", -1,
"-5", NULL);
5535 scan_ctl(filename, argc, argv,
"CHEMGRID_Z1", -1,
"85", NULL);
5537 (int)
scan_ctl(filename, argc, argv,
"CHEMGRID_NZ", -1,
"90", NULL);
5539 scan_ctl(filename, argc, argv,
"CHEMGRID_LON0", -1,
"-180", NULL);
5541 scan_ctl(filename, argc, argv,
"CHEMGRID_LON1", -1,
"180", NULL);
5543 (int)
scan_ctl(filename, argc, argv,
"CHEMGRID_NX", -1,
"360", NULL);
5545 scan_ctl(filename, argc, argv,
"CHEMGRID_LAT0", -1,
"-90", NULL);
5547 scan_ctl(filename, argc, argv,
"CHEMGRID_LAT1", -1,
"90", NULL);
5549 (int)
scan_ctl(filename, argc, argv,
"CHEMGRID_NY", -1,
"180", NULL);
5554 scan_ctl(filename, argc, argv,
"TDEC_STRAT", -1,
"0", NULL);
5557 ctl->
psc_h2o =
scan_ctl(filename, argc, argv,
"PSC_H2O", -1,
"4e-6", NULL);
5559 scan_ctl(filename, argc, argv,
"PSC_HNO3", -1,
"9e-9", NULL);
5565 scan_ctl(filename, argc, argv,
"ATM_DT_OUT", -1,
"86400", NULL);
5567 (int)
scan_ctl(filename, argc, argv,
"ATM_FILTER", -1,
"0", NULL);
5569 (int)
scan_ctl(filename, argc, argv,
"ATM_STRIDE", -1,
"1", NULL);
5571 (int)
scan_ctl(filename, argc, argv,
"ATM_TYPE", -1,
"0", NULL);
5573 (int)
scan_ctl(filename, argc, argv,
"ATM_TYPE_OUT", -1,
"-1", NULL);
5577 (int)
scan_ctl(filename, argc, argv,
"ATM_NC_LEVEL", -1,
"0", NULL);
5578 for (
int iq = 0; iq < ctl->
nq; iq++)
5580 (
int)
scan_ctl(filename, argc, argv,
"ATM_NC_QUANT", iq,
"0", NULL);
5582 (int)
scan_ctl(filename, argc, argv,
"OBS_TYPE", -1,
"0", NULL);
5586 scan_ctl(filename, argc, argv,
"CSI_ENS_BASENAME", -1,
"-",
5588 ctl->
nens = (int)
scan_ctl(filename, argc, argv,
"NENS", -1,
"0", NULL);
5591 scan_ctl(filename, argc, argv,
"CSI_DT_OUT", -1,
"86400", NULL);
5594 scan_ctl(filename, argc, argv,
"CSI_OBSMIN", -1,
"0", NULL);
5596 scan_ctl(filename, argc, argv,
"CSI_MODMIN", -1,
"0", NULL);
5597 ctl->
csi_z0 =
scan_ctl(filename, argc, argv,
"CSI_Z0", -1,
"-5", NULL);
5598 ctl->
csi_z1 =
scan_ctl(filename, argc, argv,
"CSI_Z1", -1,
"85", NULL);
5599 ctl->
csi_nz = (int)
scan_ctl(filename, argc, argv,
"CSI_NZ", -1,
"1", NULL);
5601 scan_ctl(filename, argc, argv,
"CSI_LON0", -1,
"-180", NULL);
5602 ctl->
csi_lon1 =
scan_ctl(filename, argc, argv,
"CSI_LON1", -1,
"180", NULL);
5604 (int)
scan_ctl(filename, argc, argv,
"CSI_NX", -1,
"360", NULL);
5605 ctl->
csi_lat0 =
scan_ctl(filename, argc, argv,
"CSI_LAT0", -1,
"-90", NULL);
5606 ctl->
csi_lat1 =
scan_ctl(filename, argc, argv,
"CSI_LAT1", -1,
"90", NULL);
5608 (int)
scan_ctl(filename, argc, argv,
"CSI_NY", -1,
"180", NULL);
5613 scan_ctl(filename, argc, argv,
"ENS_DT_OUT", -1,
"86400", NULL);
5616 scan_ctl(filename, argc, argv,
"GRID_BASENAME", -1,
"-",
5621 scan_ctl(filename, argc, argv,
"GRID_DT_OUT", -1,
"86400", NULL);
5623 (int)
scan_ctl(filename, argc, argv,
"GRID_SPARSE", -1,
"0", NULL);
5625 (int)
scan_ctl(filename, argc, argv,
"GRID_NC_LEVEL", -1,
"0", NULL);
5626 for (
int iq = 0; iq < ctl->
nq; iq++)
5628 (
int)
scan_ctl(filename, argc, argv,
"GRID_NC_QUANT", iq,
"0", NULL);
5630 (int)
scan_ctl(filename, argc, argv,
"GRID_STDDEV", -1,
"0", NULL);
5631 ctl->
grid_z0 =
scan_ctl(filename, argc, argv,
"GRID_Z0", -1,
"-5", NULL);
5632 ctl->
grid_z1 =
scan_ctl(filename, argc, argv,
"GRID_Z1", -1,
"85", NULL);
5634 (int)
scan_ctl(filename, argc, argv,
"GRID_NZ", -1,
"1", NULL);
5636 scan_ctl(filename, argc, argv,
"GRID_LON0", -1,
"-180", NULL);
5638 scan_ctl(filename, argc, argv,
"GRID_LON1", -1,
"180", NULL);
5640 (int)
scan_ctl(filename, argc, argv,
"GRID_NX", -1,
"360", NULL);
5642 scan_ctl(filename, argc, argv,
"GRID_LAT0", -1,
"-90", NULL);
5644 scan_ctl(filename, argc, argv,
"GRID_LAT1", -1,
"90", NULL);
5646 (int)
scan_ctl(filename, argc, argv,
"GRID_NY", -1,
"180", NULL);
5648 (int)
scan_ctl(filename, argc, argv,
"GRID_TYPE", -1,
"0", NULL);
5651 scan_ctl(filename, argc, argv,
"PROF_BASENAME", -1,
"-",
5654 ctl->
prof_z0 =
scan_ctl(filename, argc, argv,
"PROF_Z0", -1,
"0", NULL);
5655 ctl->
prof_z1 =
scan_ctl(filename, argc, argv,
"PROF_Z1", -1,
"60", NULL);
5657 (int)
scan_ctl(filename, argc, argv,
"PROF_NZ", -1,
"60", NULL);
5659 scan_ctl(filename, argc, argv,
"PROF_LON0", -1,
"-180", NULL);
5661 scan_ctl(filename, argc, argv,
"PROF_LON1", -1,
"180", NULL);
5663 (int)
scan_ctl(filename, argc, argv,
"PROF_NX", -1,
"360", NULL);
5665 scan_ctl(filename, argc, argv,
"PROF_LAT0", -1,
"-90", NULL);
5667 scan_ctl(filename, argc, argv,
"PROF_LAT1", -1,
"90", NULL);
5669 (int)
scan_ctl(filename, argc, argv,
"PROF_NY", -1,
"180", NULL);
5672 scan_ctl(filename, argc, argv,
"SAMPLE_BASENAME", -1,
"-",
5674 scan_ctl(filename, argc, argv,
"SAMPLE_KERNEL", -1,
"-",
5676 scan_ctl(filename, argc, argv,
"SAMPLE_OBSFILE", -1,
"-",
5679 scan_ctl(filename, argc, argv,
"SAMPLE_DX", -1,
"50", NULL);
5681 scan_ctl(filename, argc, argv,
"SAMPLE_DZ", -1,
"-999", NULL);
5684 scan_ctl(filename, argc, argv,
"STAT_BASENAME", -1,
"-",
5688 ctl->
stat_r =
scan_ctl(filename, argc, argv,
"STAT_R", -1,
"50", NULL);
5690 scan_ctl(filename, argc, argv,
"STAT_T0", -1,
"-1e100", NULL);
5691 ctl->
stat_t1 =
scan_ctl(filename, argc, argv,
"STAT_T1", -1,
"1e100", NULL);
5696 scan_ctl(filename, argc, argv,
"VTK_DT_OUT", -1,
"86400", NULL);
5698 (int)
scan_ctl(filename, argc, argv,
"VTK_STRIDE", -1,
"1", NULL);
5700 scan_ctl(filename, argc, argv,
"VTK_SCALE", -1,
"1.0", NULL);
5702 scan_ctl(filename, argc, argv,
"VTK_OFFSET", -1,
"0.0", NULL);
5704 (int)
scan_ctl(filename, argc, argv,
"VTK_SPHERE", -1,
"0", NULL);
5710 const char *filename,
5716 LOG(1,
"Read meteo data: %s", filename);
5722 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
5749 ERRMSG(
"MET_TYPE not implemented!");
5758 LOG(2,
"Broadcast data on rank %d...", rank);
5891 ERRMSG(
"Code was compiled without KPP!");
5924#pragma acc update device(ctl[:1])
5928 if (cache != NULL) {
5931#pragma acc update device(cache[:1])
5938#pragma acc update device(clim[:1])
5945 met_t *met0up = *met0;
5946#pragma acc update device(met0up[:1])
5953 met_t *met1up = *met1;
5954#pragma acc update device(met1up[:1])
5961#pragma acc update device(atm[:1])
5980#pragma acc update host(ctl[:1])
5984 if (cache != NULL) {
5987#pragma acc update host(cache[:1])
5994#pragma acc update host(clim[:1])
6001 met_t *met0up = *met0;
6002#pragma acc update host(met0up[:1])
6009 met_t *met1up = *met1;
6010#pragma acc update host(met1up[:1])
6017#pragma acc update host(atm[:1])
6025 const char *filename,
6034 LOG(1,
"Write atmospheric data: %s", filename);
6058 ERRMSG(
"Atmospheric data type not supported!");
6062 LOG(2,
"Number of particles: %d", atm->
np);
6063 gsl_stats_minmax(&mini, &maxi, atm->
time, 1, (
size_t) atm->
np);
6064 LOG(2,
"Time range: %.2f ... %.2f s", mini, maxi);
6065 gsl_stats_minmax(&mini, &maxi, atm->
p, 1, (
size_t) atm->
np);
6066 LOG(2,
"Altitude range: %g ... %g km",
Z(maxi),
Z(mini));
6067 LOG(2,
"Pressure range: %g ... %g hPa", maxi, mini);
6068 gsl_stats_minmax(&mini, &maxi, atm->
lon, 1, (
size_t) atm->
np);
6069 LOG(2,
"Longitude range: %g ... %g deg", mini, maxi);
6070 gsl_stats_minmax(&mini, &maxi, atm->
lat, 1, (
size_t) atm->
np);
6071 LOG(2,
"Latitude range: %g ... %g deg", mini, maxi);
6072 for (
int iq = 0; iq < ctl->
nq; iq++) {
6074 sprintf(msg,
"Quantity %s range: %s ... %s %s",
6077 gsl_stats_minmax(&mini, &maxi, atm->
q[iq], 1, (
size_t) atm->
np);
6078 LOG(2, msg, mini, maxi);
6085 const char *filename,
6093 LOG(1,
"Write meteo data: %s", filename);
6098 ERRMSG(
"MPTRAC was compiled without zfp compression!");
6102 ERRMSG(
"MPTRAC was compiled without zstd compression!");
6106 ERRMSG(
"MPTRAC was compiled without cmultiscale compression!");
6119 ERRMSG(
"MET_TYPE not implemented!");
6125 const char *dirname,
6132 char ext[10], filename[2 *
LEN];
6136 int year, mon, day, hour, min, sec;
6139 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
6154 sprintf(ext,
"tab");
6156 sprintf(ext,
"bin");
6159 sprintf(filename,
"%s/%s_%04d_%02d_%02d_%02d_%02d.%s",
6160 dirname, ctl->
atm_basename, year, mon, day, hour, min, ext);
6166 sprintf(filename,
"%s/%s_%04d_%02d_%02d_%02d_%02d.%s",
6169 write_grid(filename, ctl, met0, met1, atm, t);
6174 sprintf(filename,
"%s/%s.tab", dirname, ctl->
csi_basename);
6186 sprintf(filename,
"%s/%s_%04d_%02d_%02d_%02d_%02d.tab",
6187 dirname, ctl->
ens_basename, year, mon, day, hour, min);
6193 sprintf(filename,
"%s/%s.tab", dirname, ctl->
prof_basename);
6194 write_prof(filename, ctl, met0, met1, atm, t);
6205 sprintf(filename,
"%s/%s.tab", dirname, ctl->
stat_basename);
6214 sprintf(filename,
"%s/%s_%05d.vtk", dirname, ctl->
vtk_basename, ++nvtk);
6224 const double hno3) {
6227 const double h2o_help =
MAX(h2o, 0.1e-6);
6230 const double p_hno3 = hno3 * p / 1.333224;
6231 const double p_h2o = h2o_help * p / 1.333224;
6232 const double a = 0.009179 - 0.00088 * log10(p_h2o);
6233 const double b = (38.9855 - log10(p_hno3) - 2.7836 * log10(p_h2o)) / a;
6234 const double c = -11397.0 / a;
6235 double tnat = (-b + sqrt(b * b - 4. * c)) / 2.;
6236 double x2 = (-b - sqrt(b * b - 4. * c)) / 2.;
6254 const double p0 = pbl;
6257 if (atm->
p[ip] > p0)
6259 else if (atm->
p[ip] < p1)
6262 return LIN(p0, 1.0, p1, 0.0, atm->
p[ip]);
6268 const char *filename,
6274 if (!(in = fopen(filename,
"r"))) {
6275 WARN(
"Cannot open file!");
6281 while (fgets(line,
LEN, in)) {
6285 TOK(line, tok,
"%lg", atm->
time[atm->
np]);
6286 TOK(NULL, tok,
"%lg", atm->
p[atm->
np]);
6287 TOK(NULL, tok,
"%lg", atm->
lon[atm->
np]);
6288 TOK(NULL, tok,
"%lg", atm->
lat[atm->
np]);
6289 for (
int iq = 0; iq < ctl->
nq; iq++)
6290 TOK(NULL, tok,
"%lg", atm->
q[iq][atm->
np]);
6293 atm->
p[atm->
np] =
P(atm->
p[atm->
np]);
6296 if ((++atm->
np) >
NP)
6297 ERRMSG(
"Too many data points!");
6310 const char *filename,
6316 if (!(in = fopen(filename,
"r")))
6321 FREAD(&version,
int,
6325 ERRMSG(
"Wrong version of binary data!");
6343 for (
int iq = 0; iq < ctl->
nq; iq++)
6344 FREAD(atm->
q[iq],
double,
6354 ERRMSG(
"Error while reading binary data!");
6366 const char *filename,
6373 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR)
6380 if (nc_inq_varid(ncid,
"TIME_INIT", &varid) == NC_NOERR) {
6381 NC(nc_get_var_double(ncid, varid, atm->
time));
6383 WARN(
"TIME_INIT not found use time instead!");
6386 for (
int ip = 0; ip < atm->
np; ip++) {
6387 atm->
time[ip] = time_init;
6399 if (nc_inq_varid(ncid,
"PRESS_INIT", &varid) == NC_NOERR) {
6400 NC(nc_get_var_double(ncid, varid, atm->
p));
6402 WARN(
"PRESS_INIT not found use PRESS instead!");
6403 nc_inq_varid(ncid,
"PRESS", &varid);
6404 NC(nc_get_var_double(ncid, varid, atm->
p));
6422 const char *filename,
6429 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR)
6442 for (
int iq = 0; iq < ctl->
nq; iq++)
6455 const char *filename,
6461 LOG(1,
"Read photolysis rates: %s", filename);
6464 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
6465 WARN(
"Photolysis rate data are missing!");
6472 if (photo->
p[0] < photo->
p[1])
6473 ERRMSG(
"Pressure data are not descending!");
6478 if (photo->
o3c[0] > photo->
o3c[1])
6479 ERRMSG(
"Total column ozone data are not ascending!");
6484 if (photo->
sza[0] > photo->
sza[1])
6485 ERRMSG(
"Solar zenith angle data are not ascending!");
6502 LOG(2,
"Number of pressure levels: %d", photo->
np);
6503 LOG(2,
"Altitude levels: %g, %g ... %g km",
6504 Z(photo->
p[0]),
Z(photo->
p[1]),
Z(photo->
p[photo->
np - 1]));
6505 LOG(2,
"Pressure levels: %g, %g ... %g hPa",
6506 photo->
p[0], photo->
p[1], photo->
p[photo->
np - 1]);
6507 LOG(2,
"Number of solar zenith angles: %d", photo->
nsza);
6508 LOG(2,
"Solar zenith angles: %g, %g ... %g deg",
6511 LOG(2,
"Number of total column ozone values: %d", photo->
no3c);
6512 LOG(2,
"Total column ozone: %g, %g ... %g DU",
6514 LOG(2,
"N2O photolysis rate: %g, %g ... %g s**-1",
6515 photo->
n2o[0][0][0], photo->
n2o[1][0][0],
6516 photo->
n2o[photo->
np - 1][photo->
nsza - 1][photo->
no3c - 1]);
6517 LOG(2,
"CCl4 photolysis rate: %g, %g ... %g s**-1",
6518 photo->
ccl4[0][0][0], photo->
ccl4[1][0][0],
6520 LOG(2,
"CFC-11 photolysis rate: %g, %g ... %g s**-1",
6521 photo->
ccl3f[0][0][0], photo->
ccl3f[1][0][0],
6523 LOG(2,
"CFC-12 photolysis rate: %g, %g ... %g s**-1",
6526 LOG(2,
"O2 photolysis rate: %g, %g ... %g s**-1",
6527 photo->
o2[0][0][0], photo->
o2[1][0][0],
6528 photo->
o2[photo->
np - 1][photo->
nsza - 1][photo->
no3c - 1]);
6529 LOG(2,
"O3 -> O(1D) photolysis rate: %g, %g ... %g s**-1",
6530 photo->
o3_1[0][0][0], photo->
o3_1[1][0][0],
6532 LOG(2,
"O3 -> O(3P) photolysis rate: %g, %g ... %g s**-1",
6533 photo->
o3_2[0][0][0], photo->
o3_2[1][0][0],
6535 LOG(2,
"H2O2 photolysis rate: %g, %g ... %g s**-1",
6536 photo->
h2o2[0][0][0], photo->
h2o2[1][0][0],
6538 LOG(2,
"H2O photolysis rate: %g, %g ... %g s**-1",
6539 photo->
h2o[0][0][0], photo->
h2o[1][0][0],
6540 photo->
h2o[photo->
np - 1][photo->
nsza - 1][photo->
no3c - 1]);
6547 const char *varname,
6561 for (
int ip = 0; ip < photo->
np; ip++)
6562 for (
int is = 0; is < photo->
nsza; is++)
6563 for (
int io = 0; io < photo->
no3c; io++)
6574 const char *filename,
6578 LOG(1,
"Read climatological time series: %s", filename);
6582 if (!(in = fopen(filename,
"r"))) {
6583 WARN(
"Cannot open file!");
6590 while (fgets(line,
LEN, in))
6591 if (sscanf(line,
"%lg %lg", &ts->
time[nh], &ts->
vmr[nh]) == 2) {
6594 ts->
time[nh] = (ts->
time[nh] - 2000.0) * 365.25 * 86400.;
6597 if (nh > 0 && ts->
time[nh] <= ts->
time[nh - 1])
6598 ERRMSG(
"Time series must be ascending!");
6602 ERRMSG(
"Too many data points!");
6611 ERRMSG(
"Not enough data points!");
6614 LOG(2,
"Number of time steps: %d", ts->
ntime);
6615 LOG(2,
"Time steps: %.2f, %.2f ... %.2f s", ts->
time[0], ts->
time[1],
6617 LOG(2,
"Volume mixing ratio range: %g ... %g ppv",
6618 gsl_stats_min(ts->
vmr, 1, (
size_t) nh), gsl_stats_max(ts->
vmr, 1,
6628 const char *filename,
6629 const char *varname,
6632 int ncid, varid, it, iy, iz, iz2, nt;
6634 double *help, varmin = 1e99, varmax = -1e99;
6637 LOG(1,
"Read %s data: %s", varname, filename);
6640 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
6641 WARN(
"%s climatology data are missing!", varname);
6648 if (zm->
p[0] < zm->
p[1])
6649 ERRMSG(
"Pressure data are not descending!");
6654 if (zm->
lat[0] > zm->
lat[1])
6655 ERRMSG(
"Latitude data are not ascending!");
6659 zm->
time[0] = 1209600.00;
6660 zm->
time[1] = 3888000.00;
6661 zm->
time[2] = 6393600.00;
6662 zm->
time[3] = 9072000.00;
6663 zm->
time[4] = 11664000.00;
6664 zm->
time[5] = 14342400.00;
6665 zm->
time[6] = 16934400.00;
6666 zm->
time[7] = 19612800.00;
6667 zm->
time[8] = 22291200.00;
6668 zm->
time[9] = 24883200.00;
6669 zm->
time[10] = 27561600.00;
6670 zm->
time[11] = 30153600.00;
6679 for (it = 0; it < zm->
ntime; it++)
6680 for (iz = 0; iz < zm->
np; iz++)
6681 for (iy = 0; iy < zm->
nlat; iy++)
6686 for (it = 0; it < zm->
ntime; it++)
6687 for (iy = 0; iy < zm->
nlat; iy++)
6688 for (iz = 0; iz < zm->
np; iz++) {
6689 if (zm->
vmr[it][iz][iy] < 0) {
6690 for (iz2 = 0; iz2 < zm->
np; iz2++)
6691 if (zm->
vmr[it][iz2][iy] >= 0) {
6692 zm->
vmr[it][iz][iy] = zm->
vmr[it][iz2][iy];
6695 for (iz2 = zm->
np - 1; iz2 >= 0; iz2--)
6696 if (zm->
vmr[it][iz2][iy] >= 0) {
6697 zm->
vmr[it][iz][iy] = zm->
vmr[it][iz2][iy];
6701 varmin =
MIN(varmin, zm->
vmr[it][iz][iy]);
6702 varmax =
MAX(varmax, zm->
vmr[it][iz][iy]);
6709 LOG(2,
"Number of time steps: %d", zm->
ntime);
6710 LOG(2,
"Time steps: %.2f, %.2f ... %.2f s",
6712 LOG(2,
"Number of pressure levels: %d", zm->
np);
6713 LOG(2,
"Altitude levels: %g, %g ... %g km",
6714 Z(zm->
p[0]),
Z(zm->
p[1]),
Z(zm->
p[zm->
np - 1]));
6715 LOG(2,
"Pressure levels: %g, %g ... %g hPa", zm->
p[0],
6716 zm->
p[1], zm->
p[zm->
np - 1]);
6717 LOG(2,
"Number of latitudes: %d", zm->
nlat);
6718 LOG(2,
"Latitudes: %g, %g ... %g deg",
6720 LOG(2,
"%s volume mixing ratio range: %g ... %g ppv", varname, varmin,
6727 const char *filename,
6733 LOG(1,
"Read kernel function: %s", filename);
6737 if (!(in = fopen(filename,
"r")))
6738 ERRMSG(
"Cannot open file!");
6743 while (fgets(line,
LEN, in))
6744 if (sscanf(line,
"%lg %lg", &kz[n], &kw[n]) == 2) {
6745 if (n > 0 && kz[n] < kz[n - 1])
6746 ERRMSG(
"Height levels must be ascending!");
6748 ERRMSG(
"Too many height levels!");
6757 ERRMSG(
"Not enough height levels!");
6760 const double kmax = gsl_stats_max(kw, 1, (
size_t) n);
6761 for (
int iz = 0; iz < n; iz++)
6768 const char *filename,
6776 int year, mon, day, hour, min, sec;
6782 if (!(in = fopen(filename,
"r"))) {
6783 WARN(
"Cannot open file!");
6789 FREAD(&met_type,
int,
6793 ERRMSG(
"Wrong MET_TYPE of binary data!");
6797 FREAD(&version,
int,
6801 ERRMSG(
"Wrong version of binary data!");
6807 jsec2time(met->
time, &year, &mon, &day, &hour, &min, &sec, &r);
6808 LOG(2,
"Time: %.2f (%d-%02d-%02d, %02d:%02d UTC)",
6809 met->
time, year, mon, day, hour, min);
6810 if (year < 1900 || year > 2100 || mon < 1 || mon > 12
6811 || day < 1 || day > 31 || hour < 0 || hour > 23)
6812 ERRMSG(
"Error while reading time!");
6818 LOG(2,
"Number of longitudes: %d", met->
nx);
6819 if (met->
nx < 2 || met->
nx >
EX)
6820 ERRMSG(
"Number of longitudes out of range!");
6825 LOG(2,
"Number of latitudes: %d", met->
ny);
6826 if (met->
ny < 2 || met->
ny >
EY)
6827 ERRMSG(
"Number of latitudes out of range!");
6832 LOG(2,
"Number of levels: %d", met->
np);
6833 if (met->
np < 2 || met->
np >
EP)
6834 ERRMSG(
"Number of levels out of range!");
6840 LOG(2,
"Longitudes: %g, %g ... %g deg",
6846 LOG(2,
"Latitudes: %g, %g ... %g deg",
6852 LOG(2,
"Altitude levels: %g, %g ... %g km",
6853 Z(met->
p[0]),
Z(met->
p[1]),
Z(met->
p[met->
np - 1]));
6854 LOG(2,
"Pressure levels: %g, %g ... %g hPa",
6855 met->
p[0], met->
p[1], met->
p[met->
np - 1]);
6904 ERRMSG(
"Error while reading binary data!");
6919 const char *varname) {
6928 LOG(2,
"Read 2-D variable: %s (uncompressed)", varname);
6930 (
size_t) (met->
nx * met->
ny),
6934 for (
int ix = 0; ix < met->
nx; ix++)
6935 for (
int iy = 0; iy < met->
ny; iy++)
6936 var[ix][iy] = help[
ARRAY_2D(ix, iy, met->
ny)];
6949 const char *varname,
6950 const float bound_min,
6951 const float bound_max) {
6961 LOG(2,
"Read 3-D variable: %s (uncompressed)", varname);
6963 (
size_t) (met->
nx * met->
ny * met->
np),
6970 (
size_t) met->
np, 1, in);
6976 FREAD(&precision,
int,
6981 FREAD(&tolerance,
double,
6988 ERRMSG(
"MPTRAC was compiled without zfp compression!");
6998 ERRMSG(
"MPTRAC was compiled without zstd compression!");
7006 (
size_t) met->
np, 1, in);
7008 ERRMSG(
"MPTRAC was compiled without cmultiscale compression!");
7013#pragma omp parallel for default(shared) collapse(2)
7014 for (
int ix = 0; ix < met->
nx; ix++)
7015 for (
int iy = 0; iy < met->
ny; iy++)
7016 for (
int ip = 0; ip < met->
np; ip++) {
7017 var[ix][iy][ip] = help[
ARRAY_3D(ix, iy, met->
ny, ip, met->
np)];
7018 if (var[ix][iy][ip] < bound_min)
7019 var[ix][iy][ip] = bound_min;
7020 else if (var[ix][iy][ip] > bound_max)
7021 var[ix][iy][ip] = bound_max;
7041 LOG(2,
"Calculate CAPE...");
7044 const double pfac = 1.01439, dz0 =
RI /
MA /
G0 * log(pfac);
7047#pragma omp parallel for default(shared) collapse(2)
7048 for (
int ix = 0; ix < met->
nx; ix++)
7049 for (
int iy = 0; iy < met->
ny; iy++) {
7053 double h2o = 0, t, theta = 0;
7054 double pbot =
MIN(met->
ps[ix][iy], met->
p[0]);
7055 double ptop = pbot - 50.;
7056 for (
int ip = 0; ip < met->
np; ip++) {
7057 if (met->
p[ip] <= pbot) {
7058 theta +=
THETA(met->
p[ip], met->
t[ix][iy][ip]);
7059 h2o += met->
h2o[ix][iy][ip];
7062 if (met->
p[ip] < ptop && n > 0)
7069 met->
plcl[ix][iy] = NAN;
7070 met->
plfc[ix][iy] = NAN;
7071 met->
pel[ix][iy] = NAN;
7072 met->
cape[ix][iy] = NAN;
7073 met->
cin[ix][iy] = NAN;
7079 pbot = met->
ps[ix][iy];
7081 met->
plcl[ix][iy] = (float) (0.5 * (pbot + ptop));
7082 t = theta / pow(1000. / met->
plcl[ix][iy], 0.286);
7083 if (
RH(met->
plcl[ix][iy], t, h2o) > 100.)
7084 ptop = met->
plcl[ix][iy];
7086 pbot = met->
plcl[ix][iy];
7087 }
while (pbot - ptop > 0.1);
7091 double dcape, dz, h2o_env, t_env;
7092 double p = met->
ps[ix][iy];
7093 met->
cape[ix][iy] = met->
cin[ix][iy] = 0;
7095 dz = dz0 *
TVIRT(t, h2o);
7097 t = theta / pow(1000. / p, 0.286);
7101 &h2o_env, ci, cw, 0);
7102 dcape = 1e3 *
G0 * (
TVIRT(t, h2o) -
TVIRT(t_env, h2o_env)) /
7103 TVIRT(t_env, h2o_env) * dz;
7105 met->
cin[ix][iy] += fabsf((
float) dcape);
7106 }
while (p > met->
plcl[ix][iy]);
7111 p = met->
plcl[ix][iy];
7112 t = theta / pow(1000. / p, 0.286);
7115 dz = dz0 *
TVIRT(t, h2o);
7118 double psat =
PSAT(t);
7119 h2o = psat / (p - (1. -
EPS) * psat);
7123 &h2o_env, ci, cw, 0);
7124 double dcape_old = dcape;
7125 dcape = 1e3 *
G0 * (
TVIRT(t, h2o) -
TVIRT(t_env, h2o_env)) /
7126 TVIRT(t_env, h2o_env) * dz;
7128 met->
cape[ix][iy] += (float) dcape;
7129 if (!isfinite(met->
plfc[ix][iy]))
7130 met->
plfc[ix][iy] = (
float) p;
7131 }
else if (dcape_old > 0)
7132 met->
pel[ix][iy] = (float) p;
7133 if (dcape < 0 && !isfinite(met->
plfc[ix][iy]))
7134 met->
cin[ix][iy] += fabsf((
float) dcape);
7138 if (!isfinite(met->
plfc[ix][iy]))
7139 met->
cin[ix][iy] = NAN;
7150 LOG(2,
"Calculate cloud data...");
7153 const double ccmin = 0.01, cwmin = 1e-6;
7156#pragma omp parallel for default(shared) collapse(2)
7157 for (
int ix = 0; ix < met->
nx; ix++)
7158 for (
int iy = 0; iy < met->
ny; iy++) {
7161 met->
pct[ix][iy] = NAN;
7162 met->
pcb[ix][iy] = NAN;
7163 met->
cl[ix][iy] = 0;
7166 for (
int ip = 0; ip < met->
np - 1; ip++) {
7169 if (met->
p[ip] > met->
ps[ix][iy] || met->
p[ip] <
P(20.))
7173 if (met->
cc[ix][iy][ip] > ccmin
7174 && (met->
lwc[ix][iy][ip] > cwmin
7175 || met->
rwc[ix][iy][ip] > cwmin
7176 || met->
iwc[ix][iy][ip] > cwmin
7177 || met->
swc[ix][iy][ip] > cwmin)) {
7181 = (float) (0.5 * (met->
p[ip] + (
float) met->
p[ip + 1]));
7184 if (!isfinite(met->
pcb[ix][iy]))
7186 = (
float) (0.5 * (met->
p[ip] + met->
p[
MAX(ip - 1, 0)]));
7190 met->
cl[ix][iy] += (float)
7191 (0.5 * (met->
lwc[ix][iy][ip] + met->
lwc[ix][iy][ip + 1]
7192 + met->
rwc[ix][iy][ip] + met->
rwc[ix][iy][ip + 1]
7193 + met->
iwc[ix][iy][ip] + met->
iwc[ix][iy][ip + 1]
7194 + met->
swc[ix][iy][ip] + met->
swc[ix][iy][ip + 1])
7195 * 100. * (met->
p[ip] - met->
p[ip + 1]) /
G0);
7213 SELECT_TIMER(
"READ_MET_DETREND",
"METPROC", NVTX_READ);
7214 LOG(2,
"Detrend meteo data...");
7221 const double tssq = 2. *
SQR(sigma);
7224 int sy = (int) (3. *
DY2DEG(sigma) / fabs(met->
lat[1] - met->
lat[0]));
7228#pragma omp parallel for default(shared) collapse(2)
7229 for (
int ix = 0; ix < met->
nx; ix++) {
7230 for (
int iy = 0; iy < met->
ny; iy++) {
7238 (int) (3. *
DX2DEG(sigma, met->
lat[iy]) /
7239 fabs(met->
lon[1] - met->
lon[0]));
7244 for (
int ip = 0; ip < met->
np; ip++) {
7245 help->
t[ix][iy][ip] = 0;
7246 help->
u[ix][iy][ip] = 0;
7247 help->
v[ix][iy][ip] = 0;
7248 help->
w[ix][iy][ip] = 0;
7252 for (
int ix2 = ix - sx; ix2 <= ix + sx; ix2++) {
7256 else if (ix3 >= met->
nx)
7258 for (
int iy2 =
MAX(iy - sy, 0);
7259 iy2 <=
MIN(iy + sy, met->
ny - 1); iy2++) {
7266 const float w = (float) exp(-
DIST2(x0, x1) / tssq);
7270 for (
int ip = 0; ip < met->
np; ip++) {
7271 help->
t[ix][iy][ip] += w * met->
t[ix3][iy2][ip];
7272 help->
u[ix][iy][ip] += w * met->
u[ix3][iy2][ip];
7273 help->
v[ix][iy][ip] += w * met->
v[ix3][iy2][ip];
7274 help->
w[ix][iy][ip] += w * met->
w[ix3][iy2][ip];
7280 for (
int ip = 0; ip < met->
np; ip++) {
7281 help->
t[ix][iy][ip] /= wsum;
7282 help->
u[ix][iy][ip] /= wsum;
7283 help->
v[ix][iy][ip] /= wsum;
7284 help->
w[ix][iy][ip] /= wsum;
7290#pragma omp parallel for default(shared) collapse(3)
7291 for (
int ix = 0; ix < met->
nx; ix++)
7292 for (
int iy = 0; iy < met->
ny; iy++)
7293 for (
int ip = 0; ip < met->
np; ip++) {
7294 met->
t[ix][iy][ip] -= help->
t[ix][iy][ip];
7295 met->
u[ix][iy][ip] -= help->
u[ix][iy][ip];
7296 met->
v[ix][iy][ip] -= help->
v[ix][iy][ip];
7297 met->
w[ix][iy][ip] -= help->
w[ix][iy][ip];
7310 SELECT_TIMER(
"READ_MET_EXTRAPOLATE",
"METPROC", NVTX_READ);
7311 LOG(2,
"Extrapolate meteo data...");
7314#pragma omp parallel for default(shared) collapse(2)
7315 for (
int ix = 0; ix < met->
nx; ix++)
7316 for (
int iy = 0; iy < met->
ny; iy++) {
7320 for (ip0 = met->
np - 1; ip0 >= 0; ip0--)
7321 if (!isfinite(met->
t[ix][iy][ip0])
7322 || !isfinite(met->
u[ix][iy][ip0])
7323 || !isfinite(met->
v[ix][iy][ip0])
7324 || !isfinite(met->
w[ix][iy][ip0]))
7328 for (
int ip = ip0; ip >= 0; ip--) {
7329 met->
t[ix][iy][ip] = met->
t[ix][iy][ip + 1];
7330 met->
u[ix][iy][ip] = met->
u[ix][iy][ip + 1];
7331 met->
v[ix][iy][ip] = met->
v[ix][iy][ip + 1];
7332 met->
w[ix][iy][ip] = met->
w[ix][iy][ip + 1];
7333 met->
h2o[ix][iy][ip] = met->
h2o[ix][iy][ip + 1];
7334 met->
o3[ix][iy][ip] = met->
o3[ix][iy][ip + 1];
7335 met->
lwc[ix][iy][ip] = met->
lwc[ix][iy][ip + 1];
7336 met->
rwc[ix][iy][ip] = met->
rwc[ix][iy][ip + 1];
7337 met->
iwc[ix][iy][ip] = met->
iwc[ix][iy][ip + 1];
7338 met->
swc[ix][iy][ip] = met->
swc[ix][iy][ip + 1];
7339 met->
cc[ix][iy][ip] = met->
cc[ix][iy][ip + 1];
7358 LOG(2,
"Calculate geopotential heights...");
7365#pragma omp parallel for default(shared)
7366 for (
int ip = 0; ip < met->
np; ip++)
7367 logp[ip] = log(met->
p[ip]);
7370#pragma omp parallel for default(shared) collapse(2)
7371 for (
int ix = 0; ix < met->
nx; ix++)
7372 for (
int iy = 0; iy < met->
ny; iy++) {
7375 const double zs = met->
zs[ix][iy];
7376 const double lnps = log(met->
ps[ix][iy]);
7380 const double ts =
LIN(met->
p[ip0], met->
t[ix][iy][ip0], met->
p[ip0 + 1],
7381 met->
t[ix][iy][ip0 + 1], met->
ps[ix][iy]);
7383 LIN(met->
p[ip0], met->
h2o[ix][iy][ip0], met->
p[ip0 + 1],
7384 met->
h2o[ix][iy][ip0 + 1], met->
ps[ix][iy]);
7387 met->
z[ix][iy][ip0 + 1]
7389 ZDIFF(lnps, ts, h2os, logp[ip0 + 1],
7390 met->
t[ix][iy][ip0 + 1], met->
h2o[ix][iy][ip0 + 1]));
7391 for (
int ip = ip0 + 2; ip < met->
np; ip++)
7393 = (
float) (met->
z[ix][iy][ip - 1] +
7394 ZDIFF(logp[ip - 1], met->
t[ix][iy][ip - 1],
7395 met->
h2o[ix][iy][ip - 1], logp[ip],
7396 met->
t[ix][iy][ip], met->
h2o[ix][iy][ip]));
7401 ZDIFF(lnps, ts, h2os, logp[ip0],
7402 met->
t[ix][iy][ip0], met->
h2o[ix][iy][ip0]));
7403 for (
int ip = ip0 - 1; ip >= 0; ip--)
7405 = (
float) (met->
z[ix][iy][ip + 1] +
7406 ZDIFF(logp[ip + 1], met->
t[ix][iy][ip + 1],
7407 met->
h2o[ix][iy][ip + 1], logp[ip],
7408 met->
t[ix][iy][ip], met->
h2o[ix][iy][ip]));
7412 if (dx == 0 || dy == 0)
7416 if (dx < 0 || dy < 0) {
7417 if (fabs(met->
lon[1] - met->
lon[0]) < 0.5) {
7427 float ws[dx + 1][dy + 1];
7428#pragma omp parallel for default(shared) collapse(2)
7429 for (
int ix = 0; ix <= dx; ix++)
7430 for (
int iy = 0; iy < dy; iy++)
7431 ws[ix][iy] = (1.0f - (
float) ix / (float) dx)
7432 * (1.0f - (float) iy / (
float) dy);
7435#pragma omp parallel for default(shared) collapse(3)
7436 for (
int ix = 0; ix < met->
nx; ix++)
7437 for (
int iy = 0; iy < met->
ny; iy++)
7438 for (
int ip = 0; ip < met->
np; ip++)
7439 help[
ARRAY_3D(ip, ix, met->
nx, iy, met->
ny)] = met->
z[ix][iy][ip];
7442#pragma omp parallel for default(shared) collapse(3)
7443 for (
int ip = 0; ip < met->
np; ip++)
7444 for (
int ix = 0; ix < met->
nx; ix++)
7445 for (
int iy = 0; iy < met->
ny; iy++) {
7446 float res = 0, wsum = 0;
7447 int iy0 =
MAX(iy - dy + 1, 0);
7448 int iy1 =
MIN(iy + dy - 1, met->
ny - 1);
7449 for (
int ix2 = ix - dx + 1; ix2 <= ix + dx - 1; ++ix2) {
7453 else if (ix3 >= met->
nx)
7455 for (
int iy2 = iy0; iy2 <= iy1; ++iy2)
7456 if (isfinite(help[
ARRAY_3D(ip, ix3, met->
nx, iy2, met->
ny)])) {
7457 float w = ws[abs(ix - ix2)][abs(iy - iy2)];
7458 res += w * help[
ARRAY_3D(ip, ix3, met->
nx, iy2, met->
ny)];
7463 met->
z[ix][iy][ip] = res / wsum;
7465 met->
z[ix][iy][ip] = NAN;
7475 const char *filename,
7480 char levname[
LEN], tstr[10];
7482 double rtime = 0, r, r2;
7484 int varid, year2, mon2, day2, hour2, min2, sec2,
7485 year, mon, day, hour, min, sec;
7491 LOG(2,
"Read meteo grid information...");
7500 jsec2time(met->
time, &year, &mon, &day, &hour, &min, &sec, &r);
7501 if (nc_inq_varid(ncid,
"time", &varid) == NC_NOERR) {
7502 NC(nc_get_var_double(ncid, varid, &rtime));
7503 if (fabs(year * 10000. + mon * 100. + day + hour / 24. - rtime) > 1.0)
7504 WARN(
"Time information in meteo file does not match filename!");
7506 WARN(
"Time information in meteo file is missing!");
7517 sprintf(tstr,
"19%.2s", &filename[strlen(filename) - 11]);
7519 sprintf(tstr,
"20%.2s", &filename[strlen(filename) - 11]);
7521 sprintf(tstr,
"%.2s", &filename[strlen(filename) - 9]);
7523 sprintf(tstr,
"%.2s", &filename[strlen(filename) - 7]);
7525 sprintf(tstr,
"%.2s", &filename[strlen(filename) - 5]);
7531 if (year < 1900 || year > 2100 || mon < 1 || mon > 12
7532 || day < 1 || day > 31 || hour < 0 || hour > 23)
7533 ERRMSG(
"Cannot read time from filename!");
7534 jsec2time(met->
time, &year2, &mon2, &day2, &hour2, &min2, &sec2, &r2);
7535 LOG(2,
"Time: %.2f (%d-%02d-%02d, %02d:%02d UTC)",
7536 met->
time, year2, mon2, day2, hour2, min2);
7540 LOG(2,
"Number of longitudes: %d", met->
nx);
7543 LOG(2,
"Number of latitudes: %d", met->
ny);
7546 sprintf(levname,
"lev");
7547 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR)
7548 sprintf(levname,
"plev");
7549 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR)
7550 sprintf(levname,
"hybrid");
7551 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR)
7552 sprintf(levname,
"hybrid_level");
7556 sprintf(levname,
"lev_2");
7557 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR) {
7558 sprintf(levname,
"plev");
7559 NC(nc_inq_dimid(ncid, levname, &dimid2));
7561 NC(nc_inq_dimlen(ncid, dimid2, &np));
7564 LOG(2,
"Number of levels: %d", met->
np);
7565 if (met->
np < 2 || met->
np >
EP)
7566 ERRMSG(
"Number of levels out of range!");
7570 LOG(2,
"Longitudes: %g, %g ... %g deg",
7573 LOG(2,
"Latitudes: %g, %g ... %g deg",
7577 for (
int ix = 2; ix < met->
nx; ix++)
7579 (fabs(met->
lon[ix] - met->
lon[ix - 1]) -
7580 fabs(met->
lon[1] - met->
lon[0])) > 0.001)
7581 ERRMSG(
"No regular grid spacing in longitudes!");
7582 for (
int iy = 2; iy < met->
ny; iy++)
7584 (fabs(met->
lat[iy] - met->
lat[iy - 1]) -
7585 fabs(met->
lat[1] - met->
lat[0])) > 0.001) {
7586 WARN(
"No regular grid spacing in latitudes!");
7593 for (
int ip = 0; ip < met->
np; ip++)
7595 LOG(2,
"Altitude levels: %g, %g ... %g km",
7596 Z(met->
p[0]),
Z(met->
p[1]),
Z(met->
p[met->
np - 1]));
7597 LOG(2,
"Pressure levels: %g, %g ... %g hPa",
7598 met->
p[0], met->
p[1], met->
p[met->
np - 1]);
7602 if (strcasecmp(levname,
"hybrid") == 0)
7609void read_met_global_grib(
7610 codes_handle **handles,
7615 SELECT_TIMER(
"READ_MET_GLOBAL_GRIB",
"INPUT", NVTX_READ);
7616 LOG(2,
"Read meteo grid information...");
7621 char year[20], month[20], day[20], hour[20];
7622 size_t s =
sizeof(datestr);
7624 ECC(codes_get_string(handles[0],
"dataDate", datestr, &s));
7625 ECC(codes_get_string(handles[0],
"dataTime", timestr, &s));
7626 strncpy(year, datestr, 4);
7628 strncpy(month, datestr + 4, 2);
7630 strncpy(day, datestr + 6, 2);
7632 strncpy(hour, timestr, 2);
7634 time2jsec(atoi(year), atoi(month), atoi(day), atoi(hour), 0, 0, 0,
7638 LOG(2,
"Time: %.2f (%d-%02d-%02d, %02d:%02d UTC)",
7639 met->
time, atoi(year), atoi(month), atoi(day), atoi(hour), 0);
7642 long count_lat = 0, count_lon = 0;
7643 ECC(codes_get_long(handles[0],
"Nj", &count_lat));
7644 ECC(codes_get_long(handles[0],
"Ni", &count_lon));
7645 met->
ny = (int) count_lat;
7646 met->
nx = (int) count_lon;
7649 LOG(2,
"Number of longitudes: %d", met->
nx);
7650 if (met->
nx < 2 || met->
nx >
EX)
7651 ERRMSG(
"Number of longitudes out of range!");
7652 LOG(2,
"Number of latitudes: %d", met->
ny);
7653 if (met->
ny < 2 || met->
ny >
EY)
7654 ERRMSG(
"Number of latitudes out of range!");
7656 double first_lon, last_lon, first_lat, last_lat, inc_lon, inc_lat;
7657 ECC(codes_get_double
7658 (handles[0],
"longitudeOfFirstGridPointInDegrees", &first_lon));
7659 ECC(codes_get_double
7660 (handles[0],
"latitudeOfFirstGridPointInDegrees", &first_lat));
7661 ECC(codes_get_double
7662 (handles[0],
"longitudeOfLastGridPointInDegrees", &last_lon));
7663 ECC(codes_get_double
7664 (handles[0],
"latitudeOfLastGridPointInDegrees", &last_lat));
7665 ECC(codes_get_double(handles[0],
"iDirectionIncrementInDegrees", &inc_lon));
7666 ECC(codes_get_double(handles[0],
"jDirectionIncrementInDegrees", &inc_lat));
7668 long jscanpos, iscanneg;
7669 ECC(codes_get_long(handles[0],
"iScansNegatively", &iscanneg));
7670 ECC(codes_get_long(handles[0],
"jScansPositively", &jscanpos));
7674 if (iscanneg == 0) {
7675 for (
double i = first_lon; i <= last_lon + 1e-6; i += inc_lon) {
7676 met->
lon[counter] = i;
7680 for (
double i = first_lon; i > last_lon - 1e-6; i -= inc_lon) {
7681 met->
lon[counter] = i;
7687 if (jscanpos == 0) {
7688 for (
double i = first_lat; i > last_lat - 1e-6; i -= inc_lat) {
7689 met->
lat[counter] = i;
7693 for (
double i = first_lat; i <= last_lat + 1e-6; i += inc_lat) {
7694 met->
lat[counter] = i;
7700 LOG(2,
"Longitudes: %g, %g ... %g deg",
7702 LOG(2,
"Latitudes: %g, %g ... %g deg",
7707 for (
int i = 0; i < count_handles; i++) {
7709 ECC(codes_get_long(handles[i],
"level", &level));
7710 if (level > max_level) {
7711 max_level = (int) level;
7714 met->
npl = max_level;
7717 LOG(2,
"Number of levels: %d", met->
npl);
7719 ERRMSG(
"Number of levels out of range!");
7732 LOG(2,
"Read level data...");
7735 if (!
read_met_nc_3d(ncid,
"t",
"T",
"temp",
"TEMP", ctl, met, met->
t, 1.0))
7736 ERRMSG(
"Cannot read temperature!");
7739 if (!
read_met_nc_3d(ncid,
"u",
"U", NULL, NULL, ctl, met, met->
u, 1.0))
7740 ERRMSG(
"Cannot read zonal wind!");
7741 if (!
read_met_nc_3d(ncid,
"v",
"V", NULL, NULL, ctl, met, met->
v, 1.0))
7742 ERRMSG(
"Cannot read meridional wind!");
7744 (ncid,
"w",
"W",
"omega",
"OMEGA", ctl, met, met->
w, 0.01f))
7745 WARN(
"Cannot read vertical velocity!");
7750 (ncid,
"q",
"Q",
"sh",
"SH", ctl, met, met->
h2o, (
float) (
MA /
MH2O)))
7751 WARN(
"Cannot read specific humidity!");
7754 (ncid,
"rh",
"RH", NULL, NULL, ctl, met, met->
h2o, 0.01f))
7755 WARN(
"Cannot read relative humidity!");
7756#pragma omp parallel for default(shared) collapse(2)
7757 for (
int ix = 0; ix < met->
nx; ix++)
7758 for (
int iy = 0; iy < met->
ny; iy++)
7759 for (
int ip = 0; ip < met->
np; ip++) {
7760 double pw = met->
h2o[ix][iy][ip] *
PSAT(met->
t[ix][iy][ip]);
7761 met->
h2o[ix][iy][ip] =
7762 (float) (pw / (met->
p[ip] - (1.0 -
EPS) * pw));
7768 (ncid,
"o3",
"O3", NULL, NULL, ctl, met, met->
o3, (
float) (
MA /
MO3)))
7769 WARN(
"Cannot read ozone data!");
7773 (ncid,
"clwc",
"CLWC", NULL, NULL, ctl, met, met->
lwc, 1.0))
7774 WARN(
"Cannot read cloud liquid water content!");
7776 (ncid,
"crwc",
"CRWC", NULL, NULL, ctl, met, met->
rwc, 1.0))
7777 WARN(
"Cannot read cloud rain water content!");
7779 (ncid,
"ciwc",
"CIWC", NULL, NULL, ctl, met, met->
iwc, 1.0))
7780 WARN(
"Cannot read cloud ice water content!");
7782 (ncid,
"cswc",
"CSWC", NULL, NULL, ctl, met, met->
swc, 1.0))
7783 WARN(
"Cannot read cloud snow water content!");
7785 WARN(
"Cannot read cloud cover!");
7789 (ncid,
"ZETA",
"zeta", NULL, NULL, ctl, met, met->
zetal, 1.0))
7790 WARN(
"Cannot read ZETA!");
7792 (ncid,
"ZETA_DOT_TOT",
"ZETA_DOT_clr",
"zeta_dot_clr",
7793 NULL, ctl, met, met->
zeta_dotl, 0.00001157407f))
7794 WARN(
"Cannot read ZETA_DOT!");
7798 for (
int ix = 0; ix < met->
nx; ix++)
7799 for (
int iy = 0; iy < met->
ny; iy++)
7800 for (
int ip = 0; ip < met->
np; ip++) {
7801 met->
ul[ix][iy][ip] = met->
u[ix][iy][ip];
7802 met->
vl[ix][iy][ip] = met->
v[ix][iy][ip];
7803 met->
wl[ix][iy][ip] = met->
w[ix][iy][ip];
7816 (ncid,
"pl",
"PL",
"pressure",
"PRESSURE", ctl, met, met->
pl,
7819 (ncid,
"press",
"PRESS", NULL, NULL, ctl, met, met->
pl, 1.0))
7820 ERRMSG(
"Cannot read pressure on model levels!");
7827 double hyam[
EP], hybm[
EP];
7832 if (nc_inq_varid(ncid,
"hyam", &varid) == NC_NOERR
7833 && nc_inq_varid(ncid,
"hybm", &varid) == NC_NOERR) {
7836 }
else if (nc_inq_varid(ncid,
"a_hybrid_level", &varid) == NC_NOERR
7837 && nc_inq_varid(ncid,
"b_hybrid_level",
7838 &varid) == NC_NOERR) {
7842 ERRMSG(
"Cannot read a and b level coefficients from netCDF file!");
7850 ERRMSG(
"Mismatch in number of model levels!");
7853 for (
int ip = 0; ip < met->
np; ip++) {
7860 for (
int ix = 0; ix < met->
nx; ix++)
7861 for (
int iy = 0; iy < met->
ny; iy++)
7862 for (
int ip = 0; ip < met->
np; ip++)
7863 met->
pl[ix][iy][ip] =
7864 (
float) (hyam[ip] / 100. + hybm[ip] * met->
ps[ix][iy]);
7871 double hyam[
EP], hybm[
EP];
7874 for (
int ip = 0; ip < met->
np + 1; ip++) {
7881 ERRMSG(
"Mismatch in number of model levels!");
7884#pragma omp parallel for default(shared) collapse(2)
7885 for (
int ix = 0; ix < met->
nx; ix++)
7886 for (
int iy = 0; iy < met->
ny; iy++)
7887 for (
int ip = 0; ip < met->
np; ip++) {
7888 double p0 = hyam[ip] / 100. + hybm[ip] * met->
ps[ix][iy];
7889 double p1 = hyam[ip + 1] / 100. + hybm[ip + 1] * met->
ps[ix][iy];
7890 met->
pl[ix][iy][ip] = (float) ((p1 - p0) / log(p1 / p0));
7895 for (
int ix = 0; ix < met->
nx; ix++)
7896 for (
int iy = 0; iy < met->
ny; iy++)
7897 for (
int ip = 1; ip < met->
np; ip++)
7898 if ((met->
pl[ix][iy][0] > met->
pl[ix][iy][1]
7899 && met->
pl[ix][iy][ip - 1] <= met->
pl[ix][iy][ip])
7900 || (met->
pl[ix][iy][0] < met->
pl[ix][iy][1]
7901 && met->
pl[ix][iy][ip - 1] >= met->
pl[ix][iy][ip]))
7902 ERRMSG(
"Pressure profiles are not monotonic!");
7909 if (met->
pl[0][0][0] <= 0)
7910 ERRMSG(
"Pressure on model levels is missing, check MET_VERT_COORD!");
7927 for (
int ip = 0; ip < met->
np; ip++)
7928 met->
p[ip] = ctl->
met_p[ip];
7932 for (
int ip = 1; ip < met->
np; ip++)
7933 if (met->
p[ip - 1] < met->
p[ip])
7934 ERRMSG(
"Pressure levels must be descending!");
7940void read_met_levels_grib(
7941 codes_handle **handles,
7942 const int num_messages,
7946 int t_flag = 0, u_flag = 0, v_flag = 0, w_flag = 0, o3_flag = 0, h2o_flag =
7947 0, lwc_flag = 0, rwc_flag = 0, iwc_flag = 0, swc_flag = 0, cc_flag = 0;
7950 for (
int i = 0; i < num_messages; i++) {
7951 size_t max_size = 50;
7952 char short_name[max_size];
7958 ECC(codes_get_long(handles[i],
"level", ¤t_level));
7962 ECC(codes_get_string(handles[i],
"shortName", short_name, &max_size));
7963 ECC(codes_get_size(handles[i],
"values", &value_count));
7964 ALLOC(values,
double,
7966 codes_get_double_array(handles[i],
8040 if (t_flag != met->
npl) {
8041 WARN(
"Cannot read{ temperature!");
8043 if (u_flag != met->
npl) {
8044 WARN(
"Cannot read zonal wind!");
8046 if (v_flag != met->
npl) {
8047 WARN(
"Cannot read meridional wind!");
8049 if (w_flag != met->
npl) {
8050 WARN(
"Cannot read vertical velocity!");
8052 if (o3_flag != met->
npl) {
8053 WARN(
"Cannot read ozone data!");
8055 if (h2o_flag != met->
npl) {
8056 WARN(
"Cannot read specific humidity!");
8058 if (lwc_flag != met->
npl) {
8059 WARN(
"Cannot read cloud liquid water content!");
8061 if (rwc_flag != met->
npl) {
8062 WARN(
"Cannot read cloud rain water content!");
8064 if (iwc_flag != met->
npl) {
8065 WARN(
"Cannot read cloud ice water content!");
8067 if (swc_flag != met->
npl) {
8068 WARN(
"Cannot read cloud snow water content!");
8070 if (cc_flag != met->
npl) {
8071 WARN(
"Cannot read cloud cover!");
8075 for (
int ix = 0; ix < met->
nx; ix++)
8076 for (
int iy = 0; iy < met->
ny; iy++)
8077 for (
int ip = 1; ip < met->
np; ip++)
8078 if ((met->
pl[ix][iy][0] > met->
pl[ix][iy][1]
8079 && met->
pl[ix][iy][ip - 1] <= met->
pl[ix][iy][ip])
8080 || (met->
pl[ix][iy][0] < met->
pl[ix][iy][1]
8081 && met->
pl[ix][iy][ip - 1] >= met->
pl[ix][iy][ip])) {
8082 LOG(1,
"%f %f %f %f", met->
pl[ix][iy][0], met->
pl[ix][iy][1],
8083 met->
pl[ix][iy][ip - 1], met->
pl[ix][iy][ip]);
8084 ERRMSG(
"Pressure profiles are not monotonic!");
8105 for (
int ip = 0; ip < met->
np; ip++)
8106 met->
p[ip] = ctl->
met_p[ip];
8110 for (
int ip = 1; ip < met->
np; ip++)
8111 if (met->
p[ip - 1] < met->
p[ip])
8112 ERRMSG(
"Pressure levels must be descending!");
8122 const char *varname) {
8124 double aux[
EP], p[
EP];
8128 LOG(2,
"Interpolate meteo data to pressure levels: %s", varname);
8131#pragma omp parallel for default(shared) private(aux,p) collapse(2)
8132 for (
int ix = 0; ix < met->
nx; ix++)
8133 for (
int iy = 0; iy < met->
ny; iy++) {
8136 for (
int ip = 0; ip < met->
np; ip++)
8137 p[ip] = met->
pl[ix][iy][ip];
8140 for (
int ip = 0; ip < ctl->
met_np; ip++) {
8141 double pt = ctl->
met_p[ip];
8142 if ((pt > p[0] && p[0] > p[1]) || (pt < p[0] && p[0] < p[1]))
8144 else if ((pt > p[met->
np - 1] && p[1] > p[0])
8145 || (pt < p[met->
np - 1] && p[1] < p[0]))
8146 pt = p[met->
np - 1];
8148 aux[ip] =
LIN(p[ip2], var[ix][iy][ip2],
8149 p[ip2 + 1], var[ix][iy][ip2 + 1], pt);
8153 for (
int ip = 0; ip < ctl->
met_np; ip++)
8154 var[ix][iy][ip] = (
float) aux[ip];
8169 SELECT_TIMER(
"READ_MET_MONOTONIZE",
"METPROC", NVTX_READ);
8170 LOG(2,
"Make zeta profiles monotone...");
8173#pragma omp parallel for default(shared) collapse(2)
8174 for (
int i = 0; i < met->
nx; i++)
8175 for (
int j = 0; j < met->
ny; j++) {
8178 while (k < met->npl) {
8179 if ((met->
zetal[i][j][k - 1] >= met->
zetal[i][j][k])) {
8185 while ((met->
zetal[i][j][k - 1] >=
8186 met->
zetal[i][j][k + l]) & (k + l < met->npl));
8191 (float) (met->
zetal[i][j][k + l] - met->
zetal[i][j][k - 1])
8194 for (
int m = k; m < k + l; m++) {
8195 float d = (float) (met->
hybrid[m] - met->
hybrid[k - 1]);
8196 met->
zetal[i][j][m] = s * d + met->
zetal[i][j][k - 1];
8208#pragma omp parallel for default(shared) collapse(2)
8209 for (
int i = 0; i < met->
nx; i++)
8210 for (
int j = 0; j < met->
ny; j++) {
8213 while (k < met->npl) {
8214 if ((met->
pl[i][j][k - 1] <= met->
pl[i][j][k])) {
8221 while ((met->
pl[i][j][k - 1] <= met->
pl[i][j][k + l]) & (k + l <
8226 float s = (float) (met->
pl[i][j][k + l] - met->
pl[i][j][k - 1])
8229 for (
int m = k; m < k + l; m++) {
8230 float d = (float) (met->
hybrid[m] - met->
hybrid[k - 1]);
8231 met->
pl[i][j][m] = s * d + met->
pl[i][j][k - 1];
8247 const char *filename,
8252 size_t filename_len = strlen(filename) + 1;
8254 char sf_filename[filename_len];
8255 char ml_filename[filename_len];
8256 strcpy(sf_filename, filename);
8257 strcpy(ml_filename, filename);
8265 FILE *ml_file = fopen(ml_filename,
"rb");
8266 FILE *sf_file = fopen(sf_filename,
"rb");
8268 if (ml_file == NULL || sf_file == NULL) {
8269 if (ml_file != NULL) {
8271 LOG(1,
"Cannot open file: %s", sf_filename);
8273 if (sf_file != NULL) {
8275 LOG(1,
"Cannot open file: %s", ml_filename);
8282 codes_handle **ml_handles;
8283 codes_handle **sf_handles;
8285 int ml_num_messages = 0;
8286 ECC(codes_count_in_file(0, ml_file, &ml_num_messages));
8288 (codes_handle **) malloc(
sizeof(codes_handle *) *
8289 (size_t) ml_num_messages);
8290 for (
int i = 0; i < ml_num_messages; i++) {
8291 codes_handle *h = NULL;
8292 if ((h = codes_grib_handle_new_from_file(0, ml_file, &err)) != NULL) {
8296 int sf_num_messages = 0;
8297 ECC(codes_count_in_file(0, sf_file, &sf_num_messages));
8299 (codes_handle **) malloc(
sizeof(codes_handle *) *
8300 (size_t) sf_num_messages);
8301 for (
int i = 0; i < sf_num_messages; i++) {
8302 codes_handle *h = NULL;
8303 if ((h = codes_grib_handle_new_from_file(0, sf_file, &err)) != NULL) {
8312 read_met_global_grib(ml_handles, ml_num_messages, met);
8314 read_met_surface_grib(sf_handles, sf_num_messages, ctl, met);
8315 for (
int i = 0; i < sf_num_messages; i++) {
8316 codes_handle_delete(sf_handles[i]);
8322 ECC(codes_get_size(ml_handles[0],
"pv", &value_count))
8323 double *values = (
double *) malloc(value_count *
sizeof(
double));
8324 ECC(codes_get_double_array(ml_handles[0],
"pv", values, &value_count))
8325 double a_vals[138], b_vals[138];
8326 for (
int i = 0; i <= 137; i++) {
8327 a_vals[i] = values[i];
8328 b_vals[i] = values[i + 137];
8330 for (
int nx = 0; nx < met->
nx; nx++) {
8331 for (
int ny = 0; ny < met->
ny; ny++) {
8332 for (
int level = 0; level <= met->
npl; level++) {
8335 (float) ((a_vals[level] * 0.01f + met->
ps[nx][ny] * b_vals[level]));
8337 (float) ((a_vals[level + 1] * 0.01f +
8338 met->
ps[nx][ny] * b_vals[level + 1]));
8339 met->
pl[nx][ny][level] = (p1 + p2) * 0.5f;
8345 read_met_levels_grib(ml_handles, ml_num_messages, ctl, met);
8346 for (
int i = 0; i < ml_num_messages; i++) {
8347 codes_handle_delete(ml_handles[i]);
8398 const char *filename,
8406 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
8407 WARN(
"Cannot open file!");
8470 const char *varname,
8471 const char *varname2,
8472 const char *varname3,
8473 const char *varname4,
8474 const char *varname5,
8475 const char *varname6,
8484 float offset, scalfac;
8489 if (nc_inq_varid(ncid, varname, &varid) == NC_NOERR)
8490 sprintf(varsel,
"%s", varname);
8491 else if (varname2 != NULL
8492 && nc_inq_varid(ncid, varname2, &varid) == NC_NOERR)
8493 sprintf(varsel,
"%s", varname2);
8494 else if (varname3 != NULL
8495 && nc_inq_varid(ncid, varname3, &varid) == NC_NOERR)
8496 sprintf(varsel,
"%s", varname3);
8497 else if (varname4 != NULL
8498 && nc_inq_varid(ncid, varname4, &varid) == NC_NOERR)
8499 sprintf(varsel,
"%s", varname4);
8500 else if (varname5 != NULL
8501 && nc_inq_varid(ncid, varname5, &varid) == NC_NOERR)
8502 sprintf(varsel,
"%s", varname5);
8503 else if (varname6 != NULL
8504 && nc_inq_varid(ncid, varname6, &varid) == NC_NOERR)
8505 sprintf(varsel,
"%s", varname6);
8511 && nc_get_att_float(ncid, varid,
"add_offset", &offset) == NC_NOERR
8512 && nc_get_att_float(ncid, varid,
"scale_factor",
8513 &scalfac) == NC_NOERR) {
8521 short fillval, missval;
8522 if (nc_get_att_short(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
8524 if (nc_get_att_short(ncid, varid,
"missing_value", &missval) != NC_NOERR)
8528 LOG(2,
"Read 2-D variable: %s"
8529 " (FILL = %d, MISS = %d, SCALE = %g, OFFSET = %g)",
8530 varsel, fillval, missval, scalfac, offset);
8533 NC(nc_get_var_short(ncid, varid, help));
8537 ERRMSG(
"Meteo data layout not implemented for packed netCDF files!");
8540#pragma omp parallel for default(shared) num_threads(12)
8541 for (
int ix = 0; ix < met->
nx; ix++)
8542 for (
int iy = 0; iy < met->
ny; iy++) {
8545 const short aux = help[
ARRAY_2D(iy, ix, met->
nx)];
8546 if ((fillval == 0 || aux != fillval)
8547 && (missval == 0 || aux != missval)
8548 && fabsf(aux * scalfac + offset) < 1e14f)
8549 dest[ix][iy] += scl * (aux * scalfac + offset);
8567 float fillval, missval;
8568 if (nc_get_att_float(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
8570 if (nc_get_att_float(ncid, varid,
"missing_value", &missval) != NC_NOERR)
8574 LOG(2,
"Read 2-D variable: %s (FILL = %g, MISS = %g)",
8575 varsel, fillval, missval);
8578 NC(nc_get_var_float(ncid, varid, help));
8584#pragma omp parallel for default(shared) num_threads(12)
8585 for (
int ix = 0; ix < met->
nx; ix++)
8586 for (
int iy = 0; iy < met->
ny; iy++) {
8589 const float aux = help[
ARRAY_2D(iy, ix, met->
nx)];
8590 if ((fillval == 0 || aux != fillval)
8591 && (missval == 0 || aux != missval)
8592 && fabsf(aux) < 1e14f)
8593 dest[ix][iy] += scl * aux;
8601#pragma omp parallel for default(shared) num_threads(12)
8602 for (
int iy = 0; iy < met->
ny; iy++)
8603 for (
int ix = 0; ix < met->
nx; ix++) {
8606 const float aux = help[
ARRAY_2D(ix, iy, met->
ny)];
8607 if ((fillval == 0 || aux != fillval)
8608 && (missval == 0 || aux != missval)
8609 && fabsf(aux) < 1e14f)
8610 dest[ix][iy] += scl * aux;
8628 const char *varname,
8629 const char *varname2,
8630 const char *varname3,
8631 const char *varname4,
8639 float offset, scalfac;
8644 if (nc_inq_varid(ncid, varname, &varid) == NC_NOERR)
8645 sprintf(varsel,
"%s", varname);
8646 else if (varname2 != NULL
8647 && nc_inq_varid(ncid, varname2, &varid) == NC_NOERR)
8648 sprintf(varsel,
"%s", varname2);
8649 else if (varname3 != NULL
8650 && nc_inq_varid(ncid, varname3, &varid) == NC_NOERR)
8651 sprintf(varsel,
"%s", varname3);
8652 else if (varname4 != NULL
8653 && nc_inq_varid(ncid, varname4, &varid) == NC_NOERR)
8654 sprintf(varsel,
"%s", varname4);
8660 && nc_get_att_float(ncid, varid,
"add_offset", &offset) == NC_NOERR
8661 && nc_get_att_float(ncid, varid,
"scale_factor",
8662 &scalfac) == NC_NOERR) {
8670 short fillval, missval;
8671 if (nc_get_att_short(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
8673 if (nc_get_att_short(ncid, varid,
"missing_value", &missval) != NC_NOERR)
8677 LOG(2,
"Read 3-D variable: %s "
8678 "(FILL = %d, MISS = %d, SCALE = %g, OFFSET = %g)",
8679 varsel, fillval, missval, scalfac, offset);
8682 NC(nc_get_var_short(ncid, varid, help));
8686 ERRMSG(
"Meteo data layout not implemented for packed netCDF files!");
8689#pragma omp parallel for default(shared) num_threads(12)
8690 for (
int ix = 0; ix < met->
nx; ix++)
8691 for (
int iy = 0; iy < met->
ny; iy++)
8692 for (
int ip = 0; ip < met->
np; ip++) {
8693 const short aux = help[
ARRAY_3D(ip, iy, met->
ny, ix, met->
nx)];
8694 if ((fillval == 0 || aux != fillval)
8695 && (missval == 0 || aux != missval)
8696 && fabsf(aux * scalfac + offset) < 1e14f)
8697 dest[ix][iy][ip] = scl * (aux * scalfac + offset);
8699 dest[ix][iy][ip] = NAN;
8715 float fillval, missval;
8716 if (nc_get_att_float(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
8718 if (nc_get_att_float(ncid, varid,
"missing_value", &missval) != NC_NOERR)
8722 LOG(2,
"Read 3-D variable: %s (FILL = %g, MISS = %g)",
8723 varsel, fillval, missval);
8726 NC(nc_get_var_float(ncid, varid, help));
8732#pragma omp parallel for default(shared) num_threads(12)
8733 for (
int ix = 0; ix < met->
nx; ix++)
8734 for (
int iy = 0; iy < met->
ny; iy++)
8735 for (
int ip = 0; ip < met->
np; ip++) {
8736 const float aux = help[
ARRAY_3D(ip, iy, met->
ny, ix, met->
nx)];
8737 if ((fillval == 0 || aux != fillval)
8738 && (missval == 0 || aux != missval)
8739 && fabsf(aux) < 1e14f)
8740 dest[ix][iy][ip] = scl * aux;
8742 dest[ix][iy][ip] = NAN;
8748#pragma omp parallel for default(shared) num_threads(12)
8749 for (
int ip = 0; ip < met->
np; ip++)
8750 for (
int iy = 0; iy < met->
ny; iy++)
8751 for (
int ix = 0; ix < met->
nx; ix++) {
8752 const float aux = help[
ARRAY_3D(ix, iy, met->
ny, ip, met->
np)];
8753 if ((fillval == 0 || aux != fillval)
8754 && (missval == 0 || aux != missval)
8755 && fabsf(aux) < 1e14f)
8756 dest[ix][iy][ip] = scl * aux;
8758 dest[ix][iy][ip] = NAN;
8778 LOG(2,
"Calculate planetary boundary layer...");
8784#pragma omp parallel for default(shared) collapse(2)
8785 for (
int ix = 0; ix < met->
nx; ix++)
8786 for (
int iy = 0; iy < met->
ny; iy++) {
8789 const float z = met->
zs[ix][iy] + met->
pbl[ix][iy];
8792 (float) (
LIN(met->
z[ix][iy][ip], met->
p[ip],
8793 met->
z[ix][iy][ip + 1], met->
p[ip + 1], z));
8802 const double rib_crit = 0.25, dz = 0.05, umin = 5.0;
8805#pragma omp parallel for default(shared) collapse(2)
8806 for (
int ix = 0; ix < met->
nx; ix++)
8807 for (
int iy = 0; iy < met->
ny; iy++) {
8810 const double pbl_bot = met->
ps[ix][iy] * exp(-dz /
H0);
8814 for (ip = 1; ip < met->
np; ip++)
8815 if (met->
p[ip] < pbl_bot)
8819 const double h2os =
LIN(met->
p[ip - 1], met->
h2o[ix][iy][ip - 1],
8820 met->
p[ip], met->
h2o[ix][iy][ip], pbl_bot);
8821 const double tvs =
THETAVIRT(pbl_bot, met->
ts[ix][iy], h2os);
8827 for (; ip < met->
np; ip++) {
8830 double vh2 =
SQR(met->
u[ix][iy][ip] - met->
us[ix][iy])
8831 +
SQR(met->
v[ix][iy][ip] - met->
vs[ix][iy]);
8832 vh2 =
MAX(vh2,
SQR(umin));
8836 G0 * 1e3 * (met->
z[ix][iy][ip] - met->
zs[ix][iy]) / tvs
8838 met->
h2o[ix][iy][ip]) - tvs) / vh2;
8841 if (rib >= rib_crit) {
8842 met->
pbl[ix][iy] = (float) (
LIN(rib_old, met->
p[ip - 1],
8843 rib, met->
p[ip], rib_crit));
8844 if (met->
pbl[ix][iy] > pbl_bot)
8845 met->
pbl[ix][iy] = (float) pbl_bot;
8860 const double dtheta = 2.0, zmin = 0.1;
8863#pragma omp parallel for default(shared) collapse(2)
8864 for (
int ix = 0; ix < met->
nx; ix++)
8865 for (
int iy = 0; iy < met->
ny; iy++) {
8868 const double theta0 =
THETA(met->
ps[ix][iy], met->
ts[ix][iy]);
8872 for (ip = met->
np - 2; ip > 0; ip--)
8873 if (met->
p[ip] >= 300.)
8874 if (met->
p[ip] > met->
ps[ix][iy]
8875 ||
THETA(met->
p[ip], met->
t[ix][iy][ip]) <= theta0 + dtheta)
8880 = (float) (
LIN(
THETA(met->
p[ip + 1], met->
t[ix][iy][ip + 1]),
8882 THETA(met->
p[ip], met->
t[ix][iy][ip]),
8883 met->
p[ip], theta0 + dtheta));
8886 double pbl_min = met->
ps[ix][iy] * exp(-zmin /
H0);
8887 if (met->
pbl[ix][iy] > pbl_min || met->
p[ip] > met->
ps[ix][iy])
8888 met->
pbl[ix][iy] = (float) pbl_min;
8893#pragma omp parallel for default(shared) collapse(2)
8894 for (
int ix = 0; ix < met->
nx; ix++)
8895 for (
int iy = 0; iy < met->
ny; iy++) {
8899 met->
pbl[ix][iy] =
MIN(met->
pbl[ix][iy], (
float) pbl_min);
8903 met->
pbl[ix][iy] =
MAX(met->
pbl[ix][iy], (
float) pbl_max);
8913 SELECT_TIMER(
"READ_MET_PERIODIC",
"METPROC", NVTX_READ);
8914 LOG(2,
"Apply periodic boundary conditions...");
8917 if (!(fabs(met->
lon[met->
nx - 1] - met->
lon[0]
8918 + met->
lon[1] - met->
lon[0] - 360) < 0.01))
8922 if ((++met->
nx) >=
EX)
8923 ERRMSG(
"Cannot create periodic boundary conditions!");
8929#pragma omp parallel for default(shared)
8930 for (
int iy = 0; iy < met->
ny; iy++) {
8931 met->
ps[met->
nx - 1][iy] = met->
ps[0][iy];
8932 met->
zs[met->
nx - 1][iy] = met->
zs[0][iy];
8933 met->
ts[met->
nx - 1][iy] = met->
ts[0][iy];
8934 met->
us[met->
nx - 1][iy] = met->
us[0][iy];
8935 met->
vs[met->
nx - 1][iy] = met->
vs[0][iy];
8936 met->
ess[met->
nx - 1][iy] = met->
ess[0][iy];
8937 met->
nss[met->
nx - 1][iy] = met->
nss[0][iy];
8938 met->
shf[met->
nx - 1][iy] = met->
shf[0][iy];
8939 met->
lsm[met->
nx - 1][iy] = met->
lsm[0][iy];
8940 met->
sst[met->
nx - 1][iy] = met->
sst[0][iy];
8941 met->
pbl[met->
nx - 1][iy] = met->
pbl[0][iy];
8942 met->
cape[met->
nx - 1][iy] = met->
cape[0][iy];
8943 met->
cin[met->
nx - 1][iy] = met->
cin[0][iy];
8944 for (
int ip = 0; ip < met->
np; ip++) {
8945 met->
t[met->
nx - 1][iy][ip] = met->
t[0][iy][ip];
8946 met->
u[met->
nx - 1][iy][ip] = met->
u[0][iy][ip];
8947 met->
v[met->
nx - 1][iy][ip] = met->
v[0][iy][ip];
8948 met->
w[met->
nx - 1][iy][ip] = met->
w[0][iy][ip];
8949 met->
h2o[met->
nx - 1][iy][ip] = met->
h2o[0][iy][ip];
8950 met->
o3[met->
nx - 1][iy][ip] = met->
o3[0][iy][ip];
8951 met->
lwc[met->
nx - 1][iy][ip] = met->
lwc[0][iy][ip];
8952 met->
rwc[met->
nx - 1][iy][ip] = met->
rwc[0][iy][ip];
8953 met->
iwc[met->
nx - 1][iy][ip] = met->
iwc[0][iy][ip];
8954 met->
swc[met->
nx - 1][iy][ip] = met->
swc[0][iy][ip];
8955 met->
cc[met->
nx - 1][iy][ip] = met->
cc[0][iy][ip];
8957 for (
int ip = 0; ip < met->
npl; ip++) {
8958 met->
ul[met->
nx - 1][iy][ip] = met->
ul[0][iy][ip];
8959 met->
vl[met->
nx - 1][iy][ip] = met->
vl[0][iy][ip];
8960 met->
wl[met->
nx - 1][iy][ip] = met->
wl[0][iy][ip];
8961 met->
pl[met->
nx - 1][iy][ip] = met->
pl[0][iy][ip];
8962 met->
zetal[met->
nx - 1][iy][ip] = met->
zetal[0][iy][ip];
8974 SELECT_TIMER(
"READ_MET_POLAR_WINDS",
"METPROC", NVTX_READ);
8975 LOG(2,
"Apply fix for polar winds...");
8978 if (fabs(met->
lat[0]) < 89.999 || fabs(met->
lat[met->
ny - 1]) < 89.999)
8982 for (
int ihem = 0; ihem < 2; ihem++) {
8985 int i89 = 1, i90 = 0, sign = 1;
8990 if (met->
lat[i90] < 0)
8994 double clon[
EX], slon[
EX];
8995#pragma omp parallel for default(shared)
8996 for (
int ix = 0; ix < met->
nx; ix++) {
8997 clon[ix] = cos(sign *
DEG2RAD(met->
lon[ix]));
8998 slon[ix] = sin(sign *
DEG2RAD(met->
lon[ix]));
9002#pragma omp parallel for default(shared)
9003 for (
int ip = 0; ip < met->
np; ip++) {
9006 double vel89x = 0, vel89y = 0;
9007 for (
int ix = 0; ix < met->
nx; ix++) {
9009 (met->
u[ix][i89][ip] * clon[ix] -
9010 met->
v[ix][i89][ip] * slon[ix]) / met->
nx;
9012 (met->
u[ix][i89][ip] * slon[ix] +
9013 met->
v[ix][i89][ip] * clon[ix]) / met->
nx;
9017 for (
int ix = 0; ix < met->
nx; ix++) {
9019 = (float) (vel89x * clon[ix] + vel89y * slon[ix]);
9021 = (float) (-vel89x * slon[ix] + vel89y * clon[ix]);
9036 LOG(2,
"Calculate potential vorticity...");
9039#pragma omp parallel for default(shared)
9040 for (
int ip = 0; ip < met->
np; ip++)
9041 pows[ip] = pow(1000. / met->
p[ip], 0.286);
9044#pragma omp parallel for default(shared)
9045 for (
int ix = 0; ix < met->
nx; ix++) {
9048 const int ix0 =
MAX(ix - 1, 0);
9049 const int ix1 =
MIN(ix + 1, met->
nx - 1);
9052 for (
int iy = 0; iy < met->
ny; iy++) {
9055 const int iy0 =
MAX(iy - 1, 0);
9056 const int iy1 =
MIN(iy + 1, met->
ny - 1);
9059 const double latr = 0.5 * (met->
lat[iy1] + met->
lat[iy0]);
9060 const double dx = 1000. *
DEG2DX(met->
lon[ix1] - met->
lon[ix0], latr);
9061 const double dy = 1000. *
DEG2DY(met->
lat[iy1] - met->
lat[iy0]);
9062 const double c0 = cos(
DEG2RAD(met->
lat[iy0]));
9063 const double c1 = cos(
DEG2RAD(met->
lat[iy1]));
9064 const double cr = cos(
DEG2RAD(latr));
9065 const double vort = 2 * 7.2921e-5 * sin(
DEG2RAD(latr));
9068 for (
int ip = 0; ip < met->
np; ip++) {
9072 = (met->
t[ix1][iy][ip] - met->
t[ix0][iy][ip]) * pows[ip] / dx;
9073 const double dvdx = (met->
v[ix1][iy][ip] - met->
v[ix0][iy][ip]) / dx;
9077 = (met->
t[ix][iy1][ip] - met->
t[ix][iy0][ip]) * pows[ip] / dy;
9079 = (met->
u[ix][iy1][ip] * c1 - met->
u[ix][iy0][ip] * c0) / dy;
9082 const int ip0 =
MAX(ip - 1, 0);
9083 const int ip1 =
MIN(ip + 1, met->
np - 1);
9086 double dtdp, dudp, dvdp;
9087 const double dp0 = 100. * (met->
p[ip] - met->
p[ip0]);
9088 const double dp1 = 100. * (met->
p[ip1] - met->
p[ip]);
9089 if (ip != ip0 && ip != ip1) {
9090 double denom = dp0 * dp1 * (dp0 + dp1);
9091 dtdp = (dp0 * dp0 * met->
t[ix][iy][ip1] * pows[ip1]
9092 - dp1 * dp1 * met->
t[ix][iy][ip0] * pows[ip0]
9093 + (dp1 * dp1 - dp0 * dp0) * met->
t[ix][iy][ip] * pows[ip])
9095 dudp = (dp0 * dp0 * met->
u[ix][iy][ip1]
9096 - dp1 * dp1 * met->
u[ix][iy][ip0]
9097 + (dp1 * dp1 - dp0 * dp0) * met->
u[ix][iy][ip])
9099 dvdp = (dp0 * dp0 * met->
v[ix][iy][ip1]
9100 - dp1 * dp1 * met->
v[ix][iy][ip0]
9101 + (dp1 * dp1 - dp0 * dp0) * met->
v[ix][iy][ip])
9104 const double denom = dp0 + dp1;
9106 (met->
t[ix][iy][ip1] * pows[ip1] -
9107 met->
t[ix][iy][ip0] * pows[ip0]) / denom;
9108 dudp = (met->
u[ix][iy][ip1] - met->
u[ix][iy][ip0]) / denom;
9109 dvdp = (met->
v[ix][iy][ip1] - met->
v[ix][iy][ip0]) / denom;
9113 met->
pv[ix][iy][ip] = (float)
9115 (-dtdp * (dvdx - dudy / cr + vort) + dvdp * dtdx - dudp * dtdy));
9121#pragma omp parallel for default(shared)
9122 for (
int ix = 0; ix < met->
nx; ix++)
9123 for (
int ip = 0; ip < met->
np; ip++) {
9125 = met->
pv[ix][1][ip]
9126 = met->
pv[ix][2][ip];
9127 met->
pv[ix][met->
ny - 1][ip]
9128 = met->
pv[ix][met->
ny - 2][ip]
9129 = met->
pv[ix][met->
ny - 3][ip];
9140 LOG(2,
"Calculate total column ozone...");
9143#pragma omp parallel for default(shared) collapse(2)
9144 for (
int ix = 0; ix < met->
nx; ix++)
9145 for (
int iy = 0; iy < met->
ny; iy++) {
9149 for (
int ip = 1; ip < met->
np; ip++)
9150 if (met->
p[ip - 1] <= met->
ps[ix][iy]) {
9152 0.5 * (met->
o3[ix][iy][ip - 1] + met->
o3[ix][iy][ip]);
9153 const double dp = met->
p[ip - 1] - met->
p[ip];
9154 cd += vmr *
MO3 /
MA * dp * 1e2 /
G0;
9158 met->
o3c[ix][iy] = (float) (cd / 2.1415e-5);
9177 LOG(2,
"Downsampling of meteo data...");
9186 memcpy(help->
lon, met->
lon,
sizeof(met->
lon));
9187 memcpy(help->
lat, met->
lat,
sizeof(met->
lat));
9188 memcpy(help->
p, met->
p,
sizeof(met->
p));
9191 for (
int ix = 0; ix < met->
nx; ix += ctl->
met_dx) {
9192 for (
int iy = 0; iy < met->
ny; iy += ctl->
met_dy) {
9193 for (
int ip = 0; ip < met->
np; ip += ctl->
met_dp) {
9194 help->
ps[ix][iy] = 0;
9195 help->
zs[ix][iy] = 0;
9196 help->
ts[ix][iy] = 0;
9197 help->
us[ix][iy] = 0;
9198 help->
vs[ix][iy] = 0;
9199 help->
ess[ix][iy] = 0;
9200 help->
nss[ix][iy] = 0;
9201 help->
shf[ix][iy] = 0;
9202 help->
lsm[ix][iy] = 0;
9203 help->
sst[ix][iy] = 0;
9204 help->
pbl[ix][iy] = 0;
9205 help->
cape[ix][iy] = 0;
9206 help->
cin[ix][iy] = 0;
9207 help->
t[ix][iy][ip] = 0;
9208 help->
u[ix][iy][ip] = 0;
9209 help->
v[ix][iy][ip] = 0;
9210 help->
w[ix][iy][ip] = 0;
9211 help->
h2o[ix][iy][ip] = 0;
9212 help->
o3[ix][iy][ip] = 0;
9213 help->
lwc[ix][iy][ip] = 0;
9214 help->
rwc[ix][iy][ip] = 0;
9215 help->
iwc[ix][iy][ip] = 0;
9216 help->
swc[ix][iy][ip] = 0;
9217 help->
cc[ix][iy][ip] = 0;
9219 for (
int ix2 = ix - ctl->
met_sx + 1; ix2 <= ix + ctl->met_sx - 1;
9224 else if (ix3 >= met->
nx)
9227 for (
int iy2 =
MAX(iy - ctl->
met_sy + 1, 0);
9228 iy2 <=
MIN(iy + ctl->
met_sy - 1, met->
ny - 1); iy2++)
9229 for (
int ip2 =
MAX(ip - ctl->
met_sp + 1, 0);
9230 ip2 <=
MIN(ip + ctl->
met_sp - 1, met->
np - 1); ip2++) {
9231 float w = (1.0f - (float) abs(ix - ix2) / (float) ctl->
met_sx)
9232 * (1.0f - (float) abs(iy - iy2) / (float) ctl->
met_sy)
9233 * (1.0f - (float) abs(ip - ip2) / (float) ctl->
met_sp);
9234 help->
ps[ix][iy] += w * met->
ps[ix3][iy2];
9235 help->
zs[ix][iy] += w * met->
zs[ix3][iy2];
9236 help->
ts[ix][iy] += w * met->
ts[ix3][iy2];
9237 help->
us[ix][iy] += w * met->
us[ix3][iy2];
9238 help->
vs[ix][iy] += w * met->
vs[ix3][iy2];
9239 help->
ess[ix][iy] += w * met->
ess[ix3][iy2];
9240 help->
nss[ix][iy] += w * met->
nss[ix3][iy2];
9241 help->
shf[ix][iy] += w * met->
shf[ix3][iy2];
9242 help->
lsm[ix][iy] += w * met->
lsm[ix3][iy2];
9243 help->
sst[ix][iy] += w * met->
sst[ix3][iy2];
9244 help->
pbl[ix][iy] += w * met->
pbl[ix3][iy2];
9245 help->
cape[ix][iy] += w * met->
cape[ix3][iy2];
9246 help->
cin[ix][iy] += w * met->
cin[ix3][iy2];
9247 help->
t[ix][iy][ip] += w * met->
t[ix3][iy2][ip2];
9248 help->
u[ix][iy][ip] += w * met->
u[ix3][iy2][ip2];
9249 help->
v[ix][iy][ip] += w * met->
v[ix3][iy2][ip2];
9250 help->
w[ix][iy][ip] += w * met->
w[ix3][iy2][ip2];
9251 help->
h2o[ix][iy][ip] += w * met->
h2o[ix3][iy2][ip2];
9252 help->
o3[ix][iy][ip] += w * met->
o3[ix3][iy2][ip2];
9253 help->
lwc[ix][iy][ip] += w * met->
lwc[ix3][iy2][ip2];
9254 help->
rwc[ix][iy][ip] += w * met->
rwc[ix3][iy2][ip2];
9255 help->
iwc[ix][iy][ip] += w * met->
iwc[ix3][iy2][ip2];
9256 help->
swc[ix][iy][ip] += w * met->
swc[ix3][iy2][ip2];
9257 help->
cc[ix][iy][ip] += w * met->
cc[ix3][iy2][ip2];
9261 help->
ps[ix][iy] /= wsum;
9262 help->
zs[ix][iy] /= wsum;
9263 help->
ts[ix][iy] /= wsum;
9264 help->
us[ix][iy] /= wsum;
9265 help->
vs[ix][iy] /= wsum;
9266 help->
ess[ix][iy] /= wsum;
9267 help->
nss[ix][iy] /= wsum;
9268 help->
shf[ix][iy] /= wsum;
9269 help->
lsm[ix][iy] /= wsum;
9270 help->
sst[ix][iy] /= wsum;
9271 help->
pbl[ix][iy] /= wsum;
9272 help->
cape[ix][iy] /= wsum;
9273 help->
cin[ix][iy] /= wsum;
9274 help->
t[ix][iy][ip] /= wsum;
9275 help->
u[ix][iy][ip] /= wsum;
9276 help->
v[ix][iy][ip] /= wsum;
9277 help->
w[ix][iy][ip] /= wsum;
9278 help->
h2o[ix][iy][ip] /= wsum;
9279 help->
o3[ix][iy][ip] /= wsum;
9280 help->
lwc[ix][iy][ip] /= wsum;
9281 help->
rwc[ix][iy][ip] /= wsum;
9282 help->
iwc[ix][iy][ip] /= wsum;
9283 help->
swc[ix][iy][ip] /= wsum;
9284 help->
cc[ix][iy][ip] /= wsum;
9291 for (
int ix = 0; ix < help->
nx; ix += ctl->
met_dx) {
9294 for (
int iy = 0; iy < help->
ny; iy += ctl->
met_dy) {
9296 met->
ps[met->
nx][met->
ny] = help->
ps[ix][iy];
9297 met->
zs[met->
nx][met->
ny] = help->
zs[ix][iy];
9298 met->
ts[met->
nx][met->
ny] = help->
ts[ix][iy];
9299 met->
us[met->
nx][met->
ny] = help->
us[ix][iy];
9300 met->
vs[met->
nx][met->
ny] = help->
vs[ix][iy];
9301 met->
ess[met->
nx][met->
ny] = help->
ess[ix][iy];
9302 met->
nss[met->
nx][met->
ny] = help->
nss[ix][iy];
9303 met->
shf[met->
nx][met->
ny] = help->
shf[ix][iy];
9304 met->
lsm[met->
nx][met->
ny] = help->
lsm[ix][iy];
9305 met->
sst[met->
nx][met->
ny] = help->
sst[ix][iy];
9306 met->
pbl[met->
nx][met->
ny] = help->
pbl[ix][iy];
9308 met->
cin[met->
nx][met->
ny] = help->
cin[ix][iy];
9310 for (
int ip = 0; ip < help->
np; ip += ctl->
met_dp) {
9311 met->
p[met->
np] = help->
p[ip];
9312 met->
t[met->
nx][met->
ny][met->
np] = help->
t[ix][iy][ip];
9313 met->
u[met->
nx][met->
ny][met->
np] = help->
u[ix][iy][ip];
9314 met->
v[met->
nx][met->
ny][met->
np] = help->
v[ix][iy][ip];
9315 met->
w[met->
nx][met->
ny][met->
np] = help->
w[ix][iy][ip];
9316 met->
h2o[met->
nx][met->
ny][met->
np] = help->
h2o[ix][iy][ip];
9317 met->
o3[met->
nx][met->
ny][met->
np] = help->
o3[ix][iy][ip];
9318 met->
lwc[met->
nx][met->
ny][met->
np] = help->
lwc[ix][iy][ip];
9319 met->
rwc[met->
nx][met->
ny][met->
np] = help->
rwc[ix][iy][ip];
9320 met->
iwc[met->
nx][met->
ny][met->
np] = help->
iwc[ix][iy][ip];
9321 met->
swc[met->
nx][met->
ny][met->
np] = help->
swc[ix][iy][ip];
9322 met->
cc[met->
nx][met->
ny][met->
np] = help->
cc[ix][iy][ip];
9343 LOG(2,
"Read surface data...");
9347 (ncid,
"lnsp",
"LNSP", NULL, NULL, NULL, NULL, ctl, met, met->
ps,
9349 for (
int ix = 0; ix < met->
nx; ix++)
9350 for (
int iy = 0; iy < met->
ny; iy++)
9351 met->
ps[ix][iy] = (
float) (exp(met->
ps[ix][iy]) / 100.);
9354 (ncid,
"ps",
"PS",
"sp",
"SP", NULL, NULL, ctl, met, met->
ps, 0.01f,
9356 WARN(
"Cannot not read surface pressure data (use lowest level)!");
9357 for (
int ix = 0; ix < met->
nx; ix++)
9358 for (
int iy = 0; iy < met->
ny; iy++)
9360 = (ctl->
met_np > 0 ? (
float) ctl->
met_p[0] : (
float) met->
p[0]);
9368 (ncid,
"z",
"Z", NULL, NULL, NULL, NULL, ctl, met, met->
zs,
9369 (
float) (1. / (1000. *
G0)), 1))
9371 (ncid,
"zm",
"ZM", NULL, NULL, NULL, NULL, ctl, met, met->
zs,
9372 (
float) (1. / 1000.), 1))
9373 WARN(
"Cannot read surface geopotential height!");
9384 memcpy(help, met->
pl,
sizeof(met->
pl));
9386 (ncid,
"gph",
"GPH", NULL, NULL, ctl, met, met->
pl,
9387 (
float) (1e-3 /
G0)))
9388 ERRMSG(
"Cannot read geopotential height!");
9389 for (
int ix = 0; ix < met->
nx; ix++)
9390 for (
int iy = 0; iy < met->
ny; iy++)
9391 met->
zs[ix][iy] = met->
pl[ix][iy][0];
9392 memcpy(met->
pl, help,
sizeof(met->
pl));
9398 (ncid,
"t2m",
"T2M",
"2t",
"2T",
"t2",
"T2", ctl, met, met->
ts, 1.0, 1))
9399 WARN(
"Cannot read surface temperature!");
9403 (ncid,
"u10m",
"U10M",
"10u",
"10U",
"u10",
"U10", ctl, met, met->
us,
9405 WARN(
"Cannot read surface zonal wind!");
9409 (ncid,
"v10m",
"V10M",
"10v",
"10V",
"v10",
"V10", ctl, met, met->
vs,
9411 WARN(
"Cannot read surface meridional wind!");
9415 (ncid,
"iews",
"IEWS", NULL, NULL, NULL, NULL, ctl, met, met->
ess,
9417 WARN(
"Cannot read eastward turbulent surface stress!");
9421 (ncid,
"inss",
"INSS", NULL, NULL, NULL, NULL, ctl, met, met->
nss,
9423 WARN(
"Cannot read nothward turbulent surface stress!");
9427 (ncid,
"ishf",
"ISHF", NULL, NULL, NULL, NULL, ctl, met, met->
shf,
9429 WARN(
"Cannot read surface sensible heat flux!");
9433 (ncid,
"lsm",
"LSM", NULL, NULL, NULL, NULL, ctl, met, met->
lsm, 1.0,
9435 WARN(
"Cannot read land-sea mask!");
9439 (ncid,
"sstk",
"SSTK",
"sst",
"SST", NULL, NULL, ctl, met, met->
sst,
9441 WARN(
"Cannot read sea surface temperature!");
9446 (ncid,
"blp",
"BLP", NULL, NULL, NULL, NULL, ctl, met, met->
pbl,
9448 WARN(
"Cannot read planetary boundary layer pressure!");
9451 (ncid,
"blh",
"BLH", NULL, NULL, NULL, NULL, ctl, met, met->
pbl,
9453 WARN(
"Cannot read planetary boundary layer height!");
9458 (ncid,
"cape",
"CAPE", NULL, NULL, NULL, NULL, ctl, met, met->
cape,
9460 WARN(
"Cannot read CAPE!");
9465 (ncid,
"cin",
"CIN", NULL, NULL, NULL, NULL, ctl, met, met->
cin,
9467 WARN(
"Cannot read convective inhibition!");
9473void read_met_surface_grib(
9474 codes_handle **handles,
9475 const int num_messages,
9479 int sp_flag = 0, z_flag = 0, t_flag = 0, u_flag = 0, v_flag = 0, lsm_flag =
9480 0, sst_flag = 0, cape_flag = 0, cin_flag = 0, pbl_flag = 0;
9482 for (
int i = 0; i < num_messages; i++) {
9483 size_t max_size = 50;
9484 char short_name[max_size];
9489 ECC(codes_get_string(handles[i],
"shortName", short_name, &max_size));
9490 ECC(codes_get_size(handles[i],
"values", &value_count));
9491 double *values = (
double *) malloc(value_count *
sizeof(
double));
9492 ECC(codes_get_double_array(handles[i],
"values", values, &value_count))
9521 WARN(
"Cannot read surface pressure data!");
9524 WARN(
"Cannot read surface geopotential height!");
9527 WARN(
"Cannot read surface temperature!");
9530 WARN(
"Cannot read surface zonal wind!");
9533 WARN(
"Cannot read surface meridional wind!");
9535 if (lsm_flag == 0) {
9536 WARN(
"Cannot read land-sea mask!");
9538 if (sst_flag == 0) {
9539 WARN(
"Cannot read sea surface temperature!");
9542 if (cape_flag == 0) {
9543 WARN(
"Cannot read CAPE!");
9545 if (cin_flag == 0) {
9546 WARN(
"Cannot read convective inhibition!");
9550 if (pbl_flag == 0) {
9551 WARN(
"Cannot read planetary boundary layer!");
9555 LOG(1,
"Finished reading surface data")
9566 double p2[200], pv[
EP], pv2[200], t[
EP], t2[200], th[
EP],
9567 th2[200], z[
EP], z2[200];
9571 LOG(2,
"Calculate tropopause...");
9574#pragma omp parallel for default(shared)
9575 for (
int iz = 0; iz < met->
np; iz++)
9576 z[iz] =
Z(met->
p[iz]);
9577#pragma omp parallel for default(shared)
9578 for (
int iz = 0; iz <= 190; iz++) {
9579 z2[iz] = 4.5 + 0.1 * iz;
9585#pragma omp parallel for default(shared) collapse(2)
9586 for (
int ix = 0; ix < met->
nx; ix++)
9587 for (
int iy = 0; iy < met->
ny; iy++)
9588 met->
pt[ix][iy] = NAN;
9592#pragma omp parallel for default(shared) collapse(2)
9593 for (
int ix = 0; ix < met->
nx; ix++)
9594 for (
int iy = 0; iy < met->
ny; iy++)
9602#pragma omp parallel for default(shared) private(t,t2) collapse(2)
9603 for (
int ix = 0; ix < met->
nx; ix++)
9604 for (
int iy = 0; iy < met->
ny; iy++) {
9607 for (
int iz = 0; iz < met->
np; iz++)
9608 t[iz] = met->
t[ix][iy][iz];
9612 int iz = (int) gsl_stats_min_index(t2, 1, 171);
9613 if (iz > 0 && iz < 170)
9614 met->
pt[ix][iy] = (float) p2[iz];
9616 met->
pt[ix][iy] = NAN;
9624#pragma omp parallel for default(shared) private(t,t2) collapse(2)
9625 for (
int ix = 0; ix < met->
nx; ix++)
9626 for (
int iy = 0; iy < met->
ny; iy++) {
9630 for (iz = 0; iz < met->
np; iz++)
9631 t[iz] = met->
t[ix][iy][iz];
9635 met->
pt[ix][iy] = NAN;
9636 for (iz = 0; iz <= 170; iz++) {
9638 for (
int iz2 = iz + 1; iz2 <= iz + 20; iz2++)
9639 if (
LAPSE(p2[iz], t2[iz], p2[iz2], t2[iz2]) > 2.0) {
9644 if (iz > 0 && iz < 170)
9645 met->
pt[ix][iy] = (float) p2[iz];
9652 met->
pt[ix][iy] = NAN;
9653 for (; iz <= 170; iz++) {
9655 for (
int iz2 = iz + 1; iz2 <= iz + 10; iz2++)
9656 if (
LAPSE(p2[iz], t2[iz], p2[iz2], t2[iz2]) < 3.0) {
9663 for (; iz <= 170; iz++) {
9665 for (
int iz2 = iz + 1; iz2 <= iz + 20; iz2++)
9666 if (
LAPSE(p2[iz], t2[iz], p2[iz2], t2[iz2]) > 2.0) {
9671 if (iz > 0 && iz < 170)
9672 met->
pt[ix][iy] = (float) p2[iz];
9684#pragma omp parallel for default(shared) private(pv,pv2,th,th2) collapse(2)
9685 for (
int ix = 0; ix < met->
nx; ix++)
9686 for (
int iy = 0; iy < met->
ny; iy++) {
9689 for (
int iz = 0; iz < met->
np; iz++)
9690 pv[iz] = met->
pv[ix][iy][iz];
9694 for (
int iz = 0; iz < met->
np; iz++)
9695 th[iz] =
THETA(met->
p[iz], met->
t[ix][iy][iz]);
9699 met->
pt[ix][iy] = NAN;
9700 for (
int iz = 0; iz <= 170; iz++)
9703 if (iz > 0 && iz < 170)
9704 met->
pt[ix][iy] = (float) p2[iz];
9711 ERRMSG(
"Cannot calculate tropopause!");
9714#pragma omp parallel for default(shared) collapse(2)
9715 for (
int ix = 0; ix < met->
nx; ix++)
9716 for (
int iy = 0; iy < met->
ny; iy++) {
9717 double h2ot, tt, zt;
9720 met->
lat[iy], &tt, ci, cw, 1);
9722 met->
lat[iy], &zt, ci, cw, 0);
9724 met->
lat[iy], &h2ot, ci, cw, 0);
9725 met->
tt[ix][iy] = (float) tt;
9726 met->
zt[ix][iy] = (float) zt;
9727 met->
h2ot[ix][iy] = (float) h2ot;
9734 const char *filename,
9744 LOG(1,
"Read observation data: %s", filename);
9748 read_obs_asc(filename, rt, rz, rlon, rlat, robs, nobs);
9750 read_obs_nc(filename, rt, rz, rlon, rlat, robs, nobs);
9752 ERRMSG(
"Set OBS_TYPE to 0 or 1!");
9755 for (
int i = 1; i < *nobs; i++)
9756 if (rt[i] < rt[i - 1])
9757 ERRMSG(
"Time must be ascending!");
9762 LOG(2,
"Number of observations: %d", *nobs);
9763 gsl_stats_minmax(&mini, &maxi, rt, 1, (
size_t) n);
9764 LOG(2,
"Time range: %.2f ... %.2f s", mini, maxi);
9765 gsl_stats_minmax(&mini, &maxi, rz, 1, (
size_t) n);
9766 LOG(2,
"Altitude range: %g ... %g km", mini, maxi);
9767 gsl_stats_minmax(&mini, &maxi, rlon, 1, (
size_t) n);
9768 LOG(2,
"Longitude range: %g ... %g deg", mini, maxi);
9769 gsl_stats_minmax(&mini, &maxi, rlat, 1, (
size_t) n);
9770 LOG(2,
"Latitude range: %g ... %g deg", mini, maxi);
9771 gsl_stats_minmax(&mini, &maxi, robs, 1, (
size_t) n);
9772 LOG(2,
"Observation range: %g ... %g", mini, maxi);
9778 const char *filename,
9788 if (!(in = fopen(filename,
"r")))
9789 ERRMSG(
"Cannot open file!");
9793 while (fgets(line,
LEN, in))
9794 if (sscanf(line,
"%lg %lg %lg %lg %lg", &rt[*nobs], &rz[*nobs],
9795 &rlon[*nobs], &rlat[*nobs], &robs[*nobs]) == 5)
9796 if ((++(*nobs)) >=
NOBS)
9797 ERRMSG(
"Too many observations!");
9806 const char *filename,
9817 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR)
9818 ERRMSG(
"Cannot open file!");
9835 const char *filename,
9838 const char *varname,
9840 const char *defvalue,
9845 char fullname1[
LEN], fullname2[
LEN], rval[
LEN];
9850 if (filename[strlen(filename) - 1] !=
'-')
9851 if (!(in = fopen(filename,
"r")))
9852 ERRMSG(
"Cannot open file!");
9856 sprintf(fullname1,
"%s[%d]", varname, arridx);
9857 sprintf(fullname2,
"%s[*]", varname);
9859 sprintf(fullname1,
"%s", varname);
9860 sprintf(fullname2,
"%s", varname);
9865 char dummy[
LEN], line[
LEN], rvarname[
LEN];
9866 while (fgets(line,
LEN, in)) {
9867 if (sscanf(line,
"%4999s %4999s %4999s", rvarname, dummy, rval) == 3)
9868 if (strcasecmp(rvarname, fullname1) == 0 ||
9869 strcasecmp(rvarname, fullname2) == 0) {
9875 for (i = 1; i < argc - 1; i++)
9876 if (strcasecmp(argv[i], fullname1) == 0 ||
9877 strcasecmp(argv[i], fullname2) == 0) {
9878 sprintf(rval,
"%s", argv[i + 1]);
9889 if (strlen(defvalue) > 0)
9890 sprintf(rval,
"%s", defvalue);
9892 ERRMSG(
"Missing variable %s!\n", fullname1);
9896 LOG(1,
"%s = %s", fullname1, rval);
9900 sprintf(value,
"%s", rval);
9910 const double rhop) {
9913 const double rp_help = rp * 1e-6;
9916 const double rho =
RHO(p, T);
9919 const double eta = 1.8325e-5 * (416.16 / (T + 120.)) * pow(T / 296.16, 1.5);
9922 const double v = sqrt(8. *
KB * T / (M_PI * 4.8096e-26));
9925 const double lambda = 2. * eta / (rho * v);
9928 const double K = lambda / rp_help;
9931 const double G = 1. + K * (1.249 + 0.42 * exp(-0.87 / K));
9934 return 2. *
SQR(rp_help) * (rhop - rho) *
G0 / (9. * eta) * G;
9952 gsl_interp_accel *acc = gsl_interp_accel_alloc();
9953 gsl_spline *s = gsl_spline_alloc(gsl_interp_cspline, (
size_t) n);
9956 gsl_spline_init(s, x, y, (
size_t) n);
9957 for (
int i = 0; i < n2; i++)
9960 else if (x2[i] >= x[n - 1])
9963 y2[i] = gsl_spline_eval(s, x2[i], acc);
9967 gsl_interp_accel_free(acc);
9972 for (
int i = 0; i < n2; i++)
9975 else if (x2[i] >= x[n - 1])
9979 y2[i] =
LIN(x[idx], y[idx], x[idx + 1], y[idx + 1], x2[i]);
9993 float mean = 0, var = 0;
9995 for (
int i = 0; i < n; ++i) {
9997 var +=
SQR(data[i]);
10000 var = var / (float) n -
SQR(mean / (
float) n);
10002 return (var > 0 ? sqrtf(var) : 0);
10010 const double lat) {
10013 const double D = sec / 86400 - 0.5;
10016 const double g =
DEG2RAD(357.529 + 0.98560028 * D);
10017 const double q = 280.459 + 0.98564736 * D;
10018 const double L =
DEG2RAD(q + 1.915 * sin(g) + 0.020 * sin(2 * g));
10021 const double e =
DEG2RAD(23.439 - 0.00000036 * D);
10024 const double sindec = sin(e) * sin(L);
10027 const double ra = atan2(cos(e) * sin(L), cos(L));
10030 const double GMST = 18.697374558 + 24.06570982441908 * D;
10033 const double LST = GMST + lon / 15;
10036 const double h = LST / 12 * M_PI - ra;
10039 const double lat_help =
DEG2RAD(lat);
10042 return acos(sin(lat_help) * sindec +
10043 cos(lat_help) * sqrt(1 -
SQR(sindec)) * cos(h));
10055 const double remain,
10067 t1.tm_year = year - 1900;
10068 t1.tm_mon = mon - 1;
10074 *jsec = (double) timegm(&t1) - (double) timegm(&t0) + remain;
10082 const int output) {
10089 static int iname = -1, igroup = -1, nname, ngroup, ct_name[
NTIMER];
10092 t1 = omp_get_wtime();
10097 rt_name[iname] += dt;
10098 rt_min[iname] = (ct_name[iname] <= 0 ? dt :
MIN(rt_min[iname], dt));
10099 rt_max[iname] = (ct_name[iname] <= 0 ? dt :
MAX(rt_max[iname], dt));
10103 rt_group[igroup] += t1 - t0;
10107 for (
int i = 0; i < nname; i++)
10108 LOG(1,
"TIMER_%s = %.3f s (min= %g s, mean= %g s,"
10109 " max= %g s, n= %d)", names[i], rt_name[i], rt_min[i],
10110 rt_name[i] / ct_name[i], rt_max[i], ct_name[i]);
10111 for (
int i = 0; i < ngroup; i++)
10112 LOG(1,
"TIMER_GROUP_%s = %.3f s", groups[i], rt_group[i]);
10113 double total = 0.0;
10114 for (
int i = 0; i < nname; i++)
10115 total += rt_name[i];
10116 LOG(1,
"TIMER_TOTAL = %.3f s", total);
10120 for (iname = 0; iname < nname; iname++)
10121 if (strcasecmp(name, names[iname]) == 0)
10123 for (igroup = 0; igroup < ngroup; igroup++)
10124 if (strcasecmp(group, groups[igroup]) == 0)
10128 if (iname >= nname) {
10129 sprintf(names[iname],
"%s", name);
10130 if ((++nname) >=
NTIMER)
10131 ERRMSG(
"Too many timers!");
10135 if (igroup >= ngroup) {
10136 sprintf(groups[igroup],
"%s", group);
10137 if ((++ngroup) >=
NTIMER)
10138 ERRMSG(
"Too many groups!");
10148 const char *filename,
10149 const int offset) {
10156 int len = (int) strlen(filename);
10157 sprintf(tstr,
"%.4s", &filename[len - offset]);
10158 int year = atoi(tstr);
10159 sprintf(tstr,
"%.2s", &filename[len - offset + 5]);
10160 int mon = atoi(tstr);
10161 sprintf(tstr,
"%.2s", &filename[len - offset + 8]);
10162 int day = atoi(tstr);
10163 sprintf(tstr,
"%.2s", &filename[len - offset + 11]);
10164 int hour = atoi(tstr);
10165 sprintf(tstr,
"%.2s", &filename[len - offset + 14]);
10166 int min = atoi(tstr);
10169 if (year < 1900 || year > 2100 || mon < 1 || mon > 12 || day < 1
10170 || day > 31 || hour < 0 || hour > 23 || min < 0 || min > 59)
10171 ERRMSG(
"Cannot read time from filename!");
10174 time2jsec(year, mon, day, hour, min, 0, 0.0, &t);
10191 const double p1 = pt * 0.866877899;
10192 const double p0 = pt / 0.866877899;
10195 if (atm->
p[ip] > p0)
10197 else if (atm->
p[ip] < p1)
10200 return LIN(p0, 1.0, p1, 0.0, atm->
p[ip]);
10206 const char *filename,
10214 const double t0 = t - 0.5 * ctl->
dt_mod;
10215 const double t1 = t + 0.5 * ctl->
dt_mod;
10221 if (!(out = popen(
"gnuplot",
"w")))
10222 ERRMSG(
"Cannot create pipe to gnuplot!");
10225 fprintf(out,
"set out \"%s.png\"\n", filename);
10229 int year, mon, day, hour, min, sec;
10230 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
10231 fprintf(out,
"timestr=\"%d-%02d-%02d, %02d:%02d UTC\"\n",
10232 year, mon, day, hour, min);
10237 ERRMSG(
"Cannot open file!");
10239 while (fgets(line,
LEN, in))
10240 fprintf(out,
"%s", line);
10247 if (!(out = fopen(filename,
"w")))
10248 ERRMSG(
"Cannot create file!");
10253 "# $1 = time [s]\n"
10254 "# $2 = altitude [km]\n"
10255 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
10256 for (
int iq = 0; iq < ctl->
nq; iq++)
10257 fprintf(out,
"# $%i = %s [%s]\n", iq + 5, ctl->
qnt_name[iq],
10259 fprintf(out,
"\n");
10262 for (
int ip = 0; ip < atm->
np; ip += ctl->
atm_stride) {
10269 fprintf(out,
"%.2f %g %g %g", atm->
time[ip],
Z(atm->
p[ip]),
10270 atm->
lon[ip], atm->
lat[ip]);
10271 for (
int iq = 0; iq < ctl->
nq; iq++) {
10276 fprintf(out, ctl->
qnt_format[iq], atm->
q[iq][ip]);
10278 fprintf(out,
"\n");
10288 const char *filename,
10290 const atm_t *atm) {
10295 if (!(out = fopen(filename,
"w")))
10296 ERRMSG(
"Cannot create file!");
10320 for (
int iq = 0; iq < ctl->
nq; iq++)
10338 const char *filename,
10340 const atm_t *atm) {
10342 int tid, pid, ncid, varid;
10343 size_t start[2], count[2];
10346 nc_create(filename, NC_NETCDF4, &ncid);
10349 NC(nc_def_dim(ncid,
"time", 1, &tid));
10350 NC(nc_def_dim(ncid,
"NPARTS", (
size_t) atm->
np, &pid));
10353 int dim_ids[2] = { tid, pid };
10354 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"Time",
10355 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
10356 NC_DEF_VAR(
"LAT", NC_DOUBLE, 1, &pid,
"Latitude",
"deg",
10358 NC_DEF_VAR(
"LON", NC_DOUBLE, 1, &pid,
"Longitude",
"deg",
10360 NC_DEF_VAR(
"PRESS", NC_DOUBLE, 1, &pid,
"Pressure",
"hPa",
10363 for (
int iq = 0; iq < ctl->
nq; iq++)
10373 NC(nc_enddef(ncid));
10381 for (
int iq = 0; iq < ctl->
nq; iq++)
10385 NC(nc_close(ncid));
10391 const char *dirname,
10397 static size_t out_cnt = 0;
10399 double r, r_start, r_stop;
10400 int year, mon, day, hour, min, sec;
10401 int year_start, mon_start, day_start, hour_start, min_start, sec_start;
10402 int year_stop, mon_stop, day_stop, hour_stop, min_stop, sec_stop;
10403 char filename_out[2 *
LEN] =
"traj_fix_3d_YYYYMMDDHH_YYYYMMDDHH.nc";
10405 int ncid, varid, tid, pid, cid;
10413 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
10415 &min_start, &sec_start, &r_start);
10417 &min_stop, &sec_stop, &r_stop);
10419 sprintf(filename_out,
10420 "%s/traj_fix_3d_%02d%02d%02d%02d_%02d%02d%02d%02d.nc", dirname,
10421 year_start % 100, mon_start, day_start, hour_start,
10422 year_stop % 100, mon_stop, day_stop, hour_stop);
10423 LOG(1,
"Write traj file: %s", filename_out);
10426 start[0] = out_cnt;
10429 count[1] = (size_t) atm->
np;
10432 if (out_cnt == 0) {
10435 nc_create(filename_out, NC_NETCDF4, &ncid);
10438 NC(nc_def_dim(ncid,
"time", NC_UNLIMITED, &tid));
10439 NC(nc_def_dim(ncid,
"NPARTS", (
size_t) atm->
np, &pid));
10440 NC(nc_def_dim(ncid,
"TMDT", 7, &cid));
10445 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"Time",
10446 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
10447 NC_DEF_VAR(
"LAT", NC_DOUBLE, 2, dim_ids,
"Latitude",
"deg",
10449 NC_DEF_VAR(
"LON", NC_DOUBLE, 2, dim_ids,
"Longitude",
"deg",
10451 NC_DEF_VAR(
"PRESS", NC_DOUBLE, 2, dim_ids,
"Pressure",
"hPa",
10453 NC_DEF_VAR(
"ZETA", NC_DOUBLE, 2, dim_ids,
"Zeta",
"K",
10455 for (
int iq = 0; iq < ctl->
nq; iq++)
10465 NC(nc_enddef(ncid));
10466 NC(nc_close(ncid));
10473 NC(nc_open(filename_out, NC_WRITE, &ncid));
10485 for (
int iq = 0; iq < ctl->
nq; iq++)
10489 NC(nc_close(ncid));
10492 if ((year == year_stop) && (mon == mon_stop)
10493 && (day == day_stop) && (hour == hour_stop)) {
10496 char filename_init[2 *
LEN] =
"./init_fix_YYYYMMDDHH.nc";
10497 sprintf(filename_init,
"%s/init_fix_%02d%02d%02d%02d.nc",
10498 dirname, year_stop % 100, mon_stop, day_stop, hour_stop);
10499 LOG(1,
"Write init file: %s", filename_init);
10502 nc_create(filename_init, NC_NETCDF4, &ncid);
10505 NC(nc_def_dim(ncid,
"time", 1, &tid));
10506 NC(nc_def_dim(ncid,
"NPARTS", (
size_t) atm->
np, &pid));
10511 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"Time",
10512 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
10513 NC_DEF_VAR(
"LAT", NC_DOUBLE, 1, &pid,
"Latitude",
"deg",
10515 NC_DEF_VAR(
"LON", NC_DOUBLE, 1, &pid,
"Longitude",
"deg",
10517 NC_DEF_VAR(
"PRESS", NC_DOUBLE, 1, &pid,
"Pressure",
"hPa",
10520 for (
int iq = 0; iq < ctl->
nq; iq++)
10530 NC(nc_enddef(ncid));
10538 for (
int iq = 0; iq < ctl->
nq; iq++)
10542 NC(nc_close(ncid));
10549 const char *filename,
10551 const atm_t *atm) {
10553 int ncid, obsid, varid;
10555 size_t start[2], count[2];
10558 NC(nc_create(filename, NC_NETCDF4, &ncid));
10561 NC(nc_def_dim(ncid,
"obs", (
size_t) atm->
np, &obsid));
10564 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &obsid,
"time",
10565 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
10566 NC_DEF_VAR(
"press", NC_DOUBLE, 1, &obsid,
"pressure",
"hPa",
10568 NC_DEF_VAR(
"lon", NC_DOUBLE, 1, &obsid,
"longitude",
"degrees_east",
10570 NC_DEF_VAR(
"lat", NC_DOUBLE, 1, &obsid,
"latitude",
"degrees_north",
10572 for (
int iq = 0; iq < ctl->
nq; iq++)
10581 NC(nc_enddef(ncid));
10588 for (
int iq = 0; iq < ctl->
nq; iq++)
10592 NC(nc_close(ncid));
10598 const char *filename,
10605 static double *modmean, *obsmean, *obsstd, *rt, *rz, *rlon, *rlat, *robs,
10608 static int *obscount, ct, cx, cy, cz, ip, ix, iy, iz, n, nobs, nk;
10617 if (ctl->
qnt_m < 0)
10618 ERRMSG(
"Need quantity mass!");
10621 ALLOC(area,
double,
10627 ALLOC(rlon,
double,
10629 ALLOC(rlat,
double,
10631 ALLOC(robs,
double,
10642 LOG(1,
"Write CSI data: %s", filename);
10643 if (!(out = fopen(filename,
"w")))
10644 ERRMSG(
"Cannot create file!");
10648 "# $1 = time [s]\n"
10649 "# $2 = number of hits (cx)\n"
10650 "# $3 = number of misses (cy)\n"
10651 "# $4 = number of false alarms (cz)\n"
10652 "# $5 = number of observations (cx + cy)\n"
10653 "# $6 = number of forecasts (cx + cz)\n"
10654 "# $7 = bias (ratio of forecasts and observations) [%%]\n"
10655 "# $8 = probability of detection (POD) [%%]\n"
10656 "# $9 = false alarm rate (FAR) [%%]\n"
10657 "# $10 = critical success index (CSI) [%%]\n");
10659 "# $11 = hits associated with random chance\n"
10660 "# $12 = equitable threat score (ETS) [%%]\n"
10661 "# $13 = Pearson linear correlation coefficient\n"
10662 "# $14 = Spearman rank-order correlation coefficient\n"
10663 "# $15 = column density mean error (F - O) [kg/m^2]\n"
10664 "# $16 = column density root mean square error (RMSE) [kg/m^2]\n"
10665 "# $17 = column density mean absolute error [kg/m^2]\n"
10666 "# $18 = log-likelihood function\n"
10667 "# $19 = number of data points\n\n");
10675 for (iy = 0; iy < ctl->
csi_ny; iy++) {
10676 const double lat = ctl->
csi_lat0 + dlat * (iy + 0.5);
10677 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat));
10682 const double t0 = t - 0.5 * ctl->
dt_mod;
10683 const double t1 = t + 0.5 * ctl->
dt_mod;
10686 ALLOC(modmean,
double,
10688 ALLOC(obsmean,
double,
10690 ALLOC(obscount,
int,
10692 ALLOC(obsstd,
double,
10696 for (
int i = 0; i < nobs; i++) {
10701 else if (rt[i] >= t1)
10705 if (!isfinite(robs[i]))
10709 ix = (int) ((rlon[i] - ctl->
csi_lon0) / dlon);
10710 iy = (int) ((rlat[i] - ctl->
csi_lat0) / dlat);
10711 iz = (int) ((rz[i] - ctl->
csi_z0) / dz);
10714 if (ix < 0 || ix >= ctl->
csi_nx ||
10715 iy < 0 || iy >= ctl->
csi_ny || iz < 0 || iz >= ctl->
csi_nz)
10720 obsmean[idx] += robs[i];
10721 obsstd[idx] +=
SQR(robs[i]);
10726 for (ip = 0; ip < atm->
np; ip++) {
10729 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
10733 ix = (int) ((atm->
lon[ip] - ctl->
csi_lon0) / dlon);
10734 iy = (int) ((atm->
lat[ip] - ctl->
csi_lat0) / dlat);
10735 iz = (int) ((
Z(atm->
p[ip]) - ctl->
csi_z0) / dz);
10738 if (ix < 0 || ix >= ctl->
csi_nx ||
10739 iy < 0 || iy >= ctl->
csi_ny || iz < 0 || iz >= ctl->
csi_nz)
10745 * atm->
q[ctl->
qnt_m][ip];
10749 for (ix = 0; ix < ctl->
csi_nx; ix++)
10750 for (iy = 0; iy < ctl->
csi_ny; iy++)
10751 for (iz = 0; iz < ctl->
csi_nz; iz++) {
10755 if (obscount[idx] > 0) {
10756 obsmean[idx] /= obscount[idx];
10757 obsstd[idx] -=
SQR(obsmean[idx]);
10758 obsstd[idx] = sqrt(obsstd[idx]);
10762 if (modmean[idx] > 0)
10763 modmean[idx] /= (1e6 * area[iy]);
10766 if (obscount[idx] > 0) {
10780 if (obscount[idx] > 0
10783 x[n] = modmean[idx];
10784 y[n] = obsmean[idx];
10786 obsstdn[n] = obsstd[idx];
10788 ERRMSG(
"Too many data points to calculate statistics!");
10797 static double work[2 *
NCSI], work2[2 *
NCSI];;
10798 const int n_obs = cx + cy;
10799 const int n_for = cx + cz;
10800 const double bias = (n_obs > 0) ? 100. * n_for / n_obs : NAN;
10801 const double pod = (n_obs > 0) ? (100. * cx) / n_obs : NAN;
10802 const double far = (n_for > 0) ? (100. * cz) / n_for : NAN;
10804 (cx + cy + cz > 0) ? (100. * cx) / (cx + cy + cz) : NAN;
10805 const double cx_rd = (ct > 0) ? (1. * n_obs * n_for) / ct : NAN;
10806 const double ets = (cx + cy + cz - cx_rd > 0) ?
10807 (100. * (cx - cx_rd)) / (cx + cy + cz - cx_rd) : NAN;
10808 const double rho_p =
10809 (n > 0) ? gsl_stats_correlation(x, 1, y, 1, (
size_t) n) : NAN;
10810 const double rho_s =
10811 (n > 0) ? gsl_stats_spearman(x, 1, y, 1, (
size_t) n, work) : NAN;
10812 for (
int i = 0; i < n; i++) {
10813 work[i] = x[i] - y[i];
10814 work2[i] = (obsstdn[i] != 0) ? (x[i] - y[i]) / obsstdn[i] : 0;
10816 const double mean = (n > 0) ? gsl_stats_mean(work, 1, (
size_t) n) : NAN;
10817 const double rmse =
10818 (n > 0) ? gsl_stats_sd_with_fixed_mean(work, 1, (
size_t) n,
10820 const double absdev =
10821 (n > 0) ? gsl_stats_absdev_m(work, 1, (
size_t) n, 0.0) : NAN;
10822 const double loglikelihood =
10823 (n > 0) ? gsl_stats_tss(work2, 1, (
size_t) n) * (-0.5) : GSL_NAN;
10827 "%.2f %d %d %d %d %d %g %g %g %g %g %g %g %g %g %g %g %g %d\n",
10828 t, cx, cy, cz, n_obs, n_for, bias, pod, far, csi, cx_rd, ets,
10829 rho_p, rho_s, mean, rmse, absdev, loglikelihood, n);
10832 n = ct = cx = cy = cz = 0;
10860 const char *filename,
10867 static double *modmean, *obsmean, *obsstd, *rt, *rz, *rlon, *rlat, *robs,
10871 iz, n[
NENS], nobs, nk;
10877 if (ctl->
qnt_m < 0)
10878 ERRMSG(
"Need quantity mass!");
10882 ERRMSG(
"Missing ensemble IDs!");
10885 ERRMSG(
"Too much ensembles!")
10889 ALLOC(area,
double,
10895 ALLOC(rlon,
double,
10897 ALLOC(rlat,
double,
10899 ALLOC(robs,
double,
10910 LOG(1,
"Write CSI ensemble data: %s", filename);
10911 if (!(out = fopen(filename,
"w")))
10912 ERRMSG(
"Cannot create file!");
10916 "# $1 = time [s]\n"
10917 "# $2 = ensemble ID\n"
10918 "# $3 = number of hits (cx)\n"
10919 "# $4 = number of misses (cy)\n"
10920 "# $5 = number of false alarms (cz)\n"
10921 "# $6 = number of observations (cx + cy)\n"
10922 "# $7 = number of forecasts (cx + cz)\n"
10923 "# $8 = bias (ratio of forecasts and observations) [%%]\n"
10924 "# $9 = probability of detection (POD) [%%]\n"
10925 "# $10 = false alarm rate (FAR) [%%]\n"
10926 "# $11 = critical success index (CSI) [%%]\n"
10927 "# $12 = hits associated with random chance\n"
10928 "# $13 = equitable threat score (ETS) [%%]\n"
10929 "# $14 = Pearson linear correlation coefficient\n"
10930 "# $15 = Spearman rank-order correlation coefficient\n"
10931 "# $16 = column density mean error (F - O) [kg/m^2]\n"
10932 "# $17 = column density root mean square error (RMSE) [kg/m^2]\n"
10933 "# $18 = column density mean absolute error [kg/m^2]\n"
10934 "# $19 = log-likelihood function\n"
10935 "# $20 = number of data points\n\n");
10943 for (iy = 0; iy < ctl->
csi_ny; iy++) {
10944 const double lat = ctl->
csi_lat0 + dlat * (iy + 0.5);
10945 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat));
10950 const double t0 = t - 0.5 * ctl->
dt_mod;
10951 const double t1 = t + 0.5 * ctl->
dt_mod;
10954 ALLOC(modmean,
double,
10957 ALLOC(obsmean,
double,
10959 ALLOC(obscount,
int,
10961 ALLOC(obsstd,
double,
10965 for (
int i = 0; i < ctl->
nens; i++) {
10966 ct[i] = cx[i] = cy[i] = cz[i] = n[i] = 0;
10971 for (
int i = 0; i < nobs; i++) {
10975 else if (rt[i] >= t1)
10979 if (!isfinite(robs[i]))
10983 ix = (int) ((rlon[i] - ctl->
csi_lon0) / dlon);
10984 iy = (int) ((rlat[i] - ctl->
csi_lat0) / dlat);
10985 iz = (int) ((rz[i] - ctl->
csi_z0) / dz);
10988 if (ix < 0 || ix >= ctl->
csi_nx ||
10989 iy < 0 || iy >= ctl->
csi_ny || iz < 0 || iz >= ctl->
csi_nz)
10994 obsmean[idx] += robs[i];
10995 obsstd[idx] +=
SQR(robs[i]);
11000 for (ip = 0; ip < atm->
np; ip++) {
11002 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11006 int ens = (int) atm->
q[ctl->
qnt_ens][ip];
11007 if (ens < 0 || ens > ctl->
nens)
11008 ERRMSG(
"Ensemble ID is out of range!");
11011 ix = (int) ((atm->
lon[ip] - ctl->
csi_lon0) / dlon);
11012 iy = (int) ((atm->
lat[ip] - ctl->
csi_lat0) / dlat);
11013 iz = (int) ((
Z(atm->
p[ip]) - ctl->
csi_z0) / dz);
11016 if (ix < 0 || ix >= ctl->
csi_nx ||
11017 iy < 0 || iy >= ctl->
csi_ny || iz < 0 || iz >= ctl->
csi_nz)
11024 * atm->
q[ctl->
qnt_m][ip];
11028 for (ix = 0; ix < ctl->
csi_nx; ix++)
11029 for (iy = 0; iy < ctl->
csi_ny; iy++)
11030 for (iz = 0; iz < ctl->
csi_nz; iz++) {
11033 if (obscount[idx] > 0) {
11034 obsmean[idx] /= obscount[idx];
11035 obsstd[idx] -=
SQR(obsmean[idx]);
11036 obsstd[idx] = sqrt(obsstd[idx]);
11040 for (
int i = 0; i < ctl->
nens; i++) {
11043 if (modmean[mod_idx] > 0)
11044 modmean[mod_idx] /= (1e6 * area[iy]);
11048 if (obscount[idx] > 0) {
11049 for (
int i = 0; i < ctl->
nens; i++) {
11066 for (
int i = 0; i < ctl->
nens; i++) {
11067 if (obscount[idx] > 0
11069 || modmean[i * grid_size + idx] >= ctl->
csi_modmin)) {
11072 x[n[i]] = modmean[mod_idx];
11073 y[n[i]] = obsmean[idx];
11075 obsstdn[n[i]] = obsstd[idx];
11076 if ((++n[i]) >=
NCSI)
11077 ERRMSG(
"Too many data points to calculate statistics!");
11084 for (
int i = 0; i < ctl->
nens; i++) {
11087 static double work[2 *
NCSI], work2[2 *
NCSI];
11088 const int n_obs = cx[i] + cy[i];
11089 const int n_for = cx[i] + cz[i];
11090 const double bias = (n_obs > 0) ? 100. * n_for / n_obs : NAN;
11091 const double pod = (n_obs > 0) ? (100. * cx[i]) / n_obs : NAN;
11092 const double far = (n_for > 0) ? (100. * cz[i]) / n_for : NAN;
11094 (cx[i] + cy[i] + cz[i] >
11095 0) ? (100. * cx[i]) / (cx[i] + cy[i] + cz[i]) : NAN;
11096 const double cx_rd = (ct[i] > 0) ? (1. * n_obs * n_for) / ct[i] : NAN;
11098 (cx[i] + cy[i] + cz[i] - cx_rd >
11099 0) ? (100. * (cx[i] - cx_rd)) / (cx[i] + cy[i] + cz[i] -
11101 const double rho_p = (n[i] > 0) ? gsl_stats_correlation(x, 1, y, 1,
11104 const double rho_s =
11105 (n[i] > 0) ? gsl_stats_spearman(x, 1, y, 1, (
size_t) n[i],
11107 for (
int j = 0; j < n[i]; j++) {
11108 work[j] = x[j] - y[j];
11109 work2[j] = (obsstdn[j] != 0) ? (x[j] - y[j]) / obsstdn[j] : 0;
11111 const double mean =
11112 (n[i] > 0) ? gsl_stats_mean(work, 1, (
size_t) n[i]) : NAN;
11113 const double rmse =
11114 (n[i] > 0) ? gsl_stats_sd_with_fixed_mean(work, 1, (
size_t) n[i],
11116 const double absdev =
11117 (n[i] > 0) ? gsl_stats_absdev_m(work, 1, (
size_t) n[i],
11119 const double loglikelihood = (n[i] > 0) ? gsl_stats_tss(work2, 1,
11121 * (-0.5) : GSL_NAN;
11125 "%.2f %d %d %d %d %d %d %g %g %g %g %g %g %g %g %g %g %g %g %d\n",
11126 t, i, cx[i], cy[i], cz[i], n_obs, n_for, bias, pod, far,
11127 csi, cx_rd, ets, rho_p, rho_s, mean, rmse, absdev,
11128 loglikelihood, n[i]);
11157 const char *filename,
11167 static int n[
NENS];
11174 ERRMSG(
"Missing ensemble IDs!");
11177 const double t0 = t - 0.5 * ctl->
dt_mod;
11178 const double t1 = t + 0.5 * ctl->
dt_mod;
11181 for (
int i = 0; i <
NENS; i++) {
11182 for (
int iq = 0; iq < ctl->
nq; iq++)
11183 qm[iq][i] = qs[iq][i] = 0;
11184 xm[i][0] = xm[i][1] = xm[i][2] = zm[i] = 0;
11189 for (
int ip = 0; ip < atm->
np; ip++) {
11192 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11197 ERRMSG(
"Ensemble ID is out of range!");
11201 for (
int iq = 0; iq < ctl->
nq; iq++) {
11202 qm[iq][ctl->
qnt_ens] += atm->
q[iq][ip];
11213 LOG(1,
"Write ensemble data: %s", filename);
11214 if (!(out = fopen(filename,
"w")))
11215 ERRMSG(
"Cannot create file!");
11219 "# $1 = time [s]\n"
11220 "# $2 = altitude [km]\n"
11221 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
11222 for (
int iq = 0; iq < ctl->
nq; iq++)
11223 fprintf(out,
"# $%d = %s (mean) [%s]\n", 5 + iq,
11225 for (
int iq = 0; iq < ctl->
nq; iq++)
11226 fprintf(out,
"# $%d = %s (sigma) [%s]\n", 5 + ctl->
nq + iq,
11228 fprintf(out,
"# $%d = number of members\n\n", 5 + 2 * ctl->
nq);
11231 for (
int i = 0; i <
NENS; i++)
11233 cart2geo(xm[i], &dummy, &lon, &lat);
11234 fprintf(out,
"%.2f %g %g %g", t, zm[i] / n[i], lon, lat);
11235 for (
int iq = 0; iq < ctl->
nq; iq++) {
11237 fprintf(out, ctl->
qnt_format[iq], qm[iq][i] / n[i]);
11239 for (
int iq = 0; iq < ctl->
nq; iq++) {
11241 double var = qs[iq][i] / n[i] -
SQR(qm[iq][i] / n[i]);
11242 fprintf(out, ctl->
qnt_format[iq], (var > 0 ? sqrt(var) : 0));
11244 fprintf(out,
" %d\n", n[i]);
11254 const char *filename,
11261 static double kz[
EP], kw[
EP];
11265 double *cd, *mean[
NQ], *sigma[
NQ], *vmr_impl, *z, *lon, *lat, *area, *press;
11267 int *ixs, *iys, *izs, *np;
11273 LOG(1,
"Write grid data: %s", filename);
11286 for (
int iq = 0; iq < ctl->
nq; iq++) {
11287 ALLOC(mean[iq],
double,
11289 ALLOC(sigma[iq],
double,
11292 ALLOC(vmr_impl,
double,
11300 ALLOC(area,
double,
11302 ALLOC(press,
double,
11319#pragma omp parallel
for default(shared)
11320 for (
int iz = 0; iz < ctl->
grid_nz; iz++) {
11321 z[iz] = ctl->
grid_z0 + dz * (iz + 0.5);
11322 press[iz] =
P(z[iz]);
11326 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
11327 lon[ix] = ctl->
grid_lon0 + dlon * (ix + 0.5);
11328#pragma omp parallel for default(shared)
11329 for (
int iy = 0; iy < ctl->
grid_ny; iy++) {
11330 lat[iy] = ctl->
grid_lat0 + dlat * (iy + 0.5);
11331 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat[iy]));
11335 const double t0 = t - 0.5 * ctl->
dt_mod;
11336 const double t1 = t + 0.5 * ctl->
dt_mod;
11339#pragma omp parallel for default(shared)
11340 for (
int ip = 0; ip < atm->
np; ip++) {
11341 ixs[ip] = (int) ((atm->
lon[ip] - ctl->
grid_lon0) / dlon);
11342 iys[ip] = (int) ((atm->
lat[ip] - ctl->
grid_lat0) / dlat);
11343 izs[ip] = (int) ((
Z(atm->
p[ip]) - ctl->
grid_z0) / dz);
11344 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
11345 || ixs[ip] < 0 || ixs[ip] >= ctl->
grid_nx
11346 || iys[ip] < 0 || iys[ip] >= ctl->
grid_ny
11347 || izs[ip] < 0 || izs[ip] >= ctl->
grid_nz)
11352 for (
int ip = 0; ip < atm->
np; ip++)
11353 if (izs[ip] >= 0) {
11358 for (
int iq = 0; iq < ctl->
nq; iq++) {
11359 mean[iq][idx] += kernel * atm->
q[iq][ip];
11360 sigma[iq][idx] +=
SQR(kernel * atm->
q[iq][ip]);
11365#pragma omp parallel for default(shared)
11366 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
11367 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
11368 for (
int iz = 0; iz < ctl->
grid_nz; iz++) {
11375 if (ctl->
qnt_m >= 0)
11376 cd[idx] = mean[ctl->
qnt_m][idx] / (1e6 * area[iy]);
11379 vmr_impl[idx] = NAN;
11380 if (ctl->
qnt_m >= 0 && ctl->
molmass > 0 && met0 != NULL
11383 if (mean[ctl->
qnt_m][idx] > 0) {
11389 lon[ix], lat[iy], &temp, ci, cw, 1);
11393 MA / ctl->
molmass * cd[idx] / (
RHO(press[iz], temp) * dz * 1e3);
11399 for (
int iq = 0; iq < ctl->
nq; iq++) {
11400 mean[iq][idx] /= np[idx];
11401 double var = sigma[iq][idx] / np[idx] -
SQR(mean[iq][idx]);
11402 sigma[iq][idx] = (var > 0 ? sqrt(var) : 0);
11404 for (
int iq = 0; iq < ctl->
nq; iq++) {
11405 mean[iq][idx] = NAN;
11406 sigma[iq][idx] = NAN;
11413 t, z, lon, lat, area, dz, np);
11418 t, z, lon, lat, area, dz, np);
11422 ERRMSG(
"Grid data format GRID_TYPE unknown!");
11426 for (
int iq = 0; iq < ctl->
nq; iq++) {
11445 const char *filename,
11450 const double *vmr_impl,
11455 const double *area,
11465 if (!(out = popen(
"gnuplot",
"w")))
11466 ERRMSG(
"Cannot create pipe to gnuplot!");
11469 fprintf(out,
"set out \"%s.png\"\n", filename);
11473 int year, mon, day, hour, min, sec;
11474 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
11475 fprintf(out,
"timestr=\"%d-%02d-%02d, %02d:%02d UTC\"\n",
11476 year, mon, day, hour, min);
11482 ERRMSG(
"Cannot open file!");
11483 while (fgets(line,
LEN, in))
11484 fprintf(out,
"%s", line);
11491 if (!(out = fopen(filename,
"w")))
11492 ERRMSG(
"Cannot create file!");
11497 "# $1 = time [s]\n"
11498 "# $2 = altitude [km]\n"
11499 "# $3 = longitude [deg]\n"
11500 "# $4 = latitude [deg]\n"
11501 "# $5 = surface area [km^2]\n"
11502 "# $6 = layer depth [km]\n"
11503 "# $7 = column density (implicit) [kg/m^2]\n"
11504 "# $8 = volume mixing ratio (implicit) [ppv]\n"
11505 "# $9 = number of particles [1]\n");
11506 for (
int iq = 0; iq < ctl->
nq; iq++)
11507 fprintf(out,
"# $%i = %s (mean) [%s]\n", 10 + iq, ctl->
qnt_name[iq],
11510 for (
int iq = 0; iq < ctl->
nq; iq++)
11511 fprintf(out,
"# $%i = %s (stddev) [%s]\n", 10 + ctl->
nq + iq,
11513 fprintf(out,
"\n");
11516 for (
int ix = 0; ix < ctl->
grid_nx; ix++) {
11518 fprintf(out,
"\n");
11519 for (
int iy = 0; iy < ctl->
grid_ny; iy++) {
11521 fprintf(out,
"\n");
11522 for (
int iz = 0; iz < ctl->
grid_nz; iz++) {
11525 fprintf(out,
"%.2f %g %g %g %g %g %g %g %d", t, z[iz], lon[ix],
11526 lat[iy], area[iy], dz, cd[idx], vmr_impl[idx], np[idx]);
11527 for (
int iq = 0; iq < ctl->
nq; iq++) {
11529 fprintf(out, ctl->
qnt_format[iq], mean[iq][idx]);
11532 for (
int iq = 0; iq < ctl->
nq; iq++) {
11534 fprintf(out, ctl->
qnt_format[iq], sigma[iq][idx]);
11536 fprintf(out,
"\n");
11549 const char *filename,
11554 const double *vmr_impl,
11559 const double *area,
11563 char longname[2 *
LEN], varname[2 *
LEN];
11567 int *help2, ncid, dimid[10], varid;
11569 size_t start[2], count[2];
11572 ALLOC(help,
double,
11578 NC(nc_create(filename, NC_NETCDF4, &ncid));
11581 NC(nc_def_dim(ncid,
"time", 1, &dimid[0]));
11582 NC(nc_def_dim(ncid,
"z", (
size_t) ctl->
grid_nz, &dimid[1]));
11583 NC(nc_def_dim(ncid,
"lat", (
size_t) ctl->
grid_ny, &dimid[2]));
11584 NC(nc_def_dim(ncid,
"lon", (
size_t) ctl->
grid_nx, &dimid[3]));
11585 NC(nc_def_dim(ncid,
"dz", 1, &dimid[4]));
11588 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &dimid[0],
"time",
11589 "seconds since 2000-01-01 00:00:00 UTC", 0, 0);
11590 NC_DEF_VAR(
"z", NC_DOUBLE, 1, &dimid[1],
"altitude",
"km", 0, 0);
11591 NC_DEF_VAR(
"lat", NC_DOUBLE, 1, &dimid[2],
"latitude",
"degrees_north", 0,
11593 NC_DEF_VAR(
"lon", NC_DOUBLE, 1, &dimid[3],
"longitude",
"degrees_east", 0,
11595 NC_DEF_VAR(
"dz", NC_DOUBLE, 1, &dimid[1],
"layer depth",
"km", 0, 0);
11596 NC_DEF_VAR(
"area", NC_DOUBLE, 1, &dimid[2],
"surface area",
"km**2", 0, 0);
11598 NC_DEF_VAR(
"cd", NC_FLOAT, 4, dimid,
"column density",
"kg m**-2",
11601 "volume mixing ratio (implicit)",
"ppv", ctl->
grid_nc_level, 0);
11602 NC_DEF_VAR(
"np", NC_INT, 4, dimid,
"number of particles",
"1", 0, 0);
11603 for (
int iq = 0; iq < ctl->
nq; iq++) {
11604 sprintf(varname,
"%s_mean", ctl->
qnt_name[iq]);
11605 sprintf(longname,
"%s (mean)", ctl->
qnt_longname[iq]);
11609 sprintf(varname,
"%s_stddev", ctl->
qnt_name[iq]);
11610 sprintf(longname,
"%s (stddev)", ctl->
qnt_longname[iq]);
11616 NC(nc_enddef(ncid));
11626 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
11627 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
11628 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
11633 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
11634 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
11635 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
11640 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
11641 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
11642 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
11647 for (
int iq = 0; iq < ctl->
nq; iq++) {
11648 sprintf(varname,
"%s_mean", ctl->
qnt_name[iq]);
11649 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
11650 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
11651 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
11658 for (
int iq = 0; iq < ctl->
nq; iq++) {
11659 sprintf(varname,
"%s_stddev", ctl->
qnt_name[iq]);
11660 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
11661 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
11662 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
11669 NC(nc_close(ncid));
11679 const char *filename,
11685 if (!(out = fopen(filename,
"w")))
11686 ERRMSG(
"Cannot create file!");
11783 const char *varname) {
11792 for (
int ix = 0; ix < met->
nx; ix++)
11793 for (
int iy = 0; iy < met->
ny; iy++)
11794 help[
ARRAY_2D(ix, iy, met->
ny)] = var[ix][iy];
11797 LOG(2,
"Write 2-D variable: %s (uncompressed)", varname);
11799 (
size_t) (met->
nx * met->
ny),
11813 const char *varname,
11814 const int precision,
11815 const double tolerance) {
11824#pragma omp parallel for default(shared) collapse(2)
11825 for (
int ix = 0; ix < met->
nx; ix++)
11826 for (
int iy = 0; iy < met->
ny; iy++)
11827 for (
int ip = 0; ip < met->
np; ip++)
11828 help[
ARRAY_3D(ix, iy, met->
ny, ip, met->
np)] = var[ix][iy][ip];
11832 LOG(2,
"Write 3-D variable: %s (uncompressed)", varname);
11834 (
size_t) (met->
nx * met->
ny * met->
np),
11841 (
size_t) met->
np, 0, out);
11849 FWRITE(&tolerance,
double,
11853 tolerance, 0, out);
11868 (
size_t) met->
np, 0, out);
11874 ERRMSG(
"MET_TYPE not supported!");
11875 LOG(3,
"%d %g", precision, tolerance);
11885 const char *filename,
11891 size_t start[4], count[4];
11892 nc_create(filename, NC_NETCDF4, &ncid);
11895 int tid, lonid, latid, levid;
11896 NC(nc_def_dim(ncid,
"time", 1, &tid));
11897 NC(nc_def_dim(ncid,
"lon", (
size_t) met->
nx, &lonid));
11898 NC(nc_def_dim(ncid,
"lat", (
size_t) met->
ny, &latid));
11899 NC(nc_def_dim(ncid,
"lev", (
size_t) met->
np, &levid));
11902 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"time",
11903 "seconds since 2000-01-01 00:00:00 UTC", 0, 0);
11904 NC_DEF_VAR(
"lon", NC_DOUBLE, 1, &lonid,
"longitude",
"degrees_east", 0, 0);
11905 NC_DEF_VAR(
"lat", NC_DOUBLE, 1, &latid,
"latitude",
"degrees_north", 0, 0);
11906 NC_DEF_VAR(
"lev", NC_DOUBLE, 1, &levid,
"pressure",
"Pa", 0, 0);
11909 int dimid2[2] = { latid, lonid };
11910 NC_DEF_VAR(
"sp", NC_FLOAT, 2, dimid2,
"Surface pressure",
"Pa",
11912 NC_DEF_VAR(
"z", NC_FLOAT, 2, dimid2,
"Geopotential",
"m**2 s**-2",
11914 NC_DEF_VAR(
"t2m", NC_FLOAT, 2, dimid2,
"2 metre temperature",
"K",
11916 NC_DEF_VAR(
"u10m", NC_FLOAT, 2, dimid2,
"10 metre U wind component",
11918 NC_DEF_VAR(
"v10m", NC_FLOAT, 2, dimid2,
"10 metre V wind component",
11921 "Instantaneous eastward turbulent surface stress",
"N m**-2",
11924 "Instantaneous northward turbulent surface stress",
"N m**-2",
11927 "Instantaneous surface sensible heat flux",
"W m**-1",
11929 NC_DEF_VAR(
"lsm", NC_FLOAT, 2, dimid2,
"Land/sea mask",
"-",
11931 NC_DEF_VAR(
"sstk", NC_FLOAT, 2, dimid2,
"Sea surface temperature",
"K",
11933 NC_DEF_VAR(
"blp", NC_FLOAT, 2, dimid2,
"Boundary layer pressure",
"Pa",
11935 NC_DEF_VAR(
"pt", NC_FLOAT, 2, dimid2,
"Tropopause pressure",
"Pa",
11937 NC_DEF_VAR(
"tt", NC_FLOAT, 2, dimid2,
"Tropopause temperature",
"K",
11939 NC_DEF_VAR(
"zt", NC_FLOAT, 2, dimid2,
"Tropopause height",
"m",
11941 NC_DEF_VAR(
"h2ot", NC_FLOAT, 2, dimid2,
"Tropopause water vapor",
"ppv",
11943 NC_DEF_VAR(
"pct", NC_FLOAT, 2, dimid2,
"Cloud top pressure",
"Pa",
11945 NC_DEF_VAR(
"pcb", NC_FLOAT, 2, dimid2,
"Cloud bottom pressure",
"Pa",
11947 NC_DEF_VAR(
"cl", NC_FLOAT, 2, dimid2,
"Total column cloud water",
11950 "Pressure at lifted condensation level (LCL)",
"Pa",
11953 "Pressure at level of free convection (LFC)",
"Pa",
11956 "Pressure at equilibrium level (EL)",
"Pa", ctl->
met_nc_level,
11959 "Convective available potential energy",
"J kg**-1",
11961 NC_DEF_VAR(
"cin", NC_FLOAT, 2, dimid2,
"Convective inhibition",
11963 NC_DEF_VAR(
"o3c", NC_FLOAT, 2, dimid2,
"Total column ozone",
"DU",
11967 int dimid3[3] = { levid, latid, lonid };
11968 NC_DEF_VAR(
"t", NC_FLOAT, 3, dimid3,
"Temperature",
"K",
11970 NC_DEF_VAR(
"u", NC_FLOAT, 3, dimid3,
"U velocity",
"m s**-1",
11972 NC_DEF_VAR(
"v", NC_FLOAT, 3, dimid3,
"V velocity",
"m s**-1",
11974 NC_DEF_VAR(
"w", NC_FLOAT, 3, dimid3,
"Vertical velocity",
"Pa s**-1",
11976 NC_DEF_VAR(
"q", NC_FLOAT, 3, dimid3,
"Specific humidity",
"kg kg**-1",
11978 NC_DEF_VAR(
"o3", NC_FLOAT, 3, dimid3,
"Ozone mass mixing ratio",
11980 NC_DEF_VAR(
"clwc", NC_FLOAT, 3, dimid3,
"Cloud liquid water content",
11982 NC_DEF_VAR(
"crwc", NC_FLOAT, 3, dimid3,
"Cloud rain water content",
11984 NC_DEF_VAR(
"ciwc", NC_FLOAT, 3, dimid3,
"Cloud ice water content",
11986 NC_DEF_VAR(
"cswc", NC_FLOAT, 3, dimid3,
"Cloud snow water content",
11988 NC_DEF_VAR(
"cc", NC_FLOAT, 3, dimid3,
"Cloud cover",
"-",
11992 NC(nc_enddef(ncid));
11999 for (
int ip = 0; ip < met->
np; ip++)
12000 phelp[ip] = 100. * met->
p[ip];
12043 NC(nc_close(ncid));
12050 const char *varname,
12056 size_t start[4], count[4];
12064 for (
int ix = 0; ix < met->
nx; ix++)
12065 for (
int iy = 0; iy < met->
ny; iy++)
12066 help[
ARRAY_2D(iy, ix, met->
nx)] = scl * var[ix][iy];
12079 const char *varname,
12085 size_t start[4], count[4];
12093 for (
int ix = 0; ix < met->
nx; ix++)
12094 for (
int iy = 0; iy < met->
ny; iy++)
12095 for (
int ip = 0; ip < met->
np; ip++)
12096 help[
ARRAY_3D(ip, iy, met->
ny, ix, met->
nx)] = scl * var[ix][iy][ip];
12108 const char *filename,
12117 static double *mass, *obsmean, *rt, *rz, *rlon, *rlat, *robs, *area,
12118 dz, dlon, dlat, *lon, *lat, *z, *press, temp, vmr, h2o, o3;
12120 static int nobs, *obscount, ip, okay;
12129 if (ctl->
qnt_m < 0)
12130 ERRMSG(
"Need quantity mass!");
12134 ERRMSG(
"Specify molar mass!");
12141 ALLOC(area,
double,
12145 ALLOC(press,
double,
12151 ALLOC(rlon,
double,
12153 ALLOC(rlat,
double,
12155 ALLOC(robs,
double,
12162 LOG(1,
"Write profile data: %s", filename);
12163 if (!(out = fopen(filename,
"w")))
12164 ERRMSG(
"Cannot create file!");
12168 "# $1 = time [s]\n"
12169 "# $2 = altitude [km]\n"
12170 "# $3 = longitude [deg]\n"
12171 "# $4 = latitude [deg]\n"
12172 "# $5 = pressure [hPa]\n"
12173 "# $6 = temperature [K]\n"
12174 "# $7 = volume mixing ratio [ppv]\n"
12175 "# $8 = H2O volume mixing ratio [ppv]\n"
12176 "# $9 = O3 volume mixing ratio [ppv]\n"
12177 "# $10 = observed BT index [K]\n"
12178 "# $11 = number of observations\n");
12186 for (
int iz = 0; iz < ctl->
prof_nz; iz++) {
12187 z[iz] = ctl->
prof_z0 + dz * (iz + 0.5);
12188 press[iz] =
P(z[iz]);
12192 for (
int ix = 0; ix < ctl->
prof_nx; ix++)
12193 lon[ix] = ctl->
prof_lon0 + dlon * (ix + 0.5);
12194 for (
int iy = 0; iy < ctl->
prof_ny; iy++) {
12195 lat[iy] = ctl->
prof_lat0 + dlat * (iy + 0.5);
12196 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat[iy]));
12201 const double t0 = t - 0.5 * ctl->
dt_mod;
12202 const double t1 = t + 0.5 * ctl->
dt_mod;
12205 ALLOC(mass,
double,
12207 ALLOC(obsmean,
double,
12209 ALLOC(obscount,
int,
12213 for (
int i = 0; i < nobs; i++) {
12218 else if (rt[i] >= t1)
12222 if (!isfinite(robs[i]))
12226 int ix = (int) ((rlon[i] - ctl->
prof_lon0) / dlon);
12227 int iy = (int) ((rlat[i] - ctl->
prof_lat0) / dlat);
12230 if (ix < 0 || ix >= ctl->
prof_nx || iy < 0 || iy >= ctl->
prof_ny)
12235 obsmean[idx] += robs[i];
12240 for (ip = 0; ip < atm->
np; ip++) {
12243 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
12247 int ix = (int) ((atm->
lon[ip] - ctl->
prof_lon0) / dlon);
12248 int iy = (int) ((atm->
lat[ip] - ctl->
prof_lat0) / dlat);
12249 int iz = (int) ((
Z(atm->
p[ip]) - ctl->
prof_z0) / dz);
12252 if (ix < 0 || ix >= ctl->
prof_nx ||
12258 mass[idx] += atm->
q[ctl->
qnt_m][ip];
12262 for (
int ix = 0; ix < ctl->
prof_nx; ix++)
12263 for (
int iy = 0; iy < ctl->
prof_ny; iy++) {
12265 if (obscount[idx2] > 0) {
12269 for (
int iz = 0; iz < ctl->
prof_nz; iz++) {
12271 if (mass[idx3] > 0) {
12280 fprintf(out,
"\n");
12283 for (
int iz = 0; iz < ctl->
prof_nz; iz++) {
12288 lon[ix], lat[iy], &temp, ci, cw, 1);
12290 lon[ix], lat[iy], &h2o, ci, cw, 0);
12292 lon[ix], lat[iy], &o3, ci, cw, 0);
12297 / (
RHO(press[iz], temp) * area[iy] * dz * 1e9);
12300 fprintf(out,
"%.2f %g %g %g %g %g %g %g %g %g %d\n",
12301 t, z[iz], lon[ix], lat[iy], press[iz], temp, vmr, h2o, o3,
12302 obsmean[idx2] / obscount[idx2], obscount[idx2]);
12335 const char *filename,
12344 static double area, dlat, rmax2, *rt, *rz, *rlon, *rlat, *robs, kz[
EP],
12347 static int nobs, nk;
12360 ALLOC(rlon,
double,
12362 ALLOC(rlat,
double,
12364 ALLOC(robs,
double,
12375 LOG(1,
"Write sample data: %s", filename);
12376 if (!(out = fopen(filename,
"w")))
12377 ERRMSG(
"Cannot create file!");
12381 "# $1 = time [s]\n"
12382 "# $2 = altitude [km]\n"
12383 "# $3 = longitude [deg]\n"
12384 "# $4 = latitude [deg]\n"
12385 "# $5 = surface area [km^2]\n"
12386 "# $6 = layer depth [km]\n"
12387 "# $7 = number of particles [1]\n"
12388 "# $8 = column density [kg/m^2]\n"
12389 "# $9 = volume mixing ratio [ppv]\n"
12390 "# $10 = observed BT index [K]\n\n");
12395 area = M_PI * rmax2;
12399 const double t0 = t - 0.5 * ctl->
dt_mod;
12400 const double t1 = t + 0.5 * ctl->
dt_mod;
12403 for (
int i = 0; i < nobs; i++) {
12408 else if (rt[i] >= t1)
12413 geo2cart(0, rlon[i], rlat[i], x0);
12416 const double rp =
P(rz[i]);
12417 const double ptop =
P(rz[i] + ctl->
sample_dz);
12418 const double pbot =
P(rz[i] - ctl->
sample_dz);
12426 for (
int ip = 0; ip < atm->
np; ip++) {
12429 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
12433 if (fabs(rlat[i] - atm->
lat[ip]) > dlat)
12439 if (
DIST2(x0, x1) > rmax2)
12444 if (atm->
p[ip] > pbot || atm->
p[ip] < ptop)
12448 if (ctl->
qnt_m >= 0)
12455 const double cd = mass / (1e6 * area);
12466 rlon[i], rlat[i], &temp, ci, cw, 1);
12475 fprintf(out,
"%.2f %g %g %g %g %g %d %g %g %g\n", rt[i], rz[i],
12476 rlon[i], rlat[i], area, ctl->
sample_dz, np, cd, vmr, robs[i]);
12497 const char *filename,
12504 static double rmax2, x0[3], x1[3];
12513 LOG(1,
"Write station data: %s", filename);
12516 if (!(out = fopen(filename,
"w")))
12517 ERRMSG(
"Cannot create file!");
12521 "# $1 = time [s]\n"
12522 "# $2 = altitude [km]\n"
12523 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
12524 for (
int iq = 0; iq < ctl->
nq; iq++)
12525 fprintf(out,
"# $%i = %s [%s]\n", (iq + 5),
12527 fprintf(out,
"\n");
12535 const double t0 = t - 0.5 * ctl->
dt_mod;
12536 const double t1 = t + 0.5 * ctl->
dt_mod;
12539 for (
int ip = 0; ip < atm->
np; ip++) {
12542 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
12558 if (
DIST2(x0, x1) > rmax2)
12566 fprintf(out,
"%.2f %g %g %g",
12567 atm->
time[ip],
Z(atm->
p[ip]), atm->
lon[ip], atm->
lat[ip]);
12568 for (
int iq = 0; iq < ctl->
nq; iq++) {
12570 fprintf(out, ctl->
qnt_format[iq], atm->
q[iq][ip]);
12572 fprintf(out,
"\n");
12583 const char *filename,
12594 LOG(1,
"Write VTK data: %s", filename);
12597 const double t0 = t - 0.5 * ctl->
dt_mod;
12598 const double t1 = t + 0.5 * ctl->
dt_mod;
12601 if (!(out = fopen(filename,
"w")))
12602 ERRMSG(
"Cannot create file!");
12606 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
12607 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
12614 "# vtk DataFile Version 3.0\n"
12615 "vtk output\n" "ASCII\n" "DATASET POLYDATA\n");
12618 fprintf(out,
"POINTS %d float\n", np);
12620 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
12621 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
12625 const double coslat = cos(
DEG2RAD(atm->
lat[ip]));
12626 const double x = radius * coslat * cos(
DEG2RAD(atm->
lon[ip]));
12627 const double y = radius * coslat * sin(
DEG2RAD(atm->
lon[ip]));
12628 const double z = radius * sin(
DEG2RAD(atm->
lat[ip]));
12629 fprintf(out,
"%g %g %g\n", x, y, z);
12632 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
12633 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
12635 fprintf(out,
"%g %g %g\n", atm->
lon[ip], atm->
lat[ip],
12640 fprintf(out,
"POINT_DATA %d\n", np);
12641 for (
int iq = 0; iq < ctl->
nq; iq++) {
12642 fprintf(out,
"SCALARS %s float 1\n" "LOOKUP_TABLE default\n",
12644 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
12645 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
12647 fprintf(out,
"%g\n", atm->
q[iq][ip]);
void read_met_geopot(const ctl_t *ctl, met_t *met)
Calculates geopotential heights from meteorological data.
void mptrac_write_atm(const char *filename, const ctl_t *ctl, const atm_t *atm, const double t)
Writes air parcel data to a file in various formats.
void day2doy(const int year, const int mon, const int day, int *doy)
Get day of year from date.
void read_met_extrapolate(met_t *met)
Extrapolates meteorological data.
void read_met_levels(const int ncid, const ctl_t *ctl, met_t *met)
Reads meteorological variables at different vertical levels from a NetCDF file.
int read_met_nc(const char *filename, const ctl_t *ctl, const clim_t *clim, met_t *met)
Reads meteorological data from a NetCDF file and processes it.
void write_atm_clams_traj(const char *dirname, const ctl_t *ctl, const atm_t *atm, const double t)
Writes CLaMS trajectory data to a NetCDF file.
void write_met_nc_2d(const int ncid, const char *varname, met_t *met, float var[EX][EY], const float scl)
Writes a 2D meteorological variable to a NetCDF file.
void mptrac_alloc(ctl_t **ctl, cache_t **cache, clim_t **clim, met_t **met0, met_t **met1, atm_t **atm)
Allocates and initializes memory resources for MPTRAC.
void read_met_sample(const ctl_t *ctl, met_t *met)
Downsamples meteorological data based on specified parameters.
void write_met_bin_3d(FILE *out, const ctl_t *ctl, met_t *met, float var[EX][EY][EP], const char *varname, const int precision, const double tolerance)
Writes a 3-dimensional meteorological variable to a binary file.
void read_obs(const char *filename, const ctl_t *ctl, double *rt, double *rz, double *rlon, double *rlat, double *robs, int *nobs)
Reads observation data from a file and stores it in arrays.
void module_advect(const ctl_t *ctl, const cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Advances particle positions using different advection schemes.
void module_timesteps(const ctl_t *ctl, cache_t *cache, met_t *met0, atm_t *atm, const double t)
Calculate time steps for air parcels based on specified conditions.
int mptrac_read_met(const char *filename, const ctl_t *ctl, const clim_t *clim, met_t *met)
Reads meteorological data from a file, supporting multiple formats and MPI broadcasting.
void module_meteo(const ctl_t *ctl, const cache_t *cache, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Update atmospheric properties using meteorological data.
void read_clim_photo(const char *filename, clim_photo_t *photo)
Reads photolysis rates from a NetCDF file and populates the given photolysis structure.
void read_met_cloud(met_t *met)
Calculates cloud-related variables for each grid point.
void module_decay(const ctl_t *ctl, const cache_t *cache, const clim_t *clim, atm_t *atm)
Simulate exponential decay processes for atmospheric particles.
double sedi(const double p, const double T, const double rp, const double rhop)
Calculates the sedimentation velocity of a particle in air.
void intpol_met_space_2d(const met_t *met, float array[EX][EY], const double lon, const double lat, double *var, int *ci, double *cw, const int init)
Interpolates meteorological variables in 2D space.
int read_atm_nc(const char *filename, const ctl_t *ctl, atm_t *atm)
Reads air parcel data from a generic netCDF file and populates the given atmospheric structure.
void write_csi_ens(const char *filename, const ctl_t *ctl, const atm_t *atm, const double t)
Writes ensemble-based Critical Success Index (CSI) and other verification statistics to an output fil...
void read_met_pbl(const ctl_t *ctl, met_t *met)
Computes the planetary boundary layer (PBL) pressure based on meteorological data.
void read_met_detrend(const ctl_t *ctl, met_t *met)
Detrends meteorological data.
int read_met_nc_2d(const int ncid, const char *varname, const char *varname2, const char *varname3, const char *varname4, const char *varname5, const char *varname6, const ctl_t *ctl, const met_t *met, float dest[EX][EY], const float scl, const int init)
Reads a 2-dimensional meteorological variable from a NetCDF file.
void read_met_tropo(const ctl_t *ctl, const clim_t *clim, met_t *met)
Reads surface meteorological data from a grib file and stores it in the meteorological data structure...
void read_obs_asc(const char *filename, double *rt, double *rz, double *rlon, double *rlat, double *robs, int *nobs)
Reads observation data from an ASCII file.
void module_chem_init(const ctl_t *ctl, const cache_t *cache, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Initializes the chemistry modules by setting atmospheric composition.
int locate_reg(const double *xx, const int n, const double x)
Locate the index of the interval containing a given value in a regular grid.
void get_tropo(const int met_tropo, ctl_t *ctl, clim_t *clim, met_t *met, const double *lons, const int nx, const double *lats, const int ny, double *pt, double *zt, double *tt, double *qt, double *o3t, double *ps, double *zs)
Calculate tropopause data.
void mptrac_get_met(ctl_t *ctl, clim_t *clim, const double t, met_t **met0, met_t **met1)
Retrieves meteorological data for the specified time.
void read_met_monotonize(const ctl_t *ctl, met_t *met)
Makes zeta and pressure profiles monotone.
int read_clim_ts(const char *filename, clim_ts_t *ts)
Reads a climatological time series from a file and populates the given time series structure.
void read_met_periodic(met_t *met)
Applies periodic boundary conditions to meteorological data along longitudinal axis.
void module_chem_grid_ens(const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, const double tt)
Processes atmospheric ensemble chemical data on a defined 3D grid.
void module_timesteps_init(ctl_t *ctl, const atm_t *atm)
Initialize start time and time interval for time-stepping.
void write_ens(const char *filename, const ctl_t *ctl, const atm_t *atm, const double t)
Writes ensemble data to a file.
void module_mixing(const ctl_t *ctl, const clim_t *clim, atm_t *atm, const double t)
Update atmospheric properties through interparcel mixing.
double clim_zm(const clim_zm_t *zm, const double t, const double lat, const double p)
Interpolates monthly mean zonal mean climatological variables.
void read_clim_photo_help(const int ncid, const char *varname, const clim_photo_t *photo, double var[CP][CSZA][CO3])
Reads a 3D climatological photochemistry variable from a NetCDF file.
void read_met_ml2pl(const ctl_t *ctl, const met_t *met, float var[EX][EY][EP], const char *varname)
Reads meteorological variables at different vertical levels from a grib file.
double clim_tropo(const clim_t *clim, const double t, const double lat)
Calculates the tropopause pressure based on climatological data.
void read_obs_nc(const char *filename, double *rt, double *rz, double *rlon, double *rlat, double *robs, int *nobs)
Reads observation data from a NetCDF file.
void read_met_grid(const char *filename, const int ncid, const ctl_t *ctl, met_t *met)
Reads meteorological grid information from a NetCDF file.
void read_met_bin_2d(FILE *in, const met_t *met, float var[EX][EY], const char *varname)
Reads a 2-dimensional meteorological variable from a binary file and stores it in the provided array.
int locate_irr(const double *xx, const int n, const double x)
Locate the index of the interval containing a given value in a sorted array.
void module_isosurf_init(const ctl_t *ctl, cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Initialize the isosurface module based on atmospheric data.
void level_definitions(ctl_t *ctl)
Defines pressure levels for meteorological data.
void intpol_met_4d_coord(const met_t *met0, float heights0[EX][EY][EP], float array0[EX][EY][EP], const met_t *met1, float heights1[EX][EY][EP], float array1[EX][EY][EP], const double ts, const double height, const double lon, const double lat, double *var, int *ci, double *cw, const int init)
Interpolates meteorological variables to a given position and time.
void module_mixing_help_ens(const ctl_t *ctl, const clim_t *clim, atm_t *atm, const int *ixs, const int *iys, const int *izs, const int qnt_idx)
Applies ensemble-based interparcel mixing for a given tracer quantity.
void write_grid_asc(const char *filename, const ctl_t *ctl, const double *cd, double *mean[NQ], double *sigma[NQ], const double *vmr_impl, const double t, const double *z, const double *lon, const double *lat, const double *area, const double dz, const int *np)
Writes grid data to an ASCII file.
void mptrac_update_device(const ctl_t *ctl, const cache_t *cache, const clim_t *clim, met_t **met0, met_t **met1, const atm_t *atm)
Updates device memory for specified data structures.
void time2jsec(const int year, const int mon, const int day, const int hour, const int min, const int sec, const double remain, double *jsec)
Converts time components to seconds since January 1, 2000, 12:00:00 UTC.
void mptrac_init(ctl_t *ctl, cache_t *cache, clim_t *clim, atm_t *atm, const int ntask)
Initializes the MPTRAC model and its associated components.
void intpol_met_time_3d(const met_t *met0, float array0[EX][EY][EP], const met_t *met1, float array1[EX][EY][EP], const double ts, const double p, const double lon, const double lat, double *var, int *ci, double *cw, const int init)
Interpolates meteorological data in 3D space and time.
void intpol_met_space_3d_ml(const met_t *met, float zs[EX][EY][EP], float array[EX][EY][EP], const double z, const double lon, const double lat, double *var)
Interpolates meteorological data in 3D space.
void fft_help(double *fcReal, double *fcImag, const int n)
Computes the Fast Fourier Transform (FFT) of a complex sequence.
void module_wet_depo(const ctl_t *ctl, const cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Perform wet deposition calculations for air parcels.
void compress_pck(const char *varname, float *array, const size_t nxy, const size_t nz, const int decompress, FILE *inout)
Compresses or decompresses a 3D array of floats.
double nat_temperature(const double p, const double h2o, const double hno3)
Calculates the nitric acid trihydrate (NAT) temperature.
void spline(const double *x, const double *y, const int n, const double *x2, double *y2, const int n2, const int method)
Performs spline interpolation or linear interpolation.
void module_chem_grid(const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, const double tt)
Calculate grid data for chemistry modules.
double clim_photo(const double rate[CP][CSZA][CO3], const clim_photo_t *photo, const double p, const double sza, const double o3c)
Calculates the photolysis rate for a given set of atmospheric conditions.
void read_clim_zm(const char *filename, const char *varname, clim_zm_t *zm)
Reads zonally averaged climatological data from a netCDF file and populates the given structure.
void module_sedi(const ctl_t *ctl, const cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Simulate sedimentation of particles in the atmosphere.
void timer(const char *name, const char *group, const int output)
Measures and reports elapsed time for named and grouped timers.
void write_atm_asc(const char *filename, const ctl_t *ctl, const atm_t *atm, const double t)
Writes air parcel data to an ASCII file or gnuplot.
void intpol_met_space_3d(const met_t *met, float array[EX][EY][EP], const double p, const double lon, const double lat, double *var, int *ci, double *cw, const int init)
Interpolates meteorological variables in 3D space.
void read_met_surface(const int ncid, const ctl_t *ctl, met_t *met)
Reads surface meteorological data from a netCDF file and stores it in the meteorological data structu...
void intpol_met_time_3d_ml(const met_t *met0, float zs0[EX][EY][EP], float array0[EX][EY][EP], const met_t *met1, float zs1[EX][EY][EP], float array1[EX][EY][EP], const double ts, const double p, const double lon, const double lat, double *var)
Interpolates meteorological data in both space and time.
void module_convection(const ctl_t *ctl, cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Performs convective mixing of atmospheric particles.
void read_kernel(const char *filename, double kz[EP], double kw[EP], int *nk)
Reads kernel function data from a file and populates the provided arrays.
void module_bound_cond(const ctl_t *ctl, const cache_t *cache, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Apply boundary conditions to particles based on meteorological and climatological data.
double scan_ctl(const char *filename, int argc, char *argv[], const char *varname, const int arridx, const char *defvalue, char *value)
Scans a control file or command-line arguments for a specified variable.
void module_advect_init(const ctl_t *ctl, const cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Initializes the advection module by setting up pressure fields.
void module_sort_help(double *a, const int *p, const int np)
Reorder an array based on a given permutation.
float stddev(const float *data, const int n)
Calculates the standard deviation of a set of data.
void intpol_tropo_3d(const double time0, float array0[EX][EY], const double time1, float array1[EX][EY], const double lons[EX], const double lats[EY], const int nlon, const int nlat, const double time, const double lon, const double lat, const int method, double *var, double *sigma)
Interpolates tropopause data in 3D (latitude, longitude, and time).
int read_met_nc_3d(const int ncid, const char *varname, const char *varname2, const char *varname3, const char *varname4, const ctl_t *ctl, const met_t *met, float dest[EX][EY][EP], const float scl)
Reads a 3-dimensional meteorological variable from a NetCDF file.
void read_met_bin_3d(FILE *in, const ctl_t *ctl, const met_t *met, float var[EX][EY][EP], const char *varname, const float bound_min, const float bound_max)
Reads 3D meteorological data from a binary file, potentially using different compression methods.
int locate_irr_float(const float *xx, const int n, const double x, const int ig)
Locate the index of the interval containing a given value in an irregularly spaced array.
double time_from_filename(const char *filename, const int offset)
Extracts and converts a timestamp from a filename to Julian seconds.
void write_prof(const char *filename, const ctl_t *ctl, met_t *met0, met_t *met1, const atm_t *atm, const double t)
Writes profile data to a specified file.
void mptrac_read_clim(const ctl_t *ctl, clim_t *clim)
Reads various climatological data and populates the given climatology structure.
double tropo_weight(const clim_t *clim, const atm_t *atm, const int ip)
Computes a weighting factor based on tropopause pressure.
void write_met_nc(const char *filename, const ctl_t *ctl, met_t *met)
Writes meteorological data to a NetCDF file.
void module_rng_init(const int ntask)
Initialize random number generators for parallel tasks.
int mptrac_read_atm(const char *filename, const ctl_t *ctl, atm_t *atm)
Reads air parcel data from a specified file into the given atmospheric structure.
void mptrac_update_host(const ctl_t *ctl, const cache_t *cache, const clim_t *clim, met_t **met0, met_t **met1, const atm_t *atm)
Updates host memory for specified data structures.
void mptrac_write_output(const char *dirname, const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, const double t)
Writes various types of output data to files in a specified directory.
double clim_oh(const ctl_t *ctl, const clim_t *clim, const double t, const double lon, const double lat, const double p)
Calculates the hydroxyl radical (OH) concentration from climatology data, with an optional diurnal co...
void read_met_ozone(met_t *met)
Calculates the total column ozone from meteorological ozone data.
void mptrac_free(ctl_t *ctl, cache_t *cache, clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Frees memory resources allocated for MPTRAC.
void clim_tropo_init(clim_t *clim)
Initializes the tropopause data in the climatology structure.
void module_rng(const ctl_t *ctl, double *rs, const size_t n, const int method)
Generate random numbers using various methods and distributions.
void get_met_help(const ctl_t *ctl, const double t, const int direct, const char *metbase, const double dt_met, char *filename)
Generates a formatted filename for meteorological data files based on the input parameters.
void write_station(const char *filename, const ctl_t *ctl, atm_t *atm, const double t)
Writes station data to a specified file.
void cart2geo(const double *x, double *z, double *lon, double *lat)
State variables of cuRAND random number generator.
double sza_calc(const double sec, const double lon, const double lat)
Calculates the solar zenith angle.
void module_mixing_help(const ctl_t *ctl, const clim_t *clim, atm_t *atm, const int *ixs, const int *iys, const int *izs, const int qnt_idx)
Perform interparcel mixing for a specific quantity.
void doy2day(const int year, const int doy, int *mon, int *day)
Converts a given day of the year (DOY) to a date (month and day).
void intpol_met_time_2d(const met_t *met0, float array0[EX][EY], const met_t *met1, float array1[EX][EY], const double ts, const double lon, const double lat, double *var, int *ci, double *cw, const int init)
Interpolates meteorological data in 2D space and time.
void module_position(const cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Update the positions and pressure levels of atmospheric particles.
void clim_oh_diurnal_correction(const ctl_t *ctl, clim_t *clim)
Applies a diurnal correction to the hydroxyl radical (OH) concentration in climatology data.
void locate_vert(float profiles[EX][EY][EP], const int np, const int lon_ap_ind, const int lat_ap_ind, const double height_ap, int *ind)
Locate the four vertical indizes of a box for a given height value.
void write_met_bin_2d(FILE *out, met_t *met, float var[EX][EY], const char *varname)
Writes a 2-dimensional meteorological variable to a binary file.
void read_met_pv(met_t *met)
Calculates potential vorticity (PV) from meteorological data.
int read_atm_bin(const char *filename, const ctl_t *ctl, atm_t *atm)
Reads air parcel data from a binary file and populates the given atmospheric structure.
void get_met_replace(char *orig, char *search, char *repl)
Replaces occurrences of a substring in a string with another substring.
void module_diff_meso(const ctl_t *ctl, cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Simulate mesoscale diffusion for atmospheric particles.
void module_sort(const ctl_t *ctl, met_t *met0, atm_t *atm)
Sort particles according to box index.
double clim_ts(const clim_ts_t *ts, const double t)
Interpolates a time series of climatological variables.
void jsec2time(const double jsec, int *year, int *mon, int *day, int *hour, int *min, int *sec, double *remain)
Converts Julian seconds to calendar date and time components.
int read_met_bin(const char *filename, const ctl_t *ctl, met_t *met)
Reads meteorological data from a binary file.
void mptrac_run_timestep(ctl_t *ctl, cache_t *cache, clim_t *clim, met_t **met0, met_t **met1, atm_t *atm, double t)
Executes a single timestep of the MPTRAC model simulation.
void write_atm_clams(const char *filename, const ctl_t *ctl, const atm_t *atm)
Writes air parcel data to a NetCDF file in the CLaMS format.
void module_diff_turb(const ctl_t *ctl, cache_t *cache, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Applies turbulent diffusion processes to atmospheric particles.
int read_atm_clams(const char *filename, const ctl_t *ctl, atm_t *atm)
Reads atmospheric data from a CLAMS NetCDF file.
void write_vtk(const char *filename, const ctl_t *ctl, const atm_t *atm, const double t)
Writes VTK (Visualization Toolkit) data to a specified file.
void module_tracer_chem(const ctl_t *ctl, const cache_t *cache, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Simulate chemical reactions involving long-lived atmospheric tracers.
void mptrac_read_ctl(const char *filename, int argc, char *argv[], ctl_t *ctl)
Reads control parameters from a configuration file and populates the given structure.
void read_met_polar_winds(met_t *met)
Applies a fix for polar winds in meteorological data.
void module_h2o2_chem(const ctl_t *ctl, const cache_t *cache, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Perform chemical reactions involving H2O2 within cloud particles.
void write_grid_nc(const char *filename, const ctl_t *ctl, const double *cd, double *mean[NQ], double *sigma[NQ], const double *vmr_impl, const double t, const double *z, const double *lon, const double *lat, const double *area, const double dz, const int *np)
Writes grid data to a NetCDF file.
double pbl_weight(const ctl_t *ctl, const atm_t *atm, const int ip, const double pbl, const double ps)
Computes a weighting factor based on planetary boundary layer pressure.
void module_diff_pbl(const ctl_t *ctl, cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Computes particle diffusion within the planetary boundary layer (PBL).
void write_met_nc_3d(const int ncid, const char *varname, met_t *met, float var[EX][EY][EP], const float scl)
Writes a 3D meteorological variable to a NetCDF file.
void module_isosurf(const ctl_t *ctl, const cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Apply the isosurface module to adjust atmospheric properties.
void module_oh_chem(const ctl_t *ctl, const cache_t *cache, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Perform hydroxyl chemistry calculations for atmospheric particles.
void geo2cart(const double z, const double lon, const double lat, double *x)
Converts geographic coordinates (longitude, latitude, altitude) to Cartesian coordinates.
double kernel_weight(const double kz[EP], const double kw[EP], const int nk, const double p)
Calculates the kernel weight based on altitude and given kernel data.
int read_atm_asc(const char *filename, const ctl_t *ctl, atm_t *atm)
Reads air parcel data from an ASCII file and populates the given atmospheric structure.
void intpol_check_lon_lat(const double *lons, const int nlon, const double *lats, const int nlat, const double lon, const double lat, double *lon2, double *lat2)
Adjusts longitude and latitude to ensure they fall within valid bounds.
void write_sample(const char *filename, const ctl_t *ctl, met_t *met0, met_t *met1, const atm_t *atm, const double t)
Writes sample data to a specified file.
void write_grid(const char *filename, const ctl_t *ctl, met_t *met0, met_t *met1, const atm_t *atm, const double t)
Writes grid data to a file in ASCII or netCDF format.
void module_dry_depo(const ctl_t *ctl, const cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Simulate dry deposition of atmospheric particles.
void write_met_bin(const char *filename, const ctl_t *ctl, met_t *met)
Writes meteorological data in binary format to a specified file.
void write_atm_bin(const char *filename, const ctl_t *ctl, const atm_t *atm)
Writes air parcel data to a binary file.
void read_met_cape(const ctl_t *ctl, const clim_t *clim, met_t *met)
Calculates Convective Available Potential Energy (CAPE) for each grid point.
void mptrac_write_met(const char *filename, const ctl_t *ctl, met_t *met)
Writes meteorological data to a file, supporting multiple formats and compression options.
double lapse_rate(const double t, const double h2o)
Calculates the moist adiabatic lapse rate in Kelvin per kilometer.
void write_csi(const char *filename, const ctl_t *ctl, const atm_t *atm, const double t)
Writes Critical Success Index (CSI) data to a file.
void write_atm_nc(const char *filename, const ctl_t *ctl, const atm_t *atm)
Writes air parcel data to a NetCDF file.
MPTRAC library declarations.
#define NN(x0, y0, x1, y1, x)
Perform nearest-neighbor interpolation.
void compress_zstd(const char *varname, float *array, const size_t n, const int decompress, const int level, FILE *inout)
Compresses or decompresses a float array using Zstandard (ZSTD).
#define LEN
Maximum length of ASCII data lines.
#define RE
Mean radius of Earth [km].
#define TVIRT(t, h2o)
Compute virtual temperature.
#define ARRAY_3D(ix, iy, ny, iz, nz)
Compute the linear index of a 3D array element.
#define PARTICLE_LOOP(ip0, ip1, check_dt,...)
Loop over particle indices with OpenACC acceleration.
#define MA
Molar mass of dry air [g/mol].
#define AVO
Avogadro constant [1/mol].
#define KB
Boltzmann constant [kg m^2/(K s^2)].
#define MH2O
Molar mass of water vapor [g/mol].
#define NENS
Maximum number of data points for ensemble analysis.
#define FWRITE(ptr, type, size, out)
Write data from memory to a file stream.
#define PW(p, h2o)
Calculate partial water vapor pressure.
#define H0
Scale height [km].
#define NC_PUT_ATT_GLOBAL(attname, text)
Add a global text attribute to a NetCDF file.
#define MOLEC_DENS(p, t)
Calculate the density of a gas molecule.
#define LAPSE(p1, t1, p2, t2)
Calculate lapse rate.
#define NC(cmd)
Execute a NetCDF command and check for errors.
#define ECC_READ_3D(variable, level, target, scaling_factor, found_flag)
Writes 3D data from a grib message into the met struct.
#define RA
Specific gas constant of dry air [J/(kg K)].
int read_met_grib(const char *filename, const ctl_t *ctl, const clim_t *clim, met_t *met)
Reads global meteorological information from a grib file.
#define KARMAN
Karman's constant.
#define INTPOL_INIT
Initialize arrays for interpolation.
#define MIN(a, b)
Macro to determine the minimum of two values.
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
#define NC_PUT_INT(varname, ptr, hyperslab)
Write integer data to a NetCDF variable.
void compress_cms(const ctl_t *ctl, const char *varname, float *array, const size_t nx, const size_t ny, const size_t np, const int decompress, FILE *inout)
Compresses or decompresses a 3D array of floats using a custom multiscale compression algorithm.
void compress_zfp(const char *varname, float *array, const int nx, const int ny, const int nz, const int precision, const double tolerance, const int decompress, FILE *inout)
Compresses or decompresses a 3D array of floats using the ZFP library.
#define EY
Maximum number of latitudes for meteo data.
#define SH(h2o)
Compute specific humidity from water vapor volume mixing ratio.
#define INTPOL_3D(var, init)
Perform 3D interpolation for a meteorological variable.
#define NOBS
Maximum number of observation data points.
#define NTHREADS
Maximum number of OpenMP threads.
#define ARRAY_2D(ix, iy, ny)
Macro for computing the linear index of a 2D array element.
#define Z(p)
Convert pressure to altitude.
#define P(z)
Compute pressure at given altitude.
#define LV
Latent heat of vaporization of water [J/kg].
#define G0
Standard gravity [m/s^2].
#define CP
Maximum number of pressure levels for climatological data.
#define NQ
Maximum number of quantities per data point.
#define FREAD(ptr, type, size, in)
Read data from a file stream and store it in memory.
#define DX2DEG(dx, lat)
Convert a distance in kilometers to degrees longitude at a given latitude.
#define DEG2DY(dlat)
Convert a latitude difference to a distance in the y-direction (north-south).
#define EX
Maximum number of longitudes for meteo data.
#define EPS
Ratio of the specific gas constant of dry air and water vapor [1].
#define PSICE(t)
Compute saturation pressure over ice (WMO, 2018).
#define THETA(p, t)
Compute potential temperature.
#define RI
Ideal gas constant [J/(mol K)].
#define NORM(a)
Compute the norm (magnitude) of a vector.
#define SET_QNT(qnt, name, longname, unit)
Set atmospheric quantity index.
#define TICE(p, h2o)
Calculate frost point temperature (WMO, 2018).
#define TOK(line, tok, format, var)
Get string tokens.
#define ZDIFF(lnp0, t0, h2o0, lnp1, t1, h2o1)
Calculate geopotential height difference.
#define THETAVIRT(p, t, h2o)
Compute virtual potential temperature.
#define DZ2DP(dz, p)
Convert a change in altitude to a change in pressure.
#define WARN(...)
Print a warning message with contextual information.
#define ZETA(ps, p, t)
Computes the value of the zeta vertical coordinate.
#define RHICE(p, t, h2o)
Compute relative humidity over ice.
#define INTPOL_TIME_ALL(time, p, lon, lat)
Interpolate multiple meteorological variables in time.
#define ALLOC(ptr, type, n)
Allocate memory for a pointer with error handling.
#define SET_ATM(qnt, val)
Set atmospheric quantity value.
#define CTS
Maximum number of data points of climatological time series.
#define ECC_READ_2D(variable, target, scaling_factor, found_flag)
Writes 2-D data from a grib message into the met struct.
#define DEG2RAD(deg)
Converts degrees to radians.
void broadcast_large_data(void *data, size_t N)
Broadcasts large data across all processes in an MPI communicator.
#define MO3
Molar mass of ozone [g/mol].
#define SQR(x)
Compute the square of a value.
#define RAD2DEG(rad)
Converts radians to degrees.
#define NC_INQ_DIM(dimname, ptr, min, max)
Inquire the length of a dimension in a NetCDF file.
#define NP
Maximum number of atmospheric data points.
#define NTIMER
Maximum number of timers.
#define SELECT_TIMER(id, group, color)
Select and start a timer with specific attributes.
#define INTPOL_2D(var, init)
Perform 2D interpolation for a meteorological variable.
#define RH(p, t, h2o)
Compute relative humidity over water.
#define NC_PUT_FLOAT(varname, ptr, hyperslab)
Write a float array to a NetCDF file.
#define CY
Maximum number of latitudes for climatological data.
#define LOG(level,...)
Print a log message with a specified logging level.
void thrustSortWrapper(double *__restrict__ c, int n, int *__restrict__ index)
Wrapper to Thrust sorting function.
#define NC_DEF_VAR(varname, type, ndims, dims, long_name, units, level, quant)
Define a NetCDF variable with attributes.
#define TDEW(p, h2o)
Calculate dew point temperature.
#define ARRHENIUS(a, b, t)
Calculate the Arrhenius rate constant.
#define NCSI
Maximum number of data points for CSI calculation.
#define NC_GET_DOUBLE(varname, ptr, force)
Retrieve a double-precision variable from a NetCDF file.
#define EP
Maximum number of pressure levels for meteo data.
#define PSAT(t)
Compute saturation pressure over water.
#define RHO(p, t)
Compute density of air.
void module_kpp_chem(ctl_t *ctl, cache_t *cache, clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
KPP chemistry module.
#define CO3
Maximum number of total column ozone data for climatological data.
#define NC_PUT_DOUBLE(varname, ptr, hyperslab)
Write double precision data to a NetCDF variable.
#define ECC(cmd)
Execute a ECCODES command and check for errors.
#define LIN(x0, y0, x1, y1, x)
Linear interpolation.
#define DIST2(a, b)
Calculate the squared Euclidean distance between two points in Cartesian coordinates.
#define DEG2DX(dlon, lat)
Convert a longitude difference to a distance in the x-direction (east-west) at a specific latitude.
#define CPD
Specific heat of dry air at constant pressure [J/(kg K)].
#define CSZA
Maximum number of solar zenith angles for climatological data.
#define DY2DEG(dy)
Convert a distance in kilometers to degrees latitude.
#define MAX(a, b)
Macro to determine the maximum of two values.
#define FMOD(x, y)
Calculate the floating-point remainder of dividing x by y.
double lat[NP]
Latitude [deg].
double lon[NP]
Longitude [deg].
int np
Number of air parcels.
double q[NQ][NP]
Quantity data (for various, user-defined attributes).
double p[NP]
Pressure [hPa].
double dt[NP]
Timesteps [s].
double iso_ts[NP]
Isosurface balloon time [s].
int iso_n
Isosurface balloon number of data points.
double iso_ps[NP]
Isosurface balloon pressure [hPa].
double rs[3 *NP+1]
Random numbers.
float uvwp[NP][3]
Wind perturbations [m/s].
double iso_var[NP]
Isosurface variables.
Climatological data in the form of photolysis rates.
int nsza
Number of solar zenith angles.
double sza[CSZA]
Solar zenith angle [rad].
double o3_1[CP][CSZA][CO3]
O3 photolysis rate (O3 + hv = O1d + O2) [1/s].
double p[CP]
Pressure [hPa].
double ccl2f2[CP][CSZA][CO3]
CCl2F2 photolysis rate [1/s].
double o2[CP][CSZA][CO3]
O2 photolysis rate [1/s].
double ccl3f[CP][CSZA][CO3]
CCl3F photolysis rate [1/s].
double n2o[CP][CSZA][CO3]
N2O photolysis rate [1/s].
double h2o2[CP][CSZA][CO3]
H2O2 photolysis rate [1/s].
double h2o[CP][CSZA][CO3]
H2O photolysis rate [1/s].
double ccl4[CP][CSZA][CO3]
CCl4 photolysis rate [1/s].
double o3_2[CP][CSZA][CO3]
O3 photolysis rate (O3 + hv = O3p + O2) [1/s].
double o3c[CO3]
Total column ozone [DU].
int np
Number of pressure levels.
int no3c
Number of total ozone columns.
clim_ts_t ccl2f2
CFC-12 time series.
clim_photo_t photo
Photolysis rates.
clim_zm_t ho2
HO2 zonal means.
clim_zm_t hno3
HNO3 zonal means.
int tropo_ntime
Number of tropopause timesteps.
clim_ts_t sf6
SF6 time series.
clim_ts_t ccl4
CFC-10 time series.
clim_ts_t ccl3f
CFC-11 time series.
clim_zm_t o1d
O(1D) zonal means.
double tropo_lat[73]
Tropopause latitudes [deg].
clim_zm_t h2o2
H2O2 zonal means.
int tropo_nlat
Number of tropopause latitudes.
clim_zm_t oh
OH zonal means.
double tropo[12][73]
Tropopause pressure values [hPa].
double tropo_time[12]
Tropopause time steps [s].
clim_ts_t n2o
N2O time series.
Climatological data in the form of time series.
double vmr[CTS]
Volume mixing ratio [ppv].
double time[CTS]
Time [s].
int ntime
Number of timesteps.
Climatological data in the form of zonal means.
int np
Number of pressure levels.
double p[CP]
Pressure [hPa].
double vmr[CT][CP][CY]
Volume mixing ratio [ppv].
int ntime
Number of timesteps.
int nlat
Number of latitudes.
double lat[CY]
Latitude [deg].
double grid_z0
Lower altitude of gridded data [km].
int qnt_o3
Quantity array index for ozone volume mixing ratio.
double csi_lat1
Upper latitude of gridded CSI data [deg].
char csi_obsfile[LEN]
Observation data file for CSI analysis.
int qnt_Coh
Quantity array index for OH volume mixing ratio (chemistry code).
double wet_depo_ic_a
Coefficient A for wet deposition in cloud (exponential form).
int met_nc_scale
Check netCDF scaling factors (0=no, 1=yes).
int qnt_pel
Quantity array index for pressure at equilibrium level (EL).
int csi_nz
Number of altitudes of gridded CSI data.
double molmass
Molar mass [g/mol].
int qnt_p
Quantity array index for pressure.
int qnt_Cccl2f2
Quantity array index for CFC-12 volume mixing ratio (chemistry code).
char atm_gpfile[LEN]
Gnuplot file for atmospheric data.
int mixing_nx
Number of longitudes of mixing grid.
double chemgrid_z1
Upper altitude of chemistry grid [km].
char qnt_format[NQ][LEN]
Quantity output format.
int qnt_m
Quantity array index for mass.
int qnt_aoa
Quantity array index for age of air.
int qnt_rhop
Quantity array index for particle density.
int qnt_swc
Quantity array index for cloud snow water content.
double csi_obsmin
Minimum observation index to trigger detection.
int qnt_pcb
Quantity array index for cloud bottom pressure.
char clim_n2o_timeseries[LEN]
Filename of N2O time series.
double bound_dzs
Boundary conditions surface layer depth [km].
double csi_lon1
Upper longitude of gridded CSI data [deg].
int qnt_u
Quantity array index for zonal wind.
double stat_lon
Longitude of station [deg].
double mixing_trop
Interparcel exchange parameter for mixing in the troposphere.
double sort_dt
Time step for sorting of particle data [s].
double mixing_z1
Upper altitude of mixing grid [km].
double stat_r
Search radius around station [km].
double wet_depo_bc_a
Coefficient A for wet deposition below cloud (exponential form).
int met_zstd_level
ZSTD compression level (from -5 to 22).
int csi_ny
Number of latitudes of gridded CSI data.
int vtk_sphere
Spherical projection for VTK data (0=no, 1=yes).
double chemgrid_z0
Lower altitude of chemistry grid [km].
double met_pbl_min
Minimum depth of planetary boundary layer [km].
int qnt_iwc
Quantity array index for cloud ice water content.
double chemgrid_lat0
Lower latitude of chemistry grid [deg].
double conv_cape
CAPE threshold for convection module [J/kg].
int qnt_Co1d
Quantity array index for O(1D) volume mixing ratio (chemistry code).
double met_cms_eps_pv
cmultiscale compression epsilon for potential vorticity.
int qnt_pw
Quantity array index for partial water vapor pressure.
char prof_basename[LEN]
Basename for profile output file.
double grid_z1
Upper altitude of gridded data [km].
int direction
Direction flag (1=forward calculation, -1=backward calculation).
char balloon[LEN]
Balloon position filename.
int qnt_Cccl4
Quantity array index for CFC-10 volume mixing ratio (chemistry code).
int met_dp
Stride for pressure levels.
double met_dt_out
Time step for sampling of meteo data along trajectories [s].
int qnt_h2o2
Quantity array index for H2O2 volume mixing ratio (climatology).
int qnt_vh
Quantity array index for horizontal wind.
char species[LEN]
Species.
int csi_nx
Number of longitudes of gridded CSI data.
double csi_lat0
Lower latitude of gridded CSI data [deg].
double turb_dz_trop
Vertical turbulent diffusion coefficient (troposphere) [m^2/s].
int met_pbl
Planetary boundary layer data (0=file, 1=z2p, 2=Richardson, 3=theta).
int qnt_lwc
Quantity array index for cloud liquid water content.
double turb_mesoz
Vertical scaling factor for mesoscale wind fluctuations.
int grid_nc_level
zlib compression level of netCDF grid data files (0=off).
int grid_nx
Number of longitudes of gridded data.
int atm_type
Type of atmospheric data files (0=ASCII, 1=binary, 2=netCDF, 3=CLaMS_traj, 4=CLaMS_pos).
double bound_mass
Boundary conditions mass per particle [kg].
double grid_lat0
Lower latitude of gridded data [deg].
int qnt_ts
Quantity array index for surface temperature.
int qnt_loss_rate
Quantity array index for total loss rate.
double met_cms_eps_h2o
cmultiscale compression epsilon for water vapor.
int qnt_plfc
Quantity array index for pressure at level of free convection (LCF).
double grid_lon0
Lower longitude of gridded data [deg].
int qnt_o1d
Quantity array index for O(1D) volume mixing ratio (climatology).
int met_tropo_spline
Tropopause interpolation method (0=linear, 1=spline).
char sample_kernel[LEN]
Kernel data file for sample output.
int qnt_tvirt
Quantity array index for virtual temperature.
double dt_met
Time step of meteo data [s].
char clim_ho2_filename[LEN]
Filename of HO2 climatology.
double chemgrid_lat1
Upper latitude of chemistry grid [deg].
int met_geopot_sy
Latitudinal smoothing of geopotential heights.
char grid_gpfile[LEN]
Gnuplot file for gridded data.
double met_cms_eps_u
cmultiscale compression epsilon for zonal wind.
double turb_dx_strat
Horizontal turbulent diffusion coefficient (stratosphere) [m^2/s].
int qnt_vmr
Quantity array index for volume mixing ratio.
int qnt_lsm
Quantity array index for land-sea mask.
int qnt_theta
Quantity array index for potential temperature.
double bound_lat1
Boundary conditions maximum longitude [deg].
double stat_t1
Stop time for station output [s].
char csi_kernel[LEN]
Kernel data file for CSI output.
double turb_dx_trop
Horizontal turbulent diffusion coefficient (troposphere) [m^2/s].
int grid_type
Type of grid data files (0=ASCII, 1=netCDF).
double csi_lon0
Lower longitude of gridded CSI data [deg].
int qnt_pbl
Quantity array index for boundary layer pressure.
double oh_chem[4]
Coefficients for OH reaction rate (A, E/R or k0, n, kinf, m).
int grid_stddev
Include standard deviations in grid output (0=no, 1=yes).
int qnt_psice
Quantity array index for saturation pressure over ice.
double chemgrid_lon0
Lower longitude of chemistry grid [deg].
int bound_pbl
Boundary conditions planetary boundary layer (0=no, 1=yes).
int qnt_mloss_wet
Quantity array index for total mass loss due to wet deposition.
int met_geopot_sx
Longitudinal smoothing of geopotential heights.
int met_sy
Smoothing for latitudes.
int qnt_ps
Quantity array index for surface pressure.
int rng_type
Random number generator (0=GSL, 1=Squares, 2=cuRAND).
char prof_obsfile[LEN]
Observation data file for profile output.
int isosurf
Isosurface parameter (0=none, 1=pressure, 2=density, 3=theta, 4=balloon).
double bound_p1
Boundary conditions top pressure [hPa].
int qnt_zs
Quantity array index for surface geopotential height.
int prof_nz
Number of altitudes of gridded profile data.
double csi_dt_out
Time step for CSI output [s].
int met_cape
Convective available potential energy data (0=file, 1=calculate).
double csi_modmin
Minimum column density to trigger detection [kg/m^2].
int met_sx
Smoothing for longitudes.
double chemgrid_lon1
Upper longitude of chemistry grid [deg].
double turb_mesox
Horizontal scaling factor for mesoscale wind fluctuations.
double met_cms_eps_iwc
cmultiscale compression epsilon for cloud ice water content.
double met_cms_eps_swc
cmultiscale compression epsilon for cloud snow water content.
char grid_kernel[LEN]
Kernel data file for grid output.
int met_zfp_prec
ZFP compression precision for all variables, except z and T.
double met_cms_eps_v
cmultiscale compression epsilon for meridional wind.
double prof_z0
Lower altitude of gridded profile data [km].
int qnt_w
Quantity array index for vertical velocity.
double bound_vmr
Boundary conditions volume mixing ratio [ppv].
double met_tropo_pv
Dynamical tropopause potential vorticity threshold [PVU].
int prof_nx
Number of longitudes of gridded profile data.
int qnt_stat
Quantity array index for station flag.
int met_tropo
Tropopause definition (0=none, 1=clim, 2=cold point, 3=WMO_1st, 4=WMO_2nd, 5=dynamical).
int qnt_rp
Quantity array index for particle radius.
int met_mpi_share
Use MPI to share meteo (0=no, 1=yes).
double mixing_strat
Interparcel exchange parameter for mixing in the stratosphere.
int qnt_vz
Quantity array index for vertical velocity.
int qnt_ho2
Quantity array index for HO2 volume mixing ratio (climatology).
double csi_z1
Upper altitude of gridded CSI data [km].
double stat_t0
Start time for station output [s].
double oh_chem_beta
Beta parameter for diurnal variablity of OH.
char clim_o1d_filename[LEN]
Filename of O(1D) climatology.
char clim_photo[LEN]
Filename of photolysis rates climatology.
double wet_depo_so2_ph
pH value used to calculate effective Henry constant of SO2.
double mixing_z0
Lower altitude of mixing grid [km].
int qnt_mloss_decay
Quantity array index for total mass loss due to exponential decay.
int atm_type_out
Type of atmospheric data files for output (-1=same as ATM_TYPE, 0=ASCII, 1=binary,...
int met_nlev
Number of meteo data model levels.
double dt_kpp
Time step for KPP chemistry [s].
char csi_basename[LEN]
Basename of CSI data files.
double dry_depo_dp
Dry deposition surface layer [hPa].
int qnt_shf
Quantity array index for surface sensible heat flux.
int qnt_vs
Quantity array index for surface meridional wind.
int qnt_Cco
Quantity array index for CO volume mixing ratio (chemistry code).
double vtk_dt_out
Time step for VTK data output [s].
double t_stop
Stop time of simulation [s].
double conv_dt
Time interval for convection module [s].
char sample_obsfile[LEN]
Observation data file for sample output.
int qnt_hno3
Quantity array index for HNO3 volume mixing ratio (climatology).
char grid_basename[LEN]
Basename of grid data files.
int met_clams
Read MPTRAC or CLaMS meteo data (0=MPTRAC, 1=CLaMS).
int qnt_h2ot
Quantity array index for tropopause water vapor volume mixing ratio.
int qnt_rh
Quantity array index for relative humidity over water.
double met_cms_eps_cc
cmultiscale compression epsilon for cloud cover.
double bound_lat0
Boundary conditions minimum longitude [deg].
double met_pbl_max
Maximum depth of planetary boundary layer [km].
int met_dx
Stride for longitudes.
int mixing_ny
Number of latitudes of mixing grid.
int met_convention
Meteo data layout (0=[lev, lat, lon], 1=[lon, lat, lev]).
int qnt_zeta_d
Quantity array index for diagnosed zeta vertical coordinate.
char clim_h2o2_filename[LEN]
Filename of H2O2 climatology.
int tracer_chem
Switch for first order tracer chemistry module (0=off, 1=on).
double dt_mod
Time step of simulation [s].
int diffusion
Diffusion scheme (0=off, 1=fixed-K, 2=PBL).
int qnt_tnat
Quantity array index for T_NAT.
int qnt_tice
Quantity array index for T_ice.
int qnt_zg
Quantity array index for geopotential height.
double vtk_offset
Vertical offset for VTK data [km].
int qnt_v
Quantity array index for meridional wind.
int qnt_mloss_dry
Quantity array index for total mass loss due to dry deposition.
double bound_vmr_trend
Boundary conditions volume mixing ratio trend [ppv/s].
int met_cache
Preload meteo data into disk cache (0=no, 1=yes).
int qnt_oh
Quantity array index for OH volume mixing ratio (climatology).
char qnt_unit[NQ][LEN]
Quantity units.
int qnt_Ch
Quantity array index for H volume mixing ratio (chemistry code).
int met_press_level_def
Use predefined pressure levels or not.
int oh_chem_reaction
Reaction type for OH chemistry (0=none, 2=bimolecular, 3=termolecular).
int qnt_h2o
Quantity array index for water vapor volume mixing ratio.
int prof_ny
Number of latitudes of gridded profile data.
int qnt_rhice
Quantity array index for relative humidity over ice.
int qnt_rho
Quantity array index for density of air.
double sample_dz
Layer depth for sample output [km].
double tdec_strat
Life time of particles in the stratosphere [s].
int obs_type
Type of observation data files (0=ASCII, 1=netCDF).
int grid_nc_quant[NQ]
Number of digits for quantization of netCDF grid data files (0=off).
double met_cms_eps_lwc
cmultiscale compression epsilon for cloud liquid water content.
int qnt_us
Quantity array index for surface zonal wind.
double met_cms_eps_z
cmultiscale compression epsilon for geopotential height.
double grid_lon1
Upper longitude of gridded data [deg].
int qnt_Cn2o
Quantity array index for N2O volume mixing ratio (chemistry code).
int qnt_Cccl3f
Quantity array index for CFC-11 volume mixing ratio (chemistry code).
char qnt_name[NQ][LEN]
Quantity names.
char atm_basename[LEN]
Basename of atmospheric data files.
double mixing_lat0
Lower latitude of mixing grid [deg].
int nens
Number of ensembles.
int qnt_pt
Quantity array index for tropopause pressure.
int qnt_cl
Quantity array index for total column cloud water.
int advect
Advection scheme (0=off, 1=Euler, 2=midpoint, 4=Runge-Kutta).
double prof_z1
Upper altitude of gridded profile data [km].
double met_lev_hyam[EP]
Meteo data model level a coefficients.
int qnt_t
Quantity array index for temperature.
int atm_filter
Time filter for atmospheric data output (0=none, 1=missval, 2=remove).
int kpp_chem
Switch for KPP chemistry module (0=off, 1=on).
int qnt_zeta
Quantity array index for zeta vertical coordinate.
double conv_pbl_trans
Depth of PBL transition layer (fraction of PBL depth).
char ens_basename[LEN]
Basename of ensemble data file.
double wet_depo_pre[2]
Coefficients for precipitation calculation.
int met_vert_coord
Vertical coordinate of input meteo data (0=plev, 1=mlev_p_file, 2=mlev_ab_file, 3=mlev_ab_full,...
double csi_z0
Lower altitude of gridded CSI data [km].
int qnt_lapse
Quantity array index for lapse rate.
double stat_lat
Latitude of station [deg].
int qnt_Cho2
Quantity array index for HO2 volume mixing ratio (chemistry code).
double wet_depo_bc_h[2]
Coefficients for wet deposition below cloud (Henry's law: Hb, Cb).
int grid_ny
Number of latitudes of gridded data.
int qnt_Csf6
Quantity array index for SF6 volume mixing ratio (chemistry code).
int qnt_Ch2o
Quantity array index for H2O volume mixing ratio (chemistry code).
double met_detrend
FWHM of horizontal Gaussian used for detrending [km].
int conv_mix_pbl
Vertical mixing in the PBL (0=off, 1=on).
char metbase[LEN]
Basename for meteo data.
double bound_dps
Boundary conditions surface layer depth [hPa].
double met_cms_eps_t
cmultiscale compression epsilon for temperature.
int chemgrid_nz
Number of altitudes of chemistry grid.
int qnt_cape
Quantity array index for convective available potential energy (CAPE).
double bound_mass_trend
Boundary conditions mass per particle trend [kg/s].
int mixing_nz
Number of altitudes of mixing grid.
int qnt_o3c
Quantity array index for total column ozone.
double bound_p0
Boundary conditions bottom pressure [hPa].
double mixing_lon0
Lower longitude of mixing grid [deg].
char clim_ccl4_timeseries[LEN]
Filename of CFC-10 time series.
int qnt_Co3
Quantity array index for O3 volume mixing ratio (chemistry code).
int qnt_tsts
Quantity array index for T_STS.
int grid_nz
Number of altitudes of gridded data.
char clim_oh_filename[LEN]
Filename of OH climatology.
int qnt_nss
Quantity array index for northward turbulent surface stress.
double ens_dt_out
Time step for ensemble output [s].
char sample_basename[LEN]
Basename of sample data file.
int atm_stride
Particle index stride for atmospheric data files.
int met_relhum
Try to read relative humidity (0=no, 1=yes).
double mixing_lat1
Upper latitude of mixing grid [deg].
double atm_dt_out
Time step for atmospheric data output [s].
char clim_sf6_timeseries[LEN]
Filename of SF6 time series.
double prof_lat1
Upper latitude of gridded profile data [deg].
int met_cms_batch
cmultiscale batch size.
double psc_h2o
H2O volume mixing ratio for PSC analysis.
int met_sp
Smoothing for pressure levels.
double prof_lon0
Lower longitude of gridded profile data [deg].
int chemgrid_nx
Number of longitudes of chemistry grid.
int qnt_pct
Quantity array index for cloud top pressure.
int qnt_mloss_kpp
Quantity array index for total mass loss due to KPP chemistry.
int qnt_psat
Quantity array index for saturation pressure over water.
double met_lev_hybm[EP]
Meteo data model level b coefficients.
double prof_lat0
Lower latitude of gridded profile data [deg].
int qnt_cin
Quantity array index for convective inhibition (CIN).
double psc_hno3
HNO3 volume mixing ratio for PSC analysis.
double prof_lon1
Upper longitude of gridded profile data [deg].
double met_cms_eps_rwc
cmultiscale compression epsilon for cloud rain water content.
int met_nc_quant
Number of digits for quantization of netCDF meteo files (0=off).
int h2o2_chem_reaction
Reaction type for H2O2 chemistry (0=none, 1=SO2).
int qnt_Co3p
Quantity array index for O(3P) volume mixing ratio (chemistry code).
int atm_nc_quant[NQ]
Number of digits for quantization of netCDF atmospheric data files (0=off).
double wet_depo_bc_ret_ratio
Coefficients for wet deposition below cloud: retention ratio.
int chemgrid_ny
Number of latitudes of chemistry grid.
char clim_ccl3f_timeseries[LEN]
Filename of CFC-11 time series.
double met_cms_eps_o3
cmultiscale compression epsilon for ozone.
int met_cms_zstd
cmultiscale zstd compression (0=off, 1=on).
int grid_sparse
Sparse output in grid data files (0=no, 1=yes).
char vtk_basename[LEN]
Basename of VTK data files.
double dry_depo_vdep
Dry deposition velocity [m/s].
int qnt_tt
Quantity array index for tropopause temperature.
int met_np
Number of target pressure levels.
int qnt_ens
Quantity array index for ensemble IDs.
int met_nc_level
zlib compression level of netCDF meteo files (0=off).
double met_zfp_tol_t
ZFP compression tolerance for temperature.
double mixing_dt
Time interval for mixing [s].
int qnt_mloss_h2o2
Quantity array index for total mass loss due to H2O2 chemistry.
double met_zfp_tol_z
ZFP compression tolerance for geopotential height.
double vtk_scale
Vertical scaling factor for VTK data.
char clim_ccl2f2_timeseries[LEN]
Filename of CFC-12 time series.
double met_cms_eps_w
cmultiscale compression epsilon for vertical velocity.
double wet_depo_ic_h[2]
Coefficients for wet deposition in cloud (Henry's law: Hb, Cb).
double turb_dx_pbl
Horizontal turbulent diffusion coefficient (PBL) [m^2/s].
double conv_cin
CIN threshold for convection module [J/kg].
int qnt_pv
Quantity array index for potential vorticity.
int advect_vert_coord
Vertical velocity of air parcels (0=omega_on_plev, 1=zetadot_on_mlev, 2=omega_on_mlev).
int qnt_mloss_oh
Quantity array index for total mass loss due to OH chemistry.
int qnt_Ch2o2
Quantity array index for H2O2 volume mixing ratio (chemistry code).
int qnt_sst
Quantity array index for sea surface temperature.
double mixing_lon1
Upper longitude of mixing grid [deg].
int atm_nc_level
zlib compression level of netCDF atmospheric data files (0=off).
char clim_hno3_filename[LEN]
Filename of HNO3 climatology.
int met_cms_heur
cmultiscale coarsening heuristics (0=default, 1=mean diff, 2=median diff, 3=max diff).
double wet_depo_ic_ret_ratio
Coefficients for wet deposition in cloud: retention ratio.
int qnt_sh
Quantity array index for specific humidity.
char csi_ens_basename[LEN]
Basename of CSI ensemble data files.
int qnt_ess
Quantity array index for eastward turbulent surface stress.
double wet_depo_ic_b
Coefficient B for wet deposition in cloud (exponential form).
double wet_depo_bc_b
Coefficient B for wet deposition below cloud (exponential form).
int met_dy
Stride for latitudes.
int qnt_Cx
Quantity array index for trace species x volume mixing ratio (chemistry code).
double turb_dz_strat
Vertical turbulent diffusion coefficient (stratosphere) [m^2/s].
double bound_zetas
Boundary conditions surface layer zeta [K].
int qnt_idx
Quantity array index for air parcel IDs.
double met_tropo_theta
Dynamical tropopause potential temperature threshold [K].
int qnt_rwc
Quantity array index for cloud rain water content.
double t_start
Start time of simulation [s].
char qnt_longname[NQ][LEN]
Quantity long names.
double met_p[EP]
Target pressure levels [hPa].
int nq
Number of quantities.
double tdec_trop
Life time of particles in the troposphere [s].
double sample_dx
Horizontal radius for sample output [km].
int vtk_stride
Particle index stride for VTK data.
char stat_basename[LEN]
Basename of station data file.
double turb_dz_pbl
Vertical turbulent diffusion coefficient (PBL) [m^2/s].
double grid_lat1
Upper latitude of gridded data [deg].
int qnt_zt
Quantity array index for tropopause geopotential height.
int met_type
Type of meteo data files (0=netCDF, 1=binary, 2=pck, 3=zfp, 4=zstd, 5=cms).
int qnt_cc
Quantity array index for cloud cover.
int qnt_plcl
Quantity array index for pressure at lifted condensation level (LCL).
double grid_dt_out
Time step for gridded data output [s].
int qnt_tdew
Quantity array index for dew point temperature.
float zt[EX][EY]
Tropopause geopotential height [km].
float sst[EX][EY]
Sea surface temperature [K].
float rwc[EX][EY][EP]
Cloud rain water content [kg/kg].
float o3c[EX][EY]
Total column ozone [DU].
float zeta_dotl[EX][EY][EP]
Vertical velocity on model levels [K/s].
float h2o[EX][EY][EP]
Water vapor volume mixing ratio [1].
float cape[EX][EY]
Convective available potential energy [J/kg].
float w[EX][EY][EP]
Vertical velocity [hPa/s].
float pct[EX][EY]
Cloud top pressure [hPa].
double hybrid[EP]
Model hybrid levels.
int nx
Number of longitudes.
int ny
Number of latitudes.
float shf[EX][EY]
Surface sensible heat flux [W/m^2].
float ps[EX][EY]
Surface pressure [hPa].
float lwc[EX][EY][EP]
Cloud liquid water content [kg/kg].
float us[EX][EY]
Surface zonal wind [m/s].
float wl[EX][EY][EP]
Vertical velocity on model levels [hPa/s].
float vl[EX][EY][EP]
Meridional wind on model levels [m/s].
float zs[EX][EY]
Surface geopotential height [km].
float o3[EX][EY][EP]
Ozone volume mixing ratio [1].
float cc[EX][EY][EP]
Cloud cover [1].
int np
Number of pressure levels.
float t[EX][EY][EP]
Temperature [K].
float ts[EX][EY]
Surface temperature [K].
float u[EX][EY][EP]
Zonal wind [m/s].
float ess[EX][EY]
Eastward turbulent surface stress [N/m^2].
float ul[EX][EY][EP]
Zonal wind on model levels [m/s].
float pcb[EX][EY]
Cloud bottom pressure [hPa].
float pel[EX][EY]
Pressure at equilibrium level (EL) [hPa].
float cin[EX][EY]
Convective inhibition [J/kg].
float plcl[EX][EY]
Pressure at lifted condensation level (LCL) [hPa].
double lon[EX]
Longitude [deg].
float pt[EX][EY]
Tropopause pressure [hPa].
float tt[EX][EY]
Tropopause temperature [K].
float pbl[EX][EY]
Boundary layer pressure [hPa].
float vs[EX][EY]
Surface meridional wind [m/s].
float z[EX][EY][EP]
Geopotential height [km].
float v[EX][EY][EP]
Meridional wind [m/s].
int npl
Number of model levels.
float lsm[EX][EY]
Land-sea mask [1].
float iwc[EX][EY][EP]
Cloud ice water content [kg/kg].
float h2ot[EX][EY]
Tropopause water vapor volume mixing ratio [ppv].
float pv[EX][EY][EP]
Potential vorticity [PVU].
float cl[EX][EY]
Total column cloud water [kg/m^2].
float nss[EX][EY]
Northward turbulent surface stress [N/m^2].
float pl[EX][EY][EP]
Pressure on model levels [hPa].
float plfc[EX][EY]
Pressure at level of free convection (LFC) [hPa].
double lat[EY]
Latitude [deg].
float swc[EX][EY][EP]
Cloud snow water content [kg/kg].
float zetal[EX][EY][EP]
Zeta on model levels [K].
double p[EP]
Pressure levels [hPa].