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);
1014 char cachefile[
LEN], cmd[2 *
LEN], filename[
LEN];
1020 if (t == ctl->
t_start || !init) {
1026 if (!
read_met(filename, ctl, clim, *met0))
1027 ERRMSG(
"Cannot open file!");
1031 if (!
read_met(filename, ctl, clim, *met1))
1032 ERRMSG(
"Cannot open file!");
1037 met_t *met0up = *met0;
1038 met_t *met1up = *met1;
1040#pragma acc update device(met0up[:1],met1up[:1]) async(5)
1042#pragma acc update device(met0up[:1],met1up[:1])
1051 sprintf(cmd,
"cat %s > /dev/null &", cachefile);
1052 LOG(1,
"Caching: %s", cachefile);
1053 if (system(cmd) != 0)
1054 WARN(
"Caching command failed!");
1059 if (t > (*met1)->time) {
1068 if (!
read_met(filename, ctl, clim, *met1))
1069 ERRMSG(
"Cannot open file!");
1074 met_t *met1up = *met1;
1076#pragma acc update device(met1up[:1]) async(5)
1078#pragma acc update device(met1up[:1])
1087 sprintf(cmd,
"cat %s > /dev/null &", cachefile);
1088 LOG(1,
"Caching: %s", cachefile);
1089 if (system(cmd) != 0)
1090 WARN(
"Caching command failed!");
1095 if (t < (*met0)->time) {
1104 if (!
read_met(filename, ctl, clim, *met0))
1105 ERRMSG(
"Cannot open file!");
1110 met_t *met0up = *met0;
1112#pragma acc update device(met0up[:1]) async(5)
1114#pragma acc update device(met0up[:1])
1123 sprintf(cmd,
"cat %s > /dev/null &", cachefile);
1124 LOG(1,
"Caching: %s", cachefile);
1125 if (system(cmd) != 0)
1126 WARN(
"Caching command failed!");
1131 if ((*met0)->nx != 0 && (*met1)->nx != 0) {
1132 if ((*met0)->nx != (*met1)->nx
1133 || (*met0)->ny != (*met1)->ny || (*met0)->np != (*met1)->np)
1134 ERRMSG(
"Meteo grid dimensions do not match!");
1135 for (
int ix = 0; ix < (*met0)->nx; ix++)
1136 if (fabs((*met0)->lon[ix] - (*met1)->lon[ix]) > 0.001)
1137 ERRMSG(
"Meteo grid longitudes do not match!");
1138 for (
int iy = 0; iy < (*met0)->ny; iy++)
1139 if (fabs((*met0)->lat[iy] - (*met1)->lat[iy]) > 0.001)
1140 ERRMSG(
"Meteo grid latitudes do not match!");
1141 for (
int ip = 0; ip < (*met0)->np; ip++)
1142 if (fabs((*met0)->p[ip] - (*met1)->p[ip]) > 0.001)
1143 ERRMSG(
"Meteo grid pressure levels do not match!");
1153 const char *metbase,
1154 const double dt_met,
1161 int year, mon, day, hour, min, sec;
1165 t6 = floor(t / dt_met) * dt_met;
1167 t6 = ceil(t / dt_met) * dt_met;
1170 jsec2time(t6, &year, &mon, &day, &hour, &min, &sec, &r);
1175 sprintf(filename,
"%s_YYYY_MM_DD_HH.nc", metbase);
1177 sprintf(filename,
"%s_YYYY_MM_DD_HH.bin", metbase);
1179 sprintf(filename,
"%s_YYYY_MM_DD_HH.pck", metbase);
1181 sprintf(filename,
"%s_YYYY_MM_DD_HH.zfp", metbase);
1183 sprintf(filename,
"%s_YYYY_MM_DD_HH.zstd", metbase);
1185 sprintf(filename,
"%s_YYYY_MM_DD_HH.cms", metbase);
1186 sprintf(repl,
"%d", year);
1188 sprintf(repl,
"%02d", mon);
1190 sprintf(repl,
"%02d", day);
1192 sprintf(repl,
"%02d", hour);
1198 sprintf(filename,
"%s_YYMMDDHH.nc", metbase);
1199 sprintf(repl,
"%d", year);
1201 sprintf(repl,
"%02d", year % 100);
1203 sprintf(repl,
"%02d", mon);
1205 sprintf(repl,
"%02d", day);
1207 sprintf(repl,
"%02d", hour);
1222 for (
int i = 0; i < 3; i++) {
1226 if (!(ch = strstr(orig, search)))
1228 strncpy(buffer, orig, (
size_t) (ch - orig));
1229 buffer[ch - orig] = 0;
1230 sprintf(buffer + (ch - orig),
"%s%s", repl, ch + strlen(search));
1232 strcpy(orig, buffer);
1239 const int met_tropo,
1259#pragma omp parallel for default(shared) private(ci,cw)
1260 for (
int ix = 0; ix < nx; ix++)
1261 for (
int iy = 0; iy < ny; iy++) {
1263 &pt[iy * nx + ix], ci, cw, 1);
1265 &ps[iy * nx + ix], ci, cw, 0);
1267 &zs[iy * nx + ix], ci, cw, 0);
1269 lats[iy], &zt[iy * nx + ix], ci, cw, 1);
1271 lats[iy], &tt[iy * nx + ix], ci, cw, 0);
1273 lats[iy], &qt[iy * nx + ix], ci, cw, 0);
1275 lats[iy], &o3t[iy * nx + ix], ci, cw, 0);
1283 float heights0[
EX][
EY][
EP],
1284 float array0[
EX][
EY][
EP],
1286 float heights1[
EX][
EY][
EP],
1287 float array1[
EX][
EY][
EP],
1289 const double height,
1300 double lon2 =
FMOD(lon, 360.);
1301 if (lon2 < met0->lon[0])
1303 else if (lon2 > met0->
lon[met0->
nx - 1])
1317 int k_max = ind[0][0];
1318 for (
int i = 0; i < 2; i++)
1319 for (
int j = 0; j < 4; j++) {
1320 if (ci[2] > ind[i][j])
1322 if (k_max < ind[i][j])
1328 cw[0] = (lon2 - met0->
lon[ci[0]]) /
1329 (met0->
lon[ci[0] + 1] - met0->
lon[ci[0]]);
1330 cw[1] = (lat - met0->
lat[ci[1]]) /
1331 (met0->
lat[ci[1] + 1] - met0->
lat[ci[1]]);
1334 double height_top, height_bot;
1335 double height00, height01, height10, height11, height0, height1;
1338 height00 = cw[3] * (heights1[ci[0]][ci[1]][ci[2]]
1339 - heights0[ci[0]][ci[1]][ci[2]])
1340 + heights0[ci[0]][ci[1]][ci[2]];
1341 height01 = cw[3] * (heights1[ci[0]][ci[1] + 1][ci[2]]
1342 - heights0[ci[0]][ci[1] + 1][ci[2]])
1343 + heights0[ci[0]][ci[1] + 1][ci[2]];
1344 height10 = cw[3] * (heights1[ci[0] + 1][ci[1]][ci[2]]
1345 - heights0[ci[0] + 1][ci[1]][ci[2]])
1346 + heights0[ci[0] + 1][ci[1]][ci[2]];
1347 height11 = cw[3] * (heights1[ci[0] + 1][ci[1] + 1][ci[2]]
1348 - heights0[ci[0] + 1][ci[1] + 1][ci[2]])
1349 + heights0[ci[0] + 1][ci[1] + 1][ci[2]];
1352 height0 = cw[1] * (height01 - height00) + height00;
1353 height1 = cw[1] * (height11 - height10) + height10;
1356 height_bot = cw[0] * (height1 - height0) + height0;
1359 height00 = cw[3] * (heights1[ci[0]][ci[1]][ci[2] + 1]
1360 - heights0[ci[0]][ci[1]][ci[2] + 1])
1361 + heights0[ci[0]][ci[1]][ci[2] + 1];
1362 height01 = cw[3] * (heights1[ci[0]][ci[1] + 1][ci[2] + 1]
1363 - heights0[ci[0]][ci[1] + 1][ci[2] + 1])
1364 + heights0[ci[0]][ci[1] + 1][ci[2] + 1];
1365 height10 = cw[3] * (heights1[ci[0] + 1][ci[1]][ci[2] + 1]
1366 - heights0[ci[0] + 1][ci[1]][ci[2] + 1])
1367 + heights0[ci[0] + 1][ci[1]][ci[2] + 1];
1368 height11 = cw[3] * (heights1[ci[0] + 1][ci[1] + 1][ci[2] + 1]
1369 - heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1])
1370 + heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1];
1373 height0 = cw[1] * (height01 - height00) + height00;
1374 height1 = cw[1] * (height11 - height10) + height10;
1377 height_top = cw[0] * (height1 - height0) + height0;
1380 while (((heights0[0][0][0] > heights0[0][0][1]) &&
1381 ((height_bot <= height) || (height_top > height))
1382 && (height_bot >= height) && (ci[2] < k_max))
1384 ((heights0[0][0][0] < heights0[0][0][1]) &&
1385 ((height_bot >= height) || (height_top < height))
1386 && (height_bot <= height) && (ci[2] < k_max))
1390 height_bot = height_top;
1393 height00 = cw[3] * (heights1[ci[0]][ci[1]][ci[2] + 1]
1394 - heights0[ci[0]][ci[1]][ci[2] + 1])
1395 + heights0[ci[0]][ci[1]][ci[2] + 1];
1396 height01 = cw[3] * (heights1[ci[0]][ci[1] + 1][ci[2] + 1]
1397 - heights0[ci[0]][ci[1] + 1][ci[2] + 1])
1398 + heights0[ci[0]][ci[1] + 1][ci[2] + 1];
1399 height10 = cw[3] * (heights1[ci[0] + 1][ci[1]][ci[2] + 1]
1400 - heights0[ci[0] + 1][ci[1]][ci[2] + 1])
1401 + heights0[ci[0] + 1][ci[1]][ci[2] + 1];
1402 height11 = cw[3] * (heights1[ci[0] + 1][ci[1] + 1][ci[2] + 1]
1403 - heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1])
1404 + heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1];
1407 height0 = cw[1] * (height01 - height00) + height00;
1408 height1 = cw[1] * (height11 - height10) + height10;
1411 height_top = cw[0] * (height1 - height0) + height0;
1415 cw[2] = (height - height_bot)
1416 / (height_top - height_bot);
1420 double array000 = cw[3] * (array1[ci[0]][ci[1]][ci[2]]
1421 - array0[ci[0]][ci[1]][ci[2]])
1422 + array0[ci[0]][ci[1]][ci[2]];
1423 double array100 = cw[3] * (array1[ci[0] + 1][ci[1]][ci[2]]
1424 - array0[ci[0] + 1][ci[1]][ci[2]])
1425 + array0[ci[0] + 1][ci[1]][ci[2]];
1426 double array010 = cw[3] * (array1[ci[0]][ci[1] + 1][ci[2]]
1427 - array0[ci[0]][ci[1] + 1][ci[2]])
1428 + array0[ci[0]][ci[1] + 1][ci[2]];
1429 double array110 = cw[3] * (array1[ci[0] + 1][ci[1] + 1][ci[2]]
1430 - array0[ci[0] + 1][ci[1] + 1][ci[2]])
1431 + array0[ci[0] + 1][ci[1] + 1][ci[2]];
1432 double array001 = cw[3] * (array1[ci[0]][ci[1]][ci[2] + 1]
1433 - array0[ci[0]][ci[1]][ci[2] + 1])
1434 + array0[ci[0]][ci[1]][ci[2] + 1];
1435 double array101 = cw[3] * (array1[ci[0] + 1][ci[1]][ci[2] + 1]
1436 - array0[ci[0] + 1][ci[1]][ci[2] + 1])
1437 + array0[ci[0] + 1][ci[1]][ci[2] + 1];
1438 double array011 = cw[3] * (array1[ci[0]][ci[1] + 1][ci[2] + 1]
1439 - array0[ci[0]][ci[1] + 1][ci[2] + 1])
1440 + array0[ci[0]][ci[1] + 1][ci[2] + 1];
1441 double array111 = cw[3] * (array1[ci[0] + 1][ci[1] + 1][ci[2] + 1]
1442 - array0[ci[0] + 1][ci[1] + 1][ci[2] + 1])
1443 + array0[ci[0] + 1][ci[1] + 1][ci[2] + 1];
1445 double array00 = cw[0] * (array100 - array000) + array000;
1446 double array10 = cw[0] * (array110 - array010) + array010;
1447 double array01 = cw[0] * (array101 - array001) + array001;
1448 double array11 = cw[0] * (array111 - array011) + array011;
1450 double aux0 = cw[1] * (array10 - array00) + array00;
1451 double aux1 = cw[1] * (array11 - array01) + array01;
1454 *var = cw[2] * (aux1 - aux0) + aux0;
1474 double lon2 =
FMOD(lon, 360.);
1475 if (lon2 < met->lon[0])
1477 else if (lon2 > met->
lon[met->
nx - 1])
1486 cw[0] = (met->
p[ci[0] + 1] - p)
1487 / (met->
p[ci[0] + 1] - met->
p[ci[0]]);
1488 cw[1] = (met->
lon[ci[1] + 1] - lon2)
1489 / (met->
lon[ci[1] + 1] - met->
lon[ci[1]]);
1490 cw[2] = (met->
lat[ci[2] + 1] - lat)
1491 / (met->
lat[ci[2] + 1] - met->
lat[ci[2]]);
1496 cw[0] * (array[ci[1]][ci[2]][ci[0]] - array[ci[1]][ci[2]][ci[0] + 1])
1497 + array[ci[1]][ci[2]][ci[0] + 1];
1499 cw[0] * (array[ci[1]][ci[2] + 1][ci[0]] -
1500 array[ci[1]][ci[2] + 1][ci[0] + 1])
1501 + array[ci[1]][ci[2] + 1][ci[0] + 1];
1503 cw[0] * (array[ci[1] + 1][ci[2]][ci[0]] -
1504 array[ci[1] + 1][ci[2]][ci[0] + 1])
1505 + array[ci[1] + 1][ci[2]][ci[0] + 1];
1507 cw[0] * (array[ci[1] + 1][ci[2] + 1][ci[0]] -
1508 array[ci[1] + 1][ci[2] + 1][ci[0] + 1])
1509 + array[ci[1] + 1][ci[2] + 1][ci[0] + 1];
1512 aux00 = cw[2] * (aux00 - aux01) + aux01;
1513 aux11 = cw[2] * (aux10 - aux11) + aux11;
1514 *var = cw[1] * (aux00 - aux11) + aux11;
1528 double lon2 =
FMOD(lon, 360.);
1529 if (lon2 < met->lon[0])
1531 else if (lon2 > met->
lon[met->
nx - 1])
1541 if (p >= met->
pl[ix][iy][iz + 1])
1542 aux00 = array[ix][iy][iz + 1];
1543 else if (p <= met->pl[ix][iy][iz])
1544 aux00 = array[ix][iy][iz];
1546 aux00 =
LIN(met->
pl[ix][iy][iz],
1548 met->
pl[ix][iy][iz + 1], array[ix][iy][iz + 1], p);
1552 if (p >= met->
pl[ix][iy + 1][iz + 1])
1553 aux01 = array[ix][iy + 1][iz + 1];
1554 else if (p <= met->pl[ix][iy + 1][iz])
1555 aux01 = array[ix][iy + 1][iz];
1557 aux01 =
LIN(met->
pl[ix][iy + 1][iz],
1558 array[ix][iy + 1][iz],
1559 met->
pl[ix][iy + 1][iz + 1], array[ix][iy + 1][iz + 1], p);
1563 if (p >= met->
pl[ix + 1][iy][iz + 1])
1564 aux10 = array[ix + 1][iy][iz + 1];
1565 else if (p <= met->pl[ix + 1][iy][iz])
1566 aux10 = array[ix + 1][iy][iz];
1568 aux10 =
LIN(met->
pl[ix + 1][iy][iz],
1569 array[ix + 1][iy][iz],
1570 met->
pl[ix + 1][iy][iz + 1], array[ix + 1][iy][iz + 1], p);
1574 if (p >= met->
pl[ix + 1][iy + 1][iz + 1])
1575 aux11 = array[ix + 1][iy + 1][iz + 1];
1576 else if (p <= met->pl[ix + 1][iy + 1][iz])
1577 aux11 = array[ix + 1][iy + 1][iz];
1579 aux11 =
LIN(met->
pl[ix + 1][iy + 1][iz],
1580 array[ix + 1][iy + 1][iz],
1581 met->
pl[ix + 1][iy + 1][iz + 1],
1582 array[ix + 1][iy + 1][iz + 1], p);
1585 double aux0 =
LIN(met->
lat[iy], aux00, met->
lat[iy + 1], aux01, lat);
1586 double aux1 =
LIN(met->
lat[iy], aux10, met->
lat[iy + 1], aux11, lat);
1587 *var =
LIN(met->
lon[ix], aux0, met->
lon[ix + 1], aux1, lon2);
1594 float array[
EX][
EY],
1606 double lon2 =
FMOD(lon, 360.);
1607 if (lon2 < met->lon[0])
1609 else if (lon2 > met->
lon[met->
nx - 1])
1617 cw[1] = (met->
lon[ci[1] + 1] - lon2)
1618 / (met->
lon[ci[1] + 1] - met->
lon[ci[1]]);
1619 cw[2] = (met->
lat[ci[2] + 1] - lat)
1620 / (met->
lat[ci[2] + 1] - met->
lat[ci[2]]);
1624 double aux00 = array[ci[1]][ci[2]];
1625 double aux01 = array[ci[1]][ci[2] + 1];
1626 double aux10 = array[ci[1] + 1][ci[2]];
1627 double aux11 = array[ci[1] + 1][ci[2] + 1];
1630 if (isfinite(aux00) && isfinite(aux01)
1631 && isfinite(aux10) && isfinite(aux11)) {
1632 aux00 = cw[2] * (aux00 - aux01) + aux01;
1633 aux11 = cw[2] * (aux10 - aux11) + aux11;
1634 *var = cw[1] * (aux00 - aux11) + aux11;
1654 float array0[
EX][
EY][
EP],
1656 float array1[
EX][
EY][
EP],
1673 const double wt = (met1->
time - ts) / (met1->
time - met0->
time);
1676 *var = wt * (var0 - var1) + var1;
1683 float array0[
EX][
EY][
EP],
1685 float array1[
EX][
EY][
EP],
1699 *var =
LIN(met0->
time, var0, met1->
time, var1, ts);
1706 float array0[
EX][
EY],
1708 float array1[
EX][
EY],
1724 const double wt = (met1->
time - ts) / (met1->
time - met0->
time);
1727 if (isfinite(var0) && isfinite(var1))
1728 *var = wt * (var0 - var1) + var1;
1739 float array0[
EX][
EY],
1741 float array1[
EX][
EY],
1742 const double lons[
EX],
1743 const double lats[
EY],
1753 double aux0, aux1, aux00, aux01, aux10, aux11, mean = 0;
1758 double lon2 =
FMOD(lon, 360.);
1761 else if (lon2 > lons[nlon - 1])
1765 const int ix =
locate_reg(lons, (
int) nlon, lon2);
1766 const int iy =
locate_reg(lats, (
int) nlat, lat);
1770 for (
int dx = 0; dx < 2; dx++)
1771 for (
int dy = 0; dy < 2; dy++) {
1772 if (isfinite(array0[ix + dx][iy + dy])) {
1773 mean += array0[ix + dx][iy + dy];
1774 *sigma +=
SQR(array0[ix + dx][iy + dy]);
1777 if (isfinite(array1[ix + dx][iy + dy])) {
1778 mean += array1[ix + dx][iy + dy];
1779 *sigma +=
SQR(array1[ix + dx][iy + dy]);
1784 *sigma = sqrt(
MAX(*sigma / n -
SQR(mean / n), 0.0));
1787 if (method == 1 && isfinite(array0[ix][iy])
1788 && isfinite(array0[ix][iy + 1])
1789 && isfinite(array0[ix + 1][iy])
1790 && isfinite(array0[ix + 1][iy + 1])
1791 && isfinite(array1[ix][iy])
1792 && isfinite(array1[ix][iy + 1])
1793 && isfinite(array1[ix + 1][iy])
1794 && isfinite(array1[ix + 1][iy + 1])) {
1796 aux00 =
LIN(lons[ix], array0[ix][iy],
1797 lons[ix + 1], array0[ix + 1][iy], lon2);
1798 aux01 =
LIN(lons[ix], array0[ix][iy + 1],
1799 lons[ix + 1], array0[ix + 1][iy + 1], lon2);
1800 aux0 =
LIN(lats[iy], aux00, lats[iy + 1], aux01, lat);
1802 aux10 =
LIN(lons[ix], array1[ix][iy],
1803 lons[ix + 1], array1[ix + 1][iy], lon2);
1804 aux11 =
LIN(lons[ix], array1[ix][iy + 1],
1805 lons[ix + 1], array1[ix + 1][iy + 1], lon2);
1806 aux1 =
LIN(lats[iy], aux10, lats[iy + 1], aux11, lat);
1808 *var =
LIN(time0, aux0, time1, aux1, time);
1813 aux00 =
NN(lons[ix], array0[ix][iy],
1814 lons[ix + 1], array0[ix + 1][iy], lon2);
1815 aux01 =
NN(lons[ix], array0[ix][iy + 1],
1816 lons[ix + 1], array0[ix + 1][iy + 1], lon2);
1817 aux0 =
NN(lats[iy], aux00, lats[iy + 1], aux01, lat);
1819 aux10 =
NN(lons[ix], array1[ix][iy],
1820 lons[ix + 1], array1[ix + 1][iy], lon2);
1821 aux11 =
NN(lons[ix], array1[ix][iy + 1],
1822 lons[ix + 1], array1[ix + 1][iy + 1], lon2);
1823 aux1 =
NN(lats[iy], aux10, lats[iy + 1], aux11, lat);
1825 *var =
NN(time0, aux0, time1, aux1, time);
1850 const time_t jsec0 = (time_t) jsec + timegm(&t0);
1851 t1 = gmtime(&jsec0);
1853 *year = t1->tm_year + 1900;
1854 *mon = t1->tm_mon + 1;
1856 *hour = t1->tm_hour;
1859 *remain = jsec - floor(jsec);
1865 const double kz[
EP],
1866 const double kw[
EP],
1875 const double z =
Z(p);
1880 else if (z > kz[nk - 1])
1884 return LIN(kz[idx], kw[idx], kz[idx + 1], kw[idx + 1], z);
1901 const double a =
RA *
SQR(t), r =
SH(h2o) / (1. -
SH(h2o));
1915 const double press[138] = {
1916 0.0200, 0.0310, 0.0467, 0.0683, 0.0975, 0.1361, 0.1861, 0.2499,
1917 0.3299, 0.4288, 0.5496, 0.6952, 0.8690, 1.0742, 1.3143, 1.5928, 1.9134,
1918 2.2797, 2.6954, 3.1642, 3.6898, 4.2759, 4.9262, 5.6441, 6.4334, 7.2974,
1919 8.2397, 9.2634, 10.3720, 11.5685, 12.8561, 14.2377, 15.7162, 17.2945,
1920 18.9752, 20.7610, 22.6543, 24.6577, 26.7735, 29.0039, 31.3512, 33.8174,
1921 36.4047, 39.1149, 41.9493, 44.9082, 47.9915, 51.1990, 54.5299, 57.9834,
1922 61.5607, 65.2695, 69.1187, 73.1187, 77.2810, 81.6182, 86.1450, 90.8774,
1923 95.8280, 101.0047, 106.4153, 112.0681, 117.9714, 124.1337, 130.5637,
1924 137.2703, 144.2624, 151.5493, 159.1403, 167.0450, 175.2731, 183.8344,
1925 192.7389, 201.9969, 211.6186, 221.6146, 231.9954, 242.7719, 253.9549,
1926 265.5556, 277.5852, 290.0548, 302.9762, 316.3607, 330.2202, 344.5663,
1927 359.4111, 374.7666, 390.6450, 407.0583, 424.0190, 441.5395, 459.6321,
1928 478.3096, 497.5845, 517.4198, 537.7195, 558.3430, 579.1926, 600.1668,
1929 621.1624, 642.0764, 662.8084, 683.2620, 703.3467, 722.9795, 742.0855,
1930 760.5996, 778.4661, 795.6396, 812.0847, 827.7756, 842.6959, 856.8376,
1931 870.2004, 882.7910, 894.6222, 905.7116, 916.0815, 925.7571, 934.7666,
1932 943.1399, 950.9082, 958.1037, 964.7584, 970.9046, 976.5737, 981.7968,
1933 986.6036, 991.0230, 995.0824, 998.8081, 1002.2250, 1005.3562, 1008.2239,
1934 1010.8487, 1013.2500, 1044.45
1937 for (
int ip = 0; ip < ctl->
met_np; ip++)
1944 const double press[92] = {
1945 0.0200, 0.0398, 0.0739, 0.1291, 0.2141, 0.3395, 0.5175, 0.7617,
1946 1.0872, 1.5099, 2.0464, 2.7136, 3.5282, 4.5069, 5.6652, 7.0181,
1947 8.5795, 10.3617, 12.3759, 14.6316, 17.1371, 19.8987, 22.9216, 26.2090,
1948 29.7630, 33.5843, 37.6720, 42.0242, 46.6378, 51.5086, 56.6316, 61.9984,
1949 67.5973, 73.4150, 79.4434, 85.7016, 92.2162, 99.0182, 106.1445,
1951 121.5502, 129.9403, 138.8558, 148.3260, 158.3816, 169.0545, 180.3786,
1952 192.3889, 205.1222, 218.6172, 232.9140, 248.0547, 264.0833, 281.0456,
1953 298.9895, 317.9651, 338.0245, 359.2221, 381.6144, 405.2606, 430.2069,
1954 456.4813, 483.8505, 512.0662, 540.8577, 569.9401, 599.0310, 627.9668,
1955 656.6129, 684.8491, 712.5573, 739.5739, 765.7697, 791.0376, 815.2774,
1956 838.3507, 860.1516, 880.6080, 899.6602, 917.2205, 933.2247, 947.6584,
1957 960.5245, 971.8169, 981.5301, 989.7322, 996.8732, 1002.8013,
1958 1007.4431, 1010.8487, 1013.2500, 1044.45
1961 for (
int ip = 0; ip < ctl->
met_np; ip++)
1968 const double press[60] = {
1969 0.01, 0.1361, 0.2499, 0.4288, 0.6952, 1.0742,
1970 2.2797, 3.1642, 4.2759, 7.2974, 9.2634, 11.5685, 14.2377, 20.761,
1971 24.6577, 33.8174, 39.1149, 51.199, 57.9834, 73.1187, 81.6182,
1972 90.8774, 101.005, 112.068, 124.134, 137.27, 151.549, 167.045, 183.834,
1973 201.997, 221.615, 242.772, 265.556, 290.055, 316.361, 344.566, 374.767,
1974 407.058, 441.539, 478.31, 517.42, 558.343, 600.167, 683.262, 722.979,
1975 760.6, 795.64, 827.776, 856.838, 882.791, 905.712, 925.757, 943.14,
1976 958.104, 972.495, 986.886, 1001.28, 1015.67, 1030.06, 1044.45
1979 for (
int ip = 0; ip < ctl->
met_np; ip++)
1986 const double press[147] = {
1987 0.0200, 0.0310, 0.0467, 0.0683, 0.0975, 0.1361, 0.1861, 0.2499,
1988 0.3299, 0.4288, 0.5496, 0.6952, 0.8690, 1.0742, 1.3143, 1.5928, 1.9134,
1989 2.2797, 2.6954, 3.1642, 3.6898, 4.2759, 4.9262, 5.6441, 6.4334, 7.2974,
1990 8.2397, 9.2634, 10.3720, 11.5685, 12.8561, 14.2377, 15.7162, 17.2945,
1991 18.9752, 20.7610, 22.6543, 24.6577, 26.7735, 29.0039, 31.3512, 33.8174,
1992 36.4047, 39.1149, 41.9493, 44.9082, 47.9915, 51.1990, 54.5299, 57.9834,
1993 61.5607, 65.2695, 69.1187, 73.1187, 77.2810, 81.6182, 86.1450, 90.8774,
1994 95.8280, 101.0047, 106.4153, 112.0681, 117.9714, 124.1337, 130.5637,
1995 137.2703, 144.2624, 151.5493, 159.1403, 167.0450, 175.2731, 183.8344,
1996 192.7389, 201.9969, 211.6186, 221.6146, 231.9954, 242.7719, 253.9549,
1997 265.5556, 277.5852, 290.0548, 302.9762, 316.3607, 330.2202, 344.5663,
1998 359.4111, 374.7666, 390.6450, 407.0583, 424.0190, 441.5395, 459.6321,
1999 478.3096, 497.5845, 517.4198, 537.7195, 558.3430, 579.1926, 600.1668,
2000 621.1624, 642.0764, 662.8084, 683.2620, 703.3467, 722.9795, 742.0855,
2001 760.5996, 778.4661, 795.6396, 812.0847, 827.7756, 842.6959, 856.8376,
2002 870.2004, 882.7910, 894.6222, 905.7116, 916.0815, 925.7571, 934.7666,
2003 943.1399, 950.9082, 958.1037, 964.7584, 970.9046, 976.5737, 981.7968,
2004 986.6036, 991.0230, 995.0824, 998.8081, 1002.2250, 1005.3562, 1008.2239,
2005 1010.8487, 1013.25, 1016.37, 1019.49, 1022.61, 1025.73, 1028.85,
2007 1035.09, 1038.21, 1041.33, 1044.45
2010 for (
int ip = 0; ip < ctl->
met_np; ip++)
2017 const double press[101] = {
2018 0.0200, 0.0398, 0.0739, 0.1291, 0.2141, 0.3395, 0.5175, 0.7617,
2019 1.0872, 1.5099, 2.0464, 2.7136, 3.5282, 4.5069, 5.6652, 7.0181,
2020 8.5795, 10.3617, 12.3759, 14.6316, 17.1371, 19.8987, 22.9216, 26.2090,
2021 29.7630, 33.5843, 37.6720, 42.0242, 46.6378, 51.5086, 56.6316, 61.9984,
2022 67.5973, 73.4150, 79.4434, 85.7016, 92.2162, 99.0182, 106.1445,
2024 121.5502, 129.9403, 138.8558, 148.3260, 158.3816, 169.0545, 180.3786,
2025 192.3889, 205.1222, 218.6172, 232.9140, 248.0547, 264.0833, 281.0456,
2026 298.9895, 317.9651, 338.0245, 359.2221, 381.6144, 405.2606, 430.2069,
2027 456.4813, 483.8505, 512.0662, 540.8577, 569.9401, 599.0310, 627.9668,
2028 656.6129, 684.8491, 712.5573, 739.5739, 765.7697, 791.0376, 815.2774,
2029 838.3507, 860.1516, 880.6080, 899.6602, 917.2205, 933.2247, 947.6584,
2030 960.5245, 971.8169, 981.5301, 989.7322, 996.8732, 1002.8013,
2031 1007.4431, 1010.8487, 1013.25, 1016.37, 1019.49, 1022.61, 1025.73,
2033 1035.09, 1038.21, 1041.33, 1044.45
2036 for (
int ip = 0; ip < ctl->
met_np; ip++)
2043 const double press[62] = {
2044 0.01, 0.1361, 0.2499, 0.4288, 0.6952, 1.0742,
2045 2.2797, 3.1642, 4.2759, 7.2974, 9.2634, 11.5685, 14.2377, 20.761,
2046 24.6577, 33.8174, 39.1149, 51.199, 57.9834, 73.1187, 81.6182,
2047 90.8774, 101.005, 112.068, 124.134, 137.27, 151.549, 167.045, 183.834,
2048 201.997, 221.615, 242.772, 265.556, 290.055, 316.361, 344.566, 374.767,
2049 407.058, 441.539, 478.31, 517.42, 558.343, 600.167, 683.262, 722.979,
2050 760.6, 795.64, 827.776, 856.838, 882.791, 905.712, 925.757, 943.14,
2051 958.104, 972.495, 986.886, 1001.28, 1015.67, 1030.06, 1034.86, 1039.65,
2055 for (
int ip = 0; ip < ctl->
met_np; ip++)
2062 const double press[137] = {
2063 0.01, 0.02, 0.031, 0.0467, 0.0683, 0.0975, 0.1361, 0.1861,
2064 0.2499, 0.3299, 0.4288, 0.5496, 0.6952, 0.869, 1.0742,
2065 1.3143, 1.5928, 1.9134, 2.2797, 2.6954, 3.1642, 3.6898,
2066 4.2759, 4.9262, 5.6441, 6.4334, 7.2974, 8.2397, 9.2634,
2067 10.372, 11.5685, 12.8561, 14.2377, 15.7162, 17.2945, 18.9752,
2068 20.761, 22.6543, 24.6577, 26.7735, 29.0039, 31.3512, 33.8174,
2069 36.4047, 39.1149, 41.9493, 44.9082, 47.9915, 51.199, 54.5299,
2070 57.9834, 61.5607, 65.2695, 69.1187, 73.1187, 77.281, 81.6182,
2071 86.145, 90.8774, 95.828, 101.005, 106.415, 112.068, 117.971,
2072 124.134, 130.564, 137.27, 144.262, 151.549, 159.14, 167.045,
2073 175.273, 183.834, 192.739, 201.997, 211.619, 221.615, 231.995,
2074 242.772, 253.955, 265.556, 277.585, 290.055, 302.976, 316.361,
2075 330.22, 344.566, 359.411, 374.767, 390.645, 407.058, 424.019,
2076 441.539, 459.632, 478.31, 497.584, 517.42, 537.72, 558.343,
2077 579.193, 600.167, 621.162, 642.076, 662.808, 683.262, 703.347,
2078 722.979, 742.086, 760.6, 778.466, 795.64, 812.085, 827.776,
2079 842.696, 856.838, 870.2, 882.791, 894.622, 905.712, 916.081,
2080 925.757, 934.767, 943.14, 950.908, 958.104, 965.299, 972.495,
2081 979.69, 986.886, 994.081, 1001.28, 1008.47, 1015.67, 1022.86,
2082 1030.06, 1037.25, 1044.45
2085 for (
int ip = 0; ip < ctl->
met_np; ip++)
2092 const double press[59] = {
2093 0.1, 0.2, 0.3843, 0.6365, 0.9564, 1.3448, 1.8058, 2.3478,
2094 2.985, 3.7397, 4.6462, 5.7565, 7.1322, 8.8366, 10.9483,
2095 13.5647, 16.8064, 20.8227, 25.7989, 31.9642, 39.6029, 49.0671,
2096 60.1802, 73.0663, 87.7274, 104.229, 122.614, 142.902, 165.089,
2097 189.147, 215.025, 242.652, 272.059, 303.217, 336.044, 370.407,
2098 406.133, 443.009, 480.791, 519.209, 557.973, 596.777, 635.306,
2099 673.24, 710.263, 746.063, 780.346, 812.83, 843.263, 871.42,
2100 897.112, 920.189, 940.551, 958.148, 975.744, 993.341, 1010.94,
2104 for (
int ip = 0; ip < ctl->
met_np; ip++)
2108 ERRMSG(
"Use 0 for l137, 1 for l91, 2 for l60 or values between 3 and 7.")
2121 int i = (ihi + ilo) >> 1;
2123 if (xx[i] < xx[i + 1])
2124 while (ihi > ilo + 1) {
2125 i = (ihi + ilo) >> 1;
2131 while (ihi > ilo + 1) {
2132 i = (ihi + ilo) >> 1;
2152 int i = (ihi + ilo) >> 1;
2154 if (x >= xx[ig] && x < xx[ig + 1])
2157 if (xx[i] < xx[i + 1])
2158 while (ihi > ilo + 1) {
2159 i = (ihi + ilo) >> 1;
2165 while (ihi > ilo + 1) {
2166 i = (ihi + ilo) >> 1;
2184 int i = (int) ((x - xx[0]) / (xx[1] - xx[0]));
2198 float profiles[
EX][
EY][
EP],
2200 const int lon_ap_ind,
2201 const int lat_ap_ind,
2202 const double height_ap,
2208 np, height_ap, ind[0]);
2210 np, height_ap, ind[1]);
2212 np, height_ap, ind[2]);
2231 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2235 double dts, u[4], um = 0, v[4], vm = 0, w[4], wm = 0,
2239 for (
int i = 0; i < ctl->
advect; i++) {
2244 x[0] = atm->
lon[ip];
2245 x[1] = atm->
lat[ip];
2248 dts = (i == 3 ? 1.0 : 0.5) * cache->
dt[ip];
2249 x[0] = atm->
lon[ip] +
DX2DEG(dts * u[i - 1] / 1000., atm->
lat[ip]);
2250 x[1] = atm->
lat[ip] +
DY2DEG(dts * v[i - 1] / 1000.);
2251 x[2] = atm->
p[ip] + dts * w[i - 1];
2253 const double tm = atm->
time[ip] + dts;
2258 tm, x[2], x[0], x[1], &u[i], ci, cw, 1);
2260 tm, x[2], x[0], x[1], &v[i], ci, cw, 0);
2262 tm, x[2], x[0], x[1], &w[i], ci, cw, 0);
2278 k = (i == 0 ? 0.0 : 1.0);
2279 else if (ctl->
advect == 4)
2280 k = (i == 0 || i == 3 ? 1.0 / 6.0 : 2.0 / 6.0);
2287 atm->
time[ip] += cache->
dt[ip];
2288 atm->
lon[ip] +=
DX2DEG(cache->
dt[ip] * um / 1000.,
2289 (ctl->
advect == 2 ? x[1] : atm->
lat[ip]));
2290 atm->
lat[ip] +=
DY2DEG(cache->
dt[ip] * vm / 1000.);
2291 atm->
p[ip] += cache->
dt[ip] * wm;
2299 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2305 atm->
lon[ip], atm->
lat[ip],
2309 double dts, u[4], um = 0, v[4], vm = 0, zeta_dot[4],
2310 zeta_dotm = 0, x[3] = { 0, 0, 0 };
2313 for (
int i = 0; i < ctl->
advect; i++) {
2318 x[0] = atm->
lon[ip];
2319 x[1] = atm->
lat[ip];
2322 dts = (i == 3 ? 1.0 : 0.5) * cache->
dt[ip];
2323 x[0] = atm->
lon[ip] +
DX2DEG(dts * u[i - 1] / 1000., atm->
lat[ip]);
2324 x[1] = atm->
lat[ip] +
DY2DEG(dts * v[i - 1] / 1000.);
2325 x[2] = atm->
q[ctl->
qnt_zeta][ip] + dts * zeta_dot[i - 1];
2327 const double tm = atm->
time[ip] + dts;
2331 met1->
ul, tm, x[2], x[0], x[1], &u[i], ci, cw, 1);
2333 met1->
vl, tm, x[2], x[0], x[1], &v[i], ci, cw, 0);
2336 x[1], &zeta_dot[i], ci, cw, 0);
2341 k = (i == 0 ? 0.0 : 1.0);
2342 else if (ctl->
advect == 4)
2343 k = (i == 0 || i == 3 ? 1.0 / 6.0 : 2.0 / 6.0);
2346 zeta_dotm += k * zeta_dot[i];
2350 atm->
time[ip] += cache->
dt[ip];
2351 atm->
lon[ip] +=
DX2DEG(cache->
dt[ip] * um / 1000.,
2352 (ctl->
advect == 2 ? x[1] : atm->
lat[ip]));
2353 atm->
lat[ip] +=
DY2DEG(cache->
dt[ip] * vm / 1000.);
2354 atm->
q[ctl->
qnt_zeta][ip] += cache->
dt[ip] * zeta_dotm;
2363 atm->
lon[ip], atm->
lat[ip], &atm->
p[ip], ci, cw, 1);
2378#pragma omp parallel for default(shared)
2379 for (
int ip = 0; ip < atm->
np; ip++) {
2383 ERRMSG(
"Time of air parcel is out of range!");
2389 atm->
lon[ip], atm->
lat[ip], &atm->
p[ip], ci, cw, 1);
2415 "acc data present(ctl,cache,clim,met0,met1,atm)") {
2451 if (atm->
p[ip] < pbl)
2503 ERRMSG(
"Molar mass is not defined!");
2509 const int np = atm->
np;
2513 const int ngrid = nx * ny * nz;
2515 double *restrict
const z = (
double *) malloc((
size_t) nz *
sizeof(double));
2516 double *restrict
const press =
2517 (
double *) malloc((
size_t) nz *
sizeof(double));
2518 double *restrict
const mass =
2519 (
double *) calloc((
size_t) ngrid,
sizeof(double));
2520 double *restrict
const area =
2521 (
double *) malloc((
size_t) ny *
sizeof(double));
2522 double *restrict
const lon =
2523 (
double *) malloc((
size_t) nx *
sizeof(double));
2524 double *restrict
const lat =
2525 (
double *) malloc((
size_t) ny *
sizeof(double));
2527 int *restrict
const ixs = (
int *) malloc((
size_t) np *
sizeof(int));
2528 int *restrict
const iys = (
int *) malloc((
size_t) np *
sizeof(int));
2529 int *restrict
const izs = (
int *) malloc((
size_t) np *
sizeof(int));
2538#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])
2539#pragma acc data present(ctl,met0,met1,atm,ixs,iys,izs,z,press,mass,area,lon,lat)
2540#pragma acc parallel loop independent gang vector
2542#pragma omp parallel for default(shared)
2544 for (
int iz = 0; iz < nz; iz++) {
2546 press[iz] =
P(z[iz]);
2550 const double t0 = tt - 0.5 * ctl->
dt_mod;
2551 const double t1 = tt + 0.5 * ctl->
dt_mod;
2555#pragma acc parallel loop independent gang vector
2557#pragma omp parallel for default(shared)
2559 for (
int ip = 0; ip < np; ip++) {
2563 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
2564 || ixs[ip] < 0 || ixs[ip] >= nx
2565 || iys[ip] < 0 || iys[ip] >= ny || izs[ip] < 0 || izs[ip] >= nz)
2571#pragma acc parallel loop independent gang vector
2573#pragma omp parallel for default(shared)
2575 for (
int ix = 0; ix < nx; ix++)
2578#pragma acc parallel loop independent gang vector
2580#pragma omp parallel for default(shared)
2582 for (
int iy = 0; iy < ny; iy++) {
2584 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat[iy]));
2589#pragma acc parallel loop independent gang vector
2591 for (
int ip = 0; ip < np; ip++)
2594#pragma acc atomic update
2596 mass[
ARRAY_3D(ixs[ip], iys[ip], ny, izs[ip], nz)]
2597 += atm->
q[ctl->
qnt_m][ip];
2601#pragma acc parallel loop independent gang vector
2603#pragma omp parallel for default(shared)
2605 for (
int ip = 0; ip < np; ip++)
2612 lon[ixs[ip]], lat[iys[ip]], &temp, ci, cw, 1);
2615 const double m = mass[
ARRAY_3D(ixs[ip], iys[ip], ny, izs[ip], nz)];
2619 / (
RHO(press[izs[ip]], temp) * area[iys[ip]] * dz * 1e9);
2622#pragma acc exit data delete(ixs,iys,izs,z,press,mass,area,lon,lat)
2646#pragma omp parallel for default(shared)
2647 for (
int ip = 0; ip < atm->
np; ip++) {
2651 ERRMSG(
"Time of air parcel is out of range!");
2668 atm->
lon[ip], atm->
lat[ip], atm->
p[ip]));
2670 atm->
lat[ip], atm->
p[ip]));
2672 atm->
lat[ip], atm->
p[ip]));
2674 atm->
lat[ip], atm->
p[ip]));
2688 SELECT_TIMER(
"MODULE_CONVECTION",
"PHYSICS", NVTX_GPU);
2694 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2702 double pbot = ps, ptop = ps;
2719 double cape, cin, pel;
2725 if (isfinite(cape) && cape >= ctl->
conv_cape
2727 ptop = GSL_MIN(ptop, pel);
2731 if (ptop != pbot && atm->
p[ip] >= ptop) {
2736 pbot, atm->
lon[ip], atm->
lat[ip], &tbot, ci, cw, 1);
2738 ptop, atm->
lon[ip], atm->
lat[ip], &ttop, ci, cw, 1);
2739 const double rhobot = pbot / tbot;
2740 const double rhotop = ptop / ttop;
2743 const double rho = rhobot + (rhotop - rhobot) * cache->
rs[ip];
2746 atm->
p[ip] =
LIN(rhobot, pbot, rhotop, ptop, rho);
2764 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
2767 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,clim,atm)") {
2776 const double aux = exp(-cache->
dt[ip] / tdec);
2777 if (ctl->
qnt_m >= 0) {
2780 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
2781 atm->
q[ctl->
qnt_m][ip] *= aux;
2806 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2814 float umean = 0, usig = 0, vmean = 0, vsig = 0, wmean = 0, wsig = 0;
2815 for (
int i = 0; i < 2; i++)
2816 for (
int j = 0; j < 2; j++)
2817 for (
int k = 0; k < 2; k++) {
2818 umean += met0->
u[ix + i][iy + j][iz + k];
2819 usig +=
SQR(met0->
u[ix + i][iy + j][iz + k]);
2820 vmean += met0->
v[ix + i][iy + j][iz + k];
2821 vsig +=
SQR(met0->
v[ix + i][iy + j][iz + k]);
2822 wmean += met0->
w[ix + i][iy + j][iz + k];
2823 wsig +=
SQR(met0->
w[ix + i][iy + j][iz + k]);
2825 umean += met1->
u[ix + i][iy + j][iz + k];
2826 usig +=
SQR(met1->
u[ix + i][iy + j][iz + k]);
2827 vmean += met1->
v[ix + i][iy + j][iz + k];
2828 vsig +=
SQR(met1->
v[ix + i][iy + j][iz + k]);
2829 wmean += met1->
w[ix + i][iy + j][iz + k];
2830 wsig +=
SQR(met1->
w[ix + i][iy + j][iz + k]);
2832 usig = usig / 16.f -
SQR(umean / 16.f);
2833 usig = (usig > 0 ? sqrtf(usig) : 0);
2834 vsig = vsig / 16.f -
SQR(vmean / 16.f);
2835 vsig = (vsig > 0 ? sqrtf(vsig) : 0);
2836 wsig = wsig / 16.f -
SQR(wmean / 16.f);
2837 wsig = (wsig > 0 ? sqrtf(wsig) : 0);
2840 const double r = 1 - 2 * fabs(cache->
dt[ip]) / ctl->
dt_met;
2841 const double r2 = sqrt(1 - r * r);
2845 cache->
uvwp[ip][0] =
2846 (float) (r * cache->
uvwp[ip][0] +
2851 cache->
uvwp[ip][1] =
2852 (float) (r * cache->
uvwp[ip][1] +
2859 cache->
uvwp[ip][2] =
2860 (float) (r * cache->
uvwp[ip][2] +
2862 atm->
p[ip] += cache->
uvwp[ip][2] * cache->
dt[ip];
2883 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
2885 double dsigw_dz = 0.0, sig_u = 0.25, sig_w = 0.1,
2886 tau_u = 300., tau_w = 100.;
2895 if (atm->
p[ip] >= pbl) {
2898 const double p =
MIN(atm->
p[ip], ps);
2899 const double zs =
Z(ps);
2900 const double z = 1e3 * (
Z(p) - zs);
2901 const double zi = 1e3 * (
Z(pbl) - zs);
2902 const double zratio = z / zi;
2905 double ess, nss, h2o, t;
2910 const double rho =
RHO(p,
TVIRT(t, h2o));
2911 const double tau = sqrt(
SQR(ess) +
SQR(nss));
2912 const double ustar = sqrt(tau / rho);
2922 sig_u = 1e-2 + 2.0 * ustar * (1.0 - zratio);
2923 sig_w = 1e-2 + 1.3 * ustar * (1.0 - zratio);
2926 dsigw_dz = -1.3 * ustar / zi;
2929 tau_u = 0.07 * zi / sig_u * sqrt(zratio);
2930 tau_w = 0.1 * zi / sig_w * pow(zratio, 0.8);
2937 const double wstar =
2938 pow(
G0 /
THETAVIRT(p, t, h2o) * shf / (rho *
CPD) * zi, 1. / 3.);
2942 + sqrt(0.4 *
SQR(wstar) + (5.0 - 4.0 * zratio) *
SQR(ustar));
2943 sig_w = 1e-2 + sqrt(1.2 *
SQR(wstar) * (1.0 - 0.9 * zratio)
2944 * pow(zratio, 2.0 / 3.0)
2945 + (1.8 - 1.4 * zratio) *
SQR(ustar));
2948 dsigw_dz = 0.5 / sig_w / zi * (-1.4 *
SQR(ustar) +
SQR(wstar)
2950 pow(
MAX(zratio, 1e-3), -1.0 / 3.0)
2951 - 1.8 * pow(zratio, 2.0 / 3.0)));
2954 const double C0 = 3.0;
2956 (1.5 - 1.2 * pow(zratio, 1.0 / 3.0)) *
SQR(wstar) * wstar / zi
2957 +
SQR(ustar) * ustar * (1.0 - 0.8 * zratio) / (
KARMAN * z);
2958 tau_u = 2 *
SQR(sig_u) / (C0 * eps);
2959 tau_w = 2 *
SQR(sig_w) / (C0 * eps);
2964 sig_u =
MAX(sig_u, 0.25);
2965 sig_w =
MAX(sig_w, 0.1);
2966 tau_u =
MAX(tau_u, 300.);
2967 tau_w =
MAX(tau_w, 100.);
2970 const double ru = exp(-fabs(cache->
dt[ip]) / tau_u);
2971 const double ru2 = sqrt(1.0 -
SQR(ru));
2973 = (float) (cache->
uvwp[ip][0] * ru + ru2 * cache->
rs[3 * ip]);
2975 = (float) (cache->
uvwp[ip][1] * ru + ru2 * cache->
rs[3 * ip + 1]);
2977 const double rw = exp(-fabs(cache->
dt[ip]) / tau_w);
2978 const double rw2 = sqrt(1.0 -
SQR(rw));
2980 = (float) (cache->
uvwp[ip][2] * rw + rw2 * cache->
rs[3 * ip + 2]
2981 + sig_w * dsigw_dz * cache->
dt[ip]);
2988 DZ2DP(cache->
uvwp[ip][2] * cache->
dt[ip] / 1000., atm->
p[ip]);
3010 "acc data present(ctl,cache,clim,met0,met1,atm)") {
3019 const double wpbl =
pbl_weight(ctl, atm, ip, pbl, ps);
3020 const double wtrop =
tropo_weight(clim, atm, ip) * (1.0 - wpbl);
3021 const double wstrat = 1.0 - wpbl - wtrop;
3031 const double sigma = sqrt(2.0 * dx * fabs(cache->
dt[ip])) / 1000.;
3033 atm->
lat[ip] +=
DY2DEG(cache->
rs[3 * ip + 1] * sigma);
3038 const double sigma = sqrt(2.0 * dz * fabs(cache->
dt[ip])) / 1000.;
3039 atm->
p[ip] +=
DZ2DP(cache->
rs[3 * ip + 2] * sigma, atm->
p[ip]);
3058 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
3061 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
3073 const double dz = 1000. * (
Z(ps - ctl->
dry_depo_dp) -
Z(ps));
3093 const double aux = exp(-cache->
dt[ip] * v_dep / dz);
3094 if (ctl->
qnt_m >= 0) {
3097 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
3098 atm->
q[ctl->
qnt_m][ip] *= aux;
3122 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
3125 const double a = 3.12541941e-06;
3126 const double b = -5.72532259e-01;
3127 const double low = pow(1. / a, 1. / b);
3131 "acc data present(ctl,cache,ctl,met0,met1,atm)") {
3138 if (!(lwc > 0 || rwc > 0))
3149 const double k = 9.1e7 * exp(-29700. /
RI * (1. / t - 1. / 298.15));
3152 const double H_SO2 =
3153 1.3e-2 * exp(2900. * (1. / t - 1. / 298.15)) *
RI * t;
3154 const double K_1S = 1.23e-2 * exp(2.01e3 * (1. / t - 1. / 298.15));
3157 const double H_h2o2 =
3158 8.3e2 * exp(7600. * (1. / t - 1. / 298.15)) *
RI * t;
3164 cor = atm->
q[ctl->
qnt_Cx][ip] >
3165 low ? a * pow(atm->
q[ctl->
qnt_Cx][ip], b) : 1;
3167 const double h2o2 = H_h2o2
3169 * M * cor * 1000. /
AVO;
3172 const double rho_air = atm->
p[ip] / (
RI * t) *
MA / 10.;
3173 const double CWC = (lwc + rwc) * rho_air / 1e3;
3176 const double rate_coef = k * K_1S * h2o2 * H_SO2 * CWC;
3177 const double aux = exp(-cache->
dt[ip] * rate_coef);
3178 if (ctl->
qnt_m >= 0) {
3181 atm->
q[ctl->
qnt_m][ip] *= aux;
3209 for (
int ip = 0; ip < atm->
np; ip++)
3214 for (
int ip = 0; ip < atm->
np; ip++) {
3216 cache->
iso_var[ip] = atm->
p[ip] / t;
3221 for (
int ip = 0; ip < atm->
np; ip++) {
3230 LOG(1,
"Read balloon pressure data: %s", ctl->
balloon);
3234 if (!(in = fopen(ctl->
balloon,
"r")))
3235 ERRMSG(
"Cannot open file!");
3239 while (fgets(line,
LEN, in))
3240 if (sscanf(line,
"%lg %lg", &(cache->
iso_ts[cache->
iso_n]),
3243 ERRMSG(
"Too many data points!");
3246 if (cache->
iso_n < 1)
3247 ERRMSG(
"Could not read any data!");
3267 PARTICLE_LOOP(0, atm->
np, 0,
"acc data present(ctl,cache,met0,met1,atm)") {
3280 atm->
p[ip] = cache->
iso_var[ip] * t;
3286 atm->
p[ip] = 1000. * pow(cache->
iso_var[ip] / t, -1. / 0.286);
3292 atm->
p[ip] = cache->
iso_ps[0];
3319 const int nvar = NVAR, nfix = NFIX, nreact = NREACT;
3320 double rtol[1] = { 1.0e-3 };
3321 double atol[1] = { 1.0 };
3325#pragma acc data copy(rtol,atol,nvar,nfix,nreact)
3328 "acc data present(ctl,cache,clim,met0,met1,atm) ") {
3331 double var[nvar], fix[nfix], rconst[nreact];
3332 for (
int i = 0; i < nvar; i++)
3334 for (
int i = 0; i < nfix; i++)
3336 for (
int i = 0; i < nreact; i++)
3338 kpp_chem_initialize(ctl, clim, met0, met1, atm, var, fix, rconst, ip);
3343 for (
int i = 0; i < 20; i++) {
3350 Rosenbrock(var, fix, rconst, 0, ctl->
dt_kpp,
3351 atol, rtol, &FunTemplate, &JacTemplate, rpar, ipar);
3354 kpp_chem_output2atm(atm, ctl, met0, met1, var, ip);
3375 ERRMSG(
"Need T_ice and T_NAT to calculate T_STS!");
3379 "acc data present(ctl,cache,clim,met0,met1,atm)") {
3381 double ps, ts, zs, us, vs, ess, nss, shf, lsm, sst, pbl, pt, pct, pcb, cl,
3382 plcl, plfc, pel, cape, cin, o3c, pv, t, tt, u, v, w, h2o, h2ot, o3, lwc,
3383 rwc, iwc, swc, cc, z, zt;
3431 atm->
lon[ip], atm->
lat[ip], atm->
p[ip]));
3433 atm->
lat[ip], atm->
p[ip]));
3435 atm->
lat[ip], atm->
p[ip]));
3437 atm->
lat[ip], atm->
p[ip]));
3438 SET_ATM(qnt_vh, sqrt(u * u + v * v));
3457 atm->
lat[ip], atm->
p[ip])));
3475 const int np = atm->
np;
3476 int *restrict
const ixs = (
int *) malloc((
size_t) np *
sizeof(int));
3477 int *restrict
const iys = (
int *) malloc((
size_t) np *
sizeof(int));
3478 int *restrict
const izs = (
int *) malloc((
size_t) np *
sizeof(int));
3486 const double t0 = t - 0.5 * ctl->
dt_mod;
3487 const double t1 = t + 0.5 * ctl->
dt_mod;
3491#pragma acc enter data create(ixs[0:np],iys[0:np],izs[0:np])
3492#pragma acc data present(ctl,clim,atm,ixs,iys,izs)
3493#pragma acc parallel loop independent gang vector
3495#pragma omp parallel for default(shared)
3497 for (
int ip = 0; ip < np; ip++) {
3500 izs[ip] = (int) ((
Z(atm->
p[ip]) - ctl->
mixing_z0) / dz);
3501 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
3502 || ixs[ip] < 0 || ixs[ip] >= ctl->
mixing_nx
3503 || iys[ip] < 0 || iys[ip] >= ctl->
mixing_ny
3504 || izs[ip] < 0 || izs[ip] >= ctl->
mixing_nz)
3509 if (ctl->
qnt_m >= 0)
3546#pragma acc exit data delete(ixs,iys,izs)
3562 const int qnt_idx) {
3565 const int np = atm->
np;
3567 double *restrict
const cmean =
3568 (
double *) malloc((
size_t) ngrid *
sizeof(double));
3569 int *restrict
const count = (
int *) malloc((
size_t) ngrid *
sizeof(int));
3573#pragma acc enter data create(cmean[0:ngrid],count[0:ngrid])
3574#pragma acc data present(ctl,clim,atm,ixs,iys,izs,cmean,count)
3575#pragma acc parallel loop independent gang vector
3580#pragma omp parallel for
3582 for (
int i = 0; i < ngrid; i++) {
3589#pragma acc parallel loop independent gang vector
3591 for (
int ip = 0; ip < np; ip++)
3596#pragma acc atomic update
3598 cmean[idx] += atm->
q[qnt_idx][ip];
3600#pragma acc atomic update
3605#pragma acc parallel loop independent gang vector
3610#pragma omp parallel for
3612 for (
int i = 0; i < ngrid; i++)
3614 cmean[i] /= count[i];
3618#pragma acc parallel loop independent gang vector
3620#pragma omp parallel for
3622 for (
int ip = 0; ip < np; ip++)
3626 double mixparam = 1.0;
3633 atm->
q[qnt_idx][ip] +=
3636 - atm->
q[qnt_idx][ip]) * mixparam;
3641#pragma acc exit data delete(cmean,count)
3662 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
3665 const double a = 4.71572206e-08;
3666 const double b = -8.28782867e-01;
3667 const double low = pow(1. / a, 1. / b);
3671 "acc data present(ctl,cache,clim,met0,met1,atm)") {
3697 0 ? pow(298. / t, ctl->
oh_chem[1]) : 1.);
3700 0 ? pow(298. / t, ctl->
oh_chem[3]) : 1.);
3701 const double c = log10(k0 * M / ki);
3702 k = k0 * M / (1. + k0 * M / ki) * pow(0.6, 1. / (1. + c * c));
3711 low ? a * pow(atm->
q[ctl->
qnt_Cx][ip], b) : 1;
3714 const double rate_coef =
3716 atm->
lat[ip], atm->
p[ip]) * M * cor;
3717 const double aux = exp(-cache->
dt[ip] * rate_coef);
3718 if (ctl->
qnt_m >= 0) {
3721 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
3722 atm->
q[ctl->
qnt_m][ip] *= aux;
3743 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(cache,met0,met1,atm)") {
3754 while (atm->
lat[ip] < -90 || atm->
lat[ip] > 90) {
3755 if (atm->
lat[ip] > 90) {
3756 atm->
lat[ip] = 180 - atm->
lat[ip];
3757 atm->
lon[ip] += 180;
3759 if (atm->
lat[ip] < -90) {
3760 atm->
lat[ip] = -180 - atm->
lat[ip];
3761 atm->
lon[ip] += 180;
3766 while (atm->
lon[ip] < -180)
3767 atm->
lon[ip] += 360;
3768 while (atm->
lon[ip] >= 180)
3769 atm->
lon[ip] -= 360;
3772 if (atm->
p[ip] < met0->
p[met0->
np - 1]) {
3774 atm->
p[ip] = met0->
p[met0->
np - 1];
3775 }
else if (atm->
p[ip] > 300.) {
3779 if (atm->
p[ip] > ps)
3791 gsl_rng_env_setup();
3792 if (omp_get_max_threads() >
NTHREADS)
3793 ERRMSG(
"Too many threads!");
3794 for (
int i = 0; i <
NTHREADS; i++) {
3795 rng[i] = gsl_rng_alloc(gsl_rng_default);
3796 gsl_rng_set(rng[i], gsl_rng_default_seed
3797 + (
long unsigned) (ntask *
NTHREADS + i));
3802 if (curandCreateGenerator(&rng_curand, CURAND_RNG_PSEUDO_DEFAULT) !=
3803 CURAND_STATUS_SUCCESS)
3804 ERRMSG(
"Cannot create random number generator!");
3805 if (curandSetPseudoRandomGeneratorSeed(rng_curand, ntask) !=
3806 CURAND_STATUS_SUCCESS)
3807 ERRMSG(
"Cannot set seed for random number generator!");
3810 (cudaStream_t) acc_get_cuda_stream(acc_async_sync)) !=
3811 CURAND_STATUS_SUCCESS)
3812 ERRMSG(
"Cannot set stream for random number generator!");
3829#pragma omp parallel for default(shared)
3830 for (
size_t i = 0; i < n; ++i)
3831 rs[i] = gsl_rng_uniform(rng[omp_get_thread_num()]);
3835 else if (method == 1) {
3836#pragma omp parallel for default(shared)
3837 for (
size_t i = 0; i < n; ++i)
3838 rs[i] = gsl_ran_gaussian_ziggurat(rng[omp_get_thread_num()], 1.0);
3843#pragma acc update device(rs[:n])
3851 const uint64_t key = 0xc8e4fd154ce32f6d;
3855#pragma acc data present(rs)
3856#pragma acc parallel loop independent gang vector
3858#pragma omp parallel for default(shared)
3860 for (
size_t i = 0; i < n + 1; ++i) {
3861 uint64_t r, t, x, y, z;
3862 y = x = (rng_ctr + i) * key;
3865 x = (x >> 32) | (x << 32);
3867 x = (x >> 32) | (x << 32);
3869 x = (x >> 32) | (x << 32);
3871 x = (x >> 32) | (x << 32);
3872 r = t ^ ((x * x + y) >> 32);
3873 rs[i] = (double) r / (
double) UINT64_MAX;
3880#pragma acc parallel loop independent gang vector
3882#pragma omp parallel for default(shared)
3884 for (
size_t i = 0; i < n; i += 2) {
3885 const double r = sqrt(-2.0 * log(rs[i]));
3886 const double phi = 2.0 * M_PI * rs[i + 1];
3887 rs[i] = r * cosf((
float) phi);
3888 rs[i + 1] = r * sinf((
float) phi);
3896#pragma acc host_data use_device(rs)
3901 if (curandGenerateUniformDouble(rng_curand, rs, (n < 4 ? 4 : n)) !=
3902 CURAND_STATUS_SUCCESS)
3903 ERRMSG(
"Cannot create random numbers!");
3907 else if (method == 1) {
3908 if (curandGenerateNormalDouble
3909 (rng_curand, rs, (n < 4 ? 4 : n), 0.0,
3910 1.0) != CURAND_STATUS_SUCCESS)
3911 ERRMSG(
"Cannot create random numbers!");
3915 ERRMSG(
"MPTRAC was compiled without cuRAND!");
3933 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
3941 const double v_s =
sedi(atm->
p[ip], t, atm->
q[ctl->
qnt_rp][ip],
3945 atm->
p[ip] +=
DZ2DP(v_s * cache->
dt[ip] / 1000., atm->
p[ip]);
3960 const int np = atm->
np;
3961 double *restrict
const a = (
double *) malloc((
size_t) np *
sizeof(double));
3962 int *restrict
const p = (
int *) malloc((
size_t) np *
sizeof(int));
3965#pragma acc enter data create(a[0:np],p[0:np])
3966#pragma acc data present(ctl,met0,atm,a,p)
3971#pragma acc parallel loop independent gang vector
3973#pragma omp parallel for default(shared)
3975 for (
int ip = 0; ip < np; ip++) {
3985#pragma acc host_data use_device(a, p)
3990 ERRMSG(
"MPTRAC was compiled without Thrust library!");
3998 for (
int iq = 0; iq < ctl->
nq; iq++)
4003#pragma acc exit data delete(a,p)
4017 double *restrict
const help =
4018 (
double *) malloc((
size_t) np *
sizeof(double));
4022#pragma acc enter data create(help[0:np])
4023#pragma acc data present(a,p,help)
4024#pragma acc parallel loop independent gang vector
4026#pragma omp parallel for default(shared)
4028 for (
int ip = 0; ip < np; ip++)
4029 help[ip] = a[p[ip]];
4031#pragma acc parallel loop independent gang vector
4033#pragma omp parallel for default(shared)
4035 for (
int ip = 0; ip < np; ip++)
4040#pragma acc exit data delete(help)
4057 const double latmin = gsl_stats_min(met0->
lat, 1, (
size_t) met0->
ny),
4058 latmax = gsl_stats_max(met0->
lat, 1, (
size_t) met0->
ny);
4061 (fabs(met0->
lon[met0->
nx - 1] - met0->
lon[0] - 360.0) >= 0.01);
4064 PARTICLE_LOOP(0, atm->
np, 0,
"acc data present(ctl,cache,met0,atm)") {
4070 cache->
dt[ip] = t - atm->
time[ip];
4072 cache->
dt[ip] = 0.0;
4075 if (local && (atm->
lon[ip] <= met0->
lon[0]
4076 || atm->
lon[ip] >= met0->
lon[met0->
nx - 1]
4077 || atm->
lat[ip] <= latmin || atm->
lat[ip] >= latmax))
4078 cache->
dt[ip] = 0.0;
4093 ctl->
t_start = gsl_stats_min(atm->
time, 1, (
size_t) atm->
np);
4095 ctl->
t_stop = gsl_stats_max(atm->
time, 1, (
size_t) atm->
np);
4097 ctl->
t_start = gsl_stats_max(atm->
time, 1, (
size_t) atm->
np);
4099 ctl->
t_stop = gsl_stats_min(atm->
time, 1, (
size_t) atm->
np);
4104 ERRMSG(
"Nothing to do! Check T_STOP and DIRECTION!");
4124 SELECT_TIMER(
"MODULE_TRACERCHEM",
"PHYSICS", NVTX_GPU);
4128 "acc data present(ctl,cache,clim,met0,met1,atm)") {
4151 const double K_o1d =
ARRHENIUS(3.30e-10, 0, t) * o1d * M;
4153 atm->
p[ip], sza, o3c);
4154 atm->
q[ctl->
qnt_Cccl4][ip] *= exp(-cache->
dt[ip] * (K_hv + K_o1d));
4159 const double K_o1d =
ARRHENIUS(2.30e-10, 0, t) * o1d * M;
4161 atm->
p[ip], sza, o3c);
4162 atm->
q[ctl->
qnt_Cccl3f][ip] *= exp(-cache->
dt[ip] * (K_hv + K_o1d));
4167 const double K_o1d =
ARRHENIUS(1.40e-10, -25, t) * o1d * M;
4169 atm->
p[ip], sza, o3c);
4170 atm->
q[ctl->
qnt_Cccl2f2][ip] *= exp(-cache->
dt[ip] * (K_hv + K_o1d));
4175 const double K_o1d =
ARRHENIUS(1.19e-10, -20, t) * o1d * M;
4177 atm->
p[ip], sza, o3c);
4178 atm->
q[ctl->
qnt_Cn2o][ip] *= exp(-cache->
dt[ip] * (K_hv + K_o1d));
4197 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
4200 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,cache,met0,met1,atm)") {
4206 if (!isfinite(pct) || atm->
p[ip] <= pct)
4222 double lwc, rwc, iwc, swc;
4227 const int inside = (lwc > 0 || rwc > 0 || iwc > 0 || swc > 0);
4241 else if (t <= 238.15)
4261 const double K_1 = 1.23e-2 * exp(2.01e3 * (1. / t - 1. / 298.15));
4262 const double K_2 = 6e-8 * exp(1.12e3 * (1. / t - 1. / 298.15));
4263 h *= (1. + K_1 / H_ion + K_1 * K_2 /
SQR(H_ion));
4267 const double dz = 1e3 * (
Z(pct) -
Z(pcb));
4270 lambda = h *
RI * t * Is / 3.6e6 / dz * eta;
4296 const double dz = 1e3 * (
Z(pct) -
Z(pcb));
4299 lambda = h *
RI * t * Is / 3.6e6 / dz * eta;
4304 const double aux = exp(-cache->
dt[ip] * lambda);
4305 if (ctl->
qnt_m >= 0) {
4308 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
4309 atm->
q[ctl->
qnt_m][ip] *= aux;
4333 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
4335 if (acc_get_num_devices(acc_device_nvidia) <= 0)
4336 ERRMSG(
"Not running on a GPU device!");
4337 acc_set_device_num(rank % acc_get_num_devices(acc_device_nvidia),
4339 acc_device_t device_type = acc_get_device_type();
4340 acc_init(device_type);
4354 SELECT_TIMER(
"CREATE_DATA_REGION",
"MEMORY", NVTX_GPU);
4355 ctl_t *ctlup = *ctl;
4358 met_t *met0up = *met0;
4359 met_t *met1up = *met1;
4360 atm_t *atmup = *atm;
4361#pragma acc enter data create(ctlup[:1], cacheup[:1], climup[:1], met0up[:1], met1up[:1], atmup[:1])
4377 SELECT_TIMER(
"DELETE_DATA_REGION",
"MEMORY", NVTX_GPU);
4378#pragma acc exit data delete (ctl, cache, clim, met0, met1, atm)
4407 get_met(ctl, clim, t, met0, met1);
4499 ERRMSG(
"Code was compiled without KPP!");
4523 const double hno3) {
4526 const double h2o_help =
MAX(h2o, 0.1e-6);
4529 const double p_hno3 = hno3 * p / 1.333224;
4530 const double p_h2o = h2o_help * p / 1.333224;
4531 const double a = 0.009179 - 0.00088 * log10(p_h2o);
4532 const double b = (38.9855 - log10(p_hno3) - 2.7836 * log10(p_h2o)) / a;
4533 const double c = -11397.0 / a;
4534 double tnat = (-b + sqrt(b * b - 4. * c)) / 2.;
4535 double x2 = (-b - sqrt(b * b - 4. * c)) / 2.;
4553 const double p0 = pbl;
4556 if (atm->
p[ip] > p0)
4558 else if (atm->
p[ip] < p1)
4561 return LIN(p0, 1.0, p1, 0.0, atm->
p[ip]);
4567 const char *filename,
4580 LOG(1,
"Read atmospheric data: %s", filename);
4600 ERRMSG(
"Atmospheric data type not supported!");
4608 ERRMSG(
"Can not read any data!");
4612 LOG(2,
"Number of particles: %d", atm->
np);
4613 gsl_stats_minmax(&mini, &maxi, atm->
time, 1, (
size_t) atm->
np);
4614 LOG(2,
"Time range: %.2f ... %.2f s", mini, maxi);
4615 gsl_stats_minmax(&mini, &maxi, atm->
p, 1, (
size_t) atm->
np);
4616 LOG(2,
"Altitude range: %g ... %g km",
Z(maxi),
Z(mini));
4617 LOG(2,
"Pressure range: %g ... %g hPa", maxi, mini);
4618 gsl_stats_minmax(&mini, &maxi, atm->
lon, 1, (
size_t) atm->
np);
4619 LOG(2,
"Longitude range: %g ... %g deg", mini, maxi);
4620 gsl_stats_minmax(&mini, &maxi, atm->
lat, 1, (
size_t) atm->
np);
4621 LOG(2,
"Latitude range: %g ... %g deg", mini, maxi);
4622 for (
int iq = 0; iq < ctl->
nq; iq++) {
4624 sprintf(msg,
"Quantity %s range: %s ... %s %s",
4627 gsl_stats_minmax(&mini, &maxi, atm->
q[iq], 1, (
size_t) atm->
np);
4628 LOG(2, msg, mini, maxi);
4638 const char *filename,
4644 if (!(in = fopen(filename,
"r"))) {
4645 WARN(
"Cannot open file!");
4651 while (fgets(line,
LEN, in)) {
4655 TOK(line, tok,
"%lg", atm->
time[atm->
np]);
4656 TOK(NULL, tok,
"%lg", atm->
p[atm->
np]);
4657 TOK(NULL, tok,
"%lg", atm->
lon[atm->
np]);
4658 TOK(NULL, tok,
"%lg", atm->
lat[atm->
np]);
4659 for (
int iq = 0; iq < ctl->
nq; iq++)
4660 TOK(NULL, tok,
"%lg", atm->
q[iq][atm->
np]);
4663 atm->
p[atm->
np] =
P(atm->
p[atm->
np]);
4666 if ((++atm->
np) >
NP)
4667 ERRMSG(
"Too many data points!");
4680 const char *filename,
4686 if (!(in = fopen(filename,
"r")))
4691 FREAD(&version,
int,
4695 ERRMSG(
"Wrong version of binary data!");
4713 for (
int iq = 0; iq < ctl->
nq; iq++)
4714 FREAD(atm->
q[iq],
double,
4724 ERRMSG(
"Error while reading binary data!");
4736 const char *filename,
4743 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR)
4750 if (nc_inq_varid(ncid,
"TIME_INIT", &varid) == NC_NOERR) {
4751 NC(nc_get_var_double(ncid, varid, atm->
time));
4753 WARN(
"TIME_INIT not found use time instead!");
4756 for (
int ip = 0; ip < atm->
np; ip++) {
4757 atm->
time[ip] = time_init;
4769 if (nc_inq_varid(ncid,
"PRESS_INIT", &varid) == NC_NOERR) {
4770 NC(nc_get_var_double(ncid, varid, atm->
p));
4772 WARN(
"PRESS_INIT not found use PRESS instead!");
4773 nc_inq_varid(ncid,
"PRESS", &varid);
4774 NC(nc_get_var_double(ncid, varid, atm->
p));
4792 const char *filename,
4799 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR)
4812 for (
int iq = 0; iq < ctl->
nq; iq++)
4885 const char *filename,
4891 LOG(1,
"Read photolysis rates: %s", filename);
4894 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
4895 WARN(
"Photolysis rate data are missing!");
4902 if (photo->
p[0] < photo->
p[1])
4903 ERRMSG(
"Pressure data are not descending!");
4908 if (photo->
o3c[0] > photo->
o3c[1])
4909 ERRMSG(
"Total column ozone data are not ascending!");
4914 if (photo->
sza[0] > photo->
sza[1])
4915 ERRMSG(
"Solar zenith angle data are not ascending!");
4932 LOG(2,
"Number of pressure levels: %d", photo->
np);
4933 LOG(2,
"Altitude levels: %g, %g ... %g km",
4934 Z(photo->
p[0]),
Z(photo->
p[1]),
Z(photo->
p[photo->
np - 1]));
4935 LOG(2,
"Pressure levels: %g, %g ... %g hPa",
4936 photo->
p[0], photo->
p[1], photo->
p[photo->
np - 1]);
4937 LOG(2,
"Number of solar zenith angles: %d", photo->
nsza);
4938 LOG(2,
"Solar zenith angles: %g, %g ... %g deg",
4941 LOG(2,
"Number of total column ozone values: %d", photo->
no3c);
4942 LOG(2,
"Total column ozone: %g, %g ... %g DU",
4944 LOG(2,
"N2O photolysis rate: %g, %g ... %g s**-1",
4945 photo->
n2o[0][0][0], photo->
n2o[1][0][0],
4946 photo->
n2o[photo->
np - 1][photo->
nsza - 1][photo->
no3c - 1]);
4947 LOG(2,
"CCl4 photolysis rate: %g, %g ... %g s**-1",
4948 photo->
ccl4[0][0][0], photo->
ccl4[1][0][0],
4950 LOG(2,
"CFC-11 photolysis rate: %g, %g ... %g s**-1",
4951 photo->
ccl3f[0][0][0], photo->
ccl3f[1][0][0],
4953 LOG(2,
"CFC-12 photolysis rate: %g, %g ... %g s**-1",
4956 LOG(2,
"O2 photolysis rate: %g, %g ... %g s**-1",
4957 photo->
o2[0][0][0], photo->
o2[1][0][0],
4958 photo->
o2[photo->
np - 1][photo->
nsza - 1][photo->
no3c - 1]);
4959 LOG(2,
"O3 -> O(1D) photolysis rate: %g, %g ... %g s**-1",
4960 photo->
o3_1[0][0][0], photo->
o3_1[1][0][0],
4962 LOG(2,
"O3 -> O(3P) photolysis rate: %g, %g ... %g s**-1",
4963 photo->
o3_2[0][0][0], photo->
o3_2[1][0][0],
4965 LOG(2,
"H2O2 photolysis rate: %g, %g ... %g s**-1",
4966 photo->
h2o2[0][0][0], photo->
h2o2[1][0][0],
4968 LOG(2,
"H2O photolysis rate: %g, %g ... %g s**-1",
4969 photo->
h2o[0][0][0], photo->
h2o[1][0][0],
4970 photo->
h2o[photo->
np - 1][photo->
nsza - 1][photo->
no3c - 1]);
4977 const char *varname,
4991 for (
int ip = 0; ip < photo->
np; ip++)
4992 for (
int is = 0; is < photo->
nsza; is++)
4993 for (
int io = 0; io < photo->
no3c; io++)
5004 const char *filename,
5008 LOG(1,
"Read climatological time series: %s", filename);
5012 if (!(in = fopen(filename,
"r"))) {
5013 WARN(
"Cannot open file!");
5020 while (fgets(line,
LEN, in))
5021 if (sscanf(line,
"%lg %lg", &ts->
time[nh], &ts->
vmr[nh]) == 2) {
5024 ts->
time[nh] = (ts->
time[nh] - 2000.0) * 365.25 * 86400.;
5027 if (nh > 0 && ts->
time[nh] <= ts->
time[nh - 1])
5028 ERRMSG(
"Time series must be ascending!");
5032 ERRMSG(
"Too many data points!");
5041 ERRMSG(
"Not enough data points!");
5044 LOG(2,
"Number of time steps: %d", ts->
ntime);
5045 LOG(2,
"Time steps: %.2f, %.2f ... %.2f s", ts->
time[0], ts->
time[1],
5047 LOG(2,
"Volume mixing ratio range: %g ... %g ppv",
5048 gsl_stats_min(ts->
vmr, 1, (
size_t) nh), gsl_stats_max(ts->
vmr, 1,
5058 const char *filename,
5059 const char *varname,
5062 int ncid, varid, it, iy, iz, iz2, nt;
5064 double *help, varmin = 1e99, varmax = -1e99;
5067 LOG(1,
"Read %s data: %s", varname, filename);
5070 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
5071 WARN(
"%s climatology data are missing!", varname);
5078 if (zm->
p[0] < zm->
p[1])
5079 ERRMSG(
"Pressure data are not descending!");
5084 if (zm->
lat[0] > zm->
lat[1])
5085 ERRMSG(
"Latitude data are not ascending!");
5089 zm->
time[0] = 1209600.00;
5090 zm->
time[1] = 3888000.00;
5091 zm->
time[2] = 6393600.00;
5092 zm->
time[3] = 9072000.00;
5093 zm->
time[4] = 11664000.00;
5094 zm->
time[5] = 14342400.00;
5095 zm->
time[6] = 16934400.00;
5096 zm->
time[7] = 19612800.00;
5097 zm->
time[8] = 22291200.00;
5098 zm->
time[9] = 24883200.00;
5099 zm->
time[10] = 27561600.00;
5100 zm->
time[11] = 30153600.00;
5109 for (it = 0; it < zm->
ntime; it++)
5110 for (iz = 0; iz < zm->
np; iz++)
5111 for (iy = 0; iy < zm->
nlat; iy++)
5116 for (it = 0; it < zm->
ntime; it++)
5117 for (iy = 0; iy < zm->
nlat; iy++)
5118 for (iz = 0; iz < zm->
np; iz++) {
5119 if (zm->
vmr[it][iz][iy] < 0) {
5120 for (iz2 = 0; iz2 < zm->
np; iz2++)
5121 if (zm->
vmr[it][iz2][iy] >= 0) {
5122 zm->
vmr[it][iz][iy] = zm->
vmr[it][iz2][iy];
5125 for (iz2 = zm->
np - 1; iz2 >= 0; iz2--)
5126 if (zm->
vmr[it][iz2][iy] >= 0) {
5127 zm->
vmr[it][iz][iy] = zm->
vmr[it][iz2][iy];
5131 varmin =
MIN(varmin, zm->
vmr[it][iz][iy]);
5132 varmax =
MAX(varmax, zm->
vmr[it][iz][iy]);
5139 LOG(2,
"Number of time steps: %d", zm->
ntime);
5140 LOG(2,
"Time steps: %.2f, %.2f ... %.2f s",
5142 LOG(2,
"Number of pressure levels: %d", zm->
np);
5143 LOG(2,
"Altitude levels: %g, %g ... %g km",
5144 Z(zm->
p[0]),
Z(zm->
p[1]),
Z(zm->
p[zm->
np - 1]));
5145 LOG(2,
"Pressure levels: %g, %g ... %g hPa", zm->
p[0],
5146 zm->
p[1], zm->
p[zm->
np - 1]);
5147 LOG(2,
"Number of latitudes: %d", zm->
nlat);
5148 LOG(2,
"Latitudes: %g, %g ... %g deg",
5150 LOG(2,
"%s volume mixing ratio range: %g ... %g ppv", varname, varmin,
5157 const char *filename,
5166 LOG(1,
"\nMassive-Parallel Trajectory Calculations (MPTRAC)\n"
5167 "(executable: %s | version: %s | compiled: %s, %s)\n",
5168 argv[0], VERSION, __DATE__, __TIME__);
5264 ctl->
nq = (int)
scan_ctl(filename, argc, argv,
"NQ", -1,
"0", NULL);
5266 ERRMSG(
"Too many quantities!");
5267 for (
int iq = 0; iq < ctl->
nq; iq++) {
5273 scan_ctl(filename, argc, argv,
"QNT_FORMAT", iq,
"%g",
5275 if (strcasecmp(ctl->
qnt_name[iq],
"aoa") == 0)
5279 SET_QNT(qnt_idx,
"idx",
"particle index",
"-")
5280 SET_QNT(qnt_ens,
"ens",
"ensemble index",
"-")
5281 SET_QNT(qnt_stat,
"stat",
"station flag",
"-")
5282 SET_QNT(qnt_m,
"m",
"mass",
"kg")
5283 SET_QNT(qnt_vmr,
"vmr",
"volume mixing ratio",
"ppv")
5284 SET_QNT(qnt_rp,
"rp",
"particle radius",
"microns")
5285 SET_QNT(qnt_rhop,
"rhop",
"particle density",
"kg/m^3")
5286 SET_QNT(qnt_ps,
"ps",
"surface pressure",
"hPa")
5287 SET_QNT(qnt_ts,
"ts",
"surface temperature",
"K")
5288 SET_QNT(qnt_zs,
"zs",
"surface height",
"km")
5289 SET_QNT(qnt_us,
"us",
"surface zonal wind",
"m/s")
5290 SET_QNT(qnt_vs,
"vs",
"surface meridional wind",
"m/s")
5291 SET_QNT(qnt_ess,
"ess",
"eastward turbulent surface stress",
"N/m^2")
5292 SET_QNT(qnt_nss,
"nss",
"northward turbulent surface stress",
"N/m^2")
5293 SET_QNT(qnt_shf,
"shf",
"surface sensible heat flux",
"W/m^2")
5294 SET_QNT(qnt_lsm,
"lsm",
"land-sea mask",
"1")
5295 SET_QNT(qnt_sst,
"sst",
"sea surface temperature",
"K")
5296 SET_QNT(qnt_pbl,
"pbl",
"planetary boundary layer",
"hPa")
5297 SET_QNT(qnt_pt,
"pt",
"tropopause pressure",
"hPa")
5298 SET_QNT(qnt_tt,
"tt",
"tropopause temperature",
"K")
5299 SET_QNT(qnt_zt,
"zt",
"tropopause geopotential height",
"km")
5300 SET_QNT(qnt_h2ot,
"h2ot",
"tropopause water vapor",
"ppv")
5301 SET_QNT(qnt_zg,
"zg",
"geopotential height",
"km")
5302 SET_QNT(qnt_p,
"p",
"pressure",
"hPa")
5303 SET_QNT(qnt_t,
"t",
"temperature",
"K")
5304 SET_QNT(qnt_rho,
"rho",
"air density",
"kg/m^3")
5305 SET_QNT(qnt_u,
"u",
"zonal wind",
"m/s")
5306 SET_QNT(qnt_v,
"v",
"meridional wind",
"m/s")
5307 SET_QNT(qnt_w,
"w",
"vertical velocity",
"hPa/s")
5308 SET_QNT(qnt_h2o,
"h2o",
"water vapor",
"ppv")
5309 SET_QNT(qnt_o3,
"o3",
"ozone",
"ppv")
5310 SET_QNT(qnt_lwc,
"lwc",
"cloud liquid water content",
"kg/kg")
5311 SET_QNT(qnt_rwc,
"rwc",
"cloud rain water content",
"kg/kg")
5312 SET_QNT(qnt_iwc,
"iwc",
"cloud ice water content",
"kg/kg")
5313 SET_QNT(qnt_swc,
"iwc",
"cloud snow water content",
"kg/kg")
5314 SET_QNT(qnt_cc,
"cc",
"cloud cover",
"1")
5315 SET_QNT(qnt_pct,
"pct",
"cloud top pressure",
"hPa")
5316 SET_QNT(qnt_pcb,
"pcb",
"cloud bottom pressure",
"hPa")
5317 SET_QNT(qnt_cl,
"cl",
"total column cloud water",
"kg/m^2")
5318 SET_QNT(qnt_plcl,
"plcl",
"lifted condensation level",
"hPa")
5319 SET_QNT(qnt_plfc,
"plfc",
"level of free convection",
"hPa")
5320 SET_QNT(qnt_pel,
"pel",
"equilibrium level",
"hPa")
5321 SET_QNT(qnt_cape,
"cape",
"convective available potential energy",
5323 SET_QNT(qnt_cin,
"cin",
"convective inhibition",
"J/kg")
5324 SET_QNT(qnt_o3c,
"o3c",
"total column ozone",
"DU")
5325 SET_QNT(qnt_hno3,
"hno3",
"nitric acid",
"ppv")
5326 SET_QNT(qnt_oh,
"oh",
"hydroxyl radical",
"ppv")
5327 SET_QNT(qnt_h2o2,
"h2o2",
"hydrogen peroxide",
"ppv")
5328 SET_QNT(qnt_ho2,
"ho2",
"hydroperoxyl radical",
"ppv")
5329 SET_QNT(qnt_o1d,
"o1d",
"atomic oxygen",
"ppv")
5330 SET_QNT(qnt_mloss_oh,
"mloss_oh",
"mass loss due to OH chemistry",
"kg")
5331 SET_QNT(qnt_mloss_h2o2,
"mloss_h2o2",
"mass loss due to H2O2 chemistry",
5333 SET_QNT(qnt_mloss_kpp,
"mloss_kpp",
"mass loss due to kpp chemistry",
5335 SET_QNT(qnt_mloss_wet,
"mloss_wet",
"mass loss due to wet deposition",
5337 SET_QNT(qnt_mloss_dry,
"mloss_dry",
"mass loss due to dry deposition",
5339 SET_QNT(qnt_mloss_decay,
"mloss_decay",
5340 "mass loss due to exponential decay",
"kg")
5341 SET_QNT(qnt_loss_rate,
"loss_rate",
"total loss rate",
"s^-1")
5342 SET_QNT(qnt_psat,
"psat",
"saturation pressure over water",
"hPa")
5343 SET_QNT(qnt_psice,
"psice",
"saturation pressure over ice",
"hPa")
5344 SET_QNT(qnt_pw,
"pw",
"partial water vapor pressure",
"hPa")
5345 SET_QNT(qnt_sh,
"sh",
"specific humidity",
"kg/kg")
5346 SET_QNT(qnt_rh,
"rh",
"relative humidity",
"%%")
5347 SET_QNT(qnt_rhice,
"rhice",
"relative humidity over ice",
"%%")
5348 SET_QNT(qnt_theta,
"theta",
"potential temperature",
"K")
5349 SET_QNT(qnt_zeta,
"zeta",
"zeta coordinate",
"K")
5350 SET_QNT(qnt_zeta_d,
"zeta_d",
"diagnosed zeta coordinate",
"K")
5351 SET_QNT(qnt_tvirt,
"tvirt",
"virtual temperature",
"K")
5352 SET_QNT(qnt_lapse,
"lapse",
"temperature lapse rate",
"K/km")
5353 SET_QNT(qnt_vh,
"vh",
"horizontal velocity",
"m/s")
5354 SET_QNT(qnt_vz,
"vz",
"vertical velocity",
"m/s")
5355 SET_QNT(qnt_pv,
"pv",
"potential vorticity",
"PVU")
5356 SET_QNT(qnt_tdew,
"tdew",
"dew point temperature",
"K")
5357 SET_QNT(qnt_tice,
"tice",
"frost point temperature",
"K")
5358 SET_QNT(qnt_tsts,
"tsts",
"STS existence temperature",
"K")
5359 SET_QNT(qnt_tnat,
"tnat",
"NAT existence temperature",
"K")
5360 SET_QNT(qnt_Cx,
"Cx",
"Trace species x volume mixing ratio",
"ppv")
5361 SET_QNT(qnt_Ch2o,
"Ch2o",
"H2O volume mixing ratio",
"ppv")
5362 SET_QNT(qnt_Co3,
"Co3",
"O3 volume mixing ratio",
"ppv")
5363 SET_QNT(qnt_Cco,
"Cco",
"CO volume mixing ratio",
"ppv")
5364 SET_QNT(qnt_Coh,
"Coh",
"HO volume mixing ratio",
"ppv")
5365 SET_QNT(qnt_Ch,
"Ch",
"H radical volume mixing ratio",
"ppv")
5366 SET_QNT(qnt_Cho2,
"Cho2",
"HO2 volume mixing ratio",
"ppv")
5367 SET_QNT(qnt_Ch2o2,
"Ch2o2",
"H2O2 volume mixing ratio",
"ppv")
5368 SET_QNT(qnt_Co1d,
"Co1d",
"O(1D) volume mixing ratio",
"ppv")
5369 SET_QNT(qnt_Co3p,
"Co3p",
"O(3P) radical volume mixing ratio",
"ppv")
5370 SET_QNT(qnt_Cccl4,
"Cccl4",
"CCl4 (CFC-10) volume mixing ratio",
"ppv")
5371 SET_QNT(qnt_Cccl3f,
"Cccl3f",
"CCl3F (CFC-11) volume mixing ratio",
5373 SET_QNT(qnt_Cccl2f2,
"Cccl2f2",
"CCl2F2 (CFC-12) volume mixing ratio",
5375 SET_QNT(qnt_Cn2o,
"Cn2o",
"N2O volume mixing ratio",
"ppv")
5376 SET_QNT(qnt_Csf6,
"Csf6",
"SF6 volume mixing ratio",
"ppv")
5377 SET_QNT(qnt_aoa,
"aoa",
"age of air",
"s")
5383 (int)
scan_ctl(filename, argc, argv,
"ADVECT_VERT_COORD", -1,
"0", NULL);
5385 ERRMSG(
"Set advect_vert_coord to 0, 1, or 2!");
5387 ERRMSG(
"Please add zeta to your quantities for diabatic calculations!");
5389 (int)
scan_ctl(filename, argc, argv,
"MET_VERT_COORD", -1,
"0", NULL);
5392 (
"Using ADVECT_VERT_COORD = 2 requires meteo data on model levels!");
5396 (int)
scan_ctl(filename, argc, argv,
"DIRECTION", -1,
"1", NULL);
5398 ERRMSG(
"Set DIRECTION to -1 or 1!");
5399 ctl->
t_stop =
scan_ctl(filename, argc, argv,
"T_STOP", -1,
"1e100", NULL);
5400 ctl->
dt_mod =
scan_ctl(filename, argc, argv,
"DT_MOD", -1,
"180", NULL);
5404 ctl->
dt_met =
scan_ctl(filename, argc, argv,
"DT_MET", -1,
"3600", NULL);
5406 (int)
scan_ctl(filename, argc, argv,
"MET_CONVENTION", -1,
"0", NULL);
5408 (int)
scan_ctl(filename, argc, argv,
"MET_TYPE", -1,
"0", NULL);
5411 (
"Please use meteorological files in netcdf format for diabatic calculations.");
5413 (int)
scan_ctl(filename, argc, argv,
"MET_CLAMS", -1,
"0", NULL);
5415 (int)
scan_ctl(filename, argc, argv,
"MET_NC_SCALE", -1,
"1", NULL);
5417 (int)
scan_ctl(filename, argc, argv,
"MET_NC_LEVEL", -1,
"0", NULL);
5419 (int)
scan_ctl(filename, argc, argv,
"MET_NC_QUANT", -1,
"0", NULL);
5421 (int)
scan_ctl(filename, argc, argv,
"MET_ZFP_PREC", -1,
"8", NULL);
5423 scan_ctl(filename, argc, argv,
"MET_ZFP_TOL_T", -1,
"5.0", NULL);
5425 scan_ctl(filename, argc, argv,
"MET_ZFP_TOL_Z", -1,
"0.5", NULL);
5427 (int)
scan_ctl(filename, argc, argv,
"MET_CMS_BATCH", -1,
"-1", NULL);
5429 (int)
scan_ctl(filename, argc, argv,
"MET_CMS_HEUR", -1,
"1", NULL);
5431 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_Z", -1,
"1.0", NULL);
5433 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_T", -1,
"0.05", NULL);
5435 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_U", -1,
"0.05", NULL);
5437 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_V", -1,
"0.05", NULL);
5439 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_W", -1,
"1.0", NULL);
5441 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_PV", -1,
"1.0", NULL);
5443 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_H2O", -1,
"1.0", NULL);
5445 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_O3", -1,
"1.0", NULL);
5447 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_LWC", -1,
"1.0", NULL);
5449 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_RWC", -1,
"1.0", NULL);
5451 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_IWC", -1,
"1.0", NULL);
5453 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_SWC", -1,
"1.0", NULL);
5455 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_CC", -1,
"1.0", NULL);
5456 ctl->
met_dx = (int)
scan_ctl(filename, argc, argv,
"MET_DX", -1,
"1", NULL);
5457 ctl->
met_dy = (int)
scan_ctl(filename, argc, argv,
"MET_DY", -1,
"1", NULL);
5458 ctl->
met_dp = (int)
scan_ctl(filename, argc, argv,
"MET_DP", -1,
"1", NULL);
5460 ERRMSG(
"MET_DX, MET_DY, and MET_DP need to be greater than zero!");
5461 ctl->
met_sx = (int)
scan_ctl(filename, argc, argv,
"MET_SX", -1,
"1", NULL);
5462 ctl->
met_sy = (int)
scan_ctl(filename, argc, argv,
"MET_SY", -1,
"1", NULL);
5463 ctl->
met_sp = (int)
scan_ctl(filename, argc, argv,
"MET_SP", -1,
"1", NULL);
5465 ERRMSG(
"MET_SX, MET_SY, and MET_SP need to be greater than zero!");
5467 scan_ctl(filename, argc, argv,
"MET_DETREND", -1,
"-999", NULL);
5468 ctl->
met_np = (int)
scan_ctl(filename, argc, argv,
"MET_NP", -1,
"0", NULL);
5470 ERRMSG(
"Too many levels!");
5472 (int)
scan_ctl(filename, argc, argv,
"MET_PRESS_LEVEL_DEF", -1,
"-1",
5478 for (
int ip = 0; ip < ctl->
met_np; ip++)
5480 scan_ctl(filename, argc, argv,
"MET_P", ip,
"", NULL);
5484 (int)
scan_ctl(filename, argc, argv,
"MET_GEOPOT_SX", -1,
"-1", NULL);
5486 (int)
scan_ctl(filename, argc, argv,
"MET_GEOPOT_SY", -1,
"-1", NULL);
5488 (int)
scan_ctl(filename, argc, argv,
"MET_RELHUM", -1,
"0", NULL);
5490 (int)
scan_ctl(filename, argc, argv,
"MET_CAPE", -1,
"1", NULL);
5492 ERRMSG(
"Set MET_CAPE to 0 or 1!");
5494 (int)
scan_ctl(filename, argc, argv,
"MET_PBL", -1,
"3", NULL);
5496 ERRMSG(
"Set MET_PBL to 0 ... 3!");
5498 scan_ctl(filename, argc, argv,
"MET_PBL_MIN", -1,
"0.1", NULL);
5500 scan_ctl(filename, argc, argv,
"MET_PBL_MAX", -1,
"5.0", NULL);
5502 (int)
scan_ctl(filename, argc, argv,
"MET_TROPO", -1,
"3", NULL);
5504 ERRMSG(
"Set MET_TROPO to 0 ... 5!");
5506 scan_ctl(filename, argc, argv,
"MET_TROPO_PV", -1,
"3.5", NULL);
5508 scan_ctl(filename, argc, argv,
"MET_TROPO_THETA", -1,
"380", NULL);
5510 (int)
scan_ctl(filename, argc, argv,
"MET_TROPO_SPLINE", -1,
"1", NULL);
5512 scan_ctl(filename, argc, argv,
"MET_DT_OUT", -1,
"0.1", NULL);
5514 (int)
scan_ctl(filename, argc, argv,
"MET_CACHE", -1,
"0", NULL);
5516 (int)
scan_ctl(filename, argc, argv,
"MET_MPI_SHARE", -1,
"0", NULL);
5519 ctl->
sort_dt =
scan_ctl(filename, argc, argv,
"SORT_DT", -1,
"-999", NULL);
5523 (int)
scan_ctl(filename, argc, argv,
"ISOSURF", -1,
"0", NULL);
5528 (int)
scan_ctl(filename, argc, argv,
"RNG_TYPE", -1,
"1", NULL);
5530 ERRMSG(
"Set RNG_TYPE to 0, 1, or 2!");
5533 ctl->
advect = (int)
scan_ctl(filename, argc, argv,
"ADVECT", -1,
"2", NULL);
5536 ERRMSG(
"Set ADVECT to 0, 1, 2, or 4!");
5540 = (int)
scan_ctl(filename, argc, argv,
"DIFFUSION", -1,
"0", NULL);
5542 ERRMSG(
"Set DIFFUSION to 0, 1 or 2!");
5544 scan_ctl(filename, argc, argv,
"TURB_DX_PBL", -1,
"50", NULL);
5546 scan_ctl(filename, argc, argv,
"TURB_DX_TROP", -1,
"50", NULL);
5548 scan_ctl(filename, argc, argv,
"TURB_DX_STRAT", -1,
"0", NULL);
5550 scan_ctl(filename, argc, argv,
"TURB_DZ_PBL", -1,
"0", NULL);
5552 scan_ctl(filename, argc, argv,
"TURB_DZ_TROP", -1,
"0", NULL);
5554 scan_ctl(filename, argc, argv,
"TURB_DZ_STRAT", -1,
"0.1", NULL);
5556 scan_ctl(filename, argc, argv,
"TURB_MESOX", -1,
"0.16", NULL);
5558 scan_ctl(filename, argc, argv,
"TURB_MESOZ", -1,
"0.16", NULL);
5562 = (int)
scan_ctl(filename, argc, argv,
"CONV_MIX_PBL", -1,
"0", NULL);
5564 =
scan_ctl(filename, argc, argv,
"CONV_PBL_TRANS", -1,
"0", NULL);
5566 =
scan_ctl(filename, argc, argv,
"CONV_CAPE", -1,
"-999", NULL);
5568 =
scan_ctl(filename, argc, argv,
"CONV_CIN", -1,
"-999", NULL);
5569 ctl->
conv_dt =
scan_ctl(filename, argc, argv,
"CONV_DT", -1,
"-999", NULL);
5573 scan_ctl(filename, argc, argv,
"BOUND_MASS", -1,
"-999", NULL);
5575 scan_ctl(filename, argc, argv,
"BOUND_MASS_TREND", -1,
"0", NULL);
5577 scan_ctl(filename, argc, argv,
"BOUND_VMR", -1,
"-999", NULL);
5579 scan_ctl(filename, argc, argv,
"BOUND_VMR_TREND", -1,
"0", NULL);
5581 scan_ctl(filename, argc, argv,
"BOUND_LAT0", -1,
"-999", NULL);
5583 scan_ctl(filename, argc, argv,
"BOUND_LAT1", -1,
"-999", NULL);
5585 scan_ctl(filename, argc, argv,
"BOUND_P0", -1,
"-999", NULL);
5587 scan_ctl(filename, argc, argv,
"BOUND_P1", -1,
"-999", NULL);
5589 scan_ctl(filename, argc, argv,
"BOUND_DPS", -1,
"-999", NULL);
5591 scan_ctl(filename, argc, argv,
"BOUND_DZS", -1,
"-999", NULL);
5593 scan_ctl(filename, argc, argv,
"BOUND_ZETAS", -1,
"-999", NULL);
5595 (int)
scan_ctl(filename, argc, argv,
"BOUND_PBL", -1,
"0", NULL);
5599 if (strcasecmp(ctl->
species,
"CF2Cl2") == 0) {
5603 }
else if (strcasecmp(ctl->
species,
"CFCl3") == 0) {
5607 }
else if (strcasecmp(ctl->
species,
"CH4") == 0) {
5614 }
else if (strcasecmp(ctl->
species,
"CO") == 0) {
5623 }
else if (strcasecmp(ctl->
species,
"CO2") == 0) {
5627 }
else if (strcasecmp(ctl->
species,
"H2O") == 0) {
5629 }
else if (strcasecmp(ctl->
species,
"N2O") == 0) {
5633 }
else if (strcasecmp(ctl->
species,
"NH3") == 0) {
5640 }
else if (strcasecmp(ctl->
species,
"HNO3") == 0) {
5644 }
else if (strcasecmp(ctl->
species,
"NO") == 0) {
5653 }
else if (strcasecmp(ctl->
species,
"NO2") == 0) {
5662 }
else if (strcasecmp(ctl->
species,
"O3") == 0) {
5669 }
else if (strcasecmp(ctl->
species,
"SF6") == 0) {
5673 }
else if (strcasecmp(ctl->
species,
"SO2") == 0) {
5686 sprintf(defstr,
"%g", ctl->
molmass);
5687 ctl->
molmass =
scan_ctl(filename, argc, argv,
"MOLMASS", -1, defstr, NULL);
5692 (int)
scan_ctl(filename, argc, argv,
"OH_CHEM_REACTION", -1, defstr,
5694 for (
int ip = 0; ip < 4; ip++) {
5695 sprintf(defstr,
"%g", ctl->
oh_chem[ip]);
5697 scan_ctl(filename, argc, argv,
"OH_CHEM", ip, defstr, NULL);
5700 scan_ctl(filename, argc, argv,
"OH_CHEM_BETA", -1,
"0", NULL);
5704 (int)
scan_ctl(filename, argc, argv,
"H2O2_CHEM_REACTION", -1,
"0", NULL);
5708 (int)
scan_ctl(filename, argc, argv,
"KPP_CHEM", -1,
"0", NULL);
5709 ctl->
dt_kpp =
scan_ctl(filename, argc, argv,
"DT_KPP", -1,
"1800", NULL);
5713 (int)
scan_ctl(filename, argc, argv,
"TRACER_CHEM", -1,
"0", NULL);
5716 for (
int ip = 0; ip < 2; ip++) {
5719 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_H", ip, defstr, NULL);
5721 for (
int ip = 0; ip < 1; ip++) {
5724 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_H", ip, defstr, NULL);
5727 scan_ctl(filename, argc, argv,
"WET_DEPO_SO2_PH", -1,
"0", NULL);
5729 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_A", -1,
"0", NULL);
5731 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_B", -1,
"0", NULL);
5733 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_A", -1,
"0", NULL);
5735 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_B", -1,
"0", NULL);
5737 scan_ctl(filename, argc, argv,
"WET_DEPO_PRE", 0,
"0.5", NULL);
5739 scan_ctl(filename, argc, argv,
"WET_DEPO_PRE", 1,
"0.36", NULL);
5741 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_RET_RATIO", -1,
"1", NULL);
5743 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_RET_RATIO", -1,
"1", NULL);
5747 scan_ctl(filename, argc, argv,
"DRY_DEPO_VDEP", -1,
"0", NULL);
5749 scan_ctl(filename, argc, argv,
"DRY_DEPO_DP", -1,
"30", NULL);
5752 scan_ctl(filename, argc, argv,
"CLIM_PHOTO", -1,
5753 "../../data/clams_photolysis_rates.nc", ctl->
clim_photo);
5754 scan_ctl(filename, argc, argv,
"CLIM_HNO3_FILENAME", -1,
5756 scan_ctl(filename, argc, argv,
"CLIM_OH_FILENAME", -1,
5758 scan_ctl(filename, argc, argv,
"CLIM_H2O2_FILENAME", -1,
5760 scan_ctl(filename, argc, argv,
"CLIM_HO2_FILENAME", -1,
5762 scan_ctl(filename, argc, argv,
"CLIM_O1D_FILENAME", -1,
5764 scan_ctl(filename, argc, argv,
"CLIM_CCL4_TIMESERIES", -1,
5766 scan_ctl(filename, argc, argv,
"CLIM_CCL3F_TIMESERIES", -1,
5768 scan_ctl(filename, argc, argv,
"CLIM_CCL2F2_TIMESERIES", -1,
5770 scan_ctl(filename, argc, argv,
"CLIM_N2O_TIMESERIES", -1,
5772 scan_ctl(filename, argc, argv,
"CLIM_SF6_TIMESERIES", -1,
5777 scan_ctl(filename, argc, argv,
"MIXING_DT", -1,
"3600.", NULL);
5779 scan_ctl(filename, argc, argv,
"MIXING_TROP", -1,
"-999", NULL);
5781 scan_ctl(filename, argc, argv,
"MIXING_STRAT", -1,
"-999", NULL);
5783 scan_ctl(filename, argc, argv,
"MIXING_Z0", -1,
"-5", NULL);
5785 scan_ctl(filename, argc, argv,
"MIXING_Z1", -1,
"85", NULL);
5787 (int)
scan_ctl(filename, argc, argv,
"MIXING_NZ", -1,
"90", NULL);
5789 scan_ctl(filename, argc, argv,
"MIXING_LON0", -1,
"-180", NULL);
5791 scan_ctl(filename, argc, argv,
"MIXING_LON1", -1,
"180", NULL);
5793 (int)
scan_ctl(filename, argc, argv,
"MIXING_NX", -1,
"360", NULL);
5795 scan_ctl(filename, argc, argv,
"MIXING_LAT0", -1,
"-90", NULL);
5797 scan_ctl(filename, argc, argv,
"MIXING_LAT1", -1,
"90", NULL);
5799 (int)
scan_ctl(filename, argc, argv,
"MIXING_NY", -1,
"180", NULL);
5803 scan_ctl(filename, argc, argv,
"CHEMGRID_Z0", -1,
"-5", NULL);
5805 scan_ctl(filename, argc, argv,
"CHEMGRID_Z1", -1,
"85", NULL);
5807 (int)
scan_ctl(filename, argc, argv,
"CHEMGRID_NZ", -1,
"90", NULL);
5809 scan_ctl(filename, argc, argv,
"CHEMGRID_LON0", -1,
"-180", NULL);
5811 scan_ctl(filename, argc, argv,
"CHEMGRID_LON1", -1,
"180", NULL);
5813 (int)
scan_ctl(filename, argc, argv,
"CHEMGRID_NX", -1,
"360", NULL);
5815 scan_ctl(filename, argc, argv,
"CHEMGRID_LAT0", -1,
"-90", NULL);
5817 scan_ctl(filename, argc, argv,
"CHEMGRID_LAT1", -1,
"90", NULL);
5819 (int)
scan_ctl(filename, argc, argv,
"CHEMGRID_NY", -1,
"180", NULL);
5824 =
scan_ctl(filename, argc, argv,
"TDEC_STRAT", -1,
"0", NULL);
5827 ctl->
psc_h2o =
scan_ctl(filename, argc, argv,
"PSC_H2O", -1,
"4e-6", NULL);
5829 scan_ctl(filename, argc, argv,
"PSC_HNO3", -1,
"9e-9", NULL);
5835 scan_ctl(filename, argc, argv,
"ATM_DT_OUT", -1,
"86400", NULL);
5837 (int)
scan_ctl(filename, argc, argv,
"ATM_FILTER", -1,
"0", NULL);
5839 (int)
scan_ctl(filename, argc, argv,
"ATM_STRIDE", -1,
"1", NULL);
5841 (int)
scan_ctl(filename, argc, argv,
"ATM_TYPE", -1,
"0", NULL);
5843 (int)
scan_ctl(filename, argc, argv,
"ATM_TYPE_OUT", -1,
"-1", NULL);
5847 (int)
scan_ctl(filename, argc, argv,
"ATM_NC_LEVEL", -1,
"0", NULL);
5848 for (
int iq = 0; iq < ctl->
nq; iq++)
5850 (
int)
scan_ctl(filename, argc, argv,
"ATM_NC_QUANT", iq,
"0", NULL);
5852 (int)
scan_ctl(filename, argc, argv,
"OBS_TYPE", -1,
"0", NULL);
5858 scan_ctl(filename, argc, argv,
"CSI_DT_OUT", -1,
"86400", NULL);
5861 scan_ctl(filename, argc, argv,
"CSI_OBSMIN", -1,
"0", NULL);
5863 scan_ctl(filename, argc, argv,
"CSI_MODMIN", -1,
"0", NULL);
5864 ctl->
csi_z0 =
scan_ctl(filename, argc, argv,
"CSI_Z0", -1,
"-5", NULL);
5865 ctl->
csi_z1 =
scan_ctl(filename, argc, argv,
"CSI_Z1", -1,
"85", NULL);
5866 ctl->
csi_nz = (int)
scan_ctl(filename, argc, argv,
"CSI_NZ", -1,
"1", NULL);
5868 scan_ctl(filename, argc, argv,
"CSI_LON0", -1,
"-180", NULL);
5869 ctl->
csi_lon1 =
scan_ctl(filename, argc, argv,
"CSI_LON1", -1,
"180", NULL);
5871 (int)
scan_ctl(filename, argc, argv,
"CSI_NX", -1,
"360", NULL);
5872 ctl->
csi_lat0 =
scan_ctl(filename, argc, argv,
"CSI_LAT0", -1,
"-90", NULL);
5873 ctl->
csi_lat1 =
scan_ctl(filename, argc, argv,
"CSI_LAT1", -1,
"90", NULL);
5875 (int)
scan_ctl(filename, argc, argv,
"CSI_NY", -1,
"180", NULL);
5880 scan_ctl(filename, argc, argv,
"ENS_DT_OUT", -1,
"86400", NULL);
5883 scan_ctl(filename, argc, argv,
"GRID_BASENAME", -1,
"-",
5888 scan_ctl(filename, argc, argv,
"GRID_DT_OUT", -1,
"86400", NULL);
5890 (int)
scan_ctl(filename, argc, argv,
"GRID_SPARSE", -1,
"0", NULL);
5892 (int)
scan_ctl(filename, argc, argv,
"GRID_NC_LEVEL", -1,
"0", NULL);
5893 for (
int iq = 0; iq < ctl->
nq; iq++)
5895 (
int)
scan_ctl(filename, argc, argv,
"GRID_NC_QUANT", iq,
"0", NULL);
5897 (int)
scan_ctl(filename, argc, argv,
"GRID_STDDEV", -1,
"0", NULL);
5898 ctl->
grid_z0 =
scan_ctl(filename, argc, argv,
"GRID_Z0", -1,
"-5", NULL);
5899 ctl->
grid_z1 =
scan_ctl(filename, argc, argv,
"GRID_Z1", -1,
"85", NULL);
5901 (int)
scan_ctl(filename, argc, argv,
"GRID_NZ", -1,
"1", NULL);
5903 scan_ctl(filename, argc, argv,
"GRID_LON0", -1,
"-180", NULL);
5905 scan_ctl(filename, argc, argv,
"GRID_LON1", -1,
"180", NULL);
5907 (int)
scan_ctl(filename, argc, argv,
"GRID_NX", -1,
"360", NULL);
5909 scan_ctl(filename, argc, argv,
"GRID_LAT0", -1,
"-90", NULL);
5911 scan_ctl(filename, argc, argv,
"GRID_LAT1", -1,
"90", NULL);
5913 (int)
scan_ctl(filename, argc, argv,
"GRID_NY", -1,
"180", NULL);
5915 (int)
scan_ctl(filename, argc, argv,
"GRID_TYPE", -1,
"0", NULL);
5918 scan_ctl(filename, argc, argv,
"PROF_BASENAME", -1,
"-",
5921 ctl->
prof_z0 =
scan_ctl(filename, argc, argv,
"PROF_Z0", -1,
"0", NULL);
5922 ctl->
prof_z1 =
scan_ctl(filename, argc, argv,
"PROF_Z1", -1,
"60", NULL);
5924 (int)
scan_ctl(filename, argc, argv,
"PROF_NZ", -1,
"60", NULL);
5926 scan_ctl(filename, argc, argv,
"PROF_LON0", -1,
"-180", NULL);
5928 scan_ctl(filename, argc, argv,
"PROF_LON1", -1,
"180", NULL);
5930 (int)
scan_ctl(filename, argc, argv,
"PROF_NX", -1,
"360", NULL);
5932 scan_ctl(filename, argc, argv,
"PROF_LAT0", -1,
"-90", NULL);
5934 scan_ctl(filename, argc, argv,
"PROF_LAT1", -1,
"90", NULL);
5936 (int)
scan_ctl(filename, argc, argv,
"PROF_NY", -1,
"180", NULL);
5939 scan_ctl(filename, argc, argv,
"SAMPLE_BASENAME", -1,
"-",
5941 scan_ctl(filename, argc, argv,
"SAMPLE_KERNEL", -1,
"-",
5943 scan_ctl(filename, argc, argv,
"SAMPLE_OBSFILE", -1,
"-",
5946 scan_ctl(filename, argc, argv,
"SAMPLE_DX", -1,
"50", NULL);
5948 scan_ctl(filename, argc, argv,
"SAMPLE_DZ", -1,
"-999", NULL);
5951 scan_ctl(filename, argc, argv,
"STAT_BASENAME", -1,
"-",
5955 ctl->
stat_r =
scan_ctl(filename, argc, argv,
"STAT_R", -1,
"50", NULL);
5957 scan_ctl(filename, argc, argv,
"STAT_T0", -1,
"-1e100", NULL);
5958 ctl->
stat_t1 =
scan_ctl(filename, argc, argv,
"STAT_T1", -1,
"1e100", NULL);
5963 scan_ctl(filename, argc, argv,
"VTK_DT_OUT", -1,
"86400", NULL);
5965 (int)
scan_ctl(filename, argc, argv,
"VTK_STRIDE", -1,
"1", NULL);
5967 scan_ctl(filename, argc, argv,
"VTK_SCALE", -1,
"1.0", NULL);
5969 scan_ctl(filename, argc, argv,
"VTK_OFFSET", -1,
"0.0", NULL);
5971 (int)
scan_ctl(filename, argc, argv,
"VTK_SPHERE", -1,
"0", NULL);
5977 const char *filename,
5983 LOG(1,
"Read kernel function: %s", filename);
5987 if (!(in = fopen(filename,
"r")))
5988 ERRMSG(
"Cannot open file!");
5993 while (fgets(line,
LEN, in))
5994 if (sscanf(line,
"%lg %lg", &kz[n], &kw[n]) == 2) {
5995 if (n > 0 && kz[n] < kz[n - 1])
5996 ERRMSG(
"Height levels must be ascending!");
5998 ERRMSG(
"Too many height levels!");
6007 ERRMSG(
"Not enough height levels!");
6010 const double kmax = gsl_stats_max(kw, 1, (
size_t) n);
6011 for (
int iz = 0; iz < n; iz++)
6018 const char *filename,
6024 LOG(1,
"Read meteo data: %s", filename);
6030 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
6050 ERRMSG(
"MET_TYPE not implemented!");
6059 LOG(2,
"Broadcast data on rank %d...", rank);
6073 const char *filename,
6081 int year, mon, day, hour, min, sec;
6087 if (!(in = fopen(filename,
"r"))) {
6088 WARN(
"Cannot open file!");
6094 FREAD(&met_type,
int,
6098 ERRMSG(
"Wrong MET_TYPE of binary data!");
6102 FREAD(&version,
int,
6106 ERRMSG(
"Wrong version of binary data!");
6112 jsec2time(met->
time, &year, &mon, &day, &hour, &min, &sec, &r);
6113 LOG(2,
"Time: %.2f (%d-%02d-%02d, %02d:%02d UTC)",
6114 met->
time, year, mon, day, hour, min);
6115 if (year < 1900 || year > 2100 || mon < 1 || mon > 12
6116 || day < 1 || day > 31 || hour < 0 || hour > 23)
6117 ERRMSG(
"Error while reading time!");
6123 LOG(2,
"Number of longitudes: %d", met->
nx);
6124 if (met->
nx < 2 || met->
nx >
EX)
6125 ERRMSG(
"Number of longitudes out of range!");
6130 LOG(2,
"Number of latitudes: %d", met->
ny);
6131 if (met->
ny < 2 || met->
ny >
EY)
6132 ERRMSG(
"Number of latitudes out of range!");
6137 LOG(2,
"Number of levels: %d", met->
np);
6138 if (met->
np < 2 || met->
np >
EP)
6139 ERRMSG(
"Number of levels out of range!");
6145 LOG(2,
"Longitudes: %g, %g ... %g deg",
6151 LOG(2,
"Latitudes: %g, %g ... %g deg",
6157 LOG(2,
"Altitude levels: %g, %g ... %g km",
6158 Z(met->
p[0]),
Z(met->
p[1]),
Z(met->
p[met->
np - 1]));
6159 LOG(2,
"Pressure levels: %g, %g ... %g hPa",
6160 met->
p[0], met->
p[1], met->
p[met->
np - 1]);
6209 ERRMSG(
"Error while reading binary data!");
6224 const char *varname) {
6233 LOG(2,
"Read 2-D variable: %s (uncompressed)", varname);
6235 (
size_t) (met->
nx * met->
ny),
6239 for (
int ix = 0; ix < met->
nx; ix++)
6240 for (
int iy = 0; iy < met->
ny; iy++)
6241 var[ix][iy] = help[
ARRAY_2D(ix, iy, met->
ny)];
6254 const char *varname,
6255 const float bound_min,
6256 const float bound_max) {
6266 LOG(2,
"Read 3-D variable: %s (uncompressed)", varname);
6268 (
size_t) (met->
nx * met->
ny * met->
np),
6275 (
size_t) met->
np, 1, in);
6281 FREAD(&precision,
int,
6286 FREAD(&tolerance,
double,
6293 ERRMSG(
"MPTRAC was compiled without zfp compression!");
6303 ERRMSG(
"MPTRAC was compiled without zstd compression!");
6311 (
size_t) met->
np, 1, in);
6313 ERRMSG(
"MPTRAC was compiled without cmultiscale compression!");
6318#pragma omp parallel for default(shared) collapse(2)
6319 for (
int ix = 0; ix < met->
nx; ix++)
6320 for (
int iy = 0; iy < met->
ny; iy++)
6321 for (
int ip = 0; ip < met->
np; ip++) {
6322 var[ix][iy][ip] = help[
ARRAY_3D(ix, iy, met->
ny, ip, met->
np)];
6323 if (var[ix][iy][ip] < bound_min)
6324 var[ix][iy][ip] = bound_min;
6325 else if (var[ix][iy][ip] > bound_max)
6326 var[ix][iy][ip] = bound_max;
6346 LOG(2,
"Calculate CAPE...");
6349 const double pfac = 1.01439, dz0 =
RI /
MA /
G0 * log(pfac);
6352#pragma omp parallel for default(shared) collapse(2)
6353 for (
int ix = 0; ix < met->
nx; ix++)
6354 for (
int iy = 0; iy < met->
ny; iy++) {
6358 double h2o = 0, t, theta = 0;
6359 double pbot =
MIN(met->
ps[ix][iy], met->
p[0]);
6360 double ptop = pbot - 50.;
6361 for (
int ip = 0; ip < met->
np; ip++) {
6362 if (met->
p[ip] <= pbot) {
6363 theta +=
THETA(met->
p[ip], met->
t[ix][iy][ip]);
6364 h2o += met->
h2o[ix][iy][ip];
6367 if (met->
p[ip] < ptop && n > 0)
6374 met->
plcl[ix][iy] = NAN;
6375 met->
plfc[ix][iy] = NAN;
6376 met->
pel[ix][iy] = NAN;
6377 met->
cape[ix][iy] = NAN;
6378 met->
cin[ix][iy] = NAN;
6384 pbot = met->
ps[ix][iy];
6386 met->
plcl[ix][iy] = (float) (0.5 * (pbot + ptop));
6387 t = theta / pow(1000. / met->
plcl[ix][iy], 0.286);
6388 if (
RH(met->
plcl[ix][iy], t, h2o) > 100.)
6389 ptop = met->
plcl[ix][iy];
6391 pbot = met->
plcl[ix][iy];
6392 }
while (pbot - ptop > 0.1);
6396 double dcape, dz, h2o_env, t_env;
6397 double p = met->
ps[ix][iy];
6398 met->
cape[ix][iy] = met->
cin[ix][iy] = 0;
6400 dz = dz0 *
TVIRT(t, h2o);
6402 t = theta / pow(1000. / p, 0.286);
6406 &h2o_env, ci, cw, 0);
6407 dcape = 1e3 *
G0 * (
TVIRT(t, h2o) -
TVIRT(t_env, h2o_env)) /
6408 TVIRT(t_env, h2o_env) * dz;
6410 met->
cin[ix][iy] += fabsf((
float) dcape);
6411 }
while (p > met->
plcl[ix][iy]);
6416 p = met->
plcl[ix][iy];
6417 t = theta / pow(1000. / p, 0.286);
6420 dz = dz0 *
TVIRT(t, h2o);
6423 double psat =
PSAT(t);
6424 h2o = psat / (p - (1. -
EPS) * psat);
6428 &h2o_env, ci, cw, 0);
6429 double dcape_old = dcape;
6430 dcape = 1e3 *
G0 * (
TVIRT(t, h2o) -
TVIRT(t_env, h2o_env)) /
6431 TVIRT(t_env, h2o_env) * dz;
6433 met->
cape[ix][iy] += (float) dcape;
6434 if (!isfinite(met->
plfc[ix][iy]))
6435 met->
plfc[ix][iy] = (
float) p;
6436 }
else if (dcape_old > 0)
6437 met->
pel[ix][iy] = (float) p;
6438 if (dcape < 0 && !isfinite(met->
plfc[ix][iy]))
6439 met->
cin[ix][iy] += fabsf((
float) dcape);
6443 if (!isfinite(met->
plfc[ix][iy]))
6444 met->
cin[ix][iy] = NAN;
6455 LOG(2,
"Calculate cloud data...");
6458 const double ccmin = 0.01, cwmin = 1e-6;
6461#pragma omp parallel for default(shared) collapse(2)
6462 for (
int ix = 0; ix < met->
nx; ix++)
6463 for (
int iy = 0; iy < met->
ny; iy++) {
6466 met->
pct[ix][iy] = NAN;
6467 met->
pcb[ix][iy] = NAN;
6468 met->
cl[ix][iy] = 0;
6471 for (
int ip = 0; ip < met->
np - 1; ip++) {
6474 if (met->
p[ip] > met->
ps[ix][iy] || met->
p[ip] <
P(20.))
6478 if (met->
cc[ix][iy][ip] > ccmin
6479 && (met->
iwc[ix][iy][ip] > cwmin
6480 || met->
rwc[ix][iy][ip] > cwmin
6481 || met->
lwc[ix][iy][ip] > cwmin
6482 || met->
swc[ix][iy][ip] > cwmin)) {
6486 = (float) (0.5 * (met->
p[ip] + (
float) met->
p[ip + 1]));
6489 if (!isfinite(met->
pcb[ix][iy]))
6491 = (
float) (0.5 * (met->
p[ip] + met->
p[
MAX(ip - 1, 0)]));
6495 met->
cl[ix][iy] += (float)
6496 (0.5 * (met->
lwc[ix][iy][ip] + met->
lwc[ix][iy][ip + 1]
6497 + met->
rwc[ix][iy][ip] + met->
rwc[ix][iy][ip + 1]
6498 + met->
iwc[ix][iy][ip] + met->
iwc[ix][iy][ip + 1]
6499 + met->
swc[ix][iy][ip] + met->
swc[ix][iy][ip + 1])
6500 * 100. * (met->
p[ip] - met->
p[ip + 1]) /
G0);
6518 SELECT_TIMER(
"READ_MET_DETREND",
"METPROC", NVTX_READ);
6519 LOG(2,
"Detrend meteo data...");
6526 const double tssq = 2. *
SQR(sigma);
6529 int sy = (int) (3. *
DY2DEG(sigma) / fabs(met->
lat[1] - met->
lat[0]));
6533#pragma omp parallel for default(shared) collapse(2)
6534 for (
int ix = 0; ix < met->
nx; ix++) {
6535 for (
int iy = 0; iy < met->
ny; iy++) {
6543 (int) (3. *
DX2DEG(sigma, met->
lat[iy]) /
6544 fabs(met->
lon[1] - met->
lon[0]));
6549 for (
int ip = 0; ip < met->
np; ip++) {
6550 help->
t[ix][iy][ip] = 0;
6551 help->
u[ix][iy][ip] = 0;
6552 help->
v[ix][iy][ip] = 0;
6553 help->
w[ix][iy][ip] = 0;
6557 for (
int ix2 = ix - sx; ix2 <= ix + sx; ix2++) {
6561 else if (ix3 >= met->
nx)
6563 for (
int iy2 =
MAX(iy - sy, 0);
6564 iy2 <=
MIN(iy + sy, met->
ny - 1); iy2++) {
6571 const float w = (float) exp(-
DIST2(x0, x1) / tssq);
6575 for (
int ip = 0; ip < met->
np; ip++) {
6576 help->
t[ix][iy][ip] += w * met->
t[ix3][iy2][ip];
6577 help->
u[ix][iy][ip] += w * met->
u[ix3][iy2][ip];
6578 help->
v[ix][iy][ip] += w * met->
v[ix3][iy2][ip];
6579 help->
w[ix][iy][ip] += w * met->
w[ix3][iy2][ip];
6585 for (
int ip = 0; ip < met->
np; ip++) {
6586 help->
t[ix][iy][ip] /= wsum;
6587 help->
u[ix][iy][ip] /= wsum;
6588 help->
v[ix][iy][ip] /= wsum;
6589 help->
w[ix][iy][ip] /= wsum;
6595#pragma omp parallel for default(shared) collapse(3)
6596 for (
int ix = 0; ix < met->
nx; ix++)
6597 for (
int iy = 0; iy < met->
ny; iy++)
6598 for (
int ip = 0; ip < met->
np; ip++) {
6599 met->
t[ix][iy][ip] -= help->
t[ix][iy][ip];
6600 met->
u[ix][iy][ip] -= help->
u[ix][iy][ip];
6601 met->
v[ix][iy][ip] -= help->
v[ix][iy][ip];
6602 met->
w[ix][iy][ip] -= help->
w[ix][iy][ip];
6615 SELECT_TIMER(
"READ_MET_EXTRAPOLATE",
"METPROC", NVTX_READ);
6616 LOG(2,
"Extrapolate meteo data...");
6619#pragma omp parallel for default(shared) collapse(2)
6620 for (
int ix = 0; ix < met->
nx; ix++)
6621 for (
int iy = 0; iy < met->
ny; iy++) {
6625 for (ip0 = met->
np - 1; ip0 >= 0; ip0--)
6626 if (!isfinite(met->
t[ix][iy][ip0])
6627 || !isfinite(met->
u[ix][iy][ip0])
6628 || !isfinite(met->
v[ix][iy][ip0])
6629 || !isfinite(met->
w[ix][iy][ip0]))
6633 for (
int ip = ip0; ip >= 0; ip--) {
6634 met->
t[ix][iy][ip] = met->
t[ix][iy][ip + 1];
6635 met->
u[ix][iy][ip] = met->
u[ix][iy][ip + 1];
6636 met->
v[ix][iy][ip] = met->
v[ix][iy][ip + 1];
6637 met->
w[ix][iy][ip] = met->
w[ix][iy][ip + 1];
6638 met->
h2o[ix][iy][ip] = met->
h2o[ix][iy][ip + 1];
6639 met->
o3[ix][iy][ip] = met->
o3[ix][iy][ip + 1];
6640 met->
lwc[ix][iy][ip] = met->
lwc[ix][iy][ip + 1];
6641 met->
rwc[ix][iy][ip] = met->
rwc[ix][iy][ip + 1];
6642 met->
iwc[ix][iy][ip] = met->
iwc[ix][iy][ip + 1];
6643 met->
swc[ix][iy][ip] = met->
swc[ix][iy][ip + 1];
6644 met->
cc[ix][iy][ip] = met->
cc[ix][iy][ip + 1];
6663 LOG(2,
"Calculate geopotential heights...");
6670#pragma omp parallel for default(shared)
6671 for (
int ip = 0; ip < met->
np; ip++)
6672 logp[ip] = log(met->
p[ip]);
6675#pragma omp parallel for default(shared) collapse(2)
6676 for (
int ix = 0; ix < met->
nx; ix++)
6677 for (
int iy = 0; iy < met->
ny; iy++) {
6680 const double zs = met->
zs[ix][iy];
6681 const double lnps = log(met->
ps[ix][iy]);
6685 const double ts =
LIN(met->
p[ip0], met->
t[ix][iy][ip0], met->
p[ip0 + 1],
6686 met->
t[ix][iy][ip0 + 1], met->
ps[ix][iy]);
6688 LIN(met->
p[ip0], met->
h2o[ix][iy][ip0], met->
p[ip0 + 1],
6689 met->
h2o[ix][iy][ip0 + 1], met->
ps[ix][iy]);
6692 met->
z[ix][iy][ip0 + 1]
6694 ZDIFF(lnps, ts, h2os, logp[ip0 + 1],
6695 met->
t[ix][iy][ip0 + 1], met->
h2o[ix][iy][ip0 + 1]));
6696 for (
int ip = ip0 + 2; ip < met->
np; ip++)
6698 = (
float) (met->
z[ix][iy][ip - 1] +
6699 ZDIFF(logp[ip - 1], met->
t[ix][iy][ip - 1],
6700 met->
h2o[ix][iy][ip - 1], logp[ip],
6701 met->
t[ix][iy][ip], met->
h2o[ix][iy][ip]));
6706 ZDIFF(lnps, ts, h2os, logp[ip0],
6707 met->
t[ix][iy][ip0], met->
h2o[ix][iy][ip0]));
6708 for (
int ip = ip0 - 1; ip >= 0; ip--)
6710 = (
float) (met->
z[ix][iy][ip + 1] +
6711 ZDIFF(logp[ip + 1], met->
t[ix][iy][ip + 1],
6712 met->
h2o[ix][iy][ip + 1], logp[ip],
6713 met->
t[ix][iy][ip], met->
h2o[ix][iy][ip]));
6717 if (dx == 0 || dy == 0)
6721 if (dx < 0 || dy < 0) {
6722 if (fabs(met->
lon[1] - met->
lon[0]) < 0.5) {
6732 float ws[dx + 1][dy + 1];
6733#pragma omp parallel for default(shared) collapse(2)
6734 for (
int ix = 0; ix <= dx; ix++)
6735 for (
int iy = 0; iy < dy; iy++)
6736 ws[ix][iy] = (1.0f - (
float) ix / (float) dx)
6737 * (1.0f - (float) iy / (
float) dy);
6740#pragma omp parallel for default(shared) collapse(3)
6741 for (
int ix = 0; ix < met->
nx; ix++)
6742 for (
int iy = 0; iy < met->
ny; iy++)
6743 for (
int ip = 0; ip < met->
np; ip++)
6744 help[
ARRAY_3D(ip, ix, met->
nx, iy, met->
ny)] = met->
z[ix][iy][ip];
6747#pragma omp parallel for default(shared) collapse(3)
6748 for (
int ip = 0; ip < met->
np; ip++)
6749 for (
int ix = 0; ix < met->
nx; ix++)
6750 for (
int iy = 0; iy < met->
ny; iy++) {
6751 float res = 0, wsum = 0;
6752 int iy0 =
MAX(iy - dy + 1, 0);
6753 int iy1 =
MIN(iy + dy - 1, met->
ny - 1);
6754 for (
int ix2 = ix - dx + 1; ix2 <= ix + dx - 1; ++ix2) {
6758 else if (ix3 >= met->
nx)
6760 for (
int iy2 = iy0; iy2 <= iy1; ++iy2)
6761 if (isfinite(help[
ARRAY_3D(ip, ix3, met->
nx, iy2, met->
ny)])) {
6762 float w = ws[abs(ix - ix2)][abs(iy - iy2)];
6763 res += w * help[
ARRAY_3D(ip, ix3, met->
nx, iy2, met->
ny)];
6768 met->
z[ix][iy][ip] = res / wsum;
6770 met->
z[ix][iy][ip] = NAN;
6780 const char *filename,
6785 char levname[
LEN], tstr[10];
6787 double rtime = 0, r, r2;
6789 int varid, year2, mon2, day2, hour2, min2, sec2,
6790 year, mon, day, hour, min, sec;
6796 LOG(2,
"Read meteo grid information...");
6805 jsec2time(met->
time, &year, &mon, &day, &hour, &min, &sec, &r);
6806 if (nc_inq_varid(ncid,
"time", &varid) == NC_NOERR) {
6807 NC(nc_get_var_double(ncid, varid, &rtime));
6808 if (fabs(year * 10000. + mon * 100. + day + hour / 24. - rtime) > 1.0)
6809 WARN(
"Time information in meteo file does not match filename!");
6811 WARN(
"Time information in meteo file is missing!");
6822 sprintf(tstr,
"19%.2s", &filename[strlen(filename) - 11]);
6824 sprintf(tstr,
"20%.2s", &filename[strlen(filename) - 11]);
6826 sprintf(tstr,
"%.2s", &filename[strlen(filename) - 9]);
6828 sprintf(tstr,
"%.2s", &filename[strlen(filename) - 7]);
6830 sprintf(tstr,
"%.2s", &filename[strlen(filename) - 5]);
6836 if (year < 1900 || year > 2100 || mon < 1 || mon > 12
6837 || day < 1 || day > 31 || hour < 0 || hour > 23)
6838 ERRMSG(
"Cannot read time from filename!");
6839 jsec2time(met->
time, &year2, &mon2, &day2, &hour2, &min2, &sec2, &r2);
6840 LOG(2,
"Time: %.2f (%d-%02d-%02d, %02d:%02d UTC)",
6841 met->
time, year2, mon2, day2, hour2, min2);
6845 LOG(2,
"Number of longitudes: %d", met->
nx);
6848 LOG(2,
"Number of latitudes: %d", met->
ny);
6851 sprintf(levname,
"lev");
6852 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR)
6853 sprintf(levname,
"plev");
6854 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR)
6855 sprintf(levname,
"hybrid");
6859 sprintf(levname,
"lev_2");
6860 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR) {
6861 sprintf(levname,
"plev");
6862 NC(nc_inq_dimid(ncid, levname, &dimid2));
6864 NC(nc_inq_dimlen(ncid, dimid2, &np));
6867 LOG(2,
"Number of levels: %d", met->
np);
6868 if (met->
np < 2 || met->
np >
EP)
6869 ERRMSG(
"Number of levels out of range!");
6873 LOG(2,
"Longitudes: %g, %g ... %g deg",
6876 LOG(2,
"Latitudes: %g, %g ... %g deg",
6882 for (
int ip = 0; ip < met->
np; ip++)
6884 LOG(2,
"Altitude levels: %g, %g ... %g km",
6885 Z(met->
p[0]),
Z(met->
p[1]),
Z(met->
p[met->
np - 1]));
6886 LOG(2,
"Pressure levels: %g, %g ... %g hPa",
6887 met->
p[0], met->
p[1], met->
p[met->
np - 1]);
6891 if (strcasecmp(levname,
"hybrid") == 0)
6904 LOG(2,
"Read level data...");
6907 if (!
read_met_nc_3d(ncid,
"t",
"T",
"temp",
"TEMP", ctl, met, met->
t, 1.0))
6908 ERRMSG(
"Cannot read temperature!");
6911 if (!
read_met_nc_3d(ncid,
"u",
"U", NULL, NULL, ctl, met, met->
u, 1.0))
6912 ERRMSG(
"Cannot read zonal wind!");
6913 if (!
read_met_nc_3d(ncid,
"v",
"V", NULL, NULL, ctl, met, met->
v, 1.0))
6914 ERRMSG(
"Cannot read meridional wind!");
6916 (ncid,
"w",
"W",
"omega",
"OMEGA", ctl, met, met->
w, 0.01f))
6917 WARN(
"Cannot read vertical velocity!");
6922 (ncid,
"q",
"Q",
"sh",
"SH", ctl, met, met->
h2o, (
float) (
MA /
MH2O)))
6923 WARN(
"Cannot read specific humidity!");
6926 (ncid,
"rh",
"RH", NULL, NULL, ctl, met, met->
h2o, 0.01f))
6927 WARN(
"Cannot read relative humidity!");
6928#pragma omp parallel for default(shared) collapse(2)
6929 for (
int ix = 0; ix < met->
nx; ix++)
6930 for (
int iy = 0; iy < met->
ny; iy++)
6931 for (
int ip = 0; ip < met->
np; ip++) {
6932 double pw = met->
h2o[ix][iy][ip] *
PSAT(met->
t[ix][iy][ip]);
6933 met->
h2o[ix][iy][ip] =
6934 (float) (pw / (met->
p[ip] - (1.0 -
EPS) * pw));
6940 (ncid,
"o3",
"O3", NULL, NULL, ctl, met, met->
o3, (
float) (
MA /
MO3)))
6941 WARN(
"Cannot read ozone data!");
6945 (ncid,
"clwc",
"CLWC", NULL, NULL, ctl, met, met->
lwc, 1.0))
6946 WARN(
"Cannot read cloud liquid water content!");
6948 (ncid,
"crwc",
"CRWC", NULL, NULL, ctl, met, met->
rwc, 1.0))
6949 WARN(
"Cannot read cloud rain water content!");
6951 (ncid,
"ciwc",
"CIWC", NULL, NULL, ctl, met, met->
iwc, 1.0))
6952 WARN(
"Cannot read cloud ice water content!");
6954 (ncid,
"cswc",
"CSWC", NULL, NULL, ctl, met, met->
swc, 1.0))
6955 WARN(
"Cannot read cloud snow water content!");
6957 WARN(
"Cannot read cloud cover!");
6961 (ncid,
"ZETA",
"zeta", NULL, NULL, ctl, met, met->
zetal, 1.0))
6962 WARN(
"Cannot read ZETA!");
6964 (ncid,
"ZETA_DOT_TOT",
"ZETA_DOT_clr",
"zeta_dot_clr",
6965 NULL, ctl, met, met->
zeta_dotl, 0.00001157407f))
6966 WARN(
"Cannot read ZETA_DOT!");
6970 for (
int ix = 0; ix < met->
nx; ix++)
6971 for (
int iy = 0; iy < met->
ny; iy++)
6972 for (
int ip = 0; ip < met->
np; ip++) {
6973 met->
ul[ix][iy][ip] = met->
u[ix][iy][ip];
6974 met->
vl[ix][iy][ip] = met->
v[ix][iy][ip];
6975 met->
wl[ix][iy][ip] = met->
w[ix][iy][ip];
6987 (ncid,
"pl",
"PL",
"pressure",
"PRESSURE", ctl, met, met->
pl, 0.01f))
6989 (ncid,
"press",
"PRESS", NULL, NULL, ctl, met, met->
pl, 1.0))
6990 ERRMSG(
"Cannot read pressure on model levels!");
6993 for (
int ix = 0; ix < met->
nx; ix++)
6994 for (
int iy = 0; iy < met->
ny; iy++)
6995 for (
int ip = 1; ip < met->
np; ip++)
6996 if ((met->
pl[ix][iy][0] > met->
pl[ix][iy][1]
6997 && met->
pl[ix][iy][ip - 1] <= met->
pl[ix][iy][ip])
6998 || (met->
pl[ix][iy][0] < met->
pl[ix][iy][1]
6999 && met->
pl[ix][iy][ip - 1] >= met->
pl[ix][iy][ip]))
7000 ERRMSG(
"Pressure profiles are not monotonic!");
7021 for (
int ip = 0; ip < met->
np; ip++)
7022 met->
p[ip] = ctl->
met_p[ip];
7026 for (
int ip = 1; ip < met->
np; ip++)
7027 if (met->
p[ip - 1] < met->
p[ip])
7028 ERRMSG(
"Pressure levels must be descending!");
7037 const char *varname) {
7039 double aux[
EP], p[
EP];
7043 LOG(2,
"Interpolate meteo data to pressure levels: %s", varname);
7046#pragma omp parallel for default(shared) private(aux,p) collapse(2)
7047 for (
int ix = 0; ix < met->
nx; ix++)
7048 for (
int iy = 0; iy < met->
ny; iy++) {
7051 for (
int ip = 0; ip < met->
np; ip++)
7052 p[ip] = met->
pl[ix][iy][ip];
7055 for (
int ip = 0; ip < ctl->
met_np; ip++) {
7056 double pt = ctl->
met_p[ip];
7057 if ((pt > p[0] && p[0] > p[1]) || (pt < p[0] && p[0] < p[1]))
7059 else if ((pt > p[met->
np - 1] && p[1] > p[0])
7060 || (pt < p[met->
np - 1] && p[1] < p[0]))
7061 pt = p[met->
np - 1];
7063 aux[ip] =
LIN(p[ip2], var[ix][iy][ip2],
7064 p[ip2 + 1], var[ix][iy][ip2 + 1], pt);
7068 for (
int ip = 0; ip < ctl->
met_np; ip++)
7069 var[ix][iy][ip] = (
float) aux[ip];
7079 SELECT_TIMER(
"READ_MET_MONOTONIZE",
"METPROC", NVTX_READ);
7080 LOG(2,
"Make zeta profiles monotone...");
7083#pragma omp parallel for default(shared) collapse(2)
7084 for (
int i = 0; i < met->
nx; i++)
7085 for (
int j = 0; j < met->
ny; j++) {
7088 while (k < met->npl) {
7089 if ((met->
zetal[i][j][k - 1] >= met->
zetal[i][j][k])) {
7095 while ((met->
zetal[i][j][k - 1] >=
7096 met->
zetal[i][j][k + l]) & (k + l < met->npl));
7101 (float) (met->
zetal[i][j][k + l] - met->
zetal[i][j][k - 1])
7104 for (
int m = k; m < k + l; m++) {
7105 float d = (float) (met->
hybrid[m] - met->
hybrid[k - 1]);
7106 met->
zetal[i][j][m] = s * d + met->
zetal[i][j][k - 1];
7118#pragma omp parallel for default(shared) collapse(2)
7119 for (
int i = 0; i < met->
nx; i++)
7120 for (
int j = 0; j < met->
ny; j++) {
7123 while (k < met->npl) {
7124 if ((met->
pl[i][j][k - 1] <= met->
pl[i][j][k])) {
7131 while ((met->
pl[i][j][k - 1] <= met->
pl[i][j][k + l]) & (k + l <
7136 float s = (float) (met->
pl[i][j][k + l] - met->
pl[i][j][k - 1])
7139 for (
int m = k; m < k + l; m++) {
7140 float d = (float) (met->
hybrid[m] - met->
hybrid[k - 1]);
7141 met->
pl[i][j][m] = s * d + met->
pl[i][j][k - 1];
7156 const char *filename,
7164 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
7165 WARN(
"Cannot open file!");
7229 const char *varname,
7230 const char *varname2,
7231 const char *varname3,
7232 const char *varname4,
7233 const char *varname5,
7234 const char *varname6,
7243 float offset, scalfac;
7248 if (nc_inq_varid(ncid, varname, &varid) == NC_NOERR)
7249 sprintf(varsel,
"%s", varname);
7250 else if (varname2 != NULL
7251 && nc_inq_varid(ncid, varname2, &varid) == NC_NOERR)
7252 sprintf(varsel,
"%s", varname2);
7253 else if (varname3 != NULL
7254 && nc_inq_varid(ncid, varname3, &varid) == NC_NOERR)
7255 sprintf(varsel,
"%s", varname3);
7256 else if (varname4 != NULL
7257 && nc_inq_varid(ncid, varname4, &varid) == NC_NOERR)
7258 sprintf(varsel,
"%s", varname4);
7259 else if (varname5 != NULL
7260 && nc_inq_varid(ncid, varname5, &varid) == NC_NOERR)
7261 sprintf(varsel,
"%s", varname5);
7262 else if (varname6 != NULL
7263 && nc_inq_varid(ncid, varname6, &varid) == NC_NOERR)
7264 sprintf(varsel,
"%s", varname6);
7270 && nc_get_att_float(ncid, varid,
"add_offset", &offset) == NC_NOERR
7271 && nc_get_att_float(ncid, varid,
"scale_factor",
7272 &scalfac) == NC_NOERR) {
7280 short fillval, missval;
7281 if (nc_get_att_short(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
7283 if (nc_get_att_short(ncid, varid,
"missing_value", &missval) != NC_NOERR)
7287 LOG(2,
"Read 2-D variable: %s"
7288 " (FILL = %d, MISS = %d, SCALE = %g, OFFSET = %g)",
7289 varsel, fillval, missval, scalfac, offset);
7292 NC(nc_get_var_short(ncid, varid, help));
7296 ERRMSG(
"Meteo data layout not implemented for packed netCDF files!");
7299#pragma omp parallel for default(shared) num_threads(12)
7300 for (
int ix = 0; ix < met->
nx; ix++)
7301 for (
int iy = 0; iy < met->
ny; iy++) {
7304 const short aux = help[
ARRAY_2D(iy, ix, met->
nx)];
7305 if ((fillval == 0 || aux != fillval)
7306 && (missval == 0 || aux != missval)
7307 && fabsf(aux * scalfac + offset) < 1e14f)
7308 dest[ix][iy] += scl * (aux * scalfac + offset);
7326 float fillval, missval;
7327 if (nc_get_att_float(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
7329 if (nc_get_att_float(ncid, varid,
"missing_value", &missval) != NC_NOERR)
7333 LOG(2,
"Read 2-D variable: %s (FILL = %g, MISS = %g)",
7334 varsel, fillval, missval);
7337 NC(nc_get_var_float(ncid, varid, help));
7343#pragma omp parallel for default(shared) num_threads(12)
7344 for (
int ix = 0; ix < met->
nx; ix++)
7345 for (
int iy = 0; iy < met->
ny; iy++) {
7348 const float aux = help[
ARRAY_2D(iy, ix, met->
nx)];
7349 if ((fillval == 0 || aux != fillval)
7350 && (missval == 0 || aux != missval)
7351 && fabsf(aux) < 1e14f)
7352 dest[ix][iy] += scl * aux;
7360#pragma omp parallel for default(shared) num_threads(12)
7361 for (
int iy = 0; iy < met->
ny; iy++)
7362 for (
int ix = 0; ix < met->
nx; ix++) {
7365 const float aux = help[
ARRAY_2D(ix, iy, met->
ny)];
7366 if ((fillval == 0 || aux != fillval)
7367 && (missval == 0 || aux != missval)
7368 && fabsf(aux) < 1e14f)
7369 dest[ix][iy] += scl * aux;
7387 const char *varname,
7388 const char *varname2,
7389 const char *varname3,
7390 const char *varname4,
7398 float offset, scalfac;
7403 if (nc_inq_varid(ncid, varname, &varid) == NC_NOERR)
7404 sprintf(varsel,
"%s", varname);
7405 else if (varname2 != NULL
7406 && nc_inq_varid(ncid, varname2, &varid) == NC_NOERR)
7407 sprintf(varsel,
"%s", varname2);
7408 else if (varname3 != NULL
7409 && nc_inq_varid(ncid, varname3, &varid) == NC_NOERR)
7410 sprintf(varsel,
"%s", varname3);
7411 else if (varname4 != NULL
7412 && nc_inq_varid(ncid, varname4, &varid) == NC_NOERR)
7413 sprintf(varsel,
"%s", varname4);
7419 && nc_get_att_float(ncid, varid,
"add_offset", &offset) == NC_NOERR
7420 && nc_get_att_float(ncid, varid,
"scale_factor",
7421 &scalfac) == NC_NOERR) {
7429 short fillval, missval;
7430 if (nc_get_att_short(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
7432 if (nc_get_att_short(ncid, varid,
"missing_value", &missval) != NC_NOERR)
7436 LOG(2,
"Read 3-D variable: %s "
7437 "(FILL = %d, MISS = %d, SCALE = %g, OFFSET = %g)",
7438 varsel, fillval, missval, scalfac, offset);
7441 NC(nc_get_var_short(ncid, varid, help));
7445 ERRMSG(
"Meteo data layout not implemented for packed netCDF files!");
7448#pragma omp parallel for default(shared) num_threads(12)
7449 for (
int ix = 0; ix < met->
nx; ix++)
7450 for (
int iy = 0; iy < met->
ny; iy++)
7451 for (
int ip = 0; ip < met->
np; ip++) {
7452 const short aux = help[
ARRAY_3D(ip, iy, met->
ny, ix, met->
nx)];
7453 if ((fillval == 0 || aux != fillval)
7454 && (missval == 0 || aux != missval)
7455 && fabsf(aux * scalfac + offset) < 1e14f)
7456 dest[ix][iy][ip] = scl * (aux * scalfac + offset);
7458 dest[ix][iy][ip] = NAN;
7474 float fillval, missval;
7475 if (nc_get_att_float(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
7477 if (nc_get_att_float(ncid, varid,
"missing_value", &missval) != NC_NOERR)
7481 LOG(2,
"Read 3-D variable: %s (FILL = %g, MISS = %g)",
7482 varsel, fillval, missval);
7485 NC(nc_get_var_float(ncid, varid, help));
7491#pragma omp parallel for default(shared) num_threads(12)
7492 for (
int ix = 0; ix < met->
nx; ix++)
7493 for (
int iy = 0; iy < met->
ny; iy++)
7494 for (
int ip = 0; ip < met->
np; ip++) {
7495 const float aux = help[
ARRAY_3D(ip, iy, met->
ny, ix, met->
nx)];
7496 if ((fillval == 0 || aux != fillval)
7497 && (missval == 0 || aux != missval)
7498 && fabsf(aux) < 1e14f)
7499 dest[ix][iy][ip] = scl * aux;
7501 dest[ix][iy][ip] = NAN;
7507#pragma omp parallel for default(shared) num_threads(12)
7508 for (
int ip = 0; ip < met->
np; ip++)
7509 for (
int iy = 0; iy < met->
ny; iy++)
7510 for (
int ix = 0; ix < met->
nx; ix++) {
7511 const float aux = help[
ARRAY_3D(ix, iy, met->
ny, ip, met->
np)];
7512 if ((fillval == 0 || aux != fillval)
7513 && (missval == 0 || aux != missval)
7514 && fabsf(aux) < 1e14f)
7515 dest[ix][iy][ip] = scl * aux;
7517 dest[ix][iy][ip] = NAN;
7537 LOG(2,
"Calculate planetary boundary layer...");
7543#pragma omp parallel for default(shared) collapse(2)
7544 for (
int ix = 0; ix < met->
nx; ix++)
7545 for (
int iy = 0; iy < met->
ny; iy++) {
7548 const float z = met->
zs[ix][iy] + met->
pbl[ix][iy];
7551 (float) (
LIN(met->
z[ix][iy][ip], met->
p[ip],
7552 met->
z[ix][iy][ip + 1], met->
p[ip + 1], z));
7561 const double rib_crit = 0.25, dz = 0.05, umin = 5.0;
7564#pragma omp parallel for default(shared) collapse(2)
7565 for (
int ix = 0; ix < met->
nx; ix++)
7566 for (
int iy = 0; iy < met->
ny; iy++) {
7569 const double pbl_bot = met->
ps[ix][iy] * exp(-dz /
H0);
7573 for (ip = 1; ip < met->
np; ip++)
7574 if (met->
p[ip] < pbl_bot)
7578 const double h2os =
LIN(met->
p[ip - 1], met->
h2o[ix][iy][ip - 1],
7579 met->
p[ip], met->
h2o[ix][iy][ip], pbl_bot);
7580 const double tvs =
THETAVIRT(pbl_bot, met->
ts[ix][iy], h2os);
7586 for (; ip < met->
np; ip++) {
7589 double vh2 =
SQR(met->
u[ix][iy][ip] - met->
us[ix][iy])
7590 +
SQR(met->
v[ix][iy][ip] - met->
vs[ix][iy]);
7591 vh2 =
MAX(vh2,
SQR(umin));
7595 G0 * 1e3 * (met->
z[ix][iy][ip] - met->
zs[ix][iy]) / tvs
7597 met->
h2o[ix][iy][ip]) - tvs) / vh2;
7600 if (rib >= rib_crit) {
7601 met->
pbl[ix][iy] = (float) (
LIN(rib_old, met->
p[ip - 1],
7602 rib, met->
p[ip], rib_crit));
7603 if (met->
pbl[ix][iy] > pbl_bot)
7604 met->
pbl[ix][iy] = (float) pbl_bot;
7619 const double dtheta = 2.0, zmin = 0.1;
7622#pragma omp parallel for default(shared) collapse(2)
7623 for (
int ix = 0; ix < met->
nx; ix++)
7624 for (
int iy = 0; iy < met->
ny; iy++) {
7627 const double theta0 =
THETA(met->
ps[ix][iy], met->
ts[ix][iy]);
7631 for (ip = met->
np - 2; ip > 0; ip--)
7632 if (met->
p[ip] >= 300.)
7633 if (met->
p[ip] > met->
ps[ix][iy]
7634 ||
THETA(met->
p[ip], met->
t[ix][iy][ip]) <= theta0 + dtheta)
7639 = (float) (
LIN(
THETA(met->
p[ip + 1], met->
t[ix][iy][ip + 1]),
7641 THETA(met->
p[ip], met->
t[ix][iy][ip]),
7642 met->
p[ip], theta0 + dtheta));
7645 double pbl_min = met->
ps[ix][iy] * exp(-zmin /
H0);
7646 if (met->
pbl[ix][iy] > pbl_min || met->
p[ip] > met->
ps[ix][iy])
7647 met->
pbl[ix][iy] = (float) pbl_min;
7652#pragma omp parallel for default(shared) collapse(2)
7653 for (
int ix = 0; ix < met->
nx; ix++)
7654 for (
int iy = 0; iy < met->
ny; iy++) {
7658 met->
pbl[ix][iy] =
MIN(met->
pbl[ix][iy], (
float) pbl_min);
7662 met->
pbl[ix][iy] =
MAX(met->
pbl[ix][iy], (
float) pbl_max);
7672 SELECT_TIMER(
"READ_MET_PERIODIC",
"METPROC", NVTX_READ);
7673 LOG(2,
"Apply periodic boundary conditions...");
7676 if (!(fabs(met->
lon[met->
nx - 1] - met->
lon[0]
7677 + met->
lon[1] - met->
lon[0] - 360) < 0.01))
7681 if ((++met->
nx) >=
EX)
7682 ERRMSG(
"Cannot create periodic boundary conditions!");
7688#pragma omp parallel for default(shared)
7689 for (
int iy = 0; iy < met->
ny; iy++) {
7690 met->
ps[met->
nx - 1][iy] = met->
ps[0][iy];
7691 met->
zs[met->
nx - 1][iy] = met->
zs[0][iy];
7692 met->
ts[met->
nx - 1][iy] = met->
ts[0][iy];
7693 met->
us[met->
nx - 1][iy] = met->
us[0][iy];
7694 met->
vs[met->
nx - 1][iy] = met->
vs[0][iy];
7695 met->
ess[met->
nx - 1][iy] = met->
ess[0][iy];
7696 met->
nss[met->
nx - 1][iy] = met->
nss[0][iy];
7697 met->
shf[met->
nx - 1][iy] = met->
shf[0][iy];
7698 met->
lsm[met->
nx - 1][iy] = met->
lsm[0][iy];
7699 met->
sst[met->
nx - 1][iy] = met->
sst[0][iy];
7700 met->
pbl[met->
nx - 1][iy] = met->
pbl[0][iy];
7701 met->
cape[met->
nx - 1][iy] = met->
cape[0][iy];
7702 met->
cin[met->
nx - 1][iy] = met->
cin[0][iy];
7703 for (
int ip = 0; ip < met->
np; ip++) {
7704 met->
t[met->
nx - 1][iy][ip] = met->
t[0][iy][ip];
7705 met->
u[met->
nx - 1][iy][ip] = met->
u[0][iy][ip];
7706 met->
v[met->
nx - 1][iy][ip] = met->
v[0][iy][ip];
7707 met->
w[met->
nx - 1][iy][ip] = met->
w[0][iy][ip];
7708 met->
h2o[met->
nx - 1][iy][ip] = met->
h2o[0][iy][ip];
7709 met->
o3[met->
nx - 1][iy][ip] = met->
o3[0][iy][ip];
7710 met->
lwc[met->
nx - 1][iy][ip] = met->
lwc[0][iy][ip];
7711 met->
rwc[met->
nx - 1][iy][ip] = met->
rwc[0][iy][ip];
7712 met->
iwc[met->
nx - 1][iy][ip] = met->
iwc[0][iy][ip];
7713 met->
swc[met->
nx - 1][iy][ip] = met->
swc[0][iy][ip];
7714 met->
cc[met->
nx - 1][iy][ip] = met->
cc[0][iy][ip];
7716 for (
int ip = 0; ip < met->
npl; ip++) {
7717 met->
ul[met->
nx - 1][iy][ip] = met->
ul[0][iy][ip];
7718 met->
vl[met->
nx - 1][iy][ip] = met->
vl[0][iy][ip];
7719 met->
wl[met->
nx - 1][iy][ip] = met->
wl[0][iy][ip];
7720 met->
pl[met->
nx - 1][iy][ip] = met->
pl[0][iy][ip];
7721 met->
zetal[met->
nx - 1][iy][ip] = met->
zetal[0][iy][ip];
7733 SELECT_TIMER(
"READ_MET_POLAR_WINDS",
"METPROC", NVTX_READ);
7734 LOG(2,
"Apply fix for polar winds...");
7737 if (fabs(met->
lat[0]) < 89.999 || fabs(met->
lat[met->
ny - 1]) < 89.999)
7741 for (
int ihem = 0; ihem < 2; ihem++) {
7744 int i89 = 1, i90 = 0, sign = 1;
7749 if (met->
lat[i90] < 0)
7753 double clon[
EX], slon[
EX];
7754#pragma omp parallel for default(shared)
7755 for (
int ix = 0; ix < met->
nx; ix++) {
7756 clon[ix] = cos(sign *
DEG2RAD(met->
lon[ix]));
7757 slon[ix] = sin(sign *
DEG2RAD(met->
lon[ix]));
7761#pragma omp parallel for default(shared)
7762 for (
int ip = 0; ip < met->
np; ip++) {
7765 double vel89x = 0, vel89y = 0;
7766 for (
int ix = 0; ix < met->
nx; ix++) {
7768 (met->
u[ix][i89][ip] * clon[ix] -
7769 met->
v[ix][i89][ip] * slon[ix]) / met->
nx;
7771 (met->
u[ix][i89][ip] * slon[ix] +
7772 met->
v[ix][i89][ip] * clon[ix]) / met->
nx;
7776 for (
int ix = 0; ix < met->
nx; ix++) {
7778 = (float) (vel89x * clon[ix] + vel89y * slon[ix]);
7780 = (float) (-vel89x * slon[ix] + vel89y * clon[ix]);
7795 LOG(2,
"Calculate potential vorticity...");
7798#pragma omp parallel for default(shared)
7799 for (
int ip = 0; ip < met->
np; ip++)
7800 pows[ip] = pow(1000. / met->
p[ip], 0.286);
7803#pragma omp parallel for default(shared)
7804 for (
int ix = 0; ix < met->
nx; ix++) {
7807 const int ix0 =
MAX(ix - 1, 0);
7808 const int ix1 =
MIN(ix + 1, met->
nx - 1);
7811 for (
int iy = 0; iy < met->
ny; iy++) {
7814 const int iy0 =
MAX(iy - 1, 0);
7815 const int iy1 =
MIN(iy + 1, met->
ny - 1);
7818 const double latr = 0.5 * (met->
lat[iy1] + met->
lat[iy0]);
7819 const double dx = 1000. *
DEG2DX(met->
lon[ix1] - met->
lon[ix0], latr);
7820 const double dy = 1000. *
DEG2DY(met->
lat[iy1] - met->
lat[iy0]);
7821 const double c0 = cos(
DEG2RAD(met->
lat[iy0]));
7822 const double c1 = cos(
DEG2RAD(met->
lat[iy1]));
7823 const double cr = cos(
DEG2RAD(latr));
7824 const double vort = 2 * 7.2921e-5 * sin(
DEG2RAD(latr));
7827 for (
int ip = 0; ip < met->
np; ip++) {
7831 = (met->
t[ix1][iy][ip] - met->
t[ix0][iy][ip]) * pows[ip] / dx;
7832 const double dvdx = (met->
v[ix1][iy][ip] - met->
v[ix0][iy][ip]) / dx;
7836 = (met->
t[ix][iy1][ip] - met->
t[ix][iy0][ip]) * pows[ip] / dy;
7838 = (met->
u[ix][iy1][ip] * c1 - met->
u[ix][iy0][ip] * c0) / dy;
7841 const int ip0 =
MAX(ip - 1, 0);
7842 const int ip1 =
MIN(ip + 1, met->
np - 1);
7845 double dtdp, dudp, dvdp;
7846 const double dp0 = 100. * (met->
p[ip] - met->
p[ip0]);
7847 const double dp1 = 100. * (met->
p[ip1] - met->
p[ip]);
7848 if (ip != ip0 && ip != ip1) {
7849 double denom = dp0 * dp1 * (dp0 + dp1);
7850 dtdp = (dp0 * dp0 * met->
t[ix][iy][ip1] * pows[ip1]
7851 - dp1 * dp1 * met->
t[ix][iy][ip0] * pows[ip0]
7852 + (dp1 * dp1 - dp0 * dp0) * met->
t[ix][iy][ip] * pows[ip])
7854 dudp = (dp0 * dp0 * met->
u[ix][iy][ip1]
7855 - dp1 * dp1 * met->
u[ix][iy][ip0]
7856 + (dp1 * dp1 - dp0 * dp0) * met->
u[ix][iy][ip])
7858 dvdp = (dp0 * dp0 * met->
v[ix][iy][ip1]
7859 - dp1 * dp1 * met->
v[ix][iy][ip0]
7860 + (dp1 * dp1 - dp0 * dp0) * met->
v[ix][iy][ip])
7863 const double denom = dp0 + dp1;
7865 (met->
t[ix][iy][ip1] * pows[ip1] -
7866 met->
t[ix][iy][ip0] * pows[ip0]) / denom;
7867 dudp = (met->
u[ix][iy][ip1] - met->
u[ix][iy][ip0]) / denom;
7868 dvdp = (met->
v[ix][iy][ip1] - met->
v[ix][iy][ip0]) / denom;
7872 met->
pv[ix][iy][ip] = (float)
7874 (-dtdp * (dvdx - dudy / cr + vort) + dvdp * dtdx - dudp * dtdy));
7880#pragma omp parallel for default(shared)
7881 for (
int ix = 0; ix < met->
nx; ix++)
7882 for (
int ip = 0; ip < met->
np; ip++) {
7884 = met->
pv[ix][1][ip]
7885 = met->
pv[ix][2][ip];
7886 met->
pv[ix][met->
ny - 1][ip]
7887 = met->
pv[ix][met->
ny - 2][ip]
7888 = met->
pv[ix][met->
ny - 3][ip];
7899 LOG(2,
"Calculate total column ozone...");
7902#pragma omp parallel for default(shared) collapse(2)
7903 for (
int ix = 0; ix < met->
nx; ix++)
7904 for (
int iy = 0; iy < met->
ny; iy++) {
7908 for (
int ip = 1; ip < met->
np; ip++)
7909 if (met->
p[ip - 1] <= met->
ps[ix][iy]) {
7911 0.5 * (met->
o3[ix][iy][ip - 1] + met->
o3[ix][iy][ip]);
7912 const double dp = met->
p[ip - 1] - met->
p[ip];
7913 cd += vmr *
MO3 /
MA * dp * 1e2 /
G0;
7917 met->
o3c[ix][iy] = (float) (cd / 2.1415e-5);
7936 LOG(2,
"Downsampling of meteo data...");
7945 memcpy(help->
lon, met->
lon,
sizeof(met->
lon));
7946 memcpy(help->
lat, met->
lat,
sizeof(met->
lat));
7947 memcpy(help->
p, met->
p,
sizeof(met->
p));
7950 for (
int ix = 0; ix < met->
nx; ix += ctl->
met_dx) {
7951 for (
int iy = 0; iy < met->
ny; iy += ctl->
met_dy) {
7952 for (
int ip = 0; ip < met->
np; ip += ctl->
met_dp) {
7953 help->
ps[ix][iy] = 0;
7954 help->
zs[ix][iy] = 0;
7955 help->
ts[ix][iy] = 0;
7956 help->
us[ix][iy] = 0;
7957 help->
vs[ix][iy] = 0;
7958 help->
ess[ix][iy] = 0;
7959 help->
nss[ix][iy] = 0;
7960 help->
shf[ix][iy] = 0;
7961 help->
lsm[ix][iy] = 0;
7962 help->
sst[ix][iy] = 0;
7963 help->
pbl[ix][iy] = 0;
7964 help->
cape[ix][iy] = 0;
7965 help->
cin[ix][iy] = 0;
7966 help->
t[ix][iy][ip] = 0;
7967 help->
u[ix][iy][ip] = 0;
7968 help->
v[ix][iy][ip] = 0;
7969 help->
w[ix][iy][ip] = 0;
7970 help->
h2o[ix][iy][ip] = 0;
7971 help->
o3[ix][iy][ip] = 0;
7972 help->
lwc[ix][iy][ip] = 0;
7973 help->
rwc[ix][iy][ip] = 0;
7974 help->
iwc[ix][iy][ip] = 0;
7975 help->
swc[ix][iy][ip] = 0;
7976 help->
cc[ix][iy][ip] = 0;
7978 for (
int ix2 = ix - ctl->
met_sx + 1; ix2 <= ix + ctl->met_sx - 1;
7983 else if (ix3 >= met->
nx)
7986 for (
int iy2 =
MAX(iy - ctl->
met_sy + 1, 0);
7987 iy2 <=
MIN(iy + ctl->
met_sy - 1, met->
ny - 1); iy2++)
7988 for (
int ip2 =
MAX(ip - ctl->
met_sp + 1, 0);
7989 ip2 <=
MIN(ip + ctl->
met_sp - 1, met->
np - 1); ip2++) {
7990 float w = (1.0f - (float) abs(ix - ix2) / (float) ctl->
met_sx)
7991 * (1.0f - (float) abs(iy - iy2) / (float) ctl->
met_sy)
7992 * (1.0f - (float) abs(ip - ip2) / (float) ctl->
met_sp);
7993 help->
ps[ix][iy] += w * met->
ps[ix3][iy2];
7994 help->
zs[ix][iy] += w * met->
zs[ix3][iy2];
7995 help->
ts[ix][iy] += w * met->
ts[ix3][iy2];
7996 help->
us[ix][iy] += w * met->
us[ix3][iy2];
7997 help->
vs[ix][iy] += w * met->
vs[ix3][iy2];
7998 help->
ess[ix][iy] += w * met->
ess[ix3][iy2];
7999 help->
nss[ix][iy] += w * met->
nss[ix3][iy2];
8000 help->
shf[ix][iy] += w * met->
shf[ix3][iy2];
8001 help->
lsm[ix][iy] += w * met->
lsm[ix3][iy2];
8002 help->
sst[ix][iy] += w * met->
sst[ix3][iy2];
8003 help->
pbl[ix][iy] += w * met->
pbl[ix3][iy2];
8004 help->
cape[ix][iy] += w * met->
cape[ix3][iy2];
8005 help->
cin[ix][iy] += w * met->
cin[ix3][iy2];
8006 help->
t[ix][iy][ip] += w * met->
t[ix3][iy2][ip2];
8007 help->
u[ix][iy][ip] += w * met->
u[ix3][iy2][ip2];
8008 help->
v[ix][iy][ip] += w * met->
v[ix3][iy2][ip2];
8009 help->
w[ix][iy][ip] += w * met->
w[ix3][iy2][ip2];
8010 help->
h2o[ix][iy][ip] += w * met->
h2o[ix3][iy2][ip2];
8011 help->
o3[ix][iy][ip] += w * met->
o3[ix3][iy2][ip2];
8012 help->
lwc[ix][iy][ip] += w * met->
lwc[ix3][iy2][ip2];
8013 help->
rwc[ix][iy][ip] += w * met->
rwc[ix3][iy2][ip2];
8014 help->
iwc[ix][iy][ip] += w * met->
iwc[ix3][iy2][ip2];
8015 help->
swc[ix][iy][ip] += w * met->
swc[ix3][iy2][ip2];
8016 help->
cc[ix][iy][ip] += w * met->
cc[ix3][iy2][ip2];
8020 help->
ps[ix][iy] /= wsum;
8021 help->
zs[ix][iy] /= wsum;
8022 help->
ts[ix][iy] /= wsum;
8023 help->
us[ix][iy] /= wsum;
8024 help->
vs[ix][iy] /= wsum;
8025 help->
ess[ix][iy] /= wsum;
8026 help->
nss[ix][iy] /= wsum;
8027 help->
shf[ix][iy] /= wsum;
8028 help->
lsm[ix][iy] /= wsum;
8029 help->
sst[ix][iy] /= wsum;
8030 help->
pbl[ix][iy] /= wsum;
8031 help->
cape[ix][iy] /= wsum;
8032 help->
cin[ix][iy] /= wsum;
8033 help->
t[ix][iy][ip] /= wsum;
8034 help->
u[ix][iy][ip] /= wsum;
8035 help->
v[ix][iy][ip] /= wsum;
8036 help->
w[ix][iy][ip] /= wsum;
8037 help->
h2o[ix][iy][ip] /= wsum;
8038 help->
o3[ix][iy][ip] /= wsum;
8039 help->
lwc[ix][iy][ip] /= wsum;
8040 help->
rwc[ix][iy][ip] /= wsum;
8041 help->
iwc[ix][iy][ip] /= wsum;
8042 help->
swc[ix][iy][ip] /= wsum;
8043 help->
cc[ix][iy][ip] /= wsum;
8050 for (
int ix = 0; ix < help->
nx; ix += ctl->
met_dx) {
8053 for (
int iy = 0; iy < help->
ny; iy += ctl->
met_dy) {
8055 met->
ps[met->
nx][met->
ny] = help->
ps[ix][iy];
8056 met->
zs[met->
nx][met->
ny] = help->
zs[ix][iy];
8057 met->
ts[met->
nx][met->
ny] = help->
ts[ix][iy];
8058 met->
us[met->
nx][met->
ny] = help->
us[ix][iy];
8059 met->
vs[met->
nx][met->
ny] = help->
vs[ix][iy];
8060 met->
ess[met->
nx][met->
ny] = help->
ess[ix][iy];
8061 met->
nss[met->
nx][met->
ny] = help->
nss[ix][iy];
8062 met->
shf[met->
nx][met->
ny] = help->
shf[ix][iy];
8063 met->
lsm[met->
nx][met->
ny] = help->
lsm[ix][iy];
8064 met->
sst[met->
nx][met->
ny] = help->
sst[ix][iy];
8065 met->
pbl[met->
nx][met->
ny] = help->
pbl[ix][iy];
8067 met->
cin[met->
nx][met->
ny] = help->
cin[ix][iy];
8069 for (
int ip = 0; ip < help->
np; ip += ctl->
met_dp) {
8070 met->
p[met->
np] = help->
p[ip];
8071 met->
t[met->
nx][met->
ny][met->
np] = help->
t[ix][iy][ip];
8072 met->
u[met->
nx][met->
ny][met->
np] = help->
u[ix][iy][ip];
8073 met->
v[met->
nx][met->
ny][met->
np] = help->
v[ix][iy][ip];
8074 met->
w[met->
nx][met->
ny][met->
np] = help->
w[ix][iy][ip];
8075 met->
h2o[met->
nx][met->
ny][met->
np] = help->
h2o[ix][iy][ip];
8076 met->
o3[met->
nx][met->
ny][met->
np] = help->
o3[ix][iy][ip];
8077 met->
lwc[met->
nx][met->
ny][met->
np] = help->
lwc[ix][iy][ip];
8078 met->
rwc[met->
nx][met->
ny][met->
np] = help->
rwc[ix][iy][ip];
8079 met->
iwc[met->
nx][met->
ny][met->
np] = help->
iwc[ix][iy][ip];
8080 met->
swc[met->
nx][met->
ny][met->
np] = help->
swc[ix][iy][ip];
8081 met->
cc[met->
nx][met->
ny][met->
np] = help->
cc[ix][iy][ip];
8102 LOG(2,
"Read surface data...");
8106 (ncid,
"lnsp",
"LNSP", NULL, NULL, NULL, NULL, ctl, met, met->
ps, 1.0f,
8108 for (
int ix = 0; ix < met->
nx; ix++)
8109 for (
int iy = 0; iy < met->
ny; iy++)
8110 met->
ps[ix][iy] = (
float) (exp(met->
ps[ix][iy]) / 100.);
8113 (ncid,
"ps",
"PS",
"sp",
"SP", NULL, NULL, ctl, met, met->
ps, 0.01f,
8115 WARN(
"Cannot not read surface pressure data (use lowest level)!");
8116 for (
int ix = 0; ix < met->
nx; ix++)
8117 for (
int iy = 0; iy < met->
ny; iy++)
8118 met->
ps[ix][iy] = (
float) met->
p[0];
8126 (ncid,
"z",
"Z", NULL, NULL, NULL, NULL, ctl, met, met->
zs,
8127 (
float) (1. / (1000. *
G0)), 1))
8129 (ncid,
"zm",
"ZM", NULL, NULL, NULL, NULL, ctl, met, met->
zs,
8130 (
float) (1. / 1000.), 1))
8131 WARN(
"Cannot read surface geopotential height!");
8142 memcpy(help, met->
pl,
sizeof(met->
pl));
8144 (ncid,
"gph",
"GPH", NULL, NULL, ctl, met, met->
pl,
8145 (
float) (1e-3 /
G0)))
8146 ERRMSG(
"Cannot read geopotential height!");
8147 for (
int ix = 0; ix < met->
nx; ix++)
8148 for (
int iy = 0; iy < met->
ny; iy++)
8149 met->
zs[ix][iy] = met->
pl[ix][iy][0];
8150 memcpy(met->
pl, help,
sizeof(met->
pl));
8156 (ncid,
"t2m",
"T2M",
"2t",
"2T",
"t2",
"T2", ctl, met, met->
ts, 1.0, 1))
8157 WARN(
"Cannot read surface temperature!");
8161 (ncid,
"u10m",
"U10M",
"10u",
"10U",
"u10",
"U10", ctl, met, met->
us,
8163 WARN(
"Cannot read surface zonal wind!");
8167 (ncid,
"v10m",
"V10M",
"10v",
"10V",
"v10",
"V10", ctl, met, met->
vs,
8169 WARN(
"Cannot read surface meridional wind!");
8173 (ncid,
"iews",
"IEWS", NULL, NULL, NULL, NULL, ctl, met, met->
ess, 1.0,
8175 WARN(
"Cannot read eastward turbulent surface stress!");
8179 (ncid,
"inss",
"INSS", NULL, NULL, NULL, NULL, ctl, met, met->
nss, 1.0,
8181 WARN(
"Cannot read nothward turbulent surface stress!");
8185 (ncid,
"ishf",
"ISHF", NULL, NULL, NULL, NULL, ctl, met, met->
shf, 1.0,
8187 WARN(
"Cannot read surface sensible heat flux!");
8191 (ncid,
"lsm",
"LSM", NULL, NULL, NULL, NULL, ctl, met, met->
lsm, 1.0,
8193 WARN(
"Cannot read land-sea mask!");
8197 (ncid,
"sstk",
"SSTK",
"sst",
"SST", NULL, NULL, ctl, met, met->
sst,
8199 WARN(
"Cannot read sea surface temperature!");
8204 (ncid,
"blp",
"BLP", NULL, NULL, NULL, NULL, ctl, met, met->
pbl,
8206 WARN(
"Cannot read planetary boundary layer pressure!");
8209 (ncid,
"blh",
"BLH", NULL, NULL, NULL, NULL, ctl, met, met->
pbl,
8211 WARN(
"Cannot read planetary boundary layer height!");
8216 (ncid,
"cape",
"CAPE", NULL, NULL, NULL, NULL, ctl, met, met->
cape,
8218 WARN(
"Cannot read CAPE!");
8223 (ncid,
"cin",
"CIN", NULL, NULL, NULL, NULL, ctl, met, met->
cin,
8225 WARN(
"Cannot read convective inhibition!");
8235 double p2[200], pv[
EP], pv2[200], t[
EP], t2[200], th[
EP],
8236 th2[200], z[
EP], z2[200];
8240 LOG(2,
"Calculate tropopause...");
8243#pragma omp parallel for default(shared)
8244 for (
int iz = 0; iz < met->
np; iz++)
8245 z[iz] =
Z(met->
p[iz]);
8246#pragma omp parallel for default(shared)
8247 for (
int iz = 0; iz <= 190; iz++) {
8248 z2[iz] = 4.5 + 0.1 * iz;
8254#pragma omp parallel for default(shared) collapse(2)
8255 for (
int ix = 0; ix < met->
nx; ix++)
8256 for (
int iy = 0; iy < met->
ny; iy++)
8257 met->
pt[ix][iy] = NAN;
8261#pragma omp parallel for default(shared) collapse(2)
8262 for (
int ix = 0; ix < met->
nx; ix++)
8263 for (
int iy = 0; iy < met->
ny; iy++)
8271#pragma omp parallel for default(shared) private(t,t2) collapse(2)
8272 for (
int ix = 0; ix < met->
nx; ix++)
8273 for (
int iy = 0; iy < met->
ny; iy++) {
8276 for (
int iz = 0; iz < met->
np; iz++)
8277 t[iz] = met->
t[ix][iy][iz];
8281 int iz = (int) gsl_stats_min_index(t2, 1, 171);
8282 if (iz > 0 && iz < 170)
8283 met->
pt[ix][iy] = (float) p2[iz];
8285 met->
pt[ix][iy] = NAN;
8293#pragma omp parallel for default(shared) private(t,t2) collapse(2)
8294 for (
int ix = 0; ix < met->
nx; ix++)
8295 for (
int iy = 0; iy < met->
ny; iy++) {
8299 for (iz = 0; iz < met->
np; iz++)
8300 t[iz] = met->
t[ix][iy][iz];
8304 met->
pt[ix][iy] = NAN;
8305 for (iz = 0; iz <= 170; iz++) {
8307 for (
int iz2 = iz + 1; iz2 <= iz + 20; iz2++)
8308 if (
LAPSE(p2[iz], t2[iz], p2[iz2], t2[iz2]) > 2.0) {
8313 if (iz > 0 && iz < 170)
8314 met->
pt[ix][iy] = (float) p2[iz];
8321 met->
pt[ix][iy] = NAN;
8322 for (; iz <= 170; iz++) {
8324 for (
int iz2 = iz + 1; iz2 <= iz + 10; iz2++)
8325 if (
LAPSE(p2[iz], t2[iz], p2[iz2], t2[iz2]) < 3.0) {
8332 for (; iz <= 170; iz++) {
8334 for (
int iz2 = iz + 1; iz2 <= iz + 20; iz2++)
8335 if (
LAPSE(p2[iz], t2[iz], p2[iz2], t2[iz2]) > 2.0) {
8340 if (iz > 0 && iz < 170)
8341 met->
pt[ix][iy] = (float) p2[iz];
8353#pragma omp parallel for default(shared) private(pv,pv2,th,th2) collapse(2)
8354 for (
int ix = 0; ix < met->
nx; ix++)
8355 for (
int iy = 0; iy < met->
ny; iy++) {
8358 for (
int iz = 0; iz < met->
np; iz++)
8359 pv[iz] = met->
pv[ix][iy][iz];
8363 for (
int iz = 0; iz < met->
np; iz++)
8364 th[iz] =
THETA(met->
p[iz], met->
t[ix][iy][iz]);
8368 met->
pt[ix][iy] = NAN;
8369 for (
int iz = 0; iz <= 170; iz++)
8372 if (iz > 0 && iz < 170)
8373 met->
pt[ix][iy] = (float) p2[iz];
8380 ERRMSG(
"Cannot calculate tropopause!");
8383#pragma omp parallel for default(shared) collapse(2)
8384 for (
int ix = 0; ix < met->
nx; ix++)
8385 for (
int iy = 0; iy < met->
ny; iy++) {
8386 double h2ot, tt, zt;
8389 met->
lat[iy], &tt, ci, cw, 1);
8391 met->
lat[iy], &zt, ci, cw, 0);
8393 met->
lat[iy], &h2ot, ci, cw, 0);
8394 met->
tt[ix][iy] = (float) tt;
8395 met->
zt[ix][iy] = (float) zt;
8396 met->
h2ot[ix][iy] = (float) h2ot;
8403 const char *filename,
8413 LOG(1,
"Read observation data: %s", filename);
8417 read_obs_asc(filename, rt, rz, rlon, rlat, robs, nobs);
8419 read_obs_nc(filename, rt, rz, rlon, rlat, robs, nobs);
8421 ERRMSG(
"Set OBS_TYPE to 0 or 1!");
8424 for (
int i = 1; i < *nobs; i++)
8425 if (rt[i] < rt[i - 1])
8426 ERRMSG(
"Time must be ascending!");
8431 LOG(2,
"Number of observations: %d", *nobs);
8432 gsl_stats_minmax(&mini, &maxi, rt, 1, (
size_t) n);
8433 LOG(2,
"Time range: %.2f ... %.2f s", mini, maxi);
8434 gsl_stats_minmax(&mini, &maxi, rz, 1, (
size_t) n);
8435 LOG(2,
"Altitude range: %g ... %g km", mini, maxi);
8436 gsl_stats_minmax(&mini, &maxi, rlon, 1, (
size_t) n);
8437 LOG(2,
"Longitude range: %g ... %g deg", mini, maxi);
8438 gsl_stats_minmax(&mini, &maxi, rlat, 1, (
size_t) n);
8439 LOG(2,
"Latitude range: %g ... %g deg", mini, maxi);
8440 gsl_stats_minmax(&mini, &maxi, robs, 1, (
size_t) n);
8441 LOG(2,
"Observation range: %g ... %g", mini, maxi);
8447 const char *filename,
8457 if (!(in = fopen(filename,
"r")))
8458 ERRMSG(
"Cannot open file!");
8462 while (fgets(line,
LEN, in))
8463 if (sscanf(line,
"%lg %lg %lg %lg %lg", &rt[*nobs], &rz[*nobs],
8464 &rlon[*nobs], &rlat[*nobs], &robs[*nobs]) == 5)
8465 if ((++(*nobs)) >=
NOBS)
8466 ERRMSG(
"Too many observations!");
8475 const char *filename,
8486 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR)
8487 ERRMSG(
"Cannot open file!");
8504 const char *filename,
8507 const char *varname,
8509 const char *defvalue,
8514 char fullname1[
LEN], fullname2[
LEN], rval[
LEN];
8519 if (filename[strlen(filename) - 1] !=
'-')
8520 if (!(in = fopen(filename,
"r")))
8521 ERRMSG(
"Cannot open file!");
8525 sprintf(fullname1,
"%s[%d]", varname, arridx);
8526 sprintf(fullname2,
"%s[*]", varname);
8528 sprintf(fullname1,
"%s", varname);
8529 sprintf(fullname2,
"%s", varname);
8534 char dummy[
LEN], line[
LEN], rvarname[
LEN];
8535 while (fgets(line,
LEN, in)) {
8536 if (sscanf(line,
"%4999s %4999s %4999s", rvarname, dummy, rval) == 3)
8537 if (strcasecmp(rvarname, fullname1) == 0 ||
8538 strcasecmp(rvarname, fullname2) == 0) {
8544 for (i = 1; i < argc - 1; i++)
8545 if (strcasecmp(argv[i], fullname1) == 0 ||
8546 strcasecmp(argv[i], fullname2) == 0) {
8547 sprintf(rval,
"%s", argv[i + 1]);
8558 if (strlen(defvalue) > 0)
8559 sprintf(rval,
"%s", defvalue);
8561 ERRMSG(
"Missing variable %s!\n", fullname1);
8565 LOG(1,
"%s = %s", fullname1, rval);
8569 sprintf(value,
"%s", rval);
8579 const double rhop) {
8582 const double rp_help = rp * 1e-6;
8585 const double rho =
RHO(p, T);
8588 const double eta = 1.8325e-5 * (416.16 / (T + 120.)) * pow(T / 296.16, 1.5);
8591 const double v = sqrt(8. *
KB * T / (M_PI * 4.8096e-26));
8594 const double lambda = 2. * eta / (rho * v);
8597 const double K = lambda / rp_help;
8600 const double G = 1. + K * (1.249 + 0.42 * exp(-0.87 / K));
8603 return 2. *
SQR(rp_help) * (rhop - rho) *
G0 / (9. * eta) * G;
8621 gsl_interp_accel *acc = gsl_interp_accel_alloc();
8622 gsl_spline *s = gsl_spline_alloc(gsl_interp_cspline, (
size_t) n);
8625 gsl_spline_init(s, x, y, (
size_t) n);
8626 for (
int i = 0; i < n2; i++)
8629 else if (x2[i] >= x[n - 1])
8632 y2[i] = gsl_spline_eval(s, x2[i], acc);
8636 gsl_interp_accel_free(acc);
8641 for (
int i = 0; i < n2; i++)
8644 else if (x2[i] >= x[n - 1])
8648 y2[i] =
LIN(x[idx], y[idx], x[idx + 1], y[idx + 1], x2[i]);
8662 float mean = 0, var = 0;
8664 for (
int i = 0; i < n; ++i) {
8666 var +=
SQR(data[i]);
8669 var = var / (float) n -
SQR(mean / (
float) n);
8671 return (var > 0 ? sqrtf(var) : 0);
8682 const double D = sec / 86400 - 0.5;
8685 const double g =
DEG2RAD(357.529 + 0.98560028 * D);
8686 const double q = 280.459 + 0.98564736 * D;
8687 const double L =
DEG2RAD(q + 1.915 * sin(g) + 0.020 * sin(2 * g));
8690 const double e =
DEG2RAD(23.439 - 0.00000036 * D);
8693 const double sindec = sin(e) * sin(L);
8696 const double ra = atan2(cos(e) * sin(L), cos(L));
8699 const double GMST = 18.697374558 + 24.06570982441908 * D;
8702 const double LST = GMST + lon / 15;
8705 const double h = LST / 12 * M_PI - ra;
8708 const double lat_help =
DEG2RAD(lat);
8711 return acos(sin(lat_help) * sindec +
8712 cos(lat_help) * sqrt(1 -
SQR(sindec)) * cos(h));
8724 const double remain,
8736 t1.tm_year = year - 1900;
8737 t1.tm_mon = mon - 1;
8743 *jsec = (double) timegm(&t1) - (double) timegm(&t0) + remain;
8758 static int iname = -1, igroup = -1, nname, ngroup, ct_name[
NTIMER];
8761 t1 = omp_get_wtime();
8766 rt_name[iname] += dt;
8767 rt_min[iname] = (ct_name[iname] <= 0 ? dt :
MIN(rt_min[iname], dt));
8768 rt_max[iname] = (ct_name[iname] <= 0 ? dt :
MAX(rt_max[iname], dt));
8772 rt_group[igroup] += t1 - t0;
8776 for (
int i = 0; i < nname; i++)
8777 LOG(1,
"TIMER_%s = %.3f s (min= %g s, mean= %g s,"
8778 " max= %g s, n= %d)", names[i], rt_name[i], rt_min[i],
8779 rt_name[i] / ct_name[i], rt_max[i], ct_name[i]);
8780 for (
int i = 0; i < ngroup; i++)
8781 LOG(1,
"TIMER_GROUP_%s = %.3f s", groups[i], rt_group[i]);
8783 for (
int i = 0; i < nname; i++)
8784 total += rt_name[i];
8785 LOG(1,
"TIMER_TOTAL = %.3f s", total);
8789 for (iname = 0; iname < nname; iname++)
8790 if (strcasecmp(name, names[iname]) == 0)
8792 for (igroup = 0; igroup < ngroup; igroup++)
8793 if (strcasecmp(group, groups[igroup]) == 0)
8797 if (iname >= nname) {
8798 sprintf(names[iname],
"%s", name);
8800 ERRMSG(
"Too many timers!");
8804 if (igroup >= ngroup) {
8805 sprintf(groups[igroup],
"%s", group);
8806 if ((++ngroup) >=
NTIMER)
8807 ERRMSG(
"Too many groups!");
8817 const char *filename,
8825 int len = (int) strlen(filename);
8826 sprintf(tstr,
"%.4s", &filename[len - offset]);
8827 int year = atoi(tstr);
8828 sprintf(tstr,
"%.2s", &filename[len - offset + 5]);
8829 int mon = atoi(tstr);
8830 sprintf(tstr,
"%.2s", &filename[len - offset + 8]);
8831 int day = atoi(tstr);
8832 sprintf(tstr,
"%.2s", &filename[len - offset + 11]);
8833 int hour = atoi(tstr);
8834 sprintf(tstr,
"%.2s", &filename[len - offset + 14]);
8835 int min = atoi(tstr);
8838 if (year < 1900 || year > 2100 || mon < 1 || mon > 12 || day < 1
8839 || day > 31 || hour < 0 || hour > 23 || min < 0 || min > 59)
8840 ERRMSG(
"Cannot read time from filename!");
8843 time2jsec(year, mon, day, hour, min, 0, 0.0, &t);
8860 const double p1 = pt * 0.866877899;
8861 const double p0 = pt / 0.866877899;
8864 if (atm->
p[ip] > p0)
8866 else if (atm->
p[ip] < p1)
8869 return LIN(p0, 1.0, p1, 0.0, atm->
p[ip]);
8875 const char *filename,
8884 LOG(1,
"Write atmospheric data: %s", filename);
8908 ERRMSG(
"Atmospheric data type not supported!");
8912 LOG(2,
"Number of particles: %d", atm->
np);
8913 gsl_stats_minmax(&mini, &maxi, atm->
time, 1, (
size_t) atm->
np);
8914 LOG(2,
"Time range: %.2f ... %.2f s", mini, maxi);
8915 gsl_stats_minmax(&mini, &maxi, atm->
p, 1, (
size_t) atm->
np);
8916 LOG(2,
"Altitude range: %g ... %g km",
Z(maxi),
Z(mini));
8917 LOG(2,
"Pressure range: %g ... %g hPa", maxi, mini);
8918 gsl_stats_minmax(&mini, &maxi, atm->
lon, 1, (
size_t) atm->
np);
8919 LOG(2,
"Longitude range: %g ... %g deg", mini, maxi);
8920 gsl_stats_minmax(&mini, &maxi, atm->
lat, 1, (
size_t) atm->
np);
8921 LOG(2,
"Latitude range: %g ... %g deg", mini, maxi);
8922 for (
int iq = 0; iq < ctl->
nq; iq++) {
8924 sprintf(msg,
"Quantity %s range: %s ... %s %s",
8927 gsl_stats_minmax(&mini, &maxi, atm->
q[iq], 1, (
size_t) atm->
np);
8928 LOG(2, msg, mini, maxi);
8935 const char *filename,
8943 const double t0 = t - 0.5 * ctl->
dt_mod;
8944 const double t1 = t + 0.5 * ctl->
dt_mod;
8950 if (!(out = popen(
"gnuplot",
"w")))
8951 ERRMSG(
"Cannot create pipe to gnuplot!");
8954 fprintf(out,
"set out \"%s.png\"\n", filename);
8958 int year, mon, day, hour, min, sec;
8959 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
8960 fprintf(out,
"timestr=\"%d-%02d-%02d, %02d:%02d UTC\"\n",
8961 year, mon, day, hour, min);
8966 ERRMSG(
"Cannot open file!");
8968 while (fgets(line,
LEN, in))
8969 fprintf(out,
"%s", line);
8976 if (!(out = fopen(filename,
"w")))
8977 ERRMSG(
"Cannot create file!");
8983 "# $2 = altitude [km]\n"
8984 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
8985 for (
int iq = 0; iq < ctl->
nq; iq++)
8986 fprintf(out,
"# $%i = %s [%s]\n", iq + 5, ctl->
qnt_name[iq],
8991 for (
int ip = 0; ip < atm->
np; ip += ctl->
atm_stride) {
8998 fprintf(out,
"%.2f %g %g %g", atm->
time[ip],
Z(atm->
p[ip]),
8999 atm->
lon[ip], atm->
lat[ip]);
9000 for (
int iq = 0; iq < ctl->
nq; iq++) {
9005 fprintf(out, ctl->
qnt_format[iq], atm->
q[iq][ip]);
9017 const char *filename,
9024 if (!(out = fopen(filename,
"w")))
9025 ERRMSG(
"Cannot create file!");
9049 for (
int iq = 0; iq < ctl->
nq; iq++)
9067 const char *filename,
9071 int tid, pid, ncid, varid;
9072 size_t start[2], count[2];
9075 nc_create(filename, NC_NETCDF4, &ncid);
9078 NC(nc_def_dim(ncid,
"time", 1, &tid));
9079 NC(nc_def_dim(ncid,
"NPARTS", (
size_t) atm->
np, &pid));
9082 int dim_ids[2] = { tid, pid };
9083 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"Time",
9084 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
9085 NC_DEF_VAR(
"LAT", NC_DOUBLE, 1, &pid,
"Latitude",
"deg",
9087 NC_DEF_VAR(
"LON", NC_DOUBLE, 1, &pid,
"Longitude",
"deg",
9089 NC_DEF_VAR(
"PRESS", NC_DOUBLE, 1, &pid,
"Pressure",
"hPa",
9092 for (
int iq = 0; iq < ctl->
nq; iq++)
9102 NC(nc_enddef(ncid));
9110 for (
int iq = 0; iq < ctl->
nq; iq++)
9120 const char *dirname,
9126 static size_t out_cnt = 0;
9128 double r, r_start, r_stop;
9129 int year, mon, day, hour, min, sec;
9130 int year_start, mon_start, day_start, hour_start, min_start, sec_start;
9131 int year_stop, mon_stop, day_stop, hour_stop, min_stop, sec_stop;
9132 char filename_out[2 *
LEN] =
"traj_fix_3d_YYYYMMDDHH_YYYYMMDDHH.nc";
9134 int ncid, varid, tid, pid, cid;
9142 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
9144 &min_start, &sec_start, &r_start);
9146 &min_stop, &sec_stop, &r_stop);
9148 sprintf(filename_out,
"%s/traj_fix_3d_%02d%02d%02d%02d_%02d%02d%02d%02d.nc",
9150 year_start % 100, mon_start, day_start, hour_start,
9151 year_stop % 100, mon_stop, day_stop, hour_stop);
9152 LOG(1,
"Write traj file: %s", filename_out);
9158 count[1] = (size_t) atm->
np;
9164 nc_create(filename_out, NC_NETCDF4, &ncid);
9167 NC(nc_def_dim(ncid,
"time", NC_UNLIMITED, &tid));
9168 NC(nc_def_dim(ncid,
"NPARTS", (
size_t) atm->
np, &pid));
9169 NC(nc_def_dim(ncid,
"TMDT", 7, &cid));
9174 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"Time",
9175 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
9176 NC_DEF_VAR(
"LAT", NC_DOUBLE, 2, dim_ids,
"Latitude",
"deg",
9178 NC_DEF_VAR(
"LON", NC_DOUBLE, 2, dim_ids,
"Longitude",
"deg",
9180 NC_DEF_VAR(
"PRESS", NC_DOUBLE, 2, dim_ids,
"Pressure",
"hPa",
9182 NC_DEF_VAR(
"ZETA", NC_DOUBLE, 2, dim_ids,
"Zeta",
"K",
9184 for (
int iq = 0; iq < ctl->
nq; iq++)
9194 NC(nc_enddef(ncid));
9202 NC(nc_open(filename_out, NC_WRITE, &ncid));
9214 for (
int iq = 0; iq < ctl->
nq; iq++)
9221 if ((year == year_stop) && (mon == mon_stop)
9222 && (day == day_stop) && (hour == hour_stop)) {
9225 char filename_init[2 *
LEN] =
"./init_fix_YYYYMMDDHH.nc";
9226 sprintf(filename_init,
"%s/init_fix_%02d%02d%02d%02d.nc",
9227 dirname, year_stop % 100, mon_stop, day_stop, hour_stop);
9228 LOG(1,
"Write init file: %s", filename_init);
9231 nc_create(filename_init, NC_NETCDF4, &ncid);
9234 NC(nc_def_dim(ncid,
"time", 1, &tid));
9235 NC(nc_def_dim(ncid,
"NPARTS", (
size_t) atm->
np, &pid));
9240 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"Time",
9241 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
9242 NC_DEF_VAR(
"LAT", NC_DOUBLE, 1, &pid,
"Latitude",
"deg",
9244 NC_DEF_VAR(
"LON", NC_DOUBLE, 1, &pid,
"Longitude",
"deg",
9246 NC_DEF_VAR(
"PRESS", NC_DOUBLE, 1, &pid,
"Pressure",
"hPa",
9249 for (
int iq = 0; iq < ctl->
nq; iq++)
9259 NC(nc_enddef(ncid));
9267 for (
int iq = 0; iq < ctl->
nq; iq++)
9278 const char *filename,
9282 int ncid, obsid, varid;
9284 size_t start[2], count[2];
9287 NC(nc_create(filename, NC_NETCDF4, &ncid));
9290 NC(nc_def_dim(ncid,
"obs", (
size_t) atm->
np, &obsid));
9293 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &obsid,
"time",
9294 "seconds since 2000-01-01 00:00:00 UTC", ctl->
atm_nc_level, 0);
9295 NC_DEF_VAR(
"press", NC_DOUBLE, 1, &obsid,
"pressure",
"hPa",
9297 NC_DEF_VAR(
"lon", NC_DOUBLE, 1, &obsid,
"longitude",
"degrees_east",
9299 NC_DEF_VAR(
"lat", NC_DOUBLE, 1, &obsid,
"latitude",
"degrees_north",
9301 for (
int iq = 0; iq < ctl->
nq; iq++)
9310 NC(nc_enddef(ncid));
9317 for (
int iq = 0; iq < ctl->
nq; iq++)
9327 const char *filename,
9334 static double *modmean, *obsmean, *obsstd, *rt, *rz, *rlon, *rlat, *robs,
9337 static int *obscount, ct, cx, cy, cz, ip, ix, iy, iz, n, nobs, nk;
9347 ERRMSG(
"Need quantity mass!");
9371 LOG(1,
"Write CSI data: %s", filename);
9372 if (!(out = fopen(filename,
"w")))
9373 ERRMSG(
"Cannot create file!");
9378 "# $2 = number of hits (cx)\n"
9379 "# $3 = number of misses (cy)\n"
9380 "# $4 = number of false alarms (cz)\n"
9381 "# $5 = number of observations (cx + cy)\n"
9382 "# $6 = number of forecasts (cx + cz)\n"
9383 "# $7 = bias (ratio of forecasts and observations) [%%]\n"
9384 "# $8 = probability of detection (POD) [%%]\n"
9385 "# $9 = false alarm rate (FAR) [%%]\n"
9386 "# $10 = critical success index (CSI) [%%]\n");
9388 "# $11 = hits associated with random chance\n"
9389 "# $12 = equitable threat score (ETS) [%%]\n"
9390 "# $13 = Pearson linear correlation coefficient\n"
9391 "# $14 = Spearman rank-order correlation coefficient\n"
9392 "# $15 = column density mean error (F - O) [kg/m^2]\n"
9393 "# $16 = column density root mean square error (RMSE) [kg/m^2]\n"
9394 "# $17 = column density mean absolute error [kg/m^2]\n"
9395 "# $18 = log-likelihood function\n"
9396 "# $19 = number of data points\n\n");
9404 for (iy = 0; iy < ctl->
csi_ny; iy++) {
9405 const double lat = ctl->
csi_lat0 + dlat * (iy + 0.5);
9406 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat));
9411 const double t0 = t - 0.5 * ctl->
dt_mod;
9412 const double t1 = t + 0.5 * ctl->
dt_mod;
9415 ALLOC(modmean,
double,
9417 ALLOC(obsmean,
double,
9419 ALLOC(obscount,
int,
9421 ALLOC(obsstd,
double,
9425 for (
int i = 0; i < nobs; i++) {
9430 else if (rt[i] >= t1)
9434 if (!isfinite(robs[i]))
9438 ix = (int) ((rlon[i] - ctl->
csi_lon0) / dlon);
9439 iy = (int) ((rlat[i] - ctl->
csi_lat0) / dlat);
9440 iz = (int) ((rz[i] - ctl->
csi_z0) / dz);
9443 if (ix < 0 || ix >= ctl->
csi_nx ||
9444 iy < 0 || iy >= ctl->
csi_ny || iz < 0 || iz >= ctl->
csi_nz)
9449 obsmean[idx] += robs[i];
9450 obsstd[idx] +=
SQR(robs[i]);
9455 for (ip = 0; ip < atm->
np; ip++) {
9458 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
9462 ix = (int) ((atm->
lon[ip] - ctl->
csi_lon0) / dlon);
9463 iy = (int) ((atm->
lat[ip] - ctl->
csi_lat0) / dlat);
9464 iz = (int) ((
Z(atm->
p[ip]) - ctl->
csi_z0) / dz);
9467 if (ix < 0 || ix >= ctl->
csi_nx ||
9468 iy < 0 || iy >= ctl->
csi_ny || iz < 0 || iz >= ctl->
csi_nz)
9474 * atm->
q[ctl->
qnt_m][ip];
9478 for (ix = 0; ix < ctl->
csi_nx; ix++)
9479 for (iy = 0; iy < ctl->
csi_ny; iy++)
9480 for (iz = 0; iz < ctl->
csi_nz; iz++) {
9484 if (obscount[idx] > 0) {
9485 obsmean[idx] /= obscount[idx];
9486 obsstd[idx] -=
SQR(obsmean[idx]);
9487 obsstd[idx] = sqrt(obsstd[idx]);
9491 if (modmean[idx] > 0)
9492 modmean[idx] /= (1e6 * area[iy]);
9495 if (obscount[idx] > 0) {
9509 if (obscount[idx] > 0
9512 x[n] = modmean[idx];
9513 y[n] = obsmean[idx];
9515 obsstdn[n] = obsstd[idx];
9517 ERRMSG(
"Too many data points to calculate statistics!");
9526 static double work[2 *
NCSI], work2[2 *
NCSI];;
9527 const int n_obs = cx + cy;
9528 const int n_for = cx + cz;
9529 const double bias = (n_obs > 0) ? 100. * n_for / n_obs : NAN;
9530 const double pod = (n_obs > 0) ? (100. * cx) / n_obs : NAN;
9531 const double far = (n_for > 0) ? (100. * cz) / n_for : NAN;
9533 (cx + cy + cz > 0) ? (100. * cx) / (cx + cy + cz) : NAN;
9534 const double cx_rd = (ct > 0) ? (1. * n_obs * n_for) / ct : NAN;
9535 const double ets = (cx + cy + cz - cx_rd > 0) ?
9536 (100. * (cx - cx_rd)) / (cx + cy + cz - cx_rd) : NAN;
9537 const double rho_p =
9538 (n > 0) ? gsl_stats_correlation(x, 1, y, 1, (
size_t) n) : NAN;
9539 const double rho_s =
9540 (n > 0) ? gsl_stats_spearman(x, 1, y, 1, (
size_t) n, work) : NAN;
9541 for (
int i = 0; i < n; i++) {
9542 work[i] = x[i] - y[i];
9543 work2[i] = (obsstdn[i] != 0) ? (x[i] - y[i]) / obsstdn[i] : 0;
9545 const double mean = (n > 0) ? gsl_stats_mean(work, 1, (
size_t) n) : NAN;
9547 (n > 0) ? gsl_stats_sd_with_fixed_mean(work, 1, (
size_t) n,
9549 const double absdev =
9550 (n > 0) ? gsl_stats_absdev_m(work, 1, (
size_t) n, 0.0) : NAN;
9551 const double loglikelihood =
9552 (n > 0) ? gsl_stats_tss(work2, 1, (
size_t) n) * (-0.5) : GSL_NAN;
9556 "%.2f %d %d %d %d %d %g %g %g %g %g %g %g %g %g %g %g %g %d\n", t,
9557 cx, cy, cz, n_obs, n_for, bias, pod, far, csi, cx_rd, ets, rho_p,
9558 rho_s, mean, rmse, absdev, loglikelihood, n);
9561 n = ct = cx = cy = cz = 0;
9589 const char *filename,
9606 ERRMSG(
"Missing ensemble IDs!");
9609 const double t0 = t - 0.5 * ctl->
dt_mod;
9610 const double t1 = t + 0.5 * ctl->
dt_mod;
9613 for (
int i = 0; i <
NENS; i++) {
9614 for (
int iq = 0; iq < ctl->
nq; iq++)
9615 qm[iq][i] = qs[iq][i] = 0;
9616 xm[i][0] = xm[i][1] = xm[i][2] = zm[i] = 0;
9621 for (
int ip = 0; ip < atm->
np; ip++) {
9624 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
9629 ERRMSG(
"Ensemble ID is out of range!");
9633 for (
int iq = 0; iq < ctl->
nq; iq++) {
9634 qm[iq][ctl->
qnt_ens] += atm->
q[iq][ip];
9645 LOG(1,
"Write ensemble data: %s", filename);
9646 if (!(out = fopen(filename,
"w")))
9647 ERRMSG(
"Cannot create file!");
9652 "# $2 = altitude [km]\n"
9653 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
9654 for (
int iq = 0; iq < ctl->
nq; iq++)
9655 fprintf(out,
"# $%d = %s (mean) [%s]\n", 5 + iq,
9657 for (
int iq = 0; iq < ctl->
nq; iq++)
9658 fprintf(out,
"# $%d = %s (sigma) [%s]\n", 5 + ctl->
nq + iq,
9660 fprintf(out,
"# $%d = number of members\n\n", 5 + 2 * ctl->
nq);
9663 for (
int i = 0; i <
NENS; i++)
9665 cart2geo(xm[i], &dummy, &lon, &lat);
9666 fprintf(out,
"%.2f %g %g %g", t, zm[i] / n[i], lon, lat);
9667 for (
int iq = 0; iq < ctl->
nq; iq++) {
9669 fprintf(out, ctl->
qnt_format[iq], qm[iq][i] / n[i]);
9671 for (
int iq = 0; iq < ctl->
nq; iq++) {
9673 double var = qs[iq][i] / n[i] -
SQR(qm[iq][i] / n[i]);
9674 fprintf(out, ctl->
qnt_format[iq], (var > 0 ? sqrt(var) : 0));
9676 fprintf(out,
" %d\n", n[i]);
9686 const char *filename,
9693 static double kz[
EP], kw[
EP];
9697 double *cd, *mean[
NQ], *sigma[
NQ], *vmr_impl, *z, *lon, *lat, *area, *press;
9699 int *ixs, *iys, *izs, *np;
9705 LOG(1,
"Write grid data: %s", filename);
9718 for (
int iq = 0; iq < ctl->
nq; iq++) {
9719 ALLOC(mean[iq],
double,
9721 ALLOC(sigma[iq],
double,
9724 ALLOC(vmr_impl,
double,
9734 ALLOC(press,
double,
9751#pragma omp parallel
for default(shared)
9752 for (
int iz = 0; iz < ctl->
grid_nz; iz++) {
9753 z[iz] = ctl->
grid_z0 + dz * (iz + 0.5);
9754 press[iz] =
P(z[iz]);
9758 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
9759 lon[ix] = ctl->
grid_lon0 + dlon * (ix + 0.5);
9760#pragma omp parallel for default(shared)
9761 for (
int iy = 0; iy < ctl->
grid_ny; iy++) {
9762 lat[iy] = ctl->
grid_lat0 + dlat * (iy + 0.5);
9763 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat[iy]));
9767 const double t0 = t - 0.5 * ctl->
dt_mod;
9768 const double t1 = t + 0.5 * ctl->
dt_mod;
9771#pragma omp parallel for default(shared)
9772 for (
int ip = 0; ip < atm->
np; ip++) {
9773 ixs[ip] = (int) ((atm->
lon[ip] - ctl->
grid_lon0) / dlon);
9774 iys[ip] = (int) ((atm->
lat[ip] - ctl->
grid_lat0) / dlat);
9775 izs[ip] = (int) ((
Z(atm->
p[ip]) - ctl->
grid_z0) / dz);
9776 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
9777 || ixs[ip] < 0 || ixs[ip] >= ctl->
grid_nx
9778 || iys[ip] < 0 || iys[ip] >= ctl->
grid_ny
9779 || izs[ip] < 0 || izs[ip] >= ctl->
grid_nz)
9784 for (
int ip = 0; ip < atm->
np; ip++)
9790 for (
int iq = 0; iq < ctl->
nq; iq++) {
9791 mean[iq][idx] += kernel * atm->
q[iq][ip];
9792 sigma[iq][idx] +=
SQR(kernel * atm->
q[iq][ip]);
9797#pragma omp parallel for default(shared)
9798 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
9799 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
9800 for (
int iz = 0; iz < ctl->
grid_nz; iz++) {
9807 if (ctl->
qnt_m >= 0)
9808 cd[idx] = mean[ctl->
qnt_m][idx] / (1e6 * area[iy]);
9811 vmr_impl[idx] = NAN;
9812 if (ctl->
qnt_m >= 0 && ctl->
molmass > 0 && met0 != NULL
9815 if (mean[ctl->
qnt_m][idx] > 0) {
9821 lon[ix], lat[iy], &temp, ci, cw, 1);
9825 MA / ctl->
molmass * cd[idx] / (
RHO(press[iz], temp) * dz * 1e3);
9831 for (
int iq = 0; iq < ctl->
nq; iq++) {
9832 mean[iq][idx] /= np[idx];
9833 double var = sigma[iq][idx] / np[idx] -
SQR(mean[iq][idx]);
9834 sigma[iq][idx] = (var > 0 ? sqrt(var) : 0);
9836 for (
int iq = 0; iq < ctl->
nq; iq++) {
9837 mean[iq][idx] = NAN;
9838 sigma[iq][idx] = NAN;
9845 t, z, lon, lat, area, dz, np);
9850 t, z, lon, lat, area, dz, np);
9854 ERRMSG(
"Grid data format GRID_TYPE unknown!");
9858 for (
int iq = 0; iq < ctl->
nq; iq++) {
9877 const char *filename,
9882 const double *vmr_impl,
9897 if (!(out = popen(
"gnuplot",
"w")))
9898 ERRMSG(
"Cannot create pipe to gnuplot!");
9901 fprintf(out,
"set out \"%s.png\"\n", filename);
9905 int year, mon, day, hour, min, sec;
9906 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
9907 fprintf(out,
"timestr=\"%d-%02d-%02d, %02d:%02d UTC\"\n",
9908 year, mon, day, hour, min);
9914 ERRMSG(
"Cannot open file!");
9915 while (fgets(line,
LEN, in))
9916 fprintf(out,
"%s", line);
9923 if (!(out = fopen(filename,
"w")))
9924 ERRMSG(
"Cannot create file!");
9930 "# $2 = altitude [km]\n"
9931 "# $3 = longitude [deg]\n"
9932 "# $4 = latitude [deg]\n"
9933 "# $5 = surface area [km^2]\n"
9934 "# $6 = layer depth [km]\n"
9935 "# $7 = column density (implicit) [kg/m^2]\n"
9936 "# $8 = volume mixing ratio (implicit) [ppv]\n"
9937 "# $9 = number of particles [1]\n");
9938 for (
int iq = 0; iq < ctl->
nq; iq++)
9939 fprintf(out,
"# $%i = %s (mean) [%s]\n", 10 + iq, ctl->
qnt_name[iq],
9942 for (
int iq = 0; iq < ctl->
nq; iq++)
9943 fprintf(out,
"# $%i = %s (stddev) [%s]\n", 10 + ctl->
nq + iq,
9948 for (
int ix = 0; ix < ctl->
grid_nx; ix++) {
9951 for (
int iy = 0; iy < ctl->
grid_ny; iy++) {
9954 for (
int iz = 0; iz < ctl->
grid_nz; iz++) {
9957 fprintf(out,
"%.2f %g %g %g %g %g %g %g %d", t, z[iz], lon[ix],
9958 lat[iy], area[iy], dz, cd[idx], vmr_impl[idx], np[idx]);
9959 for (
int iq = 0; iq < ctl->
nq; iq++) {
9961 fprintf(out, ctl->
qnt_format[iq], mean[iq][idx]);
9964 for (
int iq = 0; iq < ctl->
nq; iq++) {
9966 fprintf(out, ctl->
qnt_format[iq], sigma[iq][idx]);
9981 const char *filename,
9986 const double *vmr_impl,
9995 char longname[2 *
LEN], varname[2 *
LEN];
9999 int *help2, ncid, dimid[10], varid;
10001 size_t start[2], count[2];
10004 ALLOC(help,
double,
10010 NC(nc_create(filename, NC_NETCDF4, &ncid));
10013 NC(nc_def_dim(ncid,
"time", 1, &dimid[0]));
10014 NC(nc_def_dim(ncid,
"z", (
size_t) ctl->
grid_nz, &dimid[1]));
10015 NC(nc_def_dim(ncid,
"lat", (
size_t) ctl->
grid_ny, &dimid[2]));
10016 NC(nc_def_dim(ncid,
"lon", (
size_t) ctl->
grid_nx, &dimid[3]));
10017 NC(nc_def_dim(ncid,
"dz", 1, &dimid[4]));
10020 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &dimid[0],
"time",
10021 "seconds since 2000-01-01 00:00:00 UTC", 0, 0);
10022 NC_DEF_VAR(
"z", NC_DOUBLE, 1, &dimid[1],
"altitude",
"km", 0, 0);
10023 NC_DEF_VAR(
"lat", NC_DOUBLE, 1, &dimid[2],
"latitude",
"degrees_north", 0,
10025 NC_DEF_VAR(
"lon", NC_DOUBLE, 1, &dimid[3],
"longitude",
"degrees_east", 0,
10027 NC_DEF_VAR(
"dz", NC_DOUBLE, 1, &dimid[1],
"layer depth",
"km", 0, 0);
10028 NC_DEF_VAR(
"area", NC_DOUBLE, 1, &dimid[2],
"surface area",
"km**2", 0, 0);
10030 NC_DEF_VAR(
"cd", NC_FLOAT, 4, dimid,
"column density",
"kg m**-2",
10032 NC_DEF_VAR(
"vmr_impl", NC_FLOAT, 4, dimid,
"volume mixing ratio (implicit)",
10034 NC_DEF_VAR(
"np", NC_INT, 4, dimid,
"number of particles",
"1", 0, 0);
10035 for (
int iq = 0; iq < ctl->
nq; iq++) {
10036 sprintf(varname,
"%s_mean", ctl->
qnt_name[iq]);
10037 sprintf(longname,
"%s (mean)", ctl->
qnt_longname[iq]);
10041 sprintf(varname,
"%s_stddev", ctl->
qnt_name[iq]);
10042 sprintf(longname,
"%s (stddev)", ctl->
qnt_longname[iq]);
10048 NC(nc_enddef(ncid));
10058 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
10059 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
10060 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
10065 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
10066 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
10067 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
10072 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
10073 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
10074 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
10079 for (
int iq = 0; iq < ctl->
nq; iq++) {
10080 sprintf(varname,
"%s_mean", ctl->
qnt_name[iq]);
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 for (
int iq = 0; iq < ctl->
nq; iq++) {
10091 sprintf(varname,
"%s_stddev", ctl->
qnt_name[iq]);
10092 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
10093 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
10094 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
10101 NC(nc_close(ncid));
10111 const char *filename,
10119 LOG(1,
"Write meteo data: %s", filename);
10124 ERRMSG(
"MPTRAC was compiled without zfp compression!");
10128 ERRMSG(
"MPTRAC was compiled without zstd compression!");
10132 ERRMSG(
"MPTRAC was compiled without cmultiscale compression!");
10145 ERRMSG(
"MET_TYPE not implemented!");
10151 const char *filename,
10157 if (!(out = fopen(filename,
"w")))
10158 ERRMSG(
"Cannot create file!");
10255 const char *varname) {
10264 for (
int ix = 0; ix < met->
nx; ix++)
10265 for (
int iy = 0; iy < met->
ny; iy++)
10266 help[
ARRAY_2D(ix, iy, met->
ny)] = var[ix][iy];
10269 LOG(2,
"Write 2-D variable: %s (uncompressed)", varname);
10271 (
size_t) (met->
nx * met->
ny),
10285 const char *varname,
10286 const int precision,
10287 const double tolerance) {
10296#pragma omp parallel for default(shared) collapse(2)
10297 for (
int ix = 0; ix < met->
nx; ix++)
10298 for (
int iy = 0; iy < met->
ny; iy++)
10299 for (
int ip = 0; ip < met->
np; ip++)
10300 help[
ARRAY_3D(ix, iy, met->
ny, ip, met->
np)] = var[ix][iy][ip];
10304 LOG(2,
"Write 3-D variable: %s (uncompressed)", varname);
10306 (
size_t) (met->
nx * met->
ny * met->
np),
10313 (
size_t) met->
np, 0, out);
10321 FWRITE(&tolerance,
double,
10325 tolerance, 0, out);
10340 (
size_t) met->
np, 0, out);
10346 ERRMSG(
"MET_TYPE not supported!");
10347 LOG(3,
"%d %g", precision, tolerance);
10357 const char *filename,
10363 size_t start[4], count[4];
10364 nc_create(filename, NC_NETCDF4, &ncid);
10367 int tid, lonid, latid, levid;
10368 NC(nc_def_dim(ncid,
"time", 1, &tid));
10369 NC(nc_def_dim(ncid,
"lon", (
size_t) met->
nx, &lonid));
10370 NC(nc_def_dim(ncid,
"lat", (
size_t) met->
ny, &latid));
10371 NC(nc_def_dim(ncid,
"lev", (
size_t) met->
np, &levid));
10374 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"time",
10375 "seconds since 2000-01-01 00:00:00 UTC", 0, 0);
10376 NC_DEF_VAR(
"lon", NC_DOUBLE, 1, &lonid,
"longitude",
"degrees_east", 0, 0);
10377 NC_DEF_VAR(
"lat", NC_DOUBLE, 1, &latid,
"latitude",
"degrees_north", 0, 0);
10378 NC_DEF_VAR(
"lev", NC_DOUBLE, 1, &levid,
"pressure",
"Pa", 0, 0);
10381 int dimid2[2] = { latid, lonid };
10382 NC_DEF_VAR(
"sp", NC_FLOAT, 2, dimid2,
"Surface pressure",
"Pa",
10384 NC_DEF_VAR(
"z", NC_FLOAT, 2, dimid2,
"Geopotential",
"m**2 s**-2",
10386 NC_DEF_VAR(
"t2m", NC_FLOAT, 2, dimid2,
"2 metre temperature",
"K",
10388 NC_DEF_VAR(
"u10m", NC_FLOAT, 2, dimid2,
"10 metre U wind component",
10390 NC_DEF_VAR(
"v10m", NC_FLOAT, 2, dimid2,
"10 metre V wind component",
10393 "Instantaneous eastward turbulent surface stress",
"N m**-2",
10396 "Instantaneous northward turbulent surface stress",
"N m**-2",
10399 "Instantaneous surface sensible heat flux",
"W m**-1",
10401 NC_DEF_VAR(
"lsm", NC_FLOAT, 2, dimid2,
"Land/sea mask",
"-",
10403 NC_DEF_VAR(
"sstk", NC_FLOAT, 2, dimid2,
"Sea surface temperature",
"K",
10405 NC_DEF_VAR(
"blp", NC_FLOAT, 2, dimid2,
"Boundary layer pressure",
"Pa",
10407 NC_DEF_VAR(
"pt", NC_FLOAT, 2, dimid2,
"Tropopause pressure",
"Pa",
10409 NC_DEF_VAR(
"tt", NC_FLOAT, 2, dimid2,
"Tropopause temperature",
"K",
10411 NC_DEF_VAR(
"zt", NC_FLOAT, 2, dimid2,
"Tropopause height",
"m",
10413 NC_DEF_VAR(
"h2ot", NC_FLOAT, 2, dimid2,
"Tropopause water vapor",
"ppv",
10415 NC_DEF_VAR(
"pct", NC_FLOAT, 2, dimid2,
"Cloud top pressure",
"Pa",
10417 NC_DEF_VAR(
"pcb", NC_FLOAT, 2, dimid2,
"Cloud bottom pressure",
"Pa",
10419 NC_DEF_VAR(
"cl", NC_FLOAT, 2, dimid2,
"Total column cloud water",
"kg m**2",
10422 "Pressure at lifted condensation level (LCL)",
"Pa",
10425 "Pressure at level of free convection (LFC)",
"Pa",
10427 NC_DEF_VAR(
"pel", NC_FLOAT, 2, dimid2,
"Pressure at equilibrium level (EL)",
10430 "Convective available potential energy",
"J kg**-1",
10432 NC_DEF_VAR(
"cin", NC_FLOAT, 2, dimid2,
"Convective inhibition",
"J kg**-1",
10434 NC_DEF_VAR(
"o3c", NC_FLOAT, 2, dimid2,
"Total column ozone",
"DU",
10438 int dimid3[3] = { levid, latid, lonid };
10439 NC_DEF_VAR(
"t", NC_FLOAT, 3, dimid3,
"Temperature",
"K",
10441 NC_DEF_VAR(
"u", NC_FLOAT, 3, dimid3,
"U velocity",
"m s**-1",
10443 NC_DEF_VAR(
"v", NC_FLOAT, 3, dimid3,
"V velocity",
"m s**-1",
10445 NC_DEF_VAR(
"w", NC_FLOAT, 3, dimid3,
"Vertical velocity",
"Pa s**-1",
10447 NC_DEF_VAR(
"q", NC_FLOAT, 3, dimid3,
"Specific humidity",
"kg kg**-1",
10449 NC_DEF_VAR(
"o3", NC_FLOAT, 3, dimid3,
"Ozone mass mixing ratio",
10451 NC_DEF_VAR(
"clwc", NC_FLOAT, 3, dimid3,
"Cloud liquid water content",
10453 NC_DEF_VAR(
"crwc", NC_FLOAT, 3, dimid3,
"Cloud rain water content",
10455 NC_DEF_VAR(
"ciwc", NC_FLOAT, 3, dimid3,
"Cloud ice water content",
10457 NC_DEF_VAR(
"cswc", NC_FLOAT, 3, dimid3,
"Cloud snow water content",
10459 NC_DEF_VAR(
"cc", NC_FLOAT, 3, dimid3,
"Cloud cover",
"-",
10463 NC(nc_enddef(ncid));
10470 for (
int ip = 0; ip < met->
np; ip++)
10471 phelp[ip] = 100. * met->
p[ip];
10514 NC(nc_close(ncid));
10521 const char *varname,
10527 size_t start[4], count[4];
10535 for (
int ix = 0; ix < met->
nx; ix++)
10536 for (
int iy = 0; iy < met->
ny; iy++)
10537 help[
ARRAY_2D(iy, ix, met->
nx)] = scl * var[ix][iy];
10550 const char *varname,
10556 size_t start[4], count[4];
10564 for (
int ix = 0; ix < met->
nx; ix++)
10565 for (
int iy = 0; iy < met->
ny; iy++)
10566 for (
int ip = 0; ip < met->
np; ip++)
10567 help[
ARRAY_3D(ip, iy, met->
ny, ix, met->
nx)] = scl * var[ix][iy][ip];
10579 const char *dirname,
10586 char ext[10], filename[2 *
LEN];
10590 int year, mon, day, hour, min, sec;
10593 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
10604#pragma acc update host(atm[:1])
10612 sprintf(ext,
"tab");
10614 sprintf(ext,
"bin");
10616 sprintf(ext,
"nc");
10617 sprintf(filename,
"%s/%s_%04d_%02d_%02d_%02d_%02d.%s",
10618 dirname, ctl->
atm_basename, year, mon, day, hour, min, ext);
10624 sprintf(filename,
"%s/%s_%04d_%02d_%02d_%02d_%02d.%s",
10627 write_grid(filename, ctl, met0, met1, atm, t);
10632 sprintf(filename,
"%s/%s.tab", dirname, ctl->
csi_basename);
10638 sprintf(filename,
"%s/%s_%04d_%02d_%02d_%02d_%02d.tab",
10639 dirname, ctl->
ens_basename, year, mon, day, hour, min);
10645 sprintf(filename,
"%s/%s.tab", dirname, ctl->
prof_basename);
10646 write_prof(filename, ctl, met0, met1, atm, t);
10657 sprintf(filename,
"%s/%s.tab", dirname, ctl->
stat_basename);
10666 sprintf(filename,
"%s/%s_%05d.vtk", dirname, ctl->
vtk_basename, ++nvtk);
10674 const char *filename,
10683 static double *mass, *obsmean, *rt, *rz, *rlon, *rlat, *robs, *area,
10684 dz, dlon, dlat, *lon, *lat, *z, *press, temp, vmr, h2o, o3;
10686 static int nobs, *obscount, ip, okay;
10695 if (ctl->
qnt_m < 0)
10696 ERRMSG(
"Need quantity mass!");
10700 ERRMSG(
"Specify molar mass!");
10707 ALLOC(area,
double,
10711 ALLOC(press,
double,
10717 ALLOC(rlon,
double,
10719 ALLOC(rlat,
double,
10721 ALLOC(robs,
double,
10728 LOG(1,
"Write profile data: %s", filename);
10729 if (!(out = fopen(filename,
"w")))
10730 ERRMSG(
"Cannot create file!");
10734 "# $1 = time [s]\n"
10735 "# $2 = altitude [km]\n"
10736 "# $3 = longitude [deg]\n"
10737 "# $4 = latitude [deg]\n"
10738 "# $5 = pressure [hPa]\n"
10739 "# $6 = temperature [K]\n"
10740 "# $7 = volume mixing ratio [ppv]\n"
10741 "# $8 = H2O volume mixing ratio [ppv]\n"
10742 "# $9 = O3 volume mixing ratio [ppv]\n"
10743 "# $10 = observed BT index [K]\n"
10744 "# $11 = number of observations\n");
10752 for (
int iz = 0; iz < ctl->
prof_nz; iz++) {
10753 z[iz] = ctl->
prof_z0 + dz * (iz + 0.5);
10754 press[iz] =
P(z[iz]);
10758 for (
int ix = 0; ix < ctl->
prof_nx; ix++)
10759 lon[ix] = ctl->
prof_lon0 + dlon * (ix + 0.5);
10760 for (
int iy = 0; iy < ctl->
prof_ny; iy++) {
10761 lat[iy] = ctl->
prof_lat0 + dlat * (iy + 0.5);
10762 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(
DEG2RAD(lat[iy]));
10767 const double t0 = t - 0.5 * ctl->
dt_mod;
10768 const double t1 = t + 0.5 * ctl->
dt_mod;
10771 ALLOC(mass,
double,
10773 ALLOC(obsmean,
double,
10775 ALLOC(obscount,
int,
10779 for (
int i = 0; i < nobs; i++) {
10784 else if (rt[i] >= t1)
10788 if (!isfinite(robs[i]))
10792 int ix = (int) ((rlon[i] - ctl->
prof_lon0) / dlon);
10793 int iy = (int) ((rlat[i] - ctl->
prof_lat0) / dlat);
10796 if (ix < 0 || ix >= ctl->
prof_nx || iy < 0 || iy >= ctl->
prof_ny)
10801 obsmean[idx] += robs[i];
10806 for (ip = 0; ip < atm->
np; ip++) {
10809 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
10813 int ix = (int) ((atm->
lon[ip] - ctl->
prof_lon0) / dlon);
10814 int iy = (int) ((atm->
lat[ip] - ctl->
prof_lat0) / dlat);
10815 int iz = (int) ((
Z(atm->
p[ip]) - ctl->
prof_z0) / dz);
10818 if (ix < 0 || ix >= ctl->
prof_nx ||
10824 mass[idx] += atm->
q[ctl->
qnt_m][ip];
10828 for (
int ix = 0; ix < ctl->
prof_nx; ix++)
10829 for (
int iy = 0; iy < ctl->
prof_ny; iy++) {
10831 if (obscount[idx2] > 0) {
10835 for (
int iz = 0; iz < ctl->
prof_nz; iz++) {
10837 if (mass[idx3] > 0) {
10846 fprintf(out,
"\n");
10849 for (
int iz = 0; iz < ctl->
prof_nz; iz++) {
10854 lon[ix], lat[iy], &temp, ci, cw, 1);
10856 lon[ix], lat[iy], &h2o, ci, cw, 0);
10858 lon[ix], lat[iy], &o3, ci, cw, 0);
10863 / (
RHO(press[iz], temp) * area[iy] * dz * 1e9);
10866 fprintf(out,
"%.2f %g %g %g %g %g %g %g %g %g %d\n",
10867 t, z[iz], lon[ix], lat[iy], press[iz], temp, vmr, h2o, o3,
10868 obsmean[idx2] / obscount[idx2], obscount[idx2]);
10901 const char *filename,
10910 static double area, dlat, rmax2, *rt, *rz, *rlon, *rlat, *robs, kz[
EP],
10913 static int nobs, nk;
10926 ALLOC(rlon,
double,
10928 ALLOC(rlat,
double,
10930 ALLOC(robs,
double,
10941 LOG(1,
"Write sample data: %s", filename);
10942 if (!(out = fopen(filename,
"w")))
10943 ERRMSG(
"Cannot create file!");
10947 "# $1 = time [s]\n"
10948 "# $2 = altitude [km]\n"
10949 "# $3 = longitude [deg]\n"
10950 "# $4 = latitude [deg]\n"
10951 "# $5 = surface area [km^2]\n"
10952 "# $6 = layer depth [km]\n"
10953 "# $7 = number of particles [1]\n"
10954 "# $8 = column density [kg/m^2]\n"
10955 "# $9 = volume mixing ratio [ppv]\n"
10956 "# $10 = observed BT index [K]\n\n");
10961 area = M_PI * rmax2;
10965 const double t0 = t - 0.5 * ctl->
dt_mod;
10966 const double t1 = t + 0.5 * ctl->
dt_mod;
10969 for (
int i = 0; i < nobs; i++) {
10974 else if (rt[i] >= t1)
10979 geo2cart(0, rlon[i], rlat[i], x0);
10982 const double rp =
P(rz[i]);
10983 const double ptop =
P(rz[i] + ctl->
sample_dz);
10984 const double pbot =
P(rz[i] - ctl->
sample_dz);
10992 for (
int ip = 0; ip < atm->
np; ip++) {
10995 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
10999 if (fabs(rlat[i] - atm->
lat[ip]) > dlat)
11005 if (
DIST2(x0, x1) > rmax2)
11010 if (atm->
p[ip] > pbot || atm->
p[ip] < ptop)
11014 if (ctl->
qnt_m >= 0)
11021 const double cd = mass / (1e6 * area);
11032 rlon[i], rlat[i], &temp, ci, cw, 1);
11041 fprintf(out,
"%.2f %g %g %g %g %g %d %g %g %g\n", rt[i], rz[i],
11042 rlon[i], rlat[i], area, ctl->
sample_dz, np, cd, vmr, robs[i]);
11063 const char *filename,
11070 static double rmax2, x0[3], x1[3];
11079 LOG(1,
"Write station data: %s", filename);
11082 if (!(out = fopen(filename,
"w")))
11083 ERRMSG(
"Cannot create file!");
11087 "# $1 = time [s]\n"
11088 "# $2 = altitude [km]\n"
11089 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
11090 for (
int iq = 0; iq < ctl->
nq; iq++)
11091 fprintf(out,
"# $%i = %s [%s]\n", (iq + 5),
11093 fprintf(out,
"\n");
11101 const double t0 = t - 0.5 * ctl->
dt_mod;
11102 const double t1 = t + 0.5 * ctl->
dt_mod;
11105 for (
int ip = 0; ip < atm->
np; ip++) {
11108 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11124 if (
DIST2(x0, x1) > rmax2)
11132 fprintf(out,
"%.2f %g %g %g",
11133 atm->
time[ip],
Z(atm->
p[ip]), atm->
lon[ip], atm->
lat[ip]);
11134 for (
int iq = 0; iq < ctl->
nq; iq++) {
11136 fprintf(out, ctl->
qnt_format[iq], atm->
q[iq][ip]);
11138 fprintf(out,
"\n");
11149 const char *filename,
11160 LOG(1,
"Write VTK data: %s", filename);
11163 const double t0 = t - 0.5 * ctl->
dt_mod;
11164 const double t1 = t + 0.5 * ctl->
dt_mod;
11167 if (!(out = fopen(filename,
"w")))
11168 ERRMSG(
"Cannot create file!");
11172 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
11173 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11180 "# vtk DataFile Version 3.0\n"
11181 "vtk output\n" "ASCII\n" "DATASET POLYDATA\n");
11184 fprintf(out,
"POINTS %d float\n", np);
11186 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
11187 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11191 const double coslat = cos(
DEG2RAD(atm->
lat[ip]));
11192 const double x = radius * coslat * cos(
DEG2RAD(atm->
lon[ip]));
11193 const double y = radius * coslat * sin(
DEG2RAD(atm->
lon[ip]));
11194 const double z = radius * sin(
DEG2RAD(atm->
lat[ip]));
11195 fprintf(out,
"%g %g %g\n", x, y, z);
11198 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
11199 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11201 fprintf(out,
"%g %g %g\n", atm->
lon[ip], atm->
lat[ip],
11206 fprintf(out,
"POINT_DATA %d\n", np);
11207 for (
int iq = 0; iq < ctl->
nq; iq++) {
11208 fprintf(out,
"SCALARS %s float 1\n" "LOOKUP_TABLE default\n",
11210 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
11211 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
11213 fprintf(out,
"%g\n", atm->
q[iq][ip]);
void read_met_geopot(const ctl_t *ctl, met_t *met)
Calculates geopotential heights from meteorological data.
void day2doy(const int year, const int mon, const int day, int *doy)
Get day of year from date.
void read_met_extrapolate(met_t *met)
Extrapolates meteorological data.
void read_met_levels(const int ncid, const ctl_t *ctl, met_t *met)
Reads meteorological variables at different vertical levels from a NetCDF file.
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 module_wet_deposition(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 write_met_bin_3d(FILE *out, const ctl_t *ctl, met_t *met, float var[EX][EY][EP], const char *varname, const int precision, const double tolerance)
Writes a 3-dimensional meteorological variable to a binary file.
void read_obs(const char *filename, const ctl_t *ctl, double *rt, double *rz, double *rlon, double *rlat, double *robs, int *nobs)
Reads observation data from a file and stores it in arrays.
void get_met(ctl_t *ctl, clim_t *clim, const double t, met_t **met0, met_t **met1)
Retrieves meteorological data for the specified time.
void module_advect(const ctl_t *ctl, 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 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.
void intpol_met_time_3d_ml(const met_t *met0, float array0[EX][EY][EP], const met_t *met1, float array1[EX][EY][EP], const double ts, const double p, const double lon, const double lat, double *var)
Interpolates a meteorological variable in time and 3D space (longitude, latitude, pressure).
int read_atm_nc(const char *filename, const ctl_t *ctl, atm_t *atm)
Reads air parcel data from a generic netCDF file and populates the given atmospheric structure.
void read_met_pbl(const ctl_t *ctl, met_t *met)
Computes the planetary boundary layer (PBL) 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.
int locate_reg(const double *xx, const int n, const double x)
Locate the index of the interval containing a given value in a regular grid.
void get_tropo(const int met_tropo, ctl_t *ctl, clim_t *clim, met_t *met, const double *lons, const int nx, const double *lats, const int ny, double *pt, double *zt, double *tt, double *qt, double *o3t, double *ps, double *zs)
Calculate tropopause data.
void module_chem_init(const ctl_t *ctl, const clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Initializes the chemistry modules by setting atmospheric composition.
int read_clim_ts(const char *filename, clim_ts_t *ts)
Reads a climatological time series from a file and populates the given time series structure.
void module_dry_deposition(const ctl_t *ctl, const cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Simulate dry deposition of atmospheric particles.
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 module_chemgrid(const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, const double tt)
Calculate grid data for chemistry modules.
void read_clim_photo_help(const int ncid, const char *varname, const clim_photo_t *photo, double var[CP][CSZA][CO3])
Reads a 3D climatological photochemistry variable from a NetCDF file.
void read_met_ml2pl(const ctl_t *ctl, const met_t *met, float var[EX][EY][EP], const char *varname)
Interpolates meteorological data to specified pressure levels.
double clim_tropo(const clim_t *clim, const double t, const double lat)
Calculates the tropopause pressure based on climatological data.
void read_obs_nc(const char *filename, double *rt, double *rz, double *rlon, double *rlat, double *robs, int *nobs)
Reads observation data from a NetCDF file.
void read_met_grid(const char *filename, const int ncid, const ctl_t *ctl, met_t *met)
Reads meteorological grid information from a NetCDF file.
void read_met_bin_2d(FILE *in, const met_t *met, float var[EX][EY], const char *varname)
Reads a 2-dimensional meteorological variable from a binary file and stores it in the provided array.
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 time2jsec(const int year, const int mon, const int day, const int hour, const int min, const int sec, const double remain, double *jsec)
Converts time components to seconds since January 1, 2000, 12:00:00 UTC.
void intpol_met_time_3d(const met_t *met0, float array0[EX][EY][EP], const met_t *met1, float array1[EX][EY][EP], const double ts, const double p, const double lon, const double lat, double *var, int *ci, double *cw, const int init)
Interpolates meteorological data in 3D space and time.
void write_atm(const char *filename, const ctl_t *ctl, const atm_t *atm, const double t)
Writes air parcel data to a file in various formats.
void fft_help(double *fcReal, double *fcImag, const int n)
Computes the Fast Fourier Transform (FFT) of a complex sequence.
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_diffusion_meso(const ctl_t *ctl, cache_t *cache, met_t *met0, met_t *met1, atm_t *atm)
Simulate mesoscale diffusion for atmospheric particles.
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 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_advect_init(const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm)
Initializes the advection module by setting up pressure fields.
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_sort_help(double *a, const int *p, const int np)
Reorder an array based on a given permutation.
float stddev(const float *data, const int n)
Calculates the standard deviation of a set of data.
void write_met(const char *filename, const ctl_t *ctl, met_t *met)
Writes meteorological data to a file, supporting multiple formats and compression options.
void module_diffusion_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.
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 module_diffusion_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).
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.
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.
void write_output(const char *dirname, const ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, const double t)
Writes various types of output data to files in a specified directory.
double sza_calc(const double sec, const double lon, const double lat)
Calculates the solar zenith angle.
void module_mixing_help(const ctl_t *ctl, const clim_t *clim, atm_t *atm, const int *ixs, const int *iys, const int *izs, const int qnt_idx)
Perform interparcel mixing for a specific quantity.
void doy2day(const int year, const int doy, int *mon, int *day)
Converts a given day of the year (DOY) to a date (month and day).
void read_ctl(const char *filename, int argc, char *argv[], ctl_t *ctl)
Reads control parameters from a configuration file and populates the given structure.
void intpol_met_time_2d(const met_t *met0, float array0[EX][EY], const met_t *met1, float array1[EX][EY], const double ts, const double lon, const double lat, double *var, int *ci, double *cw, const int init)
Interpolates meteorological data in 2D space and time.
void module_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_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.
int read_atm_clams(const char *filename, const ctl_t *ctl, atm_t *atm)
Reads air parcel data from a CLaMS netCDF file and populates the given atmospheric structure.
int read_atm(const char *filename, const ctl_t *ctl, atm_t *atm)
Reads air parcel data from a specified file into the given atmospheric structure.
void write_vtk(const char *filename, const ctl_t *ctl, const atm_t *atm, const double t)
Writes VTK (Visualization Toolkit) data to a specified file.
void 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 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 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 read_clim(const ctl_t *ctl, clim_t *clim)
Reads various climatological data and populates the given climatology structure.
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.
void intpol_met_space_3d_ml(const met_t *met, float array[EX][EY][EP], const double p, const double lon, const double lat, double *var)
Interpolates a meteorological variable in 3D space (longitude, latitude, pressure).
int read_atm_asc(const char *filename, const ctl_t *ctl, atm_t *atm)
Reads air parcel data from an ASCII file and populates the given atmospheric structure.
void write_sample(const char *filename, const ctl_t *ctl, met_t *met0, met_t *met1, const atm_t *atm, const double t)
Writes sample data to a specified file.
void write_grid(const char *filename, const ctl_t *ctl, met_t *met0, met_t *met1, const atm_t *atm, const double t)
Writes grid data to a file in ASCII or netCDF format.
void write_met_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.
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)
Calculate potential vorticity using the Zeta approximation.
#define RHICE(p, t, h2o)
Compute relative humidity over ice.
#define INTPOL_TIME_ALL(time, p, lon, lat)
Interpolate multiple meteorological variables in time.
#define ALLOC(ptr, type, n)
Allocate memory for a pointer with error handling.
#define SET_ATM(qnt, val)
Set atmospheric quantity value.
#define CTS
Maximum number of data points of climatological time series.
#define DEG2RAD(deg)
Converts degrees to radians.
void broadcast_large_data(void *data, size_t N)
Broadcasts large data across all processes in an MPI communicator.
#define MO3
Molar mass of ozone [g/mol].
#define SQR(x)
Compute the square of a value.
#define RAD2DEG(rad)
Converts radians to degrees.
#define NC_INQ_DIM(dimname, ptr, min, max)
Inquire the length of a dimension in a NetCDF file.
#define NP
Maximum number of atmospheric data points.
#define NTIMER
Maximum number of timers.
#define SELECT_TIMER(id, group, color)
Select and start a timer with specific attributes.
#define INTPOL_2D(var, init)
Perform 2D interpolation for a meteorological variable.
#define RH(p, t, h2o)
Compute relative humidity over water.
#define NC_PUT_FLOAT(varname, ptr, hyperslab)
Write a float array to a NetCDF file.
#define CY
Maximum number of latitudes for climatological data.
#define LOG(level,...)
Print a log message with a specified logging level.
void thrustSortWrapper(double *__restrict__ c, int n, int *__restrict__ index)
Wrapper to Thrust sorting function.
#define NC_DEF_VAR(varname, type, ndims, dims, long_name, units, level, quant)
Define a NetCDF variable with attributes.
#define TDEW(p, h2o)
Calculate dew point temperature.
#define ARRHENIUS(a, b, t)
Calculate the Arrhenius rate constant.
#define NCSI
Maximum number of data points for CSI calculation.
#define NC_GET_DOUBLE(varname, ptr, force)
Retrieve a double-precision variable from a NetCDF file.
#define EP
Maximum number of pressure levels for meteo data.
#define PSAT(t)
Compute saturation pressure over water.
void compress_zstd(const char *varname, float *array, const size_t n, const int decompress, FILE *inout)
Compresses or decompresses an array of floats using the Zstandard (ZSTD) library.
#define RHO(p, t)
Compute density of air.
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).
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].