37 double k, kw[
EP], kz[
EP], mmax = 0, mtot = 0, z, zmin = 0, zmax = 0;
47 ERRMSG(
"Give parameters: <ctl> <atm_in> <atm_out>");
51 const int n = (int)
scan_ctl(argv[1], argc, argv,
"SPLIT_N", -1,
"", NULL);
52 const double m =
scan_ctl(argv[1], argc, argv,
"SPLIT_M", -1,
"-999", NULL);
53 const double um =
scan_ctl(argv[1], argc, argv,
"SPLIT_UM", -1,
"0", NULL);
54 const double dt =
scan_ctl(argv[1], argc, argv,
"SPLIT_DT", -1,
"0", NULL);
55 const double t0 =
scan_ctl(argv[1], argc, argv,
"SPLIT_T0", -1,
"0", NULL);
56 const double t1 =
scan_ctl(argv[1], argc, argv,
"SPLIT_T1", -1,
"0", NULL);
57 const double dz =
scan_ctl(argv[1], argc, argv,
"SPLIT_DZ", -1,
"0", NULL);
58 const double z0 =
scan_ctl(argv[1], argc, argv,
"SPLIT_Z0", -1,
"0", NULL);
59 const double z1 =
scan_ctl(argv[1], argc, argv,
"SPLIT_Z1", -1,
"0", NULL);
60 const double dx =
scan_ctl(argv[1], argc, argv,
"SPLIT_DX", -1,
"0", NULL);
62 scan_ctl(argv[1], argc, argv,
"SPLIT_LON0", -1,
"0", NULL);
64 scan_ctl(argv[1], argc, argv,
"SPLIT_LON1", -1,
"0", NULL);
66 scan_ctl(argv[1], argc, argv,
"SPLIT_LAT0", -1,
"0", NULL);
68 scan_ctl(argv[1], argc, argv,
"SPLIT_LAT1", -1,
"0", NULL);
69 scan_ctl(argv[1], argc, argv,
"SPLIT_KERNEL", -1,
"-", kernel);
73 gsl_rng *rng = gsl_rng_alloc(gsl_rng_default);
77 ERRMSG(
"Cannot open file!");
80 if (kernel[0] !=
'-') {
82 zmax = gsl_stats_max(kz, 1, (
size_t) nk);
83 zmin = gsl_stats_min(kz, 1, (
size_t) nk);
88 for (ip = 0; ip < atm->
np; ip++) {
89 mtot += atm->
q[ctl.
qnt_m][ip];
96 for (
int i = 0; i < n; i++) {
101 ip = (int) gsl_rng_uniform_int(rng, (
long unsigned int) atm->
np);
102 }
while (gsl_rng_uniform(rng) > atm->
q[ctl.
qnt_m][ip] / mmax);
104 ip = (int) gsl_rng_uniform_int(rng, (
long unsigned int) atm->
np);
108 atm2->
time[atm2->
np] = t0 + (t1 - t0) * gsl_rng_uniform_pos(rng);
111 + gsl_ran_gaussian_ziggurat(rng, dt / 2.3548);
117 z = zmin + (zmax - zmin) * gsl_rng_uniform_pos(rng);
119 }
while (gsl_rng_uniform(rng) > k);
120 atm2->
p[atm2->
np] =
P(z);
122 atm2->
p[atm2->
np] =
P(z0 + (z1 - z0) * gsl_rng_uniform_pos(rng));
124 atm2->
p[atm2->
np] = atm->
p[ip]
125 +
DZ2DP(gsl_ran_gaussian_ziggurat(rng, dz / 2.3548), atm->
p[ip]);
126 }
while (atm2->
p[atm2->
np] <
P(100.) || atm2->
p[atm2->
np] >
P(-1.));
129 if (lon1 > lon0 && lat1 > lat0) {
130 atm2->
lon[atm2->
np] = lon0 + (lon1 - lon0) * gsl_rng_uniform_pos(rng);
131 atm2->
lat[atm2->
np] = lat0 + (lat1 - lat0) * gsl_rng_uniform_pos(rng);
134 + gsl_ran_gaussian_ziggurat(rng,
DX2DEG(dx, atm->
lat[ip]) / 2.3548);
136 + gsl_ran_gaussian_ziggurat(rng,
DY2DEG(dx) / 2.3548);
140 for (
int iq = 0; iq < ctl.
nq; iq++)
141 atm2->
q[iq][atm2->
np] = atm->
q[iq][ip];
146 = (mtot + (um > 0 ? um * (gsl_rng_uniform_pos(rng) - 0.5) : 0.0)) / n;
153 if ((++atm2->
np) >
NP)
154 ERRMSG(
"Too many air parcels!");
int main(int argc, char *argv[])
void write_atm(const char *filename, const ctl_t *ctl, const atm_t *atm, const double t)
Writes air parcel data to a file in various formats.
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.
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 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 read_atm(const char *filename, const ctl_t *ctl, atm_t *atm)
Reads air parcel data from a specified file into the given atmospheric structure.
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.
MPTRAC library declarations.
#define LEN
Maximum length of ASCII data lines.
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
#define P(z)
Compute pressure at given altitude.
#define DX2DEG(dx, lat)
Convert a distance in kilometers to degrees longitude at a given latitude.
#define DZ2DP(dz, p)
Convert a change in altitude to a change in pressure.
#define ALLOC(ptr, type, n)
Allocate memory for a pointer with error handling.
#define NP
Maximum number of atmospheric data points.
#define EP
Maximum number of pressure levels for meteo data.
#define DY2DEG(dy)
Convert a distance in kilometers to degrees latitude.
#define MAX(a, b)
Macro to determine the maximum of two values.
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].
int qnt_m
Quantity array index for mass.
int qnt_idx
Quantity array index for air parcel IDs.
int nq
Number of quantities.