Skip to content

Commit

Permalink
multi-mode AeroDist initialsation (also in Scenario) + AeroDist::n_mo…
Browse files Browse the repository at this point in the history
…de & AeroDist::mode(idx) (#193)

Co-authored-by: Jeff Curtis <[email protected]>
  • Loading branch information
slayoo and jcurtis2 authored Mar 9, 2023
1 parent d0d1121 commit 1b09467
Show file tree
Hide file tree
Showing 10 changed files with 263 additions and 61 deletions.
32 changes: 32 additions & 0 deletions src/aero_dist.F90
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,36 @@ subroutine f_aero_dist_from_json(ptr_c, aero_data_ptr_c) bind(C)

call spec_file_read_aero_dist(file, aero_data_ptr_f, aero_dist)
end subroutine

subroutine f_aero_dist_n_mode(ptr_c, n_mode) bind(C)
type(aero_dist_t), pointer :: aero_dist => null()
type(c_ptr), intent(in) :: ptr_c
integer(c_int), intent(out) :: n_mode

call c_f_pointer(ptr_c, aero_dist)
n_mode = aero_dist_n_mode(aero_dist)
end subroutine

subroutine f_aero_dist_total_num_conc(ptr_c, total_num_conc) bind(C)
type(aero_dist_t), pointer :: aero_dist => null()
type(c_ptr), intent(in) :: ptr_c
real(c_double), intent(out) :: total_num_conc

call c_f_pointer(ptr_c, aero_dist)
total_num_conc = aero_dist_total_num_conc(aero_dist)
end subroutine

subroutine f_aero_dist_mode(ptr_c, aero_mode_ptr_c, index) bind(C)
type(c_ptr) :: ptr_c, aero_mode_ptr_c
type(aero_dist_t), pointer :: aero_dist
type(aero_mode_t), pointer :: aero_mode
integer(c_int), intent(in) :: index

call c_f_pointer(ptr_c, aero_dist)
call c_f_pointer(aero_mode_ptr_c, aero_mode)

aero_mode = aero_dist%mode(index + 1)

end subroutine

end module
50 changes: 47 additions & 3 deletions src/aero_dist.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#pragma once

#include "pmc_resource.hpp"
#include "aero_mode.hpp"

extern "C" void f_aero_dist_ctor(
void *ptr
Expand All @@ -16,19 +17,62 @@ extern "C" void f_aero_dist_dtor(
void *ptr
) noexcept;

extern "C" void f_aero_dist_n_mode(
const void *ptr,
int *n_mode
) noexcept;

extern "C" void f_aero_dist_from_json(
void *ptr,
void *aero_data_ptr
) noexcept;

extern "C" void f_aero_dist_total_num_conc(
const void *ptr,
double *total_num_conc
) noexcept;

extern "C" void f_aero_dist_mode(
const void *ptr,
void *ptr_c,
const int *index
) noexcept;

struct AeroDist {
PMCResource ptr;
std::shared_ptr<AeroData> aero_data;

AeroDist(AeroData &aero_data, const nlohmann::json &json):
ptr(f_aero_dist_ctor, f_aero_dist_dtor)
AeroDist(
std::shared_ptr<AeroData> aero_data,
const nlohmann::json &json
):
ptr(f_aero_dist_ctor, f_aero_dist_dtor),
aero_data(aero_data)
{
gimmick_ptr() = std::make_unique<InputGimmick>(json, "", "mode_name", 1);
f_aero_dist_from_json(ptr.f_arg_non_const(), aero_data.ptr.f_arg_non_const());
f_aero_dist_from_json(ptr.f_arg_non_const(), aero_data->ptr.f_arg_non_const());
gimmick_ptr().reset();
}

static auto get_n_mode(const AeroDist &self) {
int n_mode;
f_aero_dist_n_mode(self.ptr.f_arg(), &n_mode);
return n_mode;
}

static auto get_total_num_conc(const AeroDist &self) {
double total_num_conc;
f_aero_dist_total_num_conc(self.ptr.f_arg(), &total_num_conc);
return total_num_conc;
}

static AeroMode* get_mode(const AeroDist &self, const int &idx) {
if (idx < 0 || idx >= AeroDist::get_n_mode(self))
throw std::out_of_range("Index out of range");

AeroMode *ptr = new AeroMode();
f_aero_dist_mode(self.ptr.f_arg(), ptr, &idx);

return ptr;
}
};
29 changes: 18 additions & 11 deletions src/aero_mode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ extern "C" void f_aero_mode_from_json(
struct AeroMode {
PMCResource ptr;

AeroMode() :
ptr(f_aero_mode_ctor, f_aero_mode_dtor)
{}

AeroMode(AeroData &aero_data, const nlohmann::json &json) :
ptr(f_aero_mode_ctor, f_aero_mode_dtor)
{
Expand Down Expand Up @@ -230,27 +234,30 @@ struct AeroMode {
}

static auto types() {
static auto vec = std::vector<std::string>({
static auto vec = std::vector<std::string>{
"log_normal",
"exp",
"mono",
"sampled"
});
};
return vec;
};

static void set_type(AeroMode &self, const std::string &mode_type) {
auto it = std::find(
AeroMode::types().begin(),
AeroMode::types().end(),
mode_type
);

if (it == AeroMode::types().end())
auto found = false;
auto type = 0;

for (auto el : AeroMode::types()) {
++type;
if (el == mode_type) {
found = true;
break;
}
}

if (!found)
throw std::invalid_argument("Invalid mode type.");

int type = 1 + std::distance(AeroMode::types().begin(), it);

f_aero_mode_set_type(self.ptr.f_arg_non_const(), &type);
}

Expand Down
5 changes: 3 additions & 2 deletions src/aero_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,12 +332,13 @@ struct AeroState {
const AeroState &self,
const int &idx
) {
if (idx < 0 || idx >= (int)__len__(self))
throw std::out_of_range("Index out of range");

int len = AeroData::__len__(*self.aero_data);
std::valarray<double> data(len);

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

return ptr;
Expand Down
20 changes: 15 additions & 5 deletions src/fake_spec_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,20 @@ void c_spec_file_read_line(
std::string name, data;
*eof = gimmick_ptr()->read_line(name, data);

int i = 0;
for (const auto &ch : name) {
assert(i < *name_size);
name_data[i++] = ch;
{
int i = 0;
for (const auto &ch : name) {
assert(i < *name_size);
name_data[i++] = ch;
}
*name_size = i;
}
{
int i = 0;
for (const auto &ch : data) {
assert(i < *data0_size);
data0_data[i++] = ch;
}
*data0_size = i;
}
*name_size = i;
}
82 changes: 44 additions & 38 deletions src/gimmicks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,21 @@ struct Gimmick {
return this->json->dump();
}

std::string last_dict_key() const noexcept {
std::string key = "<NOT FOUND>";
for (const auto& item : this->json->items())
{
template <class T>
std::string next_dict_key(T last_key, const T key_cond) const noexcept {
std::string key = "", prev_key = "";
if (last_key == key_cond)
last_key = "";

for (const auto& item : this->json->items()) {
if (this->json->is_array()) {
for (auto &entry : item.value().items()) {
key = entry.key();
if (prev_key == last_key) {
key = entry.key();
break;
}
else
prev_key = entry.key();
}
} else {
key = item.key();
Expand All @@ -63,7 +71,7 @@ struct Gimmick {

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

// TODO #112: to be removed after initialising GasData with a list, and not JSON?
std::string first_field_name() const noexcept {
auto first_field_name() const noexcept {
// TODO #112: handle errors
std::string name = "";
assert(this->json->size() > 0);
assert(this->json->begin()->size() > 0);
for (auto &entry : this->json->at(0).items())
{
return entry.key();
name = entry.key();
}
assert(false);
return "";
}

auto is_empty() noexcept {
return this->json->empty();
}

auto size() noexcept {
return this->json->size();
if (name == "")
assert(false);
return name;
}

std::size_t n_elements(const bpstd::string_view &name) noexcept {
auto n_elements(const bpstd::string_view &name) noexcept {
std::size_t n_elem = 0;
for (auto i=0u; i<this->json->size(); ++i) {
for (auto &entry : this->json->at(i).items()) {
if (entry.key() == name)
return entry.value().size();
n_elem = entry.value().size();
}
}
assert(false);
return 0;
return n_elem;
}

auto n_numeric_array_entries() noexcept {
Expand Down Expand Up @@ -223,26 +225,30 @@ struct InputGimmick: Gimmick {
}

bool read_line(std::string &name, std::string &data) {
bool eof = this->is_empty();

if (this->zoom_level() == this->max_zoom_level) { // TODO #112
eof = true;
bool subsequent_record = false;
if (this->zoom_level() == this->max_zoom_level) {
this->zoom_out();
}

if (!eof) {
assert(this->size() == 1);
auto key = this->last_dict_key();
if (this->key_name != "" && (this->key_cond == this->last_read_line_key)) {
name = this->key_name;
this->zoom_in(key);
} else {
name = key;
auto key = this->next_dict_key(this->last_read_line_key, this->key_cond);
if (key == "") {
this->last_read_line_key = "";
return true;
}
data = key;
this->last_read_line_key = key;
else
subsequent_record = true;
}
return eof;

auto key = this->next_dict_key(this->last_read_line_key, this->key_cond);
if (subsequent_record || (this->key_name != "" && (this->key_cond == this->last_read_line_key))) {
name = this->key_name;
this->zoom_in(key);
} else {
name = key;
}
data = key;
this->last_read_line_key = key;

return false;
}
};

Expand Down
6 changes: 5 additions & 1 deletion src/pypartmc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,11 @@ PYBIND11_MODULE(_PyPartMC, m) {
;

py::class_<AeroDist>(m,"AeroDist")
.def(py::init<AeroData&, const nlohmann::json&>())
.def(py::init<std::shared_ptr<AeroData>, const nlohmann::json&>())
.def_property_readonly("n_mode", &AeroDist::get_n_mode)
.def_property_readonly("num_conc", &AeroDist::get_total_num_conc)
.def("mode", AeroDist::get_mode,
"returns the mode of a given index")
;

m.def(
Expand Down
Loading

0 comments on commit 1b09467

Please sign in to comment.