MPTRAC
Loading...
Searching...
No Matches
wind.c File Reference

Create meteorological data files with synthetic wind fields. More...

#include "mptrac.h"
#include <limits.h>

Go to the source code of this file.

Functions

void usage (void)
 Print command-line help.
 
int main (int argc, char *argv[])
 

Detailed Description

Create meteorological data files with synthetic wind fields.

Definition in file wind.c.

Function Documentation

◆ usage()

void usage ( void )

Print command-line help.

Definition at line 217 of file wind.c.

218 {
219
220 printf("\nMPTRAC wind tool.\n\n");
221 printf("Create meteorological data with synthetic wind fields.\n");
222 printf("\n");
223 printf("Usage:\n");
224 printf(" wind <ctl> <metbase> [KEY VALUE ...]\n");
225 printf("\n");
226 printf("Arguments:\n");
227 printf(" <ctl> Control file.\n");
228 printf(" <metbase> Basename of the output meteorological data.\n");
229 printf(" [KEY VALUE] Optional control parameters.\n");
230 printf("\nFurther information:\n");
231 printf(" Manual: https://slcs-jsc.github.io/mptrac/\n");
232}

◆ main()

int main ( int argc,
char * argv[] )

Definition at line 40 of file wind.c.

42 {
43
44 static ctl_t ctl;
45 met_t *met;
46
47 static char filename[LEN];
48
49 static int year, mon, day, hour, min, sec;
50 static double r;
51
52 /* Print usage information... */
53 USAGE;
54
55 /* Check arguments... */
56 if (argc < 3)
57 ERRMSG("Missing or invalid command-line arguments.\n\n"
58 "Usage: wind <ctl> <metbase> [KEY VALUE ...]\n\n"
59 "Use -h for full help.");
60
61 /* Read control parameters... */
62 mptrac_read_ctl(argv[1], argc, argv, &ctl);
63 const double t0 = scan_ctl(argv[1], argc, argv, "WIND_T0", -1, "0", NULL);
64 const int nx =
65 (int) scan_ctl(argv[1], argc, argv, "WIND_NX", -1, "360", NULL);
66 const int ny =
67 (int) scan_ctl(argv[1], argc, argv, "WIND_NY", -1, "181", NULL);
68 const int nz =
69 (int) scan_ctl(argv[1], argc, argv, "WIND_NZ", -1, "61", NULL);
70 const double z0 = scan_ctl(argv[1], argc, argv, "WIND_Z0", -1, "0", NULL);
71 const double z1 = scan_ctl(argv[1], argc, argv, "WIND_Z1", -1, "60", NULL);
72 const double u0 =
73 scan_ctl(argv[1], argc, argv, "WIND_U0", -1, "38.587660177302", NULL);
74 const double u1 =
75 scan_ctl(argv[1], argc, argv, "WIND_U1", -1, "38.587660177302", NULL);
76 const double w0 = scan_ctl(argv[1], argc, argv, "WIND_W0", -1, "0", NULL);
77 const double pert_u =
78 scan_ctl(argv[1], argc, argv, "WIND_PERT_U", -1, "0", NULL);
79 const double pert_v =
80 scan_ctl(argv[1], argc, argv, "WIND_PERT_V", -1, "0", NULL);
81 const double pert_w =
82 scan_ctl(argv[1], argc, argv, "WIND_PERT_W", -1, "0", NULL);
83 const double pert_k_raw =
84 scan_ctl(argv[1], argc, argv, "WIND_PERT_K", -1, "24", NULL);
85 const int perturb = (pert_u != 0 || pert_v != 0 || pert_w != 0);
86 if (!isfinite(pert_u) || !isfinite(pert_v) || !isfinite(pert_w)
87 || !isfinite(pert_k_raw) || pert_k_raw < 1 || pert_k_raw > INT_MAX
88 || pert_k_raw != floor(pert_k_raw))
89 ERRMSG("WIND_PERT amplitudes must be finite and WIND_PERT_K a positive integer!");
90 const int pert_k = (int) pert_k_raw;
91 const double alpha =
92 scan_ctl(argv[1], argc, argv, "WIND_ALPHA", -1, "0.0", NULL);
93 const int lat_reverse =
94 (int) scan_ctl(argv[1], argc, argv, "WIND_LAT_REVERSE", -1, "0", NULL);
95 const double temp0 =
96 scan_ctl(argv[1], argc, argv, "WIND_TEMP0", -1, "280", NULL);
97 const double temp1 =
98 scan_ctl(argv[1], argc, argv, "WIND_TEMP1", -1, "280", NULL);
99 const double ps =
100 scan_ctl(argv[1], argc, argv, "WIND_PS", -1, "1013.25", NULL);
101 const double zs = scan_ctl(argv[1], argc, argv, "WIND_ZS", -1, "0", NULL);
102 const double t2m =
103 scan_ctl(argv[1], argc, argv, "WIND_T2M", -1, "280", NULL);
104 const double iews =
105 scan_ctl(argv[1], argc, argv, "WIND_IEWS", -1, "0", NULL);
106 const double inss =
107 scan_ctl(argv[1], argc, argv, "WIND_INSS", -1, "0", NULL);
108 const double ishf =
109 scan_ctl(argv[1], argc, argv, "WIND_ISHF", -1, "0", NULL);
110 const double lsm = scan_ctl(argv[1], argc, argv, "WIND_LSM", -1, "1", NULL);
111 const double sst =
112 scan_ctl(argv[1], argc, argv, "WIND_SST", -1, "280", NULL);
113 const double blh =
114 scan_ctl(argv[1], argc, argv, "WIND_BLH", -1, "1.0", NULL);
115 const double q = scan_ctl(argv[1], argc, argv, "WIND_Q", -1, "0", NULL);
116 const double o3 = scan_ctl(argv[1], argc, argv, "WIND_O3", -1, "0", NULL);
117
118 /* Check dimensions... */
119 if (nx < 2 || nx > EX)
120 ERRMSG("Set 2 <= NX <= MAX!");
121 if (ny < 2 || ny > EY)
122 ERRMSG("Set 2 <= NY <= MAX!");
123 if (nz < 2 || nz > EP)
124 ERRMSG("Set 2 <= NZ <= MAX!");
125
126 /* Get time and output filename... */
127 jsec2time(t0, &year, &mon, &day, &hour, &min, &sec, &r);
128 sprintf(filename, "%s_%d_%02d_%02d_%02d.nc", argv[2], year, mon, day, hour);
129
130 /* Initialize synthetic meteorological data. */
131 ALLOC(met, met_t, 1);
132 met->time = t0;
133 met->coord_type = 0;
134 met->nx = nx;
135 met->ny = ny;
136 met->np = nz;
137
138 /* Set grid... */
139 for (int ix = 0; ix < nx; ix++)
140 met->lon[ix] = 360.0 / nx * (double) ix;
141 for (int iy = 0; iy < ny; iy++)
142 met->lat[iy] = (lat_reverse ? -(180.0 / (ny - 1) * (double) iy - 90.0)
143 : (180.0 / (ny - 1) * (double) iy - 90.0));
144 for (int iz = 0; iz < nz; iz++)
145 met->p[iz] = P(LIN(0.0, z0, nz - 1.0, z1, iz));
146
147 /* Set meteo data... */
148 for (int ix = 0; ix < nx; ix++)
149 for (int iy = 0; iy < ny; iy++) {
150 double shape_u = 0, shape_v = 0, shape_w = 0;
151 if (perturb) {
152 /* Taper the waves to zero at the poles. */
153 const double lon_phase = pert_k * DEG2RAD(met->lon[ix]);
154 const double lat_phase = pert_k * DEG2RAD(met->lat[iy]);
155 const double taper = SQR(cos(DEG2RAD(met->lat[iy])));
156 shape_u = taper * sin(lon_phase) * cos(lat_phase);
157 shape_v = taper * cos(lon_phase) * cos(lat_phase + M_PI / 4);
158 shape_w = taper * sin(lon_phase + M_PI / 4)
159 * sin(lat_phase + M_PI / 4);
160 }
161 const double usfc = u0
162 * (cos(DEG2RAD(met->lat[iy])) * cos(DEG2RAD(alpha))
163 + sin(DEG2RAD(met->lat[iy])) * cos(DEG2RAD(met->lon[ix]))
164 * sin(DEG2RAD(alpha)));
165 const double vsfc =
166 -u0 * sin(DEG2RAD(met->lon[ix])) * sin(DEG2RAD(alpha));
167
168 met->ps[ix][iy] = (float) ps;
169 met->zs[ix][iy] = (float) zs;
170 met->ts[ix][iy] = (float) t2m;
171 met->us[ix][iy] = (float) (perturb ? usfc + pert_u * shape_u : usfc);
172 met->vs[ix][iy] = (float) (perturb ? vsfc + pert_v * shape_v : vsfc);
173 met->ess[ix][iy] = (float) iews;
174 met->nss[ix][iy] = (float) inss;
175 met->shf[ix][iy] = (float) ishf;
176 met->lsm[ix][iy] = (float) lsm;
177 met->sst[ix][iy] = (float) sst;
178 met->pbl[ix][iy] = (float) P(zs + blh);
179
180 for (int iz = 0; iz < nz; iz++) {
181 double u = LIN(0.0, u0, nz - 1.0, u1, iz)
182 * (cos(DEG2RAD(met->lat[iy])) * cos(DEG2RAD(alpha))
183 + sin(DEG2RAD(met->lat[iy])) * cos(DEG2RAD(met->lon[ix]))
184 * sin(DEG2RAD(alpha)));
185 double v = -LIN(0.0, u0, nz - 1.0, u1, iz)
186 * sin(DEG2RAD(met->lon[ix])) * sin(DEG2RAD(alpha));
187 double w = w0;
188 if (perturb) {
189 const double height_factor =
190 0.75 + 0.25 * cos(2 * M_PI * iz / (nz - 1.));
191 u += pert_u * shape_u * height_factor;
192 v += pert_v * shape_v * height_factor;
193 w += pert_w * shape_w * height_factor;
194 }
195
196 met->t[ix][iy][iz] = (float) LIN(0.0, temp0, nz - 1.0, temp1, iz);
197 met->u[ix][iy][iz] = (float) u;
198 met->v[ix][iy][iz] = (float) v;
199 met->w[ix][iy][iz] = (float) DZ2DP(1e-3 * w, met->p[iz]);
200 met->h2o[ix][iy][iz] = (float) (q * MA / MH2O);
201 met->o3[ix][iy][iz] = (float) (o3 * MA / MO3);
202 }
203 }
204
205 /* Write synthetic meteorological data. */
206 write_met_nc(filename, &ctl, met);
207
208 /* Free... */
209 free(met);
210
211 return EXIT_SUCCESS;
212}
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.
Definition mptrac.c:13329
void write_met_nc(const char *filename, const ctl_t *ctl, met_t *met)
Writes meteorological data to a NetCDF file.
Definition mptrac.c:15432
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.
Definition mptrac.c:3571
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.
Definition mptrac.c:7089
#define LEN
Maximum length of ASCII data lines.
Definition mptrac.h:559
#define MA
Molar mass of dry air [g/mol].
Definition mptrac.h:290
#define MH2O
Molar mass of water vapor [g/mol].
Definition mptrac.h:295
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
Definition mptrac.h:2426
#define EY
Maximum number of latitudes for meteo data.
Definition mptrac.h:554
#define USAGE
Print usage information on -h or --help.
Definition mptrac.h:2233
#define P(z)
Compute pressure at given altitude.
Definition mptrac.h:1804
#define EX
Maximum number of longitudes for meteo data.
Definition mptrac.h:549
#define DZ2DP(dz, p)
Convert a change in altitude to a change in pressure.
Definition mptrac.h:943
#define ALLOC(ptr, type, n)
Allocate memory for a pointer with error handling.
Definition mptrac.h:668
#define DEG2RAD(deg)
Converts degrees to radians.
Definition mptrac.h:859
#define MO3
Molar mass of ozone [g/mol].
Definition mptrac.h:300
#define SQR(x)
Compute the square of a value.
Definition mptrac.h:2057
#define EP
Maximum number of pressure levels for meteo data.
Definition mptrac.h:544
#define LIN(x0, y0, x1, y1, x)
Linear interpolation.
Definition mptrac.h:1360
Control parameters.
Definition mptrac.h:2514
Meteo data structure.
Definition mptrac.h:3896
float sst[EX][EY]
Sea surface temperature [K].
Definition mptrac.h:3965
float h2o[EX][EY][EP]
Water vapor volume mixing ratio [1].
Definition mptrac.h:4028
int coord_type
Definition mptrac.h:3902
float w[EX][EY][EP]
Vertical velocity [hPa/s].
Definition mptrac.h:4022
int nx
Number of longitudes.
Definition mptrac.h:3905
int ny
Number of latitudes.
Definition mptrac.h:3908
float shf[EX][EY]
Surface sensible heat flux [W/m^2].
Definition mptrac.h:3959
float ps[EX][EY]
Surface pressure [hPa].
Definition mptrac.h:3938
float us[EX][EY]
Surface zonal wind [m/s].
Definition mptrac.h:3947
float zs[EX][EY]
Surface geopotential height [km].
Definition mptrac.h:3944
float o3[EX][EY][EP]
Ozone volume mixing ratio [1].
Definition mptrac.h:4031
int np
Number of pressure levels.
Definition mptrac.h:3911
float t[EX][EY][EP]
Temperature [K].
Definition mptrac.h:4013
float ts[EX][EY]
Surface temperature [K].
Definition mptrac.h:3941
float u[EX][EY][EP]
Zonal wind [m/s].
Definition mptrac.h:4016
float ess[EX][EY]
Eastward turbulent surface stress [N/m^2].
Definition mptrac.h:3953
double lon[EX]
Longitudes [deg].
Definition mptrac.h:3917
float pbl[EX][EY]
Boundary layer pressure [hPa].
Definition mptrac.h:3968
float vs[EX][EY]
Surface meridional wind [m/s].
Definition mptrac.h:3950
float v[EX][EY][EP]
Meridional wind [m/s].
Definition mptrac.h:4019
float lsm[EX][EY]
Land-sea mask [1].
Definition mptrac.h:3962
double time
Time [s].
Definition mptrac.h:3899
float nss[EX][EY]
Northward turbulent surface stress [N/m^2].
Definition mptrac.h:3956
double lat[EY]
Latitudes [deg].
Definition mptrac.h:3920
double p[EP]
Pressure levels [hPa].
Definition mptrac.h:3923
Here is the call graph for this function: