39 double k, kw[
EP], kz[
EP], mmax = 0, mtot = 0, z, zmin = 0, zmax = 0;
49 ERRMSG(
"Give parameters: <ctl> <atm_in> <atm_out>");
53 int n = (int)
scan_ctl(argv[1], argc, argv,
"SPLIT_N", -1,
"", NULL);
54 double m =
scan_ctl(argv[1], argc, argv,
"SPLIT_M", -1,
"-999", NULL);
55 double um =
scan_ctl(argv[1], argc, argv,
"SPLIT_UM", -1,
"0", NULL);
56 double dt =
scan_ctl(argv[1], argc, argv,
"SPLIT_DT", -1,
"0", NULL);
57 double t0 =
scan_ctl(argv[1], argc, argv,
"SPLIT_T0", -1,
"0", NULL);
58 double t1 =
scan_ctl(argv[1], argc, argv,
"SPLIT_T1", -1,
"0", NULL);
59 double dz =
scan_ctl(argv[1], argc, argv,
"SPLIT_DZ", -1,
"0", NULL);
60 double z0 =
scan_ctl(argv[1], argc, argv,
"SPLIT_Z0", -1,
"0", NULL);
61 double z1 =
scan_ctl(argv[1], argc, argv,
"SPLIT_Z1", -1,
"0", NULL);
62 double dx =
scan_ctl(argv[1], argc, argv,
"SPLIT_DX", -1,
"0", NULL);
63 double lon0 =
scan_ctl(argv[1], argc, argv,
"SPLIT_LON0", -1,
"0", NULL);
64 double lon1 =
scan_ctl(argv[1], argc, argv,
"SPLIT_LON1", -1,
"0", NULL);
65 double lat0 =
scan_ctl(argv[1], argc, argv,
"SPLIT_LAT0", -1,
"0", NULL);
66 double lat1 =
scan_ctl(argv[1], argc, argv,
"SPLIT_LAT1", -1,
"0", NULL);
67 scan_ctl(argv[1], argc, argv,
"SPLIT_KERNEL", -1,
"-", kernel);
71 rng = gsl_rng_alloc(gsl_rng_default);
75 ERRMSG(
"Cannot open file!");
78 if (kernel[0] !=
'-') {
80 zmax = gsl_stats_max(kz, 1, (
size_t) nk);
81 zmin = gsl_stats_min(kz, 1, (
size_t) nk);
86 for (ip = 0; ip < atm->
np; ip++) {
87 mtot += atm->
q[ctl.
qnt_m][ip];
94 for (
int i = 0; i < n; i++) {
99 ip = (int) gsl_rng_uniform_int(rng, (
long unsigned int) atm->
np);
100 }
while (gsl_rng_uniform(rng) > atm->
q[ctl.
qnt_m][ip] / mmax);
102 ip = (int) gsl_rng_uniform_int(rng, (
long unsigned int) atm->
np);
106 atm2->
time[atm2->
np] = t0 + (t1 - t0) * gsl_rng_uniform_pos(rng);
109 + gsl_ran_gaussian_ziggurat(rng, dt / 2.3548);
115 z = zmin + (zmax - zmin) * gsl_rng_uniform_pos(rng);
117 }
while (gsl_rng_uniform(rng) > k);
118 atm2->
p[atm2->
np] =
P(z);
120 atm2->
p[atm2->
np] =
P(z0 + (z1 - z0) * gsl_rng_uniform_pos(rng));
122 atm2->
p[atm2->
np] = atm->
p[ip]
123 +
DZ2DP(gsl_ran_gaussian_ziggurat(rng, dz / 2.3548), atm->
p[ip]);
124 }
while (atm2->
p[atm2->
np] <
P(100.) || atm2->
p[atm2->
np] >
P(-1.));
127 if (lon1 > lon0 && lat1 > lat0) {
128 atm2->
lon[atm2->
np] = lon0 + (lon1 - lon0) * gsl_rng_uniform_pos(rng);
129 atm2->
lat[atm2->
np] = lat0 + (lat1 - lat0) * gsl_rng_uniform_pos(rng);
132 + gsl_ran_gaussian_ziggurat(rng,
DX2DEG(dx, atm->
lat[ip]) / 2.3548);
134 + gsl_ran_gaussian_ziggurat(rng,
DY2DEG(dx) / 2.3548);
138 for (
int iq = 0; iq < ctl.
nq; iq++)
139 atm2->
q[iq][atm2->
np] = atm->
q[iq][ip];
144 = (mtot + (um > 0 ? um * (gsl_rng_uniform_pos(rng) - 0.5) : 0.0)) / n;
151 if ((++atm2->
np) >
NP)
152 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.