Skip to content

Commit fa6007f

Browse files
zdaq12slayoo
andauthored
Aero particle additions (#212)
Co-authored-by: Sylwester Arabas <[email protected]>
1 parent 3e6794e commit fa6007f

File tree

4 files changed

+523
-4
lines changed

4 files changed

+523
-4
lines changed

src/aero_particle.F90

Lines changed: 195 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ subroutine f_aero_particle_init(ptr_c, aero_data_ptr_c, arr_data, arr_size) bind
3636
real(c_double), dimension(arr_size), intent(in) :: arr_data
3737
call c_f_pointer(ptr_c, ptr_f)
3838
call c_f_pointer(aero_data_ptr_c, aero_data_ptr_f)
39-
allocate(ptr_f%vol(arr_size))
39+
call aero_particle_zero(ptr_f, aero_data_ptr_f)
4040
call aero_particle_set_vols(ptr_f, arr_data)
4141
end subroutine
4242

@@ -193,4 +193,198 @@ subroutine f_aero_particle_solute_kappa(aero_particle_ptr_c, aero_data_ptr_c, ka
193193
kappa = aero_particle_solute_kappa(aero_particle_ptr_f, aero_data_ptr_f)
194194
end subroutine
195195

196+
subroutine f_aero_particle_moles(aero_particle_ptr_c, aero_data_ptr_c, moles) bind(C)
197+
type(aero_particle_t), pointer :: aero_particle_ptr_f => null()
198+
type(aero_data_t), pointer :: aero_data_ptr_f => null()
199+
type(c_ptr), intent(in) :: aero_particle_ptr_c, aero_data_ptr_c
200+
real(c_double), intent(out) :: moles
201+
202+
call c_f_pointer(aero_particle_ptr_c, aero_particle_ptr_f)
203+
call c_f_pointer(aero_data_ptr_c, aero_data_ptr_f)
204+
205+
moles = aero_particle_moles(aero_particle_ptr_f, aero_data_ptr_f)
206+
end subroutine
207+
208+
subroutine f_aero_particle_mobility_diameter( &
209+
aero_particle_ptr_c, &
210+
aero_data_ptr_c, &
211+
env_state_ptr_c, &
212+
mobility_diameter &
213+
) bind(C)
214+
215+
type(aero_particle_t), pointer :: aero_particle_ptr_f => null()
216+
type(aero_data_t), pointer :: aero_data_ptr_f => null()
217+
type(env_state_t), pointer :: env_state_ptr_f => null()
218+
type(c_ptr), intent(in) :: aero_particle_ptr_c, aero_data_ptr_c, &
219+
env_state_ptr_c
220+
real(c_double), intent(out) :: mobility_diameter
221+
222+
call c_f_pointer(aero_particle_ptr_c, aero_particle_ptr_f)
223+
call c_f_pointer(aero_data_ptr_c, aero_data_ptr_f)
224+
call c_f_pointer(env_state_ptr_c, env_state_ptr_f)
225+
226+
mobility_diameter = aero_particle_mobility_diameter( &
227+
aero_particle_ptr_f, &
228+
aero_data_ptr_f, &
229+
env_state_ptr_f &
230+
)
231+
end subroutine
232+
233+
subroutine f_aero_particle_density( &
234+
aero_particle_ptr_c, &
235+
aero_data_ptr_c, &
236+
density &
237+
) bind(C)
238+
239+
type(aero_particle_t), pointer :: aero_particle_ptr_f => null()
240+
type(aero_data_t), pointer :: aero_data_ptr_f => null()
241+
type(c_ptr), intent(in) :: aero_particle_ptr_c, aero_data_ptr_c
242+
real(c_double), intent(out) :: density
243+
244+
call c_f_pointer(aero_particle_ptr_c, aero_particle_ptr_f)
245+
call c_f_pointer(aero_data_ptr_c, aero_data_ptr_f)
246+
247+
density = aero_particle_density( &
248+
aero_particle_ptr_f, &
249+
aero_data_ptr_f &
250+
)
251+
end subroutine
252+
253+
subroutine f_aero_particle_approx_crit_rel_humid( &
254+
aero_particle_ptr_c, &
255+
aero_data_ptr_c, &
256+
env_state_ptr_c, &
257+
approx_crit_rel_humid &
258+
) bind(C)
259+
260+
type(aero_particle_t), pointer :: aero_particle_ptr_f => null()
261+
type(aero_data_t), pointer :: aero_data_ptr_f => null()
262+
type(env_state_t), pointer :: env_state_ptr_f => null()
263+
type(c_ptr), intent(in) :: aero_particle_ptr_c, aero_data_ptr_c, &
264+
env_state_ptr_c
265+
real(c_double), intent(out) :: approx_crit_rel_humid
266+
267+
call c_f_pointer(aero_particle_ptr_c, aero_particle_ptr_f)
268+
call c_f_pointer(aero_data_ptr_c, aero_data_ptr_f)
269+
call c_f_pointer(env_state_ptr_c, env_state_ptr_f)
270+
271+
approx_crit_rel_humid = aero_particle_approx_crit_rel_humid( &
272+
aero_particle_ptr_f, &
273+
aero_data_ptr_f, &
274+
env_state_ptr_f &
275+
)
276+
end subroutine
277+
278+
subroutine f_aero_particle_crit_rel_humid( &
279+
aero_particle_ptr_c, &
280+
aero_data_ptr_c, &
281+
env_state_ptr_c, &
282+
crit_rel_humid &
283+
) bind(C)
284+
285+
type(aero_particle_t), pointer :: aero_particle_ptr_f => null()
286+
type(aero_data_t), pointer :: aero_data_ptr_f => null()
287+
type(env_state_t), pointer :: env_state_ptr_f => null()
288+
type(c_ptr), intent(in) :: aero_particle_ptr_c, aero_data_ptr_c, &
289+
env_state_ptr_c
290+
real(c_double), intent(out) :: crit_rel_humid
291+
292+
call c_f_pointer(aero_particle_ptr_c, aero_particle_ptr_f)
293+
call c_f_pointer(aero_data_ptr_c, aero_data_ptr_f)
294+
call c_f_pointer(env_state_ptr_c, env_state_ptr_f)
295+
296+
crit_rel_humid = aero_particle_crit_rel_humid( &
297+
aero_particle_ptr_f, &
298+
aero_data_ptr_f, &
299+
env_state_ptr_f &
300+
)
301+
end subroutine
302+
303+
subroutine f_aero_particle_crit_diameter( &
304+
aero_particle_ptr_c, &
305+
aero_data_ptr_c, &
306+
env_state_ptr_c, &
307+
crit_diameter &
308+
) bind(C)
309+
310+
type(aero_particle_t), pointer :: aero_particle_ptr_f => null()
311+
type(aero_data_t), pointer :: aero_data_ptr_f => null()
312+
type(env_state_t), pointer :: env_state_ptr_f => null()
313+
type(c_ptr), intent(in) :: aero_particle_ptr_c, aero_data_ptr_c, &
314+
env_state_ptr_c
315+
real(c_double), intent(out) :: crit_diameter
316+
317+
call c_f_pointer(aero_particle_ptr_c, aero_particle_ptr_f)
318+
call c_f_pointer(aero_data_ptr_c, aero_data_ptr_f)
319+
call c_f_pointer(env_state_ptr_c, env_state_ptr_f)
320+
321+
crit_diameter = aero_particle_crit_diameter( &
322+
aero_particle_ptr_f, &
323+
aero_data_ptr_f, &
324+
env_state_ptr_f &
325+
)
326+
end subroutine
327+
328+
subroutine f_aero_particle_coagulate( &
329+
aero_particle_1_ptr_c, &
330+
aero_particle_2_ptr_c, &
331+
aero_particle_new_ptr_c &
332+
) bind(C)
333+
334+
type(aero_particle_t), pointer :: aero_particle_1_ptr_f => null()
335+
type(aero_particle_t), pointer :: aero_particle_2_ptr_f => null()
336+
type(aero_particle_t), pointer :: aero_particle_new_ptr_f => null()
337+
type(c_ptr), intent(in) :: aero_particle_1_ptr_c, aero_particle_2_ptr_c
338+
type(c_ptr), intent(inout) :: aero_particle_new_ptr_c
339+
340+
call c_f_pointer(aero_particle_1_ptr_c, aero_particle_1_ptr_f)
341+
call c_f_pointer(aero_particle_2_ptr_c, aero_particle_2_ptr_f)
342+
call c_f_pointer(aero_particle_new_ptr_c, aero_particle_new_ptr_f)
343+
344+
call aero_particle_coagulate( &
345+
aero_particle_1_ptr_f, &
346+
aero_particle_2_ptr_f, &
347+
aero_particle_new_ptr_f &
348+
)
349+
350+
aero_particle_new_ptr_c = c_loc(aero_particle_new_ptr_f)
351+
end subroutine
352+
353+
subroutine f_aero_particle_zero( &
354+
aero_particle_ptr_c, &
355+
aero_data_ptr_c &
356+
) bind(C)
357+
358+
type(aero_particle_t), pointer :: aero_particle_ptr_f => null()
359+
type(aero_data_t), pointer :: aero_data_ptr_f => null()
360+
type(c_ptr), intent(in) :: aero_particle_ptr_c, aero_data_ptr_c
361+
362+
call c_f_pointer(aero_particle_ptr_c, aero_particle_ptr_f)
363+
call c_f_pointer(aero_data_ptr_c, aero_data_ptr_f)
364+
365+
call aero_particle_zero( &
366+
aero_particle_ptr_f, &
367+
aero_data_ptr_f &
368+
)
369+
end subroutine
370+
371+
subroutine f_aero_particle_set_vols( &
372+
aero_particle_ptr_c, &
373+
vol_size, &
374+
volumes &
375+
) bind(C)
376+
377+
type(aero_particle_t), pointer :: aero_particle_ptr_f => null()
378+
type(c_ptr), intent(in) :: aero_particle_ptr_c
379+
integer(c_int), intent(in) :: vol_size
380+
real(c_double), dimension(vol_size), intent(in) :: volumes
381+
382+
call c_f_pointer(aero_particle_ptr_c, aero_particle_ptr_f)
383+
384+
call aero_particle_set_vols( &
385+
aero_particle_ptr_f, &
386+
volumes &
387+
)
388+
end subroutine
389+
196390
end module

src/aero_particle.hpp

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "pmc_resource.hpp"
1010
#include "aero_data.hpp"
11+
#include "env_state.hpp"
1112
#include "pybind11/stl.h"
1213

1314
extern "C" void f_aero_particle_ctor(void *ptr) noexcept;
@@ -25,7 +26,15 @@ extern "C" void f_aero_particle_mass(const void *aero_particle_ptr, const void *
2526
extern "C" void f_aero_particle_species_mass(const void *aero_particle_ptr, const int *i_spec, const void *aero_data_ptr, double *mass) noexcept;
2627
extern "C" void f_aero_particle_species_masses(const void *aero_particle_ptr, const void *aero_data_ptr, const int *size_masses, void *masses) noexcept;
2728
extern "C" void f_aero_particle_solute_kappa(const void *aero_particle_ptr, const void *aero_data_ptr, void *kappa) noexcept;
28-
29+
extern "C" void f_aero_particle_moles(const void *aero_particle_ptr, const void *aero_data_ptr, void *moles) noexcept;
30+
extern "C" void f_aero_particle_mobility_diameter(const void *aero_particle_ptr, const void *aero_data_ptr, const void *env_state_ptr, void *mobility_diameter) noexcept;
31+
extern "C" void f_aero_particle_density(const void *aero_particle_ptr, const void *aero_data_ptr, void *density) noexcept;
32+
extern "C" void f_aero_particle_approx_crit_rel_humid(const void *aero_particle_ptr, const void *aero_data_ptr, const void *env_state_ptr, void *approx_crit_rel_humid) noexcept;
33+
extern "C" void f_aero_particle_crit_rel_humid(const void *aero_particle_ptr, const void *aero_data_ptr, const void *env_state_ptr, void *crit_rel_humid) noexcept;
34+
extern "C" void f_aero_particle_crit_diameter(const void *aero_particle_ptr, const void *aero_data_ptr, const void *env_state, void *crit_diameter) noexcept;
35+
extern "C" void f_aero_particle_coagulate(const void *aero_particle_1_ptr, const void *aero_particle_2_ptr, void *new_particle_ptr) noexcept;
36+
extern "C" void f_aero_particle_zero(void *aero_particle_ptr, const void *aero_data_ptr) noexcept;
37+
extern "C" void f_aero_particle_set_vols(void *aero_particle_ptr, const int *vol_size, const void *volumes) noexcept;
2938

3039
namespace py = pybind11;
3140
struct AeroParticle {
@@ -169,5 +178,98 @@ struct AeroParticle {
169178
return kappa;
170179
}
171180

172-
};
181+
static auto moles(const AeroParticle &self) {
182+
double moles;
183+
f_aero_particle_moles(
184+
self.ptr.f_arg(),
185+
self.aero_data.get(),
186+
&moles
187+
);
188+
return moles;
189+
}
190+
191+
static auto mobility_diameter(const AeroParticle &self, const EnvState &env_state) {
192+
double mobility_diameter;
193+
f_aero_particle_mobility_diameter(
194+
self.ptr.f_arg(),
195+
self.aero_data.get(),
196+
env_state.ptr.f_arg(),
197+
&mobility_diameter
198+
);
199+
return mobility_diameter;
200+
}
201+
202+
static auto density(const AeroParticle &self) {
203+
double density;
204+
f_aero_particle_density(
205+
self.ptr.f_arg(),
206+
self.aero_data.get(),
207+
&density
208+
);
209+
return density;
210+
}
211+
212+
static auto approx_crit_rel_humid(const AeroParticle &self, const EnvState &env_state) {
213+
double approx_crit_rel_humid;
214+
f_aero_particle_approx_crit_rel_humid(
215+
self.ptr.f_arg(),
216+
self.aero_data.get(),
217+
env_state.ptr.f_arg(),
218+
&approx_crit_rel_humid
219+
);
220+
return approx_crit_rel_humid;
221+
}
222+
223+
static auto crit_rel_humid(const AeroParticle &self, const EnvState &env_state) {
224+
double crit_rel_humid;
225+
f_aero_particle_crit_rel_humid(
226+
self.ptr.f_arg(),
227+
self.aero_data.get(),
228+
env_state.ptr.f_arg(),
229+
&crit_rel_humid
230+
);
231+
return crit_rel_humid;
232+
}
233+
234+
static auto crit_diameter(const AeroParticle &self, const EnvState &env_state) {
235+
double crit_diameter;
236+
f_aero_particle_crit_diameter(
237+
self.ptr.f_arg(),
238+
self.aero_data.get(),
239+
env_state.ptr.f_arg(),
240+
&crit_diameter
241+
);
242+
return crit_diameter;
243+
}
244+
245+
static auto coagulate(const AeroParticle &self, const AeroParticle &two) {
246+
int len = AeroData::__len__(*self.aero_data);
247+
std::valarray<double> data(len);
248+
AeroParticle* new_ptr = new AeroParticle(self.aero_data, data);
249+
f_aero_particle_coagulate(
250+
self.ptr.f_arg(),
251+
two.ptr.f_arg(),
252+
new_ptr
253+
);
254+
return new_ptr;
255+
}
256+
257+
static void zero(AeroParticle &self) {
258+
f_aero_particle_zero(
259+
self.ptr.f_arg_non_const(),
260+
self.aero_data.get()
261+
);
262+
}
263+
264+
static void set_vols(AeroParticle &self, const std::valarray<double>&volumes) {
265+
int len = AeroData::__len__(*self.aero_data.get());
266+
if (volumes.size() != size_t(len))
267+
throw std::runtime_error("AeroData size mistmatch");
268+
f_aero_particle_set_vols(
269+
self.ptr.f_arg_non_const(),
270+
&len,
271+
begin(volumes)
272+
);
273+
}
173274

275+
};

src/pypartmc.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,24 @@ PYBIND11_MODULE(_PyPartMC, m) {
124124
"Mass of all species in the particle (kg).")
125125
.def_property_readonly("solute_kappa", AeroParticle::solute_kappa,
126126
"Returns the average of the solute kappas (1).")
127+
.def_property_readonly("moles", AeroParticle::moles,
128+
"Total moles in the particle (1).")
129+
.def("mobility_diameter", AeroParticle::mobility_diameter,
130+
"Mobility diameter of the particle (m).")
131+
.def_property_readonly("density", AeroParticle::density,
132+
"Average density of the particle (kg/m^3)")
133+
.def("approx_crit_rel_humid", AeroParticle::approx_crit_rel_humid,
134+
"Returns the approximate critical relative humidity (1).")
135+
.def("crit_rel_humid", AeroParticle::crit_rel_humid,
136+
"Returns the critical relative humidity (1).")
137+
.def("crit_diameter", AeroParticle::crit_diameter,
138+
"Returns the critical diameter (m).")
139+
.def("coagulate", AeroParticle::coagulate,
140+
"Coagulate two particles together to make a new one. The new particle will not have its ID set.")
141+
.def("zero", AeroParticle::zero,
142+
"Resets an aero_particle to be zero.")
143+
.def("set_vols", AeroParticle::set_vols,
144+
"Sets the aerosol particle volumes.")
127145
;
128146

129147
py::class_<AeroState>(m, "AeroState",

0 commit comments

Comments
 (0)