48 {
49
51
53
55
57
58 FILE *out;
59
60 static double timem[
NZ], z, lon, lonm[
NZ], lat, latm[
NZ], t, tm[
NZ], u,
61 um[
NZ], v, vm[
NZ], w, wm[
NZ], h2o, h2om[
NZ], h2ot, h2otm[
NZ], o3, o3m[
NZ],
62 lwc, lwcm[
NZ], rwc, rwcm[
NZ], iwc, iwcm[
NZ], swc, swcm[
NZ], cc, ccm[
NZ],
63 ps, psm[
NZ], ts, tsm[
NZ], zs, zsm[
NZ], us, usm[
NZ], vs, vsm[
NZ],
64 ess, essm[
NZ], nss, nssm[
NZ], shf, shfm[
NZ], lsm, lsmm[
NZ],
65 sst, sstm[
NZ], pbl, pblm[
NZ], pt, ptm[
NZ], pct, pctm[
NZ], pcb,
66 pcbm[
NZ], cl, clm[
NZ], plcl, plclm[
NZ], plfc, plfcm[
NZ], pel, pelm[
NZ],
67 cape, capem[
NZ], cin, cinm[
NZ], o3c, o3cm[
NZ], tt, ttm[
NZ], zm[
NZ], zt,
68 ztm[
NZ], pv, pvm[
NZ], plev[
NZ], rhm[
NZ], rhicem[
NZ], tdewm[
NZ], ticem[
NZ],
69 tnatm[
NZ], hno3m[
NZ], ohm[
NZ], h2o2m[
NZ], ho2m[
NZ], o1dm[
NZ];
70
71 static int iz, np[
NZ], npc[
NZ], npt[
NZ], nz;
72
73
77
78
80
81
82 if (argc < 4)
83 ERRMSG(
"Missing or invalid command-line arguments.\n\n"
84 "Usage: met_prof <ctl> <prof.tab> <met0> [<met1> ...]\n\n"
85 "Use -h for full help.");
86
87
89 double z0 =
scan_ctl(argv[1], argc, argv,
"PROF_Z0", -1,
"-999", NULL);
90 double z1 =
scan_ctl(argv[1], argc, argv,
"PROF_Z1", -1,
"-999", NULL);
91 double dz =
scan_ctl(argv[1], argc, argv,
"PROF_DZ", -1,
"-999", NULL);
92 double lon0 =
scan_ctl(argv[1], argc, argv,
"PROF_LON0", -1,
"0", NULL);
93 double lon1 =
scan_ctl(argv[1], argc, argv,
"PROF_LON1", -1,
"0", NULL);
94 double dlon =
scan_ctl(argv[1], argc, argv,
"PROF_DLON", -1,
"-999", NULL);
95 double lat0 =
scan_ctl(argv[1], argc, argv,
"PROF_LAT0", -1,
"0", NULL);
96 double lat1 =
scan_ctl(argv[1], argc, argv,
"PROF_LAT1", -1,
"0", NULL);
97 double dlat =
scan_ctl(argv[1], argc, argv,
"PROF_DLAT", -1,
"-999", NULL);
98
99
101
102
103 for (int i = 3; i < argc; i++) {
104
105
107 continue;
108
109
110 if (z0 < 0)
112 if (z1 < 0)
113 z1 =
Z(met->
p[met->
np - 1]);
114 nz = 0;
115 if (dz < 0) {
116 for (iz = 0; iz < met->
np; iz++)
117 if (
Z(met->
p[iz]) >= z0 &&
Z(met->
p[iz]) <= z1) {
118 plev[nz] = met->
p[iz];
120 ERRMSG(
"Too many pressure levels!");
121 }
122 } else
123 for (z = z0; z <= z1; z += dz) {
126 ERRMSG(
"Too many pressure levels!");
127 }
128
129
130 if (dlon <= 0)
131 dlon = fabs(met->
lon[1] - met->
lon[0]);
132 if (dlat <= 0)
133 dlat = fabs(met->
lat[1] - met->
lat[0]);
134
135
136 for (iz = 0; iz < nz; iz++)
137 for (lon = lon0; lon <= lon1; lon += dlon)
138 for (lat = lat0; lat <= lat1; lat += dlat) {
139
140
143
144
145 if (isfinite(t) && isfinite(u) && isfinite(v) && isfinite(w)) {
146 timem[iz] += met->
time;
147 lonm[iz] += lon;
148 latm[iz] += lat;
149 zm[iz] += z;
150 tm[iz] += t;
151 um[iz] += u;
152 vm[iz] += v;
153 wm[iz] += w;
154 pvm[iz] += pv;
155 h2om[iz] += h2o;
156 o3m[iz] += o3;
157 lwcm[iz] += lwc;
158 rwcm[iz] += rwc;
159 iwcm[iz] += iwc;
160 swcm[iz] += swc;
161 ccm[iz] += cc;
162 psm[iz] += ps;
163 tsm[iz] += ts;
164 zsm[iz] += zs;
165 usm[iz] += us;
166 vsm[iz] += vs;
167 essm[iz] += ess;
168 nssm[iz] += nss;
169 shfm[iz] += shf;
170 lsmm[iz] += lsm;
171 sstm[iz] += sst;
172 pblm[iz] += pbl;
173 pctm[iz] += pct;
174 pcbm[iz] += pcb;
175 clm[iz] += cl;
176 if (isfinite(plfc) && isfinite(pel) && cape >= ctl.
conv_cape
178 plclm[iz] += plcl;
179 plfcm[iz] += plfc;
180 pelm[iz] += pel;
181 capem[iz] += cape;
182 cinm[iz] += cin;
183 npc[iz]++;
184 }
185 if (isfinite(pt)) {
186 ptm[iz] += pt;
187 ztm[iz] += zt;
188 ttm[iz] += tt;
189 h2otm[iz] += h2ot;
190 npt[iz]++;
191 }
192 o3cm[iz] += o3c;
193 rhm[iz] +=
RH(plev[iz], t, h2o);
194 rhicem[iz] +=
RHICE(plev[iz], t, h2o);
195 tdewm[iz] +=
TDEW(plev[iz], h2o);
196 ticem[iz] +=
TICE(plev[iz], h2o);
198 tnatm[iz] +=
201 ohm[iz] +=
clim_oh(&ctl, clim, met->
time, lon, lat, plev[iz]);
205 np[iz]++;
206 }
207 }
208 }
209
210
211 LOG(1,
"Write meteorological data file: %s", argv[2]);
212 if (!(out = fopen(argv[2], "w")))
213 ERRMSG(
"Cannot create file!");
214
215
217
218
219 fprintf(out, "\n");
220 for (iz = 0; iz < nz; iz++)
221 fprintf(out,
222 "%.2f %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g"
223 " %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g"
224 " %g %g %g %g %g %g %g %g %g %g %g %g %g %d %d %d\n",
225 timem[iz] / np[iz],
Z(plev[iz]), lonm[iz] / np[iz],
226 latm[iz] / np[iz], plev[iz], tm[iz] / np[iz], um[iz] / np[iz],
227 vm[iz] / np[iz], wm[iz] / np[iz], h2om[iz] / np[iz],
228 o3m[iz] / np[iz], zm[iz] / np[iz], pvm[iz] / np[iz],
229 psm[iz] / np[iz], tsm[iz] / np[iz], zsm[iz] / np[iz],
230 usm[iz] / np[iz], vsm[iz] / np[iz], essm[iz] / np[iz],
231 nssm[iz] / np[iz], shfm[iz] / np[iz], lsmm[iz] / np[iz],
232 sstm[iz] / np[iz], ptm[iz] / npt[iz], ztm[iz] / npt[iz],
233 ttm[iz] / npt[iz], h2otm[iz] / npt[iz],
234 lwcm[iz] / np[iz], rwcm[iz] / np[iz], iwcm[iz] / np[iz],
235 swcm[iz] / np[iz], ccm[iz] / np[iz], clm[iz] / np[iz],
236 pctm[iz] / np[iz], pcbm[iz] / np[iz], plclm[iz] / npc[iz],
237 plfcm[iz] / npc[iz], pelm[iz] / npc[iz], capem[iz] / npc[iz],
238 cinm[iz] / npc[iz], rhm[iz] / np[iz], rhicem[iz] / np[iz],
239 tdewm[iz] / np[iz], ticem[iz] / np[iz], tnatm[iz] / np[iz],
240 hno3m[iz] / np[iz], ohm[iz] / np[iz], h2o2m[iz] / np[iz],
241 ho2m[iz] / np[iz], o1dm[iz] / np[iz], pblm[iz] / np[iz],
242 o3cm[iz] / np[iz], np[iz], npt[iz], npc[iz]);
243
244
245 fclose(out);
246
247
248 free(clim);
249 free(met);
250 free(dd);
251
252 return EXIT_SUCCESS;
253}
#define NZ
Maximum number of altitudes.
double clim_zm(const clim_zm_t *zm, const double t, const double lat, const double p)
Interpolates monthly mean zonal mean climatological variables.
double nat_temperature(const double p, const double h2o, const double hno3)
Calculates the nitric acid trihydrate (NAT) temperature.
double scan_ctl(const char *filename, int argc, char *argv[], const char *varname, const int arridx, const char *defvalue, char *value)
Scans a control file or command-line arguments for a specified variable.
void mptrac_read_clim(const ctl_t *ctl, clim_t *clim)
Reads various climatological data and populates the given climatology structure.
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...
int mptrac_read_met(const char *filename, const ctl_t *ctl, const clim_t *clim, met_t *met, dd_t *dd)
Reads meteorological data from a file, supporting multiple formats and MPI broadcasting.
void mptrac_read_ctl(const char *filename, int argc, char *argv[], ctl_t *ctl)
Reads control parameters from a configuration file and populates the given structure.
#define INTPOL_SPACE_ALL(p, lon, lat)
Interpolate multiple meteorological variables in space.
#define INTPOL_INIT
Initialize arrays for interpolation.
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
#define USAGE
Print usage information on -h or --help.
#define Z(p)
Convert pressure to altitude.
#define P(z)
Compute pressure at given altitude.
#define MET_HEADER
Write header for meteorological data file.
#define TICE(p, h2o)
Calculate frost point temperature (WMO, 2018).
#define RHICE(p, t, h2o)
Compute relative humidity over ice.
#define ALLOC(ptr, type, n)
Allocate memory for a pointer with error handling.
#define RH(p, t, h2o)
Compute relative humidity over water.
#define LOG(level,...)
Print a log message with a specified logging level.
#define TDEW(p, h2o)
Calculate dew point temperature.
clim_zm_t ho2
HO2 zonal means.
clim_zm_t hno3
HNO3 zonal means.
clim_zm_t o1d
O(1D) zonal means.
clim_zm_t h2o2
H2O2 zonal means.
double conv_cape
CAPE threshold for convection module [J/kg].
double conv_cin
CIN threshold for convection module [J/kg].
Domain decomposition data structure.
int np
Number of pressure levels.
double lon[EX]
Longitudes [deg].
double lat[EY]
Latitudes [deg].
double p[EP]
Pressure levels [hPa].