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;
2275 atm->
lon[ip], atm->
lat[ip], &atm->
p[ip], ci, cw, 1);
2294 SELECT_TIMER(
"MODULE_ADVECT_INIT",
"PHYSICS", NVTX_GPU);
2303 atm->
lon[ip], atm->
lat[ip], &atm->
p[ip], ci, cw, 1);
2318 SELECT_TIMER(
"MODULE_BOUND_COND",
"PHYSICS", NVTX_GPU);
2328 "acc data present(ctl,cache,clim,met0,met1,atm)") {
2364 if (atm->
p[ip] < pbl)
2416 ERRMSG(
"Molar mass is not defined!");
2422 const int np = atm->
np;
2426 const int ngrid = nx * ny * nz;
2428 double *restrict
const z = (
double *) malloc((
size_t) nz *
sizeof(double));
2429 double *restrict
const press =
2430 (
double *) malloc((
size_t) nz *
sizeof(double));
2431 double *restrict
const mass =
2432 (
double *) calloc((
size_t) ngrid,
sizeof(double));
2433 double *restrict
const area =
2434 (
double *) malloc((
size_t) ny *
sizeof(double));
2435 double *restrict
const lon =
2436 (
double *) malloc((
size_t) nx *
sizeof(double));
2437 double *restrict
const lat =
2438 (
double *) malloc((
size_t) ny *
sizeof(double));
2440 int *restrict
const ixs = (
int *) malloc((
size_t) np *
sizeof(int));
2441 int *restrict
const iys = (
int *) malloc((
size_t) np *
sizeof(int));
2442 int *restrict
const izs = (
int *) malloc((
size_t) np *
sizeof(int));
2451#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])
2452#pragma acc data present(ctl,met0,met1,atm,ixs,iys,izs,z,press,mass,area,lon,lat)
2453#pragma acc parallel loop independent gang vector
2455#pragma omp parallel for default(shared)
2457 for (
int iz = 0; iz < nz; iz++) {
2459 press[iz] =
P(z[iz]);
2463 const double t0 = tt - 0.5 * ctl->
dt_mod;
2464 const double t1 = tt + 0.5 * ctl->
dt_mod;
2468#pragma acc parallel loop independent gang vector
2470#pragma omp parallel for default(shared)
2472 for (
int ip = 0; ip < np; ip++) {
2476 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
2477 || ixs[ip] < 0 || ixs[ip] >= nx
2478 || iys[ip] < 0 || iys[ip] >= ny || izs[ip] < 0 || izs[ip] >= nz)
2484#pragma acc parallel loop independent gang vector
2486#pragma omp parallel for default(shared)
2488 for (
int ix = 0; ix < nx; ix++)
2491#pragma acc parallel loop independent gang vector
2493#pragma omp parallel for default(shared)
2495 for (
int iy = 0; iy < ny; iy++) {
2497 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat[iy]));
2502#pragma acc parallel loop independent gang vector
2504 for (
int ip = 0; ip < np; ip++)
2507#pragma acc atomic update
2509 mass[
ARRAY_3D(ixs[ip], iys[ip], ny, izs[ip], nz)]
2510 += atm->
q[ctl->
qnt_m][ip];
2514#pragma acc parallel loop independent gang vector
2516#pragma omp parallel for default(shared)
2518 for (
int ip = 0; ip < np; ip++)
2525 lon[ixs[ip]], lat[iys[ip]], &temp, ci, cw, 1);
2528 const double m = mass[
ARRAY_3D(ixs[ip], iys[ip], ny, izs[ip], nz)];
2532 / (
RHO(press[izs[ip]], temp) * area[iys[ip]] * dz * 1e9);
2535#pragma acc exit data delete(ixs,iys,izs,z,press,mass,area,lon,lat)
2565 "acc data present(ctl,cache,clim,met0,met1,atm)") {
2582 atm->
lon[ip], atm->
lat[ip], atm->
p[ip]));
2584 atm->
lat[ip], atm->
p[ip]));
2586 atm->
lat[ip], atm->
p[ip]));
2588 atm->
lat[ip], atm->
p[ip]));
2602 SELECT_TIMER(
"MODULE_CONVECTION",
"PHYSICS", NVTX_GPU);
2608 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2616 double pbot = ps, ptop = ps;
2633 double cape, cin, pel;
2639 if (isfinite(cape) && cape >= ctl->
conv_cape
2641 ptop = GSL_MIN(ptop, pel);
2645 if (ptop != pbot && atm->
p[ip] >= ptop) {
2650 pbot, atm->
lon[ip], atm->
lat[ip], &tbot, ci, cw, 1);
2652 ptop, atm->
lon[ip], atm->
lat[ip], &ttop, ci, cw, 1);
2653 const double rhobot = pbot / tbot;
2654 const double rhotop = ptop / ttop;
2657 const double rho = rhobot + (rhotop - rhobot) * cache->
rs[ip];
2660 atm->
p[ip] =
LIN(rhobot, pbot, rhotop, ptop, rho);
2678 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
2681 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,clim,atm)") {
2690 const double aux = exp(-cache->
dt[ip] / tdec);
2691 if (ctl->
qnt_m >= 0) {
2694 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
2695 atm->
q[ctl->
qnt_m][ip] *= aux;
2720 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2728 float umean = 0, usig = 0, vmean = 0, vsig = 0, wmean = 0, wsig = 0;
2729 for (
int i = 0; i < 2; i++)
2730 for (
int j = 0; j < 2; j++)
2731 for (
int k = 0; k < 2; k++) {
2732 umean += met0->
u[ix + i][iy + j][iz + k];
2733 usig +=
SQR(met0->
u[ix + i][iy + j][iz + k]);
2734 vmean += met0->
v[ix + i][iy + j][iz + k];
2735 vsig +=
SQR(met0->
v[ix + i][iy + j][iz + k]);
2736 wmean += met0->
w[ix + i][iy + j][iz + k];
2737 wsig +=
SQR(met0->
w[ix + i][iy + j][iz + k]);
2739 umean += met1->
u[ix + i][iy + j][iz + k];
2740 usig +=
SQR(met1->
u[ix + i][iy + j][iz + k]);
2741 vmean += met1->
v[ix + i][iy + j][iz + k];
2742 vsig +=
SQR(met1->
v[ix + i][iy + j][iz + k]);
2743 wmean += met1->
w[ix + i][iy + j][iz + k];
2744 wsig +=
SQR(met1->
w[ix + i][iy + j][iz + k]);
2746 usig = usig / 16.f -
SQR(umean / 16.f);
2747 usig = (usig > 0 ? sqrtf(usig) : 0);
2748 vsig = vsig / 16.f -
SQR(vmean / 16.f);
2749 vsig = (vsig > 0 ? sqrtf(vsig) : 0);
2750 wsig = wsig / 16.f -
SQR(wmean / 16.f);
2751 wsig = (wsig > 0 ? sqrtf(wsig) : 0);
2754 const double r = 1 - 2 * fabs(cache->
dt[ip]) / ctl->
dt_met;
2755 const double r2 = sqrt(1 - r * r);
2759 cache->
uvwp[ip][0] =
2760 (float) (r * cache->
uvwp[ip][0] +
2765 cache->
uvwp[ip][1] =
2766 (float) (r * cache->
uvwp[ip][1] +
2773 cache->
uvwp[ip][2] =
2774 (float) (r * cache->
uvwp[ip][2] +
2776 atm->
p[ip] += cache->
uvwp[ip][2] * cache->
dt[ip];
2797 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2799 double dsigw_dz = 0.0, sig_u = 0.25, sig_w = 0.1,
2800 tau_u = 300., tau_w = 100.;
2809 if (atm->
p[ip] >= pbl) {
2812 const double p =
MIN(atm->
p[ip], ps);
2813 const double zs =
Z(ps);
2814 const double z = 1e3 * (
Z(p) - zs);
2815 const double zi = 1e3 * (
Z(pbl) - zs);
2816 const double zratio = z / zi;
2819 double ess, nss, h2o, t;
2824 const double rho =
RHO(p,
TVIRT(t, h2o));
2825 const double tau = sqrt(
SQR(ess) +
SQR(nss));
2826 const double ustar = sqrt(tau / rho);
2836 sig_u = 1e-2 + 2.0 * ustar * (1.0 - zratio);
2837 sig_w = 1e-2 + 1.3 * ustar * (1.0 - zratio);
2840 dsigw_dz = -1.3 * ustar / zi;
2843 tau_u = 0.07 * zi / sig_u * sqrt(zratio);
2844 tau_w = 0.1 * zi / sig_w * pow(zratio, 0.8);
2851 const double wstar =
2852 pow(
G0 /
THETAVIRT(p, t, h2o) * shf / (rho *
CPD) * zi, 1. / 3.);
2856 + sqrt(0.4 *
SQR(wstar) + (5.0 - 4.0 * zratio) *
SQR(ustar));
2857 sig_w = 1e-2 + sqrt(1.2 *
SQR(wstar) * (1.0 - 0.9 * zratio)
2858 * pow(zratio, 2.0 / 3.0)
2859 + (1.8 - 1.4 * zratio) *
SQR(ustar));
2862 dsigw_dz = 0.5 / sig_w / zi * (-1.4 *
SQR(ustar) +
SQR(wstar)
2864 pow(
MAX(zratio, 1e-3), -1.0 / 3.0)
2865 - 1.8 * pow(zratio, 2.0 / 3.0)));
2868 const double C0 = 3.0;
2870 (1.5 - 1.2 * pow(zratio, 1.0 / 3.0)) *
SQR(wstar) * wstar / zi
2871 +
SQR(ustar) * ustar * (1.0 - 0.8 * zratio) / (
KARMAN * z);
2872 tau_u = 2 *
SQR(sig_u) / (C0 * eps);
2873 tau_w = 2 *
SQR(sig_w) / (C0 * eps);
2878 sig_u =
MAX(sig_u, 0.25);
2879 sig_w =
MAX(sig_w, 0.1);
2880 tau_u =
MAX(tau_u, 300.);
2881 tau_w =
MAX(tau_w, 100.);
2884 const double ru = exp(-fabs(cache->
dt[ip]) / tau_u);
2885 const double ru2 = sqrt(1.0 -
SQR(ru));
2887 = (float) (cache->
uvwp[ip][0] * ru + ru2 * cache->
rs[3 * ip]);
2889 = (float) (cache->
uvwp[ip][1] * ru + ru2 * cache->
rs[3 * ip + 1]);
2891 const double rw = exp(-fabs(cache->
dt[ip]) / tau_w);
2892 const double rw2 = sqrt(1.0 -
SQR(rw));
2894 = (float) (cache->
uvwp[ip][2] * rw + rw2 * cache->
rs[3 * ip + 2]
2895 + sig_w * dsigw_dz * cache->
dt[ip]);
2902 DZ2DP(cache->
uvwp[ip][2] * cache->
dt[ip] / 1000., atm->
p[ip]);
2924 "acc data present(ctl,cache,clim,met0,met1,atm)") {
2933 const double wpbl =
pbl_weight(ctl, atm, ip, pbl, ps);
2934 const double wtrop =
tropo_weight(clim, atm, ip) * (1.0 - wpbl);
2935 const double wstrat = 1.0 - wpbl - wtrop;
2945 const double sigma = sqrt(2.0 * dx * fabs(cache->
dt[ip])) / 1000.;
2947 atm->
lat[ip] +=
DY2DEG(cache->
rs[3 * ip + 1] * sigma);
2952 const double sigma = sqrt(2.0 * dz * fabs(cache->
dt[ip])) / 1000.;
2953 atm->
p[ip] +=
DZ2DP(cache->
rs[3 * ip + 2] * sigma, atm->
p[ip]);
2972 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
2975 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2987 const double dz = 1000. * (
Z(ps - ctl->
dry_depo_dp) -
Z(ps));
3007 const double aux = exp(-cache->
dt[ip] * v_dep / dz);
3008 if (ctl->
qnt_m >= 0) {
3011 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
3012 atm->
q[ctl->
qnt_m][ip] *= aux;
3036 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
3039 const double a = 3.12541941e-06;
3040 const double b = -5.72532259e-01;
3041 const double low = pow(1. / a, 1. / b);
3045 "acc data present(ctl,cache,ctl,met0,met1,atm)") {
3052 if (!(lwc > 0 || rwc > 0))
3063 const double k = 9.1e7 * exp(-29700. /
RI * (1. / t - 1. / 298.15));
3066 const double H_SO2 =
3067 1.3e-2 * exp(2900. * (1. / t - 1. / 298.15)) *
RI * t;
3068 const double K_1S = 1.23e-2 * exp(2.01e3 * (1. / t - 1. / 298.15));
3071 const double H_h2o2 =
3072 8.3e2 * exp(7600. * (1. / t - 1. / 298.15)) *
RI * t;
3078 cor = atm->
q[ctl->
qnt_Cx][ip] >
3079 low ? a * pow(atm->
q[ctl->
qnt_Cx][ip], b) : 1;
3081 const double h2o2 = H_h2o2
3083 * M * cor * 1000. /
AVO;
3086 const double rho_air = atm->
p[ip] / (
RI * t) *
MA / 10.;
3087 const double CWC = (lwc + rwc) * rho_air / 1e3;
3090 const double rate_coef = k * K_1S * h2o2 * H_SO2 * CWC;
3091 const double aux = exp(-cache->
dt[ip] * rate_coef);
3092 if (ctl->
qnt_m >= 0) {
3095 atm->
q[ctl->
qnt_m][ip] *= aux;
3116 SELECT_TIMER(
"MODULE_ISOSURF_INIT",
"PHYSICS", NVTX_GPU);
3127 PARTICLE_LOOP(0, atm->
np, 0,
"acc data present(cache,met0,met1,atm)") {
3130 cache->
iso_var[ip] = atm->
p[ip] / t;
3136 PARTICLE_LOOP(0, atm->
np, 0,
"acc data present(cache,met0,met1,atm)") {
3147 LOG(1,
"Read balloon pressure data: %s", ctl->
balloon);
3151 if (!(in = fopen(ctl->
balloon,
"r")))
3152 ERRMSG(
"Cannot open file!");
3156 while (fgets(line,
LEN, in))
3157 if (sscanf(line,
"%lg %lg", &(cache->
iso_ts[cache->
iso_n]),
3160 ERRMSG(
"Too many data points!");
3163 if (cache->
iso_n < 1)
3164 ERRMSG(
"Could not read any data!");
3187 PARTICLE_LOOP(0, atm->
np, 0,
"acc data present(ctl,cache,met0,met1,atm)") {
3200 atm->
p[ip] = cache->
iso_var[ip] * t;
3206 atm->
p[ip] = 1000. * pow(cache->
iso_var[ip] / t, -1. / 0.286);
3212 atm->
p[ip] = cache->
iso_ps[0];
3239 const int nvar = NVAR, nfix = NFIX, nreact = NREACT;
3240 double rtol[1] = { 1.0e-3 };
3241 double atol[1] = { 1.0 };
3245#pragma acc data copy(rtol,atol,nvar,nfix,nreact)
3248 "acc data present(ctl,cache,clim,met0,met1,atm) ") {
3251 double var[nvar], fix[nfix], rconst[nreact];
3252 for (
int i = 0; i < nvar; i++)
3254 for (
int i = 0; i < nfix; i++)
3256 for (
int i = 0; i < nreact; i++)
3258 kpp_chem_initialize(ctl, clim, met0, met1, atm, var, fix, rconst, ip);
3263 for (
int i = 0; i < 20; i++) {
3270 Rosenbrock(var, fix, rconst, 0, ctl->
dt_kpp,
3271 atol, rtol, &FunTemplate, &JacTemplate, rpar, ipar);
3274 kpp_chem_output2atm(atm, ctl, met0, met1, var, ip);
3295 ERRMSG(
"Need T_ice and T_NAT to calculate T_STS!");
3299 "acc data present(ctl,cache,clim,met0,met1,atm)") {
3301 double ps, ts, zs, us, vs, ess, nss, shf, lsm, sst, pbl, pt, pct, pcb, cl,
3302 plcl, plfc, pel, cape, cin, o3c, pv, t, tt, u, v, w, h2o, h2ot, o3, lwc,
3303 rwc, iwc, swc, cc, z, zt;
3351 atm->
lon[ip], atm->
lat[ip], atm->
p[ip]));
3353 atm->
lat[ip], atm->
p[ip]));
3355 atm->
lat[ip], atm->
p[ip]));
3357 atm->
lat[ip], atm->
p[ip]));
3358 SET_ATM(qnt_vh, sqrt(u * u + v * v));
3377 atm->
lat[ip], atm->
p[ip])));
3395 const int np = atm->
np;
3396 int *restrict
const ixs = (
int *) malloc((
size_t) np *
sizeof(int));
3397 int *restrict
const iys = (
int *) malloc((
size_t) np *
sizeof(int));
3398 int *restrict
const izs = (
int *) malloc((
size_t) np *
sizeof(int));
3406 const double t0 = t - 0.5 * ctl->
dt_mod;
3407 const double t1 = t + 0.5 * ctl->
dt_mod;
3411#pragma acc enter data create(ixs[0:np],iys[0:np],izs[0:np])
3412#pragma acc data present(ctl,clim,atm,ixs,iys,izs)
3413#pragma acc parallel loop independent gang vector
3415#pragma omp parallel for default(shared)
3417 for (
int ip = 0; ip < np; ip++) {
3420 izs[ip] = (int) ((
Z(atm->
p[ip]) - ctl->
mixing_z0) / dz);
3421 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
3422 || ixs[ip] < 0 || ixs[ip] >= ctl->
mixing_nx
3423 || iys[ip] < 0 || iys[ip] >= ctl->
mixing_ny
3424 || izs[ip] < 0 || izs[ip] >= ctl->
mixing_nz)
3429 if (ctl->
qnt_m >= 0)
3466#pragma acc exit data delete(ixs,iys,izs)
3482 const int qnt_idx) {
3485 const int np = atm->
np;
3487 double *restrict
const cmean =
3488 (
double *) malloc((
size_t) ngrid *
sizeof(double));
3489 int *restrict
const count = (
int *) malloc((
size_t) ngrid *
sizeof(int));
3493#pragma acc enter data create(cmean[0:ngrid],count[0:ngrid])
3494#pragma acc data present(ctl,clim,atm,ixs,iys,izs,cmean,count)
3495#pragma acc parallel loop independent gang vector
3500#pragma omp parallel for
3502 for (
int i = 0; i < ngrid; i++) {
3509#pragma acc parallel loop independent gang vector
3511 for (
int ip = 0; ip < np; ip++)
3516#pragma acc atomic update
3518 cmean[idx] += atm->
q[qnt_idx][ip];
3520#pragma acc atomic update
3525#pragma acc parallel loop independent gang vector
3530#pragma omp parallel for
3532 for (
int i = 0; i < ngrid; i++)
3534 cmean[i] /= count[i];
3538#pragma acc parallel loop independent gang vector
3540#pragma omp parallel for
3542 for (
int ip = 0; ip < np; ip++)
3546 double mixparam = 1.0;
3553 atm->
q[qnt_idx][ip] +=
3556 - atm->
q[qnt_idx][ip]) * mixparam;
3561#pragma acc exit data delete(cmean,count)
3582 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
3585 const double a = 4.71572206e-08;
3586 const double b = -8.28782867e-01;
3587 const double low = pow(1. / a, 1. / b);
3591 "acc data present(ctl,cache,clim,met0,met1,atm)") {
3617 0 ? pow(298. / t, ctl->
oh_chem[1]) : 1.);
3620 0 ? pow(298. / t, ctl->
oh_chem[3]) : 1.);
3621 const double c = log10(k0 * M / ki);
3622 k = k0 * M / (1. + k0 * M / ki) * pow(0.6, 1. / (1. + c * c));
3631 low ? a * pow(atm->
q[ctl->
qnt_Cx][ip], b) : 1;
3634 const double rate_coef =
3636 atm->
lat[ip], atm->
p[ip]) * M * cor;
3637 const double aux = exp(-cache->
dt[ip] * rate_coef);
3638 if (ctl->
qnt_m >= 0) {
3641 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
3642 atm->
q[ctl->
qnt_m][ip] *= aux;
3663 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(cache,met0,met1,atm)") {
3674 while (atm->
lat[ip] < -90 || atm->
lat[ip] > 90) {
3675 if (atm->
lat[ip] > 90) {
3676 atm->
lat[ip] = 180 - atm->
lat[ip];
3677 atm->
lon[ip] += 180;
3679 if (atm->
lat[ip] < -90) {
3680 atm->
lat[ip] = -180 - atm->
lat[ip];
3681 atm->
lon[ip] += 180;
3686 while (atm->
lon[ip] < -180)
3687 atm->
lon[ip] += 360;
3688 while (atm->
lon[ip] >= 180)
3689 atm->
lon[ip] -= 360;
3692 if (atm->
p[ip] < met0->
p[met0->
np - 1]) {
3693 atm->
p[ip] = met0->
p[met0->
np - 1];
3694 }
else if (atm->
p[ip] > 300.) {
3696 if (atm->
p[ip] > ps)
3708 gsl_rng_env_setup();
3709 if (omp_get_max_threads() >
NTHREADS)
3710 ERRMSG(
"Too many threads!");
3711 for (
int i = 0; i <
NTHREADS; i++) {
3712 rng[i] = gsl_rng_alloc(gsl_rng_default);
3713 gsl_rng_set(rng[i], gsl_rng_default_seed
3714 + (
long unsigned) (ntask *
NTHREADS + i));
3719 if (curandCreateGenerator(&rng_curand, CURAND_RNG_PSEUDO_DEFAULT) !=
3720 CURAND_STATUS_SUCCESS)
3721 ERRMSG(
"Cannot create random number generator!");
3722 if (curandSetPseudoRandomGeneratorSeed(rng_curand, ntask) !=
3723 CURAND_STATUS_SUCCESS)
3724 ERRMSG(
"Cannot set seed for random number generator!");
3727 (cudaStream_t) acc_get_cuda_stream(acc_async_sync)) !=
3728 CURAND_STATUS_SUCCESS)
3729 ERRMSG(
"Cannot set stream for random number generator!");
3746#pragma omp parallel for default(shared)
3747 for (
size_t i = 0; i < n; ++i)
3748 rs[i] = gsl_rng_uniform(rng[omp_get_thread_num()]);
3752 else if (method == 1) {
3753#pragma omp parallel for default(shared)
3754 for (
size_t i = 0; i < n; ++i)
3755 rs[i] = gsl_ran_gaussian_ziggurat(rng[omp_get_thread_num()], 1.0);
3761#pragma acc update device(rs[:n])
3769 const uint64_t key = 0xc8e4fd154ce32f6d;
3773#pragma acc data present(rs)
3774#pragma acc parallel loop independent gang vector
3776#pragma omp parallel for default(shared)
3778 for (
size_t i = 0; i < n + 1; ++i) {
3779 uint64_t r, t, x, y, z;
3780 y = x = (rng_ctr + i) * key;
3783 x = (x >> 32) | (x << 32);
3785 x = (x >> 32) | (x << 32);
3787 x = (x >> 32) | (x << 32);
3789 x = (x >> 32) | (x << 32);
3790 r = t ^ ((x * x + y) >> 32);
3791 rs[i] = (double) r / (
double) UINT64_MAX;
3798#pragma acc parallel loop independent gang vector
3800#pragma omp parallel for default(shared)
3802 for (
size_t i = 0; i < n; i += 2) {
3803 const double r = sqrt(-2.0 * log(rs[i]));
3804 const double phi = 2.0 * M_PI * rs[i + 1];
3805 rs[i] = r * cosf((
float) phi);
3806 rs[i + 1] = r * sinf((
float) phi);
3814#pragma acc host_data use_device(rs)
3819 if (curandGenerateUniformDouble(rng_curand, rs, (n < 4 ? 4 : n)) !=
3820 CURAND_STATUS_SUCCESS)
3821 ERRMSG(
"Cannot create random numbers!");
3825 else if (method == 1) {
3826 if (curandGenerateNormalDouble
3827 (rng_curand, rs, (n < 4 ? 4 : n), 0.0,
3828 1.0) != CURAND_STATUS_SUCCESS)
3829 ERRMSG(
"Cannot create random numbers!");
3833 ERRMSG(
"MPTRAC was compiled without cuRAND!");
3851 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
3859 const double v_s =
sedi(atm->
p[ip], t, atm->
q[ctl->
qnt_rp][ip],
3863 atm->
p[ip] +=
DZ2DP(v_s * cache->
dt[ip] / 1000., atm->
p[ip]);
3878 const int np = atm->
np;
3879 double *restrict
const a = (
double *) malloc((
size_t) np *
sizeof(double));
3880 int *restrict
const p = (
int *) malloc((
size_t) np *
sizeof(int));
3883#pragma acc enter data create(a[0:np],p[0:np])
3884#pragma acc data present(ctl,met0,atm,a,p)
3889#pragma acc parallel loop independent gang vector
3891#pragma omp parallel for default(shared)
3893 for (
int ip = 0; ip < np; ip++) {
3903#pragma acc host_data use_device(a,p)
3908 ERRMSG(
"MPTRAC was compiled without Thrust library!");
3916 for (
int iq = 0; iq < ctl->
nq; iq++)
3921#pragma acc exit data delete(a,p)
3935 double *restrict
const help =
3936 (
double *) malloc((
size_t) np *
sizeof(double));
3940#pragma acc enter data create(help[0:np])
3941#pragma acc data present(a,p,help)
3942#pragma acc parallel loop independent gang vector
3944#pragma omp parallel for default(shared)
3946 for (
int ip = 0; ip < np; ip++)
3947 help[ip] = a[p[ip]];
3949#pragma acc parallel loop independent gang vector
3951#pragma omp parallel for default(shared)
3953 for (
int ip = 0; ip < np; ip++)
3958#pragma acc exit data delete(help)
3975 const double latmin = gsl_stats_min(met0->
lat, 1, (
size_t) met0->
ny),
3976 latmax = gsl_stats_max(met0->
lat, 1, (
size_t) met0->
ny);
3979 (fabs(met0->
lon[met0->
nx - 1] - met0->
lon[0] - 360.0) >= 0.01);
3982 PARTICLE_LOOP(0, atm->
np, 0,
"acc data present(ctl,cache,met0,atm)") {
3988 cache->
dt[ip] = t - atm->
time[ip];
3990 cache->
dt[ip] = 0.0;
3993 if (local && (atm->
lon[ip] <= met0->
lon[0]
3994 || atm->
lon[ip] >= met0->
lon[met0->
nx - 1]
3995 || atm->
lat[ip] <= latmin || atm->
lat[ip] >= latmax))
3996 cache->
dt[ip] = 0.0;
4007 SELECT_TIMER(
"MODULE_TIMESTEPS_INIT",
"PHYSICS", NVTX_GPU);
4011 ctl->
t_start = gsl_stats_min(atm->
time, 1, (
size_t) atm->
np);
4013 ctl->
t_stop = gsl_stats_max(atm->
time, 1, (
size_t) atm->
np);
4015 ctl->
t_start = gsl_stats_max(atm->
time, 1, (
size_t) atm->
np);
4017 ctl->
t_stop = gsl_stats_min(atm->
time, 1, (
size_t) atm->
np);
4022 ERRMSG(
"Nothing to do! Check T_STOP and DIRECTION!");
4042 SELECT_TIMER(
"MODULE_TRACER_CHEM",
"PHYSICS", NVTX_GPU);
4046 "acc data present(ctl,cache,clim,met0,met1,atm)") {
4069 const double K_o1d =
ARRHENIUS(3.30e-10, 0, t) * o1d * M;
4071 atm->
p[ip], sza, o3c);
4072 atm->
q[ctl->
qnt_Cccl4][ip] *= exp(-cache->
dt[ip] * (K_hv + K_o1d));
4077 const double K_o1d =
ARRHENIUS(2.30e-10, 0, t) * o1d * M;
4079 atm->
p[ip], sza, o3c);
4080 atm->
q[ctl->
qnt_Cccl3f][ip] *= exp(-cache->
dt[ip] * (K_hv + K_o1d));
4085 const double K_o1d =
ARRHENIUS(1.40e-10, -25, t) * o1d * M;
4087 atm->
p[ip], sza, o3c);
4088 atm->
q[ctl->
qnt_Cccl2f2][ip] *= exp(-cache->
dt[ip] * (K_hv + K_o1d));
4093 const double K_o1d =
ARRHENIUS(1.19e-10, -20, t) * o1d * M;
4095 atm->
p[ip], sza, o3c);
4096 atm->
q[ctl->
qnt_Cn2o][ip] *= exp(-cache->
dt[ip] * (K_hv + K_o1d));
4115 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
4118 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
4124 if (!isfinite(pct) || atm->
p[ip] <= pct)
4140 double lwc, rwc, iwc, swc;
4145 const int inside = (lwc > 0 || rwc > 0 || iwc > 0 || swc > 0);
4159 else if (t <= 238.15)
4179 const double K_1 = 1.23e-2 * exp(2.01e3 * (1. / t - 1. / 298.15));
4180 const double K_2 = 6e-8 * exp(1.12e3 * (1. / t - 1. / 298.15));
4181 h *= (1. + K_1 / H_ion + K_1 * K_2 /
SQR(H_ion));
4185 const double dz = 1e3 * (
Z(pct) -
Z(pcb));
4188 lambda = h *
RI * t * Is / 3.6e6 / dz * eta;
4214 const double dz = 1e3 * (
Z(pct) -
Z(pcb));
4217 lambda = h *
RI * t * Is / 3.6e6 / dz * eta;
4222 const double aux = exp(-cache->
dt[ip] * lambda);
4223 if (ctl->
qnt_m >= 0) {
4226 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
4227 atm->
q[ctl->
qnt_m][ip] *= aux;
4251 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
4253 if (acc_get_num_devices(acc_device_nvidia) <= 0)
4254 ERRMSG(
"Not running on a GPU device!");
4255 acc_set_device_num(rank % acc_get_num_devices(acc_device_nvidia),
4257 acc_device_t device_type = acc_get_device_type();
4258 acc_init(device_type);
4272 SELECT_TIMER(
"CREATE_DATA_REGION",
"MEMORY", NVTX_GPU);
4273 ctl_t *ctlup = *ctl;
4276 met_t *met0up = *met0;
4277 met_t *met1up = *met1;
4278 atm_t *atmup = *atm;
4279#pragma acc enter data create(ctlup[:1],cacheup[:1],climup[:1],met0up[:1],met1up[:1],atmup[:1])
4295 SELECT_TIMER(
"DELETE_DATA_REGION",
"MEMORY", NVTX_GPU);
4296#pragma acc exit data delete (ctl,cache,clim,met0,met1,atm)
4322 char cachefile[
LEN], cmd[2 *
LEN], filename[
LEN];
4328 if (t == ctl->
t_start || !init) {
4335 ERRMSG(
"Cannot open file!");
4340 ERRMSG(
"Cannot open file!");
4350 sprintf(cmd,
"cat %s > /dev/null &", cachefile);
4351 LOG(1,
"Caching: %s", cachefile);
4352 if (system(cmd) != 0)
4353 WARN(
"Caching command failed!");
4358 if (t > (*met1)->time) {
4368 ERRMSG(
"Cannot open file!");
4378 sprintf(cmd,
"cat %s > /dev/null &", cachefile);
4379 LOG(1,
"Caching: %s", cachefile);
4380 if (system(cmd) != 0)
4381 WARN(
"Caching command failed!");
4386 if (t < (*met0)->time) {
4396 ERRMSG(
"Cannot open file!");
4406 sprintf(cmd,
"cat %s > /dev/null &", cachefile);
4407 LOG(1,
"Caching: %s", cachefile);
4408 if (system(cmd) != 0)
4409 WARN(
"Caching command failed!");
4414 if ((*met0)->nx != 0 && (*met1)->nx != 0) {
4415 if ((*met0)->nx != (*met1)->nx
4416 || (*met0)->ny != (*met1)->ny || (*met0)->np != (*met1)->np)
4417 ERRMSG(
"Meteo grid dimensions do not match!");
4418 for (
int ix = 0; ix < (*met0)->nx; ix++)
4419 if (fabs((*met0)->lon[ix] - (*met1)->lon[ix]) > 0.001)
4420 ERRMSG(
"Meteo grid longitudes do not match!");
4421 for (
int iy = 0; iy < (*met0)->ny; iy++)
4422 if (fabs((*met0)->lat[iy] - (*met1)->lat[iy]) > 0.001)
4423 ERRMSG(
"Meteo grid latitudes do not match!");
4424 for (
int ip = 0; ip < (*met0)->np; ip++)
4425 if (fabs((*met0)->p[ip] - (*met1)->p[ip]) > 0.001)
4426 ERRMSG(
"Meteo grid pressure levels do not match!");
4452 const char *filename,
4465 LOG(1,
"Read atmospheric data: %s", filename);
4485 ERRMSG(
"Atmospheric data type not supported!");
4493 ERRMSG(
"Can not read any data!");
4497 LOG(2,
"Number of particles: %d", atm->
np);
4498 gsl_stats_minmax(&mini, &maxi, atm->
time, 1, (
size_t) atm->
np);
4499 LOG(2,
"Time range: %.2f ... %.2f s", mini, maxi);
4500 gsl_stats_minmax(&mini, &maxi, atm->
p, 1, (
size_t) atm->
np);
4501 LOG(2,
"Altitude range: %g ... %g km",
Z(maxi),
Z(mini));
4502 LOG(2,
"Pressure range: %g ... %g hPa", maxi, mini);
4503 gsl_stats_minmax(&mini, &maxi, atm->
lon, 1, (
size_t) atm->
np);
4504 LOG(2,
"Longitude range: %g ... %g deg", mini, maxi);
4505 gsl_stats_minmax(&mini, &maxi, atm->
lat, 1, (
size_t) atm->
np);
4506 LOG(2,
"Latitude range: %g ... %g deg", mini, maxi);
4507 for (
int iq = 0; iq < ctl->
nq; iq++) {
4509 sprintf(msg,
"Quantity %s range: %s ... %s %s",
4512 gsl_stats_minmax(&mini, &maxi, atm->
q[iq], 1, (
size_t) atm->
np);
4513 LOG(2, msg, mini, maxi);
4583 const char *filename,
4592 LOG(1,
"\nMassive-Parallel Trajectory Calculations (MPTRAC)\n"
4593 "(executable: %s | version: %s | compiled: %s, %s)\n",
4594 argv[0], VERSION, __DATE__, __TIME__);
4690 ctl->
nq = (int)
scan_ctl(filename, argc, argv,
"NQ", -1,
"0", NULL);
4692 ERRMSG(
"Too many quantities!");
4693 for (
int iq = 0; iq < ctl->
nq; iq++) {
4699 scan_ctl(filename, argc, argv,
"QNT_FORMAT", iq,
"%g",
4701 if (strcasecmp(ctl->
qnt_name[iq],
"aoa") == 0)
4705 SET_QNT(qnt_idx,
"idx",
"particle index",
"-")
4706 SET_QNT(qnt_ens,
"ens",
"ensemble index",
"-")
4707 SET_QNT(qnt_stat,
"stat",
"station flag",
"-")
4708 SET_QNT(qnt_m,
"m",
"mass",
"kg")
4709 SET_QNT(qnt_vmr,
"vmr",
"volume mixing ratio",
"ppv")
4710 SET_QNT(qnt_rp,
"rp",
"particle radius",
"microns")
4711 SET_QNT(qnt_rhop,
"rhop",
"particle density",
"kg/m^3")
4712 SET_QNT(qnt_ps,
"ps",
"surface pressure",
"hPa")
4713 SET_QNT(qnt_ts,
"ts",
"surface temperature",
"K")
4714 SET_QNT(qnt_zs,
"zs",
"surface height",
"km")
4715 SET_QNT(qnt_us,
"us",
"surface zonal wind",
"m/s")
4716 SET_QNT(qnt_vs,
"vs",
"surface meridional wind",
"m/s")
4717 SET_QNT(qnt_ess,
"ess",
"eastward turbulent surface stress",
"N/m^2")
4718 SET_QNT(qnt_nss,
"nss",
"northward turbulent surface stress",
"N/m^2")
4719 SET_QNT(qnt_shf,
"shf",
"surface sensible heat flux",
"W/m^2")
4720 SET_QNT(qnt_lsm,
"lsm",
"land-sea mask",
"1")
4721 SET_QNT(qnt_sst,
"sst",
"sea surface temperature",
"K")
4722 SET_QNT(qnt_pbl,
"pbl",
"planetary boundary layer",
"hPa")
4723 SET_QNT(qnt_pt,
"pt",
"tropopause pressure",
"hPa")
4724 SET_QNT(qnt_tt,
"tt",
"tropopause temperature",
"K")
4725 SET_QNT(qnt_zt,
"zt",
"tropopause geopotential height",
"km")
4726 SET_QNT(qnt_h2ot,
"h2ot",
"tropopause water vapor",
"ppv")
4727 SET_QNT(qnt_zg,
"zg",
"geopotential height",
"km")
4728 SET_QNT(qnt_p,
"p",
"pressure",
"hPa")
4729 SET_QNT(qnt_t,
"t",
"temperature",
"K")
4730 SET_QNT(qnt_rho,
"rho",
"air density",
"kg/m^3")
4731 SET_QNT(qnt_u,
"u",
"zonal wind",
"m/s")
4732 SET_QNT(qnt_v,
"v",
"meridional wind",
"m/s")
4733 SET_QNT(qnt_w,
"w",
"vertical velocity",
"hPa/s")
4734 SET_QNT(qnt_h2o,
"h2o",
"water vapor",
"ppv")
4735 SET_QNT(qnt_o3,
"o3",
"ozone",
"ppv")
4736 SET_QNT(qnt_lwc,
"lwc",
"cloud liquid water content",
"kg/kg")
4737 SET_QNT(qnt_rwc,
"rwc",
"cloud rain water content",
"kg/kg")
4738 SET_QNT(qnt_iwc,
"iwc",
"cloud ice water content",
"kg/kg")
4739 SET_QNT(qnt_swc,
"swc",
"cloud snow water content",
"kg/kg")
4740 SET_QNT(qnt_cc,
"cc",
"cloud cover",
"1")
4741 SET_QNT(qnt_pct,
"pct",
"cloud top pressure",
"hPa")
4742 SET_QNT(qnt_pcb,
"pcb",
"cloud bottom pressure",
"hPa")
4743 SET_QNT(qnt_cl,
"cl",
"total column cloud water",
"kg/m^2")
4744 SET_QNT(qnt_plcl,
"plcl",
"lifted condensation level",
"hPa")
4745 SET_QNT(qnt_plfc,
"plfc",
"level of free convection",
"hPa")
4746 SET_QNT(qnt_pel,
"pel",
"equilibrium level",
"hPa")
4747 SET_QNT(qnt_cape,
"cape",
"convective available potential energy",
4749 SET_QNT(qnt_cin,
"cin",
"convective inhibition",
"J/kg")
4750 SET_QNT(qnt_o3c,
"o3c",
"total column ozone",
"DU")
4751 SET_QNT(qnt_hno3,
"hno3",
"nitric acid",
"ppv")
4752 SET_QNT(qnt_oh,
"oh",
"hydroxyl radical",
"ppv")
4753 SET_QNT(qnt_h2o2,
"h2o2",
"hydrogen peroxide",
"ppv")
4754 SET_QNT(qnt_ho2,
"ho2",
"hydroperoxyl radical",
"ppv")
4755 SET_QNT(qnt_o1d,
"o1d",
"atomic oxygen",
"ppv")
4756 SET_QNT(qnt_mloss_oh,
"mloss_oh",
"mass loss due to OH chemistry",
"kg")
4757 SET_QNT(qnt_mloss_h2o2,
"mloss_h2o2",
"mass loss due to H2O2 chemistry",
4759 SET_QNT(qnt_mloss_kpp,
"mloss_kpp",
"mass loss due to kpp chemistry",
4761 SET_QNT(qnt_mloss_wet,
"mloss_wet",
"mass loss due to wet deposition",
4763 SET_QNT(qnt_mloss_dry,
"mloss_dry",
"mass loss due to dry deposition",
4765 SET_QNT(qnt_mloss_decay,
"mloss_decay",
4766 "mass loss due to exponential decay",
"kg")
4767 SET_QNT(qnt_loss_rate,
"loss_rate",
"total loss rate",
"s^-1")
4768 SET_QNT(qnt_psat,
"psat",
"saturation pressure over water",
"hPa")
4769 SET_QNT(qnt_psice,
"psice",
"saturation pressure over ice",
"hPa")
4770 SET_QNT(qnt_pw,
"pw",
"partial water vapor pressure",
"hPa")
4771 SET_QNT(qnt_sh,
"sh",
"specific humidity",
"kg/kg")
4772 SET_QNT(qnt_rh,
"rh",
"relative humidity",
"%%")
4773 SET_QNT(qnt_rhice,
"rhice",
"relative humidity over ice",
"%%")
4774 SET_QNT(qnt_theta,
"theta",
"potential temperature",
"K")
4775 SET_QNT(qnt_zeta,
"zeta",
"zeta coordinate",
"K")
4776 SET_QNT(qnt_zeta_d,
"zeta_d",
"diagnosed zeta coordinate",
"K")
4777 SET_QNT(qnt_tvirt,
"tvirt",
"virtual temperature",
"K")
4778 SET_QNT(qnt_lapse,
"lapse",
"temperature lapse rate",
"K/km")
4779 SET_QNT(qnt_vh,
"vh",
"horizontal velocity",
"m/s")
4780 SET_QNT(qnt_vz,
"vz",
"vertical velocity",
"m/s")
4781 SET_QNT(qnt_pv,
"pv",
"potential vorticity",
"PVU")
4782 SET_QNT(qnt_tdew,
"tdew",
"dew point temperature",
"K")
4783 SET_QNT(qnt_tice,
"tice",
"frost point temperature",
"K")
4784 SET_QNT(qnt_tsts,
"tsts",
"STS existence temperature",
"K")
4785 SET_QNT(qnt_tnat,
"tnat",
"NAT existence temperature",
"K")
4786 SET_QNT(qnt_Cx,
"Cx",
"Trace species x volume mixing ratio",
"ppv")
4787 SET_QNT(qnt_Ch2o,
"Ch2o",
"H2O volume mixing ratio",
"ppv")
4788 SET_QNT(qnt_Co3,
"Co3",
"O3 volume mixing ratio",
"ppv")
4789 SET_QNT(qnt_Cco,
"Cco",
"CO volume mixing ratio",
"ppv")
4790 SET_QNT(qnt_Coh,
"Coh",
"HO volume mixing ratio",
"ppv")
4791 SET_QNT(qnt_Ch,
"Ch",
"H radical volume mixing ratio",
"ppv")
4792 SET_QNT(qnt_Cho2,
"Cho2",
"HO2 volume mixing ratio",
"ppv")
4793 SET_QNT(qnt_Ch2o2,
"Ch2o2",
"H2O2 volume mixing ratio",
"ppv")
4794 SET_QNT(qnt_Co1d,
"Co1d",
"O(1D) volume mixing ratio",
"ppv")
4795 SET_QNT(qnt_Co3p,
"Co3p",
"O(3P) radical volume mixing ratio",
"ppv")
4796 SET_QNT(qnt_Cccl4,
"Cccl4",
"CCl4 (CFC-10) volume mixing ratio",
"ppv")
4797 SET_QNT(qnt_Cccl3f,
"Cccl3f",
"CCl3F (CFC-11) volume mixing ratio",
4799 SET_QNT(qnt_Cccl2f2,
"Cccl2f2",
"CCl2F2 (CFC-12) volume mixing ratio",
4801 SET_QNT(qnt_Cn2o,
"Cn2o",
"N2O volume mixing ratio",
"ppv")
4802 SET_QNT(qnt_Csf6,
"Csf6",
"SF6 volume mixing ratio",
"ppv")
4803 SET_QNT(qnt_aoa,
"aoa",
"age of air",
"s")
4809 (int)
scan_ctl(filename, argc, argv,
"ADVECT_VERT_COORD", -1,
"0", NULL);
4811 ERRMSG(
"Set ADVECT_VERT_COORD to 0, 1, or 2!");
4813 (int)
scan_ctl(filename, argc, argv,
"MET_VERT_COORD", -1,
"0", NULL);
4815 ERRMSG(
"Set MET_VERT_COORD to 0, 1, 2, 3, or 4!");
4817 ERRMSG(
"Please add zeta to your quantities for diabatic calculations!");
4820 (
"Using ADVECT_VERT_COORD = 2 requires meteo data on model levels!");
4824 (int)
scan_ctl(filename, argc, argv,
"DIRECTION", -1,
"1", NULL);
4826 ERRMSG(
"Set DIRECTION to -1 or 1!");
4827 ctl->
t_stop =
scan_ctl(filename, argc, argv,
"T_STOP", -1,
"1e100", NULL);
4828 ctl->
dt_mod =
scan_ctl(filename, argc, argv,
"DT_MOD", -1,
"180", NULL);
4832 ctl->
dt_met =
scan_ctl(filename, argc, argv,
"DT_MET", -1,
"3600", NULL);
4834 (int)
scan_ctl(filename, argc, argv,
"MET_CONVENTION", -1,
"0", NULL);
4836 (int)
scan_ctl(filename, argc, argv,
"MET_TYPE", -1,
"0", NULL);
4839 (
"Please use meteo files in netcdf format for diabatic calculations.");
4841 (int)
scan_ctl(filename, argc, argv,
"MET_CLAMS", -1,
"0", NULL);
4843 (int)
scan_ctl(filename, argc, argv,
"MET_NC_SCALE", -1,
"1", NULL);
4845 (int)
scan_ctl(filename, argc, argv,
"MET_NC_LEVEL", -1,
"0", NULL);
4847 (int)
scan_ctl(filename, argc, argv,
"MET_NC_QUANT", -1,
"0", NULL);
4849 (int)
scan_ctl(filename, argc, argv,
"MET_ZSTD_LEVEL", -1,
"0", NULL);
4851 (int)
scan_ctl(filename, argc, argv,
"MET_ZFP_PREC", -1,
"8", NULL);
4853 scan_ctl(filename, argc, argv,
"MET_ZFP_TOL_T", -1,
"5.0", NULL);
4855 scan_ctl(filename, argc, argv,
"MET_ZFP_TOL_Z", -1,
"0.5", NULL);
4857 (int)
scan_ctl(filename, argc, argv,
"MET_CMS_BATCH", -1,
"-1", NULL);
4859 (int)
scan_ctl(filename, argc, argv,
"MET_CMS_ZSTD", -1,
"1", NULL);
4861 (int)
scan_ctl(filename, argc, argv,
"MET_CMS_HEUR", -1,
"1", NULL);
4863 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_Z", -1,
"1.0", NULL);
4865 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_T", -1,
"0.05", NULL);
4867 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_U", -1,
"0.05", NULL);
4869 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_V", -1,
"0.05", NULL);
4871 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_W", -1,
"1.0", NULL);
4873 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_PV", -1,
"1.0", NULL);
4875 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_H2O", -1,
"1.0", NULL);
4877 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_O3", -1,
"1.0", NULL);
4879 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_LWC", -1,
"1.0", NULL);
4881 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_RWC", -1,
"1.0", NULL);
4883 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_IWC", -1,
"1.0", NULL);
4885 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_SWC", -1,
"1.0", NULL);
4887 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_CC", -1,
"1.0", NULL);
4888 ctl->
met_dx = (int)
scan_ctl(filename, argc, argv,
"MET_DX", -1,
"1", NULL);
4889 ctl->
met_dy = (int)
scan_ctl(filename, argc, argv,
"MET_DY", -1,
"1", NULL);
4890 ctl->
met_dp = (int)
scan_ctl(filename, argc, argv,
"MET_DP", -1,
"1", NULL);
4892 ERRMSG(
"MET_DX, MET_DY, and MET_DP need to be greater than zero!");
4893 ctl->
met_sx = (int)
scan_ctl(filename, argc, argv,
"MET_SX", -1,
"1", NULL);
4894 ctl->
met_sy = (int)
scan_ctl(filename, argc, argv,
"MET_SY", -1,
"1", NULL);
4895 ctl->
met_sp = (int)
scan_ctl(filename, argc, argv,
"MET_SP", -1,
"1", NULL);
4897 ERRMSG(
"MET_SX, MET_SY, and MET_SP need to be greater than zero!");
4899 scan_ctl(filename, argc, argv,
"MET_DETREND", -1,
"-999", NULL);
4900 ctl->
met_np = (int)
scan_ctl(filename, argc, argv,
"MET_NP", -1,
"0", NULL);
4902 ERRMSG(
"Too many pressure levels!");
4904 (int)
scan_ctl(filename, argc, argv,
"MET_PRESS_LEVEL_DEF", -1,
"-1",
4910 for (
int ip = 0; ip < ctl->
met_np; ip++)
4912 scan_ctl(filename, argc, argv,
"MET_P", ip,
"", NULL);
4916 (int)
scan_ctl(filename, argc, argv,
"MET_NLEV", -1,
"0", NULL);
4918 ERRMSG(
"Too many model levels!");
4919 for (
int ip = 0; ip < ctl->
met_nlev; ip++) {
4921 scan_ctl(filename, argc, argv,
"MET_LEV_HYAM", ip,
"", NULL);
4923 scan_ctl(filename, argc, argv,
"MET_LEV_HYBM", ip,
"", NULL);
4926 (int)
scan_ctl(filename, argc, argv,
"MET_GEOPOT_SX", -1,
"-1", NULL);
4928 (int)
scan_ctl(filename, argc, argv,
"MET_GEOPOT_SY", -1,
"-1", NULL);
4930 (int)
scan_ctl(filename, argc, argv,
"MET_RELHUM", -1,
"0", NULL);
4932 (int)
scan_ctl(filename, argc, argv,
"MET_CAPE", -1,
"1", NULL);
4934 ERRMSG(
"Set MET_CAPE to 0 or 1!");
4936 (int)
scan_ctl(filename, argc, argv,
"MET_PBL", -1,
"3", NULL);
4938 ERRMSG(
"Set MET_PBL to 0 ... 3!");
4940 scan_ctl(filename, argc, argv,
"MET_PBL_MIN", -1,
"0.1", NULL);
4942 scan_ctl(filename, argc, argv,
"MET_PBL_MAX", -1,
"5.0", NULL);
4944 (int)
scan_ctl(filename, argc, argv,
"MET_TROPO", -1,
"3", NULL);
4946 ERRMSG(
"Set MET_TROPO to 0 ... 5!");
4948 scan_ctl(filename, argc, argv,
"MET_TROPO_PV", -1,
"3.5", NULL);
4950 scan_ctl(filename, argc, argv,
"MET_TROPO_THETA", -1,
"380", NULL);
4952 (int)
scan_ctl(filename, argc, argv,
"MET_TROPO_SPLINE", -1,
"1", NULL);
4954 scan_ctl(filename, argc, argv,
"MET_DT_OUT", -1,
"0.1", NULL);
4956 (int)
scan_ctl(filename, argc, argv,
"MET_CACHE", -1,
"0", NULL);
4958 (int)
scan_ctl(filename, argc, argv,
"MET_MPI_SHARE", -1,
"0", NULL);
4961 ctl->
sort_dt =
scan_ctl(filename, argc, argv,
"SORT_DT", -1,
"-999", NULL);
4965 (int)
scan_ctl(filename, argc, argv,
"ISOSURF", -1,
"0", NULL);
4970 (int)
scan_ctl(filename, argc, argv,
"RNG_TYPE", -1,
"1", NULL);
4972 ERRMSG(
"Set RNG_TYPE to 0, 1, or 2!");
4975 ctl->
advect = (int)
scan_ctl(filename, argc, argv,
"ADVECT", -1,
"2", NULL);
4978 ERRMSG(
"Set ADVECT to 0, 1, 2, or 4!");
4982 = (int)
scan_ctl(filename, argc, argv,
"DIFFUSION", -1,
"0", NULL);
4984 ERRMSG(
"Set DIFFUSION to 0, 1 or 2!");
4986 scan_ctl(filename, argc, argv,
"TURB_DX_PBL", -1,
"50", NULL);
4988 scan_ctl(filename, argc, argv,
"TURB_DX_TROP", -1,
"50", NULL);
4990 scan_ctl(filename, argc, argv,
"TURB_DX_STRAT", -1,
"0", NULL);
4992 scan_ctl(filename, argc, argv,
"TURB_DZ_PBL", -1,
"0", NULL);
4994 scan_ctl(filename, argc, argv,
"TURB_DZ_TROP", -1,
"0", NULL);
4996 scan_ctl(filename, argc, argv,
"TURB_DZ_STRAT", -1,
"0.1", NULL);
4998 scan_ctl(filename, argc, argv,
"TURB_MESOX", -1,
"0.16", NULL);
5000 scan_ctl(filename, argc, argv,
"TURB_MESOZ", -1,
"0.16", NULL);
5004 = (int)
scan_ctl(filename, argc, argv,
"CONV_MIX_PBL", -1,
"0", NULL);
5006 =
scan_ctl(filename, argc, argv,
"CONV_PBL_TRANS", -1,
"0", NULL);
5008 =
scan_ctl(filename, argc, argv,
"CONV_CAPE", -1,
"-999", NULL);
5010 =
scan_ctl(filename, argc, argv,
"CONV_CIN", -1,
"-999", NULL);
5011 ctl->
conv_dt =
scan_ctl(filename, argc, argv,
"CONV_DT", -1,
"-999", NULL);
5015 scan_ctl(filename, argc, argv,
"BOUND_MASS", -1,
"-999", NULL);
5017 scan_ctl(filename, argc, argv,
"BOUND_MASS_TREND", -1,
"0", NULL);
5019 scan_ctl(filename, argc, argv,
"BOUND_VMR", -1,
"-999", NULL);
5021 scan_ctl(filename, argc, argv,
"BOUND_VMR_TREND", -1,
"0", NULL);
5023 scan_ctl(filename, argc, argv,
"BOUND_LAT0", -1,
"-999", NULL);
5025 scan_ctl(filename, argc, argv,
"BOUND_LAT1", -1,
"-999", NULL);
5027 scan_ctl(filename, argc, argv,
"BOUND_P0", -1,
"-999", NULL);
5029 scan_ctl(filename, argc, argv,
"BOUND_P1", -1,
"-999", NULL);
5031 scan_ctl(filename, argc, argv,
"BOUND_DPS", -1,
"-999", NULL);
5033 scan_ctl(filename, argc, argv,
"BOUND_DZS", -1,
"-999", NULL);
5035 scan_ctl(filename, argc, argv,
"BOUND_ZETAS", -1,
"-999", NULL);
5037 (int)
scan_ctl(filename, argc, argv,
"BOUND_PBL", -1,
"0", NULL);
5041 if (strcasecmp(ctl->
species,
"CF2Cl2") == 0) {
5045 }
else if (strcasecmp(ctl->
species,
"CFCl3") == 0) {
5049 }
else if (strcasecmp(ctl->
species,
"CH4") == 0) {
5056 }
else if (strcasecmp(ctl->
species,
"CO") == 0) {
5065 }
else if (strcasecmp(ctl->
species,
"CO2") == 0) {
5069 }
else if (strcasecmp(ctl->
species,
"H2O") == 0) {
5071 }
else if (strcasecmp(ctl->
species,
"N2O") == 0) {
5075 }
else if (strcasecmp(ctl->
species,
"NH3") == 0) {
5082 }
else if (strcasecmp(ctl->
species,
"HNO3") == 0) {
5086 }
else if (strcasecmp(ctl->
species,
"NO") == 0) {
5095 }
else if (strcasecmp(ctl->
species,
"NO2") == 0) {
5104 }
else if (strcasecmp(ctl->
species,
"O3") == 0) {
5111 }
else if (strcasecmp(ctl->
species,
"SF6") == 0) {
5115 }
else if (strcasecmp(ctl->
species,
"SO2") == 0) {
5128 sprintf(defstr,
"%g", ctl->
molmass);
5129 ctl->
molmass =
scan_ctl(filename, argc, argv,
"MOLMASS", -1, defstr, NULL);
5134 (int)
scan_ctl(filename, argc, argv,
"OH_CHEM_REACTION", -1, defstr,
5136 for (
int ip = 0; ip < 4; ip++) {
5137 sprintf(defstr,
"%g", ctl->
oh_chem[ip]);
5139 scan_ctl(filename, argc, argv,
"OH_CHEM", ip, defstr, NULL);
5142 scan_ctl(filename, argc, argv,
"OH_CHEM_BETA", -1,
"0", NULL);
5146 (int)
scan_ctl(filename, argc, argv,
"H2O2_CHEM_REACTION", -1,
"0", NULL);
5150 (int)
scan_ctl(filename, argc, argv,
"KPP_CHEM", -1,
"0", NULL);
5151 ctl->
dt_kpp =
scan_ctl(filename, argc, argv,
"DT_KPP", -1,
"1800", NULL);
5155 (int)
scan_ctl(filename, argc, argv,
"TRACER_CHEM", -1,
"0", NULL);
5158 for (
int ip = 0; ip < 2; ip++) {
5161 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_H", ip, defstr, NULL);
5163 for (
int ip = 0; ip < 1; ip++) {
5166 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_H", ip, defstr, NULL);
5169 scan_ctl(filename, argc, argv,
"WET_DEPO_SO2_PH", -1,
"0", NULL);
5171 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_A", -1,
"0", NULL);
5173 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_B", -1,
"0", NULL);
5175 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_A", -1,
"0", NULL);
5177 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_B", -1,
"0", NULL);
5179 scan_ctl(filename, argc, argv,
"WET_DEPO_PRE", 0,
"0.5", NULL);
5181 scan_ctl(filename, argc, argv,
"WET_DEPO_PRE", 1,
"0.36", NULL);
5183 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_RET_RATIO", -1,
"1", NULL);
5185 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_RET_RATIO", -1,
"1", NULL);
5189 scan_ctl(filename, argc, argv,
"DRY_DEPO_VDEP", -1,
"0", NULL);
5191 scan_ctl(filename, argc, argv,
"DRY_DEPO_DP", -1,
"30", NULL);
5194 scan_ctl(filename, argc, argv,
"CLIM_PHOTO", -1,
5195 "../../data/clams_photolysis_rates.nc", ctl->
clim_photo);
5196 scan_ctl(filename, argc, argv,
"CLIM_HNO3_FILENAME", -1,
5198 scan_ctl(filename, argc, argv,
"CLIM_OH_FILENAME", -1,
5200 scan_ctl(filename, argc, argv,
"CLIM_H2O2_FILENAME", -1,
5202 scan_ctl(filename, argc, argv,
"CLIM_HO2_FILENAME", -1,
5204 scan_ctl(filename, argc, argv,
"CLIM_O1D_FILENAME", -1,
5206 scan_ctl(filename, argc, argv,
"CLIM_CCL4_TIMESERIES", -1,
5208 scan_ctl(filename, argc, argv,
"CLIM_CCL3F_TIMESERIES", -1,
5210 scan_ctl(filename, argc, argv,
"CLIM_CCL2F2_TIMESERIES", -1,
5212 scan_ctl(filename, argc, argv,
"CLIM_N2O_TIMESERIES", -1,
5214 scan_ctl(filename, argc, argv,
"CLIM_SF6_TIMESERIES", -1,
5219 scan_ctl(filename, argc, argv,
"MIXING_DT", -1,
"3600.", NULL);
5221 scan_ctl(filename, argc, argv,
"MIXING_TROP", -1,
"-999", NULL);
5223 scan_ctl(filename, argc, argv,
"MIXING_STRAT", -1,
"-999", NULL);
5225 scan_ctl(filename, argc, argv,
"MIXING_Z0", -1,
"-5", NULL);
5227 scan_ctl(filename, argc, argv,
"MIXING_Z1", -1,
"85", NULL);
5229 (int)
scan_ctl(filename, argc, argv,
"MIXING_NZ", -1,
"90", NULL);
5231 scan_ctl(filename, argc, argv,
"MIXING_LON0", -1,
"-180", NULL);
5233 scan_ctl(filename, argc, argv,
"MIXING_LON1", -1,
"180", NULL);
5235 (int)
scan_ctl(filename, argc, argv,
"MIXING_NX", -1,
"360", NULL);
5237 scan_ctl(filename, argc, argv,
"MIXING_LAT0", -1,
"-90", NULL);
5239 scan_ctl(filename, argc, argv,
"MIXING_LAT1", -1,
"90", NULL);
5241 (int)
scan_ctl(filename, argc, argv,
"MIXING_NY", -1,
"180", NULL);
5245 scan_ctl(filename, argc, argv,
"CHEMGRID_Z0", -1,
"-5", NULL);
5247 scan_ctl(filename, argc, argv,
"CHEMGRID_Z1", -1,
"85", NULL);
5249 (int)
scan_ctl(filename, argc, argv,
"CHEMGRID_NZ", -1,
"90", NULL);
5251 scan_ctl(filename, argc, argv,
"CHEMGRID_LON0", -1,
"-180", NULL);
5253 scan_ctl(filename, argc, argv,
"CHEMGRID_LON1", -1,
"180", NULL);
5255 (int)
scan_ctl(filename, argc, argv,
"CHEMGRID_NX", -1,
"360", NULL);
5257 scan_ctl(filename, argc, argv,
"CHEMGRID_LAT0", -1,
"-90", NULL);
5259 scan_ctl(filename, argc, argv,
"CHEMGRID_LAT1", -1,
"90", NULL);
5261 (int)
scan_ctl(filename, argc, argv,
"CHEMGRID_NY", -1,
"180", NULL);
5266 =
scan_ctl(filename, argc, argv,
"TDEC_STRAT", -1,
"0", NULL);
5269 ctl->
psc_h2o =
scan_ctl(filename, argc, argv,
"PSC_H2O", -1,
"4e-6", NULL);
5271 scan_ctl(filename, argc, argv,
"PSC_HNO3", -1,
"9e-9", NULL);
5277 scan_ctl(filename, argc, argv,
"ATM_DT_OUT", -1,
"86400", NULL);
5279 (int)
scan_ctl(filename, argc, argv,
"ATM_FILTER", -1,
"0", NULL);
5281 (int)
scan_ctl(filename, argc, argv,
"ATM_STRIDE", -1,
"1", NULL);
5283 (int)
scan_ctl(filename, argc, argv,
"ATM_TYPE", -1,
"0", NULL);
5285 (int)
scan_ctl(filename, argc, argv,
"ATM_TYPE_OUT", -1,
"-1", NULL);
5289 (int)
scan_ctl(filename, argc, argv,
"ATM_NC_LEVEL", -1,
"0", NULL);
5290 for (
int iq = 0; iq < ctl->
nq; iq++)
5292 (
int)
scan_ctl(filename, argc, argv,
"ATM_NC_QUANT", iq,
"0", NULL);
5294 (int)
scan_ctl(filename, argc, argv,
"OBS_TYPE", -1,
"0", NULL);
5300 scan_ctl(filename, argc, argv,
"CSI_DT_OUT", -1,
"86400", NULL);
5303 scan_ctl(filename, argc, argv,
"CSI_OBSMIN", -1,
"0", NULL);
5305 scan_ctl(filename, argc, argv,
"CSI_MODMIN", -1,
"0", NULL);
5306 ctl->
csi_z0 =
scan_ctl(filename, argc, argv,
"CSI_Z0", -1,
"-5", NULL);
5307 ctl->
csi_z1 =
scan_ctl(filename, argc, argv,
"CSI_Z1", -1,
"85", NULL);
5308 ctl->
csi_nz = (int)
scan_ctl(filename, argc, argv,
"CSI_NZ", -1,
"1", NULL);
5310 scan_ctl(filename, argc, argv,
"CSI_LON0", -1,
"-180", NULL);
5311 ctl->
csi_lon1 =
scan_ctl(filename, argc, argv,
"CSI_LON1", -1,
"180", NULL);
5313 (int)
scan_ctl(filename, argc, argv,
"CSI_NX", -1,
"360", NULL);
5314 ctl->
csi_lat0 =
scan_ctl(filename, argc, argv,
"CSI_LAT0", -1,
"-90", NULL);
5315 ctl->
csi_lat1 =
scan_ctl(filename, argc, argv,
"CSI_LAT1", -1,
"90", NULL);
5317 (int)
scan_ctl(filename, argc, argv,
"CSI_NY", -1,
"180", NULL);
5322 scan_ctl(filename, argc, argv,
"ENS_DT_OUT", -1,
"86400", NULL);
5325 scan_ctl(filename, argc, argv,
"GRID_BASENAME", -1,
"-",
5330 scan_ctl(filename, argc, argv,
"GRID_DT_OUT", -1,
"86400", NULL);
5332 (int)
scan_ctl(filename, argc, argv,
"GRID_SPARSE", -1,
"0", NULL);
5334 (int)
scan_ctl(filename, argc, argv,
"GRID_NC_LEVEL", -1,
"0", NULL);
5335 for (
int iq = 0; iq < ctl->
nq; iq++)
5337 (
int)
scan_ctl(filename, argc, argv,
"GRID_NC_QUANT", iq,
"0", NULL);
5339 (int)
scan_ctl(filename, argc, argv,
"GRID_STDDEV", -1,
"0", NULL);
5340 ctl->
grid_z0 =
scan_ctl(filename, argc, argv,
"GRID_Z0", -1,
"-5", NULL);
5341 ctl->
grid_z1 =
scan_ctl(filename, argc, argv,
"GRID_Z1", -1,
"85", NULL);
5343 (int)
scan_ctl(filename, argc, argv,
"GRID_NZ", -1,
"1", NULL);
5345 scan_ctl(filename, argc, argv,
"GRID_LON0", -1,
"-180", NULL);
5347 scan_ctl(filename, argc, argv,
"GRID_LON1", -1,
"180", NULL);
5349 (int)
scan_ctl(filename, argc, argv,
"GRID_NX", -1,
"360", NULL);
5351 scan_ctl(filename, argc, argv,
"GRID_LAT0", -1,
"-90", NULL);
5353 scan_ctl(filename, argc, argv,
"GRID_LAT1", -1,
"90", NULL);
5355 (int)
scan_ctl(filename, argc, argv,
"GRID_NY", -1,
"180", NULL);
5357 (int)
scan_ctl(filename, argc, argv,
"GRID_TYPE", -1,
"0", NULL);
5360 scan_ctl(filename, argc, argv,
"PROF_BASENAME", -1,
"-",
5363 ctl->
prof_z0 =
scan_ctl(filename, argc, argv,
"PROF_Z0", -1,
"0", NULL);
5364 ctl->
prof_z1 =
scan_ctl(filename, argc, argv,
"PROF_Z1", -1,
"60", NULL);
5366 (int)
scan_ctl(filename, argc, argv,
"PROF_NZ", -1,
"60", NULL);
5368 scan_ctl(filename, argc, argv,
"PROF_LON0", -1,
"-180", NULL);
5370 scan_ctl(filename, argc, argv,
"PROF_LON1", -1,
"180", NULL);
5372 (int)
scan_ctl(filename, argc, argv,
"PROF_NX", -1,
"360", NULL);
5374 scan_ctl(filename, argc, argv,
"PROF_LAT0", -1,
"-90", NULL);
5376 scan_ctl(filename, argc, argv,
"PROF_LAT1", -1,
"90", NULL);
5378 (int)
scan_ctl(filename, argc, argv,
"PROF_NY", -1,
"180", NULL);
5381 scan_ctl(filename, argc, argv,
"SAMPLE_BASENAME", -1,
"-",
5383 scan_ctl(filename, argc, argv,
"SAMPLE_KERNEL", -1,
"-",
5385 scan_ctl(filename, argc, argv,
"SAMPLE_OBSFILE", -1,
"-",
5388 scan_ctl(filename, argc, argv,
"SAMPLE_DX", -1,
"50", NULL);
5390 scan_ctl(filename, argc, argv,
"SAMPLE_DZ", -1,
"-999", NULL);
5393 scan_ctl(filename, argc, argv,
"STAT_BASENAME", -1,
"-",
5397 ctl->
stat_r =
scan_ctl(filename, argc, argv,
"STAT_R", -1,
"50", NULL);
5399 scan_ctl(filename, argc, argv,
"STAT_T0", -1,
"-1e100", NULL);
5400 ctl->
stat_t1 =
scan_ctl(filename, argc, argv,
"STAT_T1", -1,
"1e100", NULL);
5405 scan_ctl(filename, argc, argv,
"VTK_DT_OUT", -1,
"86400", NULL);
5407 (int)
scan_ctl(filename, argc, argv,
"VTK_STRIDE", -1,
"1", NULL);
5409 scan_ctl(filename, argc, argv,
"VTK_SCALE", -1,
"1.0", NULL);
5411 scan_ctl(filename, argc, argv,
"VTK_OFFSET", -1,
"0.0", NULL);
5413 (int)
scan_ctl(filename, argc, argv,
"VTK_SPHERE", -1,
"0", NULL);
5419 const char *filename,
5425 LOG(1,
"Read meteo data: %s", filename);
5431 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
5451 ERRMSG(
"MET_TYPE not implemented!");
5460 LOG(2,
"Broadcast data on rank %d...", rank);
5589 ERRMSG(
"Code was compiled without KPP!");
5622#pragma acc update device(ctl[:1])
5626 if (cache != NULL) {
5629#pragma acc update device(cache[:1])
5636#pragma acc update device(clim[:1])
5643 met_t *met0up = *met0;
5644#pragma acc update device(met0up[:1])
5651 met_t *met1up = *met1;
5652#pragma acc update device(met1up[:1])
5659#pragma acc update device(atm[:1])
5678#pragma acc update host(ctl[:1])
5682 if (cache != NULL) {
5685#pragma acc update host(cache[:1])
5692#pragma acc update host(clim[:1])
5699 met_t *met0up = *met0;
5700#pragma acc update host(met0up[:1])
5707 met_t *met1up = *met1;
5708#pragma acc update host(met1up[:1])
5715#pragma acc update host(atm[:1])
5723 const char *filename,
5732 LOG(1,
"Write atmospheric data: %s", filename);
5756 ERRMSG(
"Atmospheric data type not supported!");
5760 LOG(2,
"Number of particles: %d", atm->
np);
5761 gsl_stats_minmax(&mini, &maxi, atm->
time, 1, (
size_t) atm->
np);
5762 LOG(2,
"Time range: %.2f ... %.2f s", mini, maxi);
5763 gsl_stats_minmax(&mini, &maxi, atm->
p, 1, (
size_t) atm->
np);
5764 LOG(2,
"Altitude range: %g ... %g km",
Z(maxi),
Z(mini));
5765 LOG(2,
"Pressure range: %g ... %g hPa", maxi, mini);
5766 gsl_stats_minmax(&mini, &maxi, atm->
lon, 1, (
size_t) atm->
np);
5767 LOG(2,
"Longitude range: %g ... %g deg", mini, maxi);
5768 gsl_stats_minmax(&mini, &maxi, atm->
lat, 1, (
size_t) atm->
np);
5769 LOG(2,
"Latitude range: %g ... %g deg", mini, maxi);
5770 for (
int iq = 0; iq < ctl->
nq; iq++) {
5772 sprintf(msg,
"Quantity %s range: %s ... %s %s",
5775 gsl_stats_minmax(&mini, &maxi, atm->
q[iq], 1, (
size_t) atm->
np);
5776 LOG(2, msg, mini, maxi);
5783 const char *filename,
5791 LOG(1,
"Write meteo data: %s", filename);
5796 ERRMSG(
"MPTRAC was compiled without zfp compression!");
5800 ERRMSG(
"MPTRAC was compiled without zstd compression!");
5804 ERRMSG(
"MPTRAC was compiled without cmultiscale compression!");
5817 ERRMSG(
"MET_TYPE not implemented!");
5823 const char *dirname,
5830 char ext[10], filename[2 *
LEN];
5834 int year, mon, day, hour, min, sec;
5837 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
5852 sprintf(ext,
"tab");
5854 sprintf(ext,
"bin");
5857 sprintf(filename,
"%s/%s_%04d_%02d_%02d_%02d_%02d.%s",
5858 dirname, ctl->
atm_basename, year, mon, day, hour, min, ext);
5864 sprintf(filename,
"%s/%s_%04d_%02d_%02d_%02d_%02d.%s",
5867 write_grid(filename, ctl, met0, met1, atm, t);
5872 sprintf(filename,
"%s/%s.tab", dirname, ctl->
csi_basename);
5878 sprintf(filename,
"%s/%s_%04d_%02d_%02d_%02d_%02d.tab",
5879 dirname, ctl->
ens_basename, year, mon, day, hour, min);
5885 sprintf(filename,
"%s/%s.tab", dirname, ctl->
prof_basename);
5886 write_prof(filename, ctl, met0, met1, atm, t);
5897 sprintf(filename,
"%s/%s.tab", dirname, ctl->
stat_basename);
5906 sprintf(filename,
"%s/%s_%05d.vtk", dirname, ctl->
vtk_basename, ++nvtk);
5916 const double hno3) {
5919 const double h2o_help =
MAX(h2o, 0.1e-6);
5922 const double p_hno3 = hno3 * p / 1.333224;
5923 const double p_h2o = h2o_help * p / 1.333224;
5924 const double a = 0.009179 - 0.00088 * log10(p_h2o);
5925 const double b = (38.9855 - log10(p_hno3) - 2.7836 * log10(p_h2o)) / a;
5926 const double c = -11397.0 / a;
5927 double tnat = (-b + sqrt(b * b - 4. * c)) / 2.;
5928 double x2 = (-b - sqrt(b * b - 4. * c)) / 2.;
5946 const double p0 = pbl;
5949 if (atm->
p[ip] > p0)
5951 else if (atm->
p[ip] < p1)
5954 return LIN(p0, 1.0, p1, 0.0, atm->
p[ip]);
5960 const char *filename,
5966 if (!(in = fopen(filename,
"r"))) {
5967 WARN(
"Cannot open file!");
5973 while (fgets(line,
LEN, in)) {
5977 TOK(line, tok,
"%lg", atm->
time[atm->
np]);
5978 TOK(NULL, tok,
"%lg", atm->
p[atm->
np]);
5979 TOK(NULL, tok,
"%lg", atm->
lon[atm->
np]);
5980 TOK(NULL, tok,
"%lg", atm->
lat[atm->
np]);
5981 for (
int iq = 0; iq < ctl->
nq; iq++)
5982 TOK(NULL, tok,
"%lg", atm->
q[iq][atm->
np]);
5985 atm->
p[atm->
np] =
P(atm->
p[atm->
np]);
5988 if ((++atm->
np) >
NP)
5989 ERRMSG(
"Too many data points!");
6002 const char *filename,
6008 if (!(in = fopen(filename,
"r")))
6013 FREAD(&version,
int,
6017 ERRMSG(
"Wrong version of binary data!");
6035 for (
int iq = 0; iq < ctl->
nq; iq++)
6036 FREAD(atm->
q[iq],
double,
6046 ERRMSG(
"Error while reading binary data!");
6058 const char *filename,
6065 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR)
6072 if (nc_inq_varid(ncid,
"TIME_INIT", &varid) == NC_NOERR) {
6073 NC(nc_get_var_double(ncid, varid, atm->
time));
6075 WARN(
"TIME_INIT not found use time instead!");
6078 for (
int ip = 0; ip < atm->
np; ip++) {
6079 atm->
time[ip] = time_init;
6091 if (nc_inq_varid(ncid,
"PRESS_INIT", &varid) == NC_NOERR) {
6092 NC(nc_get_var_double(ncid, varid, atm->
p));
6094 WARN(
"PRESS_INIT not found use PRESS instead!");
6095 nc_inq_varid(ncid,
"PRESS", &varid);
6096 NC(nc_get_var_double(ncid, varid, atm->
p));
6114 const char *filename,
6121 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR)
6134 for (
int iq = 0; iq < ctl->
nq; iq++)
6147 const char *filename,
6153 LOG(1,
"Read photolysis rates: %s", filename);
6156 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
6157 WARN(
"Photolysis rate data are missing!");
6164 if (photo->
p[0] < photo->
p[1])
6165 ERRMSG(
"Pressure data are not descending!");
6170 if (photo->
o3c[0] > photo->
o3c[1])
6171 ERRMSG(
"Total column ozone data are not ascending!");
6176 if (photo->
sza[0] > photo->
sza[1])
6177 ERRMSG(
"Solar zenith angle data are not ascending!");
6194 LOG(2,
"Number of pressure levels: %d", photo->
np);
6195 LOG(2,
"Altitude levels: %g, %g ... %g km",
6196 Z(photo->
p[0]),
Z(photo->
p[1]),
Z(photo->
p[photo->
np - 1]));
6197 LOG(2,
"Pressure levels: %g, %g ... %g hPa",
6198 photo->
p[0], photo->
p[1], photo->
p[photo->
np - 1]);
6199 LOG(2,
"Number of solar zenith angles: %d", photo->
nsza);
6200 LOG(2,
"Solar zenith angles: %g, %g ... %g deg",
6203 LOG(2,
"Number of total column ozone values: %d", photo->
no3c);
6204 LOG(2,
"Total column ozone: %g, %g ... %g DU",
6206 LOG(2,
"N2O photolysis rate: %g, %g ... %g s**-1",
6207 photo->
n2o[0][0][0], photo->
n2o[1][0][0],
6208 photo->
n2o[photo->
np - 1][photo->
nsza - 1][photo->
no3c - 1]);
6209 LOG(2,
"CCl4 photolysis rate: %g, %g ... %g s**-1",
6210 photo->
ccl4[0][0][0], photo->
ccl4[1][0][0],
6212 LOG(2,
"CFC-11 photolysis rate: %g, %g ... %g s**-1",
6213 photo->
ccl3f[0][0][0], photo->
ccl3f[1][0][0],
6215 LOG(2,
"CFC-12 photolysis rate: %g, %g ... %g s**-1",
6218 LOG(2,
"O2 photolysis rate: %g, %g ... %g s**-1",
6219 photo->
o2[0][0][0], photo->
o2[1][0][0],
6220 photo->
o2[photo->
np - 1][photo->
nsza - 1][photo->
no3c - 1]);
6221 LOG(2,
"O3 -> O(1D) photolysis rate: %g, %g ... %g s**-1",
6222 photo->
o3_1[0][0][0], photo->
o3_1[1][0][0],
6224 LOG(2,
"O3 -> O(3P) photolysis rate: %g, %g ... %g s**-1",
6225 photo->
o3_2[0][0][0], photo->
o3_2[1][0][0],
6227 LOG(2,
"H2O2 photolysis rate: %g, %g ... %g s**-1",
6228 photo->
h2o2[0][0][0], photo->
h2o2[1][0][0],
6230 LOG(2,
"H2O photolysis rate: %g, %g ... %g s**-1",
6231 photo->
h2o[0][0][0], photo->
h2o[1][0][0],
6232 photo->
h2o[photo->
np - 1][photo->
nsza - 1][photo->
no3c - 1]);
6239 const char *varname,
6253 for (
int ip = 0; ip < photo->
np; ip++)
6254 for (
int is = 0; is < photo->
nsza; is++)
6255 for (
int io = 0; io < photo->
no3c; io++)
6266 const char *filename,
6270 LOG(1,
"Read climatological time series: %s", filename);
6274 if (!(in = fopen(filename,
"r"))) {
6275 WARN(
"Cannot open file!");
6282 while (fgets(line,
LEN, in))
6283 if (sscanf(line,
"%lg %lg", &ts->
time[nh], &ts->
vmr[nh]) == 2) {
6286 ts->
time[nh] = (ts->
time[nh] - 2000.0) * 365.25 * 86400.;
6289 if (nh > 0 && ts->
time[nh] <= ts->
time[nh - 1])
6290 ERRMSG(
"Time series must be ascending!");
6294 ERRMSG(
"Too many data points!");
6303 ERRMSG(
"Not enough data points!");
6306 LOG(2,
"Number of time steps: %d", ts->
ntime);
6307 LOG(2,
"Time steps: %.2f, %.2f ... %.2f s", ts->
time[0], ts->
time[1],
6309 LOG(2,
"Volume mixing ratio range: %g ... %g ppv",
6310 gsl_stats_min(ts->
vmr, 1, (
size_t) nh), gsl_stats_max(ts->
vmr, 1,
6320 const char *filename,
6321 const char *varname,
6324 int ncid, varid, it, iy, iz, iz2, nt;
6326 double *help, varmin = 1e99, varmax = -1e99;
6329 LOG(1,
"Read %s data: %s", varname, filename);
6332 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
6333 WARN(
"%s climatology data are missing!", varname);
6340 if (zm->
p[0] < zm->
p[1])
6341 ERRMSG(
"Pressure data are not descending!");
6346 if (zm->
lat[0] > zm->
lat[1])
6347 ERRMSG(
"Latitude data are not ascending!");
6351 zm->
time[0] = 1209600.00;
6352 zm->
time[1] = 3888000.00;
6353 zm->
time[2] = 6393600.00;
6354 zm->
time[3] = 9072000.00;
6355 zm->
time[4] = 11664000.00;
6356 zm->
time[5] = 14342400.00;
6357 zm->
time[6] = 16934400.00;
6358 zm->
time[7] = 19612800.00;
6359 zm->
time[8] = 22291200.00;
6360 zm->
time[9] = 24883200.00;
6361 zm->
time[10] = 27561600.00;
6362 zm->
time[11] = 30153600.00;
6371 for (it = 0; it < zm->
ntime; it++)
6372 for (iz = 0; iz < zm->
np; iz++)
6373 for (iy = 0; iy < zm->
nlat; iy++)
6378 for (it = 0; it < zm->
ntime; it++)
6379 for (iy = 0; iy < zm->
nlat; iy++)
6380 for (iz = 0; iz < zm->
np; iz++) {
6381 if (zm->
vmr[it][iz][iy] < 0) {
6382 for (iz2 = 0; iz2 < zm->
np; iz2++)
6383 if (zm->
vmr[it][iz2][iy] >= 0) {
6384 zm->
vmr[it][iz][iy] = zm->
vmr[it][iz2][iy];
6387 for (iz2 = zm->
np - 1; iz2 >= 0; iz2--)
6388 if (zm->
vmr[it][iz2][iy] >= 0) {
6389 zm->
vmr[it][iz][iy] = zm->
vmr[it][iz2][iy];
6393 varmin =
MIN(varmin, zm->
vmr[it][iz][iy]);
6394 varmax =
MAX(varmax, zm->
vmr[it][iz][iy]);
6401 LOG(2,
"Number of time steps: %d", zm->
ntime);
6402 LOG(2,
"Time steps: %.2f, %.2f ... %.2f s",
6404 LOG(2,
"Number of pressure levels: %d", zm->
np);
6405 LOG(2,
"Altitude levels: %g, %g ... %g km",
6406 Z(zm->
p[0]),
Z(zm->
p[1]),
Z(zm->
p[zm->
np - 1]));
6407 LOG(2,
"Pressure levels: %g, %g ... %g hPa", zm->
p[0],
6408 zm->
p[1], zm->
p[zm->
np - 1]);
6409 LOG(2,
"Number of latitudes: %d", zm->
nlat);
6410 LOG(2,
"Latitudes: %g, %g ... %g deg",
6412 LOG(2,
"%s volume mixing ratio range: %g ... %g ppv", varname, varmin,
6419 const char *filename,
6425 LOG(1,
"Read kernel function: %s", filename);
6429 if (!(in = fopen(filename,
"r")))
6430 ERRMSG(
"Cannot open file!");
6435 while (fgets(line,
LEN, in))
6436 if (sscanf(line,
"%lg %lg", &kz[n], &kw[n]) == 2) {
6437 if (n > 0 && kz[n] < kz[n - 1])
6438 ERRMSG(
"Height levels must be ascending!");
6440 ERRMSG(
"Too many height levels!");
6449 ERRMSG(
"Not enough height levels!");
6452 const double kmax = gsl_stats_max(kw, 1, (
size_t) n);
6453 for (
int iz = 0; iz < n; iz++)
6460 const char *filename,
6468 int year, mon, day, hour, min, sec;
6474 if (!(in = fopen(filename,
"r"))) {
6475 WARN(
"Cannot open file!");
6481 FREAD(&met_type,
int,
6485 ERRMSG(
"Wrong MET_TYPE of binary data!");
6489 FREAD(&version,
int,
6493 ERRMSG(
"Wrong version of binary data!");
6499 jsec2time(met->
time, &year, &mon, &day, &hour, &min, &sec, &r);
6500 LOG(2,
"Time: %.2f (%d-%02d-%02d, %02d:%02d UTC)",
6501 met->
time, year, mon, day, hour, min);
6502 if (year < 1900 || year > 2100 || mon < 1 || mon > 12
6503 || day < 1 || day > 31 || hour < 0 || hour > 23)
6504 ERRMSG(
"Error while reading time!");
6510 LOG(2,
"Number of longitudes: %d", met->
nx);
6511 if (met->
nx < 2 || met->
nx >
EX)
6512 ERRMSG(
"Number of longitudes out of range!");
6517 LOG(2,
"Number of latitudes: %d", met->
ny);
6518 if (met->
ny < 2 || met->
ny >
EY)
6519 ERRMSG(
"Number of latitudes out of range!");
6524 LOG(2,
"Number of levels: %d", met->
np);
6525 if (met->
np < 2 || met->
np >
EP)
6526 ERRMSG(
"Number of levels out of range!");
6532 LOG(2,
"Longitudes: %g, %g ... %g deg",
6538 LOG(2,
"Latitudes: %g, %g ... %g deg",
6544 LOG(2,
"Altitude levels: %g, %g ... %g km",
6545 Z(met->
p[0]),
Z(met->
p[1]),
Z(met->
p[met->
np - 1]));
6546 LOG(2,
"Pressure levels: %g, %g ... %g hPa",
6547 met->
p[0], met->
p[1], met->
p[met->
np - 1]);
6596 ERRMSG(
"Error while reading binary data!");
6611 const char *varname) {
6620 LOG(2,
"Read 2-D variable: %s (uncompressed)", varname);
6622 (
size_t) (met->
nx * met->
ny),
6626 for (
int ix = 0; ix < met->
nx; ix++)
6627 for (
int iy = 0; iy < met->
ny; iy++)
6628 var[ix][iy] = help[
ARRAY_2D(ix, iy, met->
ny)];
6641 const char *varname,
6642 const float bound_min,
6643 const float bound_max) {
6653 LOG(2,
"Read 3-D variable: %s (uncompressed)", varname);
6655 (
size_t) (met->
nx * met->
ny * met->
np),
6662 (
size_t) met->
np, 1, in);
6668 FREAD(&precision,
int,
6673 FREAD(&tolerance,
double,
6680 ERRMSG(
"MPTRAC was compiled without zfp compression!");
6690 ERRMSG(
"MPTRAC was compiled without zstd compression!");
6698 (
size_t) met->
np, 1, in);
6700 ERRMSG(
"MPTRAC was compiled without cmultiscale compression!");
6705#pragma omp parallel for default(shared) collapse(2)
6706 for (
int ix = 0; ix < met->
nx; ix++)
6707 for (
int iy = 0; iy < met->
ny; iy++)
6708 for (
int ip = 0; ip < met->
np; ip++) {
6709 var[ix][iy][ip] = help[
ARRAY_3D(ix, iy, met->
ny, ip, met->
np)];
6710 if (var[ix][iy][ip] < bound_min)
6711 var[ix][iy][ip] = bound_min;
6712 else if (var[ix][iy][ip] > bound_max)
6713 var[ix][iy][ip] = bound_max;
6733 LOG(2,
"Calculate CAPE...");
6736 const double pfac = 1.01439, dz0 =
RI /
MA /
G0 * log(pfac);
6739#pragma omp parallel for default(shared) collapse(2)
6740 for (
int ix = 0; ix < met->
nx; ix++)
6741 for (
int iy = 0; iy < met->
ny; iy++) {
6745 double h2o = 0, t, theta = 0;
6746 double pbot =
MIN(met->
ps[ix][iy], met->
p[0]);
6747 double ptop = pbot - 50.;
6748 for (
int ip = 0; ip < met->
np; ip++) {
6749 if (met->
p[ip] <= pbot) {
6750 theta +=
THETA(met->
p[ip], met->
t[ix][iy][ip]);
6751 h2o += met->
h2o[ix][iy][ip];
6754 if (met->
p[ip] < ptop && n > 0)
6761 met->
plcl[ix][iy] = NAN;
6762 met->
plfc[ix][iy] = NAN;
6763 met->
pel[ix][iy] = NAN;
6764 met->
cape[ix][iy] = NAN;
6765 met->
cin[ix][iy] = NAN;
6771 pbot = met->
ps[ix][iy];
6773 met->
plcl[ix][iy] = (float) (0.5 * (pbot + ptop));
6774 t = theta / pow(1000. / met->
plcl[ix][iy], 0.286);
6775 if (
RH(met->
plcl[ix][iy], t, h2o) > 100.)
6776 ptop = met->
plcl[ix][iy];
6778 pbot = met->
plcl[ix][iy];
6779 }
while (pbot - ptop > 0.1);
6783 double dcape, dz, h2o_env, t_env;
6784 double p = met->
ps[ix][iy];
6785 met->
cape[ix][iy] = met->
cin[ix][iy] = 0;
6787 dz = dz0 *
TVIRT(t, h2o);
6789 t = theta / pow(1000. / p, 0.286);
6793 &h2o_env, ci, cw, 0);
6794 dcape = 1e3 *
G0 * (
TVIRT(t, h2o) -
TVIRT(t_env, h2o_env)) /
6795 TVIRT(t_env, h2o_env) * dz;
6797 met->
cin[ix][iy] += fabsf((
float) dcape);
6798 }
while (p > met->
plcl[ix][iy]);
6803 p = met->
plcl[ix][iy];
6804 t = theta / pow(1000. / p, 0.286);
6807 dz = dz0 *
TVIRT(t, h2o);
6810 double psat =
PSAT(t);
6811 h2o = psat / (p - (1. -
EPS) * psat);
6815 &h2o_env, ci, cw, 0);
6816 double dcape_old = dcape;
6817 dcape = 1e3 *
G0 * (
TVIRT(t, h2o) -
TVIRT(t_env, h2o_env)) /
6818 TVIRT(t_env, h2o_env) * dz;
6820 met->
cape[ix][iy] += (float) dcape;
6821 if (!isfinite(met->
plfc[ix][iy]))
6822 met->
plfc[ix][iy] = (
float) p;
6823 }
else if (dcape_old > 0)
6824 met->
pel[ix][iy] = (float) p;
6825 if (dcape < 0 && !isfinite(met->
plfc[ix][iy]))
6826 met->
cin[ix][iy] += fabsf((
float) dcape);
6830 if (!isfinite(met->
plfc[ix][iy]))
6831 met->
cin[ix][iy] = NAN;
6842 LOG(2,
"Calculate cloud data...");
6845 const double ccmin = 0.01, cwmin = 1e-6;
6848#pragma omp parallel for default(shared) collapse(2)
6849 for (
int ix = 0; ix < met->
nx; ix++)
6850 for (
int iy = 0; iy < met->
ny; iy++) {
6853 met->
pct[ix][iy] = NAN;
6854 met->
pcb[ix][iy] = NAN;
6855 met->
cl[ix][iy] = 0;
6858 for (
int ip = 0; ip < met->
np - 1; ip++) {
6861 if (met->
p[ip] > met->
ps[ix][iy] || met->
p[ip] <
P(20.))
6865 if (met->
cc[ix][iy][ip] > ccmin
6866 && (met->
lwc[ix][iy][ip] > cwmin
6867 || met->
rwc[ix][iy][ip] > cwmin
6868 || met->
iwc[ix][iy][ip] > cwmin
6869 || met->
swc[ix][iy][ip] > cwmin)) {
6873 = (float) (0.5 * (met->
p[ip] + (
float) met->
p[ip + 1]));
6876 if (!isfinite(met->
pcb[ix][iy]))
6878 = (
float) (0.5 * (met->
p[ip] + met->
p[
MAX(ip - 1, 0)]));
6882 met->
cl[ix][iy] += (float)
6883 (0.5 * (met->
lwc[ix][iy][ip] + met->
lwc[ix][iy][ip + 1]
6884 + met->
rwc[ix][iy][ip] + met->
rwc[ix][iy][ip + 1]
6885 + met->
iwc[ix][iy][ip] + met->
iwc[ix][iy][ip + 1]
6886 + met->
swc[ix][iy][ip] + met->
swc[ix][iy][ip + 1])
6887 * 100. * (met->
p[ip] - met->
p[ip + 1]) /
G0);
6905 SELECT_TIMER(
"READ_MET_DETREND",
"METPROC", NVTX_READ);
6906 LOG(2,
"Detrend meteo data...");
6913 const double tssq = 2. *
SQR(sigma);
6916 int sy = (int) (3. *
DY2DEG(sigma) / fabs(met->
lat[1] - met->
lat[0]));
6920#pragma omp parallel for default(shared) collapse(2)
6921 for (
int ix = 0; ix < met->
nx; ix++) {
6922 for (
int iy = 0; iy < met->
ny; iy++) {
6930 (int) (3. *
DX2DEG(sigma, met->
lat[iy]) /
6931 fabs(met->
lon[1] - met->
lon[0]));
6936 for (
int ip = 0; ip < met->
np; ip++) {
6937 help->
t[ix][iy][ip] = 0;
6938 help->
u[ix][iy][ip] = 0;
6939 help->
v[ix][iy][ip] = 0;
6940 help->
w[ix][iy][ip] = 0;
6944 for (
int ix2 = ix - sx; ix2 <= ix + sx; ix2++) {
6948 else if (ix3 >= met->
nx)
6950 for (
int iy2 =
MAX(iy - sy, 0);
6951 iy2 <=
MIN(iy + sy, met->
ny - 1); iy2++) {
6958 const float w = (float) exp(-
DIST2(x0, x1) / tssq);
6962 for (
int ip = 0; ip < met->
np; ip++) {
6963 help->
t[ix][iy][ip] += w * met->
t[ix3][iy2][ip];
6964 help->
u[ix][iy][ip] += w * met->
u[ix3][iy2][ip];
6965 help->
v[ix][iy][ip] += w * met->
v[ix3][iy2][ip];
6966 help->
w[ix][iy][ip] += w * met->
w[ix3][iy2][ip];
6972 for (
int ip = 0; ip < met->
np; ip++) {
6973 help->
t[ix][iy][ip] /= wsum;
6974 help->
u[ix][iy][ip] /= wsum;
6975 help->
v[ix][iy][ip] /= wsum;
6976 help->
w[ix][iy][ip] /= wsum;
6982#pragma omp parallel for default(shared) collapse(3)
6983 for (
int ix = 0; ix < met->
nx; ix++)
6984 for (
int iy = 0; iy < met->
ny; iy++)
6985 for (
int ip = 0; ip < met->
np; ip++) {
6986 met->
t[ix][iy][ip] -= help->
t[ix][iy][ip];
6987 met->
u[ix][iy][ip] -= help->
u[ix][iy][ip];
6988 met->
v[ix][iy][ip] -= help->
v[ix][iy][ip];
6989 met->
w[ix][iy][ip] -= help->
w[ix][iy][ip];
7002 SELECT_TIMER(
"READ_MET_EXTRAPOLATE",
"METPROC", NVTX_READ);
7003 LOG(2,
"Extrapolate meteo data...");
7006#pragma omp parallel for default(shared) collapse(2)
7007 for (
int ix = 0; ix < met->
nx; ix++)
7008 for (
int iy = 0; iy < met->
ny; iy++) {
7012 for (ip0 = met->
np - 1; ip0 >= 0; ip0--)
7013 if (!isfinite(met->
t[ix][iy][ip0])
7014 || !isfinite(met->
u[ix][iy][ip0])
7015 || !isfinite(met->
v[ix][iy][ip0])
7016 || !isfinite(met->
w[ix][iy][ip0]))
7020 for (
int ip = ip0; ip >= 0; ip--) {
7021 met->
t[ix][iy][ip] = met->
t[ix][iy][ip + 1];
7022 met->
u[ix][iy][ip] = met->
u[ix][iy][ip + 1];
7023 met->
v[ix][iy][ip] = met->
v[ix][iy][ip + 1];
7024 met->
w[ix][iy][ip] = met->
w[ix][iy][ip + 1];
7025 met->
h2o[ix][iy][ip] = met->
h2o[ix][iy][ip + 1];
7026 met->
o3[ix][iy][ip] = met->
o3[ix][iy][ip + 1];
7027 met->
lwc[ix][iy][ip] = met->
lwc[ix][iy][ip + 1];
7028 met->
rwc[ix][iy][ip] = met->
rwc[ix][iy][ip + 1];
7029 met->
iwc[ix][iy][ip] = met->
iwc[ix][iy][ip + 1];
7030 met->
swc[ix][iy][ip] = met->
swc[ix][iy][ip + 1];
7031 met->
cc[ix][iy][ip] = met->
cc[ix][iy][ip + 1];
7050 LOG(2,
"Calculate geopotential heights...");
7057#pragma omp parallel for default(shared)
7058 for (
int ip = 0; ip < met->
np; ip++)
7059 logp[ip] = log(met->
p[ip]);
7062#pragma omp parallel for default(shared) collapse(2)
7063 for (
int ix = 0; ix < met->
nx; ix++)
7064 for (
int iy = 0; iy < met->
ny; iy++) {
7067 const double zs = met->
zs[ix][iy];
7068 const double lnps = log(met->
ps[ix][iy]);
7072 const double ts =
LIN(met->
p[ip0], met->
t[ix][iy][ip0], met->
p[ip0 + 1],
7073 met->
t[ix][iy][ip0 + 1], met->
ps[ix][iy]);
7075 LIN(met->
p[ip0], met->
h2o[ix][iy][ip0], met->
p[ip0 + 1],
7076 met->
h2o[ix][iy][ip0 + 1], met->
ps[ix][iy]);
7079 met->
z[ix][iy][ip0 + 1]
7081 ZDIFF(lnps, ts, h2os, logp[ip0 + 1],
7082 met->
t[ix][iy][ip0 + 1], met->
h2o[ix][iy][ip0 + 1]));
7083 for (
int ip = ip0 + 2; ip < met->
np; ip++)
7085 = (
float) (met->
z[ix][iy][ip - 1] +
7086 ZDIFF(logp[ip - 1], met->
t[ix][iy][ip - 1],
7087 met->
h2o[ix][iy][ip - 1], logp[ip],
7088 met->
t[ix][iy][ip], met->
h2o[ix][iy][ip]));
7093 ZDIFF(lnps, ts, h2os, logp[ip0],
7094 met->
t[ix][iy][ip0], met->
h2o[ix][iy][ip0]));
7095 for (
int ip = ip0 - 1; ip >= 0; ip--)
7097 = (
float) (met->
z[ix][iy][ip + 1] +
7098 ZDIFF(logp[ip + 1], met->
t[ix][iy][ip + 1],
7099 met->
h2o[ix][iy][ip + 1], logp[ip],
7100 met->
t[ix][iy][ip], met->
h2o[ix][iy][ip]));
7104 if (dx == 0 || dy == 0)
7108 if (dx < 0 || dy < 0) {
7109 if (fabs(met->
lon[1] - met->
lon[0]) < 0.5) {
7119 float ws[dx + 1][dy + 1];
7120#pragma omp parallel for default(shared) collapse(2)
7121 for (
int ix = 0; ix <= dx; ix++)
7122 for (
int iy = 0; iy < dy; iy++)
7123 ws[ix][iy] = (1.0f - (
float) ix / (float) dx)
7124 * (1.0f - (float) iy / (
float) dy);
7127#pragma omp parallel for default(shared) collapse(3)
7128 for (
int ix = 0; ix < met->
nx; ix++)
7129 for (
int iy = 0; iy < met->
ny; iy++)
7130 for (
int ip = 0; ip < met->
np; ip++)
7131 help[
ARRAY_3D(ip, ix, met->
nx, iy, met->
ny)] = met->
z[ix][iy][ip];
7134#pragma omp parallel for default(shared) collapse(3)
7135 for (
int ip = 0; ip < met->
np; ip++)
7136 for (
int ix = 0; ix < met->
nx; ix++)
7137 for (
int iy = 0; iy < met->
ny; iy++) {
7138 float res = 0, wsum = 0;
7139 int iy0 =
MAX(iy - dy + 1, 0);
7140 int iy1 =
MIN(iy + dy - 1, met->
ny - 1);
7141 for (
int ix2 = ix - dx + 1; ix2 <= ix + dx - 1; ++ix2) {
7145 else if (ix3 >= met->
nx)
7147 for (
int iy2 = iy0; iy2 <= iy1; ++iy2)
7148 if (isfinite(help[
ARRAY_3D(ip, ix3, met->
nx, iy2, met->
ny)])) {
7149 float w = ws[abs(ix - ix2)][abs(iy - iy2)];
7150 res += w * help[
ARRAY_3D(ip, ix3, met->
nx, iy2, met->
ny)];
7155 met->
z[ix][iy][ip] = res / wsum;
7157 met->
z[ix][iy][ip] = NAN;
7167 const char *filename,
7172 char levname[
LEN], tstr[10];
7174 double rtime = 0, r, r2;
7176 int varid, year2, mon2, day2, hour2, min2, sec2,
7177 year, mon, day, hour, min, sec;
7183 LOG(2,
"Read meteo grid information...");
7192 jsec2time(met->
time, &year, &mon, &day, &hour, &min, &sec, &r);
7193 if (nc_inq_varid(ncid,
"time", &varid) == NC_NOERR) {
7194 NC(nc_get_var_double(ncid, varid, &rtime));
7195 if (fabs(year * 10000. + mon * 100. + day + hour / 24. - rtime) > 1.0)
7196 WARN(
"Time information in meteo file does not match filename!");
7198 WARN(
"Time information in meteo file is missing!");
7209 sprintf(tstr,
"19%.2s", &filename[strlen(filename) - 11]);
7211 sprintf(tstr,
"20%.2s", &filename[strlen(filename) - 11]);
7213 sprintf(tstr,
"%.2s", &filename[strlen(filename) - 9]);
7215 sprintf(tstr,
"%.2s", &filename[strlen(filename) - 7]);
7217 sprintf(tstr,
"%.2s", &filename[strlen(filename) - 5]);
7223 if (year < 1900 || year > 2100 || mon < 1 || mon > 12
7224 || day < 1 || day > 31 || hour < 0 || hour > 23)
7225 ERRMSG(
"Cannot read time from filename!");
7226 jsec2time(met->
time, &year2, &mon2, &day2, &hour2, &min2, &sec2, &r2);
7227 LOG(2,
"Time: %.2f (%d-%02d-%02d, %02d:%02d UTC)",
7228 met->
time, year2, mon2, day2, hour2, min2);
7232 LOG(2,
"Number of longitudes: %d", met->
nx);
7235 LOG(2,
"Number of latitudes: %d", met->
ny);
7238 sprintf(levname,
"lev");
7239 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR)
7240 sprintf(levname,
"plev");
7241 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR)
7242 sprintf(levname,
"hybrid");
7243 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR)
7244 sprintf(levname,
"hybrid_level");
7248 sprintf(levname,
"lev_2");
7249 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR) {
7250 sprintf(levname,
"plev");
7251 NC(nc_inq_dimid(ncid, levname, &dimid2));
7253 NC(nc_inq_dimlen(ncid, dimid2, &np));
7256 LOG(2,
"Number of levels: %d", met->
np);
7257 if (met->
np < 2 || met->
np >
EP)
7258 ERRMSG(
"Number of levels out of range!");
7262 LOG(2,
"Longitudes: %g, %g ... %g deg",
7265 LOG(2,
"Latitudes: %g, %g ... %g deg",
7269 for (
int ix = 2; ix < met->
nx; ix++)
7271 (fabs(met->
lon[ix] - met->
lon[ix - 1]) -
7272 fabs(met->
lon[1] - met->
lon[0])) > 0.001)
7273 ERRMSG(
"No regular grid spacing in longitudes!");
7274 for (
int iy = 2; iy < met->
ny; iy++)
7276 (fabs(met->
lat[iy] - met->
lat[iy - 1]) -
7277 fabs(met->
lat[1] - met->
lat[0])) > 0.001) {
7278 WARN(
"No regular grid spacing in latitudes!");
7285 for (
int ip = 0; ip < met->
np; ip++)
7287 LOG(2,
"Altitude levels: %g, %g ... %g km",
7288 Z(met->
p[0]),
Z(met->
p[1]),
Z(met->
p[met->
np - 1]));
7289 LOG(2,
"Pressure levels: %g, %g ... %g hPa",
7290 met->
p[0], met->
p[1], met->
p[met->
np - 1]);
7294 if (strcasecmp(levname,
"hybrid") == 0)
7307 LOG(2,
"Read level data...");
7310 if (!
read_met_nc_3d(ncid,
"t",
"T",
"temp",
"TEMP", ctl, met, met->
t, 1.0))
7311 ERRMSG(
"Cannot read temperature!");
7314 if (!
read_met_nc_3d(ncid,
"u",
"U", NULL, NULL, ctl, met, met->
u, 1.0))
7315 ERRMSG(
"Cannot read zonal wind!");
7316 if (!
read_met_nc_3d(ncid,
"v",
"V", NULL, NULL, ctl, met, met->
v, 1.0))
7317 ERRMSG(
"Cannot read meridional wind!");
7319 (ncid,
"w",
"W",
"omega",
"OMEGA", ctl, met, met->
w, 0.01f))
7320 WARN(
"Cannot read vertical velocity!");
7325 (ncid,
"q",
"Q",
"sh",
"SH", ctl, met, met->
h2o, (
float) (
MA /
MH2O)))
7326 WARN(
"Cannot read specific humidity!");
7329 (ncid,
"rh",
"RH", NULL, NULL, ctl, met, met->
h2o, 0.01f))
7330 WARN(
"Cannot read relative humidity!");
7331#pragma omp parallel for default(shared) collapse(2)
7332 for (
int ix = 0; ix < met->
nx; ix++)
7333 for (
int iy = 0; iy < met->
ny; iy++)
7334 for (
int ip = 0; ip < met->
np; ip++) {
7335 double pw = met->
h2o[ix][iy][ip] *
PSAT(met->
t[ix][iy][ip]);
7336 met->
h2o[ix][iy][ip] =
7337 (float) (pw / (met->
p[ip] - (1.0 -
EPS) * pw));
7343 (ncid,
"o3",
"O3", NULL, NULL, ctl, met, met->
o3, (
float) (
MA /
MO3)))
7344 WARN(
"Cannot read ozone data!");
7348 (ncid,
"clwc",
"CLWC", NULL, NULL, ctl, met, met->
lwc, 1.0))
7349 WARN(
"Cannot read cloud liquid water content!");
7351 (ncid,
"crwc",
"CRWC", NULL, NULL, ctl, met, met->
rwc, 1.0))
7352 WARN(
"Cannot read cloud rain water content!");
7354 (ncid,
"ciwc",
"CIWC", NULL, NULL, ctl, met, met->
iwc, 1.0))
7355 WARN(
"Cannot read cloud ice water content!");
7357 (ncid,
"cswc",
"CSWC", NULL, NULL, ctl, met, met->
swc, 1.0))
7358 WARN(
"Cannot read cloud snow water content!");
7360 WARN(
"Cannot read cloud cover!");
7364 (ncid,
"ZETA",
"zeta", NULL, NULL, ctl, met, met->
zetal, 1.0))
7365 WARN(
"Cannot read ZETA!");
7367 (ncid,
"ZETA_DOT_TOT",
"ZETA_DOT_clr",
"zeta_dot_clr",
7368 NULL, ctl, met, met->
zeta_dotl, 0.00001157407f))
7369 WARN(
"Cannot read ZETA_DOT!");
7373 for (
int ix = 0; ix < met->
nx; ix++)
7374 for (
int iy = 0; iy < met->
ny; iy++)
7375 for (
int ip = 0; ip < met->
np; ip++) {
7376 met->
ul[ix][iy][ip] = met->
u[ix][iy][ip];
7377 met->
vl[ix][iy][ip] = met->
v[ix][iy][ip];
7378 met->
wl[ix][iy][ip] = met->
w[ix][iy][ip];
7391 (ncid,
"pl",
"PL",
"pressure",
"PRESSURE", ctl, met, met->
pl,
7394 (ncid,
"press",
"PRESS", NULL, NULL, ctl, met, met->
pl, 1.0))
7395 ERRMSG(
"Cannot read pressure on model levels!");
7402 double hyam[
EP], hybm[
EP];
7407 if (nc_inq_varid(ncid,
"hyam", &varid) == NC_NOERR
7408 && nc_inq_varid(ncid,
"hybm", &varid) == NC_NOERR) {
7411 }
else if (nc_inq_varid(ncid,
"a_hybrid_level", &varid) == NC_NOERR
7412 && nc_inq_varid(ncid,
"b_hybrid_level",
7413 &varid) == NC_NOERR) {
7417 ERRMSG(
"Cannot read a and b level coefficients from netCDF file!");
7425 ERRMSG(
"Mismatch in number of model levels!");
7428 for (
int ip = 0; ip < met->
np; ip++) {
7435 for (
int ix = 0; ix < met->
nx; ix++)
7436 for (
int iy = 0; iy < met->
ny; iy++)
7437 for (
int ip = 0; ip < met->
np; ip++)
7438 met->
pl[ix][iy][ip] =
7439 (
float) (hyam[ip] / 100. + hybm[ip] * met->
ps[ix][iy]);
7446 double hyam[
EP], hybm[
EP];
7449 for (
int ip = 0; ip < met->
np + 1; ip++) {
7456 ERRMSG(
"Mismatch in number of model levels!");
7459#pragma omp parallel for default(shared) collapse(2)
7460 for (
int ix = 0; ix < met->
nx; ix++)
7461 for (
int iy = 0; iy < met->
ny; iy++)
7462 for (
int ip = 0; ip < met->
np; ip++) {
7463 double p0 = hyam[ip] / 100. + hybm[ip] * met->
ps[ix][iy];
7464 double p1 = hyam[ip + 1] / 100. + hybm[ip + 1] * met->
ps[ix][iy];
7465 met->
pl[ix][iy][ip] = (float) ((p1 - p0) / log(p1 / p0));
7470 for (
int ix = 0; ix < met->
nx; ix++)
7471 for (
int iy = 0; iy < met->
ny; iy++)
7472 for (
int ip = 1; ip < met->
np; ip++)
7473 if ((met->
pl[ix][iy][0] > met->
pl[ix][iy][1]
7474 && met->
pl[ix][iy][ip - 1] <= met->
pl[ix][iy][ip])
7475 || (met->
pl[ix][iy][0] < met->
pl[ix][iy][1]
7476 && met->
pl[ix][iy][ip - 1] >= met->
pl[ix][iy][ip]))
7477 ERRMSG(
"Pressure profiles are not monotonic!");
7484 if (met->
pl[0][0][0] <= 0)
7485 ERRMSG(
"Pressure on model levels is missing, check MET_VERT_COORD!");
7502 for (
int ip = 0; ip < met->
np; ip++)
7503 met->
p[ip] = ctl->
met_p[ip];
7507 for (
int ip = 1; ip < met->
np; ip++)
7508 if (met->
p[ip - 1] < met->
p[ip])
7509 ERRMSG(
"Pressure levels must be descending!");
7518 const char *varname) {
7520 double aux[
EP], p[
EP];
7524 LOG(2,
"Interpolate meteo data to pressure levels: %s", varname);
7527#pragma omp parallel for default(shared) private(aux,p) collapse(2)
7528 for (
int ix = 0; ix < met->
nx; ix++)
7529 for (
int iy = 0; iy < met->
ny; iy++) {
7532 for (
int ip = 0; ip < met->
np; ip++)
7533 p[ip] = met->
pl[ix][iy][ip];
7536 for (
int ip = 0; ip < ctl->
met_np; ip++) {
7537 double pt = ctl->
met_p[ip];
7538 if ((pt > p[0] && p[0] > p[1]) || (pt < p[0] && p[0] < p[1]))
7540 else if ((pt > p[met->
np - 1] && p[1] > p[0])
7541 || (pt < p[met->
np - 1] && p[1] < p[0]))
7542 pt = p[met->
np - 1];
7544 aux[ip] =
LIN(p[ip2], var[ix][iy][ip2],
7545 p[ip2 + 1], var[ix][iy][ip2 + 1], pt);
7549 for (
int ip = 0; ip < ctl->
met_np; ip++)
7550 var[ix][iy][ip] = (
float) aux[ip];
7565 SELECT_TIMER(
"READ_MET_MONOTONIZE",
"METPROC", NVTX_READ);
7566 LOG(2,
"Make zeta profiles monotone...");
7569#pragma omp parallel for default(shared) collapse(2)
7570 for (
int i = 0; i < met->
nx; i++)
7571 for (
int j = 0; j < met->
ny; j++) {
7574 while (k < met->npl) {
7575 if ((met->
zetal[i][j][k - 1] >= met->
zetal[i][j][k])) {
7581 while ((met->
zetal[i][j][k - 1] >=
7582 met->
zetal[i][j][k + l]) & (k + l < met->npl));
7587 (float) (met->
zetal[i][j][k + l] - met->
zetal[i][j][k - 1])
7590 for (
int m = k; m < k + l; m++) {
7591 float d = (float) (met->
hybrid[m] - met->
hybrid[k - 1]);
7592 met->
zetal[i][j][m] = s * d + met->
zetal[i][j][k - 1];
7604#pragma omp parallel for default(shared) collapse(2)
7605 for (
int i = 0; i < met->
nx; i++)
7606 for (
int j = 0; j < met->
ny; j++) {
7609 while (k < met->npl) {
7610 if ((met->
pl[i][j][k - 1] <= met->
pl[i][j][k])) {
7617 while ((met->
pl[i][j][k - 1] <= met->
pl[i][j][k + l]) & (k + l <
7622 float s = (float) (met->
pl[i][j][k + l] - met->
pl[i][j][k - 1])
7625 for (
int m = k; m < k + l; m++) {
7626 float d = (float) (met->
hybrid[m] - met->
hybrid[k - 1]);
7627 met->
pl[i][j][m] = s * d + met->
pl[i][j][k - 1];
7642 const char *filename,
7650 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
7651 WARN(
"Cannot open file!");
7714 const char *varname,
7715 const char *varname2,
7716 const char *varname3,
7717 const char *varname4,
7718 const char *varname5,
7719 const char *varname6,
7728 float offset, scalfac;
7733 if (nc_inq_varid(ncid, varname, &varid) == NC_NOERR)
7734 sprintf(varsel,
"%s", varname);
7735 else if (varname2 != NULL
7736 && nc_inq_varid(ncid, varname2, &varid) == NC_NOERR)
7737 sprintf(varsel,
"%s", varname2);
7738 else if (varname3 != NULL
7739 && nc_inq_varid(ncid, varname3, &varid) == NC_NOERR)
7740 sprintf(varsel,
"%s", varname3);
7741 else if (varname4 != NULL
7742 && nc_inq_varid(ncid, varname4, &varid) == NC_NOERR)
7743 sprintf(varsel,
"%s", varname4);
7744 else if (varname5 != NULL
7745 && nc_inq_varid(ncid, varname5, &varid) == NC_NOERR)
7746 sprintf(varsel,
"%s", varname5);
7747 else if (varname6 != NULL
7748 && nc_inq_varid(ncid, varname6, &varid) == NC_NOERR)
7749 sprintf(varsel,
"%s", varname6);
7755 && nc_get_att_float(ncid, varid,
"add_offset", &offset) == NC_NOERR
7756 && nc_get_att_float(ncid, varid,
"scale_factor",
7757 &scalfac) == NC_NOERR) {
7765 short fillval, missval;
7766 if (nc_get_att_short(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
7768 if (nc_get_att_short(ncid, varid,
"missing_value", &missval) != NC_NOERR)
7772 LOG(2,
"Read 2-D variable: %s"
7773 " (FILL = %d, MISS = %d, SCALE = %g, OFFSET = %g)",
7774 varsel, fillval, missval, scalfac, offset);
7777 NC(nc_get_var_short(ncid, varid, help));
7781 ERRMSG(
"Meteo data layout not implemented for packed netCDF files!");
7784#pragma omp parallel for default(shared) num_threads(12)
7785 for (
int ix = 0; ix < met->
nx; ix++)
7786 for (
int iy = 0; iy < met->
ny; iy++) {
7789 const short aux = help[
ARRAY_2D(iy, ix, met->
nx)];
7790 if ((fillval == 0 || aux != fillval)
7791 && (missval == 0 || aux != missval)
7792 && fabsf(aux * scalfac + offset) < 1e14f)
7793 dest[ix][iy] += scl * (aux * scalfac + offset);
7811 float fillval, missval;
7812 if (nc_get_att_float(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
7814 if (nc_get_att_float(ncid, varid,
"missing_value", &missval) != NC_NOERR)
7818 LOG(2,
"Read 2-D variable: %s (FILL = %g, MISS = %g)",
7819 varsel, fillval, missval);
7822 NC(nc_get_var_float(ncid, varid, help));
7828#pragma omp parallel for default(shared) num_threads(12)
7829 for (
int ix = 0; ix < met->
nx; ix++)
7830 for (
int iy = 0; iy < met->
ny; iy++) {
7833 const float aux = help[
ARRAY_2D(iy, ix, met->
nx)];
7834 if ((fillval == 0 || aux != fillval)
7835 && (missval == 0 || aux != missval)
7836 && fabsf(aux) < 1e14f)
7837 dest[ix][iy] += scl * aux;
7845#pragma omp parallel for default(shared) num_threads(12)
7846 for (
int iy = 0; iy < met->
ny; iy++)
7847 for (
int ix = 0; ix < met->
nx; ix++) {
7850 const float aux = help[
ARRAY_2D(ix, iy, met->
ny)];
7851 if ((fillval == 0 || aux != fillval)
7852 && (missval == 0 || aux != missval)
7853 && fabsf(aux) < 1e14f)
7854 dest[ix][iy] += scl * aux;
7872 const char *varname,
7873 const char *varname2,
7874 const char *varname3,
7875 const char *varname4,
7883 float offset, scalfac;
7888 if (nc_inq_varid(ncid, varname, &varid) == NC_NOERR)
7889 sprintf(varsel,
"%s", varname);
7890 else if (varname2 != NULL
7891 && nc_inq_varid(ncid, varname2, &varid) == NC_NOERR)
7892 sprintf(varsel,
"%s", varname2);
7893 else if (varname3 != NULL
7894 && nc_inq_varid(ncid, varname3, &varid) == NC_NOERR)
7895 sprintf(varsel,
"%s", varname3);
7896 else if (varname4 != NULL
7897 && nc_inq_varid(ncid, varname4, &varid) == NC_NOERR)
7898 sprintf(varsel,
"%s", varname4);
7904 && nc_get_att_float(ncid, varid,
"add_offset", &offset) == NC_NOERR
7905 && nc_get_att_float(ncid, varid,
"scale_factor",
7906 &scalfac) == NC_NOERR) {
7914 short fillval, missval;
7915 if (nc_get_att_short(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
7917 if (nc_get_att_short(ncid, varid,
"missing_value", &missval) != NC_NOERR)
7921 LOG(2,
"Read 3-D variable: %s "
7922 "(FILL = %d, MISS = %d, SCALE = %g, OFFSET = %g)",
7923 varsel, fillval, missval, scalfac, offset);
7926 NC(nc_get_var_short(ncid, varid, help));
7930 ERRMSG(
"Meteo data layout not implemented for packed netCDF files!");
7933#pragma omp parallel for default(shared) num_threads(12)
7934 for (
int ix = 0; ix < met->
nx; ix++)
7935 for (
int iy = 0; iy < met->
ny; iy++)
7936 for (
int ip = 0; ip < met->
np; ip++) {
7937 const short aux = help[
ARRAY_3D(ip, iy, met->
ny, ix, met->
nx)];
7938 if ((fillval == 0 || aux != fillval)
7939 && (missval == 0 || aux != missval)
7940 && fabsf(aux * scalfac + offset) < 1e14f)
7941 dest[ix][iy][ip] = scl * (aux * scalfac + offset);
7943 dest[ix][iy][ip] = NAN;
7959 float fillval, missval;
7960 if (nc_get_att_float(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
7962 if (nc_get_att_float(ncid, varid,
"missing_value", &missval) != NC_NOERR)
7966 LOG(2,
"Read 3-D variable: %s (FILL = %g, MISS = %g)",
7967 varsel, fillval, missval);
7970 NC(nc_get_var_float(ncid, varid, help));
7976#pragma omp parallel for default(shared) num_threads(12)
7977 for (
int ix = 0; ix < met->
nx; ix++)
7978 for (
int iy = 0; iy < met->
ny; iy++)
7979 for (
int ip = 0; ip < met->
np; ip++) {
7980 const float aux = help[
ARRAY_3D(ip, iy, met->
ny, ix, met->
nx)];
7981 if ((fillval == 0 || aux != fillval)
7982 && (missval == 0 || aux != missval)
7983 && fabsf(aux) < 1e14f)
7984 dest[ix][iy][ip] = scl * aux;
7986 dest[ix][iy][ip] = NAN;
7992#pragma omp parallel for default(shared) num_threads(12)
7993 for (
int ip = 0; ip < met->
np; ip++)
7994 for (
int iy = 0; iy < met->
ny; iy++)
7995 for (
int ix = 0; ix < met->
nx; ix++) {
7996 const float aux = help[
ARRAY_3D(ix, iy, met->
ny, ip, met->
np)];
7997 if ((fillval == 0 || aux != fillval)
7998 && (missval == 0 || aux != missval)
7999 && fabsf(aux) < 1e14f)
8000 dest[ix][iy][ip] = scl * aux;
8002 dest[ix][iy][ip] = NAN;
8022 LOG(2,
"Calculate planetary boundary layer...");
8028#pragma omp parallel for default(shared) collapse(2)
8029 for (
int ix = 0; ix < met->
nx; ix++)
8030 for (
int iy = 0; iy < met->
ny; iy++) {
8033 const float z = met->
zs[ix][iy] + met->
pbl[ix][iy];
8036 (float) (
LIN(met->
z[ix][iy][ip], met->
p[ip],
8037 met->
z[ix][iy][ip + 1], met->
p[ip + 1], z));
8046 const double rib_crit = 0.25, dz = 0.05, umin = 5.0;
8049#pragma omp parallel for default(shared) collapse(2)
8050 for (
int ix = 0; ix < met->
nx; ix++)
8051 for (
int iy = 0; iy < met->
ny; iy++) {
8054 const double pbl_bot = met->
ps[ix][iy] * exp(-dz /
H0);
8058 for (ip = 1; ip < met->
np; ip++)
8059 if (met->
p[ip] < pbl_bot)
8063 const double h2os =
LIN(met->
p[ip - 1], met->
h2o[ix][iy][ip - 1],
8064 met->
p[ip], met->
h2o[ix][iy][ip], pbl_bot);
8065 const double tvs =
THETAVIRT(pbl_bot, met->
ts[ix][iy], h2os);
8071 for (; ip < met->
np; ip++) {
8074 double vh2 =
SQR(met->
u[ix][iy][ip] - met->
us[ix][iy])
8075 +
SQR(met->
v[ix][iy][ip] - met->
vs[ix][iy]);
8076 vh2 =
MAX(vh2,
SQR(umin));
8080 G0 * 1e3 * (met->
z[ix][iy][ip] - met->
zs[ix][iy]) / tvs
8082 met->
h2o[ix][iy][ip]) - tvs) / vh2;
8085 if (rib >= rib_crit) {
8086 met->
pbl[ix][iy] = (float) (
LIN(rib_old, met->
p[ip - 1],
8087 rib, met->
p[ip], rib_crit));
8088 if (met->
pbl[ix][iy] > pbl_bot)
8089 met->
pbl[ix][iy] = (float) pbl_bot;
8104 const double dtheta = 2.0, zmin = 0.1;
8107#pragma omp parallel for default(shared) collapse(2)
8108 for (
int ix = 0; ix < met->
nx; ix++)
8109 for (
int iy = 0; iy < met->
ny; iy++) {
8112 const double theta0 =
THETA(met->
ps[ix][iy], met->
ts[ix][iy]);
8116 for (ip = met->
np - 2; ip > 0; ip--)
8117 if (met->
p[ip] >= 300.)
8118 if (met->
p[ip] > met->
ps[ix][iy]
8119 ||
THETA(met->
p[ip], met->
t[ix][iy][ip]) <= theta0 + dtheta)
8124 = (float) (
LIN(
THETA(met->
p[ip + 1], met->
t[ix][iy][ip + 1]),
8126 THETA(met->
p[ip], met->
t[ix][iy][ip]),
8127 met->
p[ip], theta0 + dtheta));
8130 double pbl_min = met->
ps[ix][iy] * exp(-zmin /
H0);
8131 if (met->
pbl[ix][iy] > pbl_min || met->
p[ip] > met->
ps[ix][iy])
8132 met->
pbl[ix][iy] = (float) pbl_min;
8137#pragma omp parallel for default(shared) collapse(2)
8138 for (
int ix = 0; ix < met->
nx; ix++)
8139 for (
int iy = 0; iy < met->
ny; iy++) {
8143 met->
pbl[ix][iy] =
MIN(met->
pbl[ix][iy], (
float) pbl_min);
8147 met->
pbl[ix][iy] =
MAX(met->
pbl[ix][iy], (
float) pbl_max);
8157 SELECT_TIMER(
"READ_MET_PERIODIC",
"METPROC", NVTX_READ);
8158 LOG(2,
"Apply periodic boundary conditions...");
8161 if (!(fabs(met->
lon[met->
nx - 1] - met->
lon[0]
8162 + met->
lon[1] - met->
lon[0] - 360) < 0.01))
8166 if ((++met->
nx) >=
EX)
8167 ERRMSG(
"Cannot create periodic boundary conditions!");
8173#pragma omp parallel for default(shared)
8174 for (
int iy = 0; iy < met->
ny; iy++) {
8175 met->
ps[met->
nx - 1][iy] = met->
ps[0][iy];
8176 met->
zs[met->
nx - 1][iy] = met->
zs[0][iy];
8177 met->
ts[met->
nx - 1][iy] = met->
ts[0][iy];
8178 met->
us[met->
nx - 1][iy] = met->
us[0][iy];
8179 met->
vs[met->
nx - 1][iy] = met->
vs[0][iy];
8180 met->
ess[met->
nx - 1][iy] = met->
ess[0][iy];
8181 met->
nss[met->
nx - 1][iy] = met->
nss[0][iy];
8182 met->
shf[met->
nx - 1][iy] = met->
shf[0][iy];
8183 met->
lsm[met->
nx - 1][iy] = met->
lsm[0][iy];
8184 met->
sst[met->
nx - 1][iy] = met->
sst[0][iy];
8185 met->
pbl[met->
nx - 1][iy] = met->
pbl[0][iy];
8186 met->
cape[met->
nx - 1][iy] = met->
cape[0][iy];
8187 met->
cin[met->
nx - 1][iy] = met->
cin[0][iy];
8188 for (
int ip = 0; ip < met->
np; ip++) {
8189 met->
t[met->
nx - 1][iy][ip] = met->
t[0][iy][ip];
8190 met->
u[met->
nx - 1][iy][ip] = met->
u[0][iy][ip];
8191 met->
v[met->
nx - 1][iy][ip] = met->
v[0][iy][ip];
8192 met->
w[met->
nx - 1][iy][ip] = met->
w[0][iy][ip];
8193 met->
h2o[met->
nx - 1][iy][ip] = met->
h2o[0][iy][ip];
8194 met->
o3[met->
nx - 1][iy][ip] = met->
o3[0][iy][ip];
8195 met->
lwc[met->
nx - 1][iy][ip] = met->
lwc[0][iy][ip];
8196 met->
rwc[met->
nx - 1][iy][ip] = met->
rwc[0][iy][ip];
8197 met->
iwc[met->
nx - 1][iy][ip] = met->
iwc[0][iy][ip];
8198 met->
swc[met->
nx - 1][iy][ip] = met->
swc[0][iy][ip];
8199 met->
cc[met->
nx - 1][iy][ip] = met->
cc[0][iy][ip];
8201 for (
int ip = 0; ip < met->
npl; ip++) {
8202 met->
ul[met->
nx - 1][iy][ip] = met->
ul[0][iy][ip];
8203 met->
vl[met->
nx - 1][iy][ip] = met->
vl[0][iy][ip];
8204 met->
wl[met->
nx - 1][iy][ip] = met->
wl[0][iy][ip];
8205 met->
pl[met->
nx - 1][iy][ip] = met->
pl[0][iy][ip];
8206 met->
zetal[met->
nx - 1][iy][ip] = met->
zetal[0][iy][ip];
8218 SELECT_TIMER(
"READ_MET_POLAR_WINDS",
"METPROC", NVTX_READ);
8219 LOG(2,
"Apply fix for polar winds...");
8222 if (fabs(met->
lat[0]) < 89.999 || fabs(met->
lat[met->
ny - 1]) < 89.999)
8226 for (
int ihem = 0; ihem < 2; ihem++) {
8229 int i89 = 1, i90 = 0, sign = 1;
8234 if (met->
lat[i90] < 0)
8238 double clon[
EX], slon[
EX];
8239#pragma omp parallel for default(shared)
8240 for (
int ix = 0; ix < met->
nx; ix++) {
8241 clon[ix] = cos(sign *
DEG2RAD(met->
lon[ix]));
8242 slon[ix] = sin(sign *
DEG2RAD(met->
lon[ix]));
8246#pragma omp parallel for default(shared)
8247 for (
int ip = 0; ip < met->
np; ip++) {
8250 double vel89x = 0, vel89y = 0;
8251 for (
int ix = 0; ix < met->
nx; ix++) {
8253 (met->
u[ix][i89][ip] * clon[ix] -
8254 met->
v[ix][i89][ip] * slon[ix]) / met->
nx;
8256 (met->
u[ix][i89][ip] * slon[ix] +
8257 met->
v[ix][i89][ip] * clon[ix]) / met->
nx;
8261 for (
int ix = 0; ix < met->
nx; ix++) {
8263 = (float) (vel89x * clon[ix] + vel89y * slon[ix]);
8265 = (float) (-vel89x * slon[ix] + vel89y * clon[ix]);
8280 LOG(2,
"Calculate potential vorticity...");
8283#pragma omp parallel for default(shared)
8284 for (
int ip = 0; ip < met->
np; ip++)
8285 pows[ip] = pow(1000. / met->
p[ip], 0.286);
8288#pragma omp parallel for default(shared)
8289 for (
int ix = 0; ix < met->
nx; ix++) {
8292 const int ix0 =
MAX(ix - 1, 0);
8293 const int ix1 =
MIN(ix + 1, met->
nx - 1);
8296 for (
int iy = 0; iy < met->
ny; iy++) {
8299 const int iy0 =
MAX(iy - 1, 0);
8300 const int iy1 =
MIN(iy + 1, met->
ny - 1);
8303 const double latr = 0.5 * (met->
lat[iy1] + met->
lat[iy0]);
8304 const double dx = 1000. *
DEG2DX(met->
lon[ix1] - met->
lon[ix0], latr);
8305 const double dy = 1000. *
DEG2DY(met->
lat[iy1] - met->
lat[iy0]);
8306 const double c0 = cos(
DEG2RAD(met->
lat[iy0]));
8307 const double c1 = cos(
DEG2RAD(met->
lat[iy1]));
8308 const double cr = cos(
DEG2RAD(latr));
8309 const double vort = 2 * 7.2921e-5 * sin(
DEG2RAD(latr));
8312 for (
int ip = 0; ip < met->
np; ip++) {
8316 = (met->
t[ix1][iy][ip] - met->
t[ix0][iy][ip]) * pows[ip] / dx;
8317 const double dvdx = (met->
v[ix1][iy][ip] - met->
v[ix0][iy][ip]) / dx;
8321 = (met->
t[ix][iy1][ip] - met->
t[ix][iy0][ip]) * pows[ip] / dy;
8323 = (met->
u[ix][iy1][ip] * c1 - met->
u[ix][iy0][ip] * c0) / dy;
8326 const int ip0 =
MAX(ip - 1, 0);
8327 const int ip1 =
MIN(ip + 1, met->
np - 1);
8330 double dtdp, dudp, dvdp;
8331 const double dp0 = 100. * (met->
p[ip] - met->
p[ip0]);
8332 const double dp1 = 100. * (met->
p[ip1] - met->
p[ip]);
8333 if (ip != ip0 && ip != ip1) {
8334 double denom = dp0 * dp1 * (dp0 + dp1);
8335 dtdp = (dp0 * dp0 * met->
t[ix][iy][ip1] * pows[ip1]
8336 - dp1 * dp1 * met->
t[ix][iy][ip0] * pows[ip0]
8337 + (dp1 * dp1 - dp0 * dp0) * met->
t[ix][iy][ip] * pows[ip])
8339 dudp = (dp0 * dp0 * met->
u[ix][iy][ip1]
8340 - dp1 * dp1 * met->
u[ix][iy][ip0]
8341 + (dp1 * dp1 - dp0 * dp0) * met->
u[ix][iy][ip])
8343 dvdp = (dp0 * dp0 * met->
v[ix][iy][ip1]
8344 - dp1 * dp1 * met->
v[ix][iy][ip0]
8345 + (dp1 * dp1 - dp0 * dp0) * met->
v[ix][iy][ip])
8348 const double denom = dp0 + dp1;
8350 (met->
t[ix][iy][ip1] * pows[ip1] -
8351 met->
t[ix][iy][ip0] * pows[ip0]) / denom;
8352 dudp = (met->
u[ix][iy][ip1] - met->
u[ix][iy][ip0]) / denom;
8353 dvdp = (met->
v[ix][iy][ip1] - met->
v[ix][iy][ip0]) / denom;
8357 met->
pv[ix][iy][ip] = (float)
8359 (-dtdp * (dvdx - dudy / cr + vort) + dvdp * dtdx - dudp * dtdy));
8365#pragma omp parallel for default(shared)
8366 for (
int ix = 0; ix < met->
nx; ix++)
8367 for (
int ip = 0; ip < met->
np; ip++) {
8369 = met->
pv[ix][1][ip]
8370 = met->
pv[ix][2][ip];
8371 met->
pv[ix][met->
ny - 1][ip]
8372 = met->
pv[ix][met->
ny - 2][ip]
8373 = met->
pv[ix][met->
ny - 3][ip];
8384 LOG(2,
"Calculate total column ozone...");
8387#pragma omp parallel for default(shared) collapse(2)
8388 for (
int ix = 0; ix < met->
nx; ix++)
8389 for (
int iy = 0; iy < met->
ny; iy++) {
8393 for (
int ip = 1; ip < met->
np; ip++)
8394 if (met->
p[ip - 1] <= met->
ps[ix][iy]) {
8396 0.5 * (met->
o3[ix][iy][ip - 1] + met->
o3[ix][iy][ip]);
8397 const double dp = met->
p[ip - 1] - met->
p[ip];
8398 cd += vmr *
MO3 /
MA * dp * 1e2 /
G0;
8402 met->
o3c[ix][iy] = (float) (cd / 2.1415e-5);
8421 LOG(2,
"Downsampling of meteo data...");
8430 memcpy(help->
lon, met->
lon,
sizeof(met->
lon));
8431 memcpy(help->
lat, met->
lat,
sizeof(met->
lat));
8432 memcpy(help->
p, met->
p,
sizeof(met->
p));
8435 for (
int ix = 0; ix < met->
nx; ix += ctl->
met_dx) {
8436 for (
int iy = 0; iy < met->
ny; iy += ctl->
met_dy) {
8437 for (
int ip = 0; ip < met->
np; ip += ctl->
met_dp) {
8438 help->
ps[ix][iy] = 0;
8439 help->
zs[ix][iy] = 0;
8440 help->
ts[ix][iy] = 0;
8441 help->
us[ix][iy] = 0;
8442 help->
vs[ix][iy] = 0;
8443 help->
ess[ix][iy] = 0;
8444 help->
nss[ix][iy] = 0;
8445 help->
shf[ix][iy] = 0;
8446 help->
lsm[ix][iy] = 0;
8447 help->
sst[ix][iy] = 0;
8448 help->
pbl[ix][iy] = 0;
8449 help->
cape[ix][iy] = 0;
8450 help->
cin[ix][iy] = 0;
8451 help->
t[ix][iy][ip] = 0;
8452 help->
u[ix][iy][ip] = 0;
8453 help->
v[ix][iy][ip] = 0;
8454 help->
w[ix][iy][ip] = 0;
8455 help->
h2o[ix][iy][ip] = 0;
8456 help->
o3[ix][iy][ip] = 0;
8457 help->
lwc[ix][iy][ip] = 0;
8458 help->
rwc[ix][iy][ip] = 0;
8459 help->
iwc[ix][iy][ip] = 0;
8460 help->
swc[ix][iy][ip] = 0;
8461 help->
cc[ix][iy][ip] = 0;
8463 for (
int ix2 = ix - ctl->
met_sx + 1; ix2 <= ix + ctl->met_sx - 1;
8468 else if (ix3 >= met->
nx)
8471 for (
int iy2 =
MAX(iy - ctl->
met_sy + 1, 0);
8472 iy2 <=
MIN(iy + ctl->
met_sy - 1, met->
ny - 1); iy2++)
8473 for (
int ip2 =
MAX(ip - ctl->
met_sp + 1, 0);
8474 ip2 <=
MIN(ip + ctl->
met_sp - 1, met->
np - 1); ip2++) {
8475 float w = (1.0f - (float) abs(ix - ix2) / (float) ctl->
met_sx)
8476 * (1.0f - (float) abs(iy - iy2) / (float) ctl->
met_sy)
8477 * (1.0f - (float) abs(ip - ip2) / (float) ctl->
met_sp);
8478 help->
ps[ix][iy] += w * met->
ps[ix3][iy2];
8479 help->
zs[ix][iy] += w * met->
zs[ix3][iy2];
8480 help->
ts[ix][iy] += w * met->
ts[ix3][iy2];
8481 help->
us[ix][iy] += w * met->
us[ix3][iy2];
8482 help->
vs[ix][iy] += w * met->
vs[ix3][iy2];
8483 help->
ess[ix][iy] += w * met->
ess[ix3][iy2];
8484 help->
nss[ix][iy] += w * met->
nss[ix3][iy2];
8485 help->
shf[ix][iy] += w * met->
shf[ix3][iy2];
8486 help->
lsm[ix][iy] += w * met->
lsm[ix3][iy2];
8487 help->
sst[ix][iy] += w * met->
sst[ix3][iy2];
8488 help->
pbl[ix][iy] += w * met->
pbl[ix3][iy2];
8489 help->
cape[ix][iy] += w * met->
cape[ix3][iy2];
8490 help->
cin[ix][iy] += w * met->
cin[ix3][iy2];
8491 help->
t[ix][iy][ip] += w * met->
t[ix3][iy2][ip2];
8492 help->
u[ix][iy][ip] += w * met->
u[ix3][iy2][ip2];
8493 help->
v[ix][iy][ip] += w * met->
v[ix3][iy2][ip2];
8494 help->
w[ix][iy][ip] += w * met->
w[ix3][iy2][ip2];
8495 help->
h2o[ix][iy][ip] += w * met->
h2o[ix3][iy2][ip2];
8496 help->
o3[ix][iy][ip] += w * met->
o3[ix3][iy2][ip2];
8497 help->
lwc[ix][iy][ip] += w * met->
lwc[ix3][iy2][ip2];
8498 help->
rwc[ix][iy][ip] += w * met->
rwc[ix3][iy2][ip2];
8499 help->
iwc[ix][iy][ip] += w * met->
iwc[ix3][iy2][ip2];
8500 help->
swc[ix][iy][ip] += w * met->
swc[ix3][iy2][ip2];
8501 help->
cc[ix][iy][ip] += w * met->
cc[ix3][iy2][ip2];
8505 help->
ps[ix][iy] /= wsum;
8506 help->
zs[ix][iy] /= wsum;
8507 help->
ts[ix][iy] /= wsum;
8508 help->
us[ix][iy] /= wsum;
8509 help->
vs[ix][iy] /= wsum;
8510 help->
ess[ix][iy] /= wsum;
8511 help->
nss[ix][iy] /= wsum;
8512 help->
shf[ix][iy] /= wsum;
8513 help->
lsm[ix][iy] /= wsum;
8514 help->
sst[ix][iy] /= wsum;
8515 help->
pbl[ix][iy] /= wsum;
8516 help->
cape[ix][iy] /= wsum;
8517 help->
cin[ix][iy] /= wsum;
8518 help->
t[ix][iy][ip] /= wsum;
8519 help->
u[ix][iy][ip] /= wsum;
8520 help->
v[ix][iy][ip] /= wsum;
8521 help->
w[ix][iy][ip] /= wsum;
8522 help->
h2o[ix][iy][ip] /= wsum;
8523 help->
o3[ix][iy][ip] /= wsum;
8524 help->
lwc[ix][iy][ip] /= wsum;
8525 help->
rwc[ix][iy][ip] /= wsum;
8526 help->
iwc[ix][iy][ip] /= wsum;
8527 help->
swc[ix][iy][ip] /= wsum;
8528 help->
cc[ix][iy][ip] /= wsum;
8535 for (
int ix = 0; ix < help->
nx; ix += ctl->
met_dx) {
8538 for (
int iy = 0; iy < help->
ny; iy += ctl->
met_dy) {
8540 met->
ps[met->
nx][met->
ny] = help->
ps[ix][iy];
8541 met->
zs[met->
nx][met->
ny] = help->
zs[ix][iy];
8542 met->
ts[met->
nx][met->
ny] = help->
ts[ix][iy];
8543 met->
us[met->
nx][met->
ny] = help->
us[ix][iy];
8544 met->
vs[met->
nx][met->
ny] = help->
vs[ix][iy];
8545 met->
ess[met->
nx][met->
ny] = help->
ess[ix][iy];
8546 met->
nss[met->
nx][met->
ny] = help->
nss[ix][iy];
8547 met->
shf[met->
nx][met->
ny] = help->
shf[ix][iy];
8548 met->
lsm[met->
nx][met->
ny] = help->
lsm[ix][iy];
8549 met->
sst[met->
nx][met->
ny] = help->
sst[ix][iy];
8550 met->
pbl[met->
nx][met->
ny] = help->
pbl[ix][iy];
8552 met->
cin[met->
nx][met->
ny] = help->
cin[ix][iy];
8554 for (
int ip = 0; ip < help->
np; ip += ctl->
met_dp) {
8555 met->
p[met->
np] = help->
p[ip];
8556 met->
t[met->
nx][met->
ny][met->
np] = help->
t[ix][iy][ip];
8557 met->
u[met->
nx][met->
ny][met->
np] = help->
u[ix][iy][ip];
8558 met->
v[met->
nx][met->
ny][met->
np] = help->
v[ix][iy][ip];
8559 met->
w[met->
nx][met->
ny][met->
np] = help->
w[ix][iy][ip];
8560 met->
h2o[met->
nx][met->
ny][met->
np] = help->
h2o[ix][iy][ip];
8561 met->
o3[met->
nx][met->
ny][met->
np] = help->
o3[ix][iy][ip];
8562 met->
lwc[met->
nx][met->
ny][met->
np] = help->
lwc[ix][iy][ip];
8563 met->
rwc[met->
nx][met->
ny][met->
np] = help->
rwc[ix][iy][ip];
8564 met->
iwc[met->
nx][met->
ny][met->
np] = help->
iwc[ix][iy][ip];
8565 met->
swc[met->
nx][met->
ny][met->
np] = help->
swc[ix][iy][ip];
8566 met->
cc[met->
nx][met->
ny][met->
np] = help->
cc[ix][iy][ip];
8587 LOG(2,
"Read surface data...");
8591 (ncid,
"lnsp",
"LNSP", NULL, NULL, NULL, NULL, ctl, met, met->
ps, 1.0f,
8593 for (
int ix = 0; ix < met->
nx; ix++)
8594 for (
int iy = 0; iy < met->
ny; iy++)
8595 met->
ps[ix][iy] = (
float) (exp(met->
ps[ix][iy]) / 100.);
8598 (ncid,
"ps",
"PS",
"sp",
"SP", NULL, NULL, ctl, met, met->
ps, 0.01f,
8600 WARN(
"Cannot not read surface pressure data (use lowest level)!");
8601 for (
int ix = 0; ix < met->
nx; ix++)
8602 for (
int iy = 0; iy < met->
ny; iy++)
8604 = (ctl->
met_np > 0 ? (
float) ctl->
met_p[0] : (
float) met->
p[0]);
8612 (ncid,
"z",
"Z", NULL, NULL, NULL, NULL, ctl, met, met->
zs,
8613 (
float) (1. / (1000. *
G0)), 1))
8615 (ncid,
"zm",
"ZM", NULL, NULL, NULL, NULL, ctl, met, met->
zs,
8616 (
float) (1. / 1000.), 1))
8617 WARN(
"Cannot read surface geopotential height!");
8628 memcpy(help, met->
pl,
sizeof(met->
pl));
8630 (ncid,
"gph",
"GPH", NULL, NULL, ctl, met, met->
pl,
8631 (
float) (1e-3 /
G0)))
8632 ERRMSG(
"Cannot read geopotential height!");
8633 for (
int ix = 0; ix < met->
nx; ix++)
8634 for (
int iy = 0; iy < met->
ny; iy++)
8635 met->
zs[ix][iy] = met->
pl[ix][iy][0];
8636 memcpy(met->
pl, help,
sizeof(met->
pl));
8642 (ncid,
"t2m",
"T2M",
"2t",
"2T",
"t2",
"T2", ctl, met, met->
ts, 1.0, 1))
8643 WARN(
"Cannot read surface temperature!");
8647 (ncid,
"u10m",
"U10M",
"10u",
"10U",
"u10",
"U10", ctl, met, met->
us,
8649 WARN(
"Cannot read surface zonal wind!");
8653 (ncid,
"v10m",
"V10M",
"10v",
"10V",
"v10",
"V10", ctl, met, met->
vs,
8655 WARN(
"Cannot read surface meridional wind!");
8659 (ncid,
"iews",
"IEWS", NULL, NULL, NULL, NULL, ctl, met, met->
ess, 1.0,
8661 WARN(
"Cannot read eastward turbulent surface stress!");
8665 (ncid,
"inss",
"INSS", NULL, NULL, NULL, NULL, ctl, met, met->
nss, 1.0,
8667 WARN(
"Cannot read nothward turbulent surface stress!");
8671 (ncid,
"ishf",
"ISHF", NULL, NULL, NULL, NULL, ctl, met, met->
shf, 1.0,
8673 WARN(
"Cannot read surface sensible heat flux!");
8677 (ncid,
"lsm",
"LSM", NULL, NULL, NULL, NULL, ctl, met, met->
lsm, 1.0,
8679 WARN(
"Cannot read land-sea mask!");
8683 (ncid,
"sstk",
"SSTK",
"sst",
"SST", NULL, NULL, ctl, met, met->
sst,
8685 WARN(
"Cannot read sea surface temperature!");
8690 (ncid,
"blp",
"BLP", NULL, NULL, NULL, NULL, ctl, met, met->
pbl,
8692 WARN(
"Cannot read planetary boundary layer pressure!");
8695 (ncid,
"blh",
"BLH", NULL, NULL, NULL, NULL, ctl, met, met->
pbl,
8697 WARN(
"Cannot read planetary boundary layer height!");
8702 (ncid,
"cape",
"CAPE", NULL, NULL, NULL, NULL, ctl, met, met->
cape,
8704 WARN(
"Cannot read CAPE!");
8709 (ncid,
"cin",
"CIN", NULL, NULL, NULL, NULL, ctl, met, met->
cin,
8711 WARN(
"Cannot read convective inhibition!");
8721 double p2[200], pv[
EP], pv2[200], t[
EP], t2[200], th[
EP],
8722 th2[200], z[
EP], z2[200];
8726 LOG(2,
"Calculate tropopause...");
8729#pragma omp parallel for default(shared)
8730 for (
int iz = 0; iz < met->
np; iz++)
8731 z[iz] =
Z(met->
p[iz]);
8732#pragma omp parallel for default(shared)
8733 for (
int iz = 0; iz <= 190; iz++) {
8734 z2[iz] = 4.5 + 0.1 * iz;
8740#pragma omp parallel for default(shared) collapse(2)
8741 for (
int ix = 0; ix < met->
nx; ix++)
8742 for (
int iy = 0; iy < met->
ny; iy++)
8743 met->
pt[ix][iy] = NAN;
8747#pragma omp parallel for default(shared) collapse(2)
8748 for (
int ix = 0; ix < met->
nx; ix++)
8749 for (
int iy = 0; iy < met->
ny; iy++)
8757#pragma omp parallel for default(shared) private(t,t2) collapse(2)
8758 for (
int ix = 0; ix < met->
nx; ix++)
8759 for (
int iy = 0; iy < met->
ny; iy++) {
8762 for (
int iz = 0; iz < met->
np; iz++)
8763 t[iz] = met->
t[ix][iy][iz];
8767 int iz = (int) gsl_stats_min_index(t2, 1, 171);
8768 if (iz > 0 && iz < 170)
8769 met->
pt[ix][iy] = (float) p2[iz];
8771 met->
pt[ix][iy] = NAN;
8779#pragma omp parallel for default(shared) private(t,t2) collapse(2)
8780 for (
int ix = 0; ix < met->
nx; ix++)
8781 for (
int iy = 0; iy < met->
ny; iy++) {
8785 for (iz = 0; iz < met->
np; iz++)
8786 t[iz] = met->
t[ix][iy][iz];
8790 met->
pt[ix][iy] = NAN;
8791 for (iz = 0; iz <= 170; iz++) {
8793 for (
int iz2 = iz + 1; iz2 <= iz + 20; iz2++)
8794 if (
LAPSE(p2[iz], t2[iz], p2[iz2], t2[iz2]) > 2.0) {
8799 if (iz > 0 && iz < 170)
8800 met->
pt[ix][iy] = (float) p2[iz];
8807 met->
pt[ix][iy] = NAN;
8808 for (; iz <= 170; iz++) {
8810 for (
int iz2 = iz + 1; iz2 <= iz + 10; iz2++)
8811 if (
LAPSE(p2[iz], t2[iz], p2[iz2], t2[iz2]) < 3.0) {
8818 for (; iz <= 170; iz++) {
8820 for (
int iz2 = iz + 1; iz2 <= iz + 20; iz2++)
8821 if (
LAPSE(p2[iz], t2[iz], p2[iz2], t2[iz2]) > 2.0) {
8826 if (iz > 0 && iz < 170)
8827 met->
pt[ix][iy] = (float) p2[iz];
8839#pragma omp parallel for default(shared) private(pv,pv2,th,th2) collapse(2)
8840 for (
int ix = 0; ix < met->
nx; ix++)
8841 for (
int iy = 0; iy < met->
ny; iy++) {
8844 for (
int iz = 0; iz < met->
np; iz++)
8845 pv[iz] = met->
pv[ix][iy][iz];
8849 for (
int iz = 0; iz < met->
np; iz++)
8850 th[iz] =
THETA(met->
p[iz], met->
t[ix][iy][iz]);
8854 met->
pt[ix][iy] = NAN;
8855 for (
int iz = 0; iz <= 170; iz++)
8858 if (iz > 0 && iz < 170)
8859 met->
pt[ix][iy] = (float) p2[iz];
8866 ERRMSG(
"Cannot calculate tropopause!");
8869#pragma omp parallel for default(shared) collapse(2)
8870 for (
int ix = 0; ix < met->
nx; ix++)
8871 for (
int iy = 0; iy < met->
ny; iy++) {
8872 double h2ot, tt, zt;
8875 met->
lat[iy], &tt, ci, cw, 1);
8877 met->
lat[iy], &zt, ci, cw, 0);
8879 met->
lat[iy], &h2ot, ci, cw, 0);
8880 met->
tt[ix][iy] = (float) tt;
8881 met->
zt[ix][iy] = (float) zt;
8882 met->
h2ot[ix][iy] = (float) h2ot;
8889 const char *filename,
8899 LOG(1,
"Read observation data: %s", filename);
8903 read_obs_asc(filename, rt, rz, rlon, rlat, robs, nobs);
8905 read_obs_nc(filename, rt, rz, rlon, rlat, robs, nobs);
8907 ERRMSG(
"Set OBS_TYPE to 0 or 1!");
8910 for (
int i = 1; i < *nobs; i++)
8911 if (rt[i] < rt[i - 1])
8912 ERRMSG(
"Time must be ascending!");
8917 LOG(2,
"Number of observations: %d", *nobs);
8918 gsl_stats_minmax(&mini, &maxi, rt, 1, (
size_t) n);
8919 LOG(2,
"Time range: %.2f ... %.2f s", mini, maxi);
8920 gsl_stats_minmax(&mini, &maxi, rz, 1, (
size_t) n);
8921 LOG(2,
"Altitude range: %g ... %g km", mini, maxi);
8922 gsl_stats_minmax(&mini, &maxi, rlon, 1, (
size_t) n);
8923 LOG(2,
"Longitude range: %g ... %g deg", mini, maxi);
8924 gsl_stats_minmax(&mini, &maxi, rlat, 1, (
size_t) n);
8925 LOG(2,
"Latitude range: %g ... %g deg", mini, maxi);
8926 gsl_stats_minmax(&mini, &maxi, robs, 1, (
size_t) n);
8927 LOG(2,
"Observation range: %g ... %g", mini, maxi);
8933 const char *filename,
8943 if (!(in = fopen(filename,
"r")))
8944 ERRMSG(
"Cannot open file!");
8948 while (fgets(line,
LEN, in))
8949 if (sscanf(line,
"%lg %lg %lg %lg %lg", &rt[*nobs], &rz[*nobs],
8950 &rlon[*nobs], &rlat[*nobs], &robs[*nobs]) == 5)
8951 if ((++(*nobs)) >=
NOBS)
8952 ERRMSG(
"Too many observations!");
8961 const char *filename,
8972 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR)
8973 ERRMSG(
"Cannot open file!");
8990 const char *filename,
8993 const char *varname,
8995 const char *defvalue,
9000 char fullname1[
LEN], fullname2[
LEN], rval[
LEN];
9005 if (filename[strlen(filename) - 1] !=
'-')
9006 if (!(in = fopen(filename,
"r")))
9007 ERRMSG(
"Cannot open file!");
9011 sprintf(fullname1,
"%s[%d]", varname, arridx);
9012 sprintf(fullname2,
"%s[*]", varname);
9014 sprintf(fullname1,
"%s", varname);
9015 sprintf(fullname2,
"%s", varname);
9020 char dummy[
LEN], line[
LEN], rvarname[
LEN];
9021 while (fgets(line,
LEN, in)) {
9022 if (sscanf(line,
"%4999s %4999s %4999s", rvarname, dummy, rval) == 3)
9023 if (strcasecmp(rvarname, fullname1) == 0 ||
9024 strcasecmp(rvarname, fullname2) == 0) {
9030 for (i = 1; i < argc - 1; i++)
9031 if (strcasecmp(argv[i], fullname1) == 0 ||
9032 strcasecmp(argv[i], fullname2) == 0) {
9033 sprintf(rval,
"%s", argv[i + 1]);
9044 if (strlen(defvalue) > 0)
9045 sprintf(rval,
"%s", defvalue);
9047 ERRMSG(
"Missing variable %s!\n", fullname1);
9051 LOG(1,
"%s = %s", fullname1, rval);
9055 sprintf(value,
"%s", rval);
9065 const double rhop) {
9068 const double rp_help = rp * 1e-6;
9071 const double rho =
RHO(p, T);
9074 const double eta = 1.8325e-5 * (416.16 / (T + 120.)) * pow(T / 296.16, 1.5);
9077 const double v = sqrt(8. *
KB * T / (M_PI * 4.8096e-26));
9080 const double lambda = 2. * eta / (rho * v);
9083 const double K = lambda / rp_help;
9086 const double G = 1. + K * (1.249 + 0.42 * exp(-0.87 / K));
9089 return 2. *
SQR(rp_help) * (rhop - rho) *
G0 / (9. * eta) * G;
9107 gsl_interp_accel *acc = gsl_interp_accel_alloc();
9108 gsl_spline *s = gsl_spline_alloc(gsl_interp_cspline, (
size_t) n);
9111 gsl_spline_init(s, x, y, (
size_t) n);
9112 for (
int i = 0; i < n2; i++)
9115 else if (x2[i] >= x[n - 1])
9118 y2[i] = gsl_spline_eval(s, x2[i], acc);
9122 gsl_interp_accel_free(acc);
9127 for (
int i = 0; i < n2; i++)
9130 else if (x2[i] >= x[n - 1])
9134 y2[i] =
LIN(x[idx], y[idx], x[idx + 1], y[idx + 1], x2[i]);
9148 float mean = 0, var = 0;
9150 for (
int i = 0; i < n; ++i) {
9152 var +=
SQR(data[i]);
9155 var = var / (float) n -
SQR(mean / (
float) n);
9157 return (var > 0 ? sqrtf(var) : 0);
9168 const double D = sec / 86400 - 0.5;
9171 const double g =
DEG2RAD(357.529 + 0.98560028 * D);
9172 const double q = 280.459 + 0.98564736 * D;
9173 const double L =
DEG2RAD(q + 1.915 * sin(g) + 0.020 * sin(2 * g));
9176 const double e =
DEG2RAD(23.439 - 0.00000036 * D);
9179 const double sindec = sin(e) * sin(L);
9182 const double ra = atan2(cos(e) * sin(L), cos(L));
9185 const double GMST = 18.697374558 + 24.06570982441908 * D;
9188 const double LST = GMST + lon / 15;
9191 const double h = LST / 12 * M_PI - ra;
9194 const double lat_help =
DEG2RAD(lat);
9197 return acos(sin(lat_help) * sindec +
9198 cos(lat_help) * sqrt(1 -
SQR(sindec)) * cos(h));
9210 const double remain,
9222 t1.tm_year = year - 1900;
9223 t1.tm_mon = mon - 1;
9229 *jsec = (double) timegm(&t1) - (double) timegm(&t0) + remain;
9244 static int iname = -1, igroup = -1, nname, ngroup, ct_name[
NTIMER];
9247 t1 = omp_get_wtime();
9252 rt_name[iname] += dt;
9253 rt_min[iname] = (ct_name[iname] <= 0 ? dt :
MIN(rt_min[iname], dt));
9254 rt_max[iname] = (ct_name[iname] <= 0 ? dt :
MAX(rt_max[iname], dt));
9258 rt_group[igroup] += t1 - t0;
9262 for (
int i = 0; i < nname; i++)
9263 LOG(1,
"TIMER_%s = %.3f s (min= %g s, mean= %g s,"
9264 " max= %g s, n= %d)", names[i], rt_name[i], rt_min[i],
9265 rt_name[i] / ct_name[i], rt_max[i], ct_name[i]);
9266 for (
int i = 0; i < ngroup; i++)
9267 LOG(1,
"TIMER_GROUP_%s = %.3f s", groups[i], rt_group[i]);
9269 for (
int i = 0; i < nname; i++)
9270 total += rt_name[i];
9271 LOG(1,
"TIMER_TOTAL = %.3f s", total);
9275 for (iname = 0; iname < nname; iname++)
9276 if (strcasecmp(name, names[iname]) == 0)
9278 for (igroup = 0; igroup < ngroup; igroup++)
9279 if (strcasecmp(group, groups[igroup]) == 0)
9283 if (iname >= nname) {
9284 sprintf(names[iname],
"%s", name);
9286 ERRMSG(
"Too many timers!");
9290 if (igroup >= ngroup) {
9291 sprintf(groups[igroup],
"%s", group);
9292 if ((++ngroup) >=
NTIMER)
9293 ERRMSG(
"Too many groups!");
9303 const char *filename,
9311 int len = (int) strlen(filename);
9312 sprintf(tstr,
"%.4s", &filename[len - offset]);
9313 int year = atoi(tstr);
9314 sprintf(tstr,
"%.2s", &filename[len - offset + 5]);
9315 int mon = atoi(tstr);
9316 sprintf(tstr,
"%.2s", &filename[len - offset + 8]);
9317 int day = atoi(tstr);
9318 sprintf(tstr,
"%.2s", &filename[len - offset + 11]);
9319 int hour = atoi(tstr);
9320 sprintf(tstr,
"%.2s", &filename[len - offset + 14]);
9321 int min = atoi(tstr);
9324 if (year < 1900 || year > 2100 || mon < 1 || mon > 12 || day < 1
9325 || day > 31 || hour < 0 || hour > 23 || min < 0 || min > 59)
9326 ERRMSG(
"Cannot read time from filename!");
9329 time2jsec(year, mon, day, hour, min, 0, 0.0, &t);
9346 const double p1 = pt * 0.866877899;
9347 const double p0 = pt / 0.866877899;
9350 if (atm->
p[ip] > p0)
9352 else if (atm->
p[ip] < p1)
9355 return LIN(p0, 1.0, p1, 0.0, atm->
p[ip]);
9361 const char *filename,
9369 const double t0 = t - 0.5 * ctl->
dt_mod;
9370 const double t1 = t + 0.5 * ctl->
dt_mod;
9376 if (!(out = popen(
"gnuplot",
"w")))
9377 ERRMSG(
"Cannot create pipe to gnuplot!");
9380 fprintf(out,
"set out \"%s.png\"\n", filename);
9384 int year, mon, day, hour, min, sec;
9385 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
9386 fprintf(out,
"timestr=\"%d-%02d-%02d, %02d:%02d UTC\"\n",
9387 year, mon, day, hour, min);
9392 ERRMSG(
"Cannot open file!");
9394 while (fgets(line,
LEN, in))
9395 fprintf(out,
"%s", line);
9402 if (!(out = fopen(filename,
"w")))
9403 ERRMSG(
"Cannot create file!");
9409 "# $2 = altitude [km]\n"
9410 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
9411 for (
int iq = 0; iq < ctl->
nq; iq++)
9412 fprintf(out,
"# $%i = %s [%s]\n", iq + 5, ctl->
qnt_name[iq],
9417 for (
int ip = 0; ip < atm->
np; ip += ctl->
atm_stride) {
9424 fprintf(out,
"%.2f %g %g %g", atm->
time[ip],
Z(atm->
p[ip]),
9425 atm->
lon[ip], atm->
lat[ip]);
9426 for (
int iq = 0; iq < ctl->
nq; iq++) {
9431 fprintf(out, ctl->
qnt_format[iq], atm->
q[iq][ip]);
9443 const char *filename,
9450 if (!(out = fopen(filename,
"w")))
9451 ERRMSG(
"Cannot create file!");
9475 for (
int iq = 0; iq < ctl->
nq; iq++)
9493 const char *filename,
9497 int tid, pid, ncid, varid;
9498 size_t start[2], count[2];
9501 nc_create(filename, NC_NETCDF4, &ncid);
9504 NC(nc_def_dim(ncid,
"time", 1, &tid));
9505 NC(nc_def_dim(ncid,
"NPARTS", (
size_t) atm->
np, &pid));
9508 int dim_ids[2] = { tid, pid };
9509 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"Time",
9510 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
9511 NC_DEF_VAR(
"LAT", NC_DOUBLE, 1, &pid,
"Latitude",
"deg",
9513 NC_DEF_VAR(
"LON", NC_DOUBLE, 1, &pid,
"Longitude",
"deg",
9515 NC_DEF_VAR(
"PRESS", NC_DOUBLE, 1, &pid,
"Pressure",
"hPa",
9518 for (
int iq = 0; iq < ctl->
nq; iq++)
9528 NC(nc_enddef(ncid));
9536 for (
int iq = 0; iq < ctl->
nq; iq++)
9546 const char *dirname,
9552 static size_t out_cnt = 0;
9554 double r, r_start, r_stop;
9555 int year, mon, day, hour, min, sec;
9556 int year_start, mon_start, day_start, hour_start, min_start, sec_start;
9557 int year_stop, mon_stop, day_stop, hour_stop, min_stop, sec_stop;
9558 char filename_out[2 *
LEN] =
"traj_fix_3d_YYYYMMDDHH_YYYYMMDDHH.nc";
9560 int ncid, varid, tid, pid, cid;
9568 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
9570 &min_start, &sec_start, &r_start);
9572 &min_stop, &sec_stop, &r_stop);
9574 sprintf(filename_out,
"%s/traj_fix_3d_%02d%02d%02d%02d_%02d%02d%02d%02d.nc",
9576 year_start % 100, mon_start, day_start, hour_start,
9577 year_stop % 100, mon_stop, day_stop, hour_stop);
9578 LOG(1,
"Write traj file: %s", filename_out);
9584 count[1] = (size_t) atm->
np;
9590 nc_create(filename_out, NC_NETCDF4, &ncid);
9593 NC(nc_def_dim(ncid,
"time", NC_UNLIMITED, &tid));
9594 NC(nc_def_dim(ncid,
"NPARTS", (
size_t) atm->
np, &pid));
9595 NC(nc_def_dim(ncid,
"TMDT", 7, &cid));
9600 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"Time",
9601 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
9602 NC_DEF_VAR(
"LAT", NC_DOUBLE, 2, dim_ids,
"Latitude",
"deg",
9604 NC_DEF_VAR(
"LON", NC_DOUBLE, 2, dim_ids,
"Longitude",
"deg",
9606 NC_DEF_VAR(
"PRESS", NC_DOUBLE, 2, dim_ids,
"Pressure",
"hPa",
9608 NC_DEF_VAR(
"ZETA", NC_DOUBLE, 2, dim_ids,
"Zeta",
"K",
9610 for (
int iq = 0; iq < ctl->
nq; iq++)
9620 NC(nc_enddef(ncid));
9628 NC(nc_open(filename_out, NC_WRITE, &ncid));
9640 for (
int iq = 0; iq < ctl->
nq; iq++)
9647 if ((year == year_stop) && (mon == mon_stop)
9648 && (day == day_stop) && (hour == hour_stop)) {
9651 char filename_init[2 *
LEN] =
"./init_fix_YYYYMMDDHH.nc";
9652 sprintf(filename_init,
"%s/init_fix_%02d%02d%02d%02d.nc",
9653 dirname, year_stop % 100, mon_stop, day_stop, hour_stop);
9654 LOG(1,
"Write init file: %s", filename_init);
9657 nc_create(filename_init, NC_NETCDF4, &ncid);
9660 NC(nc_def_dim(ncid,
"time", 1, &tid));
9661 NC(nc_def_dim(ncid,
"NPARTS", (
size_t) atm->
np, &pid));
9666 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"Time",
9667 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
9668 NC_DEF_VAR(
"LAT", NC_DOUBLE, 1, &pid,
"Latitude",
"deg",
9670 NC_DEF_VAR(
"LON", NC_DOUBLE, 1, &pid,
"Longitude",
"deg",
9672 NC_DEF_VAR(
"PRESS", NC_DOUBLE, 1, &pid,
"Pressure",
"hPa",
9675 for (
int iq = 0; iq < ctl->
nq; iq++)
9685 NC(nc_enddef(ncid));
9693 for (
int iq = 0; iq < ctl->
nq; iq++)
9704 const char *filename,
9708 int ncid, obsid, varid;
9710 size_t start[2], count[2];
9713 NC(nc_create(filename, NC_NETCDF4, &ncid));
9716 NC(nc_def_dim(ncid,
"obs", (
size_t) atm->
np, &obsid));
9719 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &obsid,
"time",
9720 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
9721 NC_DEF_VAR(
"press", NC_DOUBLE, 1, &obsid,
"pressure",
"hPa",
9723 NC_DEF_VAR(
"lon", NC_DOUBLE, 1, &obsid,
"longitude",
"degrees_east",
9725 NC_DEF_VAR(
"lat", NC_DOUBLE, 1, &obsid,
"latitude",
"degrees_north",
9727 for (
int iq = 0; iq < ctl->
nq; iq++)
9736 NC(nc_enddef(ncid));
9743 for (
int iq = 0; iq < ctl->
nq; iq++)
9753 const char *filename,
9760 static double *modmean, *obsmean, *obsstd, *rt, *rz, *rlon, *rlat, *robs,
9763 static int *obscount, ct, cx, cy, cz, ip, ix, iy, iz, n, nobs, nk;
9773 ERRMSG(
"Need quantity mass!");
9797 LOG(1,
"Write CSI data: %s", filename);
9798 if (!(out = fopen(filename,
"w")))
9799 ERRMSG(
"Cannot create file!");
9804 "# $2 = number of hits (cx)\n"
9805 "# $3 = number of misses (cy)\n"
9806 "# $4 = number of false alarms (cz)\n"
9807 "# $5 = number of observations (cx + cy)\n"
9808 "# $6 = number of forecasts (cx + cz)\n"
9809 "# $7 = bias (ratio of forecasts and observations) [%%]\n"
9810 "# $8 = probability of detection (POD) [%%]\n"
9811 "# $9 = false alarm rate (FAR) [%%]\n"
9812 "# $10 = critical success index (CSI) [%%]\n");
9814 "# $11 = hits associated with random chance\n"
9815 "# $12 = equitable threat score (ETS) [%%]\n"
9816 "# $13 = Pearson linear correlation coefficient\n"
9817 "# $14 = Spearman rank-order correlation coefficient\n"
9818 "# $15 = column density mean error (F - O) [kg/m^2]\n"
9819 "# $16 = column density root mean square error (RMSE) [kg/m^2]\n"
9820 "# $17 = column density mean absolute error [kg/m^2]\n"
9821 "# $18 = log-likelihood function\n"
9822 "# $19 = number of data points\n\n");
9830 for (iy = 0; iy < ctl->
csi_ny; iy++) {
9831 const double lat = ctl->
csi_lat0 + dlat * (iy + 0.5);
9832 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat));
9837 const double t0 = t - 0.5 * ctl->
dt_mod;
9838 const double t1 = t + 0.5 * ctl->
dt_mod;
9841 ALLOC(modmean,
double,
9843 ALLOC(obsmean,
double,
9845 ALLOC(obscount,
int,
9847 ALLOC(obsstd,
double,
9851 for (
int i = 0; i < nobs; i++) {
9856 else if (rt[i] >= t1)
9860 if (!isfinite(robs[i]))
9864 ix = (int) ((rlon[i] - ctl->
csi_lon0) / dlon);
9865 iy = (int) ((rlat[i] - ctl->
csi_lat0) / dlat);
9866 iz = (int) ((rz[i] - ctl->
csi_z0) / dz);
9869 if (ix < 0 || ix >= ctl->
csi_nx ||
9870 iy < 0 || iy >= ctl->
csi_ny || iz < 0 || iz >= ctl->
csi_nz)
9875 obsmean[idx] += robs[i];
9876 obsstd[idx] +=
SQR(robs[i]);
9881 for (ip = 0; ip < atm->
np; ip++) {
9884 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
9888 ix = (int) ((atm->
lon[ip] - ctl->
csi_lon0) / dlon);
9889 iy = (int) ((atm->
lat[ip] - ctl->
csi_lat0) / dlat);
9890 iz = (int) ((
Z(atm->
p[ip]) - ctl->
csi_z0) / dz);
9893 if (ix < 0 || ix >= ctl->
csi_nx ||
9894 iy < 0 || iy >= ctl->
csi_ny || iz < 0 || iz >= ctl->
csi_nz)
9900 * atm->
q[ctl->
qnt_m][ip];
9904 for (ix = 0; ix < ctl->
csi_nx; ix++)
9905 for (iy = 0; iy < ctl->
csi_ny; iy++)
9906 for (iz = 0; iz < ctl->
csi_nz; iz++) {
9910 if (obscount[idx] > 0) {
9911 obsmean[idx] /= obscount[idx];
9912 obsstd[idx] -=
SQR(obsmean[idx]);
9913 obsstd[idx] = sqrt(obsstd[idx]);
9917 if (modmean[idx] > 0)
9918 modmean[idx] /= (1e6 * area[iy]);
9921 if (obscount[idx] > 0) {
9935 if (obscount[idx] > 0
9938 x[n] = modmean[idx];
9939 y[n] = obsmean[idx];
9941 obsstdn[n] = obsstd[idx];
9943 ERRMSG(
"Too many data points to calculate statistics!");
9952 static double work[2 *
NCSI], work2[2 *
NCSI];;
9953 const int n_obs = cx + cy;
9954 const int n_for = cx + cz;
9955 const double bias = (n_obs > 0) ? 100. * n_for / n_obs : NAN;
9956 const double pod = (n_obs > 0) ? (100. * cx) / n_obs : NAN;
9957 const double far = (n_for > 0) ? (100. * cz) / n_for : NAN;
9959 (cx + cy + cz > 0) ? (100. * cx) / (cx + cy + cz) : NAN;
9960 const double cx_rd = (ct > 0) ? (1. * n_obs * n_for) / ct : NAN;
9961 const double ets = (cx + cy + cz - cx_rd > 0) ?
9962 (100. * (cx - cx_rd)) / (cx + cy + cz - cx_rd) : NAN;
9963 const double rho_p =
9964 (n > 0) ? gsl_stats_correlation(x, 1, y, 1, (
size_t) n) : NAN;
9965 const double rho_s =
9966 (n > 0) ? gsl_stats_spearman(x, 1, y, 1, (
size_t) n, work) : NAN;
9967 for (
int i = 0; i < n; i++) {
9968 work[i] = x[i] - y[i];
9969 work2[i] = (obsstdn[i] != 0) ? (x[i] - y[i]) / obsstdn[i] : 0;
9971 const double mean = (n > 0) ? gsl_stats_mean(work, 1, (
size_t) n) : NAN;
9973 (n > 0) ? gsl_stats_sd_with_fixed_mean(work, 1, (
size_t) n,
9975 const double absdev =
9976 (n > 0) ? gsl_stats_absdev_m(work, 1, (
size_t) n, 0.0) : NAN;
9977 const double loglikelihood =
9978 (n > 0) ? gsl_stats_tss(work2, 1, (
size_t) n) * (-0.5) : GSL_NAN;
9982 "%.2f %d %d %d %d %d %g %g %g %g %g %g %g %g %g %g %g %g %d\n", t,
9983 cx, cy, cz, n_obs, n_for, bias, pod, far, csi, cx_rd, ets, rho_p,
9984 rho_s, mean, rmse, absdev, loglikelihood, n);
9987 n = ct = cx = cy = cz = 0;
10015 const char *filename,
10025 static int n[
NENS];
10032 ERRMSG(
"Missing ensemble IDs!");
10035 const double t0 = t - 0.5 * ctl->
dt_mod;
10036 const double t1 = t + 0.5 * ctl->
dt_mod;
10039 for (
int i = 0; i <
NENS; i++) {
10040 for (
int iq = 0; iq < ctl->
nq; iq++)
10041 qm[iq][i] = qs[iq][i] = 0;
10042 xm[i][0] = xm[i][1] = xm[i][2] = zm[i] = 0;
10047 for (
int ip = 0; ip < atm->
np; ip++) {
10050 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
10055 ERRMSG(
"Ensemble ID is out of range!");
10059 for (
int iq = 0; iq < ctl->
nq; iq++) {
10060 qm[iq][ctl->
qnt_ens] += atm->
q[iq][ip];
10071 LOG(1,
"Write ensemble data: %s", filename);
10072 if (!(out = fopen(filename,
"w")))
10073 ERRMSG(
"Cannot create file!");
10077 "# $1 = time [s]\n"
10078 "# $2 = altitude [km]\n"
10079 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
10080 for (
int iq = 0; iq < ctl->
nq; iq++)
10081 fprintf(out,
"# $%d = %s (mean) [%s]\n", 5 + iq,
10083 for (
int iq = 0; iq < ctl->
nq; iq++)
10084 fprintf(out,
"# $%d = %s (sigma) [%s]\n", 5 + ctl->
nq + iq,
10086 fprintf(out,
"# $%d = number of members\n\n", 5 + 2 * ctl->
nq);
10089 for (
int i = 0; i <
NENS; i++)
10091 cart2geo(xm[i], &dummy, &lon, &lat);
10092 fprintf(out,
"%.2f %g %g %g", t, zm[i] / n[i], lon, lat);
10093 for (
int iq = 0; iq < ctl->
nq; iq++) {
10095 fprintf(out, ctl->
qnt_format[iq], qm[iq][i] / n[i]);
10097 for (
int iq = 0; iq < ctl->
nq; iq++) {
10099 double var = qs[iq][i] / n[i] -
SQR(qm[iq][i] / n[i]);
10100 fprintf(out, ctl->
qnt_format[iq], (var > 0 ? sqrt(var) : 0));
10102 fprintf(out,
" %d\n", n[i]);
10112 const char *filename,
10119 static double kz[
EP], kw[
EP];
10123 double *cd, *mean[
NQ], *sigma[
NQ], *vmr_impl, *z, *lon, *lat, *area, *press;
10125 int *ixs, *iys, *izs, *np;
10131 LOG(1,
"Write grid data: %s", filename);
10144 for (
int iq = 0; iq < ctl->
nq; iq++) {
10145 ALLOC(mean[iq],
double,
10147 ALLOC(sigma[iq],
double,
10150 ALLOC(vmr_impl,
double,
10158 ALLOC(area,
double,
10160 ALLOC(press,
double,
10177#pragma omp parallel
for default(shared)
10178 for (
int iz = 0; iz < ctl->
grid_nz; iz++) {
10179 z[iz] = ctl->
grid_z0 + dz * (iz + 0.5);
10180 press[iz] =
P(z[iz]);
10184 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
10185 lon[ix] = ctl->
grid_lon0 + dlon * (ix + 0.5);
10186#pragma omp parallel for default(shared)
10187 for (
int iy = 0; iy < ctl->
grid_ny; iy++) {
10188 lat[iy] = ctl->
grid_lat0 + dlat * (iy + 0.5);
10189 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat[iy]));
10193 const double t0 = t - 0.5 * ctl->
dt_mod;
10194 const double t1 = t + 0.5 * ctl->
dt_mod;
10197#pragma omp parallel for default(shared)
10198 for (
int ip = 0; ip < atm->
np; ip++) {
10199 ixs[ip] = (int) ((atm->
lon[ip] - ctl->
grid_lon0) / dlon);
10200 iys[ip] = (int) ((atm->
lat[ip] - ctl->
grid_lat0) / dlat);
10201 izs[ip] = (int) ((
Z(atm->
p[ip]) - ctl->
grid_z0) / dz);
10202 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
10203 || ixs[ip] < 0 || ixs[ip] >= ctl->
grid_nx
10204 || iys[ip] < 0 || iys[ip] >= ctl->
grid_ny
10205 || izs[ip] < 0 || izs[ip] >= ctl->
grid_nz)
10210 for (
int ip = 0; ip < atm->
np; ip++)
10211 if (izs[ip] >= 0) {
10216 for (
int iq = 0; iq < ctl->
nq; iq++) {
10217 mean[iq][idx] += kernel * atm->
q[iq][ip];
10218 sigma[iq][idx] +=
SQR(kernel * atm->
q[iq][ip]);
10223#pragma omp parallel for default(shared)
10224 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
10225 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
10226 for (
int iz = 0; iz < ctl->
grid_nz; iz++) {
10233 if (ctl->
qnt_m >= 0)
10234 cd[idx] = mean[ctl->
qnt_m][idx] / (1e6 * area[iy]);
10237 vmr_impl[idx] = NAN;
10238 if (ctl->
qnt_m >= 0 && ctl->
molmass > 0 && met0 != NULL
10241 if (mean[ctl->
qnt_m][idx] > 0) {
10247 lon[ix], lat[iy], &temp, ci, cw, 1);
10251 MA / ctl->
molmass * cd[idx] / (
RHO(press[iz], temp) * dz * 1e3);
10257 for (
int iq = 0; iq < ctl->
nq; iq++) {
10258 mean[iq][idx] /= np[idx];
10259 double var = sigma[iq][idx] / np[idx] -
SQR(mean[iq][idx]);
10260 sigma[iq][idx] = (var > 0 ? sqrt(var) : 0);
10262 for (
int iq = 0; iq < ctl->
nq; iq++) {
10263 mean[iq][idx] = NAN;
10264 sigma[iq][idx] = NAN;
10271 t, z, lon, lat, area, dz, np);
10276 t, z, lon, lat, area, dz, np);
10280 ERRMSG(
"Grid data format GRID_TYPE unknown!");
10284 for (
int iq = 0; iq < ctl->
nq; iq++) {
10303 const char *filename,
10308 const double *vmr_impl,
10313 const double *area,
10323 if (!(out = popen(
"gnuplot",
"w")))
10324 ERRMSG(
"Cannot create pipe to gnuplot!");
10327 fprintf(out,
"set out \"%s.png\"\n", filename);
10331 int year, mon, day, hour, min, sec;
10332 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
10333 fprintf(out,
"timestr=\"%d-%02d-%02d, %02d:%02d UTC\"\n",
10334 year, mon, day, hour, min);
10340 ERRMSG(
"Cannot open file!");
10341 while (fgets(line,
LEN, in))
10342 fprintf(out,
"%s", line);
10349 if (!(out = fopen(filename,
"w")))
10350 ERRMSG(
"Cannot create file!");
10355 "# $1 = time [s]\n"
10356 "# $2 = altitude [km]\n"
10357 "# $3 = longitude [deg]\n"
10358 "# $4 = latitude [deg]\n"
10359 "# $5 = surface area [km^2]\n"
10360 "# $6 = layer depth [km]\n"
10361 "# $7 = column density (implicit) [kg/m^2]\n"
10362 "# $8 = volume mixing ratio (implicit) [ppv]\n"
10363 "# $9 = number of particles [1]\n");
10364 for (
int iq = 0; iq < ctl->
nq; iq++)
10365 fprintf(out,
"# $%i = %s (mean) [%s]\n", 10 + iq, ctl->
qnt_name[iq],
10368 for (
int iq = 0; iq < ctl->
nq; iq++)
10369 fprintf(out,
"# $%i = %s (stddev) [%s]\n", 10 + ctl->
nq + iq,
10371 fprintf(out,
"\n");
10374 for (
int ix = 0; ix < ctl->
grid_nx; ix++) {
10376 fprintf(out,
"\n");
10377 for (
int iy = 0; iy < ctl->
grid_ny; iy++) {
10379 fprintf(out,
"\n");
10380 for (
int iz = 0; iz < ctl->
grid_nz; iz++) {
10383 fprintf(out,
"%.2f %g %g %g %g %g %g %g %d", t, z[iz], lon[ix],
10384 lat[iy], area[iy], dz, cd[idx], vmr_impl[idx], np[idx]);
10385 for (
int iq = 0; iq < ctl->
nq; iq++) {
10387 fprintf(out, ctl->
qnt_format[iq], mean[iq][idx]);
10390 for (
int iq = 0; iq < ctl->
nq; iq++) {
10392 fprintf(out, ctl->
qnt_format[iq], sigma[iq][idx]);
10394 fprintf(out,
"\n");
10407 const char *filename,
10412 const double *vmr_impl,
10417 const double *area,
10421 char longname[2 *
LEN], varname[2 *
LEN];
10425 int *help2, ncid, dimid[10], varid;
10427 size_t start[2], count[2];
10430 ALLOC(help,
double,
10436 NC(nc_create(filename, NC_NETCDF4, &ncid));
10439 NC(nc_def_dim(ncid,
"time", 1, &dimid[0]));
10440 NC(nc_def_dim(ncid,
"z", (
size_t) ctl->
grid_nz, &dimid[1]));
10441 NC(nc_def_dim(ncid,
"lat", (
size_t) ctl->
grid_ny, &dimid[2]));
10442 NC(nc_def_dim(ncid,
"lon", (
size_t) ctl->
grid_nx, &dimid[3]));
10443 NC(nc_def_dim(ncid,
"dz", 1, &dimid[4]));
10446 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &dimid[0],
"time",
10447 "seconds since 2000-01-01 00:00:00 UTC", 0, 0);
10448 NC_DEF_VAR(
"z", NC_DOUBLE, 1, &dimid[1],
"altitude",
"km", 0, 0);
10449 NC_DEF_VAR(
"lat", NC_DOUBLE, 1, &dimid[2],
"latitude",
"degrees_north", 0,
10451 NC_DEF_VAR(
"lon", NC_DOUBLE, 1, &dimid[3],
"longitude",
"degrees_east", 0,
10453 NC_DEF_VAR(
"dz", NC_DOUBLE, 1, &dimid[1],
"layer depth",
"km", 0, 0);
10454 NC_DEF_VAR(
"area", NC_DOUBLE, 1, &dimid[2],
"surface area",
"km**2", 0, 0);
10456 NC_DEF_VAR(
"cd", NC_FLOAT, 4, dimid,
"column density",
"kg m**-2",
10458 NC_DEF_VAR(
"vmr_impl", NC_FLOAT, 4, dimid,
"volume mixing ratio (implicit)",
10460 NC_DEF_VAR(
"np", NC_INT, 4, dimid,
"number of particles",
"1", 0, 0);
10461 for (
int iq = 0; iq < ctl->
nq; iq++) {
10462 sprintf(varname,
"%s_mean", ctl->
qnt_name[iq]);
10463 sprintf(longname,
"%s (mean)", ctl->
qnt_longname[iq]);
10467 sprintf(varname,
"%s_stddev", ctl->
qnt_name[iq]);
10468 sprintf(longname,
"%s (stddev)", ctl->
qnt_longname[iq]);
10474 NC(nc_enddef(ncid));
10484 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
10485 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
10486 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
10491 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
10492 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
10493 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
10498 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
10499 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
10500 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
10505 for (
int iq = 0; iq < ctl->
nq; iq++) {
10506 sprintf(varname,
"%s_mean", ctl->
qnt_name[iq]);
10507 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
10508 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
10509 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
10516 for (
int iq = 0; iq < ctl->
nq; iq++) {
10517 sprintf(varname,
"%s_stddev", ctl->
qnt_name[iq]);
10518 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
10519 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
10520 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
10527 NC(nc_close(ncid));
10537 const char *filename,
10543 if (!(out = fopen(filename,
"w")))
10544 ERRMSG(
"Cannot create file!");
10641 const char *varname) {
10650 for (
int ix = 0; ix < met->
nx; ix++)
10651 for (
int iy = 0; iy < met->
ny; iy++)
10652 help[
ARRAY_2D(ix, iy, met->
ny)] = var[ix][iy];
10655 LOG(2,
"Write 2-D variable: %s (uncompressed)", varname);
10657 (
size_t) (met->
nx * met->
ny),
10671 const char *varname,
10672 const int precision,
10673 const double tolerance) {
10682#pragma omp parallel for default(shared) collapse(2)
10683 for (
int ix = 0; ix < met->
nx; ix++)
10684 for (
int iy = 0; iy < met->
ny; iy++)
10685 for (
int ip = 0; ip < met->
np; ip++)
10686 help[
ARRAY_3D(ix, iy, met->
ny, ip, met->
np)] = var[ix][iy][ip];
10690 LOG(2,
"Write 3-D variable: %s (uncompressed)", varname);
10692 (
size_t) (met->
nx * met->
ny * met->
np),
10699 (
size_t) met->
np, 0, out);
10707 FWRITE(&tolerance,
double,
10711 tolerance, 0, out);
10726 (
size_t) met->
np, 0, out);
10732 ERRMSG(
"MET_TYPE not supported!");
10733 LOG(3,
"%d %g", precision, tolerance);
10743 const char *filename,
10749 size_t start[4], count[4];
10750 nc_create(filename, NC_NETCDF4, &ncid);
10753 int tid, lonid, latid, levid;
10754 NC(nc_def_dim(ncid,
"time", 1, &tid));
10755 NC(nc_def_dim(ncid,
"lon", (
size_t) met->
nx, &lonid));
10756 NC(nc_def_dim(ncid,
"lat", (
size_t) met->
ny, &latid));
10757 NC(nc_def_dim(ncid,
"lev", (
size_t) met->
np, &levid));
10760 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"time",
10761 "seconds since 2000-01-01 00:00:00 UTC", 0, 0);
10762 NC_DEF_VAR(
"lon", NC_DOUBLE, 1, &lonid,
"longitude",
"degrees_east", 0, 0);
10763 NC_DEF_VAR(
"lat", NC_DOUBLE, 1, &latid,
"latitude",
"degrees_north", 0, 0);
10764 NC_DEF_VAR(
"lev", NC_DOUBLE, 1, &levid,
"pressure",
"Pa", 0, 0);
10767 int dimid2[2] = { latid, lonid };
10768 NC_DEF_VAR(
"sp", NC_FLOAT, 2, dimid2,
"Surface pressure",
"Pa",
10770 NC_DEF_VAR(
"z", NC_FLOAT, 2, dimid2,
"Geopotential",
"m**2 s**-2",
10772 NC_DEF_VAR(
"t2m", NC_FLOAT, 2, dimid2,
"2 metre temperature",
"K",
10774 NC_DEF_VAR(
"u10m", NC_FLOAT, 2, dimid2,
"10 metre U wind component",
10776 NC_DEF_VAR(
"v10m", NC_FLOAT, 2, dimid2,
"10 metre V wind component",
10779 "Instantaneous eastward turbulent surface stress",
"N m**-2",
10782 "Instantaneous northward turbulent surface stress",
"N m**-2",
10785 "Instantaneous surface sensible heat flux",
"W m**-1",
10787 NC_DEF_VAR(
"lsm", NC_FLOAT, 2, dimid2,
"Land/sea mask",
"-",
10789 NC_DEF_VAR(
"sstk", NC_FLOAT, 2, dimid2,
"Sea surface temperature",
"K",
10791 NC_DEF_VAR(
"blp", NC_FLOAT, 2, dimid2,
"Boundary layer pressure",
"Pa",
10793 NC_DEF_VAR(
"pt", NC_FLOAT, 2, dimid2,
"Tropopause pressure",
"Pa",
10795 NC_DEF_VAR(
"tt", NC_FLOAT, 2, dimid2,
"Tropopause temperature",
"K",
10797 NC_DEF_VAR(
"zt", NC_FLOAT, 2, dimid2,
"Tropopause height",
"m",
10799 NC_DEF_VAR(
"h2ot", NC_FLOAT, 2, dimid2,
"Tropopause water vapor",
"ppv",
10801 NC_DEF_VAR(
"pct", NC_FLOAT, 2, dimid2,
"Cloud top pressure",
"Pa",
10803 NC_DEF_VAR(
"pcb", NC_FLOAT, 2, dimid2,
"Cloud bottom pressure",
"Pa",
10805 NC_DEF_VAR(
"cl", NC_FLOAT, 2, dimid2,
"Total column cloud water",
"kg m**2",
10808 "Pressure at lifted condensation level (LCL)",
"Pa",
10811 "Pressure at level of free convection (LFC)",
"Pa",
10813 NC_DEF_VAR(
"pel", NC_FLOAT, 2, dimid2,
"Pressure at equilibrium level (EL)",
10816 "Convective available potential energy",
"J kg**-1",
10818 NC_DEF_VAR(
"cin", NC_FLOAT, 2, dimid2,
"Convective inhibition",
"J kg**-1",
10820 NC_DEF_VAR(
"o3c", NC_FLOAT, 2, dimid2,
"Total column ozone",
"DU",
10824 int dimid3[3] = { levid, latid, lonid };
10825 NC_DEF_VAR(
"t", NC_FLOAT, 3, dimid3,
"Temperature",
"K",
10827 NC_DEF_VAR(
"u", NC_FLOAT, 3, dimid3,
"U velocity",
"m s**-1",
10829 NC_DEF_VAR(
"v", NC_FLOAT, 3, dimid3,
"V velocity",
"m s**-1",
10831 NC_DEF_VAR(
"w", NC_FLOAT, 3, dimid3,
"Vertical velocity",
"Pa s**-1",
10833 NC_DEF_VAR(
"q", NC_FLOAT, 3, dimid3,
"Specific humidity",
"kg kg**-1",
10835 NC_DEF_VAR(
"o3", NC_FLOAT, 3, dimid3,
"Ozone mass mixing ratio",
10837 NC_DEF_VAR(
"clwc", NC_FLOAT, 3, dimid3,
"Cloud liquid water content",
10839 NC_DEF_VAR(
"crwc", NC_FLOAT, 3, dimid3,
"Cloud rain water content",
10841 NC_DEF_VAR(
"ciwc", NC_FLOAT, 3, dimid3,
"Cloud ice water content",
10843 NC_DEF_VAR(
"cswc", NC_FLOAT, 3, dimid3,
"Cloud snow water content",
10845 NC_DEF_VAR(
"cc", NC_FLOAT, 3, dimid3,
"Cloud cover",
"-",
10849 NC(nc_enddef(ncid));
10856 for (
int ip = 0; ip < met->
np; ip++)
10857 phelp[ip] = 100. * met->
p[ip];
10900 NC(nc_close(ncid));
10907 const char *varname,
10913 size_t start[4], count[4];
10921 for (
int ix = 0; ix < met->
nx; ix++)
10922 for (
int iy = 0; iy < met->
ny; iy++)
10923 help[
ARRAY_2D(iy, ix, met->
nx)] = scl * var[ix][iy];
10936 const char *varname,
10942 size_t start[4], count[4];
10950 for (
int ix = 0; ix < met->
nx; ix++)
10951 for (
int iy = 0; iy < met->
ny; iy++)
10952 for (
int ip = 0; ip < met->
np; ip++)
10953 help[
ARRAY_3D(ip, iy, met->
ny, ix, met->
nx)] = scl * var[ix][iy][ip];
10965 const char *filename,
10974 static double *mass, *obsmean, *rt, *rz, *rlon, *rlat, *robs, *area,
10975 dz, dlon, dlat, *lon, *lat, *z, *press, temp, vmr, h2o, o3;
10977 static int nobs, *obscount, ip, okay;
10986 if (ctl->
qnt_m < 0)
10987 ERRMSG(
"Need quantity mass!");
10991 ERRMSG(
"Specify molar mass!");
10998 ALLOC(area,
double,
11002 ALLOC(press,
double,
11008 ALLOC(rlon,
double,
11010 ALLOC(rlat,
double,
11012 ALLOC(robs,
double,
11019 LOG(1,
"Write profile data: %s", filename);
11020 if (!(out = fopen(filename,
"w")))
11021 ERRMSG(
"Cannot create file!");
11025 "# $1 = time [s]\n"
11026 "# $2 = altitude [km]\n"
11027 "# $3 = longitude [deg]\n"
11028 "# $4 = latitude [deg]\n"
11029 "# $5 = pressure [hPa]\n"
11030 "# $6 = temperature [K]\n"
11031 "# $7 = volume mixing ratio [ppv]\n"
11032 "# $8 = H2O volume mixing ratio [ppv]\n"
11033 "# $9 = O3 volume mixing ratio [ppv]\n"
11034 "# $10 = observed BT index [K]\n"
11035 "# $11 = number of observations\n");
11043 for (
int iz = 0; iz < ctl->
prof_nz; iz++) {
11044 z[iz] = ctl->
prof_z0 + dz * (iz + 0.5);
11045 press[iz] =
P(z[iz]);
11049 for (
int ix = 0; ix < ctl->
prof_nx; ix++)
11050 lon[ix] = ctl->
prof_lon0 + dlon * (ix + 0.5);
11051 for (
int iy = 0; iy < ctl->
prof_ny; iy++) {
11052 lat[iy] = ctl->
prof_lat0 + dlat * (iy + 0.5);
11053 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat[iy]));
11058 const double t0 = t - 0.5 * ctl->
dt_mod;
11059 const double t1 = t + 0.5 * ctl->
dt_mod;
11062 ALLOC(mass,
double,
11064 ALLOC(obsmean,
double,
11066 ALLOC(obscount,
int,
11070 for (
int i = 0; i < nobs; i++) {
11075 else if (rt[i] >= t1)
11079 if (!isfinite(robs[i]))
11083 int ix = (int) ((rlon[i] - ctl->
prof_lon0) / dlon);
11084 int iy = (int) ((rlat[i] - ctl->
prof_lat0) / dlat);
11087 if (ix < 0 || ix >= ctl->
prof_nx || iy < 0 || iy >= ctl->
prof_ny)
11092 obsmean[idx] += robs[i];
11097 for (ip = 0; ip < atm->
np; ip++) {
11100 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11104 int ix = (int) ((atm->
lon[ip] - ctl->
prof_lon0) / dlon);
11105 int iy = (int) ((atm->
lat[ip] - ctl->
prof_lat0) / dlat);
11106 int iz = (int) ((
Z(atm->
p[ip]) - ctl->
prof_z0) / dz);
11109 if (ix < 0 || ix >= ctl->
prof_nx ||
11115 mass[idx] += atm->
q[ctl->
qnt_m][ip];
11119 for (
int ix = 0; ix < ctl->
prof_nx; ix++)
11120 for (
int iy = 0; iy < ctl->
prof_ny; iy++) {
11122 if (obscount[idx2] > 0) {
11126 for (
int iz = 0; iz < ctl->
prof_nz; iz++) {
11128 if (mass[idx3] > 0) {
11137 fprintf(out,
"\n");
11140 for (
int iz = 0; iz < ctl->
prof_nz; iz++) {
11145 lon[ix], lat[iy], &temp, ci, cw, 1);
11147 lon[ix], lat[iy], &h2o, ci, cw, 0);
11149 lon[ix], lat[iy], &o3, ci, cw, 0);
11154 / (
RHO(press[iz], temp) * area[iy] * dz * 1e9);
11157 fprintf(out,
"%.2f %g %g %g %g %g %g %g %g %g %d\n",
11158 t, z[iz], lon[ix], lat[iy], press[iz], temp, vmr, h2o, o3,
11159 obsmean[idx2] / obscount[idx2], obscount[idx2]);
11192 const char *filename,
11201 static double area, dlat, rmax2, *rt, *rz, *rlon, *rlat, *robs, kz[
EP],
11204 static int nobs, nk;
11217 ALLOC(rlon,
double,
11219 ALLOC(rlat,
double,
11221 ALLOC(robs,
double,
11232 LOG(1,
"Write sample data: %s", filename);
11233 if (!(out = fopen(filename,
"w")))
11234 ERRMSG(
"Cannot create file!");
11238 "# $1 = time [s]\n"
11239 "# $2 = altitude [km]\n"
11240 "# $3 = longitude [deg]\n"
11241 "# $4 = latitude [deg]\n"
11242 "# $5 = surface area [km^2]\n"
11243 "# $6 = layer depth [km]\n"
11244 "# $7 = number of particles [1]\n"
11245 "# $8 = column density [kg/m^2]\n"
11246 "# $9 = volume mixing ratio [ppv]\n"
11247 "# $10 = observed BT index [K]\n\n");
11252 area = M_PI * rmax2;
11256 const double t0 = t - 0.5 * ctl->
dt_mod;
11257 const double t1 = t + 0.5 * ctl->
dt_mod;
11260 for (
int i = 0; i < nobs; i++) {
11265 else if (rt[i] >= t1)
11270 geo2cart(0, rlon[i], rlat[i], x0);
11273 const double rp =
P(rz[i]);
11274 const double ptop =
P(rz[i] + ctl->
sample_dz);
11275 const double pbot =
P(rz[i] - ctl->
sample_dz);
11283 for (
int ip = 0; ip < atm->
np; ip++) {
11286 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11290 if (fabs(rlat[i] - atm->
lat[ip]) > dlat)
11296 if (
DIST2(x0, x1) > rmax2)
11301 if (atm->
p[ip] > pbot || atm->
p[ip] < ptop)
11305 if (ctl->
qnt_m >= 0)
11312 const double cd = mass / (1e6 * area);
11323 rlon[i], rlat[i], &temp, ci, cw, 1);
11332 fprintf(out,
"%.2f %g %g %g %g %g %d %g %g %g\n", rt[i], rz[i],
11333 rlon[i], rlat[i], area, ctl->
sample_dz, np, cd, vmr, robs[i]);
11354 const char *filename,
11361 static double rmax2, x0[3], x1[3];
11370 LOG(1,
"Write station data: %s", filename);
11373 if (!(out = fopen(filename,
"w")))
11374 ERRMSG(
"Cannot create file!");
11378 "# $1 = time [s]\n"
11379 "# $2 = altitude [km]\n"
11380 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
11381 for (
int iq = 0; iq < ctl->
nq; iq++)
11382 fprintf(out,
"# $%i = %s [%s]\n", (iq + 5),
11384 fprintf(out,
"\n");
11392 const double t0 = t - 0.5 * ctl->
dt_mod;
11393 const double t1 = t + 0.5 * ctl->
dt_mod;
11396 for (
int ip = 0; ip < atm->
np; ip++) {
11399 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11415 if (
DIST2(x0, x1) > rmax2)
11423 fprintf(out,
"%.2f %g %g %g",
11424 atm->
time[ip],
Z(atm->
p[ip]), atm->
lon[ip], atm->
lat[ip]);
11425 for (
int iq = 0; iq < ctl->
nq; iq++) {
11427 fprintf(out, ctl->
qnt_format[iq], atm->
q[iq][ip]);
11429 fprintf(out,
"\n");
11440 const char *filename,
11451 LOG(1,
"Write VTK data: %s", filename);
11454 const double t0 = t - 0.5 * ctl->
dt_mod;
11455 const double t1 = t + 0.5 * ctl->
dt_mod;
11458 if (!(out = fopen(filename,
"w")))
11459 ERRMSG(
"Cannot create file!");
11463 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
11464 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11471 "# vtk DataFile Version 3.0\n"
11472 "vtk output\n" "ASCII\n" "DATASET POLYDATA\n");
11475 fprintf(out,
"POINTS %d float\n", np);
11477 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
11478 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11482 const double coslat = cos(
DEG2RAD(atm->
lat[ip]));
11483 const double x = radius * coslat * cos(
DEG2RAD(atm->
lon[ip]));
11484 const double y = radius * coslat * sin(
DEG2RAD(atm->
lon[ip]));
11485 const double z = radius * sin(
DEG2RAD(atm->
lat[ip]));
11486 fprintf(out,
"%g %g %g\n", x, y, z);
11489 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
11490 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11492 fprintf(out,
"%g %g %g\n", atm->
lon[ip], atm->
lat[ip],
11497 fprintf(out,
"POINT_DATA %d\n", np);
11498 for (
int iq = 0; iq < ctl->
nq; iq++) {
11499 fprintf(out,
"SCALARS %s float 1\n" "LOOKUP_TABLE default\n",
11501 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
11502 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11504 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 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)
Calculates the tropopause and related meteorological variables based on various methods and stores th...
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_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)
Interpolates meteorological data to specified pressure levels.
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 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 RA
Specific gas constant of dry air [J/(kg K)].
#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 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 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 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.
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].