41 {
42
44
46
48
50
51 FILE *out;
52
53 static double cutImag[
EX], cutReal[
EX], lx[
EX], A[
EX], phi[
EX];
54
55
59
60
62
63
64 if (argc < 4)
65 ERRMSG(
"Missing or invalid command-line arguments.\n\n"
66 "Usage: met_spec <ctl> <spec.tab> <met0>\n\n"
67 "Use -h for full help.");
68
69
71 const double wavemax =
72 (int)
scan_ctl(argv[1], argc, argv,
"SPEC_WAVEMAX", -1,
"7", NULL);
73
74
76
77
79 ERRMSG(
"Cannot read meteo data!");
80
81
82 LOG(1,
"Write spectral data file: %s", argv[2]);
83 if (!(out = fopen(argv[2], "w")))
84 ERRMSG(
"Cannot create file!");
85
86
87 fprintf(out,
88 "# $1 = time [s]\n"
89 "# $2 = altitude [km]\n"
90 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
91 for (int ix = 0; ix <= wavemax; ix++) {
92 fprintf(out, "# $%d = wavelength (PW%d) [km]\n", 5 + 3 * ix, ix);
93 fprintf(out, "# $%d = amplitude (PW%d) [K]\n", 6 + 3 * ix, ix);
94 fprintf(out, "# $%d = phase (PW%d) [deg]\n", 7 + 3 * ix, ix);
95 }
96
97
98 for (
int ip = 0; ip < met->
np; ip++) {
99
100
101 fprintf(out, "\n");
102
103
104 for (
int iy = 0; iy < met->
ny; iy++) {
105
106
107 for (
int ix = 0; ix < met->
nx; ix++) {
108 cutReal[ix] = met->
t[ix][iy][ip];
109 cutImag[ix] = 0.0;
110 }
111
112
114
115
116
117
118
119 for (
int ix = 0; ix < met->
nx; ix++) {
121 / ((ix < met->
nx / 2) ? (
double) ix : -(double) (met->
nx - ix));
122 A[ix] = (ix == 0 ? 1.0 : 2.0) / (met->
nx)
123 * sqrt(gsl_pow_2(cutReal[ix]) + gsl_pow_2(cutImag[ix]));
124 phi[ix] =
RAD2DEG(atan2(cutImag[ix], cutReal[ix]));
125 }
126
127
128 fprintf(out,
"%.2f %g %g %g", met->
time,
Z(met->
p[ip]), 0.0,
130 for (int ix = 0; ix <= wavemax; ix++)
131 fprintf(out, " %g %g %g", lx[ix], A[ix], phi[ix]);
132 fprintf(out, "\n");
133 }
134 }
135
136
137 fclose(out);
138
139
140 free(clim);
141 free(met);
142 free(dd);
143
144 return EXIT_SUCCESS;
145}
void fft_help(double *fcReal, double *fcImag, const int n)
Computes the Fast Fourier Transform (FFT) of a complex sequence.
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.
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 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 EX
Maximum number of longitudes for meteo data.
#define ALLOC(ptr, type, n)
Allocate memory for a pointer with error handling.
#define RAD2DEG(rad)
Converts radians to degrees.
#define LOG(level,...)
Print a log message with a specified logging level.
#define DEG2DX(dlon, lat)
Convert a longitude difference to a distance in the x-direction (east-west) at a specific latitude.
Domain decomposition data structure.
int nx
Number of longitudes.
int ny
Number of latitudes.
int np
Number of pressure levels.
float t[EX][EY][EP]
Temperature [K].
double lon[EX]
Longitudes [deg].
double lat[EY]
Latitudes [deg].
double p[EP]
Pressure levels [hPa].