MPTRAC
Functions
atm_init.c File Reference

Create atmospheric data file with initial air parcel positions. More...

#include "mptrac.h"

Go to the source code of this file.

Functions

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

Detailed Description

Create atmospheric data file with initial air parcel positions.

Definition in file atm_init.c.

Function Documentation

◆ main()

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

Definition at line 27 of file atm_init.c.

29 {
30
31 atm_t *atm;
32
33 ctl_t ctl;
34
35 /* Allocate... */
36 ALLOC(atm, atm_t, 1);
37
38 /* Check arguments... */
39 if (argc < 3)
40 ERRMSG("Give parameters: <ctl> <atm_out>");
41
42 /* Read control parameters... */
43 read_ctl(argv[1], argc, argv, &ctl);
44 const double t0 = scan_ctl(argv[1], argc, argv, "INIT_T0", -1, "0", NULL);
45 const double t1 = scan_ctl(argv[1], argc, argv, "INIT_T1", -1, "0", NULL);
46 const double dt = scan_ctl(argv[1], argc, argv, "INIT_DT", -1, "1", NULL);
47 const double z0 = scan_ctl(argv[1], argc, argv, "INIT_Z0", -1, "0", NULL);
48 const double z1 = scan_ctl(argv[1], argc, argv, "INIT_Z1", -1, "0", NULL);
49 const double dz = scan_ctl(argv[1], argc, argv, "INIT_DZ", -1, "1", NULL);
50 const double lon0 =
51 scan_ctl(argv[1], argc, argv, "INIT_LON0", -1, "0", NULL);
52 const double lon1 =
53 scan_ctl(argv[1], argc, argv, "INIT_LON1", -1, "0", NULL);
54 const double dlon =
55 scan_ctl(argv[1], argc, argv, "INIT_DLON", -1, "1", NULL);
56 const double lat0 =
57 scan_ctl(argv[1], argc, argv, "INIT_LAT0", -1, "0", NULL);
58 const double lat1 =
59 scan_ctl(argv[1], argc, argv, "INIT_LAT1", -1, "0", NULL);
60 const double dlat =
61 scan_ctl(argv[1], argc, argv, "INIT_DLAT", -1, "1", NULL);
62 const double st = scan_ctl(argv[1], argc, argv, "INIT_ST", -1, "0", NULL);
63 const double sz = scan_ctl(argv[1], argc, argv, "INIT_SZ", -1, "0", NULL);
64 const double slon =
65 scan_ctl(argv[1], argc, argv, "INIT_SLON", -1, "0", NULL);
66 const double slat =
67 scan_ctl(argv[1], argc, argv, "INIT_SLAT", -1, "0", NULL);
68 const double sx = scan_ctl(argv[1], argc, argv, "INIT_SX", -1, "0", NULL);
69 const double ut = scan_ctl(argv[1], argc, argv, "INIT_UT", -1, "0", NULL);
70 const double uz = scan_ctl(argv[1], argc, argv, "INIT_UZ", -1, "0", NULL);
71 const double ulon =
72 scan_ctl(argv[1], argc, argv, "INIT_ULON", -1, "0", NULL);
73 const double ulat =
74 scan_ctl(argv[1], argc, argv, "INIT_ULAT", -1, "0", NULL);
75 const int even =
76 (int) scan_ctl(argv[1], argc, argv, "INIT_EVENLY", -1, "0", NULL);
77 const int rep =
78 (int) scan_ctl(argv[1], argc, argv, "INIT_REP", -1, "1", NULL);
79 const double m = scan_ctl(argv[1], argc, argv, "INIT_MASS", -1, "0", NULL);
80 const double vmr = scan_ctl(argv[1], argc, argv, "INIT_VMR", -1, "0", NULL);
81 const double bellrad =
82 scan_ctl(argv[1], argc, argv, "INIT_BELLRAD", -1, "0", NULL);
83
84 /* Initialize random number generator... */
85 gsl_rng_env_setup();
86 gsl_rng *rng = gsl_rng_alloc(gsl_rng_default);
87
88 /* Create grid... */
89 for (double t = t0; t <= t1; t += dt)
90 for (double z = z0; z <= z1; z += dz)
91 for (double lon = lon0; lon <= lon1; lon += dlon)
92 for (double lat = lat0; lat <= lat1; lat += dlat)
93 for (int irep = 0; irep < rep; irep++) {
94
95 /* Set position... */
96 double rg = gsl_ran_gaussian_ziggurat(rng, st / 2.3548);
97 double ru = ut * (gsl_rng_uniform(rng) - 0.5);
98 atm->time[atm->np] = (t + rg + ru);
99
100 rg = gsl_ran_gaussian_ziggurat(rng, sz / 2.3548);
101 ru = uz * (gsl_rng_uniform(rng) - 0.5);
102 atm->p[atm->np] = P(z + rg + ru);
103
104 rg = gsl_ran_gaussian_ziggurat(rng, slon / 2.3548);
105 double rx =
106 gsl_ran_gaussian_ziggurat(rng, DX2DEG(sx, lat) / 2.3548);
107 ru = ulon * (gsl_rng_uniform(rng) - 0.5);
108 atm->lon[atm->np] = (lon + rg + rx + ru);
109
110 do {
111 rg = gsl_ran_gaussian_ziggurat(rng, slat / 2.3548);
112 rx = gsl_ran_gaussian_ziggurat(rng, DY2DEG(sx) / 2.3548);
113 ru = ulat * (gsl_rng_uniform(rng) - 0.5);
114 atm->lat[atm->np] = (lat + rg + rx + ru);
115 } while (even && gsl_rng_uniform(rng) >
116 fabs(cos(DEG2RAD(atm->lat[atm->np]))));
117
118 /* Apply cosine bell (Williamson et al., 1992)... */
119 if (bellrad > 0) {
120 double x0[3], x1[3];
121 geo2cart(0.0, 0.5 * (lon0 + lon1), 0.5 * (lat0 + lat1), x0);
122 geo2cart(0.0, atm->lon[atm->np], atm->lat[atm->np], x1);
123 const double rad =
124 RE * acos(DOTP(x0, x1) / NORM(x0) / NORM(x1));
125 if (rad > bellrad)
126 continue;
127 if (ctl.qnt_m >= 0)
128 atm->q[ctl.qnt_m][atm->np] =
129 0.5 * (1. + cos(M_PI * rad / bellrad));
130 if (ctl.qnt_vmr >= 0)
131 atm->q[ctl.qnt_vmr][atm->np] =
132 0.5 * (1. + cos(M_PI * rad / bellrad));
133 }
134
135 /* Set particle counter... */
136 if ((++atm->np) > NP)
137 ERRMSG("Too many particles!");
138 }
139
140 /* Check number of air parcels... */
141 if (atm->np <= 0)
142 ERRMSG("Did not create any air parcels!");
143
144 /* Initialize mass... */
145 if (ctl.qnt_m >= 0 && bellrad <= 0)
146 for (int ip = 0; ip < atm->np; ip++)
147 atm->q[ctl.qnt_m][ip] = m / atm->np;
148
149 /* Initialize volume mixing ratio... */
150 if (ctl.qnt_vmr >= 0 && bellrad <= 0)
151 for (int ip = 0; ip < atm->np; ip++)
152 atm->q[ctl.qnt_vmr][ip] = vmr;
153
154 /* Initialize air parcel index... */
155 if (ctl.qnt_idx >= 0)
156 for (int ip = 0; ip < atm->np; ip++)
157 atm->q[ctl.qnt_idx][ip] = ip;
158
159 /* Initialize age of air... */
160 if (ctl.qnt_aoa >= 0)
161 for (int ip = 0; ip < atm->np; ip++)
162 atm->q[ctl.qnt_aoa][ip] = atm->time[ip];
163
164 /* Save data... */
165 write_atm(argv[2], &ctl, atm, 0);
166
167 /* Free... */
168 gsl_rng_free(rng);
169 free(atm);
170
171 return EXIT_SUCCESS;
172}
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.
Definition: mptrac.c:8874
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:8503
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.
Definition: mptrac.c:5156
void geo2cart(const double z, const double lon, const double lat, double *x)
Converts geographic coordinates (longitude, latitude, altitude) to Cartesian coordinates.
Definition: mptrac.c:985
#define RE
Mean radius of Earth [km].
Definition: mptrac.h:222
#define DOTP(a, b)
Calculate the dot product of two vectors.
Definition: mptrac.h:610
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
Definition: mptrac.h:1916
#define P(z)
Compute pressure at given altitude.
Definition: mptrac.h:1304
#define DX2DEG(dx, lat)
Convert a distance in kilometers to degrees longitude at a given latitude.
Definition: mptrac.h:525
#define NORM(a)
Compute the norm (magnitude) of a vector.
Definition: mptrac.h:1247
#define ALLOC(ptr, type, n)
Allocate memory for a pointer with error handling.
Definition: mptrac.h:349
#define DEG2RAD(deg)
Converts degrees to radians.
Definition: mptrac.h:478
#define NP
Maximum number of atmospheric data points.
Definition: mptrac.h:246
#define DY2DEG(dy)
Convert a distance in kilometers to degrees latitude.
Definition: mptrac.h:543
Air parcel data.
Definition: mptrac.h:3147
double time[NP]
Time [s].
Definition: mptrac.h:3153
double lat[NP]
Latitude [deg].
Definition: mptrac.h:3162
double lon[NP]
Longitude [deg].
Definition: mptrac.h:3159
int np
Number of air parcels.
Definition: mptrac.h:3150
double q[NQ][NP]
Quantity data (for various, user-defined attributes).
Definition: mptrac.h:3165
double p[NP]
Pressure [hPa].
Definition: mptrac.h:3156
Control parameters.
Definition: mptrac.h:2170
int qnt_m
Quantity array index for mass.
Definition: mptrac.h:2201
int qnt_aoa
Quantity array index for age of air.
Definition: mptrac.h:2462
int qnt_vmr
Quantity array index for volume mixing ratio.
Definition: mptrac.h:2204
int qnt_idx
Quantity array index for air parcel IDs.
Definition: mptrac.h:2192
Here is the call graph for this function: