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], 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;
955 ERRMSG(
"Too many data points!");
958 gsl_fft_complex_wavetable *wavetable =
959 gsl_fft_complex_wavetable_alloc((
size_t) n);
960 gsl_fft_complex_workspace *workspace =
961 gsl_fft_complex_workspace_alloc((
size_t) n);
964 for (
int i = 0; i < n; i++) {
965 data[2 * i] = fcReal[i];
966 data[2 * i + 1] = fcImag[i];
970 gsl_fft_complex_forward(data, 1, (
size_t) n, wavetable, workspace);
973 for (
int i = 0; i < n; i++) {
974 fcReal[i] = data[2 * i];
975 fcImag[i] = data[2 * i + 1];
979 gsl_fft_complex_wavetable_free(wavetable);
980 gsl_fft_complex_workspace_free(workspace);
991 const double radius = z +
RE;
992 const double latrad =
DEG2RAD(lat);
993 const double lonrad =
DEG2RAD(lon);
994 const double coslat = cos(latrad);
996 x[0] = radius * coslat * cos(lonrad);
997 x[1] = radius * coslat * sin(lonrad);
998 x[2] = radius * sin(latrad);
1007 const char *metbase,
1008 const double dt_met,
1015 int year, mon, day, hour, min, sec;
1019 t6 = floor(t / dt_met) * dt_met;
1021 t6 = ceil(t / dt_met) * dt_met;
1024 jsec2time(t6, &year, &mon, &day, &hour, &min, &sec, &r);
1029 sprintf(filename,
"%s_YYYY_MM_DD_HH.nc", metbase);
1031 sprintf(filename,
"%s_YYYY_MM_DD_HH.bin", metbase);
1033 sprintf(filename,
"%s_YYYY_MM_DD_HH.pck", metbase);
1035 sprintf(filename,
"%s_YYYY_MM_DD_HH.zfp", metbase);
1037 sprintf(filename,
"%s_YYYY_MM_DD_HH.zstd", metbase);
1039 sprintf(filename,
"%s_YYYY_MM_DD_HH.cms", metbase);
1040 sprintf(repl,
"%d", year);
1042 sprintf(repl,
"%02d", mon);
1044 sprintf(repl,
"%02d", day);
1046 sprintf(repl,
"%02d", hour);
1052 sprintf(filename,
"%s_YYMMDDHH.nc", metbase);
1053 sprintf(repl,
"%d", year);
1055 sprintf(repl,
"%02d", year % 100);
1057 sprintf(repl,
"%02d", mon);
1059 sprintf(repl,
"%02d", day);
1061 sprintf(repl,
"%02d", hour);
1076 for (
int i = 0; i < 3; i++) {
1080 if (!(ch = strstr(orig, search)))
1082 strncpy(buffer, orig, (
size_t) (ch - orig));
1083 buffer[ch - orig] = 0;
1084 sprintf(buffer + (ch - orig),
"%s%s", repl, ch + strlen(search));
1086 strcpy(orig, buffer);
1093 const int met_tropo,
1113#pragma omp parallel for default(shared) private(ci,cw)
1114 for (
int ix = 0; ix < nx; ix++)
1115 for (
int iy = 0; iy < ny; iy++) {
1117 &pt[iy * nx + ix], ci, cw, 1);
1119 &ps[iy * nx + ix], ci, cw, 0);
1121 &zs[iy * nx + ix], ci, cw, 0);
1123 lats[iy], &zt[iy * nx + ix], ci, cw, 1);
1125 lats[iy], &tt[iy * nx + ix], ci, cw, 0);
1127 lats[iy], &qt[iy * nx + ix], ci, cw, 0);
1129 lats[iy], &o3t[iy * nx + ix], ci, cw, 0);
1137 float heights0[
EX][
EY][
EP],
1138 float array0[
EX][
EY][
EP],
1140 float heights1[
EX][
EY][
EP],
1141 float array1[
EX][
EY][
EP],
1143 const double height,
1154 double lon2 =
FMOD(lon, 360.);
1155 if (lon2 < met0->lon[0])
1157 else if (lon2 > met0->
lon[met0->
nx - 1])
1171 int k_max = ind[0][0];
1172 for (
int i = 0; i < 2; i++)
1173 for (
int j = 0; j < 4; j++) {
1174 if (ci[2] > ind[i][j])
1176 if (k_max < ind[i][j])
1182 cw[0] = (lon2 - met0->
lon[ci[0]]) /
1183 (met0->
lon[ci[0] + 1] - met0->
lon[ci[0]]);
1184 cw[1] = (lat - met0->
lat[ci[1]]) /
1185 (met0->
lat[ci[1] + 1] - met0->
lat[ci[1]]);
1188 double height_top, height_bot;
1189 double height00, height01, height10, height11, height0, height1;
1192 height00 = cw[3] * (heights1[ci[0]][ci[1]][ci[2]]
1193 - heights0[ci[0]][ci[1]][ci[2]])
1194 + heights0[ci[0]][ci[1]][ci[2]];
1195 height01 = cw[3] * (heights1[ci[0]][ci[1] + 1][ci[2]]
1196 - heights0[ci[0]][ci[1] + 1][ci[2]])
1197 + heights0[ci[0]][ci[1] + 1][ci[2]];
1198 height10 = cw[3] * (heights1[ci[0] + 1][ci[1]][ci[2]]
1199 - heights0[ci[0] + 1][ci[1]][ci[2]])
1200 + heights0[ci[0] + 1][ci[1]][ci[2]];
1201 height11 = cw[3] * (heights1[ci[0] + 1][ci[1] + 1][ci[2]]
1202 - heights0[ci[0] + 1][ci[1] + 1][ci[2]])
1203 + heights0[ci[0] + 1][ci[1] + 1][ci[2]];
1206 height0 = cw[1] * (height01 - height00) + height00;
1207 height1 = cw[1] * (height11 - height10) + height10;
1210 height_bot = cw[0] * (height1 - height0) + height0;
1213 height00 = cw[3] * (heights1[ci[0]][ci[1]][ci[2] + 1]
1214 - heights0[ci[0]][ci[1]][ci[2] + 1])
1215 + heights0[ci[0]][ci[1]][ci[2] + 1];
1216 height01 = cw[3] * (heights1[ci[0]][ci[1] + 1][ci[2] + 1]
1217 - heights0[ci[0]][ci[1] + 1][ci[2] + 1])
1218 + heights0[ci[0]][ci[1] + 1][ci[2] + 1];
1219 height10 = cw[3] * (heights1[ci[0] + 1][ci[1]][ci[2] + 1]
1220 - heights0[ci[0] + 1][ci[1]][ci[2] + 1])
1221 + heights0[ci[0] + 1][ci[1]][ci[2] + 1];
1222 height11 = cw[3] * (heights1[ci[0] + 1][ci[1] + 1][ci[2] + 1]
1223 - heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1])
1224 + heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1];
1227 height0 = cw[1] * (height01 - height00) + height00;
1228 height1 = cw[1] * (height11 - height10) + height10;
1231 height_top = cw[0] * (height1 - height0) + height0;
1234 while (((heights0[0][0][0] > heights0[0][0][1]) &&
1235 ((height_bot <= height) || (height_top > height))
1236 && (height_bot >= height) && (ci[2] < k_max))
1238 ((heights0[0][0][0] < heights0[0][0][1]) &&
1239 ((height_bot >= height) || (height_top < height))
1240 && (height_bot <= height) && (ci[2] < k_max))
1244 height_bot = height_top;
1247 height00 = cw[3] * (heights1[ci[0]][ci[1]][ci[2] + 1]
1248 - heights0[ci[0]][ci[1]][ci[2] + 1])
1249 + heights0[ci[0]][ci[1]][ci[2] + 1];
1250 height01 = cw[3] * (heights1[ci[0]][ci[1] + 1][ci[2] + 1]
1251 - heights0[ci[0]][ci[1] + 1][ci[2] + 1])
1252 + heights0[ci[0]][ci[1] + 1][ci[2] + 1];
1253 height10 = cw[3] * (heights1[ci[0] + 1][ci[1]][ci[2] + 1]
1254 - heights0[ci[0] + 1][ci[1]][ci[2] + 1])
1255 + heights0[ci[0] + 1][ci[1]][ci[2] + 1];
1256 height11 = cw[3] * (heights1[ci[0] + 1][ci[1] + 1][ci[2] + 1]
1257 - heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1])
1258 + heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1];
1261 height0 = cw[1] * (height01 - height00) + height00;
1262 height1 = cw[1] * (height11 - height10) + height10;
1265 height_top = cw[0] * (height1 - height0) + height0;
1269 cw[2] = (height - height_bot)
1270 / (height_top - height_bot);
1274 double array000 = cw[3] * (array1[ci[0]][ci[1]][ci[2]]
1275 - array0[ci[0]][ci[1]][ci[2]])
1276 + array0[ci[0]][ci[1]][ci[2]];
1277 double array100 = cw[3] * (array1[ci[0] + 1][ci[1]][ci[2]]
1278 - array0[ci[0] + 1][ci[1]][ci[2]])
1279 + array0[ci[0] + 1][ci[1]][ci[2]];
1280 double array010 = cw[3] * (array1[ci[0]][ci[1] + 1][ci[2]]
1281 - array0[ci[0]][ci[1] + 1][ci[2]])
1282 + array0[ci[0]][ci[1] + 1][ci[2]];
1283 double array110 = cw[3] * (array1[ci[0] + 1][ci[1] + 1][ci[2]]
1284 - array0[ci[0] + 1][ci[1] + 1][ci[2]])
1285 + array0[ci[0] + 1][ci[1] + 1][ci[2]];
1286 double array001 = cw[3] * (array1[ci[0]][ci[1]][ci[2] + 1]
1287 - array0[ci[0]][ci[1]][ci[2] + 1])
1288 + array0[ci[0]][ci[1]][ci[2] + 1];
1289 double array101 = cw[3] * (array1[ci[0] + 1][ci[1]][ci[2] + 1]
1290 - array0[ci[0] + 1][ci[1]][ci[2] + 1])
1291 + array0[ci[0] + 1][ci[1]][ci[2] + 1];
1292 double array011 = cw[3] * (array1[ci[0]][ci[1] + 1][ci[2] + 1]
1293 - array0[ci[0]][ci[1] + 1][ci[2] + 1])
1294 + array0[ci[0]][ci[1] + 1][ci[2] + 1];
1295 double array111 = cw[3] * (array1[ci[0] + 1][ci[1] + 1][ci[2] + 1]
1296 - array0[ci[0] + 1][ci[1] + 1][ci[2] + 1])
1297 + array0[ci[0] + 1][ci[1] + 1][ci[2] + 1];
1299 double array00 = cw[0] * (array100 - array000) + array000;
1300 double array10 = cw[0] * (array110 - array010) + array010;
1301 double array01 = cw[0] * (array101 - array001) + array001;
1302 double array11 = cw[0] * (array111 - array011) + array011;
1304 double aux0 = cw[1] * (array10 - array00) + array00;
1305 double aux1 = cw[1] * (array11 - array01) + array01;
1308 *var = cw[2] * (aux1 - aux0) + aux0;
1328 double lon2 =
FMOD(lon, 360.);
1329 if (lon2 < met->lon[0])
1331 else if (lon2 > met->
lon[met->
nx - 1])
1340 cw[0] = (met->
p[ci[0] + 1] - p)
1341 / (met->
p[ci[0] + 1] - met->
p[ci[0]]);
1342 cw[1] = (met->
lon[ci[1] + 1] - lon2)
1343 / (met->
lon[ci[1] + 1] - met->
lon[ci[1]]);
1344 cw[2] = (met->
lat[ci[2] + 1] - lat)
1345 / (met->
lat[ci[2] + 1] - met->
lat[ci[2]]);
1350 cw[0] * (array[ci[1]][ci[2]][ci[0]] - array[ci[1]][ci[2]][ci[0] + 1])
1351 + array[ci[1]][ci[2]][ci[0] + 1];
1353 cw[0] * (array[ci[1]][ci[2] + 1][ci[0]] -
1354 array[ci[1]][ci[2] + 1][ci[0] + 1])
1355 + array[ci[1]][ci[2] + 1][ci[0] + 1];
1357 cw[0] * (array[ci[1] + 1][ci[2]][ci[0]] -
1358 array[ci[1] + 1][ci[2]][ci[0] + 1])
1359 + array[ci[1] + 1][ci[2]][ci[0] + 1];
1361 cw[0] * (array[ci[1] + 1][ci[2] + 1][ci[0]] -
1362 array[ci[1] + 1][ci[2] + 1][ci[0] + 1])
1363 + array[ci[1] + 1][ci[2] + 1][ci[0] + 1];
1366 aux00 = cw[2] * (aux00 - aux01) + aux01;
1367 aux11 = cw[2] * (aux10 - aux11) + aux11;
1368 *var = cw[1] * (aux00 - aux11) + aux11;
1383 double lon2 =
FMOD(lon, 360.);
1384 if (lon2 < met->lon[0])
1386 else if (lon2 > met->
lon[met->
nx - 1])
1396 if (z >= zs[ix][iy][iz + 1])
1397 aux00 = array[ix][iy][iz + 1];
1398 else if (z <= zs[ix][iy][iz])
1399 aux00 = array[ix][iy][iz];
1401 aux00 =
LIN(zs[ix][iy][iz], array[ix][iy][iz],
1402 zs[ix][iy][iz + 1], array[ix][iy][iz + 1], z);
1406 if (z >= zs[ix][iy + 1][iz + 1])
1407 aux01 = array[ix][iy + 1][iz + 1];
1408 else if (z <= zs[ix][iy + 1][iz])
1409 aux01 = array[ix][iy + 1][iz];
1411 aux01 =
LIN(zs[ix][iy + 1][iz], array[ix][iy + 1][iz],
1412 zs[ix][iy + 1][iz + 1], array[ix][iy + 1][iz + 1], z);
1416 if (z >= zs[ix + 1][iy][iz + 1])
1417 aux10 = array[ix + 1][iy][iz + 1];
1418 else if (z <= zs[ix + 1][iy][iz])
1419 aux10 = array[ix + 1][iy][iz];
1421 aux10 =
LIN(zs[ix + 1][iy][iz], array[ix + 1][iy][iz],
1422 zs[ix + 1][iy][iz + 1], array[ix + 1][iy][iz + 1], z);
1426 if (z >= zs[ix + 1][iy + 1][iz + 1])
1427 aux11 = array[ix + 1][iy + 1][iz + 1];
1428 else if (z <= zs[ix + 1][iy + 1][iz])
1429 aux11 = array[ix + 1][iy + 1][iz];
1431 aux11 =
LIN(zs[ix + 1][iy + 1][iz], array[ix + 1][iy + 1][iz],
1432 zs[ix + 1][iy + 1][iz + 1], array[ix + 1][iy + 1][iz + 1], z);
1435 double aux0 =
LIN(met->
lat[iy], aux00, met->
lat[iy + 1], aux01, lat);
1436 double aux1 =
LIN(met->
lat[iy], aux10, met->
lat[iy + 1], aux11, lat);
1437 *var =
LIN(met->
lon[ix], aux0, met->
lon[ix + 1], aux1, lon2);
1444 float array[
EX][
EY],
1456 double lon2 =
FMOD(lon, 360.);
1457 if (lon2 < met->lon[0])
1459 else if (lon2 > met->
lon[met->
nx - 1])
1467 cw[1] = (met->
lon[ci[1] + 1] - lon2)
1468 / (met->
lon[ci[1] + 1] - met->
lon[ci[1]]);
1469 cw[2] = (met->
lat[ci[2] + 1] - lat)
1470 / (met->
lat[ci[2] + 1] - met->
lat[ci[2]]);
1474 double aux00 = array[ci[1]][ci[2]];
1475 double aux01 = array[ci[1]][ci[2] + 1];
1476 double aux10 = array[ci[1] + 1][ci[2]];
1477 double aux11 = array[ci[1] + 1][ci[2] + 1];
1480 if (isfinite(aux00) && isfinite(aux01)
1481 && isfinite(aux10) && isfinite(aux11)) {
1482 aux00 = cw[2] * (aux00 - aux01) + aux01;
1483 aux11 = cw[2] * (aux10 - aux11) + aux11;
1484 *var = cw[1] * (aux00 - aux11) + aux11;
1504 float array0[
EX][
EY][
EP],
1506 float array1[
EX][
EY][
EP],
1523 const double wt = (met1->
time - ts) / (met1->
time - met0->
time);
1526 *var = wt * (var0 - var1) + var1;
1534 float array0[
EX][
EY][
EP],
1537 float array1[
EX][
EY][
EP],
1551 *var =
LIN(met0->
time, var0, met1->
time, var1, ts);
1558 float array0[
EX][
EY],
1560 float array1[
EX][
EY],
1576 const double wt = (met1->
time - ts) / (met1->
time - met0->
time);
1579 if (isfinite(var0) && isfinite(var1))
1580 *var = wt * (var0 - var1) + var1;
1591 float array0[
EX][
EY],
1593 float array1[
EX][
EY],
1594 const double lons[
EX],
1595 const double lats[
EY],
1605 double aux0, aux1, aux00, aux01, aux10, aux11, mean = 0;
1610 double lon2 =
FMOD(lon, 360.);
1613 else if (lon2 > lons[nlon - 1])
1617 const int ix =
locate_reg(lons, (
int) nlon, lon2);
1618 const int iy =
locate_reg(lats, (
int) nlat, lat);
1622 for (
int dx = 0; dx < 2; dx++)
1623 for (
int dy = 0; dy < 2; dy++) {
1624 if (isfinite(array0[ix + dx][iy + dy])) {
1625 mean += array0[ix + dx][iy + dy];
1626 *sigma +=
SQR(array0[ix + dx][iy + dy]);
1629 if (isfinite(array1[ix + dx][iy + dy])) {
1630 mean += array1[ix + dx][iy + dy];
1631 *sigma +=
SQR(array1[ix + dx][iy + dy]);
1636 *sigma = sqrt(
MAX(*sigma / n -
SQR(mean / n), 0.0));
1639 if (method == 1 && isfinite(array0[ix][iy])
1640 && isfinite(array0[ix][iy + 1])
1641 && isfinite(array0[ix + 1][iy])
1642 && isfinite(array0[ix + 1][iy + 1])
1643 && isfinite(array1[ix][iy])
1644 && isfinite(array1[ix][iy + 1])
1645 && isfinite(array1[ix + 1][iy])
1646 && isfinite(array1[ix + 1][iy + 1])) {
1648 aux00 =
LIN(lons[ix], array0[ix][iy],
1649 lons[ix + 1], array0[ix + 1][iy], lon2);
1650 aux01 =
LIN(lons[ix], array0[ix][iy + 1],
1651 lons[ix + 1], array0[ix + 1][iy + 1], lon2);
1652 aux0 =
LIN(lats[iy], aux00, lats[iy + 1], aux01, lat);
1654 aux10 =
LIN(lons[ix], array1[ix][iy],
1655 lons[ix + 1], array1[ix + 1][iy], lon2);
1656 aux11 =
LIN(lons[ix], array1[ix][iy + 1],
1657 lons[ix + 1], array1[ix + 1][iy + 1], lon2);
1658 aux1 =
LIN(lats[iy], aux10, lats[iy + 1], aux11, lat);
1660 *var =
LIN(time0, aux0, time1, aux1, time);
1665 aux00 =
NN(lons[ix], array0[ix][iy],
1666 lons[ix + 1], array0[ix + 1][iy], lon2);
1667 aux01 =
NN(lons[ix], array0[ix][iy + 1],
1668 lons[ix + 1], array0[ix + 1][iy + 1], lon2);
1669 aux0 =
NN(lats[iy], aux00, lats[iy + 1], aux01, lat);
1671 aux10 =
NN(lons[ix], array1[ix][iy],
1672 lons[ix + 1], array1[ix + 1][iy], lon2);
1673 aux11 =
NN(lons[ix], array1[ix][iy + 1],
1674 lons[ix + 1], array1[ix + 1][iy + 1], lon2);
1675 aux1 =
NN(lats[iy], aux10, lats[iy + 1], aux11, lat);
1677 *var =
NN(time0, aux0, time1, aux1, time);
1702 const time_t jsec0 = (time_t) jsec + timegm(&t0);
1703 t1 = gmtime(&jsec0);
1705 *year = t1->tm_year + 1900;
1706 *mon = t1->tm_mon + 1;
1708 *hour = t1->tm_hour;
1711 *remain = jsec - floor(jsec);
1717 const double kz[
EP],
1718 const double kw[
EP],
1727 const double z =
Z(p);
1732 else if (z > kz[nk - 1])
1736 return LIN(kz[idx], kw[idx], kz[idx + 1], kw[idx + 1], z);
1753 const double a =
RA *
SQR(t), r =
SH(h2o) / (1. -
SH(h2o));
1767 const double press[138] = {
1768 0.0200, 0.0310, 0.0467, 0.0683, 0.0975, 0.1361, 0.1861, 0.2499,
1769 0.3299, 0.4288, 0.5496, 0.6952, 0.8690, 1.0742, 1.3143, 1.5928, 1.9134,
1770 2.2797, 2.6954, 3.1642, 3.6898, 4.2759, 4.9262, 5.6441, 6.4334, 7.2974,
1771 8.2397, 9.2634, 10.3720, 11.5685, 12.8561, 14.2377, 15.7162, 17.2945,
1772 18.9752, 20.7610, 22.6543, 24.6577, 26.7735, 29.0039, 31.3512, 33.8174,
1773 36.4047, 39.1149, 41.9493, 44.9082, 47.9915, 51.1990, 54.5299, 57.9834,
1774 61.5607, 65.2695, 69.1187, 73.1187, 77.2810, 81.6182, 86.1450, 90.8774,
1775 95.8280, 101.0047, 106.4153, 112.0681, 117.9714, 124.1337, 130.5637,
1776 137.2703, 144.2624, 151.5493, 159.1403, 167.0450, 175.2731, 183.8344,
1777 192.7389, 201.9969, 211.6186, 221.6146, 231.9954, 242.7719, 253.9549,
1778 265.5556, 277.5852, 290.0548, 302.9762, 316.3607, 330.2202, 344.5663,
1779 359.4111, 374.7666, 390.6450, 407.0583, 424.0190, 441.5395, 459.6321,
1780 478.3096, 497.5845, 517.4198, 537.7195, 558.3430, 579.1926, 600.1668,
1781 621.1624, 642.0764, 662.8084, 683.2620, 703.3467, 722.9795, 742.0855,
1782 760.5996, 778.4661, 795.6396, 812.0847, 827.7756, 842.6959, 856.8376,
1783 870.2004, 882.7910, 894.6222, 905.7116, 916.0815, 925.7571, 934.7666,
1784 943.1399, 950.9082, 958.1037, 964.7584, 970.9046, 976.5737, 981.7968,
1785 986.6036, 991.0230, 995.0824, 998.8081, 1002.2250, 1005.3562, 1008.2239,
1786 1010.8487, 1013.2500, 1044.45
1789 for (
int ip = 0; ip < ctl->
met_np; ip++)
1796 const double press[92] = {
1797 0.0200, 0.0398, 0.0739, 0.1291, 0.2141, 0.3395, 0.5175, 0.7617,
1798 1.0872, 1.5099, 2.0464, 2.7136, 3.5282, 4.5069, 5.6652, 7.0181,
1799 8.5795, 10.3617, 12.3759, 14.6316, 17.1371, 19.8987, 22.9216, 26.2090,
1800 29.7630, 33.5843, 37.6720, 42.0242, 46.6378, 51.5086, 56.6316, 61.9984,
1801 67.5973, 73.4150, 79.4434, 85.7016, 92.2162, 99.0182, 106.1445,
1803 121.5502, 129.9403, 138.8558, 148.3260, 158.3816, 169.0545, 180.3786,
1804 192.3889, 205.1222, 218.6172, 232.9140, 248.0547, 264.0833, 281.0456,
1805 298.9895, 317.9651, 338.0245, 359.2221, 381.6144, 405.2606, 430.2069,
1806 456.4813, 483.8505, 512.0662, 540.8577, 569.9401, 599.0310, 627.9668,
1807 656.6129, 684.8491, 712.5573, 739.5739, 765.7697, 791.0376, 815.2774,
1808 838.3507, 860.1516, 880.6080, 899.6602, 917.2205, 933.2247, 947.6584,
1809 960.5245, 971.8169, 981.5301, 989.7322, 996.8732, 1002.8013,
1810 1007.4431, 1010.8487, 1013.2500, 1044.45
1813 for (
int ip = 0; ip < ctl->
met_np; ip++)
1820 const double press[60] = {
1821 0.01, 0.1361, 0.2499, 0.4288, 0.6952, 1.0742,
1822 2.2797, 3.1642, 4.2759, 7.2974, 9.2634, 11.5685, 14.2377, 20.761,
1823 24.6577, 33.8174, 39.1149, 51.199, 57.9834, 73.1187, 81.6182,
1824 90.8774, 101.005, 112.068, 124.134, 137.27, 151.549, 167.045, 183.834,
1825 201.997, 221.615, 242.772, 265.556, 290.055, 316.361, 344.566, 374.767,
1826 407.058, 441.539, 478.31, 517.42, 558.343, 600.167, 683.262, 722.979,
1827 760.6, 795.64, 827.776, 856.838, 882.791, 905.712, 925.757, 943.14,
1828 958.104, 972.495, 986.886, 1001.28, 1015.67, 1030.06, 1044.45
1831 for (
int ip = 0; ip < ctl->
met_np; ip++)
1838 const double press[147] = {
1839 0.0200, 0.0310, 0.0467, 0.0683, 0.0975, 0.1361, 0.1861, 0.2499,
1840 0.3299, 0.4288, 0.5496, 0.6952, 0.8690, 1.0742, 1.3143, 1.5928, 1.9134,
1841 2.2797, 2.6954, 3.1642, 3.6898, 4.2759, 4.9262, 5.6441, 6.4334, 7.2974,
1842 8.2397, 9.2634, 10.3720, 11.5685, 12.8561, 14.2377, 15.7162, 17.2945,
1843 18.9752, 20.7610, 22.6543, 24.6577, 26.7735, 29.0039, 31.3512, 33.8174,
1844 36.4047, 39.1149, 41.9493, 44.9082, 47.9915, 51.1990, 54.5299, 57.9834,
1845 61.5607, 65.2695, 69.1187, 73.1187, 77.2810, 81.6182, 86.1450, 90.8774,
1846 95.8280, 101.0047, 106.4153, 112.0681, 117.9714, 124.1337, 130.5637,
1847 137.2703, 144.2624, 151.5493, 159.1403, 167.0450, 175.2731, 183.8344,
1848 192.7389, 201.9969, 211.6186, 221.6146, 231.9954, 242.7719, 253.9549,
1849 265.5556, 277.5852, 290.0548, 302.9762, 316.3607, 330.2202, 344.5663,
1850 359.4111, 374.7666, 390.6450, 407.0583, 424.0190, 441.5395, 459.6321,
1851 478.3096, 497.5845, 517.4198, 537.7195, 558.3430, 579.1926, 600.1668,
1852 621.1624, 642.0764, 662.8084, 683.2620, 703.3467, 722.9795, 742.0855,
1853 760.5996, 778.4661, 795.6396, 812.0847, 827.7756, 842.6959, 856.8376,
1854 870.2004, 882.7910, 894.6222, 905.7116, 916.0815, 925.7571, 934.7666,
1855 943.1399, 950.9082, 958.1037, 964.7584, 970.9046, 976.5737, 981.7968,
1856 986.6036, 991.0230, 995.0824, 998.8081, 1002.2250, 1005.3562, 1008.2239,
1857 1010.8487, 1013.25, 1016.37, 1019.49, 1022.61, 1025.73, 1028.85,
1859 1035.09, 1038.21, 1041.33, 1044.45
1862 for (
int ip = 0; ip < ctl->
met_np; ip++)
1869 const double press[101] = {
1870 0.0200, 0.0398, 0.0739, 0.1291, 0.2141, 0.3395, 0.5175, 0.7617,
1871 1.0872, 1.5099, 2.0464, 2.7136, 3.5282, 4.5069, 5.6652, 7.0181,
1872 8.5795, 10.3617, 12.3759, 14.6316, 17.1371, 19.8987, 22.9216, 26.2090,
1873 29.7630, 33.5843, 37.6720, 42.0242, 46.6378, 51.5086, 56.6316, 61.9984,
1874 67.5973, 73.4150, 79.4434, 85.7016, 92.2162, 99.0182, 106.1445,
1876 121.5502, 129.9403, 138.8558, 148.3260, 158.3816, 169.0545, 180.3786,
1877 192.3889, 205.1222, 218.6172, 232.9140, 248.0547, 264.0833, 281.0456,
1878 298.9895, 317.9651, 338.0245, 359.2221, 381.6144, 405.2606, 430.2069,
1879 456.4813, 483.8505, 512.0662, 540.8577, 569.9401, 599.0310, 627.9668,
1880 656.6129, 684.8491, 712.5573, 739.5739, 765.7697, 791.0376, 815.2774,
1881 838.3507, 860.1516, 880.6080, 899.6602, 917.2205, 933.2247, 947.6584,
1882 960.5245, 971.8169, 981.5301, 989.7322, 996.8732, 1002.8013,
1883 1007.4431, 1010.8487, 1013.25, 1016.37, 1019.49, 1022.61, 1025.73,
1885 1035.09, 1038.21, 1041.33, 1044.45
1888 for (
int ip = 0; ip < ctl->
met_np; ip++)
1895 const double press[62] = {
1896 0.01, 0.1361, 0.2499, 0.4288, 0.6952, 1.0742,
1897 2.2797, 3.1642, 4.2759, 7.2974, 9.2634, 11.5685, 14.2377, 20.761,
1898 24.6577, 33.8174, 39.1149, 51.199, 57.9834, 73.1187, 81.6182,
1899 90.8774, 101.005, 112.068, 124.134, 137.27, 151.549, 167.045, 183.834,
1900 201.997, 221.615, 242.772, 265.556, 290.055, 316.361, 344.566, 374.767,
1901 407.058, 441.539, 478.31, 517.42, 558.343, 600.167, 683.262, 722.979,
1902 760.6, 795.64, 827.776, 856.838, 882.791, 905.712, 925.757, 943.14,
1903 958.104, 972.495, 986.886, 1001.28, 1015.67, 1030.06, 1034.86, 1039.65,
1907 for (
int ip = 0; ip < ctl->
met_np; ip++)
1914 const double press[137] = {
1915 0.01, 0.02, 0.031, 0.0467, 0.0683, 0.0975, 0.1361, 0.1861,
1916 0.2499, 0.3299, 0.4288, 0.5496, 0.6952, 0.869, 1.0742,
1917 1.3143, 1.5928, 1.9134, 2.2797, 2.6954, 3.1642, 3.6898,
1918 4.2759, 4.9262, 5.6441, 6.4334, 7.2974, 8.2397, 9.2634,
1919 10.372, 11.5685, 12.8561, 14.2377, 15.7162, 17.2945, 18.9752,
1920 20.761, 22.6543, 24.6577, 26.7735, 29.0039, 31.3512, 33.8174,
1921 36.4047, 39.1149, 41.9493, 44.9082, 47.9915, 51.199, 54.5299,
1922 57.9834, 61.5607, 65.2695, 69.1187, 73.1187, 77.281, 81.6182,
1923 86.145, 90.8774, 95.828, 101.005, 106.415, 112.068, 117.971,
1924 124.134, 130.564, 137.27, 144.262, 151.549, 159.14, 167.045,
1925 175.273, 183.834, 192.739, 201.997, 211.619, 221.615, 231.995,
1926 242.772, 253.955, 265.556, 277.585, 290.055, 302.976, 316.361,
1927 330.22, 344.566, 359.411, 374.767, 390.645, 407.058, 424.019,
1928 441.539, 459.632, 478.31, 497.584, 517.42, 537.72, 558.343,
1929 579.193, 600.167, 621.162, 642.076, 662.808, 683.262, 703.347,
1930 722.979, 742.086, 760.6, 778.466, 795.64, 812.085, 827.776,
1931 842.696, 856.838, 870.2, 882.791, 894.622, 905.712, 916.081,
1932 925.757, 934.767, 943.14, 950.908, 958.104, 965.299, 972.495,
1933 979.69, 986.886, 994.081, 1001.28, 1008.47, 1015.67, 1022.86,
1934 1030.06, 1037.25, 1044.45
1937 for (
int ip = 0; ip < ctl->
met_np; ip++)
1944 const double press[59] = {
1945 0.1, 0.2, 0.3843, 0.6365, 0.9564, 1.3448, 1.8058, 2.3478,
1946 2.985, 3.7397, 4.6462, 5.7565, 7.1322, 8.8366, 10.9483,
1947 13.5647, 16.8064, 20.8227, 25.7989, 31.9642, 39.6029, 49.0671,
1948 60.1802, 73.0663, 87.7274, 104.229, 122.614, 142.902, 165.089,
1949 189.147, 215.025, 242.652, 272.059, 303.217, 336.044, 370.407,
1950 406.133, 443.009, 480.791, 519.209, 557.973, 596.777, 635.306,
1951 673.24, 710.263, 746.063, 780.346, 812.83, 843.263, 871.42,
1952 897.112, 920.189, 940.551, 958.148, 975.744, 993.341, 1010.94,
1956 for (
int ip = 0; ip < ctl->
met_np; ip++)
1960 ERRMSG(
"Use 0 for l137, 1 for l91, 2 for l60 or values between 3 and 7.")
1973 int i = (ihi + ilo) >> 1;
1975 if (xx[i] < xx[i + 1])
1976 while (ihi > ilo + 1) {
1977 i = (ihi + ilo) >> 1;
1983 while (ihi > ilo + 1) {
1984 i = (ihi + ilo) >> 1;
2004 int i = (ihi + ilo) >> 1;
2006 if (x >= xx[ig] && x < xx[ig + 1])
2009 if (xx[i] < xx[i + 1])
2010 while (ihi > ilo + 1) {
2011 i = (ihi + ilo) >> 1;
2017 while (ihi > ilo + 1) {
2018 i = (ihi + ilo) >> 1;
2036 int i = (int) ((x - xx[0]) / (xx[1] - xx[0]));
2050 float profiles[
EX][
EY][
EP],
2052 const int lon_ap_ind,
2053 const int lat_ap_ind,
2054 const double height_ap,
2060 np, height_ap, ind[0]);
2062 np, height_ap, ind[1]);
2064 np, height_ap, ind[2]);
2083 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2087 double dts, u[4], um = 0, v[4], vm = 0, w[4], wm = 0,
2091 for (
int i = 0; i < ctl->
advect; i++) {
2096 x[0] = atm->
lon[ip];
2097 x[1] = atm->
lat[ip];
2100 dts = (i == 3 ? 1.0 : 0.5) * cache->
dt[ip];
2101 x[0] = atm->
lon[ip] +
DX2DEG(dts * u[i - 1] / 1000., atm->
lat[ip]);
2102 x[1] = atm->
lat[ip] +
DY2DEG(dts * v[i - 1] / 1000.);
2103 x[2] = atm->
p[ip] + dts * w[i - 1];
2105 const double tm = atm->
time[ip] + dts;
2110 tm, x[2], x[0], x[1], &u[i], ci, cw, 1);
2112 tm, x[2], x[0], x[1], &v[i], ci, cw, 0);
2114 tm, x[2], x[0], x[1], &w[i], ci, cw, 0);
2120 met1, met1->
pl, met1->
ul,
2121 tm, x[2], x[0], x[1], &u[i]);
2123 met1, met1->
pl, met1->
vl,
2124 tm, x[2], x[0], x[1], &v[i]);
2126 met1, met1->
pl, met1->
wl,
2127 tm, x[2], x[0], x[1], &w[i]);
2133 k = (i == 0 ? 0.0 : 1.0);
2134 else if (ctl->
advect == 4)
2135 k = (i == 0 || i == 3 ? 1.0 / 6.0 : 2.0 / 6.0);
2142 atm->
time[ip] += cache->
dt[ip];
2143 atm->
lon[ip] +=
DX2DEG(cache->
dt[ip] * um / 1000.,
2144 (ctl->
advect == 2 ? x[1] : atm->
lat[ip]));
2145 atm->
lat[ip] +=
DY2DEG(cache->
dt[ip] * vm / 1000.);
2146 atm->
p[ip] += cache->
dt[ip] * wm;
2154 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2163 atm->
lon[ip], atm->
lat[ip],
2167 double dts, u[4], um = 0, v[4], vm = 0, zeta_dot[4],
2168 zeta_dotm = 0, x[3] = { 0, 0, 0 };
2171 for (
int i = 0; i < ctl->
advect; i++) {
2176 x[0] = atm->
lon[ip];
2177 x[1] = atm->
lat[ip];
2180 dts = (i == 3 ? 1.0 : 0.5) * cache->
dt[ip];
2181 x[0] = atm->
lon[ip] +
DX2DEG(dts * u[i - 1] / 1000., atm->
lat[ip]);
2182 x[1] = atm->
lat[ip] +
DY2DEG(dts * v[i - 1] / 1000.);
2183 x[2] = atm->
q[ctl->
qnt_zeta][ip] + dts * zeta_dot[i - 1];
2185 const double tm = atm->
time[ip] + dts;
2189 met1->
ul, tm, x[2], x[0], x[1], &u[i], ci, cw, 1);
2191 met1->
vl, tm, x[2], x[0], x[1], &v[i], ci, cw, 0);
2194 x[1], &zeta_dot[i], ci, cw, 0);
2199 k = (i == 0 ? 0.0 : 1.0);
2200 else if (ctl->
advect == 4)
2201 k = (i == 0 || i == 3 ? 1.0 / 6.0 : 2.0 / 6.0);
2204 zeta_dotm += k * zeta_dot[i];
2208 atm->
time[ip] += cache->
dt[ip];
2209 atm->
lon[ip] +=
DX2DEG(cache->
dt[ip] * um / 1000.,
2210 (ctl->
advect == 2 ? x[1] : atm->
lat[ip]));
2211 atm->
lat[ip] +=
DY2DEG(cache->
dt[ip] * vm / 1000.);
2212 atm->
q[ctl->
qnt_zeta][ip] += cache->
dt[ip] * zeta_dotm;
2221 atm->
lon[ip], atm->
lat[ip], &atm->
p[ip], ci, cw, 1);
2240 SELECT_TIMER(
"MODULE_ADVECT_INIT",
"PHYSICS", NVTX_GPU);
2249 atm->
lon[ip], atm->
lat[ip], &atm->
p[ip], ci, cw, 1);
2264 SELECT_TIMER(
"MODULE_BOUND_COND",
"PHYSICS", NVTX_GPU);
2274 "acc data present(ctl,cache,clim,met0,met1,atm)") {
2310 if (atm->
p[ip] < pbl)
2362 ERRMSG(
"Molar mass is not defined!");
2368 const int np = atm->
np;
2372 const int ngrid = nx * ny * nz;
2374 double *restrict
const z = (
double *) malloc((
size_t) nz *
sizeof(double));
2375 double *restrict
const press =
2376 (
double *) malloc((
size_t) nz *
sizeof(double));
2377 double *restrict
const mass =
2378 (
double *) calloc((
size_t) ngrid,
sizeof(double));
2379 double *restrict
const area =
2380 (
double *) malloc((
size_t) ny *
sizeof(double));
2381 double *restrict
const lon =
2382 (
double *) malloc((
size_t) nx *
sizeof(double));
2383 double *restrict
const lat =
2384 (
double *) malloc((
size_t) ny *
sizeof(double));
2386 int *restrict
const ixs = (
int *) malloc((
size_t) np *
sizeof(int));
2387 int *restrict
const iys = (
int *) malloc((
size_t) np *
sizeof(int));
2388 int *restrict
const izs = (
int *) malloc((
size_t) np *
sizeof(int));
2397#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])
2398#pragma acc data present(ctl,met0,met1,atm,ixs,iys,izs,z,press,mass,area,lon,lat)
2399#pragma acc parallel loop independent gang vector
2401#pragma omp parallel for default(shared)
2403 for (
int iz = 0; iz < nz; iz++) {
2405 press[iz] =
P(z[iz]);
2409 const double t0 = tt - 0.5 * ctl->
dt_mod;
2410 const double t1 = tt + 0.5 * ctl->
dt_mod;
2414#pragma acc parallel loop independent gang vector
2416#pragma omp parallel for default(shared)
2418 for (
int ip = 0; ip < np; ip++) {
2422 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
2423 || ixs[ip] < 0 || ixs[ip] >= nx
2424 || iys[ip] < 0 || iys[ip] >= ny || izs[ip] < 0 || izs[ip] >= nz)
2430#pragma acc parallel loop independent gang vector
2432#pragma omp parallel for default(shared)
2434 for (
int ix = 0; ix < nx; ix++)
2437#pragma acc parallel loop independent gang vector
2439#pragma omp parallel for default(shared)
2441 for (
int iy = 0; iy < ny; iy++) {
2443 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat[iy]));
2448#pragma acc parallel loop independent gang vector
2450 for (
int ip = 0; ip < np; ip++)
2453#pragma acc atomic update
2455 mass[
ARRAY_3D(ixs[ip], iys[ip], ny, izs[ip], nz)]
2456 += atm->
q[ctl->
qnt_m][ip];
2460#pragma acc parallel loop independent gang vector
2462#pragma omp parallel for default(shared)
2464 for (
int ip = 0; ip < np; ip++)
2471 lon[ixs[ip]], lat[iys[ip]], &temp, ci, cw, 1);
2474 const double m = mass[
ARRAY_3D(ixs[ip], iys[ip], ny, izs[ip], nz)];
2478 / (
RHO(press[izs[ip]], temp) * area[iys[ip]] * dz * 1e9);
2481#pragma acc exit data delete(ixs,iys,izs,z,press,mass,area,lon,lat)
2511 "acc data present(ctl,cache,clim,met0,met1,atm)") {
2528 atm->
lon[ip], atm->
lat[ip], atm->
p[ip]));
2530 atm->
lat[ip], atm->
p[ip]));
2532 atm->
lat[ip], atm->
p[ip]));
2534 atm->
lat[ip], atm->
p[ip]));
2548 SELECT_TIMER(
"MODULE_CONVECTION",
"PHYSICS", NVTX_GPU);
2554 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2562 double pbot = ps, ptop = ps;
2579 double cape, cin, pel;
2585 if (isfinite(cape) && cape >= ctl->
conv_cape
2587 ptop = GSL_MIN(ptop, pel);
2591 if (ptop != pbot && atm->
p[ip] >= ptop) {
2596 pbot, atm->
lon[ip], atm->
lat[ip], &tbot, ci, cw, 1);
2598 ptop, atm->
lon[ip], atm->
lat[ip], &ttop, ci, cw, 1);
2599 const double rhobot = pbot / tbot;
2600 const double rhotop = ptop / ttop;
2603 const double rho = rhobot + (rhotop - rhobot) * cache->
rs[ip];
2606 atm->
p[ip] =
LIN(rhobot, pbot, rhotop, ptop, rho);
2624 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
2627 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,clim,atm)") {
2636 const double aux = exp(-cache->
dt[ip] / tdec);
2637 if (ctl->
qnt_m >= 0) {
2640 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
2641 atm->
q[ctl->
qnt_m][ip] *= aux;
2666 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2674 float umean = 0, usig = 0, vmean = 0, vsig = 0, wmean = 0, wsig = 0;
2675 for (
int i = 0; i < 2; i++)
2676 for (
int j = 0; j < 2; j++)
2677 for (
int k = 0; k < 2; k++) {
2678 umean += met0->
u[ix + i][iy + j][iz + k];
2679 usig +=
SQR(met0->
u[ix + i][iy + j][iz + k]);
2680 vmean += met0->
v[ix + i][iy + j][iz + k];
2681 vsig +=
SQR(met0->
v[ix + i][iy + j][iz + k]);
2682 wmean += met0->
w[ix + i][iy + j][iz + k];
2683 wsig +=
SQR(met0->
w[ix + i][iy + j][iz + k]);
2685 umean += met1->
u[ix + i][iy + j][iz + k];
2686 usig +=
SQR(met1->
u[ix + i][iy + j][iz + k]);
2687 vmean += met1->
v[ix + i][iy + j][iz + k];
2688 vsig +=
SQR(met1->
v[ix + i][iy + j][iz + k]);
2689 wmean += met1->
w[ix + i][iy + j][iz + k];
2690 wsig +=
SQR(met1->
w[ix + i][iy + j][iz + k]);
2692 usig = usig / 16.f -
SQR(umean / 16.f);
2693 usig = (usig > 0 ? sqrtf(usig) : 0);
2694 vsig = vsig / 16.f -
SQR(vmean / 16.f);
2695 vsig = (vsig > 0 ? sqrtf(vsig) : 0);
2696 wsig = wsig / 16.f -
SQR(wmean / 16.f);
2697 wsig = (wsig > 0 ? sqrtf(wsig) : 0);
2700 const double r = 1 - 2 * fabs(cache->
dt[ip]) / ctl->
dt_met;
2701 const double r2 = sqrt(1 - r * r);
2705 cache->
uvwp[ip][0] =
2706 (float) (r * cache->
uvwp[ip][0] +
2711 cache->
uvwp[ip][1] =
2712 (float) (r * cache->
uvwp[ip][1] +
2719 cache->
uvwp[ip][2] =
2720 (float) (r * cache->
uvwp[ip][2] +
2722 atm->
p[ip] += cache->
uvwp[ip][2] * cache->
dt[ip];
2743 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2745 double dsigw_dz = 0.0, sig_u = 0.25, sig_w = 0.1,
2746 tau_u = 300., tau_w = 100.;
2755 if (atm->
p[ip] >= pbl) {
2758 const double p =
MIN(atm->
p[ip], ps);
2759 const double zs =
Z(ps);
2760 const double z = 1e3 * (
Z(p) - zs);
2761 const double zi = 1e3 * (
Z(pbl) - zs);
2762 const double zratio = z / zi;
2765 double ess, nss, h2o, t;
2770 const double rho =
RHO(p,
TVIRT(t, h2o));
2771 const double tau = sqrt(
SQR(ess) +
SQR(nss));
2772 const double ustar = sqrt(tau / rho);
2782 sig_u = 1e-2 + 2.0 * ustar * (1.0 - zratio);
2783 sig_w = 1e-2 + 1.3 * ustar * (1.0 - zratio);
2786 dsigw_dz = -1.3 * ustar / zi;
2789 tau_u = 0.07 * zi / sig_u * sqrt(zratio);
2790 tau_w = 0.1 * zi / sig_w * pow(zratio, 0.8);
2797 const double wstar =
2798 pow(
G0 /
THETAVIRT(p, t, h2o) * shf / (rho *
CPD) * zi, 1. / 3.);
2802 + sqrt(0.4 *
SQR(wstar) + (5.0 - 4.0 * zratio) *
SQR(ustar));
2803 sig_w = 1e-2 + sqrt(1.2 *
SQR(wstar) * (1.0 - 0.9 * zratio)
2804 * pow(zratio, 2.0 / 3.0)
2805 + (1.8 - 1.4 * zratio) *
SQR(ustar));
2808 dsigw_dz = 0.5 / sig_w / zi * (-1.4 *
SQR(ustar) +
SQR(wstar)
2810 pow(
MAX(zratio, 1e-3), -1.0 / 3.0)
2811 - 1.8 * pow(zratio, 2.0 / 3.0)));
2814 const double C0 = 3.0;
2816 (1.5 - 1.2 * pow(zratio, 1.0 / 3.0)) *
SQR(wstar) * wstar / zi
2817 +
SQR(ustar) * ustar * (1.0 - 0.8 * zratio) / (
KARMAN * z);
2818 tau_u = 2 *
SQR(sig_u) / (C0 * eps);
2819 tau_w = 2 *
SQR(sig_w) / (C0 * eps);
2824 sig_u =
MAX(sig_u, 0.25);
2825 sig_w =
MAX(sig_w, 0.1);
2826 tau_u =
MAX(tau_u, 300.);
2827 tau_w =
MAX(tau_w, 100.);
2830 const double ru = exp(-fabs(cache->
dt[ip]) / tau_u);
2831 const double ru2 = sqrt(1.0 -
SQR(ru));
2833 = (float) (cache->
uvwp[ip][0] * ru + ru2 * cache->
rs[3 * ip]);
2835 = (float) (cache->
uvwp[ip][1] * ru + ru2 * cache->
rs[3 * ip + 1]);
2837 const double rw = exp(-fabs(cache->
dt[ip]) / tau_w);
2838 const double rw2 = sqrt(1.0 -
SQR(rw));
2840 = (float) (cache->
uvwp[ip][2] * rw + rw2 * cache->
rs[3 * ip + 2]
2841 + sig_w * dsigw_dz * cache->
dt[ip]);
2848 DZ2DP(cache->
uvwp[ip][2] * cache->
dt[ip] / 1000., atm->
p[ip]);
2870 "acc data present(ctl,cache,clim,met0,met1,atm)") {
2879 const double wpbl =
pbl_weight(ctl, atm, ip, pbl, ps);
2880 const double wtrop =
tropo_weight(clim, atm, ip) * (1.0 - wpbl);
2881 const double wstrat = 1.0 - wpbl - wtrop;
2891 const double sigma = sqrt(2.0 * dx * fabs(cache->
dt[ip])) / 1000.;
2893 atm->
lat[ip] +=
DY2DEG(cache->
rs[3 * ip + 1] * sigma);
2898 const double sigma = sqrt(2.0 * dz * fabs(cache->
dt[ip])) / 1000.;
2899 atm->
p[ip] +=
DZ2DP(cache->
rs[3 * ip + 2] * sigma, atm->
p[ip]);
2918 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
2921 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2933 const double dz = 1000. * (
Z(ps - ctl->
dry_depo_dp) -
Z(ps));
2953 const double aux = exp(-cache->
dt[ip] * v_dep / dz);
2954 if (ctl->
qnt_m >= 0) {
2957 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
2958 atm->
q[ctl->
qnt_m][ip] *= aux;
2982 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
2985 const double a = 3.12541941e-06;
2986 const double b = -5.72532259e-01;
2987 const double low = pow(1. / a, 1. / b);
2991 "acc data present(ctl,cache,ctl,met0,met1,atm)") {
2998 if (!(lwc > 0 || rwc > 0))
3009 const double k = 9.1e7 * exp(-29700. /
RI * (1. / t - 1. / 298.15));
3012 const double H_SO2 =
3013 1.3e-2 * exp(2900. * (1. / t - 1. / 298.15)) *
RI * t;
3014 const double K_1S = 1.23e-2 * exp(2.01e3 * (1. / t - 1. / 298.15));
3017 const double H_h2o2 =
3018 8.3e2 * exp(7600. * (1. / t - 1. / 298.15)) *
RI * t;
3024 cor = atm->
q[ctl->
qnt_Cx][ip] >
3025 low ? a * pow(atm->
q[ctl->
qnt_Cx][ip], b) : 1;
3027 const double h2o2 = H_h2o2
3029 * M * cor * 1000. /
AVO;
3032 const double rho_air = atm->
p[ip] / (
RI * t) *
MA / 10.;
3033 const double CWC = (lwc + rwc) * rho_air / 1e3;
3036 const double rate_coef = k * K_1S * h2o2 * H_SO2 * CWC;
3037 const double aux = exp(-cache->
dt[ip] * rate_coef);
3038 if (ctl->
qnt_m >= 0) {
3041 atm->
q[ctl->
qnt_m][ip] *= aux;
3062 SELECT_TIMER(
"MODULE_ISOSURF_INIT",
"PHYSICS", NVTX_GPU);
3073 PARTICLE_LOOP(0, atm->
np, 0,
"acc data present(cache,met0,met1,atm)") {
3076 cache->
iso_var[ip] = atm->
p[ip] / t;
3082 PARTICLE_LOOP(0, atm->
np, 0,
"acc data present(cache,met0,met1,atm)") {
3093 LOG(1,
"Read balloon pressure data: %s", ctl->
balloon);
3097 if (!(in = fopen(ctl->
balloon,
"r")))
3098 ERRMSG(
"Cannot open file!");
3102 while (fgets(line,
LEN, in))
3103 if (sscanf(line,
"%lg %lg", &(cache->
iso_ts[cache->
iso_n]),
3106 ERRMSG(
"Too many data points!");
3109 if (cache->
iso_n < 1)
3110 ERRMSG(
"Could not read any data!");
3133 PARTICLE_LOOP(0, atm->
np, 0,
"acc data present(ctl,cache,met0,met1,atm)") {
3146 atm->
p[ip] = cache->
iso_var[ip] * t;
3152 atm->
p[ip] = 1000. * pow(cache->
iso_var[ip] / t, -1. / 0.286);
3158 atm->
p[ip] = cache->
iso_ps[0];
3185 const int nvar = NVAR, nfix = NFIX, nreact = NREACT;
3186 double rtol[1] = { 1.0e-3 };
3187 double atol[1] = { 1.0 };
3191#pragma acc data copy(rtol,atol,nvar,nfix,nreact)
3194 "acc data present(ctl,cache,clim,met0,met1,atm) ") {
3197 double var[nvar], fix[nfix], rconst[nreact];
3198 for (
int i = 0; i < nvar; i++)
3200 for (
int i = 0; i < nfix; i++)
3202 for (
int i = 0; i < nreact; i++)
3204 kpp_chem_initialize(ctl, clim, met0, met1, atm, var, fix, rconst, ip);
3209 for (
int i = 0; i < 20; i++) {
3216 Rosenbrock(var, fix, rconst, 0, ctl->
dt_kpp,
3217 atol, rtol, &FunTemplate, &JacTemplate, rpar, ipar);
3220 kpp_chem_output2atm(atm, ctl, met0, met1, var, ip);
3241 ERRMSG(
"Need T_ice and T_NAT to calculate T_STS!");
3245 "acc data present(ctl,cache,clim,met0,met1,atm)") {
3247 double ps, ts, zs, us, vs, ess, nss, shf, lsm, sst, pbl, pt, pct, pcb, cl,
3248 plcl, plfc, pel, cape, cin, o3c, pv, t, tt, u, v, w, h2o, h2ot, o3, lwc,
3249 rwc, iwc, swc, cc, z, zt;
3297 atm->
lon[ip], atm->
lat[ip], atm->
p[ip]));
3299 atm->
lat[ip], atm->
p[ip]));
3301 atm->
lat[ip], atm->
p[ip]));
3303 atm->
lat[ip], atm->
p[ip]));
3304 SET_ATM(qnt_vh, sqrt(u * u + v * v));
3323 atm->
lat[ip], atm->
p[ip])));
3341 const int np = atm->
np;
3342 int *restrict
const ixs = (
int *) malloc((
size_t) np *
sizeof(int));
3343 int *restrict
const iys = (
int *) malloc((
size_t) np *
sizeof(int));
3344 int *restrict
const izs = (
int *) malloc((
size_t) np *
sizeof(int));
3352 const double t0 = t - 0.5 * ctl->
dt_mod;
3353 const double t1 = t + 0.5 * ctl->
dt_mod;
3357#pragma acc enter data create(ixs[0:np],iys[0:np],izs[0:np])
3358#pragma acc data present(ctl,clim,atm,ixs,iys,izs)
3359#pragma acc parallel loop independent gang vector
3361#pragma omp parallel for default(shared)
3363 for (
int ip = 0; ip < np; ip++) {
3366 izs[ip] = (int) ((
Z(atm->
p[ip]) - ctl->
mixing_z0) / dz);
3367 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
3368 || ixs[ip] < 0 || ixs[ip] >= ctl->
mixing_nx
3369 || iys[ip] < 0 || iys[ip] >= ctl->
mixing_ny
3370 || izs[ip] < 0 || izs[ip] >= ctl->
mixing_nz)
3375 if (ctl->
qnt_m >= 0)
3412#pragma acc exit data delete(ixs,iys,izs)
3428 const int qnt_idx) {
3431 const int np = atm->
np;
3433 double *restrict
const cmean =
3434 (
double *) malloc((
size_t) ngrid *
sizeof(double));
3435 int *restrict
const count = (
int *) malloc((
size_t) ngrid *
sizeof(int));
3439#pragma acc enter data create(cmean[0:ngrid],count[0:ngrid])
3440#pragma acc data present(ctl,clim,atm,ixs,iys,izs,cmean,count)
3441#pragma acc parallel loop independent gang vector
3446#pragma omp parallel for
3448 for (
int i = 0; i < ngrid; i++) {
3455#pragma acc parallel loop independent gang vector
3457 for (
int ip = 0; ip < np; ip++)
3462#pragma acc atomic update
3464 cmean[idx] += atm->
q[qnt_idx][ip];
3466#pragma acc atomic update
3471#pragma acc parallel loop independent gang vector
3476#pragma omp parallel for
3478 for (
int i = 0; i < ngrid; i++)
3480 cmean[i] /= count[i];
3484#pragma acc parallel loop independent gang vector
3486#pragma omp parallel for
3488 for (
int ip = 0; ip < np; ip++)
3492 double mixparam = 1.0;
3499 atm->
q[qnt_idx][ip] +=
3502 - atm->
q[qnt_idx][ip]) * mixparam;
3507#pragma acc exit data delete(cmean,count)
3528 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
3531 const double a = 4.71572206e-08;
3532 const double b = -8.28782867e-01;
3533 const double low = pow(1. / a, 1. / b);
3537 "acc data present(ctl,cache,clim,met0,met1,atm)") {
3563 0 ? pow(298. / t, ctl->
oh_chem[1]) : 1.);
3566 0 ? pow(298. / t, ctl->
oh_chem[3]) : 1.);
3567 const double c = log10(k0 * M / ki);
3568 k = k0 * M / (1. + k0 * M / ki) * pow(0.6, 1. / (1. + c * c));
3577 low ? a * pow(atm->
q[ctl->
qnt_Cx][ip], b) : 1;
3580 const double rate_coef =
3582 atm->
lat[ip], atm->
p[ip]) * M * cor;
3583 const double aux = exp(-cache->
dt[ip] * rate_coef);
3584 if (ctl->
qnt_m >= 0) {
3587 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
3588 atm->
q[ctl->
qnt_m][ip] *= aux;
3609 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(cache,met0,met1,atm)") {
3620 while (atm->
lat[ip] < -90 || atm->
lat[ip] > 90) {
3621 if (atm->
lat[ip] > 90) {
3622 atm->
lat[ip] = 180 - atm->
lat[ip];
3623 atm->
lon[ip] += 180;
3625 if (atm->
lat[ip] < -90) {
3626 atm->
lat[ip] = -180 - atm->
lat[ip];
3627 atm->
lon[ip] += 180;
3632 while (atm->
lon[ip] < -180)
3633 atm->
lon[ip] += 360;
3634 while (atm->
lon[ip] >= 180)
3635 atm->
lon[ip] -= 360;
3638 if (atm->
p[ip] < met0->
p[met0->
np - 1]) {
3640 atm->
p[ip] = met0->
p[met0->
np - 1];
3641 }
else if (atm->
p[ip] > 300.) {
3645 if (atm->
p[ip] > ps)
3657 gsl_rng_env_setup();
3658 if (omp_get_max_threads() >
NTHREADS)
3659 ERRMSG(
"Too many threads!");
3660 for (
int i = 0; i <
NTHREADS; i++) {
3661 rng[i] = gsl_rng_alloc(gsl_rng_default);
3662 gsl_rng_set(rng[i], gsl_rng_default_seed
3663 + (
long unsigned) (ntask *
NTHREADS + i));
3668 if (curandCreateGenerator(&rng_curand, CURAND_RNG_PSEUDO_DEFAULT) !=
3669 CURAND_STATUS_SUCCESS)
3670 ERRMSG(
"Cannot create random number generator!");
3671 if (curandSetPseudoRandomGeneratorSeed(rng_curand, ntask) !=
3672 CURAND_STATUS_SUCCESS)
3673 ERRMSG(
"Cannot set seed for random number generator!");
3676 (cudaStream_t) acc_get_cuda_stream(acc_async_sync)) !=
3677 CURAND_STATUS_SUCCESS)
3678 ERRMSG(
"Cannot set stream for random number generator!");
3695#pragma omp parallel for default(shared)
3696 for (
size_t i = 0; i < n; ++i)
3697 rs[i] = gsl_rng_uniform(rng[omp_get_thread_num()]);
3701 else if (method == 1) {
3702#pragma omp parallel for default(shared)
3703 for (
size_t i = 0; i < n; ++i)
3704 rs[i] = gsl_ran_gaussian_ziggurat(rng[omp_get_thread_num()], 1.0);
3710#pragma acc update device(rs[:n])
3718 const uint64_t key = 0xc8e4fd154ce32f6d;
3722#pragma acc data present(rs)
3723#pragma acc parallel loop independent gang vector
3725#pragma omp parallel for default(shared)
3727 for (
size_t i = 0; i < n + 1; ++i) {
3728 uint64_t r, t, x, y, z;
3729 y = x = (rng_ctr + i) * key;
3732 x = (x >> 32) | (x << 32);
3734 x = (x >> 32) | (x << 32);
3736 x = (x >> 32) | (x << 32);
3738 x = (x >> 32) | (x << 32);
3739 r = t ^ ((x * x + y) >> 32);
3740 rs[i] = (double) r / (
double) UINT64_MAX;
3747#pragma acc parallel loop independent gang vector
3749#pragma omp parallel for default(shared)
3751 for (
size_t i = 0; i < n; i += 2) {
3752 const double r = sqrt(-2.0 * log(rs[i]));
3753 const double phi = 2.0 * M_PI * rs[i + 1];
3754 rs[i] = r * cosf((
float) phi);
3755 rs[i + 1] = r * sinf((
float) phi);
3763#pragma acc host_data use_device(rs)
3768 if (curandGenerateUniformDouble(rng_curand, rs, (n < 4 ? 4 : n)) !=
3769 CURAND_STATUS_SUCCESS)
3770 ERRMSG(
"Cannot create random numbers!");
3774 else if (method == 1) {
3775 if (curandGenerateNormalDouble
3776 (rng_curand, rs, (n < 4 ? 4 : n), 0.0,
3777 1.0) != CURAND_STATUS_SUCCESS)
3778 ERRMSG(
"Cannot create random numbers!");
3782 ERRMSG(
"MPTRAC was compiled without cuRAND!");
3800 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
3808 const double v_s =
sedi(atm->
p[ip], t, atm->
q[ctl->
qnt_rp][ip],
3812 atm->
p[ip] +=
DZ2DP(v_s * cache->
dt[ip] / 1000., atm->
p[ip]);
3827 const int np = atm->
np;
3828 double *restrict
const a = (
double *) malloc((
size_t) np *
sizeof(double));
3829 int *restrict
const p = (
int *) malloc((
size_t) np *
sizeof(int));
3832#pragma acc enter data create(a[0:np],p[0:np])
3833#pragma acc data present(ctl,met0,atm,a,p)
3838#pragma acc parallel loop independent gang vector
3840#pragma omp parallel for default(shared)
3842 for (
int ip = 0; ip < np; ip++) {
3852#pragma acc host_data use_device(a,p)
3857 ERRMSG(
"MPTRAC was compiled without Thrust library!");
3865 for (
int iq = 0; iq < ctl->
nq; iq++)
3870#pragma acc exit data delete(a,p)
3884 double *restrict
const help =
3885 (
double *) malloc((
size_t) np *
sizeof(double));
3889#pragma acc enter data create(help[0:np])
3890#pragma acc data present(a,p,help)
3891#pragma acc parallel loop independent gang vector
3893#pragma omp parallel for default(shared)
3895 for (
int ip = 0; ip < np; ip++)
3896 help[ip] = a[p[ip]];
3898#pragma acc parallel loop independent gang vector
3900#pragma omp parallel for default(shared)
3902 for (
int ip = 0; ip < np; ip++)
3907#pragma acc exit data delete(help)
3924 const double latmin = gsl_stats_min(met0->
lat, 1, (
size_t) met0->
ny),
3925 latmax = gsl_stats_max(met0->
lat, 1, (
size_t) met0->
ny);
3928 (fabs(met0->
lon[met0->
nx - 1] - met0->
lon[0] - 360.0) >= 0.01);
3931 PARTICLE_LOOP(0, atm->
np, 0,
"acc data present(ctl,cache,met0,atm)") {
3937 cache->
dt[ip] = t - atm->
time[ip];
3939 cache->
dt[ip] = 0.0;
3942 if (local && (atm->
lon[ip] <= met0->
lon[0]
3943 || atm->
lon[ip] >= met0->
lon[met0->
nx - 1]
3944 || atm->
lat[ip] <= latmin || atm->
lat[ip] >= latmax))
3945 cache->
dt[ip] = 0.0;
3956 SELECT_TIMER(
"MODULE_TIMESTEPS_INIT",
"PHYSICS", NVTX_GPU);
3960 ctl->
t_start = gsl_stats_min(atm->
time, 1, (
size_t) atm->
np);
3962 ctl->
t_stop = gsl_stats_max(atm->
time, 1, (
size_t) atm->
np);
3964 ctl->
t_start = gsl_stats_max(atm->
time, 1, (
size_t) atm->
np);
3966 ctl->
t_stop = gsl_stats_min(atm->
time, 1, (
size_t) atm->
np);
3971 ERRMSG(
"Nothing to do! Check T_STOP and DIRECTION!");
3991 SELECT_TIMER(
"MODULE_TRACER_CHEM",
"PHYSICS", NVTX_GPU);
3995 "acc data present(ctl,cache,clim,met0,met1,atm)") {
4018 const double K_o1d =
ARRHENIUS(3.30e-10, 0, t) * o1d * M;
4020 atm->
p[ip], sza, o3c);
4021 atm->
q[ctl->
qnt_Cccl4][ip] *= exp(-cache->
dt[ip] * (K_hv + K_o1d));
4026 const double K_o1d =
ARRHENIUS(2.30e-10, 0, t) * o1d * M;
4028 atm->
p[ip], sza, o3c);
4029 atm->
q[ctl->
qnt_Cccl3f][ip] *= exp(-cache->
dt[ip] * (K_hv + K_o1d));
4034 const double K_o1d =
ARRHENIUS(1.40e-10, -25, t) * o1d * M;
4036 atm->
p[ip], sza, o3c);
4037 atm->
q[ctl->
qnt_Cccl2f2][ip] *= exp(-cache->
dt[ip] * (K_hv + K_o1d));
4042 const double K_o1d =
ARRHENIUS(1.19e-10, -20, t) * o1d * M;
4044 atm->
p[ip], sza, o3c);
4045 atm->
q[ctl->
qnt_Cn2o][ip] *= exp(-cache->
dt[ip] * (K_hv + K_o1d));
4064 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
4067 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
4073 if (!isfinite(pct) || atm->
p[ip] <= pct)
4089 double lwc, rwc, iwc, swc;
4094 const int inside = (lwc > 0 || rwc > 0 || iwc > 0 || swc > 0);
4108 else if (t <= 238.15)
4128 const double K_1 = 1.23e-2 * exp(2.01e3 * (1. / t - 1. / 298.15));
4129 const double K_2 = 6e-8 * exp(1.12e3 * (1. / t - 1. / 298.15));
4130 h *= (1. + K_1 / H_ion + K_1 * K_2 /
SQR(H_ion));
4134 const double dz = 1e3 * (
Z(pct) -
Z(pcb));
4137 lambda = h *
RI * t * Is / 3.6e6 / dz * eta;
4163 const double dz = 1e3 * (
Z(pct) -
Z(pcb));
4166 lambda = h *
RI * t * Is / 3.6e6 / dz * eta;
4171 const double aux = exp(-cache->
dt[ip] * lambda);
4172 if (ctl->
qnt_m >= 0) {
4175 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
4176 atm->
q[ctl->
qnt_m][ip] *= aux;
4200 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
4202 if (acc_get_num_devices(acc_device_nvidia) <= 0)
4203 ERRMSG(
"Not running on a GPU device!");
4204 acc_set_device_num(rank % acc_get_num_devices(acc_device_nvidia),
4206 acc_device_t device_type = acc_get_device_type();
4207 acc_init(device_type);
4221 SELECT_TIMER(
"CREATE_DATA_REGION",
"MEMORY", NVTX_GPU);
4222 ctl_t *ctlup = *ctl;
4225 met_t *met0up = *met0;
4226 met_t *met1up = *met1;
4227 atm_t *atmup = *atm;
4228#pragma acc enter data create(ctlup[:1],cacheup[:1],climup[:1],met0up[:1],met1up[:1],atmup[:1])
4244 SELECT_TIMER(
"DELETE_DATA_REGION",
"MEMORY", NVTX_GPU);
4245#pragma acc exit data delete (ctl,cache,clim,met0,met1,atm)
4271 char cachefile[
LEN], cmd[2 *
LEN], filename[
LEN];
4277 if (t == ctl->
t_start || !init) {
4284 ERRMSG(
"Cannot open file!");
4289 ERRMSG(
"Cannot open file!");
4299 sprintf(cmd,
"cat %s > /dev/null &", cachefile);
4300 LOG(1,
"Caching: %s", cachefile);
4301 if (system(cmd) != 0)
4302 WARN(
"Caching command failed!");
4307 if (t > (*met1)->time) {
4317 ERRMSG(
"Cannot open file!");
4327 sprintf(cmd,
"cat %s > /dev/null &", cachefile);
4328 LOG(1,
"Caching: %s", cachefile);
4329 if (system(cmd) != 0)
4330 WARN(
"Caching command failed!");
4335 if (t < (*met0)->time) {
4345 ERRMSG(
"Cannot open file!");
4355 sprintf(cmd,
"cat %s > /dev/null &", cachefile);
4356 LOG(1,
"Caching: %s", cachefile);
4357 if (system(cmd) != 0)
4358 WARN(
"Caching command failed!");
4363 if ((*met0)->nx != 0 && (*met1)->nx != 0) {
4364 if ((*met0)->nx != (*met1)->nx
4365 || (*met0)->ny != (*met1)->ny || (*met0)->np != (*met1)->np)
4366 ERRMSG(
"Meteo grid dimensions do not match!");
4367 for (
int ix = 0; ix < (*met0)->nx; ix++)
4368 if (fabs((*met0)->lon[ix] - (*met1)->lon[ix]) > 0.001)
4369 ERRMSG(
"Meteo grid longitudes do not match!");
4370 for (
int iy = 0; iy < (*met0)->ny; iy++)
4371 if (fabs((*met0)->lat[iy] - (*met1)->lat[iy]) > 0.001)
4372 ERRMSG(
"Meteo grid latitudes do not match!");
4373 for (
int ip = 0; ip < (*met0)->np; ip++)
4374 if (fabs((*met0)->p[ip] - (*met1)->p[ip]) > 0.001)
4375 ERRMSG(
"Meteo grid pressure levels do not match!");
4401 const char *filename,
4414 LOG(1,
"Read atmospheric data: %s", filename);
4434 ERRMSG(
"Atmospheric data type not supported!");
4442 ERRMSG(
"Can not read any data!");
4446 LOG(2,
"Number of particles: %d", atm->
np);
4447 gsl_stats_minmax(&mini, &maxi, atm->
time, 1, (
size_t) atm->
np);
4448 LOG(2,
"Time range: %.2f ... %.2f s", mini, maxi);
4449 gsl_stats_minmax(&mini, &maxi, atm->
p, 1, (
size_t) atm->
np);
4450 LOG(2,
"Altitude range: %g ... %g km",
Z(maxi),
Z(mini));
4451 LOG(2,
"Pressure range: %g ... %g hPa", maxi, mini);
4452 gsl_stats_minmax(&mini, &maxi, atm->
lon, 1, (
size_t) atm->
np);
4453 LOG(2,
"Longitude range: %g ... %g deg", mini, maxi);
4454 gsl_stats_minmax(&mini, &maxi, atm->
lat, 1, (
size_t) atm->
np);
4455 LOG(2,
"Latitude range: %g ... %g deg", mini, maxi);
4456 for (
int iq = 0; iq < ctl->
nq; iq++) {
4458 sprintf(msg,
"Quantity %s range: %s ... %s %s",
4461 gsl_stats_minmax(&mini, &maxi, atm->
q[iq], 1, (
size_t) atm->
np);
4462 LOG(2, msg, mini, maxi);
4532 const char *filename,
4541 LOG(1,
"\nMassive-Parallel Trajectory Calculations (MPTRAC)\n"
4542 "(executable: %s | version: %s | compiled: %s, %s)\n",
4543 argv[0], VERSION, __DATE__, __TIME__);
4639 ctl->
nq = (int)
scan_ctl(filename, argc, argv,
"NQ", -1,
"0", NULL);
4641 ERRMSG(
"Too many quantities!");
4642 for (
int iq = 0; iq < ctl->
nq; iq++) {
4648 scan_ctl(filename, argc, argv,
"QNT_FORMAT", iq,
"%g",
4650 if (strcasecmp(ctl->
qnt_name[iq],
"aoa") == 0)
4654 SET_QNT(qnt_idx,
"idx",
"particle index",
"-")
4655 SET_QNT(qnt_ens,
"ens",
"ensemble index",
"-")
4656 SET_QNT(qnt_stat,
"stat",
"station flag",
"-")
4657 SET_QNT(qnt_m,
"m",
"mass",
"kg")
4658 SET_QNT(qnt_vmr,
"vmr",
"volume mixing ratio",
"ppv")
4659 SET_QNT(qnt_rp,
"rp",
"particle radius",
"microns")
4660 SET_QNT(qnt_rhop,
"rhop",
"particle density",
"kg/m^3")
4661 SET_QNT(qnt_ps,
"ps",
"surface pressure",
"hPa")
4662 SET_QNT(qnt_ts,
"ts",
"surface temperature",
"K")
4663 SET_QNT(qnt_zs,
"zs",
"surface height",
"km")
4664 SET_QNT(qnt_us,
"us",
"surface zonal wind",
"m/s")
4665 SET_QNT(qnt_vs,
"vs",
"surface meridional wind",
"m/s")
4666 SET_QNT(qnt_ess,
"ess",
"eastward turbulent surface stress",
"N/m^2")
4667 SET_QNT(qnt_nss,
"nss",
"northward turbulent surface stress",
"N/m^2")
4668 SET_QNT(qnt_shf,
"shf",
"surface sensible heat flux",
"W/m^2")
4669 SET_QNT(qnt_lsm,
"lsm",
"land-sea mask",
"1")
4670 SET_QNT(qnt_sst,
"sst",
"sea surface temperature",
"K")
4671 SET_QNT(qnt_pbl,
"pbl",
"planetary boundary layer",
"hPa")
4672 SET_QNT(qnt_pt,
"pt",
"tropopause pressure",
"hPa")
4673 SET_QNT(qnt_tt,
"tt",
"tropopause temperature",
"K")
4674 SET_QNT(qnt_zt,
"zt",
"tropopause geopotential height",
"km")
4675 SET_QNT(qnt_h2ot,
"h2ot",
"tropopause water vapor",
"ppv")
4676 SET_QNT(qnt_zg,
"zg",
"geopotential height",
"km")
4677 SET_QNT(qnt_p,
"p",
"pressure",
"hPa")
4678 SET_QNT(qnt_t,
"t",
"temperature",
"K")
4679 SET_QNT(qnt_rho,
"rho",
"air density",
"kg/m^3")
4680 SET_QNT(qnt_u,
"u",
"zonal wind",
"m/s")
4681 SET_QNT(qnt_v,
"v",
"meridional wind",
"m/s")
4682 SET_QNT(qnt_w,
"w",
"vertical velocity",
"hPa/s")
4683 SET_QNT(qnt_h2o,
"h2o",
"water vapor",
"ppv")
4684 SET_QNT(qnt_o3,
"o3",
"ozone",
"ppv")
4685 SET_QNT(qnt_lwc,
"lwc",
"cloud liquid water content",
"kg/kg")
4686 SET_QNT(qnt_rwc,
"rwc",
"cloud rain water content",
"kg/kg")
4687 SET_QNT(qnt_iwc,
"iwc",
"cloud ice water content",
"kg/kg")
4688 SET_QNT(qnt_swc,
"iwc",
"cloud snow water content",
"kg/kg")
4689 SET_QNT(qnt_cc,
"cc",
"cloud cover",
"1")
4690 SET_QNT(qnt_pct,
"pct",
"cloud top pressure",
"hPa")
4691 SET_QNT(qnt_pcb,
"pcb",
"cloud bottom pressure",
"hPa")
4692 SET_QNT(qnt_cl,
"cl",
"total column cloud water",
"kg/m^2")
4693 SET_QNT(qnt_plcl,
"plcl",
"lifted condensation level",
"hPa")
4694 SET_QNT(qnt_plfc,
"plfc",
"level of free convection",
"hPa")
4695 SET_QNT(qnt_pel,
"pel",
"equilibrium level",
"hPa")
4696 SET_QNT(qnt_cape,
"cape",
"convective available potential energy",
4698 SET_QNT(qnt_cin,
"cin",
"convective inhibition",
"J/kg")
4699 SET_QNT(qnt_o3c,
"o3c",
"total column ozone",
"DU")
4700 SET_QNT(qnt_hno3,
"hno3",
"nitric acid",
"ppv")
4701 SET_QNT(qnt_oh,
"oh",
"hydroxyl radical",
"ppv")
4702 SET_QNT(qnt_h2o2,
"h2o2",
"hydrogen peroxide",
"ppv")
4703 SET_QNT(qnt_ho2,
"ho2",
"hydroperoxyl radical",
"ppv")
4704 SET_QNT(qnt_o1d,
"o1d",
"atomic oxygen",
"ppv")
4705 SET_QNT(qnt_mloss_oh,
"mloss_oh",
"mass loss due to OH chemistry",
"kg")
4706 SET_QNT(qnt_mloss_h2o2,
"mloss_h2o2",
"mass loss due to H2O2 chemistry",
4708 SET_QNT(qnt_mloss_kpp,
"mloss_kpp",
"mass loss due to kpp chemistry",
4710 SET_QNT(qnt_mloss_wet,
"mloss_wet",
"mass loss due to wet deposition",
4712 SET_QNT(qnt_mloss_dry,
"mloss_dry",
"mass loss due to dry deposition",
4714 SET_QNT(qnt_mloss_decay,
"mloss_decay",
4715 "mass loss due to exponential decay",
"kg")
4716 SET_QNT(qnt_loss_rate,
"loss_rate",
"total loss rate",
"s^-1")
4717 SET_QNT(qnt_psat,
"psat",
"saturation pressure over water",
"hPa")
4718 SET_QNT(qnt_psice,
"psice",
"saturation pressure over ice",
"hPa")
4719 SET_QNT(qnt_pw,
"pw",
"partial water vapor pressure",
"hPa")
4720 SET_QNT(qnt_sh,
"sh",
"specific humidity",
"kg/kg")
4721 SET_QNT(qnt_rh,
"rh",
"relative humidity",
"%%")
4722 SET_QNT(qnt_rhice,
"rhice",
"relative humidity over ice",
"%%")
4723 SET_QNT(qnt_theta,
"theta",
"potential temperature",
"K")
4724 SET_QNT(qnt_zeta,
"zeta",
"zeta coordinate",
"K")
4725 SET_QNT(qnt_zeta_d,
"zeta_d",
"diagnosed zeta coordinate",
"K")
4726 SET_QNT(qnt_tvirt,
"tvirt",
"virtual temperature",
"K")
4727 SET_QNT(qnt_lapse,
"lapse",
"temperature lapse rate",
"K/km")
4728 SET_QNT(qnt_vh,
"vh",
"horizontal velocity",
"m/s")
4729 SET_QNT(qnt_vz,
"vz",
"vertical velocity",
"m/s")
4730 SET_QNT(qnt_pv,
"pv",
"potential vorticity",
"PVU")
4731 SET_QNT(qnt_tdew,
"tdew",
"dew point temperature",
"K")
4732 SET_QNT(qnt_tice,
"tice",
"frost point temperature",
"K")
4733 SET_QNT(qnt_tsts,
"tsts",
"STS existence temperature",
"K")
4734 SET_QNT(qnt_tnat,
"tnat",
"NAT existence temperature",
"K")
4735 SET_QNT(qnt_Cx,
"Cx",
"Trace species x volume mixing ratio",
"ppv")
4736 SET_QNT(qnt_Ch2o,
"Ch2o",
"H2O volume mixing ratio",
"ppv")
4737 SET_QNT(qnt_Co3,
"Co3",
"O3 volume mixing ratio",
"ppv")
4738 SET_QNT(qnt_Cco,
"Cco",
"CO volume mixing ratio",
"ppv")
4739 SET_QNT(qnt_Coh,
"Coh",
"HO volume mixing ratio",
"ppv")
4740 SET_QNT(qnt_Ch,
"Ch",
"H radical volume mixing ratio",
"ppv")
4741 SET_QNT(qnt_Cho2,
"Cho2",
"HO2 volume mixing ratio",
"ppv")
4742 SET_QNT(qnt_Ch2o2,
"Ch2o2",
"H2O2 volume mixing ratio",
"ppv")
4743 SET_QNT(qnt_Co1d,
"Co1d",
"O(1D) volume mixing ratio",
"ppv")
4744 SET_QNT(qnt_Co3p,
"Co3p",
"O(3P) radical volume mixing ratio",
"ppv")
4745 SET_QNT(qnt_Cccl4,
"Cccl4",
"CCl4 (CFC-10) volume mixing ratio",
"ppv")
4746 SET_QNT(qnt_Cccl3f,
"Cccl3f",
"CCl3F (CFC-11) volume mixing ratio",
4748 SET_QNT(qnt_Cccl2f2,
"Cccl2f2",
"CCl2F2 (CFC-12) volume mixing ratio",
4750 SET_QNT(qnt_Cn2o,
"Cn2o",
"N2O volume mixing ratio",
"ppv")
4751 SET_QNT(qnt_Csf6,
"Csf6",
"SF6 volume mixing ratio",
"ppv")
4752 SET_QNT(qnt_aoa,
"aoa",
"age of air",
"s")
4758 (int)
scan_ctl(filename, argc, argv,
"ADVECT_VERT_COORD", -1,
"0", NULL);
4760 ERRMSG(
"Set advect_vert_coord to 0, 1, or 2!");
4762 ERRMSG(
"Please add zeta to your quantities for diabatic calculations!");
4764 (int)
scan_ctl(filename, argc, argv,
"MET_VERT_COORD", -1,
"0", NULL);
4766 ERRMSG(
"Set MET_VERT_COORD to 0, 1, or 2!");
4769 (
"Using ADVECT_VERT_COORD = 2 requires meteo data on model levels!");
4773 (int)
scan_ctl(filename, argc, argv,
"DIRECTION", -1,
"1", NULL);
4775 ERRMSG(
"Set DIRECTION to -1 or 1!");
4776 ctl->
t_stop =
scan_ctl(filename, argc, argv,
"T_STOP", -1,
"1e100", NULL);
4777 ctl->
dt_mod =
scan_ctl(filename, argc, argv,
"DT_MOD", -1,
"180", NULL);
4781 ctl->
dt_met =
scan_ctl(filename, argc, argv,
"DT_MET", -1,
"3600", NULL);
4783 (int)
scan_ctl(filename, argc, argv,
"MET_CONVENTION", -1,
"0", NULL);
4785 (int)
scan_ctl(filename, argc, argv,
"MET_TYPE", -1,
"0", NULL);
4788 (
"Please use meteorological files in netcdf format for diabatic calculations.");
4790 (int)
scan_ctl(filename, argc, argv,
"MET_CLAMS", -1,
"0", NULL);
4792 (int)
scan_ctl(filename, argc, argv,
"MET_NC_SCALE", -1,
"1", NULL);
4794 (int)
scan_ctl(filename, argc, argv,
"MET_NC_LEVEL", -1,
"0", NULL);
4796 (int)
scan_ctl(filename, argc, argv,
"MET_NC_QUANT", -1,
"0", NULL);
4798 (int)
scan_ctl(filename, argc, argv,
"MET_ZFP_PREC", -1,
"8", NULL);
4800 scan_ctl(filename, argc, argv,
"MET_ZFP_TOL_T", -1,
"5.0", NULL);
4802 scan_ctl(filename, argc, argv,
"MET_ZFP_TOL_Z", -1,
"0.5", NULL);
4804 (int)
scan_ctl(filename, argc, argv,
"MET_CMS_BATCH", -1,
"-1", NULL);
4806 (int)
scan_ctl(filename, argc, argv,
"MET_CMS_HEUR", -1,
"1", NULL);
4808 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_Z", -1,
"1.0", NULL);
4810 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_T", -1,
"0.05", NULL);
4812 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_U", -1,
"0.05", NULL);
4814 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_V", -1,
"0.05", NULL);
4816 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_W", -1,
"1.0", NULL);
4818 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_PV", -1,
"1.0", NULL);
4820 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_H2O", -1,
"1.0", NULL);
4822 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_O3", -1,
"1.0", NULL);
4824 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_LWC", -1,
"1.0", NULL);
4826 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_RWC", -1,
"1.0", NULL);
4828 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_IWC", -1,
"1.0", NULL);
4830 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_SWC", -1,
"1.0", NULL);
4832 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_CC", -1,
"1.0", NULL);
4833 ctl->
met_dx = (int)
scan_ctl(filename, argc, argv,
"MET_DX", -1,
"1", NULL);
4834 ctl->
met_dy = (int)
scan_ctl(filename, argc, argv,
"MET_DY", -1,
"1", NULL);
4835 ctl->
met_dp = (int)
scan_ctl(filename, argc, argv,
"MET_DP", -1,
"1", NULL);
4837 ERRMSG(
"MET_DX, MET_DY, and MET_DP need to be greater than zero!");
4838 ctl->
met_sx = (int)
scan_ctl(filename, argc, argv,
"MET_SX", -1,
"1", NULL);
4839 ctl->
met_sy = (int)
scan_ctl(filename, argc, argv,
"MET_SY", -1,
"1", NULL);
4840 ctl->
met_sp = (int)
scan_ctl(filename, argc, argv,
"MET_SP", -1,
"1", NULL);
4842 ERRMSG(
"MET_SX, MET_SY, and MET_SP need to be greater than zero!");
4844 scan_ctl(filename, argc, argv,
"MET_DETREND", -1,
"-999", NULL);
4845 ctl->
met_np = (int)
scan_ctl(filename, argc, argv,
"MET_NP", -1,
"0", NULL);
4847 ERRMSG(
"Too many levels!");
4849 (int)
scan_ctl(filename, argc, argv,
"MET_PRESS_LEVEL_DEF", -1,
"-1",
4855 for (
int ip = 0; ip < ctl->
met_np; ip++)
4857 scan_ctl(filename, argc, argv,
"MET_P", ip,
"", NULL);
4861 (int)
scan_ctl(filename, argc, argv,
"MET_GEOPOT_SX", -1,
"-1", NULL);
4863 (int)
scan_ctl(filename, argc, argv,
"MET_GEOPOT_SY", -1,
"-1", NULL);
4865 (int)
scan_ctl(filename, argc, argv,
"MET_RELHUM", -1,
"0", NULL);
4867 (int)
scan_ctl(filename, argc, argv,
"MET_CAPE", -1,
"1", NULL);
4869 ERRMSG(
"Set MET_CAPE to 0 or 1!");
4871 (int)
scan_ctl(filename, argc, argv,
"MET_PBL", -1,
"3", NULL);
4873 ERRMSG(
"Set MET_PBL to 0 ... 3!");
4875 scan_ctl(filename, argc, argv,
"MET_PBL_MIN", -1,
"0.1", NULL);
4877 scan_ctl(filename, argc, argv,
"MET_PBL_MAX", -1,
"5.0", NULL);
4879 (int)
scan_ctl(filename, argc, argv,
"MET_TROPO", -1,
"3", NULL);
4881 ERRMSG(
"Set MET_TROPO to 0 ... 5!");
4883 scan_ctl(filename, argc, argv,
"MET_TROPO_PV", -1,
"3.5", NULL);
4885 scan_ctl(filename, argc, argv,
"MET_TROPO_THETA", -1,
"380", NULL);
4887 (int)
scan_ctl(filename, argc, argv,
"MET_TROPO_SPLINE", -1,
"1", NULL);
4889 scan_ctl(filename, argc, argv,
"MET_DT_OUT", -1,
"0.1", NULL);
4891 (int)
scan_ctl(filename, argc, argv,
"MET_CACHE", -1,
"0", NULL);
4893 (int)
scan_ctl(filename, argc, argv,
"MET_MPI_SHARE", -1,
"0", NULL);
4896 ctl->
sort_dt =
scan_ctl(filename, argc, argv,
"SORT_DT", -1,
"-999", NULL);
4900 (int)
scan_ctl(filename, argc, argv,
"ISOSURF", -1,
"0", NULL);
4905 (int)
scan_ctl(filename, argc, argv,
"RNG_TYPE", -1,
"1", NULL);
4907 ERRMSG(
"Set RNG_TYPE to 0, 1, or 2!");
4910 ctl->
advect = (int)
scan_ctl(filename, argc, argv,
"ADVECT", -1,
"2", NULL);
4913 ERRMSG(
"Set ADVECT to 0, 1, 2, or 4!");
4917 = (int)
scan_ctl(filename, argc, argv,
"DIFFUSION", -1,
"0", NULL);
4919 ERRMSG(
"Set DIFFUSION to 0, 1 or 2!");
4921 scan_ctl(filename, argc, argv,
"TURB_DX_PBL", -1,
"50", NULL);
4923 scan_ctl(filename, argc, argv,
"TURB_DX_TROP", -1,
"50", NULL);
4925 scan_ctl(filename, argc, argv,
"TURB_DX_STRAT", -1,
"0", NULL);
4927 scan_ctl(filename, argc, argv,
"TURB_DZ_PBL", -1,
"0", NULL);
4929 scan_ctl(filename, argc, argv,
"TURB_DZ_TROP", -1,
"0", NULL);
4931 scan_ctl(filename, argc, argv,
"TURB_DZ_STRAT", -1,
"0.1", NULL);
4933 scan_ctl(filename, argc, argv,
"TURB_MESOX", -1,
"0.16", NULL);
4935 scan_ctl(filename, argc, argv,
"TURB_MESOZ", -1,
"0.16", NULL);
4939 = (int)
scan_ctl(filename, argc, argv,
"CONV_MIX_PBL", -1,
"0", NULL);
4941 =
scan_ctl(filename, argc, argv,
"CONV_PBL_TRANS", -1,
"0", NULL);
4943 =
scan_ctl(filename, argc, argv,
"CONV_CAPE", -1,
"-999", NULL);
4945 =
scan_ctl(filename, argc, argv,
"CONV_CIN", -1,
"-999", NULL);
4946 ctl->
conv_dt =
scan_ctl(filename, argc, argv,
"CONV_DT", -1,
"-999", NULL);
4950 scan_ctl(filename, argc, argv,
"BOUND_MASS", -1,
"-999", NULL);
4952 scan_ctl(filename, argc, argv,
"BOUND_MASS_TREND", -1,
"0", NULL);
4954 scan_ctl(filename, argc, argv,
"BOUND_VMR", -1,
"-999", NULL);
4956 scan_ctl(filename, argc, argv,
"BOUND_VMR_TREND", -1,
"0", NULL);
4958 scan_ctl(filename, argc, argv,
"BOUND_LAT0", -1,
"-999", NULL);
4960 scan_ctl(filename, argc, argv,
"BOUND_LAT1", -1,
"-999", NULL);
4962 scan_ctl(filename, argc, argv,
"BOUND_P0", -1,
"-999", NULL);
4964 scan_ctl(filename, argc, argv,
"BOUND_P1", -1,
"-999", NULL);
4966 scan_ctl(filename, argc, argv,
"BOUND_DPS", -1,
"-999", NULL);
4968 scan_ctl(filename, argc, argv,
"BOUND_DZS", -1,
"-999", NULL);
4970 scan_ctl(filename, argc, argv,
"BOUND_ZETAS", -1,
"-999", NULL);
4972 (int)
scan_ctl(filename, argc, argv,
"BOUND_PBL", -1,
"0", NULL);
4976 if (strcasecmp(ctl->
species,
"CF2Cl2") == 0) {
4980 }
else if (strcasecmp(ctl->
species,
"CFCl3") == 0) {
4984 }
else if (strcasecmp(ctl->
species,
"CH4") == 0) {
4991 }
else if (strcasecmp(ctl->
species,
"CO") == 0) {
5000 }
else if (strcasecmp(ctl->
species,
"CO2") == 0) {
5004 }
else if (strcasecmp(ctl->
species,
"H2O") == 0) {
5006 }
else if (strcasecmp(ctl->
species,
"N2O") == 0) {
5010 }
else if (strcasecmp(ctl->
species,
"NH3") == 0) {
5017 }
else if (strcasecmp(ctl->
species,
"HNO3") == 0) {
5021 }
else if (strcasecmp(ctl->
species,
"NO") == 0) {
5030 }
else if (strcasecmp(ctl->
species,
"NO2") == 0) {
5039 }
else if (strcasecmp(ctl->
species,
"O3") == 0) {
5046 }
else if (strcasecmp(ctl->
species,
"SF6") == 0) {
5050 }
else if (strcasecmp(ctl->
species,
"SO2") == 0) {
5063 sprintf(defstr,
"%g", ctl->
molmass);
5064 ctl->
molmass =
scan_ctl(filename, argc, argv,
"MOLMASS", -1, defstr, NULL);
5069 (int)
scan_ctl(filename, argc, argv,
"OH_CHEM_REACTION", -1, defstr,
5071 for (
int ip = 0; ip < 4; ip++) {
5072 sprintf(defstr,
"%g", ctl->
oh_chem[ip]);
5074 scan_ctl(filename, argc, argv,
"OH_CHEM", ip, defstr, NULL);
5077 scan_ctl(filename, argc, argv,
"OH_CHEM_BETA", -1,
"0", NULL);
5081 (int)
scan_ctl(filename, argc, argv,
"H2O2_CHEM_REACTION", -1,
"0", NULL);
5085 (int)
scan_ctl(filename, argc, argv,
"KPP_CHEM", -1,
"0", NULL);
5086 ctl->
dt_kpp =
scan_ctl(filename, argc, argv,
"DT_KPP", -1,
"1800", NULL);
5090 (int)
scan_ctl(filename, argc, argv,
"TRACER_CHEM", -1,
"0", NULL);
5093 for (
int ip = 0; ip < 2; ip++) {
5096 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_H", ip, defstr, NULL);
5098 for (
int ip = 0; ip < 1; ip++) {
5101 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_H", ip, defstr, NULL);
5104 scan_ctl(filename, argc, argv,
"WET_DEPO_SO2_PH", -1,
"0", NULL);
5106 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_A", -1,
"0", NULL);
5108 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_B", -1,
"0", NULL);
5110 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_A", -1,
"0", NULL);
5112 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_B", -1,
"0", NULL);
5114 scan_ctl(filename, argc, argv,
"WET_DEPO_PRE", 0,
"0.5", NULL);
5116 scan_ctl(filename, argc, argv,
"WET_DEPO_PRE", 1,
"0.36", NULL);
5118 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_RET_RATIO", -1,
"1", NULL);
5120 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_RET_RATIO", -1,
"1", NULL);
5124 scan_ctl(filename, argc, argv,
"DRY_DEPO_VDEP", -1,
"0", NULL);
5126 scan_ctl(filename, argc, argv,
"DRY_DEPO_DP", -1,
"30", NULL);
5129 scan_ctl(filename, argc, argv,
"CLIM_PHOTO", -1,
5130 "../../data/clams_photolysis_rates.nc", ctl->
clim_photo);
5131 scan_ctl(filename, argc, argv,
"CLIM_HNO3_FILENAME", -1,
5133 scan_ctl(filename, argc, argv,
"CLIM_OH_FILENAME", -1,
5135 scan_ctl(filename, argc, argv,
"CLIM_H2O2_FILENAME", -1,
5137 scan_ctl(filename, argc, argv,
"CLIM_HO2_FILENAME", -1,
5139 scan_ctl(filename, argc, argv,
"CLIM_O1D_FILENAME", -1,
5141 scan_ctl(filename, argc, argv,
"CLIM_CCL4_TIMESERIES", -1,
5143 scan_ctl(filename, argc, argv,
"CLIM_CCL3F_TIMESERIES", -1,
5145 scan_ctl(filename, argc, argv,
"CLIM_CCL2F2_TIMESERIES", -1,
5147 scan_ctl(filename, argc, argv,
"CLIM_N2O_TIMESERIES", -1,
5149 scan_ctl(filename, argc, argv,
"CLIM_SF6_TIMESERIES", -1,
5154 scan_ctl(filename, argc, argv,
"MIXING_DT", -1,
"3600.", NULL);
5156 scan_ctl(filename, argc, argv,
"MIXING_TROP", -1,
"-999", NULL);
5158 scan_ctl(filename, argc, argv,
"MIXING_STRAT", -1,
"-999", NULL);
5160 scan_ctl(filename, argc, argv,
"MIXING_Z0", -1,
"-5", NULL);
5162 scan_ctl(filename, argc, argv,
"MIXING_Z1", -1,
"85", NULL);
5164 (int)
scan_ctl(filename, argc, argv,
"MIXING_NZ", -1,
"90", NULL);
5166 scan_ctl(filename, argc, argv,
"MIXING_LON0", -1,
"-180", NULL);
5168 scan_ctl(filename, argc, argv,
"MIXING_LON1", -1,
"180", NULL);
5170 (int)
scan_ctl(filename, argc, argv,
"MIXING_NX", -1,
"360", NULL);
5172 scan_ctl(filename, argc, argv,
"MIXING_LAT0", -1,
"-90", NULL);
5174 scan_ctl(filename, argc, argv,
"MIXING_LAT1", -1,
"90", NULL);
5176 (int)
scan_ctl(filename, argc, argv,
"MIXING_NY", -1,
"180", NULL);
5180 scan_ctl(filename, argc, argv,
"CHEMGRID_Z0", -1,
"-5", NULL);
5182 scan_ctl(filename, argc, argv,
"CHEMGRID_Z1", -1,
"85", NULL);
5184 (int)
scan_ctl(filename, argc, argv,
"CHEMGRID_NZ", -1,
"90", NULL);
5186 scan_ctl(filename, argc, argv,
"CHEMGRID_LON0", -1,
"-180", NULL);
5188 scan_ctl(filename, argc, argv,
"CHEMGRID_LON1", -1,
"180", NULL);
5190 (int)
scan_ctl(filename, argc, argv,
"CHEMGRID_NX", -1,
"360", NULL);
5192 scan_ctl(filename, argc, argv,
"CHEMGRID_LAT0", -1,
"-90", NULL);
5194 scan_ctl(filename, argc, argv,
"CHEMGRID_LAT1", -1,
"90", NULL);
5196 (int)
scan_ctl(filename, argc, argv,
"CHEMGRID_NY", -1,
"180", NULL);
5201 =
scan_ctl(filename, argc, argv,
"TDEC_STRAT", -1,
"0", NULL);
5204 ctl->
psc_h2o =
scan_ctl(filename, argc, argv,
"PSC_H2O", -1,
"4e-6", NULL);
5206 scan_ctl(filename, argc, argv,
"PSC_HNO3", -1,
"9e-9", NULL);
5212 scan_ctl(filename, argc, argv,
"ATM_DT_OUT", -1,
"86400", NULL);
5214 (int)
scan_ctl(filename, argc, argv,
"ATM_FILTER", -1,
"0", NULL);
5216 (int)
scan_ctl(filename, argc, argv,
"ATM_STRIDE", -1,
"1", NULL);
5218 (int)
scan_ctl(filename, argc, argv,
"ATM_TYPE", -1,
"0", NULL);
5220 (int)
scan_ctl(filename, argc, argv,
"ATM_TYPE_OUT", -1,
"-1", NULL);
5224 (int)
scan_ctl(filename, argc, argv,
"ATM_NC_LEVEL", -1,
"0", NULL);
5225 for (
int iq = 0; iq < ctl->
nq; iq++)
5227 (
int)
scan_ctl(filename, argc, argv,
"ATM_NC_QUANT", iq,
"0", NULL);
5229 (int)
scan_ctl(filename, argc, argv,
"OBS_TYPE", -1,
"0", NULL);
5235 scan_ctl(filename, argc, argv,
"CSI_DT_OUT", -1,
"86400", NULL);
5238 scan_ctl(filename, argc, argv,
"CSI_OBSMIN", -1,
"0", NULL);
5240 scan_ctl(filename, argc, argv,
"CSI_MODMIN", -1,
"0", NULL);
5241 ctl->
csi_z0 =
scan_ctl(filename, argc, argv,
"CSI_Z0", -1,
"-5", NULL);
5242 ctl->
csi_z1 =
scan_ctl(filename, argc, argv,
"CSI_Z1", -1,
"85", NULL);
5243 ctl->
csi_nz = (int)
scan_ctl(filename, argc, argv,
"CSI_NZ", -1,
"1", NULL);
5245 scan_ctl(filename, argc, argv,
"CSI_LON0", -1,
"-180", NULL);
5246 ctl->
csi_lon1 =
scan_ctl(filename, argc, argv,
"CSI_LON1", -1,
"180", NULL);
5248 (int)
scan_ctl(filename, argc, argv,
"CSI_NX", -1,
"360", NULL);
5249 ctl->
csi_lat0 =
scan_ctl(filename, argc, argv,
"CSI_LAT0", -1,
"-90", NULL);
5250 ctl->
csi_lat1 =
scan_ctl(filename, argc, argv,
"CSI_LAT1", -1,
"90", NULL);
5252 (int)
scan_ctl(filename, argc, argv,
"CSI_NY", -1,
"180", NULL);
5257 scan_ctl(filename, argc, argv,
"ENS_DT_OUT", -1,
"86400", NULL);
5260 scan_ctl(filename, argc, argv,
"GRID_BASENAME", -1,
"-",
5265 scan_ctl(filename, argc, argv,
"GRID_DT_OUT", -1,
"86400", NULL);
5267 (int)
scan_ctl(filename, argc, argv,
"GRID_SPARSE", -1,
"0", NULL);
5269 (int)
scan_ctl(filename, argc, argv,
"GRID_NC_LEVEL", -1,
"0", NULL);
5270 for (
int iq = 0; iq < ctl->
nq; iq++)
5272 (
int)
scan_ctl(filename, argc, argv,
"GRID_NC_QUANT", iq,
"0", NULL);
5274 (int)
scan_ctl(filename, argc, argv,
"GRID_STDDEV", -1,
"0", NULL);
5275 ctl->
grid_z0 =
scan_ctl(filename, argc, argv,
"GRID_Z0", -1,
"-5", NULL);
5276 ctl->
grid_z1 =
scan_ctl(filename, argc, argv,
"GRID_Z1", -1,
"85", NULL);
5278 (int)
scan_ctl(filename, argc, argv,
"GRID_NZ", -1,
"1", NULL);
5280 scan_ctl(filename, argc, argv,
"GRID_LON0", -1,
"-180", NULL);
5282 scan_ctl(filename, argc, argv,
"GRID_LON1", -1,
"180", NULL);
5284 (int)
scan_ctl(filename, argc, argv,
"GRID_NX", -1,
"360", NULL);
5286 scan_ctl(filename, argc, argv,
"GRID_LAT0", -1,
"-90", NULL);
5288 scan_ctl(filename, argc, argv,
"GRID_LAT1", -1,
"90", NULL);
5290 (int)
scan_ctl(filename, argc, argv,
"GRID_NY", -1,
"180", NULL);
5292 (int)
scan_ctl(filename, argc, argv,
"GRID_TYPE", -1,
"0", NULL);
5295 scan_ctl(filename, argc, argv,
"PROF_BASENAME", -1,
"-",
5298 ctl->
prof_z0 =
scan_ctl(filename, argc, argv,
"PROF_Z0", -1,
"0", NULL);
5299 ctl->
prof_z1 =
scan_ctl(filename, argc, argv,
"PROF_Z1", -1,
"60", NULL);
5301 (int)
scan_ctl(filename, argc, argv,
"PROF_NZ", -1,
"60", NULL);
5303 scan_ctl(filename, argc, argv,
"PROF_LON0", -1,
"-180", NULL);
5305 scan_ctl(filename, argc, argv,
"PROF_LON1", -1,
"180", NULL);
5307 (int)
scan_ctl(filename, argc, argv,
"PROF_NX", -1,
"360", NULL);
5309 scan_ctl(filename, argc, argv,
"PROF_LAT0", -1,
"-90", NULL);
5311 scan_ctl(filename, argc, argv,
"PROF_LAT1", -1,
"90", NULL);
5313 (int)
scan_ctl(filename, argc, argv,
"PROF_NY", -1,
"180", NULL);
5316 scan_ctl(filename, argc, argv,
"SAMPLE_BASENAME", -1,
"-",
5318 scan_ctl(filename, argc, argv,
"SAMPLE_KERNEL", -1,
"-",
5320 scan_ctl(filename, argc, argv,
"SAMPLE_OBSFILE", -1,
"-",
5323 scan_ctl(filename, argc, argv,
"SAMPLE_DX", -1,
"50", NULL);
5325 scan_ctl(filename, argc, argv,
"SAMPLE_DZ", -1,
"-999", NULL);
5328 scan_ctl(filename, argc, argv,
"STAT_BASENAME", -1,
"-",
5332 ctl->
stat_r =
scan_ctl(filename, argc, argv,
"STAT_R", -1,
"50", NULL);
5334 scan_ctl(filename, argc, argv,
"STAT_T0", -1,
"-1e100", NULL);
5335 ctl->
stat_t1 =
scan_ctl(filename, argc, argv,
"STAT_T1", -1,
"1e100", NULL);
5340 scan_ctl(filename, argc, argv,
"VTK_DT_OUT", -1,
"86400", NULL);
5342 (int)
scan_ctl(filename, argc, argv,
"VTK_STRIDE", -1,
"1", NULL);
5344 scan_ctl(filename, argc, argv,
"VTK_SCALE", -1,
"1.0", NULL);
5346 scan_ctl(filename, argc, argv,
"VTK_OFFSET", -1,
"0.0", NULL);
5348 (int)
scan_ctl(filename, argc, argv,
"VTK_SPHERE", -1,
"0", NULL);
5354 const char *filename,
5360 LOG(1,
"Read meteo data: %s", filename);
5366 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
5386 ERRMSG(
"MET_TYPE not implemented!");
5395 LOG(2,
"Broadcast data on rank %d...", rank);
5524 ERRMSG(
"Code was compiled without KPP!");
5557#pragma acc update device(ctl[:1])
5561 if (cache != NULL) {
5564#pragma acc update device(cache[:1])
5571#pragma acc update device(clim[:1])
5578 met_t *met0up = *met0;
5579#pragma acc update device(met0up[:1])
5586 met_t *met1up = *met1;
5587#pragma acc update device(met1up[:1])
5594#pragma acc update device(atm[:1])
5613#pragma acc update host(ctl[:1])
5617 if (cache != NULL) {
5620#pragma acc update host(cache[:1])
5627#pragma acc update host(clim[:1])
5634 met_t *met0up = *met0;
5635#pragma acc update host(met0up[:1])
5642 met_t *met1up = *met1;
5643#pragma acc update host(met1up[:1])
5650#pragma acc update host(atm[:1])
5658 const char *filename,
5667 LOG(1,
"Write atmospheric data: %s", filename);
5691 ERRMSG(
"Atmospheric data type not supported!");
5695 LOG(2,
"Number of particles: %d", atm->
np);
5696 gsl_stats_minmax(&mini, &maxi, atm->
time, 1, (
size_t) atm->
np);
5697 LOG(2,
"Time range: %.2f ... %.2f s", mini, maxi);
5698 gsl_stats_minmax(&mini, &maxi, atm->
p, 1, (
size_t) atm->
np);
5699 LOG(2,
"Altitude range: %g ... %g km",
Z(maxi),
Z(mini));
5700 LOG(2,
"Pressure range: %g ... %g hPa", maxi, mini);
5701 gsl_stats_minmax(&mini, &maxi, atm->
lon, 1, (
size_t) atm->
np);
5702 LOG(2,
"Longitude range: %g ... %g deg", mini, maxi);
5703 gsl_stats_minmax(&mini, &maxi, atm->
lat, 1, (
size_t) atm->
np);
5704 LOG(2,
"Latitude range: %g ... %g deg", mini, maxi);
5705 for (
int iq = 0; iq < ctl->
nq; iq++) {
5707 sprintf(msg,
"Quantity %s range: %s ... %s %s",
5710 gsl_stats_minmax(&mini, &maxi, atm->
q[iq], 1, (
size_t) atm->
np);
5711 LOG(2, msg, mini, maxi);
5718 const char *filename,
5726 LOG(1,
"Write meteo data: %s", filename);
5731 ERRMSG(
"MPTRAC was compiled without zfp compression!");
5735 ERRMSG(
"MPTRAC was compiled without zstd compression!");
5739 ERRMSG(
"MPTRAC was compiled without cmultiscale compression!");
5752 ERRMSG(
"MET_TYPE not implemented!");
5758 const char *dirname,
5765 char ext[10], filename[2 *
LEN];
5769 int year, mon, day, hour, min, sec;
5772 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
5787 sprintf(ext,
"tab");
5789 sprintf(ext,
"bin");
5792 sprintf(filename,
"%s/%s_%04d_%02d_%02d_%02d_%02d.%s",
5793 dirname, ctl->
atm_basename, year, mon, day, hour, min, ext);
5799 sprintf(filename,
"%s/%s_%04d_%02d_%02d_%02d_%02d.%s",
5802 write_grid(filename, ctl, met0, met1, atm, t);
5807 sprintf(filename,
"%s/%s.tab", dirname, ctl->
csi_basename);
5813 sprintf(filename,
"%s/%s_%04d_%02d_%02d_%02d_%02d.tab",
5814 dirname, ctl->
ens_basename, year, mon, day, hour, min);
5820 sprintf(filename,
"%s/%s.tab", dirname, ctl->
prof_basename);
5821 write_prof(filename, ctl, met0, met1, atm, t);
5832 sprintf(filename,
"%s/%s.tab", dirname, ctl->
stat_basename);
5841 sprintf(filename,
"%s/%s_%05d.vtk", dirname, ctl->
vtk_basename, ++nvtk);
5851 const double hno3) {
5854 const double h2o_help =
MAX(h2o, 0.1e-6);
5857 const double p_hno3 = hno3 * p / 1.333224;
5858 const double p_h2o = h2o_help * p / 1.333224;
5859 const double a = 0.009179 - 0.00088 * log10(p_h2o);
5860 const double b = (38.9855 - log10(p_hno3) - 2.7836 * log10(p_h2o)) / a;
5861 const double c = -11397.0 / a;
5862 double tnat = (-b + sqrt(b * b - 4. * c)) / 2.;
5863 double x2 = (-b - sqrt(b * b - 4. * c)) / 2.;
5881 const double p0 = pbl;
5884 if (atm->
p[ip] > p0)
5886 else if (atm->
p[ip] < p1)
5889 return LIN(p0, 1.0, p1, 0.0, atm->
p[ip]);
5895 const char *filename,
5901 if (!(in = fopen(filename,
"r"))) {
5902 WARN(
"Cannot open file!");
5908 while (fgets(line,
LEN, in)) {
5912 TOK(line, tok,
"%lg", atm->
time[atm->
np]);
5913 TOK(NULL, tok,
"%lg", atm->
p[atm->
np]);
5914 TOK(NULL, tok,
"%lg", atm->
lon[atm->
np]);
5915 TOK(NULL, tok,
"%lg", atm->
lat[atm->
np]);
5916 for (
int iq = 0; iq < ctl->
nq; iq++)
5917 TOK(NULL, tok,
"%lg", atm->
q[iq][atm->
np]);
5920 atm->
p[atm->
np] =
P(atm->
p[atm->
np]);
5923 if ((++atm->
np) >
NP)
5924 ERRMSG(
"Too many data points!");
5937 const char *filename,
5943 if (!(in = fopen(filename,
"r")))
5948 FREAD(&version,
int,
5952 ERRMSG(
"Wrong version of binary data!");
5970 for (
int iq = 0; iq < ctl->
nq; iq++)
5971 FREAD(atm->
q[iq],
double,
5981 ERRMSG(
"Error while reading binary data!");
5993 const char *filename,
6000 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR)
6007 if (nc_inq_varid(ncid,
"TIME_INIT", &varid) == NC_NOERR) {
6008 NC(nc_get_var_double(ncid, varid, atm->
time));
6010 WARN(
"TIME_INIT not found use time instead!");
6013 for (
int ip = 0; ip < atm->
np; ip++) {
6014 atm->
time[ip] = time_init;
6026 if (nc_inq_varid(ncid,
"PRESS_INIT", &varid) == NC_NOERR) {
6027 NC(nc_get_var_double(ncid, varid, atm->
p));
6029 WARN(
"PRESS_INIT not found use PRESS instead!");
6030 nc_inq_varid(ncid,
"PRESS", &varid);
6031 NC(nc_get_var_double(ncid, varid, atm->
p));
6049 const char *filename,
6056 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR)
6069 for (
int iq = 0; iq < ctl->
nq; iq++)
6082 const char *filename,
6088 LOG(1,
"Read photolysis rates: %s", filename);
6091 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
6092 WARN(
"Photolysis rate data are missing!");
6099 if (photo->
p[0] < photo->
p[1])
6100 ERRMSG(
"Pressure data are not descending!");
6105 if (photo->
o3c[0] > photo->
o3c[1])
6106 ERRMSG(
"Total column ozone data are not ascending!");
6111 if (photo->
sza[0] > photo->
sza[1])
6112 ERRMSG(
"Solar zenith angle data are not ascending!");
6129 LOG(2,
"Number of pressure levels: %d", photo->
np);
6130 LOG(2,
"Altitude levels: %g, %g ... %g km",
6131 Z(photo->
p[0]),
Z(photo->
p[1]),
Z(photo->
p[photo->
np - 1]));
6132 LOG(2,
"Pressure levels: %g, %g ... %g hPa",
6133 photo->
p[0], photo->
p[1], photo->
p[photo->
np - 1]);
6134 LOG(2,
"Number of solar zenith angles: %d", photo->
nsza);
6135 LOG(2,
"Solar zenith angles: %g, %g ... %g deg",
6138 LOG(2,
"Number of total column ozone values: %d", photo->
no3c);
6139 LOG(2,
"Total column ozone: %g, %g ... %g DU",
6141 LOG(2,
"N2O photolysis rate: %g, %g ... %g s**-1",
6142 photo->
n2o[0][0][0], photo->
n2o[1][0][0],
6143 photo->
n2o[photo->
np - 1][photo->
nsza - 1][photo->
no3c - 1]);
6144 LOG(2,
"CCl4 photolysis rate: %g, %g ... %g s**-1",
6145 photo->
ccl4[0][0][0], photo->
ccl4[1][0][0],
6147 LOG(2,
"CFC-11 photolysis rate: %g, %g ... %g s**-1",
6148 photo->
ccl3f[0][0][0], photo->
ccl3f[1][0][0],
6150 LOG(2,
"CFC-12 photolysis rate: %g, %g ... %g s**-1",
6153 LOG(2,
"O2 photolysis rate: %g, %g ... %g s**-1",
6154 photo->
o2[0][0][0], photo->
o2[1][0][0],
6155 photo->
o2[photo->
np - 1][photo->
nsza - 1][photo->
no3c - 1]);
6156 LOG(2,
"O3 -> O(1D) photolysis rate: %g, %g ... %g s**-1",
6157 photo->
o3_1[0][0][0], photo->
o3_1[1][0][0],
6159 LOG(2,
"O3 -> O(3P) photolysis rate: %g, %g ... %g s**-1",
6160 photo->
o3_2[0][0][0], photo->
o3_2[1][0][0],
6162 LOG(2,
"H2O2 photolysis rate: %g, %g ... %g s**-1",
6163 photo->
h2o2[0][0][0], photo->
h2o2[1][0][0],
6165 LOG(2,
"H2O photolysis rate: %g, %g ... %g s**-1",
6166 photo->
h2o[0][0][0], photo->
h2o[1][0][0],
6167 photo->
h2o[photo->
np - 1][photo->
nsza - 1][photo->
no3c - 1]);
6174 const char *varname,
6188 for (
int ip = 0; ip < photo->
np; ip++)
6189 for (
int is = 0; is < photo->
nsza; is++)
6190 for (
int io = 0; io < photo->
no3c; io++)
6201 const char *filename,
6205 LOG(1,
"Read climatological time series: %s", filename);
6209 if (!(in = fopen(filename,
"r"))) {
6210 WARN(
"Cannot open file!");
6217 while (fgets(line,
LEN, in))
6218 if (sscanf(line,
"%lg %lg", &ts->
time[nh], &ts->
vmr[nh]) == 2) {
6221 ts->
time[nh] = (ts->
time[nh] - 2000.0) * 365.25 * 86400.;
6224 if (nh > 0 && ts->
time[nh] <= ts->
time[nh - 1])
6225 ERRMSG(
"Time series must be ascending!");
6229 ERRMSG(
"Too many data points!");
6238 ERRMSG(
"Not enough data points!");
6241 LOG(2,
"Number of time steps: %d", ts->
ntime);
6242 LOG(2,
"Time steps: %.2f, %.2f ... %.2f s", ts->
time[0], ts->
time[1],
6244 LOG(2,
"Volume mixing ratio range: %g ... %g ppv",
6245 gsl_stats_min(ts->
vmr, 1, (
size_t) nh), gsl_stats_max(ts->
vmr, 1,
6255 const char *filename,
6256 const char *varname,
6259 int ncid, varid, it, iy, iz, iz2, nt;
6261 double *help, varmin = 1e99, varmax = -1e99;
6264 LOG(1,
"Read %s data: %s", varname, filename);
6267 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
6268 WARN(
"%s climatology data are missing!", varname);
6275 if (zm->
p[0] < zm->
p[1])
6276 ERRMSG(
"Pressure data are not descending!");
6281 if (zm->
lat[0] > zm->
lat[1])
6282 ERRMSG(
"Latitude data are not ascending!");
6286 zm->
time[0] = 1209600.00;
6287 zm->
time[1] = 3888000.00;
6288 zm->
time[2] = 6393600.00;
6289 zm->
time[3] = 9072000.00;
6290 zm->
time[4] = 11664000.00;
6291 zm->
time[5] = 14342400.00;
6292 zm->
time[6] = 16934400.00;
6293 zm->
time[7] = 19612800.00;
6294 zm->
time[8] = 22291200.00;
6295 zm->
time[9] = 24883200.00;
6296 zm->
time[10] = 27561600.00;
6297 zm->
time[11] = 30153600.00;
6306 for (it = 0; it < zm->
ntime; it++)
6307 for (iz = 0; iz < zm->
np; iz++)
6308 for (iy = 0; iy < zm->
nlat; iy++)
6313 for (it = 0; it < zm->
ntime; it++)
6314 for (iy = 0; iy < zm->
nlat; iy++)
6315 for (iz = 0; iz < zm->
np; iz++) {
6316 if (zm->
vmr[it][iz][iy] < 0) {
6317 for (iz2 = 0; iz2 < zm->
np; iz2++)
6318 if (zm->
vmr[it][iz2][iy] >= 0) {
6319 zm->
vmr[it][iz][iy] = zm->
vmr[it][iz2][iy];
6322 for (iz2 = zm->
np - 1; iz2 >= 0; iz2--)
6323 if (zm->
vmr[it][iz2][iy] >= 0) {
6324 zm->
vmr[it][iz][iy] = zm->
vmr[it][iz2][iy];
6328 varmin =
MIN(varmin, zm->
vmr[it][iz][iy]);
6329 varmax =
MAX(varmax, zm->
vmr[it][iz][iy]);
6336 LOG(2,
"Number of time steps: %d", zm->
ntime);
6337 LOG(2,
"Time steps: %.2f, %.2f ... %.2f s",
6339 LOG(2,
"Number of pressure levels: %d", zm->
np);
6340 LOG(2,
"Altitude levels: %g, %g ... %g km",
6341 Z(zm->
p[0]),
Z(zm->
p[1]),
Z(zm->
p[zm->
np - 1]));
6342 LOG(2,
"Pressure levels: %g, %g ... %g hPa", zm->
p[0],
6343 zm->
p[1], zm->
p[zm->
np - 1]);
6344 LOG(2,
"Number of latitudes: %d", zm->
nlat);
6345 LOG(2,
"Latitudes: %g, %g ... %g deg",
6347 LOG(2,
"%s volume mixing ratio range: %g ... %g ppv", varname, varmin,
6354 const char *filename,
6360 LOG(1,
"Read kernel function: %s", filename);
6364 if (!(in = fopen(filename,
"r")))
6365 ERRMSG(
"Cannot open file!");
6370 while (fgets(line,
LEN, in))
6371 if (sscanf(line,
"%lg %lg", &kz[n], &kw[n]) == 2) {
6372 if (n > 0 && kz[n] < kz[n - 1])
6373 ERRMSG(
"Height levels must be ascending!");
6375 ERRMSG(
"Too many height levels!");
6384 ERRMSG(
"Not enough height levels!");
6387 const double kmax = gsl_stats_max(kw, 1, (
size_t) n);
6388 for (
int iz = 0; iz < n; iz++)
6395 const char *filename,
6403 int year, mon, day, hour, min, sec;
6409 if (!(in = fopen(filename,
"r"))) {
6410 WARN(
"Cannot open file!");
6416 FREAD(&met_type,
int,
6420 ERRMSG(
"Wrong MET_TYPE of binary data!");
6424 FREAD(&version,
int,
6428 ERRMSG(
"Wrong version of binary data!");
6434 jsec2time(met->
time, &year, &mon, &day, &hour, &min, &sec, &r);
6435 LOG(2,
"Time: %.2f (%d-%02d-%02d, %02d:%02d UTC)",
6436 met->
time, year, mon, day, hour, min);
6437 if (year < 1900 || year > 2100 || mon < 1 || mon > 12
6438 || day < 1 || day > 31 || hour < 0 || hour > 23)
6439 ERRMSG(
"Error while reading time!");
6445 LOG(2,
"Number of longitudes: %d", met->
nx);
6446 if (met->
nx < 2 || met->
nx >
EX)
6447 ERRMSG(
"Number of longitudes out of range!");
6452 LOG(2,
"Number of latitudes: %d", met->
ny);
6453 if (met->
ny < 2 || met->
ny >
EY)
6454 ERRMSG(
"Number of latitudes out of range!");
6459 LOG(2,
"Number of levels: %d", met->
np);
6460 if (met->
np < 2 || met->
np >
EP)
6461 ERRMSG(
"Number of levels out of range!");
6467 LOG(2,
"Longitudes: %g, %g ... %g deg",
6473 LOG(2,
"Latitudes: %g, %g ... %g deg",
6479 LOG(2,
"Altitude levels: %g, %g ... %g km",
6480 Z(met->
p[0]),
Z(met->
p[1]),
Z(met->
p[met->
np - 1]));
6481 LOG(2,
"Pressure levels: %g, %g ... %g hPa",
6482 met->
p[0], met->
p[1], met->
p[met->
np - 1]);
6531 ERRMSG(
"Error while reading binary data!");
6546 const char *varname) {
6555 LOG(2,
"Read 2-D variable: %s (uncompressed)", varname);
6557 (
size_t) (met->
nx * met->
ny),
6561 for (
int ix = 0; ix < met->
nx; ix++)
6562 for (
int iy = 0; iy < met->
ny; iy++)
6563 var[ix][iy] = help[
ARRAY_2D(ix, iy, met->
ny)];
6576 const char *varname,
6577 const float bound_min,
6578 const float bound_max) {
6588 LOG(2,
"Read 3-D variable: %s (uncompressed)", varname);
6590 (
size_t) (met->
nx * met->
ny * met->
np),
6597 (
size_t) met->
np, 1, in);
6603 FREAD(&precision,
int,
6608 FREAD(&tolerance,
double,
6615 ERRMSG(
"MPTRAC was compiled without zfp compression!");
6625 ERRMSG(
"MPTRAC was compiled without zstd compression!");
6633 (
size_t) met->
np, 1, in);
6635 ERRMSG(
"MPTRAC was compiled without cmultiscale compression!");
6640#pragma omp parallel for default(shared) collapse(2)
6641 for (
int ix = 0; ix < met->
nx; ix++)
6642 for (
int iy = 0; iy < met->
ny; iy++)
6643 for (
int ip = 0; ip < met->
np; ip++) {
6644 var[ix][iy][ip] = help[
ARRAY_3D(ix, iy, met->
ny, ip, met->
np)];
6645 if (var[ix][iy][ip] < bound_min)
6646 var[ix][iy][ip] = bound_min;
6647 else if (var[ix][iy][ip] > bound_max)
6648 var[ix][iy][ip] = bound_max;
6668 LOG(2,
"Calculate CAPE...");
6671 const double pfac = 1.01439, dz0 =
RI /
MA /
G0 * log(pfac);
6674#pragma omp parallel for default(shared) collapse(2)
6675 for (
int ix = 0; ix < met->
nx; ix++)
6676 for (
int iy = 0; iy < met->
ny; iy++) {
6680 double h2o = 0, t, theta = 0;
6681 double pbot =
MIN(met->
ps[ix][iy], met->
p[0]);
6682 double ptop = pbot - 50.;
6683 for (
int ip = 0; ip < met->
np; ip++) {
6684 if (met->
p[ip] <= pbot) {
6685 theta +=
THETA(met->
p[ip], met->
t[ix][iy][ip]);
6686 h2o += met->
h2o[ix][iy][ip];
6689 if (met->
p[ip] < ptop && n > 0)
6696 met->
plcl[ix][iy] = NAN;
6697 met->
plfc[ix][iy] = NAN;
6698 met->
pel[ix][iy] = NAN;
6699 met->
cape[ix][iy] = NAN;
6700 met->
cin[ix][iy] = NAN;
6706 pbot = met->
ps[ix][iy];
6708 met->
plcl[ix][iy] = (float) (0.5 * (pbot + ptop));
6709 t = theta / pow(1000. / met->
plcl[ix][iy], 0.286);
6710 if (
RH(met->
plcl[ix][iy], t, h2o) > 100.)
6711 ptop = met->
plcl[ix][iy];
6713 pbot = met->
plcl[ix][iy];
6714 }
while (pbot - ptop > 0.1);
6718 double dcape, dz, h2o_env, t_env;
6719 double p = met->
ps[ix][iy];
6720 met->
cape[ix][iy] = met->
cin[ix][iy] = 0;
6722 dz = dz0 *
TVIRT(t, h2o);
6724 t = theta / pow(1000. / p, 0.286);
6728 &h2o_env, ci, cw, 0);
6729 dcape = 1e3 *
G0 * (
TVIRT(t, h2o) -
TVIRT(t_env, h2o_env)) /
6730 TVIRT(t_env, h2o_env) * dz;
6732 met->
cin[ix][iy] += fabsf((
float) dcape);
6733 }
while (p > met->
plcl[ix][iy]);
6738 p = met->
plcl[ix][iy];
6739 t = theta / pow(1000. / p, 0.286);
6742 dz = dz0 *
TVIRT(t, h2o);
6745 double psat =
PSAT(t);
6746 h2o = psat / (p - (1. -
EPS) * psat);
6750 &h2o_env, ci, cw, 0);
6751 double dcape_old = dcape;
6752 dcape = 1e3 *
G0 * (
TVIRT(t, h2o) -
TVIRT(t_env, h2o_env)) /
6753 TVIRT(t_env, h2o_env) * dz;
6755 met->
cape[ix][iy] += (float) dcape;
6756 if (!isfinite(met->
plfc[ix][iy]))
6757 met->
plfc[ix][iy] = (
float) p;
6758 }
else if (dcape_old > 0)
6759 met->
pel[ix][iy] = (float) p;
6760 if (dcape < 0 && !isfinite(met->
plfc[ix][iy]))
6761 met->
cin[ix][iy] += fabsf((
float) dcape);
6765 if (!isfinite(met->
plfc[ix][iy]))
6766 met->
cin[ix][iy] = NAN;
6777 LOG(2,
"Calculate cloud data...");
6780 const double ccmin = 0.01, cwmin = 1e-6;
6783#pragma omp parallel for default(shared) collapse(2)
6784 for (
int ix = 0; ix < met->
nx; ix++)
6785 for (
int iy = 0; iy < met->
ny; iy++) {
6788 met->
pct[ix][iy] = NAN;
6789 met->
pcb[ix][iy] = NAN;
6790 met->
cl[ix][iy] = 0;
6793 for (
int ip = 0; ip < met->
np - 1; ip++) {
6796 if (met->
p[ip] > met->
ps[ix][iy] || met->
p[ip] <
P(20.))
6800 if (met->
cc[ix][iy][ip] > ccmin
6801 && (met->
iwc[ix][iy][ip] > cwmin
6802 || met->
rwc[ix][iy][ip] > cwmin
6803 || met->
lwc[ix][iy][ip] > cwmin
6804 || met->
swc[ix][iy][ip] > cwmin)) {
6808 = (float) (0.5 * (met->
p[ip] + (
float) met->
p[ip + 1]));
6811 if (!isfinite(met->
pcb[ix][iy]))
6813 = (
float) (0.5 * (met->
p[ip] + met->
p[
MAX(ip - 1, 0)]));
6817 met->
cl[ix][iy] += (float)
6818 (0.5 * (met->
lwc[ix][iy][ip] + met->
lwc[ix][iy][ip + 1]
6819 + met->
rwc[ix][iy][ip] + met->
rwc[ix][iy][ip + 1]
6820 + met->
iwc[ix][iy][ip] + met->
iwc[ix][iy][ip + 1]
6821 + met->
swc[ix][iy][ip] + met->
swc[ix][iy][ip + 1])
6822 * 100. * (met->
p[ip] - met->
p[ip + 1]) /
G0);
6840 SELECT_TIMER(
"READ_MET_DETREND",
"METPROC", NVTX_READ);
6841 LOG(2,
"Detrend meteo data...");
6848 const double tssq = 2. *
SQR(sigma);
6851 int sy = (int) (3. *
DY2DEG(sigma) / fabs(met->
lat[1] - met->
lat[0]));
6855#pragma omp parallel for default(shared) collapse(2)
6856 for (
int ix = 0; ix < met->
nx; ix++) {
6857 for (
int iy = 0; iy < met->
ny; iy++) {
6865 (int) (3. *
DX2DEG(sigma, met->
lat[iy]) /
6866 fabs(met->
lon[1] - met->
lon[0]));
6871 for (
int ip = 0; ip < met->
np; ip++) {
6872 help->
t[ix][iy][ip] = 0;
6873 help->
u[ix][iy][ip] = 0;
6874 help->
v[ix][iy][ip] = 0;
6875 help->
w[ix][iy][ip] = 0;
6879 for (
int ix2 = ix - sx; ix2 <= ix + sx; ix2++) {
6883 else if (ix3 >= met->
nx)
6885 for (
int iy2 =
MAX(iy - sy, 0);
6886 iy2 <=
MIN(iy + sy, met->
ny - 1); iy2++) {
6893 const float w = (float) exp(-
DIST2(x0, x1) / tssq);
6897 for (
int ip = 0; ip < met->
np; ip++) {
6898 help->
t[ix][iy][ip] += w * met->
t[ix3][iy2][ip];
6899 help->
u[ix][iy][ip] += w * met->
u[ix3][iy2][ip];
6900 help->
v[ix][iy][ip] += w * met->
v[ix3][iy2][ip];
6901 help->
w[ix][iy][ip] += w * met->
w[ix3][iy2][ip];
6907 for (
int ip = 0; ip < met->
np; ip++) {
6908 help->
t[ix][iy][ip] /= wsum;
6909 help->
u[ix][iy][ip] /= wsum;
6910 help->
v[ix][iy][ip] /= wsum;
6911 help->
w[ix][iy][ip] /= wsum;
6917#pragma omp parallel for default(shared) collapse(3)
6918 for (
int ix = 0; ix < met->
nx; ix++)
6919 for (
int iy = 0; iy < met->
ny; iy++)
6920 for (
int ip = 0; ip < met->
np; ip++) {
6921 met->
t[ix][iy][ip] -= help->
t[ix][iy][ip];
6922 met->
u[ix][iy][ip] -= help->
u[ix][iy][ip];
6923 met->
v[ix][iy][ip] -= help->
v[ix][iy][ip];
6924 met->
w[ix][iy][ip] -= help->
w[ix][iy][ip];
6937 SELECT_TIMER(
"READ_MET_EXTRAPOLATE",
"METPROC", NVTX_READ);
6938 LOG(2,
"Extrapolate meteo data...");
6941#pragma omp parallel for default(shared) collapse(2)
6942 for (
int ix = 0; ix < met->
nx; ix++)
6943 for (
int iy = 0; iy < met->
ny; iy++) {
6947 for (ip0 = met->
np - 1; ip0 >= 0; ip0--)
6948 if (!isfinite(met->
t[ix][iy][ip0])
6949 || !isfinite(met->
u[ix][iy][ip0])
6950 || !isfinite(met->
v[ix][iy][ip0])
6951 || !isfinite(met->
w[ix][iy][ip0]))
6955 for (
int ip = ip0; ip >= 0; ip--) {
6956 met->
t[ix][iy][ip] = met->
t[ix][iy][ip + 1];
6957 met->
u[ix][iy][ip] = met->
u[ix][iy][ip + 1];
6958 met->
v[ix][iy][ip] = met->
v[ix][iy][ip + 1];
6959 met->
w[ix][iy][ip] = met->
w[ix][iy][ip + 1];
6960 met->
h2o[ix][iy][ip] = met->
h2o[ix][iy][ip + 1];
6961 met->
o3[ix][iy][ip] = met->
o3[ix][iy][ip + 1];
6962 met->
lwc[ix][iy][ip] = met->
lwc[ix][iy][ip + 1];
6963 met->
rwc[ix][iy][ip] = met->
rwc[ix][iy][ip + 1];
6964 met->
iwc[ix][iy][ip] = met->
iwc[ix][iy][ip + 1];
6965 met->
swc[ix][iy][ip] = met->
swc[ix][iy][ip + 1];
6966 met->
cc[ix][iy][ip] = met->
cc[ix][iy][ip + 1];
6985 LOG(2,
"Calculate geopotential heights...");
6992#pragma omp parallel for default(shared)
6993 for (
int ip = 0; ip < met->
np; ip++)
6994 logp[ip] = log(met->
p[ip]);
6997#pragma omp parallel for default(shared) collapse(2)
6998 for (
int ix = 0; ix < met->
nx; ix++)
6999 for (
int iy = 0; iy < met->
ny; iy++) {
7002 const double zs = met->
zs[ix][iy];
7003 const double lnps = log(met->
ps[ix][iy]);
7007 const double ts =
LIN(met->
p[ip0], met->
t[ix][iy][ip0], met->
p[ip0 + 1],
7008 met->
t[ix][iy][ip0 + 1], met->
ps[ix][iy]);
7010 LIN(met->
p[ip0], met->
h2o[ix][iy][ip0], met->
p[ip0 + 1],
7011 met->
h2o[ix][iy][ip0 + 1], met->
ps[ix][iy]);
7014 met->
z[ix][iy][ip0 + 1]
7016 ZDIFF(lnps, ts, h2os, logp[ip0 + 1],
7017 met->
t[ix][iy][ip0 + 1], met->
h2o[ix][iy][ip0 + 1]));
7018 for (
int ip = ip0 + 2; ip < met->
np; ip++)
7020 = (
float) (met->
z[ix][iy][ip - 1] +
7021 ZDIFF(logp[ip - 1], met->
t[ix][iy][ip - 1],
7022 met->
h2o[ix][iy][ip - 1], logp[ip],
7023 met->
t[ix][iy][ip], met->
h2o[ix][iy][ip]));
7028 ZDIFF(lnps, ts, h2os, logp[ip0],
7029 met->
t[ix][iy][ip0], met->
h2o[ix][iy][ip0]));
7030 for (
int ip = ip0 - 1; ip >= 0; ip--)
7032 = (
float) (met->
z[ix][iy][ip + 1] +
7033 ZDIFF(logp[ip + 1], met->
t[ix][iy][ip + 1],
7034 met->
h2o[ix][iy][ip + 1], logp[ip],
7035 met->
t[ix][iy][ip], met->
h2o[ix][iy][ip]));
7039 if (dx == 0 || dy == 0)
7043 if (dx < 0 || dy < 0) {
7044 if (fabs(met->
lon[1] - met->
lon[0]) < 0.5) {
7054 float ws[dx + 1][dy + 1];
7055#pragma omp parallel for default(shared) collapse(2)
7056 for (
int ix = 0; ix <= dx; ix++)
7057 for (
int iy = 0; iy < dy; iy++)
7058 ws[ix][iy] = (1.0f - (
float) ix / (float) dx)
7059 * (1.0f - (float) iy / (
float) dy);
7062#pragma omp parallel for default(shared) collapse(3)
7063 for (
int ix = 0; ix < met->
nx; ix++)
7064 for (
int iy = 0; iy < met->
ny; iy++)
7065 for (
int ip = 0; ip < met->
np; ip++)
7066 help[
ARRAY_3D(ip, ix, met->
nx, iy, met->
ny)] = met->
z[ix][iy][ip];
7069#pragma omp parallel for default(shared) collapse(3)
7070 for (
int ip = 0; ip < met->
np; ip++)
7071 for (
int ix = 0; ix < met->
nx; ix++)
7072 for (
int iy = 0; iy < met->
ny; iy++) {
7073 float res = 0, wsum = 0;
7074 int iy0 =
MAX(iy - dy + 1, 0);
7075 int iy1 =
MIN(iy + dy - 1, met->
ny - 1);
7076 for (
int ix2 = ix - dx + 1; ix2 <= ix + dx - 1; ++ix2) {
7080 else if (ix3 >= met->
nx)
7082 for (
int iy2 = iy0; iy2 <= iy1; ++iy2)
7083 if (isfinite(help[
ARRAY_3D(ip, ix3, met->
nx, iy2, met->
ny)])) {
7084 float w = ws[abs(ix - ix2)][abs(iy - iy2)];
7085 res += w * help[
ARRAY_3D(ip, ix3, met->
nx, iy2, met->
ny)];
7090 met->
z[ix][iy][ip] = res / wsum;
7092 met->
z[ix][iy][ip] = NAN;
7102 const char *filename,
7107 char levname[
LEN], tstr[10];
7109 double rtime = 0, r, r2;
7111 int varid, year2, mon2, day2, hour2, min2, sec2,
7112 year, mon, day, hour, min, sec;
7118 LOG(2,
"Read meteo grid information...");
7127 jsec2time(met->
time, &year, &mon, &day, &hour, &min, &sec, &r);
7128 if (nc_inq_varid(ncid,
"time", &varid) == NC_NOERR) {
7129 NC(nc_get_var_double(ncid, varid, &rtime));
7130 if (fabs(year * 10000. + mon * 100. + day + hour / 24. - rtime) > 1.0)
7131 WARN(
"Time information in meteo file does not match filename!");
7133 WARN(
"Time information in meteo file is missing!");
7144 sprintf(tstr,
"19%.2s", &filename[strlen(filename) - 11]);
7146 sprintf(tstr,
"20%.2s", &filename[strlen(filename) - 11]);
7148 sprintf(tstr,
"%.2s", &filename[strlen(filename) - 9]);
7150 sprintf(tstr,
"%.2s", &filename[strlen(filename) - 7]);
7152 sprintf(tstr,
"%.2s", &filename[strlen(filename) - 5]);
7158 if (year < 1900 || year > 2100 || mon < 1 || mon > 12
7159 || day < 1 || day > 31 || hour < 0 || hour > 23)
7160 ERRMSG(
"Cannot read time from filename!");
7161 jsec2time(met->
time, &year2, &mon2, &day2, &hour2, &min2, &sec2, &r2);
7162 LOG(2,
"Time: %.2f (%d-%02d-%02d, %02d:%02d UTC)",
7163 met->
time, year2, mon2, day2, hour2, min2);
7167 LOG(2,
"Number of longitudes: %d", met->
nx);
7170 LOG(2,
"Number of latitudes: %d", met->
ny);
7173 sprintf(levname,
"lev");
7174 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR)
7175 sprintf(levname,
"plev");
7176 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR)
7177 sprintf(levname,
"hybrid");
7181 sprintf(levname,
"lev_2");
7182 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR) {
7183 sprintf(levname,
"plev");
7184 NC(nc_inq_dimid(ncid, levname, &dimid2));
7186 NC(nc_inq_dimlen(ncid, dimid2, &np));
7189 LOG(2,
"Number of levels: %d", met->
np);
7190 if (met->
np < 2 || met->
np >
EP)
7191 ERRMSG(
"Number of levels out of range!");
7195 LOG(2,
"Longitudes: %g, %g ... %g deg",
7198 LOG(2,
"Latitudes: %g, %g ... %g deg",
7204 for (
int ip = 0; ip < met->
np; ip++)
7206 LOG(2,
"Altitude levels: %g, %g ... %g km",
7207 Z(met->
p[0]),
Z(met->
p[1]),
Z(met->
p[met->
np - 1]));
7208 LOG(2,
"Pressure levels: %g, %g ... %g hPa",
7209 met->
p[0], met->
p[1], met->
p[met->
np - 1]);
7213 if (strcasecmp(levname,
"hybrid") == 0)
7226 LOG(2,
"Read level data...");
7229 if (!
read_met_nc_3d(ncid,
"t",
"T",
"temp",
"TEMP", ctl, met, met->
t, 1.0))
7230 ERRMSG(
"Cannot read temperature!");
7233 if (!
read_met_nc_3d(ncid,
"u",
"U", NULL, NULL, ctl, met, met->
u, 1.0))
7234 ERRMSG(
"Cannot read zonal wind!");
7235 if (!
read_met_nc_3d(ncid,
"v",
"V", NULL, NULL, ctl, met, met->
v, 1.0))
7236 ERRMSG(
"Cannot read meridional wind!");
7238 (ncid,
"w",
"W",
"omega",
"OMEGA", ctl, met, met->
w, 0.01f))
7239 WARN(
"Cannot read vertical velocity!");
7244 (ncid,
"q",
"Q",
"sh",
"SH", ctl, met, met->
h2o, (
float) (
MA /
MH2O)))
7245 WARN(
"Cannot read specific humidity!");
7248 (ncid,
"rh",
"RH", NULL, NULL, ctl, met, met->
h2o, 0.01f))
7249 WARN(
"Cannot read relative humidity!");
7250#pragma omp parallel for default(shared) collapse(2)
7251 for (
int ix = 0; ix < met->
nx; ix++)
7252 for (
int iy = 0; iy < met->
ny; iy++)
7253 for (
int ip = 0; ip < met->
np; ip++) {
7254 double pw = met->
h2o[ix][iy][ip] *
PSAT(met->
t[ix][iy][ip]);
7255 met->
h2o[ix][iy][ip] =
7256 (float) (pw / (met->
p[ip] - (1.0 -
EPS) * pw));
7262 (ncid,
"o3",
"O3", NULL, NULL, ctl, met, met->
o3, (
float) (
MA /
MO3)))
7263 WARN(
"Cannot read ozone data!");
7267 (ncid,
"clwc",
"CLWC", NULL, NULL, ctl, met, met->
lwc, 1.0))
7268 WARN(
"Cannot read cloud liquid water content!");
7270 (ncid,
"crwc",
"CRWC", NULL, NULL, ctl, met, met->
rwc, 1.0))
7271 WARN(
"Cannot read cloud rain water content!");
7273 (ncid,
"ciwc",
"CIWC", NULL, NULL, ctl, met, met->
iwc, 1.0))
7274 WARN(
"Cannot read cloud ice water content!");
7276 (ncid,
"cswc",
"CSWC", NULL, NULL, ctl, met, met->
swc, 1.0))
7277 WARN(
"Cannot read cloud snow water content!");
7279 WARN(
"Cannot read cloud cover!");
7283 (ncid,
"ZETA",
"zeta", NULL, NULL, ctl, met, met->
zetal, 1.0))
7284 WARN(
"Cannot read ZETA!");
7286 (ncid,
"ZETA_DOT_TOT",
"ZETA_DOT_clr",
"zeta_dot_clr",
7287 NULL, ctl, met, met->
zeta_dotl, 0.00001157407f))
7288 WARN(
"Cannot read ZETA_DOT!");
7292 for (
int ix = 0; ix < met->
nx; ix++)
7293 for (
int iy = 0; iy < met->
ny; iy++)
7294 for (
int ip = 0; ip < met->
np; ip++) {
7295 met->
ul[ix][iy][ip] = met->
u[ix][iy][ip];
7296 met->
vl[ix][iy][ip] = met->
v[ix][iy][ip];
7297 met->
wl[ix][iy][ip] = met->
w[ix][iy][ip];
7310 (ncid,
"pl",
"PL",
"pressure",
"PRESSURE", ctl, met, met->
pl,
7313 (ncid,
"press",
"PRESS", NULL, NULL, ctl, met, met->
pl, 1.0))
7314 ERRMSG(
"Cannot read pressure on model levels!");
7322 double hyam[
EP], hybm[
EP];
7327 for (
int ix = 0; ix < met->
nx; ix++)
7328 for (
int iy = 0; iy < met->
ny; iy++)
7329 for (
int ip = 0; ip < met->
np; ip++)
7330 met->
pl[ix][iy][ip] =
7331 (
float) (hyam[ip] / 100. + hybm[ip] * met->
ps[ix][iy]);
7335 for (
int ix = 0; ix < met->
nx; ix++)
7336 for (
int iy = 0; iy < met->
ny; iy++)
7337 for (
int ip = 1; ip < met->
np; ip++)
7338 if ((met->
pl[ix][iy][0] > met->
pl[ix][iy][1]
7339 && met->
pl[ix][iy][ip - 1] <= met->
pl[ix][iy][ip])
7340 || (met->
pl[ix][iy][0] < met->
pl[ix][iy][1]
7341 && met->
pl[ix][iy][ip - 1] >= met->
pl[ix][iy][ip]))
7342 ERRMSG(
"Pressure profiles are not monotonic!");
7363 for (
int ip = 0; ip < met->
np; ip++)
7364 met->
p[ip] = ctl->
met_p[ip];
7368 for (
int ip = 1; ip < met->
np; ip++)
7369 if (met->
p[ip - 1] < met->
p[ip])
7370 ERRMSG(
"Pressure levels must be descending!");
7379 const char *varname) {
7381 double aux[
EP], p[
EP];
7385 LOG(2,
"Interpolate meteo data to pressure levels: %s", varname);
7388#pragma omp parallel for default(shared) private(aux,p) collapse(2)
7389 for (
int ix = 0; ix < met->
nx; ix++)
7390 for (
int iy = 0; iy < met->
ny; iy++) {
7393 for (
int ip = 0; ip < met->
np; ip++)
7394 p[ip] = met->
pl[ix][iy][ip];
7397 for (
int ip = 0; ip < ctl->
met_np; ip++) {
7398 double pt = ctl->
met_p[ip];
7399 if ((pt > p[0] && p[0] > p[1]) || (pt < p[0] && p[0] < p[1]))
7401 else if ((pt > p[met->
np - 1] && p[1] > p[0])
7402 || (pt < p[met->
np - 1] && p[1] < p[0]))
7403 pt = p[met->
np - 1];
7405 aux[ip] =
LIN(p[ip2], var[ix][iy][ip2],
7406 p[ip2 + 1], var[ix][iy][ip2 + 1], pt);
7410 for (
int ip = 0; ip < ctl->
met_np; ip++)
7411 var[ix][iy][ip] = (
float) aux[ip];
7421 SELECT_TIMER(
"READ_MET_MONOTONIZE",
"METPROC", NVTX_READ);
7422 LOG(2,
"Make zeta profiles monotone...");
7425#pragma omp parallel for default(shared) collapse(2)
7426 for (
int i = 0; i < met->
nx; i++)
7427 for (
int j = 0; j < met->
ny; j++) {
7430 while (k < met->npl) {
7431 if ((met->
zetal[i][j][k - 1] >= met->
zetal[i][j][k])) {
7437 while ((met->
zetal[i][j][k - 1] >=
7438 met->
zetal[i][j][k + l]) & (k + l < met->npl));
7443 (float) (met->
zetal[i][j][k + l] - met->
zetal[i][j][k - 1])
7446 for (
int m = k; m < k + l; m++) {
7447 float d = (float) (met->
hybrid[m] - met->
hybrid[k - 1]);
7448 met->
zetal[i][j][m] = s * d + met->
zetal[i][j][k - 1];
7460#pragma omp parallel for default(shared) collapse(2)
7461 for (
int i = 0; i < met->
nx; i++)
7462 for (
int j = 0; j < met->
ny; j++) {
7465 while (k < met->npl) {
7466 if ((met->
pl[i][j][k - 1] <= met->
pl[i][j][k])) {
7473 while ((met->
pl[i][j][k - 1] <= met->
pl[i][j][k + l]) & (k + l <
7478 float s = (float) (met->
pl[i][j][k + l] - met->
pl[i][j][k - 1])
7481 for (
int m = k; m < k + l; m++) {
7482 float d = (float) (met->
hybrid[m] - met->
hybrid[k - 1]);
7483 met->
pl[i][j][m] = s * d + met->
pl[i][j][k - 1];
7498 const char *filename,
7506 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
7507 WARN(
"Cannot open file!");
7571 const char *varname,
7572 const char *varname2,
7573 const char *varname3,
7574 const char *varname4,
7575 const char *varname5,
7576 const char *varname6,
7585 float offset, scalfac;
7590 if (nc_inq_varid(ncid, varname, &varid) == NC_NOERR)
7591 sprintf(varsel,
"%s", varname);
7592 else if (varname2 != NULL
7593 && nc_inq_varid(ncid, varname2, &varid) == NC_NOERR)
7594 sprintf(varsel,
"%s", varname2);
7595 else if (varname3 != NULL
7596 && nc_inq_varid(ncid, varname3, &varid) == NC_NOERR)
7597 sprintf(varsel,
"%s", varname3);
7598 else if (varname4 != NULL
7599 && nc_inq_varid(ncid, varname4, &varid) == NC_NOERR)
7600 sprintf(varsel,
"%s", varname4);
7601 else if (varname5 != NULL
7602 && nc_inq_varid(ncid, varname5, &varid) == NC_NOERR)
7603 sprintf(varsel,
"%s", varname5);
7604 else if (varname6 != NULL
7605 && nc_inq_varid(ncid, varname6, &varid) == NC_NOERR)
7606 sprintf(varsel,
"%s", varname6);
7612 && nc_get_att_float(ncid, varid,
"add_offset", &offset) == NC_NOERR
7613 && nc_get_att_float(ncid, varid,
"scale_factor",
7614 &scalfac) == NC_NOERR) {
7622 short fillval, missval;
7623 if (nc_get_att_short(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
7625 if (nc_get_att_short(ncid, varid,
"missing_value", &missval) != NC_NOERR)
7629 LOG(2,
"Read 2-D variable: %s"
7630 " (FILL = %d, MISS = %d, SCALE = %g, OFFSET = %g)",
7631 varsel, fillval, missval, scalfac, offset);
7634 NC(nc_get_var_short(ncid, varid, help));
7638 ERRMSG(
"Meteo data layout not implemented for packed netCDF files!");
7641#pragma omp parallel for default(shared) num_threads(12)
7642 for (
int ix = 0; ix < met->
nx; ix++)
7643 for (
int iy = 0; iy < met->
ny; iy++) {
7646 const short aux = help[
ARRAY_2D(iy, ix, met->
nx)];
7647 if ((fillval == 0 || aux != fillval)
7648 && (missval == 0 || aux != missval)
7649 && fabsf(aux * scalfac + offset) < 1e14f)
7650 dest[ix][iy] += scl * (aux * scalfac + offset);
7668 float fillval, missval;
7669 if (nc_get_att_float(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
7671 if (nc_get_att_float(ncid, varid,
"missing_value", &missval) != NC_NOERR)
7675 LOG(2,
"Read 2-D variable: %s (FILL = %g, MISS = %g)",
7676 varsel, fillval, missval);
7679 NC(nc_get_var_float(ncid, varid, help));
7685#pragma omp parallel for default(shared) num_threads(12)
7686 for (
int ix = 0; ix < met->
nx; ix++)
7687 for (
int iy = 0; iy < met->
ny; iy++) {
7690 const float aux = help[
ARRAY_2D(iy, ix, met->
nx)];
7691 if ((fillval == 0 || aux != fillval)
7692 && (missval == 0 || aux != missval)
7693 && fabsf(aux) < 1e14f)
7694 dest[ix][iy] += scl * aux;
7702#pragma omp parallel for default(shared) num_threads(12)
7703 for (
int iy = 0; iy < met->
ny; iy++)
7704 for (
int ix = 0; ix < met->
nx; ix++) {
7707 const float aux = help[
ARRAY_2D(ix, iy, met->
ny)];
7708 if ((fillval == 0 || aux != fillval)
7709 && (missval == 0 || aux != missval)
7710 && fabsf(aux) < 1e14f)
7711 dest[ix][iy] += scl * aux;
7729 const char *varname,
7730 const char *varname2,
7731 const char *varname3,
7732 const char *varname4,
7740 float offset, scalfac;
7745 if (nc_inq_varid(ncid, varname, &varid) == NC_NOERR)
7746 sprintf(varsel,
"%s", varname);
7747 else if (varname2 != NULL
7748 && nc_inq_varid(ncid, varname2, &varid) == NC_NOERR)
7749 sprintf(varsel,
"%s", varname2);
7750 else if (varname3 != NULL
7751 && nc_inq_varid(ncid, varname3, &varid) == NC_NOERR)
7752 sprintf(varsel,
"%s", varname3);
7753 else if (varname4 != NULL
7754 && nc_inq_varid(ncid, varname4, &varid) == NC_NOERR)
7755 sprintf(varsel,
"%s", varname4);
7761 && nc_get_att_float(ncid, varid,
"add_offset", &offset) == NC_NOERR
7762 && nc_get_att_float(ncid, varid,
"scale_factor",
7763 &scalfac) == NC_NOERR) {
7771 short fillval, missval;
7772 if (nc_get_att_short(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
7774 if (nc_get_att_short(ncid, varid,
"missing_value", &missval) != NC_NOERR)
7778 LOG(2,
"Read 3-D variable: %s "
7779 "(FILL = %d, MISS = %d, SCALE = %g, OFFSET = %g)",
7780 varsel, fillval, missval, scalfac, offset);
7783 NC(nc_get_var_short(ncid, varid, help));
7787 ERRMSG(
"Meteo data layout not implemented for packed netCDF files!");
7790#pragma omp parallel for default(shared) num_threads(12)
7791 for (
int ix = 0; ix < met->
nx; ix++)
7792 for (
int iy = 0; iy < met->
ny; iy++)
7793 for (
int ip = 0; ip < met->
np; ip++) {
7794 const short aux = help[
ARRAY_3D(ip, iy, met->
ny, ix, met->
nx)];
7795 if ((fillval == 0 || aux != fillval)
7796 && (missval == 0 || aux != missval)
7797 && fabsf(aux * scalfac + offset) < 1e14f)
7798 dest[ix][iy][ip] = scl * (aux * scalfac + offset);
7800 dest[ix][iy][ip] = NAN;
7816 float fillval, missval;
7817 if (nc_get_att_float(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
7819 if (nc_get_att_float(ncid, varid,
"missing_value", &missval) != NC_NOERR)
7823 LOG(2,
"Read 3-D variable: %s (FILL = %g, MISS = %g)",
7824 varsel, fillval, missval);
7827 NC(nc_get_var_float(ncid, varid, help));
7833#pragma omp parallel for default(shared) num_threads(12)
7834 for (
int ix = 0; ix < met->
nx; ix++)
7835 for (
int iy = 0; iy < met->
ny; iy++)
7836 for (
int ip = 0; ip < met->
np; ip++) {
7837 const float aux = help[
ARRAY_3D(ip, iy, met->
ny, ix, met->
nx)];
7838 if ((fillval == 0 || aux != fillval)
7839 && (missval == 0 || aux != missval)
7840 && fabsf(aux) < 1e14f)
7841 dest[ix][iy][ip] = scl * aux;
7843 dest[ix][iy][ip] = NAN;
7849#pragma omp parallel for default(shared) num_threads(12)
7850 for (
int ip = 0; ip < met->
np; ip++)
7851 for (
int iy = 0; iy < met->
ny; iy++)
7852 for (
int ix = 0; ix < met->
nx; ix++) {
7853 const float aux = help[
ARRAY_3D(ix, iy, met->
ny, ip, met->
np)];
7854 if ((fillval == 0 || aux != fillval)
7855 && (missval == 0 || aux != missval)
7856 && fabsf(aux) < 1e14f)
7857 dest[ix][iy][ip] = scl * aux;
7859 dest[ix][iy][ip] = NAN;
7879 LOG(2,
"Calculate planetary boundary layer...");
7885#pragma omp parallel for default(shared) collapse(2)
7886 for (
int ix = 0; ix < met->
nx; ix++)
7887 for (
int iy = 0; iy < met->
ny; iy++) {
7890 const float z = met->
zs[ix][iy] + met->
pbl[ix][iy];
7893 (float) (
LIN(met->
z[ix][iy][ip], met->
p[ip],
7894 met->
z[ix][iy][ip + 1], met->
p[ip + 1], z));
7903 const double rib_crit = 0.25, dz = 0.05, umin = 5.0;
7906#pragma omp parallel for default(shared) collapse(2)
7907 for (
int ix = 0; ix < met->
nx; ix++)
7908 for (
int iy = 0; iy < met->
ny; iy++) {
7911 const double pbl_bot = met->
ps[ix][iy] * exp(-dz /
H0);
7915 for (ip = 1; ip < met->
np; ip++)
7916 if (met->
p[ip] < pbl_bot)
7920 const double h2os =
LIN(met->
p[ip - 1], met->
h2o[ix][iy][ip - 1],
7921 met->
p[ip], met->
h2o[ix][iy][ip], pbl_bot);
7922 const double tvs =
THETAVIRT(pbl_bot, met->
ts[ix][iy], h2os);
7928 for (; ip < met->
np; ip++) {
7931 double vh2 =
SQR(met->
u[ix][iy][ip] - met->
us[ix][iy])
7932 +
SQR(met->
v[ix][iy][ip] - met->
vs[ix][iy]);
7933 vh2 =
MAX(vh2,
SQR(umin));
7937 G0 * 1e3 * (met->
z[ix][iy][ip] - met->
zs[ix][iy]) / tvs
7939 met->
h2o[ix][iy][ip]) - tvs) / vh2;
7942 if (rib >= rib_crit) {
7943 met->
pbl[ix][iy] = (float) (
LIN(rib_old, met->
p[ip - 1],
7944 rib, met->
p[ip], rib_crit));
7945 if (met->
pbl[ix][iy] > pbl_bot)
7946 met->
pbl[ix][iy] = (float) pbl_bot;
7961 const double dtheta = 2.0, zmin = 0.1;
7964#pragma omp parallel for default(shared) collapse(2)
7965 for (
int ix = 0; ix < met->
nx; ix++)
7966 for (
int iy = 0; iy < met->
ny; iy++) {
7969 const double theta0 =
THETA(met->
ps[ix][iy], met->
ts[ix][iy]);
7973 for (ip = met->
np - 2; ip > 0; ip--)
7974 if (met->
p[ip] >= 300.)
7975 if (met->
p[ip] > met->
ps[ix][iy]
7976 ||
THETA(met->
p[ip], met->
t[ix][iy][ip]) <= theta0 + dtheta)
7981 = (float) (
LIN(
THETA(met->
p[ip + 1], met->
t[ix][iy][ip + 1]),
7983 THETA(met->
p[ip], met->
t[ix][iy][ip]),
7984 met->
p[ip], theta0 + dtheta));
7987 double pbl_min = met->
ps[ix][iy] * exp(-zmin /
H0);
7988 if (met->
pbl[ix][iy] > pbl_min || met->
p[ip] > met->
ps[ix][iy])
7989 met->
pbl[ix][iy] = (float) pbl_min;
7994#pragma omp parallel for default(shared) collapse(2)
7995 for (
int ix = 0; ix < met->
nx; ix++)
7996 for (
int iy = 0; iy < met->
ny; iy++) {
8000 met->
pbl[ix][iy] =
MIN(met->
pbl[ix][iy], (
float) pbl_min);
8004 met->
pbl[ix][iy] =
MAX(met->
pbl[ix][iy], (
float) pbl_max);
8014 SELECT_TIMER(
"READ_MET_PERIODIC",
"METPROC", NVTX_READ);
8015 LOG(2,
"Apply periodic boundary conditions...");
8018 if (!(fabs(met->
lon[met->
nx - 1] - met->
lon[0]
8019 + met->
lon[1] - met->
lon[0] - 360) < 0.01))
8023 if ((++met->
nx) >=
EX)
8024 ERRMSG(
"Cannot create periodic boundary conditions!");
8030#pragma omp parallel for default(shared)
8031 for (
int iy = 0; iy < met->
ny; iy++) {
8032 met->
ps[met->
nx - 1][iy] = met->
ps[0][iy];
8033 met->
zs[met->
nx - 1][iy] = met->
zs[0][iy];
8034 met->
ts[met->
nx - 1][iy] = met->
ts[0][iy];
8035 met->
us[met->
nx - 1][iy] = met->
us[0][iy];
8036 met->
vs[met->
nx - 1][iy] = met->
vs[0][iy];
8037 met->
ess[met->
nx - 1][iy] = met->
ess[0][iy];
8038 met->
nss[met->
nx - 1][iy] = met->
nss[0][iy];
8039 met->
shf[met->
nx - 1][iy] = met->
shf[0][iy];
8040 met->
lsm[met->
nx - 1][iy] = met->
lsm[0][iy];
8041 met->
sst[met->
nx - 1][iy] = met->
sst[0][iy];
8042 met->
pbl[met->
nx - 1][iy] = met->
pbl[0][iy];
8043 met->
cape[met->
nx - 1][iy] = met->
cape[0][iy];
8044 met->
cin[met->
nx - 1][iy] = met->
cin[0][iy];
8045 for (
int ip = 0; ip < met->
np; ip++) {
8046 met->
t[met->
nx - 1][iy][ip] = met->
t[0][iy][ip];
8047 met->
u[met->
nx - 1][iy][ip] = met->
u[0][iy][ip];
8048 met->
v[met->
nx - 1][iy][ip] = met->
v[0][iy][ip];
8049 met->
w[met->
nx - 1][iy][ip] = met->
w[0][iy][ip];
8050 met->
h2o[met->
nx - 1][iy][ip] = met->
h2o[0][iy][ip];
8051 met->
o3[met->
nx - 1][iy][ip] = met->
o3[0][iy][ip];
8052 met->
lwc[met->
nx - 1][iy][ip] = met->
lwc[0][iy][ip];
8053 met->
rwc[met->
nx - 1][iy][ip] = met->
rwc[0][iy][ip];
8054 met->
iwc[met->
nx - 1][iy][ip] = met->
iwc[0][iy][ip];
8055 met->
swc[met->
nx - 1][iy][ip] = met->
swc[0][iy][ip];
8056 met->
cc[met->
nx - 1][iy][ip] = met->
cc[0][iy][ip];
8058 for (
int ip = 0; ip < met->
npl; ip++) {
8059 met->
ul[met->
nx - 1][iy][ip] = met->
ul[0][iy][ip];
8060 met->
vl[met->
nx - 1][iy][ip] = met->
vl[0][iy][ip];
8061 met->
wl[met->
nx - 1][iy][ip] = met->
wl[0][iy][ip];
8062 met->
pl[met->
nx - 1][iy][ip] = met->
pl[0][iy][ip];
8063 met->
zetal[met->
nx - 1][iy][ip] = met->
zetal[0][iy][ip];
8075 SELECT_TIMER(
"READ_MET_POLAR_WINDS",
"METPROC", NVTX_READ);
8076 LOG(2,
"Apply fix for polar winds...");
8079 if (fabs(met->
lat[0]) < 89.999 || fabs(met->
lat[met->
ny - 1]) < 89.999)
8083 for (
int ihem = 0; ihem < 2; ihem++) {
8086 int i89 = 1, i90 = 0, sign = 1;
8091 if (met->
lat[i90] < 0)
8095 double clon[
EX], slon[
EX];
8096#pragma omp parallel for default(shared)
8097 for (
int ix = 0; ix < met->
nx; ix++) {
8098 clon[ix] = cos(sign *
DEG2RAD(met->
lon[ix]));
8099 slon[ix] = sin(sign *
DEG2RAD(met->
lon[ix]));
8103#pragma omp parallel for default(shared)
8104 for (
int ip = 0; ip < met->
np; ip++) {
8107 double vel89x = 0, vel89y = 0;
8108 for (
int ix = 0; ix < met->
nx; ix++) {
8110 (met->
u[ix][i89][ip] * clon[ix] -
8111 met->
v[ix][i89][ip] * slon[ix]) / met->
nx;
8113 (met->
u[ix][i89][ip] * slon[ix] +
8114 met->
v[ix][i89][ip] * clon[ix]) / met->
nx;
8118 for (
int ix = 0; ix < met->
nx; ix++) {
8120 = (float) (vel89x * clon[ix] + vel89y * slon[ix]);
8122 = (float) (-vel89x * slon[ix] + vel89y * clon[ix]);
8137 LOG(2,
"Calculate potential vorticity...");
8140#pragma omp parallel for default(shared)
8141 for (
int ip = 0; ip < met->
np; ip++)
8142 pows[ip] = pow(1000. / met->
p[ip], 0.286);
8145#pragma omp parallel for default(shared)
8146 for (
int ix = 0; ix < met->
nx; ix++) {
8149 const int ix0 =
MAX(ix - 1, 0);
8150 const int ix1 =
MIN(ix + 1, met->
nx - 1);
8153 for (
int iy = 0; iy < met->
ny; iy++) {
8156 const int iy0 =
MAX(iy - 1, 0);
8157 const int iy1 =
MIN(iy + 1, met->
ny - 1);
8160 const double latr = 0.5 * (met->
lat[iy1] + met->
lat[iy0]);
8161 const double dx = 1000. *
DEG2DX(met->
lon[ix1] - met->
lon[ix0], latr);
8162 const double dy = 1000. *
DEG2DY(met->
lat[iy1] - met->
lat[iy0]);
8163 const double c0 = cos(
DEG2RAD(met->
lat[iy0]));
8164 const double c1 = cos(
DEG2RAD(met->
lat[iy1]));
8165 const double cr = cos(
DEG2RAD(latr));
8166 const double vort = 2 * 7.2921e-5 * sin(
DEG2RAD(latr));
8169 for (
int ip = 0; ip < met->
np; ip++) {
8173 = (met->
t[ix1][iy][ip] - met->
t[ix0][iy][ip]) * pows[ip] / dx;
8174 const double dvdx = (met->
v[ix1][iy][ip] - met->
v[ix0][iy][ip]) / dx;
8178 = (met->
t[ix][iy1][ip] - met->
t[ix][iy0][ip]) * pows[ip] / dy;
8180 = (met->
u[ix][iy1][ip] * c1 - met->
u[ix][iy0][ip] * c0) / dy;
8183 const int ip0 =
MAX(ip - 1, 0);
8184 const int ip1 =
MIN(ip + 1, met->
np - 1);
8187 double dtdp, dudp, dvdp;
8188 const double dp0 = 100. * (met->
p[ip] - met->
p[ip0]);
8189 const double dp1 = 100. * (met->
p[ip1] - met->
p[ip]);
8190 if (ip != ip0 && ip != ip1) {
8191 double denom = dp0 * dp1 * (dp0 + dp1);
8192 dtdp = (dp0 * dp0 * met->
t[ix][iy][ip1] * pows[ip1]
8193 - dp1 * dp1 * met->
t[ix][iy][ip0] * pows[ip0]
8194 + (dp1 * dp1 - dp0 * dp0) * met->
t[ix][iy][ip] * pows[ip])
8196 dudp = (dp0 * dp0 * met->
u[ix][iy][ip1]
8197 - dp1 * dp1 * met->
u[ix][iy][ip0]
8198 + (dp1 * dp1 - dp0 * dp0) * met->
u[ix][iy][ip])
8200 dvdp = (dp0 * dp0 * met->
v[ix][iy][ip1]
8201 - dp1 * dp1 * met->
v[ix][iy][ip0]
8202 + (dp1 * dp1 - dp0 * dp0) * met->
v[ix][iy][ip])
8205 const double denom = dp0 + dp1;
8207 (met->
t[ix][iy][ip1] * pows[ip1] -
8208 met->
t[ix][iy][ip0] * pows[ip0]) / denom;
8209 dudp = (met->
u[ix][iy][ip1] - met->
u[ix][iy][ip0]) / denom;
8210 dvdp = (met->
v[ix][iy][ip1] - met->
v[ix][iy][ip0]) / denom;
8214 met->
pv[ix][iy][ip] = (float)
8216 (-dtdp * (dvdx - dudy / cr + vort) + dvdp * dtdx - dudp * dtdy));
8222#pragma omp parallel for default(shared)
8223 for (
int ix = 0; ix < met->
nx; ix++)
8224 for (
int ip = 0; ip < met->
np; ip++) {
8226 = met->
pv[ix][1][ip]
8227 = met->
pv[ix][2][ip];
8228 met->
pv[ix][met->
ny - 1][ip]
8229 = met->
pv[ix][met->
ny - 2][ip]
8230 = met->
pv[ix][met->
ny - 3][ip];
8241 LOG(2,
"Calculate total column ozone...");
8244#pragma omp parallel for default(shared) collapse(2)
8245 for (
int ix = 0; ix < met->
nx; ix++)
8246 for (
int iy = 0; iy < met->
ny; iy++) {
8250 for (
int ip = 1; ip < met->
np; ip++)
8251 if (met->
p[ip - 1] <= met->
ps[ix][iy]) {
8253 0.5 * (met->
o3[ix][iy][ip - 1] + met->
o3[ix][iy][ip]);
8254 const double dp = met->
p[ip - 1] - met->
p[ip];
8255 cd += vmr *
MO3 /
MA * dp * 1e2 /
G0;
8259 met->
o3c[ix][iy] = (float) (cd / 2.1415e-5);
8278 LOG(2,
"Downsampling of meteo data...");
8287 memcpy(help->
lon, met->
lon,
sizeof(met->
lon));
8288 memcpy(help->
lat, met->
lat,
sizeof(met->
lat));
8289 memcpy(help->
p, met->
p,
sizeof(met->
p));
8292 for (
int ix = 0; ix < met->
nx; ix += ctl->
met_dx) {
8293 for (
int iy = 0; iy < met->
ny; iy += ctl->
met_dy) {
8294 for (
int ip = 0; ip < met->
np; ip += ctl->
met_dp) {
8295 help->
ps[ix][iy] = 0;
8296 help->
zs[ix][iy] = 0;
8297 help->
ts[ix][iy] = 0;
8298 help->
us[ix][iy] = 0;
8299 help->
vs[ix][iy] = 0;
8300 help->
ess[ix][iy] = 0;
8301 help->
nss[ix][iy] = 0;
8302 help->
shf[ix][iy] = 0;
8303 help->
lsm[ix][iy] = 0;
8304 help->
sst[ix][iy] = 0;
8305 help->
pbl[ix][iy] = 0;
8306 help->
cape[ix][iy] = 0;
8307 help->
cin[ix][iy] = 0;
8308 help->
t[ix][iy][ip] = 0;
8309 help->
u[ix][iy][ip] = 0;
8310 help->
v[ix][iy][ip] = 0;
8311 help->
w[ix][iy][ip] = 0;
8312 help->
h2o[ix][iy][ip] = 0;
8313 help->
o3[ix][iy][ip] = 0;
8314 help->
lwc[ix][iy][ip] = 0;
8315 help->
rwc[ix][iy][ip] = 0;
8316 help->
iwc[ix][iy][ip] = 0;
8317 help->
swc[ix][iy][ip] = 0;
8318 help->
cc[ix][iy][ip] = 0;
8320 for (
int ix2 = ix - ctl->
met_sx + 1; ix2 <= ix + ctl->met_sx - 1;
8325 else if (ix3 >= met->
nx)
8328 for (
int iy2 =
MAX(iy - ctl->
met_sy + 1, 0);
8329 iy2 <=
MIN(iy + ctl->
met_sy - 1, met->
ny - 1); iy2++)
8330 for (
int ip2 =
MAX(ip - ctl->
met_sp + 1, 0);
8331 ip2 <=
MIN(ip + ctl->
met_sp - 1, met->
np - 1); ip2++) {
8332 float w = (1.0f - (float) abs(ix - ix2) / (float) ctl->
met_sx)
8333 * (1.0f - (float) abs(iy - iy2) / (float) ctl->
met_sy)
8334 * (1.0f - (float) abs(ip - ip2) / (float) ctl->
met_sp);
8335 help->
ps[ix][iy] += w * met->
ps[ix3][iy2];
8336 help->
zs[ix][iy] += w * met->
zs[ix3][iy2];
8337 help->
ts[ix][iy] += w * met->
ts[ix3][iy2];
8338 help->
us[ix][iy] += w * met->
us[ix3][iy2];
8339 help->
vs[ix][iy] += w * met->
vs[ix3][iy2];
8340 help->
ess[ix][iy] += w * met->
ess[ix3][iy2];
8341 help->
nss[ix][iy] += w * met->
nss[ix3][iy2];
8342 help->
shf[ix][iy] += w * met->
shf[ix3][iy2];
8343 help->
lsm[ix][iy] += w * met->
lsm[ix3][iy2];
8344 help->
sst[ix][iy] += w * met->
sst[ix3][iy2];
8345 help->
pbl[ix][iy] += w * met->
pbl[ix3][iy2];
8346 help->
cape[ix][iy] += w * met->
cape[ix3][iy2];
8347 help->
cin[ix][iy] += w * met->
cin[ix3][iy2];
8348 help->
t[ix][iy][ip] += w * met->
t[ix3][iy2][ip2];
8349 help->
u[ix][iy][ip] += w * met->
u[ix3][iy2][ip2];
8350 help->
v[ix][iy][ip] += w * met->
v[ix3][iy2][ip2];
8351 help->
w[ix][iy][ip] += w * met->
w[ix3][iy2][ip2];
8352 help->
h2o[ix][iy][ip] += w * met->
h2o[ix3][iy2][ip2];
8353 help->
o3[ix][iy][ip] += w * met->
o3[ix3][iy2][ip2];
8354 help->
lwc[ix][iy][ip] += w * met->
lwc[ix3][iy2][ip2];
8355 help->
rwc[ix][iy][ip] += w * met->
rwc[ix3][iy2][ip2];
8356 help->
iwc[ix][iy][ip] += w * met->
iwc[ix3][iy2][ip2];
8357 help->
swc[ix][iy][ip] += w * met->
swc[ix3][iy2][ip2];
8358 help->
cc[ix][iy][ip] += w * met->
cc[ix3][iy2][ip2];
8362 help->
ps[ix][iy] /= wsum;
8363 help->
zs[ix][iy] /= wsum;
8364 help->
ts[ix][iy] /= wsum;
8365 help->
us[ix][iy] /= wsum;
8366 help->
vs[ix][iy] /= wsum;
8367 help->
ess[ix][iy] /= wsum;
8368 help->
nss[ix][iy] /= wsum;
8369 help->
shf[ix][iy] /= wsum;
8370 help->
lsm[ix][iy] /= wsum;
8371 help->
sst[ix][iy] /= wsum;
8372 help->
pbl[ix][iy] /= wsum;
8373 help->
cape[ix][iy] /= wsum;
8374 help->
cin[ix][iy] /= wsum;
8375 help->
t[ix][iy][ip] /= wsum;
8376 help->
u[ix][iy][ip] /= wsum;
8377 help->
v[ix][iy][ip] /= wsum;
8378 help->
w[ix][iy][ip] /= wsum;
8379 help->
h2o[ix][iy][ip] /= wsum;
8380 help->
o3[ix][iy][ip] /= wsum;
8381 help->
lwc[ix][iy][ip] /= wsum;
8382 help->
rwc[ix][iy][ip] /= wsum;
8383 help->
iwc[ix][iy][ip] /= wsum;
8384 help->
swc[ix][iy][ip] /= wsum;
8385 help->
cc[ix][iy][ip] /= wsum;
8392 for (
int ix = 0; ix < help->
nx; ix += ctl->
met_dx) {
8395 for (
int iy = 0; iy < help->
ny; iy += ctl->
met_dy) {
8397 met->
ps[met->
nx][met->
ny] = help->
ps[ix][iy];
8398 met->
zs[met->
nx][met->
ny] = help->
zs[ix][iy];
8399 met->
ts[met->
nx][met->
ny] = help->
ts[ix][iy];
8400 met->
us[met->
nx][met->
ny] = help->
us[ix][iy];
8401 met->
vs[met->
nx][met->
ny] = help->
vs[ix][iy];
8402 met->
ess[met->
nx][met->
ny] = help->
ess[ix][iy];
8403 met->
nss[met->
nx][met->
ny] = help->
nss[ix][iy];
8404 met->
shf[met->
nx][met->
ny] = help->
shf[ix][iy];
8405 met->
lsm[met->
nx][met->
ny] = help->
lsm[ix][iy];
8406 met->
sst[met->
nx][met->
ny] = help->
sst[ix][iy];
8407 met->
pbl[met->
nx][met->
ny] = help->
pbl[ix][iy];
8409 met->
cin[met->
nx][met->
ny] = help->
cin[ix][iy];
8411 for (
int ip = 0; ip < help->
np; ip += ctl->
met_dp) {
8412 met->
p[met->
np] = help->
p[ip];
8413 met->
t[met->
nx][met->
ny][met->
np] = help->
t[ix][iy][ip];
8414 met->
u[met->
nx][met->
ny][met->
np] = help->
u[ix][iy][ip];
8415 met->
v[met->
nx][met->
ny][met->
np] = help->
v[ix][iy][ip];
8416 met->
w[met->
nx][met->
ny][met->
np] = help->
w[ix][iy][ip];
8417 met->
h2o[met->
nx][met->
ny][met->
np] = help->
h2o[ix][iy][ip];
8418 met->
o3[met->
nx][met->
ny][met->
np] = help->
o3[ix][iy][ip];
8419 met->
lwc[met->
nx][met->
ny][met->
np] = help->
lwc[ix][iy][ip];
8420 met->
rwc[met->
nx][met->
ny][met->
np] = help->
rwc[ix][iy][ip];
8421 met->
iwc[met->
nx][met->
ny][met->
np] = help->
iwc[ix][iy][ip];
8422 met->
swc[met->
nx][met->
ny][met->
np] = help->
swc[ix][iy][ip];
8423 met->
cc[met->
nx][met->
ny][met->
np] = help->
cc[ix][iy][ip];
8444 LOG(2,
"Read surface data...");
8448 (ncid,
"lnsp",
"LNSP", NULL, NULL, NULL, NULL, ctl, met, met->
ps, 1.0f,
8450 for (
int ix = 0; ix < met->
nx; ix++)
8451 for (
int iy = 0; iy < met->
ny; iy++)
8452 met->
ps[ix][iy] = (
float) (exp(met->
ps[ix][iy]) / 100.);
8455 (ncid,
"ps",
"PS",
"sp",
"SP", NULL, NULL, ctl, met, met->
ps, 0.01f,
8457 WARN(
"Cannot not read surface pressure data (use lowest level)!");
8458 for (
int ix = 0; ix < met->
nx; ix++)
8459 for (
int iy = 0; iy < met->
ny; iy++)
8461 = (ctl->
met_np > 0 ? (
float) ctl->
met_p[0] : (
float) met->
p[0]);
8469 (ncid,
"z",
"Z", NULL, NULL, NULL, NULL, ctl, met, met->
zs,
8470 (
float) (1. / (1000. *
G0)), 1))
8472 (ncid,
"zm",
"ZM", NULL, NULL, NULL, NULL, ctl, met, met->
zs,
8473 (
float) (1. / 1000.), 1))
8474 WARN(
"Cannot read surface geopotential height!");
8485 memcpy(help, met->
pl,
sizeof(met->
pl));
8487 (ncid,
"gph",
"GPH", NULL, NULL, ctl, met, met->
pl,
8488 (
float) (1e-3 /
G0)))
8489 ERRMSG(
"Cannot read geopotential height!");
8490 for (
int ix = 0; ix < met->
nx; ix++)
8491 for (
int iy = 0; iy < met->
ny; iy++)
8492 met->
zs[ix][iy] = met->
pl[ix][iy][0];
8493 memcpy(met->
pl, help,
sizeof(met->
pl));
8499 (ncid,
"t2m",
"T2M",
"2t",
"2T",
"t2",
"T2", ctl, met, met->
ts, 1.0, 1))
8500 WARN(
"Cannot read surface temperature!");
8504 (ncid,
"u10m",
"U10M",
"10u",
"10U",
"u10",
"U10", ctl, met, met->
us,
8506 WARN(
"Cannot read surface zonal wind!");
8510 (ncid,
"v10m",
"V10M",
"10v",
"10V",
"v10",
"V10", ctl, met, met->
vs,
8512 WARN(
"Cannot read surface meridional wind!");
8516 (ncid,
"iews",
"IEWS", NULL, NULL, NULL, NULL, ctl, met, met->
ess, 1.0,
8518 WARN(
"Cannot read eastward turbulent surface stress!");
8522 (ncid,
"inss",
"INSS", NULL, NULL, NULL, NULL, ctl, met, met->
nss, 1.0,
8524 WARN(
"Cannot read nothward turbulent surface stress!");
8528 (ncid,
"ishf",
"ISHF", NULL, NULL, NULL, NULL, ctl, met, met->
shf, 1.0,
8530 WARN(
"Cannot read surface sensible heat flux!");
8534 (ncid,
"lsm",
"LSM", NULL, NULL, NULL, NULL, ctl, met, met->
lsm, 1.0,
8536 WARN(
"Cannot read land-sea mask!");
8540 (ncid,
"sstk",
"SSTK",
"sst",
"SST", NULL, NULL, ctl, met, met->
sst,
8542 WARN(
"Cannot read sea surface temperature!");
8547 (ncid,
"blp",
"BLP", NULL, NULL, NULL, NULL, ctl, met, met->
pbl,
8549 WARN(
"Cannot read planetary boundary layer pressure!");
8552 (ncid,
"blh",
"BLH", NULL, NULL, NULL, NULL, ctl, met, met->
pbl,
8554 WARN(
"Cannot read planetary boundary layer height!");
8559 (ncid,
"cape",
"CAPE", NULL, NULL, NULL, NULL, ctl, met, met->
cape,
8561 WARN(
"Cannot read CAPE!");
8566 (ncid,
"cin",
"CIN", NULL, NULL, NULL, NULL, ctl, met, met->
cin,
8568 WARN(
"Cannot read convective inhibition!");
8578 double p2[200], pv[
EP], pv2[200], t[
EP], t2[200], th[
EP],
8579 th2[200], z[
EP], z2[200];
8583 LOG(2,
"Calculate tropopause...");
8586#pragma omp parallel for default(shared)
8587 for (
int iz = 0; iz < met->
np; iz++)
8588 z[iz] =
Z(met->
p[iz]);
8589#pragma omp parallel for default(shared)
8590 for (
int iz = 0; iz <= 190; iz++) {
8591 z2[iz] = 4.5 + 0.1 * iz;
8597#pragma omp parallel for default(shared) collapse(2)
8598 for (
int ix = 0; ix < met->
nx; ix++)
8599 for (
int iy = 0; iy < met->
ny; iy++)
8600 met->
pt[ix][iy] = NAN;
8604#pragma omp parallel for default(shared) collapse(2)
8605 for (
int ix = 0; ix < met->
nx; ix++)
8606 for (
int iy = 0; iy < met->
ny; iy++)
8614#pragma omp parallel for default(shared) private(t,t2) collapse(2)
8615 for (
int ix = 0; ix < met->
nx; ix++)
8616 for (
int iy = 0; iy < met->
ny; iy++) {
8619 for (
int iz = 0; iz < met->
np; iz++)
8620 t[iz] = met->
t[ix][iy][iz];
8624 int iz = (int) gsl_stats_min_index(t2, 1, 171);
8625 if (iz > 0 && iz < 170)
8626 met->
pt[ix][iy] = (float) p2[iz];
8628 met->
pt[ix][iy] = NAN;
8636#pragma omp parallel for default(shared) private(t,t2) collapse(2)
8637 for (
int ix = 0; ix < met->
nx; ix++)
8638 for (
int iy = 0; iy < met->
ny; iy++) {
8642 for (iz = 0; iz < met->
np; iz++)
8643 t[iz] = met->
t[ix][iy][iz];
8647 met->
pt[ix][iy] = NAN;
8648 for (iz = 0; iz <= 170; iz++) {
8650 for (
int iz2 = iz + 1; iz2 <= iz + 20; iz2++)
8651 if (
LAPSE(p2[iz], t2[iz], p2[iz2], t2[iz2]) > 2.0) {
8656 if (iz > 0 && iz < 170)
8657 met->
pt[ix][iy] = (float) p2[iz];
8664 met->
pt[ix][iy] = NAN;
8665 for (; iz <= 170; iz++) {
8667 for (
int iz2 = iz + 1; iz2 <= iz + 10; iz2++)
8668 if (
LAPSE(p2[iz], t2[iz], p2[iz2], t2[iz2]) < 3.0) {
8675 for (; iz <= 170; iz++) {
8677 for (
int iz2 = iz + 1; iz2 <= iz + 20; iz2++)
8678 if (
LAPSE(p2[iz], t2[iz], p2[iz2], t2[iz2]) > 2.0) {
8683 if (iz > 0 && iz < 170)
8684 met->
pt[ix][iy] = (float) p2[iz];
8696#pragma omp parallel for default(shared) private(pv,pv2,th,th2) collapse(2)
8697 for (
int ix = 0; ix < met->
nx; ix++)
8698 for (
int iy = 0; iy < met->
ny; iy++) {
8701 for (
int iz = 0; iz < met->
np; iz++)
8702 pv[iz] = met->
pv[ix][iy][iz];
8706 for (
int iz = 0; iz < met->
np; iz++)
8707 th[iz] =
THETA(met->
p[iz], met->
t[ix][iy][iz]);
8711 met->
pt[ix][iy] = NAN;
8712 for (
int iz = 0; iz <= 170; iz++)
8715 if (iz > 0 && iz < 170)
8716 met->
pt[ix][iy] = (float) p2[iz];
8723 ERRMSG(
"Cannot calculate tropopause!");
8726#pragma omp parallel for default(shared) collapse(2)
8727 for (
int ix = 0; ix < met->
nx; ix++)
8728 for (
int iy = 0; iy < met->
ny; iy++) {
8729 double h2ot, tt, zt;
8732 met->
lat[iy], &tt, ci, cw, 1);
8734 met->
lat[iy], &zt, ci, cw, 0);
8736 met->
lat[iy], &h2ot, ci, cw, 0);
8737 met->
tt[ix][iy] = (float) tt;
8738 met->
zt[ix][iy] = (float) zt;
8739 met->
h2ot[ix][iy] = (float) h2ot;
8746 const char *filename,
8756 LOG(1,
"Read observation data: %s", filename);
8760 read_obs_asc(filename, rt, rz, rlon, rlat, robs, nobs);
8762 read_obs_nc(filename, rt, rz, rlon, rlat, robs, nobs);
8764 ERRMSG(
"Set OBS_TYPE to 0 or 1!");
8767 for (
int i = 1; i < *nobs; i++)
8768 if (rt[i] < rt[i - 1])
8769 ERRMSG(
"Time must be ascending!");
8774 LOG(2,
"Number of observations: %d", *nobs);
8775 gsl_stats_minmax(&mini, &maxi, rt, 1, (
size_t) n);
8776 LOG(2,
"Time range: %.2f ... %.2f s", mini, maxi);
8777 gsl_stats_minmax(&mini, &maxi, rz, 1, (
size_t) n);
8778 LOG(2,
"Altitude range: %g ... %g km", mini, maxi);
8779 gsl_stats_minmax(&mini, &maxi, rlon, 1, (
size_t) n);
8780 LOG(2,
"Longitude range: %g ... %g deg", mini, maxi);
8781 gsl_stats_minmax(&mini, &maxi, rlat, 1, (
size_t) n);
8782 LOG(2,
"Latitude range: %g ... %g deg", mini, maxi);
8783 gsl_stats_minmax(&mini, &maxi, robs, 1, (
size_t) n);
8784 LOG(2,
"Observation range: %g ... %g", mini, maxi);
8790 const char *filename,
8800 if (!(in = fopen(filename,
"r")))
8801 ERRMSG(
"Cannot open file!");
8805 while (fgets(line,
LEN, in))
8806 if (sscanf(line,
"%lg %lg %lg %lg %lg", &rt[*nobs], &rz[*nobs],
8807 &rlon[*nobs], &rlat[*nobs], &robs[*nobs]) == 5)
8808 if ((++(*nobs)) >=
NOBS)
8809 ERRMSG(
"Too many observations!");
8818 const char *filename,
8829 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR)
8830 ERRMSG(
"Cannot open file!");
8847 const char *filename,
8850 const char *varname,
8852 const char *defvalue,
8857 char fullname1[
LEN], fullname2[
LEN], rval[
LEN];
8862 if (filename[strlen(filename) - 1] !=
'-')
8863 if (!(in = fopen(filename,
"r")))
8864 ERRMSG(
"Cannot open file!");
8868 sprintf(fullname1,
"%s[%d]", varname, arridx);
8869 sprintf(fullname2,
"%s[*]", varname);
8871 sprintf(fullname1,
"%s", varname);
8872 sprintf(fullname2,
"%s", varname);
8877 char dummy[
LEN], line[
LEN], rvarname[
LEN];
8878 while (fgets(line,
LEN, in)) {
8879 if (sscanf(line,
"%4999s %4999s %4999s", rvarname, dummy, rval) == 3)
8880 if (strcasecmp(rvarname, fullname1) == 0 ||
8881 strcasecmp(rvarname, fullname2) == 0) {
8887 for (i = 1; i < argc - 1; i++)
8888 if (strcasecmp(argv[i], fullname1) == 0 ||
8889 strcasecmp(argv[i], fullname2) == 0) {
8890 sprintf(rval,
"%s", argv[i + 1]);
8901 if (strlen(defvalue) > 0)
8902 sprintf(rval,
"%s", defvalue);
8904 ERRMSG(
"Missing variable %s!\n", fullname1);
8908 LOG(1,
"%s = %s", fullname1, rval);
8912 sprintf(value,
"%s", rval);
8922 const double rhop) {
8925 const double rp_help = rp * 1e-6;
8928 const double rho =
RHO(p, T);
8931 const double eta = 1.8325e-5 * (416.16 / (T + 120.)) * pow(T / 296.16, 1.5);
8934 const double v = sqrt(8. *
KB * T / (M_PI * 4.8096e-26));
8937 const double lambda = 2. * eta / (rho * v);
8940 const double K = lambda / rp_help;
8943 const double G = 1. + K * (1.249 + 0.42 * exp(-0.87 / K));
8946 return 2. *
SQR(rp_help) * (rhop - rho) *
G0 / (9. * eta) * G;
8964 gsl_interp_accel *acc = gsl_interp_accel_alloc();
8965 gsl_spline *s = gsl_spline_alloc(gsl_interp_cspline, (
size_t) n);
8968 gsl_spline_init(s, x, y, (
size_t) n);
8969 for (
int i = 0; i < n2; i++)
8972 else if (x2[i] >= x[n - 1])
8975 y2[i] = gsl_spline_eval(s, x2[i], acc);
8979 gsl_interp_accel_free(acc);
8984 for (
int i = 0; i < n2; i++)
8987 else if (x2[i] >= x[n - 1])
8991 y2[i] =
LIN(x[idx], y[idx], x[idx + 1], y[idx + 1], x2[i]);
9005 float mean = 0, var = 0;
9007 for (
int i = 0; i < n; ++i) {
9009 var +=
SQR(data[i]);
9012 var = var / (float) n -
SQR(mean / (
float) n);
9014 return (var > 0 ? sqrtf(var) : 0);
9025 const double D = sec / 86400 - 0.5;
9028 const double g =
DEG2RAD(357.529 + 0.98560028 * D);
9029 const double q = 280.459 + 0.98564736 * D;
9030 const double L =
DEG2RAD(q + 1.915 * sin(g) + 0.020 * sin(2 * g));
9033 const double e =
DEG2RAD(23.439 - 0.00000036 * D);
9036 const double sindec = sin(e) * sin(L);
9039 const double ra = atan2(cos(e) * sin(L), cos(L));
9042 const double GMST = 18.697374558 + 24.06570982441908 * D;
9045 const double LST = GMST + lon / 15;
9048 const double h = LST / 12 * M_PI - ra;
9051 const double lat_help =
DEG2RAD(lat);
9054 return acos(sin(lat_help) * sindec +
9055 cos(lat_help) * sqrt(1 -
SQR(sindec)) * cos(h));
9067 const double remain,
9079 t1.tm_year = year - 1900;
9080 t1.tm_mon = mon - 1;
9086 *jsec = (double) timegm(&t1) - (double) timegm(&t0) + remain;
9101 static int iname = -1, igroup = -1, nname, ngroup, ct_name[
NTIMER];
9104 t1 = omp_get_wtime();
9109 rt_name[iname] += dt;
9110 rt_min[iname] = (ct_name[iname] <= 0 ? dt :
MIN(rt_min[iname], dt));
9111 rt_max[iname] = (ct_name[iname] <= 0 ? dt :
MAX(rt_max[iname], dt));
9115 rt_group[igroup] += t1 - t0;
9119 for (
int i = 0; i < nname; i++)
9120 LOG(1,
"TIMER_%s = %.3f s (min= %g s, mean= %g s,"
9121 " max= %g s, n= %d)", names[i], rt_name[i], rt_min[i],
9122 rt_name[i] / ct_name[i], rt_max[i], ct_name[i]);
9123 for (
int i = 0; i < ngroup; i++)
9124 LOG(1,
"TIMER_GROUP_%s = %.3f s", groups[i], rt_group[i]);
9126 for (
int i = 0; i < nname; i++)
9127 total += rt_name[i];
9128 LOG(1,
"TIMER_TOTAL = %.3f s", total);
9132 for (iname = 0; iname < nname; iname++)
9133 if (strcasecmp(name, names[iname]) == 0)
9135 for (igroup = 0; igroup < ngroup; igroup++)
9136 if (strcasecmp(group, groups[igroup]) == 0)
9140 if (iname >= nname) {
9141 sprintf(names[iname],
"%s", name);
9143 ERRMSG(
"Too many timers!");
9147 if (igroup >= ngroup) {
9148 sprintf(groups[igroup],
"%s", group);
9149 if ((++ngroup) >=
NTIMER)
9150 ERRMSG(
"Too many groups!");
9160 const char *filename,
9168 int len = (int) strlen(filename);
9169 sprintf(tstr,
"%.4s", &filename[len - offset]);
9170 int year = atoi(tstr);
9171 sprintf(tstr,
"%.2s", &filename[len - offset + 5]);
9172 int mon = atoi(tstr);
9173 sprintf(tstr,
"%.2s", &filename[len - offset + 8]);
9174 int day = atoi(tstr);
9175 sprintf(tstr,
"%.2s", &filename[len - offset + 11]);
9176 int hour = atoi(tstr);
9177 sprintf(tstr,
"%.2s", &filename[len - offset + 14]);
9178 int min = atoi(tstr);
9181 if (year < 1900 || year > 2100 || mon < 1 || mon > 12 || day < 1
9182 || day > 31 || hour < 0 || hour > 23 || min < 0 || min > 59)
9183 ERRMSG(
"Cannot read time from filename!");
9186 time2jsec(year, mon, day, hour, min, 0, 0.0, &t);
9203 const double p1 = pt * 0.866877899;
9204 const double p0 = pt / 0.866877899;
9207 if (atm->
p[ip] > p0)
9209 else if (atm->
p[ip] < p1)
9212 return LIN(p0, 1.0, p1, 0.0, atm->
p[ip]);
9218 const char *filename,
9226 const double t0 = t - 0.5 * ctl->
dt_mod;
9227 const double t1 = t + 0.5 * ctl->
dt_mod;
9233 if (!(out = popen(
"gnuplot",
"w")))
9234 ERRMSG(
"Cannot create pipe to gnuplot!");
9237 fprintf(out,
"set out \"%s.png\"\n", filename);
9241 int year, mon, day, hour, min, sec;
9242 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
9243 fprintf(out,
"timestr=\"%d-%02d-%02d, %02d:%02d UTC\"\n",
9244 year, mon, day, hour, min);
9249 ERRMSG(
"Cannot open file!");
9251 while (fgets(line,
LEN, in))
9252 fprintf(out,
"%s", line);
9259 if (!(out = fopen(filename,
"w")))
9260 ERRMSG(
"Cannot create file!");
9266 "# $2 = altitude [km]\n"
9267 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
9268 for (
int iq = 0; iq < ctl->
nq; iq++)
9269 fprintf(out,
"# $%i = %s [%s]\n", iq + 5, ctl->
qnt_name[iq],
9274 for (
int ip = 0; ip < atm->
np; ip += ctl->
atm_stride) {
9281 fprintf(out,
"%.2f %g %g %g", atm->
time[ip],
Z(atm->
p[ip]),
9282 atm->
lon[ip], atm->
lat[ip]);
9283 for (
int iq = 0; iq < ctl->
nq; iq++) {
9288 fprintf(out, ctl->
qnt_format[iq], atm->
q[iq][ip]);
9300 const char *filename,
9307 if (!(out = fopen(filename,
"w")))
9308 ERRMSG(
"Cannot create file!");
9332 for (
int iq = 0; iq < ctl->
nq; iq++)
9350 const char *filename,
9354 int tid, pid, ncid, varid;
9355 size_t start[2], count[2];
9358 nc_create(filename, NC_NETCDF4, &ncid);
9361 NC(nc_def_dim(ncid,
"time", 1, &tid));
9362 NC(nc_def_dim(ncid,
"NPARTS", (
size_t) atm->
np, &pid));
9365 int dim_ids[2] = { tid, pid };
9366 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"Time",
9367 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
9368 NC_DEF_VAR(
"LAT", NC_DOUBLE, 1, &pid,
"Latitude",
"deg",
9370 NC_DEF_VAR(
"LON", NC_DOUBLE, 1, &pid,
"Longitude",
"deg",
9372 NC_DEF_VAR(
"PRESS", NC_DOUBLE, 1, &pid,
"Pressure",
"hPa",
9375 for (
int iq = 0; iq < ctl->
nq; iq++)
9385 NC(nc_enddef(ncid));
9393 for (
int iq = 0; iq < ctl->
nq; iq++)
9403 const char *dirname,
9409 static size_t out_cnt = 0;
9411 double r, r_start, r_stop;
9412 int year, mon, day, hour, min, sec;
9413 int year_start, mon_start, day_start, hour_start, min_start, sec_start;
9414 int year_stop, mon_stop, day_stop, hour_stop, min_stop, sec_stop;
9415 char filename_out[2 *
LEN] =
"traj_fix_3d_YYYYMMDDHH_YYYYMMDDHH.nc";
9417 int ncid, varid, tid, pid, cid;
9425 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
9427 &min_start, &sec_start, &r_start);
9429 &min_stop, &sec_stop, &r_stop);
9431 sprintf(filename_out,
"%s/traj_fix_3d_%02d%02d%02d%02d_%02d%02d%02d%02d.nc",
9433 year_start % 100, mon_start, day_start, hour_start,
9434 year_stop % 100, mon_stop, day_stop, hour_stop);
9435 LOG(1,
"Write traj file: %s", filename_out);
9441 count[1] = (size_t) atm->
np;
9447 nc_create(filename_out, NC_NETCDF4, &ncid);
9450 NC(nc_def_dim(ncid,
"time", NC_UNLIMITED, &tid));
9451 NC(nc_def_dim(ncid,
"NPARTS", (
size_t) atm->
np, &pid));
9452 NC(nc_def_dim(ncid,
"TMDT", 7, &cid));
9457 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"Time",
9458 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
9459 NC_DEF_VAR(
"LAT", NC_DOUBLE, 2, dim_ids,
"Latitude",
"deg",
9461 NC_DEF_VAR(
"LON", NC_DOUBLE, 2, dim_ids,
"Longitude",
"deg",
9463 NC_DEF_VAR(
"PRESS", NC_DOUBLE, 2, dim_ids,
"Pressure",
"hPa",
9465 NC_DEF_VAR(
"ZETA", NC_DOUBLE, 2, dim_ids,
"Zeta",
"K",
9467 for (
int iq = 0; iq < ctl->
nq; iq++)
9477 NC(nc_enddef(ncid));
9485 NC(nc_open(filename_out, NC_WRITE, &ncid));
9497 for (
int iq = 0; iq < ctl->
nq; iq++)
9504 if ((year == year_stop) && (mon == mon_stop)
9505 && (day == day_stop) && (hour == hour_stop)) {
9508 char filename_init[2 *
LEN] =
"./init_fix_YYYYMMDDHH.nc";
9509 sprintf(filename_init,
"%s/init_fix_%02d%02d%02d%02d.nc",
9510 dirname, year_stop % 100, mon_stop, day_stop, hour_stop);
9511 LOG(1,
"Write init file: %s", filename_init);
9514 nc_create(filename_init, NC_NETCDF4, &ncid);
9517 NC(nc_def_dim(ncid,
"time", 1, &tid));
9518 NC(nc_def_dim(ncid,
"NPARTS", (
size_t) atm->
np, &pid));
9523 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"Time",
9524 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
9525 NC_DEF_VAR(
"LAT", NC_DOUBLE, 1, &pid,
"Latitude",
"deg",
9527 NC_DEF_VAR(
"LON", NC_DOUBLE, 1, &pid,
"Longitude",
"deg",
9529 NC_DEF_VAR(
"PRESS", NC_DOUBLE, 1, &pid,
"Pressure",
"hPa",
9532 for (
int iq = 0; iq < ctl->
nq; iq++)
9542 NC(nc_enddef(ncid));
9550 for (
int iq = 0; iq < ctl->
nq; iq++)
9561 const char *filename,
9565 int ncid, obsid, varid;
9567 size_t start[2], count[2];
9570 NC(nc_create(filename, NC_NETCDF4, &ncid));
9573 NC(nc_def_dim(ncid,
"obs", (
size_t) atm->
np, &obsid));
9576 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &obsid,
"time",
9577 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
9578 NC_DEF_VAR(
"press", NC_DOUBLE, 1, &obsid,
"pressure",
"hPa",
9580 NC_DEF_VAR(
"lon", NC_DOUBLE, 1, &obsid,
"longitude",
"degrees_east",
9582 NC_DEF_VAR(
"lat", NC_DOUBLE, 1, &obsid,
"latitude",
"degrees_north",
9584 for (
int iq = 0; iq < ctl->
nq; iq++)
9593 NC(nc_enddef(ncid));
9600 for (
int iq = 0; iq < ctl->
nq; iq++)
9610 const char *filename,
9617 static double *modmean, *obsmean, *obsstd, *rt, *rz, *rlon, *rlat, *robs,
9620 static int *obscount, ct, cx, cy, cz, ip, ix, iy, iz, n, nobs, nk;
9630 ERRMSG(
"Need quantity mass!");
9654 LOG(1,
"Write CSI data: %s", filename);
9655 if (!(out = fopen(filename,
"w")))
9656 ERRMSG(
"Cannot create file!");
9661 "# $2 = number of hits (cx)\n"
9662 "# $3 = number of misses (cy)\n"
9663 "# $4 = number of false alarms (cz)\n"
9664 "# $5 = number of observations (cx + cy)\n"
9665 "# $6 = number of forecasts (cx + cz)\n"
9666 "# $7 = bias (ratio of forecasts and observations) [%%]\n"
9667 "# $8 = probability of detection (POD) [%%]\n"
9668 "# $9 = false alarm rate (FAR) [%%]\n"
9669 "# $10 = critical success index (CSI) [%%]\n");
9671 "# $11 = hits associated with random chance\n"
9672 "# $12 = equitable threat score (ETS) [%%]\n"
9673 "# $13 = Pearson linear correlation coefficient\n"
9674 "# $14 = Spearman rank-order correlation coefficient\n"
9675 "# $15 = column density mean error (F - O) [kg/m^2]\n"
9676 "# $16 = column density root mean square error (RMSE) [kg/m^2]\n"
9677 "# $17 = column density mean absolute error [kg/m^2]\n"
9678 "# $18 = log-likelihood function\n"
9679 "# $19 = number of data points\n\n");
9687 for (iy = 0; iy < ctl->
csi_ny; iy++) {
9688 const double lat = ctl->
csi_lat0 + dlat * (iy + 0.5);
9689 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat));
9694 const double t0 = t - 0.5 * ctl->
dt_mod;
9695 const double t1 = t + 0.5 * ctl->
dt_mod;
9698 ALLOC(modmean,
double,
9700 ALLOC(obsmean,
double,
9702 ALLOC(obscount,
int,
9704 ALLOC(obsstd,
double,
9708 for (
int i = 0; i < nobs; i++) {
9713 else if (rt[i] >= t1)
9717 if (!isfinite(robs[i]))
9721 ix = (int) ((rlon[i] - ctl->
csi_lon0) / dlon);
9722 iy = (int) ((rlat[i] - ctl->
csi_lat0) / dlat);
9723 iz = (int) ((rz[i] - ctl->
csi_z0) / dz);
9726 if (ix < 0 || ix >= ctl->
csi_nx ||
9727 iy < 0 || iy >= ctl->
csi_ny || iz < 0 || iz >= ctl->
csi_nz)
9732 obsmean[idx] += robs[i];
9733 obsstd[idx] +=
SQR(robs[i]);
9738 for (ip = 0; ip < atm->
np; ip++) {
9741 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
9745 ix = (int) ((atm->
lon[ip] - ctl->
csi_lon0) / dlon);
9746 iy = (int) ((atm->
lat[ip] - ctl->
csi_lat0) / dlat);
9747 iz = (int) ((
Z(atm->
p[ip]) - ctl->
csi_z0) / dz);
9750 if (ix < 0 || ix >= ctl->
csi_nx ||
9751 iy < 0 || iy >= ctl->
csi_ny || iz < 0 || iz >= ctl->
csi_nz)
9757 * atm->
q[ctl->
qnt_m][ip];
9761 for (ix = 0; ix < ctl->
csi_nx; ix++)
9762 for (iy = 0; iy < ctl->
csi_ny; iy++)
9763 for (iz = 0; iz < ctl->
csi_nz; iz++) {
9767 if (obscount[idx] > 0) {
9768 obsmean[idx] /= obscount[idx];
9769 obsstd[idx] -=
SQR(obsmean[idx]);
9770 obsstd[idx] = sqrt(obsstd[idx]);
9774 if (modmean[idx] > 0)
9775 modmean[idx] /= (1e6 * area[iy]);
9778 if (obscount[idx] > 0) {
9792 if (obscount[idx] > 0
9795 x[n] = modmean[idx];
9796 y[n] = obsmean[idx];
9798 obsstdn[n] = obsstd[idx];
9800 ERRMSG(
"Too many data points to calculate statistics!");
9809 static double work[2 *
NCSI], work2[2 *
NCSI];;
9810 const int n_obs = cx + cy;
9811 const int n_for = cx + cz;
9812 const double bias = (n_obs > 0) ? 100. * n_for / n_obs : NAN;
9813 const double pod = (n_obs > 0) ? (100. * cx) / n_obs : NAN;
9814 const double far = (n_for > 0) ? (100. * cz) / n_for : NAN;
9816 (cx + cy + cz > 0) ? (100. * cx) / (cx + cy + cz) : NAN;
9817 const double cx_rd = (ct > 0) ? (1. * n_obs * n_for) / ct : NAN;
9818 const double ets = (cx + cy + cz - cx_rd > 0) ?
9819 (100. * (cx - cx_rd)) / (cx + cy + cz - cx_rd) : NAN;
9820 const double rho_p =
9821 (n > 0) ? gsl_stats_correlation(x, 1, y, 1, (
size_t) n) : NAN;
9822 const double rho_s =
9823 (n > 0) ? gsl_stats_spearman(x, 1, y, 1, (
size_t) n, work) : NAN;
9824 for (
int i = 0; i < n; i++) {
9825 work[i] = x[i] - y[i];
9826 work2[i] = (obsstdn[i] != 0) ? (x[i] - y[i]) / obsstdn[i] : 0;
9828 const double mean = (n > 0) ? gsl_stats_mean(work, 1, (
size_t) n) : NAN;
9830 (n > 0) ? gsl_stats_sd_with_fixed_mean(work, 1, (
size_t) n,
9832 const double absdev =
9833 (n > 0) ? gsl_stats_absdev_m(work, 1, (
size_t) n, 0.0) : NAN;
9834 const double loglikelihood =
9835 (n > 0) ? gsl_stats_tss(work2, 1, (
size_t) n) * (-0.5) : GSL_NAN;
9839 "%.2f %d %d %d %d %d %g %g %g %g %g %g %g %g %g %g %g %g %d\n", t,
9840 cx, cy, cz, n_obs, n_for, bias, pod, far, csi, cx_rd, ets, rho_p,
9841 rho_s, mean, rmse, absdev, loglikelihood, n);
9844 n = ct = cx = cy = cz = 0;
9872 const char *filename,
9889 ERRMSG(
"Missing ensemble IDs!");
9892 const double t0 = t - 0.5 * ctl->
dt_mod;
9893 const double t1 = t + 0.5 * ctl->
dt_mod;
9896 for (
int i = 0; i <
NENS; i++) {
9897 for (
int iq = 0; iq < ctl->
nq; iq++)
9898 qm[iq][i] = qs[iq][i] = 0;
9899 xm[i][0] = xm[i][1] = xm[i][2] = zm[i] = 0;
9904 for (
int ip = 0; ip < atm->
np; ip++) {
9907 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
9912 ERRMSG(
"Ensemble ID is out of range!");
9916 for (
int iq = 0; iq < ctl->
nq; iq++) {
9917 qm[iq][ctl->
qnt_ens] += atm->
q[iq][ip];
9928 LOG(1,
"Write ensemble data: %s", filename);
9929 if (!(out = fopen(filename,
"w")))
9930 ERRMSG(
"Cannot create file!");
9935 "# $2 = altitude [km]\n"
9936 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
9937 for (
int iq = 0; iq < ctl->
nq; iq++)
9938 fprintf(out,
"# $%d = %s (mean) [%s]\n", 5 + iq,
9940 for (
int iq = 0; iq < ctl->
nq; iq++)
9941 fprintf(out,
"# $%d = %s (sigma) [%s]\n", 5 + ctl->
nq + iq,
9943 fprintf(out,
"# $%d = number of members\n\n", 5 + 2 * ctl->
nq);
9946 for (
int i = 0; i <
NENS; i++)
9948 cart2geo(xm[i], &dummy, &lon, &lat);
9949 fprintf(out,
"%.2f %g %g %g", t, zm[i] / n[i], lon, lat);
9950 for (
int iq = 0; iq < ctl->
nq; iq++) {
9952 fprintf(out, ctl->
qnt_format[iq], qm[iq][i] / n[i]);
9954 for (
int iq = 0; iq < ctl->
nq; iq++) {
9956 double var = qs[iq][i] / n[i] -
SQR(qm[iq][i] / n[i]);
9957 fprintf(out, ctl->
qnt_format[iq], (var > 0 ? sqrt(var) : 0));
9959 fprintf(out,
" %d\n", n[i]);
9969 const char *filename,
9976 static double kz[
EP], kw[
EP];
9980 double *cd, *mean[
NQ], *sigma[
NQ], *vmr_impl, *z, *lon, *lat, *area, *press;
9982 int *ixs, *iys, *izs, *np;
9988 LOG(1,
"Write grid data: %s", filename);
10001 for (
int iq = 0; iq < ctl->
nq; iq++) {
10002 ALLOC(mean[iq],
double,
10004 ALLOC(sigma[iq],
double,
10007 ALLOC(vmr_impl,
double,
10015 ALLOC(area,
double,
10017 ALLOC(press,
double,
10034#pragma omp parallel
for default(shared)
10035 for (
int iz = 0; iz < ctl->
grid_nz; iz++) {
10036 z[iz] = ctl->
grid_z0 + dz * (iz + 0.5);
10037 press[iz] =
P(z[iz]);
10041 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
10042 lon[ix] = ctl->
grid_lon0 + dlon * (ix + 0.5);
10043#pragma omp parallel for default(shared)
10044 for (
int iy = 0; iy < ctl->
grid_ny; iy++) {
10045 lat[iy] = ctl->
grid_lat0 + dlat * (iy + 0.5);
10046 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat[iy]));
10050 const double t0 = t - 0.5 * ctl->
dt_mod;
10051 const double t1 = t + 0.5 * ctl->
dt_mod;
10054#pragma omp parallel for default(shared)
10055 for (
int ip = 0; ip < atm->
np; ip++) {
10056 ixs[ip] = (int) ((atm->
lon[ip] - ctl->
grid_lon0) / dlon);
10057 iys[ip] = (int) ((atm->
lat[ip] - ctl->
grid_lat0) / dlat);
10058 izs[ip] = (int) ((
Z(atm->
p[ip]) - ctl->
grid_z0) / dz);
10059 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
10060 || ixs[ip] < 0 || ixs[ip] >= ctl->
grid_nx
10061 || iys[ip] < 0 || iys[ip] >= ctl->
grid_ny
10062 || izs[ip] < 0 || izs[ip] >= ctl->
grid_nz)
10067 for (
int ip = 0; ip < atm->
np; ip++)
10068 if (izs[ip] >= 0) {
10073 for (
int iq = 0; iq < ctl->
nq; iq++) {
10074 mean[iq][idx] += kernel * atm->
q[iq][ip];
10075 sigma[iq][idx] +=
SQR(kernel * atm->
q[iq][ip]);
10080#pragma omp parallel for default(shared)
10081 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
10082 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
10083 for (
int iz = 0; iz < ctl->
grid_nz; iz++) {
10090 if (ctl->
qnt_m >= 0)
10091 cd[idx] = mean[ctl->
qnt_m][idx] / (1e6 * area[iy]);
10094 vmr_impl[idx] = NAN;
10095 if (ctl->
qnt_m >= 0 && ctl->
molmass > 0 && met0 != NULL
10098 if (mean[ctl->
qnt_m][idx] > 0) {
10104 lon[ix], lat[iy], &temp, ci, cw, 1);
10108 MA / ctl->
molmass * cd[idx] / (
RHO(press[iz], temp) * dz * 1e3);
10114 for (
int iq = 0; iq < ctl->
nq; iq++) {
10115 mean[iq][idx] /= np[idx];
10116 double var = sigma[iq][idx] / np[idx] -
SQR(mean[iq][idx]);
10117 sigma[iq][idx] = (var > 0 ? sqrt(var) : 0);
10119 for (
int iq = 0; iq < ctl->
nq; iq++) {
10120 mean[iq][idx] = NAN;
10121 sigma[iq][idx] = NAN;
10128 t, z, lon, lat, area, dz, np);
10133 t, z, lon, lat, area, dz, np);
10137 ERRMSG(
"Grid data format GRID_TYPE unknown!");
10141 for (
int iq = 0; iq < ctl->
nq; iq++) {
10160 const char *filename,
10165 const double *vmr_impl,
10170 const double *area,
10180 if (!(out = popen(
"gnuplot",
"w")))
10181 ERRMSG(
"Cannot create pipe to gnuplot!");
10184 fprintf(out,
"set out \"%s.png\"\n", filename);
10188 int year, mon, day, hour, min, sec;
10189 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
10190 fprintf(out,
"timestr=\"%d-%02d-%02d, %02d:%02d UTC\"\n",
10191 year, mon, day, hour, min);
10197 ERRMSG(
"Cannot open file!");
10198 while (fgets(line,
LEN, in))
10199 fprintf(out,
"%s", line);
10206 if (!(out = fopen(filename,
"w")))
10207 ERRMSG(
"Cannot create file!");
10212 "# $1 = time [s]\n"
10213 "# $2 = altitude [km]\n"
10214 "# $3 = longitude [deg]\n"
10215 "# $4 = latitude [deg]\n"
10216 "# $5 = surface area [km^2]\n"
10217 "# $6 = layer depth [km]\n"
10218 "# $7 = column density (implicit) [kg/m^2]\n"
10219 "# $8 = volume mixing ratio (implicit) [ppv]\n"
10220 "# $9 = number of particles [1]\n");
10221 for (
int iq = 0; iq < ctl->
nq; iq++)
10222 fprintf(out,
"# $%i = %s (mean) [%s]\n", 10 + iq, ctl->
qnt_name[iq],
10225 for (
int iq = 0; iq < ctl->
nq; iq++)
10226 fprintf(out,
"# $%i = %s (stddev) [%s]\n", 10 + ctl->
nq + iq,
10228 fprintf(out,
"\n");
10231 for (
int ix = 0; ix < ctl->
grid_nx; ix++) {
10233 fprintf(out,
"\n");
10234 for (
int iy = 0; iy < ctl->
grid_ny; iy++) {
10236 fprintf(out,
"\n");
10237 for (
int iz = 0; iz < ctl->
grid_nz; iz++) {
10240 fprintf(out,
"%.2f %g %g %g %g %g %g %g %d", t, z[iz], lon[ix],
10241 lat[iy], area[iy], dz, cd[idx], vmr_impl[idx], np[idx]);
10242 for (
int iq = 0; iq < ctl->
nq; iq++) {
10244 fprintf(out, ctl->
qnt_format[iq], mean[iq][idx]);
10247 for (
int iq = 0; iq < ctl->
nq; iq++) {
10249 fprintf(out, ctl->
qnt_format[iq], sigma[iq][idx]);
10251 fprintf(out,
"\n");
10264 const char *filename,
10269 const double *vmr_impl,
10274 const double *area,
10278 char longname[2 *
LEN], varname[2 *
LEN];
10282 int *help2, ncid, dimid[10], varid;
10284 size_t start[2], count[2];
10287 ALLOC(help,
double,
10293 NC(nc_create(filename, NC_NETCDF4, &ncid));
10296 NC(nc_def_dim(ncid,
"time", 1, &dimid[0]));
10297 NC(nc_def_dim(ncid,
"z", (
size_t) ctl->
grid_nz, &dimid[1]));
10298 NC(nc_def_dim(ncid,
"lat", (
size_t) ctl->
grid_ny, &dimid[2]));
10299 NC(nc_def_dim(ncid,
"lon", (
size_t) ctl->
grid_nx, &dimid[3]));
10300 NC(nc_def_dim(ncid,
"dz", 1, &dimid[4]));
10303 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &dimid[0],
"time",
10304 "seconds since 2000-01-01 00:00:00 UTC", 0, 0);
10305 NC_DEF_VAR(
"z", NC_DOUBLE, 1, &dimid[1],
"altitude",
"km", 0, 0);
10306 NC_DEF_VAR(
"lat", NC_DOUBLE, 1, &dimid[2],
"latitude",
"degrees_north", 0,
10308 NC_DEF_VAR(
"lon", NC_DOUBLE, 1, &dimid[3],
"longitude",
"degrees_east", 0,
10310 NC_DEF_VAR(
"dz", NC_DOUBLE, 1, &dimid[1],
"layer depth",
"km", 0, 0);
10311 NC_DEF_VAR(
"area", NC_DOUBLE, 1, &dimid[2],
"surface area",
"km**2", 0, 0);
10313 NC_DEF_VAR(
"cd", NC_FLOAT, 4, dimid,
"column density",
"kg m**-2",
10315 NC_DEF_VAR(
"vmr_impl", NC_FLOAT, 4, dimid,
"volume mixing ratio (implicit)",
10317 NC_DEF_VAR(
"np", NC_INT, 4, dimid,
"number of particles",
"1", 0, 0);
10318 for (
int iq = 0; iq < ctl->
nq; iq++) {
10319 sprintf(varname,
"%s_mean", ctl->
qnt_name[iq]);
10320 sprintf(longname,
"%s (mean)", ctl->
qnt_longname[iq]);
10324 sprintf(varname,
"%s_stddev", ctl->
qnt_name[iq]);
10325 sprintf(longname,
"%s (stddev)", ctl->
qnt_longname[iq]);
10331 NC(nc_enddef(ncid));
10341 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
10342 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
10343 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
10348 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
10349 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
10350 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
10355 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
10356 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
10357 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
10362 for (
int iq = 0; iq < ctl->
nq; iq++) {
10363 sprintf(varname,
"%s_mean", ctl->
qnt_name[iq]);
10364 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
10365 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
10366 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
10373 for (
int iq = 0; iq < ctl->
nq; iq++) {
10374 sprintf(varname,
"%s_stddev", ctl->
qnt_name[iq]);
10375 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
10376 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
10377 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
10384 NC(nc_close(ncid));
10394 const char *filename,
10400 if (!(out = fopen(filename,
"w")))
10401 ERRMSG(
"Cannot create file!");
10498 const char *varname) {
10507 for (
int ix = 0; ix < met->
nx; ix++)
10508 for (
int iy = 0; iy < met->
ny; iy++)
10509 help[
ARRAY_2D(ix, iy, met->
ny)] = var[ix][iy];
10512 LOG(2,
"Write 2-D variable: %s (uncompressed)", varname);
10514 (
size_t) (met->
nx * met->
ny),
10528 const char *varname,
10529 const int precision,
10530 const double tolerance) {
10539#pragma omp parallel for default(shared) collapse(2)
10540 for (
int ix = 0; ix < met->
nx; ix++)
10541 for (
int iy = 0; iy < met->
ny; iy++)
10542 for (
int ip = 0; ip < met->
np; ip++)
10543 help[
ARRAY_3D(ix, iy, met->
ny, ip, met->
np)] = var[ix][iy][ip];
10547 LOG(2,
"Write 3-D variable: %s (uncompressed)", varname);
10549 (
size_t) (met->
nx * met->
ny * met->
np),
10556 (
size_t) met->
np, 0, out);
10564 FWRITE(&tolerance,
double,
10568 tolerance, 0, out);
10583 (
size_t) met->
np, 0, out);
10589 ERRMSG(
"MET_TYPE not supported!");
10590 LOG(3,
"%d %g", precision, tolerance);
10600 const char *filename,
10606 size_t start[4], count[4];
10607 nc_create(filename, NC_NETCDF4, &ncid);
10610 int tid, lonid, latid, levid;
10611 NC(nc_def_dim(ncid,
"time", 1, &tid));
10612 NC(nc_def_dim(ncid,
"lon", (
size_t) met->
nx, &lonid));
10613 NC(nc_def_dim(ncid,
"lat", (
size_t) met->
ny, &latid));
10614 NC(nc_def_dim(ncid,
"lev", (
size_t) met->
np, &levid));
10617 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"time",
10618 "seconds since 2000-01-01 00:00:00 UTC", 0, 0);
10619 NC_DEF_VAR(
"lon", NC_DOUBLE, 1, &lonid,
"longitude",
"degrees_east", 0, 0);
10620 NC_DEF_VAR(
"lat", NC_DOUBLE, 1, &latid,
"latitude",
"degrees_north", 0, 0);
10621 NC_DEF_VAR(
"lev", NC_DOUBLE, 1, &levid,
"pressure",
"Pa", 0, 0);
10624 int dimid2[2] = { latid, lonid };
10625 NC_DEF_VAR(
"sp", NC_FLOAT, 2, dimid2,
"Surface pressure",
"Pa",
10627 NC_DEF_VAR(
"z", NC_FLOAT, 2, dimid2,
"Geopotential",
"m**2 s**-2",
10629 NC_DEF_VAR(
"t2m", NC_FLOAT, 2, dimid2,
"2 metre temperature",
"K",
10631 NC_DEF_VAR(
"u10m", NC_FLOAT, 2, dimid2,
"10 metre U wind component",
10633 NC_DEF_VAR(
"v10m", NC_FLOAT, 2, dimid2,
"10 metre V wind component",
10636 "Instantaneous eastward turbulent surface stress",
"N m**-2",
10639 "Instantaneous northward turbulent surface stress",
"N m**-2",
10642 "Instantaneous surface sensible heat flux",
"W m**-1",
10644 NC_DEF_VAR(
"lsm", NC_FLOAT, 2, dimid2,
"Land/sea mask",
"-",
10646 NC_DEF_VAR(
"sstk", NC_FLOAT, 2, dimid2,
"Sea surface temperature",
"K",
10648 NC_DEF_VAR(
"blp", NC_FLOAT, 2, dimid2,
"Boundary layer pressure",
"Pa",
10650 NC_DEF_VAR(
"pt", NC_FLOAT, 2, dimid2,
"Tropopause pressure",
"Pa",
10652 NC_DEF_VAR(
"tt", NC_FLOAT, 2, dimid2,
"Tropopause temperature",
"K",
10654 NC_DEF_VAR(
"zt", NC_FLOAT, 2, dimid2,
"Tropopause height",
"m",
10656 NC_DEF_VAR(
"h2ot", NC_FLOAT, 2, dimid2,
"Tropopause water vapor",
"ppv",
10658 NC_DEF_VAR(
"pct", NC_FLOAT, 2, dimid2,
"Cloud top pressure",
"Pa",
10660 NC_DEF_VAR(
"pcb", NC_FLOAT, 2, dimid2,
"Cloud bottom pressure",
"Pa",
10662 NC_DEF_VAR(
"cl", NC_FLOAT, 2, dimid2,
"Total column cloud water",
"kg m**2",
10665 "Pressure at lifted condensation level (LCL)",
"Pa",
10668 "Pressure at level of free convection (LFC)",
"Pa",
10670 NC_DEF_VAR(
"pel", NC_FLOAT, 2, dimid2,
"Pressure at equilibrium level (EL)",
10673 "Convective available potential energy",
"J kg**-1",
10675 NC_DEF_VAR(
"cin", NC_FLOAT, 2, dimid2,
"Convective inhibition",
"J kg**-1",
10677 NC_DEF_VAR(
"o3c", NC_FLOAT, 2, dimid2,
"Total column ozone",
"DU",
10681 int dimid3[3] = { levid, latid, lonid };
10682 NC_DEF_VAR(
"t", NC_FLOAT, 3, dimid3,
"Temperature",
"K",
10684 NC_DEF_VAR(
"u", NC_FLOAT, 3, dimid3,
"U velocity",
"m s**-1",
10686 NC_DEF_VAR(
"v", NC_FLOAT, 3, dimid3,
"V velocity",
"m s**-1",
10688 NC_DEF_VAR(
"w", NC_FLOAT, 3, dimid3,
"Vertical velocity",
"Pa s**-1",
10690 NC_DEF_VAR(
"q", NC_FLOAT, 3, dimid3,
"Specific humidity",
"kg kg**-1",
10692 NC_DEF_VAR(
"o3", NC_FLOAT, 3, dimid3,
"Ozone mass mixing ratio",
10694 NC_DEF_VAR(
"clwc", NC_FLOAT, 3, dimid3,
"Cloud liquid water content",
10696 NC_DEF_VAR(
"crwc", NC_FLOAT, 3, dimid3,
"Cloud rain water content",
10698 NC_DEF_VAR(
"ciwc", NC_FLOAT, 3, dimid3,
"Cloud ice water content",
10700 NC_DEF_VAR(
"cswc", NC_FLOAT, 3, dimid3,
"Cloud snow water content",
10702 NC_DEF_VAR(
"cc", NC_FLOAT, 3, dimid3,
"Cloud cover",
"-",
10706 NC(nc_enddef(ncid));
10713 for (
int ip = 0; ip < met->
np; ip++)
10714 phelp[ip] = 100. * met->
p[ip];
10757 NC(nc_close(ncid));
10764 const char *varname,
10770 size_t start[4], count[4];
10778 for (
int ix = 0; ix < met->
nx; ix++)
10779 for (
int iy = 0; iy < met->
ny; iy++)
10780 help[
ARRAY_2D(iy, ix, met->
nx)] = scl * var[ix][iy];
10793 const char *varname,
10799 size_t start[4], count[4];
10807 for (
int ix = 0; ix < met->
nx; ix++)
10808 for (
int iy = 0; iy < met->
ny; iy++)
10809 for (
int ip = 0; ip < met->
np; ip++)
10810 help[
ARRAY_3D(ip, iy, met->
ny, ix, met->
nx)] = scl * var[ix][iy][ip];
10822 const char *filename,
10831 static double *mass, *obsmean, *rt, *rz, *rlon, *rlat, *robs, *area,
10832 dz, dlon, dlat, *lon, *lat, *z, *press, temp, vmr, h2o, o3;
10834 static int nobs, *obscount, ip, okay;
10843 if (ctl->
qnt_m < 0)
10844 ERRMSG(
"Need quantity mass!");
10848 ERRMSG(
"Specify molar mass!");
10855 ALLOC(area,
double,
10859 ALLOC(press,
double,
10865 ALLOC(rlon,
double,
10867 ALLOC(rlat,
double,
10869 ALLOC(robs,
double,
10876 LOG(1,
"Write profile data: %s", filename);
10877 if (!(out = fopen(filename,
"w")))
10878 ERRMSG(
"Cannot create file!");
10882 "# $1 = time [s]\n"
10883 "# $2 = altitude [km]\n"
10884 "# $3 = longitude [deg]\n"
10885 "# $4 = latitude [deg]\n"
10886 "# $5 = pressure [hPa]\n"
10887 "# $6 = temperature [K]\n"
10888 "# $7 = volume mixing ratio [ppv]\n"
10889 "# $8 = H2O volume mixing ratio [ppv]\n"
10890 "# $9 = O3 volume mixing ratio [ppv]\n"
10891 "# $10 = observed BT index [K]\n"
10892 "# $11 = number of observations\n");
10900 for (
int iz = 0; iz < ctl->
prof_nz; iz++) {
10901 z[iz] = ctl->
prof_z0 + dz * (iz + 0.5);
10902 press[iz] =
P(z[iz]);
10906 for (
int ix = 0; ix < ctl->
prof_nx; ix++)
10907 lon[ix] = ctl->
prof_lon0 + dlon * (ix + 0.5);
10908 for (
int iy = 0; iy < ctl->
prof_ny; iy++) {
10909 lat[iy] = ctl->
prof_lat0 + dlat * (iy + 0.5);
10910 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat[iy]));
10915 const double t0 = t - 0.5 * ctl->
dt_mod;
10916 const double t1 = t + 0.5 * ctl->
dt_mod;
10919 ALLOC(mass,
double,
10921 ALLOC(obsmean,
double,
10923 ALLOC(obscount,
int,
10927 for (
int i = 0; i < nobs; i++) {
10932 else if (rt[i] >= t1)
10936 if (!isfinite(robs[i]))
10940 int ix = (int) ((rlon[i] - ctl->
prof_lon0) / dlon);
10941 int iy = (int) ((rlat[i] - ctl->
prof_lat0) / dlat);
10944 if (ix < 0 || ix >= ctl->
prof_nx || iy < 0 || iy >= ctl->
prof_ny)
10949 obsmean[idx] += robs[i];
10954 for (ip = 0; ip < atm->
np; ip++) {
10957 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
10961 int ix = (int) ((atm->
lon[ip] - ctl->
prof_lon0) / dlon);
10962 int iy = (int) ((atm->
lat[ip] - ctl->
prof_lat0) / dlat);
10963 int iz = (int) ((
Z(atm->
p[ip]) - ctl->
prof_z0) / dz);
10966 if (ix < 0 || ix >= ctl->
prof_nx ||
10972 mass[idx] += atm->
q[ctl->
qnt_m][ip];
10976 for (
int ix = 0; ix < ctl->
prof_nx; ix++)
10977 for (
int iy = 0; iy < ctl->
prof_ny; iy++) {
10979 if (obscount[idx2] > 0) {
10983 for (
int iz = 0; iz < ctl->
prof_nz; iz++) {
10985 if (mass[idx3] > 0) {
10994 fprintf(out,
"\n");
10997 for (
int iz = 0; iz < ctl->
prof_nz; iz++) {
11002 lon[ix], lat[iy], &temp, ci, cw, 1);
11004 lon[ix], lat[iy], &h2o, ci, cw, 0);
11006 lon[ix], lat[iy], &o3, ci, cw, 0);
11011 / (
RHO(press[iz], temp) * area[iy] * dz * 1e9);
11014 fprintf(out,
"%.2f %g %g %g %g %g %g %g %g %g %d\n",
11015 t, z[iz], lon[ix], lat[iy], press[iz], temp, vmr, h2o, o3,
11016 obsmean[idx2] / obscount[idx2], obscount[idx2]);
11049 const char *filename,
11058 static double area, dlat, rmax2, *rt, *rz, *rlon, *rlat, *robs, kz[
EP],
11061 static int nobs, nk;
11074 ALLOC(rlon,
double,
11076 ALLOC(rlat,
double,
11078 ALLOC(robs,
double,
11089 LOG(1,
"Write sample data: %s", filename);
11090 if (!(out = fopen(filename,
"w")))
11091 ERRMSG(
"Cannot create file!");
11095 "# $1 = time [s]\n"
11096 "# $2 = altitude [km]\n"
11097 "# $3 = longitude [deg]\n"
11098 "# $4 = latitude [deg]\n"
11099 "# $5 = surface area [km^2]\n"
11100 "# $6 = layer depth [km]\n"
11101 "# $7 = number of particles [1]\n"
11102 "# $8 = column density [kg/m^2]\n"
11103 "# $9 = volume mixing ratio [ppv]\n"
11104 "# $10 = observed BT index [K]\n\n");
11109 area = M_PI * rmax2;
11113 const double t0 = t - 0.5 * ctl->
dt_mod;
11114 const double t1 = t + 0.5 * ctl->
dt_mod;
11117 for (
int i = 0; i < nobs; i++) {
11122 else if (rt[i] >= t1)
11127 geo2cart(0, rlon[i], rlat[i], x0);
11130 const double rp =
P(rz[i]);
11131 const double ptop =
P(rz[i] + ctl->
sample_dz);
11132 const double pbot =
P(rz[i] - ctl->
sample_dz);
11140 for (
int ip = 0; ip < atm->
np; ip++) {
11143 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11147 if (fabs(rlat[i] - atm->
lat[ip]) > dlat)
11153 if (
DIST2(x0, x1) > rmax2)
11158 if (atm->
p[ip] > pbot || atm->
p[ip] < ptop)
11162 if (ctl->
qnt_m >= 0)
11169 const double cd = mass / (1e6 * area);
11180 rlon[i], rlat[i], &temp, ci, cw, 1);
11189 fprintf(out,
"%.2f %g %g %g %g %g %d %g %g %g\n", rt[i], rz[i],
11190 rlon[i], rlat[i], area, ctl->
sample_dz, np, cd, vmr, robs[i]);
11211 const char *filename,
11218 static double rmax2, x0[3], x1[3];
11227 LOG(1,
"Write station data: %s", filename);
11230 if (!(out = fopen(filename,
"w")))
11231 ERRMSG(
"Cannot create file!");
11235 "# $1 = time [s]\n"
11236 "# $2 = altitude [km]\n"
11237 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
11238 for (
int iq = 0; iq < ctl->
nq; iq++)
11239 fprintf(out,
"# $%i = %s [%s]\n", (iq + 5),
11241 fprintf(out,
"\n");
11249 const double t0 = t - 0.5 * ctl->
dt_mod;
11250 const double t1 = t + 0.5 * ctl->
dt_mod;
11253 for (
int ip = 0; ip < atm->
np; ip++) {
11256 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11272 if (
DIST2(x0, x1) > rmax2)
11280 fprintf(out,
"%.2f %g %g %g",
11281 atm->
time[ip],
Z(atm->
p[ip]), atm->
lon[ip], atm->
lat[ip]);
11282 for (
int iq = 0; iq < ctl->
nq; iq++) {
11284 fprintf(out, ctl->
qnt_format[iq], atm->
q[iq][ip]);
11286 fprintf(out,
"\n");
11297 const char *filename,
11308 LOG(1,
"Write VTK data: %s", filename);
11311 const double t0 = t - 0.5 * ctl->
dt_mod;
11312 const double t1 = t + 0.5 * ctl->
dt_mod;
11315 if (!(out = fopen(filename,
"w")))
11316 ERRMSG(
"Cannot create file!");
11320 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
11321 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11328 "# vtk DataFile Version 3.0\n"
11329 "vtk output\n" "ASCII\n" "DATASET POLYDATA\n");
11332 fprintf(out,
"POINTS %d float\n", np);
11334 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
11335 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11339 const double coslat = cos(
DEG2RAD(atm->
lat[ip]));
11340 const double x = radius * coslat * cos(
DEG2RAD(atm->
lon[ip]));
11341 const double y = radius * coslat * sin(
DEG2RAD(atm->
lon[ip]));
11342 const double z = radius * sin(
DEG2RAD(atm->
lat[ip]));
11343 fprintf(out,
"%g %g %g\n", x, y, z);
11346 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
11347 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11349 fprintf(out,
"%g %g %g\n", atm->
lon[ip], atm->
lat[ip],
11354 fprintf(out,
"POINT_DATA %d\n", np);
11355 for (
int iq = 0; iq < ctl->
nq; iq++) {
11356 fprintf(out,
"SCALARS %s float 1\n" "LOOKUP_TABLE default\n",
11358 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
11359 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11361 fprintf(out,
"%g\n", atm->
q[iq][ip]);
void read_met_geopot(const ctl_t *ctl, met_t *met)
Calculates geopotential heights from meteorological data.
void mptrac_write_atm(const char *filename, const ctl_t *ctl, const atm_t *atm, const double t)
Writes air parcel data to a file in various formats.
void day2doy(const int year, const int mon, const int day, int *doy)
Get day of year from date.
void read_met_extrapolate(met_t *met)
Extrapolates meteorological data.
void read_met_levels(const int ncid, const ctl_t *ctl, met_t *met)
Reads meteorological variables at different vertical levels from a NetCDF file.
int read_met_nc(const char *filename, const ctl_t *ctl, const clim_t *clim, met_t *met)
Reads meteorological data from a NetCDF file and processes it.
void write_atm_clams_traj(const char *dirname, const ctl_t *ctl, const atm_t *atm, const double t)
Writes CLaMS trajectory data to a NetCDF file.
void write_met_nc_2d(const int ncid, const char *varname, met_t *met, float var[EX][EY], const float scl)
Writes a 2D meteorological variable to a NetCDF file.
void mptrac_alloc(ctl_t **ctl, cache_t **cache, clim_t **clim, met_t **met0, met_t **met1, atm_t **atm)
Allocates and initializes memory resources for MPTRAC.
void read_met_sample(const ctl_t *ctl, met_t *met)
Downsamples meteorological data based on specified parameters.
void write_met_bin_3d(FILE *out, const ctl_t *ctl, met_t *met, float var[EX][EY][EP], const char *varname, const int precision, const double tolerance)
Writes a 3-dimensional meteorological variable to a binary file.
void read_obs(const char *filename, const ctl_t *ctl, double *rt, double *rz, double *rlon, double *rlat, double *robs, int *nobs)
Reads observation data from a file and stores it in arrays.
void module_advect(const ctl_t *ctl, const cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Performs the advection of atmospheric particles using meteorological data.
void module_timesteps(const ctl_t *ctl, cache_t *cache, met_t *met0, atm_t *atm, const double t)
Calculate time steps for air parcels based on specified conditions.
int mptrac_read_met(const char *filename, const ctl_t *ctl, const clim_t *clim, met_t *met)
Reads meteorological data from a file, supporting multiple formats and MPI broadcasting.
void module_meteo(const ctl_t *ctl, const cache_t *cache, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Update atmospheric properties using meteorological data.
void read_clim_photo(const char *filename, clim_photo_t *photo)
Reads photolysis rates from a NetCDF file and populates the given photolysis structure.
void read_met_cloud(met_t *met)
Calculates cloud-related variables for each grid point.
void module_decay(const ctl_t *ctl, const cache_t *cache, const clim_t *clim, atm_t *atm)
Simulate exponential decay processes for atmospheric particles.
double sedi(const double p, const double T, const double rp, const double rhop)
Calculates the sedimentation velocity of a particle in air.
void intpol_met_space_2d(const met_t *met, float array[EX][EY], const double lon, const double lat, double *var, int *ci, double *cw, const int init)
Interpolates meteorological variables in 2D space.
int read_atm_nc(const char *filename, const ctl_t *ctl, atm_t *atm)
Reads air parcel data from a generic netCDF file and populates the given atmospheric structure.
void read_met_pbl(const ctl_t *ctl, met_t *met)
Computes the planetary boundary layer (PBL) pressure based on meteorological data.
void read_met_detrend(const ctl_t *ctl, met_t *met)
Detrends meteorological data.
int read_met_nc_2d(const int ncid, const char *varname, const char *varname2, const char *varname3, const char *varname4, const char *varname5, const char *varname6, const ctl_t *ctl, const met_t *met, float dest[EX][EY], const float scl, const int init)
Reads a 2-dimensional meteorological variable from a NetCDF file.
void read_met_tropo(const ctl_t *ctl, const clim_t *clim, met_t *met)
Calculates the tropopause and related meteorological variables based on various methods and stores th...
void read_obs_asc(const char *filename, double *rt, double *rz, double *rlon, double *rlat, double *robs, int *nobs)
Reads observation data from an ASCII file.
void module_chem_init(const ctl_t *ctl, const cache_t *cache, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Initializes the chemistry modules by setting atmospheric composition.
int locate_reg(const double *xx, const int n, const double x)
Locate the index of the interval containing a given value in a regular grid.
void get_tropo(const int met_tropo, ctl_t *ctl, clim_t *clim, met_t *met, const double *lons, const int nx, const double *lats, const int ny, double *pt, double *zt, double *tt, double *qt, double *o3t, double *ps, double *zs)
Calculate tropopause data.
void mptrac_get_met(ctl_t *ctl, clim_t *clim, const double t, met_t **met0, met_t **met1)
Retrieves meteorological data for the specified time.
int read_clim_ts(const char *filename, clim_ts_t *ts)
Reads a climatological time series from a file and populates the given time series structure.
void read_met_periodic(met_t *met)
Applies periodic boundary conditions to meteorological data along longitudinal axis.
void module_timesteps_init(ctl_t *ctl, const atm_t *atm)
Initialize start time and time interval for time-stepping.
void write_ens(const char *filename, const ctl_t *ctl, const atm_t *atm, const double t)
Writes ensemble data to a file.
void module_mixing(const ctl_t *ctl, const clim_t *clim, atm_t *atm, const double t)
Update atmospheric properties through interparcel mixing.
double clim_zm(const clim_zm_t *zm, const double t, const double lat, const double p)
Interpolates monthly mean zonal mean climatological variables.
void read_clim_photo_help(const int ncid, const char *varname, const clim_photo_t *photo, double var[CP][CSZA][CO3])
Reads a 3D climatological photochemistry variable from a NetCDF file.
void read_met_ml2pl(const ctl_t *ctl, const met_t *met, float var[EX][EY][EP], const char *varname)
Interpolates meteorological data to specified pressure levels.
double clim_tropo(const clim_t *clim, const double t, const double lat)
Calculates the tropopause pressure based on climatological data.
void read_obs_nc(const char *filename, double *rt, double *rz, double *rlon, double *rlat, double *robs, int *nobs)
Reads observation data from a NetCDF file.
void read_met_grid(const char *filename, const int ncid, const ctl_t *ctl, met_t *met)
Reads meteorological grid information from a NetCDF file.
void read_met_bin_2d(FILE *in, const met_t *met, float var[EX][EY], const char *varname)
Reads a 2-dimensional meteorological variable from a binary file and stores it in the provided array.
int locate_irr(const double *xx, const int n, const double x)
Locate the index of the interval containing a given value in a sorted array.
void module_isosurf_init(const ctl_t *ctl, cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Initialize the isosurface module based on atmospheric data.
void level_definitions(ctl_t *ctl)
Defines pressure levels for meteorological data.
void intpol_met_4d_coord(const met_t *met0, float heights0[EX][EY][EP], float array0[EX][EY][EP], const met_t *met1, float heights1[EX][EY][EP], float array1[EX][EY][EP], const double ts, const double height, const double lon, const double lat, double *var, int *ci, double *cw, const int init)
Interpolates meteorological variables to a given position and time.
void write_grid_asc(const char *filename, const ctl_t *ctl, const double *cd, double *mean[NQ], double *sigma[NQ], const double *vmr_impl, const double t, const double *z, const double *lon, const double *lat, const double *area, const double dz, const int *np)
Writes grid data to an ASCII file.
void mptrac_update_device(const ctl_t *ctl, const cache_t *cache, const clim_t *clim, met_t **met0, met_t **met1, const atm_t *atm)
Updates device memory for specified data structures.
void time2jsec(const int year, const int mon, const int day, const int hour, const int min, const int sec, const double remain, double *jsec)
Converts time components to seconds since January 1, 2000, 12:00:00 UTC.
void mptrac_init(ctl_t *ctl, cache_t *cache, clim_t *clim, atm_t *atm, const int ntask)
Initializes the MPTRAC model and its associated components.
void intpol_met_time_3d(const met_t *met0, float array0[EX][EY][EP], const met_t *met1, float array1[EX][EY][EP], const double ts, const double p, const double lon, const double lat, double *var, int *ci, double *cw, const int init)
Interpolates meteorological data in 3D space and time.
void intpol_met_space_3d_ml(const met_t *met, float zs[EX][EY][EP], float array[EX][EY][EP], const double z, const double lon, const double lat, double *var)
Interpolates meteorological data in 3D space.
void fft_help(double *fcReal, double *fcImag, const int n)
Computes the Fast Fourier Transform (FFT) of a complex sequence.
void module_wet_depo(const ctl_t *ctl, const cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Perform wet deposition calculations for air parcels.
void compress_pck(const char *varname, float *array, const size_t nxy, const size_t nz, const int decompress, FILE *inout)
Compresses or decompresses a 3D array of floats.
double nat_temperature(const double p, const double h2o, const double hno3)
Calculates the nitric acid trihydrate (NAT) temperature.
void spline(const double *x, const double *y, const int n, const double *x2, double *y2, const int n2, const int method)
Performs spline interpolation or linear interpolation.
void module_chem_grid(const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, const double tt)
Calculate grid data for chemistry modules.
double clim_photo(const double rate[CP][CSZA][CO3], const clim_photo_t *photo, const double p, const double sza, const double o3c)
Calculates the photolysis rate for a given set of atmospheric conditions.
void read_clim_zm(const char *filename, const char *varname, clim_zm_t *zm)
Reads zonally averaged climatological data from a netCDF file and populates the given structure.
void module_sedi(const ctl_t *ctl, const cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Simulate sedimentation of particles in the atmosphere.
void timer(const char *name, const char *group, const int output)
Measures and reports elapsed time for named and grouped timers.
void 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 intpol_met_space_3d(const met_t *met, float array[EX][EY][EP], const double p, const double lon, const double lat, double *var, int *ci, double *cw, const int init)
Interpolates meteorological variables in 3D space.
void read_met_surface(const int ncid, const ctl_t *ctl, met_t *met)
Reads surface meteorological data from a netCDF file and stores it in the meteorological data structu...
void intpol_met_time_3d_ml(const met_t *met0, float zs0[EX][EY][EP], float array0[EX][EY][EP], const met_t *met1, float zs1[EX][EY][EP], float array1[EX][EY][EP], const double ts, const double p, const double lon, const double lat, double *var)
Interpolates meteorological data in both space and time.
void module_convection(const ctl_t *ctl, cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Performs convective mixing of atmospheric particles.
void read_kernel(const char *filename, double kz[EP], double kw[EP], int *nk)
Reads kernel function data from a file and populates the provided arrays.
void module_bound_cond(const ctl_t *ctl, const cache_t *cache, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Apply boundary conditions to particles based on meteorological and climatological data.
double scan_ctl(const char *filename, int argc, char *argv[], const char *varname, const int arridx, const char *defvalue, char *value)
Scans a control file or command-line arguments for a specified variable.
void module_advect_init(const ctl_t *ctl, const cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Initializes the advection module by setting up pressure fields.
void module_sort_help(double *a, const int *p, const int np)
Reorder an array based on a given permutation.
float stddev(const float *data, const int n)
Calculates the standard deviation of a set of data.
void intpol_tropo_3d(const double time0, float array0[EX][EY], const double time1, float array1[EX][EY], const double lons[EX], const double lats[EY], const int nlon, const int nlat, const double time, const double lon, const double lat, const int method, double *var, double *sigma)
Interpolates tropopause data in 3D (latitude, longitude, and time).
int read_met_nc_3d(const int ncid, const char *varname, const char *varname2, const char *varname3, const char *varname4, const ctl_t *ctl, const met_t *met, float dest[EX][EY][EP], const float scl)
Reads a 3-dimensional meteorological variable from a NetCDF file.
void read_met_bin_3d(FILE *in, const ctl_t *ctl, const met_t *met, float var[EX][EY][EP], const char *varname, const float bound_min, const float bound_max)
Reads 3D meteorological data from a binary file, potentially using different compression methods.
int locate_irr_float(const float *xx, const int n, const double x, const int ig)
Locate the index of the interval containing a given value in an irregularly spaced array.
double time_from_filename(const char *filename, const int offset)
Extracts and converts a timestamp from a filename to Julian seconds.
void write_prof(const char *filename, const ctl_t *ctl, met_t *met0, met_t *met1, const atm_t *atm, const double t)
Writes profile data to a specified file.
void mptrac_read_clim(const ctl_t *ctl, clim_t *clim)
Reads various climatological data and populates the given climatology structure.
double tropo_weight(const clim_t *clim, const atm_t *atm, const int ip)
Computes a weighting factor based on tropopause pressure.
void write_met_nc(const char *filename, const ctl_t *ctl, met_t *met)
Writes meteorological data to a NetCDF file.
void module_rng_init(const int ntask)
Initialize random number generators for parallel tasks.
int mptrac_read_atm(const char *filename, const ctl_t *ctl, atm_t *atm)
Reads air parcel data from a specified file into the given atmospheric structure.
void mptrac_update_host(const ctl_t *ctl, const cache_t *cache, const clim_t *clim, met_t **met0, met_t **met1, const atm_t *atm)
Updates host memory for specified data structures.
void mptrac_write_output(const char *dirname, const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, const double t)
Writes various types of output data to files in a specified directory.
double clim_oh(const ctl_t *ctl, const clim_t *clim, const double t, const double lon, const double lat, const double p)
Calculates the hydroxyl radical (OH) concentration from climatology data, with an optional diurnal co...
void read_met_ozone(met_t *met)
Calculates the total column ozone from meteorological ozone data.
void mptrac_free(ctl_t *ctl, cache_t *cache, clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Frees memory resources allocated for MPTRAC.
void clim_tropo_init(clim_t *clim)
Initializes the tropopause data in the climatology structure.
void module_rng(const ctl_t *ctl, double *rs, const size_t n, const int method)
Generate random numbers using various methods and distributions.
void get_met_help(const ctl_t *ctl, const double t, const int direct, const char *metbase, const double dt_met, char *filename)
Generates a formatted filename for meteorological data files based on the input parameters.
void write_station(const char *filename, const ctl_t *ctl, atm_t *atm, const double t)
Writes station data to a specified file.
void cart2geo(const double *x, double *z, double *lon, double *lat)
State variables of cuRAND random number generator.
double sza_calc(const double sec, const double lon, const double lat)
Calculates the solar zenith angle.
void module_mixing_help(const ctl_t *ctl, const clim_t *clim, atm_t *atm, const int *ixs, const int *iys, const int *izs, const int qnt_idx)
Perform interparcel mixing for a specific quantity.
void doy2day(const int year, const int doy, int *mon, int *day)
Converts a given day of the year (DOY) to a date (month and day).
void intpol_met_time_2d(const met_t *met0, float array0[EX][EY], const met_t *met1, float array1[EX][EY], const double ts, const double lon, const double lat, double *var, int *ci, double *cw, const int init)
Interpolates meteorological data in 2D space and time.
void module_position(const cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Update the positions and pressure levels of atmospheric particles.
void clim_oh_diurnal_correction(const ctl_t *ctl, clim_t *clim)
Applies a diurnal correction to the hydroxyl radical (OH) concentration in climatology data.
void locate_vert(float profiles[EX][EY][EP], const int np, const int lon_ap_ind, const int lat_ap_ind, const double height_ap, int *ind)
Locate the four vertical indizes of a box for a given height value.
void write_met_bin_2d(FILE *out, met_t *met, float var[EX][EY], const char *varname)
Writes a 2-dimensional meteorological variable to a binary file.
void read_met_pv(met_t *met)
Calculates potential vorticity (PV) from meteorological data.
int read_atm_bin(const char *filename, const ctl_t *ctl, atm_t *atm)
Reads air parcel data from a binary file and populates the given atmospheric structure.
void get_met_replace(char *orig, char *search, char *repl)
Replaces occurrences of a substring in a string with another substring.
void module_diff_meso(const ctl_t *ctl, cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Simulate mesoscale diffusion for atmospheric particles.
void module_sort(const ctl_t *ctl, met_t *met0, atm_t *atm)
Sort particles according to box index.
double clim_ts(const clim_ts_t *ts, const double t)
Interpolates a time series of climatological variables.
void jsec2time(const double jsec, int *year, int *mon, int *day, int *hour, int *min, int *sec, double *remain)
Converts Julian seconds to calendar date and time components.
int read_met_bin(const char *filename, const ctl_t *ctl, met_t *met)
Reads meteorological data from a binary file.
void mptrac_run_timestep(ctl_t *ctl, cache_t *cache, clim_t *clim, met_t **met0, met_t **met1, atm_t *atm, double t)
Executes a single timestep of the MPTRAC model simulation.
void write_atm_clams(const char *filename, const ctl_t *ctl, const atm_t *atm)
Writes air parcel data to a NetCDF file in the CLaMS format.
void module_diff_turb(const ctl_t *ctl, cache_t *cache, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Applies turbulent diffusion processes to atmospheric particles.
int read_atm_clams(const char *filename, const ctl_t *ctl, atm_t *atm)
Reads air parcel data from a CLaMS netCDF file and populates 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 module_tracer_chem(const ctl_t *ctl, const cache_t *cache, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Simulate chemical reactions involving long-lived atmospheric tracers.
void mptrac_read_ctl(const char *filename, int argc, char *argv[], ctl_t *ctl)
Reads control parameters from a configuration file and populates the given structure.
void read_met_polar_winds(met_t *met)
Applies a fix for polar winds in meteorological data.
void module_h2o2_chem(const ctl_t *ctl, const cache_t *cache, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Perform chemical reactions involving H2O2 within cloud particles.
void write_grid_nc(const char *filename, const ctl_t *ctl, const double *cd, double *mean[NQ], double *sigma[NQ], const double *vmr_impl, const double t, const double *z, const double *lon, const double *lat, const double *area, const double dz, const int *np)
Writes grid data to a NetCDF file.
double pbl_weight(const ctl_t *ctl, const atm_t *atm, const int ip, const double pbl, const double ps)
Computes a weighting factor based on planetary boundary layer pressure.
void module_diff_pbl(const ctl_t *ctl, cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Computes particle diffusion within the planetary boundary layer (PBL).
void write_met_nc_3d(const int ncid, const char *varname, met_t *met, float var[EX][EY][EP], const float scl)
Writes a 3D meteorological variable to a NetCDF file.
void module_isosurf(const ctl_t *ctl, const cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Apply the isosurface module to adjust atmospheric properties.
void module_oh_chem(const ctl_t *ctl, const cache_t *cache, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Perform hydroxyl chemistry calculations for atmospheric particles.
void geo2cart(const double z, const double lon, const double lat, double *x)
Converts geographic coordinates (longitude, latitude, altitude) to Cartesian coordinates.
double kernel_weight(const double kz[EP], const double kw[EP], const int nk, const double p)
Calculates the kernel weight based on altitude and given kernel data.
int read_atm_asc(const char *filename, const ctl_t *ctl, atm_t *atm)
Reads air parcel data from an ASCII file and populates the given atmospheric structure.
void write_sample(const char *filename, const ctl_t *ctl, met_t *met0, met_t *met1, const atm_t *atm, const double t)
Writes sample data to a specified file.
void write_grid(const char *filename, const ctl_t *ctl, met_t *met0, met_t *met1, const atm_t *atm, const double t)
Writes grid data to a file in ASCII or netCDF format.
void module_dry_depo(const ctl_t *ctl, const cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Simulate dry deposition of atmospheric particles.
void write_met_bin(const char *filename, const ctl_t *ctl, met_t *met)
Writes meteorological data in binary format to a specified file.
void write_atm_bin(const char *filename, const ctl_t *ctl, const atm_t *atm)
Writes air parcel data to a binary file.
void read_met_cape(const ctl_t *ctl, const clim_t *clim, met_t *met)
Calculates Convective Available Potential Energy (CAPE) for each grid point.
void mptrac_write_met(const char *filename, const ctl_t *ctl, met_t *met)
Writes meteorological data to a file, supporting multiple formats and compression options.
double lapse_rate(const double t, const double h2o)
Calculates the moist adiabatic lapse rate in Kelvin per kilometer.
void write_csi(const char *filename, const ctl_t *ctl, const atm_t *atm, const double t)
Writes Critical Success Index (CSI) data to a file.
void write_atm_nc(const char *filename, const ctl_t *ctl, const atm_t *atm)
Writes air parcel data to a NetCDF file.
MPTRAC library declarations.
#define NN(x0, y0, x1, y1, x)
Perform nearest-neighbor interpolation.
#define LEN
Maximum length of ASCII data lines.
#define RE
Mean radius of Earth [km].
#define TVIRT(t, h2o)
Compute virtual temperature.
#define ARRAY_3D(ix, iy, ny, iz, nz)
Compute the linear index of a 3D array element.
#define PARTICLE_LOOP(ip0, ip1, check_dt,...)
Loop over particle indices with OpenACC acceleration.
#define MA
Molar mass of dry air [g/mol].
#define AVO
Avogadro constant [1/mol].
#define KB
Boltzmann constant [kg m^2/(K s^2)].
#define MH2O
Molar mass of water vapor [g/mol].
#define NENS
Maximum number of data points for ensemble analysis.
#define FWRITE(ptr, type, size, out)
Write data from memory to a file stream.
#define PW(p, h2o)
Calculate partial water vapor pressure.
#define H0
Scale height [km].
#define NC_PUT_ATT_GLOBAL(attname, text)
Add a global text attribute to a NetCDF file.
#define MOLEC_DENS(p, t)
Calculate the density of a gas molecule.
#define LAPSE(p1, t1, p2, t2)
Calculate lapse rate.
#define NC(cmd)
Execute a NetCDF command and check for errors.
#define RA
Specific gas constant of dry air [J/(kg K)].
#define KARMAN
Karman's constant.
#define INTPOL_INIT
Initialize arrays for interpolation.
#define MIN(a, b)
Macro to determine the minimum of two values.
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
#define NC_PUT_INT(varname, ptr, hyperslab)
Write integer data to a NetCDF variable.
void compress_cms(const ctl_t *ctl, const char *varname, float *array, const size_t nx, const size_t ny, const size_t np, const int decompress, FILE *inout)
Compresses or decompresses a 3D array of floats using a custom multiscale compression algorithm.
void compress_zfp(const char *varname, float *array, const int nx, const int ny, const int nz, const int precision, const double tolerance, const int decompress, FILE *inout)
Compresses or decompresses a 3D array of floats using the ZFP library.
#define EY
Maximum number of latitudes for meteo data.
#define SH(h2o)
Compute specific humidity from water vapor volume mixing ratio.
#define INTPOL_3D(var, init)
Perform 3D interpolation for a meteorological variable.
#define NOBS
Maximum number of observation data points.
#define NTHREADS
Maximum number of OpenMP threads.
#define ARRAY_2D(ix, iy, ny)
Macro for computing the linear index of a 2D array element.
#define Z(p)
Convert pressure to altitude.
#define P(z)
Compute pressure at given altitude.
#define LV
Latent heat of vaporization of water [J/kg].
#define G0
Standard gravity [m/s^2].
#define CP
Maximum number of pressure levels for climatological data.
#define NQ
Maximum number of quantities per data point.
#define FREAD(ptr, type, size, in)
Read data from a file stream and store it in memory.
#define DX2DEG(dx, lat)
Convert a distance in kilometers to degrees longitude at a given latitude.
#define DEG2DY(dlat)
Convert a latitude difference to a distance in the y-direction (north-south).
#define EX
Maximum number of longitudes for meteo data.
#define EPS
Ratio of the specific gas constant of dry air and water vapor [1].
#define PSICE(t)
Compute saturation pressure over ice (WMO, 2018).
#define THETA(p, t)
Compute potential temperature.
#define RI
Ideal gas constant [J/(mol K)].
#define NORM(a)
Compute the norm (magnitude) of a vector.
#define SET_QNT(qnt, name, longname, unit)
Set atmospheric quantity index.
#define TICE(p, h2o)
Calculate frost point temperature (WMO, 2018).
#define TOK(line, tok, format, var)
Get string tokens.
#define ZDIFF(lnp0, t0, h2o0, lnp1, t1, h2o1)
Calculate geopotential height difference.
#define THETAVIRT(p, t, h2o)
Compute virtual potential temperature.
#define DZ2DP(dz, p)
Convert a change in altitude to a change in pressure.
#define WARN(...)
Print a warning message with contextual information.
#define ZETA(ps, p, t)
Computes the value of the zeta vertical coordinate.
#define RHICE(p, t, h2o)
Compute relative humidity over ice.
#define INTPOL_TIME_ALL(time, p, lon, lat)
Interpolate multiple meteorological variables in time.
#define ALLOC(ptr, type, n)
Allocate memory for a pointer with error handling.
#define SET_ATM(qnt, val)
Set atmospheric quantity value.
#define CTS
Maximum number of data points of climatological time series.
#define DEG2RAD(deg)
Converts degrees to radians.
void broadcast_large_data(void *data, size_t N)
Broadcasts large data across all processes in an MPI communicator.
#define MO3
Molar mass of ozone [g/mol].
#define SQR(x)
Compute the square of a value.
#define RAD2DEG(rad)
Converts radians to degrees.
#define NC_INQ_DIM(dimname, ptr, min, max)
Inquire the length of a dimension in a NetCDF file.
#define NP
Maximum number of atmospheric data points.
#define NTIMER
Maximum number of timers.
#define SELECT_TIMER(id, group, color)
Select and start a timer with specific attributes.
#define INTPOL_2D(var, init)
Perform 2D interpolation for a meteorological variable.
#define RH(p, t, h2o)
Compute relative humidity over water.
#define NC_PUT_FLOAT(varname, ptr, hyperslab)
Write a float array to a NetCDF file.
#define CY
Maximum number of latitudes for climatological data.
#define LOG(level,...)
Print a log message with a specified logging level.
void thrustSortWrapper(double *__restrict__ c, int n, int *__restrict__ index)
Wrapper to Thrust sorting function.
#define NC_DEF_VAR(varname, type, ndims, dims, long_name, units, level, quant)
Define a NetCDF variable with attributes.
#define TDEW(p, h2o)
Calculate dew point temperature.
#define ARRHENIUS(a, b, t)
Calculate the Arrhenius rate constant.
#define NCSI
Maximum number of data points for CSI calculation.
#define NC_GET_DOUBLE(varname, ptr, force)
Retrieve a double-precision variable from a NetCDF file.
#define EP
Maximum number of pressure levels for meteo data.
#define PSAT(t)
Compute saturation pressure over water.
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.
void module_kpp_chem(ctl_t *ctl, cache_t *cache, clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
KPP chemistry module.
#define CO3
Maximum number of total column ozone data for climatological data.
#define NC_PUT_DOUBLE(varname, ptr, hyperslab)
Write double precision data to a NetCDF variable.
#define LIN(x0, y0, x1, y1, x)
Linear interpolation.
#define DIST2(a, b)
Calculate the squared Euclidean distance between two points in Cartesian coordinates.
#define DEG2DX(dlon, lat)
Convert a longitude difference to a distance in the x-direction (east-west) at a specific latitude.
#define CPD
Specific heat of dry air at constant pressure [J/(kg K)].
#define CSZA
Maximum number of solar zenith angles for climatological data.
#define DY2DEG(dy)
Convert a distance in kilometers to degrees latitude.
#define MAX(a, b)
Macro to determine the maximum of two values.
#define FMOD(x, y)
Calculate the floating-point remainder of dividing x by y.
double lat[NP]
Latitude [deg].
double lon[NP]
Longitude [deg].
int np
Number of air parcels.
double q[NQ][NP]
Quantity data (for various, user-defined attributes).
double p[NP]
Pressure [hPa].
double dt[NP]
Timesteps [s].
double iso_ts[NP]
Isosurface balloon time [s].
int iso_n
Isosurface balloon number of data points.
double iso_ps[NP]
Isosurface balloon pressure [hPa].
double rs[3 *NP+1]
Random numbers.
float uvwp[NP][3]
Wind perturbations [m/s].
double iso_var[NP]
Isosurface variables.
Climatological data in the form of photolysis rates.
int nsza
Number of solar zenith angles.
double sza[CSZA]
Solar zenith angle [rad].
double o3_1[CP][CSZA][CO3]
O3 photolysis rate (O3 + hv = O1d + O2) [1/s].
double p[CP]
Pressure [hPa].
double ccl2f2[CP][CSZA][CO3]
CCl2F2 photolysis rate [1/s].
double o2[CP][CSZA][CO3]
O2 photolysis rate [1/s].
double ccl3f[CP][CSZA][CO3]
CCl3F photolysis rate [1/s].
double n2o[CP][CSZA][CO3]
N2O photolysis rate [1/s].
double h2o2[CP][CSZA][CO3]
H2O2 photolysis rate [1/s].
double h2o[CP][CSZA][CO3]
H2O photolysis rate [1/s].
double ccl4[CP][CSZA][CO3]
CCl4 photolysis rate [1/s].
double o3_2[CP][CSZA][CO3]
O3 photolysis rate (O3 + hv = O3p + O2) [1/s].
double o3c[CO3]
Total column ozone [DU].
int np
Number of pressure levels.
int no3c
Number of total ozone columns.
clim_ts_t ccl2f2
CFC-12 time series.
clim_photo_t photo
Photolysis rates.
clim_zm_t ho2
HO2 zonal means.
clim_zm_t hno3
HNO3 zonal means.
int tropo_ntime
Number of tropopause timesteps.
clim_ts_t sf6
SF6 time series.
clim_ts_t ccl4
CFC-10 time series.
clim_ts_t ccl3f
CFC-11 time series.
clim_zm_t o1d
O(1D) zonal means.
double tropo_lat[73]
Tropopause latitudes [deg].
clim_zm_t h2o2
H2O2 zonal means.
int tropo_nlat
Number of tropopause latitudes.
clim_zm_t oh
OH zonal means.
double tropo[12][73]
Tropopause pressure values [hPa].
double tropo_time[12]
Tropopause time steps [s].
clim_ts_t n2o
N2O time series.
Climatological data in the form of time series.
double vmr[CTS]
Volume mixing ratio [ppv].
double time[CTS]
Time [s].
int ntime
Number of timesteps.
Climatological data in the form of zonal means.
int np
Number of pressure levels.
double p[CP]
Pressure [hPa].
double vmr[CT][CP][CY]
Volume mixing ratio [ppv].
int ntime
Number of timesteps.
int nlat
Number of latitudes.
double lat[CY]
Latitude [deg].
double grid_z0
Lower altitude of gridded data [km].
int qnt_o3
Quantity array index for ozone volume mixing ratio.
double csi_lat1
Upper latitude of gridded CSI data [deg].
char csi_obsfile[LEN]
Observation data file for CSI analysis.
int qnt_Coh
Quantity array index for OH volume mixing ratio (chemistry code).
double wet_depo_ic_a
Coefficient A for wet deposition in cloud (exponential form).
int met_nc_scale
Check netCDF scaling factors (0=no, 1=yes).
int qnt_pel
Quantity array index for pressure at equilibrium level (EL).
int csi_nz
Number of altitudes of gridded CSI data.
double molmass
Molar mass [g/mol].
int qnt_p
Quantity array index for pressure.
int qnt_Cccl2f2
Quantity array index for CFC-12 volume mixing ratio (chemistry code).
char atm_gpfile[LEN]
Gnuplot file for atmospheric data.
int mixing_nx
Number of longitudes of mixing grid.
double chemgrid_z1
Upper altitude of chemistry grid [km].
char qnt_format[NQ][LEN]
Quantity output format.
int qnt_m
Quantity array index for mass.
int qnt_aoa
Quantity array index for age of air.
int qnt_rhop
Quantity array index for particle density.
int qnt_swc
Quantity array index for cloud snow water content.
double csi_obsmin
Minimum observation index to trigger detection.
int qnt_pcb
Quantity array index for cloud bottom pressure.
char clim_n2o_timeseries[LEN]
Filename of N2O time series.
double bound_dzs
Boundary conditions surface layer depth [km].
double csi_lon1
Upper longitude of gridded CSI data [deg].
int qnt_u
Quantity array index for zonal wind.
double stat_lon
Longitude of station [deg].
double mixing_trop
Interparcel exchange parameter for mixing in the troposphere.
double sort_dt
Time step for sorting of particle data [s].
double mixing_z1
Upper altitude of mixing grid [km].
double stat_r
Search radius around station [km].
double wet_depo_bc_a
Coefficient A for wet deposition below cloud (exponential form).
int csi_ny
Number of latitudes of gridded CSI data.
int vtk_sphere
Spherical projection for VTK data (0=no, 1=yes).
double chemgrid_z0
Lower altitude of chemistry grid [km].
double met_pbl_min
Minimum depth of planetary boundary layer [km].
int qnt_iwc
Quantity array index for cloud ice water content.
double chemgrid_lat0
Lower latitude of chemistry grid [deg].
double conv_cape
CAPE threshold for convection module [J/kg].
int qnt_Co1d
Quantity array index for O(1D) volume mixing ratio (chemistry code).
double met_cms_eps_pv
cmultiscale compression epsilon for potential vorticity.
int qnt_pw
Quantity array index for partial water vapor pressure.
char prof_basename[LEN]
Basename for profile output file.
double grid_z1
Upper altitude of gridded data [km].
int direction
Direction flag (1=forward calculation, -1=backward calculation).
char balloon[LEN]
Balloon position filename.
int qnt_Cccl4
Quantity array index for CFC-10 volume mixing ratio (chemistry code).
int met_dp
Stride for pressure levels.
double met_dt_out
Time step for sampling of meteo data along trajectories [s].
int qnt_h2o2
Quantity array index for H2O2 volume mixing ratio (climatology).
int qnt_vh
Quantity array index for horizontal wind.
char species[LEN]
Species.
int csi_nx
Number of longitudes of gridded CSI data.
double csi_lat0
Lower latitude of gridded CSI data [deg].
double turb_dz_trop
Vertical turbulent diffusion coefficient (troposphere) [m^2/s].
int met_pbl
Planetary boundary layer data (0=file, 1=z2p, 2=Richardson, 3=theta).
int qnt_lwc
Quantity array index for cloud liquid water content.
double turb_mesoz
Vertical scaling factor for mesoscale wind fluctuations.
int grid_nc_level
zlib compression level of netCDF grid data files (0=off).
int grid_nx
Number of longitudes of gridded data.
int atm_type
Type of atmospheric data files (0=ASCII, 1=binary, 2=netCDF, 3=CLaMS_traj, 4=CLaMS_pos).
double bound_mass
Boundary conditions mass per particle [kg].
double grid_lat0
Lower latitude of gridded data [deg].
int qnt_ts
Quantity array index for surface temperature.
int qnt_loss_rate
Quantity array index for total loss rate.
double met_cms_eps_h2o
cmultiscale compression epsilon for water vapor.
int qnt_plfc
Quantity array index for pressure at level of free convection (LCF).
double grid_lon0
Lower longitude of gridded data [deg].
int qnt_o1d
Quantity array index for O(1D) volume mixing ratio (climatology).
int met_tropo_spline
Tropopause interpolation method (0=linear, 1=spline).
char sample_kernel[LEN]
Kernel data file for sample output.
int qnt_tvirt
Quantity array index for virtual temperature.
double dt_met
Time step of meteo data [s].
char clim_ho2_filename[LEN]
Filename of HO2 climatology.
double chemgrid_lat1
Upper latitude of chemistry grid [deg].
int met_geopot_sy
Latitudinal smoothing of geopotential heights.
char grid_gpfile[LEN]
Gnuplot file for gridded data.
double met_cms_eps_u
cmultiscale compression epsilon for zonal wind.
double turb_dx_strat
Horizontal turbulent diffusion coefficient (stratosphere) [m^2/s].
int qnt_vmr
Quantity array index for volume mixing ratio.
int qnt_lsm
Quantity array index for land-sea mask.
int qnt_theta
Quantity array index for potential temperature.
double bound_lat1
Boundary conditions maximum longitude [deg].
double stat_t1
Stop time for station output [s].
char csi_kernel[LEN]
Kernel data file for CSI output.
double turb_dx_trop
Horizontal turbulent diffusion coefficient (troposphere) [m^2/s].
int grid_type
Type of grid data files (0=ASCII, 1=netCDF).
double csi_lon0
Lower longitude of gridded CSI data [deg].
int qnt_pbl
Quantity array index for boundary layer pressure.
double oh_chem[4]
Coefficients for OH reaction rate (A, E/R or k0, n, kinf, m).
int grid_stddev
Include standard deviations in grid output (0=no, 1=yes).
int qnt_psice
Quantity array index for saturation pressure over ice.
double chemgrid_lon0
Lower longitude of chemistry grid [deg].
int bound_pbl
Boundary conditions planetary boundary layer (0=no, 1=yes).
int qnt_mloss_wet
Quantity array index for total mass loss due to wet deposition.
int met_geopot_sx
Longitudinal smoothing of geopotential heights.
int met_sy
Smoothing for latitudes.
int qnt_ps
Quantity array index for surface pressure.
int rng_type
Random number generator (0=GSL, 1=Squares, 2=cuRAND).
char prof_obsfile[LEN]
Observation data file for profile output.
int isosurf
Isosurface parameter (0=none, 1=pressure, 2=density, 3=theta, 4=balloon).
double bound_p1
Boundary conditions top pressure [hPa].
int qnt_zs
Quantity array index for surface geopotential height.
int prof_nz
Number of altitudes of gridded profile data.
double csi_dt_out
Time step for CSI output [s].
int met_cape
Convective available potential energy data (0=file, 1=calculate).
double csi_modmin
Minimum column density to trigger detection [kg/m^2].
int met_sx
Smoothing for longitudes.
double chemgrid_lon1
Upper longitude of chemistry grid [deg].
double turb_mesox
Horizontal scaling factor for mesoscale wind fluctuations.
double met_cms_eps_iwc
cmultiscale compression epsilon for cloud ice water content.
double met_cms_eps_swc
cmultiscale compression epsilon for cloud snow water content.
char grid_kernel[LEN]
Kernel data file for grid output.
int met_zfp_prec
ZFP compression precision for all variables, except z and T.
double met_cms_eps_v
cmultiscale compression epsilon for meridional wind.
double prof_z0
Lower altitude of gridded profile data [km].
int qnt_w
Quantity array index for vertical velocity.
double bound_vmr
Boundary conditions volume mixing ratio [ppv].
double met_tropo_pv
Dynamical tropopause potential vorticity threshold [PVU].
int prof_nx
Number of longitudes of gridded profile data.
int qnt_stat
Quantity array index for station flag.
int met_tropo
Tropopause definition (0=none, 1=clim, 2=cold point, 3=WMO_1st, 4=WMO_2nd, 5=dynamical).
int qnt_rp
Quantity array index for particle radius.
int met_mpi_share
Use MPI to share meteo (0=no, 1=yes).
double mixing_strat
Interparcel exchange parameter for mixing in the stratosphere.
int qnt_vz
Quantity array index for vertical velocity.
int qnt_ho2
Quantity array index for HO2 volume mixing ratio (climatology).
double csi_z1
Upper altitude of gridded CSI data [km].
double stat_t0
Start time for station output [s].
double oh_chem_beta
Beta parameter for diurnal variablity of OH.
char clim_o1d_filename[LEN]
Filename of O(1D) climatology.
char clim_photo[LEN]
Filename of photolysis rates climatology.
double wet_depo_so2_ph
pH value used to calculate effective Henry constant of SO2.
double mixing_z0
Lower altitude of mixing grid [km].
int qnt_mloss_decay
Quantity array index for total mass loss due to exponential decay.
int atm_type_out
Type of atmospheric data files for output (-1=same as ATM_TYPE, 0=ASCII, 1=binary,...
double dt_kpp
Time step for KPP chemistry [s].
char csi_basename[LEN]
Basename of CSI data files.
double dry_depo_dp
Dry deposition surface layer [hPa].
int qnt_shf
Quantity array index for surface sensible heat flux.
int qnt_vs
Quantity array index for surface meridional wind.
int qnt_Cco
Quantity array index for CO volume mixing ratio (chemistry code).
double vtk_dt_out
Time step for VTK data output [s].
double t_stop
Stop time of simulation [s].
double conv_dt
Time interval for convection module [s].
char sample_obsfile[LEN]
Observation data file for sample output.
int qnt_hno3
Quantity array index for HNO3 volume mixing ratio (climatology).
char grid_basename[LEN]
Basename of grid data files.
int met_clams
Read MPTRAC or CLaMS meteo data (0=MPTRAC, 1=CLaMS).
int qnt_h2ot
Quantity array index for tropopause water vapor volume mixing ratio.
int qnt_rh
Quantity array index for relative humidity over water.
double met_cms_eps_cc
cmultiscale compression epsilon for cloud cover.
double bound_lat0
Boundary conditions minimum longitude [deg].
double met_pbl_max
Maximum depth of planetary boundary layer [km].
int met_dx
Stride for longitudes.
int mixing_ny
Number of latitudes of mixing grid.
int met_convention
Meteo data layout (0=[lev, lat, lon], 1=[lon, lat, lev]).
int qnt_zeta_d
Quantity array index for diagnosed zeta vertical coordinate.
char clim_h2o2_filename[LEN]
Filename of H2O2 climatology.
int tracer_chem
Switch for first order tracer chemistry module (0=off, 1=on).
double dt_mod
Time step of simulation [s].
int diffusion
Diffusion scheme (0=off, 1=fixed-K, 2=PBL).
int qnt_tnat
Quantity array index for T_NAT.
int qnt_tice
Quantity array index for T_ice.
int qnt_zg
Quantity array index for geopotential height.
double vtk_offset
Vertical offset for VTK data [km].
int qnt_v
Quantity array index for meridional wind.
int qnt_mloss_dry
Quantity array index for total mass loss due to dry deposition.
double bound_vmr_trend
Boundary conditions volume mixing ratio trend [ppv/s].
int met_cache
Preload meteo data into disk cache (0=no, 1=yes).
int qnt_oh
Quantity array index for OH volume mixing ratio (climatology).
char qnt_unit[NQ][LEN]
Quantity units.
int qnt_Ch
Quantity array index for H volume mixing ratio (chemistry code).
int met_press_level_def
Use predefined pressure levels or not.
int oh_chem_reaction
Reaction type for OH chemistry (0=none, 2=bimolecular, 3=termolecular).
int qnt_h2o
Quantity array index for water vapor volume mixing ratio.
int prof_ny
Number of latitudes of gridded profile data.
int qnt_rhice
Quantity array index for relative humidity over ice.
int qnt_rho
Quantity array index for density of air.
double sample_dz
Layer depth for sample output [km].
double tdec_strat
Life time of particles in the stratosphere [s].
int obs_type
Type of observation data files (0=ASCII, 1=netCDF).
int grid_nc_quant[NQ]
Number of digits for quantization of netCDF grid data files (0=off).
double met_cms_eps_lwc
cmultiscale compression epsilon for cloud liquid water content.
int qnt_us
Quantity array index for surface zonal wind.
double met_cms_eps_z
cmultiscale compression epsilon for geopotential height.
double grid_lon1
Upper longitude of gridded data [deg].
int qnt_Cn2o
Quantity array index for N2O volume mixing ratio (chemistry code).
int qnt_Cccl3f
Quantity array index for CFC-11 volume mixing ratio (chemistry code).
char qnt_name[NQ][LEN]
Quantity names.
char atm_basename[LEN]
Basename of atmospheric data files.
double mixing_lat0
Lower latitude of mixing grid [deg].
int qnt_pt
Quantity array index for tropopause pressure.
int qnt_cl
Quantity array index for total column cloud water.
int advect
Advection scheme (0=off, 1=Euler, 2=midpoint, 4=Runge-Kutta).
double prof_z1
Upper altitude of gridded profile data [km].
int qnt_t
Quantity array index for temperature.
int atm_filter
Time filter for atmospheric data output (0=none, 1=missval, 2=remove).
int kpp_chem
Switch for KPP chemistry module (0=off, 1=on).
int qnt_zeta
Quantity array index for zeta vertical coordinate.
double conv_pbl_trans
Depth of PBL transition layer (fraction of PBL depth).
char ens_basename[LEN]
Basename of ensemble data file.
double wet_depo_pre[2]
Coefficients for precipitation calculation.
int met_vert_coord
Vertical coordinate of input meteo data (0=pressure-level, 1=model-level_pfield, 2=model-level_abcoef...
double csi_z0
Lower altitude of gridded CSI data [km].
int qnt_lapse
Quantity array index for lapse rate.
double stat_lat
Latitude of station [deg].
int qnt_Cho2
Quantity array index for HO2 volume mixing ratio (chemistry code).
double wet_depo_bc_h[2]
Coefficients for wet deposition below cloud (Henry's law: Hb, Cb).
int grid_ny
Number of latitudes of gridded data.
int qnt_Csf6
Quantity array index for SF6 volume mixing ratio (chemistry code).
int qnt_Ch2o
Quantity array index for H2O volume mixing ratio (chemistry code).
double met_detrend
FWHM of horizontal Gaussian used for detrending [km].
int conv_mix_pbl
Vertical mixing in the PBL (0=off, 1=on).
char metbase[LEN]
Basename for meteo data.
double bound_dps
Boundary conditions surface layer depth [hPa].
double met_cms_eps_t
cmultiscale compression epsilon for temperature.
int chemgrid_nz
Number of altitudes of chemistry grid.
int qnt_cape
Quantity array index for convective available potential energy (CAPE).
double bound_mass_trend
Boundary conditions mass per particle trend [kg/s].
int mixing_nz
Number of altitudes of mixing grid.
int qnt_o3c
Quantity array index for total column ozone.
double bound_p0
Boundary conditions bottom pressure [hPa].
double mixing_lon0
Lower longitude of mixing grid [deg].
char clim_ccl4_timeseries[LEN]
Filename of CFC-10 time series.
int qnt_Co3
Quantity array index for O3 volume mixing ratio (chemistry code).
int qnt_tsts
Quantity array index for T_STS.
int grid_nz
Number of altitudes of gridded data.
char clim_oh_filename[LEN]
Filename of OH climatology.
int qnt_nss
Quantity array index for northward turbulent surface stress.
double ens_dt_out
Time step for ensemble output [s].
char sample_basename[LEN]
Basename of sample data file.
int atm_stride
Particle index stride for atmospheric data files.
int met_relhum
Try to read relative humidity (0=no, 1=yes).
double mixing_lat1
Upper latitude of mixing grid [deg].
double atm_dt_out
Time step for atmospheric data output [s].
char clim_sf6_timeseries[LEN]
Filename of SF6 time series.
double prof_lat1
Upper latitude of gridded profile data [deg].
int met_cms_batch
cmultiscale batch size.
double psc_h2o
H2O volume mixing ratio for PSC analysis.
int met_sp
Smoothing for pressure levels.
double prof_lon0
Lower longitude of gridded profile data [deg].
int chemgrid_nx
Number of longitudes of chemistry grid.
int qnt_pct
Quantity array index for cloud top pressure.
int qnt_mloss_kpp
Quantity array index for total mass loss due to KPP chemistry.
int qnt_psat
Quantity array index for saturation pressure over water.
double 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 wet_depo_ic_h[2]
Coefficients for wet deposition in cloud (Henry's law: Hb, Cb).
double turb_dx_pbl
Horizontal turbulent diffusion coefficient (PBL) [m^2/s].
double conv_cin
CIN threshold for convection module [J/kg].
int qnt_pv
Quantity array index for potential vorticity.
int advect_vert_coord
Vertical 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.
int qnt_ess
Quantity array index for eastward turbulent surface stress.
double wet_depo_ic_b
Coefficient B for wet deposition in cloud (exponential form).
double wet_depo_bc_b
Coefficient B for wet deposition below cloud (exponential form).
int met_dy
Stride for latitudes.
int qnt_Cx
Quantity array index for trace species x volume mixing ratio (chemistry code).
double turb_dz_strat
Vertical turbulent diffusion coefficient (stratosphere) [m^2/s].
double bound_zetas
Boundary conditions surface layer zeta [K].
int qnt_idx
Quantity array index for air parcel IDs.
double met_tropo_theta
Dynamical tropopause potential temperature threshold [K].
int qnt_rwc
Quantity array index for cloud rain water content.
double t_start
Start time of simulation [s].
char qnt_longname[NQ][LEN]
Quantity long names.
double met_p[EP]
Target pressure levels [hPa].
int nq
Number of quantities.
double tdec_trop
Life time of particles in the troposphere [s].
double sample_dx
Horizontal radius for sample output [km].
int vtk_stride
Particle index stride for VTK data.
char stat_basename[LEN]
Basename of station data file.
double turb_dz_pbl
Vertical turbulent diffusion coefficient (PBL) [m^2/s].
double grid_lat1
Upper latitude of gridded data [deg].
int qnt_zt
Quantity array index for tropopause geopotential height.
int met_type
Type of meteo data files (0=netCDF, 1=binary, 2=pck, 3=zfp, 4=zstd, 5=cms).
int qnt_cc
Quantity array index for cloud cover.
int qnt_plcl
Quantity array index for pressure at lifted condensation level (LCL).
double grid_dt_out
Time step for gridded data output [s].
int qnt_tdew
Quantity array index for dew point temperature.
float zt[EX][EY]
Tropopause geopotential height [km].
float sst[EX][EY]
Sea surface temperature [K].
float rwc[EX][EY][EP]
Cloud rain water content [kg/kg].
float o3c[EX][EY]
Total column ozone [DU].
float zeta_dotl[EX][EY][EP]
Vertical velocity on model levels [K/s].
float h2o[EX][EY][EP]
Water vapor volume mixing ratio [1].
float cape[EX][EY]
Convective available potential energy [J/kg].
float w[EX][EY][EP]
Vertical velocity [hPa/s].
float pct[EX][EY]
Cloud top pressure [hPa].
double hybrid[EP]
Model hybrid levels.
int nx
Number of longitudes.
int ny
Number of latitudes.
float shf[EX][EY]
Surface sensible heat flux [W/m^2].
float ps[EX][EY]
Surface pressure [hPa].
float lwc[EX][EY][EP]
Cloud liquid water content [kg/kg].
float us[EX][EY]
Surface zonal wind [m/s].
float wl[EX][EY][EP]
Vertical velocity on model levels [hPa/s].
float vl[EX][EY][EP]
Meridional wind on model levels [m/s].
float zs[EX][EY]
Surface geopotential height [km].
float o3[EX][EY][EP]
Ozone volume mixing ratio [1].
float cc[EX][EY][EP]
Cloud cover [1].
int np
Number of pressure levels.
float t[EX][EY][EP]
Temperature [K].
float ts[EX][EY]
Surface temperature [K].
float u[EX][EY][EP]
Zonal wind [m/s].
float ess[EX][EY]
Eastward turbulent surface stress [N/m^2].
float ul[EX][EY][EP]
Zonal wind on model levels [m/s].
float pcb[EX][EY]
Cloud bottom pressure [hPa].
float pel[EX][EY]
Pressure at equilibrium level (EL) [hPa].
float cin[EX][EY]
Convective inhibition [J/kg].
float plcl[EX][EY]
Pressure at lifted condensation level (LCL) [hPa].
double lon[EX]
Longitude [deg].
float pt[EX][EY]
Tropopause pressure [hPa].
float tt[EX][EY]
Tropopause temperature [K].
float pbl[EX][EY]
Boundary layer pressure [hPa].
float vs[EX][EY]
Surface meridional wind [m/s].
float z[EX][EY][EP]
Geopotential height [km].
float v[EX][EY][EP]
Meridional wind [m/s].
int npl
Number of model levels.
float lsm[EX][EY]
Land-sea mask [1].
float iwc[EX][EY][EP]
Cloud ice water content [kg/kg].
float h2ot[EX][EY]
Tropopause water vapor volume mixing ratio [ppv].
float pv[EX][EY][EP]
Potential vorticity [PVU].
float cl[EX][EY]
Total column cloud water [kg/m^2].
float nss[EX][EY]
Northward turbulent surface stress [N/m^2].
float pl[EX][EY][EP]
Pressure on model levels [hPa].
float plfc[EX][EY]
Pressure at level of free convection (LFC) [hPa].
double lat[EY]
Latitude [deg].
float swc[EX][EY][EP]
Cloud snow water content [kg/kg].
float zetal[EX][EY][EP]
Zeta on model levels [K].
double p[EP]
Pressure levels [hPa].