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 size_t num_chunks = (N + CHUNK_SIZE - 1) / CHUNK_SIZE;
58 for (
size_t i = 0; i < num_chunks; i++) {
61 size_t start = i * CHUNK_SIZE;
62 size_t end = (start + CHUNK_SIZE > N) ? N : start + CHUNK_SIZE;
63 size_t chunk_size = end - start;
66 MPI_Bcast((
char *) data + start, (
int) chunk_size, MPI_BYTE, 0,
80 double radius =
NORM(x);
81 *lat = asin(x[2] / radius) * 180. / M_PI;
82 *lon = atan2(x[1], x[0]) * 180. / M_PI;
97 double oh =
clim_zm(&clim->
oh, t, lat, p);
102 if (sza <= M_PI / 2. * 85. / 90.)
105 return oh * exp(-ctl->
oh_chem_beta / cos(M_PI / 2. * 85. / 90.));
117 for (
int it = 0; it < clim->
oh.
ntime; it++)
118 for (
int iz = 0; iz < clim->
oh.
np; iz++)
119 for (
int iy = 0; iy < clim->
oh.
nlat; iy++) {
126 for (
double lon = -180; lon < 180; lon += 1.0) {
128 if (sza <= M_PI / 2. * 85. / 90.)
131 sum += exp(-ctl->
oh_chem_beta / cos(M_PI / 2. * 85. / 90.));
136 clim->
oh.
vmr[it][iz][iy] /= (sum / (double) n);
151 if (p < photo->p[photo->
np - 1])
152 p_help = photo->
p[photo->
np - 1];
153 else if (p > photo->
p[0])
154 p_help = photo->
p[0];
157 double sza_help = sza;
158 if (sza < photo->sza[0])
159 sza_help = photo->
sza[0];
160 else if (sza > photo->
sza[photo->
nsza - 1])
161 sza_help = photo->
sza[photo->
nsza - 1];
164 double o3c_help = o3c;
165 if (o3c < photo->o3c[0])
166 o3c_help = photo->
o3c[0];
167 else if (o3c > photo->
o3c[photo->
no3c - 1])
168 o3c_help = photo->
o3c[photo->
no3c - 1];
176 double aux00 =
LIN(photo->
p[ip], rate[ip][isza][io3c],
177 photo->
p[ip + 1], rate[ip + 1][isza][io3c], p_help);
178 double aux01 =
LIN(photo->
p[ip], rate[ip][isza][io3c + 1],
179 photo->
p[ip + 1], rate[ip + 1][isza][io3c + 1], p_help);
180 double aux10 =
LIN(photo->
p[ip], rate[ip][isza + 1][io3c],
181 photo->
p[ip + 1], rate[ip + 1][isza + 1][io3c], p_help);
182 double aux11 =
LIN(photo->
p[ip], rate[ip][isza + 1][io3c + 1],
183 photo->
p[ip + 1], rate[ip + 1][isza + 1][io3c + 1],
185 aux00 =
LIN(photo->
o3c[io3c], aux00, photo->
o3c[io3c + 1], aux01, o3c_help);
186 aux11 =
LIN(photo->
o3c[io3c], aux10, photo->
o3c[io3c + 1], aux11, o3c_help);
187 aux00 =
LIN(photo->
sza[isza], aux00, photo->
sza[isza + 1], aux11, sza_help);
188 return MAX(aux00, 0.0);
199 double sec =
FMOD(t, 365.25 * 86400.);
201 sec += 365.25 * 86400.;
209 clim->
tropo[isec][ilat],
211 clim->
tropo[isec][ilat + 1], lat);
213 clim->
tropo[isec + 1][ilat],
215 clim->
tropo[isec + 1][ilat + 1], lat);
225 LOG(1,
"Initialize tropopause data...");
229 double tropo_time[12] = {
230 1209600.00, 3888000.00, 6393600.00,
231 9072000.00, 11664000.00, 14342400.00,
232 16934400.00, 19612800.00, 22291200.00,
233 24883200.00, 27561600.00, 30153600.00
239 double tropo_lat[73] = {
240 -90, -87.5, -85, -82.5, -80, -77.5, -75, -72.5, -70, -67.5,
241 -65, -62.5, -60, -57.5, -55, -52.5, -50, -47.5, -45, -42.5,
242 -40, -37.5, -35, -32.5, -30, -27.5, -25, -22.5, -20, -17.5,
243 -15, -12.5, -10, -7.5, -5, -2.5, 0, 2.5, 5, 7.5, 10, 12.5,
244 15, 17.5, 20, 22.5, 25, 27.5, 30, 32.5, 35, 37.5, 40, 42.5,
245 45, 47.5, 50, 52.5, 55, 57.5, 60, 62.5, 65, 67.5, 70, 72.5,
246 75, 77.5, 80, 82.5, 85, 87.5, 90
251 double tropo[12][73] = {
252 {324.1, 325.6, 325, 324.3, 322.5, 319.7, 314, 307.2, 301.8, 299.6,
253 297.1, 292.2, 285.6, 276.1, 264, 248.9, 231.9, 213.5, 194.4,
254 175.3, 157, 140.4, 126.7, 116.3, 109.5, 105.4, 103, 101.4, 100.4,
255 99.69, 99.19, 98.84, 98.56, 98.39, 98.39, 98.42, 98.44, 98.54,
256 98.68, 98.81, 98.89, 98.96, 99.12, 99.65, 101.4, 105.4, 113.5, 128,
257 152.1, 184.7, 214, 234.1, 247.3, 255.8, 262.6, 267.7, 271.7, 275,
258 277.2, 279, 280.1, 280.4, 280.6, 280.1, 279.3, 278.3, 276.8, 275.8,
259 275.3, 275.6, 275.4, 274.1, 273.5},
260 {337.3, 338.7, 337.8, 336.4, 333, 328.8, 321.1, 312.6, 306.6, 303.7,
261 300.2, 293.8, 285.4, 273.8, 259.6, 242.7, 224.4, 205.2, 186, 167.5,
262 150.3, 135, 122.8, 113.9, 108.2, 104.7, 102.5, 101.1, 100.2, 99.42,
263 98.88, 98.52, 98.25, 98.09, 98.07, 98.1, 98.12, 98.2, 98.25, 98.27,
264 98.26, 98.27, 98.36, 98.79, 100.2, 104.2, 113.7, 131.2, 159.5, 193,
265 220.4, 238.1, 250.2, 258.1, 264.7, 269.7, 273.7, 277.3, 280.2, 282.8,
266 284.9, 286.5, 288.1, 288.8, 289, 288.5, 287.2, 286.3, 286.1, 287.2,
267 287.5, 286.2, 285.8},
268 {335, 336, 335.7, 335.1, 332.3, 328.1, 320.6, 311.8, 305.1, 301.9,
269 297.6, 290, 280.4, 268.3, 254.6, 239.6, 223.9, 207.9, 192.2, 176.9,
270 161.7, 146.4, 132.2, 120.6, 112.3, 107.2, 104.3, 102.4, 101.3,
271 100.4, 99.86, 99.47, 99.16, 98.97, 98.94, 98.97, 99, 99.09, 99.2,
272 99.31, 99.35, 99.41, 99.51, 99.86, 101.1, 104.9, 114.3, 131, 156.8,
273 186.3, 209.3, 224.6, 236.8, 246.3, 254.9, 262.3, 268.8, 274.8,
274 279.9, 284.6, 288.6, 291.6, 294.9, 297.5, 299.8, 301.8, 303.1,
275 304.3, 304.9, 306, 306.6, 306.2, 306},
276 {306.2, 306.7, 305.7, 307.1, 307.3, 306.4, 301.8, 296.2, 292.4,
277 290.3, 287.1, 280.9, 273.4, 264.3, 254.1, 242.8, 231, 219, 207.2,
278 195.5, 183.3, 169.7, 154.7, 138.7, 124.1, 113.6, 107.8, 104.7,
279 102.8, 101.7, 100.9, 100.4, 100, 99.79, 99.7, 99.66, 99.68, 99.79,
280 99.94, 100.2, 100.5, 100.9, 101.4, 102.1, 103.4, 107, 115.2, 129.1,
281 148.7, 171, 190.8, 205.6, 218.4, 229.4, 239.6, 248.6, 256.5,
282 263.7, 270.3, 276.6, 282.6, 288.1, 294.5, 300.4, 306.3, 311.4,
283 315.1, 318.3, 320.3, 322.2, 322.8, 321.5, 321.1},
284 {266.5, 264.9, 260.8, 261, 262, 263, 261.3, 259.7, 259.2, 259.8,
285 260.1, 258.6, 256.7, 253.6, 249.5, 243.9, 237.4, 230, 222.1, 213.9,
286 205, 194.4, 180.4, 161.8, 140.7, 122.9, 112.1, 106.7, 104.1, 102.7,
287 101.8, 101.4, 101.1, 101, 101, 101, 101.1, 101.2, 101.5, 101.9,
288 102.4, 103, 103.8, 104.9, 106.8, 110.1, 115.6, 124, 135.2, 148.9,
289 165.2, 181.3, 198, 211.8, 223.5, 233.8, 242.9, 251.5, 259, 266.2,
290 273.1, 279.2, 286.2, 292.8, 299.6, 306, 311.1, 315.5, 318.8, 322.6,
291 325.3, 325.8, 325.8},
292 {220.1, 218.1, 210.8, 207.2, 207.6, 210.5, 211.4, 213.5, 217.3,
293 222.4, 227.9, 232.8, 237.4, 240.8, 242.8, 243, 241.5, 238.6, 234.2,
294 228.5, 221, 210.7, 195.1, 172.9, 147.8, 127.6, 115.6, 109.9, 107.1,
295 105.7, 105, 104.8, 104.8, 104.9, 105, 105.1, 105.3, 105.5, 105.8,
296 106.4, 107, 107.6, 108.1, 108.8, 110, 111.8, 114.2, 117.4, 121.6,
297 127.9, 137.3, 151.2, 169.5, 189, 205.8, 218.9, 229.1, 237.8, 245,
298 251.5, 257.1, 262.3, 268.2, 274, 280.4, 286.7, 292.4, 297.9, 302.9,
299 308.5, 312.2, 313.1, 313.3},
300 {187.4, 184.5, 173.3, 166.1, 165.4, 167.8, 169.6, 173.6, 179.6,
301 187.9, 198.9, 210, 220.5, 229.2, 235.7, 239.9, 241.8, 241.6, 239.6,
302 235.8, 229.4, 218.6, 200.9, 175.9, 149.4, 129.4, 118.3, 113.1,
303 110.8, 109.7, 109.3, 109.4, 109.7, 110, 110.2, 110.4, 110.5, 110.7,
304 111, 111.4, 111.8, 112.1, 112.3, 112.7, 113.2, 113.9, 115, 116.4,
305 117.9, 120.4, 124.1, 130.9, 142.2, 159.6, 179.6, 198.5, 212.9,
306 224.2, 232.7, 239.1, 243.8, 247.7, 252.4, 257.3, 263.2, 269.5,
307 275.4, 281.1, 286.3, 292, 296.3, 298.2, 298.8},
308 {166, 166.4, 155.7, 148.3, 147.1, 149, 152.1, 157, 163.6, 172.4,
309 185.3, 199.2, 212.6, 224, 233.2, 239.6, 243.3, 244.6, 243.6, 240.3,
310 233.9, 222.6, 203.7, 177, 149.5, 129.7, 119, 114, 111.7, 110.7,
311 110.3, 110.3, 110.6, 110.9, 111.1, 111.3, 111.5, 111.6, 111.9,
312 112.2, 112.5, 112.6, 112.8, 113, 113.4, 114, 115.1, 116.5, 118.3,
313 120.9, 124.4, 130.2, 139.4, 154.6, 173.8, 193.1, 208.1, 220.4,
314 230.1, 238.2, 244.7, 249.5, 254.5, 259.3, 264.5, 269.4, 273.7,
315 278.2, 282.6, 287.4, 290.9, 292.5, 293},
316 {171.9, 172.8, 166.2, 162.3, 161.4, 162.5, 165.2, 169.6, 175.3,
317 183.1, 193.8, 205.9, 218.3, 229.6, 238.5, 244.3, 246.9, 246.7,
318 243.8, 238.4, 230.2, 217.9, 199.6, 174.9, 148.9, 129.8, 119.5,
319 114.8, 112.3, 110.9, 110.3, 110.1, 110.2, 110.3, 110.4, 110.5,
320 110.6, 110.8, 111, 111.4, 111.8, 112, 112.2, 112.4, 112.9, 113.6,
321 114.7, 116.3, 118.4, 121.9, 127.1, 136.1, 149.8, 168.4, 186.9,
322 203.3, 217, 229.1, 238.7, 247, 254, 259.3, 264.3, 268.3, 272.5,
323 276.6, 280.4, 284.4, 288.4, 293.3, 297.2, 298.7, 299.1},
324 {191.6, 192.2, 189, 188.1, 190.2, 193.7, 197.8, 202.9, 208.5,
325 215.6, 224.2, 233.1, 241.2, 247.3, 250.8, 251.3, 248.9, 244.2,
326 237.3, 228.4, 217.2, 202.9, 184.5, 162.5, 140.7, 124.8, 116.2,
327 111.8, 109.4, 107.9, 107, 106.7, 106.6, 106.6, 106.7, 106.7,
328 106.8, 107, 107.4, 108, 108.7, 109.3, 109.8, 110.4, 111.2,
329 112.4, 114.2, 116.9, 121.1, 127.9, 139.3, 155.2, 173.6, 190.7,
330 206.1, 220.1, 232.3, 243, 251.8, 259.2, 265.7, 270.6, 275.3,
331 279.3, 283.3, 286.9, 289.7, 292.8, 296.1, 300.5, 303.9, 304.8,
333 {241.5, 239.6, 236.8, 237.4, 239.4, 242.3, 244.2, 246.4, 249.2,
334 253.6, 258.6, 262.7, 264.8, 264.2, 260.6, 254.1, 245.5, 235.3,
335 223.9, 211.7, 198.3, 183.1, 165.6, 147.1, 130.5, 118.7, 111.9,
336 108.1, 105.8, 104.3, 103.4, 102.8, 102.5, 102.4, 102.5, 102.5,
337 102.5, 102.7, 103.1, 103.8, 104.6, 105.4, 106.1, 107, 108.2,
338 109.9, 112.8, 117.5, 126, 140.4, 161, 181.9, 201.2, 216.8, 230.4,
339 241.8, 251.4, 259.9, 266.9, 272.8, 277.4, 280.4, 282.9, 284.6,
340 286.1, 287.4, 288.3, 289.5, 290.9, 294.2, 296.9, 297.5, 297.6},
341 {301.2, 300.3, 296.6, 295.4, 295, 294.3, 291.2, 287.4, 284.9, 284.7,
342 284.1, 281.5, 277.1, 270.4, 261.7, 250.6, 237.6, 223.1, 207.9, 192,
343 175.8, 158.8, 142.1, 127.6, 116.8, 109.9, 106, 103.6, 102.1, 101.1,
344 100.4, 99.96, 99.6, 99.37, 99.32, 99.32, 99.31, 99.46, 99.77, 100.2,
345 100.7, 101.3, 101.8, 102.7, 104.1, 106.8, 111.9, 121, 136.7, 160,
346 186.9, 209.9, 228.1, 241.2, 251.5, 259.5, 265.7, 270.9, 274.8, 278,
347 280.3, 281.8, 283, 283.3, 283.7, 283.8, 283, 282.2, 281.2, 281.4,
350 memcpy(clim->
tropo, tropo,
sizeof(clim->
tropo));
353 double tropomin = 1e99, tropomax = -1e99;
355 for (
int iy = 0; iy < clim->
tropo_nlat; iy++) {
356 tropomin =
MIN(tropomin, clim->
tropo[it][iy]);
357 tropomax =
MAX(tropomax, clim->
tropo[it][iy]);
362 LOG(2,
"Time steps: %.2f, %.2f ... %.2f s",
366 LOG(2,
"Latitudes: %g, %g ... %g deg",
369 LOG(2,
"Tropopause altitude range: %g ... %g hPa",
Z(tropomax),
371 LOG(2,
"Tropopause pressure range: %g ... %g hPa", tropomin, tropomax);
381 if (t <= ts->time[0])
388 ts->
time[idx + 1], ts->
vmr[idx + 1], t);
401 double sec =
FMOD(t, 365.25 * 86400.);
403 sec += 365.25 * 86400.;
407 if (p < zm->p[zm->
np - 1])
408 p_help = zm->
p[zm->
np - 1];
409 else if (p > zm->
p[0])
413 double lat_help = lat;
414 if (lat < zm->lat[0])
415 lat_help = zm->
lat[0];
416 else if (lat > zm->
lat[zm->
nlat - 1])
417 lat_help = zm->
lat[zm->
nlat - 1];
425 double aux00 =
LIN(zm->
p[ip], zm->
vmr[isec][ip][ilat],
426 zm->
p[ip + 1], zm->
vmr[isec][ip + 1][ilat], p_help);
427 double aux01 =
LIN(zm->
p[ip], zm->
vmr[isec][ip][ilat + 1],
428 zm->
p[ip + 1], zm->
vmr[isec][ip + 1][ilat + 1], p_help);
429 double aux10 =
LIN(zm->
p[ip], zm->
vmr[isec + 1][ip][ilat],
430 zm->
p[ip + 1], zm->
vmr[isec + 1][ip + 1][ilat], p_help);
431 double aux11 =
LIN(zm->
p[ip], zm->
vmr[isec + 1][ip][ilat + 1],
432 zm->
p[ip + 1], zm->
vmr[isec + 1][ip + 1][ilat + 1],
434 aux00 =
LIN(zm->
lat[ilat], aux00, zm->
lat[ilat + 1], aux01, lat_help);
435 aux11 =
LIN(zm->
lat[ilat], aux10, zm->
lat[ilat + 1], aux11, lat_help);
436 aux00 =
LIN(zm->
time[isec], aux00, zm->
time[isec + 1], aux11, sec);
438 return MAX(aux00, 0.0);
455 double lon[
EX], lat[
EY];
456 for (
size_t ix = 0; ix < nx; ix++)
457 lon[ix] = 360. * (
double) ix / ((double) nx - 1.);
458 for (
size_t iy = 0; iy < ny; iy++)
459 lat[iy] = -(180. * (
double) iy / ((double) ny - 1.) - 90);
462 const char domain[] =
"[0.0, 360.0]x[-90.0, 90.0]";
465 const int max_level_grid = 7;
466 cms_param_t *cms_param
467 = cms_set_parameters(nx, ny, max_level_grid, Nd0_x, Nd0_y, domain);
474 for (
size_t ip = 0; ip < np; ip++) {
477 cms_module_t *cms_ptr = cms_init(cms_param);
480 cms_sol_t *cms_sol = cms_read_sol(cms_ptr, inout);
483#pragma omp parallel for default(shared)
484 for (
size_t ix = 0; ix < nx; ix++)
485 for (
size_t iy = 0; iy < ny; iy++) {
486 double val, x[] = { lon[ix], lat[iy] };
487 cms_eval(cms_ptr, cms_sol, x, &val);
488 array[
ARRAY_3D(ix, iy, ny, ip, np)] = (float) val;
492 cr += cms_compression_rate(cms_ptr, cms_sol) / (double) np;
495 cms_delete_module(cms_ptr);
496 cms_delete_sol(cms_sol);
500 LOG(2,
"Read 3-D variable: %s (cms, RATIO= %g)", varname, cr);
507 cms_module_t *cms_ptr[
EP];
508 cms_sol_t *cms_sol[
EP];
511#pragma omp parallel for default(shared)
512 for (
size_t ip = 0; ip < np; ip++) {
515 float tmp_arr[nx * ny];
516 for (
size_t ix = 0; ix < nx; ++ix)
517 for (
size_t iy = 0; iy < ny; ++iy)
521 cms_ptr[ip] = cms_init(cms_param);
524 cms_sol[ip] = cms_read_arr(cms_ptr[ip], tmp_arr, lon, lat, nx, ny);
527 if (strcasecmp(varname,
"Z") == 0)
529 else if (strcasecmp(varname,
"T") == 0)
531 else if (strcasecmp(varname,
"U") == 0)
533 else if (strcasecmp(varname,
"V") == 0)
535 else if (strcasecmp(varname,
"W") == 0)
537 else if (strcasecmp(varname,
"PV") == 0)
539 else if (strcasecmp(varname,
"H2O") == 0)
541 else if (strcasecmp(varname,
"O3") == 0)
543 else if (strcasecmp(varname,
"LWC") == 0)
545 else if (strcasecmp(varname,
"RWC") == 0)
547 else if (strcasecmp(varname,
"IWC") == 0)
549 else if (strcasecmp(varname,
"SWC") == 0)
551 else if (strcasecmp(varname,
"CC") == 0)
554 ERRMSG(
"Variable name unknown!");
557 cms_coarsening(cms_ptr[ip], cms_sol[ip],
563 for (
size_t ip = 0; ip < np; ip++) {
566 double tmp_cms[nx * ny], tmp_org[nx * ny], tmp_diff[nx * ny];
567#pragma omp parallel for default(shared)
568 for (
size_t ix = 0; ix < nx; ix++)
569 for (
size_t iy = 0; iy < ny; iy++) {
570 double val, x[] = { lon[ix], lat[iy] };
571 cms_eval(cms_ptr[ip], cms_sol[ip], x, &val);
572 tmp_cms[
ARRAY_2D(ix, iy, ny)] = val;
580 "cmultiscale: var= %s / lev= %lu / ratio= %g / rho= %g / mean= %g / sd= %g / min= %g / max= %g",
581 varname, ip, cms_compression_rate(cms_ptr[ip], cms_sol[ip]),
582 gsl_stats_correlation(tmp_cms, 1, tmp_org, 1, nx * ny),
583 gsl_stats_mean(tmp_diff, 1, nx * ny), gsl_stats_sd(tmp_diff, 1,
585 gsl_stats_min(tmp_diff, 1, nx * ny), gsl_stats_max(tmp_diff, 1,
590 cr += cms_compression_rate(cms_ptr[ip], cms_sol[ip]) / (double) np;
593 cms_save_sol(cms_sol[ip], cms_ptr[ip], inout);
596 cms_delete_module(cms_ptr[ip]);
597 cms_delete_sol(cms_sol[ip]);
601 LOG(2,
"Write 3-D variable: %s (cms, RATIO= %g)", varname, cr);
605 cms_delete_param(cms_param);
619 double min[
EP], max[
EP], off[
EP], scl[
EP];
621 unsigned short *sarray;
624 ALLOC(sarray,
unsigned short,
631 LOG(2,
"Read 3-D variable: %s (pck, RATIO= %g)",
632 varname, (
double)
sizeof(
float) / (
double)
sizeof(
unsigned short));
641 FREAD(sarray,
unsigned short,
646#pragma omp parallel for default(shared)
647 for (
size_t ixy = 0; ixy < nxy; ixy++)
648 for (
size_t iz = 0; iz < nz; iz++)
650 = (
float) (sarray[ixy * nz + iz] * scl[iz] + off[iz]);
657 LOG(2,
"Write 3-D variable: %s (pck, RATIO= %g)",
658 varname, (
double)
sizeof(
float) / (
double)
sizeof(
unsigned short));
661 for (
size_t iz = 0; iz < nz; iz++) {
665 for (
size_t ixy = 1; ixy < nxy; ixy++)
666 for (
size_t iz = 0; iz < nz; iz++) {
667 if (array[ixy * nz + iz] < min[iz])
668 min[iz] = array[ixy * nz + iz];
669 if (array[ixy * nz + iz] > max[iz])
670 max[iz] = array[ixy * nz + iz];
674 for (
size_t iz = 0; iz < nz; iz++) {
675 scl[iz] = (max[iz] - min[iz]) / 65533.;
680#pragma omp parallel for default(shared)
681 for (
size_t ixy = 0; ixy < nxy; ixy++)
682 for (
size_t iz = 0; iz < nz; iz++)
684 sarray[ixy * nz + iz] = (
unsigned short)
685 ((array[ixy * nz + iz] - off[iz]) / scl[iz] + .5);
687 sarray[ixy * nz + iz] = 0;
696 FWRITE(sarray,
unsigned short,
728 type = zfp_type_float;
729 field = zfp_field_3d(array, type, (uint) nx, (uint) ny, (uint) nz);
732 zfp = zfp_stream_open(NULL);
736 double actual_tol = 0;
738 actual_prec = (int) zfp_stream_set_precision(zfp, (uint) precision);
739 else if (tolerance > 0)
740 actual_tol = zfp_stream_set_accuracy(zfp, tolerance);
742 ERRMSG(
"Set precision or tolerance!");
745 bufsize = zfp_stream_maximum_size(zfp, field);
746 buffer = malloc(bufsize);
749 stream = stream_open(buffer, bufsize);
750 zfp_stream_set_bit_stream(zfp, stream);
751 zfp_stream_rewind(zfp);
755 FREAD(&zfpsize,
size_t,
758 if (fread(buffer, 1, zfpsize, inout) != zfpsize)
759 ERRMSG(
"Error while reading zfp data!");
760 if (!zfp_decompress(zfp, field)) {
761 ERRMSG(
"Decompression failed!");
763 LOG(2,
"Read 3-D variable: %s "
764 "(zfp, PREC= %d, TOL= %g, RATIO= %g)",
765 varname, actual_prec, actual_tol,
766 ((
double) (nx * ny * nz)) / (
double) zfpsize);
771 zfpsize = zfp_compress(zfp, field);
773 ERRMSG(
"Compression failed!");
778 if (fwrite(buffer, 1, zfpsize, inout) != zfpsize)
779 ERRMSG(
"Error while writing zfp data!");
781 LOG(2,
"Write 3-D variable: %s "
782 "(zfp, PREC= %d, TOL= %g, RATIO= %g)",
783 varname, actual_prec, actual_tol,
784 ((
double) (nx * ny * nz)) / (
double) zfpsize);
788 zfp_field_free(field);
789 zfp_stream_close(zfp);
790 stream_close(stream);
806 size_t uncomprLen = n *
sizeof(float);
807 size_t comprLen = ZSTD_compressBound(uncomprLen);
811 char *compr = (
char *) calloc((uint) comprLen, 1);
812 char *uncompr = (
char *) array;
816 FREAD(&comprLen,
size_t,
819 if (fread(compr, 1, comprLen, inout) != comprLen)
820 ERRMSG(
"Error while reading zstd data!");
821 compsize = ZSTD_decompress(uncompr, uncomprLen, compr, comprLen);
822 if (ZSTD_isError(compsize)) {
823 ERRMSG(
"Decompression failed!");
825 LOG(2,
"Read 3-D variable: %s (zstd, RATIO= %g)",
826 varname, ((
double) uncomprLen) / (
double) comprLen);
831 compsize = ZSTD_compress(compr, comprLen, uncompr, uncomprLen, 0);
832 if (ZSTD_isError(compsize)) {
833 ERRMSG(
"Compression failed!");
838 if (fwrite(compr, 1, compsize, inout) != compsize)
839 ERRMSG(
"Error while writing zstd data!");
841 LOG(2,
"Write 3-D variable: %s (zstd, RATIO= %g)",
842 varname, ((
double) uncomprLen) / (
double) compsize);
859 d0[12] = { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 },
860 d0l[12] = { 1, 32, 61, 92, 122, 153, 183, 214, 245, 275, 306, 336 };
863 if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
864 *doy = d0l[mon - 1] + day - 1;
866 *doy = d0[mon - 1] + day - 1;
878 d0[12] = { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 },
879 d0l[12] = { 1, 32, 61, 92, 122, 153, 183, 214, 245, 275, 306, 336 };
884 if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) {
885 for (i = 11; i > 0; i--)
889 *day = doy - d0l[i] + 1;
891 for (i = 11; i > 0; i--)
895 *day = doy - d0[i] + 1;
906 gsl_fft_complex_wavetable *wavetable;
907 gsl_fft_complex_workspace *workspace;
913 ERRMSG(
"Too many data points!");
916 wavetable = gsl_fft_complex_wavetable_alloc((
size_t) n);
917 workspace = gsl_fft_complex_workspace_alloc((
size_t) n);
920 for (
int i = 0; i < n; i++) {
921 data[2 * i] = fcReal[i];
922 data[2 * i + 1] = fcImag[i];
926 gsl_fft_complex_forward(data, 1, (
size_t) n, wavetable, workspace);
929 for (
int i = 0; i < n; i++) {
930 fcReal[i] = data[2 * i];
931 fcImag[i] = data[2 * i + 1];
935 gsl_fft_complex_wavetable_free(wavetable);
936 gsl_fft_complex_workspace_free(workspace);
947 double radius = z +
RE;
948 x[0] = radius * cos(lat / 180. * M_PI) * cos(lon / 180. * M_PI);
949 x[1] = radius * cos(lat / 180. * M_PI) * sin(lon / 180. * M_PI);
950 x[2] = radius * sin(lat / 180. * M_PI);
966 char cachefile[
LEN], cmd[2 *
LEN], filename[
LEN];
972 if (t == ctl->
t_start || !init) {
978 if (!
read_met(filename, ctl, clim, *met0))
979 ERRMSG(
"Cannot open file!");
983 if (!
read_met(filename, ctl, clim, *met1))
984 ERRMSG(
"Cannot open file!");
989 met_t *met0up = *met0;
990 met_t *met1up = *met1;
992#pragma acc update device(met0up[:1],met1up[:1]) async(5)
994#pragma acc update device(met0up[:1],met1up[:1])
1003 sprintf(cmd,
"cat %s > /dev/null &", cachefile);
1004 LOG(1,
"Caching: %s", cachefile);
1005 if (system(cmd) != 0)
1006 WARN(
"Caching command failed!");
1011 if (t > (*met1)->time) {
1020 if (!
read_met(filename, ctl, clim, *met1))
1021 ERRMSG(
"Cannot open file!");
1026 met_t *met1up = *met1;
1028#pragma acc update device(met1up[:1]) async(5)
1030#pragma acc update device(met1up[:1])
1039 sprintf(cmd,
"cat %s > /dev/null &", cachefile);
1040 LOG(1,
"Caching: %s", cachefile);
1041 if (system(cmd) != 0)
1042 WARN(
"Caching command failed!");
1047 if (t < (*met0)->time) {
1056 if (!
read_met(filename, ctl, clim, *met0))
1057 ERRMSG(
"Cannot open file!");
1062 met_t *met0up = *met0;
1064#pragma acc update device(met0up[:1]) async(5)
1066#pragma acc update device(met0up[:1])
1075 sprintf(cmd,
"cat %s > /dev/null &", cachefile);
1076 LOG(1,
"Caching: %s", cachefile);
1077 if (system(cmd) != 0)
1078 WARN(
"Caching command failed!");
1083 if ((*met0)->nx != 0 && (*met1)->nx != 0) {
1084 if ((*met0)->nx != (*met1)->nx
1085 || (*met0)->ny != (*met1)->ny || (*met0)->np != (*met1)->np)
1086 ERRMSG(
"Meteo grid dimensions do not match!");
1087 for (
int ix = 0; ix < (*met0)->nx; ix++)
1088 if (fabs((*met0)->lon[ix] - (*met1)->lon[ix]) > 0.001)
1089 ERRMSG(
"Meteo grid longitudes do not match!");
1090 for (
int iy = 0; iy < (*met0)->ny; iy++)
1091 if (fabs((*met0)->lat[iy] - (*met1)->lat[iy]) > 0.001)
1092 ERRMSG(
"Meteo grid latitudes do not match!");
1093 for (
int ip = 0; ip < (*met0)->np; ip++)
1094 if (fabs((*met0)->p[ip] - (*met1)->p[ip]) > 0.001)
1095 ERRMSG(
"Meteo grid pressure levels do not match!");
1113 int year, mon, day, hour, min, sec;
1117 t6 = floor(t / dt_met) * dt_met;
1119 t6 = ceil(t / dt_met) * dt_met;
1122 jsec2time(t6, &year, &mon, &day, &hour, &min, &sec, &r);
1127 sprintf(filename,
"%s_YYYY_MM_DD_HH.nc", metbase);
1129 sprintf(filename,
"%s_YYYY_MM_DD_HH.bin", metbase);
1131 sprintf(filename,
"%s_YYYY_MM_DD_HH.pck", metbase);
1133 sprintf(filename,
"%s_YYYY_MM_DD_HH.zfp", metbase);
1135 sprintf(filename,
"%s_YYYY_MM_DD_HH.zstd", metbase);
1137 sprintf(filename,
"%s_YYYY_MM_DD_HH.cms", metbase);
1138 sprintf(repl,
"%d", year);
1140 sprintf(repl,
"%02d", mon);
1142 sprintf(repl,
"%02d", day);
1144 sprintf(repl,
"%02d", hour);
1150 sprintf(filename,
"%s_YYMMDDHH.nc", metbase);
1151 sprintf(repl,
"%d", year);
1153 sprintf(repl,
"%02d", year % 100);
1155 sprintf(repl,
"%02d", mon);
1157 sprintf(repl,
"%02d", day);
1159 sprintf(repl,
"%02d", hour);
1174 for (
int i = 0; i < 3; i++) {
1178 if (!(ch = strstr(orig, search)))
1180 strncpy(buffer, orig, (
size_t) (ch - orig));
1181 buffer[ch - orig] = 0;
1182 sprintf(buffer + (ch - orig),
"%s%s", repl, ch + strlen(search));
1184 strcpy(orig, buffer);
1211#pragma omp parallel for default(shared) private(ci,cw)
1212 for (
int ix = 0; ix < nx; ix++)
1213 for (
int iy = 0; iy < ny; iy++) {
1215 &pt[iy * nx + ix], ci, cw, 1);
1217 &ps[iy * nx + ix], ci, cw, 0);
1219 &zs[iy * nx + ix], ci, cw, 0);
1221 lats[iy], &zt[iy * nx + ix], ci, cw, 1);
1223 lats[iy], &tt[iy * nx + ix], ci, cw, 0);
1225 lats[iy], &qt[iy * nx + ix], ci, cw, 0);
1227 lats[iy], &o3t[iy * nx + ix], ci, cw, 0);
1235 float heights0[
EX][
EY][
EP],
1236 float array0[
EX][
EY][
EP],
1238 float heights1[
EX][
EY][
EP],
1239 float array1[
EX][
EY][
EP],
1252 lon =
FMOD(lon, 360.);
1253 if (met0->
lon[met0->
nx - 1] > 180 && lon < 0)
1267 int k_max = ind[0][0];
1268 for (
int i = 0; i < 2; i++)
1269 for (
int j = 0; j < 4; j++) {
1270 if (ci[2] > ind[i][j])
1272 if (k_max < ind[i][j])
1278 cw[0] = (lon - met0->
lon[ci[0]]) /
1279 (met0->
lon[ci[0] + 1] - met0->
lon[ci[0]]);
1280 cw[1] = (lat - met0->
lat[ci[1]]) /
1281 (met0->
lat[ci[1] + 1] - met0->
lat[ci[1]]);
1284 double height_top, height_bot;
1285 double height00, height01, height10, height11, height0, height1;
1288 height00 = cw[3] * (heights1[ci[0]][ci[1]][ci[2]]
1289 - heights0[ci[0]][ci[1]][ci[2]])
1290 + heights0[ci[0]][ci[1]][ci[2]];
1291 height01 = cw[3] * (heights1[ci[0]][ci[1] + 1][ci[2]]
1292 - heights0[ci[0]][ci[1] + 1][ci[2]])
1293 + heights0[ci[0]][ci[1] + 1][ci[2]];
1294 height10 = cw[3] * (heights1[ci[0] + 1][ci[1]][ci[2]]
1295 - heights0[ci[0] + 1][ci[1]][ci[2]])
1296 + heights0[ci[0] + 1][ci[1]][ci[2]];
1297 height11 = cw[3] * (heights1[ci[0] + 1][ci[1] + 1][ci[2]]
1298 - heights0[ci[0] + 1][ci[1] + 1][ci[2]])
1299 + heights0[ci[0] + 1][ci[1] + 1][ci[2]];
1302 height0 = cw[1] * (height01 - height00) + height00;
1303 height1 = cw[1] * (height11 - height10) + height10;
1306 height_bot = cw[0] * (height1 - height0) + height0;
1309 height00 = cw[3] * (heights1[ci[0]][ci[1]][ci[2] + 1]
1310 - heights0[ci[0]][ci[1]][ci[2] + 1])
1311 + heights0[ci[0]][ci[1]][ci[2] + 1];
1312 height01 = cw[3] * (heights1[ci[0]][ci[1] + 1][ci[2] + 1]
1313 - heights0[ci[0]][ci[1] + 1][ci[2] + 1])
1314 + heights0[ci[0]][ci[1] + 1][ci[2] + 1];
1315 height10 = cw[3] * (heights1[ci[0] + 1][ci[1]][ci[2] + 1]
1316 - heights0[ci[0] + 1][ci[1]][ci[2] + 1])
1317 + heights0[ci[0] + 1][ci[1]][ci[2] + 1];
1318 height11 = cw[3] * (heights1[ci[0] + 1][ci[1] + 1][ci[2] + 1]
1319 - heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1])
1320 + heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1];
1323 height0 = cw[1] * (height01 - height00) + height00;
1324 height1 = cw[1] * (height11 - height10) + height10;
1327 height_top = cw[0] * (height1 - height0) + height0;
1330 while (((heights0[0][0][0] > heights0[0][0][1]) &&
1331 ((height_bot <= height) || (height_top > height))
1332 && (height_bot >= height) && (ci[2] < k_max))
1334 ((heights0[0][0][0] < heights0[0][0][1]) &&
1335 ((height_bot >= height) || (height_top < height))
1336 && (height_bot <= height) && (ci[2] < k_max))
1340 height_bot = height_top;
1343 height00 = cw[3] * (heights1[ci[0]][ci[1]][ci[2] + 1]
1344 - heights0[ci[0]][ci[1]][ci[2] + 1])
1345 + heights0[ci[0]][ci[1]][ci[2] + 1];
1346 height01 = cw[3] * (heights1[ci[0]][ci[1] + 1][ci[2] + 1]
1347 - heights0[ci[0]][ci[1] + 1][ci[2] + 1])
1348 + heights0[ci[0]][ci[1] + 1][ci[2] + 1];
1349 height10 = cw[3] * (heights1[ci[0] + 1][ci[1]][ci[2] + 1]
1350 - heights0[ci[0] + 1][ci[1]][ci[2] + 1])
1351 + heights0[ci[0] + 1][ci[1]][ci[2] + 1];
1352 height11 = cw[3] * (heights1[ci[0] + 1][ci[1] + 1][ci[2] + 1]
1353 - heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1])
1354 + heights0[ci[0] + 1][ci[1] + 1][ci[2] + 1];
1357 height0 = cw[1] * (height01 - height00) + height00;
1358 height1 = cw[1] * (height11 - height10) + height10;
1361 height_top = cw[0] * (height1 - height0) + height0;
1365 cw[2] = (height - height_bot)
1366 / (height_top - height_bot);
1370 double array000 = cw[3] * (array1[ci[0]][ci[1]][ci[2]]
1371 - array0[ci[0]][ci[1]][ci[2]])
1372 + array0[ci[0]][ci[1]][ci[2]];
1373 double array100 = cw[3] * (array1[ci[0] + 1][ci[1]][ci[2]]
1374 - array0[ci[0] + 1][ci[1]][ci[2]])
1375 + array0[ci[0] + 1][ci[1]][ci[2]];
1376 double array010 = cw[3] * (array1[ci[0]][ci[1] + 1][ci[2]]
1377 - array0[ci[0]][ci[1] + 1][ci[2]])
1378 + array0[ci[0]][ci[1] + 1][ci[2]];
1379 double array110 = cw[3] * (array1[ci[0] + 1][ci[1] + 1][ci[2]]
1380 - array0[ci[0] + 1][ci[1] + 1][ci[2]])
1381 + array0[ci[0] + 1][ci[1] + 1][ci[2]];
1382 double array001 = cw[3] * (array1[ci[0]][ci[1]][ci[2] + 1]
1383 - array0[ci[0]][ci[1]][ci[2] + 1])
1384 + array0[ci[0]][ci[1]][ci[2] + 1];
1385 double array101 = cw[3] * (array1[ci[0] + 1][ci[1]][ci[2] + 1]
1386 - array0[ci[0] + 1][ci[1]][ci[2] + 1])
1387 + array0[ci[0] + 1][ci[1]][ci[2] + 1];
1388 double array011 = cw[3] * (array1[ci[0]][ci[1] + 1][ci[2] + 1]
1389 - array0[ci[0]][ci[1] + 1][ci[2] + 1])
1390 + array0[ci[0]][ci[1] + 1][ci[2] + 1];
1391 double array111 = cw[3] * (array1[ci[0] + 1][ci[1] + 1][ci[2] + 1]
1392 - array0[ci[0] + 1][ci[1] + 1][ci[2] + 1])
1393 + array0[ci[0] + 1][ci[1] + 1][ci[2] + 1];
1395 double array00 = cw[0] * (array100 - array000) + array000;
1396 double array10 = cw[0] * (array110 - array010) + array010;
1397 double array01 = cw[0] * (array101 - array001) + array001;
1398 double array11 = cw[0] * (array111 - array011) + array011;
1400 double aux0 = cw[1] * (array10 - array00) + array00;
1401 double aux1 = cw[1] * (array11 - array01) + array01;
1404 *var = cw[2] * (aux1 - aux0) + aux0;
1424 if (met->
lon[met->
nx - 1] > 180 && lon < 0)
1433 cw[0] = (met->
p[ci[0] + 1] - p)
1434 / (met->
p[ci[0] + 1] - met->
p[ci[0]]);
1435 cw[1] = (met->
lon[ci[1] + 1] - lon)
1436 / (met->
lon[ci[1] + 1] - met->
lon[ci[1]]);
1437 cw[2] = (met->
lat[ci[2] + 1] - lat)
1438 / (met->
lat[ci[2] + 1] - met->
lat[ci[2]]);
1443 cw[0] * (array[ci[1]][ci[2]][ci[0]] - array[ci[1]][ci[2]][ci[0] + 1])
1444 + array[ci[1]][ci[2]][ci[0] + 1];
1446 cw[0] * (array[ci[1]][ci[2] + 1][ci[0]] -
1447 array[ci[1]][ci[2] + 1][ci[0] + 1])
1448 + array[ci[1]][ci[2] + 1][ci[0] + 1];
1450 cw[0] * (array[ci[1] + 1][ci[2]][ci[0]] -
1451 array[ci[1] + 1][ci[2]][ci[0] + 1])
1452 + array[ci[1] + 1][ci[2]][ci[0] + 1];
1454 cw[0] * (array[ci[1] + 1][ci[2] + 1][ci[0]] -
1455 array[ci[1] + 1][ci[2] + 1][ci[0] + 1])
1456 + array[ci[1] + 1][ci[2] + 1][ci[0] + 1];
1459 aux00 = cw[2] * (aux00 - aux01) + aux01;
1460 aux11 = cw[2] * (aux10 - aux11) + aux11;
1461 *var = cw[1] * (aux00 - aux11) + aux11;
1475 if (met->
lon[met->
nx - 1] > 180 && lon < 0)
1485 if (p >= met->
pl[ix][iy][iz + 1])
1486 aux00 = array[ix][iy][iz + 1];
1487 else if (p <= met->pl[ix][iy][iz])
1488 aux00 = array[ix][iy][iz];
1490 aux00 =
LIN(met->
pl[ix][iy][iz],
1492 met->
pl[ix][iy][iz + 1], array[ix][iy][iz + 1], p);
1496 if (p >= met->
pl[ix][iy + 1][iz + 1])
1497 aux01 = array[ix][iy + 1][iz + 1];
1498 else if (p <= met->pl[ix][iy + 1][iz])
1499 aux01 = array[ix][iy + 1][iz];
1501 aux01 =
LIN(met->
pl[ix][iy + 1][iz],
1502 array[ix][iy + 1][iz],
1503 met->
pl[ix][iy + 1][iz + 1], array[ix][iy + 1][iz + 1], p);
1507 if (p >= met->
pl[ix + 1][iy][iz + 1])
1508 aux10 = array[ix + 1][iy][iz + 1];
1509 else if (p <= met->pl[ix + 1][iy][iz])
1510 aux10 = array[ix + 1][iy][iz];
1512 aux10 =
LIN(met->
pl[ix + 1][iy][iz],
1513 array[ix + 1][iy][iz],
1514 met->
pl[ix + 1][iy][iz + 1], array[ix + 1][iy][iz + 1], p);
1518 if (p >= met->
pl[ix + 1][iy + 1][iz + 1])
1519 aux11 = array[ix + 1][iy + 1][iz + 1];
1520 else if (p <= met->pl[ix + 1][iy + 1][iz])
1521 aux11 = array[ix + 1][iy + 1][iz];
1523 aux11 =
LIN(met->
pl[ix + 1][iy + 1][iz],
1524 array[ix + 1][iy + 1][iz],
1525 met->
pl[ix + 1][iy + 1][iz + 1],
1526 array[ix + 1][iy + 1][iz + 1], p);
1529 double aux0 =
LIN(met->
lat[iy], aux00, met->
lat[iy + 1], aux01, lat);
1530 double aux1 =
LIN(met->
lat[iy], aux10, met->
lat[iy + 1], aux11, lat);
1531 *var =
LIN(met->
lon[ix], aux0, met->
lon[ix + 1], aux1, lon);
1538 float array[
EX][
EY],
1550 if (met->
lon[met->
nx - 1] > 180 && lon < 0)
1558 cw[1] = (met->
lon[ci[1] + 1] - lon)
1559 / (met->
lon[ci[1] + 1] - met->
lon[ci[1]]);
1560 cw[2] = (met->
lat[ci[2] + 1] - lat)
1561 / (met->
lat[ci[2] + 1] - met->
lat[ci[2]]);
1565 double aux00 = array[ci[1]][ci[2]];
1566 double aux01 = array[ci[1]][ci[2] + 1];
1567 double aux10 = array[ci[1] + 1][ci[2]];
1568 double aux11 = array[ci[1] + 1][ci[2] + 1];
1571 if (isfinite(aux00) && isfinite(aux01)
1572 && isfinite(aux10) && isfinite(aux11)) {
1573 aux00 = cw[2] * (aux00 - aux01) + aux01;
1574 aux11 = cw[2] * (aux10 - aux11) + aux11;
1575 *var = cw[1] * (aux00 - aux11) + aux11;
1595 float array0[
EX][
EY][
EP],
1597 float array1[
EX][
EY][
EP],
1607 double var0, var1, wt;
1617 *var = wt * (var0 - var1) + var1;
1624 float array0[
EX][
EY][
EP],
1626 float array1[
EX][
EY][
EP],
1640 *var =
LIN(met0->
time, var0, met1->
time, var1, ts);
1647 float array0[
EX][
EY],
1649 float array1[
EX][
EY],
1658 double var0, var1, wt;
1668 if (isfinite(var0) && isfinite(var1))
1669 *var = wt * (var0 - var1) + var1;
1680 float array0[
EX][
EY],
1682 float array1[
EX][
EY],
1694 double aux0, aux1, aux00, aux01, aux10, aux11, mean = 0;
1701 else if (lon > lons[nlon - 1])
1710 for (
int dx = 0; dx < 2; dx++)
1711 for (
int dy = 0; dy < 2; dy++) {
1712 if (isfinite(array0[ix + dx][iy + dy])) {
1713 mean += array0[ix + dx][iy + dy];
1714 *sigma +=
SQR(array0[ix + dx][iy + dy]);
1717 if (isfinite(array1[ix + dx][iy + dy])) {
1718 mean += array1[ix + dx][iy + dy];
1719 *sigma +=
SQR(array1[ix + dx][iy + dy]);
1724 *sigma = sqrt(
MAX(*sigma / n -
SQR(mean / n), 0.0));
1727 if (method == 1 && isfinite(array0[ix][iy])
1728 && isfinite(array0[ix][iy + 1])
1729 && isfinite(array0[ix + 1][iy])
1730 && isfinite(array0[ix + 1][iy + 1])
1731 && isfinite(array1[ix][iy])
1732 && isfinite(array1[ix][iy + 1])
1733 && isfinite(array1[ix + 1][iy])
1734 && isfinite(array1[ix + 1][iy + 1])) {
1736 aux00 =
LIN(lons[ix], array0[ix][iy],
1737 lons[ix + 1], array0[ix + 1][iy], lon);
1738 aux01 =
LIN(lons[ix], array0[ix][iy + 1],
1739 lons[ix + 1], array0[ix + 1][iy + 1], lon);
1740 aux0 =
LIN(lats[iy], aux00, lats[iy + 1], aux01, lat);
1742 aux10 =
LIN(lons[ix], array1[ix][iy],
1743 lons[ix + 1], array1[ix + 1][iy], lon);
1744 aux11 =
LIN(lons[ix], array1[ix][iy + 1],
1745 lons[ix + 1], array1[ix + 1][iy + 1], lon);
1746 aux1 =
LIN(lats[iy], aux10, lats[iy + 1], aux11, lat);
1748 *var =
LIN(time0, aux0, time1, aux1, time);
1753 aux00 =
NN(lons[ix], array0[ix][iy],
1754 lons[ix + 1], array0[ix + 1][iy], lon);
1755 aux01 =
NN(lons[ix], array0[ix][iy + 1],
1756 lons[ix + 1], array0[ix + 1][iy + 1], lon);
1757 aux0 =
NN(lats[iy], aux00, lats[iy + 1], aux01, lat);
1759 aux10 =
NN(lons[ix], array1[ix][iy],
1760 lons[ix + 1], array1[ix + 1][iy], lon);
1761 aux11 =
NN(lons[ix], array1[ix][iy + 1],
1762 lons[ix + 1], array1[ix + 1][iy + 1], lon);
1763 aux1 =
NN(lats[iy], aux10, lats[iy + 1], aux11, lat);
1765 *var =
NN(time0, aux0, time1, aux1, time);
1790 time_t jsec0 = (time_t) jsec + timegm(&t0);
1791 t1 = gmtime(&jsec0);
1793 *year = t1->tm_year + 1900;
1794 *mon = t1->tm_mon + 1;
1796 *hour = t1->tm_hour;
1799 *remain = jsec - floor(jsec);
1805 const double kz[
EP],
1806 const double kw[
EP],
1820 else if (z > kz[nk - 1])
1824 return LIN(kz[idx], kw[idx], kz[idx + 1], kw[idx + 1], z);
1841 const double a =
RA *
SQR(t), r =
SH(h2o) / (1. -
SH(h2o));
1856 const double press[138] = {
1857 0.0200, 0.0310, 0.0467, 0.0683, 0.0975, 0.1361, 0.1861, 0.2499,
1858 0.3299, 0.4288, 0.5496, 0.6952, 0.8690, 1.0742, 1.3143, 1.5928, 1.9134,
1859 2.2797, 2.6954, 3.1642, 3.6898, 4.2759, 4.9262, 5.6441, 6.4334, 7.2974,
1860 8.2397, 9.2634, 10.3720, 11.5685, 12.8561, 14.2377, 15.7162, 17.2945,
1861 18.9752, 20.7610, 22.6543, 24.6577, 26.7735, 29.0039, 31.3512, 33.8174,
1862 36.4047, 39.1149, 41.9493, 44.9082, 47.9915, 51.1990, 54.5299, 57.9834,
1863 61.5607, 65.2695, 69.1187, 73.1187, 77.2810, 81.6182, 86.1450, 90.8774,
1864 95.8280, 101.0047, 106.4153, 112.0681, 117.9714, 124.1337, 130.5637,
1865 137.2703, 144.2624, 151.5493, 159.1403, 167.0450, 175.2731, 183.8344,
1866 192.7389, 201.9969, 211.6186, 221.6146, 231.9954, 242.7719, 253.9549,
1867 265.5556, 277.5852, 290.0548, 302.9762, 316.3607, 330.2202, 344.5663,
1868 359.4111, 374.7666, 390.6450, 407.0583, 424.0190, 441.5395, 459.6321,
1869 478.3096, 497.5845, 517.4198, 537.7195, 558.3430, 579.1926, 600.1668,
1870 621.1624, 642.0764, 662.8084, 683.2620, 703.3467, 722.9795, 742.0855,
1871 760.5996, 778.4661, 795.6396, 812.0847, 827.7756, 842.6959, 856.8376,
1872 870.2004, 882.7910, 894.6222, 905.7116, 916.0815, 925.7571, 934.7666,
1873 943.1399, 950.9082, 958.1037, 964.7584, 970.9046, 976.5737, 981.7968,
1874 986.6036, 991.0230, 995.0824, 998.8081, 1002.2250, 1005.3562, 1008.2239,
1875 1010.8487, 1013.2500, 1044.45
1878 for (
int ip = 0; ip < ctl->
met_np; ip++)
1885 const double press[92] = {
1886 0.0200, 0.0398, 0.0739, 0.1291, 0.2141, 0.3395, 0.5175, 0.7617,
1887 1.0872, 1.5099, 2.0464, 2.7136, 3.5282, 4.5069, 5.6652, 7.0181,
1888 8.5795, 10.3617, 12.3759, 14.6316, 17.1371, 19.8987, 22.9216, 26.2090,
1889 29.7630, 33.5843, 37.6720, 42.0242, 46.6378, 51.5086, 56.6316, 61.9984,
1890 67.5973, 73.4150, 79.4434, 85.7016, 92.2162, 99.0182, 106.1445,
1892 121.5502, 129.9403, 138.8558, 148.3260, 158.3816, 169.0545, 180.3786,
1893 192.3889, 205.1222, 218.6172, 232.9140, 248.0547, 264.0833, 281.0456,
1894 298.9895, 317.9651, 338.0245, 359.2221, 381.6144, 405.2606, 430.2069,
1895 456.4813, 483.8505, 512.0662, 540.8577, 569.9401, 599.0310, 627.9668,
1896 656.6129, 684.8491, 712.5573, 739.5739, 765.7697, 791.0376, 815.2774,
1897 838.3507, 860.1516, 880.6080, 899.6602, 917.2205, 933.2247, 947.6584,
1898 960.5245, 971.8169, 981.5301, 989.7322, 996.8732, 1002.8013,
1899 1007.4431, 1010.8487, 1013.2500, 1044.45
1902 for (
int ip = 0; ip < ctl->
met_np; ip++)
1909 const double press[60] = {
1910 0.01, 0.1361, 0.2499, 0.4288, 0.6952, 1.0742,
1911 2.2797, 3.1642, 4.2759, 7.2974, 9.2634, 11.5685, 14.2377, 20.761,
1912 24.6577, 33.8174, 39.1149, 51.199, 57.9834, 73.1187, 81.6182,
1913 90.8774, 101.005, 112.068, 124.134, 137.27, 151.549, 167.045, 183.834,
1914 201.997, 221.615, 242.772, 265.556, 290.055, 316.361, 344.566, 374.767,
1915 407.058, 441.539, 478.31, 517.42, 558.343, 600.167, 683.262, 722.979,
1916 760.6, 795.64, 827.776, 856.838, 882.791, 905.712, 925.757, 943.14,
1917 958.104, 972.495, 986.886, 1001.28, 1015.67, 1030.06, 1044.45
1920 for (
int ip = 0; ip < ctl->
met_np; ip++)
1927 const double press[147] = {
1928 0.0200, 0.0310, 0.0467, 0.0683, 0.0975, 0.1361, 0.1861, 0.2499,
1929 0.3299, 0.4288, 0.5496, 0.6952, 0.8690, 1.0742, 1.3143, 1.5928, 1.9134,
1930 2.2797, 2.6954, 3.1642, 3.6898, 4.2759, 4.9262, 5.6441, 6.4334, 7.2974,
1931 8.2397, 9.2634, 10.3720, 11.5685, 12.8561, 14.2377, 15.7162, 17.2945,
1932 18.9752, 20.7610, 22.6543, 24.6577, 26.7735, 29.0039, 31.3512, 33.8174,
1933 36.4047, 39.1149, 41.9493, 44.9082, 47.9915, 51.1990, 54.5299, 57.9834,
1934 61.5607, 65.2695, 69.1187, 73.1187, 77.2810, 81.6182, 86.1450, 90.8774,
1935 95.8280, 101.0047, 106.4153, 112.0681, 117.9714, 124.1337, 130.5637,
1936 137.2703, 144.2624, 151.5493, 159.1403, 167.0450, 175.2731, 183.8344,
1937 192.7389, 201.9969, 211.6186, 221.6146, 231.9954, 242.7719, 253.9549,
1938 265.5556, 277.5852, 290.0548, 302.9762, 316.3607, 330.2202, 344.5663,
1939 359.4111, 374.7666, 390.6450, 407.0583, 424.0190, 441.5395, 459.6321,
1940 478.3096, 497.5845, 517.4198, 537.7195, 558.3430, 579.1926, 600.1668,
1941 621.1624, 642.0764, 662.8084, 683.2620, 703.3467, 722.9795, 742.0855,
1942 760.5996, 778.4661, 795.6396, 812.0847, 827.7756, 842.6959, 856.8376,
1943 870.2004, 882.7910, 894.6222, 905.7116, 916.0815, 925.7571, 934.7666,
1944 943.1399, 950.9082, 958.1037, 964.7584, 970.9046, 976.5737, 981.7968,
1945 986.6036, 991.0230, 995.0824, 998.8081, 1002.2250, 1005.3562, 1008.2239,
1946 1010.8487, 1013.25, 1016.37, 1019.49, 1022.61, 1025.73, 1028.85,
1948 1035.09, 1038.21, 1041.33, 1044.45
1951 for (
int ip = 0; ip < ctl->
met_np; ip++)
1958 const double press[101] = {
1959 0.0200, 0.0398, 0.0739, 0.1291, 0.2141, 0.3395, 0.5175, 0.7617,
1960 1.0872, 1.5099, 2.0464, 2.7136, 3.5282, 4.5069, 5.6652, 7.0181,
1961 8.5795, 10.3617, 12.3759, 14.6316, 17.1371, 19.8987, 22.9216, 26.2090,
1962 29.7630, 33.5843, 37.6720, 42.0242, 46.6378, 51.5086, 56.6316, 61.9984,
1963 67.5973, 73.4150, 79.4434, 85.7016, 92.2162, 99.0182, 106.1445,
1965 121.5502, 129.9403, 138.8558, 148.3260, 158.3816, 169.0545, 180.3786,
1966 192.3889, 205.1222, 218.6172, 232.9140, 248.0547, 264.0833, 281.0456,
1967 298.9895, 317.9651, 338.0245, 359.2221, 381.6144, 405.2606, 430.2069,
1968 456.4813, 483.8505, 512.0662, 540.8577, 569.9401, 599.0310, 627.9668,
1969 656.6129, 684.8491, 712.5573, 739.5739, 765.7697, 791.0376, 815.2774,
1970 838.3507, 860.1516, 880.6080, 899.6602, 917.2205, 933.2247, 947.6584,
1971 960.5245, 971.8169, 981.5301, 989.7322, 996.8732, 1002.8013,
1972 1007.4431, 1010.8487, 1013.25, 1016.37, 1019.49, 1022.61, 1025.73,
1974 1035.09, 1038.21, 1041.33, 1044.45
1977 for (
int ip = 0; ip < ctl->
met_np; ip++)
1984 const double press[62] = {
1985 0.01, 0.1361, 0.2499, 0.4288, 0.6952, 1.0742,
1986 2.2797, 3.1642, 4.2759, 7.2974, 9.2634, 11.5685, 14.2377, 20.761,
1987 24.6577, 33.8174, 39.1149, 51.199, 57.9834, 73.1187, 81.6182,
1988 90.8774, 101.005, 112.068, 124.134, 137.27, 151.549, 167.045, 183.834,
1989 201.997, 221.615, 242.772, 265.556, 290.055, 316.361, 344.566, 374.767,
1990 407.058, 441.539, 478.31, 517.42, 558.343, 600.167, 683.262, 722.979,
1991 760.6, 795.64, 827.776, 856.838, 882.791, 905.712, 925.757, 943.14,
1992 958.104, 972.495, 986.886, 1001.28, 1015.67, 1030.06, 1034.86, 1039.65,
1996 for (
int ip = 0; ip < ctl->
met_np; ip++)
2003 const double press[137] = {
2004 0.01, 0.02, 0.031, 0.0467, 0.0683, 0.0975, 0.1361, 0.1861,
2005 0.2499, 0.3299, 0.4288, 0.5496, 0.6952, 0.869, 1.0742,
2006 1.3143, 1.5928, 1.9134, 2.2797, 2.6954, 3.1642, 3.6898,
2007 4.2759, 4.9262, 5.6441, 6.4334, 7.2974, 8.2397, 9.2634,
2008 10.372, 11.5685, 12.8561, 14.2377, 15.7162, 17.2945, 18.9752,
2009 20.761, 22.6543, 24.6577, 26.7735, 29.0039, 31.3512, 33.8174,
2010 36.4047, 39.1149, 41.9493, 44.9082, 47.9915, 51.199, 54.5299,
2011 57.9834, 61.5607, 65.2695, 69.1187, 73.1187, 77.281, 81.6182,
2012 86.145, 90.8774, 95.828, 101.005, 106.415, 112.068, 117.971,
2013 124.134, 130.564, 137.27, 144.262, 151.549, 159.14, 167.045,
2014 175.273, 183.834, 192.739, 201.997, 211.619, 221.615, 231.995,
2015 242.772, 253.955, 265.556, 277.585, 290.055, 302.976, 316.361,
2016 330.22, 344.566, 359.411, 374.767, 390.645, 407.058, 424.019,
2017 441.539, 459.632, 478.31, 497.584, 517.42, 537.72, 558.343,
2018 579.193, 600.167, 621.162, 642.076, 662.808, 683.262, 703.347,
2019 722.979, 742.086, 760.6, 778.466, 795.64, 812.085, 827.776,
2020 842.696, 856.838, 870.2, 882.791, 894.622, 905.712, 916.081,
2021 925.757, 934.767, 943.14, 950.908, 958.104, 965.299, 972.495,
2022 979.69, 986.886, 994.081, 1001.28, 1008.47, 1015.67, 1022.86,
2023 1030.06, 1037.25, 1044.45
2026 for (
int ip = 0; ip < ctl->
met_np; ip++)
2033 const double press[59] = {
2034 0.1, 0.2, 0.3843, 0.6365, 0.9564, 1.3448, 1.8058, 2.3478,
2035 2.985, 3.7397, 4.6462, 5.7565, 7.1322, 8.8366, 10.9483,
2036 13.5647, 16.8064, 20.8227, 25.7989, 31.9642, 39.6029, 49.0671,
2037 60.1802, 73.0663, 87.7274, 104.229, 122.614, 142.902, 165.089,
2038 189.147, 215.025, 242.652, 272.059, 303.217, 336.044, 370.407,
2039 406.133, 443.009, 480.791, 519.209, 557.973, 596.777, 635.306,
2040 673.24, 710.263, 746.063, 780.346, 812.83, 843.263, 871.42,
2041 897.112, 920.189, 940.551, 958.148, 975.744, 993.341, 1010.94,
2045 for (
int ip = 0; ip < ctl->
met_np; ip++)
2049 ERRMSG(
"Use 0 for l137, 1 for l91, 2 for l60 or values between 3 and 7.")
2062 int i = (ihi + ilo) >> 1;
2064 if (xx[i] < xx[i + 1])
2065 while (ihi > ilo + 1) {
2066 i = (ihi + ilo) >> 1;
2072 while (ihi > ilo + 1) {
2073 i = (ihi + ilo) >> 1;
2093 int i = (ihi + ilo) >> 1;
2095 if (x >= xx[ig] && x < xx[ig + 1])
2098 if (xx[i] < xx[i + 1])
2099 while (ihi > ilo + 1) {
2100 i = (ihi + ilo) >> 1;
2106 while (ihi > ilo + 1) {
2107 i = (ihi + ilo) >> 1;
2120 float profiles[
EX][
EY][
EP],
2128 int i = (ihi + ilo) >> 1;
2130 if (profiles[ind_lon][ind_lat][i] < profiles[ind_lon][ind_lat][i + 1])
2131 while (ihi > ilo + 1) {
2132 i = (ihi + ilo) >> 1;
2133 if (profiles[ind_lon][ind_lat][i] > x) {
2139 while (ihi > ilo + 1) {
2140 i = (ihi + ilo) >> 1;
2141 if (profiles[ind_lon][ind_lat][i] <= x) {
2159 int i = (int) ((x - xx[0]) / (xx[1] - xx[0]));
2173 float profiles[
EX][
EY][
EP],
2183 np, height_ap, ind[0]);
2185 np, height_ap, ind[1]);
2187 np, height_ap, ind[2]);
2206 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,met0,met1,atm,dt)") {
2210 double dts, u[4], um = 0, v[4], vm = 0, w[4], wm = 0,
2214 for (
int i = 0; i < ctl->
advect; i++) {
2219 x[0] = atm->
lon[ip];
2220 x[1] = atm->
lat[ip];
2223 dts = (i == 3 ? 1.0 : 0.5) * dt[ip];
2224 x[0] = atm->
lon[ip] +
DX2DEG(dts * u[i - 1] / 1000., atm->
lat[ip]);
2225 x[1] = atm->
lat[ip] +
DY2DEG(dts * v[i - 1] / 1000.);
2226 x[2] = atm->
p[ip] + dts * w[i - 1];
2228 double tm = atm->
time[ip] + dts;
2233 tm, x[2], x[0], x[1], &u[i], ci, cw, 1);
2235 tm, x[2], x[0], x[1], &v[i], ci, cw, 0);
2237 tm, x[2], x[0], x[1], &w[i], ci, cw, 0);
2253 k = (i == 0 ? 0.0 : 1.0);
2254 else if (ctl->
advect == 4)
2255 k = (i == 0 || i == 3 ? 1.0 / 6.0 : 2.0 / 6.0);
2262 atm->
time[ip] += dt[ip];
2263 atm->
lon[ip] +=
DX2DEG(dt[ip] * um / 1000.,
2264 (ctl->
advect == 2 ? x[1] : atm->
lat[ip]));
2265 atm->
lat[ip] +=
DY2DEG(dt[ip] * vm / 1000.);
2266 atm->
p[ip] += dt[ip] * wm;
2274 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,met0,met1,atm,dt)") {
2281 atm->
lon[ip], atm->
lat[ip],
2286 double dts, u[4], um = 0, v[4], vm = 0, zeta_dot[4], zeta_dotm = 0,
2290 for (
int i = 0; i < ctl->
advect; i++) {
2295 x[0] = atm->
lon[ip];
2296 x[1] = atm->
lat[ip];
2299 dts = (i == 3 ? 1.0 : 0.5) * dt[ip];
2300 x[0] = atm->
lon[ip] +
DX2DEG(dts * u[i - 1] / 1000., atm->
lat[ip]);
2301 x[1] = atm->
lat[ip] +
DY2DEG(dts * v[i - 1] / 1000.);
2302 x[2] = atm->
q[ctl->
qnt_zeta][ip] + dts * zeta_dot[i - 1];
2304 double tm = atm->
time[ip] + dts;
2309 met1->
ul, tm, x[2], x[0], x[1], &u[i], ci, cw, 1);
2311 met1->
vl, tm, x[2], x[0], x[1], &v[i], ci, cw, 0);
2314 x[1], &zeta_dot[i], ci, cw, 0);
2319 k = (i == 0 ? 0.0 : 1.0);
2320 else if (ctl->
advect == 4)
2321 k = (i == 0 || i == 3 ? 1.0 / 6.0 : 2.0 / 6.0);
2324 zeta_dotm += k * zeta_dot[i];
2328 atm->
time[ip] += dt[ip];
2329 atm->
lon[ip] +=
DX2DEG(dt[ip] * um / 1000.,
2330 (ctl->
advect == 2 ? x[1] : atm->
lat[ip]));
2331 atm->
lat[ip] +=
DY2DEG(dt[ip] * vm / 1000.);
2332 atm->
q[ctl->
qnt_zeta][ip] += dt[ip] * zeta_dotm;
2343 atm->
lon[ip], atm->
lat[ip], &atm->
p[ip], ci, cw, 1);
2358#pragma omp parallel for default(shared)
2359 for (
int ip = 0; ip < atm->
np; ip++) {
2363 atm->
lon[ip], atm->
lat[ip], &atm->
p[ip], ci, cw, 1);
2388 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,clim,met0,met1,atm,dt)") {
2424 if (atm->
p[ip] < pbl)
2474 ERRMSG(
"Molar mass is not defined!");
2476 ERRMSG(
"Module needs quantity mass!");
2478 ERRMSG(
"Module needs quantity Cx!");
2484 const int np = atm->
np;
2488 const int ngrid = nx * ny * nz;
2490 double *restrict
const z = (
double *) malloc((
size_t) nz *
sizeof(double));
2491 double *restrict
const press =
2492 (
double *) malloc((
size_t) nz *
sizeof(double));
2493 double *restrict
const mass =
2494 (
double *) calloc((
size_t) ngrid,
sizeof(double));
2495 double *restrict
const area =
2496 (
double *) malloc((
size_t) ny *
sizeof(double));
2497 double *restrict
const lon =
2498 (
double *) malloc((
size_t) nx *
sizeof(double));
2499 double *restrict
const lat =
2500 (
double *) malloc((
size_t) ny *
sizeof(double));
2502 int *restrict
const ixs = (
int *) malloc((
size_t) np *
sizeof(int));
2503 int *restrict
const iys = (
int *) malloc((
size_t) np *
sizeof(int));
2504 int *restrict
const izs = (
int *) malloc((
size_t) np *
sizeof(int));
2513#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])
2514#pragma acc data present(ctl,met0,met1,atm,ixs,iys,izs,z,press,mass,area,lon,lat)
2515#pragma acc parallel loop independent gang vector
2517#pragma omp parallel for default(shared)
2519 for (
int iz = 0; iz < nz; iz++) {
2521 press[iz] =
P(z[iz]);
2525 const double t0 = tt - 0.5 * ctl->
dt_mod;
2526 const double t1 = tt + 0.5 * ctl->
dt_mod;
2530#pragma acc parallel loop independent gang vector
2532#pragma omp parallel for default(shared)
2534 for (
int ip = 0; ip < np; ip++) {
2538 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
2539 || ixs[ip] < 0 || ixs[ip] >= nx
2540 || iys[ip] < 0 || iys[ip] >= ny || izs[ip] < 0 || izs[ip] >= nz)
2546#pragma acc parallel loop independent gang vector
2548#pragma omp parallel for default(shared)
2550 for (
int ix = 0; ix < nx; ix++)
2553#pragma acc parallel loop independent gang vector
2555#pragma omp parallel for default(shared)
2557 for (
int iy = 0; iy < ny; iy++) {
2560 dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(lat[iy] * M_PI / 180.);
2565#pragma acc parallel loop independent gang vector
2567 for (
int ip = 0; ip < np; ip++)
2570#pragma acc atomic update
2572 mass[
ARRAY_3D(ixs[ip], iys[ip], ny, izs[ip], nz)]
2573 += atm->
q[ctl->
qnt_m][ip];
2577#pragma acc parallel loop independent gang vector
2579#pragma omp parallel for default(shared)
2581 for (
int ip = 0; ip < np; ip++)
2588 lon[ixs[ip]], lat[iys[ip]], &temp, ci, cw, 1);
2591 double m = mass[
ARRAY_3D(ixs[ip], iys[ip], ny, izs[ip], nz)];
2595 / (1e9 *
RHO(press[izs[ip]], temp) * area[iys[ip]] * dz);
2598#pragma acc exit data delete(ixs,iys,izs,z,press,mass,area,lon,lat)
2622#pragma omp parallel for default(shared)
2623 for (
int ip = 0; ip < atm->
np; ip++) {
2640 atm->
lon[ip], atm->
lat[ip], atm->
p[ip]));
2642 atm->
lat[ip], atm->
p[ip]));
2644 atm->
lat[ip], atm->
p[ip]));
2646 atm->
lat[ip], atm->
p[ip]));
2661 SELECT_TIMER(
"MODULE_CONVECTION",
"PHYSICS", NVTX_GPU);
2667 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,met0,met1,atm,dt,rs)") {
2675 if (isfinite(cape) && cape >= ctl->
conv_cape) {
2681 if (isfinite(cin) && cin >= ctl->
conv_cin)
2690 if (!isfinite(pel) || atm->
p[ip] < pel)
2694 double pbot = atm->
p[ip];
2695 double ptop = atm->
p[ip];
2707 pbot, atm->
lon[ip], atm->
lat[ip], &tbot, ci, cw, 1);
2709 ptop, atm->
lon[ip], atm->
lat[ip], &ttop, ci, cw, 1);
2710 double rhobot = pbot / tbot;
2711 double rhotop = ptop / ttop;
2714 double rho = rhobot + (rhotop - rhobot) * rs[ip];
2717 atm->
p[ip] =
LIN(rhobot, pbot, rhotop, ptop, rho);
2735 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
2747 double aux = exp(-dt[ip] / tdec);
2748 if (ctl->
qnt_m >= 0) {
2751 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
2752 atm->
q[ctl->
qnt_m][ip] *= aux;
2780 "acc data present(ctl,met0,met1,atm,cache,dt,rs)") {
2788 float umean = 0, usig = 0, vmean = 0, vsig = 0, wmean = 0, wsig = 0;
2789 for (
int i = 0; i < 2; i++)
2790 for (
int j = 0; j < 2; j++)
2791 for (
int k = 0; k < 2; k++) {
2792 umean += met0->
u[ix + i][iy + j][iz + k];
2793 usig +=
SQR(met0->
u[ix + i][iy + j][iz + k]);
2794 vmean += met0->
v[ix + i][iy + j][iz + k];
2795 vsig +=
SQR(met0->
v[ix + i][iy + j][iz + k]);
2796 wmean += met0->
w[ix + i][iy + j][iz + k];
2797 wsig +=
SQR(met0->
w[ix + i][iy + j][iz + k]);
2799 umean += met1->
u[ix + i][iy + j][iz + k];
2800 usig +=
SQR(met1->
u[ix + i][iy + j][iz + k]);
2801 vmean += met1->
v[ix + i][iy + j][iz + k];
2802 vsig +=
SQR(met1->
v[ix + i][iy + j][iz + k]);
2803 wmean += met1->
w[ix + i][iy + j][iz + k];
2804 wsig +=
SQR(met1->
w[ix + i][iy + j][iz + k]);
2806 usig = usig / 16.f -
SQR(umean / 16.f);
2807 usig = (usig > 0 ? sqrtf(usig) : 0);
2808 vsig = vsig / 16.f -
SQR(vmean / 16.f);
2809 vsig = (vsig > 0 ? sqrtf(vsig) : 0);
2810 wsig = wsig / 16.f -
SQR(wmean / 16.f);
2811 wsig = (wsig > 0 ? sqrtf(wsig) : 0);
2814 double r = 1 - 2 * fabs(dt[ip]) / ctl->
dt_met;
2815 double r2 = sqrt(1 - r * r);
2819 cache->
uvwp[ip][0] =
2820 (float) (r * cache->
uvwp[ip][0] +
2825 cache->
uvwp[ip][1] =
2826 (float) (r * cache->
uvwp[ip][1] +
2827 r2 * rs[3 * ip + 1] * ctl->
turb_mesox * vsig);
2828 atm->
lat[ip] +=
DY2DEG(cache->
uvwp[ip][1] * dt[ip] / 1000.);
2833 cache->
uvwp[ip][2] =
2834 (float) (r * cache->
uvwp[ip][2] +
2835 r2 * rs[3 * ip + 2] * ctl->
turb_mesoz * wsig);
2836 atm->
p[ip] += cache->
uvwp[ip][2] * dt[ip];
2857 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,clim,atm,dt,rs)") {
2868 double sigma = sqrt(2.0 * dx * fabs(dt[ip]));
2869 atm->
lon[ip] +=
DX2DEG(rs[3 * ip] * sigma / 1000., atm->
lat[ip]);
2870 atm->
lat[ip] +=
DY2DEG(rs[3 * ip + 1] * sigma / 1000.);
2875 double sigma = sqrt(2.0 * dz * fabs(dt[ip]));
2876 atm->
p[ip] +=
DZ2DP(rs[3 * ip + 2] * sigma / 1000., atm->
p[ip]);
2895 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
2898 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,met0,met1,atm,dt)") {
2930 double aux = exp(-dt[ip] * v_dep / dz);
2931 if (ctl->
qnt_m >= 0) {
2934 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
2935 atm->
q[ctl->
qnt_m][ip] *= aux;
2959 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
2962 const double a = 3.12541941e-06;
2963 const double b = -5.72532259e-01;
2964 const double low = pow(1 / a, 1 / b);
2967 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(clim,ctl,met0,met1,atm,dt)") {
2974 if (!(lwc > 0 || rwc > 0))
2985 double k = 9.1e7 * exp(-29700 /
RI * (1. / t - 1. / 298.15));
2988 double H_SO2 = 1.3e-2 * exp(2900 * (1. / t - 1. / 298.15)) *
RI * t;
2989 double K_1S = 1.23e-2 * exp(2.01e3 * (1. / t - 1. / 298.15));
2992 double H_h2o2 = 8.3e2 * exp(7600 * (1 / t - 1 / 298.15)) *
RI * t;
2998 cor = atm->
q[ctl->
qnt_Cx][ip] >
2999 low ? a * pow(atm->
q[ctl->
qnt_Cx][ip], b) : 1;
3001 double h2o2 = H_h2o2
3003 * M * cor * 1000 /
AVO;
3006 double rho_air = 100 * atm->
p[ip] / (
RI * t) *
MA / 1000;
3007 double CWC = (lwc + rwc) * rho_air / 1000;
3010 double rate_coef = k * K_1S * h2o2 * H_SO2 * CWC;
3011 double aux = exp(-dt[ip] * rate_coef);
3012 if (ctl->
qnt_m >= 0) {
3015 atm->
q[ctl->
qnt_m][ip] *= aux;
3043 for (
int ip = 0; ip < atm->
np; ip++)
3048 for (
int ip = 0; ip < atm->
np; ip++) {
3050 cache->
iso_var[ip] = atm->
p[ip] / t;
3055 for (
int ip = 0; ip < atm->
np; ip++) {
3064 LOG(1,
"Read balloon pressure data: %s", ctl->
balloon);
3068 if (!(in = fopen(ctl->
balloon,
"r")))
3069 ERRMSG(
"Cannot open file!");
3073 while (fgets(line,
LEN, in))
3074 if (sscanf(line,
"%lg %lg", &(cache->
iso_ts[cache->
iso_n]),
3077 ERRMSG(
"Too many data points!");
3080 if (cache->
iso_n < 1)
3081 ERRMSG(
"Could not read any data!");
3102 PARTICLE_LOOP(0, atm->
np, 0,
"acc data present(ctl,met0,met1,atm,cache,dt)") {
3115 atm->
p[ip] = cache->
iso_var[ip] * t;
3121 atm->
p[ip] = 1000. * pow(cache->
iso_var[ip] / t, -1. / 0.286);
3127 atm->
p[ip] = cache->
iso_ps[0];
3154 const int nvar = NVAR, nfix = NFIX, nreact = NREACT;
3155 double rtol[1] = { 1.0e-3 };
3156 double atol[1] = { 1.0 };
3160#pragma acc data copy(rtol,atol,nvar,nfix,nreact)
3162 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,clim,met0,met1,atm,dt) ") {
3164 double var[nvar], fix[nfix], rconst[nreact];
3165 for (
int i = 0; i < nvar; i++) {
3168 for (
int i = 0; i < nfix; i++) {
3171 for (
int i = 0; i < nreact; i++) {
3175 kpp_chem_initialize(ctl, clim, met0, met1, atm, var, fix, rconst, ip);
3181 for (
int i = 0; i < 20; i++) {
3190 Rosenbrock(var, fix, rconst, 0, ctl->
dt_kpp,
3191 atol, rtol, &FunTemplate, &JacTemplate, rpar, ipar);
3194 kpp_chem_output2atm(atm, ctl, met0, met1, var, ip);
3216 ERRMSG(
"Need T_ice and T_NAT to calculate T_STS!");
3219 PARTICLE_LOOP(0, atm->
np, 0,
"acc data present(ctl,clim,met0,met1,atm,dt)") {
3221 double ps, ts, zs, us, vs, lsm, sst, pbl, pt, pct, pcb, cl, plcl, plfc,
3222 pel, cape, cin, o3c, pv, t, tt, u, v, w, h2o, h2ot, o3,
3223 lwc, rwc, iwc, swc, cc, z, zt;
3268 atm->
lon[ip], atm->
lat[ip], atm->
p[ip]));
3270 atm->
lat[ip], atm->
p[ip]));
3272 atm->
lat[ip], atm->
p[ip]));
3274 atm->
lat[ip], atm->
p[ip]));
3275 SET_ATM(qnt_vh, sqrt(u * u + v * v));
3294 atm->
lat[ip], atm->
p[ip])));
3312 const int np = atm->
np;
3313 int *restrict
const ixs = (
int *) malloc((
size_t) np *
sizeof(int));
3314 int *restrict
const iys = (
int *) malloc((
size_t) np *
sizeof(int));
3315 int *restrict
const izs = (
int *) malloc((
size_t) np *
sizeof(int));
3323 const double t0 = t - 0.5 * ctl->
dt_mod;
3324 const double t1 = t + 0.5 * ctl->
dt_mod;
3328#pragma acc enter data create(ixs[0:np],iys[0:np],izs[0:np])
3329#pragma acc data present(ctl,clim,atm,ixs,iys,izs)
3330#pragma acc parallel loop independent gang vector
3332#pragma omp parallel for default(shared)
3334 for (
int ip = 0; ip < np; ip++) {
3337 izs[ip] = (int) ((
Z(atm->
p[ip]) - ctl->
mixing_z0) / dz);
3338 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
3339 || ixs[ip] < 0 || ixs[ip] >= ctl->
mixing_nx
3340 || iys[ip] < 0 || iys[ip] >= ctl->
mixing_ny
3341 || izs[ip] < 0 || izs[ip] >= ctl->
mixing_nz)
3346 if (ctl->
qnt_m >= 0)
3383#pragma acc exit data delete(ixs,iys,izs)
3402 const int np = atm->
np;
3404 double *restrict
const cmean =
3405 (
double *) malloc((
size_t) ngrid *
sizeof(double));
3406 int *restrict
const count = (
int *) malloc((
size_t) ngrid *
sizeof(int));
3410#pragma acc enter data create(cmean[0:ngrid],count[0:ngrid])
3411#pragma acc data present(ctl,clim,atm,ixs,iys,izs,cmean,count)
3412#pragma acc parallel loop independent gang vector
3417#pragma omp parallel for
3419 for (
int i = 0; i < ngrid; i++) {
3426#pragma acc parallel loop independent gang vector
3428 for (
int ip = 0; ip < np; ip++)
3433#pragma acc atomic update
3435 cmean[idx] += atm->
q[qnt_idx][ip];
3437#pragma acc atomic update
3442#pragma acc parallel loop independent gang vector
3447#pragma omp parallel for
3449 for (
int i = 0; i < ngrid; i++)
3451 cmean[i] /= count[i];
3455#pragma acc parallel loop independent gang vector
3457#pragma omp parallel for
3459 for (
int ip = 0; ip < np; ip++)
3463 double mixparam = 1.0;
3471 atm->
q[qnt_idx][ip] +=
3474 - atm->
q[qnt_idx][ip]) * mixparam;
3479#pragma acc exit data delete(cmean,count)
3500 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
3503 const double a = 4.71572206e-08;
3504 const double b = -8.28782867e-01;
3505 const double low = pow(1 / a, 1 / b);
3508 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,clim,met0,met1,atm,dt)") {
3534 0 ? pow(298. / t, ctl->
oh_chem[1]) : 1.);
3537 0 ? pow(298. / t, ctl->
oh_chem[3]) : 1.);
3538 double c = log10(k0 * M / ki);
3539 k = k0 * M / (1. + k0 * M / ki) * pow(0.6, 1. / (1. + c * c));
3548 low ? a * pow(atm->
q[ctl->
qnt_Cx][ip], b) : 1;
3551 double rate_coef = k *
clim_oh(ctl, clim, atm->
time[ip], atm->
lon[ip],
3552 atm->
lat[ip], atm->
p[ip]) * M * cor;
3553 double aux = exp(-dt[ip] * rate_coef);
3554 if (ctl->
qnt_m >= 0) {
3557 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
3558 atm->
q[ctl->
qnt_m][ip] *= aux;
3580 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,met0,met1,atm,dt)") {
3591 while (atm->
lat[ip] < -90 || atm->
lat[ip] > 90) {
3592 if (atm->
lat[ip] > 90) {
3593 atm->
lat[ip] = 180 - atm->
lat[ip];
3594 atm->
lon[ip] += 180;
3596 if (atm->
lat[ip] < -90) {
3597 atm->
lat[ip] = -180 - atm->
lat[ip];
3598 atm->
lon[ip] += 180;
3603 while (atm->
lon[ip] < -180)
3604 atm->
lon[ip] += 360;
3605 while (atm->
lon[ip] >= 180)
3606 atm->
lon[ip] -= 360;
3609 if (atm->
p[ip] < met0->
p[met0->
np - 1]) {
3611 atm->
p[ip] = 2. * met0->
p[met0->
np - 1] - atm->
p[ip];
3613 atm->
p[ip] = met0->
p[met0->
np - 1];
3614 }
else if (atm->
p[ip] > 300.) {
3616 if (atm->
p[ip] > ps) {
3618 atm->
p[ip] = 2. * ps - atm->
p[ip];
3632 gsl_rng_env_setup();
3633 if (omp_get_max_threads() >
NTHREADS)
3634 ERRMSG(
"Too many threads!");
3635 for (
int i = 0; i <
NTHREADS; i++) {
3636 rng[i] = gsl_rng_alloc(gsl_rng_default);
3637 gsl_rng_set(rng[i], gsl_rng_default_seed
3638 + (
long unsigned) (ntask *
NTHREADS + i));
3643 if (curandCreateGenerator(&rng_curand, CURAND_RNG_PSEUDO_DEFAULT) !=
3644 CURAND_STATUS_SUCCESS)
3645 ERRMSG(
"Cannot create random number generator!");
3646 if (curandSetPseudoRandomGeneratorSeed(rng_curand, ntask) !=
3647 CURAND_STATUS_SUCCESS)
3648 ERRMSG(
"Cannot set seed for random number generator!");
3651 (cudaStream_t) acc_get_cuda_stream(acc_async_sync)) !=
3652 CURAND_STATUS_SUCCESS)
3653 ERRMSG(
"Cannot set stream for random number generator!");
3670#pragma omp parallel for default(shared)
3671 for (
size_t i = 0; i < n; ++i)
3672 rs[i] = gsl_rng_uniform(rng[omp_get_thread_num()]);
3676 else if (method == 1) {
3677#pragma omp parallel for default(shared)
3678 for (
size_t i = 0; i < n; ++i)
3679 rs[i] = gsl_ran_gaussian_ziggurat(rng[omp_get_thread_num()], 1.0);
3684#pragma acc update device(rs[:n])
3692 const uint64_t key = 0xc8e4fd154ce32f6d;
3696#pragma acc data present(rs)
3697#pragma acc parallel loop independent gang vector
3699#pragma omp parallel for default(shared)
3701 for (
size_t i = 0; i < n + 1; ++i) {
3702 uint64_t r, t, x, y, z;
3703 y = x = (rng_ctr + i) * key;
3706 x = (x >> 32) | (x << 32);
3708 x = (x >> 32) | (x << 32);
3710 x = (x >> 32) | (x << 32);
3712 x = (x >> 32) | (x << 32);
3713 r = t ^ ((x * x + y) >> 32);
3714 rs[i] = (double) r / (
double) UINT64_MAX;
3721#pragma acc parallel loop independent gang vector
3723#pragma omp parallel for default(shared)
3725 for (
size_t i = 0; i < n; i += 2) {
3726 double r = sqrt(-2.0 * log(rs[i]));
3727 double phi = 2.0 * M_PI * rs[i + 1];
3728 rs[i] = r * cosf((
float) phi);
3729 rs[i + 1] = r * sinf((
float) phi);
3737#pragma acc host_data use_device(rs)
3742 if (curandGenerateUniformDouble(rng_curand, rs, (n < 4 ? 4 : n)) !=
3743 CURAND_STATUS_SUCCESS)
3744 ERRMSG(
"Cannot create random numbers!");
3748 else if (method == 1) {
3749 if (curandGenerateNormalDouble
3750 (rng_curand, rs, (n < 4 ? 4 : n), 0.0,
3751 1.0) != CURAND_STATUS_SUCCESS)
3752 ERRMSG(
"Cannot create random numbers!");
3756 ERRMSG(
"MPTRAC was compiled without cuRAND!");
3774 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,met0,met1,atm,dt)") {
3782 double v_s =
sedi(atm->
p[ip], t, atm->
q[ctl->
qnt_rp][ip],
3786 atm->
p[ip] +=
DZ2DP(v_s * dt[ip] / 1000., atm->
p[ip]);
3801 const int np = atm->
np;
3802 double *restrict
const a = (
double *) malloc((
size_t) np *
sizeof(double));
3803 int *restrict
const p = (
int *) malloc((
size_t) np *
sizeof(int));
3806#pragma acc enter data create(a[0:np],p[0:np])
3807#pragma acc data present(ctl,met0,atm,a,p)
3812#pragma acc parallel loop independent gang vector
3814#pragma omp parallel for default(shared)
3816 for (
int ip = 0; ip < np; ip++) {
3826#pragma acc host_data use_device(a, p)
3831 ERRMSG(
"MPTRAC was compiled without Thrust library!");
3839 for (
int iq = 0; iq < ctl->
nq; iq++)
3844#pragma acc exit data delete(a,p)
3858 double *restrict
const help =
3859 (
double *) malloc((
size_t) np *
sizeof(double));
3863#pragma acc enter data create(help[0:np])
3864#pragma acc data present(a,p,help)
3865#pragma acc parallel loop independent gang vector
3867#pragma omp parallel for default(shared)
3869 for (
int ip = 0; ip < np; ip++)
3870 help[ip] = a[p[ip]];
3872#pragma acc parallel loop independent gang vector
3874#pragma omp parallel for default(shared)
3876 for (
int ip = 0; ip < np; ip++)
3881#pragma acc exit data delete(help)
3898 const double latmin = gsl_stats_min(met0->
lat, 1, (
size_t) met0->
ny),
3899 latmax = gsl_stats_max(met0->
lat, 1, (
size_t) met0->
ny);
3902 (fabs(met0->
lon[met0->
nx - 1] - met0->
lon[0] - 360.0) >= 0.01);
3911 dt[ip] = t - atm->
time[ip];
3916 if (local && (atm->
lon[ip] <= met0->
lon[0]
3917 || atm->
lon[ip] >= met0->
lon[met0->
nx - 1]
3918 || atm->
lat[ip] <= latmin || atm->
lat[ip] >= latmax))
3934 ctl->
t_start = gsl_stats_min(atm->
time, 1, (
size_t) atm->
np);
3936 ctl->
t_stop = gsl_stats_max(atm->
time, 1, (
size_t) atm->
np);
3938 ctl->
t_start = gsl_stats_max(atm->
time, 1, (
size_t) atm->
np);
3940 ctl->
t_stop = gsl_stats_min(atm->
time, 1, (
size_t) atm->
np);
3945 ERRMSG(
"Nothing to do! Check T_STOP and DIRECTION!");
3965 SELECT_TIMER(
"MODULE_TRACERCHEM",
"PHYSICS", NVTX_GPU);
3968 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,clim,met0,atm,met1,dt)") {
3990 double K_o1d =
ARRHENIUS(3.30e-10, 0, t) * o1d * M;
3992 atm->
p[ip], sza, o3c);
3993 atm->
q[ctl->
qnt_Cccl4][ip] *= exp(-dt[ip] * (K_hv + K_o1d));
3998 double K_o1d =
ARRHENIUS(2.30e-10, 0, t) * o1d * M;
4000 atm->
p[ip], sza, o3c);
4001 atm->
q[ctl->
qnt_Cccl3f][ip] *= exp(-dt[ip] * (K_hv + K_o1d));
4006 double K_o1d =
ARRHENIUS(1.40e-10, -25, t) * o1d * M;
4008 atm->
p[ip], sza, o3c);
4009 atm->
q[ctl->
qnt_Cccl2f2][ip] *= exp(-dt[ip] * (K_hv + K_o1d));
4014 double K_o1d =
ARRHENIUS(1.19e-10, -20, t) * o1d * M;
4016 atm->
p[ip], sza, o3c);
4017 atm->
q[ctl->
qnt_Cn2o][ip] *= exp(-dt[ip] * (K_hv + K_o1d));
4036 ERRMSG(
"Module needs quantity mass or volume mixing ratio!");
4039 PARTICLE_LOOP(0, atm->
np, 1,
"acc data present(ctl,met0,met1,atm,dt)") {
4045 if (!isfinite(pct) || atm->
p[ip] <= pct)
4061 double lwc, rwc, iwc, swc;
4066 int inside = (lwc > 0 || rwc > 0 || iwc > 0 || swc > 0);
4080 else if (t <= 238.15)
4100 double K_1 = 1.23e-2 * exp(2.01e3 * (1. / t - 1. / 298.15));
4101 double K_2 = 6e-8 * exp(1.12e3 * (1. / t - 1. / 298.15));
4102 h *= (1 + K_1 / H_ion + K_1 * K_2 / pow(H_ion, 2));
4106 double dz = 1e3 * (
Z(pct) -
Z(pcb));
4109 lambda = h *
RI * t * Is / 3.6e6 / dz * eta;
4135 double dz = 1e3 * (
Z(pct) -
Z(pcb));
4138 lambda = h *
RI * t * Is / 3.6e6 / dz * eta;
4143 double aux = exp(-dt[ip] * lambda);
4144 if (ctl->
qnt_m >= 0) {
4147 += atm->
q[ctl->
qnt_m][ip] * (1 - aux);
4148 atm->
q[ctl->
qnt_m][ip] *= aux;
4162 const double hno3) {
4165 double h2o_help =
MAX(h2o, 0.1e-6);
4168 double p_hno3 = hno3 * p / 1.333224;
4169 double p_h2o = h2o_help * p / 1.333224;
4170 double a = 0.009179 - 0.00088 * log10(p_h2o);
4171 double b = (38.9855 - log10(p_hno3) - 2.7836 * log10(p_h2o)) / a;
4172 double c = -11397.0 / a;
4173 double tnat = (-b + sqrt(b * b - 4. * c)) / 2.;
4174 double x2 = (-b - sqrt(b * b - 4. * c)) / 2.;
4184 const char *filename,
4197 LOG(1,
"Read atmospheric data: %s", filename);
4217 ERRMSG(
"Atmospheric data type not supported!");
4225 ERRMSG(
"Can not read any data!");
4229 LOG(2,
"Number of particles: %d", atm->
np);
4230 gsl_stats_minmax(&mini, &maxi, atm->
time, 1, (
size_t) atm->
np);
4231 LOG(2,
"Time range: %.2f ... %.2f s", mini, maxi);
4232 gsl_stats_minmax(&mini, &maxi, atm->
p, 1, (
size_t) atm->
np);
4233 LOG(2,
"Altitude range: %g ... %g km",
Z(maxi),
Z(mini));
4234 LOG(2,
"Pressure range: %g ... %g hPa", maxi, mini);
4235 gsl_stats_minmax(&mini, &maxi, atm->
lon, 1, (
size_t) atm->
np);
4236 LOG(2,
"Longitude range: %g ... %g deg", mini, maxi);
4237 gsl_stats_minmax(&mini, &maxi, atm->
lat, 1, (
size_t) atm->
np);
4238 LOG(2,
"Latitude range: %g ... %g deg", mini, maxi);
4239 for (
int iq = 0; iq < ctl->
nq; iq++) {
4241 sprintf(msg,
"Quantity %s range: %s ... %s %s",
4244 gsl_stats_minmax(&mini, &maxi, atm->
q[iq], 1, (
size_t) atm->
np);
4245 LOG(2, msg, mini, maxi);
4255 const char *filename,
4261 if (!(in = fopen(filename,
"r"))) {
4262 WARN(
"Cannot open file!");
4268 while (fgets(line,
LEN, in)) {
4272 TOK(line, tok,
"%lg", atm->
time[atm->
np]);
4273 TOK(NULL, tok,
"%lg", atm->
p[atm->
np]);
4274 TOK(NULL, tok,
"%lg", atm->
lon[atm->
np]);
4275 TOK(NULL, tok,
"%lg", atm->
lat[atm->
np]);
4276 for (
int iq = 0; iq < ctl->
nq; iq++)
4277 TOK(NULL, tok,
"%lg", atm->
q[iq][atm->
np]);
4280 atm->
p[atm->
np] =
P(atm->
p[atm->
np]);
4283 if ((++atm->
np) >
NP)
4284 ERRMSG(
"Too many data points!");
4297 const char *filename,
4303 if (!(in = fopen(filename,
"r")))
4308 FREAD(&version,
int,
4312 ERRMSG(
"Wrong version of binary data!");
4330 for (
int iq = 0; iq < ctl->
nq; iq++)
4331 FREAD(atm->
q[iq],
double,
4341 ERRMSG(
"Error while reading binary data!");
4353 const char *filename,
4360 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR)
4367 if (nc_inq_varid(ncid,
"TIME_INIT", &varid) == NC_NOERR) {
4368 NC(nc_get_var_double(ncid, varid, atm->
time));
4370 WARN(
"TIME_INIT not found use time instead!");
4373 for (
int ip = 0; ip < atm->
np; ip++) {
4374 atm->
time[ip] = time_init;
4386 if (nc_inq_varid(ncid,
"PRESS_INIT", &varid) == NC_NOERR) {
4387 NC(nc_get_var_double(ncid, varid, atm->
p));
4389 WARN(
"PRESS_INIT not found use PRESS instead!");
4390 nc_inq_varid(ncid,
"PRESS", &varid);
4391 NC(nc_get_var_double(ncid, varid, atm->
p));
4409 const char *filename,
4416 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR)
4429 for (
int iq = 0; iq < ctl->
nq; iq++)
4502 const char *filename,
4505 int ncid, varid, ip, is, io;
4507 double *help1, *help2, *help3, *help4;
4510 LOG(1,
"Read photolysis rates: %s", filename);
4513 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
4514 WARN(
"Photolysis rate data are missing!");
4521 if (photo->
p[0] < photo->
p[1])
4522 ERRMSG(
"Pressure data are not descending!");
4527 if (photo->
o3c[0] > photo->
o3c[1])
4528 ERRMSG(
"Total column ozone data are not ascending!");
4533 if (photo->
sza[0] > photo->
sza[1])
4534 ERRMSG(
"Solar zenith angle data are not ascending!");
4537 ALLOC(help1,
double,
4539 ALLOC(help2,
double,
4541 ALLOC(help3,
double,
4543 ALLOC(help4,
double,
4549 for (ip = 0; ip < photo->
np; ip++)
4550 for (is = 0; is < photo->
nsza; is++)
4551 for (io = 0; io < photo->
no3c; io++) {
4552 photo->
n2o[ip][is][io] =
4554 photo->
ccl4[ip][is][io] =
4556 photo->
ccl3f[ip][is][io] =
4558 photo->
ccl2f2[ip][is][io] =
4566 for (ip = 0; ip < photo->
np; ip++)
4567 for (is = 0; is < photo->
nsza; is++)
4568 for (io = 0; io < photo->
no3c; io++) {
4569 photo->
o2[ip][is][io] =
4571 photo->
o3_1[ip][is][io] =
4573 photo->
o3_2[ip][is][io] =
4575 photo->
h2o2[ip][is][io] =
4579 for (ip = 0; ip < photo->
np; ip++)
4580 for (is = 0; is < photo->
nsza; is++)
4581 for (io = 0; io < photo->
no3c; io++)
4582 photo->
h2o[ip][is][io] =
4593 LOG(2,
"Number of pressure levels: %d", photo->
np);
4594 LOG(2,
"Altitude levels: %g, %g ... %g km",
4595 Z(photo->
p[0]),
Z(photo->
p[1]),
Z(photo->
p[photo->
np - 1]));
4596 LOG(2,
"Pressure levels: %g, %g ... %g hPa",
4597 photo->
p[0], photo->
p[1], photo->
p[photo->
np - 1]);
4598 LOG(2,
"Number of solar zenith angles: %d", photo->
nsza);
4599 LOG(2,
"Solar zenith angles: %g, %g ... %g deg",
4600 photo->
sza[0] * 180. / M_PI, photo->
sza[1] * 180. / M_PI,
4601 photo->
sza[photo->
nsza - 1] * 180. / M_PI);
4602 LOG(2,
"Number of total column ozone values: %d", photo->
no3c);
4603 LOG(2,
"Total column ozone: %g, %g ... %g DU",
4605 LOG(2,
"N2O photolysis rate: %g, %g ... %g s**-1",
4606 photo->
n2o[0][0][0], photo->
n2o[1][0][0],
4607 photo->
n2o[photo->
np - 1][photo->
nsza - 1][photo->
no3c - 1]);
4608 LOG(2,
"CCl4 photolysis rate: %g, %g ... %g s**-1",
4609 photo->
ccl4[0][0][0], photo->
ccl4[1][0][0],
4611 LOG(2,
"CFC-11 photolysis rate: %g, %g ... %g s**-1",
4612 photo->
ccl3f[0][0][0], photo->
ccl3f[1][0][0],
4614 LOG(2,
"CFC-12 photolysis rate: %g, %g ... %g s**-1",
4617 LOG(2,
"O2 photolysis rate: %g, %g ... %g s**-1",
4618 photo->
o2[0][0][0], photo->
o2[1][0][0],
4619 photo->
o2[photo->
np - 1][photo->
nsza - 1][photo->
no3c - 1]);
4620 LOG(2,
"O3 -> O(1D) photolysis rate: %g, %g ... %g s**-1",
4621 photo->
o3_1[0][0][0], photo->
o3_1[1][0][0],
4623 LOG(2,
"O3 -> O(3P) photolysis rate: %g, %g ... %g s**-1",
4624 photo->
o3_2[0][0][0], photo->
o3_2[1][0][0],
4626 LOG(2,
"H2O2 photolysis rate: %g, %g ... %g s**-1",
4627 photo->
h2o2[0][0][0], photo->
h2o2[1][0][0],
4629 LOG(2,
"H2O photolysis rate: %g, %g ... %g s**-1",
4630 photo->
h2o[0][0][0], photo->
h2o[1][0][0],
4631 photo->
h2o[photo->
np - 1][photo->
nsza - 1][photo->
no3c - 1]);
4637 const char *filename,
4641 LOG(1,
"Read climatological time series: %s", filename);
4645 if (!(in = fopen(filename,
"r"))) {
4646 WARN(
"Cannot open file!");
4653 while (fgets(line,
LEN, in))
4654 if (sscanf(line,
"%lg %lg", &ts->
time[nh], &ts->
vmr[nh]) == 2) {
4657 ts->
time[nh] = (ts->
time[nh] - 2000.0) * 365.25 * 86400.;
4660 if (nh > 0 && ts->
time[nh] <= ts->
time[nh - 1])
4661 ERRMSG(
"Time series must be ascending!");
4665 ERRMSG(
"Too many data points!");
4674 ERRMSG(
"Not enough data points!");
4677 LOG(2,
"Number of time steps: %d", ts->
ntime);
4678 LOG(2,
"Time steps: %.2f, %.2f ... %.2f s", ts->
time[0], ts->
time[1],
4680 LOG(2,
"Volume mixing ratio range: %g ... %g ppv",
4681 gsl_stats_min(ts->
vmr, 1, (
size_t) nh), gsl_stats_max(ts->
vmr, 1,
4691 const char *filename,
4695 int ncid, varid, it, iy, iz, iz2, nt;
4697 double *help, varmin = 1e99, varmax = -1e99;
4700 LOG(1,
"Read %s data: %s", varname, filename);
4703 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
4704 WARN(
"%s climatology data are missing!", varname);
4711 if (zm->
p[0] < zm->
p[1])
4712 ERRMSG(
"Pressure data are not descending!");
4717 if (zm->
lat[0] > zm->
lat[1])
4718 ERRMSG(
"Latitude data are not ascending!");
4722 zm->
time[0] = 1209600.00;
4723 zm->
time[1] = 3888000.00;
4724 zm->
time[2] = 6393600.00;
4725 zm->
time[3] = 9072000.00;
4726 zm->
time[4] = 11664000.00;
4727 zm->
time[5] = 14342400.00;
4728 zm->
time[6] = 16934400.00;
4729 zm->
time[7] = 19612800.00;
4730 zm->
time[8] = 22291200.00;
4731 zm->
time[9] = 24883200.00;
4732 zm->
time[10] = 27561600.00;
4733 zm->
time[11] = 30153600.00;
4742 for (it = 0; it < zm->
ntime; it++)
4743 for (iz = 0; iz < zm->
np; iz++)
4744 for (iy = 0; iy < zm->
nlat; iy++)
4749 for (it = 0; it < zm->
ntime; it++)
4750 for (iy = 0; iy < zm->
nlat; iy++)
4751 for (iz = 0; iz < zm->
np; iz++) {
4752 if (zm->
vmr[it][iz][iy] < 0) {
4753 for (iz2 = 0; iz2 < zm->
np; iz2++)
4754 if (zm->
vmr[it][iz2][iy] >= 0) {
4755 zm->
vmr[it][iz][iy] = zm->
vmr[it][iz2][iy];
4758 for (iz2 = zm->
np - 1; iz2 >= 0; iz2--)
4759 if (zm->
vmr[it][iz2][iy] >= 0) {
4760 zm->
vmr[it][iz][iy] = zm->
vmr[it][iz2][iy];
4764 varmin =
MIN(varmin, zm->
vmr[it][iz][iy]);
4765 varmax =
MAX(varmax, zm->
vmr[it][iz][iy]);
4772 LOG(2,
"Number of time steps: %d", zm->
ntime);
4773 LOG(2,
"Time steps: %.2f, %.2f ... %.2f s",
4775 LOG(2,
"Number of pressure levels: %d", zm->
np);
4776 LOG(2,
"Altitude levels: %g, %g ... %g km",
4777 Z(zm->
p[0]),
Z(zm->
p[1]),
Z(zm->
p[zm->
np - 1]));
4778 LOG(2,
"Pressure levels: %g, %g ... %g hPa", zm->
p[0],
4779 zm->
p[1], zm->
p[zm->
np - 1]);
4780 LOG(2,
"Number of latitudes: %d", zm->
nlat);
4781 LOG(2,
"Latitudes: %g, %g ... %g deg",
4783 LOG(2,
"%s volume mixing ratio range: %g ... %g ppv", varname, varmin,
4790 const char *filename,
4799 LOG(1,
"\nMassive-Parallel Trajectory Calculations (MPTRAC)\n"
4800 "(executable: %s | version: %s | compiled: %s, %s)\n",
4801 argv[0], VERSION, __DATE__, __TIME__);
4894 ctl->
nq = (int)
scan_ctl(filename, argc, argv,
"NQ", -1,
"0", NULL);
4896 ERRMSG(
"Too many quantities!");
4897 for (
int iq = 0; iq < ctl->
nq; iq++) {
4903 scan_ctl(filename, argc, argv,
"QNT_FORMAT", iq,
"%g",
4905 if (strcasecmp(ctl->
qnt_name[iq],
"aoa") == 0)
4909 SET_QNT(qnt_idx,
"idx",
"particle index",
"-")
4910 SET_QNT(qnt_ens,
"ens",
"ensemble index",
"-")
4911 SET_QNT(qnt_stat,
"stat",
"station flag",
"-")
4912 SET_QNT(qnt_m,
"m",
"mass",
"kg")
4913 SET_QNT(qnt_vmr,
"vmr",
"volume mixing ratio",
"ppv")
4914 SET_QNT(qnt_rp,
"rp",
"particle radius",
"microns")
4915 SET_QNT(qnt_rhop,
"rhop",
"particle density",
"kg/m^3")
4916 SET_QNT(qnt_ps,
"ps",
"surface pressure",
"hPa")
4917 SET_QNT(qnt_ts,
"ts",
"surface temperature",
"K")
4918 SET_QNT(qnt_zs,
"zs",
"surface height",
"km")
4919 SET_QNT(qnt_us,
"us",
"surface zonal wind",
"m/s")
4920 SET_QNT(qnt_vs,
"vs",
"surface meridional wind",
"m/s")
4921 SET_QNT(qnt_lsm,
"lsm",
"land-sea mask",
"1")
4922 SET_QNT(qnt_sst,
"sst",
"sea surface temperature",
"K")
4923 SET_QNT(qnt_pbl,
"pbl",
"planetary boundary layer",
"hPa")
4924 SET_QNT(qnt_pt,
"pt",
"tropopause pressure",
"hPa")
4925 SET_QNT(qnt_tt,
"tt",
"tropopause temperature",
"K")
4926 SET_QNT(qnt_zt,
"zt",
"tropopause geopotential height",
"km")
4927 SET_QNT(qnt_h2ot,
"h2ot",
"tropopause water vapor",
"ppv")
4928 SET_QNT(qnt_zg,
"zg",
"geopotential height",
"km")
4929 SET_QNT(qnt_p,
"p",
"pressure",
"hPa")
4930 SET_QNT(qnt_t,
"t",
"temperature",
"K")
4931 SET_QNT(qnt_rho,
"rho",
"air density",
"kg/m^3")
4932 SET_QNT(qnt_u,
"u",
"zonal wind",
"m/s")
4933 SET_QNT(qnt_v,
"v",
"meridional wind",
"m/s")
4934 SET_QNT(qnt_w,
"w",
"vertical velocity",
"hPa/s")
4935 SET_QNT(qnt_h2o,
"h2o",
"water vapor",
"ppv")
4936 SET_QNT(qnt_o3,
"o3",
"ozone",
"ppv")
4937 SET_QNT(qnt_lwc,
"lwc",
"cloud liquid water content",
"kg/kg")
4938 SET_QNT(qnt_rwc,
"rwc",
"cloud rain water content",
"kg/kg")
4939 SET_QNT(qnt_iwc,
"iwc",
"cloud ice water content",
"kg/kg")
4940 SET_QNT(qnt_swc,
"iwc",
"cloud snow water content",
"kg/kg")
4941 SET_QNT(qnt_cc,
"cc",
"cloud cover",
"1")
4942 SET_QNT(qnt_pct,
"pct",
"cloud top pressure",
"hPa")
4943 SET_QNT(qnt_pcb,
"pcb",
"cloud bottom pressure",
"hPa")
4944 SET_QNT(qnt_cl,
"cl",
"total column cloud water",
"kg/m^2")
4945 SET_QNT(qnt_plcl,
"plcl",
"lifted condensation level",
"hPa")
4946 SET_QNT(qnt_plfc,
"plfc",
"level of free convection",
"hPa")
4947 SET_QNT(qnt_pel,
"pel",
"equilibrium level",
"hPa")
4948 SET_QNT(qnt_cape,
"cape",
"convective available potential energy",
4950 SET_QNT(qnt_cin,
"cin",
"convective inhibition",
"J/kg")
4951 SET_QNT(qnt_o3c,
"o3c",
"total column ozone",
"DU")
4952 SET_QNT(qnt_hno3,
"hno3",
"nitric acid",
"ppv")
4953 SET_QNT(qnt_oh,
"oh",
"hydroxyl radical",
"ppv")
4954 SET_QNT(qnt_h2o2,
"h2o2",
"hydrogen peroxide",
"ppv")
4955 SET_QNT(qnt_ho2,
"ho2",
"hydroperoxyl radical",
"ppv")
4956 SET_QNT(qnt_o1d,
"o1d",
"atomic oxygen",
"ppv")
4957 SET_QNT(qnt_mloss_oh,
"mloss_oh",
"mass loss due to OH chemistry",
"kg")
4958 SET_QNT(qnt_mloss_h2o2,
"mloss_h2o2",
"mass loss due to H2O2 chemistry",
4960 SET_QNT(qnt_mloss_kpp,
"mloss_kpp",
"mass loss due to kpp chemistry",
4962 SET_QNT(qnt_mloss_wet,
"mloss_wet",
"mass loss due to wet deposition",
4964 SET_QNT(qnt_mloss_dry,
"mloss_dry",
"mass loss due to dry deposition",
4966 SET_QNT(qnt_mloss_decay,
"mloss_decay",
4967 "mass loss due to exponential decay",
"kg")
4968 SET_QNT(qnt_loss_rate,
"loss_rate",
"total loss rate",
"s^-1")
4969 SET_QNT(qnt_psat,
"psat",
"saturation pressure over water",
"hPa")
4970 SET_QNT(qnt_psice,
"psice",
"saturation pressure over ice",
"hPa")
4971 SET_QNT(qnt_pw,
"pw",
"partial water vapor pressure",
"hPa")
4972 SET_QNT(qnt_sh,
"sh",
"specific humidity",
"kg/kg")
4973 SET_QNT(qnt_rh,
"rh",
"relative humidity",
"%%")
4974 SET_QNT(qnt_rhice,
"rhice",
"relative humidity over ice",
"%%")
4975 SET_QNT(qnt_theta,
"theta",
"potential temperature",
"K")
4976 SET_QNT(qnt_zeta,
"zeta",
"zeta coordinate",
"K")
4977 SET_QNT(qnt_zeta_d,
"zeta_d",
"diagnosed zeta coordinate",
"K")
4978 SET_QNT(qnt_tvirt,
"tvirt",
"virtual temperature",
"K")
4979 SET_QNT(qnt_lapse,
"lapse",
"temperature lapse rate",
"K/km")
4980 SET_QNT(qnt_vh,
"vh",
"horizontal velocity",
"m/s")
4981 SET_QNT(qnt_vz,
"vz",
"vertical velocity",
"m/s")
4982 SET_QNT(qnt_pv,
"pv",
"potential vorticity",
"PVU")
4983 SET_QNT(qnt_tdew,
"tdew",
"dew point temperature",
"K")
4984 SET_QNT(qnt_tice,
"tice",
"frost point temperature",
"K")
4985 SET_QNT(qnt_tsts,
"tsts",
"STS existence temperature",
"K")
4986 SET_QNT(qnt_tnat,
"tnat",
"NAT existence temperature",
"K")
4987 SET_QNT(qnt_Cx,
"Cx",
"Trace species x volume mixing ratio",
"ppv")
4988 SET_QNT(qnt_Ch2o,
"Ch2o",
"H2O volume mixing ratio",
"ppv")
4989 SET_QNT(qnt_Co3,
"Co3",
"O3 volume mixing ratio",
"ppv")
4990 SET_QNT(qnt_Cco,
"Cco",
"CO volume mixing ratio",
"ppv")
4991 SET_QNT(qnt_Coh,
"Coh",
"HO volume mixing ratio",
"ppv")
4992 SET_QNT(qnt_Ch,
"Ch",
"H radical volume mixing ratio",
"ppv")
4993 SET_QNT(qnt_Cho2,
"Cho2",
"HO2 volume mixing ratio",
"ppv")
4994 SET_QNT(qnt_Ch2o2,
"Ch2o2",
"H2O2 volume mixing ratio",
"ppv")
4995 SET_QNT(qnt_Co1d,
"Co1d",
"O(1D) volume mixing ratio",
"ppv")
4996 SET_QNT(qnt_Co3p,
"Co3p",
"O(3P) radical volume mixing ratio",
"ppv")
4997 SET_QNT(qnt_Cccl4,
"Cccl4",
"CCl4 (CFC-10) volume mixing ratio",
"ppv")
4998 SET_QNT(qnt_Cccl3f,
"Cccl3f",
"CCl3F (CFC-11) volume mixing ratio",
5000 SET_QNT(qnt_Cccl2f2,
"Cccl2f2",
"CCl2F2 (CFC-12) volume mixing ratio",
5002 SET_QNT(qnt_Cn2o,
"Cn2o",
"N2O volume mixing ratio",
"ppv")
5003 SET_QNT(qnt_Csf6,
"Csf6",
"SF6 volume mixing ratio",
"ppv")
5004 SET_QNT(qnt_aoa,
"aoa",
"age of air",
"s")
5010 (int)
scan_ctl(filename, argc, argv,
"ADVECT_VERT_COORD", -1,
"0", NULL);
5012 ERRMSG(
"Set advect_vert_coord to 0, 1, or 2!");
5014 ERRMSG(
"Please add zeta to your quantities for diabatic calculations!");
5016 (int)
scan_ctl(filename, argc, argv,
"MET_VERT_COORD", -1,
"0", NULL);
5019 (
"Using ADVECT_VERT_COORD = 2 requires meteo data on model levels!");
5021 (int)
scan_ctl(filename, argc, argv,
"MET_CLAMS", -1,
"0", NULL);
5023 (int)
scan_ctl(filename, argc, argv,
"ADVECT_ZETA_PRESS_MODULES", -1,
"1",
5028 (int)
scan_ctl(filename, argc, argv,
"DIRECTION", -1,
"1", NULL);
5030 ERRMSG(
"Set DIRECTION to -1 or 1!");
5031 ctl->
t_stop =
scan_ctl(filename, argc, argv,
"T_STOP", -1,
"1e100", NULL);
5032 ctl->
dt_mod =
scan_ctl(filename, argc, argv,
"DT_MOD", -1,
"180", NULL);
5036 ctl->
dt_met =
scan_ctl(filename, argc, argv,
"DT_MET", -1,
"3600", NULL);
5038 (int)
scan_ctl(filename, argc, argv,
"MET_CONVENTION", -1,
"0", NULL);
5040 (int)
scan_ctl(filename, argc, argv,
"MET_TYPE", -1,
"0", NULL);
5043 (
"Please use meteorological files in netcdf format for diabatic calculations.");
5045 (int)
scan_ctl(filename, argc, argv,
"MET_NC_SCALE", -1,
"1", NULL);
5047 (int)
scan_ctl(filename, argc, argv,
"MET_ZFP_PREC", -1,
"8", NULL);
5049 scan_ctl(filename, argc, argv,
"MET_ZFP_TOL_T", -1,
"5.0", NULL);
5051 scan_ctl(filename, argc, argv,
"MET_ZFP_TOL_Z", -1,
"0.5", NULL);
5053 (int)
scan_ctl(filename, argc, argv,
"MET_CMS_HEUR", -1,
"1", NULL);
5055 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_Z", -1,
"1.0", NULL);
5057 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_T", -1,
"0.05", NULL);
5059 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_U", -1,
"0.05", NULL);
5061 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_V", -1,
"0.05", NULL);
5063 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_W", -1,
"1.0", NULL);
5065 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_PV", -1,
"1.0", NULL);
5067 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_H2O", -1,
"1.0", NULL);
5069 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_O3", -1,
"1.0", NULL);
5071 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_LWC", -1,
"1.0", NULL);
5073 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_RWC", -1,
"1.0", NULL);
5075 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_IWC", -1,
"1.0", NULL);
5077 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_SWC", -1,
"1.0", NULL);
5079 scan_ctl(filename, argc, argv,
"MET_CMS_EPS_CC", -1,
"1.0", NULL);
5080 ctl->
met_dx = (int)
scan_ctl(filename, argc, argv,
"MET_DX", -1,
"1", NULL);
5081 ctl->
met_dy = (int)
scan_ctl(filename, argc, argv,
"MET_DY", -1,
"1", NULL);
5082 ctl->
met_dp = (int)
scan_ctl(filename, argc, argv,
"MET_DP", -1,
"1", NULL);
5084 ERRMSG(
"MET_DX, MET_DY, and MET_DP need to be greater than zero!");
5085 ctl->
met_sx = (int)
scan_ctl(filename, argc, argv,
"MET_SX", -1,
"1", NULL);
5086 ctl->
met_sy = (int)
scan_ctl(filename, argc, argv,
"MET_SY", -1,
"1", NULL);
5087 ctl->
met_sp = (int)
scan_ctl(filename, argc, argv,
"MET_SP", -1,
"1", NULL);
5089 ERRMSG(
"MET_SX, MET_SY, and MET_SP need to be greater than zero!");
5091 scan_ctl(filename, argc, argv,
"MET_DETREND", -1,
"-999", NULL);
5092 ctl->
met_np = (int)
scan_ctl(filename, argc, argv,
"MET_NP", -1,
"0", NULL);
5094 ERRMSG(
"Too many levels!");
5096 (int)
scan_ctl(filename, argc, argv,
"MET_PRESS_LEVEL_DEF", -1,
"-1",
5102 for (
int ip = 0; ip < ctl->
met_np; ip++)
5104 scan_ctl(filename, argc, argv,
"MET_P", ip,
"", NULL);
5108 = (int)
scan_ctl(filename, argc, argv,
"MET_GEOPOT_SX", -1,
"-1", NULL);
5110 = (int)
scan_ctl(filename, argc, argv,
"MET_GEOPOT_SY", -1,
"-1", NULL);
5112 = (int)
scan_ctl(filename, argc, argv,
"MET_RELHUM", -1,
"0", NULL);
5114 (int)
scan_ctl(filename, argc, argv,
"MET_TROPO", -1,
"3", NULL);
5116 ERRMSG(
"Set MET_TROPO = 0 ... 5!");
5118 scan_ctl(filename, argc, argv,
"MET_TROPO_PV", -1,
"3.5", NULL);
5120 scan_ctl(filename, argc, argv,
"MET_TROPO_THETA", -1,
"380", NULL);
5122 (int)
scan_ctl(filename, argc, argv,
"MET_TROPO_SPLINE", -1,
"1", NULL);
5124 scan_ctl(filename, argc, argv,
"MET_DT_OUT", -1,
"0.1", NULL);
5126 (int)
scan_ctl(filename, argc, argv,
"MET_CACHE", -1,
"0", NULL);
5128 (int)
scan_ctl(filename, argc, argv,
"MET_MPI_SHARE", -1,
"0", NULL);
5131 ctl->
sort_dt =
scan_ctl(filename, argc, argv,
"SORT_DT", -1,
"-999", NULL);
5135 (int)
scan_ctl(filename, argc, argv,
"ISOSURF", -1,
"0", NULL);
5140 (int)
scan_ctl(filename, argc, argv,
"RNG_TYPE", -1,
"0", NULL);
5142 ERRMSG(
"Set RNG_TYPE to 0, 1, or 2!");
5145 ctl->
advect = (int)
scan_ctl(filename, argc, argv,
"ADVECT", -1,
"2", NULL);
5148 ERRMSG(
"Set ADVECT to 0, 1, 2, or 4!");
5150 (int)
scan_ctl(filename, argc, argv,
"REFLECT", -1,
"0", NULL);
5154 scan_ctl(filename, argc, argv,
"TURB_DX_TROP", -1,
"50", NULL);
5156 scan_ctl(filename, argc, argv,
"TURB_DX_STRAT", -1,
"0", NULL);
5158 scan_ctl(filename, argc, argv,
"TURB_DZ_TROP", -1,
"0", NULL);
5160 scan_ctl(filename, argc, argv,
"TURB_DZ_STRAT", -1,
"0.1", NULL);
5162 scan_ctl(filename, argc, argv,
"TURB_MESOX", -1,
"0.16", NULL);
5164 scan_ctl(filename, argc, argv,
"TURB_MESOZ", -1,
"0.16", NULL);
5168 =
scan_ctl(filename, argc, argv,
"CONV_CAPE", -1,
"-999", NULL);
5170 =
scan_ctl(filename, argc, argv,
"CONV_CIN", -1,
"-999", NULL);
5171 ctl->
conv_dt =
scan_ctl(filename, argc, argv,
"CONV_DT", -1,
"-999", NULL);
5173 = (int)
scan_ctl(filename, argc, argv,
"CONV_MIX_BOT", -1,
"1", NULL);
5175 = (int)
scan_ctl(filename, argc, argv,
"CONV_MIX_TOP", -1,
"1", NULL);
5179 scan_ctl(filename, argc, argv,
"BOUND_MASS", -1,
"-999", NULL);
5181 scan_ctl(filename, argc, argv,
"BOUND_MASS_TREND", -1,
"0", NULL);
5183 scan_ctl(filename, argc, argv,
"BOUND_VMR", -1,
"-999", NULL);
5185 scan_ctl(filename, argc, argv,
"BOUND_VMR_TREND", -1,
"0", NULL);
5187 scan_ctl(filename, argc, argv,
"BOUND_LAT0", -1,
"-999", NULL);
5189 scan_ctl(filename, argc, argv,
"BOUND_LAT1", -1,
"-999", NULL);
5191 scan_ctl(filename, argc, argv,
"BOUND_P0", -1,
"-999", NULL);
5193 scan_ctl(filename, argc, argv,
"BOUND_P1", -1,
"-999", NULL);
5195 scan_ctl(filename, argc, argv,
"BOUND_DPS", -1,
"-999", NULL);
5197 scan_ctl(filename, argc, argv,
"BOUND_DZS", -1,
"-999", NULL);
5199 scan_ctl(filename, argc, argv,
"BOUND_ZETAS", -1,
"-999", NULL);
5201 (int)
scan_ctl(filename, argc, argv,
"BOUND_PBL", -1,
"0", NULL);
5205 if (strcasecmp(ctl->
species,
"CF2Cl2") == 0) {
5209 }
else if (strcasecmp(ctl->
species,
"CFCl3") == 0) {
5213 }
else if (strcasecmp(ctl->
species,
"CH4") == 0) {
5220 }
else if (strcasecmp(ctl->
species,
"CO") == 0) {
5229 }
else if (strcasecmp(ctl->
species,
"CO2") == 0) {
5233 }
else if (strcasecmp(ctl->
species,
"H2O") == 0) {
5235 }
else if (strcasecmp(ctl->
species,
"N2O") == 0) {
5239 }
else if (strcasecmp(ctl->
species,
"NH3") == 0) {
5246 }
else if (strcasecmp(ctl->
species,
"HNO3") == 0) {
5250 }
else if (strcasecmp(ctl->
species,
"NO") == 0) {
5259 }
else if (strcasecmp(ctl->
species,
"NO2") == 0) {
5268 }
else if (strcasecmp(ctl->
species,
"O3") == 0) {
5275 }
else if (strcasecmp(ctl->
species,
"SF6") == 0) {
5279 }
else if (strcasecmp(ctl->
species,
"SO2") == 0) {
5292 sprintf(defstr,
"%g", ctl->
molmass);
5293 ctl->
molmass =
scan_ctl(filename, argc, argv,
"MOLMASS", -1, defstr, NULL);
5298 (int)
scan_ctl(filename, argc, argv,
"OH_CHEM_REACTION", -1, defstr,
5300 for (
int ip = 0; ip < 4; ip++) {
5301 sprintf(defstr,
"%g", ctl->
oh_chem[ip]);
5303 scan_ctl(filename, argc, argv,
"OH_CHEM", ip, defstr, NULL);
5306 scan_ctl(filename, argc, argv,
"OH_CHEM_BETA", -1,
"0", NULL);
5310 (int)
scan_ctl(filename, argc, argv,
"H2O2_CHEM_REACTION", -1,
"0", NULL);
5314 (int)
scan_ctl(filename, argc, argv,
"KPP_CHEM", -1,
"0", NULL);
5315 ctl->
dt_kpp =
scan_ctl(filename, argc, argv,
"DT_KPP", -1,
"1800", NULL);
5319 (int)
scan_ctl(filename, argc, argv,
"TRACER_CHEM", -1,
"0", NULL);
5322 for (
int ip = 0; ip < 3; ip++) {
5325 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_H", ip, defstr, NULL);
5327 for (
int ip = 0; ip < 1; ip++) {
5330 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_H", ip, defstr, NULL);
5333 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_A", -1,
"0", NULL);
5335 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_B", -1,
"0", NULL);
5337 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_A", -1,
"0", NULL);
5339 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_B", -1,
"0", NULL);
5341 scan_ctl(filename, argc, argv,
"WET_DEPO_PRE", 0,
"0.5", NULL);
5343 scan_ctl(filename, argc, argv,
"WET_DEPO_PRE", 1,
"0.36", NULL);
5345 scan_ctl(filename, argc, argv,
"WET_DEPO_IC_RET_RATIO", -1,
"1", NULL);
5347 scan_ctl(filename, argc, argv,
"WET_DEPO_BC_RET_RATIO", -1,
"1", NULL);
5351 scan_ctl(filename, argc, argv,
"DRY_DEPO_VDEP", -1,
"0", NULL);
5353 scan_ctl(filename, argc, argv,
"DRY_DEPO_DP", -1,
"30", NULL);
5356 scan_ctl(filename, argc, argv,
"CLIM_PHOTO", -1,
5357 "../../data/clams_photolysis_rates.nc", ctl->
clim_photo);
5358 scan_ctl(filename, argc, argv,
"CLIM_HNO3_FILENAME", -1,
5360 scan_ctl(filename, argc, argv,
"CLIM_OH_FILENAME", -1,
5362 scan_ctl(filename, argc, argv,
"CLIM_H2O2_FILENAME", -1,
5364 scan_ctl(filename, argc, argv,
"CLIM_HO2_FILENAME", -1,
5366 scan_ctl(filename, argc, argv,
"CLIM_O1D_FILENAME", -1,
5368 scan_ctl(filename, argc, argv,
"CLIM_CCL4_TIMESERIES", -1,
5370 scan_ctl(filename, argc, argv,
"CLIM_CCL3F_TIMESERIES", -1,
5372 scan_ctl(filename, argc, argv,
"CLIM_CCL2F2_TIMESERIES", -1,
5374 scan_ctl(filename, argc, argv,
"CLIM_N2O_TIMESERIES", -1,
5376 scan_ctl(filename, argc, argv,
"CLIM_SF6_TIMESERIES", -1,
5381 scan_ctl(filename, argc, argv,
"MIXING_DT", -1,
"3600.", NULL);
5383 scan_ctl(filename, argc, argv,
"MIXING_TROP", -1,
"-999", NULL);
5385 scan_ctl(filename, argc, argv,
"MIXING_STRAT", -1,
"-999", NULL);
5387 scan_ctl(filename, argc, argv,
"MIXING_Z0", -1,
"-5", NULL);
5389 scan_ctl(filename, argc, argv,
"MIXING_Z1", -1,
"85", NULL);
5391 (int)
scan_ctl(filename, argc, argv,
"MIXING_NZ", -1,
"90", NULL);
5393 scan_ctl(filename, argc, argv,
"MIXING_LON0", -1,
"-180", NULL);
5395 scan_ctl(filename, argc, argv,
"MIXING_LON1", -1,
"180", NULL);
5397 (int)
scan_ctl(filename, argc, argv,
"MIXING_NX", -1,
"360", NULL);
5399 scan_ctl(filename, argc, argv,
"MIXING_LAT0", -1,
"-90", NULL);
5401 scan_ctl(filename, argc, argv,
"MIXING_LAT1", -1,
"90", NULL);
5403 (int)
scan_ctl(filename, argc, argv,
"MIXING_NY", -1,
"180", NULL);
5407 scan_ctl(filename, argc, argv,
"CHEMGRID_Z0", -1,
"-5", NULL);
5409 scan_ctl(filename, argc, argv,
"CHEMGRID_Z1", -1,
"85", NULL);
5411 (int)
scan_ctl(filename, argc, argv,
"CHEMGRID_NZ", -1,
"90", NULL);
5413 scan_ctl(filename, argc, argv,
"CHEMGRID_LON0", -1,
"-180", NULL);
5415 scan_ctl(filename, argc, argv,
"CHEMGRID_LON1", -1,
"180", NULL);
5417 (int)
scan_ctl(filename, argc, argv,
"CHEMGRID_NX", -1,
"360", NULL);
5419 scan_ctl(filename, argc, argv,
"CHEMGRID_LAT0", -1,
"-90", NULL);
5421 scan_ctl(filename, argc, argv,
"CHEMGRID_LAT1", -1,
"90", NULL);
5423 (int)
scan_ctl(filename, argc, argv,
"CHEMGRID_NY", -1,
"180", NULL);
5428 =
scan_ctl(filename, argc, argv,
"TDEC_STRAT", -1,
"0", NULL);
5431 ctl->
psc_h2o =
scan_ctl(filename, argc, argv,
"PSC_H2O", -1,
"4e-6", NULL);
5433 scan_ctl(filename, argc, argv,
"PSC_HNO3", -1,
"9e-9", NULL);
5439 scan_ctl(filename, argc, argv,
"ATM_DT_OUT", -1,
"86400", NULL);
5441 (int)
scan_ctl(filename, argc, argv,
"ATM_FILTER", -1,
"0", NULL);
5443 (int)
scan_ctl(filename, argc, argv,
"ATM_STRIDE", -1,
"1", NULL);
5445 (int)
scan_ctl(filename, argc, argv,
"ATM_TYPE", -1,
"0", NULL);
5447 (int)
scan_ctl(filename, argc, argv,
"ATM_TYPE_OUT", -1,
"-1", NULL);
5451 (int)
scan_ctl(filename, argc, argv,
"OBS_TYPE", -1,
"0", NULL);
5457 scan_ctl(filename, argc, argv,
"CSI_DT_OUT", -1,
"86400", NULL);
5460 scan_ctl(filename, argc, argv,
"CSI_OBSMIN", -1,
"0", NULL);
5462 scan_ctl(filename, argc, argv,
"CSI_MODMIN", -1,
"0", NULL);
5463 ctl->
csi_z0 =
scan_ctl(filename, argc, argv,
"CSI_Z0", -1,
"-5", NULL);
5464 ctl->
csi_z1 =
scan_ctl(filename, argc, argv,
"CSI_Z1", -1,
"85", NULL);
5465 ctl->
csi_nz = (int)
scan_ctl(filename, argc, argv,
"CSI_NZ", -1,
"1", NULL);
5467 scan_ctl(filename, argc, argv,
"CSI_LON0", -1,
"-180", NULL);
5468 ctl->
csi_lon1 =
scan_ctl(filename, argc, argv,
"CSI_LON1", -1,
"180", NULL);
5470 (int)
scan_ctl(filename, argc, argv,
"CSI_NX", -1,
"360", NULL);
5471 ctl->
csi_lat0 =
scan_ctl(filename, argc, argv,
"CSI_LAT0", -1,
"-90", NULL);
5472 ctl->
csi_lat1 =
scan_ctl(filename, argc, argv,
"CSI_LAT1", -1,
"90", NULL);
5474 (int)
scan_ctl(filename, argc, argv,
"CSI_NY", -1,
"180", NULL);
5479 scan_ctl(filename, argc, argv,
"ENS_DT_OUT", -1,
"86400", NULL);
5482 scan_ctl(filename, argc, argv,
"GRID_BASENAME", -1,
"-",
5487 scan_ctl(filename, argc, argv,
"GRID_DT_OUT", -1,
"86400", NULL);
5489 (int)
scan_ctl(filename, argc, argv,
"GRID_SPARSE", -1,
"0", NULL);
5491 (int)
scan_ctl(filename, argc, argv,
"GRID_STDDEV", -1,
"0", NULL);
5492 ctl->
grid_z0 =
scan_ctl(filename, argc, argv,
"GRID_Z0", -1,
"-5", NULL);
5493 ctl->
grid_z1 =
scan_ctl(filename, argc, argv,
"GRID_Z1", -1,
"85", NULL);
5495 (int)
scan_ctl(filename, argc, argv,
"GRID_NZ", -1,
"1", NULL);
5497 scan_ctl(filename, argc, argv,
"GRID_LON0", -1,
"-180", NULL);
5499 scan_ctl(filename, argc, argv,
"GRID_LON1", -1,
"180", NULL);
5501 (int)
scan_ctl(filename, argc, argv,
"GRID_NX", -1,
"360", NULL);
5503 scan_ctl(filename, argc, argv,
"GRID_LAT0", -1,
"-90", NULL);
5505 scan_ctl(filename, argc, argv,
"GRID_LAT1", -1,
"90", NULL);
5507 (int)
scan_ctl(filename, argc, argv,
"GRID_NY", -1,
"180", NULL);
5509 (int)
scan_ctl(filename, argc, argv,
"GRID_TYPE", -1,
"0", NULL);
5512 scan_ctl(filename, argc, argv,
"PROF_BASENAME", -1,
"-",
5515 ctl->
prof_z0 =
scan_ctl(filename, argc, argv,
"PROF_Z0", -1,
"0", NULL);
5516 ctl->
prof_z1 =
scan_ctl(filename, argc, argv,
"PROF_Z1", -1,
"60", NULL);
5518 (int)
scan_ctl(filename, argc, argv,
"PROF_NZ", -1,
"60", NULL);
5520 scan_ctl(filename, argc, argv,
"PROF_LON0", -1,
"-180", NULL);
5522 scan_ctl(filename, argc, argv,
"PROF_LON1", -1,
"180", NULL);
5524 (int)
scan_ctl(filename, argc, argv,
"PROF_NX", -1,
"360", NULL);
5526 scan_ctl(filename, argc, argv,
"PROF_LAT0", -1,
"-90", NULL);
5528 scan_ctl(filename, argc, argv,
"PROF_LAT1", -1,
"90", NULL);
5530 (int)
scan_ctl(filename, argc, argv,
"PROF_NY", -1,
"180", NULL);
5533 scan_ctl(filename, argc, argv,
"SAMPLE_BASENAME", -1,
"-",
5535 scan_ctl(filename, argc, argv,
"SAMPLE_KERNEL", -1,
"-",
5537 scan_ctl(filename, argc, argv,
"SAMPLE_OBSFILE", -1,
"-",
5540 scan_ctl(filename, argc, argv,
"SAMPLE_DX", -1,
"50", NULL);
5542 scan_ctl(filename, argc, argv,
"SAMPLE_DZ", -1,
"-999", NULL);
5545 scan_ctl(filename, argc, argv,
"STAT_BASENAME", -1,
"-",
5549 ctl->
stat_r =
scan_ctl(filename, argc, argv,
"STAT_R", -1,
"50", NULL);
5551 scan_ctl(filename, argc, argv,
"STAT_T0", -1,
"-1e100", NULL);
5552 ctl->
stat_t1 =
scan_ctl(filename, argc, argv,
"STAT_T1", -1,
"1e100", NULL);
5557 scan_ctl(filename, argc, argv,
"VTK_DT_OUT", -1,
"86400", NULL);
5559 (int)
scan_ctl(filename, argc, argv,
"VTK_STRIDE", -1,
"1", NULL);
5561 scan_ctl(filename, argc, argv,
"VTK_SCALE", -1,
"1.0", NULL);
5563 scan_ctl(filename, argc, argv,
"VTK_OFFSET", -1,
"0.0", NULL);
5565 (int)
scan_ctl(filename, argc, argv,
"VTK_SPHERE", -1,
"0", NULL);
5571 const char *filename,
5577 LOG(1,
"Read kernel function: %s", filename);
5581 if (!(in = fopen(filename,
"r")))
5582 ERRMSG(
"Cannot open file!");
5587 while (fgets(line,
LEN, in))
5588 if (sscanf(line,
"%lg %lg", &kz[n], &kw[n]) == 2) {
5589 if (n > 0 && kz[n] < kz[n - 1])
5590 ERRMSG(
"Height levels must be ascending!");
5592 ERRMSG(
"Too many height levels!");
5601 ERRMSG(
"Not enough height levels!");
5604 double kmax = gsl_stats_max(kw, 1, (
size_t) n);
5605 for (
int iz = 0; iz < n; iz++)
5612 const char *filename,
5618 LOG(1,
"Read meteo data: %s", filename);
5624 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
5634 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
5635 WARN(
"Cannot open file!");
5699 int year, mon, day, hour, min, sec;
5705 if (!(in = fopen(filename,
"r"))) {
5706 WARN(
"Cannot open file!");
5712 FREAD(&met_type,
int,
5716 ERRMSG(
"Wrong MET_TYPE of binary data!");
5720 FREAD(&version,
int,
5723 if (version != 100 && version != 101 && version != 102)
5724 ERRMSG(
"Wrong version of binary data!");
5730 jsec2time(met->
time, &year, &mon, &day, &hour, &min, &sec, &r);
5731 LOG(2,
"Time: %.2f (%d-%02d-%02d, %02d:%02d UTC)",
5732 met->
time, year, mon, day, hour, min);
5733 if (year < 1900 || year > 2100 || mon < 1 || mon > 12
5734 || day < 1 || day > 31 || hour < 0 || hour > 23)
5735 ERRMSG(
"Error while reading time!");
5741 LOG(2,
"Number of longitudes: %d", met->
nx);
5742 if (met->
nx < 2 || met->
nx >
EX)
5743 ERRMSG(
"Number of longitudes out of range!");
5748 LOG(2,
"Number of latitudes: %d", met->
ny);
5749 if (met->
ny < 2 || met->
ny >
EY)
5750 ERRMSG(
"Number of latitudes out of range!");
5755 LOG(2,
"Number of levels: %d", met->
np);
5756 if (met->
np < 2 || met->
np >
EP)
5757 ERRMSG(
"Number of levels out of range!");
5763 LOG(2,
"Longitudes: %g, %g ... %g deg",
5769 LOG(2,
"Latitudes: %g, %g ... %g deg",
5775 LOG(2,
"Altitude levels: %g, %g ... %g km",
5776 Z(met->
p[0]),
Z(met->
p[1]),
Z(met->
p[met->
np - 1]));
5777 LOG(2,
"Pressure levels: %g, %g ... %g hPa",
5778 met->
p[0], met->
p[1], met->
p[met->
np - 1]);
5786 if (version >= 101) {
5828 ERRMSG(
"Error while reading binary data!");
5836 ERRMSG(
"MET_TYPE not implemented!");
5845 LOG(2,
"Broadcast data on rank %d...", rank);
5871 LOG(2,
"Read 2-D variable: %s (uncompressed)", varname);
5873 (
size_t) (met->
nx * met->
ny),
5877 for (
int ix = 0; ix < met->
nx; ix++)
5878 for (
int iy = 0; iy < met->
ny; iy++)
5879 var[ix][iy] = help[
ARRAY_2D(ix, iy, met->
ny)];
5904 LOG(2,
"Read 3-D variable: %s (uncompressed)", varname);
5906 (
size_t) (met->
nx * met->
ny * met->
np),
5913 (
size_t) met->
np, 1, in);
5919 FREAD(&precision,
int,
5924 FREAD(&tolerance,
double,
5931 ERRMSG(
"MPTRAC was compiled without zfp compression!");
5941 ERRMSG(
"MPTRAC was compiled without zstd compression!");
5949 (
size_t) met->
np, 1, in);
5951 ERRMSG(
"MPTRAC was compiled without cmultiscale compression!");
5956#pragma omp parallel for default(shared) collapse(2)
5957 for (
int ix = 0; ix < met->
nx; ix++)
5958 for (
int iy = 0; iy < met->
ny; iy++)
5959 for (
int ip = 0; ip < met->
np; ip++) {
5960 var[ix][iy][ip] = help[
ARRAY_3D(ix, iy, met->
ny, ip, met->
np)];
5961 if (var[ix][iy][ip] < bound_min)
5962 var[ix][iy][ip] = bound_min;
5963 else if (var[ix][iy][ip] > bound_max)
5964 var[ix][iy][ip] = bound_max;
5979 LOG(2,
"Calculate CAPE...");
5982 const double pfac = 1.01439, dz0 =
RI /
MA /
G0 * log(pfac);
5985#pragma omp parallel for default(shared) collapse(2)
5986 for (
int ix = 0; ix < met->
nx; ix++)
5987 for (
int iy = 0; iy < met->
ny; iy++) {
5991 double h2o = 0, t, theta = 0;
5992 double pbot =
MIN(met->
ps[ix][iy], met->
p[0]);
5993 double ptop = pbot - 50.;
5994 for (
int ip = 0; ip < met->
np; ip++) {
5995 if (met->
p[ip] <= pbot) {
5996 theta +=
THETA(met->
p[ip], met->
t[ix][iy][ip]);
5997 h2o += met->
h2o[ix][iy][ip];
6000 if (met->
p[ip] < ptop && n > 0)
6007 met->
plcl[ix][iy] = NAN;
6008 met->
plfc[ix][iy] = NAN;
6009 met->
pel[ix][iy] = NAN;
6010 met->
cape[ix][iy] = NAN;
6011 met->
cin[ix][iy] = NAN;
6017 pbot = met->
ps[ix][iy];
6019 met->
plcl[ix][iy] = (float) (0.5 * (pbot + ptop));
6020 t = theta / pow(1000. / met->
plcl[ix][iy], 0.286);
6021 if (
RH(met->
plcl[ix][iy], t, h2o) > 100.)
6022 ptop = met->
plcl[ix][iy];
6024 pbot = met->
plcl[ix][iy];
6025 }
while (pbot - ptop > 0.1);
6029 double dcape, dz, h2o_env, t_env;
6030 double p = met->
ps[ix][iy];
6031 met->
cape[ix][iy] = met->
cin[ix][iy] = 0;
6033 dz = dz0 *
TVIRT(t, h2o);
6035 t = theta / pow(1000. / p, 0.286);
6039 &h2o_env, ci, cw, 0);
6040 dcape = 1e3 *
G0 * (
TVIRT(t, h2o) -
TVIRT(t_env, h2o_env)) /
6041 TVIRT(t_env, h2o_env) * dz;
6043 met->
cin[ix][iy] += fabsf((
float) dcape);
6044 }
while (p > met->
plcl[ix][iy]);
6049 p = met->
plcl[ix][iy];
6050 t = theta / pow(1000. / p, 0.286);
6053 dz = dz0 *
TVIRT(t, h2o);
6056 double psat =
PSAT(t);
6057 h2o = psat / (p - (1. -
EPS) * psat);
6061 &h2o_env, ci, cw, 0);
6062 double dcape_old = dcape;
6063 dcape = 1e3 *
G0 * (
TVIRT(t, h2o) -
TVIRT(t_env, h2o_env)) /
6064 TVIRT(t_env, h2o_env) * dz;
6066 met->
cape[ix][iy] += (float) dcape;
6067 if (!isfinite(met->
plfc[ix][iy]))
6068 met->
plfc[ix][iy] = (
float) p;
6069 }
else if (dcape_old > 0)
6070 met->
pel[ix][iy] = (float) p;
6071 if (dcape < 0 && !isfinite(met->
plfc[ix][iy]))
6072 met->
cin[ix][iy] += fabsf((
float) dcape);
6076 if (!isfinite(met->
plfc[ix][iy]))
6077 met->
cin[ix][iy] = NAN;
6088 LOG(2,
"Calculate cloud data...");
6091#pragma omp parallel for default(shared) collapse(2)
6092 for (
int ix = 0; ix < met->
nx; ix++)
6093 for (
int iy = 0; iy < met->
ny; iy++) {
6096 met->
pct[ix][iy] = NAN;
6097 met->
pcb[ix][iy] = NAN;
6098 met->
cl[ix][iy] = 0;
6101 for (
int ip = 0; ip < met->
np - 1; ip++) {
6104 if (met->
p[ip] > met->
ps[ix][iy] || met->
p[ip] <
P(20.))
6108 if (met->
iwc[ix][iy][ip] > 0 || met->
rwc[ix][iy][ip] > 0
6109 || met->
lwc[ix][iy][ip] > 0 || met->
swc[ix][iy][ip] > 0) {
6113 = (float) (0.5 * (met->
p[ip] + (
float) met->
p[ip + 1]));
6116 if (!isfinite(met->
pcb[ix][iy]))
6118 = (
float) (0.5 * (met->
p[ip] + met->
p[
MAX(ip - 1, 0)]));
6122 met->
cl[ix][iy] += (float)
6123 (0.5 * (met->
lwc[ix][iy][ip] + met->
lwc[ix][iy][ip + 1]
6124 + met->
rwc[ix][iy][ip] + met->
rwc[ix][iy][ip + 1]
6125 + met->
iwc[ix][iy][ip] + met->
iwc[ix][iy][ip + 1]
6126 + met->
swc[ix][iy][ip] + met->
swc[ix][iy][ip + 1])
6127 * 100. * (met->
p[ip] - met->
p[ip + 1]) /
G0);
6145 SELECT_TIMER(
"READ_MET_DETREND",
"METPROC", NVTX_READ);
6146 LOG(2,
"Detrend meteo data...");
6153 double tssq = 2. *
SQR(sigma);
6156 int sy = (int) (3. *
DY2DEG(sigma) / fabs(met->
lat[1] - met->
lat[0]));
6160#pragma omp parallel for default(shared) collapse(2)
6161 for (
int ix = 0; ix < met->
nx; ix++) {
6162 for (
int iy = 0; iy < met->
ny; iy++) {
6170 (int) (3. *
DX2DEG(sigma, met->
lat[iy]) /
6171 fabs(met->
lon[1] - met->
lon[0]));
6176 for (
int ip = 0; ip < met->
np; ip++) {
6177 help->
t[ix][iy][ip] = 0;
6178 help->
u[ix][iy][ip] = 0;
6179 help->
v[ix][iy][ip] = 0;
6180 help->
w[ix][iy][ip] = 0;
6184 for (
int ix2 = ix - sx; ix2 <= ix + sx; ix2++) {
6188 else if (ix3 >= met->
nx)
6190 for (
int iy2 =
MAX(iy - sy, 0);
6191 iy2 <=
MIN(iy + sy, met->
ny - 1); iy2++) {
6198 float w = (float) exp(-
DIST2(x0, x1) / tssq);
6202 for (
int ip = 0; ip < met->
np; ip++) {
6203 help->
t[ix][iy][ip] += w * met->
t[ix3][iy2][ip];
6204 help->
u[ix][iy][ip] += w * met->
u[ix3][iy2][ip];
6205 help->
v[ix][iy][ip] += w * met->
v[ix3][iy2][ip];
6206 help->
w[ix][iy][ip] += w * met->
w[ix3][iy2][ip];
6212 for (
int ip = 0; ip < met->
np; ip++) {
6213 help->
t[ix][iy][ip] /= wsum;
6214 help->
u[ix][iy][ip] /= wsum;
6215 help->
v[ix][iy][ip] /= wsum;
6216 help->
w[ix][iy][ip] /= wsum;
6222#pragma omp parallel for default(shared) collapse(3)
6223 for (
int ix = 0; ix < met->
nx; ix++)
6224 for (
int iy = 0; iy < met->
ny; iy++)
6225 for (
int ip = 0; ip < met->
np; ip++) {
6226 met->
t[ix][iy][ip] -= help->
t[ix][iy][ip];
6227 met->
u[ix][iy][ip] -= help->
u[ix][iy][ip];
6228 met->
v[ix][iy][ip] -= help->
v[ix][iy][ip];
6229 met->
w[ix][iy][ip] -= help->
w[ix][iy][ip];
6242 SELECT_TIMER(
"READ_MET_EXTRAPOLATE",
"METPROC", NVTX_READ);
6243 LOG(2,
"Extrapolate meteo data...");
6246#pragma omp parallel for default(shared) collapse(2)
6247 for (
int ix = 0; ix < met->
nx; ix++)
6248 for (
int iy = 0; iy < met->
ny; iy++) {
6252 for (ip0 = met->
np - 1; ip0 >= 0; ip0--)
6253 if (!isfinite(met->
t[ix][iy][ip0])
6254 || !isfinite(met->
u[ix][iy][ip0])
6255 || !isfinite(met->
v[ix][iy][ip0])
6256 || !isfinite(met->
w[ix][iy][ip0]))
6260 for (
int ip = ip0; ip >= 0; ip--) {
6261 met->
t[ix][iy][ip] = met->
t[ix][iy][ip + 1];
6262 met->
u[ix][iy][ip] = met->
u[ix][iy][ip + 1];
6263 met->
v[ix][iy][ip] = met->
v[ix][iy][ip + 1];
6264 met->
w[ix][iy][ip] = met->
w[ix][iy][ip + 1];
6265 met->
h2o[ix][iy][ip] = met->
h2o[ix][iy][ip + 1];
6266 met->
o3[ix][iy][ip] = met->
o3[ix][iy][ip + 1];
6267 met->
lwc[ix][iy][ip] = met->
lwc[ix][iy][ip + 1];
6268 met->
rwc[ix][iy][ip] = met->
rwc[ix][iy][ip + 1];
6269 met->
iwc[ix][iy][ip] = met->
iwc[ix][iy][ip + 1];
6270 met->
swc[ix][iy][ip] = met->
swc[ix][iy][ip + 1];
6271 met->
cc[ix][iy][ip] = met->
cc[ix][iy][ip + 1];
6290 LOG(2,
"Calculate geopotential heights...");
6297#pragma omp parallel for default(shared)
6298 for (
int ip = 0; ip < met->
np; ip++)
6299 logp[ip] = log(met->
p[ip]);
6302#pragma omp parallel for default(shared) collapse(2)
6303 for (
int ix = 0; ix < met->
nx; ix++)
6304 for (
int iy = 0; iy < met->
ny; iy++) {
6307 double zs = met->
zs[ix][iy];
6308 double lnps = log(met->
ps[ix][iy]);
6312 double ts =
LIN(met->
p[ip0], met->
t[ix][iy][ip0], met->
p[ip0 + 1],
6313 met->
t[ix][iy][ip0 + 1], met->
ps[ix][iy]);
6314 double h2os =
LIN(met->
p[ip0], met->
h2o[ix][iy][ip0], met->
p[ip0 + 1],
6315 met->
h2o[ix][iy][ip0 + 1], met->
ps[ix][iy]);
6318 met->
z[ix][iy][ip0 + 1]
6320 ZDIFF(lnps, ts, h2os, logp[ip0 + 1],
6321 met->
t[ix][iy][ip0 + 1], met->
h2o[ix][iy][ip0 + 1]));
6322 for (
int ip = ip0 + 2; ip < met->
np; ip++)
6324 = (
float) (met->
z[ix][iy][ip - 1] +
6325 ZDIFF(logp[ip - 1], met->
t[ix][iy][ip - 1],
6326 met->
h2o[ix][iy][ip - 1], logp[ip],
6327 met->
t[ix][iy][ip], met->
h2o[ix][iy][ip]));
6332 ZDIFF(lnps, ts, h2os, logp[ip0],
6333 met->
t[ix][iy][ip0], met->
h2o[ix][iy][ip0]));
6334 for (
int ip = ip0 - 1; ip >= 0; ip--)
6336 = (
float) (met->
z[ix][iy][ip + 1] +
6337 ZDIFF(logp[ip + 1], met->
t[ix][iy][ip + 1],
6338 met->
h2o[ix][iy][ip + 1], logp[ip],
6339 met->
t[ix][iy][ip], met->
h2o[ix][iy][ip]));
6343 if (dx == 0 || dy == 0)
6347 if (dx < 0 || dy < 0) {
6348 if (fabs(met->
lon[1] - met->
lon[0]) < 0.5) {
6358 float ws[dx + 1][dy + 1];
6359#pragma omp parallel for default(shared) collapse(2)
6360 for (
int ix = 0; ix <= dx; ix++)
6361 for (
int iy = 0; iy < dy; iy++)
6362 ws[ix][iy] = (1.0f - (
float) ix / (float) dx)
6363 * (1.0f - (float) iy / (
float) dy);
6366#pragma omp parallel for default(shared) collapse(3)
6367 for (
int ix = 0; ix < met->
nx; ix++)
6368 for (
int iy = 0; iy < met->
ny; iy++)
6369 for (
int ip = 0; ip < met->
np; ip++)
6370 help[
ARRAY_3D(ip, ix, met->
nx, iy, met->
ny)] = met->
z[ix][iy][ip];
6373#pragma omp parallel for default(shared) collapse(3)
6374 for (
int ip = 0; ip < met->
np; ip++)
6375 for (
int ix = 0; ix < met->
nx; ix++)
6376 for (
int iy = 0; iy < met->
ny; iy++) {
6377 float res = 0, wsum = 0;
6378 int iy0 =
MAX(iy - dy + 1, 0);
6379 int iy1 =
MIN(iy + dy - 1, met->
ny - 1);
6380 for (
int ix2 = ix - dx + 1; ix2 <= ix + dx - 1; ++ix2) {
6384 else if (ix3 >= met->
nx)
6386 for (
int iy2 = iy0; iy2 <= iy1; ++iy2)
6387 if (isfinite(help[
ARRAY_3D(ip, ix3, met->
nx, iy2, met->
ny)])) {
6388 float w = ws[abs(ix - ix2)][abs(iy - iy2)];
6389 res += w * help[
ARRAY_3D(ip, ix3, met->
nx, iy2, met->
ny)];
6394 met->
z[ix][iy][ip] = res / wsum;
6396 met->
z[ix][iy][ip] = NAN;
6406 const char *filename,
6411 char levname[
LEN], tstr[10];
6413 double rtime = 0, r, r2;
6415 int varid, year2, mon2, day2, hour2, min2, sec2,
6416 year, mon, day, hour, min, sec;
6422 LOG(2,
"Read meteo grid information...");
6431 jsec2time(met->
time, &year, &mon, &day, &hour, &min, &sec, &r);
6432 if (nc_inq_varid(ncid,
"time", &varid) == NC_NOERR) {
6433 NC(nc_get_var_double(ncid, varid, &rtime));
6434 if (fabs(year * 10000. + mon * 100. + day + hour / 24. - rtime) > 1.0)
6435 WARN(
"Time information in meteo file does not match filename!");
6437 WARN(
"Time information in meteo file is missing!");
6448 sprintf(tstr,
"19%.2s", &filename[strlen(filename) - 11]);
6450 sprintf(tstr,
"20%.2s", &filename[strlen(filename) - 11]);
6452 sprintf(tstr,
"%.2s", &filename[strlen(filename) - 9]);
6454 sprintf(tstr,
"%.2s", &filename[strlen(filename) - 7]);
6456 sprintf(tstr,
"%.2s", &filename[strlen(filename) - 5]);
6462 if (year < 1900 || year > 2100 || mon < 1 || mon > 12
6463 || day < 1 || day > 31 || hour < 0 || hour > 23)
6464 ERRMSG(
"Cannot read time from filename!");
6465 jsec2time(met->
time, &year2, &mon2, &day2, &hour2, &min2, &sec2, &r2);
6466 LOG(2,
"Time: %.2f (%d-%02d-%02d, %02d:%02d UTC)",
6467 met->
time, year2, mon2, day2, hour2, min2);
6471 LOG(2,
"Number of longitudes: %d", met->
nx);
6474 LOG(2,
"Number of latitudes: %d", met->
ny);
6477 sprintf(levname,
"lev");
6478 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR)
6479 sprintf(levname,
"plev");
6480 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR)
6481 sprintf(levname,
"hybrid");
6485 sprintf(levname,
"lev_2");
6486 if (nc_inq_dimid(ncid, levname, &dimid2) != NC_NOERR) {
6487 sprintf(levname,
"plev");
6488 NC(nc_inq_dimid(ncid, levname, &dimid2));
6490 NC(nc_inq_dimlen(ncid, dimid2, &np));
6493 LOG(2,
"Number of levels: %d", met->
np);
6494 if (met->
np < 2 || met->
np >
EP)
6495 ERRMSG(
"Number of levels out of range!");
6499 LOG(2,
"Longitudes: %g, %g ... %g deg",
6502 LOG(2,
"Latitudes: %g, %g ... %g deg",
6508 for (
int ip = 0; ip < met->
np; ip++)
6510 LOG(2,
"Altitude levels: %g, %g ... %g km",
6511 Z(met->
p[0]),
Z(met->
p[1]),
Z(met->
p[met->
np - 1]));
6512 LOG(2,
"Pressure levels: %g, %g ... %g hPa",
6513 met->
p[0], met->
p[1], met->
p[met->
np - 1]);
6517 if (strcasecmp(levname,
"hybrid") == 0)
6530 LOG(2,
"Read level data...");
6533 if (!
read_met_nc_3d(ncid,
"t",
"T",
"temp",
"TEMP", ctl, met, met->
t, 1.0))
6534 ERRMSG(
"Cannot read temperature!");
6537 if (!
read_met_nc_3d(ncid,
"u",
"U", NULL, NULL, ctl, met, met->
u, 1.0))
6538 ERRMSG(
"Cannot read zonal wind!");
6539 if (!
read_met_nc_3d(ncid,
"v",
"V", NULL, NULL, ctl, met, met->
v, 1.0))
6540 ERRMSG(
"Cannot read meridional wind!");
6542 (ncid,
"w",
"W",
"omega",
"OMEGA", ctl, met, met->
w, 0.01f))
6543 WARN(
"Cannot read vertical velocity!");
6548 (ncid,
"q",
"Q",
"sh",
"SH", ctl, met, met->
h2o, (
float) (
MA /
MH2O)))
6549 WARN(
"Cannot read specific humidity!");
6552 (ncid,
"rh",
"RH", NULL, NULL, ctl, met, met->
h2o, 0.01f))
6553 WARN(
"Cannot read relative humidity!");
6554#pragma omp parallel for default(shared) collapse(2)
6555 for (
int ix = 0; ix < met->
nx; ix++)
6556 for (
int iy = 0; iy < met->
ny; iy++)
6557 for (
int ip = 0; ip < met->
np; ip++) {
6558 double pw = met->
h2o[ix][iy][ip] *
PSAT(met->
t[ix][iy][ip]);
6559 met->
h2o[ix][iy][ip] =
6560 (float) (pw / (met->
p[ip] - (1.0 -
EPS) * pw));
6566 (ncid,
"o3",
"O3", NULL, NULL, ctl, met, met->
o3, (
float) (
MA /
MO3)))
6567 WARN(
"Cannot read ozone data!");
6571 (ncid,
"clwc",
"CLWC", NULL, NULL, ctl, met, met->
lwc, 1.0))
6572 WARN(
"Cannot read cloud liquid water content!");
6574 (ncid,
"crwc",
"CRWC", NULL, NULL, ctl, met, met->
rwc, 1.0))
6575 WARN(
"Cannot read cloud rain water content!");
6577 (ncid,
"ciwc",
"CIWC", NULL, NULL, ctl, met, met->
iwc, 1.0))
6578 WARN(
"Cannot read cloud ice water content!");
6580 (ncid,
"cswc",
"CSWC", NULL, NULL, ctl, met, met->
swc, 1.0))
6581 WARN(
"Cannot read cloud snow water content!");
6583 WARN(
"Cannot read cloud cover!");
6587 (ncid,
"ZETA",
"zeta", NULL, NULL, ctl, met, met->
zetal, 1.0))
6588 WARN(
"Cannot read ZETA in meteo data!");
6591 (ncid,
"ZETA_DOT_TOT",
"zeta_dot_clr", NULL, NULL, ctl, met,
6594 (ncid,
"ZETA_DOT_TOT",
"ZETA_DOT_clr", NULL, NULL, ctl, met,
6596 WARN(
"Cannot read vertical velocity!");
6603 for (
int ix = 0; ix < met->
nx; ix++)
6604 for (
int iy = 0; iy < met->
ny; iy++)
6605 for (
int ip = 0; ip < met->
np; ip++) {
6606 met->
ul[ix][iy][ip] = met->
u[ix][iy][ip];
6607 met->
vl[ix][iy][ip] = met->
v[ix][iy][ip];
6608 met->
wl[ix][iy][ip] = met->
w[ix][iy][ip];
6620 (ncid,
"pl",
"PL",
"pressure",
"PRESSURE", ctl, met, met->
pl, 0.01f))
6622 (ncid,
"press",
"PRESS", NULL, NULL, ctl, met, met->
pl, 1.0))
6623 ERRMSG(
"Cannot read pressure on model levels!");
6626 for (
int ix = 0; ix < met->
nx; ix++)
6627 for (
int iy = 0; iy < met->
ny; iy++)
6628 for (
int ip = 1; ip < met->
np; ip++)
6629 if ((met->
pl[ix][iy][0] > met->
pl[ix][iy][1]
6630 && met->
pl[ix][iy][ip - 1] <= met->
pl[ix][iy][ip])
6631 || (met->
pl[ix][iy][0] < met->
pl[ix][iy][1]
6632 && met->
pl[ix][iy][ip - 1] >= met->
pl[ix][iy][ip]))
6633 ERRMSG(
"Pressure profiles are not monotonic!");
6654 for (
int ip = 0; ip < met->
np; ip++)
6655 met->
p[ip] = ctl->
met_p[ip];
6659 for (
int ip = 1; ip < met->
np; ip++)
6660 if (met->
p[ip - 1] < met->
p[ip])
6661 ERRMSG(
"Pressure levels must be descending!");
6672 double aux[
EP], p[
EP];
6676 LOG(2,
"Interpolate meteo data to pressure levels: %s", varname);
6679#pragma omp parallel for default(shared) private(aux,p) collapse(2)
6680 for (
int ix = 0; ix < met->
nx; ix++)
6681 for (
int iy = 0; iy < met->
ny; iy++) {
6684 for (
int ip = 0; ip < met->
np; ip++)
6685 p[ip] = met->
pl[ix][iy][ip];
6688 for (
int ip = 0; ip < ctl->
met_np; ip++) {
6689 double pt = ctl->
met_p[ip];
6690 if ((pt > p[0] && p[0] > p[1]) || (pt < p[0] && p[0] < p[1]))
6692 else if ((pt > p[met->
np - 1] && p[1] > p[0])
6693 || (pt < p[met->
np - 1] && p[1] < p[0]))
6694 pt = p[met->
np - 1];
6696 aux[ip] =
LIN(p[ip2], var[ix][iy][ip2],
6697 p[ip2 + 1], var[ix][iy][ip2 + 1], pt);
6701 for (
int ip = 0; ip < ctl->
met_np; ip++)
6702 var[ix][iy][ip] = (
float) aux[ip];
6712 SELECT_TIMER(
"READ_MET_MONOTONIZE",
"METPROC", NVTX_READ);
6713 LOG(2,
"Make zeta profiles monotone...");
6716#pragma omp parallel for default(shared) collapse(2)
6717 for (
int i = 0; i < met->
nx; i++)
6718 for (
int j = 0; j < met->
ny; j++) {
6721 while (k < met->npl) {
6722 if ((met->
zetal[i][j][k - 1] >= met->
zetal[i][j][k])) {
6728 while ((met->
zetal[i][j][k - 1] >=
6729 met->
zetal[i][j][k + l]) & (k + l < met->npl));
6734 (float) (met->
zetal[i][j][k + l] - met->
zetal[i][j][k - 1])
6737 for (
int m = k; m < k + l; m++) {
6738 float d = (float) (met->
hybrid[m] - met->
hybrid[k - 1]);
6739 met->
zetal[i][j][m] = s * d + met->
zetal[i][j][k - 1];
6751#pragma omp parallel for default(shared) collapse(2)
6752 for (
int i = 0; i < met->
nx; i++)
6753 for (
int j = 0; j < met->
ny; j++) {
6756 while (k < met->npl) {
6757 if ((met->
pl[i][j][k - 1] <= met->
pl[i][j][k])) {
6763 while ((met->
pl[i][j][k - 1] <= met->
pl[i][j][k + l]) & (k + l <
6768 float s = (float) (met->
pl[i][j][k + l] - met->
pl[i][j][k - 1])
6771 for (
int m = k; m < k + l; m++) {
6772 float d = (float) (met->
hybrid[m] - met->
hybrid[k - 1]);
6773 met->
pl[i][j][m] = s * d + met->
pl[i][j][k - 1];
6801 float offset, scalfac;
6806 if (nc_inq_varid(ncid, varname, &varid) == NC_NOERR)
6807 sprintf(varsel,
"%s", varname);
6808 else if (varname2 != NULL
6809 && nc_inq_varid(ncid, varname2, &varid) == NC_NOERR)
6810 sprintf(varsel,
"%s", varname2);
6811 else if (varname3 != NULL
6812 && nc_inq_varid(ncid, varname3, &varid) == NC_NOERR)
6813 sprintf(varsel,
"%s", varname3);
6814 else if (varname4 != NULL
6815 && nc_inq_varid(ncid, varname4, &varid) == NC_NOERR)
6816 sprintf(varsel,
"%s", varname4);
6822 && nc_get_att_float(ncid, varid,
"add_offset", &offset) == NC_NOERR
6823 && nc_get_att_float(ncid, varid,
"scale_factor",
6824 &scalfac) == NC_NOERR) {
6832 short fillval, missval;
6833 if (nc_get_att_short(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
6835 if (nc_get_att_short(ncid, varid,
"missing_value", &missval) != NC_NOERR)
6839 LOG(2,
"Read 2-D variable: %s"
6840 " (FILL = %d, MISS = %d, SCALE = %g, OFFSET = %g)",
6841 varsel, fillval, missval, scalfac, offset);
6844 NC(nc_get_var_short(ncid, varid, help));
6848 ERRMSG(
"Meteo data layout not implemented for packed netCDF files!");
6851#pragma omp parallel for default(shared) num_threads(12)
6852 for (
int ix = 0; ix < met->
nx; ix++)
6853 for (
int iy = 0; iy < met->
ny; iy++) {
6857 if ((fillval == 0 || aux != fillval)
6858 && (missval == 0 || aux != missval)
6859 && fabsf(aux * scalfac + offset) < 1e14f)
6860 dest[ix][iy] += scl * (aux * scalfac + offset);
6878 float fillval, missval;
6879 if (nc_get_att_float(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
6881 if (nc_get_att_float(ncid, varid,
"missing_value", &missval) != NC_NOERR)
6885 LOG(2,
"Read 2-D variable: %s (FILL = %g, MISS = %g)",
6886 varsel, fillval, missval);
6889 NC(nc_get_var_float(ncid, varid, help));
6895#pragma omp parallel for default(shared) num_threads(12)
6896 for (
int ix = 0; ix < met->
nx; ix++)
6897 for (
int iy = 0; iy < met->
ny; iy++) {
6901 if ((fillval == 0 || aux != fillval)
6902 && (missval == 0 || aux != missval)
6903 && fabsf(aux) < 1e14f)
6904 dest[ix][iy] += scl * aux;
6912#pragma omp parallel for default(shared) num_threads(12)
6913 for (
int iy = 0; iy < met->
ny; iy++)
6914 for (
int ix = 0; ix < met->
nx; ix++) {
6918 if ((fillval == 0 || aux != fillval)
6919 && (missval == 0 || aux != missval)
6920 && fabsf(aux) < 1e14f)
6921 dest[ix][iy] += scl * aux;
6950 float offset, scalfac;
6955 if (nc_inq_varid(ncid, varname, &varid) == NC_NOERR)
6956 sprintf(varsel,
"%s", varname);
6957 else if (varname2 != NULL
6958 && nc_inq_varid(ncid, varname2, &varid) == NC_NOERR)
6959 sprintf(varsel,
"%s", varname2);
6960 else if (varname3 != NULL
6961 && nc_inq_varid(ncid, varname3, &varid) == NC_NOERR)
6962 sprintf(varsel,
"%s", varname3);
6963 else if (varname4 != NULL
6964 && nc_inq_varid(ncid, varname4, &varid) == NC_NOERR)
6965 sprintf(varsel,
"%s", varname4);
6971 && nc_get_att_float(ncid, varid,
"add_offset", &offset) == NC_NOERR
6972 && nc_get_att_float(ncid, varid,
"scale_factor",
6973 &scalfac) == NC_NOERR) {
6981 short fillval, missval;
6982 if (nc_get_att_short(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
6984 if (nc_get_att_short(ncid, varid,
"missing_value", &missval) != NC_NOERR)
6988 LOG(2,
"Read 3-D variable: %s "
6989 "(FILL = %d, MISS = %d, SCALE = %g, OFFSET = %g)",
6990 varsel, fillval, missval, scalfac, offset);
6993 NC(nc_get_var_short(ncid, varid, help));
6997 ERRMSG(
"Meteo data layout not implemented for packed netCDF files!");
7000#pragma omp parallel for default(shared) num_threads(12)
7001 for (
int ix = 0; ix < met->
nx; ix++)
7002 for (
int iy = 0; iy < met->
ny; iy++)
7003 for (
int ip = 0; ip < met->
np; ip++) {
7004 short aux = help[
ARRAY_3D(ip, iy, met->
ny, ix, met->
nx)];
7005 if ((fillval == 0 || aux != fillval)
7006 && (missval == 0 || aux != missval)
7007 && fabsf(aux * scalfac + offset) < 1e14f)
7008 dest[ix][iy][ip] = scl * (aux * scalfac + offset);
7010 dest[ix][iy][ip] = NAN;
7026 float fillval, missval;
7027 if (nc_get_att_float(ncid, varid,
"_FillValue", &fillval) != NC_NOERR)
7029 if (nc_get_att_float(ncid, varid,
"missing_value", &missval) != NC_NOERR)
7033 LOG(2,
"Read 3-D variable: %s (FILL = %g, MISS = %g)",
7034 varsel, fillval, missval);
7037 NC(nc_get_var_float(ncid, varid, help));
7043#pragma omp parallel for default(shared) num_threads(12)
7044 for (
int ix = 0; ix < met->
nx; ix++)
7045 for (
int iy = 0; iy < met->
ny; iy++)
7046 for (
int ip = 0; ip < met->
np; ip++) {
7047 float aux = help[
ARRAY_3D(ip, iy, met->
ny, ix, met->
nx)];
7048 if ((fillval == 0 || aux != fillval)
7049 && (missval == 0 || aux != missval)
7050 && fabsf(aux) < 1e14f)
7051 dest[ix][iy][ip] = scl * aux;
7053 dest[ix][iy][ip] = NAN;
7059#pragma omp parallel for default(shared) num_threads(12)
7060 for (
int ip = 0; ip < met->
np; ip++)
7061 for (
int iy = 0; iy < met->
ny; iy++)
7062 for (
int ix = 0; ix < met->
nx; ix++) {
7063 float aux = help[
ARRAY_3D(ix, iy, met->
ny, ip, met->
np)];
7064 if ((fillval == 0 || aux != fillval)
7065 && (missval == 0 || aux != missval)
7066 && fabsf(aux) < 1e14f)
7067 dest[ix][iy][ip] = scl * aux;
7069 dest[ix][iy][ip] = NAN;
7088 LOG(2,
"Calculate planetary boundary layer...");
7092 const double rib_crit = 0.25, dz = 0.05, umin = 5.0;
7095#pragma omp parallel for default(shared) collapse(2)
7096 for (
int ix = 0; ix < met->
nx; ix++)
7097 for (
int iy = 0; iy < met->
ny; iy++) {
7100 double pbl_bot = met->
ps[ix][iy] +
DZ2DP(dz, met->
ps[ix][iy]);
7104 for (ip = 1; ip < met->
np; ip++)
7105 if (met->
p[ip] < pbl_bot)
7109 double zs =
LIN(met->
p[ip - 1], met->
z[ix][iy][ip - 1],
7110 met->
p[ip], met->
z[ix][iy][ip], pbl_bot);
7111 double ts =
LIN(met->
p[ip - 1], met->
t[ix][iy][ip - 1],
7112 met->
p[ip], met->
t[ix][iy][ip], pbl_bot);
7113 double us =
LIN(met->
p[ip - 1], met->
u[ix][iy][ip - 1],
7114 met->
p[ip], met->
u[ix][iy][ip], pbl_bot);
7115 double vs =
LIN(met->
p[ip - 1], met->
v[ix][iy][ip - 1],
7116 met->
p[ip], met->
v[ix][iy][ip], pbl_bot);
7117 double h2os =
LIN(met->
p[ip - 1], met->
h2o[ix][iy][ip - 1],
7118 met->
p[ip], met->
h2o[ix][iy][ip], pbl_bot);
7119 double tvs =
THETAVIRT(pbl_bot, ts, h2os);
7125 for (; ip < met->
np; ip++) {
7129 =
SQR(met->
u[ix][iy][ip] - us) +
SQR(met->
v[ix][iy][ip] - vs);
7130 vh2 =
MAX(vh2,
SQR(umin));
7133 double rib =
G0 * 1e3 * (met->
z[ix][iy][ip] - zs) / tvs
7135 met->
h2o[ix][iy][ip]) - tvs) / vh2;
7138 if (rib >= rib_crit) {
7139 met->
pbl[ix][iy] = (float) (
LIN(rib_old, met->
p[ip - 1],
7140 rib, met->
p[ip], rib_crit));
7141 if (met->
pbl[ix][iy] > pbl_bot)
7142 met->
pbl[ix][iy] = (float) pbl_bot;
7158 SELECT_TIMER(
"READ_MET_PERIODIC",
"METPROC", NVTX_READ);
7159 LOG(2,
"Apply periodic boundary conditions...");
7162 if (!(fabs(met->
lon[met->
nx - 1] - met->
lon[0]
7163 + met->
lon[1] - met->
lon[0] - 360) < 0.01))
7167 if ((++met->
nx) >=
EX)
7168 ERRMSG(
"Cannot create periodic boundary conditions!");
7174#pragma omp parallel for default(shared)
7175 for (
int iy = 0; iy < met->
ny; iy++) {
7176 met->
ps[met->
nx - 1][iy] = met->
ps[0][iy];
7177 met->
zs[met->
nx - 1][iy] = met->
zs[0][iy];
7178 met->
ts[met->
nx - 1][iy] = met->
ts[0][iy];
7179 met->
us[met->
nx - 1][iy] = met->
us[0][iy];
7180 met->
vs[met->
nx - 1][iy] = met->
vs[0][iy];
7181 met->
lsm[met->
nx - 1][iy] = met->
lsm[0][iy];
7182 met->
sst[met->
nx - 1][iy] = met->
sst[0][iy];
7183 for (
int ip = 0; ip < met->
np; ip++) {
7184 met->
t[met->
nx - 1][iy][ip] = met->
t[0][iy][ip];
7185 met->
u[met->
nx - 1][iy][ip] = met->
u[0][iy][ip];
7186 met->
v[met->
nx - 1][iy][ip] = met->
v[0][iy][ip];
7187 met->
w[met->
nx - 1][iy][ip] = met->
w[0][iy][ip];
7188 met->
h2o[met->
nx - 1][iy][ip] = met->
h2o[0][iy][ip];
7189 met->
o3[met->
nx - 1][iy][ip] = met->
o3[0][iy][ip];
7190 met->
lwc[met->
nx - 1][iy][ip] = met->
lwc[0][iy][ip];
7191 met->
rwc[met->
nx - 1][iy][ip] = met->
rwc[0][iy][ip];
7192 met->
iwc[met->
nx - 1][iy][ip] = met->
iwc[0][iy][ip];
7193 met->
swc[met->
nx - 1][iy][ip] = met->
swc[0][iy][ip];
7194 met->
cc[met->
nx - 1][iy][ip] = met->
cc[0][iy][ip];
7196 for (
int ip = 0; ip < met->
npl; ip++) {
7197 met->
ul[met->
nx - 1][iy][ip] = met->
ul[0][iy][ip];
7198 met->
vl[met->
nx - 1][iy][ip] = met->
vl[0][iy][ip];
7199 met->
wl[met->
nx - 1][iy][ip] = met->
wl[0][iy][ip];
7200 met->
pl[met->
nx - 1][iy][ip] = met->
pl[0][iy][ip];
7201 met->
zetal[met->
nx - 1][iy][ip] = met->
zetal[0][iy][ip];
7213 SELECT_TIMER(
"READ_MET_POLAR_WINDS",
"METPROC", NVTX_READ);
7214 LOG(2,
"Apply fix for polar winds...");
7217 if (fabs(met->
lat[0]) < 89.999 || fabs(met->
lat[met->
ny - 1]) < 89.999)
7221 for (
int ihem = 0; ihem < 2; ihem++) {
7224 int i89 = 1, i90 = 0, sign = 1;
7229 if (met->
lat[i90] < 0)
7233 double clon[
EX], slon[
EX];
7234#pragma omp parallel for default(shared)
7235 for (
int ix = 0; ix < met->
nx; ix++) {
7236 clon[ix] = cos(sign * met->
lon[ix] / 180. * M_PI);
7237 slon[ix] = sin(sign * met->
lon[ix] / 180. * M_PI);
7241#pragma omp parallel for default(shared)
7242 for (
int ip = 0; ip < met->
np; ip++) {
7245 double vel89x = 0, vel89y = 0;
7246 for (
int ix = 0; ix < met->
nx; ix++) {
7248 (met->
u[ix][i89][ip] * clon[ix] -
7249 met->
v[ix][i89][ip] * slon[ix]) / met->
nx;
7251 (met->
u[ix][i89][ip] * slon[ix] +
7252 met->
v[ix][i89][ip] * clon[ix]) / met->
nx;
7256 for (
int ix = 0; ix < met->
nx; ix++) {
7258 = (float) (vel89x * clon[ix] + vel89y * slon[ix]);
7260 = (float) (-vel89x * slon[ix] + vel89y * clon[ix]);
7275 LOG(2,
"Calculate potential vorticity...");
7278#pragma omp parallel for default(shared)
7279 for (
int ip = 0; ip < met->
np; ip++)
7280 pows[ip] = pow(1000. / met->
p[ip], 0.286);
7283#pragma omp parallel for default(shared)
7284 for (
int ix = 0; ix < met->
nx; ix++) {
7287 int ix0 =
MAX(ix - 1, 0);
7288 int ix1 =
MIN(ix + 1, met->
nx - 1);
7291 for (
int iy = 0; iy < met->
ny; iy++) {
7294 int iy0 =
MAX(iy - 1, 0);
7295 int iy1 =
MIN(iy + 1, met->
ny - 1);
7298 double latr = 0.5 * (met->
lat[iy1] + met->
lat[iy0]);
7299 double dx = 1000. *
DEG2DX(met->
lon[ix1] - met->
lon[ix0], latr);
7300 double dy = 1000. *
DEG2DY(met->
lat[iy1] - met->
lat[iy0]);
7301 double c0 = cos(met->
lat[iy0] / 180. * M_PI);
7302 double c1 = cos(met->
lat[iy1] / 180. * M_PI);
7303 double cr = cos(latr / 180. * M_PI);
7304 double vort = 2 * 7.2921e-5 * sin(latr * M_PI / 180.);
7307 for (
int ip = 0; ip < met->
np; ip++) {
7311 = (met->
t[ix1][iy][ip] - met->
t[ix0][iy][ip]) * pows[ip] / dx;
7312 double dvdx = (met->
v[ix1][iy][ip] - met->
v[ix0][iy][ip]) / dx;
7316 = (met->
t[ix][iy1][ip] - met->
t[ix][iy0][ip]) * pows[ip] / dy;
7318 = (met->
u[ix][iy1][ip] * c1 - met->
u[ix][iy0][ip] * c0) / dy;
7321 int ip0 =
MAX(ip - 1, 0);
7322 int ip1 =
MIN(ip + 1, met->
np - 1);
7325 double dtdp, dudp, dvdp;
7326 double dp0 = 100. * (met->
p[ip] - met->
p[ip0]);
7327 double dp1 = 100. * (met->
p[ip1] - met->
p[ip]);
7328 if (ip != ip0 && ip != ip1) {
7329 double denom = dp0 * dp1 * (dp0 + dp1);
7330 dtdp = (dp0 * dp0 * met->
t[ix][iy][ip1] * pows[ip1]
7331 - dp1 * dp1 * met->
t[ix][iy][ip0] * pows[ip0]
7332 + (dp1 * dp1 - dp0 * dp0) * met->
t[ix][iy][ip] * pows[ip])
7334 dudp = (dp0 * dp0 * met->
u[ix][iy][ip1]
7335 - dp1 * dp1 * met->
u[ix][iy][ip0]
7336 + (dp1 * dp1 - dp0 * dp0) * met->
u[ix][iy][ip])
7338 dvdp = (dp0 * dp0 * met->
v[ix][iy][ip1]
7339 - dp1 * dp1 * met->
v[ix][iy][ip0]
7340 + (dp1 * dp1 - dp0 * dp0) * met->
v[ix][iy][ip])
7343 double denom = dp0 + dp1;
7345 (met->
t[ix][iy][ip1] * pows[ip1] -
7346 met->
t[ix][iy][ip0] * pows[ip0]) / denom;
7347 dudp = (met->
u[ix][iy][ip1] - met->
u[ix][iy][ip0]) / denom;
7348 dvdp = (met->
v[ix][iy][ip1] - met->
v[ix][iy][ip0]) / denom;
7352 met->
pv[ix][iy][ip] = (float)
7354 (-dtdp * (dvdx - dudy / cr + vort) + dvdp * dtdx - dudp * dtdy));
7360#pragma omp parallel for default(shared)
7361 for (
int ix = 0; ix < met->
nx; ix++)
7362 for (
int ip = 0; ip < met->
np; ip++) {
7364 = met->
pv[ix][1][ip]
7365 = met->
pv[ix][2][ip];
7366 met->
pv[ix][met->
ny - 1][ip]
7367 = met->
pv[ix][met->
ny - 2][ip]
7368 = met->
pv[ix][met->
ny - 3][ip];
7379 LOG(2,
"Calculate total column ozone...");
7382#pragma omp parallel for default(shared) collapse(2)
7383 for (
int ix = 0; ix < met->
nx; ix++)
7384 for (
int iy = 0; iy < met->
ny; iy++) {
7388 for (
int ip = 1; ip < met->
np; ip++)
7389 if (met->
p[ip - 1] <= met->
ps[ix][iy]) {
7390 double vmr = 0.5 * (met->
o3[ix][iy][ip - 1] + met->
o3[ix][iy][ip]);
7391 double dp = met->
p[ip - 1] - met->
p[ip];
7392 cd += vmr *
MO3 /
MA * dp * 1e2 /
G0;
7396 met->
o3c[ix][iy] = (float) (cd / 2.1415e-5);
7415 LOG(2,
"Downsampling of meteo data...");
7424 memcpy(help->
lon, met->
lon,
sizeof(met->
lon));
7425 memcpy(help->
lat, met->
lat,
sizeof(met->
lat));
7426 memcpy(help->
p, met->
p,
sizeof(met->
p));
7429 for (
int ix = 0; ix < met->
nx; ix += ctl->
met_dx) {
7430 for (
int iy = 0; iy < met->
ny; iy += ctl->
met_dy) {
7431 for (
int ip = 0; ip < met->
np; ip += ctl->
met_dp) {
7432 help->
ps[ix][iy] = 0;
7433 help->
zs[ix][iy] = 0;
7434 help->
ts[ix][iy] = 0;
7435 help->
us[ix][iy] = 0;
7436 help->
vs[ix][iy] = 0;
7437 help->
lsm[ix][iy] = 0;
7438 help->
sst[ix][iy] = 0;
7439 help->
t[ix][iy][ip] = 0;
7440 help->
u[ix][iy][ip] = 0;
7441 help->
v[ix][iy][ip] = 0;
7442 help->
w[ix][iy][ip] = 0;
7443 help->
h2o[ix][iy][ip] = 0;
7444 help->
o3[ix][iy][ip] = 0;
7445 help->
lwc[ix][iy][ip] = 0;
7446 help->
rwc[ix][iy][ip] = 0;
7447 help->
iwc[ix][iy][ip] = 0;
7448 help->
swc[ix][iy][ip] = 0;
7449 help->
cc[ix][iy][ip] = 0;
7451 for (
int ix2 = ix - ctl->
met_sx + 1; ix2 <= ix + ctl->met_sx - 1;
7456 else if (ix3 >= met->
nx)
7459 for (
int iy2 =
MAX(iy - ctl->
met_sy + 1, 0);
7460 iy2 <=
MIN(iy + ctl->
met_sy - 1, met->
ny - 1); iy2++)
7461 for (
int ip2 =
MAX(ip - ctl->
met_sp + 1, 0);
7462 ip2 <=
MIN(ip + ctl->
met_sp - 1, met->
np - 1); ip2++) {
7463 float w = (1.0f - (float) abs(ix - ix2) / (float) ctl->
met_sx)
7464 * (1.0f - (float) abs(iy - iy2) / (float) ctl->
met_sy)
7465 * (1.0f - (float) abs(ip - ip2) / (float) ctl->
met_sp);
7466 help->
ps[ix][iy] += w * met->
ps[ix3][iy2];
7467 help->
zs[ix][iy] += w * met->
zs[ix3][iy2];
7468 help->
ts[ix][iy] += w * met->
ts[ix3][iy2];
7469 help->
us[ix][iy] += w * met->
us[ix3][iy2];
7470 help->
vs[ix][iy] += w * met->
vs[ix3][iy2];
7471 help->
lsm[ix][iy] += w * met->
lsm[ix3][iy2];
7472 help->
sst[ix][iy] += w * met->
sst[ix3][iy2];
7473 help->
t[ix][iy][ip] += w * met->
t[ix3][iy2][ip2];
7474 help->
u[ix][iy][ip] += w * met->
u[ix3][iy2][ip2];
7475 help->
v[ix][iy][ip] += w * met->
v[ix3][iy2][ip2];
7476 help->
w[ix][iy][ip] += w * met->
w[ix3][iy2][ip2];
7477 help->
h2o[ix][iy][ip] += w * met->
h2o[ix3][iy2][ip2];
7478 help->
o3[ix][iy][ip] += w * met->
o3[ix3][iy2][ip2];
7479 help->
lwc[ix][iy][ip] += w * met->
lwc[ix3][iy2][ip2];
7480 help->
rwc[ix][iy][ip] += w * met->
rwc[ix3][iy2][ip2];
7481 help->
iwc[ix][iy][ip] += w * met->
iwc[ix3][iy2][ip2];
7482 help->
swc[ix][iy][ip] += w * met->
swc[ix3][iy2][ip2];
7483 help->
cc[ix][iy][ip] += w * met->
cc[ix3][iy2][ip2];
7487 help->
ps[ix][iy] /= wsum;
7488 help->
zs[ix][iy] /= wsum;
7489 help->
ts[ix][iy] /= wsum;
7490 help->
us[ix][iy] /= wsum;
7491 help->
vs[ix][iy] /= wsum;
7492 help->
lsm[ix][iy] /= wsum;
7493 help->
sst[ix][iy] /= wsum;
7494 help->
t[ix][iy][ip] /= wsum;
7495 help->
u[ix][iy][ip] /= wsum;
7496 help->
v[ix][iy][ip] /= wsum;
7497 help->
w[ix][iy][ip] /= wsum;
7498 help->
h2o[ix][iy][ip] /= wsum;
7499 help->
o3[ix][iy][ip] /= wsum;
7500 help->
lwc[ix][iy][ip] /= wsum;
7501 help->
rwc[ix][iy][ip] /= wsum;
7502 help->
iwc[ix][iy][ip] /= wsum;
7503 help->
swc[ix][iy][ip] /= wsum;
7504 help->
cc[ix][iy][ip] /= wsum;
7511 for (
int ix = 0; ix < help->
nx; ix += ctl->
met_dx) {
7514 for (
int iy = 0; iy < help->
ny; iy += ctl->
met_dy) {
7516 met->
ps[met->
nx][met->
ny] = help->
ps[ix][iy];
7517 met->
zs[met->
nx][met->
ny] = help->
zs[ix][iy];
7518 met->
ts[met->
nx][met->
ny] = help->
ts[ix][iy];
7519 met->
us[met->
nx][met->
ny] = help->
us[ix][iy];
7520 met->
vs[met->
nx][met->
ny] = help->
vs[ix][iy];
7521 met->
lsm[met->
nx][met->
ny] = help->
lsm[ix][iy];
7522 met->
sst[met->
nx][met->
ny] = help->
sst[ix][iy];
7524 for (
int ip = 0; ip < help->
np; ip += ctl->
met_dp) {
7525 met->
p[met->
np] = help->
p[ip];
7526 met->
t[met->
nx][met->
ny][met->
np] = help->
t[ix][iy][ip];
7527 met->
u[met->
nx][met->
ny][met->
np] = help->
u[ix][iy][ip];
7528 met->
v[met->
nx][met->
ny][met->
np] = help->
v[ix][iy][ip];
7529 met->
w[met->
nx][met->
ny][met->
np] = help->
w[ix][iy][ip];
7530 met->
h2o[met->
nx][met->
ny][met->
np] = help->
h2o[ix][iy][ip];
7531 met->
o3[met->
nx][met->
ny][met->
np] = help->
o3[ix][iy][ip];
7532 met->
lwc[met->
nx][met->
ny][met->
np] = help->
lwc[ix][iy][ip];
7533 met->
rwc[met->
nx][met->
ny][met->
np] = help->
rwc[ix][iy][ip];
7534 met->
iwc[met->
nx][met->
ny][met->
np] = help->
iwc[ix][iy][ip];
7535 met->
swc[met->
nx][met->
ny][met->
np] = help->
swc[ix][iy][ip];
7536 met->
cc[met->
nx][met->
ny][met->
np] = help->
cc[ix][iy][ip];
7557 LOG(2,
"Read surface data...");
7564 (ncid,
"lnsp",
"LNSP", NULL, NULL, ctl, met, met->
ps, 1.0f, 1)) {
7565 for (
int ix = 0; ix < met->
nx; ix++)
7566 for (
int iy = 0; iy < met->
ny; iy++)
7567 met->
ps[ix][iy] = (
float) (exp(met->
ps[ix][iy]) / 100.);
7570 (ncid,
"ps",
"PS",
"sp",
"SP", ctl, met, met->
ps, 0.01f, 1)) {
7571 WARN(
"Cannot not read surface pressure data (use lowest level)!");
7572 for (
int ix = 0; ix < met->
nx; ix++)
7573 for (
int iy = 0; iy < met->
ny; iy++)
7574 met->
ps[ix][iy] = (
float) met->
p[0];
7579 (ncid,
"z",
"Z", NULL, NULL, ctl, met, met->
zs,
7580 (
float) (1. / (1000. *
G0)), 1))
7582 (ncid,
"zm",
"ZM", NULL, NULL, ctl, met, met->
zs,
7583 (
float) (1. / 1000.), 1))
7584 WARN(
"Cannot read surface geopotential height!");
7588 (ncid,
"t2m",
"T2M",
"2t",
"2T", ctl, met, met->
ts, 1.0, 1))
7589 WARN(
"Cannot read surface temperature!");
7593 (ncid,
"u10m",
"U10M",
"10u",
"10U", ctl, met, met->
us, 1.0, 1))
7594 WARN(
"Cannot read surface zonal wind!");
7598 (ncid,
"v10m",
"V10M",
"10v",
"10V", ctl, met, met->
vs, 1.0, 1))
7599 WARN(
"Cannot read surface meridional wind!");
7603 (ncid,
"lsm",
"LSM", NULL, NULL, ctl, met, met->
lsm, 1.0, 1))
7604 WARN(
"Cannot read land-sea mask!");
7608 (ncid,
"sstk",
"SSTK",
"sst",
"SST", ctl, met, met->
sst, 1.0, 1))
7609 WARN(
"Cannot read sea surface temperature!");
7617 (ncid,
"ps",
"PS", NULL, NULL, ctl, met, met->
ps, 0.01f, 1)) {
7618 WARN(
"Cannot not read surface pressure data (use lowest level)!");
7619 for (
int ix = 0; ix < met->
nx; ix++)
7620 for (
int iy = 0; iy < met->
ny; iy++)
7621 met->
ps[ix][iy] = (
float) met->
p[0];
7629 memcpy(help, met->
pl,
sizeof(met->
pl));
7631 (ncid,
"gph",
"GPH", NULL, NULL, ctl, met, met->
pl,
7632 (
float) (1e-3 /
G0))) {
7633 ERRMSG(
"Cannot read geopotential height!");
7635 for (
int ix = 0; ix < met->
nx; ix++)
7636 for (
int iy = 0; iy < met->
ny; iy++)
7637 met->
zs[ix][iy] = met->
pl[ix][iy][0];
7638 memcpy(met->
pl, help,
sizeof(met->
pl));
7643 (ncid,
"t2",
"T2", NULL, NULL, ctl, met, met->
ts, 1.0, 1))
7644 WARN(
"Cannot read surface temperature!");
7648 (ncid,
"u10",
"U10", NULL, NULL, ctl, met, met->
us, 1.0, 1))
7649 WARN(
"Cannot read surface zonal wind!");
7653 (ncid,
"v10",
"V10", NULL, NULL, ctl, met, met->
vs, 1.0, 1))
7654 WARN(
"Cannot read surface meridional wind!");
7658 (ncid,
"lsm",
"LSM", NULL, NULL, ctl, met, met->
lsm, 1.0, 1))
7659 WARN(
"Cannot read land-sea mask!");
7663 (ncid,
"sstk",
"SSTK", NULL, NULL, ctl, met, met->
sst, 1.0, 1))
7664 WARN(
"Cannot read sea surface temperature!");
7675 double p2[200], pv[
EP], pv2[200], t[
EP], t2[200], th[
EP],
7676 th2[200], z[
EP], z2[200];
7680 LOG(2,
"Calculate tropopause...");
7683#pragma omp parallel for default(shared)
7684 for (
int iz = 0; iz < met->
np; iz++)
7685 z[iz] =
Z(met->
p[iz]);
7686#pragma omp parallel for default(shared)
7687 for (
int iz = 0; iz <= 190; iz++) {
7688 z2[iz] = 4.5 + 0.1 * iz;
7694#pragma omp parallel for default(shared) collapse(2)
7695 for (
int ix = 0; ix < met->
nx; ix++)
7696 for (
int iy = 0; iy < met->
ny; iy++)
7697 met->
pt[ix][iy] = NAN;
7701#pragma omp parallel for default(shared) collapse(2)
7702 for (
int ix = 0; ix < met->
nx; ix++)
7703 for (
int iy = 0; iy < met->
ny; iy++)
7711#pragma omp parallel for default(shared) private(t,t2) collapse(2)
7712 for (
int ix = 0; ix < met->
nx; ix++)
7713 for (
int iy = 0; iy < met->
ny; iy++) {
7716 for (
int iz = 0; iz < met->
np; iz++)
7717 t[iz] = met->
t[ix][iy][iz];
7721 int iz = (int) gsl_stats_min_index(t2, 1, 171);
7722 if (iz > 0 && iz < 170)
7723 met->
pt[ix][iy] = (float) p2[iz];
7725 met->
pt[ix][iy] = NAN;
7733#pragma omp parallel for default(shared) private(t,t2) collapse(2)
7734 for (
int ix = 0; ix < met->
nx; ix++)
7735 for (
int iy = 0; iy < met->
ny; iy++) {
7739 for (iz = 0; iz < met->
np; iz++)
7740 t[iz] = met->
t[ix][iy][iz];
7744 met->
pt[ix][iy] = NAN;
7745 for (iz = 0; iz <= 170; iz++) {
7747 for (
int iz2 = iz + 1; iz2 <= iz + 20; iz2++)
7748 if (
LAPSE(p2[iz], t2[iz], p2[iz2], t2[iz2]) > 2.0) {
7753 if (iz > 0 && iz < 170)
7754 met->
pt[ix][iy] = (float) p2[iz];
7761 met->
pt[ix][iy] = NAN;
7762 for (; iz <= 170; iz++) {
7764 for (
int iz2 = iz + 1; iz2 <= iz + 10; iz2++)
7765 if (
LAPSE(p2[iz], t2[iz], p2[iz2], t2[iz2]) < 3.0) {
7772 for (; iz <= 170; iz++) {
7774 for (
int iz2 = iz + 1; iz2 <= iz + 20; iz2++)
7775 if (
LAPSE(p2[iz], t2[iz], p2[iz2], t2[iz2]) > 2.0) {
7780 if (iz > 0 && iz < 170)
7781 met->
pt[ix][iy] = (float) p2[iz];
7793#pragma omp parallel for default(shared) private(pv,pv2,th,th2) collapse(2)
7794 for (
int ix = 0; ix < met->
nx; ix++)
7795 for (
int iy = 0; iy < met->
ny; iy++) {
7798 for (
int iz = 0; iz < met->
np; iz++)
7799 pv[iz] = met->
pv[ix][iy][iz];
7803 for (
int iz = 0; iz < met->
np; iz++)
7804 th[iz] =
THETA(met->
p[iz], met->
t[ix][iy][iz]);
7808 met->
pt[ix][iy] = NAN;
7809 for (
int iz = 0; iz <= 170; iz++)
7812 if (iz > 0 && iz < 170)
7813 met->
pt[ix][iy] = (float) p2[iz];
7820 ERRMSG(
"Cannot calculate tropopause!");
7823#pragma omp parallel for default(shared) collapse(2)
7824 for (
int ix = 0; ix < met->
nx; ix++)
7825 for (
int iy = 0; iy < met->
ny; iy++) {
7826 double h2ot, tt, zt;
7829 met->
lat[iy], &tt, ci, cw, 1);
7831 met->
lat[iy], &zt, ci, cw, 0);
7833 met->
lat[iy], &h2ot, ci, cw, 0);
7834 met->
tt[ix][iy] = (float) tt;
7835 met->
zt[ix][iy] = (float) zt;
7836 met->
h2ot[ix][iy] = (float) h2ot;
7843 const char *filename,
7853 LOG(1,
"Read observation data: %s", filename);
7857 read_obs_asc(filename, rt, rz, rlon, rlat, robs, nobs);
7859 read_obs_nc(filename, rt, rz, rlon, rlat, robs, nobs);
7861 ERRMSG(
"Set OBS_TYPE to 0 or 1!");
7864 for (
int i = 1; i < *nobs; i++)
7865 if (rt[i] < rt[i - 1])
7866 ERRMSG(
"Time must be ascending!");
7871 LOG(2,
"Number of observations: %d", *nobs);
7872 gsl_stats_minmax(&mini, &maxi, rt, 1, (
size_t) n);
7873 LOG(2,
"Time range: %.2f ... %.2f s", mini, maxi);
7874 gsl_stats_minmax(&mini, &maxi, rz, 1, (
size_t) n);
7875 LOG(2,
"Altitude range: %g ... %g km", mini, maxi);
7876 gsl_stats_minmax(&mini, &maxi, rlon, 1, (
size_t) n);
7877 LOG(2,
"Longitude range: %g ... %g deg", mini, maxi);
7878 gsl_stats_minmax(&mini, &maxi, rlat, 1, (
size_t) n);
7879 LOG(2,
"Latitude range: %g ... %g deg", mini, maxi);
7880 gsl_stats_minmax(&mini, &maxi, robs, 1, (
size_t) n);
7881 LOG(2,
"Observation range: %g ... %g", mini, maxi);
7887 const char *filename,
7897 if (!(in = fopen(filename,
"r")))
7898 ERRMSG(
"Cannot open file!");
7902 while (fgets(line,
LEN, in))
7903 if (sscanf(line,
"%lg %lg %lg %lg %lg", &rt[*nobs], &rz[*nobs],
7904 &rlon[*nobs], &rlat[*nobs], &robs[*nobs]) == 5)
7905 if ((++(*nobs)) >=
NOBS)
7906 ERRMSG(
"Too many observations!");
7915 const char *filename,
7926 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR)
7927 ERRMSG(
"Cannot open file!");
7944 const char *filename,
7947 const char *varname,
7949 const char *defvalue,
7954 char fullname1[
LEN], fullname2[
LEN], rval[
LEN];
7959 if (filename[strlen(filename) - 1] !=
'-')
7960 if (!(in = fopen(filename,
"r")))
7961 ERRMSG(
"Cannot open file!");
7965 sprintf(fullname1,
"%s[%d]", varname, arridx);
7966 sprintf(fullname2,
"%s[*]", varname);
7968 sprintf(fullname1,
"%s", varname);
7969 sprintf(fullname2,
"%s", varname);
7974 char dummy[
LEN], line[
LEN], rvarname[
LEN];
7975 while (fgets(line,
LEN, in)) {
7976 if (sscanf(line,
"%4999s %4999s %4999s", rvarname, dummy, rval) == 3)
7977 if (strcasecmp(rvarname, fullname1) == 0 ||
7978 strcasecmp(rvarname, fullname2) == 0) {
7984 for (i = 1; i < argc - 1; i++)
7985 if (strcasecmp(argv[i], fullname1) == 0 ||
7986 strcasecmp(argv[i], fullname2) == 0) {
7987 sprintf(rval,
"%s", argv[i + 1]);
7998 if (strlen(defvalue) > 0)
7999 sprintf(rval,
"%s", defvalue);
8001 ERRMSG(
"Missing variable %s!\n", fullname1);
8005 LOG(1,
"%s = %s", fullname1, rval);
8009 sprintf(value,
"%s", rval);
8019 const double rhop) {
8022 double rp_help = rp * 1e-6;
8025 double rho =
RHO(p, T);
8028 double eta = 1.8325e-5 * (416.16 / (T + 120.)) * pow(T / 296.16, 1.5);
8031 double v = sqrt(8. *
KB * T / (M_PI * 4.8096e-26));
8034 double lambda = 2. * eta / (rho * v);
8037 double K = lambda / rp_help;
8040 double G = 1. + K * (1.249 + 0.42 * exp(-0.87 / K));
8043 return 2. *
SQR(rp_help) * (rhop - rho) *
G0 / (9. * eta) * G;
8061 gsl_interp_accel *acc;
8063 acc = gsl_interp_accel_alloc();
8064 s = gsl_spline_alloc(gsl_interp_cspline, (
size_t) n);
8067 gsl_spline_init(s, x, y, (
size_t) n);
8068 for (
int i = 0; i < n2; i++)
8071 else if (x2[i] >= x[n - 1])
8074 y2[i] = gsl_spline_eval(s, x2[i], acc);
8078 gsl_interp_accel_free(acc);
8083 for (
int i = 0; i < n2; i++)
8086 else if (x2[i] >= x[n - 1])
8090 y2[i] =
LIN(x[idx], y[idx], x[idx + 1], y[idx + 1], x2[i]);
8104 float mean = 0, var = 0;
8106 for (
int i = 0; i < n; ++i) {
8108 var +=
SQR(data[i]);
8111 var = var / (float) n -
SQR(mean / (
float) n);
8113 return (var > 0 ? sqrtf(var) : 0);
8124 const double D = sec / 86400 - 0.5;
8127 const double g = (357.529 + 0.98560028 * D) * M_PI / 180;
8128 const double q = 280.459 + 0.98564736 * D;
8129 const double L = (q + 1.915 * sin(g) + 0.020 * sin(2 * g)) * M_PI / 180;
8132 const double e = (23.439 - 0.00000036 * D) * M_PI / 180;
8135 const double sindec = sin(e) * sin(L);
8138 const double ra = atan2(cos(e) * sin(L), cos(L));
8141 const double GMST = 18.697374558 + 24.06570982441908 * D;
8144 const double LST = GMST + lon / 15;
8147 const double h = LST / 12 * M_PI - ra;
8150 const double lat_help = lat * M_PI / 180;
8153 return acos(sin(lat_help) * sindec +
8154 cos(lat_help) * sqrt(1 -
SQR(sindec)) * cos(h));
8166 const double remain,
8178 t1.tm_year = year - 1900;
8179 t1.tm_mon = mon - 1;
8185 *jsec = (double) timegm(&t1) - (double) timegm(&t0) + remain;
8200 static int iname = -1, igroup = -1, nname, ngroup, ct_name[
NTIMER];
8203 t1 = omp_get_wtime();
8208 rt_name[iname] += dt;
8209 rt_min[iname] = (ct_name[iname] <= 0 ? dt :
MIN(rt_min[iname], dt));
8210 rt_max[iname] = (ct_name[iname] <= 0 ? dt :
MAX(rt_max[iname], dt));
8214 rt_group[igroup] += t1 - t0;
8218 for (
int i = 0; i < nname; i++)
8219 LOG(1,
"TIMER_%s = %.3f s (min= %g s, mean= %g s,"
8220 " max= %g s, n= %d)", names[i], rt_name[i], rt_min[i],
8221 rt_name[i] / ct_name[i], rt_max[i], ct_name[i]);
8222 for (
int i = 0; i < ngroup; i++)
8223 LOG(1,
"TIMER_GROUP_%s = %.3f s", groups[i], rt_group[i]);
8225 for (
int i = 0; i < nname; i++)
8226 total += rt_name[i];
8227 LOG(1,
"TIMER_TOTAL = %.3f s", total);
8231 for (iname = 0; iname < nname; iname++)
8232 if (strcasecmp(name, names[iname]) == 0)
8234 for (igroup = 0; igroup < ngroup; igroup++)
8235 if (strcasecmp(group, groups[igroup]) == 0)
8239 if (iname >= nname) {
8240 sprintf(names[iname],
"%s", name);
8242 ERRMSG(
"Too many timers!");
8246 if (igroup >= ngroup) {
8247 sprintf(groups[igroup],
"%s", group);
8248 if ((++ngroup) >=
NTIMER)
8249 ERRMSG(
"Too many groups!");
8259 const char *filename,
8267 int len = (int) strlen(filename);
8268 sprintf(tstr,
"%.4s", &filename[len - offset]);
8269 int year = atoi(tstr);
8270 sprintf(tstr,
"%.2s", &filename[len - offset + 5]);
8271 int mon = atoi(tstr);
8272 sprintf(tstr,
"%.2s", &filename[len - offset + 8]);
8273 int day = atoi(tstr);
8274 sprintf(tstr,
"%.2s", &filename[len - offset + 11]);
8275 int hour = atoi(tstr);
8276 sprintf(tstr,
"%.2s", &filename[len - offset + 14]);
8277 int min = atoi(tstr);
8280 if (year < 1900 || year > 2100 || mon < 1 || mon > 12 || day < 1
8281 || day > 31 || hour < 0 || hour > 23 || min < 0 || min > 59)
8282 ERRMSG(
"Cannot read time from filename!");
8285 time2jsec(year, mon, day, hour, min, 0, 0.0, &t);
8303 double p1 = pt * 0.866877899;
8304 double p0 = pt / 0.866877899;
8312 return LIN(p0, 1.0, p1, 0.0, p);
8318 const char *filename,
8327 LOG(1,
"Write atmospheric data: %s", filename);
8351 ERRMSG(
"Atmospheric data type not supported!");
8355 LOG(2,
"Number of particles: %d", atm->
np);
8356 gsl_stats_minmax(&mini, &maxi, atm->
time, 1, (
size_t) atm->
np);
8357 LOG(2,
"Time range: %.2f ... %.2f s", mini, maxi);
8358 gsl_stats_minmax(&mini, &maxi, atm->
p, 1, (
size_t) atm->
np);
8359 LOG(2,
"Altitude range: %g ... %g km",
Z(maxi),
Z(mini));
8360 LOG(2,
"Pressure range: %g ... %g hPa", maxi, mini);
8361 gsl_stats_minmax(&mini, &maxi, atm->
lon, 1, (
size_t) atm->
np);
8362 LOG(2,
"Longitude range: %g ... %g deg", mini, maxi);
8363 gsl_stats_minmax(&mini, &maxi, atm->
lat, 1, (
size_t) atm->
np);
8364 LOG(2,
"Latitude range: %g ... %g deg", mini, maxi);
8365 for (
int iq = 0; iq < ctl->
nq; iq++) {
8367 sprintf(msg,
"Quantity %s range: %s ... %s %s",
8370 gsl_stats_minmax(&mini, &maxi, atm->
q[iq], 1, (
size_t) atm->
np);
8371 LOG(2, msg, mini, maxi);
8378 const char *filename,
8386 double t0 = t - 0.5 * ctl->
dt_mod;
8387 double t1 = t + 0.5 * ctl->
dt_mod;
8393 if (!(out = popen(
"gnuplot",
"w")))
8394 ERRMSG(
"Cannot create pipe to gnuplot!");
8397 fprintf(out,
"set out \"%s.png\"\n", filename);
8401 int year, mon, day, hour, min, sec;
8402 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
8403 fprintf(out,
"timestr=\"%d-%02d-%02d, %02d:%02d UTC\"\n",
8404 year, mon, day, hour, min);
8409 ERRMSG(
"Cannot open file!");
8411 while (fgets(line,
LEN, in))
8412 fprintf(out,
"%s", line);
8419 if (!(out = fopen(filename,
"w")))
8420 ERRMSG(
"Cannot create file!");
8426 "# $2 = altitude [km]\n"
8427 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
8428 for (
int iq = 0; iq < ctl->
nq; iq++)
8429 fprintf(out,
"# $%i = %s [%s]\n", iq + 5, ctl->
qnt_name[iq],
8434 for (
int ip = 0; ip < atm->
np; ip += ctl->
atm_stride) {
8441 fprintf(out,
"%.2f %g %g %g", atm->
time[ip],
Z(atm->
p[ip]),
8442 atm->
lon[ip], atm->
lat[ip]);
8443 for (
int iq = 0; iq < ctl->
nq; iq++) {
8448 fprintf(out, ctl->
qnt_format[iq], atm->
q[iq][ip]);
8460 const char *filename,
8467 if (!(out = fopen(filename,
"w")))
8468 ERRMSG(
"Cannot create file!");
8492 for (
int iq = 0; iq < ctl->
nq; iq++)
8510 const char *filename,
8514 int tid, pid, ncid, varid;
8515 size_t start[2], count[2];
8518 nc_create(filename, NC_CLOBBER, &ncid);
8521 NC(nc_def_dim(ncid,
"time", 1, &tid));
8522 NC(nc_def_dim(ncid,
"NPARTS", (
size_t) atm->
np, &pid));
8525 int dim_ids[2] = { tid, pid };
8526 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"Time",
8527 "seconds since 2000-01-01 00:00:00 UTC");
8528 NC_DEF_VAR(
"LAT", NC_DOUBLE, 1, &pid,
"Latitude",
"deg");
8529 NC_DEF_VAR(
"LON", NC_DOUBLE, 1, &pid,
"Longitude",
"deg");
8530 NC_DEF_VAR(
"PRESS", NC_DOUBLE, 1, &pid,
"Pressure",
"hPa");
8531 NC_DEF_VAR(
"ZETA", NC_DOUBLE, 1, &pid,
"Zeta",
"K");
8532 for (
int iq = 0; iq < ctl->
nq; iq++)
8541 NC(nc_enddef(ncid));
8549 for (
int iq = 0; iq < ctl->
nq; iq++)
8559 const char *dirname,
8565 static size_t out_cnt = 0;
8567 double r, r_start, r_stop;
8568 int year, mon, day, hour, min, sec;
8569 int year_start, mon_start, day_start, hour_start, min_start, sec_start;
8570 int year_stop, mon_stop, day_stop, hour_stop, min_stop, sec_stop;
8571 char filename_out[2 *
LEN] =
"traj_fix_3d_YYYYMMDDHH_YYYYMMDDHH.nc";
8573 int ncid, varid, tid, pid, cid;
8581 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
8583 &min_start, &sec_start, &r_start);
8585 &min_stop, &sec_stop, &r_stop);
8587 sprintf(filename_out,
"%s/traj_fix_3d_%02d%02d%02d%02d_%02d%02d%02d%02d.nc",
8589 year_start % 100, mon_start, day_start, hour_start,
8590 year_stop % 100, mon_stop, day_stop, hour_stop);
8591 LOG(1,
"Write traj file: %s", filename_out);
8597 count[1] = (size_t) atm->
np;
8603 nc_create(filename_out, NC_CLOBBER, &ncid);
8606 NC(nc_def_dim(ncid,
"time", NC_UNLIMITED, &tid));
8607 NC(nc_def_dim(ncid,
"NPARTS", (
size_t) atm->
np, &pid));
8608 NC(nc_def_dim(ncid,
"TMDT", 7, &cid));
8613 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"Time",
8614 "seconds since 2000-01-01 00:00:00 UTC");
8615 NC_DEF_VAR(
"LAT", NC_DOUBLE, 2, dim_ids,
"Latitude",
"deg");
8616 NC_DEF_VAR(
"LON", NC_DOUBLE, 2, dim_ids,
"Longitude",
"deg");
8617 NC_DEF_VAR(
"PRESS", NC_DOUBLE, 2, dim_ids,
"Pressure",
"hPa");
8618 NC_DEF_VAR(
"ZETA", NC_DOUBLE, 2, dim_ids,
"Zeta",
"K");
8619 for (
int iq = 0; iq < ctl->
nq; iq++)
8628 NC(nc_enddef(ncid));
8636 NC(nc_open(filename_out, NC_WRITE, &ncid));
8648 for (
int iq = 0; iq < ctl->
nq; iq++)
8655 if ((year == year_stop) && (mon == mon_stop)
8656 && (day == day_stop) && (hour == hour_stop)) {
8659 char filename_init[2 *
LEN] =
"./init_fix_YYYYMMDDHH.nc";
8660 sprintf(filename_init,
"%s/init_fix_%02d%02d%02d%02d.nc",
8661 dirname, year_stop % 100, mon_stop, day_stop, hour_stop);
8662 LOG(1,
"Write init file: %s", filename_init);
8665 nc_create(filename_init, NC_CLOBBER, &ncid);
8668 NC(nc_def_dim(ncid,
"time", 1, &tid));
8669 NC(nc_def_dim(ncid,
"NPARTS", (
size_t) atm->
np, &pid));
8674 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &tid,
"Time",
8675 "seconds since 2000-01-01 00:00:00 UTC");
8676 NC_DEF_VAR(
"LAT", NC_DOUBLE, 1, &pid,
"Latitude",
"deg");
8677 NC_DEF_VAR(
"LON", NC_DOUBLE, 1, &pid,
"Longitude",
"deg");
8678 NC_DEF_VAR(
"PRESS", NC_DOUBLE, 1, &pid,
"Pressure",
"hPa");
8679 NC_DEF_VAR(
"ZETA", NC_DOUBLE, 1, &pid,
"Zeta",
"K");
8680 for (
int iq = 0; iq < ctl->
nq; iq++)
8689 NC(nc_enddef(ncid));
8697 for (
int iq = 0; iq < ctl->
nq; iq++)
8708 const char *filename,
8712 int ncid, obsid, varid;
8714 size_t start[2], count[2];
8717 NC(nc_create(filename, NC_CLOBBER, &ncid));
8720 NC(nc_def_dim(ncid,
"obs", (
size_t) atm->
np, &obsid));
8723 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &obsid,
"time",
8724 "seconds since 2000-01-01 00:00:00 UTC");
8725 NC_DEF_VAR(
"press", NC_DOUBLE, 1, &obsid,
"pressure",
"hPa");
8726 NC_DEF_VAR(
"lon", NC_DOUBLE, 1, &obsid,
"longitude",
"degrees_east");
8727 NC_DEF_VAR(
"lat", NC_DOUBLE, 1, &obsid,
"latitude",
"degrees_north");
8728 for (
int iq = 0; iq < ctl->
nq; iq++)
8736 NC(nc_enddef(ncid));
8743 for (
int iq = 0; iq < ctl->
nq; iq++)
8753 const char *filename,
8760 static double *modmean, *obsmean, *obsstd, *rt, *rz, *rlon, *rlat, *robs,
8763 static int *obscount, ct, cx, cy, cz, ip, ix, iy, iz, n, nobs, nk;
8773 ERRMSG(
"Need quantity mass!");
8797 LOG(1,
"Write CSI data: %s", filename);
8798 if (!(out = fopen(filename,
"w")))
8799 ERRMSG(
"Cannot create file!");
8804 "# $2 = number of hits (cx)\n"
8805 "# $3 = number of misses (cy)\n"
8806 "# $4 = number of false alarms (cz)\n"
8807 "# $5 = number of observations (cx + cy)\n"
8808 "# $6 = number of forecasts (cx + cz)\n"
8809 "# $7 = bias (ratio of forecasts and observations) [%%]\n"
8810 "# $8 = probability of detection (POD) [%%]\n"
8811 "# $9 = false alarm rate (FAR) [%%]\n"
8812 "# $10 = critical success index (CSI) [%%]\n");
8814 "# $11 = hits associated with random chance\n"
8815 "# $12 = equitable threat score (ETS) [%%]\n"
8816 "# $13 = Pearson linear correlation coefficient\n"
8817 "# $14 = Spearman rank-order correlation coefficient\n"
8818 "# $15 = column density mean error (F - O) [kg/m^2]\n"
8819 "# $16 = column density root mean square error (RMSE) [kg/m^2]\n"
8820 "# $17 = column density mean absolute error [kg/m^2]\n"
8821 "# $18 = log-likelihood function\n"
8822 "# $19 = number of data points\n\n");
8830 for (iy = 0; iy < ctl->
csi_ny; iy++) {
8831 double lat = ctl->
csi_lat0 + dlat * (iy + 0.5);
8832 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.) * cos(lat * M_PI / 180.);
8837 double t0 = t - 0.5 * ctl->
dt_mod;
8838 double t1 = t + 0.5 * ctl->
dt_mod;
8841 ALLOC(modmean,
double,
8843 ALLOC(obsmean,
double,
8845 ALLOC(obscount,
int,
8847 ALLOC(obsstd,
double,
8851 for (
int i = 0; i < nobs; i++) {
8856 else if (rt[i] >= t1)
8860 if (!isfinite(robs[i]))
8864 ix = (int) ((rlon[i] - ctl->
csi_lon0) / dlon);
8865 iy = (int) ((rlat[i] - ctl->
csi_lat0) / dlat);
8866 iz = (int) ((rz[i] - ctl->
csi_z0) / dz);
8869 if (ix < 0 || ix >= ctl->
csi_nx ||
8870 iy < 0 || iy >= ctl->
csi_ny || iz < 0 || iz >= ctl->
csi_nz)
8875 obsmean[idx] += robs[i];
8876 obsstd[idx] +=
SQR(robs[i]);
8881 for (ip = 0; ip < atm->
np; ip++) {
8884 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
8888 ix = (int) ((atm->
lon[ip] - ctl->
csi_lon0) / dlon);
8889 iy = (int) ((atm->
lat[ip] - ctl->
csi_lat0) / dlat);
8890 iz = (int) ((
Z(atm->
p[ip]) - ctl->
csi_z0) / dz);
8893 if (ix < 0 || ix >= ctl->
csi_nx ||
8894 iy < 0 || iy >= ctl->
csi_ny || iz < 0 || iz >= ctl->
csi_nz)
8900 * atm->
q[ctl->
qnt_m][ip];
8904 for (ix = 0; ix < ctl->
csi_nx; ix++)
8905 for (iy = 0; iy < ctl->
csi_ny; iy++)
8906 for (iz = 0; iz < ctl->
csi_nz; iz++) {
8910 if (obscount[idx] > 0) {
8911 obsmean[idx] /= obscount[idx];
8912 obsstd[idx] -=
SQR(obsmean[idx]);
8913 obsstd[idx] = sqrt(obsstd[idx]);
8917 if (modmean[idx] > 0)
8918 modmean[idx] /= (1e6 * area[iy]);
8921 if (obscount[idx] > 0) {
8935 if (obscount[idx] > 0
8938 x[n] = modmean[idx];
8939 y[n] = obsmean[idx];
8941 obsstdn[n] = obsstd[idx];
8943 ERRMSG(
"Too many data points to calculate statistics!");
8952 static double work[2 *
NCSI], work2[2 *
NCSI];;
8953 int n_obs = cx + cy;
8954 int n_for = cx + cz;
8955 double bias = (n_obs > 0) ? 100. * n_for / n_obs : NAN;
8956 double pod = (n_obs > 0) ? (100. * cx) / n_obs : NAN;
8957 double far = (n_for > 0) ? (100. * cz) / n_for : NAN;
8958 double csi = (cx + cy + cz > 0) ? (100. * cx) / (cx + cy + cz) : NAN;
8959 double cx_rd = (ct > 0) ? (1. * n_obs * n_for) / ct : NAN;
8960 double ets = (cx + cy + cz - cx_rd > 0) ?
8961 (100. * (cx - cx_rd)) / (cx + cy + cz - cx_rd) : NAN;
8963 (n > 0) ? gsl_stats_correlation(x, 1, y, 1, (
size_t) n) : NAN;
8965 (n > 0) ? gsl_stats_spearman(x, 1, y, 1, (
size_t) n, work) : NAN;
8966 for (
int i = 0; i < n; i++) {
8967 work[i] = x[i] - y[i];
8968 work2[i] = (obsstdn[i] != 0) ? (x[i] - y[i]) / obsstdn[i] : 0;
8970 double mean = (n > 0) ? gsl_stats_mean(work, 1, (
size_t) n) : NAN;
8971 double rmse = (n > 0) ? gsl_stats_sd_with_fixed_mean(work, 1, (
size_t) n,
8974 (n > 0) ? gsl_stats_absdev_m(work, 1, (
size_t) n, 0.0) : NAN;
8975 double loglikelihood =
8976 (n > 0) ? gsl_stats_tss(work2, 1, (
size_t) n) * (-0.5) : GSL_NAN;
8980 "%.2f %d %d %d %d %d %g %g %g %g %g %g %g %g %g %g %g %g %d\n", t,
8981 cx, cy, cz, n_obs, n_for, bias, pod, far, csi, cx_rd, ets, rho_p,
8982 rho_s, mean, rmse, absdev, loglikelihood, n);
8985 n = ct = cx = cy = cz = 0;
9013 const char *filename,
9030 ERRMSG(
"Missing ensemble IDs!");
9033 double t0 = t - 0.5 * ctl->
dt_mod;
9034 double t1 = t + 0.5 * ctl->
dt_mod;
9037 for (
int i = 0; i <
NENS; i++) {
9038 for (
int iq = 0; iq < ctl->
nq; iq++)
9039 qm[iq][i] = qs[iq][i] = 0;
9040 xm[i][0] = xm[i][1] = xm[i][2] = zm[i] = 0;
9045 for (
int ip = 0; ip < atm->
np; ip++) {
9048 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
9053 ERRMSG(
"Ensemble ID is out of range!");
9057 for (
int iq = 0; iq < ctl->
nq; iq++) {
9058 qm[iq][ctl->
qnt_ens] += atm->
q[iq][ip];
9069 LOG(1,
"Write ensemble data: %s", filename);
9070 if (!(out = fopen(filename,
"w")))
9071 ERRMSG(
"Cannot create file!");
9076 "# $2 = altitude [km]\n"
9077 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
9078 for (
int iq = 0; iq < ctl->
nq; iq++)
9079 fprintf(out,
"# $%d = %s (mean) [%s]\n", 5 + iq,
9081 for (
int iq = 0; iq < ctl->
nq; iq++)
9082 fprintf(out,
"# $%d = %s (sigma) [%s]\n", 5 + ctl->
nq + iq,
9084 fprintf(out,
"# $%d = number of members\n\n", 5 + 2 * ctl->
nq);
9087 for (
int i = 0; i <
NENS; i++)
9089 cart2geo(xm[i], &dummy, &lon, &lat);
9090 fprintf(out,
"%.2f %g %g %g", t, zm[i] / n[i], lon, lat);
9091 for (
int iq = 0; iq < ctl->
nq; iq++) {
9093 fprintf(out, ctl->
qnt_format[iq], qm[iq][i] / n[i]);
9095 for (
int iq = 0; iq < ctl->
nq; iq++) {
9097 double var = qs[iq][i] / n[i] -
SQR(qm[iq][i] / n[i]);
9098 fprintf(out, ctl->
qnt_format[iq], (var > 0 ? sqrt(var) : 0));
9100 fprintf(out,
" %d\n", n[i]);
9110 const char *filename,
9117 static double kz[
EP], kw[
EP];
9121 double *cd, *mean[
NQ], *sigma[
NQ], *vmr_impl, *z, *lon, *lat, *area, *press;
9123 int *ixs, *iys, *izs, *np;
9129 LOG(1,
"Write grid data: %s", filename);
9142 for (
int iq = 0; iq < ctl->
nq; iq++) {
9143 ALLOC(mean[iq],
double,
9145 ALLOC(sigma[iq],
double,
9148 ALLOC(vmr_impl,
double,
9158 ALLOC(press,
double,
9175#pragma omp parallel
for default(shared)
9176 for (
int iz = 0; iz < ctl->
grid_nz; iz++) {
9177 z[iz] = ctl->
grid_z0 + dz * (iz + 0.5);
9178 press[iz] =
P(z[iz]);
9182 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
9183 lon[ix] = ctl->
grid_lon0 + dlon * (ix + 0.5);
9184#pragma omp parallel for default(shared)
9185 for (
int iy = 0; iy < ctl->
grid_ny; iy++) {
9186 lat[iy] = ctl->
grid_lat0 + dlat * (iy + 0.5);
9187 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.)
9188 * cos(lat[iy] * M_PI / 180.);
9192 double t0 = t - 0.5 * ctl->
dt_mod;
9193 double t1 = t + 0.5 * ctl->
dt_mod;
9196#pragma omp parallel for default(shared)
9197 for (
int ip = 0; ip < atm->
np; ip++) {
9198 ixs[ip] = (int) ((atm->
lon[ip] - ctl->
grid_lon0) / dlon);
9199 iys[ip] = (int) ((atm->
lat[ip] - ctl->
grid_lat0) / dlat);
9200 izs[ip] = (int) ((
Z(atm->
p[ip]) - ctl->
grid_z0) / dz);
9201 if (atm->
time[ip] < t0 || atm->
time[ip] > t1
9202 || ixs[ip] < 0 || ixs[ip] >= ctl->
grid_nx
9203 || iys[ip] < 0 || iys[ip] >= ctl->
grid_ny
9204 || izs[ip] < 0 || izs[ip] >= ctl->
grid_nz)
9209 for (
int ip = 0; ip < atm->
np; ip++)
9215 for (
int iq = 0; iq < ctl->
nq; iq++) {
9216 mean[iq][idx] += kernel * atm->
q[iq][ip];
9217 sigma[iq][idx] +=
SQR(kernel * atm->
q[iq][ip]);
9222#pragma omp parallel for default(shared)
9223 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
9224 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
9225 for (
int iz = 0; iz < ctl->
grid_nz; iz++) {
9232 if (ctl->
qnt_m >= 0)
9233 cd[idx] = mean[ctl->
qnt_m][idx] / (1e6 * area[iy]);
9236 vmr_impl[idx] = NAN;
9237 if (ctl->
qnt_m >= 0 && ctl->
molmass > 0 && met0 != NULL
9240 if (mean[ctl->
qnt_m][idx] > 0) {
9246 lon[ix], lat[iy], &temp, ci, cw, 1);
9250 / (
RHO(press[iz], temp) * 1e6 * area[iy] * 1e3 * dz);
9256 for (
int iq = 0; iq < ctl->
nq; iq++) {
9257 mean[iq][idx] /= np[idx];
9258 double var = sigma[iq][idx] / np[idx] -
SQR(mean[iq][idx]);
9259 sigma[iq][idx] = (var > 0 ? sqrt(var) : 0);
9261 for (
int iq = 0; iq < ctl->
nq; iq++) {
9262 mean[iq][idx] = NAN;
9263 sigma[iq][idx] = NAN;
9270 t, z, lon, lat, area, dz, np);
9275 t, z, lon, lat, area, dz, np);
9279 ERRMSG(
"Grid data format GRID_TYPE unknown!");
9283 for (
int iq = 0; iq < ctl->
nq; iq++) {
9302 const char *filename,
9322 if (!(out = popen(
"gnuplot",
"w")))
9323 ERRMSG(
"Cannot create pipe to gnuplot!");
9326 fprintf(out,
"set out \"%s.png\"\n", filename);
9330 int year, mon, day, hour, min, sec;
9331 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
9332 fprintf(out,
"timestr=\"%d-%02d-%02d, %02d:%02d UTC\"\n",
9333 year, mon, day, hour, min);
9339 ERRMSG(
"Cannot open file!");
9340 while (fgets(line,
LEN, in))
9341 fprintf(out,
"%s", line);
9348 if (!(out = fopen(filename,
"w")))
9349 ERRMSG(
"Cannot create file!");
9355 "# $2 = altitude [km]\n"
9356 "# $3 = longitude [deg]\n"
9357 "# $4 = latitude [deg]\n"
9358 "# $5 = surface area [km^2]\n"
9359 "# $6 = layer depth [km]\n"
9360 "# $7 = column density (implicit) [kg/m^2]\n"
9361 "# $8 = volume mixing ratio (implicit) [ppv]\n"
9362 "# $9 = number of particles [1]\n");
9363 for (
int iq = 0; iq < ctl->
nq; iq++)
9364 fprintf(out,
"# $%i = %s (mean) [%s]\n", 10 + iq, ctl->
qnt_name[iq],
9367 for (
int iq = 0; iq < ctl->
nq; iq++)
9368 fprintf(out,
"# $%i = %s (stddev) [%s]\n", 10 + ctl->
nq + iq,
9373 for (
int ix = 0; ix < ctl->
grid_nx; ix++) {
9376 for (
int iy = 0; iy < ctl->
grid_ny; iy++) {
9379 for (
int iz = 0; iz < ctl->
grid_nz; iz++) {
9382 fprintf(out,
"%.2f %g %g %g %g %g %g %g %d", t, z[iz], lon[ix],
9383 lat[iy], area[iy], dz, cd[idx], vmr_impl[idx], np[idx]);
9384 for (
int iq = 0; iq < ctl->
nq; iq++) {
9386 fprintf(out, ctl->
qnt_format[iq], mean[iq][idx]);
9389 for (
int iq = 0; iq < ctl->
nq; iq++) {
9391 fprintf(out, ctl->
qnt_format[iq], sigma[iq][idx]);
9406 const char *filename,
9420 char longname[2 *
LEN], varname[2 *
LEN];
9424 int *help2, ncid, dimid[10], varid;
9426 size_t start[2], count[2];
9435 NC(nc_create(filename, NC_CLOBBER, &ncid));
9438 NC(nc_def_dim(ncid,
"time", 1, &dimid[0]));
9439 NC(nc_def_dim(ncid,
"z", (
size_t) ctl->
grid_nz, &dimid[1]));
9440 NC(nc_def_dim(ncid,
"lat", (
size_t) ctl->
grid_ny, &dimid[2]));
9441 NC(nc_def_dim(ncid,
"lon", (
size_t) ctl->
grid_nx, &dimid[3]));
9442 NC(nc_def_dim(ncid,
"dz", 1, &dimid[4]));
9445 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &dimid[0],
"time",
9446 "seconds since 2000-01-01 00:00:00 UTC");
9447 NC_DEF_VAR(
"z", NC_DOUBLE, 1, &dimid[1],
"altitude",
"km");
9448 NC_DEF_VAR(
"lat", NC_DOUBLE, 1, &dimid[2],
"latitude",
"degrees_north");
9449 NC_DEF_VAR(
"lon", NC_DOUBLE, 1, &dimid[3],
"longitude",
"degrees_east");
9450 NC_DEF_VAR(
"dz", NC_DOUBLE, 1, &dimid[1],
"layer depth",
"km");
9451 NC_DEF_VAR(
"area", NC_DOUBLE, 1, &dimid[2],
"surface area",
"km**2");
9452 NC_DEF_VAR(
"cd", NC_FLOAT, 4, dimid,
"column density",
"kg m**-2");
9454 "volume mixing ratio (implicit)",
"ppv");
9455 NC_DEF_VAR(
"np", NC_INT, 4, dimid,
"number of particles",
"1");
9456 for (
int iq = 0; iq < ctl->
nq; iq++) {
9457 sprintf(varname,
"%s_mean", ctl->
qnt_name[iq]);
9461 sprintf(varname,
"%s_stddev", ctl->
qnt_name[iq]);
9462 sprintf(longname,
"%s (stddev)", ctl->
qnt_longname[iq]);
9467 NC(nc_enddef(ncid));
9477 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
9478 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
9479 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
9484 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
9485 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
9486 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
9491 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
9492 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
9493 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
9498 for (
int iq = 0; iq < ctl->
nq; iq++) {
9499 sprintf(varname,
"%s_mean", ctl->
qnt_name[iq]);
9500 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
9501 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
9502 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
9509 for (
int iq = 0; iq < ctl->
nq; iq++) {
9510 sprintf(varname,
"%s_stddev", ctl->
qnt_name[iq]);
9511 for (
int ix = 0; ix < ctl->
grid_nx; ix++)
9512 for (
int iy = 0; iy < ctl->
grid_ny; iy++)
9513 for (
int iz = 0; iz < ctl->
grid_nz; iz++)
9530 const char *filename,
9538 LOG(1,
"Write meteo data: %s", filename);
9543 ERRMSG(
"MPTRAC was compiled without zfp compression!");
9547 ERRMSG(
"MPTRAC was compiled without zstd compression!");
9551 ERRMSG(
"MPTRAC was compiled without cmultiscale compression!");
9559 if (!(out = fopen(filename,
"w")))
9560 ERRMSG(
"Cannot create file!");
9665 for (
int ix = 0; ix < met->
nx; ix++)
9666 for (
int iy = 0; iy < met->
ny; iy++)
9667 help[
ARRAY_2D(ix, iy, met->
ny)] = var[ix][iy];
9670 LOG(2,
"Write 2-D variable: %s (uncompressed)", varname);
9672 (
size_t) (met->
nx * met->
ny),
9697#pragma omp parallel for default(shared) collapse(2)
9698 for (
int ix = 0; ix < met->
nx; ix++)
9699 for (
int iy = 0; iy < met->
ny; iy++)
9700 for (
int ip = 0; ip < met->
np; ip++)
9701 help[
ARRAY_3D(ix, iy, met->
ny, ip, met->
np)] = var[ix][iy][ip];
9705 LOG(2,
"Write 3-D variable: %s (uncompressed)", varname);
9707 (
size_t) (met->
nx * met->
ny * met->
np),
9714 (
size_t) met->
np, 0, out);
9722 FWRITE(&tolerance,
double,
9741 (
size_t) met->
np, 0, out);
9747 ERRMSG(
"MET_TYPE not supported!");
9748 LOG(3,
"%d %g", precision, tolerance);
9758 const char *dirname,
9765 char ext[10], filename[2 *
LEN];
9769 int year, mon, day, hour, min, sec;
9772 jsec2time(t, &year, &mon, &day, &hour, &min, &sec, &r);
9783#pragma acc update host(atm[:1])
9791 sprintf(ext,
"tab");
9793 sprintf(ext,
"bin");
9796 sprintf(filename,
"%s/%s_%04d_%02d_%02d_%02d_%02d.%s",
9797 dirname, ctl->
atm_basename, year, mon, day, hour, min, ext);
9803 sprintf(filename,
"%s/%s_%04d_%02d_%02d_%02d_%02d.%s",
9806 write_grid(filename, ctl, met0, met1, atm, t);
9811 sprintf(filename,
"%s/%s.tab", dirname, ctl->
csi_basename);
9817 sprintf(filename,
"%s/%s_%04d_%02d_%02d_%02d_%02d.tab",
9818 dirname, ctl->
ens_basename, year, mon, day, hour, min);
9824 sprintf(filename,
"%s/%s.tab", dirname, ctl->
prof_basename);
9825 write_prof(filename, ctl, met0, met1, atm, t);
9836 sprintf(filename,
"%s/%s.tab", dirname, ctl->
stat_basename);
9845 sprintf(filename,
"%s/%s_%05d.vtk", dirname, ctl->
vtk_basename, ++nvtk);
9853 const char *filename,
9862 static double *mass, *obsmean, *rt, *rz, *rlon, *rlat, *robs, *area,
9863 dz, dlon, dlat, *lon, *lat, *z, *press, temp, vmr, h2o, o3;
9865 static int nobs, *obscount, ip, okay;
9875 ERRMSG(
"Need quantity mass!");
9879 ERRMSG(
"Specify molar mass!");
9890 ALLOC(press,
double,
9907 LOG(1,
"Write profile data: %s", filename);
9908 if (!(out = fopen(filename,
"w")))
9909 ERRMSG(
"Cannot create file!");
9914 "# $2 = altitude [km]\n"
9915 "# $3 = longitude [deg]\n"
9916 "# $4 = latitude [deg]\n"
9917 "# $5 = pressure [hPa]\n"
9918 "# $6 = temperature [K]\n"
9919 "# $7 = volume mixing ratio [ppv]\n"
9920 "# $8 = H2O volume mixing ratio [ppv]\n"
9921 "# $9 = O3 volume mixing ratio [ppv]\n"
9922 "# $10 = observed BT index [K]\n"
9923 "# $11 = number of observations\n");
9931 for (
int iz = 0; iz < ctl->
prof_nz; iz++) {
9932 z[iz] = ctl->
prof_z0 + dz * (iz + 0.5);
9933 press[iz] =
P(z[iz]);
9937 for (
int ix = 0; ix < ctl->
prof_nx; ix++)
9938 lon[ix] = ctl->
prof_lon0 + dlon * (ix + 0.5);
9939 for (
int iy = 0; iy < ctl->
prof_ny; iy++) {
9940 lat[iy] = ctl->
prof_lat0 + dlat * (iy + 0.5);
9941 area[iy] = dlat * dlon *
SQR(
RE * M_PI / 180.)
9942 * cos(lat[iy] * M_PI / 180.);
9947 double t0 = t - 0.5 * ctl->
dt_mod;
9948 double t1 = t + 0.5 * ctl->
dt_mod;
9953 ALLOC(obsmean,
double,
9955 ALLOC(obscount,
int,
9959 for (
int i = 0; i < nobs; i++) {
9964 else if (rt[i] >= t1)
9968 if (!isfinite(robs[i]))
9972 int ix = (int) ((rlon[i] - ctl->
prof_lon0) / dlon);
9973 int iy = (int) ((rlat[i] - ctl->
prof_lat0) / dlat);
9976 if (ix < 0 || ix >= ctl->
prof_nx || iy < 0 || iy >= ctl->
prof_ny)
9981 obsmean[idx] += robs[i];
9986 for (ip = 0; ip < atm->
np; ip++) {
9989 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
9993 int ix = (int) ((atm->
lon[ip] - ctl->
prof_lon0) / dlon);
9994 int iy = (int) ((atm->
lat[ip] - ctl->
prof_lat0) / dlat);
9995 int iz = (int) ((
Z(atm->
p[ip]) - ctl->
prof_z0) / dz);
9998 if (ix < 0 || ix >= ctl->
prof_nx ||
10004 mass[idx] += atm->
q[ctl->
qnt_m][ip];
10008 for (
int ix = 0; ix < ctl->
prof_nx; ix++)
10009 for (
int iy = 0; iy < ctl->
prof_ny; iy++) {
10011 if (obscount[idx2] > 0) {
10015 for (
int iz = 0; iz < ctl->
prof_nz; iz++) {
10017 if (mass[idx3] > 0) {
10026 fprintf(out,
"\n");
10029 for (
int iz = 0; iz < ctl->
prof_nz; iz++) {
10034 lon[ix], lat[iy], &temp, ci, cw, 1);
10036 lon[ix], lat[iy], &h2o, ci, cw, 0);
10038 lon[ix], lat[iy], &o3, ci, cw, 0);
10043 / (
RHO(press[iz], temp) * area[iy] * dz * 1e9);
10046 fprintf(out,
"%.2f %g %g %g %g %g %g %g %g %g %d\n",
10047 t, z[iz], lon[ix], lat[iy], press[iz], temp, vmr, h2o, o3,
10048 obsmean[idx2] / obscount[idx2], obscount[idx2]);
10081 const char *filename,
10090 static double area, dlat, rmax2, *rt, *rz, *rlon, *rlat, *robs, kz[
EP],
10093 static int nobs, nk;
10106 ALLOC(rlon,
double,
10108 ALLOC(rlat,
double,
10110 ALLOC(robs,
double,
10121 LOG(1,
"Write sample data: %s", filename);
10122 if (!(out = fopen(filename,
"w")))
10123 ERRMSG(
"Cannot create file!");
10127 "# $1 = time [s]\n"
10128 "# $2 = altitude [km]\n"
10129 "# $3 = longitude [deg]\n"
10130 "# $4 = latitude [deg]\n"
10131 "# $5 = surface area [km^2]\n"
10132 "# $6 = layer depth [km]\n"
10133 "# $7 = number of particles [1]\n"
10134 "# $8 = column density [kg/m^2]\n"
10135 "# $9 = volume mixing ratio [ppv]\n"
10136 "# $10 = observed BT index [K]\n\n");
10141 area = M_PI * rmax2;
10145 double t0 = t - 0.5 * ctl->
dt_mod;
10146 double t1 = t + 0.5 * ctl->
dt_mod;
10149 for (
int i = 0; i < nobs; i++) {
10154 else if (rt[i] >= t1)
10159 geo2cart(0, rlon[i], rlat[i], x0);
10162 double rp =
P(rz[i]);
10171#pragma omp parallel for default(shared) reduction(+:mass,np)
10172 for (
int ip = 0; ip < atm->
np; ip++) {
10175 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
10179 if (fabs(rlat[i] - atm->
lat[ip]) > dlat)
10185 if (
DIST2(x0, x1) > rmax2)
10190 if (atm->
p[ip] > pbot || atm->
p[ip] < ptop)
10194 if (ctl->
qnt_m >= 0)
10201 double cd = mass / (1e6 * area);
10212 rlon[i], rlat[i], &temp, ci, cw, 1);
10216 / (
RHO(rp, temp) * 1e6 * area * 1e3 * ctl->
sample_dz);
10222 fprintf(out,
"%.2f %g %g %g %g %g %d %g %g %g\n", rt[i], rz[i],
10223 rlon[i], rlat[i], area, ctl->
sample_dz, np, cd, vmr, robs[i]);
10244 const char *filename,
10251 static double rmax2, x0[3], x1[3];
10260 LOG(1,
"Write station data: %s", filename);
10263 if (!(out = fopen(filename,
"w")))
10264 ERRMSG(
"Cannot create file!");
10268 "# $1 = time [s]\n"
10269 "# $2 = altitude [km]\n"
10270 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
10271 for (
int iq = 0; iq < ctl->
nq; iq++)
10272 fprintf(out,
"# $%i = %s [%s]\n", (iq + 5),
10274 fprintf(out,
"\n");
10282 double t0 = t - 0.5 * ctl->
dt_mod;
10283 double t1 = t + 0.5 * ctl->
dt_mod;
10286 for (
int ip = 0; ip < atm->
np; ip++) {
10289 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
10305 if (
DIST2(x0, x1) > rmax2)
10313 fprintf(out,
"%.2f %g %g %g",
10314 atm->
time[ip],
Z(atm->
p[ip]), atm->
lon[ip], atm->
lat[ip]);
10315 for (
int iq = 0; iq < ctl->
nq; iq++) {
10317 fprintf(out, ctl->
qnt_format[iq], atm->
q[iq][ip]);
10319 fprintf(out,
"\n");
10330 const char *filename,
10341 LOG(1,
"Write VTK data: %s", filename);
10344 double t0 = t - 0.5 * ctl->
dt_mod;
10345 double t1 = t + 0.5 * ctl->
dt_mod;
10348 if (!(out = fopen(filename,
"w")))
10349 ERRMSG(
"Cannot create file!");
10353 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
10354 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
10361 "# vtk DataFile Version 3.0\n"
10362 "vtk output\n" "ASCII\n" "DATASET POLYDATA\n");
10365 fprintf(out,
"POINTS %d float\n", np);
10367 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
10368 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
10372 double x = radius * cos(atm->
lat[ip] / 180. * M_PI)
10373 * cos(atm->
lon[ip] / 180. * M_PI);
10374 double y = radius * cos(atm->
lat[ip] / 180. * M_PI)
10375 * sin(atm->
lon[ip] / 180. * M_PI);
10376 double z = radius * sin(atm->
lat[ip] / 180. * M_PI);
10377 fprintf(out,
"%g %g %g\n", x, y, z);
10380 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
10381 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
10383 fprintf(out,
"%g %g %g\n", atm->
lon[ip], atm->
lat[ip],
10388 fprintf(out,
"POINT_DATA %d\n", np);
10389 for (
int iq = 0; iq < ctl->
nq; iq++) {
10390 fprintf(out,
"SCALARS %s float 1\n" "LOOKUP_TABLE default\n",
10392 for (
int ip = 0; ip < atm->
np; ip += ctl->
vtk_stride) {
10393 if (atm->
time[ip] < t0 || atm->
time[ip] > t1)
10395 fprintf(out,
"%g\n", atm->
q[iq][ip]);
void module_mixing_help(ctl_t *ctl, clim_t *clim, atm_t *atm, const int *ixs, const int *iys, const int *izs, int qnt_idx)
Perform interparcel mixing for a specific quantity.
int write_met(const char *filename, ctl_t *ctl, met_t *met)
Writes meteorological data to a binary file.
void read_met_bin_2d(FILE *in, met_t *met, float var[EX][EY], char *varname)
Reads a 2-dimensional meteorological variable from a binary file and stores it in the provided array.
void module_chem_init(ctl_t *ctl, clim_t *clim, met_t *met0, met_t *met1, atm_t *atm)
Initializes the chemistry modules by setting atmospheric composition.
void intpol_met_time_2d(met_t *met0, float array0[EX][EY], met_t *met1, float array1[EX][EY], double ts, double lon, double lat, double *var, int *ci, double *cw, int init)
Interpolates meteorological data in 2D space and time.
void module_timesteps(ctl_t *ctl, met_t *met0, atm_t *atm, double *dt, double t)
Calculate time steps for air parcels based on specified conditions.
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.
int read_atm_nc(const char *filename, ctl_t *ctl, atm_t *atm)
Reads air parcel data from a generic netCDF file and populates the given atmospheric structure.
void write_grid_asc(const char *filename, ctl_t *ctl, double *cd, double *mean[NQ], double *sigma[NQ], double *vmr_impl, double t, double *z, double *lon, double *lat, double *area, double dz, int *np)
Writes grid data to an ASCII file.
int read_atm(const char *filename, ctl_t *ctl, atm_t *atm)
Reads air parcel data from a specified file into the given atmospheric structure.
void read_met_levels(int ncid, ctl_t *ctl, met_t *met)
Reads meteorological variables at different vertical levels from a NetCDF file.
void timer(const char *name, const char *group, int output)
Measures and reports elapsed time for named and grouped timers.
void read_clim_photo(const char *filename, clim_photo_t *photo)
Reads photolysis rates from a NetCDF file and populates the given photolysis structure.
void read_met_cloud(met_t *met)
Calculates cloud-related variables for each grid point.
double sedi(const double p, const double T, const double rp, const double rhop)
Calculates the sedimentation velocity of a particle in air.
void module_sedi(ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, double *dt)
Simulate sedimentation of particles in the atmosphere.
void module_advect_init(ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm)
Initializes the advection module by setting up pressure fields.
void read_met_grid(const char *filename, int ncid, ctl_t *ctl, met_t *met)
Reads meteorological grid information from a NetCDF file.
void write_met_bin_3d(FILE *out, ctl_t *ctl, met_t *met, float var[EX][EY][EP], char *varname, int precision, double tolerance)
Writes a 3-dimensional meteorological variable to a binary file.
void read_clim(ctl_t *ctl, clim_t *clim)
Reads various climatological data and populates the given climatology structure.
void module_wet_deposition(ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, double *dt)
Perform wet deposition calculations for air parcels.
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.
int read_met_nc_2d(int ncid, char *varname, char *varname2, char *varname3, char *varname4, ctl_t *ctl, met_t *met, float dest[EX][EY], float scl, int init)
Reads a 2-dimensional meteorological variable from a NetCDF file.
void write_vtk(const char *filename, ctl_t *ctl, atm_t *atm, double t)
Writes VTK (Visualization Toolkit) data to a specified file.
void module_sort(ctl_t *ctl, met_t *met0, atm_t *atm)
Sort particles according to box index.
int read_atm_asc(const char *filename, ctl_t *ctl, atm_t *atm)
Reads air parcel data from an ASCII file and populates the given atmospheric structure.
void module_rng_init(int ntask)
Initialize random number generators for parallel tasks.
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 write_atm_asc(const char *filename, ctl_t *ctl, atm_t *atm, double t)
Writes air parcel data to an ASCII file or gnuplot.
void write_grid_nc(const char *filename, ctl_t *ctl, double *cd, double *mean[NQ], double *sigma[NQ], double *vmr_impl, double t, double *z, double *lon, double *lat, double *area, double dz, int *np)
Writes grid data to a NetCDF file.
void read_met_periodic(met_t *met)
Applies periodic boundary conditions to meteorological data along longitudinal axis.
void clim_oh_diurnal_correction(ctl_t *ctl, clim_t *clim)
Applies a diurnal correction to the hydroxyl radical (OH) concentration in climatology data.
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_tracer_chem(ctl_t *ctl, clim_t *clim, met_t *met0, met_t *met1, atm_t *atm, double *dt)
Simulate chemical reactions involving long-lived atmospheric tracers.
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 intpol_met_space_3d_ml(met_t *met, float array[EX][EY][EP], double p, double lon, double lat, double *var)
Interpolates a meteorological variable in 3D space (longitude, latitude, pressure).
void intpol_met_time_3d(met_t *met0, float array0[EX][EY][EP], met_t *met1, float array1[EX][EY][EP], double ts, double p, double lon, double lat, double *var, int *ci, double *cw, int init)
Interpolates meteorological data in 3D space and time.
void write_met_bin_2d(FILE *out, met_t *met, float var[EX][EY], char *varname)
Writes a 2-dimensional meteorological variable to a binary file.
void fft_help(double *fcReal, double *fcImag, int n)
Computes the Fast Fourier Transform (FFT) of a complex sequence.
void module_rng(ctl_t *ctl, double *rs, size_t n, int method)
Generate random numbers using various methods and distributions.
void module_advect(ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, double *dt)
Performs the advection of atmospheric particles using meteorological data.
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 get_tropo(int met_tropo, ctl_t *ctl, clim_t *clim, met_t *met, double *lons, int nx, double *lats, int ny, double *pt, double *zt, double *tt, double *qt, double *o3t, double *ps, double *zs)
Calculate tropopause data.
void level_definitions(ctl_t *ctl)
Defines pressure levels for meteorological data.
void write_atm_clams_traj(const char *dirname, ctl_t *ctl, atm_t *atm, double t)
Writes CLaMS trajectory data to a NetCDF file.
void read_obs(const char *filename, 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 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 write_grid(const char *filename, ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, double t)
Writes grid data to a file in ASCII or netCDF format.
void read_clim_zm(const char *filename, char *varname, clim_zm_t *zm)
Reads zonally averaged climatological data from a netCDF file and populates the given structure.
void read_met_pbl(met_t *met)
Calculates the planetary boundary layer (PBL) height for each grid point.
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 read_met_tropo(ctl_t *ctl, clim_t *clim, met_t *met)
Calculates the tropopause and related meteorological variables based on various methods and stores th...
int read_atm_clams(const char *filename, ctl_t *ctl, atm_t *atm)
Reads air parcel data from a CLaMS netCDF file and populates the given atmospheric structure.
void write_sample(const char *filename, ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, double t)
Writes sample data to a specified file.
void module_bound_cond(ctl_t *ctl, clim_t *clim, met_t *met0, met_t *met1, atm_t *atm, double *dt)
Apply boundary conditions to particles based on meteorological and climatological data.
void module_timesteps_init(ctl_t *ctl, atm_t *atm)
Initialize start time and time interval for time-stepping.
int read_atm_bin(const char *filename, ctl_t *ctl, atm_t *atm)
Reads air parcel data from a binary file and populates the given atmospheric structure.
void read_met_sample(ctl_t *ctl, met_t *met)
Downsamples meteorological data based on specified parameters.
void module_h2o2_chem(ctl_t *ctl, clim_t *clim, met_t *met0, met_t *met1, atm_t *atm, double *dt)
Perform chemical reactions involving H2O2 within cloud particles.
void write_station(const char *filename, ctl_t *ctl, atm_t *atm, double t)
Writes station data to a specified file.
void read_met_monotonize(met_t *met)
Makes zeta and pressure profiles monotone.
void write_atm(const char *filename, ctl_t *ctl, atm_t *atm, double t)
Writes air parcel data to a file in various formats.
void write_csi(const char *filename, ctl_t *ctl, atm_t *atm, double t)
Writes Critical Success Index (CSI) data to a file.
void intpol_tropo_3d(double time0, float array0[EX][EY], double time1, float array1[EX][EY], double lons[EX], double lats[EY], int nlon, int nlat, double time, double lon, double lat, int method, double *var, double *sigma)
Interpolates tropopause data in 3D (latitude, longitude, and time).
void read_met_ml2pl(ctl_t *ctl, met_t *met, float var[EX][EY][EP], char *varname)
Interpolates meteorological data to specified pressure levels.
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_mixing(ctl_t *ctl, clim_t *clim, atm_t *atm, double t)
Update atmospheric properties through interparcel mixing.
void module_position(ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, double *dt)
Update the positions and pressure levels of atmospheric particles.
void module_meteo(ctl_t *ctl, clim_t *clim, met_t *met0, met_t *met1, atm_t *atm, double *dt)
Update atmospheric properties using meteorological data.
void get_met(ctl_t *ctl, clim_t *clim, double t, met_t **met0, met_t **met1)
Retrieves meteorological data for the specified time.
void module_oh_chem(ctl_t *ctl, clim_t *clim, met_t *met0, met_t *met1, atm_t *atm, double *dt)
Perform hydroxyl chemistry calculations for atmospheric particles.
void module_sort_help(double *a, const int *p, const int np)
Reorder an array based on a given permutation.
void module_chemgrid(ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, double tt)
Calculate grid data for chemistry modules.
float stddev(const float *data, const int n)
Calculates the standard deviation of a set of data.
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.
void read_met_bin_3d(FILE *in, ctl_t *ctl, met_t *met, float var[EX][EY][EP], char *varname, float bound_min, float bound_max)
Reads 3D meteorological data from a binary file, potentially using different compression methods.
void intpol_met_4d_coord(met_t *met0, float heights0[EX][EY][EP], float array0[EX][EY][EP], met_t *met1, float heights1[EX][EY][EP], float array1[EX][EY][EP], double ts, double height, double lon, double lat, double *var, int *ci, double *cw, int init)
Interpolates meteorological variables to a given position and time.
void module_isosurf_init(ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, cache_t *cache)
Initialize the isosurface module based on atmospheric data.
int read_met_nc_3d(int ncid, char *varname, char *varname2, char *varname3, char *varname4, ctl_t *ctl, met_t *met, float dest[EX][EY][EP], float scl)
Reads a 3-dimensional meteorological variable from a NetCDF file.
void read_met_detrend(ctl_t *ctl, met_t *met)
Detrends meteorological data.
double time_from_filename(const char *filename, int offset)
Extracts and converts a timestamp from a filename to Julian seconds.
void module_dry_deposition(ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, double *dt)
Simulate dry deposition of atmospheric particles.
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 intpol_met_time_3d_ml(met_t *met0, float array0[EX][EY][EP], met_t *met1, float array1[EX][EY][EP], double ts, double p, double lon, double lat, double *var)
Interpolates a meteorological variable in time and 3D space (longitude, latitude, pressure).
void write_atm_clams(const char *filename, ctl_t *ctl, atm_t *atm)
Writes air parcel data to a NetCDF file in the CLaMS format.
void clim_tropo_init(clim_t *clim)
Initializes the tropopause data in the climatology structure.
void cart2geo(const double *x, double *z, double *lon, double *lat)
State variables of cuRAND random number generator.
double sza_calc(const double sec, const double lon, const double lat)
Calculates the solar zenith angle.
void read_met_surface(int ncid, met_t *met, ctl_t *ctl)
Reads surface meteorological data from a netCDF file and stores it in the meteorological data structu...
void module_decay(ctl_t *ctl, clim_t *clim, atm_t *atm, double *dt)
Simulate exponential decay processes for atmospheric particles.
void doy2day(const int year, const int doy, int *mon, int *day)
Converts a given day of the year (DOY) to a date (month and day).
void intpol_met_space_3d(met_t *met, float array[EX][EY][EP], double p, double lon, double lat, double *var, int *ci, double *cw, int init)
Interpolates meteorological variables in 3D space.
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.
int locate_irr_3d(float profiles[EX][EY][EP], int np, int ind_lon, int ind_lat, double x)
Locate the index of the interval containing a given value in a 3D irregular grid.
int read_met(const char *filename, ctl_t *ctl, clim_t *clim, met_t *met)
Reads meteorological data from a file and populates the provided structures.
void read_met_pv(met_t *met)
Calculates potential vorticity (PV) from meteorological data.
void module_isosurf(ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, cache_t *cache, double *dt)
Apply the isosurface module to adjust atmospheric properties.
void get_met_replace(char *orig, char *search, char *repl)
Replaces occurrences of a substring in a string with another substring.
void write_atm_bin(const char *filename, ctl_t *ctl, atm_t *atm)
Writes air parcel data to a binary file.
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.
double scan_ctl(const char *filename, int argc, char *argv[], const char *varname, int arridx, const char *defvalue, char *value)
Scans a control file or command-line arguments for a specified variable.
void write_atm_nc(const char *filename, ctl_t *ctl, atm_t *atm)
Writes air parcel data to a NetCDF file.
void module_convection(ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, double *dt, double *rs)
Simulate convective processes for atmospheric particles.
void locate_vert(float profiles[EX][EY][EP], int np, int lon_ap_ind, int lat_ap_ind, double height_ap, int *ind)
Locate the four vertical indizes of a box for a given height value.
void get_met_help(ctl_t *ctl, double t, int direct, char *metbase, double dt_met, char *filename)
Helper function to generate the filename for meteorological data.
void intpol_met_space_2d(met_t *met, float array[EX][EY], double lon, double lat, double *var, int *ci, double *cw, int init)
Interpolates meteorological variables in 2D space.
void module_diffusion_meso(ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, cache_t *cache, double *dt, double *rs)
Simulate mesoscale diffusion for atmospheric particles.
void read_met_polar_winds(met_t *met)
Applies a fix for polar winds in meteorological data.
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 module_diffusion_turb(ctl_t *ctl, clim_t *clim, atm_t *atm, double *dt, double *rs)
Simulate turbulent diffusion for atmospheric particles.
void read_met_cape(clim_t *clim, met_t *met)
Calculates Convective Available Potential Energy (CAPE) for each grid point.
double tropo_weight(const clim_t *clim, const double t, const double lat, const double p)
Computes the weighting factor for a given pressure with respect to the tropopause.
void read_met_geopot(ctl_t *ctl, met_t *met)
Calculates geopotential heights from meteorological data.
void write_output(const char *dirname, ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, double t)
Writes various types of output data to files in a specified directory.
void write_prof(const char *filename, ctl_t *ctl, met_t *met0, met_t *met1, atm_t *atm, double t)
Writes profile data to a specified file.
void compress_pck(char *varname, float *array, size_t nxy, size_t nz, int decompress, FILE *inout)
Compresses or decompresses a 3D array of floats.
void write_ens(const char *filename, ctl_t *ctl, atm_t *atm, double t)
Writes ensemble data to a file.
double lapse_rate(const double t, const double h2o)
Calculates the moist adiabatic lapse rate in Kelvin per kilometer.
double clim_photo(double rate[CP][CSZA][CO3], clim_photo_t *photo, double p, double sza, double o3c)
Calculates the photolysis rate for a given set of atmospheric conditions.
MPTRAC library declarations.
#define NN(x0, y0, x1, y1, x)
Perform nearest-neighbor interpolation.
#define LEN
Maximum length of ASCII data lines.
#define RE
Mean radius of Earth [km].
#define TVIRT(t, h2o)
Compute virtual temperature.
void module_kpp_chem(ctl_t *ctl, clim_t *clim, met_t *met0, met_t *met1, atm_t *atm, double *dt)
KPP chemistry module.
#define ARRAY_3D(ix, iy, ny, iz, nz)
Compute the linear index of a 3D array element.
void compress_cms(ctl_t *ctl, char *varname, float *array, size_t nx, size_t ny, size_t np, int decompress, FILE *inout)
Compresses or decompresses a 3D array of floats using a custom multiscale compression algorithm.
#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].
void compress_zstd(char *varname, float *array, size_t n, int decompress, FILE *inout)
Compresses or decompresses an array of floats using the Zstandard (ZSTD) library.
#define NENS
Maximum number of data points for ensemble analysis.
#define FWRITE(ptr, type, size, out)
Write data from memory to a file stream.
#define PW(p, h2o)
Calculate partial water vapor pressure.
#define H0
Scale height [km].
#define NC_PUT_ATT_GLOBAL(attname, text)
Add a global text attribute to a NetCDF file.
#define MOLEC_DENS(p, t)
Calculate the density of a gas molecule.
#define LAPSE(p1, t1, p2, t2)
Calculate lapse rate.
#define NC(cmd)
Execute a NetCDF command and check for errors.
#define RA
Specific gas constant of dry air [J/(kg K)].
#define INTPOL_INIT
Initialize arrays for interpolation.
#define MIN(a, b)
Macro to determine the minimum of two values.
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
#define NC_PUT_INT(varname, ptr, hyperslab)
Write integer data to a NetCDF variable.
#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.
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 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 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 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_zfp(char *varname, float *array, int nx, int ny, int nz, int precision, double tolerance, int decompress, FILE *inout)
Compresses or decompresses a 3D array of floats using the ZFP library.
#define RHO(p, t)
Compute density of air.
#define CO3
Maximum number of total column ozone data for climatological data.
#define NC_PUT_DOUBLE(varname, ptr, hyperslab)
Write double precision data to a NetCDF variable.
#define LIN(x0, y0, x1, y1, x)
Linear interpolation.
#define NC_DEF_VAR(varname, type, ndims, dims, long_name, units)
Define a NetCDF variable with attributes.
#define DIST2(a, b)
Calculate the squared Euclidean distance between two points in Cartesian coordinates.
#define DEG2DX(dlon, lat)
Convert a longitude difference to a distance in the x-direction (east-west) at a specific latitude.
#define CPD
Specific heat of dry air at constant pressure [J/(kg K)].
#define CSZA
Maximum number of solar zenith angles for climatological data.
#define DY2DEG(dy)
Convert a distance in kilometers to degrees latitude.
#define MAX(a, b)
Macro to determine the maximum of two values.
#define FMOD(x, y)
Calculate the floating-point remainder of dividing x by y.
double lat[NP]
Latitude [deg].
double lon[NP]
Longitude [deg].
int np
Number of air parcels.
double q[NQ][NP]
Quantity data (for various, user-defined attributes).
double p[NP]
Pressure [hPa].
double iso_ts[NP]
Isosurface balloon time [s].
int iso_n
Isosurface balloon number of data points.
double iso_ps[NP]
Isosurface balloon pressure [hPa].
float uvwp[NP][3]
Wind perturbations [m/s].
double iso_var[NP]
Isosurface variables.
Climatological data in the form of photolysis rates.
int nsza
Number of solar zenith angles.
double sza[CSZA]
Solar zenith angle [rad].
double o3_1[CP][CSZA][CO3]
O3 photolysis rate (O3 + hv = O1d + O2) [1/s].
double p[CP]
Pressure [hPa].
double ccl2f2[CP][CSZA][CO3]
CCl2F2 photolysis rate [1/s].
double o2[CP][CSZA][CO3]
O2 photolysis rate [1/s].
double ccl3f[CP][CSZA][CO3]
CCl3F photolysis rate [1/s].
double n2o[CP][CSZA][CO3]
N2O photolysis rate [1/s].
double h2o2[CP][CSZA][CO3]
H2O2 photolysis rate [1/s].
double h2o[CP][CSZA][CO3]
H2O photolysis rate [1/s].
double ccl4[CP][CSZA][CO3]
CCl4 photolysis rate [1/s].
double o3_2[CP][CSZA][CO3]
O3 photolysis rate (O3 + hv = O3p + O2) [1/s].
double o3c[CO3]
Total column ozone [DU].
int np
Number of pressure levels.
int no3c
Number of total ozone columns.
clim_ts_t ccl2f2
CFC-12 time series.
clim_photo_t photo
Photolysis rates.
clim_zm_t ho2
HO2 zonal means.
clim_zm_t hno3
HNO3 zonal means.
int tropo_ntime
Number of tropopause timesteps.
clim_ts_t sf6
SF6 time series.
clim_ts_t ccl4
CFC-10 time series.
clim_ts_t ccl3f
CFC-11 time series.
clim_zm_t o1d
O(1D) zonal means.
double tropo_lat[73]
Tropopause latitudes [deg].
clim_zm_t h2o2
H2O2 zonal means.
int tropo_nlat
Number of tropopause latitudes.
clim_zm_t oh
OH zonal means.
double tropo[12][73]
Tropopause pressure values [hPa].
double tropo_time[12]
Tropopause time steps [s].
clim_ts_t n2o
N2O time series.
Climatological data in the form of time series.
double vmr[CTS]
Volume mixing ratio [ppv].
double time[CTS]
Time [s].
int ntime
Number of timesteps.
Climatological data in the form of zonal means.
int np
Number of pressure levels.
double p[CP]
Pressure [hPa].
double vmr[CT][CP][CY]
Volume mixing ratio [ppv].
int ntime
Number of timesteps.
int nlat
Number of latitudes.
double lat[CY]
Latitude [deg].
double grid_z0
Lower altitude of gridded data [km].
int qnt_o3
Quantity array index for ozone volume mixing ratio.
double csi_lat1
Upper latitude of gridded CSI data [deg].
char csi_obsfile[LEN]
Observation data file for CSI analysis.
int qnt_Coh
Quantity array index for OH volume mixing ratio (chemistry code).
double wet_depo_ic_a
Coefficient A for wet deposition in cloud (exponential form).
int met_nc_scale
Check netCDF scaling factors (0=no, 1=yes).
int qnt_pel
Quantity array index for pressure at equilibrium level (EL).
int csi_nz
Number of altitudes of gridded CSI data.
double molmass
Molar mass [g/mol].
int qnt_p
Quantity array index for pressure.
int qnt_Cccl2f2
Quantity array index for CFC-12 volume mixing ratio (chemistry code).
char atm_gpfile[LEN]
Gnuplot file for atmospheric data.
int mixing_nx
Number of longitudes of mixing grid.
double chemgrid_z1
Upper altitude of chemistry grid [km].
char qnt_format[NQ][LEN]
Quantity output format.
int qnt_m
Quantity array index for mass.
int qnt_aoa
Quantity array index for age of air.
int qnt_rhop
Quantity array index for particle density.
int qnt_swc
Quantity array index for cloud snow water content.
double csi_obsmin
Minimum observation index to trigger detection.
int qnt_pcb
Quantity array index for cloud bottom pressure.
char clim_n2o_timeseries[LEN]
Filename of N2O time series.
double bound_dzs
Boundary conditions surface layer depth [km].
double csi_lon1
Upper longitude of gridded CSI data [deg].
int qnt_u
Quantity array index for zonal wind.
double stat_lon
Longitude of station [deg].
double mixing_trop
Interparcel exchange parameter for mixing in the troposphere.
double sort_dt
Time step for sorting of particle data [s].
double mixing_z1
Upper altitude of mixing grid [km].
double stat_r
Search radius around station [km].
double wet_depo_bc_a
Coefficient A for wet deposition below cloud (exponential form).
int csi_ny
Number of latitudes of gridded CSI data.
int vtk_sphere
Spherical projection for VTK data (0=no, 1=yes).
double chemgrid_z0
Lower altitude of chemistry grid [km].
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 qnt_lwc
Quantity array index for cloud liquid water content.
double turb_mesoz
Vertical scaling factor for mesoscale wind fluctuations.
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].
double csi_modmin
Minimum column density to trigger detection [kg/m^2].
int met_sx
Smoothing for longitudes.
double chemgrid_lon1
Upper longitude of chemistry grid [deg].
double turb_mesox
Horizontal scaling factor for mesoscale wind fluctuations.
double met_cms_eps_iwc
cmultiscale compression epsilon for cloud ice water content.
int conv_mix_bot
Lower level for mixing (0=particle pressure, 1=surface).
double met_cms_eps_swc
cmultiscale compression epsilon for cloud snow water content.
char grid_kernel[LEN]
Kernel data file for grid output.
int met_zfp_prec
ZFP compression precision for all variables, except z and T.
double met_cms_eps_v
cmultiscale compression epsilon for meridional wind.
double prof_z0
Lower altitude of gridded profile data [km].
int qnt_w
Quantity array index for vertical velocity.
double bound_vmr
Boundary conditions volume mixing ratio [ppv].
double met_tropo_pv
Dynamical tropopause potential vorticity threshold [PVU].
int prof_nx
Number of longitudes of gridded profile data.
int qnt_stat
Quantity array index for station flag.
int met_tropo
Tropopause definition (0=none, 1=clim, 2=cold point, 3=WMO_1st, 4=WMO_2nd, 5=dynamical).
int qnt_rp
Quantity array index for particle radius.
int met_mpi_share
Use MPI to share meteo (0=no, 1=yes).
double mixing_strat
Interparcel exchange parameter for mixing in the stratosphere.
int qnt_vz
Quantity array index for vertical velocity.
int qnt_ho2
Quantity array index for HO2 volume mixing ratio (climatology).
double csi_z1
Upper altitude of gridded CSI data [km].
double stat_t0
Start time for station output [s].
double oh_chem_beta
Beta parameter for diurnal variablity of OH.
char clim_o1d_filename[LEN]
Filename of O(1D) climatology.
char clim_photo[LEN]
Filename of photolysis rates climatology.
double mixing_z0
Lower altitude of mixing grid [km].
int qnt_mloss_decay
Quantity array index for total mass loss due to exponential decay.
int atm_type_out
Type of atmospheric data files for output (-1=same as ATM_TYPE, 0=ASCII, 1=binary,...
double dt_kpp
Time step for KPP chemistry [s].
char csi_basename[LEN]
Basename of CSI data files.
double dry_depo_dp
Dry deposition surface layer [hPa].
int qnt_vs
Quantity array index for surface meridional wind.
int qnt_Cco
Quantity array index for CO volume mixing ratio (chemistry code).
double vtk_dt_out
Time step for VTK data output [s].
double t_stop
Stop time of simulation [s].
double conv_dt
Time interval for convection module [s].
char sample_obsfile[LEN]
Observation data file for sample output.
int qnt_hno3
Quantity array index for HNO3 volume mixing ratio (climatology).
char grid_basename[LEN]
Basename of grid data files.
int met_clams
Read MPTRAC or CLaMS meteo data (0=MPTRAC, 1=CLaMS).
int qnt_h2ot
Quantity array index for tropopause water vapor volume mixing ratio.
int qnt_rh
Quantity array index for relative humidity over water.
double met_cms_eps_cc
cmultiscale compression epsilon for cloud cover.
double bound_lat0
Boundary conditions minimum longitude [deg].
int met_dx
Stride for longitudes.
int mixing_ny
Number of latitudes of mixing grid.
int met_convention
Meteo data layout (0=[lev, lat, lon], 1 = [lon, lat, lev]).
int qnt_zeta_d
Quantity array index for diagnosed zeta vertical coordinate.
char clim_h2o2_filename[LEN]
Filename of H2O2 climatology.
int tracer_chem
Switch for first order tracer chemistry module (0=off, 1=on).
double dt_mod
Time step of simulation [s].
int qnt_tnat
Quantity array index for T_NAT.
int qnt_tice
Quantity array index for T_ice.
int qnt_zg
Quantity array index for geopotential height.
double vtk_offset
Vertical offset for VTK data [km].
int qnt_v
Quantity array index for meridional wind.
int qnt_mloss_dry
Quantity array index for total mass loss due to dry deposition.
double bound_vmr_trend
Boundary conditions volume mixing ratio trend [ppv/s].
int met_cache
Preload meteo data into disk cache (0=no, 1=yes).
int qnt_oh
Quantity array index for OH volume mixing ratio (climatology).
char qnt_unit[NQ][LEN]
Quantity units.
int qnt_Ch
Quantity array index for H volume mixing ratio (chemistry code).
int met_press_level_def
Use predefined pressure levels or not.
int oh_chem_reaction
Reaction type for OH chemistry (0=none, 2=bimolecular, 3=termolecular).
int qnt_h2o
Quantity array index for water vapor volume mixing ratio.
int prof_ny
Number of latitudes of gridded profile data.
int qnt_rhice
Quantity array index for relative humidity over ice.
int qnt_rho
Quantity array index for density of air.
double sample_dz
Layer depth for sample output [km].
double wet_depo_ic_h[3]
Coefficients for wet deposition in cloud (Henry's law: Hb, Cb, pH).
double tdec_strat
Life time of particles in the stratosphere [s].
int obs_type
Type of observation data files (0=ASCII, 1=netCDF).
double met_cms_eps_lwc
cmultiscale compression epsilon for cloud liquid water content.
int qnt_us
Quantity array index for surface zonal wind.
double met_cms_eps_z
cmultiscale compression epsilon for geopotential height.
double grid_lon1
Upper longitude of gridded data [deg].
int conv_mix_top
Upper level for mixing (0=particle pressure, 1=EL).
int qnt_Cn2o
Quantity array index for N2O volume mixing ratio (chemistry code).
int qnt_Cccl3f
Quantity array index for CFC-11 volume mixing ratio (chemistry code).
char qnt_name[NQ][LEN]
Quantity names.
char atm_basename[LEN]
Basename of atmospheric data files.
double mixing_lat0
Lower latitude of mixing grid [deg].
int qnt_pt
Quantity array index for tropopause pressure.
int qnt_cl
Quantity array index for total column cloud water.
int advect
Advection scheme (0=off, 1=Euler, 2=midpoint, 4=Runge-Kutta).
double prof_z1
Upper altitude of gridded profile data [km].
int reflect
Reflection of particles at top and bottom boundary (0=no, 1=yes).
int qnt_t
Quantity array index for temperature.
int atm_filter
Time filter for atmospheric data output (0=none, 1=missval, 2=remove).
int kpp_chem
Switch for KPP chemistry module (0=off, 1=on).
int qnt_zeta
Quantity array index for zeta vertical coordinate.
char ens_basename[LEN]
Basename of ensemble data file.
double wet_depo_pre[2]
Coefficients for precipitation calculation.
int met_vert_coord
Vertical coordinate of input meteo data (0=pressure-level, 1=model-level).
double csi_z0
Lower altitude of gridded CSI data [km].
int qnt_lapse
Quantity array index for lapse rate.
double stat_lat
Latitude of station [deg].
int qnt_Cho2
Quantity array index for HO2 volume mixing ratio (chemistry code).
double wet_depo_bc_h[2]
Coefficients for wet deposition below cloud (Henry's law: Hb, Cb).
int grid_ny
Number of latitudes of gridded data.
int qnt_Csf6
Quantity array index for SF6 volume mixing ratio (chemistry code).
int qnt_Ch2o
Quantity array index for H2O volume mixing ratio (chemistry code).
double met_detrend
FWHM of horizontal Gaussian used for detrending [km].
char metbase[LEN]
Basename for meteo data.
double bound_dps
Boundary conditions surface layer depth [hPa].
double met_cms_eps_t
cmultiscale compression epsilon for temperature.
int chemgrid_nz
Number of altitudes of chemistry grid.
int qnt_cape
Quantity array index for convective available potential energy (CAPE).
double bound_mass_trend
Boundary conditions mass per particle trend [kg/s].
int mixing_nz
Number of altitudes of mixing grid.
int qnt_o3c
Quantity array index for total column ozone.
double bound_p0
Boundary conditions bottom pressure [hPa].
double mixing_lon0
Lower longitude of mixing grid [deg].
char clim_ccl4_timeseries[LEN]
Filename of CFC-10 time series.
int qnt_Co3
Quantity array index for O3 volume mixing ratio (chemistry code).
int qnt_tsts
Quantity array index for T_STS.
int grid_nz
Number of altitudes of gridded data.
char clim_oh_filename[LEN]
Filename of OH climatology.
double ens_dt_out
Time step for ensemble output [s].
char sample_basename[LEN]
Basename of sample data file.
int atm_stride
Particle index stride for atmospheric data files.
int advect_cpl_zeta_and_press_modules
Coupled use of pressure based modules and diabatic advection.
int met_relhum
Try to read relative humidity (0=no, 1=yes).
double mixing_lat1
Upper latitude of mixing grid [deg].
double atm_dt_out
Time step for atmospheric data output [s].
char clim_sf6_timeseries[LEN]
Filename of SF6 time series.
double prof_lat1
Upper latitude of gridded profile data [deg].
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 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).
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.
double met_zfp_tol_t
ZFP compression tolerance for temperature.
double mixing_dt
Time interval for mixing [s].
int qnt_mloss_h2o2
Quantity array index for total mass loss due to H2O2 chemistry.
double met_zfp_tol_z
ZFP compression tolerance for geopotential height.
double vtk_scale
Vertical scaling factor for VTK data.
char clim_ccl2f2_timeseries[LEN]
Filename of CFC-12 time series.
double met_cms_eps_w
cmultiscale compression epsilon for vertical velocity.
double conv_cin
CIN threshold for convection module [J/kg].
int qnt_pv
Quantity array index for potential vorticity.
int advect_vert_coord
Vertical coordinate of air parcels (0=pressure, 1=zeta, 2=eta).
int qnt_mloss_oh
Quantity array index for total mass loss due to OH chemistry.
int qnt_Ch2o2
Quantity array index for H2O2 volume mixing ratio (chemistry code).
int qnt_sst
Quantity array index for sea surface temperature.
double mixing_lon1
Upper longitude of mixing grid [deg].
char clim_hno3_filename[LEN]
Filename of HNO3 climatology.
int met_cms_heur
cmultiscale coarsening heuristics (0=default, 1=mean diff, 2=median diff, 3=max diff).
double wet_depo_ic_ret_ratio
Coefficients for wet deposition in cloud: retention ratio.
int qnt_sh
Quantity array index for specific humidity.
double wet_depo_ic_b
Coefficient B for wet deposition in cloud (exponential form).
double wet_depo_bc_b
Coefficient B for wet deposition below cloud (exponential form).
int met_dy
Stride for latitudes.
int qnt_Cx
Quantity array index for trace species x volume mixing ratio (chemistry code).
double turb_dz_strat
Vertical turbulent diffusion coefficient (stratosphere) [m^2/s].
double bound_zetas
Boundary conditions surface layer zeta [K].
int qnt_idx
Quantity array index for air parcel IDs.
double met_tropo_theta
Dynamical tropopause potential temperature threshold [K].
int qnt_rwc
Quantity array index for cloud rain water content.
double t_start
Start time of simulation [s].
char qnt_longname[NQ][LEN]
Quantity long names.
double met_p[EP]
Target pressure levels [hPa].
int nq
Number of quantities.
double tdec_trop
Life time of particles in the troposphere [s].
double sample_dx
Horizontal radius for sample output [km].
int vtk_stride
Particle index stride for VTK data.
char stat_basename[LEN]
Basename of station data file.
double grid_lat1
Upper latitude of gridded data [deg].
int qnt_zt
Quantity array index for tropopause geopotential height.
int met_type
Type of meteo data files (0=netCDF, 1=binary, 2=pck, 3=zfp, 4=zstd, 5=cms).
int qnt_cc
Quantity array index for cloud cover.
int qnt_plcl
Quantity array index for pressure at lifted condensation level (LCL).
double grid_dt_out
Time step for gridded data output [s].
int qnt_tdew
Quantity array index for dew point temperature.
float zt[EX][EY]
Tropopause geopotential height [km].
float sst[EX][EY]
Sea surface temperature [K].
float rwc[EX][EY][EP]
Cloud rain water content [kg/kg].
float o3c[EX][EY]
Total column ozone [DU].
float zeta_dotl[EX][EY][EP]
Vertical velocity on model levels [K/s].
float h2o[EX][EY][EP]
Water vapor volume mixing ratio [1].
float cape[EX][EY]
Convective available potential energy [J/kg].
float w[EX][EY][EP]
Vertical velocity [hPa/s].
float pct[EX][EY]
Cloud top pressure [hPa].
double hybrid[EP]
Model hybrid levels.
int nx
Number of longitudes.
int ny
Number of latitudes.
float ps[EX][EY]
Surface pressure [hPa].
float lwc[EX][EY][EP]
Cloud liquid water content [kg/kg].
float us[EX][EY]
Surface zonal wind [m/s].
float wl[EX][EY][EP]
Vertical velocity on model levels [hPa/s].
float vl[EX][EY][EP]
Meridional wind on model levels [m/s].
float zs[EX][EY]
Surface geopotential height [km].
float o3[EX][EY][EP]
Ozone volume mixing ratio [1].
float cc[EX][EY][EP]
Cloud cover [1].
int np
Number of pressure levels.
float t[EX][EY][EP]
Temperature [K].
float ts[EX][EY]
Surface temperature [K].
float u[EX][EY][EP]
Zonal wind [m/s].
float ul[EX][EY][EP]
Zonal wind on model levels [m/s].
float pcb[EX][EY]
Cloud bottom pressure [hPa].
float pel[EX][EY]
Pressure at equilibrium level [hPa].
float cin[EX][EY]
Convective inhibition [J/kg].
float plcl[EX][EY]
Pressure at lifted condensation level (LCL) [hPa].
double lon[EX]
Longitude [deg].
float pt[EX][EY]
Tropopause pressure [hPa].
float tt[EX][EY]
Tropopause temperature [K].
float pbl[EX][EY]
Boundary layer pressure [hPa].
float vs[EX][EY]
Surface meridional wind [m/s].
float z[EX][EY][EP]
Geopotential height [km].
float v[EX][EY][EP]
Meridional wind [m/s].
int npl
Number of model levels.
float lsm[EX][EY]
Land-sea mask [1].
float iwc[EX][EY][EP]
Cloud ice water content [kg/kg].
float h2ot[EX][EY]
Tropopause water vapor volume mixing ratio [ppv].
float pv[EX][EY][EP]
Potential vorticity [PVU].
float cl[EX][EY]
Total column cloud water [kg/m^2].
float pl[EX][EY][EP]
Pressure on model levels [hPa].
float plfc[EX][EY]
Pressure at level of free convection (LFC) [hPa].
double lat[EY]
Latitude [deg].
float swc[EX][EY][EP]
Cloud snow water content [kg/kg].
float zetal[EX][EY][EP]
Zeta on model levels [K].
double p[EP]
Pressure levels [hPa].