Skip to content

Commit 800f9ba

Browse files
slayoojcurtis2
andauthored
time-varying aero specs in Scenario (#207)
Co-authored-by: Jeff Curtis <[email protected]>
1 parent 9f5c6ef commit 800f9ba

File tree

9 files changed

+449
-37
lines changed

9 files changed

+449
-37
lines changed

src/aero_dist.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ struct AeroDist {
5454
gimmick_ptr().reset();
5555
}
5656

57+
AeroDist() :
58+
ptr(f_aero_dist_ctor, f_aero_dist_dtor)
59+
{}
60+
5761
static auto get_n_mode(const AeroDist &self) {
5862
int n_mode;
5963
f_aero_dist_n_mode(self.ptr.f_arg(), &n_mode);

src/fake_spec_file.F90

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ subroutine c_spec_file_read_real_named_array_data( &
8282
integer, intent(in) :: row, vals_size, names_size
8383
end subroutine
8484

85+
subroutine c_spec_file_read_line_data_size(sz) bind(C)
86+
import c_int
87+
integer(kind=c_int), intent(out) :: sz
88+
end subroutine
89+
8590
subroutine c_spec_file_read_line( &
8691
name_data, name_size, &
8792
data0_data, data0_size, &
@@ -100,7 +105,11 @@ subroutine spec_file_check_line_name(file, line, name)
100105
type(spec_file_t), intent(in) :: file
101106
type(spec_line_t), intent(in) :: line
102107
character(len=*), intent(in) :: name
103-
if (line%name /= name) then
108+
integer :: substr_len
109+
110+
substr_len = len(name)
111+
112+
if (line%name(1:substr_len) /= name(1:substr_len)) then
104113
print*, 'line must begin with: ' // trim(name) // ' not: ' // trim(line%name)
105114
call pmc_stop(462932478)
106115
end if
@@ -115,10 +124,14 @@ subroutine spec_file_read_real_named_array(file, max_lines, names, vals)
115124
integer :: row, col, n_rows, n_cols, name_size;
116125

117126
call c_spec_file_read_real_named_array_size(n_rows, n_cols)
127+
128+
if (max_lines .ne. 0 .and. max_lines .lt. n_rows) then
129+
n_rows = max_lines
130+
end if
131+
118132
allocate(names(n_rows))
119133
allocate(vals(n_rows, n_cols))
120134
allocate(vals_row(n_cols))
121-
! TODO #112: handle max_lines
122135
do row = 1, n_rows
123136
name_size = len(names(row))
124137
call c_spec_file_read_real_named_array_data( &
@@ -146,7 +159,9 @@ subroutine spec_file_check_line_length(file, line, length)
146159
type(spec_line_t), intent(in) :: line
147160
integer, intent(in) :: length
148161
if (size(line%data) /= length) then
149-
print*, 'expected ' // trim(integer_to_string(length)) // ' data items on line'
162+
print*, 'expected ' // trim(integer_to_string(length)) &
163+
// ' data items on line, not ' &
164+
// trim(integer_to_string(size(line%data)))
150165
call pmc_stop(189339129)
151166
end if
152167
end subroutine
@@ -197,17 +212,21 @@ subroutine spec_file_read_line(file, line, eof)
197212
type(spec_line_t), intent(inout) :: line
198213
logical, intent(out) :: eof
199214

200-
integer :: name_size, data0_size
215+
integer :: name_size, data0_size, data_size, i
201216
logical(c_bool) :: c_eof
202217

203-
allocate(line%data(1))
218+
call c_spec_file_read_line_data_size(data_size)
219+
220+
allocate(line%data(data_size))
204221
name_size = len(line%name)
205222
data0_size = len(line%data(1))
206223
call c_spec_file_read_line(line%name, name_size, line%data(1), data0_size, c_eof)
207224
eof = c_eof
208225
if (.not. eof) then
209226
line%name = line%name(1:name_size)
210-
line%data(1) = line%data(1)(1:data0_size)
227+
do i = 1, data_size
228+
line%data(i) = line%data(1)(1:data0_size)
229+
end do
211230
else
212231
deallocate(line%data)
213232
end if

src/fake_spec_file.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,12 @@ void c_spec_file_read_real_named_array_data(
205205
);
206206
}
207207

208+
/*********************************************************************************/
209+
extern "C"
210+
void c_spec_file_read_line_data_size(int *size) noexcept {
211+
*size = gimmick_ptr()->read_line_data_size_and_start_enumerating();
212+
}
213+
208214
/*********************************************************************************/
209215
extern "C"
210216
void c_spec_file_read_line(

src/gimmicks.hpp

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ struct Gimmick {
2626
}
2727

2828
protected:
29+
size_t index = 0;
30+
2931
Gimmick() {}
3032

3133
Gimmick(const nlohmann::json &json) {
@@ -73,9 +75,15 @@ struct Gimmick {
7375
auto it = this->json->is_array()
7476
? this->json->at(this->json->size()-1).find(sub)
7577
: this->json->find(sub);
76-
// TODO #112: handle errors
78+
79+
assert(*it != NULL);
7780
this->json_parent.push(this->json);
78-
this->set_current_json_ptr(&(*it));
81+
82+
if (sub == "dist") // TODO #112: do better than hardcoding "dist"...
83+
this->set_current_json_ptr(&(it->at(this->n_elements(sub) - this->index--)));
84+
else
85+
this->set_current_json_ptr(&(*it));
86+
7987
}
8088

8189
void zoom_out() noexcept {
@@ -84,7 +92,7 @@ struct Gimmick {
8492
this->json_parent.pop();
8593
}
8694

87-
auto zoom_level() noexcept {
95+
auto zoom_level() const noexcept {
8896
auto level = this->json_parent.size();
8997
return level;
9098
}
@@ -108,7 +116,7 @@ struct Gimmick {
108116
return name;
109117
}
110118

111-
auto n_elements(const bpstd::string_view &name) noexcept {
119+
std::size_t n_elements(const bpstd::string_view &name) const noexcept {
112120
std::size_t n_elem = 0;
113121
for (auto i=0u; i<this->json->size(); ++i) {
114122
for (auto &entry : this->json->at(i).items()) {
@@ -203,6 +211,8 @@ struct Gimmick {
203211
virtual std::string str() const = 0;
204212

205213
virtual bool read_line(std::string &name, std::string &data) = 0;
214+
215+
virtual int read_line_data_size_and_start_enumerating() = 0;
206216
};
207217

208218
struct InputGimmick: Gimmick {
@@ -218,7 +228,8 @@ struct InputGimmick: Gimmick {
218228
const std::string key_name = "",
219229
const std::size_t max_zoom_level = 3
220230
) : Gimmick(json), key_cond(key_cond), key_name(key_name), max_zoom_level(max_zoom_level)
221-
{}
231+
{
232+
}
222233

223234
std::string str() const {
224235
throw std::logic_error("str() called on InputGimmick!");
@@ -231,7 +242,10 @@ struct InputGimmick: Gimmick {
231242

232243
auto key = this->next_dict_key(this->last_read_line_key, this->key_cond);
233244
if (key == "") {
234-
this->last_read_line_key = "";
245+
if (this->index == 0)
246+
this->last_read_line_key = "";
247+
else
248+
this->last_read_line_key = this->key_cond;
235249
return true;
236250
}
237251
else
@@ -250,6 +264,14 @@ struct InputGimmick: Gimmick {
250264

251265
return false;
252266
}
267+
268+
int read_line_data_size_and_start_enumerating() {
269+
if (this->zoom_level() == this->max_zoom_level - 2) {
270+
this->index = this->n_elements(this->key_cond);
271+
return this->index;
272+
}
273+
return 1;
274+
}
253275
};
254276

255277
struct OutputGimmick: Gimmick {
@@ -266,6 +288,10 @@ struct OutputGimmick: Gimmick {
266288
bool read_line(std::string &, std::string &) {
267289
throw std::logic_error("read_line() called on OutputGimmick!");
268290
}
291+
292+
int read_line_data_size_and_start_enumerating() {
293+
throw std::logic_error("read_line_data_size_and_start_enumerating() called on OutputGimmick!");
294+
}
269295
};
270296

271297
std::unique_ptr<Gimmick> &gimmick_ptr();

src/pypartmc.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,19 @@ PYBIND11_MODULE(_PyPartMC, m) {
281281
"returns a string with JSON representation of the object")
282282
.def("init_env_state", Scenario::init_env_state,
283283
"initializes the EnvState")
284+
.def("aero_emissions", Scenario::get_dist,
285+
"returns aero_emissions AeroDists at a given index")
286+
.def_property_readonly("aero_emissions_n_times", Scenario::get_emissions_n_times,
287+
"returns the number of times specified for emissions")
288+
.def_property_readonly("aero_emissions_rate_scale", Scenario::emission_rate_scale)
289+
.def_property_readonly("aero_emissions_time", Scenario::emission_time)
290+
.def("aero_background", Scenario::get_aero_background_dist,
291+
"returns aero_background AeroDists at a given index")
292+
.def_property_readonly("aero_dilution_n_times", Scenario::get_aero_dilution_n_times,
293+
"returns the number of times specified for dilution")
294+
.def_property_readonly("aero_dilution_rate", Scenario::aero_dilution_rate)
295+
.def_property_readonly("aero_dilution_time", Scenario::aero_dilution_time)
296+
284297
;
285298

286299
py::class_<GasState>(m,

src/scenario.F90

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,112 @@ subroutine f_scenario_init_env_state(scenario_ptr_c, env_state_ptr_c, &
109109

110110
end subroutine
111111

112+
subroutine f_scenario_aero_dist_emission(scenario_ptr_c, aero_dist_ptr_c, index) bind(C)
113+
114+
type(c_ptr), intent(in) :: scenario_ptr_c, aero_dist_ptr_c
115+
integer(c_int), intent(in) :: index
116+
type(scenario_t), pointer :: scenario_ptr_f => null()
117+
type(aero_dist_t), pointer :: aero_dist_ptr_f => null()
118+
119+
call c_f_pointer(scenario_ptr_c, scenario_ptr_f)
120+
call c_f_pointer(aero_dist_ptr_c, aero_dist_ptr_f)
121+
122+
aero_dist_ptr_f = scenario_ptr_f%aero_emission(index + 1)
123+
124+
end subroutine
125+
126+
subroutine f_scenario_aero_emission_n_times(scenario_ptr_c, n_times) bind(C)
127+
128+
type(c_ptr), intent(in) :: scenario_ptr_c
129+
integer(c_int), intent(out) :: n_times
130+
type(scenario_t), pointer :: scenario_ptr_f => null()
131+
132+
call c_f_pointer(scenario_ptr_c, scenario_ptr_f)
133+
134+
n_times = size(scenario_ptr_f%aero_emission_time)
135+
136+
end subroutine
137+
138+
subroutine f_scenario_emission_rates(scenario_ptr_c, emission_rates, &
139+
n_times) bind(C)
140+
141+
type(c_ptr), intent(in) :: scenario_ptr_c
142+
type(scenario_t), pointer :: scenario_ptr_f => null()
143+
integer(c_int) :: n_times
144+
real(c_double) :: emission_rates(n_times)
145+
146+
call c_f_pointer(scenario_ptr_c, scenario_ptr_f)
147+
148+
emission_rates = scenario_ptr_f%aero_emission_rate_scale
149+
150+
end subroutine
151+
152+
subroutine f_scenario_emission_time(scenario_ptr_c, emission_time, &
153+
n_times) bind(C)
154+
155+
type(c_ptr), intent(in) :: scenario_ptr_c
156+
type(scenario_t), pointer :: scenario_ptr_f => null()
157+
integer(c_int) :: n_times
158+
real(c_double) :: emission_time(n_times)
159+
160+
call c_f_pointer(scenario_ptr_c, scenario_ptr_f)
161+
162+
emission_time = scenario_ptr_f%aero_emission_time
163+
164+
end subroutine
165+
166+
subroutine f_scenario_aero_dist_background(scenario_ptr_c, aero_dist_ptr_c, index) bind(C)
167+
168+
type(c_ptr), intent(in) :: scenario_ptr_c, aero_dist_ptr_c
169+
integer(c_int), intent(in) :: index
170+
type(scenario_t), pointer :: scenario_ptr_f => null()
171+
type(aero_dist_t), pointer :: aero_dist_ptr_f => null()
172+
173+
call c_f_pointer(scenario_ptr_c, scenario_ptr_f)
174+
call c_f_pointer(aero_dist_ptr_c, aero_dist_ptr_f)
175+
176+
aero_dist_ptr_f = scenario_ptr_f%aero_background(index + 1)
177+
178+
end subroutine
179+
180+
subroutine f_scenario_aero_background_n_times(scenario_ptr_c, n_times) bind(C)
181+
182+
type(c_ptr), intent(in) :: scenario_ptr_c
183+
integer(c_int), intent(out) :: n_times
184+
type(scenario_t), pointer :: scenario_ptr_f => null()
185+
186+
call c_f_pointer(scenario_ptr_c, scenario_ptr_f)
187+
188+
n_times = size(scenario_ptr_f%aero_dilution_time)
189+
190+
end subroutine
191+
192+
subroutine f_scenario_aero_background_rate_scale(scenario_ptr_c, &
193+
aero_background_rate_scale, n_times) bind(C)
194+
195+
type(c_ptr), intent(in) :: scenario_ptr_c
196+
type(scenario_t), pointer :: scenario_ptr_f => null()
197+
integer(c_int) :: n_times
198+
real(c_double) :: aero_background_rate_scale(n_times)
199+
200+
call c_f_pointer(scenario_ptr_c, scenario_ptr_f)
201+
202+
aero_background_rate_scale = scenario_ptr_f%aero_dilution_rate
203+
204+
end subroutine
205+
206+
subroutine f_scenario_aero_background_time(scenario_ptr_c, aero_background_time, &
207+
n_times) bind(C)
208+
209+
type(c_ptr), intent(in) :: scenario_ptr_c
210+
type(scenario_t), pointer :: scenario_ptr_f => null()
211+
integer(c_int) :: n_times
212+
real(c_double) :: aero_background_time(n_times)
213+
214+
call c_f_pointer(scenario_ptr_c, scenario_ptr_f)
215+
216+
aero_background_time = scenario_ptr_f%aero_dilution_time
217+
218+
end subroutine
219+
112220
end module

0 commit comments

Comments
 (0)