Skip to content

Commit fe367cb

Browse files
authored
Merge pull request #427 from pdziekan/relax_ccn_profile_and_accr_acnv_diag
Relax ccn profile and accr acnv diag
2 parents a48614c + 88d906e commit fe367cb

40 files changed

+1484
-493
lines changed

bindings/python/lgrngn.hpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,35 @@ namespace libcloudphxx
319319
}
320320
}
321321

322+
template <typename real_t>
323+
void set_rdd( // rlx_dry_distros
324+
lgr::opts_init_t<real_t> *arg,
325+
const bp::dict &kappa_func
326+
)
327+
{
328+
arg->rlx_dry_distros.clear();
329+
if(len(kappa_func.keys()) == 0)
330+
return;
331+
332+
// loop over kappas
333+
for (int i = 0; i < len(kappa_func.keys()); ++i)
334+
{
335+
std::cerr << i << std::endl;
336+
const real_t kappa = bp::extract<real_t>(kappa_func.keys()[i]);
337+
std::cerr << kappa << std::endl;
338+
const bp::list nlnrd_kparange_zrange_list = bp::extract<bp::list>(kappa_func.values()[i]);
339+
assert(len(nlnrd_kparange_zrange_list) == 3);
340+
auto nlnrd = std::make_shared<detail::pyunary<real_t>>(nlnrd_kparange_zrange_list[0]);
341+
const bp::list kparange_list = bp::extract<bp::list>(nlnrd_kparange_zrange_list[1]);
342+
std::pair<real_t, real_t> kparange{bp::extract<real_t>(kparange_list[0]), bp::extract<real_t>(kparange_list[1])};
343+
std::cerr << kparange.first << " " << kparange.second << std::endl;
344+
const bp::list zrange_list = bp::extract<bp::list>(nlnrd_kparange_zrange_list[2]);
345+
std::pair<real_t, real_t> zrange{bp::extract<real_t>(zrange_list[0]), bp::extract<real_t>(zrange_list[1])};
346+
std::cerr << zrange.first << " " << zrange.second << std::endl;
347+
arg->rlx_dry_distros[kappa] = std::make_tuple(nlnrd, kparange, zrange);
348+
}
349+
}
350+
322351
template <typename real_t>
323352
void get_ds(
324353
lgr::opts_init_t<real_t> *arg
@@ -351,6 +380,14 @@ namespace libcloudphxx
351380
throw std::runtime_error("source_dry_distros does not feature a getter yet - TODO");
352381
}
353382

