Skip to content

Commit 30d768f

Browse files
jcurtis2slayoo
andauthored
Add more functionality for AeroState (sample/add[particles], make_dry, mobility_diameters, ids) (#341)
Co-authored-by: Sylwester Arabas <[email protected]>
1 parent 8630eb9 commit 30d768f

File tree

4 files changed

+390
-37
lines changed

4 files changed

+390
-37
lines changed

src/aero_state.F90

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,24 @@ subroutine f_aero_state_dry_diameters(ptr_c, aero_data_ptr_c, diameters, n_parts
194194

195195
end subroutine
196196

197+
subroutine f_aero_state_mobility_diameters(ptr_c, aero_data_ptr_c, &
198+
env_state_ptr_c, diameters, n_parts) bind (C)
199+
type(c_ptr), intent(in) :: ptr_c, aero_data_ptr_c, env_state_ptr_c
200+
integer(c_int), intent(in) :: n_parts
201+
real(c_double), intent(out) :: diameters(n_parts)
202+
type(aero_state_t), pointer :: ptr_f => null()
203+
type(aero_data_t), pointer :: aero_data_ptr_f => null()
204+
type(env_state_t) , pointer :: env_state_ptr_f => null()
205+
206+
call c_f_pointer(ptr_c, ptr_f)
207+
call c_f_pointer(aero_data_ptr_c, aero_data_ptr_f)
208+
call c_f_pointer(env_state_ptr_c, env_state_ptr_f)
209+
210+
diameters = aero_state_mobility_diameters(ptr_f, aero_data_ptr_f, &
211+
env_state_ptr_f)
212+
213+
end subroutine
214+
197215
subroutine f_aero_state_diameters(ptr_c, aero_data_ptr_c, diameters, &
198216
n_parts, include_len, exclude_len, include, exclude) bind(C)
199217

@@ -534,4 +552,91 @@ subroutine f_aero_state_zero(ptr_c) bind(C)
534552

535553
end subroutine
536554

555+
subroutine f_aero_state_ids(ptr_c, ids, n_parts) bind(C)
556+
type(c_ptr), intent(in) :: ptr_c
557+
integer(c_int), intent(in) :: n_parts
558+
integer(c_int), intent(out) :: ids(n_parts)
559+
type(aero_state_t), pointer :: ptr_f => null()
560+
561+
call c_f_pointer(ptr_c, ptr_f)
562+
563+
ids = aero_state_ids(ptr_f)
564+
565+
end subroutine
566+
567+
subroutine f_aero_state_make_dry(ptr_c, aero_data_ptr_c) bind(C)
568+
type(c_ptr), intent(in) :: ptr_c, aero_data_ptr_c
569+
type(aero_state_t), pointer :: ptr_f => null()
570+
type(aero_data_t), pointer :: aero_data_ptr_f => null()
571+
572+
call c_f_pointer(ptr_c, ptr_f)
573+
call c_f_pointer(aero_data_ptr_c, aero_data_ptr_f)
574+
575+
call aero_state_make_dry(ptr_f, aero_data_ptr_f)
576+
577+
end subroutine
578+
579+
subroutine f_aero_state_add(ptr_c, delta_ptr_c, aero_data_ptr_c) bind(C)
580+
type(c_ptr), intent(in) :: ptr_c, delta_ptr_c, aero_data_ptr_c
581+
type(aero_state_t), pointer :: ptr_f => null()
582+
type(aero_state_t), pointer :: delta_ptr_f => null()
583+
type(aero_data_t), pointer :: aero_data_ptr_f => null()
584+
585+
call c_f_pointer(ptr_c, ptr_f)
586+
call c_f_pointer(delta_ptr_c, delta_ptr_f)
587+
call c_f_pointer(aero_data_ptr_c, aero_data_ptr_f)
588+
589+
call aero_state_add(ptr_f, delta_ptr_f, aero_data_ptr_f)
590+
591+
end subroutine
592+
593+
subroutine f_aero_state_add_particles(ptr_c, delta_ptr_c, aero_data_ptr_c &
594+
) bind(C)
595+
type(c_ptr), intent(in) :: ptr_c, delta_ptr_c, aero_data_ptr_c
596+
type(aero_state_t), pointer :: ptr_f => null()
597+
type(aero_state_t), pointer :: delta_ptr_f => null()
598+
type(aero_data_t), pointer :: aero_data_ptr_f => null()
599+
600+
call c_f_pointer(ptr_c, ptr_f)
601+
call c_f_pointer(delta_ptr_c, delta_ptr_f)
602+
call c_f_pointer(aero_data_ptr_c, aero_data_ptr_f)
603+
604+
call aero_state_add_particles(ptr_f, delta_ptr_f, aero_data_ptr_f)
605+
606+
end subroutine
607+
608+
subroutine f_aero_state_sample(ptr_c, aero_state_to_ptr_c, aero_data_ptr_c, &
609+
sample_prob) bind(C)
610+
type(c_ptr), intent(in) :: ptr_c, aero_state_to_ptr_c, aero_data_ptr_c
611+
real(c_double), intent(in) :: sample_prob
612+
type(aero_state_t), pointer :: ptr_f => null()
613+
type(aero_state_t), pointer :: aero_state_to_ptr_f => null()
614+
type(aero_data_t), pointer :: aero_data_ptr_f => null()
615+
616+
call c_f_pointer(ptr_c, ptr_f)
617+
call c_f_pointer(aero_state_to_ptr_c, aero_state_to_ptr_f)
618+
call c_f_pointer(aero_data_ptr_c, aero_data_ptr_f)
619+
620+
call aero_state_sample(ptr_f, aero_state_to_ptr_f, aero_data_ptr_f, &
621+
sample_prob, AERO_INFO_NONE)
622+
623+
end subroutine
624+
625+
subroutine f_aero_state_sample_particles(ptr_c, aero_state_to_ptr_c, &
626+
aero_data_ptr_c, sample_prob) bind(C)
627+
type(c_ptr), intent(in) :: ptr_c, aero_state_to_ptr_c, aero_data_ptr_c
628+
real(c_double), intent(in) :: sample_prob
629+
type(aero_state_t), pointer :: ptr_f => null()
630+
type(aero_state_t), pointer :: aero_state_to_ptr_f => null()
631+
type(aero_data_t), pointer :: aero_data_ptr_f => null()
632+
633+
call c_f_pointer(ptr_c, ptr_f)
634+
call c_f_pointer(aero_state_to_ptr_c, aero_state_to_ptr_f)
635+
call c_f_pointer(aero_data_ptr_c, aero_data_ptr_f)
636+
637+
call aero_state_sample_particles(ptr_f, aero_state_to_ptr_f, &
638+
aero_data_ptr_f, sample_prob, AERO_INFO_NONE)
639+
640+
end subroutine
641+
537642
end module

src/aero_state.hpp

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ extern "C" void f_aero_state_dry_diameters(
7171
const int *n_parts
7272
) noexcept;
7373

74+
extern "C" void f_aero_state_mobility_diameters(
75+
const void *ptr,
76+
const void *aero_dataptr,
77+
const void *env_stateptr,
78+
double *mobility_diameters,
79+
const int *n_parts
80+
) noexcept;
81+
7482
extern "C" void f_aero_state_diameters(
7583
const void *ptr,
7684
const void *aero_dataptr,
@@ -101,6 +109,11 @@ extern "C" void f_aero_state_crit_rel_humids(
101109
const int *n_parts
102110
) noexcept;
103111

112+
extern "C" void f_aero_state_make_dry(
113+
void *ptr,
114+
const void *aero_dataptr
115+
) noexcept;
116+
104117
extern "C" void f_aero_state_mixing_state_metrics(
105118
const void *aero_state,
106119
const void *aero_data,
@@ -163,6 +176,38 @@ extern "C" void f_aero_state_zero(
163176
void *ptr_c
164177
) noexcept;
165178

179+
extern "C" void f_aero_state_ids(
180+
const void *ptr_c,
181+
int *ids,
182+
const int *n_parts
183+
) noexcept;
184+
185+
extern "C" void f_aero_state_add(
186+
void *ptr_c,
187+
const void *delta_ptr_c,
188+
const void *aero_data_ptr
189+
) noexcept;
190+
191+
extern "C" void f_aero_state_add_particles(
192+
void *ptr_c,
193+
const void *delta_ptr_c,
194+
const void *aero_data_ptr
195+
) noexcept;
196+
197+
extern "C" void f_aero_state_sample(
198+
void *ptr_c,
199+
void *aero_state_to_ptr_c,
200+
const void *aero_data_ptr,
201+
const double *sample_prob
202+
) noexcept;
203+
204+
extern "C" void f_aero_state_sample_particles(
205+
void *ptr_c,
206+
void *aero_state_to_ptr_c,
207+
const void *aero_data_ptr,
208+
const double *sample_prob
209+
) noexcept;
210+
166211
template <typename arr_t, typename arg_t>
167212
auto pointer_vec_magic(arr_t &data_vec, const arg_t &arg) {
168213
std::vector<char*> pointer_vec(data_vec.size());
@@ -313,6 +358,25 @@ struct AeroState {
313358
return dry_diameters;
314359
}
315360

361+
static auto mobility_diameters(const AeroState &self, const EnvState &env_state) {
362+
int len;
363+
f_aero_state_len(
364+
self.ptr.f_arg(),
365+
&len
366+
);
367+
std::valarray<double> mobility_diameters(len);
368+
369+
f_aero_state_mobility_diameters(
370+
self.ptr.f_arg(),
371+
self.aero_data->ptr.f_arg(),
372+
env_state.ptr.f_arg(),
373+
begin(mobility_diameters),
374+
&len
375+
);
376+
377+
return mobility_diameters;
378+
}
379+
316380
static auto diameters(
317381
const AeroState &self,
318382
const tl::optional<std::valarray<std::string>> &include,
@@ -401,6 +465,32 @@ struct AeroState {
401465
return crit_rel_humids;
402466
}
403467

468+
static void make_dry(
469+
AeroState &self
470+
) {
471+
f_aero_state_make_dry(
472+
self.ptr.f_arg_non_const(),
473+
self.aero_data->ptr.f_arg()
474+
);
475+
}
476+
477+
static auto ids(const AeroState &self) {
478+
int len;
479+
f_aero_state_len(
480+
self.ptr.f_arg(),
481+
&len
482+
);
483+
std::valarray<int> ids(len);
484+
485+
f_aero_state_ids(
486+
self.ptr.f_arg(),
487+
begin(ids),
488+
&len
489+
);
490+
491+
return ids;
492+
}
493+
404494
static auto mixing_state(
405495
const AeroState &self,
406496
const tl::optional<std::valarray<std::string>> &include,
@@ -538,4 +628,48 @@ struct AeroState {
538628
) {
539629
f_aero_state_zero(self.ptr.f_arg_non_const());
540630
}
631+
632+
static void add(
633+
AeroState &self,
634+
const AeroState &delta
635+
) {
636+
f_aero_state_add(self.ptr.f_arg_non_const(),
637+
delta.ptr.f_arg(),
638+
self.aero_data->ptr.f_arg()
639+
);
640+
}
641+
642+
static void add_particles(
643+
AeroState &self,
644+
const AeroState &delta
645+
) {
646+
f_aero_state_add_particles(self.ptr.f_arg_non_const(),
647+
delta.ptr.f_arg(),
648+
self.aero_data->ptr.f_arg()
649+
);
650+
}
651+
652+
static void sample(
653+
AeroState &self,
654+
AeroState &aero_state_sample,
655+
const double sample_prob
656+
) {
657+
f_aero_state_sample(self.ptr.f_arg_non_const(),
658+
aero_state_sample.ptr.f_arg_non_const(),
659+
self.aero_data->ptr.f_arg(),
660+
&sample_prob
661+
);
662+
}
663+
664+
static void sample_particles(
665+
AeroState &self,
666+
AeroState &aero_state_sample,
667+
const double sample_prob
668+
) {
669+
f_aero_state_sample_particles(self.ptr.f_arg_non_const(),
670+
aero_state_sample.ptr.f_arg_non_const(),
671+
self.aero_data->ptr.f_arg(),
672+
&sample_prob
673+
);
674+
}
541675
};

src/pypartmc.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,17 @@ PYBIND11_MODULE(_PyPartMC, m) {
223223
py::arg("include") = py::none(), py::arg("exclude") = py::none())
224224
.def_property_readonly("dry_diameters", AeroState::dry_diameters,
225225
"returns the dry diameter of each particle in the population")
226+
.def("mobility_diameters", AeroState::mobility_diameters,
227+
"returns the mobility diameter of each particle in the population")
226228
.def("diameters", AeroState::diameters,
227229
"returns the diameter of each particle in the population",
228230
py::arg("include") = py::none(), py::arg("exclude") = py::none())
229231
.def("crit_rel_humids", AeroState::crit_rel_humids,
230232
"returns the critical relative humidity of each particle in the population")
233+
.def("make_dry", AeroState::make_dry,
234+
"Make all particles dry (water set to zero).")
235+
.def_property_readonly("ids", AeroState::ids,
236+
"returns the IDs of all particles.")
231237
.def("mixing_state", AeroState::mixing_state,
232238
"returns the mixing state parameters (d_alpha, d_gamma, chi) of the population",
233239
py::arg("include") = py::none(), py::arg("exclude") = py::none(),
@@ -243,6 +249,24 @@ PYBIND11_MODULE(_PyPartMC, m) {
243249
py::arg("AeroDist"), py::arg("sample_prop") = 1.0, py::arg("create_time") = 0.0,
244250
py::arg("allow_doubling") = true, py::arg("allow_halving") = true)
245251
.def("add_particle", AeroState::add_particle, "add a particle to an AeroState")
252+
.def("add", AeroState::add,
253+
R"pbdoc(aero_state += aero_state_delta, including combining the
254+
weights, so the new concentration is the weighted average of the
255+
two concentrations.)pbdoc")
256+
.def("add_particles", AeroState::add_particles,
257+
R"pbdoc(aero_state += aero_state_delta, with the weight left unchanged
258+
so the new concentration is the sum of the two concentrations.)pbdoc")
259+
.def("sample", AeroState::sample,
260+
R"pbdoc(Generates a random sample by removing particles from
261+
aero_state_from and adding them to aero_state_to, transfering
262+
weight as well. This is the equivalent of aero_state_add().)pbdoc")
263+
.def("sample_particles", AeroState::sample_particles,
264+
R"pbdoc( !> Generates a random sample by removing particles from
265+
aero_state_from and adding them to aero_state_to, which must be
266+
already allocated (and should have its weight set).
267+
268+
None of the weights are altered by this sampling, making this the
269+
equivalent of aero_state_add_particles().)pbdoc")
246270
.def("copy_weight", AeroState::copy_weight,
247271
"copy weighting from another AeroState")
248272
.def("remove_particle", AeroState::remove_particle,

0 commit comments

Comments
 (0)