Skip to content

Commit 1b09467

Browse files
slayoojcurtis2
andauthored
multi-mode AeroDist initialsation (also in Scenario) + AeroDist::n_mode & AeroDist::mode(idx) (#193)
Co-authored-by: Jeff Curtis <[email protected]>
1 parent d0d1121 commit 1b09467

File tree

10 files changed

+263
-61
lines changed

10 files changed

+263
-61
lines changed

src/aero_dist.F90

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,36 @@ subroutine f_aero_dist_from_json(ptr_c, aero_data_ptr_c) bind(C)
4040

4141
call spec_file_read_aero_dist(file, aero_data_ptr_f, aero_dist)
4242
end subroutine
43+
44+
subroutine f_aero_dist_n_mode(ptr_c, n_mode) bind(C)
45+
type(aero_dist_t), pointer :: aero_dist => null()
46+
type(c_ptr), intent(in) :: ptr_c
47+
integer(c_int), intent(out) :: n_mode
48+
49+
call c_f_pointer(ptr_c, aero_dist)
50+
n_mode = aero_dist_n_mode(aero_dist)
51+
end subroutine
52+
53+
subroutine f_aero_dist_total_num_conc(ptr_c, total_num_conc) bind(C)
54+
type(aero_dist_t), pointer :: aero_dist => null()
55+
type(c_ptr), intent(in) :: ptr_c
56+
real(c_double), intent(out) :: total_num_conc
57+
58+
call c_f_pointer(ptr_c, aero_dist)
59+
total_num_conc = aero_dist_total_num_conc(aero_dist)
60+
end subroutine
61+
62+
subroutine f_aero_dist_mode(ptr_c, aero_mode_ptr_c, index) bind(C)
63+
type(c_ptr) :: ptr_c, aero_mode_ptr_c
64+
type(aero_dist_t), pointer :: aero_dist
65+
type(aero_mode_t), pointer :: aero_mode
66+
integer(c_int), intent(in) :: index
67+
68+
call c_f_pointer(ptr_c, aero_dist)
69+
call c_f_pointer(aero_mode_ptr_c, aero_mode)
70+
71+
aero_mode = aero_dist%mode(index + 1)
72+
73+
end subroutine
74+
4375
end module

src/aero_dist.hpp

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#pragma once
88

99
#include "pmc_resource.hpp"
10+
#include "aero_mode.hpp"
1011

1112
extern "C" void f_aero_dist_ctor(
1213
void *ptr
@@ -16,19 +17,62 @@ extern "C" void f_aero_dist_dtor(
1617
void *ptr
1718
) noexcept;
1819

20+
extern "C" void f_aero_dist_n_mode(
21+
const void *ptr,
22+
int *n_mode
23+
) noexcept;
24+
1925
extern "C" void f_aero_dist_from_json(
2026
void *ptr,
2127
void *aero_data_ptr
2228
) noexcept;
2329

30+
extern "C" void f_aero_dist_total_num_conc(
31+
const void *ptr,
32+
double *total_num_conc
33+
) noexcept;
34+
35+
extern "C" void f_aero_dist_mode(
36+
const void *ptr,
37+
void *ptr_c,
38+
const int *index
39+
) noexcept;
40+
2441
struct AeroDist {
2542
PMCResource ptr;
43+
std::shared_ptr<AeroData> aero_data;
2644

27-
AeroDist(AeroData &aero_data, const nlohmann::json &json):
28-
ptr(f_aero_dist_ctor, f_aero_dist_dtor)
45+
AeroDist(
46+
std::shared_ptr<AeroData> aero_data,
47+
const nlohmann::json &json
48+
):
49+
ptr(f_aero_dist_ctor, f_aero_dist_dtor),
50+
aero_data(aero_data)
2951
{
3052
gimmick_ptr() = std::make_unique<InputGimmick>(json, "", "mode_name", 1);
31-
f_aero_dist_from_json(ptr.f_arg_non_const(), aero_data.ptr.f_arg_non_const());
53+
f_aero_dist_from_json(ptr.f_arg_non_const(), aero_data->ptr.f_arg_non_const());
3254
gimmick_ptr().reset();
3355
}
56+
57+
static auto get_n_mode(const AeroDist &self) {
58+
int n_mode;
59+
f_aero_dist_n_mode(self.ptr.f_arg(), &n_mode);
60+
return n_mode;
61+
}
62+
63+
static auto get_total_num_conc(const AeroDist &self) {
64+
double total_num_conc;
65+
f_aero_dist_total_num_conc(self.ptr.f_arg(), &total_num_conc);
66+
return total_num_conc;
67+
}
68+
69+
static AeroMode* get_mode(const AeroDist &self, const int &idx) {
70+
if (idx < 0 || idx >= AeroDist::get_n_mode(self))
71+
throw std::out_of_range("Index out of range");
72+
73+
AeroMode *ptr = new AeroMode();
74+
f_aero_dist_mode(self.ptr.f_arg(), ptr, &idx);
75+
76+
return ptr;
77+
}
3478
};

src/aero_mode.hpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ extern "C" void f_aero_mode_from_json(
109109
struct AeroMode {
110110
PMCResource ptr;
111111

112+
AeroMode() :
113+
ptr(f_aero_mode_ctor, f_aero_mode_dtor)
114+
{}
115+
112116
AeroMode(AeroData &aero_data, const nlohmann::json &json) :
113117
ptr(f_aero_mode_ctor, f_aero_mode_dtor)
114118
{
@@ -230,27 +234,30 @@ struct AeroMode {
230234
}
231235

232236
static auto types() {
233-
static auto vec = std::vector<std::string>({
237+
static auto vec = std::vector<std::string>{
234238
"log_normal",
235239
"exp",
236240
"mono",
237241
"sampled"
238-
});
242+
};
239243
return vec;
240244
};
241245

242246
static void set_type(AeroMode &self, const std::string &mode_type) {
243-
auto it = std::find(
244-
AeroMode::types().begin(),
245-
AeroMode::types().end(),
246-
mode_type
247-
);
248-
249-
if (it == AeroMode::types().end())
247+
auto found = false;
248+
auto type = 0;
249+
250+
for (auto el : AeroMode::types()) {
251+
++type;
252+
if (el == mode_type) {
253+
found = true;
254+
break;
255+
}
256+
}
257+
258+
if (!found)
250259
throw std::invalid_argument("Invalid mode type.");
251260

252-
int type = 1 + std::distance(AeroMode::types().begin(), it);
253-
254261
f_aero_mode_set_type(self.ptr.f_arg_non_const(), &type);
255262
}
256263

src/aero_state.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,12 +332,13 @@ struct AeroState {
332332
const AeroState &self,
333333
const int &idx
334334
) {
335+
if (idx < 0 || idx >= (int)__len__(self))
336+
throw std::out_of_range("Index out of range");
337+
335338
int len = AeroData::__len__(*self.aero_data);
336339
std::valarray<double> data(len);
337340

338341
AeroParticle *ptr = new AeroParticle(self.aero_data, data);
339-
if (idx < 0 || idx >= (int)__len__(self))
340-
throw std::out_of_range("Index out of range");
341342
f_aero_state_particle(self.ptr.f_arg(), ptr, &idx);
342343

343344
return ptr;

src/fake_spec_file.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,20 @@ void c_spec_file_read_line(
217217
std::string name, data;
218218
*eof = gimmick_ptr()->read_line(name, data);
219219

220-
int i = 0;
221-
for (const auto &ch : name) {
222-
assert(i < *name_size);
223-
name_data[i++] = ch;
220+
{
221+
int i = 0;
222+
for (const auto &ch : name) {
223+
assert(i < *name_size);
224+
name_data[i++] = ch;
225+
}
226+
*name_size = i;
227+
}
228+
{
229+
int i = 0;
230+
for (const auto &ch : data) {
231+
assert(i < *data0_size);
232+
data0_data[i++] = ch;
233+
}
234+
*data0_size = i;
224235
}
225-
*name_size = i;
226236
}

src/gimmicks.hpp

Lines changed: 44 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,21 @@ struct Gimmick {
4343
return this->json->dump();
4444
}
4545

46-
std::string last_dict_key() const noexcept {
47-
std::string key = "<NOT FOUND>";
48-
for (const auto& item : this->json->items())
49-
{
46+
template <class T>
47+
std::string next_dict_key(T last_key, const T key_cond) const noexcept {
48+
std::string key = "", prev_key = "";
49+
if (last_key == key_cond)
50+
last_key = "";
51+
52+
for (const auto& item : this->json->items()) {
5053
if (this->json->is_array()) {
5154
for (auto &entry : item.value().items()) {
52-
key = entry.key();
55+
if (prev_key == last_key) {
56+
key = entry.key();
57+
break;
58+
}
59+
else
60+
prev_key = entry.key();
5361
}
5462
} else {
5563
key = item.key();
@@ -63,7 +71,7 @@ struct Gimmick {
6371

6472
void zoom_in(const bpstd::string_view &sub) noexcept {
6573
auto it = this->json->is_array()
66-
? this->json->at(this->json->size()-1).begin()
74+
? this->json->at(this->json->size()-1).find(sub)
6775
: this->json->find(sub);
6876
// TODO #112: handle errors
6977
this->json_parent.push(this->json);
@@ -86,35 +94,29 @@ struct Gimmick {
8694
}
8795

8896
// TODO #112: to be removed after initialising GasData with a list, and not JSON?
89-
std::string first_field_name() const noexcept {
97+
auto first_field_name() const noexcept {
9098
// TODO #112: handle errors
99+
std::string name = "";
91100
assert(this->json->size() > 0);
92101
assert(this->json->begin()->size() > 0);
93102
for (auto &entry : this->json->at(0).items())
94103
{
95-
return entry.key();
104+
name = entry.key();
96105
}
97-
assert(false);
98-
return "";
99-
}
100-
101-
auto is_empty() noexcept {
102-
return this->json->empty();
103-
}
104-
105-
auto size() noexcept {
106-
return this->json->size();
106+
if (name == "")
107+
assert(false);
108+
return name;
107109
}
108110

109-
std::size_t n_elements(const bpstd::string_view &name) noexcept {
111+
auto n_elements(const bpstd::string_view &name) noexcept {
112+
std::size_t n_elem = 0;
110113
for (auto i=0u; i<this->json->size(); ++i) {
111114
for (auto &entry : this->json->at(i).items()) {
112115
if (entry.key() == name)
113-
return entry.value().size();
116+
n_elem = entry.value().size();
114117
}
115118
}
116-
assert(false);
117-
return 0;
119+
return n_elem;
118120
}
119121

120122
auto n_numeric_array_entries() noexcept {
@@ -223,26 +225,30 @@ struct InputGimmick: Gimmick {
223225
}
224226

225227
bool read_line(std::string &name, std::string &data) {
226-
bool eof = this->is_empty();
227-
228-
if (this->zoom_level() == this->max_zoom_level) { // TODO #112
229-
eof = true;
228+
bool subsequent_record = false;
229+
if (this->zoom_level() == this->max_zoom_level) {
230230
this->zoom_out();
231-
}
232231

233-
if (!eof) {
234-
assert(this->size() == 1);
235-
auto key = this->last_dict_key();
236-
if (this->key_name != "" && (this->key_cond == this->last_read_line_key)) {
237-
name = this->key_name;
238-
this->zoom_in(key);
239-
} else {
240-
name = key;
232+
auto key = this->next_dict_key(this->last_read_line_key, this->key_cond);
233+
if (key == "") {
234+
this->last_read_line_key = "";
235+
return true;
241236
}
242-
data = key;
243-
this->last_read_line_key = key;
237+
else
238+
subsequent_record = true;
244239
}
245-
return eof;
240+
241+
auto key = this->next_dict_key(this->last_read_line_key, this->key_cond);
242+
if (subsequent_record || (this->key_name != "" && (this->key_cond == this->last_read_line_key))) {
243+
name = this->key_name;
244+
this->zoom_in(key);
245+
} else {
246+
name = key;
247+
}
248+
data = key;
249+
this->last_read_line_key = key;
250+
251+
return false;
246252
}
247253
};
248254

src/pypartmc.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,11 @@ PYBIND11_MODULE(_PyPartMC, m) {
326326
;
327327

328328
py::class_<AeroDist>(m,"AeroDist")
329-
.def(py::init<AeroData&, const nlohmann::json&>())
329+
.def(py::init<std::shared_ptr<AeroData>, const nlohmann::json&>())
330+
.def_property_readonly("n_mode", &AeroDist::get_n_mode)
331+
.def_property_readonly("num_conc", &AeroDist::get_total_num_conc)
332+
.def("mode", AeroDist::get_mode,
333+
"returns the mode of a given index")
330334
;
331335

332336
m.def(

0 commit comments

Comments
 (0)