383+
template <typename real_t>
384+
void get_rdd(
385+
lgr::opts_init_t<real_t> *arg
386+
)
387+
{
388+
throw std::runtime_error("relax_dry_distros does not feature a getter yet - TODO");
389+
}
390+
354391
template <typename real_t>
355392
void set_kp(
356393
lgr::opts_init_t<real_t> *arg,

bindings/python/lib.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ BOOST_PYTHON_MODULE(libcloudphxx)
243243
.def_readwrite("coal", &lgr::opts_t<real_t>::coal)
244244
.def_readwrite("src", &lgr::opts_t<real_t>::src)
245245
.def_readwrite("rcyc", &lgr::opts_t<real_t>::rcyc)
246+
.def_readwrite("rlx", &lgr::opts_t<real_t>::rlx)
246247
.def_readwrite("chem_dsl", &lgr::opts_t<real_t>::chem_dsl)
247248
.def_readwrite("chem_dsc", &lgr::opts_t<real_t>::chem_dsc)
248249
.def_readwrite("chem_rct", &lgr::opts_t<real_t>::chem_rct)
@@ -257,6 +258,7 @@ BOOST_PYTHON_MODULE(libcloudphxx)
257258
.add_property("dry_sizes", &lgrngn::get_ds<real_t>, &lgrngn::set_ds<real_t>)
258259
.add_property("src_dry_distros", &lgrngn::get_sdd<real_t>, &lgrngn::set_sdd<real_t>)
259260
.add_property("src_dry_sizes", &lgrngn::get_ds<real_t>, &lgrngn::set_sds<real_t>)
261+
.add_property("rlx_dry_distros", &lgrngn::get_rdd<real_t>, &lgrngn::set_rdd<real_t>)
260262
.def_readwrite("nx", &lgr::opts_init_t<real_t>::nx)
261263
.def_readwrite("ny", &lgr::opts_init_t<real_t>::ny)
262264
.def_readwrite("nz", &lgr::opts_init_t<real_t>::nz)
@@ -285,6 +287,7 @@ BOOST_PYTHON_MODULE(libcloudphxx)
285287
.def_readwrite("sedi_switch", &lgr::opts_init_t<real_t>::sedi_switch)
286288
.def_readwrite("subs_switch", &lgr::opts_init_t<real_t>::subs_switch)
287289
.def_readwrite("src_switch", &lgr::opts_init_t<real_t>::src_switch)
290+
.def_readwrite("rlx_switch", &lgr::opts_init_t<real_t>::rlx_switch)
288291
.def_readwrite("turb_adve_switch", &lgr::opts_init_t<real_t>::turb_adve_switch)
289292
.def_readwrite("turb_cond_switch", &lgr::opts_init_t<real_t>::turb_cond_switch)
290293
.def_readwrite("turb_coal_switch", &lgr::opts_init_t<real_t>::turb_coal_switch)
@@ -293,20 +296,25 @@ BOOST_PYTHON_MODULE(libcloudphxx)
293296
.def_readwrite("sstp_coal", &lgr::opts_init_t<real_t>::sstp_coal)
294297
.def_readwrite("sstp_chem", &lgr::opts_init_t<real_t>::sstp_chem)
295298
.def_readwrite("supstp_src", &lgr::opts_init_t<real_t>::supstp_src)
299+
.def_readwrite("supstp_rlx", &lgr::opts_init_t<real_t>::supstp_rlx)
296300
.def_readwrite("kernel", &lgr::opts_init_t<real_t>::kernel)
297301
.def_readwrite("adve_scheme", &lgr::opts_init_t<real_t>::adve_scheme)
298302
.def_readwrite("sd_conc", &lgr::opts_init_t<real_t>::sd_conc)
299303
.def_readwrite("sd_conc_large_tail", &lgr::opts_init_t<real_t>::sd_conc_large_tail)
300304
.def_readwrite("aerosol_independent_of_rhod", &lgr::opts_init_t<real_t>::aerosol_independent_of_rhod)
301305
.def_readwrite("sd_const_multi", &lgr::opts_init_t<real_t>::sd_const_multi)
302306
.def_readwrite("src_sd_conc", &lgr::opts_init_t<real_t>::src_sd_conc)
307+
.def_readwrite("rlx_bins", &lgr::opts_init_t<real_t>::rlx_bins)
308+
.def_readwrite("rlx_sd_per_bin", &lgr::opts_init_t<real_t>::rlx_sd_per_bin)
309+
.def_readwrite("rlx_timescale", &lgr::opts_init_t<real_t>::rlx_timescale)
303310
.def_readwrite("n_sd_max", &lgr::opts_init_t<real_t>::n_sd_max)
304311
.def_readwrite("terminal_velocity", &lgr::opts_init_t<real_t>::terminal_velocity)
305312
.def_readwrite("RH_formula", &lgr::opts_init_t<real_t>::RH_formula)
306313
.def_readwrite("chem_rho", &lgr::opts_init_t<real_t>::chem_rho)
307314
.def_readwrite("RH_max", &lgr::opts_init_t<real_t>::RH_max)
308315
.def_readwrite("rng_seed", &lgr::opts_init_t<real_t>::rng_seed)
309316
.def_readwrite("rng_seed_init", &lgr::opts_init_t<real_t>::rng_seed_init)
317+
.def_readwrite("rng_seed_init_switch", &lgr::opts_init_t<real_t>::rng_seed_init_switch)
310318
.def_readwrite("diag_incloud_time", &lgr::opts_init_t<real_t>::diag_incloud_time)
311319
.add_property("w_LS", &lgrngn::get_w_LS<real_t>, &lgrngn::set_w_LS<real_t>)
312320
.add_property("SGS_mix_len", &lgrngn::get_SGS_mix_len<real_t>, &lgrngn::set_SGS_mix_len<real_t>)

include/libcloudph++/blk_1m/extincl.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
#include <algorithm>
44

5-
#include <boost/numeric/odeint.hpp>
5+
#include <boost/numeric/odeint/stepper/runge_kutta4.hpp>
6+
#include <boost/numeric/odeint/algebra/vector_space_algebra.hpp>
7+
#include <boost/numeric/odeint/algebra/default_operations.hpp>
8+
#include <boost/numeric/odeint/util/resizer.hpp>
69

710
#include "../common/const_cp.hpp"
811
#include "../common/theta_dry.hpp"

include/libcloudph++/lgrngn/opts.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace libcloudphxx
1919
struct opts_t
2020
{
2121
// process toggling
22-
bool adve, sedi, subs, cond, coal, src, rcyc, turb_adve, turb_cond, turb_coal;
22+
bool adve, sedi, subs, cond, coal, src, rlx, rcyc, turb_adve, turb_cond, turb_coal;
2323

2424
// RH limit for drop growth
2525
real_t RH_max;
@@ -33,7 +33,7 @@ namespace libcloudphxx
3333

3434
// ctor with defaults (C++03 compliant) ...
3535
opts_t() :
36-
adve(true), sedi(true), subs(false), cond(true), coal(true), src(false), rcyc(false),
36+
adve(true), sedi(true), subs(false), cond(true), coal(true), src(false), rlx(false), rcyc(false),
3737
chem_dsl(false), chem_dsc(false), chem_rct(false),
3838
turb_adve(false), turb_cond(false), turb_coal(false),
3939
RH_max(44), // :) (anything greater than 1.1 would be enough

include/libcloudph++/lgrngn/opts_init.hpp

Lines changed: 61 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,6 @@ namespace libcloudphxx
4848

4949
// no. of substeps
5050
int sstp_cond, sstp_coal;
51-
52-
// timestep interval at which source will be applied
53-
int supstp_src;
5451

5552
// Lagrangian domain extents
5653
real_t x0, y0, z0, x1, y1, z1;
@@ -74,19 +71,6 @@ namespace libcloudphxx
7471
// should be enough to store particles from sources
7572
unsigned long long n_sd_max;
7673

77-
// source distro per unit time
78-
dry_distros_t src_dry_distros;
79-
80-
// number of SDs created from src_dry_distros per cell per source iteration
81-
unsigned long long src_sd_conc;
82-
83-
// dry sizes of droplets added from the source, STP_concentration created per unit time instead of the STP_concentration
84-
dry_sizes_t src_dry_sizes;
85-
86-
// box in which aerosol from source will be created
87-
// will be rounded to cell number - cells are supposed to be uniform
88-
real_t src_x0, src_y0, src_z0, src_x1, src_y1, src_z1;
89-
9074
// coalescence Kernel type
9175
kernel_t::kernel_t kernel;
9276

@@ -108,6 +92,7 @@ namespace libcloudphxx
10892
sedi_switch, // if false no sedimentation throughout the whole simulation
10993
subs_switch, // if false no subsidence throughout the whole simulation
11094
src_switch, // if false no source throughout the whole simulation
95+
rlx_switch, // if false no relaxation throughout the whole simulation
11196
turb_adve_switch, // if true, turbulent motion of SDs is modeled
11297
turb_cond_switch, // if true, turbulent condensation of SDs is modeled
11398
turb_coal_switch, // if true, turbulent coalescence kernels can be used
@@ -126,6 +111,9 @@ namespace libcloudphxx
126111
int rng_seed,
127112
rng_seed_init; // seed used to init SD (positions and dry sizes)
128113

114+
// should the separate rng seed for initialization be used?
115+
bool rng_seed_init_switch;
116+
129117
// no of GPUs per MPI node to use, 0 for all available
130118
int dev_count;
131119

@@ -146,6 +134,54 @@ namespace libcloudphxx
146134
periodic_topbot_walls; // if true, top and bot walls are periodic. Open otherwise
147135

148136

137+
// --- aerosol source stuff ---
138+
139+
// source distro per unit time
140+
dry_distros_t src_dry_distros;
141+
142+
// number of SDs created from src_dry_distros per cell per source iteration
143+
unsigned long long src_sd_conc;
144+
145+
// dry sizes of droplets added from the source, STP_concentration created per unit time instead of the STP_concentration
146+
dry_sizes_t src_dry_sizes;
147+
148+
// box in which aerosol from source will be created
149+
// will be rounded to cell number - cells are supposed to be uniform
150+
real_t src_x0, src_y0, src_z0, src_x1, src_y1, src_z1;
151+
152+
// timestep interval at which source will be applied
153+
int supstp_src;
154+
155+
156+
// --- aerosol relaxation stuff ---
157+
// initial dry sizes of aerosol
158+
// defined with a distribution
159+
// uses shared_ptr to make opts_init copyable
160+
typedef std::unordered_map<
161+
real_t, // kappa
162+
std::tuple<
163+
std::shared_ptr<unary_function<real_t>>, // n(ln(rd)) @ STP; alternatively it's n(ln(rd)) independent of rhod if aerosol_independent_of_rhod=true
164+
std::pair<real_t, real_t>, // kappa range of CCN considered to belong to this distribution, ranges of different members of the map need to be exclusive (TODO: add a check of this)
165+
std::pair<real_t, real_t> // range of altitudes at which this relaxation acts
166+
>
167+
> rlx_dry_distros_t;
168+
169+
rlx_dry_distros_t rlx_dry_distros;
170+
171+
// number of bins into which the relaxation distro is divided
172+
unsigned long long rlx_bins;
173+
174+
// number of SD created per bin
175+
real_t rlx_sd_per_bin; // floating, because it gets divided by the number of GPUs per node * number of nodes
176+
177+
// timestep interval at which relaxation will be applied
178+
int supstp_rlx;
179+
180+
// relaxation time scale [s]
181+
real_t rlx_timescale;
182+
183+
// -- ctors ---
184+
149185
// ctor with defaults (C++03 compliant) ...
150186
opts_init_t() :
151187
nx(0), ny(0), nz(0),
@@ -158,20 +194,20 @@ namespace libcloudphxx
158194
sd_const_multi(0),
159195
dt(0),
160196
sstp_cond(1), sstp_coal(1), sstp_chem(1),
161-
supstp_src(1),
162197
chem_switch(false), // chemical reactions turned off by default
163198
sedi_switch(true), // sedimentation turned on by default
164199
subs_switch(false), // subsidence turned off by default
165200
coal_switch(true), // coalescence turned on by default
166201
src_switch(false), // source turned off by default
202+
rlx_switch(false),
167203
exact_sstp_cond(false),
168204
turb_cond_switch(false),
169205
turb_adve_switch(false),
170206
turb_coal_switch(false),
171207
RH_max(.95), // value seggested in Lebo and Seinfeld 2011
172208
chem_rho(0), // dry particle density //TODO add checking if the user gave a different value (np w init) (was 1.8e-3)
173209
rng_seed(44),
174-
rng_seed_init(rng_seed),
210+
rng_seed_init(44),
175211
terminal_velocity(vt_t::undefined),
176212
kernel(kernel_t::undefined),
177213
adve_scheme(as_t::implicit),
@@ -186,12 +222,18 @@ namespace libcloudphxx
186222
src_y1(0),
187223
src_z0(0),
188224
src_z1(0),
225+
supstp_src(1),
226+
rlx_bins(0),
227+
rlx_timescale(1),
228+
rlx_sd_per_bin(0),
229+
supstp_rlx(1),
189230
rd_min(0.),
190231
diag_incloud_time(false),
191232
no_ccn_at_init(false),
192233
open_side_walls(false),
193234
periodic_topbot_walls(false),
194-
variable_dt_switch(false)
235+
variable_dt_switch(false),
236+
rng_seed_init_switch(false)
195237
{}
196238

197239
// dtor (just to silence -Winline warnings)

include/libcloudph++/lgrngn/particles.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ namespace libcloudphxx
110110
virtual void diag_vel_div() { assert(false); }
111111
virtual std::map<libcloudphxx::common::output_t, real_t> diag_puddle() { assert(false); return std::map<libcloudphxx::common::output_t, real_t>(); }
112112
virtual real_t *outbuf() { assert(false); return NULL; }
113+
virtual void diag_accr25() { assert(false); }
114+
virtual void diag_acnv25() { assert(false); }
113115

114116
// storing a pointer to opts_init (e.g. for interrogatin about
115117
// dimensions in Python bindings)
@@ -199,6 +201,8 @@ namespace libcloudphxx
199201
void diag_vel_div();
200202
std::map<libcloudphxx::common::output_t, real_t> diag_puddle();
201203
real_t *outbuf();
204+
virtual void diag_accr25();
205+
virtual void diag_acnv25();
202206

203207
struct impl;
204208
std::unique_ptr<impl> pimpl;
@@ -286,6 +290,8 @@ namespace libcloudphxx
286290
void diag_incloud_time_mom(const int&);
287291
void diag_wet_mass_dens(const real_t&, const real_t&);
288292
real_t *outbuf();
293+
virtual void diag_accr25();
294+
virtual void diag_acnv25();
289295

290296
void diag_chem(const enum common::chem::chem_species_t&);
291297
void diag_rw_ge_rc();

src/detail/config.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ namespace libcloudphxx
3030

3131
const real_t bcond_tolerance = 2e-4; // [m]; error tolerance for position near bcond after distmem copy
3232

33+
const real_t rlx_conc_tolerance = 0.1; // tolerance of the relaxation scheme; new SD will be created if missing_conc/expected_conc > tolerance
34+
3335
// ctor
3436
config():
3537
vt0_ln_r_min(log(5e-7)),

src/detail/distmem_opts.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ namespace libcloudphxx
4646

4747
opts_init.n_sd_max = opts_init.n_sd_max / size + 1;
4848

49+
opts_init.rlx_sd_per_bin /= size;
50+
4951
return n_x_bfr;
5052
}
5153
}

