MPTRAC
Functions
wind.c File Reference

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

#include "mptrac.h"

Go to the source code of this file.

Functions

void usage (void)
 Print command-line help. More...
 
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 189 of file wind.c.

190 {
191
192 printf("\nMPTRAC wind tool.\n\n");
193 printf("Create meteorological data with synthetic wind fields.\n");
194 printf("\n");
195 printf("Usage:\n");
196 printf(" wind <ctl> <metbase> [KEY VALUE ...]\n");
197 printf("\n");
198 printf("Arguments:\n");
199 printf(" <ctl> Control file.\n");
200 printf(" <metbase> Basename of the output meteorological data.\n");
201 printf(" [KEY VALUE] Optional control parameters.\n");
202 printf("\nFurther information:\n");
203 printf(" Manual: https://slcs-jsc.github.io/mptrac/\n");
204}

◆ main()

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

Definition at line 39 of file wind.c.

41 {
42
43 ctl_t ctl;
44
45 static char filename[LEN];
46
47 static double r, dataLon[EX], dataLat[EY], dataZ[EP];
48
49 static float *dataT, *dataU, *dataV, *dataW;
50
51 static int ncid, varid, dims[4], year, mon, day, hour, min, sec;
52
53 static size_t start[4], count[4];
54
55 /* Allocate... */
56 ALLOC(dataT, float,
57 EP * EY * EX);
58 ALLOC(dataU, float,
59 EP * EY * EX);
60 ALLOC(dataV, float,
61 EP * EY * EX);
62 ALLOC(dataW, float,
63 EP * EY * EX);
64
65 /* Print usage information... */
66 USAGE;
67
68 /* Check arguments... */
69 if (argc < 3)
70 ERRMSG("Missing or invalid command-line arguments.\n\n"
71 "Usage: wind <ctl> <metbase> [KEY VALUE ...]\n\n"
72 "Use -h for full help.");
73
74 /* Read control parameters... */
75 mptrac_read_ctl(argv[1], argc, argv, &ctl);
76 double t0 = scan_ctl(argv[1], argc, argv, "WIND_T0", -1, "0", NULL);
77 const int nx =
78 (int) scan_ctl(argv[1], argc, argv, "WIND_NX", -1, "360", NULL);
79 const int ny =
80 (int) scan_ctl(argv[1], argc, argv, "WIND_NY", -1, "181", NULL);
81 const int nz =
82 (int) scan_ctl(argv[1], argc, argv, "WIND_NZ", -1, "61", NULL);
83 const double z0 = scan_ctl(argv[1], argc, argv, "WIND_Z0", -1, "0", NULL);
84 const double z1 = scan_ctl(argv[1], argc, argv, "WIND_Z1", -1, "60", NULL);
85 const double u0 =
86 scan_ctl(argv[1], argc, argv, "WIND_U0", -1, "38.587660177302", NULL);
87 const double u1 =
88 scan_ctl(argv[1], argc, argv, "WIND_U1", -1, "38.587660177302", NULL);
89 const double w0 = scan_ctl(argv[1], argc, argv, "WIND_W0", -1, "0", NULL);
90 const double alpha =
91 scan_ctl(argv[1], argc, argv, "WIND_ALPHA", -1, "0.0", NULL);
92 const int lat_reverse =
93 (int) scan_ctl(argv[1], argc, argv, "WIND_LAT_REVERSE", -1, "0", NULL);
94
95 /* Check dimensions... */
96 if (nx < 1 || nx > EX)
97 ERRMSG("Set 1 <= NX <= MAX!");
98 if (ny < 1 || ny > EY)
99 ERRMSG("Set 1 <= NY <= MAX!");
100 if (nz < 1 || nz > EP)
101 ERRMSG("Set 1 <= NZ <= MAX!");
102
103 /* Get time... */
104 jsec2time(t0, &year, &mon, &day, &hour, &min, &sec, &r);
105 t0 = year * 10000. + mon * 100. + day + hour / 24.;
106
107 /* Set filename... */
108 sprintf(filename, "%s_%d_%02d_%02d_%02d.nc", argv[2], year, mon, day, hour);
109
110 /* Create netCDF file... */
111 NC(nc_create(filename, NC_NETCDF4, &ncid));
112
113 /* Create dimensions... */
114 NC(nc_def_dim(ncid, "time", 1, &dims[0]));
115 NC(nc_def_dim(ncid, "lev", (size_t) nz, &dims[1]));
116 NC(nc_def_dim(ncid, "lat", (size_t) ny, &dims[2]));
117 NC(nc_def_dim(ncid, "lon", (size_t) nx, &dims[3]));
118
119 /* Create variables... */
120 NC_DEF_VAR("time", NC_DOUBLE, 1, &dims[0], "time", "day as %Y%m%d.%f", 0,
121 0);
122 NC_DEF_VAR("lev", NC_DOUBLE, 1, &dims[1], "air_pressure", "Pa", 0, 0);
123 NC_DEF_VAR("lat", NC_DOUBLE, 1, &dims[2], "latitude", "degrees_north", 0,
124 0);
125 NC_DEF_VAR("lon", NC_DOUBLE, 1, &dims[3], "longitude", "degrees_east", 0,
126 0);
127 NC_DEF_VAR("T", NC_FLOAT, 4, &dims[0], "Temperature", "K", 0, 0);
128 NC_DEF_VAR("U", NC_FLOAT, 4, &dims[0], "zonal wind", "m s**-1", 0, 0);
129 NC_DEF_VAR("V", NC_FLOAT, 4, &dims[0], "meridional wind", "m s**-1", 0, 0);
130 NC_DEF_VAR("W", NC_FLOAT, 4, &dims[0], "vertical velocity", "Pa s**-1", 0,
131 0);
132
133 /* End definition... */
134 NC(nc_enddef(ncid));
135
136 /* Set coordinates... */
137 for (int ix = 0; ix < nx; ix++)
138 dataLon[ix] = 360.0 / nx * (double) ix;
139 for (int iy = 0; iy < ny; iy++)
140 dataLat[iy] = (lat_reverse ? -(180.0 / (ny - 1) * (double) iy - 90)
141 : (180.0 / (ny - 1) * (double) iy - 90));
142 for (int iz = 0; iz < nz; iz++)
143 dataZ[iz] = 100. * P(LIN(0.0, z0, nz - 1.0, z1, iz));
144
145 /* Write coordinates... */
146 NC_PUT_DOUBLE("time", &t0, 0);
147 NC_PUT_DOUBLE("lev", dataZ, 0);
148 NC_PUT_DOUBLE("lat", dataLat, 0);
149 NC_PUT_DOUBLE("lon", dataLon, 0);
150
151 /* Create wind fields (Williamson et al., 1992)... */
152 for (int ix = 0; ix < nx; ix++)
153 for (int iy = 0; iy < ny; iy++)
154 for (int iz = 0; iz < nz; iz++) {
155 int idx = (iz * ny + iy) * nx + ix;
156 dataU[idx] = (float) (LIN(0.0, u0, nz - 1.0, u1, iz)
157 * (cos(DEG2RAD(dataLat[iy]))
158 * cos(DEG2RAD(alpha))
159 + sin(DEG2RAD(dataLat[iy]))
160 * cos(DEG2RAD(dataLon[ix]))
161 * sin(DEG2RAD(alpha))));
162 dataV[idx] = (float) (-LIN(0.0, u0, nz - 1.0, u1, iz)
163 * sin(DEG2RAD(dataLon[ix]))
164 * sin(DEG2RAD(alpha)));
165 dataW[idx] = (float) DZ2DP(1e-3 * w0, dataZ[iz]);
166 }
167
168 /* Write data... */
169 NC_PUT_FLOAT("T", dataT, 0);
170 NC_PUT_FLOAT("U", dataU, 0);
171 NC_PUT_FLOAT("V", dataV, 0);
172 NC_PUT_FLOAT("W", dataW, 0);
173
174 /* Close file... */
175 NC(nc_close(ncid));
176
177 /* Free... */
178 free(dataT);
179 free(dataU);
180 free(dataV);
181 free(dataW);
182
183 return EXIT_SUCCESS;
184}
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:10745
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:2294
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:5248
#define LEN
Maximum length of ASCII data lines.
Definition: mptrac.h:345
#define NC(cmd)
Execute a NetCDF command and check for errors.
Definition: mptrac.h:1204
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
Definition: mptrac.h:2102
#define EY
Maximum number of latitudes for meteo data.
Definition: mptrac.h:340
#define USAGE
Print usage information on -h or --help.
Definition: mptrac.h:1909
#define P(z)
Compute pressure at given altitude.
Definition: mptrac.h:1480
#define EX
Maximum number of longitudes for meteo data.
Definition: mptrac.h:335
#define DZ2DP(dz, p)
Convert a change in altitude to a change in pressure.
Definition: mptrac.h:688
#define ALLOC(ptr, type, n)
Allocate memory for a pointer with error handling.
Definition: mptrac.h:453
#define DEG2RAD(deg)
Converts degrees to radians.
Definition: mptrac.h:604
#define NC_PUT_FLOAT(varname, ptr, hyperslab)
Write a float array to a NetCDF file.
Definition: mptrac.h:1341
#define NC_DEF_VAR(varname, type, ndims, dims, long_name, units, level, quant)
Define a NetCDF variable with attributes.
Definition: mptrac.h:1233
#define EP
Maximum number of pressure levels for meteo data.
Definition: mptrac.h:330
#define NC_PUT_DOUBLE(varname, ptr, hyperslab)
Write double precision data to a NetCDF variable.
Definition: mptrac.h:1317
#define LIN(x0, y0, x1, y1, x)
Linear interpolation.
Definition: mptrac.h:1047
Control parameters.
Definition: mptrac.h:2190
Here is the call graph for this function: