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]";
473 const int max_level_grid = 7;
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);
490 cms_sol_t *cms_sol = cms_read_sol(cms_ptr, inout);
493#pragma omp parallel for default(shared)
494 for (
size_t ix = 0; ix < nx; ix++)
495 for (
size_t iy = 0; iy < ny; iy++) {
496 double val, x[] = { lon[ix], lat[iy] };
497 cms_eval(cms_ptr, cms_sol, x, &val);
498 array[
ARRAY_3D(ix, iy, ny, ip, np)] = (float) val;
502 cr += cms_compression_rate(cms_ptr, cms_sol) / (double) np;
505 cms_delete_sol(cms_sol);
506 cms_delete_module(cms_ptr);
510 LOG(2,
"Read 3-D variable: %s (cms, RATIO= %g %%)", varname, cr);
517 cms_module_t *cms_ptr[
EP];
518 cms_sol_t *cms_sol[
EP];
522 ? (size_t) omp_get_max_threads()
524 for (
size_t ip0 = 0; ip0 < np; ip0 += dip) {
527 double t0 = omp_get_wtime();
530#pragma omp parallel for default(shared)
531 for (
size_t ip = ip0; ip <
MIN(ip0 + dip, np); ip++) {
535 ALLOC(tmp_arr,
float,
539 for (
size_t ix = 0; ix < nx; ++ix)
540 for (
size_t iy = 0; iy < ny; ++iy)
542 array[
ARRAY_3D(ix, iy, ny, ip, np)];
545 cms_ptr[ip] = cms_init(cms_param);
548 cms_sol[ip] = cms_read_arr(cms_ptr[ip], tmp_arr, lon, lat, nx, ny);
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_coarsening(cms_ptr[ip], cms_sol[ip],
589 t_coars += (omp_get_wtime() - t0);
592 for (
size_t ip = ip0; ip <
MIN(ip0 + dip, np); ip++) {
595 double *tmp_cms, *tmp_org, *tmp_diff;
596 ALLOC(tmp_cms,
double,
598 ALLOC(tmp_org,
double,
600 ALLOC(tmp_diff,
double,
604 t0 = omp_get_wtime();
607#pragma omp parallel for default(shared)
608 for (
size_t ix = 0; ix < nx; ix++)
609 for (
size_t iy = 0; iy < ny; iy++) {
611 double x[] = { lon[ix], lat[iy] };
612 cms_eval(cms_ptr[ip], cms_sol[ip], x, &tmp_cms[idx]);
613 tmp_org[idx] = array[
ARRAY_3D(ix, iy, ny, ip, np)];
614 tmp_diff[idx] = tmp_cms[idx] - tmp_org[idx];
618 t_eval += (omp_get_wtime() - t0);
622 "cmultiscale: var= %s / lev= %lu / ratio= %g / rho= %g"
623 " / mean= %g / sd= %g / min= %g / max= %g", varname, ip,
624 cms_compression_rate(cms_ptr[ip], cms_sol[ip]),
625 gsl_stats_correlation(tmp_cms, 1, tmp_org, 1, nxy),
626 gsl_stats_mean(tmp_diff, 1, nxy), gsl_stats_sd(tmp_diff, 1, nxy),
627 gsl_stats_min(tmp_diff, 1, nxy), gsl_stats_max(tmp_diff, 1, nxy));
630 cr += cms_compression_rate(cms_ptr[ip], cms_sol[ip]) / (double) np;
633 cms_save_sol(cms_sol[ip], cms_ptr[ip], inout);
636 cms_delete_sol(cms_sol[ip]);
637 cms_delete_module(cms_ptr[ip]);
645 LOG(2,
"Write 3-D variable: %s"
646 " (cms, RATIO= %g, T_COARS= %g s, T_EVAL= %g s)",
647 varname, cr, t_coars, t_eval);
651 cms_delete_param(cms_param);
662 const int decompress,
665 double min[
EP], max[
EP], off[
EP], scl[
EP];
667 unsigned short *sarray;
670 ALLOC(sarray,
unsigned short,
677 LOG(2,
"Read 3-D variable: %s (pck, RATIO= %g)",
678 varname, (
double)
sizeof(
float) / (
double)
sizeof(
unsigned short));
687 FREAD(sarray,
unsigned short,
692#pragma omp parallel for default(shared)
693 for (
size_t ixy = 0; ixy < nxy; ixy++)
694 for (
size_t iz = 0; iz < nz; iz++)
696 = (
float) (sarray[ixy * nz + iz] * scl[iz] + off[iz]);
703 LOG(2,
"Write 3-D variable: %s (pck, RATIO= %g)",
704 varname, (
double)
sizeof(
float) / (
double)
sizeof(
unsigned short));
707 for (
size_t iz = 0; iz < nz; iz++) {
711 for (
size_t ixy = 1; ixy < nxy; ixy++)
712 for (
size_t iz = 0; iz < nz; iz++) {
713 if (array[ixy * nz + iz] < min[iz])
714 min[iz] = array[ixy * nz + iz];
715 if (array[ixy * nz + iz] > max[iz])
716 max[iz] = array[ixy * nz + iz];
720 for (
size_t iz = 0; iz < nz; iz++) {
721 scl[iz] = (max[iz] - min[iz]) / 65533.;
726#pragma omp parallel for default(shared)
727 for (
size_t ixy = 0; ixy < nxy; ixy++)
728 for (
size_t iz = 0; iz < nz; iz++)
730 sarray[ixy * nz + iz] = (
unsigned short)
731 ((array[ixy * nz + iz] - off[iz]) / scl[iz] + .5);
733 sarray[ixy * nz + iz] = 0;
742 FWRITE(sarray,
unsigned short,
761 const double tolerance,
762 const int decompress,
773 const zfp_type type = zfp_type_float;
774 field = zfp_field_3d(array, type, (uint) nx, (uint) ny, (uint) nz);
777 zfp = zfp_stream_open(NULL);
781 double actual_tol = 0;
783 actual_prec = (int) zfp_stream_set_precision(zfp, (uint) precision);
784 else if (tolerance > 0)
785 actual_tol = zfp_stream_set_accuracy(zfp, tolerance);
787 ERRMSG(
"Set precision or tolerance!");
790 bufsize = zfp_stream_maximum_size(zfp, field);
791 buffer = malloc(bufsize);
794 stream = stream_open(buffer, bufsize);
795 zfp_stream_set_bit_stream(zfp, stream);
796 zfp_stream_rewind(zfp);
800 FREAD(&zfpsize,
size_t,
803 if (fread(buffer, 1, zfpsize, inout) != zfpsize)
804 ERRMSG(
"Error while reading zfp data!");
805 if (!zfp_decompress(zfp, field)) {
806 ERRMSG(
"Decompression failed!");
808 LOG(2,
"Read 3-D variable: %s "
809 "(zfp, PREC= %d, TOL= %g, RATIO= %g)",
810 varname, actual_prec, actual_tol,
811 ((
double) (nx * ny * nz)) / (
double) zfpsize);
816 zfpsize = zfp_compress(zfp, field);
818 ERRMSG(
"Compression failed!");
823 if (fwrite(buffer, 1, zfpsize, inout) != zfpsize)
824 ERRMSG(
"Error while writing zfp data!");
826 LOG(2,
"Write 3-D variable: %s "
827 "(zfp, PREC= %d, TOL= %g, RATIO= %g)",
828 varname, actual_prec, actual_tol,
829 ((
double) (nx * ny * nz)) / (
double) zfpsize);
833 zfp_field_free(field);
834 zfp_stream_close(zfp);
835 stream_close(stream);
847 const int decompress,
851 size_t uncomprLen = n *
sizeof(float);
852 size_t comprLen = ZSTD_compressBound(uncomprLen);
856 char *compr = (
char *) calloc((uint) comprLen, 1);
857 char *uncompr = (
char *) array;
861 FREAD(&comprLen,
size_t,
864 if (fread(compr, 1, comprLen, inout) != comprLen)
865 ERRMSG(
"Error while reading zstd data!");
866 compsize = ZSTD_decompress(uncompr, uncomprLen, compr, comprLen);
867 if (ZSTD_isError(compsize)) {
868 ERRMSG(
"Decompression failed!");
870 LOG(2,
"Read 3-D variable: %s (zstd, RATIO= %g)",
871 varname, ((
double) uncomprLen) / (
double) comprLen)
876 compsize = ZSTD_compress(compr, comprLen, uncompr, uncomprLen, 0);
877 if (ZSTD_isError(compsize)) {
878 ERRMSG(
"Compression failed!");
883 if (fwrite(compr, 1, compsize, inout) != compsize)
884 ERRMSG(
"Error while writing zstd data!");
886 LOG(2,
"Write 3-D variable: %s (zstd, RATIO= %g)",
887 varname, ((
double) uncomprLen) / (
double) compsize);
904 d0[12] = { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 },
905 d0l[12] = { 1, 32, 61, 92, 122, 153, 183, 214, 245, 275, 306, 336 };
908 if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
909 *doy = d0l[mon - 1] + day - 1;
911 *doy = d0[mon - 1] + day - 1;
923 d0[12] = { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 },
924 d0l[12] = { 1, 32, 61, 92, 122, 153, 183, 214, 245, 275, 306, 336 };
929 if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) {
930 for (i = 11; i > 0; i--)
934 *day = doy - d0l[i] + 1;
936 for (i = 11; i > 0; i--)
940 *day = doy - d0[i] + 1;
951 gsl_fft_complex_wavetable *wavetable;
952 gsl_fft_complex_workspace *workspace;
958 ERRMSG(
"Too many data points!");
961 wavetable = gsl_fft_complex_wavetable_alloc((
size_t) n);
962 workspace = gsl_fft_complex_workspace_alloc((
size_t) n);
965 for (
int i = 0; i < n; i++) {
966 data[2 * i] = fcReal[i];
967 data[2 * i + 1] = fcImag[i];
971 gsl_fft_complex_forward(data, 1, (
size_t) n, wavetable, workspace);
974 for (
int i = 0; i < n; i++) {
975 fcReal[i] = data[2 * i];
976 fcImag[i] = data[2 * i + 1];
980 gsl_fft_complex_wavetable_free(wavetable);
981 gsl_fft_complex_workspace_free(workspace);
992 const double radius = z +
RE;
993 const double latrad =
DEG2RAD(lat);
994 const double lonrad =
DEG2RAD(lon);
995 const double coslat = cos(latrad);
997 x[0] = radius * coslat * cos(lonrad);
998 x[1] = radius * coslat * sin(lonrad);
999 x[2] = radius * sin(latrad);
1015 char cachefile[
LEN], cmd[2 *
LEN], filename[
LEN];
1021 if (t == ctl->
t_start || !init) {
1027 if (!
read_met(filename, ctl, clim, *met0))
1028 ERRMSG(
"Cannot open file!");
1032 if (!
read_met(filename, ctl, clim, *met1))
1033 ERRMSG(
"Cannot open file!");
1038 met_t *met0up = *met0;
1039 met_t *met1up = *met1;
1041#pragma acc update device(met0up[:1],met1up[:1]) async(5)
1043#pragma acc update device(met0up[:1],met1up[:1])
1052 sprintf(cmd,
"cat %s > /dev/null &", cachefile);
1053 LOG(1,
"Caching: %s", cachefile);
1054 if (system(cmd) != 0)
1055 WARN(
"Caching command failed!");
1060 if (t > (*met1)->time) {
1069 if (!
read_met(filename, ctl, clim, *met1))
1070 ERRMSG(
"Cannot open file!");
1075 met_t *met1up = *met1;
1077#pragma acc update device(met1up[:1]) async(5)
1079#pragma acc update device(met1up[:1])
1088 sprintf(cmd,
"cat %s > /dev/null &", cachefile);
1089 LOG(1,
"Caching: %s", cachefile);
1090 if (system(cmd) != 0)
1091 WARN(
"Caching command failed!");
1096 if (t < (*met0)->time) {
1105 if (!
read_met(filename, ctl, clim, *met0))
1106 ERRMSG(
"Cannot open file!");
1111 met_t *met0up = *met0;
1113#pragma acc update device(met0up[:1]) async(5)
1115#pragma acc update device(met0up[:1])
1124 sprintf(cmd,
"cat %s > /dev/null &", cachefile);
1125 LOG(1,
"Caching: %s", cachefile);
1126 if (system(cmd) != 0)
1127 WARN(
"Caching command failed!");
1132 if ((*met0)->nx != 0 && (*met1)->nx != 0) {
1133 if ((*met0)->nx != (*met1)->nx
1134 || (*met0)->ny != (*met1)->ny || (*met0)->np != (*met1)->np)
1135 ERRMSG(
"Meteo grid dimensions do not match!");
1136 for (
int ix = 0; ix < (*met0)->nx; ix++)
1137 if (fabs((*met0)->lon[ix] - (*met1)->lon[ix]) > 0.001)
1138 ERRMSG(
"Meteo grid longitudes do not match!");
1139 for (
int iy = 0; iy < (*met0)->ny; iy++)
1140 if (fabs((*met0)->lat[iy] - (*met1)->lat[iy]) > 0.001)
1141 ERRMSG(
"Meteo grid latitudes do not match!");
1142 for (
int ip = 0; ip < (*met0)->np; ip++)
1143 if (fabs((*met0)->p[ip] - (*met1)->p[ip]) > 0.001)
1144 ERRMSG(
"Meteo grid pressure levels do not match!");
1154 const char *metbase,
1155 const double dt_met,
1162 int year, mon, day, hour, min, sec;
1166 t6 = floor(t / dt_met) * dt_met;
1168 t6 = ceil(t / dt_met) * dt_met;
1171 jsec2time(t6, &year, &mon, &day, &hour, &min, &sec, &r);
1176 sprintf(filename,
"%s_YYYY_MM_DD_HH.nc", metbase);
1178 sprintf(filename,
"%s_YYYY_MM_DD_HH.bin", metbase);
1180 sprintf(filename,
"%s_YYYY_MM_DD_HH.pck", metbase);
1182 sprintf(filename,
"%s_YYYY_MM_DD_HH.zfp", metbase);
1184 sprintf(filename,
"%s_YYYY_MM_DD_HH.zstd", metbase);
1186 sprintf(filename,
"%s_YYYY_MM_DD_HH.cms", metbase);
1187 sprintf(repl,
"%d", year);
1189 sprintf(repl,
"%02d", mon);
1191 sprintf(repl,
"%02d", day);
1193 sprintf(repl,
"%02d", hour);
1199 sprintf(filename,
"%s_YYMMDDHH.nc", metbase);
1200 sprintf(repl,
"%d", year);
1202 sprintf(repl,
"%02d", year % 100);
1204 sprintf(repl,
"%02d", mon);
1206 sprintf(repl,
"%02d", day);
1208 sprintf(repl,
"%02d", hour);
1223 for (
int i = 0; i < 3; i++) {
1227 if (!(ch = strstr(orig, search)))
1229 strncpy(buffer, orig, (
size_t) (ch - orig));
1230 buffer[ch - orig] = 0;
1231 sprintf(buffer + (ch - orig),
"%s%s", repl, ch + strlen(search));
1233 strcpy(orig, buffer);
1240 const int met_tropo,
1260#pragma omp parallel for default(shared) private(ci,cw)
1261 for (
int ix = 0; ix < nx; ix++)
1262 for (
int iy = 0; iy < ny; iy++) {
1264 &pt[iy * nx + ix], ci, cw, 1);
1266 &ps[iy * nx + ix], ci, cw, 0);
1268 &zs[iy * nx + ix], ci, cw, 0);
1270 lats[iy], &zt[iy * nx + ix], ci, cw, 1);
1272 lats[iy], &tt[iy * nx + ix], ci, cw, 0);
1274 lats[iy], &qt[iy * nx + ix], ci, cw, 0);
1276 lats[iy], &o3t[iy * nx + ix], ci, cw, 0);
1284 float heights0[
EX][
EY][
EP],
1285 float array0[
EX][
EY][
EP],
1287 float heights1[
EX][
EY][
EP],
1288 float array1[
EX][
EY][
EP],
1290 const double height,
1301 double lon2 =
FMOD(lon, 360.);
1302 if (lon2 < met0->lon[0])
1304 else if (lon2 > met0->
lon[met0->
nx - 1])
1318 int k_max = ind[0][0];
1319 for (
int i = 0; i < 2; i++)
1320 for (
int j = 0; j < 4; j++) {
1321 if (ci[2] > ind[i][j])
1323 if (k_max < ind[i][j])
1329 cw[0] = (lon2 - met0->
lon[ci[0]]) /
1330 (met0->
lon[ci[0] + 1] - met0->
lon[ci[0]]);
1331 cw[1] = (lat - met0->
lat[ci[1]]) /
1332 (met0->
lat[ci[1] + 1] - met0->
lat[ci[1]]);
1335 double height_top, height_bot;
1336 double height00, height01, height10, height11, height0, height1;
1339 height00 = cw[3] * (heights1[ci[0]][ci[1]][ci[2]]
1340 - heights0[ci[0]][ci[1]][ci[2]])
1341 + heights0[ci[0]][ci[1]][ci[2]];
1342 height01 = cw[3] * (heights1[ci[0]][ci[1] + 1][ci[2]]
1343 - heights0[ci[0]][ci[1] + 1][ci[2]])
1344 + heights0[ci[0]][ci[1] + 1][ci[2]];
1345 height10 = cw[3] * (heights1[ci[0] + 1][ci[1]][ci[2]]
1346 - heights0[ci[0] + 1][ci[1]][ci[2]])
1347 + heights0[ci[0] + 1][ci[1]][ci[2]];
1348 height11 = cw[3] * (heights1[ci[0] + 1][ci[1] + 1][ci[2]]
1349 - heights0[ci[0] + 1][ci[1] + 1][ci[2]])
1350 + heights0[ci[0] + 1][ci[1] + 1][ci[2]];
1353 height0 = cw[1] * (height01 - height00) + height00;
1354 height1 = cw[1] * (height11 - height10) + height10;
1357 height_bot = cw[0] * (height1 - height0) + height0;
1360 height00 = cw[3] * (heights1[ci[0]][ci[1]][ci[2] + 1]
1361 - heights0[ci[0]][ci[1]][ci[2] + 1])
1362 + heights0[ci[0]][ci[1]][ci[2] + 1];
1363 height01 = cw[3] * (heights1[ci[0]][ci[1] + 1][ci[2] + 1]
1364 - heights0[ci[0]][ci[1] + 1][ci[2] + 1])
1365 + heights0[ci[0]][ci[1] + 1][ci[2] + 1];
1366 height10 = cw[3] * (heights1[ci[0] + 1][ci[1]][ci[2] + 1]
1367 - heights0[ci[0] + 1][ci[1]][ci[2] + 1])
1368 + heights0[ci[0] + 1][ci[1]][ci[2] + 1];
1369 height11 = cw[3] * (heights1[ci[0] + 1][ci[1] + 1][ci[2] + 1]
1370 - heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1])
1371 + heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1];
1374 height0 = cw[1] * (height01 - height00) + height00;
1375 height1 = cw[1] * (height11 - height10) + height10;
1378 height_top = cw[0] * (height1 - height0) + height0;
1381 while (((heights0[0][0][0] > heights0[0][0][1]) &&
1382 ((height_bot <= height) || (height_top > height))
1383 && (height_bot >= height) && (ci[2] < k_max))
1385 ((heights0[0][0][0] < heights0[0][0][1]) &&
1386 ((height_bot >= height) || (height_top < height))
1387 && (height_bot <= height) && (ci[2] < k_max))
1391 height_bot = height_top;
1394 height00 = cw[3] * (heights1[ci[0]][ci[1]][ci[2] + 1]
1395 - heights0[ci[0]][ci[1]][ci[2] + 1])
1396 + heights0[ci[0]][ci[1]][ci[2] + 1];
1397 height01 = cw[3] * (heights1[ci[0]][ci[1] + 1][ci[2] + 1]
1398 - heights0[ci[0]][ci[1] + 1][ci[2] + 1])
1399 + heights0[ci[0]][ci[1] + 1][ci[2] + 1];
1400 height10 = cw[3] * (heights1[ci[0] + 1][ci[1]][ci[2] + 1]
1401 - heights0[ci[0] + 1][ci[1]][ci[2] + 1])
1402 + heights0[ci[0] + 1][ci[1]][ci[2] + 1];
1403 height11 = cw[3] * (heights1[ci[0] + 1][ci[1] + 1][ci[2] + 1]
1404 - heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1])
1405 + heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1];
1408 height0 = cw[1] * (height01 - height00) + height00;
1409 height1 = cw[1] * (height11 - height10) + height10;
1412 height_top = cw[0] * (height1 - height0) + height0;
1416 cw[2] = (height - height_bot)
1417 / (height_top - height_bot);
1421 double array000 = cw[3] * (array1[ci[0]][ci[1]][ci[2]]
1422 - array0[ci[0]][ci[1]][ci[2]])
1423 + array0[ci[0]][ci[1]][ci[2]];
1424 double array100 = cw[3] * (array1[ci[0] + 1][ci[1]][ci[2]]
1425 - array0[ci[0] + 1][ci[1]][ci[2]])
1426 + array0[ci[0] + 1][ci[1]][ci[2]];
1427 double array010 = cw[3] * (array1[ci[0]][ci[1] + 1][ci[2]]
1428 - array0[ci[0]][ci[1] + 1][ci[2]])
1429 + array0[ci[0]][ci[1] + 1][ci[2]];
1430 double array110 = cw[3] * (array1[ci[0] + 1][ci[1] + 1][ci[2]]
1431 - array0[ci[0] + 1][ci[1] + 1][ci[2]])
1432 + array0[ci[0] + 1][ci[1] + 1][ci[2]];
1433 double array001 = cw[3] * (array1[ci[0]][ci[1]][ci[2] + 1]
1434 - array0[ci[0]][ci[1]][ci[2] + 1])
1435 + array0[ci[0]][ci[1]][ci[2] + 1];
1436 double array101 = cw[3] * (array1[ci[0] + 1][ci[1]][ci[2] + 1]
1437 - array0[ci[0] + 1][ci[1]][ci[2] + 1])
1438 + array0[ci[0] + 1][ci[1]][ci[2] + 1];
1439 double array011 = cw[3] * (array1[ci[0]][ci[1] + 1][ci[2] + 1]
1440 - array0[ci[0]][ci[1] + 1][ci[2] + 1])
1441 + array0[ci[0]][ci[1] + 1][ci[2] + 1];
1442 double array111 = cw[3] * (array1[ci[0] + 1][ci[1] + 1][ci[2] + 1]
1443 - array0[ci[0] + 1][ci[1] + 1][ci[2] + 1])
1444 + array0[ci[0] + 1][ci[1] + 1][ci[2] + 1];
1446 double array00 = cw[0] * (array100 - array000) + array000;
1447 double array10 = cw[0] * (array110 - array010) + array010;
1448 double array01 = cw[0] * (array101 - array001) + array001;
1449 double array11 = cw[0] * (array111 - array011) + array011;
1451 double aux0 = cw[1] * (array10 - array00) + array00;
1452 double aux1 = cw[1] * (array11 - array01) + array01;
1455 *var = cw[2] * (aux1 - aux0) + aux0;
1475 double lon2 =
FMOD(lon, 360.);
1476 if (lon2 < met->lon[0])
1478 else if (lon2 > met->
lon[met->
nx - 1])
1487 cw[0] = (met->
p[ci[0] + 1] - p)
1488 / (met->
p[ci[0] + 1] - met->
p[ci[0]]);
1489 cw[1] = (met->
lon[ci[1] + 1] - lon2)
1490 / (met->
lon[ci[1] + 1] - met->
lon[ci[1]]);
1491 cw[2] = (met->
lat[ci[2] + 1] - lat)
1492 / (met->
lat[ci[2] + 1] - met->
lat[ci[2]]);
1497 cw[0] * (array[ci[1]][ci[2]][ci[0]] - array[ci[1]][ci[2]][ci[0] + 1])
1498 + array[ci[1]][ci[2]][ci[0] + 1];
1500 cw[0] * (array[ci[1]][ci[2] + 1][ci[0]] -
1501 array[ci[1]][ci[2] + 1][ci[0] + 1])
1502 + array[ci[1]][ci[2] + 1][ci[0] + 1];
1504 cw[0] * (array[ci[1] + 1][ci[2]][ci[0]] -
1505 array[ci[1] + 1][ci[2]][ci[0] + 1])
1506 + array[ci[1] + 1][ci[2]][ci[0] + 1];
1508 cw[0] * (array[ci[1] + 1][ci[2] + 1][ci[0]] -
1509 array[ci[1] + 1][ci[2] + 1][ci[0] + 1])
1510 + array[ci[1] + 1][ci[2] + 1][ci[0] + 1];
1513 aux00 = cw[2] * (aux00 - aux01) + aux01;
1514 aux11 = cw[2] * (aux10 - aux11) + aux11;
1515 *var = cw[1] * (aux00 - aux11) + aux11;
1529 double lon2 =
FMOD(lon, 360.);
1530 if (lon2 < met->lon[0])
1532 else if (lon2 > met->
lon[met->
nx - 1])
1542 if (p >= met->
pl[ix][iy][iz + 1])
1543 aux00 = array[ix][iy][iz + 1];
1544 else if (p <= met->pl[ix][iy][iz])
1545 aux00 = array[ix][iy][iz];
1547 aux00 =
LIN(met->
pl[ix][iy][iz],
1549 met->
pl[ix][iy][iz + 1], array[ix][iy][iz + 1], p);
1553 if (p >= met->
pl[ix][iy + 1][iz + 1])
1554 aux01 = array[ix][iy + 1][iz + 1];
1555 else if (p <= met->pl[ix][iy + 1][iz])
1556 aux01 = array[ix][iy + 1][iz];
1558 aux01 =
LIN(met->
pl[ix][iy + 1][iz],
1559 array[ix][iy + 1][iz],
1560 met->
pl[ix][iy + 1][iz + 1], array[ix][iy + 1][iz + 1], p);
1564 if (p >= met->
pl[ix + 1][iy][iz + 1])
1565 aux10 = array[ix + 1][iy][iz + 1];
1566 else if (p <= met->pl[ix + 1][iy][iz])
1567 aux10 = array[ix + 1][iy][iz];
1569 aux10 =
LIN(met->
pl[ix + 1][iy][iz],
1570 array[ix + 1][iy][iz],
1571 met->
pl[ix + 1][iy][iz + 1], array[ix + 1][iy][iz + 1], p);
1575 if (p >= met->
pl[ix + 1][iy + 1][iz + 1])
1576 aux11 = array[ix + 1][iy + 1][iz + 1];
1577 else if (p <= met->pl[ix + 1][iy + 1][iz])
1578 aux11 = array[ix + 1][iy + 1][iz];
1580 aux11 =
LIN(met->
pl[ix + 1][iy + 1][iz],
1581 array[ix + 1][iy + 1][iz],
1582 met->
pl[ix + 1][iy + 1][iz + 1],
1583 array[ix + 1][iy + 1][iz + 1], p);
1586 double aux0 =
LIN(met->
lat[iy], aux00, met->
lat[iy + 1], aux01, lat);
1587 double aux1 =
LIN(met->
lat[iy], aux10, met->
lat[iy + 1], aux11, lat);
1588 *var =
LIN(met->
lon[ix], aux0, met->
lon[ix + 1], aux1, lon2);
1595 float array[
EX][
EY],
1607 double lon2 =
FMOD(lon, 360.);
1608 if (lon2 < met->lon[0])
1610 else if (lon2 > met->
lon[met->
nx - 1])
1618 cw[1] = (met->
lon[ci[1] + 1] - lon2)
1619 / (met->
lon[ci[1] + 1] - met->
lon[ci[1]]);
1620 cw[2] = (met->
lat[ci[2] + 1] - lat)
1621 / (met->
lat[ci[2] + 1] - met->
lat[ci[2]]);
1625 double aux00 = array[ci[1]][ci[2]];
1626 double aux01 = array[ci[1]][ci[2] + 1];
1627 double aux10 = array[ci[1] + 1][ci[2]];
1628 double aux11 = array[ci[1] + 1][ci[2] + 1];
1631 if (isfinite(aux00) && isfinite(aux01)
1632 && isfinite(aux10) && isfinite(aux11)) {
1633 aux00 = cw[2] * (aux00 - aux01) + aux01;
1634 aux11 = cw[2] * (aux10 - aux11) + aux11;
1635 *var = cw[1] * (aux00 - aux11) + aux11;
1655 float array0[
EX][
EY][
EP],
1657 float array1[
EX][
EY][
EP],
1674 const double wt = (met1->
time - ts) / (met1->
time - met0->
time);
1677 *var = wt * (var0 - var1) + var1;
1684 float array0[
EX][
EY][
EP],
1686 float array1[
EX][
EY][
EP],
1700 *var =
LIN(met0->
time, var0, met1->
time, var1, ts);
1707 float array0[
EX][
EY],
1709 float array1[
EX][
EY],
1725 const double wt = (met1->
time - ts) / (met1->
time - met0->
time);
1728 if (isfinite(var0) && isfinite(var1))
1729 *var = wt * (var0 - var1) + var1;
1740 float array0[
EX][
EY],
1742 float array1[
EX][
EY],
1743 const double lons[
EX],
1744 const double lats[
EY],
1754 double aux0, aux1, aux00, aux01, aux10, aux11, mean = 0;
1759 double lon2 =
FMOD(lon, 360.);
1762 else if (lon2 > lons[nlon - 1])
1766 const int ix =
locate_reg(lons, (
int) nlon, lon2);
1767 const int iy =
locate_reg(lats, (
int) nlat, lat);
1771 for (
int dx = 0; dx < 2; dx++)
1772 for (
int dy = 0; dy < 2; dy++) {
1773 if (isfinite(array0[ix + dx][iy + dy])) {
1774 mean += array0[ix + dx][iy + dy];
1775 *sigma +=
SQR(array0[ix + dx][iy + dy]);
1778 if (isfinite(array1[ix + dx][iy + dy])) {
1779 mean += array1[ix + dx][iy + dy];
1780 *sigma +=
SQR(array1[ix + dx][iy + dy]);
1785 *sigma = sqrt(
MAX(*sigma / n -
SQR(mean / n), 0.0));
1788 if (method == 1 && isfinite(array0[ix][iy])
1789 && isfinite(array0[ix][iy + 1])
1790 && isfinite(array0[ix + 1][iy])
1791 && isfinite(array0[ix + 1][iy + 1])
1792 && isfinite(array1[ix][iy])
1793 && isfinite(array1[ix][iy + 1])
1794 && isfinite(array1[ix + 1][iy])
1795 && isfinite(array1[ix + 1][iy + 1])) {
1797 aux00 =
LIN(lons[ix], array0[ix][iy],
1798 lons[ix + 1], array0[ix + 1][iy], lon2);
1799 aux01 =
LIN(lons[ix], array0[ix][iy + 1],
1800 lons[ix + 1], array0[ix + 1][iy + 1], lon2);
1801 aux0 =
LIN(lats[iy], aux00, lats[iy + 1], aux01, lat);
1803 aux10 =
LIN(lons[ix], array1[ix][iy],
1804 lons[ix + 1], array1[ix + 1][iy], lon2);
1805 aux11 =
LIN(lons[ix], array1[ix][iy + 1],
1806 lons[ix + 1], array1[ix + 1][iy + 1], lon2);
1807 aux1 =
LIN(lats[iy], aux10, lats[iy + 1], aux11, lat);
1809 *var =
LIN(time0, aux0, time1, aux1, time);
1814 aux00 =
NN(lons[ix], array0[ix][iy],
1815 lons[ix + 1], array0[ix + 1][iy], lon2);
1816 aux01 =
NN(lons[ix], array0[ix][iy + 1],
1817 lons[ix + 1], array0[ix + 1][iy + 1], lon2);
1818 aux0 =
NN(lats[iy], aux00, lats[iy + 1], aux01, lat);
1820 aux10 =
NN(lons[ix], array1[ix][iy],
1821 lons[ix + 1], array1[ix + 1][iy], lon2);
1822 aux11 =
NN(lons[ix], array1[ix][iy + 1],
1823 lons[ix + 1], array1[ix + 1][iy + 1], lon2);
1824 aux1 =
NN(lats[iy], aux10, lats[iy + 1], aux11, lat);
1826 *var =
NN(time0, aux0, time1, aux1, time);
1851 const time_t jsec0 = (time_t) jsec + timegm(&t0);
1852 t1 = gmtime(&jsec0);
1854 *year = t1->tm_year + 1900;
1855 *mon = t1->tm_mon + 1;
1857 *hour = t1->tm_hour;
1860 *remain = jsec - floor(jsec);
1866 const double kz[
EP],
1867 const double kw[
EP],
1876 const double z =
Z(p);
1881 else if (z > kz[nk - 1])
1885 return LIN(kz[idx], kw[idx], kz[idx + 1], kw[idx + 1], z);
1902 const double a =
RA *
SQR(t), r =
SH(h2o) / (1. -
SH(h2o));
1917 const double press[138] = {
1918 0.0200, 0.0310, 0.0467, 0.0683, 0.0975, 0.1361, 0.1861, 0.2499,
1919 0.3299, 0.4288, 0.5496, 0.6952, 0.8690, 1.0742, 1.3143, 1.5928, 1.9134,
1920 2.2797, 2.6954, 3.1642, 3.6898, 4.2759, 4.9262, 5.6441, 6.4334, 7.2974,
1921 8.2397, 9.2634, 10.3720, 11.5685, 12.8561, 14.2377, 15.7162, 17.2945,
1922 18.9752, 20.7610, 22.6543, 24.6577, 26.7735, 29.0039, 31.3512, 33.8174,
1923 36.4047, 39.1149, 41.9493, 44.9082, 47.9915, 51.1990, 54.5299, 57.9834,
1924 61.5607, 65.2695, 69.1187, 73.1187, 77.2810, 81.6182, 86.1450, 90.8774,
1925 95.8280, 101.0047, 106.4153, 112.0681, 117.9714, 124.1337, 130.5637,
1926 137.2703, 144.2624, 151.5493, 159.1403, 167.0450, 175.2731, 183.8344,
1927 192.7389, 201.9969, 211.6186, 221.6146, 231.9954, 242.7719, 253.9549,
1928 265.5556, 277.5852, 290.0548, 302.9762, 316.3607, 330.2202, 344.5663,
1929 359.4111, 374.7666, 390.6450, 407.0583, 424.0190, 441.5395, 459.6321,
1930 478.3096, 497.5845, 517.4198, 537.7195, 558.3430, 579.1926, 600.1668,
1931 621.1624, 642.0764, 662.8084, 683.2620, 703.3467, 722.9795, 742.0855,
1932 760.5996, 778.4661, 795.6396, 812.0847, 827.7756, 842.6959, 856.8376,
1933 870.2004, 882.7910, 894.6222, 905.7116, 916.0815, 925.7571, 934.7666,
1934 943.1399, 950.9082, 958.1037, 964.7584, 970.9046, 976.5737, 981.7968,
1935 986.6036, 991.0230, 995.0824, 998.8081, 1002.2250, 1005.3562, 1008.2239,
1936 1010.8487, 1013.2500, 1044.45
1939 for (
int ip = 0; ip < ctl->
met_np; ip++)
1946 const double press[92] = {
1947 0.0200, 0.0398, 0.0739, 0.1291, 0.2141, 0.3395, 0.5175, 0.7617,
1948 1.0872, 1.5099, 2.0464, 2.7136, 3.5282, 4.5069, 5.6652, 7.0181,
1949 8.5795, 10.3617, 12.3759, 14.6316, 17.1371, 19.8987, 22.9216, 26.2090,
1950 29.7630, 33.5843, 37.6720, 42.0242, 46.6378, 51.5086, 56.6316, 61.9984,
1951 67.5973, 73.4150, 79.4434, 85.7016, 92.2162, 99.0182, 106.1445,
1953 121.5502, 129.9403, 138.8558, 148.3260, 158.3816, 169.0545, 180.3786,
1954 192.3889, 205.1222, 218.6172, 232.9140, 248.0547, 264.0833, 281.0456,
1955 298.9895, 317.9651, 338.0245, 359.2221, 381.6144, 405.2606, 430.2069,
1956 456.4813, 483.8505, 512.0662, 540.8577, 569.9401, 599.0310, 627.9668,
1957 656.6129, 684.8491, 712.5573, 739.5739, 765.7697, 791.0376, 815.2774,
1958 838.3507, 860.1516, 880.6080, 899.6602, 917.2205, 933.2247, 947.6584,
1959 960.5245, 971.8169, 981.5301, 989.7322, 996.8732, 1002.8013,
1960 1007.4431, 1010.8487, 1013.2500, 1044.45
1963 for (
int ip = 0; ip < ctl->
met_np; ip++)
1970 const double press[60] = {
1971 0.01, 0.1361, 0.2499, 0.4288, 0.6952, 1.0742,
1972 2.2797, 3.1642, 4.2759, 7.2974, 9.2634, 11.5685, 14.2377, 20.761,
1973 24.6577, 33.8174, 39.1149, 51.199, 57.9834, 73.1187, 81.6182,
1974 90.8774, 101.005, 112.068, 124.134, 137.27, 151.549, 167.045, 183.834,
1975 201.997, 221.615, 242.772, 265.556, 290.055, 316.361, 344.566, 374.767,
1976 407.058, 441.539, 478.31, 517.42, 558.343, 600.167, 683.262, 722.979,
1977 760.6, 795.64, 827.776, 856.838, 882.791, 905.712, 925.757, 943.14,
1978 958.104, 972.495, 986.886, 1001.28, 1015.67, 1030.06, 1044.45
1981 for (
int ip = 0; ip < ctl->
met_np; ip++)
1988 const double press[147] = {
1989 0.0200, 0.0310, 0.0467, 0.0683, 0.0975, 0.1361, 0.1861, 0.2499,
1990 0.3299, 0.4288, 0.5496, 0.6952, 0.8690, 1.0742, 1.3143, 1.5928, 1.9134,
1991 2.2797, 2.6954, 3.1642, 3.6898, 4.2759, 4.9262, 5.6441, 6.4334, 7.2974,
1992 8.2397, 9.2634, 10.3720, 11.5685, 12.8561, 14.2377, 15.7162, 17.2945,
1993 18.9752, 20.7610, 22.6543, 24.6577, 26.7735, 29.0039, 31.3512, 33.8174,
1994 36.4047, 39.1149, 41.9493, 44.9082, 47.9915, 51.1990, 54.5299, 57.9834,
1995 61.5607, 65.2695, 69.1187, 73.1187, 77.2810, 81.6182, 86.1450, 90.8774,
1996 95.8280, 101.0047, 106.4153, 112.0681, 117.9714, 124.1337, 130.5637,
1997 137.2703, 144.2624, 151.5493, 159.1403, 167.0450, 175.2731, 183.8344,
1998 192.7389, 201.9969, 211.6186, 221.6146, 231.9954, 242.7719, 253.9549,
1999 265.5556, 277.5852, 290.0548, 302.9762, 316.3607, 330.2202, 344.5663,
2000 359.4111, 374.7666, 390.6450, 407.0583, 424.0190, 441.5395, 459.6321,
2001 478.3096, 497.5845, 517.4198, 537.7195, 558.3430, 579.1926, 600.1668,
2002 621.1624, 642.0764, 662.8084, 683.2620, 703.3467, 722.9795, 742.0855,
2003 760.5996, 778.4661, 795.6396, 812.0847, 827.7756, 842.6959, 856.8376,
2004 870.2004, 882.7910, 894.6222, 905.7116, 916.0815, 925.7571, 934.7666,
2005 943.1399, 950.9082, 958.1037, 964.7584, 970.9046, 976.5737, 981.7968,
2006 986.6036, 991.0230, 995.0824, 998.8081, 1002.2250, 1005.3562, 1008.2239,
2007 1010.8487, 1013.25, 1016.37, 1019.49, 1022.61, 1025.73, 1028.85,
2009 1035.09, 1038.21, 1041.33, 1044.45
2012 for (
int ip = 0; ip < ctl->
met_np; ip++)
2019 const double press[101] = {
2020 0.0200, 0.0398, 0.0739, 0.1291, 0.2141, 0.3395, 0.5175, 0.7617,
2021 1.0872, 1.5099, 2.0464, 2.7136, 3.5282, 4.5069, 5.6652, 7.0181,
2022 8.5795, 10.3617, 12.3759, 14.6316, 17.1371, 19.8987, 22.9216, 26.2090,
2023 29.7630, 33.5843, 37.6720, 42.0242, 46.6378, 51.5086, 56.6316, 61.9984,
2024 67.5973, 73.4150, 79.4434, 85.7016, 92.2162, 99.0182, 106.1445,
2026 121.5502, 129.9403, 138.8558, 148.3260, 158.3816, 169.0545, 180.3786,
2027 192.3889, 205.1222, 218.6172, 232.9140, 248.0547, 264.0833, 281.0456,
2028 298.9895, 317.9651, 338.0245, 359.2221, 381.6144, 405.2606, 430.2069,
2029 456.4813, 483.8505, 512.0662, 540.8577, 569.9401, 599.0310, 627.9668,
2030 656.6129, 684.8491, 712.5573, 739.5739, 765.7697, 791.0376, 815.2774,
2031 838.3507, 860.1516, 880.6080, 899.6602, 917.2205, 933.2247, 947.6584,
2032 960.5245, 971.8169, 981.5301, 989.7322, 996.8732, 1002.8013,
2033 1007.4431, 1010.8487, 1013.25, 1016.37, 1019.49, 1022.61, 1025.73,
2035 1035.09, 1038.21, 1041.33, 1044.45
2038 for (
int ip = 0; ip < ctl->
met_np; ip++)
2045 const double press[62] = {
2046 0.01, 0.1361, 0.2499, 0.4288, 0.6952, 1.0742,
2047 2.2797, 3.1642, 4.2759, 7.2974, 9.2634, 11.5685, 14.2377, 20.761,
2048 24.6577, 33.8174, 39.1149, 51.199, 57.9834, 73.1187, 81.6182,
2049 90.8774, 101.005, 112.068, 124.134, 137.27, 151.549, 167.045, 183.834,
2050 201.997, 221.615, 242.772, 265.556, 290.055, 316.361, 344.566, 374.767,
2051 407.058, 441.539, 478.31, 517.42, 558.343, 600.167, 683.262, 722.979,
2052 760.6, 795.64, 827.776, 856.838, 882.791, 905.712, 925.757, 943.14,
2053 958.104, 972.495, 986.886, 1001.28, 1015.67, 1030.06, 1034.86, 1039.65,
2057 for (
int ip = 0; ip < ctl->
met_np; ip++)
2064 const double press[137] = {
2065 0.01, 0.02, 0.031, 0.0467, 0.0683, 0.0975, 0.1361, 0.1861,
2066 0.2499, 0.3299, 0.4288, 0.5496, 0.6952, 0.869, 1.0742,
2067 1.3143, 1.5928, 1.9134, 2.2797, 2.6954, 3.1642, 3.6898,
2068 4.2759, 4.9262, 5.6441, 6.4334, 7.2974, 8.2397, 9.2634,
2069 10.372, 11.5685, 12.8561, 14.2377, 15.7162, 17.2945, 18.9752,
2070 20.761, 22.6543, 24.6577, 26.7735, 29.0039, 31.3512, 33.8174,
2071 36.4047, 39.1149, 41.9493, 44.9082, 47.9915, 51.199, 54.5299,
2072 57.9834, 61.5607, 65.2695, 69.1187, 73.1187, 77.281, 81.6182,
2073 86.145, 90.8774, 95.828, 101.005, 106.415, 112.068, 117.971,
2074 124.134, 130.564, 137.27, 144.262, 151.549, 159.14, 167.045,
2075 175.273, 183.834, 192.739, 201.997, 211.619, 221.615, 231.995,
2076 242.772, 253.955, 265.556, 277.585, 290.055, 302.976, 316.361,
2077 330.22, 344.566, 359.411, 374.767, 390.645, 407.058, 424.019,
2078 441.539, 459.632, 478.31, 497.584, 517.42, 537.72, 558.343,
2079 579.193, 600.167, 621.162, 642.076, 662.808, 683.262, 703.347,
2080 722.979, 742.086, 760.6, 778.466, 795.64, 812.085, 827.776,
2081 842.696, 856.838, 870.2, 882.791, 894.622, 905.712, 916.081,
2082 925.757, 934.767, 943.14, 950.908, 958.104, 965.299, 972.495,
2083 979.69, 986.886, 994.081, 1001.28, 1008.47, 1015.67, 1022.86,
2084 1030.06, 1037.25, 1044.45
2087 for (
int ip = 0; ip < ctl->
met_np; ip++)
2094 const double press[59] = {
2095 0.1, 0.2, 0.3843, 0.6365, 0.9564, 1.3448, 1.8058, 2.3478,
2096 2.985, 3.7397, 4.6462, 5.7565, 7.1322, 8.8366, 10.9483,
2097 13.5647, 16.8064, 20.8227, 25.7989, 31.9642, 39.6029, 49.0671,
2098 60.1802, 73.0663, 87.7274, 104.229, 122.614, 142.902, 165.089,
2099 189.147, 215.025, 242.652, 272.059, 303.217, 336.044, 370.407,
2100 406.133, 443.009, 480.791, 519.209, 557.973, 596.777, 635.306,
2101 673.24, 710.263, 746.063, 780.346, 812.83, 843.263, 871.42,
2102 897.112, 920.189, 940.551, 958.148, 975.744, 993.341, 1010.94,
2106 for (
int ip = 0; ip < ctl->
met_np; ip++)
2110 ERRMSG(
"Use 0 for l137, 1 for l91, 2 for l60 or values between 3 and 7.")
2123 int i = (ihi + ilo) >> 1;
2125 if (xx[i] < xx[i + 1])
2126 while (ihi > ilo + 1) {
2127 i = (ihi + ilo) >> 1;
2133 while (ihi > ilo + 1) {
2134 i = (ihi + ilo) >> 1;
2154 int i = (ihi + ilo) >> 1;
2156 if (x >= xx[ig] && x < xx[ig + 1])
2159 if (xx[i] < xx[i + 1])
2160 while (ihi > ilo + 1) {
2161 i = (ihi + ilo) >> 1;
2167 while (ihi > ilo + 1) {
2168 i = (ihi + ilo) >> 1;
2186 int i = (int) ((x - xx[0]) / (xx[1] - xx[0]));
2200 float profiles[
EX][
EY][
EP],
2202 const int lon_ap_ind,
2203 const int lat_ap_ind,
2204 const double height_ap,
2210 np, height_ap, ind[0]);
2212 np, height_ap, ind[1]);
2214 np, height_ap, ind[2]);
2233 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,met0,met1,atm,dt)") {
2237 double dts, u[4], um = 0, v[4], vm = 0, w[4], wm = 0,
2241 for (
int i = 0; i < ctl->
advect; i++) {
2246 x[0] = atm->
lon[ip];
2247 x[1] = atm->
lat[ip];
2250 dts = (i == 3 ? 1.0 : 0.5) * dt[ip];
2251 x[0] = atm->
lon[ip] +
DX2DEG(dts * u[i - 1] / 1000., atm->
lat[ip]);
2252 x[1] = atm->
lat[ip] +
DY2DEG(dts * v[i - 1] / 1000.);
2253 x[2] = atm->
p[ip] + dts * w[i - 1];
2255 double tm = atm->
time[ip] + dts;
2260 tm, x[2], x[0], x[1], &u[i], ci, cw, 1);
2262 tm, x[2], x[0], x[1], &v[i], ci, cw, 0);
2264 tm, x[2], x[0], x[1], &w[i], ci, cw, 0);
2280 k = (i == 0 ? 0.0 : 1.0);
2281 else if (ctl->
advect == 4)
2282 k = (i == 0 || i == 3 ? 1.0 / 6.0 : 2.0 / 6.0);
2289 atm->
time[ip] += dt[ip];
2290 atm->
lon[ip] +=
DX2DEG(dt[ip] * um / 1000.,
2291 (ctl->
advect == 2 ? x[1] : atm->
lat[ip]));
2292 atm->
lat[ip] +=
DY2DEG(dt[ip] * vm / 1000.);
2293 atm->
p[ip] += dt[ip] * wm;
2301 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,met0,met1,atm,dt)") {
2308 atm->
lon[ip], atm->
lat[ip],
2313 double dts, u[4], um = 0, v[4], vm = 0, zeta_dot[4], zeta_dotm = 0,
2317 for (
int i = 0; i < ctl->
advect; i++) {
2322 x[0] = atm->
lon[ip];
2323 x[1] = atm->
lat[ip];
2326 dts = (i == 3 ? 1.0 : 0.5) * dt[ip];
2327 x[0] = atm->
lon[ip] +
DX2DEG(dts * u[i - 1] / 1000., atm->
lat[ip]);
2328 x[1] = atm->
lat[ip] +
DY2DEG(dts * v[i - 1] / 1000.);
2329 x[2] = atm->
q[ctl->
qnt_zeta][ip] + dts * zeta_dot[i - 1];
2331 double tm = atm->
time[ip] + dts;
2336 met1->
ul, tm, x[2], x[0], x[1], &u[i], ci, cw, 1);
2338 met1->
vl, tm, x[2], x[0], x[1], &v[i], ci, cw, 0);
2341 x[1], &zeta_dot[i], ci, cw, 0);
2346 k = (i == 0 ? 0.0 : 1.0);
2347 else if (ctl->
advect == 4)
2348 k = (i == 0 || i == 3 ? 1.0 / 6.0 : 2.0 / 6.0);
2351 zeta_dotm += k * zeta_dot[i];
2355 atm->
time[ip] += dt[ip];
2356 atm->
lon[ip] +=
DX2DEG(dt[ip] * um / 1000.,
2357 (ctl->
advect == 2 ? x[1] : atm->
lat[ip]));
2358 atm->
lat[ip] +=
DY2DEG(dt[ip] * vm / 1000.);
2359 atm->
q[ctl->
qnt_zeta][ip] += dt[ip] * zeta_dotm;
2370 atm->
lon[ip], atm->
lat[ip], &atm->
p[ip], ci, cw, 1);
2385#pragma omp parallel for default(shared)
2386 for (
int ip = 0; ip < atm->
np; ip++) {
2390 ERRMSG(
"Time of air parcel is out of range!");
2396 atm->
lon[ip], atm->
lat[ip], &atm->
p[ip], ci, cw, 1);
2421 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,clim,met0,met1,atm,dt)") {
2457 if (atm->
p[ip] < pbl)
2509 ERRMSG(
"Molar mass is not defined!");
2515 const int np = atm->
np;
2519 const int ngrid = nx * ny * nz;
2521 double *restrict
const z = (
double *) malloc((
size_t) nz *
sizeof(double));
2522 double *restrict
const press =
2523 (
double *) malloc((
size_t) nz *
sizeof(double));
2524 double *restrict
const mass =
2525 (
double *) calloc((
size_t) ngrid,
sizeof(double));
2526 double *restrict
const area =
2527 (
double *) malloc((
size_t) ny *
sizeof(double));
2528 double *restrict
const lon =
2529 (
double *) malloc((
size_t) nx *
sizeof(double));
2530 double *restrict
const lat =
2531 (
double *) malloc((
size_t) ny *
sizeof(double));
2533 int *restrict
const ixs = (
int *) malloc((
size_t) np *
sizeof(int));
2534 int *restrict
const iys = (
int *) malloc((
size_t) np *
sizeof(int));
2535 int *restrict
const izs = (
int *) malloc((
size_t) np *
sizeof(int));
2544#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])
2545#pragma acc data present(ctl,met0,met1,atm,ixs,iys,izs,z,press,mass,area,lon,lat)
2546#pragma acc parallel loop independent gang vector
2548#pragma omp parallel for default(shared)
2550 for (
int iz = 0; iz < nz; iz++) {
2552 press[iz] =
P(z[iz]);
2556 const double t0 = tt - 0.5 * ctl->
dt_mod;
2557 const double t1 = tt + 0.5 * ctl->
dt_mod;
2561#pragma acc parallel loop independent gang vector
2563#pragma omp parallel for default(shared)
2565 for (
int ip = 0; ip < np; ip++) {
2569 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
2570 || ixs[ip] < 0 || ixs[ip] >= nx
2571 || iys[ip] < 0 || iys[ip] >= ny || izs[ip] < 0 || izs[ip] >= nz)
2577#pragma acc parallel loop independent gang vector
2579#pragma omp parallel for default(shared)
2581 for (
int ix = 0; ix < nx; ix++)
2584#pragma acc parallel loop independent gang vector
2586#pragma omp parallel for default(shared)
2588 for (
int iy = 0; iy < ny; iy++) {
2590 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat[iy]));
2595#pragma acc parallel loop independent gang vector
2597 for (
int ip = 0; ip < np; ip++)
2600#pragma acc atomic update
2602 mass[
ARRAY_3D(ixs[ip], iys[ip], ny, izs[ip], nz)]
2603 += atm->
q[ctl->
qnt_m][ip];
2607#pragma acc parallel loop independent gang vector
2609#pragma omp parallel for default(shared)
2611 for (
int ip = 0; ip < np; ip++)
2618 lon[ixs[ip]], lat[iys[ip]], &temp, ci, cw, 1);
2621 double m = mass[
ARRAY_3D(ixs[ip], iys[ip], ny, izs[ip], nz)];
2625 / (1e9 *
RHO(press[izs[ip]], temp) * area[iys[ip]] * dz);
2628#pragma acc exit data delete(ixs,iys,izs,z,press,mass,area,lon,lat)
2653#pragma omp parallel for default(shared)
2654 for (
int ip = 0; ip < atm->
np; ip++) {
2658 ERRMSG(
"Time of air parcel is out of range!");
2675 atm->
lon[ip], atm->
lat[ip], atm->
p[ip]));
2677 atm->
lat[ip], atm->
p[ip]));
2679 atm->
lat[ip], atm->
p[ip]));
2681 atm->
lat[ip], atm->
p[ip]));
2696 SELECT_TIMER(
"MODULE_CONVECTION",
"PHYSICS", NVTX_GPU);
2702 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,met0,met1,atm,dt,rs)") {
2710 if (isfinite(cape) && cape >= ctl->
conv_cape) {
2716 if (isfinite(cin) && cin >= ctl->
conv_cin)
2725 if (!isfinite(pel) || atm->
p[ip] < pel)
2729 double pbot = atm->
p[ip];
2730 double ptop = atm->
p[ip];
2742 pbot, atm->
lon[ip], atm->
lat[ip], &tbot, ci, cw, 1);
2744 ptop, atm->
lon[ip], atm->
lat[ip], &ttop, ci, cw, 1);
2745 double rhobot = pbot / tbot;
2746 double rhotop = ptop / ttop;
2749 double rho = rhobot + (rhotop - rhobot) * rs[ip];
2752 atm->
p[ip] =
LIN(rhobot, pbot, rhotop, ptop, rho);
2770 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
2783 const double aux = exp(-dt[ip] / tdec);
2784 if (ctl->
qnt_m >= 0) {
2787 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
2788 atm->
q[ctl->
qnt_m][ip] *= aux;
2816 "acc data present(ctl,met0,met1,atm,cache,dt,rs)") {
2824 float umean = 0, usig = 0, vmean = 0, vsig = 0, wmean = 0, wsig = 0;
2825 for (
int i = 0; i < 2; i++)
2826 for (
int j = 0; j < 2; j++)
2827 for (
int k = 0; k < 2; k++) {
2828 umean += met0->
u[ix + i][iy + j][iz + k];
2829 usig +=
SQR(met0->
u[ix + i][iy + j][iz + k]);
2830 vmean += met0->
v[ix + i][iy + j][iz + k];
2831 vsig +=
SQR(met0->
v[ix + i][iy + j][iz + k]);
2832 wmean += met0->
w[ix + i][iy + j][iz + k];
2833 wsig +=
SQR(met0->
w[ix + i][iy + j][iz + k]);
2835 umean += met1->
u[ix + i][iy + j][iz + k];
2836 usig +=
SQR(met1->
u[ix + i][iy + j][iz + k]);
2837 vmean += met1->
v[ix + i][iy + j][iz + k];
2838 vsig +=
SQR(met1->
v[ix + i][iy + j][iz + k]);
2839 wmean += met1->
w[ix + i][iy + j][iz + k];
2840 wsig +=
SQR(met1->
w[ix + i][iy + j][iz + k]);
2842 usig = usig / 16.f -
SQR(umean / 16.f);
2843 usig = (usig > 0 ? sqrtf(usig) : 0);
2844 vsig = vsig / 16.f -
SQR(vmean / 16.f);
2845 vsig = (vsig > 0 ? sqrtf(vsig) : 0);
2846 wsig = wsig / 16.f -
SQR(wmean / 16.f);
2847 wsig = (wsig > 0 ? sqrtf(wsig) : 0);
2850 const double r = 1 - 2 * fabs(dt[ip]) / ctl->
dt_met;
2851 const double r2 = sqrt(1 - r * r);
2855 cache->
uvwp[ip][0] =
2856 (float) (r * cache->
uvwp[ip][0] +
2861 cache->
uvwp[ip][1] =
2862 (float) (r * cache->
uvwp[ip][1] +
2863 r2 * rs[3 * ip + 1] * ctl->
turb_mesox * vsig);
2864 atm->
lat[ip] +=
DY2DEG(cache->
uvwp[ip][1] * dt[ip] / 1000.);
2869 cache->
uvwp[ip][2] =
2870 (float) (r * cache->
uvwp[ip][2] +
2871 r2 * rs[3 * ip + 2] * ctl->
turb_mesoz * wsig);
2872 atm->
p[ip] += cache->
uvwp[ip][2] * dt[ip];
2893 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,clim,atm,dt,rs)") {
2905 const double sigma = sqrt(2.0 * dx * fabs(dt[ip]));
2906 atm->
lon[ip] +=
DX2DEG(rs[3 * ip] * sigma / 1000., atm->
lat[ip]);
2907 atm->
lat[ip] +=
DY2DEG(rs[3 * ip + 1] * sigma / 1000.);
2912 const double sigma = sqrt(2.0 * dz * fabs(dt[ip]));
2913 atm->
p[ip] +=
DZ2DP(rs[3 * ip + 2] * sigma / 1000., atm->
p[ip]);
2932 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
2935 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,met0,met1,atm,dt)") {
2947 const double dz = 1000. * (
Z(ps - ctl->
dry_depo_dp) -
Z(ps));
2967 const double aux = exp(-dt[ip] * v_dep / dz);
2968 if (ctl->
qnt_m >= 0) {
2971 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
2972 atm->
q[ctl->
qnt_m][ip] *= aux;
2996 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
2999 const double a = 3.12541941e-06;
3000 const double b = -5.72532259e-01;
3001 const double low = pow(1 / a, 1 / b);
3004 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(clim,ctl,met0,met1,atm,dt)") {
3011 if (!(lwc > 0 || rwc > 0))
3022 const double k = 9.1e7 * exp(-29700 /
RI * (1. / t - 1. / 298.15));
3025 const double H_SO2 = 1.3e-2 * exp(2900 * (1. / t - 1. / 298.15)) *
RI * t;
3026 const double K_1S = 1.23e-2 * exp(2.01e3 * (1. / t - 1. / 298.15));
3029 const double H_h2o2 = 8.3e2 * exp(7600 * (1 / t - 1 / 298.15)) *
RI * t;
3035 cor = atm->
q[ctl->
qnt_Cx][ip] >
3036 low ? a * pow(atm->
q[ctl->
qnt_Cx][ip], b) : 1;
3038 const double h2o2 = H_h2o2
3040 * M * cor * 1000 /
AVO;
3043 const double rho_air = 100 * atm->
p[ip] / (
RI * t) *
MA / 1000;
3044 const double CWC = (lwc + rwc) * rho_air / 1000;
3047 const double rate_coef = k * K_1S * h2o2 * H_SO2 * CWC;
3048 const double aux = exp(-dt[ip] * rate_coef);
3049 if (ctl->
qnt_m >= 0) {
3052 atm->
q[ctl->
qnt_m][ip] *= aux;
3080 for (
int ip = 0; ip < atm->
np; ip++)
3085 for (
int ip = 0; ip < atm->
np; ip++) {
3087 cache->
iso_var[ip] = atm->
p[ip] / t;
3092 for (
int ip = 0; ip < atm->
np; ip++) {
3101 LOG(1,
"Read balloon pressure data: %s", ctl->
balloon);
3105 if (!(in = fopen(ctl->
balloon,
"r")))
3106 ERRMSG(
"Cannot open file!");
3110 while (fgets(line,
LEN, in))
3111 if (sscanf(line,
"%lg %lg", &(cache->
iso_ts[cache->
iso_n]),
3114 ERRMSG(
"Too many data points!");
3117 if (cache->
iso_n < 1)
3118 ERRMSG(
"Could not read any data!");
3139 PARTICLE_LOOP(0, atm->
np, 0,
"acc data present(ctl,met0,met1,atm,cache,dt)") {
3152 atm->
p[ip] = cache->
iso_var[ip] * t;
3158 atm->
p[ip] = 1000. * pow(cache->
iso_var[ip] / t, -1. / 0.286);
3164 atm->
p[ip] = cache->
iso_ps[0];
3191 const int nvar = NVAR, nfix = NFIX, nreact = NREACT;
3192 double rtol[1] = { 1.0e-3 };
3193 double atol[1] = { 1.0 };
3197#pragma acc data copy(rtol,atol,nvar,nfix,nreact)
3199 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,clim,met0,met1,atm,dt) ") {
3202 double var[nvar], fix[nfix], rconst[nreact];
3203 for (
int i = 0; i < nvar; i++)
3205 for (
int i = 0; i < nfix; i++)
3207 for (
int i = 0; i < nreact; i++)
3209 kpp_chem_initialize(ctl, clim, met0, met1, atm, var, fix, rconst, ip);
3214 for (
int i = 0; i < 20; i++) {
3221 Rosenbrock(var, fix, rconst, 0, ctl->
dt_kpp,
3222 atol, rtol, &FunTemplate, &JacTemplate, rpar, ipar);
3225 kpp_chem_output2atm(atm, ctl, met0, met1, var, ip);
3246 ERRMSG(
"Need T_ice and T_NAT to calculate T_STS!");
3249 PARTICLE_LOOP(0, atm->
np, 0,
"acc data present(ctl,clim,met0,met1,atm,dt)") {
3251 double ps, ts, zs, us, vs, lsm, sst, pbl, pt, pct, pcb, cl, plcl, plfc,
3252 pel, cape, cin, o3c, pv, t, tt, u, v, w, h2o, h2ot, o3,
3253 lwc, rwc, iwc, swc, cc, z, zt;
3298 atm->
lon[ip], atm->
lat[ip], atm->
p[ip]));
3300 atm->
lat[ip], atm->
p[ip]));
3302 atm->
lat[ip], atm->
p[ip]));
3304 atm->
lat[ip], atm->
p[ip]));
3305 SET_ATM(qnt_vh, sqrt(u * u + v * v));
3324 atm->
lat[ip], atm->
p[ip])));
3342 const int np = atm->
np;
3343 int *restrict
const ixs = (
int *) malloc((
size_t) np *
sizeof(int));
3344 int *restrict
const iys = (
int *) malloc((
size_t) np *
sizeof(int));
3345 int *restrict
const izs = (
int *) malloc((
size_t) np *
sizeof(int));
3353 const double t0 = t - 0.5 * ctl->
dt_mod;
3354 const double t1 = t + 0.5 * ctl->
dt_mod;
3358#pragma acc enter data create(ixs[0:np],iys[0:np],izs[0:np])
3359#pragma acc data present(ctl,clim,atm,ixs,iys,izs)
3360#pragma acc parallel loop independent gang vector
3362#pragma omp parallel for default(shared)
3364 for (
int ip = 0; ip < np; ip++) {
3367 izs[ip] = (int) ((
Z(atm->
p[ip]) - ctl->
mixing_z0) / dz);
3368 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
3369 || ixs[ip] < 0 || ixs[ip] >= ctl->
mixing_nx
3370 || iys[ip] < 0 || iys[ip] >= ctl->
mixing_ny
3371 || izs[ip] < 0 || izs[ip] >= ctl->
mixing_nz)
3376 if (ctl->
qnt_m >= 0)
3413#pragma acc exit data delete(ixs,iys,izs)
3429 const int qnt_idx) {
3432 const int np = atm->
np;
3434 double *restrict
const cmean =
3435 (
double *) malloc((
size_t) ngrid *
sizeof(double));
3436 int *restrict
const count = (
int *) malloc((
size_t) ngrid *
sizeof(int));
3440#pragma acc enter data create(cmean[0:ngrid],count[0:ngrid])
3441#pragma acc data present(ctl,clim,atm,ixs,iys,izs,cmean,count)
3442#pragma acc parallel loop independent gang vector
3447#pragma omp parallel for
3449 for (
int i = 0; i < ngrid; i++) {
3456#pragma acc parallel loop independent gang vector
3458 for (
int ip = 0; ip < np; ip++)
3463#pragma acc atomic update
3465 cmean[idx] += atm->
q[qnt_idx][ip];
3467#pragma acc atomic update
3472#pragma acc parallel loop independent gang vector
3477#pragma omp parallel for
3479 for (
int i = 0; i < ngrid; i++)
3481 cmean[i] /= count[i];
3485#pragma acc parallel loop independent gang vector
3487#pragma omp parallel for
3489 for (
int ip = 0; ip < np; ip++)
3493 double mixparam = 1.0;
3501 atm->
q[qnt_idx][ip] +=
3504 - atm->
q[qnt_idx][ip]) * mixparam;
3509#pragma acc exit data delete(cmean,count)
3530 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
3533 const double a = 4.71572206e-08;
3534 const double b = -8.28782867e-01;
3535 const double low = pow(1 / a, 1 / b);
3538 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,clim,met0,met1,atm,dt)") {
3564 0 ? pow(298. / t, ctl->
oh_chem[1]) : 1.);
3567 0 ? pow(298. / t, ctl->
oh_chem[3]) : 1.);
3568 double c = log10(k0 * M / ki);
3569 k = k0 * M / (1. + k0 * M / ki) * pow(0.6, 1. / (1. + c * c));
3578 low ? a * pow(atm->
q[ctl->
qnt_Cx][ip], b) : 1;
3581 const double rate_coef =
3583 atm->
lat[ip], atm->
p[ip]) * M * cor;
3584 const double aux = exp(-dt[ip] * rate_coef);
3585 if (ctl->
qnt_m >= 0) {
3588 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
3589 atm->
q[ctl->
qnt_m][ip] *= aux;
3611 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,met0,met1,atm,dt)") {
3622 while (atm->
lat[ip] < -90 || atm->
lat[ip] > 90) {
3623 if (atm->
lat[ip] > 90) {
3624 atm->
lat[ip] = 180 - atm->
lat[ip];
3625 atm->
lon[ip] += 180;
3627 if (atm->
lat[ip] < -90) {
3628 atm->
lat[ip] = -180 - atm->
lat[ip];
3629 atm->
lon[ip] += 180;
3634 while (atm->
lon[ip] < -180)
3635 atm->
lon[ip] += 360;
3636 while (atm->
lon[ip] >= 180)
3637 atm->
lon[ip] -= 360;
3640 if (atm->
p[ip] < met0->
p[met0->
np - 1]) {
3642 atm->
p[ip] = 2. * met0->
p[met0->
np - 1] - atm->
p[ip];
3644 atm->
p[ip] = met0->
p[met0->
np - 1];
3645 }
else if (atm->
p[ip] > 300.) {
3647 if (atm->
p[ip] > ps) {
3649 atm->
p[ip] = 2. * ps - atm->
p[ip];
3663 gsl_rng_env_setup();
3664 if (omp_get_max_threads() >
NTHREADS)
3665 ERRMSG(
"Too many threads!");
3666 for (
int i = 0; i <
NTHREADS; i++) {
3667 rng[i] = gsl_rng_alloc(gsl_rng_default);
3668 gsl_rng_set(rng[i], gsl_rng_default_seed
3669 + (
long unsigned) (ntask *
NTHREADS + i));
3674 if (curandCreateGenerator(&rng_curand, CURAND_RNG_PSEUDO_DEFAULT) !=
3675 CURAND_STATUS_SUCCESS)
3676 ERRMSG(
"Cannot create random number generator!");
3677 if (curandSetPseudoRandomGeneratorSeed(rng_curand, ntask) !=
3678 CURAND_STATUS_SUCCESS)
3679 ERRMSG(
"Cannot set seed for random number generator!");
3682 (cudaStream_t) acc_get_cuda_stream(acc_async_sync)) !=
3683 CURAND_STATUS_SUCCESS)
3684 ERRMSG(
"Cannot set stream for random number generator!");
3701#pragma omp parallel for default(shared)
3702 for (
size_t i = 0; i < n; ++i)
3703 rs[i] = gsl_rng_uniform(rng[omp_get_thread_num()]);
3707 else if (method == 1) {
3708#pragma omp parallel for default(shared)
3709 for (
size_t i = 0; i < n; ++i)
3710 rs[i] = gsl_ran_gaussian_ziggurat(rng[omp_get_thread_num()], 1.0);
3715#pragma acc update device(rs[:n])
3723 const uint64_t key = 0xc8e4fd154ce32f6d;
3727#pragma acc data present(rs)
3728#pragma acc parallel loop independent gang vector
3730#pragma omp parallel for default(shared)
3732 for (
size_t i = 0; i < n + 1; ++i) {
3733 uint64_t r, t, x, y, z;
3734 y = x = (rng_ctr + i) * key;
3737 x = (x >> 32) | (x << 32);
3739 x = (x >> 32) | (x << 32);
3741 x = (x >> 32) | (x << 32);
3743 x = (x >> 32) | (x << 32);
3744 r = t ^ ((x * x + y) >> 32);
3745 rs[i] = (double) r / (
double) UINT64_MAX;
3752#pragma acc parallel loop independent gang vector
3754#pragma omp parallel for default(shared)
3756 for (
size_t i = 0; i < n; i += 2) {
3757 const double r = sqrt(-2.0 * log(rs[i]));
3758 const double phi = 2.0 * M_PI * rs[i + 1];
3759 rs[i] = r * cosf((
float) phi);
3760 rs[i + 1] = r * sinf((
float) phi);
3768#pragma acc host_data use_device(rs)
3773 if (curandGenerateUniformDouble(rng_curand, rs, (n < 4 ? 4 : n)) !=
3774 CURAND_STATUS_SUCCESS)
3775 ERRMSG(
"Cannot create random numbers!");
3779 else if (method == 1) {
3780 if (curandGenerateNormalDouble
3781 (rng_curand, rs, (n < 4 ? 4 : n), 0.0,
3782 1.0) != CURAND_STATUS_SUCCESS)
3783 ERRMSG(
"Cannot create random numbers!");
3787 ERRMSG(
"MPTRAC was compiled without cuRAND!");
3805 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,met0,met1,atm,dt)") {
3813 const double v_s =
sedi(atm->
p[ip], t, atm->
q[ctl->
qnt_rp][ip],
3817 atm->
p[ip] +=
DZ2DP(v_s * dt[ip] / 1000., atm->
p[ip]);
3832 const int np = atm->
np;
3833 double *restrict
const a = (
double *) malloc((
size_t) np *
sizeof(double));
3834 int *restrict
const p = (
int *) malloc((
size_t) np *
sizeof(int));
3837#pragma acc enter data create(a[0:np],p[0:np])
3838#pragma acc data present(ctl,met0,atm,a,p)
3843#pragma acc parallel loop independent gang vector
3845#pragma omp parallel for default(shared)
3847 for (
int ip = 0; ip < np; ip++) {
3857#pragma acc host_data use_device(a, p)
3862 ERRMSG(
"MPTRAC was compiled without Thrust library!");
3870 for (
int iq = 0; iq < ctl->
nq; iq++)
3875#pragma acc exit data delete(a,p)
3889 double *restrict
const help =
3890 (
double *) malloc((
size_t) np *
sizeof(double));
3894#pragma acc enter data create(help[0:np])
3895#pragma acc data present(a,p,help)
3896#pragma acc parallel loop independent gang vector
3898#pragma omp parallel for default(shared)
3900 for (
int ip = 0; ip < np; ip++)
3901 help[ip] = a[p[ip]];
3903#pragma acc parallel loop independent gang vector
3905#pragma omp parallel for default(shared)
3907 for (
int ip = 0; ip < np; ip++)
3912#pragma acc exit data delete(help)
3929 const double latmin = gsl_stats_min(met0->
lat, 1, (
size_t) met0->
ny),
3930 latmax = gsl_stats_max(met0->
lat, 1, (
size_t) met0->
ny);
3933 (fabs(met0->
lon[met0->
nx - 1] - met0->
lon[0] - 360.0) >= 0.01);
3942 dt[ip] = t - atm->
time[ip];
3947 if (local && (atm->
lon[ip] <= met0->
lon[0]
3948 || atm->
lon[ip] >= met0->
lon[met0->
nx - 1]
3949 || atm->
lat[ip] <= latmin || atm->
lat[ip] >= latmax))
3965 ctl->
t_start = gsl_stats_min(atm->
time, 1, (
size_t) atm->
np);
3967 ctl->
t_stop = gsl_stats_max(atm->
time, 1, (
size_t) atm->
np);
3969 ctl->
t_start = gsl_stats_max(atm->
time, 1, (
size_t) atm->
np);
3971 ctl->
t_stop = gsl_stats_min(atm->
time, 1, (
size_t) atm->
np);
3976 ERRMSG(
"Nothing to do! Check T_STOP and DIRECTION!");
3996 SELECT_TIMER(
"MODULE_TRACERCHEM",
"PHYSICS", NVTX_GPU);
3999 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,clim,met0,atm,met1,dt)") {
4022 const double K_o1d =
ARRHENIUS(3.30e-10, 0, t) * o1d * M;
4024 atm->
p[ip], sza, o3c);
4025 atm->
q[ctl->
qnt_Cccl4][ip] *= exp(-dt[ip] * (K_hv + K_o1d));
4030 const double K_o1d =
ARRHENIUS(2.30e-10, 0, t) * o1d * M;
4032 atm->
p[ip], sza, o3c);
4033 atm->
q[ctl->
qnt_Cccl3f][ip] *= exp(-dt[ip] * (K_hv + K_o1d));
4038 const double K_o1d =
ARRHENIUS(1.40e-10, -25, t) * o1d * M;
4040 atm->
p[ip], sza, o3c);
4041 atm->
q[ctl->
qnt_Cccl2f2][ip] *= exp(-dt[ip] * (K_hv + K_o1d));
4046 const double K_o1d =
ARRHENIUS(1.19e-10, -20, t) * o1d * M;
4048 atm->
p[ip], sza, o3c);
4049 atm->
q[ctl->
qnt_Cn2o][ip] *= exp(-dt[ip] * (K_hv + K_o1d));
4068 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
4071 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,met0,met1,atm,dt)") {
4077 if (!isfinite(pct) || atm->
p[ip] <= pct)
4093 double lwc, rwc, iwc, swc;
4098 int inside = (lwc > 0 || rwc > 0 || iwc > 0 || swc > 0);
4112 else if (t <= 238.15)
4132 const double K_1 = 1.23e-2 * exp(2.01e3 * (1. / t - 1. / 298.15));
4133 const double K_2 = 6e-8 * exp(1.12e3 * (1. / t - 1. / 298.15));
4134 h *= (1 + K_1 / H_ion + K_1 * K_2 / pow(H_ion, 2));
4138 const double dz = 1e3 * (
Z(pct) -
Z(pcb));
4141 lambda = h *
RI * t * Is / 3.6e6 / dz * eta;
4167 const double dz = 1e3 * (
Z(pct) -
Z(pcb));
4170 lambda = h *
RI * t * Is / 3.6e6 / dz * eta;
4175 const double aux = exp(-dt[ip] * lambda);
4176 if (ctl->
qnt_m >= 0) {
4179 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
4180 atm->
q[ctl->
qnt_m][ip] *= aux;
4194 const double hno3) {
4197 const double h2o_help =
MAX(h2o, 0.1e-6);
4200 const double p_hno3 = hno3 * p / 1.333224;
4201 const double p_h2o = h2o_help * p / 1.333224;
4202 const double a = 0.009179 - 0.00088 * log10(p_h2o);
4203 const double b = (38.9855 - log10(p_hno3) - 2.7836 * log10(p_h2o)) / a;
4204 const double c = -11397.0 / a;
4205 double tnat = (-b + sqrt(b * b - 4. * c)) / 2.;
4206 double x2 = (-b - sqrt(b * b - 4. * c)) / 2.;
4216 const char *filename,
4229 LOG(1,
"Read atmospheric data: %s", filename);
4249 ERRMSG(
"Atmospheric data type not supported!");
4257 ERRMSG(
"Can not read any data!");
4261 LOG(2,
"Number of particles: %d", atm->
np);
4262 gsl_stats_minmax(&mini, &maxi, atm->
time, 1, (
size_t) atm->
np);
4263 LOG(2,
"Time range: %.2f ... %.2f s", mini, maxi);
4264 gsl_stats_minmax(&mini, &maxi, atm->
p, 1, (
size_t) atm->
np);
4265 LOG(2,
"Altitude range: %g ... %g km",
Z(maxi),
Z(mini));
4266 LOG(2,
"Pressure range: %g ... %g hPa", maxi, mini);
4267 gsl_stats_minmax(&mini, &maxi, atm->
lon, 1, (
size_t) atm->
np);
4268 LOG(2,
"Longitude range: %g ... %g deg", mini, maxi);
4269 gsl_stats_minmax(&mini, &maxi, atm->
lat, 1, (
size_t) atm->
np);
4270 LOG(2,
"Latitude range: %g ... %g deg", mini, maxi);
4271 for (
int iq = 0; iq < ctl->
nq; iq++) {
4273 sprintf(msg,
"Quantity %s range: %s ... %s %s",
4276 gsl_stats_minmax(&mini, &maxi, atm->
q[iq], 1, (
size_t) atm->
np);
4277 LOG(2, msg, mini, maxi);
4287 const char *filename,
4293 if (!(in = fopen(filename,
"r"))) {
4294 WARN(
"Cannot open file!");
4300 while (fgets(line,
LEN, in)) {
4304 TOK(line, tok,
"%lg", atm->
time[atm->
np]);
4305 TOK(NULL, tok,
"%lg", atm->
p[atm->
np]);
4306 TOK(NULL, tok,
"%lg", atm->
lon[atm->
np]);
4307 TOK(NULL, tok,
"%lg", atm->
lat[atm->
np]);
4308 for (
int iq = 0; iq < ctl->
nq; iq++)
4309 TOK(NULL, tok,
"%lg", atm->
q[iq][atm->
np]);
4312 atm->
p[atm->
np] =
P(atm->
p[atm->
np]);
4315 if ((++atm->
np) >
NP)
4316 ERRMSG(
"Too many data points!");
4329 const char *filename,
4335 if (!(in = fopen(filename,
"r")))
4340 FREAD(&version,
int,
4344 ERRMSG(
"Wrong version of binary data!");
4362 for (
int iq = 0; iq < ctl->
nq; iq++)
4363 FREAD(atm->
q[iq],
double,
4373 ERRMSG(
"Error while reading binary data!");
4385 const char *filename,
4392 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR)
4399 if (nc_inq_varid(ncid,
"TIME_INIT", &varid) == NC_NOERR) {
4400 NC(nc_get_var_double(ncid, varid, atm->
time));
4402 WARN(
"TIME_INIT not found use time instead!");
4405 for (
int ip = 0; ip < atm->
np; ip++) {
4406 atm->
time[ip] = time_init;
4418 if (nc_inq_varid(ncid,
"PRESS_INIT", &varid) == NC_NOERR) {
4419 NC(nc_get_var_double(ncid, varid, atm->
p));
4421 WARN(
"PRESS_INIT not found use PRESS instead!");
4422 nc_inq_varid(ncid,
"PRESS", &varid);
4423 NC(nc_get_var_double(ncid, varid, atm->
p));
4441 const char *filename,
4448 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR)
4461 for (
int iq = 0; iq < ctl->
nq; iq++)
4534 const char *filename,
4540 LOG(1,
"Read photolysis rates: %s", filename);
4543 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
4544 WARN(
"Photolysis rate data are missing!");
4551 if (photo->
p[0] < photo->
p[1])
4552 ERRMSG(
"Pressure data are not descending!");
4557 if (photo->
o3c[0] > photo->
o3c[1])
4558 ERRMSG(
"Total column ozone data are not ascending!");
4563 if (photo->
sza[0] > photo->
sza[1])
4564 ERRMSG(
"Solar zenith angle data are not ascending!");
4581 LOG(2,
"Number of pressure levels: %d", photo->
np);
4582 LOG(2,
"Altitude levels: %g, %g ... %g km",
4583 Z(photo->
p[0]),
Z(photo->
p[1]),
Z(photo->
p[photo->
np - 1]));
4584 LOG(2,
"Pressure levels: %g, %g ... %g hPa",
4585 photo->
p[0], photo->
p[1], photo->
p[photo->
np - 1]);
4586 LOG(2,
"Number of solar zenith angles: %d", photo->
nsza);
4587 LOG(2,
"Solar zenith angles: %g, %g ... %g deg",
4590 LOG(2,
"Number of total column ozone values: %d", photo->
no3c);
4591 LOG(2,
"Total column ozone: %g, %g ... %g DU",
4593 LOG(2,
"N2O photolysis rate: %g, %g ... %g s**-1",
4594 photo->
n2o[0][0][0], photo->
n2o[1][0][0],
4595 photo->
n2o[photo->
np - 1][photo->
nsza - 1][photo->
no3c - 1]);
4596 LOG(2,
"CCl4 photolysis rate: %g, %g ... %g s**-1",
4597 photo->
ccl4[0][0][0], photo->
ccl4[1][0][0],
4599 LOG(2,
"CFC-11 photolysis rate: %g, %g ... %g s**-1",
4600 photo->
ccl3f[0][0][0], photo->
ccl3f[1][0][0],
4602 LOG(2,
"CFC-12 photolysis rate: %g, %g ... %g s**-1",
4605 LOG(2,
"O2 photolysis rate: %g, %g ... %g s**-1",
4606 photo->
o2[0][0][0], photo->
o2[1][0][0],
4607 photo->
o2[photo->
np - 1][photo->
nsza - 1][photo->
no3c - 1]);
4608 LOG(2,
"O3 -> O(1D) photolysis rate: %g, %g ... %g s**-1",
4609 photo->
o3_1[0][0][0], photo->
o3_1[1][0][0],
4611 LOG(2,
"O3 -> O(3P) photolysis rate: %g, %g ... %g s**-1",
4612 photo->
o3_2[0][0][0], photo->
o3_2[1][0][0],
4614 LOG(2,
"H2O2 photolysis rate: %g, %g ... %g s**-1",
4615 photo->
h2o2[0][0][0], photo->
h2o2[1][0][0],
4617 LOG(2,
"H2O photolysis rate: %g, %g ... %g s**-1",
4618 photo->
h2o[0][0][0], photo->
h2o[1][0][0],
4619 photo->
h2o[photo->
np - 1][photo->
nsza - 1][photo->
no3c - 1]);
4626 const char *varname,
4640 for (
int ip = 0; ip < photo->
np; ip++)
4641 for (
int is = 0; is < photo->
nsza; is++)
4642 for (
int io = 0; io < photo->
no3c; io++)
4653 const char *filename,
4657 LOG(1,
"Read climatological time series: %s", filename);
4661 if (!(in = fopen(filename,
"r"))) {
4662 WARN(
"Cannot open file!");
4669 while (fgets(line,
LEN, in))
4670 if (sscanf(line,
"%lg %lg", &ts->
time[nh], &ts->
vmr[nh]) == 2) {
4673 ts->
time[nh] = (ts->
time[nh] - 2000.0) * 365.25 * 86400.;
4676 if (nh > 0 && ts->
time[nh] <= ts->
time[nh - 1])
4677 ERRMSG(
"Time series must be ascending!");
4681 ERRMSG(
"Too many data points!");
4690 ERRMSG(
"Not enough data points!");
4693 LOG(2,
"Number of time steps: %d", ts->
ntime);
4694 LOG(2,
"Time steps: %.2f, %.2f ... %.2f s", ts->
time[0], ts->
time[1],
4696 LOG(2,
"Volume mixing ratio range: %g ... %g ppv",
4697 gsl_stats_min(ts->
vmr, 1, (
size_t) nh), gsl_stats_max(ts->
vmr, 1,
4707 const char *filename,
4708 const char *varname,
4711 int ncid, varid, it, iy, iz, iz2, nt;
4713 double *help, varmin = 1e99, varmax = -1e99;
4716 LOG(1,
"Read %s data: %s", varname, filename);
4719 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
4720 WARN(
"%s climatology data are missing!", varname);
4727 if (zm->
p[0] < zm->
p[1])
4728 ERRMSG(
"Pressure data are not descending!");
4733 if (zm->
lat[0] > zm->
lat[1])
4734 ERRMSG(
"Latitude data are not ascending!");
4738 zm->
time[0] = 1209600.00;
4739 zm->
time[1] = 3888000.00;
4740 zm->
time[2] = 6393600.00;
4741 zm->
time[3] = 9072000.00;
4742 zm->
time[4] = 11664000.00;
4743 zm->
time[5] = 14342400.00;
4744 zm->
time[6] = 16934400.00;
4745 zm->
time[7] = 19612800.00;
4746 zm->
time[8] = 22291200.00;
4747 zm->
time[9] = 24883200.00;
4748 zm->
time[10] = 27561600.00;
4749 zm->
time[11] = 30153600.00;
4758 for (it = 0; it < zm->
ntime; it++)
4759 for (iz = 0; iz < zm->
np; iz++)
4760 for (iy = 0; iy < zm->
nlat; iy++)
4765 for (it = 0; it < zm->
ntime; it++)
4766 for (iy = 0; iy < zm->
nlat; iy++)
4767 for (iz = 0; iz < zm->
np; iz++) {
4768 if (zm->
vmr[it][iz][iy] < 0) {
4769 for (iz2 = 0; iz2 < zm->
np; iz2++)
4770 if (zm->
vmr[it][iz2][iy] >= 0) {
4771 zm->
vmr[it][iz][iy] = zm->
vmr[it][iz2][iy];
4774 for (iz2 = zm->
np - 1; iz2 >= 0; iz2--)
4775 if (zm->
vmr[it][iz2][iy] >= 0) {
4776 zm->
vmr[it][iz][iy] = zm->
vmr[it][iz2][iy];
4780 varmin =
MIN(varmin, zm->
vmr[it][iz][iy]);
4781 varmax =
MAX(varmax, zm->
vmr[it][iz][iy]);
4788 LOG(2,
"Number of time steps: %d", zm->
ntime);
4789 LOG(2,
"Time steps: %.2f, %.2f ... %.2f s",
4791 LOG(2,
"Number of pressure levels: %d", zm->
np);
4792 LOG(2,
"Altitude levels: %g, %g ... %g km",
4793 Z(zm->
p[0]),
Z(zm->
p[1]),
Z(zm->
p[zm->
np - 1]));
4794 LOG(2,
"Pressure levels: %g, %g ... %g hPa", zm->
p[0],
4795 zm->
p[1], zm->
p[zm->
np - 1]);
4796 LOG(2,
"Number of latitudes: %d", zm->
nlat);
4797 LOG(2,
"Latitudes: %g, %g ... %g deg",
4799 LOG(2,
"%s volume mixing ratio range: %g ... %g ppv", varname, varmin,
4806 const char *filename,
4815 LOG(1,
"\nMassive-Parallel Trajectory Calculations (MPTRAC)\n"
4816 "(executable: %s | version: %s | compiled: %s, %s)\n",
4817 argv[0], VERSION, __DATE__, __TIME__);
4910 ctl->
nq = (int)
scan_ctl(filename, argc, argv,
"NQ", -1,
"0", NULL);
4912 ERRMSG(
"Too many quantities!");
4913 for (
int iq = 0; iq < ctl->
nq; iq++) {
4919 scan_ctl(filename, argc, argv,
"QNT_FORMAT", iq,
"%g",
4921 if (strcasecmp(ctl->
qnt_name[iq],
"aoa") == 0)
4925 SET_QNT(qnt_idx,
"idx",
"particle index",
"-")
4926 SET_QNT(qnt_ens,
"ens",
"ensemble index",
"-")
4927 SET_QNT(qnt_stat,
"stat",
"station flag",
"-")
4928 SET_QNT(qnt_m,
"m",
"mass",
"kg")
4929 SET_QNT(qnt_vmr,
"vmr",
"volume mixing ratio",
"ppv")
4930 SET_QNT(qnt_rp,
"rp",
"particle radius",
"microns")
4931 SET_QNT(qnt_rhop,
"rhop",
"particle density",
"kg/m^3")
4932 SET_QNT(qnt_ps,
"ps",
"surface pressure",
"hPa")
4933 SET_QNT(qnt_ts,
"ts",
"surface temperature",
"K")
4934 SET_QNT(qnt_zs,
"zs",
"surface height",
"km")
4935 SET_QNT(qnt_us,
"us",
"surface zonal wind",
"m/s")
4936 SET_QNT(qnt_vs,
"vs",
"surface meridional wind",
"m/s")
4937 SET_QNT(qnt_lsm,
"lsm",
"land-sea mask",
"1")
4938 SET_QNT(qnt_sst,
"sst",
"sea surface temperature",
"K")
4939 SET_QNT(qnt_pbl,
"pbl",
"planetary boundary layer",
"hPa")
4940 SET_QNT(qnt_pt,
"pt",
"tropopause pressure",
"hPa")
4941 SET_QNT(qnt_tt,
"tt",
"tropopause temperature",
"K")
4942 SET_QNT(qnt_zt,
"zt",
"tropopause geopotential height",
"km")
4943 SET_QNT(qnt_h2ot,
"h2ot",
"tropopause water vapor",
"ppv")
4944 SET_QNT(qnt_zg,
"zg",
"geopotential height",
"km")
4945 SET_QNT(qnt_p,
"p",
"pressure",
"hPa")
4946 SET_QNT(qnt_t,
"t",
"temperature",
"K")
4947 SET_QNT(qnt_rho,
"rho",
"air density",
"kg/m^3")
4948 SET_QNT(qnt_u,
"u",
"zonal wind",
"m/s")
4949 SET_QNT(qnt_v,
"v",
"meridional wind",
"m/s")
4950 SET_QNT(qnt_w,
"w",
"vertical velocity",
"hPa/s")
4951 SET_QNT(qnt_h2o,
"h2o",
"water vapor",
"ppv")
4952 SET_QNT(qnt_o3,
"o3",
"ozone",
"ppv")
4953 SET_QNT(qnt_lwc,
"lwc",
"cloud liquid water content",
"kg/kg")
4954 SET_QNT(qnt_rwc,
"rwc",
"cloud rain water content",
"kg/kg")
4955 SET_QNT(qnt_iwc,
"iwc",
"cloud ice water content",
"kg/kg")
4956 SET_QNT(qnt_swc,
"iwc",
"cloud snow water content",
"kg/kg")
4957 SET_QNT(qnt_cc,
"cc",
"cloud cover",
"1")
4958 SET_QNT(qnt_pct,
"pct",
"cloud top pressure",
"hPa")
4959 SET_QNT(qnt_pcb,
"pcb",
"cloud bottom pressure",
"hPa")
4960 SET_QNT(qnt_cl,
"cl",
"total column cloud water",
"kg/m^2")
4961 SET_QNT(qnt_plcl,
"plcl",
"lifted condensation level",
"hPa")
4962 SET_QNT(qnt_plfc,
"plfc",
"level of free convection",
"hPa")
4963 SET_QNT(qnt_pel,
"pel",
"equilibrium level",
"hPa")
4964 SET_QNT(qnt_cape,
"cape",
"convective available potential energy",
4966 SET_QNT(qnt_cin,
"cin",
"convective inhibition",
"J/kg")
4967 SET_QNT(qnt_o3c,
"o3c",
"total column ozone",
"DU")
4968 SET_QNT(qnt_hno3,
"hno3",
"nitric acid",
"ppv")
4969 SET_QNT(qnt_oh,
"oh",
"hydroxyl radical",
"ppv")
4970 SET_QNT(qnt_h2o2,
"h2o2",
"hydrogen peroxide",
"ppv")
4971 SET_QNT(qnt_ho2,
"ho2",
"hydroperoxyl radical",
"ppv")
4972 SET_QNT(qnt_o1d,
"o1d",
"atomic oxygen",
"ppv")
4973 SET_QNT(qnt_mloss_oh,
"mloss_oh",
"mass loss due to OH chemistry",
"kg")
4974 SET_QNT(qnt_mloss_h2o2,
"mloss_h2o2",
"mass loss due to H2O2 chemistry",
4976 SET_QNT(qnt_mloss_kpp,
"mloss_kpp",
"mass loss due to kpp chemistry",
4978 SET_QNT(qnt_mloss_wet,
"mloss_wet",
"mass loss due to wet deposition",
4980 SET_QNT(qnt_mloss_dry,
"mloss_dry",
"mass loss due to dry deposition",
4982 SET_QNT(qnt_mloss_decay,
"mloss_decay",
4983 "mass loss due to exponential decay",
"kg")
4984 SET_QNT(qnt_loss_rate,
"loss_rate",
"total loss rate",
"s^-1")
4985 SET_QNT(qnt_psat,
"psat",
"saturation pressure over water",
"hPa")
4986 SET_QNT(qnt_psice,
"psice",
"saturation pressure over ice",
"hPa")
4987 SET_QNT(qnt_pw,
"pw",
"partial water vapor pressure",
"hPa")
4988 SET_QNT(qnt_sh,
"sh",
"specific humidity",
"kg/kg")
4989 SET_QNT(qnt_rh,
"rh",
"relative humidity",
"%%")
4990 SET_QNT(qnt_rhice,
"rhice",
"relative humidity over ice",
"%%")
4991 SET_QNT(qnt_theta,
"theta",
"potential temperature",
"K")
4992 SET_QNT(qnt_zeta,
"zeta",
"zeta coordinate",
"K")
4993 SET_QNT(qnt_zeta_d,
"zeta_d",
"diagnosed zeta coordinate",
"K")
4994 SET_QNT(qnt_tvirt,
"tvirt",
"virtual temperature",
"K")
4995 SET_QNT(qnt_lapse,
"lapse",
"temperature lapse rate",
"K/km")
4996 SET_QNT(qnt_vh,
"vh",
"horizontal velocity",
"m/s")
4997 SET_QNT(qnt_vz,
"vz",
"vertical velocity",
"m/s")
4998 SET_QNT(qnt_pv,
"pv",
"potential vorticity",
"PVU")
4999 SET_QNT(qnt_tdew,
"tdew",
"dew point temperature",
"K")
5000 SET_QNT(qnt_tice,
"tice",
"frost point temperature",
"K")
5001 SET_QNT(qnt_tsts,
"tsts",
"STS existence temperature",
"K")
5002 SET_QNT(qnt_tnat,
"tnat",
"NAT existence temperature",
"K")
5003 SET_QNT(qnt_Cx,
"Cx",
"Trace species x volume mixing ratio",
"ppv")
5004 SET_QNT(qnt_Ch2o,
"Ch2o",
"H2O volume mixing ratio",
"ppv")
5005 SET_QNT(qnt_Co3,
"Co3",
"O3 volume mixing ratio",
"ppv")
5006 SET_QNT(qnt_Cco,
"Cco",
"CO volume mixing ratio",
"ppv")
5007 SET_QNT(qnt_Coh,
"Coh",
"HO volume mixing ratio",
"ppv")
5008 SET_QNT(qnt_Ch,
"Ch",
"H radical volume mixing ratio",
"ppv")
5009 SET_QNT(qnt_Cho2,
"Cho2",
"HO2 volume mixing ratio",
"ppv")
5010 SET_QNT(qnt_Ch2o2,
"Ch2o2",
"H2O2 volume mixing ratio",
"ppv")
5011 SET_QNT(qnt_Co1d,
"Co1d",
"O(1D) volume mixing ratio",
"ppv")
5012 SET_QNT(qnt_Co3p,
"Co3p",
"O(3P) radical volume mixing ratio",
"ppv")
5013 SET_QNT(qnt_Cccl4,
"Cccl4",
"CCl4 (CFC-10) volume mixing ratio",
"ppv")
5014 SET_QNT(qnt_Cccl3f,
"Cccl3f",
"CCl3F (CFC-11) volume mixing ratio",
5016 SET_QNT(qnt_Cccl2f2,
"Cccl2f2",
"CCl2F2 (CFC-12) volume mixing ratio",
5018 SET_QNT(qnt_Cn2o,
"Cn2o",
"N2O volume mixing ratio",
"ppv")
5019 SET_QNT(qnt_Csf6,
"Csf6",
"SF6 volume mixing ratio",
"ppv")
5020 SET_QNT(qnt_aoa,
"aoa",
"age of air",
"s")
5026 (int)
scan_ctl(filename, argc, argv,
"ADVECT_VERT_COORD", -1,
"0", NULL);
5028 ERRMSG(
"Set advect_vert_coord to 0, 1, or 2!");
5030 ERRMSG(
"Please add zeta to your quantities for diabatic calculations!");
5032 (int)
scan_ctl(filename, argc, argv,
"MET_VERT_COORD", -1,
"0", NULL);
5035 (
"Using ADVECT_VERT_COORD = 2 requires meteo data on model levels!");
5037 (int)
scan_ctl(filename, argc, argv,
"MET_CLAMS", -1,
"0", NULL);
5039 (int)
scan_ctl(filename, argc, argv,
"ADVECT_ZETA_PRESS_MODULES", -1,
"1",
5044 (int)
scan_ctl(filename, argc, argv,
"DIRECTION", -1,
"1", NULL);
5046 ERRMSG(
"Set DIRECTION to -1 or 1!");
5047 ctl->
t_stop =
scan_ctl(filename, argc, argv,
"T_STOP", -1,
"1e100", NULL);
5048 ctl->
dt_mod =
scan_ctl(filename, argc, argv,
"DT_MOD", -1,
"180", NULL);
5052 ctl->
dt_met =
scan_ctl(filename, argc, argv,
"DT_MET", -1,
"3600", NULL);
5054 (int)
scan_ctl(filename, argc, argv,
"MET_CONVENTION", -1,
"0", NULL);
5056 (int)
scan_ctl(filename, argc, argv,
"MET_TYPE", -1,
"0", NULL);
5059 (
"Please use meteorological files in netcdf format for diabatic calculations.");
5061 (int)
scan_ctl(filename, argc, argv,
"MET_NC_SCALE", -1,
"1", NULL);
5063 (int)
scan_ctl(filename, argc, argv,
"MET_NC_LEVEL", -1,
"0", NULL);
5065 (int)
scan_ctl(filename, argc, argv,
"MET_NC_QUANT", -1,
"0", NULL);
5067 (int)
scan_ctl(filename, argc, argv,
"MET_ZFP_PREC", -1,
"8", NULL);
5069 scan_ctl(filename, argc, argv,
"MET_ZFP_TOL_T", -1,
"5.0", NULL);
5071 scan_ctl(filename, argc, argv,
"MET_ZFP_TOL_Z", -1,
"0.5", NULL);
5073 (int)
scan_ctl(filename, argc, argv,
"MET_CMS_BATCH", -1,
"-1", NULL);
5075 (int)
scan_ctl(filename, argc, argv,
"MET_CMS_HEUR", -1,
"1", NULL);
5077 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_Z", -1,
"1.0", NULL);
5079 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_T", -1,
"0.05", NULL);
5081 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_U", -1,
"0.05", NULL);
5083 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_V", -1,
"0.05", NULL);
5085 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_W", -1,
"1.0", NULL);
5087 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_PV", -1,
"1.0", NULL);
5089 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_H2O", -1,
"1.0", NULL);
5091 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_O3", -1,
"1.0", NULL);
5093 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_LWC", -1,
"1.0", NULL);
5095 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_RWC", -1,
"1.0", NULL);
5097 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_IWC", -1,
"1.0", NULL);
5099 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_SWC", -1,
"1.0", NULL);
5101 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_CC", -1,
"1.0", NULL);
5102 ctl->
met_dx = (int)
scan_ctl(filename, argc, argv,
"MET_DX", -1,
"1", NULL);
5103 ctl->
met_dy = (int)
scan_ctl(filename, argc, argv,
"MET_DY", -1,
"1", NULL);
5104 ctl->
met_dp = (int)
scan_ctl(filename, argc, argv,
"MET_DP", -1,
"1", NULL);
5106 ERRMSG(
"MET_DX, MET_DY, and MET_DP need to be greater than zero!");
5107 ctl->
met_sx = (int)
scan_ctl(filename, argc, argv,
"MET_SX", -1,
"1", NULL);
5108 ctl->
met_sy = (int)
scan_ctl(filename, argc, argv,
"MET_SY", -1,
"1", NULL);
5109 ctl->
met_sp = (int)
scan_ctl(filename, argc, argv,
"MET_SP", -1,
"1", NULL);
5111 ERRMSG(
"MET_SX, MET_SY, and MET_SP need to be greater than zero!");
5113 scan_ctl(filename, argc, argv,
"MET_DETREND", -1,
"-999", NULL);
5114 ctl->
met_np = (int)
scan_ctl(filename, argc, argv,
"MET_NP", -1,
"0", NULL);
5116 ERRMSG(
"Too many levels!");
5118 (int)
scan_ctl(filename, argc, argv,
"MET_PRESS_LEVEL_DEF", -1,
"-1",
5124 for (
int ip = 0; ip < ctl->
met_np; ip++)
5126 scan_ctl(filename, argc, argv,
"MET_P", ip,
"", NULL);
5130 (int)
scan_ctl(filename, argc, argv,
"MET_GEOPOT_SX", -1,
"-1", NULL);
5132 (int)
scan_ctl(filename, argc, argv,
"MET_GEOPOT_SY", -1,
"-1", NULL);
5134 (int)
scan_ctl(filename, argc, argv,
"MET_RELHUM", -1,
"0", NULL);
5136 (int)
scan_ctl(filename, argc, argv,
"MET_CAPE", -1,
"1", NULL);
5138 ERRMSG(
"Set MET_CAPE to 0 or 1!");
5140 (int)
scan_ctl(filename, argc, argv,
"MET_PBL", -1,
"2", NULL);
5142 ERRMSG(
"Set MET_PBL = 0 ... 2!");
5144 scan_ctl(filename, argc, argv,
"MET_PBL_MIN", -1,
"0.1", NULL);
5146 scan_ctl(filename, argc, argv,
"MET_PBL_MAX", -1,
"5.0", NULL);
5148 (int)
scan_ctl(filename, argc, argv,
"MET_TROPO", -1,
"3", NULL);
5150 ERRMSG(
"Set MET_TROPO = 0 ... 5!");
5152 scan_ctl(filename, argc, argv,
"MET_TROPO_PV", -1,
"3.5", NULL);
5154 scan_ctl(filename, argc, argv,
"MET_TROPO_THETA", -1,
"380", NULL);
5156 (int)
scan_ctl(filename, argc, argv,
"MET_TROPO_SPLINE", -1,
"1", NULL);
5158 scan_ctl(filename, argc, argv,
"MET_DT_OUT", -1,
"0.1", NULL);
5160 (int)
scan_ctl(filename, argc, argv,
"MET_CACHE", -1,
"0", NULL);
5162 (int)
scan_ctl(filename, argc, argv,
"MET_MPI_SHARE", -1,
"0", NULL);
5165 ctl->
sort_dt =
scan_ctl(filename, argc, argv,
"SORT_DT", -1,
"-999", NULL);
5169 (int)
scan_ctl(filename, argc, argv,
"ISOSURF", -1,
"0", NULL);
5174 (int)
scan_ctl(filename, argc, argv,
"RNG_TYPE", -1,
"0", NULL);
5176 ERRMSG(
"Set RNG_TYPE to 0, 1, or 2!");
5179 ctl->
advect = (int)
scan_ctl(filename, argc, argv,
"ADVECT", -1,
"2", NULL);
5182 ERRMSG(
"Set ADVECT to 0, 1, 2, or 4!");
5184 (int)
scan_ctl(filename, argc, argv,
"REFLECT", -1,
"0", NULL);
5188 scan_ctl(filename, argc, argv,
"TURB_DX_TROP", -1,
"50", NULL);
5190 scan_ctl(filename, argc, argv,
"TURB_DX_STRAT", -1,
"0", NULL);
5192 scan_ctl(filename, argc, argv,
"TURB_DZ_TROP", -1,
"0", NULL);
5194 scan_ctl(filename, argc, argv,
"TURB_DZ_STRAT", -1,
"0.1", NULL);
5196 scan_ctl(filename, argc, argv,
"TURB_MESOX", -1,
"0.16", NULL);
5198 scan_ctl(filename, argc, argv,
"TURB_MESOZ", -1,
"0.16", NULL);
5202 =
scan_ctl(filename, argc, argv,
"CONV_CAPE", -1,
"-999", NULL);
5204 =
scan_ctl(filename, argc, argv,
"CONV_CIN", -1,
"-999", NULL);
5205 ctl->
conv_dt =
scan_ctl(filename, argc, argv,
"CONV_DT", -1,
"-999", NULL);
5207 = (int)
scan_ctl(filename, argc, argv,
"CONV_MIX_BOT", -1,
"1", NULL);
5209 = (int)
scan_ctl(filename, argc, argv,
"CONV_MIX_TOP", -1,
"1", NULL);
5213 scan_ctl(filename, argc, argv,
"BOUND_MASS", -1,
"-999", NULL);
5215 scan_ctl(filename, argc, argv,
"BOUND_MASS_TREND", -1,
"0", NULL);
5217 scan_ctl(filename, argc, argv,
"BOUND_VMR", -1,
"-999", NULL);
5219 scan_ctl(filename, argc, argv,
"BOUND_VMR_TREND", -1,
"0", NULL);
5221 scan_ctl(filename, argc, argv,
"BOUND_LAT0", -1,
"-999", NULL);
5223 scan_ctl(filename, argc, argv,
"BOUND_LAT1", -1,
"-999", NULL);
5225 scan_ctl(filename, argc, argv,
"BOUND_P0", -1,
"-999", NULL);
5227 scan_ctl(filename, argc, argv,
"BOUND_P1", -1,
"-999", NULL);
5229 scan_ctl(filename, argc, argv,
"BOUND_DPS", -1,
"-999", NULL);
5231 scan_ctl(filename, argc, argv,
"BOUND_DZS", -1,
"-999", NULL);
5233 scan_ctl(filename, argc, argv,
"BOUND_ZETAS", -1,
"-999", NULL);
5235 (int)
scan_ctl(filename, argc, argv,
"BOUND_PBL", -1,
"0", NULL);
5239 if (strcasecmp(ctl->
species,
"CF2Cl2") == 0) {
5243 }
else if (strcasecmp(ctl->
species,
"CFCl3") == 0) {
5247 }
else if (strcasecmp(ctl->
species,
"CH4") == 0) {
5254 }
else if (strcasecmp(ctl->
species,
"CO") == 0) {
5263 }
else if (strcasecmp(ctl->
species,
"CO2") == 0) {
5267 }
else if (strcasecmp(ctl->
species,
"H2O") == 0) {
5269 }
else if (strcasecmp(ctl->
species,
"N2O") == 0) {
5273 }
else if (strcasecmp(ctl->
species,
"NH3") == 0) {
5280 }
else if (strcasecmp(ctl->
species,
"HNO3") == 0) {
5284 }
else if (strcasecmp(ctl->
species,
"NO") == 0) {
5293 }
else if (strcasecmp(ctl->
species,
"NO2") == 0) {
5302 }
else if (strcasecmp(ctl->
species,
"O3") == 0) {
5309 }
else if (strcasecmp(ctl->
species,
"SF6") == 0) {
5313 }
else if (strcasecmp(ctl->
species,
"SO2") == 0) {
5326 sprintf(defstr,
"%g", ctl->
molmass);
5327 ctl->
molmass =
scan_ctl(filename, argc, argv,
"MOLMASS", -1, defstr, NULL);
5332 (int)
scan_ctl(filename, argc, argv,
"OH_CHEM_REACTION", -1, defstr,
5334 for (
int ip = 0; ip < 4; ip++) {
5335 sprintf(defstr,
"%g", ctl->
oh_chem[ip]);
5337 scan_ctl(filename, argc, argv,
"OH_CHEM", ip, defstr, NULL);
5340 scan_ctl(filename, argc, argv,
"OH_CHEM_BETA", -1,
"0", NULL);
5344 (int)
scan_ctl(filename, argc, argv,
"H2O2_CHEM_REACTION", -1,
"0", NULL);
5348 (int)
scan_ctl(filename, argc, argv,
"KPP_CHEM", -1,
"0", NULL);
5349 ctl->
dt_kpp =
scan_ctl(filename, argc, argv,
"DT_KPP", -1,
"1800", NULL);
5353 (int)
scan_ctl(filename, argc, argv,
"TRACER_CHEM", -1,
"0", NULL);
5356 for (
int ip = 0; ip < 3; ip++) {
5359 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_H", ip, defstr, NULL);
5361 for (
int ip = 0; ip < 1; ip++) {
5364 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_H", ip, defstr, NULL);
5367 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_A", -1,
"0", NULL);
5369 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_B", -1,
"0", NULL);
5371 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_A", -1,
"0", NULL);
5373 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_B", -1,
"0", NULL);
5375 scan_ctl(filename, argc, argv,
"WET_DEPO_PRE", 0,
"0.5", NULL);
5377 scan_ctl(filename, argc, argv,
"WET_DEPO_PRE", 1,
"0.36", NULL);
5379 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_RET_RATIO", -1,
"1", NULL);
5381 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_RET_RATIO", -1,
"1", NULL);
5385 scan_ctl(filename, argc, argv,
"DRY_DEPO_VDEP", -1,
"0", NULL);
5387 scan_ctl(filename, argc, argv,
"DRY_DEPO_DP", -1,
"30", NULL);
5390 scan_ctl(filename, argc, argv,
"CLIM_PHOTO", -1,
5391 "../../data/clams_photolysis_rates.nc", ctl->
clim_photo);
5392 scan_ctl(filename, argc, argv,
"CLIM_HNO3_FILENAME", -1,
5394 scan_ctl(filename, argc, argv,
"CLIM_OH_FILENAME", -1,
5396 scan_ctl(filename, argc, argv,
"CLIM_H2O2_FILENAME", -1,
5398 scan_ctl(filename, argc, argv,
"CLIM_HO2_FILENAME", -1,
5400 scan_ctl(filename, argc, argv,
"CLIM_O1D_FILENAME", -1,
5402 scan_ctl(filename, argc, argv,
"CLIM_CCL4_TIMESERIES", -1,
5404 scan_ctl(filename, argc, argv,
"CLIM_CCL3F_TIMESERIES", -1,
5406 scan_ctl(filename, argc, argv,
"CLIM_CCL2F2_TIMESERIES", -1,
5408 scan_ctl(filename, argc, argv,
"CLIM_N2O_TIMESERIES", -1,
5410 scan_ctl(filename, argc, argv,
"CLIM_SF6_TIMESERIES", -1,
5415 scan_ctl(filename, argc, argv,
"MIXING_DT", -1,
"3600.", NULL);
5417 scan_ctl(filename, argc, argv,
"MIXING_TROP", -1,
"-999", NULL);
5419 scan_ctl(filename, argc, argv,
"MIXING_STRAT", -1,
"-999", NULL);
5421 scan_ctl(filename, argc, argv,
"MIXING_Z0", -1,
"-5", NULL);
5423 scan_ctl(filename, argc, argv,
"MIXING_Z1", -1,
"85", NULL);
5425 (int)
scan_ctl(filename, argc, argv,
"MIXING_NZ", -1,
"90", NULL);
5427 scan_ctl(filename, argc, argv,
"MIXING_LON0", -1,
"-180", NULL);
5429 scan_ctl(filename, argc, argv,
"MIXING_LON1", -1,
"180", NULL);
5431 (int)
scan_ctl(filename, argc, argv,
"MIXING_NX", -1,
"360", NULL);
5433 scan_ctl(filename, argc, argv,
"MIXING_LAT0", -1,
"-90", NULL);
5435 scan_ctl(filename, argc, argv,
"MIXING_LAT1", -1,
"90", NULL);
5437 (int)
scan_ctl(filename, argc, argv,
"MIXING_NY", -1,
"180", NULL);
5441 scan_ctl(filename, argc, argv,
"CHEMGRID_Z0", -1,
"-5", NULL);
5443 scan_ctl(filename, argc, argv,
"CHEMGRID_Z1", -1,
"85", NULL);
5445 (int)
scan_ctl(filename, argc, argv,
"CHEMGRID_NZ", -1,
"90", NULL);
5447 scan_ctl(filename, argc, argv,
"CHEMGRID_LON0", -1,
"-180", NULL);
5449 scan_ctl(filename, argc, argv,
"CHEMGRID_LON1", -1,
"180", NULL);
5451 (int)
scan_ctl(filename, argc, argv,
"CHEMGRID_NX", -1,
"360", NULL);
5453 scan_ctl(filename, argc, argv,
"CHEMGRID_LAT0", -1,
"-90", NULL);
5455 scan_ctl(filename, argc, argv,
"CHEMGRID_LAT1", -1,
"90", NULL);
5457 (int)
scan_ctl(filename, argc, argv,
"CHEMGRID_NY", -1,
"180", NULL);
5462 =
scan_ctl(filename, argc, argv,
"TDEC_STRAT", -1,
"0", NULL);
5465 ctl->
psc_h2o =
scan_ctl(filename, argc, argv,
"PSC_H2O", -1,
"4e-6", NULL);
5467 scan_ctl(filename, argc, argv,
"PSC_HNO3", -1,
"9e-9", NULL);
5473 scan_ctl(filename, argc, argv,
"ATM_DT_OUT", -1,
"86400", NULL);
5475 (int)
scan_ctl(filename, argc, argv,
"ATM_FILTER", -1,
"0", NULL);
5477 (int)
scan_ctl(filename, argc, argv,
"ATM_STRIDE", -1,
"1", NULL);
5479 (int)
scan_ctl(filename, argc, argv,
"ATM_TYPE", -1,
"0", NULL);
5481 (int)
scan_ctl(filename, argc, argv,
"ATM_TYPE_OUT", -1,
"-1", NULL);
5485 (int)
scan_ctl(filename, argc, argv,
"ATM_NC_LEVEL", -1,
"0", NULL);
5486 for (
int iq = 0; iq < ctl->
nq; iq++)
5488 (
int)
scan_ctl(filename, argc, argv,
"ATM_NC_QUANT", iq,
"0", NULL);
5490 (int)
scan_ctl(filename, argc, argv,
"OBS_TYPE", -1,
"0", NULL);
5496 scan_ctl(filename, argc, argv,
"CSI_DT_OUT", -1,
"86400", NULL);
5499 scan_ctl(filename, argc, argv,
"CSI_OBSMIN", -1,
"0", NULL);
5501 scan_ctl(filename, argc, argv,
"CSI_MODMIN", -1,
"0", NULL);
5502 ctl->
csi_z0 =
scan_ctl(filename, argc, argv,
"CSI_Z0", -1,
"-5", NULL);
5503 ctl->
csi_z1 =
scan_ctl(filename, argc, argv,
"CSI_Z1", -1,
"85", NULL);
5504 ctl->
csi_nz = (int)
scan_ctl(filename, argc, argv,
"CSI_NZ", -1,
"1", NULL);
5506 scan_ctl(filename, argc, argv,
"CSI_LON0", -1,
"-180", NULL);
5507 ctl->
csi_lon1 =
scan_ctl(filename, argc, argv,
"CSI_LON1", -1,
"180", NULL);
5509 (int)
scan_ctl(filename, argc, argv,
"CSI_NX", -1,
"360", NULL);
5510 ctl->
csi_lat0 =
scan_ctl(filename, argc, argv,
"CSI_LAT0", -1,
"-90", NULL);
5511 ctl->
csi_lat1 =
scan_ctl(filename, argc, argv,
"CSI_LAT1", -1,
"90", NULL);
5513 (int)
scan_ctl(filename, argc, argv,
"CSI_NY", -1,
"180", NULL);
5518 scan_ctl(filename, argc, argv,
"ENS_DT_OUT", -1,
"86400", NULL);
5521 scan_ctl(filename, argc, argv,
"GRID_BASENAME", -1,
"-",
5526 scan_ctl(filename, argc, argv,
"GRID_DT_OUT", -1,
"86400", NULL);
5528 (int)
scan_ctl(filename, argc, argv,
"GRID_SPARSE", -1,
"0", NULL);
5530 (int)
scan_ctl(filename, argc, argv,
"GRID_NC_LEVEL", -1,
"0", NULL);
5531 for (
int iq = 0; iq < ctl->
nq; iq++)
5533 (
int)
scan_ctl(filename, argc, argv,
"GRID_NC_QUANT", iq,
"0", NULL);
5535 (int)
scan_ctl(filename, argc, argv,
"GRID_STDDEV", -1,
"0", NULL);
5536 ctl->
grid_z0 =
scan_ctl(filename, argc, argv,
"GRID_Z0", -1,
"-5", NULL);
5537 ctl->
grid_z1 =
scan_ctl(filename, argc, argv,
"GRID_Z1", -1,
"85", NULL);
5539 (int)
scan_ctl(filename, argc, argv,
"GRID_NZ", -1,
"1", NULL);
5541 scan_ctl(filename, argc, argv,
"GRID_LON0", -1,
"-180", NULL);
5543 scan_ctl(filename, argc, argv,
"GRID_LON1", -1,
"180", NULL);
5545 (int)
scan_ctl(filename, argc, argv,
"GRID_NX", -1,
"360", NULL);
5547 scan_ctl(filename, argc, argv,
"GRID_LAT0", -1,
"-90", NULL);
5549 scan_ctl(filename, argc, argv,
"GRID_LAT1", -1,
"90", NULL);
5551 (int)
scan_ctl(filename, argc, argv,
"GRID_NY", -1,
"180", NULL);
5553 (int)
scan_ctl(filename, argc, argv,
"GRID_TYPE", -1,
"0", NULL);
5556 scan_ctl(filename, argc, argv,
"PROF_BASENAME", -1,
"-",
5559 ctl->
prof_z0 =
scan_ctl(filename, argc, argv,
"PROF_Z0", -1,
"0", NULL);
5560 ctl->
prof_z1 =
scan_ctl(filename, argc, argv,
"PROF_Z1", -1,
"60", NULL);
5562 (int)
scan_ctl(filename, argc, argv,
"PROF_NZ", -1,
"60", NULL);
5564 scan_ctl(filename, argc, argv,
"PROF_LON0", -1,
"-180", NULL);
5566 scan_ctl(filename, argc, argv,
"PROF_LON1", -1,
"180", NULL);
5568 (int)
scan_ctl(filename, argc, argv,
"PROF_NX", -1,
"360", NULL);
5570 scan_ctl(filename, argc, argv,
"PROF_LAT0", -1,
"-90", NULL);
5572 scan_ctl(filename, argc, argv,
"PROF_LAT1", -1,
"90", NULL);
5574 (int)
scan_ctl(filename, argc, argv,
"PROF_NY", -1,
"180", NULL);
5577 scan_ctl(filename, argc, argv,
"SAMPLE_BASENAME", -1,
"-",
5579 scan_ctl(filename, argc, argv,
"SAMPLE_KERNEL", -1,
"-",
5581 scan_ctl(filename, argc, argv,
"SAMPLE_OBSFILE", -1,
"-",
5584 scan_ctl(filename, argc, argv,
"SAMPLE_DX", -1,
"50", NULL);
5586 scan_ctl(filename, argc, argv,
"SAMPLE_DZ", -1,
"-999", NULL);
5589 scan_ctl(filename, argc, argv,
"STAT_BASENAME", -1,
"-",
5593 ctl->
stat_r =
scan_ctl(filename, argc, argv,
"STAT_R", -1,
"50", NULL);
5595 scan_ctl(filename, argc, argv,
"STAT_T0", -1,
"-1e100", NULL);
5596 ctl->
stat_t1 =
scan_ctl(filename, argc, argv,
"STAT_T1", -1,
"1e100", NULL);
5601 scan_ctl(filename, argc, argv,
"VTK_DT_OUT", -1,
"86400", NULL);
5603 (int)
scan_ctl(filename, argc, argv,
"VTK_STRIDE", -1,
"1", NULL);
5605 scan_ctl(filename, argc, argv,
"VTK_SCALE", -1,
"1.0", NULL);
5607 scan_ctl(filename, argc, argv,
"VTK_OFFSET", -1,
"0.0", NULL);
5609 (int)
scan_ctl(filename, argc, argv,
"VTK_SPHERE", -1,
"0", NULL);
5615 const char *filename,
5621 LOG(1,
"Read kernel function: %s", filename);
5625 if (!(in = fopen(filename,
"r")))
5626 ERRMSG(
"Cannot open file!");
5631 while (fgets(line,
LEN, in))
5632 if (sscanf(line,
"%lg %lg", &kz[n], &kw[n]) == 2) {
5633 if (n > 0 && kz[n] < kz[n - 1])
5634 ERRMSG(
"Height levels must be ascending!");
5636 ERRMSG(
"Too many height levels!");
5645 ERRMSG(
"Not enough height levels!");
5648 const double kmax = gsl_stats_max(kw, 1, (
size_t) n);
5649 for (
int iz = 0; iz < n; iz++)
5656 const char *filename,
5662 LOG(1,
"Read meteo data: %s", filename);
5668 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
5688 ERRMSG(
"MET_TYPE not implemented!");
5697 LOG(2,
"Broadcast data on rank %d...", rank);
5711 const char *filename,
5719 int year, mon, day, hour, min, sec;
5725 if (!(in = fopen(filename,
"r"))) {
5726 WARN(
"Cannot open file!");
5732 FREAD(&met_type,
int,
5736 ERRMSG(
"Wrong MET_TYPE of binary data!");
5740 FREAD(&version,
int,
5743 if (version != 100 && version != 101 && version != 102)
5744 ERRMSG(
"Wrong version of binary data!");
5750 jsec2time(met->
time, &year, &mon, &day, &hour, &min, &sec, &r);
5751 LOG(2,
"Time: %.2f (%d-%02d-%02d, %02d:%02d UTC)",
5752 met->
time, year, mon, day, hour, min);
5753 if (year < 1900 || year > 2100 || mon < 1 || mon > 12
5754 || day < 1 || day > 31 || hour < 0 || hour > 23)
5755 ERRMSG(
"Error while reading time!");
5761 LOG(2,
"Number of longitudes: %d", met->
nx);
5762 if (met->
nx < 2 || met->
nx >
EX)
5763 ERRMSG(
"Number of longitudes out of range!");
5768 LOG(2,
"Number of latitudes: %d", met->
ny);
5769 if (met->
ny < 2 || met->
ny >
EY)
5770 ERRMSG(
"Number of latitudes out of range!");
5775 LOG(2,
"Number of levels: %d", met->
np);
5776 if (met->
np < 2 || met->
np >
EP)
5777 ERRMSG(
"Number of levels out of range!");
5783 LOG(2,
"Longitudes: %g, %g ... %g deg",
5789 LOG(2,
"Latitudes: %g, %g ... %g deg",
5795 LOG(2,
"Altitude levels: %g, %g ... %g km",
5796 Z(met->
p[0]),
Z(met->
p[1]),
Z(met->
p[met->
np - 1]));
5797 LOG(2,
"Pressure levels: %g, %g ... %g hPa",
5798 met->
p[0], met->
p[1], met->
p[met->
np - 1]);
5806 if (version >= 101) {
5848 ERRMSG(
"Error while reading binary data!");
5863 const char *varname) {
5872 LOG(2,
"Read 2-D variable: %s (uncompressed)", varname);
5874 (
size_t) (met->
nx * met->
ny),
5878 for (
int ix = 0; ix < met->
nx; ix++)
5879 for (
int iy = 0; iy < met->
ny; iy++)
5880 var[ix][iy] = help[
ARRAY_2D(ix, iy, met->
ny)];
5893 const char *varname,
5894 const float bound_min,
5895 const float bound_max) {
5905 LOG(2,
"Read 3-D variable: %s (uncompressed)", varname);
5907 (
size_t) (met->
nx * met->
ny * met->
np),
5914 (
size_t) met->
np, 1, in);
5920 FREAD(&precision,
int,
5925 FREAD(&tolerance,
double,
5932 ERRMSG(
"MPTRAC was compiled without zfp compression!");
5942 ERRMSG(
"MPTRAC was compiled without zstd compression!");
5950 (
size_t) met->
np, 1, in);
5952 ERRMSG(
"MPTRAC was compiled without cmultiscale compression!");
5957#pragma omp parallel for default(shared) collapse(2)
5958 for (
int ix = 0; ix < met->
nx; ix++)
5959 for (
int iy = 0; iy < met->
ny; iy++)
5960 for (
int ip = 0; ip < met->
np; ip++) {
5961 var[ix][iy][ip] = help[
ARRAY_3D(ix, iy, met->
ny, ip, met->
np)];
5962 if (var[ix][iy][ip] < bound_min)
5963 var[ix][iy][ip] = bound_min;
5964 else if (var[ix][iy][ip] > bound_max)
5965 var[ix][iy][ip] = bound_max;
5985 LOG(2,
"Calculate CAPE...");
5988 const double pfac = 1.01439, dz0 =
RI /
MA /
G0 * log(pfac);
5991#pragma omp parallel for default(shared) collapse(2)
5992 for (
int ix = 0; ix < met->
nx; ix++)
5993 for (
int iy = 0; iy < met->
ny; iy++) {
5997 double h2o = 0, t, theta = 0;
5998 double pbot =
MIN(met->
ps[ix][iy], met->
p[0]);
5999 double ptop = pbot - 50.;
6000 for (
int ip = 0; ip < met->
np; ip++) {
6001 if (met->
p[ip] <= pbot) {
6002 theta +=
THETA(met->
p[ip], met->
t[ix][iy][ip]);
6003 h2o += met->
h2o[ix][iy][ip];
6006 if (met->
p[ip] < ptop && n > 0)
6013 met->
plcl[ix][iy] = NAN;
6014 met->
plfc[ix][iy] = NAN;
6015 met->
pel[ix][iy] = NAN;
6016 met->
cape[ix][iy] = NAN;
6017 met->
cin[ix][iy] = NAN;
6023 pbot = met->
ps[ix][iy];
6025 met->
plcl[ix][iy] = (float) (0.5 * (pbot + ptop));
6026 t = theta / pow(1000. / met->
plcl[ix][iy], 0.286);
6027 if (
RH(met->
plcl[ix][iy], t, h2o) > 100.)
6028 ptop = met->
plcl[ix][iy];
6030 pbot = met->
plcl[ix][iy];
6031 }
while (pbot - ptop > 0.1);
6035 double dcape, dz, h2o_env, t_env;
6036 double p = met->
ps[ix][iy];
6037 met->
cape[ix][iy] = met->
cin[ix][iy] = 0;
6039 dz = dz0 *
TVIRT(t, h2o);
6041 t = theta / pow(1000. / p, 0.286);
6045 &h2o_env, ci, cw, 0);
6046 dcape = 1e3 *
G0 * (
TVIRT(t, h2o) -
TVIRT(t_env, h2o_env)) /
6047 TVIRT(t_env, h2o_env) * dz;
6049 met->
cin[ix][iy] += fabsf((
float) dcape);
6050 }
while (p > met->
plcl[ix][iy]);
6055 p = met->
plcl[ix][iy];
6056 t = theta / pow(1000. / p, 0.286);
6059 dz = dz0 *
TVIRT(t, h2o);
6062 double psat =
PSAT(t);
6063 h2o = psat / (p - (1. -
EPS) * psat);
6067 &h2o_env, ci, cw, 0);
6068 double dcape_old = dcape;
6069 dcape = 1e3 *
G0 * (
TVIRT(t, h2o) -
TVIRT(t_env, h2o_env)) /
6070 TVIRT(t_env, h2o_env) * dz;
6072 met->
cape[ix][iy] += (float) dcape;
6073 if (!isfinite(met->
plfc[ix][iy]))
6074 met->
plfc[ix][iy] = (
float) p;
6075 }
else if (dcape_old > 0)
6076 met->
pel[ix][iy] = (float) p;
6077 if (dcape < 0 && !isfinite(met->
plfc[ix][iy]))
6078 met->
cin[ix][iy] += fabsf((
float) dcape);
6082 if (!isfinite(met->
plfc[ix][iy]))
6083 met->
cin[ix][iy] = NAN;
6094 LOG(2,
"Calculate cloud data...");
6097 const double ccmin = 0.01, cwmin = 1e-6;
6100#pragma omp parallel for default(shared) collapse(2)
6101 for (
int ix = 0; ix < met->
nx; ix++)
6102 for (
int iy = 0; iy < met->
ny; iy++) {
6105 met->
pct[ix][iy] = NAN;
6106 met->
pcb[ix][iy] = NAN;
6107 met->
cl[ix][iy] = 0;
6110 for (
int ip = 0; ip < met->
np - 1; ip++) {
6113 if (met->
p[ip] > met->
ps[ix][iy] || met->
p[ip] <
P(20.))
6117 if (met->
cc[ix][iy][ip] > ccmin
6118 && (met->
iwc[ix][iy][ip] > cwmin
6119 || met->
rwc[ix][iy][ip] > cwmin
6120 || met->
lwc[ix][iy][ip] > cwmin
6121 || met->
swc[ix][iy][ip] > cwmin)) {
6125 = (float) (0.5 * (met->
p[ip] + (
float) met->
p[ip + 1]));
6128 if (!isfinite(met->
pcb[ix][iy]))
6130 = (
float) (0.5 * (met->
p[ip] + met->
p[
MAX(ip - 1, 0)]));
6134 met->
cl[ix][iy] += (float)
6135 (0.5 * (met->
lwc[ix][iy][ip] + met->
lwc[ix][iy][ip + 1]
6136 + met->
rwc[ix][iy][ip] + met->
rwc[ix][iy][ip + 1]
6137 + met->
iwc[ix][iy][ip] + met->
iwc[ix][iy][ip + 1]
6138 + met->
swc[ix][iy][ip] + met->
swc[ix][iy][ip + 1])
6139 * 100. * (met->
p[ip] - met->
p[ip + 1]) /
G0);
6157 SELECT_TIMER(
"READ_MET_DETREND",
"METPROC", NVTX_READ);
6158 LOG(2,
"Detrend meteo data...");
6165 const double tssq = 2. *
SQR(sigma);
6168 int sy = (int) (3. *
DY2DEG(sigma) / fabs(met->
lat[1] - met->
lat[0]));
6172#pragma omp parallel for default(shared) collapse(2)
6173 for (
int ix = 0; ix < met->
nx; ix++) {
6174 for (
int iy = 0; iy < met->
ny; iy++) {
6182 (int) (3. *
DX2DEG(sigma, met->
lat[iy]) /
6183 fabs(met->
lon[1] - met->
lon[0]));
6188 for (
int ip = 0; ip < met->
np; ip++) {
6189 help->
t[ix][iy][ip] = 0;
6190 help->
u[ix][iy][ip] = 0;
6191 help->
v[ix][iy][ip] = 0;
6192 help->
w[ix][iy][ip] = 0;
6196 for (
int ix2 = ix - sx; ix2 <= ix + sx; ix2++) {
6200 else if (ix3 >= met->
nx)
6202 for (
int iy2 =
MAX(iy - sy, 0);
6203 iy2 <=
MIN(iy + sy, met->
ny - 1); iy2++) {
6210 const float w = (float) exp(-
DIST2(x0, x1) / tssq);
6214 for (
int ip = 0; ip < met->
np; ip++) {
6215 help->
t[ix][iy][ip] += w * met->
t[ix3][iy2][ip];
6216 help->
u[ix][iy][ip] += w * met->
u[ix3][iy2][ip];
6217 help->
v[ix][iy][ip] += w * met->
v[ix3][iy2][ip];
6218 help->
w[ix][iy][ip] += w * met->
w[ix3][iy2][ip];
6224 for (
int ip = 0; ip < met->
np; ip++) {
6225 help->
t[ix][iy][ip] /= wsum;
6226 help->
u[ix][iy][ip] /= wsum;
6227 help->
v[ix][iy][ip] /= wsum;
6228 help->
w[ix][iy][ip] /= wsum;
6234#pragma omp parallel for default(shared) collapse(3)
6235 for (
int ix = 0; ix < met->
nx; ix++)
6236 for (
int iy = 0; iy < met->
ny; iy++)
6237 for (
int ip = 0; ip < met->
np; ip++) {
6238 met->
t[ix][iy][ip] -= help->
t[ix][iy][ip];
6239 met->
u[ix][iy][ip] -= help->
u[ix][iy][ip];
6240 met->
v[ix][iy][ip] -= help->
v[ix][iy][ip];
6241 met->
w[ix][iy][ip] -= help->
w[ix][iy][ip];
6254 SELECT_TIMER(
"READ_MET_EXTRAPOLATE",
"METPROC", NVTX_READ);
6255 LOG(2,
"Extrapolate meteo data...");
6258#pragma omp parallel for default(shared) collapse(2)
6259 for (
int ix = 0; ix < met->
nx; ix++)
6260 for (
int iy = 0; iy < met->
ny; iy++) {
6264 for (ip0 = met->
np - 1; ip0 >= 0; ip0--)
6265 if (!isfinite(met->
t[ix][iy][ip0])
6266 || !isfinite(met->
u[ix][iy][ip0])
6267 || !isfinite(met->
v[ix][iy][ip0])
6268 || !isfinite(met->
w[ix][iy][ip0]))
6272 for (
int ip = ip0; ip >= 0; ip--) {
6273 met->
t[ix][iy][ip] = met->
t[ix][iy][ip + 1];
6274 met->
u[ix][iy][ip] = met->
u[ix][iy][ip + 1];
6275 met->
v[ix][iy][ip] = met->
v[ix][iy][ip + 1];
6276 met->
w[ix][iy][ip] = met->
w[ix][iy][ip + 1];
6277 met->
h2o[ix][iy][ip] = met->
h2o[ix][iy][ip + 1];
6278 met->
o3[ix][iy][ip] = met->
o3[ix][iy][ip + 1];
6279 met->
lwc[ix][iy][ip] = met->
lwc[ix][iy][ip + 1];
6280 met->
rwc[ix][iy][ip] = met->
rwc[ix][iy][ip + 1];
6281 met->
iwc[ix][iy][ip] = met->
iwc[ix][iy][ip + 1];
6282 met->
swc[ix][iy][ip] = met->
swc[ix][iy][ip + 1];
6283 met->
cc[ix][iy][ip] = met->
cc[ix][iy][ip + 1];
6302 LOG(2,
"Calculate geopotential heights...");
6309#pragma omp parallel for default(shared)
6310 for (
int ip = 0; ip < met->
np; ip++)
6311 logp[ip] = log(met->
p[ip]);
6314#pragma omp parallel for default(shared) collapse(2)
6315 for (
int ix = 0; ix < met->
nx; ix++)
6316 for (
int iy = 0; iy < met->
ny; iy++) {
6319 const double zs = met->
zs[ix][iy];
6320 const double lnps = log(met->
ps[ix][iy]);
6324 const double ts =
LIN(met->
p[ip0], met->
t[ix][iy][ip0], met->
p[ip0 + 1],
6325 met->
t[ix][iy][ip0 + 1], met->
ps[ix][iy]);
6327 LIN(met->
p[ip0], met->
h2o[ix][iy][ip0], met->
p[ip0 + 1],
6328 met->
h2o[ix][iy][ip0 + 1], met->
ps[ix][iy]);
6331 met->
z[ix][iy][ip0 + 1]
6333 ZDIFF(lnps, ts, h2os, logp[ip0 + 1],
6334 met->
t[ix][iy][ip0 + 1], met->
h2o[ix][iy][ip0 + 1]));
6335 for (
int ip = ip0 + 2; ip < met->
np; ip++)
6337 = (
float) (met->
z[ix][iy][ip - 1] +
6338 ZDIFF(logp[ip - 1], met->
t[ix][iy][ip - 1],
6339 met->
h2o[ix][iy][ip - 1], logp[ip],
6340 met->
t[ix][iy][ip], met->
h2o[ix][iy][ip]));
6345 ZDIFF(lnps, ts, h2os, logp[ip0],
6346 met->
t[ix][iy][ip0], met->
h2o[ix][iy][ip0]));
6347 for (
int ip = ip0 - 1; ip >= 0; ip--)
6349 = (
float) (met->
z[ix][iy][ip + 1] +
6350 ZDIFF(logp[ip + 1], met->
t[ix][iy][ip + 1],
6351 met->
h2o[ix][iy][ip + 1], logp[ip],
6352 met->
t[ix][iy][ip], met->
h2o[ix][iy][ip]));
6356 if (dx == 0 || dy == 0)
6360 if (dx < 0 || dy < 0) {
6361 if (fabs(met->
lon[1] - met->
lon[0]) < 0.5) {
6371 float ws[dx + 1][dy + 1];
6372#pragma omp parallel for default(shared) collapse(2)
6373 for (
int ix = 0; ix <= dx; ix++)
6374 for (
int iy = 0; iy < dy; iy++)
6375 ws[ix][iy] = (1.0f - (
float) ix / (float) dx)
6376 * (1.0f - (float) iy / (
float) dy);
6379#pragma omp parallel for default(shared) collapse(3)
6380 for (
int ix = 0; ix < met->
nx; ix++)
6381 for (
int iy = 0; iy < met->
ny; iy++)
6382 for (
int ip = 0; ip < met->
np; ip++)
6383 help[
ARRAY_3D(ip, ix, met->
nx, iy, met->
ny)] = met->
z[ix][iy][ip];
6386#pragma omp parallel for default(shared) collapse(3)
6387 for (
int ip = 0; ip < met->
np; ip++)
6388 for (
int ix = 0; ix < met->
nx; ix++)
6389 for (
int iy = 0; iy < met->
ny; iy++) {
6390 float res = 0, wsum = 0;
6391 int iy0 =
MAX(iy - dy + 1, 0);
6392 int iy1 =
MIN(iy + dy - 1, met->
ny - 1);
6393 for (
int ix2 = ix - dx + 1; ix2 <= ix + dx - 1; ++ix2) {
6397 else if (ix3 >= met->
nx)
6399 for (
int iy2 = iy0; iy2 <= iy1; ++iy2)
6400 if (isfinite(help[
ARRAY_3D(ip, ix3, met->
nx, iy2, met->
ny)])) {
6401 float w = ws[abs(ix - ix2)][abs(iy - iy2)];
6402 res += w * help[
ARRAY_3D(ip, ix3, met->
nx, iy2, met->
ny)];
6407 met->
z[ix][iy][ip] = res / wsum;
6409 met->
z[ix][iy][ip] = NAN;
6419 const char *filename,
6424 char levname[
LEN], tstr[10];
6426 double rtime = 0, r, r2;
6428 int varid, year2, mon2, day2, hour2, min2, sec2,
6429 year, mon, day, hour, min, sec;
6435 LOG(2,
"Read meteo grid information...");
6444 jsec2time(met->
time, &year, &mon, &day, &hour, &min, &sec, &r);
6445 if (nc_inq_varid(ncid,
"time", &varid) == NC_NOERR) {
6446 NC(nc_get_var_double(ncid, varid, &rtime));
6447 if (fabs(year * 10000. + mon * 100. + day + hour / 24. - rtime) > 1.0)
6448 WARN(
"Time information in meteo file does not match filename!");
6450 WARN(
"Time information in meteo file is missing!");
6461 sprintf(tstr,
"19%.2s", &filename[strlen(filename) - 11]);
6463 sprintf(tstr,
"20%.2s", &filename[strlen(filename) - 11]);
6465 sprintf(tstr,
"%.2s", &filename[strlen(filename) - 9]);
6467 sprintf(tstr,
"%.2s", &filename[strlen(filename) - 7]);
6469 sprintf(tstr,
"%.2s", &filename[strlen(filename) - 5]);
6475 if (year < 1900 || year > 2100 || mon < 1 || mon > 12
6476 || day < 1 || day > 31 || hour < 0 || hour > 23)
6477 ERRMSG(
"Cannot read time from filename!");
6478 jsec2time(met->
time, &year2, &mon2, &day2, &hour2, &min2, &sec2, &r2);
6479 LOG(2,
"Time: %.2f (%d-%02d-%02d, %02d:%02d UTC)",
6480 met->
time, year2, mon2, day2, hour2, min2);
6484 LOG(2,
"Number of longitudes: %d", met->
nx);
6487 LOG(2,
"Number of latitudes: %d", met->
ny);
6490 sprintf(levname,
"lev");
6491 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR)
6492 sprintf(levname,
"plev");
6493 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR)
6494 sprintf(levname,
"hybrid");
6498 sprintf(levname,
"lev_2");
6499 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR) {
6500 sprintf(levname,
"plev");
6501 NC(nc_inq_dimid(ncid, levname, &dimid2));
6503 NC(nc_inq_dimlen(ncid, dimid2, &np));
6506 LOG(2,
"Number of levels: %d", met->
np);
6507 if (met->
np < 2 || met->
np >
EP)
6508 ERRMSG(
"Number of levels out of range!");
6512 LOG(2,
"Longitudes: %g, %g ... %g deg",
6515 LOG(2,
"Latitudes: %g, %g ... %g deg",
6521 for (
int ip = 0; ip < met->
np; ip++)
6523 LOG(2,
"Altitude levels: %g, %g ... %g km",
6524 Z(met->
p[0]),
Z(met->
p[1]),
Z(met->
p[met->
np - 1]));
6525 LOG(2,
"Pressure levels: %g, %g ... %g hPa",
6526 met->
p[0], met->
p[1], met->
p[met->
np - 1]);
6530 if (strcasecmp(levname,
"hybrid") == 0)
6543 LOG(2,
"Read level data...");
6546 if (!
read_met_nc_3d(ncid,
"t",
"T",
"temp",
"TEMP", ctl, met, met->
t, 1.0))
6547 ERRMSG(
"Cannot read temperature!");
6550 if (!
read_met_nc_3d(ncid,
"u",
"U", NULL, NULL, ctl, met, met->
u, 1.0))
6551 ERRMSG(
"Cannot read zonal wind!");
6552 if (!
read_met_nc_3d(ncid,
"v",
"V", NULL, NULL, ctl, met, met->
v, 1.0))
6553 ERRMSG(
"Cannot read meridional wind!");
6555 (ncid,
"w",
"W",
"omega",
"OMEGA", ctl, met, met->
w, 0.01f))
6556 WARN(
"Cannot read vertical velocity!");
6561 (ncid,
"q",
"Q",
"sh",
"SH", ctl, met, met->
h2o, (
float) (
MA /
MH2O)))
6562 WARN(
"Cannot read specific humidity!");
6565 (ncid,
"rh",
"RH", NULL, NULL, ctl, met, met->
h2o, 0.01f))
6566 WARN(
"Cannot read relative humidity!");
6567#pragma omp parallel for default(shared) collapse(2)
6568 for (
int ix = 0; ix < met->
nx; ix++)
6569 for (
int iy = 0; iy < met->
ny; iy++)
6570 for (
int ip = 0; ip < met->
np; ip++) {
6571 double pw = met->
h2o[ix][iy][ip] *
PSAT(met->
t[ix][iy][ip]);
6572 met->
h2o[ix][iy][ip] =
6573 (float) (pw / (met->
p[ip] - (1.0 -
EPS) * pw));
6579 (ncid,
"o3",
"O3", NULL, NULL, ctl, met, met->
o3, (
float) (
MA /
MO3)))
6580 WARN(
"Cannot read ozone data!");
6584 (ncid,
"clwc",
"CLWC", NULL, NULL, ctl, met, met->
lwc, 1.0))
6585 WARN(
"Cannot read cloud liquid water content!");
6587 (ncid,
"crwc",
"CRWC", NULL, NULL, ctl, met, met->
rwc, 1.0))
6588 WARN(
"Cannot read cloud rain water content!");
6590 (ncid,
"ciwc",
"CIWC", NULL, NULL, ctl, met, met->
iwc, 1.0))
6591 WARN(
"Cannot read cloud ice water content!");
6593 (ncid,
"cswc",
"CSWC", NULL, NULL, ctl, met, met->
swc, 1.0))
6594 WARN(
"Cannot read cloud snow water content!");
6596 WARN(
"Cannot read cloud cover!");
6600 (ncid,
"ZETA",
"zeta", NULL, NULL, ctl, met, met->
zetal, 1.0))
6601 WARN(
"Cannot read ZETA!");
6603 (ncid,
"ZETA_DOT_TOT",
"ZETA_DOT_clr",
"zeta_dot_clr",
6604 NULL, ctl, met, met->
zeta_dotl, 0.00001157407f))
6605 WARN(
"Cannot read ZETA_DOT!");
6609 for (
int ix = 0; ix < met->
nx; ix++)
6610 for (
int iy = 0; iy < met->
ny; iy++)
6611 for (
int ip = 0; ip < met->
np; ip++) {
6612 met->
ul[ix][iy][ip] = met->
u[ix][iy][ip];
6613 met->
vl[ix][iy][ip] = met->
v[ix][iy][ip];
6614 met->
wl[ix][iy][ip] = met->
w[ix][iy][ip];
6626 (ncid,
"pl",
"PL",
"pressure",
"PRESSURE", ctl, met, met->
pl, 0.01f))
6628 (ncid,
"press",
"PRESS", NULL, NULL, ctl, met, met->
pl, 1.0))
6629 ERRMSG(
"Cannot read pressure on model levels!");
6632 for (
int ix = 0; ix < met->
nx; ix++)
6633 for (
int iy = 0; iy < met->
ny; iy++)
6634 for (
int ip = 1; ip < met->
np; ip++)
6635 if ((met->
pl[ix][iy][0] > met->
pl[ix][iy][1]
6636 && met->
pl[ix][iy][ip - 1] <= met->
pl[ix][iy][ip])
6637 || (met->
pl[ix][iy][0] < met->
pl[ix][iy][1]
6638 && met->
pl[ix][iy][ip - 1] >= met->
pl[ix][iy][ip]))
6639 ERRMSG(
"Pressure profiles are not monotonic!");
6660 for (
int ip = 0; ip < met->
np; ip++)
6661 met->
p[ip] = ctl->
met_p[ip];
6665 for (
int ip = 1; ip < met->
np; ip++)
6666 if (met->
p[ip - 1] < met->
p[ip])
6667 ERRMSG(
"Pressure levels must be descending!");
6676 const char *varname) {
6678 double aux[
EP], p[
EP];
6682 LOG(2,
"Interpolate meteo data to pressure levels: %s", varname);
6685#pragma omp parallel for default(shared) private(aux,p) collapse(2)
6686 for (
int ix = 0; ix < met->
nx; ix++)
6687 for (
int iy = 0; iy < met->
ny; iy++) {
6690 for (
int ip = 0; ip < met->
np; ip++)
6691 p[ip] = met->
pl[ix][iy][ip];
6694 for (
int ip = 0; ip < ctl->
met_np; ip++) {
6695 double pt = ctl->
met_p[ip];
6696 if ((pt > p[0] && p[0] > p[1]) || (pt < p[0] && p[0] < p[1]))
6698 else if ((pt > p[met->
np - 1] && p[1] > p[0])
6699 || (pt < p[met->
np - 1] && p[1] < p[0]))
6700 pt = p[met->
np - 1];
6702 aux[ip] =
LIN(p[ip2], var[ix][iy][ip2],
6703 p[ip2 + 1], var[ix][iy][ip2 + 1], pt);
6707 for (
int ip = 0; ip < ctl->
met_np; ip++)
6708 var[ix][iy][ip] = (
float) aux[ip];
6718 SELECT_TIMER(
"READ_MET_MONOTONIZE",
"METPROC", NVTX_READ);
6719 LOG(2,
"Make zeta profiles monotone...");
6722#pragma omp parallel for default(shared) collapse(2)
6723 for (
int i = 0; i < met->
nx; i++)
6724 for (
int j = 0; j < met->
ny; j++) {
6727 while (k < met->npl) {
6728 if ((met->
zetal[i][j][k - 1] >= met->
zetal[i][j][k])) {
6734 while ((met->
zetal[i][j][k - 1] >=
6735 met->
zetal[i][j][k + l]) & (k + l < met->npl));
6740 (float) (met->
zetal[i][j][k + l] - met->
zetal[i][j][k - 1])
6743 for (
int m = k; m < k + l; m++) {
6744 float d = (float) (met->
hybrid[m] - met->
hybrid[k - 1]);
6745 met->
zetal[i][j][m] = s * d + met->
zetal[i][j][k - 1];
6757#pragma omp parallel for default(shared) collapse(2)
6758 for (
int i = 0; i < met->
nx; i++)
6759 for (
int j = 0; j < met->
ny; j++) {
6762 while (k < met->npl) {
6763 if ((met->
pl[i][j][k - 1] <= met->
pl[i][j][k])) {
6770 while ((met->
pl[i][j][k - 1] <= met->
pl[i][j][k + l]) & (k + l <
6775 float s = (float) (met->
pl[i][j][k + l] - met->
pl[i][j][k - 1])
6778 for (
int m = k; m < k + l; m++) {
6779 float d = (float) (met->
hybrid[m] - met->
hybrid[k - 1]);
6780 met->
pl[i][j][m] = s * d + met->
pl[i][j][k - 1];
6795 const char *filename,
6803 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
6804 WARN(
"Cannot open file!");
6868 const char *varname,
6869 const char *varname2,
6870 const char *varname3,
6871 const char *varname4,
6872 const char *varname5,
6873 const char *varname6,
6882 float offset, scalfac;
6887 if (nc_inq_varid(ncid, varname, &varid) == NC_NOERR)
6888 sprintf(varsel,
"%s", varname);
6889 else if (varname2 != NULL
6890 && nc_inq_varid(ncid, varname2, &varid) == NC_NOERR)
6891 sprintf(varsel,
"%s", varname2);
6892 else if (varname3 != NULL
6893 && nc_inq_varid(ncid, varname3, &varid) == NC_NOERR)
6894 sprintf(varsel,
"%s", varname3);
6895 else if (varname4 != NULL
6896 && nc_inq_varid(ncid, varname4, &varid) == NC_NOERR)
6897 sprintf(varsel,
"%s", varname4);
6898 else if (varname5 != NULL
6899 && nc_inq_varid(ncid, varname5, &varid) == NC_NOERR)
6900 sprintf(varsel,
"%s", varname5);
6901 else if (varname6 != NULL
6902 && nc_inq_varid(ncid, varname6, &varid) == NC_NOERR)
6903 sprintf(varsel,
"%s", varname6);
6909 && nc_get_att_float(ncid, varid,
"add_offset", &offset) == NC_NOERR
6910 && nc_get_att_float(ncid, varid,
"scale_factor",
6911 &scalfac) == NC_NOERR) {
6919 short fillval, missval;
6920 if (nc_get_att_short(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
6922 if (nc_get_att_short(ncid, varid,
"missing_value", &missval) != NC_NOERR)
6926 LOG(2,
"Read 2-D variable: %s"
6927 " (FILL = %d, MISS = %d, SCALE = %g, OFFSET = %g)",
6928 varsel, fillval, missval, scalfac, offset);
6931 NC(nc_get_var_short(ncid, varid, help));
6935 ERRMSG(
"Meteo data layout not implemented for packed netCDF files!");
6938#pragma omp parallel for default(shared) num_threads(12)
6939 for (
int ix = 0; ix < met->
nx; ix++)
6940 for (
int iy = 0; iy < met->
ny; iy++) {
6943 const short aux = help[
ARRAY_2D(iy, ix, met->
nx)];
6944 if ((fillval == 0 || aux != fillval)
6945 && (missval == 0 || aux != missval)
6946 && fabsf(aux * scalfac + offset) < 1e14f)
6947 dest[ix][iy] += scl * (aux * scalfac + offset);
6965 float fillval, missval;
6966 if (nc_get_att_float(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
6968 if (nc_get_att_float(ncid, varid,
"missing_value", &missval) != NC_NOERR)
6972 LOG(2,
"Read 2-D variable: %s (FILL = %g, MISS = %g)",
6973 varsel, fillval, missval);
6976 NC(nc_get_var_float(ncid, varid, help));
6982#pragma omp parallel for default(shared) num_threads(12)
6983 for (
int ix = 0; ix < met->
nx; ix++)
6984 for (
int iy = 0; iy < met->
ny; iy++) {
6987 const float aux = help[
ARRAY_2D(iy, ix, met->
nx)];
6988 if ((fillval == 0 || aux != fillval)
6989 && (missval == 0 || aux != missval)
6990 && fabsf(aux) < 1e14f)
6991 dest[ix][iy] += scl * aux;
6999#pragma omp parallel for default(shared) num_threads(12)
7000 for (
int iy = 0; iy < met->
ny; iy++)
7001 for (
int ix = 0; ix < met->
nx; ix++) {
7004 const float aux = help[
ARRAY_2D(ix, iy, met->
ny)];
7005 if ((fillval == 0 || aux != fillval)
7006 && (missval == 0 || aux != missval)
7007 && fabsf(aux) < 1e14f)
7008 dest[ix][iy] += scl * aux;
7026 const char *varname,
7027 const char *varname2,
7028 const char *varname3,
7029 const char *varname4,
7037 float offset, scalfac;
7042 if (nc_inq_varid(ncid, varname, &varid) == NC_NOERR)
7043 sprintf(varsel,
"%s", varname);
7044 else if (varname2 != NULL
7045 && nc_inq_varid(ncid, varname2, &varid) == NC_NOERR)
7046 sprintf(varsel,
"%s", varname2);
7047 else if (varname3 != NULL
7048 && nc_inq_varid(ncid, varname3, &varid) == NC_NOERR)
7049 sprintf(varsel,
"%s", varname3);
7050 else if (varname4 != NULL
7051 && nc_inq_varid(ncid, varname4, &varid) == NC_NOERR)
7052 sprintf(varsel,
"%s", varname4);
7058 && nc_get_att_float(ncid, varid,
"add_offset", &offset) == NC_NOERR
7059 && nc_get_att_float(ncid, varid,
"scale_factor",
7060 &scalfac) == NC_NOERR) {
7068 short fillval, missval;
7069 if (nc_get_att_short(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
7071 if (nc_get_att_short(ncid, varid,
"missing_value", &missval) != NC_NOERR)
7075 LOG(2,
"Read 3-D variable: %s "
7076 "(FILL = %d, MISS = %d, SCALE = %g, OFFSET = %g)",
7077 varsel, fillval, missval, scalfac, offset);
7080 NC(nc_get_var_short(ncid, varid, help));
7084 ERRMSG(
"Meteo data layout not implemented for packed netCDF files!");
7087#pragma omp parallel for default(shared) num_threads(12)
7088 for (
int ix = 0; ix < met->
nx; ix++)
7089 for (
int iy = 0; iy < met->
ny; iy++)
7090 for (
int ip = 0; ip < met->
np; ip++) {
7091 const short aux = help[
ARRAY_3D(ip, iy, met->
ny, ix, met->
nx)];
7092 if ((fillval == 0 || aux != fillval)
7093 && (missval == 0 || aux != missval)
7094 && fabsf(aux * scalfac + offset) < 1e14f)
7095 dest[ix][iy][ip] = scl * (aux * scalfac + offset);
7097 dest[ix][iy][ip] = NAN;
7113 float fillval, missval;
7114 if (nc_get_att_float(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
7116 if (nc_get_att_float(ncid, varid,
"missing_value", &missval) != NC_NOERR)
7120 LOG(2,
"Read 3-D variable: %s (FILL = %g, MISS = %g)",
7121 varsel, fillval, missval);
7124 NC(nc_get_var_float(ncid, varid, help));
7130#pragma omp parallel for default(shared) num_threads(12)
7131 for (
int ix = 0; ix < met->
nx; ix++)
7132 for (
int iy = 0; iy < met->
ny; iy++)
7133 for (
int ip = 0; ip < met->
np; ip++) {
7134 const float aux = help[
ARRAY_3D(ip, iy, met->
ny, ix, met->
nx)];
7135 if ((fillval == 0 || aux != fillval)
7136 && (missval == 0 || aux != missval)
7137 && fabsf(aux) < 1e14f)
7138 dest[ix][iy][ip] = scl * aux;
7140 dest[ix][iy][ip] = NAN;
7146#pragma omp parallel for default(shared) num_threads(12)
7147 for (
int ip = 0; ip < met->
np; ip++)
7148 for (
int iy = 0; iy < met->
ny; iy++)
7149 for (
int ix = 0; ix < met->
nx; ix++) {
7150 const float aux = help[
ARRAY_3D(ix, iy, met->
ny, ip, met->
np)];
7151 if ((fillval == 0 || aux != fillval)
7152 && (missval == 0 || aux != missval)
7153 && fabsf(aux) < 1e14f)
7154 dest[ix][iy][ip] = scl * aux;
7156 dest[ix][iy][ip] = NAN;
7176 LOG(2,
"Calculate planetary boundary layer...");
7182#pragma omp parallel for default(shared) collapse(2)
7183 for (
int ix = 0; ix < met->
nx; ix++)
7184 for (
int iy = 0; iy < met->
ny; iy++) {
7187 const float z = met->
zs[ix][iy] + met->
pbl[ix][iy];
7190 (float) (
LIN(met->
z[ix][iy][ip], met->
p[ip],
7191 met->
z[ix][iy][ip + 1], met->
p[ip + 1], z));
7200 const double rib_crit = 0.25, dz = 0.05, umin = 5.0;
7203#pragma omp parallel for default(shared) collapse(2)
7204 for (
int ix = 0; ix < met->
nx; ix++)
7205 for (
int iy = 0; iy < met->
ny; iy++) {
7208 const double pbl_bot = met->
ps[ix][iy] +
DZ2DP(dz, met->
ps[ix][iy]);
7212 for (ip = 1; ip < met->
np; ip++)
7213 if (met->
p[ip] < pbl_bot)
7217 const double zs =
LIN(met->
p[ip - 1], met->
z[ix][iy][ip - 1],
7218 met->
p[ip], met->
z[ix][iy][ip], pbl_bot);
7219 const double ts =
LIN(met->
p[ip - 1], met->
t[ix][iy][ip - 1],
7220 met->
p[ip], met->
t[ix][iy][ip], pbl_bot);
7221 const double us =
LIN(met->
p[ip - 1], met->
u[ix][iy][ip - 1],
7222 met->
p[ip], met->
u[ix][iy][ip], pbl_bot);
7223 const double vs =
LIN(met->
p[ip - 1], met->
v[ix][iy][ip - 1],
7224 met->
p[ip], met->
v[ix][iy][ip], pbl_bot);
7225 const double h2os =
LIN(met->
p[ip - 1], met->
h2o[ix][iy][ip - 1],
7226 met->
p[ip], met->
h2o[ix][iy][ip], pbl_bot);
7227 const double tvs =
THETAVIRT(pbl_bot, ts, h2os);
7233 for (; ip < met->
np; ip++) {
7237 =
SQR(met->
u[ix][iy][ip] - us) +
SQR(met->
v[ix][iy][ip] - vs);
7238 vh2 =
MAX(vh2,
SQR(umin));
7241 const double rib =
G0 * 1e3 * (met->
z[ix][iy][ip] - zs) / tvs
7243 met->
h2o[ix][iy][ip]) - tvs) / vh2;
7246 if (rib >= rib_crit) {
7247 met->
pbl[ix][iy] = (float) (
LIN(rib_old, met->
p[ip - 1],
7248 rib, met->
p[ip], rib_crit));
7249 if (met->
pbl[ix][iy] > pbl_bot)
7250 met->
pbl[ix][iy] = (float) pbl_bot;
7265 const double dtheta = 2.0, zmin = 0.1;
7268#pragma omp parallel for default(shared) collapse(2)
7269 for (
int ix = 0; ix < met->
nx; ix++)
7270 for (
int iy = 0; iy < met->
ny; iy++) {
7273 const double theta0 =
THETA(met->
ps[ix][iy], met->
ts[ix][iy]);
7277 for (ip = met->
np - 2; ip > 0; ip--)
7278 if (met->
p[ip] >= 300.)
7279 if (met->
p[ip] > met->
ps[ix][iy]
7280 ||
THETA(met->
p[ip], met->
t[ix][iy][ip]) <= theta0 + dtheta)
7285 = (float) (
LIN(
THETA(met->
p[ip + 1], met->
t[ix][iy][ip + 1]),
7287 THETA(met->
p[ip], met->
t[ix][iy][ip]),
7288 met->
p[ip], theta0 + dtheta));
7291 double pbl_min = met->
ps[ix][iy] +
DZ2DP(zmin, met->
ps[ix][iy]);
7292 if (met->
pbl[ix][iy] > pbl_min || met->
p[ip] > met->
ps[ix][iy])
7293 met->
pbl[ix][iy] = (float) pbl_min;
7298#pragma omp parallel for default(shared) collapse(2)
7299 for (
int ix = 0; ix < met->
nx; ix++)
7300 for (
int iy = 0; iy < met->
ny; iy++) {
7305 met->
pbl[ix][iy] =
MIN(met->
pbl[ix][iy], (
float) pbl_min);
7310 met->
pbl[ix][iy] =
MAX(met->
pbl[ix][iy], (
float) pbl_max);
7320 SELECT_TIMER(
"READ_MET_PERIODIC",
"METPROC", NVTX_READ);
7321 LOG(2,
"Apply periodic boundary conditions...");
7324 if (!(fabs(met->
lon[met->
nx - 1] - met->
lon[0]
7325 + met->
lon[1] - met->
lon[0] - 360) < 0.01))
7329 if ((++met->
nx) >=
EX)
7330 ERRMSG(
"Cannot create periodic boundary conditions!");
7336#pragma omp parallel for default(shared)
7337 for (
int iy = 0; iy < met->
ny; iy++) {
7338 met->
ps[met->
nx - 1][iy] = met->
ps[0][iy];
7339 met->
zs[met->
nx - 1][iy] = met->
zs[0][iy];
7340 met->
ts[met->
nx - 1][iy] = met->
ts[0][iy];
7341 met->
us[met->
nx - 1][iy] = met->
us[0][iy];
7342 met->
vs[met->
nx - 1][iy] = met->
vs[0][iy];
7343 met->
lsm[met->
nx - 1][iy] = met->
lsm[0][iy];
7344 met->
sst[met->
nx - 1][iy] = met->
sst[0][iy];
7345 for (
int ip = 0; ip < met->
np; ip++) {
7346 met->
t[met->
nx - 1][iy][ip] = met->
t[0][iy][ip];
7347 met->
u[met->
nx - 1][iy][ip] = met->
u[0][iy][ip];
7348 met->
v[met->
nx - 1][iy][ip] = met->
v[0][iy][ip];
7349 met->
w[met->
nx - 1][iy][ip] = met->
w[0][iy][ip];
7350 met->
h2o[met->
nx - 1][iy][ip] = met->
h2o[0][iy][ip];
7351 met->
o3[met->
nx - 1][iy][ip] = met->
o3[0][iy][ip];
7352 met->
lwc[met->
nx - 1][iy][ip] = met->
lwc[0][iy][ip];
7353 met->
rwc[met->
nx - 1][iy][ip] = met->
rwc[0][iy][ip];
7354 met->
iwc[met->
nx - 1][iy][ip] = met->
iwc[0][iy][ip];
7355 met->
swc[met->
nx - 1][iy][ip] = met->
swc[0][iy][ip];
7356 met->
cc[met->
nx - 1][iy][ip] = met->
cc[0][iy][ip];
7358 for (
int ip = 0; ip < met->
npl; ip++) {
7359 met->
ul[met->
nx - 1][iy][ip] = met->
ul[0][iy][ip];
7360 met->
vl[met->
nx - 1][iy][ip] = met->
vl[0][iy][ip];
7361 met->
wl[met->
nx - 1][iy][ip] = met->
wl[0][iy][ip];
7362 met->
pl[met->
nx - 1][iy][ip] = met->
pl[0][iy][ip];
7363 met->
zetal[met->
nx - 1][iy][ip] = met->
zetal[0][iy][ip];
7375 SELECT_TIMER(
"READ_MET_POLAR_WINDS",
"METPROC", NVTX_READ);
7376 LOG(2,
"Apply fix for polar winds...");
7379 if (fabs(met->
lat[0]) < 89.999 || fabs(met->
lat[met->
ny - 1]) < 89.999)
7383 for (
int ihem = 0; ihem < 2; ihem++) {
7386 int i89 = 1, i90 = 0, sign = 1;
7391 if (met->
lat[i90] < 0)
7395 double clon[
EX], slon[
EX];
7396#pragma omp parallel for default(shared)
7397 for (
int ix = 0; ix < met->
nx; ix++) {
7398 clon[ix] = cos(sign *
DEG2RAD(met->
lon[ix]));
7399 slon[ix] = sin(sign *
DEG2RAD(met->
lon[ix]));
7403#pragma omp parallel for default(shared)
7404 for (
int ip = 0; ip < met->
np; ip++) {
7407 double vel89x = 0, vel89y = 0;
7408 for (
int ix = 0; ix < met->
nx; ix++) {
7410 (met->
u[ix][i89][ip] * clon[ix] -
7411 met->
v[ix][i89][ip] * slon[ix]) / met->
nx;
7413 (met->
u[ix][i89][ip] * slon[ix] +
7414 met->
v[ix][i89][ip] * clon[ix]) / met->
nx;
7418 for (
int ix = 0; ix < met->
nx; ix++) {
7420 = (float) (vel89x * clon[ix] + vel89y * slon[ix]);
7422 = (float) (-vel89x * slon[ix] + vel89y * clon[ix]);
7437 LOG(2,
"Calculate potential vorticity...");
7440#pragma omp parallel for default(shared)
7441 for (
int ip = 0; ip < met->
np; ip++)
7442 pows[ip] = pow(1000. / met->
p[ip], 0.286);
7445#pragma omp parallel for default(shared)
7446 for (
int ix = 0; ix < met->
nx; ix++) {
7449 const int ix0 =
MAX(ix - 1, 0);
7450 const int ix1 =
MIN(ix + 1, met->
nx - 1);
7453 for (
int iy = 0; iy < met->
ny; iy++) {
7456 const int iy0 =
MAX(iy - 1, 0);
7457 const int iy1 =
MIN(iy + 1, met->
ny - 1);
7460 const double latr = 0.5 * (met->
lat[iy1] + met->
lat[iy0]);
7461 const double dx = 1000. *
DEG2DX(met->
lon[ix1] - met->
lon[ix0], latr);
7462 const double dy = 1000. *
DEG2DY(met->
lat[iy1] - met->
lat[iy0]);
7463 const double c0 = cos(
DEG2RAD(met->
lat[iy0]));
7464 const double c1 = cos(
DEG2RAD(met->
lat[iy1]));
7465 const double cr = cos(
DEG2RAD(latr));
7466 const double vort = 2 * 7.2921e-5 * sin(
DEG2RAD(latr));
7469 for (
int ip = 0; ip < met->
np; ip++) {
7473 = (met->
t[ix1][iy][ip] - met->
t[ix0][iy][ip]) * pows[ip] / dx;
7474 const double dvdx = (met->
v[ix1][iy][ip] - met->
v[ix0][iy][ip]) / dx;
7478 = (met->
t[ix][iy1][ip] - met->
t[ix][iy0][ip]) * pows[ip] / dy;
7480 = (met->
u[ix][iy1][ip] * c1 - met->
u[ix][iy0][ip] * c0) / dy;
7483 const int ip0 =
MAX(ip - 1, 0);
7484 const int ip1 =
MIN(ip + 1, met->
np - 1);
7487 double dtdp, dudp, dvdp;
7488 const double dp0 = 100. * (met->
p[ip] - met->
p[ip0]);
7489 const double dp1 = 100. * (met->
p[ip1] - met->
p[ip]);
7490 if (ip != ip0 && ip != ip1) {
7491 double denom = dp0 * dp1 * (dp0 + dp1);
7492 dtdp = (dp0 * dp0 * met->
t[ix][iy][ip1] * pows[ip1]
7493 - dp1 * dp1 * met->
t[ix][iy][ip0] * pows[ip0]
7494 + (dp1 * dp1 - dp0 * dp0) * met->
t[ix][iy][ip] * pows[ip])
7496 dudp = (dp0 * dp0 * met->
u[ix][iy][ip1]
7497 - dp1 * dp1 * met->
u[ix][iy][ip0]
7498 + (dp1 * dp1 - dp0 * dp0) * met->
u[ix][iy][ip])
7500 dvdp = (dp0 * dp0 * met->
v[ix][iy][ip1]
7501 - dp1 * dp1 * met->
v[ix][iy][ip0]
7502 + (dp1 * dp1 - dp0 * dp0) * met->
v[ix][iy][ip])
7505 const double denom = dp0 + dp1;
7507 (met->
t[ix][iy][ip1] * pows[ip1] -
7508 met->
t[ix][iy][ip0] * pows[ip0]) / denom;
7509 dudp = (met->
u[ix][iy][ip1] - met->
u[ix][iy][ip0]) / denom;
7510 dvdp = (met->
v[ix][iy][ip1] - met->
v[ix][iy][ip0]) / denom;
7514 met->
pv[ix][iy][ip] = (float)
7516 (-dtdp * (dvdx - dudy / cr + vort) + dvdp * dtdx - dudp * dtdy));
7522#pragma omp parallel for default(shared)
7523 for (
int ix = 0; ix < met->
nx; ix++)
7524 for (
int ip = 0; ip < met->
np; ip++) {
7526 = met->
pv[ix][1][ip]
7527 = met->
pv[ix][2][ip];
7528 met->
pv[ix][met->
ny - 1][ip]
7529 = met->
pv[ix][met->
ny - 2][ip]
7530 = met->
pv[ix][met->
ny - 3][ip];
7541 LOG(2,
"Calculate total column ozone...");
7544#pragma omp parallel for default(shared) collapse(2)
7545 for (
int ix = 0; ix < met->
nx; ix++)
7546 for (
int iy = 0; iy < met->
ny; iy++) {
7550 for (
int ip = 1; ip < met->
np; ip++)
7551 if (met->
p[ip - 1] <= met->
ps[ix][iy]) {
7553 0.5 * (met->
o3[ix][iy][ip - 1] + met->
o3[ix][iy][ip]);
7554 const double dp = met->
p[ip - 1] - met->
p[ip];
7555 cd += vmr *
MO3 /
MA * dp * 1e2 /
G0;
7559 met->
o3c[ix][iy] = (float) (cd / 2.1415e-5);
7578 LOG(2,
"Downsampling of meteo data...");
7587 memcpy(help->
lon, met->
lon,
sizeof(met->
lon));
7588 memcpy(help->
lat, met->
lat,
sizeof(met->
lat));
7589 memcpy(help->
p, met->
p,
sizeof(met->
p));
7592 for (
int ix = 0; ix < met->
nx; ix += ctl->
met_dx) {
7593 for (
int iy = 0; iy < met->
ny; iy += ctl->
met_dy) {
7594 for (
int ip = 0; ip < met->
np; ip += ctl->
met_dp) {
7595 help->
ps[ix][iy] = 0;
7596 help->
zs[ix][iy] = 0;
7597 help->
ts[ix][iy] = 0;
7598 help->
us[ix][iy] = 0;
7599 help->
vs[ix][iy] = 0;
7600 help->
lsm[ix][iy] = 0;
7601 help->
sst[ix][iy] = 0;
7602 help->
t[ix][iy][ip] = 0;
7603 help->
u[ix][iy][ip] = 0;
7604 help->
v[ix][iy][ip] = 0;
7605 help->
w[ix][iy][ip] = 0;
7606 help->
h2o[ix][iy][ip] = 0;
7607 help->
o3[ix][iy][ip] = 0;
7608 help->
lwc[ix][iy][ip] = 0;
7609 help->
rwc[ix][iy][ip] = 0;
7610 help->
iwc[ix][iy][ip] = 0;
7611 help->
swc[ix][iy][ip] = 0;
7612 help->
cc[ix][iy][ip] = 0;
7614 for (
int ix2 = ix - ctl->
met_sx + 1; ix2 <= ix + ctl->met_sx - 1;
7619 else if (ix3 >= met->
nx)
7622 for (
int iy2 =
MAX(iy - ctl->
met_sy + 1, 0);
7623 iy2 <=
MIN(iy + ctl->
met_sy - 1, met->
ny - 1); iy2++)
7624 for (
int ip2 =
MAX(ip - ctl->
met_sp + 1, 0);
7625 ip2 <=
MIN(ip + ctl->
met_sp - 1, met->
np - 1); ip2++) {
7626 float w = (1.0f - (float) abs(ix - ix2) / (float) ctl->
met_sx)
7627 * (1.0f - (float) abs(iy - iy2) / (float) ctl->
met_sy)
7628 * (1.0f - (float) abs(ip - ip2) / (float) ctl->
met_sp);
7629 help->
ps[ix][iy] += w * met->
ps[ix3][iy2];
7630 help->
zs[ix][iy] += w * met->
zs[ix3][iy2];
7631 help->
ts[ix][iy] += w * met->
ts[ix3][iy2];
7632 help->
us[ix][iy] += w * met->
us[ix3][iy2];
7633 help->
vs[ix][iy] += w * met->
vs[ix3][iy2];
7634 help->
lsm[ix][iy] += w * met->
lsm[ix3][iy2];
7635 help->
sst[ix][iy] += w * met->
sst[ix3][iy2];
7636 help->
t[ix][iy][ip] += w * met->
t[ix3][iy2][ip2];
7637 help->
u[ix][iy][ip] += w * met->
u[ix3][iy2][ip2];
7638 help->
v[ix][iy][ip] += w * met->
v[ix3][iy2][ip2];
7639 help->
w[ix][iy][ip] += w * met->
w[ix3][iy2][ip2];
7640 help->
h2o[ix][iy][ip] += w * met->
h2o[ix3][iy2][ip2];
7641 help->
o3[ix][iy][ip] += w * met->
o3[ix3][iy2][ip2];
7642 help->
lwc[ix][iy][ip] += w * met->
lwc[ix3][iy2][ip2];
7643 help->
rwc[ix][iy][ip] += w * met->
rwc[ix3][iy2][ip2];
7644 help->
iwc[ix][iy][ip] += w * met->
iwc[ix3][iy2][ip2];
7645 help->
swc[ix][iy][ip] += w * met->
swc[ix3][iy2][ip2];
7646 help->
cc[ix][iy][ip] += w * met->
cc[ix3][iy2][ip2];
7650 help->
ps[ix][iy] /= wsum;
7651 help->
zs[ix][iy] /= wsum;
7652 help->
ts[ix][iy] /= wsum;
7653 help->
us[ix][iy] /= wsum;
7654 help->
vs[ix][iy] /= wsum;
7655 help->
lsm[ix][iy] /= wsum;
7656 help->
sst[ix][iy] /= wsum;
7657 help->
t[ix][iy][ip] /= wsum;
7658 help->
u[ix][iy][ip] /= wsum;
7659 help->
v[ix][iy][ip] /= wsum;
7660 help->
w[ix][iy][ip] /= wsum;
7661 help->
h2o[ix][iy][ip] /= wsum;
7662 help->
o3[ix][iy][ip] /= wsum;
7663 help->
lwc[ix][iy][ip] /= wsum;
7664 help->
rwc[ix][iy][ip] /= wsum;
7665 help->
iwc[ix][iy][ip] /= wsum;
7666 help->
swc[ix][iy][ip] /= wsum;
7667 help->
cc[ix][iy][ip] /= wsum;
7674 for (
int ix = 0; ix < help->
nx; ix += ctl->
met_dx) {
7677 for (
int iy = 0; iy < help->
ny; iy += ctl->
met_dy) {
7679 met->
ps[met->
nx][met->
ny] = help->
ps[ix][iy];
7680 met->
zs[met->
nx][met->
ny] = help->
zs[ix][iy];
7681 met->
ts[met->
nx][met->
ny] = help->
ts[ix][iy];
7682 met->
us[met->
nx][met->
ny] = help->
us[ix][iy];
7683 met->
vs[met->
nx][met->
ny] = help->
vs[ix][iy];
7684 met->
lsm[met->
nx][met->
ny] = help->
lsm[ix][iy];
7685 met->
sst[met->
nx][met->
ny] = help->
sst[ix][iy];
7687 for (
int ip = 0; ip < help->
np; ip += ctl->
met_dp) {
7688 met->
p[met->
np] = help->
p[ip];
7689 met->
t[met->
nx][met->
ny][met->
np] = help->
t[ix][iy][ip];
7690 met->
u[met->
nx][met->
ny][met->
np] = help->
u[ix][iy][ip];
7691 met->
v[met->
nx][met->
ny][met->
np] = help->
v[ix][iy][ip];
7692 met->
w[met->
nx][met->
ny][met->
np] = help->
w[ix][iy][ip];
7693 met->
h2o[met->
nx][met->
ny][met->
np] = help->
h2o[ix][iy][ip];
7694 met->
o3[met->
nx][met->
ny][met->
np] = help->
o3[ix][iy][ip];
7695 met->
lwc[met->
nx][met->
ny][met->
np] = help->
lwc[ix][iy][ip];
7696 met->
rwc[met->
nx][met->
ny][met->
np] = help->
rwc[ix][iy][ip];
7697 met->
iwc[met->
nx][met->
ny][met->
np] = help->
iwc[ix][iy][ip];
7698 met->
swc[met->
nx][met->
ny][met->
np] = help->
swc[ix][iy][ip];
7699 met->
cc[met->
nx][met->
ny][met->
np] = help->
cc[ix][iy][ip];
7720 LOG(2,
"Read surface data...");
7724 (ncid,
"lnsp",
"LNSP", NULL, NULL, NULL, NULL, ctl, met, met->
ps, 1.0f,
7726 for (
int ix = 0; ix < met->
nx; ix++)
7727 for (
int iy = 0; iy < met->
ny; iy++)
7728 met->
ps[ix][iy] = (
float) (exp(met->
ps[ix][iy]) / 100.);
7731 (ncid,
"ps",
"PS",
"sp",
"SP", NULL, NULL, ctl, met, met->
ps, 0.01f,
7733 WARN(
"Cannot not read surface pressure data (use lowest level)!");
7734 for (
int ix = 0; ix < met->
nx; ix++)
7735 for (
int iy = 0; iy < met->
ny; iy++)
7736 met->
ps[ix][iy] = (
float) met->
p[0];
7744 (ncid,
"z",
"Z", NULL, NULL, NULL, NULL, ctl, met, met->
zs,
7745 (
float) (1. / (1000. *
G0)), 1))
7747 (ncid,
"zm",
"ZM", NULL, NULL, NULL, NULL, ctl, met, met->
zs,
7748 (
float) (1. / 1000.), 1))
7749 WARN(
"Cannot read surface geopotential height!");
7760 memcpy(help, met->
pl,
sizeof(met->
pl));
7762 (ncid,
"gph",
"GPH", NULL, NULL, ctl, met, met->
pl,
7763 (
float) (1e-3 /
G0)))
7764 ERRMSG(
"Cannot read geopotential height!");
7765 for (
int ix = 0; ix < met->
nx; ix++)
7766 for (
int iy = 0; iy < met->
ny; iy++)
7767 met->
zs[ix][iy] = met->
pl[ix][iy][0];
7768 memcpy(met->
pl, help,
sizeof(met->
pl));
7774 (ncid,
"t2m",
"T2M",
"2t",
"2T",
"t2",
"T2", ctl, met, met->
ts, 1.0, 1))
7775 WARN(
"Cannot read surface temperature!");
7779 (ncid,
"u10m",
"U10M",
"10u",
"10U",
"u10",
"U10", ctl, met, met->
us,
7781 WARN(
"Cannot read surface zonal wind!");
7785 (ncid,
"v10m",
"V10M",
"10v",
"10V",
"v10",
"V10", ctl, met, met->
vs,
7787 WARN(
"Cannot read surface meridional wind!");
7791 (ncid,
"lsm",
"LSM", NULL, NULL, NULL, NULL, ctl, met, met->
lsm, 1.0,
7793 WARN(
"Cannot read land-sea mask!");
7797 (ncid,
"sstk",
"SSTK",
"sst",
"SST", NULL, NULL, ctl, met, met->
sst,
7799 WARN(
"Cannot read sea surface temperature!");
7804 (ncid,
"cape",
"CAPE", NULL, NULL, NULL, NULL, ctl, met, met->
cape,
7806 WARN(
"Cannot read CAPE!");
7811 (ncid,
"cin",
"CIN", NULL, NULL, NULL, NULL, ctl, met, met->
cin,
7813 WARN(
"Cannot read convective inhibition!");
7818 (ncid,
"blh",
"BLH", NULL, NULL, NULL, NULL, ctl, met, met->
pbl,
7820 ERRMSG(
"Cannot read planetary boundary layer!");
7830 double p2[200], pv[
EP], pv2[200], t[
EP], t2[200], th[
EP],
7831 th2[200], z[
EP], z2[200];
7835 LOG(2,
"Calculate tropopause...");
7838#pragma omp parallel for default(shared)
7839 for (
int iz = 0; iz < met->
np; iz++)
7840 z[iz] =
Z(met->
p[iz]);
7841#pragma omp parallel for default(shared)
7842 for (
int iz = 0; iz <= 190; iz++) {
7843 z2[iz] = 4.5 + 0.1 * iz;
7849#pragma omp parallel for default(shared) collapse(2)
7850 for (
int ix = 0; ix < met->
nx; ix++)
7851 for (
int iy = 0; iy < met->
ny; iy++)
7852 met->
pt[ix][iy] = NAN;
7856#pragma omp parallel for default(shared) collapse(2)
7857 for (
int ix = 0; ix < met->
nx; ix++)
7858 for (
int iy = 0; iy < met->
ny; iy++)
7866#pragma omp parallel for default(shared) private(t,t2) collapse(2)
7867 for (
int ix = 0; ix < met->
nx; ix++)
7868 for (
int iy = 0; iy < met->
ny; iy++) {
7871 for (
int iz = 0; iz < met->
np; iz++)
7872 t[iz] = met->
t[ix][iy][iz];
7876 int iz = (int) gsl_stats_min_index(t2, 1, 171);
7877 if (iz > 0 && iz < 170)
7878 met->
pt[ix][iy] = (float) p2[iz];
7880 met->
pt[ix][iy] = NAN;
7888#pragma omp parallel for default(shared) private(t,t2) collapse(2)
7889 for (
int ix = 0; ix < met->
nx; ix++)
7890 for (
int iy = 0; iy < met->
ny; iy++) {
7894 for (iz = 0; iz < met->
np; iz++)
7895 t[iz] = met->
t[ix][iy][iz];
7899 met->
pt[ix][iy] = NAN;
7900 for (iz = 0; iz <= 170; iz++) {
7902 for (
int iz2 = iz + 1; iz2 <= iz + 20; iz2++)
7903 if (
LAPSE(p2[iz], t2[iz], p2[iz2], t2[iz2]) > 2.0) {
7908 if (iz > 0 && iz < 170)
7909 met->
pt[ix][iy] = (float) p2[iz];
7916 met->
pt[ix][iy] = NAN;
7917 for (; iz <= 170; iz++) {
7919 for (
int iz2 = iz + 1; iz2 <= iz + 10; iz2++)
7920 if (
LAPSE(p2[iz], t2[iz], p2[iz2], t2[iz2]) < 3.0) {
7927 for (; iz <= 170; iz++) {
7929 for (
int iz2 = iz + 1; iz2 <= iz + 20; iz2++)
7930 if (
LAPSE(p2[iz], t2[iz], p2[iz2], t2[iz2]) > 2.0) {
7935 if (iz > 0 && iz < 170)
7936 met->
pt[ix][iy] = (float) p2[iz];
7948#pragma omp parallel for default(shared) private(pv,pv2,th,th2) collapse(2)
7949 for (
int ix = 0; ix < met->
nx; ix++)
7950 for (
int iy = 0; iy < met->
ny; iy++) {
7953 for (
int iz = 0; iz < met->
np; iz++)
7954 pv[iz] = met->
pv[ix][iy][iz];
7958 for (
int iz = 0; iz < met->
np; iz++)
7959 th[iz] =
THETA(met->
p[iz], met->
t[ix][iy][iz]);
7963 met->
pt[ix][iy] = NAN;
7964 for (
int iz = 0; iz <= 170; iz++)
7967 if (iz > 0 && iz < 170)
7968 met->
pt[ix][iy] = (float) p2[iz];
7975 ERRMSG(
"Cannot calculate tropopause!");
7978#pragma omp parallel for default(shared) collapse(2)
7979 for (
int ix = 0; ix < met->
nx; ix++)
7980 for (
int iy = 0; iy < met->
ny; iy++) {
7981 double h2ot, tt, zt;
7984 met->
lat[iy], &tt, ci, cw, 1);
7986 met->
lat[iy], &zt, ci, cw, 0);
7988 met->
lat[iy], &h2ot, ci, cw, 0);
7989 met->
tt[ix][iy] = (float) tt;
7990 met->
zt[ix][iy] = (float) zt;
7991 met->
h2ot[ix][iy] = (float) h2ot;
7998 const char *filename,
8008 LOG(1,
"Read observation data: %s", filename);
8012 read_obs_asc(filename, rt, rz, rlon, rlat, robs, nobs);
8014 read_obs_nc(filename, rt, rz, rlon, rlat, robs, nobs);
8016 ERRMSG(
"Set OBS_TYPE to 0 or 1!");
8019 for (
int i = 1; i < *nobs; i++)
8020 if (rt[i] < rt[i - 1])
8021 ERRMSG(
"Time must be ascending!");
8026 LOG(2,
"Number of observations: %d", *nobs);
8027 gsl_stats_minmax(&mini, &maxi, rt, 1, (
size_t) n);
8028 LOG(2,
"Time range: %.2f ... %.2f s", mini, maxi);
8029 gsl_stats_minmax(&mini, &maxi, rz, 1, (
size_t) n);
8030 LOG(2,
"Altitude range: %g ... %g km", mini, maxi);
8031 gsl_stats_minmax(&mini, &maxi, rlon, 1, (
size_t) n);
8032 LOG(2,
"Longitude range: %g ... %g deg", mini, maxi);
8033 gsl_stats_minmax(&mini, &maxi, rlat, 1, (
size_t) n);
8034 LOG(2,
"Latitude range: %g ... %g deg", mini, maxi);
8035 gsl_stats_minmax(&mini, &maxi, robs, 1, (
size_t) n);
8036 LOG(2,
"Observation range: %g ... %g", mini, maxi);
8042 const char *filename,
8052 if (!(in = fopen(filename,
"r")))
8053 ERRMSG(
"Cannot open file!");
8057 while (fgets(line,
LEN, in))
8058 if (sscanf(line,
"%lg %lg %lg %lg %lg", &rt[*nobs], &rz[*nobs],
8059 &rlon[*nobs], &rlat[*nobs], &robs[*nobs]) == 5)
8060 if ((++(*nobs)) >=
NOBS)
8061 ERRMSG(
"Too many observations!");
8070 const char *filename,
8081 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR)
8082 ERRMSG(
"Cannot open file!");
8099 const char *filename,
8102 const char *varname,
8104 const char *defvalue,
8109 char fullname1[
LEN], fullname2[
LEN], rval[
LEN];
8114 if (filename[strlen(filename) - 1] !=
'-')
8115 if (!(in = fopen(filename,
"r")))
8116 ERRMSG(
"Cannot open file!");
8120 sprintf(fullname1,
"%s[%d]", varname, arridx);
8121 sprintf(fullname2,
"%s[*]", varname);
8123 sprintf(fullname1,
"%s", varname);
8124 sprintf(fullname2,
"%s", varname);
8129 char dummy[
LEN], line[
LEN], rvarname[
LEN];
8130 while (fgets(line,
LEN, in)) {
8131 if (sscanf(line,
"%4999s %4999s %4999s", rvarname, dummy, rval) == 3)
8132 if (strcasecmp(rvarname, fullname1) == 0 ||
8133 strcasecmp(rvarname, fullname2) == 0) {
8139 for (i = 1; i < argc - 1; i++)
8140 if (strcasecmp(argv[i], fullname1) == 0 ||
8141 strcasecmp(argv[i], fullname2) == 0) {
8142 sprintf(rval,
"%s", argv[i + 1]);
8153 if (strlen(defvalue) > 0)
8154 sprintf(rval,
"%s", defvalue);
8156 ERRMSG(
"Missing variable %s!\n", fullname1);
8160 LOG(1,
"%s = %s", fullname1, rval);
8164 sprintf(value,
"%s", rval);
8174 const double rhop) {
8177 const double rp_help = rp * 1e-6;
8180 const double rho =
RHO(p, T);
8183 const double eta = 1.8325e-5 * (416.16 / (T + 120.)) * pow(T / 296.16, 1.5);
8186 const double v = sqrt(8. *
KB * T / (M_PI * 4.8096e-26));
8189 const double lambda = 2. * eta / (rho * v);
8192 const double K = lambda / rp_help;
8195 const double G = 1. + K * (1.249 + 0.42 * exp(-0.87 / K));
8198 return 2. *
SQR(rp_help) * (rhop - rho) *
G0 / (9. * eta) * G;
8216 gsl_interp_accel *acc;
8218 acc = gsl_interp_accel_alloc();
8219 s = gsl_spline_alloc(gsl_interp_cspline, (
size_t) n);
8222 gsl_spline_init(s, x, y, (
size_t) n);
8223 for (
int i = 0; i < n2; i++)
8226 else if (x2[i] >= x[n - 1])
8229 y2[i] = gsl_spline_eval(s, x2[i], acc);
8233 gsl_interp_accel_free(acc);
8238 for (
int i = 0; i < n2; i++)
8241 else if (x2[i] >= x[n - 1])
8245 y2[i] =
LIN(x[idx], y[idx], x[idx + 1], y[idx + 1], x2[i]);
8259 float mean = 0, var = 0;
8261 for (
int i = 0; i < n; ++i) {
8263 var +=
SQR(data[i]);
8266 var = var / (float) n -
SQR(mean / (
float) n);
8268 return (var > 0 ? sqrtf(var) : 0);
8279 const double D = sec / 86400 - 0.5;
8282 const double g =
DEG2RAD(357.529 + 0.98560028 * D);
8283 const double q = 280.459 + 0.98564736 * D;
8284 const double L =
DEG2RAD(q + 1.915 * sin(g) + 0.020 * sin(2 * g));
8287 const double e =
DEG2RAD(23.439 - 0.00000036 * D);
8290 const double sindec = sin(e) * sin(L);
8293 const double ra = atan2(cos(e) * sin(L), cos(L));
8296 const double GMST = 18.697374558 + 24.06570982441908 * D;
8299 const double LST = GMST + lon / 15;
8302 const double h = LST / 12 * M_PI - ra;
8305 const double lat_help =
DEG2RAD(lat);
8308 return acos(sin(lat_help) * sindec +
8309 cos(lat_help) * sqrt(1 -
SQR(sindec)) * cos(h));
8321 const double remain,
8333 t1.tm_year = year - 1900;
8334 t1.tm_mon = mon - 1;
8340 *jsec = (double) timegm(&t1) - (double) timegm(&t0) + remain;
8355 static int iname = -1, igroup = -1, nname, ngroup, ct_name[
NTIMER];
8358 t1 = omp_get_wtime();
8363 rt_name[iname] += dt;
8364 rt_min[iname] = (ct_name[iname] <= 0 ? dt :
MIN(rt_min[iname], dt));
8365 rt_max[iname] = (ct_name[iname] <= 0 ? dt :
MAX(rt_max[iname], dt));
8369 rt_group[igroup] += t1 - t0;
8373 for (
int i = 0; i < nname; i++)
8374 LOG(1,
"TIMER_%s = %.3f s (min= %g s, mean= %g s,"
8375 " max= %g s, n= %d)", names[i], rt_name[i], rt_min[i],
8376 rt_name[i] / ct_name[i], rt_max[i], ct_name[i]);
8377 for (
int i = 0; i < ngroup; i++)
8378 LOG(1,
"TIMER_GROUP_%s = %.3f s", groups[i], rt_group[i]);
8380 for (
int i = 0; i < nname; i++)
8381 total += rt_name[i];
8382 LOG(1,
"TIMER_TOTAL = %.3f s", total);
8386 for (iname = 0; iname < nname; iname++)
8387 if (strcasecmp(name, names[iname]) == 0)
8389 for (igroup = 0; igroup < ngroup; igroup++)
8390 if (strcasecmp(group, groups[igroup]) == 0)
8394 if (iname >= nname) {
8395 sprintf(names[iname],
"%s", name);
8397 ERRMSG(
"Too many timers!");
8401 if (igroup >= ngroup) {
8402 sprintf(groups[igroup],
"%s", group);
8403 if ((++ngroup) >=
NTIMER)
8404 ERRMSG(
"Too many groups!");
8414 const char *filename,
8422 int len = (int) strlen(filename);
8423 sprintf(tstr,
"%.4s", &filename[len - offset]);
8424 int year = atoi(tstr);
8425 sprintf(tstr,
"%.2s", &filename[len - offset + 5]);
8426 int mon = atoi(tstr);
8427 sprintf(tstr,
"%.2s", &filename[len - offset + 8]);
8428 int day = atoi(tstr);
8429 sprintf(tstr,
"%.2s", &filename[len - offset + 11]);
8430 int hour = atoi(tstr);
8431 sprintf(tstr,
"%.2s", &filename[len - offset + 14]);
8432 int min = atoi(tstr);
8435 if (year < 1900 || year > 2100 || mon < 1 || mon > 12 || day < 1
8436 || day > 31 || hour < 0 || hour > 23 || min < 0 || min > 59)
8437 ERRMSG(
"Cannot read time from filename!");
8440 time2jsec(year, mon, day, hour, min, 0, 0.0, &t);
8458 const double p1 = pt * 0.866877899;
8459 const double p0 = pt / 0.866877899;
8467 return LIN(p0, 1.0, p1, 0.0, p);
8473 const char *filename,
8482 LOG(1,
"Write atmospheric data: %s", filename);
8506 ERRMSG(
"Atmospheric data type not supported!");
8510 LOG(2,
"Number of particles: %d", atm->
np);
8511 gsl_stats_minmax(&mini, &maxi, atm->
time, 1, (
size_t) atm->
np);
8512 LOG(2,
"Time range: %.2f ... %.2f s", mini, maxi);
8513 gsl_stats_minmax(&mini, &maxi, atm->
p, 1, (
size_t) atm->
np);
8514 LOG(2,
"Altitude range: %g ... %g km",
Z(maxi),
Z(mini));
8515 LOG(2,
"Pressure range: %g ... %g hPa", maxi, mini);
8516 gsl_stats_minmax(&mini, &maxi, atm->
lon, 1, (
size_t) atm->
np);
8517 LOG(2,
"Longitude range: %g ... %g deg", mini, maxi);
8518 gsl_stats_minmax(&mini, &maxi, atm->
lat, 1, (
size_t) atm->
np);
8519 LOG(2,
"Latitude range: %g ... %g deg", mini, maxi);
8520 for (
int iq = 0; iq < ctl->
nq; iq++) {
8522 sprintf(msg,
"Quantity %s range: %s ... %s %s",
8525 gsl_stats_minmax(&mini, &maxi, atm->
q[iq], 1, (
size_t) atm->
np);
8526 LOG(2, msg, mini, maxi);
8533 const char *filename,
8541 const double t0 = t - 0.5 * ctl->
dt_mod;
8542 const double t1 = t + 0.5 * ctl->
dt_mod;
8548 if (!(out = popen(
"gnuplot",
"w")))
8549 ERRMSG(
"Cannot create pipe to gnuplot!");
8552 fprintf(out,
"set out \"%s.png\"\n", filename);
8556 int year, mon, day, hour, min, sec;
8557 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
8558 fprintf(out,
"timestr=\"%d-%02d-%02d, %02d:%02d UTC\"\n",
8559 year, mon, day, hour, min);
8564 ERRMSG(
"Cannot open file!");
8566 while (fgets(line,
LEN, in))
8567 fprintf(out,
"%s", line);
8574 if (!(out = fopen(filename,
"w")))
8575 ERRMSG(
"Cannot create file!");
8581 "# $2 = altitude [km]\n"
8582 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
8583 for (
int iq = 0; iq < ctl->
nq; iq++)
8584 fprintf(out,
"# $%i = %s [%s]\n", iq + 5, ctl->
qnt_name[iq],
8589 for (
int ip = 0; ip < atm->
np; ip += ctl->
atm_stride) {
8596 fprintf(out,
"%.2f %g %g %g", atm->
time[ip],
Z(atm->
p[ip]),
8597 atm->
lon[ip], atm->
lat[ip]);
8598 for (
int iq = 0; iq < ctl->
nq; iq++) {
8603 fprintf(out, ctl->
qnt_format[iq], atm->
q[iq][ip]);
8615 const char *filename,
8622 if (!(out = fopen(filename,
"w")))
8623 ERRMSG(
"Cannot create file!");
8647 for (
int iq = 0; iq < ctl->
nq; iq++)
8665 const char *filename,
8669 int tid, pid, ncid, varid;
8670 size_t start[2], count[2];
8673 nc_create(filename, NC_NETCDF4, &ncid);
8676 NC(nc_def_dim(ncid,
"time", 1, &tid));
8677 NC(nc_def_dim(ncid,
"NPARTS", (
size_t) atm->
np, &pid));
8680 int dim_ids[2] = { tid, pid };
8681 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"Time",
8682 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
8683 NC_DEF_VAR(
"LAT", NC_DOUBLE, 1, &pid,
"Latitude",
"deg",
8685 NC_DEF_VAR(
"LON", NC_DOUBLE, 1, &pid,
"Longitude",
"deg",
8687 NC_DEF_VAR(
"PRESS", NC_DOUBLE, 1, &pid,
"Pressure",
"hPa",
8690 for (
int iq = 0; iq < ctl->
nq; iq++)
8700 NC(nc_enddef(ncid));
8708 for (
int iq = 0; iq < ctl->
nq; iq++)
8718 const char *dirname,
8724 static size_t out_cnt = 0;
8726 double r, r_start, r_stop;
8727 int year, mon, day, hour, min, sec;
8728 int year_start, mon_start, day_start, hour_start, min_start, sec_start;
8729 int year_stop, mon_stop, day_stop, hour_stop, min_stop, sec_stop;
8730 char filename_out[2 *
LEN] =
"traj_fix_3d_YYYYMMDDHH_YYYYMMDDHH.nc";
8732 int ncid, varid, tid, pid, cid;
8740 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
8742 &min_start, &sec_start, &r_start);
8744 &min_stop, &sec_stop, &r_stop);
8746 sprintf(filename_out,
"%s/traj_fix_3d_%02d%02d%02d%02d_%02d%02d%02d%02d.nc",
8748 year_start % 100, mon_start, day_start, hour_start,
8749 year_stop % 100, mon_stop, day_stop, hour_stop);
8750 LOG(1,
"Write traj file: %s", filename_out);
8756 count[1] = (size_t) atm->
np;
8762 nc_create(filename_out, NC_NETCDF4, &ncid);
8765 NC(nc_def_dim(ncid,
"time", NC_UNLIMITED, &tid));
8766 NC(nc_def_dim(ncid,
"NPARTS", (
size_t) atm->
np, &pid));
8767 NC(nc_def_dim(ncid,
"TMDT", 7, &cid));
8772 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"Time",
8773 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
8774 NC_DEF_VAR(
"LAT", NC_DOUBLE, 2, dim_ids,
"Latitude",
"deg",
8776 NC_DEF_VAR(
"LON", NC_DOUBLE, 2, dim_ids,
"Longitude",
"deg",
8778 NC_DEF_VAR(
"PRESS", NC_DOUBLE, 2, dim_ids,
"Pressure",
"hPa",
8780 NC_DEF_VAR(
"ZETA", NC_DOUBLE, 2, dim_ids,
"Zeta",
"K",
8782 for (
int iq = 0; iq < ctl->
nq; iq++)
8792 NC(nc_enddef(ncid));
8800 NC(nc_open(filename_out, NC_WRITE, &ncid));
8812 for (
int iq = 0; iq < ctl->
nq; iq++)
8819 if ((year == year_stop) && (mon == mon_stop)
8820 && (day == day_stop) && (hour == hour_stop)) {
8823 char filename_init[2 *
LEN] =
"./init_fix_YYYYMMDDHH.nc";
8824 sprintf(filename_init,
"%s/init_fix_%02d%02d%02d%02d.nc",
8825 dirname, year_stop % 100, mon_stop, day_stop, hour_stop);
8826 LOG(1,
"Write init file: %s", filename_init);
8829 nc_create(filename_init, NC_NETCDF4, &ncid);
8832 NC(nc_def_dim(ncid,
"time", 1, &tid));
8833 NC(nc_def_dim(ncid,
"NPARTS", (
size_t) atm->
np, &pid));
8838 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"Time",
8839 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
8840 NC_DEF_VAR(
"LAT", NC_DOUBLE, 1, &pid,
"Latitude",
"deg",
8842 NC_DEF_VAR(
"LON", NC_DOUBLE, 1, &pid,
"Longitude",
"deg",
8844 NC_DEF_VAR(
"PRESS", NC_DOUBLE, 1, &pid,
"Pressure",
"hPa",
8847 for (
int iq = 0; iq < ctl->
nq; iq++)
8857 NC(nc_enddef(ncid));
8865 for (
int iq = 0; iq < ctl->
nq; iq++)
8876 const char *filename,
8880 int ncid, obsid, varid;
8882 size_t start[2], count[2];
8885 NC(nc_create(filename, NC_NETCDF4, &ncid));
8888 NC(nc_def_dim(ncid,
"obs", (
size_t) atm->
np, &obsid));
8891 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &obsid,
"time",
8892 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
8893 NC_DEF_VAR(
"press", NC_DOUBLE, 1, &obsid,
"pressure",
"hPa",
8895 NC_DEF_VAR(
"lon", NC_DOUBLE, 1, &obsid,
"longitude",
"degrees_east",
8897 NC_DEF_VAR(
"lat", NC_DOUBLE, 1, &obsid,
"latitude",
"degrees_north",
8899 for (
int iq = 0; iq < ctl->
nq; iq++)
8908 NC(nc_enddef(ncid));
8915 for (
int iq = 0; iq < ctl->
nq; iq++)
8925 const char *filename,
8932 static double *modmean, *obsmean, *obsstd, *rt, *rz, *rlon, *rlat, *robs,
8935 static int *obscount,
ct, cx, cy, cz, ip, ix, iy, iz, n, nobs, nk;
8945 ERRMSG(
"Need quantity mass!");
8969 LOG(1,
"Write CSI data: %s", filename);
8970 if (!(out = fopen(filename,
"w")))
8971 ERRMSG(
"Cannot create file!");
8976 "# $2 = number of hits (cx)\n"
8977 "# $3 = number of misses (cy)\n"
8978 "# $4 = number of false alarms (cz)\n"
8979 "# $5 = number of observations (cx + cy)\n"
8980 "# $6 = number of forecasts (cx + cz)\n"
8981 "# $7 = bias (ratio of forecasts and observations) [%%]\n"
8982 "# $8 = probability of detection (POD) [%%]\n"
8983 "# $9 = false alarm rate (FAR) [%%]\n"
8984 "# $10 = critical success index (CSI) [%%]\n");
8986 "# $11 = hits associated with random chance\n"
8987 "# $12 = equitable threat score (ETS) [%%]\n"
8988 "# $13 = Pearson linear correlation coefficient\n"
8989 "# $14 = Spearman rank-order correlation coefficient\n"
8990 "# $15 = column density mean error (F - O) [kg/m^2]\n"
8991 "# $16 = column density root mean square error (RMSE) [kg/m^2]\n"
8992 "# $17 = column density mean absolute error [kg/m^2]\n"
8993 "# $18 = log-likelihood function\n"
8994 "# $19 = number of data points\n\n");
9002 for (iy = 0; iy < ctl->
csi_ny; iy++) {
9003 const double lat = ctl->
csi_lat0 + dlat * (iy + 0.5);
9004 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat));
9009 const double t0 = t - 0.5 * ctl->
dt_mod;
9010 const double t1 = t + 0.5 * ctl->
dt_mod;
9013 ALLOC(modmean,
double,
9015 ALLOC(obsmean,
double,
9017 ALLOC(obscount,
int,
9019 ALLOC(obsstd,
double,
9023 for (
int i = 0; i < nobs; i++) {
9028 else if (rt[i] >= t1)
9032 if (!isfinite(robs[i]))
9036 ix = (int) ((rlon[i] - ctl->
csi_lon0) / dlon);
9037 iy = (int) ((rlat[i] - ctl->
csi_lat0) / dlat);
9038 iz = (int) ((rz[i] - ctl->
csi_z0) / dz);
9041 if (ix < 0 || ix >= ctl->
csi_nx ||
9042 iy < 0 || iy >= ctl->
csi_ny || iz < 0 || iz >= ctl->
csi_nz)
9047 obsmean[idx] += robs[i];
9048 obsstd[idx] +=
SQR(robs[i]);
9053 for (ip = 0; ip < atm->
np; ip++) {
9056 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
9060 ix = (int) ((atm->
lon[ip] - ctl->
csi_lon0) / dlon);
9061 iy = (int) ((atm->
lat[ip] - ctl->
csi_lat0) / dlat);
9062 iz = (int) ((
Z(atm->
p[ip]) - ctl->
csi_z0) / dz);
9065 if (ix < 0 || ix >= ctl->
csi_nx ||
9066 iy < 0 || iy >= ctl->
csi_ny || iz < 0 || iz >= ctl->
csi_nz)
9072 * atm->
q[ctl->
qnt_m][ip];
9076 for (ix = 0; ix < ctl->
csi_nx; ix++)
9077 for (iy = 0; iy < ctl->
csi_ny; iy++)
9078 for (iz = 0; iz < ctl->
csi_nz; iz++) {
9082 if (obscount[idx] > 0) {
9083 obsmean[idx] /= obscount[idx];
9084 obsstd[idx] -=
SQR(obsmean[idx]);
9085 obsstd[idx] = sqrt(obsstd[idx]);
9089 if (modmean[idx] > 0)
9090 modmean[idx] /= (1e6 * area[iy]);
9093 if (obscount[idx] > 0) {
9107 if (obscount[idx] > 0
9110 x[n] = modmean[idx];
9111 y[n] = obsmean[idx];
9113 obsstdn[n] = obsstd[idx];
9115 ERRMSG(
"Too many data points to calculate statistics!");
9124 static double work[2 *
NCSI], work2[2 *
NCSI];;
9125 const int n_obs = cx + cy;
9126 const int n_for = cx + cz;
9127 const double bias = (n_obs > 0) ? 100. * n_for / n_obs : NAN;
9128 const double pod = (n_obs > 0) ? (100. * cx) / n_obs : NAN;
9129 const double far = (n_for > 0) ? (100. * cz) / n_for : NAN;
9131 (cx + cy + cz > 0) ? (100. * cx) / (cx + cy + cz) : NAN;
9132 const double cx_rd = (
ct > 0) ? (1. * n_obs * n_for) /
ct : NAN;
9133 const double ets = (cx + cy + cz - cx_rd > 0) ?
9134 (100. * (cx - cx_rd)) / (cx + cy + cz - cx_rd) : NAN;
9135 const double rho_p =
9136 (n > 0) ? gsl_stats_correlation(x, 1, y, 1, (
size_t) n) : NAN;
9137 const double rho_s =
9138 (n > 0) ? gsl_stats_spearman(x, 1, y, 1, (
size_t) n, work) : NAN;
9139 for (
int i = 0; i < n; i++) {
9140 work[i] = x[i] - y[i];
9141 work2[i] = (obsstdn[i] != 0) ? (x[i] - y[i]) / obsstdn[i] : 0;
9143 const double mean = (n > 0) ? gsl_stats_mean(work, 1, (
size_t) n) : NAN;
9145 (n > 0) ? gsl_stats_sd_with_fixed_mean(work, 1, (
size_t) n,
9147 const double absdev =
9148 (n > 0) ? gsl_stats_absdev_m(work, 1, (
size_t) n, 0.0) : NAN;
9149 const double loglikelihood =
9150 (n > 0) ? gsl_stats_tss(work2, 1, (
size_t) n) * (-0.5) : GSL_NAN;
9154 "%.2f %d %d %d %d %d %g %g %g %g %g %g %g %g %g %g %g %g %d\n", t,
9155 cx, cy, cz, n_obs, n_for, bias, pod, far, csi, cx_rd, ets, rho_p,
9156 rho_s, mean, rmse, absdev, loglikelihood, n);
9159 n =
ct = cx = cy = cz = 0;
9187 const char *filename,
9204 ERRMSG(
"Missing ensemble IDs!");
9207 const double t0 = t - 0.5 * ctl->
dt_mod;
9208 const double t1 = t + 0.5 * ctl->
dt_mod;
9211 for (
int i = 0; i <
NENS; i++) {
9212 for (
int iq = 0; iq < ctl->
nq; iq++)
9213 qm[iq][i] = qs[iq][i] = 0;
9214 xm[i][0] = xm[i][1] = xm[i][2] = zm[i] = 0;
9219 for (
int ip = 0; ip < atm->
np; ip++) {
9222 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
9227 ERRMSG(
"Ensemble ID is out of range!");
9231 for (
int iq = 0; iq < ctl->
nq; iq++) {
9232 qm[iq][ctl->
qnt_ens] += atm->
q[iq][ip];
9243 LOG(1,
"Write ensemble data: %s", filename);
9244 if (!(out = fopen(filename,
"w")))
9245 ERRMSG(
"Cannot create file!");
9250 "# $2 = altitude [km]\n"
9251 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
9252 for (
int iq = 0; iq < ctl->
nq; iq++)
9253 fprintf(out,
"# $%d = %s (mean) [%s]\n", 5 + iq,
9255 for (
int iq = 0; iq < ctl->
nq; iq++)
9256 fprintf(out,
"# $%d = %s (sigma) [%s]\n", 5 + ctl->
nq + iq,
9258 fprintf(out,
"# $%d = number of members\n\n", 5 + 2 * ctl->
nq);
9261 for (
int i = 0; i <
NENS; i++)
9263 cart2geo(xm[i], &dummy, &lon, &lat);
9264 fprintf(out,
"%.2f %g %g %g", t, zm[i] / n[i], lon, lat);
9265 for (
int iq = 0; iq < ctl->
nq; iq++) {
9267 fprintf(out, ctl->
qnt_format[iq], qm[iq][i] / n[i]);
9269 for (
int iq = 0; iq < ctl->
nq; iq++) {
9271 double var = qs[iq][i] / n[i] -
SQR(qm[iq][i] / n[i]);
9272 fprintf(out, ctl->
qnt_format[iq], (var > 0 ? sqrt(var) : 0));
9274 fprintf(out,
" %d\n", n[i]);
9284 const char *filename,
9291 static double kz[
EP], kw[
EP];
9295 double *cd, *mean[
NQ], *sigma[
NQ], *vmr_impl, *z, *lon, *lat, *area, *press;
9297 int *ixs, *iys, *izs, *np;
9303 LOG(1,
"Write grid data: %s", filename);
9316 for (
int iq = 0; iq < ctl->
nq; iq++) {
9317 ALLOC(mean[iq],
double,
9319 ALLOC(sigma[iq],
double,
9322 ALLOC(vmr_impl,
double,
9332 ALLOC(press,
double,
9349#pragma omp parallel
for default(shared)
9350 for (
int iz = 0; iz < ctl->
grid_nz; iz++) {
9351 z[iz] = ctl->
grid_z0 + dz * (iz + 0.5);
9352 press[iz] =
P(z[iz]);
9356 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
9357 lon[ix] = ctl->
grid_lon0 + dlon * (ix + 0.5);
9358#pragma omp parallel for default(shared)
9359 for (
int iy = 0; iy < ctl->
grid_ny; iy++) {
9360 lat[iy] = ctl->
grid_lat0 + dlat * (iy + 0.5);
9361 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat[iy]));
9365 const double t0 = t - 0.5 * ctl->
dt_mod;
9366 const double t1 = t + 0.5 * ctl->
dt_mod;
9369#pragma omp parallel for default(shared)
9370 for (
int ip = 0; ip < atm->
np; ip++) {
9371 ixs[ip] = (int) ((atm->
lon[ip] - ctl->
grid_lon0) / dlon);
9372 iys[ip] = (int) ((atm->
lat[ip] - ctl->
grid_lat0) / dlat);
9373 izs[ip] = (int) ((
Z(atm->
p[ip]) - ctl->
grid_z0) / dz);
9374 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
9375 || ixs[ip] < 0 || ixs[ip] >= ctl->
grid_nx
9376 || iys[ip] < 0 || iys[ip] >= ctl->
grid_ny
9377 || izs[ip] < 0 || izs[ip] >= ctl->
grid_nz)
9382 for (
int ip = 0; ip < atm->
np; ip++)
9388 for (
int iq = 0; iq < ctl->
nq; iq++) {
9389 mean[iq][idx] += kernel * atm->
q[iq][ip];
9390 sigma[iq][idx] +=
SQR(kernel * atm->
q[iq][ip]);
9395#pragma omp parallel for default(shared)
9396 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
9397 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
9398 for (
int iz = 0; iz < ctl->
grid_nz; iz++) {
9405 if (ctl->
qnt_m >= 0)
9406 cd[idx] = mean[ctl->
qnt_m][idx] / (1e6 * area[iy]);
9409 vmr_impl[idx] = NAN;
9410 if (ctl->
qnt_m >= 0 && ctl->
molmass > 0 && met0 != NULL
9413 if (mean[ctl->
qnt_m][idx] > 0) {
9419 lon[ix], lat[iy], &temp, ci, cw, 1);
9423 / (
RHO(press[iz], temp) * 1e6 * area[iy] * 1e3 * dz);
9429 for (
int iq = 0; iq < ctl->
nq; iq++) {
9430 mean[iq][idx] /= np[idx];
9431 double var = sigma[iq][idx] / np[idx] -
SQR(mean[iq][idx]);
9432 sigma[iq][idx] = (var > 0 ? sqrt(var) : 0);
9434 for (
int iq = 0; iq < ctl->
nq; iq++) {
9435 mean[iq][idx] = NAN;
9436 sigma[iq][idx] = NAN;
9443 t, z, lon, lat, area, dz, np);
9448 t, z, lon, lat, area, dz, np);
9452 ERRMSG(
"Grid data format GRID_TYPE unknown!");
9456 for (
int iq = 0; iq < ctl->
nq; iq++) {
9475 const char *filename,
9480 const double *vmr_impl,
9495 if (!(out = popen(
"gnuplot",
"w")))
9496 ERRMSG(
"Cannot create pipe to gnuplot!");
9499 fprintf(out,
"set out \"%s.png\"\n", filename);
9503 int year, mon, day, hour, min, sec;
9504 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
9505 fprintf(out,
"timestr=\"%d-%02d-%02d, %02d:%02d UTC\"\n",
9506 year, mon, day, hour, min);
9512 ERRMSG(
"Cannot open file!");
9513 while (fgets(line,
LEN, in))
9514 fprintf(out,
"%s", line);
9521 if (!(out = fopen(filename,
"w")))
9522 ERRMSG(
"Cannot create file!");
9528 "# $2 = altitude [km]\n"
9529 "# $3 = longitude [deg]\n"
9530 "# $4 = latitude [deg]\n"
9531 "# $5 = surface area [km^2]\n"
9532 "# $6 = layer depth [km]\n"
9533 "# $7 = column density (implicit) [kg/m^2]\n"
9534 "# $8 = volume mixing ratio (implicit) [ppv]\n"
9535 "# $9 = number of particles [1]\n");
9536 for (
int iq = 0; iq < ctl->
nq; iq++)
9537 fprintf(out,
"# $%i = %s (mean) [%s]\n", 10 + iq, ctl->
qnt_name[iq],
9540 for (
int iq = 0; iq < ctl->
nq; iq++)
9541 fprintf(out,
"# $%i = %s (stddev) [%s]\n", 10 + ctl->
nq + iq,
9546 for (
int ix = 0; ix < ctl->
grid_nx; ix++) {
9549 for (
int iy = 0; iy < ctl->
grid_ny; iy++) {
9552 for (
int iz = 0; iz < ctl->
grid_nz; iz++) {
9555 fprintf(out,
"%.2f %g %g %g %g %g %g %g %d", t, z[iz], lon[ix],
9556 lat[iy], area[iy], dz, cd[idx], vmr_impl[idx], np[idx]);
9557 for (
int iq = 0; iq < ctl->
nq; iq++) {
9559 fprintf(out, ctl->
qnt_format[iq], mean[iq][idx]);
9562 for (
int iq = 0; iq < ctl->
nq; iq++) {
9564 fprintf(out, ctl->
qnt_format[iq], sigma[iq][idx]);
9579 const char *filename,
9584 const double *vmr_impl,
9593 char longname[2 *
LEN], varname[2 *
LEN];
9597 int *help2, ncid, dimid[10], varid;
9599 size_t start[2], count[2];
9608 NC(nc_create(filename, NC_NETCDF4, &ncid));
9611 NC(nc_def_dim(ncid,
"time", 1, &dimid[0]));
9612 NC(nc_def_dim(ncid,
"z", (
size_t) ctl->
grid_nz, &dimid[1]));
9613 NC(nc_def_dim(ncid,
"lat", (
size_t) ctl->
grid_ny, &dimid[2]));
9614 NC(nc_def_dim(ncid,
"lon", (
size_t) ctl->
grid_nx, &dimid[3]));
9615 NC(nc_def_dim(ncid,
"dz", 1, &dimid[4]));
9618 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &dimid[0],
"time",
9619 "seconds since 2000-01-01 00:00:00 UTC", 0, 0);
9620 NC_DEF_VAR(
"z", NC_DOUBLE, 1, &dimid[1],
"altitude",
"km", 0, 0);
9621 NC_DEF_VAR(
"lat", NC_DOUBLE, 1, &dimid[2],
"latitude",
"degrees_north", 0,
9623 NC_DEF_VAR(
"lon", NC_DOUBLE, 1, &dimid[3],
"longitude",
"degrees_east", 0,
9625 NC_DEF_VAR(
"dz", NC_DOUBLE, 1, &dimid[1],
"layer depth",
"km", 0, 0);
9626 NC_DEF_VAR(
"area", NC_DOUBLE, 1, &dimid[2],
"surface area",
"km**2", 0, 0);
9628 NC_DEF_VAR(
"cd", NC_FLOAT, 4, dimid,
"column density",
"kg m**-2",
9630 NC_DEF_VAR(
"vmr_impl", NC_FLOAT, 4, dimid,
"volume mixing ratio (implicit)",
9632 NC_DEF_VAR(
"np", NC_INT, 4, dimid,
"number of particles",
"1", 0, 0);
9633 for (
int iq = 0; iq < ctl->
nq; iq++) {
9634 sprintf(varname,
"%s_mean", ctl->
qnt_name[iq]);
9639 sprintf(varname,
"%s_stddev", ctl->
qnt_name[iq]);
9640 sprintf(longname,
"%s (stddev)", ctl->
qnt_longname[iq]);
9646 NC(nc_enddef(ncid));
9656 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
9657 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
9658 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
9663 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
9664 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
9665 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
9670 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
9671 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
9672 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
9677 for (
int iq = 0; iq < ctl->
nq; iq++) {
9678 sprintf(varname,
"%s_mean", ctl->
qnt_name[iq]);
9679 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
9680 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
9681 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
9688 for (
int iq = 0; iq < ctl->
nq; iq++) {
9689 sprintf(varname,
"%s_stddev", ctl->
qnt_name[iq]);
9690 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
9691 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
9692 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
9709 const char *filename,
9717 LOG(1,
"Write meteo data: %s", filename);
9722 ERRMSG(
"MPTRAC was compiled without zfp compression!");
9726 ERRMSG(
"MPTRAC was compiled without zstd compression!");
9730 ERRMSG(
"MPTRAC was compiled without cmultiscale compression!");
9743 ERRMSG(
"MET_TYPE not implemented!");
9749 const char *filename,
9755 if (!(out = fopen(filename,
"w")))
9756 ERRMSG(
"Cannot create file!");
9849 const char *varname) {
9858 for (
int ix = 0; ix < met->
nx; ix++)
9859 for (
int iy = 0; iy < met->
ny; iy++)
9860 help[
ARRAY_2D(ix, iy, met->
ny)] = var[ix][iy];
9863 LOG(2,
"Write 2-D variable: %s (uncompressed)", varname);
9865 (
size_t) (met->
nx * met->
ny),
9879 const char *varname,
9880 const int precision,
9881 const double tolerance) {
9890#pragma omp parallel for default(shared) collapse(2)
9891 for (
int ix = 0; ix < met->
nx; ix++)
9892 for (
int iy = 0; iy < met->
ny; iy++)
9893 for (
int ip = 0; ip < met->
np; ip++)
9894 help[
ARRAY_3D(ix, iy, met->
ny, ip, met->
np)] = var[ix][iy][ip];
9898 LOG(2,
"Write 3-D variable: %s (uncompressed)", varname);
9900 (
size_t) (met->
nx * met->
ny * met->
np),
9907 (
size_t) met->
np, 0, out);
9915 FWRITE(&tolerance,
double,
9934 (
size_t) met->
np, 0, out);
9940 ERRMSG(
"MET_TYPE not supported!");
9941 LOG(3,
"%d %g", precision, tolerance);
9951 const char *filename,
9957 size_t start[4], count[4];
9958 nc_create(filename, NC_NETCDF4, &ncid);
9961 int tid, lonid, latid, levid;
9962 NC(nc_def_dim(ncid,
"time", 1, &tid));
9963 NC(nc_def_dim(ncid,
"lon", (
size_t) met->
nx, &lonid));
9964 NC(nc_def_dim(ncid,
"lat", (
size_t) met->
ny, &latid));
9965 NC(nc_def_dim(ncid,
"lev", (
size_t) met->
np, &levid));
9968 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"time",
9969 "seconds since 2000-01-01 00:00:00 UTC", 0, 0);
9970 NC_DEF_VAR(
"lon", NC_DOUBLE, 1, &lonid,
"longitude",
"degrees_east", 0, 0);
9971 NC_DEF_VAR(
"lat", NC_DOUBLE, 1, &latid,
"latitude",
"degrees_north", 0, 0);
9972 NC_DEF_VAR(
"lev", NC_DOUBLE, 1, &levid,
"pressure",
"Pa", 0, 0);
9975 int dimid2[2] = { latid, lonid };
9976 NC_DEF_VAR(
"sp", NC_FLOAT, 2, dimid2,
"Surface pressure",
"Pa",
9978 NC_DEF_VAR(
"z", NC_FLOAT, 2, dimid2,
"Geopotential",
"m**2 s**-2",
9980 NC_DEF_VAR(
"t2m", NC_FLOAT, 2, dimid2,
"2 metre temperature",
"K",
9982 NC_DEF_VAR(
"u10m", NC_FLOAT, 2, dimid2,
"10 metre U wind component",
9984 NC_DEF_VAR(
"v10m", NC_FLOAT, 2, dimid2,
"10 metre V wind component",
9986 NC_DEF_VAR(
"lsm", NC_FLOAT, 2, dimid2,
"Land/sea mask",
"-",
9988 NC_DEF_VAR(
"sstk", NC_FLOAT, 2, dimid2,
"Sea surface temperature",
"K",
9992 int dimid3[3] = { levid, latid, lonid };
9993 NC_DEF_VAR(
"t", NC_FLOAT, 3, dimid3,
"Temperature",
"K",
9995 NC_DEF_VAR(
"u", NC_FLOAT, 3, dimid3,
"U velocity",
"m s**-1",
9997 NC_DEF_VAR(
"v", NC_FLOAT, 3, dimid3,
"V velocity",
"m s**-1",
9999 NC_DEF_VAR(
"w", NC_FLOAT, 3, dimid3,
"Vertical velocity",
"Pa s**-1",
10001 NC_DEF_VAR(
"q", NC_FLOAT, 3, dimid3,
"Specific humidity",
"kg kg**-1",
10003 NC_DEF_VAR(
"o3", NC_FLOAT, 3, dimid3,
"Ozone mass mixing ratio",
10005 NC_DEF_VAR(
"clwc", NC_FLOAT, 3, dimid3,
"Cloud liquid water content",
10007 NC_DEF_VAR(
"crwc", NC_FLOAT, 3, dimid3,
"Cloud rain water content",
10009 NC_DEF_VAR(
"ciwc", NC_FLOAT, 3, dimid3,
"Cloud ice water content",
10011 NC_DEF_VAR(
"cswc", NC_FLOAT, 3, dimid3,
"Cloud snow water content",
10013 NC_DEF_VAR(
"cc", NC_FLOAT, 3, dimid3,
"Cloud cover",
"-",
10017 NC(nc_enddef(ncid));
10024 for (
int ip = 0; ip < met->
np; ip++)
10025 phelp[ip] = 100. * met->
p[ip];
10051 NC(nc_close(ncid));
10058 const char *varname,
10064 size_t start[4], count[4];
10072 for (
int ix = 0; ix < met->
nx; ix++)
10073 for (
int iy = 0; iy < met->
ny; iy++)
10074 help[
ARRAY_2D(iy, ix, met->
nx)] = scl * var[ix][iy];
10087 const char *varname,
10093 size_t start[4], count[4];
10101 for (
int ix = 0; ix < met->
nx; ix++)
10102 for (
int iy = 0; iy < met->
ny; iy++)
10103 for (
int ip = 0; ip < met->
np; ip++)
10104 help[
ARRAY_3D(ip, iy, met->
ny, ix, met->
nx)] = scl * var[ix][iy][ip];
10116 const char *dirname,
10123 char ext[10], filename[2 *
LEN];
10127 int year, mon, day, hour, min, sec;
10130 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
10141#pragma acc update host(atm[:1])
10149 sprintf(ext,
"tab");
10151 sprintf(ext,
"bin");
10153 sprintf(ext,
"nc");
10154 sprintf(filename,
"%s/%s_%04d_%02d_%02d_%02d_%02d.%s",
10155 dirname, ctl->
atm_basename, year, mon, day, hour, min, ext);
10161 sprintf(filename,
"%s/%s_%04d_%02d_%02d_%02d_%02d.%s",
10164 write_grid(filename, ctl, met0, met1, atm, t);
10169 sprintf(filename,
"%s/%s.tab", dirname, ctl->
csi_basename);
10175 sprintf(filename,
"%s/%s_%04d_%02d_%02d_%02d_%02d.tab",
10176 dirname, ctl->
ens_basename, year, mon, day, hour, min);
10182 sprintf(filename,
"%s/%s.tab", dirname, ctl->
prof_basename);
10183 write_prof(filename, ctl, met0, met1, atm, t);
10194 sprintf(filename,
"%s/%s.tab", dirname, ctl->
stat_basename);
10203 sprintf(filename,
"%s/%s_%05d.vtk", dirname, ctl->
vtk_basename, ++nvtk);
10211 const char *filename,
10220 static double *mass, *obsmean, *rt, *rz, *rlon, *rlat, *robs, *area,
10221 dz, dlon, dlat, *lon, *lat, *z, *press, temp, vmr, h2o, o3;
10223 static int nobs, *obscount, ip, okay;
10232 if (ctl->
qnt_m < 0)
10233 ERRMSG(
"Need quantity mass!");
10237 ERRMSG(
"Specify molar mass!");
10244 ALLOC(area,
double,
10248 ALLOC(press,
double,
10254 ALLOC(rlon,
double,
10256 ALLOC(rlat,
double,
10258 ALLOC(robs,
double,
10265 LOG(1,
"Write profile data: %s", filename);
10266 if (!(out = fopen(filename,
"w")))
10267 ERRMSG(
"Cannot create file!");
10271 "# $1 = time [s]\n"
10272 "# $2 = altitude [km]\n"
10273 "# $3 = longitude [deg]\n"
10274 "# $4 = latitude [deg]\n"
10275 "# $5 = pressure [hPa]\n"
10276 "# $6 = temperature [K]\n"
10277 "# $7 = volume mixing ratio [ppv]\n"
10278 "# $8 = H2O volume mixing ratio [ppv]\n"
10279 "# $9 = O3 volume mixing ratio [ppv]\n"
10280 "# $10 = observed BT index [K]\n"
10281 "# $11 = number of observations\n");
10289 for (
int iz = 0; iz < ctl->
prof_nz; iz++) {
10290 z[iz] = ctl->
prof_z0 + dz * (iz + 0.5);
10291 press[iz] =
P(z[iz]);
10295 for (
int ix = 0; ix < ctl->
prof_nx; ix++)
10296 lon[ix] = ctl->
prof_lon0 + dlon * (ix + 0.5);
10297 for (
int iy = 0; iy < ctl->
prof_ny; iy++) {
10298 lat[iy] = ctl->
prof_lat0 + dlat * (iy + 0.5);
10299 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat[iy]));
10304 const double t0 = t - 0.5 * ctl->
dt_mod;
10305 const double t1 = t + 0.5 * ctl->
dt_mod;
10308 ALLOC(mass,
double,
10310 ALLOC(obsmean,
double,
10312 ALLOC(obscount,
int,
10316 for (
int i = 0; i < nobs; i++) {
10321 else if (rt[i] >= t1)
10325 if (!isfinite(robs[i]))
10329 int ix = (int) ((rlon[i] - ctl->
prof_lon0) / dlon);
10330 int iy = (int) ((rlat[i] - ctl->
prof_lat0) / dlat);
10333 if (ix < 0 || ix >= ctl->
prof_nx || iy < 0 || iy >= ctl->
prof_ny)
10338 obsmean[idx] += robs[i];
10343 for (ip = 0; ip < atm->
np; ip++) {
10346 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
10350 int ix = (int) ((atm->
lon[ip] - ctl->
prof_lon0) / dlon);
10351 int iy = (int) ((atm->
lat[ip] - ctl->
prof_lat0) / dlat);
10352 int iz = (int) ((
Z(atm->
p[ip]) - ctl->
prof_z0) / dz);
10355 if (ix < 0 || ix >= ctl->
prof_nx ||
10361 mass[idx] += atm->
q[ctl->
qnt_m][ip];
10365 for (
int ix = 0; ix < ctl->
prof_nx; ix++)
10366 for (
int iy = 0; iy < ctl->
prof_ny; iy++) {
10368 if (obscount[idx2] > 0) {
10372 for (
int iz = 0; iz < ctl->
prof_nz; iz++) {
10374 if (mass[idx3] > 0) {
10383 fprintf(out,
"\n");
10386 for (
int iz = 0; iz < ctl->
prof_nz; iz++) {
10391 lon[ix], lat[iy], &temp, ci, cw, 1);
10393 lon[ix], lat[iy], &h2o, ci, cw, 0);
10395 lon[ix], lat[iy], &o3, ci, cw, 0);
10400 / (
RHO(press[iz], temp) * area[iy] * dz * 1e9);
10403 fprintf(out,
"%.2f %g %g %g %g %g %g %g %g %g %d\n",
10404 t, z[iz], lon[ix], lat[iy], press[iz], temp, vmr, h2o, o3,
10405 obsmean[idx2] / obscount[idx2], obscount[idx2]);
10438 const char *filename,
10447 static double area, dlat, rmax2, *rt, *rz, *rlon, *rlat, *robs, kz[
EP],
10450 static int nobs, nk;
10463 ALLOC(rlon,
double,
10465 ALLOC(rlat,
double,
10467 ALLOC(robs,
double,
10478 LOG(1,
"Write sample data: %s", filename);
10479 if (!(out = fopen(filename,
"w")))
10480 ERRMSG(
"Cannot create file!");
10484 "# $1 = time [s]\n"
10485 "# $2 = altitude [km]\n"
10486 "# $3 = longitude [deg]\n"
10487 "# $4 = latitude [deg]\n"
10488 "# $5 = surface area [km^2]\n"
10489 "# $6 = layer depth [km]\n"
10490 "# $7 = number of particles [1]\n"
10491 "# $8 = column density [kg/m^2]\n"
10492 "# $9 = volume mixing ratio [ppv]\n"
10493 "# $10 = observed BT index [K]\n\n");
10498 area = M_PI * rmax2;
10502 const double t0 = t - 0.5 * ctl->
dt_mod;
10503 const double t1 = t + 0.5 * ctl->
dt_mod;
10506 for (
int i = 0; i < nobs; i++) {
10511 else if (rt[i] >= t1)
10516 geo2cart(0, rlon[i], rlat[i], x0);
10519 const double rp =
P(rz[i]);
10528#pragma omp parallel for default(shared) reduction(+:mass,np)
10529 for (
int ip = 0; ip < atm->
np; ip++) {
10532 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
10536 if (fabs(rlat[i] - atm->
lat[ip]) > dlat)
10542 if (
DIST2(x0, x1) > rmax2)
10547 if (atm->
p[ip] > pbot || atm->
p[ip] < ptop)
10551 if (ctl->
qnt_m >= 0)
10558 const double cd = mass / (1e6 * area);
10569 rlon[i], rlat[i], &temp, ci, cw, 1);
10573 / (
RHO(rp, temp) * 1e6 * area * 1e3 * ctl->
sample_dz);
10579 fprintf(out,
"%.2f %g %g %g %g %g %d %g %g %g\n", rt[i], rz[i],
10580 rlon[i], rlat[i], area, ctl->
sample_dz, np, cd, vmr, robs[i]);
10601 const char *filename,
10608 static double rmax2, x0[3], x1[3];
10617 LOG(1,
"Write station data: %s", filename);
10620 if (!(out = fopen(filename,
"w")))
10621 ERRMSG(
"Cannot create file!");
10625 "# $1 = time [s]\n"
10626 "# $2 = altitude [km]\n"
10627 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
10628 for (
int iq = 0; iq < ctl->
nq; iq++)
10629 fprintf(out,
"# $%i = %s [%s]\n", (iq + 5),
10631 fprintf(out,
"\n");
10639 const double t0 = t - 0.5 * ctl->
dt_mod;
10640 const double t1 = t + 0.5 * ctl->
dt_mod;
10643 for (
int ip = 0; ip < atm->
np; ip++) {
10646 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
10662 if (
DIST2(x0, x1) > rmax2)
10670 fprintf(out,
"%.2f %g %g %g",
10671 atm->
time[ip],
Z(atm->
p[ip]), atm->
lon[ip], atm->
lat[ip]);
10672 for (
int iq = 0; iq < ctl->
nq; iq++) {
10674 fprintf(out, ctl->
qnt_format[iq], atm->
q[iq][ip]);
10676 fprintf(out,
"\n");
10687 const char *filename,
10698 LOG(1,
"Write VTK data: %s", filename);
10701 const double t0 = t - 0.5 * ctl->
dt_mod;
10702 const double t1 = t + 0.5 * ctl->
dt_mod;
10705 if (!(out = fopen(filename,
"w")))
10706 ERRMSG(
"Cannot create file!");
10710 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
10711 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
10718 "# vtk DataFile Version 3.0\n"
10719 "vtk output\n" "ASCII\n" "DATASET POLYDATA\n");
10722 fprintf(out,
"POINTS %d float\n", np);
10724 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
10725 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
10729 const double coslat = cos(
DEG2RAD(atm->
lat[ip]));
10730 const double x = radius * coslat * cos(
DEG2RAD(atm->
lon[ip]));
10731 const double y = radius * coslat * sin(
DEG2RAD(atm->
lon[ip]));
10732 const double z = radius * sin(
DEG2RAD(atm->
lat[ip]));
10733 fprintf(out,
"%g %g %g\n", x, y, z);
10736 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
10737 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
10739 fprintf(out,
"%g %g %g\n", atm->
lon[ip], atm->
lat[ip],
10744 fprintf(out,
"POINT_DATA %d\n", np);
10745 for (
int iq = 0; iq < ctl->
nq; iq++) {
10746 fprintf(out,
"SCALARS %s float 1\n" "LOOKUP_TABLE default\n",
10748 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
10749 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
10751 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 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.
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 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 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 module_advect(const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, const double *dt)
Performs the advection of atmospheric particles 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.
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.
void intpol_met_time_3d_ml(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)
Interpolates a meteorological variable in time and 3D space (longitude, latitude, pressure).
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) height 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.
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 module_chem_init(const ctl_t *ctl, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Initializes the chemistry modules by setting atmospheric composition.
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 module_convection(const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, const double *dt, double *rs)
Simulate convective processes for atmospheric particles.
void read_met_periodic(met_t *met)
Applies periodic boundary conditions to meteorological data along longitudinal axis.
void module_diffusion_meso(const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, cache_t *cache, const double *dt, double *rs)
Simulate mesoscale diffusion for atmospheric particles.
void module_sedi(const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, const double *dt)
Simulate sedimentation of particles in the atmosphere.
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 module_oh_chem(const ctl_t *ctl, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm, const double *dt)
Perform hydroxyl chemistry calculations for atmospheric particles.
void module_chemgrid(const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, const double tt)
Calculate grid data for chemistry modules.
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.
void module_isosurf(const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, cache_t *cache, const double *dt)
Apply the isosurface module to adjust atmospheric properties.
void module_timesteps(const ctl_t *ctl, met_t *met0, atm_t *atm, double *dt, const double t)
Calculate time steps for air parcels based on specified conditions.
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 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 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 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 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 fft_help(double *fcReal, double *fcImag, const int n)
Computes the Fast Fourier Transform (FFT) of a complex sequence.
int read_met_bin(const char *filename, ctl_t *ctl, met_t *met)
Reads meteorological data from a binary file.
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_isosurf_init(const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, cache_t *cache)
Initialize the isosurface module based on atmospheric data.
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_position(const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, const double *dt)
Update the positions and pressure levels of atmospheric particles.
void timer(const char *name, const char *group, const int output)
Measures and reports elapsed time for named and grouped timers.
void read_met_monotonize(met_t *met)
Makes zeta and pressure profiles monotone.
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 module_diffusion_turb(const ctl_t *ctl, const clim_t *clim, atm_t *atm, const double *dt, double *rs)
Simulate turbulent diffusion for atmospheric particles.
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 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_advect_init(const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm)
Initializes the advection module by setting up pressure fields.
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_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 write_met(const char *filename, const ctl_t *ctl, met_t *met)
Writes meteorological data to a file, supporting multiple formats and compression options.
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 write_met_nc(const char *filename, const ctl_t *ctl, met_t *met)
Writes meteorological data to a NetCDF file.
void module_decay(const ctl_t *ctl, const clim_t *clim, atm_t *atm, const double *dt)
Simulate exponential decay processes for atmospheric particles.
void module_rng_init(const int ntask)
Initialize random number generators for parallel tasks.
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 module_wet_deposition(const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, const double *dt)
Perform wet deposition calculations for air parcels.
void module_h2o2_chem(const ctl_t *ctl, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm, const double *dt)
Perform chemical reactions involving H2O2 within cloud particles.
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 module_meteo(const ctl_t *ctl, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm, const double *dt)
Update atmospheric properties using meteorological data.
void get_met_help(const ctl_t *ctl, const double t, const int direct, const char *metbase, const double dt_met, char *filename)
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.
void 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 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 write_met_nc_2d(int ncid, const char *varname, met_t *met, float var[EX][EY], float scl)
Writes a 2D meteorological variable to a NetCDF file.
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 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 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_bound_cond(const ctl_t *ctl, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm, const double *dt)
Apply boundary conditions to particles based on meteorological and climatological data.
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 module_tracer_chem(const ctl_t *ctl, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm, const double *dt)
Simulate chemical reactions involving long-lived atmospheric tracers.
int read_met(const char *filename, ctl_t *ctl, clim_t *clim, met_t *met)
Reads meteorological data from a file, supporting multiple formats and MPI broadcasting.
void 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_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.
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.
int read_atm_clams(const char *filename, const ctl_t *ctl, atm_t *atm)
Reads air parcel data from a CLaMS netCDF file and populates the given atmospheric structure.
int 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 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 read_met_polar_winds(met_t *met)
Applies a fix for polar winds in meteorological data.
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.
void read_clim(const ctl_t *ctl, clim_t *clim)
Reads various climatological data and populates the given climatology structure.
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.
void intpol_met_space_3d_ml(const met_t *met, float array[EX][EY][EP], const double p, const double lon, const double lat, double *var)
Interpolates a meteorological variable in 3D space (longitude, latitude, pressure).
double tropo_weight(const clim_t *clim, const double t, const double lat, const double p)
Computes the weighting factor for a given pressure with respect to the tropopause.
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 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 write_met_nc_3d(int ncid, const char *varname, met_t *met, float var[EX][EY][EP], float scl)
Writes a 3D meteorological variable to a NetCDF file.
void module_dry_deposition(const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, const double *dt)
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.
int read_met_nc(const char *filename, ctl_t *ctl, clim_t *clim, met_t *met)
Reads meteorological data from a NetCDF file and processes it.
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.
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.
#define LEN
Maximum length of ASCII data lines.
#define RE
Mean radius of Earth [km].
#define TVIRT(t, h2o)
Compute virtual temperature.
void module_kpp_chem(ctl_t *ctl, clim_t *clim, met_t *met0, met_t *met1, atm_t *atm, double *dt)
KPP chemistry module.
#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 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)
Calculate potential vorticity using the Zeta approximation.
#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.
void compress_zstd(const char *varname, float *array, const size_t n, const int decompress, FILE *inout)
Compresses or decompresses an array of floats using the Zstandard (ZSTD) library.
#define RHO(p, t)
Compute density of air.
#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 iso_ts[NP]
Isosurface balloon time [s].
int iso_n
Isosurface balloon number of data points.
double iso_ps[NP]
Isosurface balloon pressure [hPa].
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 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=Richardson, 2=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.
int conv_mix_bot
Lower level for mixing (0=particle pressure, 1=surface).
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 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,...
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_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 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 wet_depo_ic_h[3]
Coefficients for wet deposition in cloud (Henry's law: Hb, Cb, pH).
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 conv_mix_top
Upper level for mixing (0=particle pressure, 1=EL).
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].
int reflect
Reflection of particles at top and bottom boundary (0=no, 1=yes).
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.
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=pressure-level, 1=model-level).
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].
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.
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 advect_cpl_zeta_and_press_modules
Coupled use of pressure based modules and diabatic advection.
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 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 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 conv_cin
CIN threshold for convection module [J/kg].
int qnt_pv
Quantity array index for potential vorticity.
int advect_vert_coord
Vertical coordinate of air parcels (0=pressure, 1=zeta, 2=eta).
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.
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 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 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 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 [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 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].