src/detail/urand.hpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ namespace libcloudphxx
6666
const thrust_size_t n
6767
) {
6868
// note: generate_n copies the third argument!!!
69-
std::generate_n(u01.begin(), n, fnctr_u01({engine, dist_u01}));
69+
std::generate_n(u01.begin(), n, fnctr_u01({engine, dist_u01})); // [0,1) range
7070
}
7171

7272
void generate_normal_n(
@@ -131,20 +131,25 @@ namespace libcloudphxx
131131
const thrust_size_t n
132132
)
133133
{
134-
int status = curandGenerateUniform(gen, thrust::raw_pointer_cast(v.data()), n);
134+
int status = curandGenerateUniform(gen, thrust::raw_pointer_cast(v.data()), n); // (0,1] range
135135
assert(status == CURAND_STATUS_SUCCESS /* && "curandGenerateUniform failed"*/);
136136
_unused(status);
137-
137+
// shift into the expected [0,1) range
138+
namespace arg = thrust::placeholders;
139+
thrust::transform(v.begin(), v.begin() + n, v.begin(), float(1) - arg::_1);
138140
}
139141

140142
void generate_n(
141143
thrust_device::vector<double> &v,
142144
const thrust_size_t n
143145
)
144146
{
145-
int status = curandGenerateUniformDouble(gen, thrust::raw_pointer_cast(v.data()), n);
147+
int status = curandGenerateUniformDouble(gen, thrust::raw_pointer_cast(v.data()), n); // (0,1] range
146148
assert(status == CURAND_STATUS_SUCCESS /* && "curandGenerateUniform failed"*/);
147149
_unused(status);
150+
// shift into the expected [0,1) range
151+
namespace arg = thrust::placeholders;
152+
thrust::transform(v.begin(), v.begin() + n, v.begin(), double(1) - arg::_1);
148153
}
149154

150155
void generate_normal_n(

0 commit comments

Comments
 (0)