From b445a7a795bcc79f68ba7fb1d721836c277f9b65 Mon Sep 17 00:00:00 2001 From: Jeff Curtis Date: Mon, 24 Nov 2025 13:41:38 -0600 Subject: [PATCH 01/15] add set and get templates for EnvState --- src/env_state.hpp | 178 +++++++++++++--------------------------------- 1 file changed, 48 insertions(+), 130 deletions(-) diff --git a/src/env_state.hpp b/src/env_state.hpp index e8e9799e..659b33d9 100644 --- a/src/env_state.hpp +++ b/src/env_state.hpp @@ -50,173 +50,97 @@ struct EnvState { ptr(f_env_state_ctor, f_env_state_dtor) {} - static void set_temperature(const EnvState &self, double &temperature) { - f_env_state_set_temperature( - self.ptr.f_arg(), - &temperature - ); + template + static T get_value(const EnvState &self, Func func) { + T value{}; + func(self.ptr.f_arg(), &value); + return value; } - static auto temp(const EnvState &self) { - double temperature; + template + static void set_value(const EnvState &self, Func func, T value) { + func(self.ptr.f_arg(), &value); + } - f_env_state_get_temperature( - self.ptr.f_arg(), - &temperature - ); - return temperature; + static double temp(const EnvState &self) { + return get_value(self, f_env_state_get_temperature); } - static auto rh(const EnvState &self) { - double rel_humid; + static void set_temperature(const EnvState &self, double temperature) { + set_value(self, f_env_state_set_temperature, temperature); + } - f_env_state_get_rel_humid( - self.ptr.f_arg(), - &rel_humid - ); - return rel_humid; + static auto rh(const EnvState &self) { + return get_value(self, f_env_state_get_rel_humid); } - + static void set_height(const EnvState &self, const double height) { - f_env_state_set_height( - self.ptr.f_arg(), - &height - ); + set_value(self, f_env_state_set_height, height); } - static auto get_height(const EnvState &self) { - double height; - - f_env_state_get_height( - self.ptr.f_arg(), - &height - ); - return height; + static double get_height(const EnvState &self) { + return get_value(self, f_env_state_get_height); } - static void set_additive_kernel_coefficient(const EnvState &self, const double additive_kernel_coefficient) { - f_env_state_set_additive_kernel_coefficient( - self.ptr.f_arg(), - &additive_kernel_coefficient - ); + static void set_additive_kernel_coefficient( + const EnvState &self, + const double additive_kernel_coefficient) + { + set_value( + self, + f_env_state_set_additive_kernel_coefficient, + additive_kernel_coefficient); } - - static auto get_additive_kernel_coefficient(const EnvState &self) { - double additive_kernel_coefficient; - - f_env_state_get_additive_kernel_coefficient( - self.ptr.f_arg(), - &additive_kernel_coefficient - ); - return additive_kernel_coefficient; + static double get_additive_kernel_coefficient(const EnvState &self) { + return get_value(self, f_env_state_get_additive_kernel_coefficient); } static void set_pressure(const EnvState &self, const double pressure) { - f_env_state_set_pressure( - self.ptr.f_arg(), - &pressure - ); + set_value(self, f_env_state_set_pressure, pressure); } - static auto get_pressure(const EnvState &self) { - double pressure; - - f_env_state_get_pressure( - self.ptr.f_arg(), - &pressure - ); - return pressure; + static double get_pressure(const EnvState &self) { + return get_value(self, f_env_state_get_pressure); } static auto get_elapsed_time(const EnvState &self) { - double elapsed_time; - - f_env_state_get_elapsed_time( - self.ptr.f_arg(), - &elapsed_time - ); - return elapsed_time; + return get_value(self, f_env_state_get_elapsed_time); } static auto get_start_time(const EnvState &self) { - double start_time; - - f_env_state_get_start_time( - self.ptr.f_arg(), - &start_time - ); - return start_time; + return get_value(self, f_env_state_get_start_time); } static auto air_density(const EnvState &self) { - double air_density; - - f_env_state_air_dens( - self.ptr.f_arg(), - &air_density - ); - return air_density; + return get_value(self, f_env_state_air_dens); } static auto air_molar_density(const EnvState &self) { - double air_molar_density; - - f_env_state_air_molar_dens( - self.ptr.f_arg(), - &air_molar_density - ); - return air_molar_density; - } - - static void set_latitude(const EnvState &self, const double latitude) { - f_env_state_set_latitude( - self.ptr.f_arg(), - &latitude - ); + return get_value(self, f_env_state_air_molar_dens); } static auto get_latitude(const EnvState &self) { - double latitude; - - f_env_state_get_latitude( - self.ptr.f_arg(), - &latitude - ); - return latitude; + return get_value(self, f_env_state_get_latitude); } - static void set_longitude(const EnvState &self, const double longitude) { - f_env_state_set_longitude( - self.ptr.f_arg(), - &longitude - ); + static void set_latitude(const EnvState &self, const double latitude) { + set_value(self, f_env_state_set_latitude, latitude); } static auto get_longitude(const EnvState &self) { - double longitude; - - f_env_state_get_longitude( - self.ptr.f_arg(), - &longitude - ); - return longitude; + return get_value(self, f_env_state_get_longitude); } - static void set_altitude(const EnvState &self, const double altitude) { - f_env_state_set_altitude( - self.ptr.f_arg(), - &altitude - ); + static void set_longitude(const EnvState &self, const double longitude) { + set_value(self, f_env_state_set_longitude, longitude); } static auto get_altitude(const EnvState &self) { - double altitude; + return get_value(self, f_env_state_get_altitude); + } - f_env_state_get_altitude( - self.ptr.f_arg(), - &altitude - ); - return altitude; + static void set_altitude(const EnvState &self, const double altitude) { + set_value(self, f_env_state_set_altitude, altitude); } static auto ppb_to_conc(const EnvState &self, const double ppb) { @@ -242,13 +166,7 @@ struct EnvState { } static auto sat_vapor_pressure(const EnvState &self) { - double sat_vapor_pressure; - - f_env_state_sat_vapor_pressure( - self.ptr.f_arg(), - &sat_vapor_pressure - ); - return sat_vapor_pressure; + return get_value(self, f_env_state_sat_vapor_pressure); } }; From 5c451098e01526749b3bbec4af0b49d68f5bb499 Mon Sep 17 00:00:00 2001 From: Jeff Curtis Date: Mon, 24 Nov 2025 14:04:10 -0600 Subject: [PATCH 02/15] add missing test for temperature --- tests/test_env_state.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/test_env_state.py b/tests/test_env_state.py index eef85fcb..7085f42e 100644 --- a/tests/test_env_state.py +++ b/tests/test_env_state.py @@ -129,6 +129,18 @@ def test_humidity_ctor(): # assert assert ENV_STATE_CTOR_ARG_MINIMAL["rel_humidity"] == sut.rh + @staticmethod + def test_temp(): + # arrange + gas_data = ppmc.GasData(GAS_DATA_CTOR_ARG_MINIMAL) + aero_data = ppmc.AeroData(AERO_DATA_CTOR_ARG_MINIMAL) + scenario = ppmc.Scenario(gas_data, aero_data, SCENARIO_CTOR_ARG_MINIMAL) + sut = ppmc.EnvState(ENV_STATE_CTOR_ARG_MINIMAL) + scenario.init_env_state(sut, 0.0) + + # assert + assert sut.temp == SCENARIO_CTOR_ARG_MINIMAL["temp_profile"][1]["temp"][0] + @staticmethod def test_elapsed_time(): # arrange and act From 1e228b21b2154e39b2b96fa55cbb96a11a1c4a85 Mon Sep 17 00:00:00 2001 From: Jeff Curtis Date: Mon, 24 Nov 2025 14:05:39 -0600 Subject: [PATCH 03/15] first draft of templates for aero_particle --- src/aero_particle.hpp | 219 +++++++++++++----------------------------- 1 file changed, 68 insertions(+), 151 deletions(-) diff --git a/src/aero_particle.hpp b/src/aero_particle.hpp index 3f7d176f..c123b7bd 100644 --- a/src/aero_particle.hpp +++ b/src/aero_particle.hpp @@ -68,6 +68,37 @@ struct AeroParticle { throw std::runtime_error("AeroData size mistmatch"); } + template + static T get_value(const AeroParticle &self, Func func) { + T value{}; + func(self.ptr.f_arg(), &value); + return value; + } + + template + static void set_value(AeroParticle &self, Func func, T value) { + func(self.ptr.f_arg_non_const(), &value); + } + + template + static T get_derived_value(const AeroParticle &self, Func func) + { + T value{}; + func(self.ptr.f_arg(), self.aero_data.get(), &value); + return value; + } + + template + static T get_derived_value_env_state( + const AeroParticle &self, + const EnvState &env_state, + Func func) + { + T value{}; + func(self.ptr.f_arg(), self.aero_data.get(), env_state.ptr.f_arg(), &value); + return value; + } + static auto volumes(const AeroParticle &self) { int len = AeroData::__len__(*self.aero_data); @@ -81,12 +112,7 @@ struct AeroParticle { } static auto volume(const AeroParticle &self) { - double vol; - f_aero_particle_volume( - self.ptr.f_arg(), - &vol - ); - return vol; + return get_value(self, f_aero_particle_volume); } static auto species_volume(const AeroParticle &self, const int &i_spec) { @@ -112,63 +138,27 @@ struct AeroParticle { } static auto dry_volume(const AeroParticle &self) { - double vol; - f_aero_particle_dry_volume( - self.ptr.f_arg(), - self.aero_data.get(), - &vol - ); - return vol; + return get_derived_value(self, f_aero_particle_dry_volume); } static auto radius(const AeroParticle &self) { - double radius; - f_aero_particle_radius( - self.ptr.f_arg(), - self.aero_data.get(), - &radius - ); - return radius; + return get_derived_value(self, f_aero_particle_radius); } static auto dry_radius(const AeroParticle &self) { - double radius; - f_aero_particle_dry_radius( - self.ptr.f_arg(), - self.aero_data.get(), - &radius - ); - return radius; + return get_derived_value(self, f_aero_particle_dry_radius); } static auto diameter(const AeroParticle &self) { - double diameter; - f_aero_particle_diameter( - self.ptr.f_arg(), - self.aero_data.get(), - &diameter - ); - return diameter; + return get_derived_value(self, f_aero_particle_diameter); } static auto dry_diameter(const AeroParticle &self) { - double diameter; - f_aero_particle_dry_diameter( - self.ptr.f_arg(), - self.aero_data.get(), - &diameter - ); - return diameter; + return get_derived_value(self, f_aero_particle_dry_diameter); } static auto mass(const AeroParticle &self) { - double mass; - f_aero_particle_mass( - self.ptr.f_arg(), - self.aero_data.get(), - &mass - ); - return mass; + return get_derived_value(self, f_aero_particle_mass); } static auto species_mass(const AeroParticle &self, const int &i_spec) { @@ -207,77 +197,43 @@ struct AeroParticle { } static auto solute_kappa(const AeroParticle &self) { - double kappa; - f_aero_particle_solute_kappa( - self.ptr.f_arg(), - self.aero_data.get(), - &kappa - ); - return kappa; + return get_derived_value(self, f_aero_particle_solute_kappa); } static auto moles(const AeroParticle &self) { - double moles; - f_aero_particle_moles( - self.ptr.f_arg(), - self.aero_data.get(), - &moles - ); - return moles; + return get_derived_value(self, f_aero_particle_moles); } static auto mobility_diameter(const AeroParticle &self, const EnvState &env_state) { - double mobility_diameter; - f_aero_particle_mobility_diameter( - self.ptr.f_arg(), - self.aero_data.get(), - env_state.ptr.f_arg(), - &mobility_diameter - ); - return mobility_diameter; + return get_derived_value_env_state( + self, + env_state, + f_aero_particle_mobility_diameter); } static auto density(const AeroParticle &self) { - double density; - f_aero_particle_density( - self.ptr.f_arg(), - self.aero_data.get(), - &density - ); - return density; + return get_derived_value(self, f_aero_particle_density); } static auto approx_crit_rel_humid(const AeroParticle &self, const EnvState &env_state) { - double approx_crit_rel_humid; - f_aero_particle_approx_crit_rel_humid( - self.ptr.f_arg(), - self.aero_data.get(), - env_state.ptr.f_arg(), - &approx_crit_rel_humid - ); - return approx_crit_rel_humid; + return get_derived_value_env_state( + self, + env_state, + f_aero_particle_approx_crit_rel_humid); } static auto crit_rel_humid(const AeroParticle &self, const EnvState &env_state) { - double crit_rel_humid; - f_aero_particle_crit_rel_humid( - self.ptr.f_arg(), - self.aero_data.get(), - env_state.ptr.f_arg(), - &crit_rel_humid - ); - return crit_rel_humid; + return get_derived_value_env_state( + self, + env_state, + f_aero_particle_crit_rel_humid); } static auto crit_diameter(const AeroParticle &self, const EnvState &env_state) { - double crit_diameter; - f_aero_particle_crit_diameter( - self.ptr.f_arg(), - self.aero_data.get(), - env_state.ptr.f_arg(), - &crit_diameter - ); - return crit_diameter; + return get_derived_value_env_state( + self, + env_state, + f_aero_particle_crit_diameter); } static auto coagulate(const AeroParticle &self, const AeroParticle &two) { @@ -357,39 +313,19 @@ struct AeroParticle { } static auto least_create_time(const AeroParticle &self) { - double val; - f_aero_particle_least_create_time( - self.ptr.f_arg(), - &val - ); - return val; + return get_value(self, f_aero_particle_least_create_time); } static auto greatest_create_time(const AeroParticle &self) { - double val; - f_aero_particle_greatest_create_time( - self.ptr.f_arg(), - &val - ); - return val; + return get_value(self, f_aero_particle_greatest_create_time); } static auto id(const AeroParticle &self) { - int64_t val; - f_aero_particle_id( - self.ptr.f_arg(), - &val - ); - return val; + return get_value(self, f_aero_particle_id); } static auto is_frozen(const AeroParticle &self) { - int val; - f_aero_particle_frozen( - self.ptr.f_arg(), - &val - ); - return val; + return get_value(self, f_aero_particle_frozen); } static auto refract_shell(const AeroParticle &self) { @@ -414,42 +350,23 @@ struct AeroParticle { return refract_core; } - static void set_weight_class(AeroParticle &self, const int weight_class) { - f_aero_particle_set_weight_class( - self.ptr.f_arg_non_const(), - &weight_class - ); - } - static auto get_weight_class(const AeroParticle &self) { - int weight_class; - - f_aero_particle_get_weight_class( - self.ptr.f_arg(), - &weight_class - ); - return weight_class; + return get_value(self, f_aero_particle_get_weight_class); } - static void set_weight_group(AeroParticle &self, const int weight_group) { - f_aero_particle_set_weight_group( - self.ptr.f_arg_non_const(), - &weight_group - ); + static void set_weight_class(AeroParticle &self, const int weight_class) { + set_value(self, f_aero_particle_set_weight_class, weight_class); } static auto get_weight_group(const AeroParticle &self) { - int weight_group; + return get_value(self, f_aero_particle_get_weight_group); + } - f_aero_particle_get_weight_group( - self.ptr.f_arg(), - &weight_group - ); - return weight_group; + static void set_weight_group(AeroParticle &self, const int weight_group) { + set_value(self, f_aero_particle_set_weight_group, weight_group); } static void new_id(AeroParticle &self) { - f_aero_particle_new_id(self.ptr.f_arg_non_const()); } }; From c3dd8f01447f8aeebcf656ef49279acabc1870fe Mon Sep 17 00:00:00 2001 From: Jeff Curtis Date: Mon, 24 Nov 2025 17:01:43 -0600 Subject: [PATCH 04/15] make setters for envstate non_const --- src/env_state.hpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/env_state.hpp b/src/env_state.hpp index 659b33d9..47814529 100644 --- a/src/env_state.hpp +++ b/src/env_state.hpp @@ -58,15 +58,15 @@ struct EnvState { } template - static void set_value(const EnvState &self, Func func, T value) { - func(self.ptr.f_arg(), &value); + static void set_value(EnvState &self, Func func, T value) { + func(self.ptr.f_arg_non_const(), &value); } static double temp(const EnvState &self) { return get_value(self, f_env_state_get_temperature); } - static void set_temperature(const EnvState &self, double temperature) { + static void set_temperature(EnvState &self, double temperature) { set_value(self, f_env_state_set_temperature, temperature); } @@ -74,7 +74,7 @@ struct EnvState { return get_value(self, f_env_state_get_rel_humid); } - static void set_height(const EnvState &self, const double height) { + static void set_height(EnvState &self, const double height) { set_value(self, f_env_state_set_height, height); } @@ -83,7 +83,7 @@ struct EnvState { } static void set_additive_kernel_coefficient( - const EnvState &self, + EnvState &self, const double additive_kernel_coefficient) { set_value( @@ -95,7 +95,7 @@ struct EnvState { return get_value(self, f_env_state_get_additive_kernel_coefficient); } - static void set_pressure(const EnvState &self, const double pressure) { + static void set_pressure(EnvState &self, const double pressure) { set_value(self, f_env_state_set_pressure, pressure); } @@ -123,7 +123,7 @@ struct EnvState { return get_value(self, f_env_state_get_latitude); } - static void set_latitude(const EnvState &self, const double latitude) { + static void set_latitude(EnvState &self, const double latitude) { set_value(self, f_env_state_set_latitude, latitude); } @@ -131,7 +131,7 @@ struct EnvState { return get_value(self, f_env_state_get_longitude); } - static void set_longitude(const EnvState &self, const double longitude) { + static void set_longitude(EnvState &self, const double longitude) { set_value(self, f_env_state_set_longitude, longitude); } @@ -139,7 +139,7 @@ struct EnvState { return get_value(self, f_env_state_get_altitude); } - static void set_altitude(const EnvState &self, const double altitude) { + static void set_altitude(EnvState &self, const double altitude) { set_value(self, f_env_state_set_altitude, altitude); } From aa328b54c725ac4c795dcd44d762ff48d6e64782 Mon Sep 17 00:00:00 2001 From: Jeff Curtis Date: Mon, 24 Nov 2025 17:03:06 -0600 Subject: [PATCH 05/15] make default type double and remove double in aero_particle setters and getters --- src/aero_particle.hpp | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/aero_particle.hpp b/src/aero_particle.hpp index c123b7bd..40e46d6f 100644 --- a/src/aero_particle.hpp +++ b/src/aero_particle.hpp @@ -68,19 +68,19 @@ struct AeroParticle { throw std::runtime_error("AeroData size mistmatch"); } - template + template static T get_value(const AeroParticle &self, Func func) { T value{}; func(self.ptr.f_arg(), &value); return value; } - template + template static void set_value(AeroParticle &self, Func func, T value) { func(self.ptr.f_arg_non_const(), &value); } - template + template static T get_derived_value(const AeroParticle &self, Func func) { T value{}; @@ -88,7 +88,7 @@ struct AeroParticle { return value; } - template + template static T get_derived_value_env_state( const AeroParticle &self, const EnvState &env_state, @@ -138,27 +138,27 @@ struct AeroParticle { } static auto dry_volume(const AeroParticle &self) { - return get_derived_value(self, f_aero_particle_dry_volume); + return get_derived_value(self, f_aero_particle_dry_volume); } static auto radius(const AeroParticle &self) { - return get_derived_value(self, f_aero_particle_radius); + return get_derived_value(self, f_aero_particle_radius); } static auto dry_radius(const AeroParticle &self) { - return get_derived_value(self, f_aero_particle_dry_radius); + return get_derived_value(self, f_aero_particle_dry_radius); } static auto diameter(const AeroParticle &self) { - return get_derived_value(self, f_aero_particle_diameter); + return get_derived_value(self, f_aero_particle_diameter); } static auto dry_diameter(const AeroParticle &self) { - return get_derived_value(self, f_aero_particle_dry_diameter); + return get_derived_value(self, f_aero_particle_dry_diameter); } static auto mass(const AeroParticle &self) { - return get_derived_value(self, f_aero_particle_mass); + return get_derived_value(self, f_aero_particle_mass); } static auto species_mass(const AeroParticle &self, const int &i_spec) { @@ -197,40 +197,40 @@ struct AeroParticle { } static auto solute_kappa(const AeroParticle &self) { - return get_derived_value(self, f_aero_particle_solute_kappa); + return get_derived_value(self, f_aero_particle_solute_kappa); } static auto moles(const AeroParticle &self) { - return get_derived_value(self, f_aero_particle_moles); + return get_derived_value(self, f_aero_particle_moles); } static auto mobility_diameter(const AeroParticle &self, const EnvState &env_state) { - return get_derived_value_env_state( + return get_derived_value_env_state( self, env_state, f_aero_particle_mobility_diameter); } static auto density(const AeroParticle &self) { - return get_derived_value(self, f_aero_particle_density); + return get_derived_value(self, f_aero_particle_density); } static auto approx_crit_rel_humid(const AeroParticle &self, const EnvState &env_state) { - return get_derived_value_env_state( + return get_derived_value_env_state( self, env_state, f_aero_particle_approx_crit_rel_humid); } static auto crit_rel_humid(const AeroParticle &self, const EnvState &env_state) { - return get_derived_value_env_state( + return get_derived_value_env_state( self, env_state, f_aero_particle_crit_rel_humid); } static auto crit_diameter(const AeroParticle &self, const EnvState &env_state) { - return get_derived_value_env_state( + return get_derived_value_env_state( self, env_state, f_aero_particle_crit_diameter); @@ -313,11 +313,11 @@ struct AeroParticle { } static auto least_create_time(const AeroParticle &self) { - return get_value(self, f_aero_particle_least_create_time); + return get_value(self, f_aero_particle_least_create_time); } static auto greatest_create_time(const AeroParticle &self) { - return get_value(self, f_aero_particle_greatest_create_time); + return get_value(self, f_aero_particle_greatest_create_time); } static auto id(const AeroParticle &self) { From efdc266aa1669e56f7da7407eb5655b4ed982bae Mon Sep 17 00:00:00 2001 From: Jeffrey Curtis Date: Mon, 24 Nov 2025 22:32:56 -0600 Subject: [PATCH 06/15] move setter and getter. refactor derived getter for aero_particle --- src/aero_particle.hpp | 72 +++++++++++++++---------------------------- src/env_state.hpp | 53 +++++++++++++------------------ src/getters.hpp | 23 ++++++++++++++ 3 files changed, 68 insertions(+), 80 deletions(-) create mode 100644 src/getters.hpp diff --git a/src/aero_particle.hpp b/src/aero_particle.hpp index 40e46d6f..8e90d3f7 100644 --- a/src/aero_particle.hpp +++ b/src/aero_particle.hpp @@ -68,34 +68,10 @@ struct AeroParticle { throw std::runtime_error("AeroData size mistmatch"); } - template - static T get_value(const AeroParticle &self, Func func) { + template + static T get_derived_value(const SelfType &self, Func func, Args&&... args) { T value{}; - func(self.ptr.f_arg(), &value); - return value; - } - - template - static void set_value(AeroParticle &self, Func func, T value) { - func(self.ptr.f_arg_non_const(), &value); - } - - template - static T get_derived_value(const AeroParticle &self, Func func) - { - T value{}; - func(self.ptr.f_arg(), self.aero_data.get(), &value); - return value; - } - - template - static T get_derived_value_env_state( - const AeroParticle &self, - const EnvState &env_state, - Func func) - { - T value{}; - func(self.ptr.f_arg(), self.aero_data.get(), env_state.ptr.f_arg(), &value); + func(self.ptr.f_arg(), self.aero_data.get(), std::forward(args)..., &value); return value; } @@ -112,7 +88,7 @@ struct AeroParticle { } static auto volume(const AeroParticle &self) { - return get_value(self, f_aero_particle_volume); + return pypartmc::get_value(self, f_aero_particle_volume); } static auto species_volume(const AeroParticle &self, const int &i_spec) { @@ -205,10 +181,10 @@ struct AeroParticle { } static auto mobility_diameter(const AeroParticle &self, const EnvState &env_state) { - return get_derived_value_env_state( + return get_derived_value( self, - env_state, - f_aero_particle_mobility_diameter); + f_aero_particle_mobility_diameter, + env_state.ptr.f_arg()); } static auto density(const AeroParticle &self) { @@ -216,24 +192,24 @@ struct AeroParticle { } static auto approx_crit_rel_humid(const AeroParticle &self, const EnvState &env_state) { - return get_derived_value_env_state( + return get_derived_value( self, - env_state, - f_aero_particle_approx_crit_rel_humid); + f_aero_particle_approx_crit_rel_humid, + env_state.ptr.f_arg()); } static auto crit_rel_humid(const AeroParticle &self, const EnvState &env_state) { - return get_derived_value_env_state( + return get_derived_value( self, - env_state, - f_aero_particle_crit_rel_humid); + f_aero_particle_crit_rel_humid, + env_state.ptr.f_arg()); } static auto crit_diameter(const AeroParticle &self, const EnvState &env_state) { - return get_derived_value_env_state( + return get_derived_value( self, - env_state, - f_aero_particle_crit_diameter); + f_aero_particle_crit_diameter, + env_state.ptr.f_arg()); } static auto coagulate(const AeroParticle &self, const AeroParticle &two) { @@ -313,19 +289,19 @@ struct AeroParticle { } static auto least_create_time(const AeroParticle &self) { - return get_value(self, f_aero_particle_least_create_time); + return pypartmc::get_value(self, f_aero_particle_least_create_time); } static auto greatest_create_time(const AeroParticle &self) { - return get_value(self, f_aero_particle_greatest_create_time); + return pypartmc::get_value(self, f_aero_particle_greatest_create_time); } static auto id(const AeroParticle &self) { - return get_value(self, f_aero_particle_id); + return pypartmc::get_value(self, f_aero_particle_id); } static auto is_frozen(const AeroParticle &self) { - return get_value(self, f_aero_particle_frozen); + return pypartmc::get_value(self, f_aero_particle_frozen); } static auto refract_shell(const AeroParticle &self) { @@ -351,19 +327,19 @@ struct AeroParticle { } static auto get_weight_class(const AeroParticle &self) { - return get_value(self, f_aero_particle_get_weight_class); + return pypartmc::get_value(self, f_aero_particle_get_weight_class); } static void set_weight_class(AeroParticle &self, const int weight_class) { - set_value(self, f_aero_particle_set_weight_class, weight_class); + pypartmc::set_value(self, f_aero_particle_set_weight_class, weight_class); } static auto get_weight_group(const AeroParticle &self) { - return get_value(self, f_aero_particle_get_weight_group); + return pypartmc::get_value(self, f_aero_particle_get_weight_group); } static void set_weight_group(AeroParticle &self, const int weight_group) { - set_value(self, f_aero_particle_set_weight_group, weight_group); + pypartmc::set_value(self, f_aero_particle_set_weight_group, weight_group); } static void new_id(AeroParticle &self) { diff --git a/src/env_state.hpp b/src/env_state.hpp index 47814529..6eec4e60 100644 --- a/src/env_state.hpp +++ b/src/env_state.hpp @@ -8,6 +8,7 @@ #include "json_resource.hpp" #include "pmc_resource.hpp" +#include "getters.hpp" extern "C" void f_env_state_ctor(void *ptr) noexcept; extern "C" void f_env_state_dtor(void *ptr) noexcept; @@ -50,97 +51,85 @@ struct EnvState { ptr(f_env_state_ctor, f_env_state_dtor) {} - template - static T get_value(const EnvState &self, Func func) { - T value{}; - func(self.ptr.f_arg(), &value); - return value; - } - - template - static void set_value(EnvState &self, Func func, T value) { - func(self.ptr.f_arg_non_const(), &value); - } - static double temp(const EnvState &self) { - return get_value(self, f_env_state_get_temperature); + return pypartmc::get_value(self, f_env_state_get_temperature); } static void set_temperature(EnvState &self, double temperature) { - set_value(self, f_env_state_set_temperature, temperature); + pypartmc::set_value(self, f_env_state_set_temperature, temperature); } static auto rh(const EnvState &self) { - return get_value(self, f_env_state_get_rel_humid); + return pypartmc::get_value(self, f_env_state_get_rel_humid); } static void set_height(EnvState &self, const double height) { - set_value(self, f_env_state_set_height, height); + pypartmc::set_value(self, f_env_state_set_height, height); } static double get_height(const EnvState &self) { - return get_value(self, f_env_state_get_height); + return pypartmc::get_value(self, f_env_state_get_height); } static void set_additive_kernel_coefficient( EnvState &self, const double additive_kernel_coefficient) { - set_value( + pypartmc::set_value( self, f_env_state_set_additive_kernel_coefficient, additive_kernel_coefficient); } static double get_additive_kernel_coefficient(const EnvState &self) { - return get_value(self, f_env_state_get_additive_kernel_coefficient); + return pypartmc::get_value(self, f_env_state_get_additive_kernel_coefficient); } static void set_pressure(EnvState &self, const double pressure) { - set_value(self, f_env_state_set_pressure, pressure); + pypartmc::set_value(self, f_env_state_set_pressure, pressure); } static double get_pressure(const EnvState &self) { - return get_value(self, f_env_state_get_pressure); + return pypartmc::get_value(self, f_env_state_get_pressure); } static auto get_elapsed_time(const EnvState &self) { - return get_value(self, f_env_state_get_elapsed_time); + return pypartmc::get_value(self, f_env_state_get_elapsed_time); } static auto get_start_time(const EnvState &self) { - return get_value(self, f_env_state_get_start_time); + return pypartmc::get_value(self, f_env_state_get_start_time); } static auto air_density(const EnvState &self) { - return get_value(self, f_env_state_air_dens); + return pypartmc::get_value(self, f_env_state_air_dens); } static auto air_molar_density(const EnvState &self) { - return get_value(self, f_env_state_air_molar_dens); + return pypartmc::get_value(self, f_env_state_air_molar_dens); } static auto get_latitude(const EnvState &self) { - return get_value(self, f_env_state_get_latitude); + return pypartmc::get_value(self, f_env_state_get_latitude); } static void set_latitude(EnvState &self, const double latitude) { - set_value(self, f_env_state_set_latitude, latitude); + pypartmc::set_value(self, f_env_state_set_latitude, latitude); } static auto get_longitude(const EnvState &self) { - return get_value(self, f_env_state_get_longitude); + return pypartmc::get_value(self, f_env_state_get_longitude); } static void set_longitude(EnvState &self, const double longitude) { - set_value(self, f_env_state_set_longitude, longitude); + pypartmc::set_value(self, f_env_state_set_longitude, longitude); } static auto get_altitude(const EnvState &self) { - return get_value(self, f_env_state_get_altitude); + return pypartmc::get_value(self, f_env_state_get_altitude); } static void set_altitude(EnvState &self, const double altitude) { - set_value(self, f_env_state_set_altitude, altitude); + pypartmc::set_value(self, f_env_state_set_altitude, altitude); } static auto ppb_to_conc(const EnvState &self, const double ppb) { @@ -166,7 +155,7 @@ struct EnvState { } static auto sat_vapor_pressure(const EnvState &self) { - return get_value(self, f_env_state_sat_vapor_pressure); + return pypartmc::get_value(self, f_env_state_sat_vapor_pressure); } }; diff --git a/src/getters.hpp b/src/getters.hpp new file mode 100644 index 00000000..3d9e4d81 --- /dev/null +++ b/src/getters.hpp @@ -0,0 +1,23 @@ +/*################################################################################################## +# This file is a part of PyPartMC licensed under the GNU General Public License v3 (LICENSE file) # +# Copyright (C) 2022 University of Illinois Urbana-Champaign # +# Authors: https://github.com/open-atmos/PyPartMC/graphs/contributors # +##################################################################################################*/ + +#pragma once + +namespace pypartmc { // possible namespace to avoid name conflicts + +template +inline T get_value(const SelfType &self, Func func) { // inline to keep it header-only + T value{}; + func(self.ptr.f_arg(), &value); + return value; +} + +template +inline void set_value(SelfType &self, Func func, T value) { + func(self.ptr.f_arg_non_const(), &value); +} + +} From 8d4054331ecb4d9419044616109dc2eb95ec1d74 Mon Sep 17 00:00:00 2001 From: Jeffrey Curtis Date: Wed, 3 Dec 2025 12:51:12 -0600 Subject: [PATCH 07/15] first pass at templates in AeroState for returning all particle values --- src/aero_state.hpp | 101 +++++++++++---------------------------------- 1 file changed, 25 insertions(+), 76 deletions(-) diff --git a/src/aero_state.hpp b/src/aero_state.hpp index 68365c39..d3e544df 100644 --- a/src/aero_state.hpp +++ b/src/aero_state.hpp @@ -305,6 +305,15 @@ struct AeroState { camp_core.ptr.f_arg()); } + template + static auto get_particle_array_values(const AeroState &self, Func f, ExtraArgs&&... extra) { + int len; + f_aero_state_len(self.ptr.f_arg(), &len); + std::valarray arr(len); + f(self.ptr.f_arg(), std::forward(extra)..., std::begin(arr), &len); + return arr; + } + static std::size_t __len__(const AeroState &self) { int len; f_aero_state_len( @@ -335,21 +344,9 @@ struct AeroState { } static auto num_concs(const AeroState &self) { - int len; - f_aero_state_len( - self.ptr.f_arg(), - &len - ); - std::valarray num_concs(len); - - f_aero_state_num_concs( - self.ptr.f_arg(), - self.aero_data->ptr.f_arg(), - begin(num_concs), - &len - ); - - return num_concs; + auto fn = f_aero_state_num_concs; + auto aero_data_ptr = self.aero_data->ptr.f_arg(); + return get_particle_array_values(self, fn, aero_data_ptr); } static auto masses( @@ -396,40 +393,16 @@ struct AeroState { } static auto dry_diameters(const AeroState &self) { - int len; - f_aero_state_len( - self.ptr.f_arg(), - &len - ); - std::valarray dry_diameters(len); - - f_aero_state_dry_diameters( - self.ptr.f_arg(), - self.aero_data->ptr.f_arg(), - begin(dry_diameters), - &len - ); - - return dry_diameters; + auto fn = f_aero_state_dry_diameters; + auto aero_data_ptr = self.aero_data->ptr.f_arg(); + return get_particle_array_values(self, fn, aero_data_ptr); } static auto mobility_diameters(const AeroState &self, const EnvState &env_state) { - int len; - f_aero_state_len( - self.ptr.f_arg(), - &len - ); - std::valarray mobility_diameters(len); - - f_aero_state_mobility_diameters( - self.ptr.f_arg(), - self.aero_data->ptr.f_arg(), - env_state.ptr.f_arg(), - begin(mobility_diameters), - &len - ); - - return mobility_diameters; + auto fn = f_aero_state_mobility_diameters; + auto aero_data_ptr = self.aero_data->ptr.f_arg(); + auto env_state_ptr = env_state.ptr.f_arg(); + return get_particle_array_values(self, fn, aero_data_ptr, env_state_ptr); } static auto diameters( @@ -502,22 +475,10 @@ struct AeroState { const AeroState &self, const EnvState &env_state ) { - int len; - f_aero_state_len( - self.ptr.f_arg(), - &len - ); - std::valarray crit_rel_humids(len); - - f_aero_state_crit_rel_humids( - self.ptr.f_arg(), - self.aero_data->ptr.f_arg(), - env_state.ptr.f_arg(), - begin(crit_rel_humids), - &len - ); - - return crit_rel_humids; + auto fn = f_aero_state_crit_rel_humids; + auto aero_data_ptr = self.aero_data->ptr.f_arg(); + auto env_state_ptr = env_state.ptr.f_arg(); + return get_particle_array_values(self, fn, aero_data_ptr, env_state_ptr); } static void make_dry( @@ -530,20 +491,8 @@ struct AeroState { } static auto ids(const AeroState &self) { - int len; - f_aero_state_len( - self.ptr.f_arg(), - &len - ); - std::valarray ids(len); - - f_aero_state_ids( - self.ptr.f_arg(), - begin(ids), - &len - ); - - return ids; + auto fn = f_aero_state_ids; + return get_particle_array_values(self, fn); } static auto mixing_state( From 761b9151210d67cea7a6a40f2e9e088fa74394ea Mon Sep 17 00:00:00 2001 From: Jeffrey Curtis Date: Wed, 3 Dec 2025 14:10:02 -0600 Subject: [PATCH 08/15] set default array to double --- src/aero_state.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/aero_state.hpp b/src/aero_state.hpp index d3e544df..27599525 100644 --- a/src/aero_state.hpp +++ b/src/aero_state.hpp @@ -305,7 +305,7 @@ struct AeroState { camp_core.ptr.f_arg()); } - template + template static auto get_particle_array_values(const AeroState &self, Func f, ExtraArgs&&... extra) { int len; f_aero_state_len(self.ptr.f_arg(), &len); @@ -346,7 +346,7 @@ struct AeroState { static auto num_concs(const AeroState &self) { auto fn = f_aero_state_num_concs; auto aero_data_ptr = self.aero_data->ptr.f_arg(); - return get_particle_array_values(self, fn, aero_data_ptr); + return get_particle_array_values(self, fn, aero_data_ptr); } static auto masses( @@ -395,14 +395,14 @@ struct AeroState { static auto dry_diameters(const AeroState &self) { auto fn = f_aero_state_dry_diameters; auto aero_data_ptr = self.aero_data->ptr.f_arg(); - return get_particle_array_values(self, fn, aero_data_ptr); + return get_particle_array_values(self, fn, aero_data_ptr); } static auto mobility_diameters(const AeroState &self, const EnvState &env_state) { auto fn = f_aero_state_mobility_diameters; auto aero_data_ptr = self.aero_data->ptr.f_arg(); auto env_state_ptr = env_state.ptr.f_arg(); - return get_particle_array_values(self, fn, aero_data_ptr, env_state_ptr); + return get_particle_array_values(self, fn, aero_data_ptr, env_state_ptr); } static auto diameters( @@ -478,7 +478,7 @@ struct AeroState { auto fn = f_aero_state_crit_rel_humids; auto aero_data_ptr = self.aero_data->ptr.f_arg(); auto env_state_ptr = env_state.ptr.f_arg(); - return get_particle_array_values(self, fn, aero_data_ptr, env_state_ptr); + return get_particle_array_values(self, fn, aero_data_ptr, env_state_ptr); } static void make_dry( From 9160ae6d64002730f34fe854099e4008cfcc6f56 Mon Sep 17 00:00:00 2001 From: Jeffrey Curtis Date: Fri, 5 Dec 2025 09:15:05 -0600 Subject: [PATCH 09/15] minor --- src/aero_state.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aero_state.hpp b/src/aero_state.hpp index 27599525..842996a6 100644 --- a/src/aero_state.hpp +++ b/src/aero_state.hpp @@ -310,7 +310,7 @@ struct AeroState { int len; f_aero_state_len(self.ptr.f_arg(), &len); std::valarray arr(len); - f(self.ptr.f_arg(), std::forward(extra)..., std::begin(arr), &len); + f(self.ptr.f_arg(), std::forward(extra)..., begin(arr), &len); return arr; } From 27535a1684c175b6dc84b6238dcef89108c5689a Mon Sep 17 00:00:00 2001 From: Jeff Curtis Date: Mon, 8 Dec 2025 14:16:16 -0600 Subject: [PATCH 10/15] switch aero_state and aero_particle templates to generic getters --- src/aero_particle.hpp | 37 +++++++++++++++++-------------------- src/aero_state.hpp | 24 ++++++++++-------------- src/getters.hpp | 19 +++++++++++++++++++ 3 files changed, 46 insertions(+), 34 deletions(-) diff --git a/src/aero_particle.hpp b/src/aero_particle.hpp index 8e90d3f7..cfbaf31a 100644 --- a/src/aero_particle.hpp +++ b/src/aero_particle.hpp @@ -68,13 +68,6 @@ struct AeroParticle { throw std::runtime_error("AeroData size mistmatch"); } - template - static T get_derived_value(const SelfType &self, Func func, Args&&... args) { - T value{}; - func(self.ptr.f_arg(), self.aero_data.get(), std::forward(args)..., &value); - return value; - } - static auto volumes(const AeroParticle &self) { int len = AeroData::__len__(*self.aero_data); @@ -114,27 +107,27 @@ struct AeroParticle { } static auto dry_volume(const AeroParticle &self) { - return get_derived_value(self, f_aero_particle_dry_volume); + return pypartmc::get_derived_value(self, f_aero_particle_dry_volume, self.aero_data.get()); } static auto radius(const AeroParticle &self) { - return get_derived_value(self, f_aero_particle_radius); + return pypartmc::get_derived_value(self, f_aero_particle_radius, self.aero_data.get()); } static auto dry_radius(const AeroParticle &self) { - return get_derived_value(self, f_aero_particle_dry_radius); + return pypartmc::get_derived_value(self, f_aero_particle_dry_radius, self.aero_data.get()); } static auto diameter(const AeroParticle &self) { - return get_derived_value(self, f_aero_particle_diameter); + return pypartmc::get_derived_value(self, f_aero_particle_diameter, self.aero_data.get()); } static auto dry_diameter(const AeroParticle &self) { - return get_derived_value(self, f_aero_particle_dry_diameter); + return pypartmc::get_derived_value(self, f_aero_particle_dry_diameter, self.aero_data.get()); } static auto mass(const AeroParticle &self) { - return get_derived_value(self, f_aero_particle_mass); + return pypartmc::get_derived_value(self, f_aero_particle_mass, self.aero_data.get()); } static auto species_mass(const AeroParticle &self, const int &i_spec) { @@ -173,42 +166,46 @@ struct AeroParticle { } static auto solute_kappa(const AeroParticle &self) { - return get_derived_value(self, f_aero_particle_solute_kappa); + return pypartmc::get_derived_value(self, f_aero_particle_solute_kappa, self.aero_data.get()); } static auto moles(const AeroParticle &self) { - return get_derived_value(self, f_aero_particle_moles); + return pypartmc::get_derived_value(self, f_aero_particle_moles, self.aero_data.get()); } static auto mobility_diameter(const AeroParticle &self, const EnvState &env_state) { - return get_derived_value( + return pypartmc::get_derived_value( self, f_aero_particle_mobility_diameter, + self.aero_data.get(), env_state.ptr.f_arg()); } static auto density(const AeroParticle &self) { - return get_derived_value(self, f_aero_particle_density); + return pypartmc::get_derived_value(self, f_aero_particle_density, self.aero_data.get()); } static auto approx_crit_rel_humid(const AeroParticle &self, const EnvState &env_state) { - return get_derived_value( + return pypartmc::get_derived_value( self, f_aero_particle_approx_crit_rel_humid, + self.aero_data.get(), env_state.ptr.f_arg()); } static auto crit_rel_humid(const AeroParticle &self, const EnvState &env_state) { - return get_derived_value( + return pypartmc::get_derived_value( self, f_aero_particle_crit_rel_humid, + self.aero_data.get(), env_state.ptr.f_arg()); } static auto crit_diameter(const AeroParticle &self, const EnvState &env_state) { - return get_derived_value( + return pypartmc::get_derived_value( self, f_aero_particle_crit_diameter, + self.aero_data.get(), env_state.ptr.f_arg()); } diff --git a/src/aero_state.hpp b/src/aero_state.hpp index 842996a6..f7c1af71 100644 --- a/src/aero_state.hpp +++ b/src/aero_state.hpp @@ -305,15 +305,6 @@ struct AeroState { camp_core.ptr.f_arg()); } - template - static auto get_particle_array_values(const AeroState &self, Func f, ExtraArgs&&... extra) { - int len; - f_aero_state_len(self.ptr.f_arg(), &len); - std::valarray arr(len); - f(self.ptr.f_arg(), std::forward(extra)..., begin(arr), &len); - return arr; - } - static std::size_t __len__(const AeroState &self) { int len; f_aero_state_len( @@ -345,8 +336,9 @@ struct AeroState { static auto num_concs(const AeroState &self) { auto fn = f_aero_state_num_concs; + auto len_fn = f_aero_state_len; auto aero_data_ptr = self.aero_data->ptr.f_arg(); - return get_particle_array_values(self, fn, aero_data_ptr); + return pypartmc::get_array_values(self, fn, len_fn, aero_data_ptr); } static auto masses( @@ -394,15 +386,17 @@ struct AeroState { static auto dry_diameters(const AeroState &self) { auto fn = f_aero_state_dry_diameters; + auto len_fn = f_aero_state_len; auto aero_data_ptr = self.aero_data->ptr.f_arg(); - return get_particle_array_values(self, fn, aero_data_ptr); + return pypartmc::get_array_values(self, fn, len_fn, aero_data_ptr); } static auto mobility_diameters(const AeroState &self, const EnvState &env_state) { auto fn = f_aero_state_mobility_diameters; + auto len_fn = f_aero_state_len; auto aero_data_ptr = self.aero_data->ptr.f_arg(); auto env_state_ptr = env_state.ptr.f_arg(); - return get_particle_array_values(self, fn, aero_data_ptr, env_state_ptr); + return pypartmc::get_array_values(self, fn, len_fn, aero_data_ptr, env_state_ptr); } static auto diameters( @@ -476,9 +470,10 @@ struct AeroState { const EnvState &env_state ) { auto fn = f_aero_state_crit_rel_humids; + auto len_fn = f_aero_state_len; auto aero_data_ptr = self.aero_data->ptr.f_arg(); auto env_state_ptr = env_state.ptr.f_arg(); - return get_particle_array_values(self, fn, aero_data_ptr, env_state_ptr); + return pypartmc::get_array_values(self, fn, len_fn, aero_data_ptr, env_state_ptr); } static void make_dry( @@ -492,7 +487,8 @@ struct AeroState { static auto ids(const AeroState &self) { auto fn = f_aero_state_ids; - return get_particle_array_values(self, fn); + auto len_fn = f_aero_state_len; + return pypartmc::get_array_values(self, fn, len_fn); } static auto mixing_state( diff --git a/src/getters.hpp b/src/getters.hpp index 3d9e4d81..c520aca0 100644 --- a/src/getters.hpp +++ b/src/getters.hpp @@ -6,6 +6,9 @@ #pragma once +#include +#include + namespace pypartmc { // possible namespace to avoid name conflicts template @@ -20,4 +23,20 @@ inline void set_value(SelfType &self, Func func, T value) { func(self.ptr.f_arg_non_const(), &value); } +template +inline T get_derived_value(const SelfType &self, Func func, Args&&... args) { + T value{}; + func(self.ptr.f_arg(), std::forward(args)..., &value); + return value; +} + +template +static auto get_array_values(const SelfType &self, Func f, LenF len_fn, + ExtraArgs&&... extra) { + int len; + len_fn(self.ptr.f_arg(), &len); + std::valarray arr(len); + f(self.ptr.f_arg(), std::forward(extra)..., begin(arr), &len); + return arr; + } } From 5922b09bf6f9fe96f09247021dae4ec98fef16bd Mon Sep 17 00:00:00 2001 From: Jeff Curtis Date: Mon, 8 Dec 2025 14:17:29 -0600 Subject: [PATCH 11/15] try a few getters for aero_mode --- src/aero_mode.hpp | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/src/aero_mode.hpp b/src/aero_mode.hpp index 46f98cbc..092b8957 100644 --- a/src/aero_mode.hpp +++ b/src/aero_mode.hpp @@ -9,6 +9,7 @@ #include "pmc_resource.hpp" #include "aero_data.hpp" #include "bin_grid.hpp" +#include "getters.hpp" extern "C" void f_aero_mode_ctor( void *ptr @@ -204,7 +205,7 @@ struct AeroMode { &len ); - return data; + return data; } static void set_vol_frac(AeroMode &self, const std::valarray&data) @@ -223,11 +224,9 @@ struct AeroMode { static auto get_vol_frac(const AeroMode &self) { - int len; - f_aero_mode_get_n_spec(self.ptr.f_arg(), &len); - std::valarray data(len); - f_aero_mode_get_vol_frac(self.ptr.f_arg(), begin(data), &len); - return data; + auto fn = f_aero_mode_get_vol_frac; + auto len_fn = f_aero_mode_get_n_spec; + return pypartmc::get_array_values(self, fn, len_fn); } static void set_vol_frac_std(AeroMode &self, const std::valarray&data) @@ -246,17 +245,13 @@ struct AeroMode { static auto get_vol_frac_std(const AeroMode &self) { - int len; - f_aero_mode_get_n_spec(self.ptr.f_arg(), &len); - std::valarray data(len); - f_aero_mode_get_vol_frac_std(self.ptr.f_arg(), begin(data), &len); - return data; + auto fn = f_aero_mode_get_vol_frac_std; + auto len_fn = f_aero_mode_get_n_spec; + return pypartmc::get_array_values(self, fn, len_fn); } static auto get_char_radius(const AeroMode &self){ - double val; - f_aero_mode_get_char_radius(self.ptr.f_arg(), &val); - return val; + return pypartmc::get_value(self, f_aero_mode_get_char_radius); } static void set_char_radius(AeroMode &self, const double &val){ @@ -264,9 +259,7 @@ struct AeroMode { } static auto get_gsd(const AeroMode &self){ - double val; - f_aero_mode_get_gsd(self.ptr.f_arg(), &val); - return val; + return pypartmc::get_value(self, f_aero_mode_get_gsd); } static void set_gsd(AeroMode &self, const double &val) { @@ -359,14 +352,8 @@ struct AeroMode { } static auto get_sample_num_conc(const AeroMode &self) { - int len; - f_aero_mode_get_sample_bins(self.ptr.f_arg(), &len); - std::valarray sample_num_conc(len); - f_aero_mode_get_sample_num_conc( - self.ptr.f_arg(), - begin(sample_num_conc), - &len - ); - return sample_num_conc; + auto fn = f_aero_mode_get_sample_num_conc; + auto len_fn = f_aero_mode_get_sample_bins; + return pypartmc::get_array_values(self, fn, len_fn); } }; From 304f1d5647aa55430b7f2bd459cbfc6822dba4fa Mon Sep 17 00:00:00 2001 From: Jeff Curtis Date: Mon, 8 Dec 2025 14:18:00 -0600 Subject: [PATCH 12/15] add some getter calls for scenario --- src/scenario.hpp | 56 +++++++++++------------------------------------- 1 file changed, 12 insertions(+), 44 deletions(-) diff --git a/src/scenario.hpp b/src/scenario.hpp index 7e0596d6..1b8b6bb4 100644 --- a/src/scenario.hpp +++ b/src/scenario.hpp @@ -165,31 +165,15 @@ struct Scenario { } static auto emission_rate_scale(const Scenario &self) { - int len; - - f_scenario_aero_emission_n_times(self.ptr.f_arg(), &len); - std::valarray rates(len); - f_scenario_emission_rates( - self.ptr.f_arg(), - begin(rates), - &len - ); - - return rates; + auto fn = f_scenario_emission_rates; + auto len_fn = f_scenario_aero_emission_n_times; + return pypartmc::get_array_values(self, fn, len_fn); } static auto emission_time(const Scenario &self) { - int len; - - f_scenario_aero_emission_n_times(self.ptr.f_arg(), &len); - std::valarray times(len); - f_scenario_emission_time( - self.ptr.f_arg(), - begin(times), - &len - ); - - return times; + auto fn = f_scenario_emission_time; + auto len_fn = f_scenario_aero_emission_n_times; + return pypartmc::get_array_values(self, fn, len_fn); } static AeroDist* get_aero_background_dist(const Scenario &self, const AeroData &aero_data, const int &idx) { @@ -207,31 +191,15 @@ struct Scenario { } static auto aero_dilution_rate(const Scenario &self) { - int len; - - f_scenario_aero_background_n_times(self.ptr.f_arg(), &len); - std::valarray rates(len); - f_scenario_aero_background_rate_scale( - self.ptr.f_arg(), - begin(rates), - &len - ); - - return rates; + auto fn = f_scenario_aero_background_rate_scale; + auto len_fn = f_scenario_aero_background_n_times; + return pypartmc::get_array_values(self, fn, len_fn); } static auto aero_dilution_time(const Scenario &self) { - int len; - - f_scenario_aero_background_n_times(self.ptr.f_arg(), &len); - std::valarray times(len); - f_scenario_aero_background_time( - self.ptr.f_arg(), - begin(times), - &len - ); - - return times; + auto fn = f_scenario_aero_background_time; + auto len_fn = f_scenario_aero_background_n_times; + return pypartmc::get_array_values(self, fn, len_fn); } }; From 70f8202ce6919325b29d6835758caad382f456a5 Mon Sep 17 00:00:00 2001 From: Jeff Curtis Date: Mon, 8 Dec 2025 16:26:56 -0600 Subject: [PATCH 13/15] aero_data setters and getters --- src/aero_data.hpp | 45 ++++++++------------------------------------- 1 file changed, 8 insertions(+), 37 deletions(-) diff --git a/src/aero_data.hpp b/src/aero_data.hpp index b57a22f2..87a039a6 100644 --- a/src/aero_data.hpp +++ b/src/aero_data.hpp @@ -8,6 +8,7 @@ #include "pmc_resource.hpp" #include "json_resource.hpp" +#include "getters.hpp" #include "camp_core.hpp" #include "aero_data_parameters.hpp" #include "nanobind/nanobind.h" @@ -78,44 +79,23 @@ struct AeroData { } static std::size_t __len__(const AeroData &self) { - int len; - f_aero_data_len( - self.ptr.f_arg(), - &len - ); - return len; + return pypartmc::get_value(self, f_aero_data_len); } static void set_frac_dim(AeroData &self, const double value) { - f_aero_data_set_frac_dim( - self.ptr.f_arg_non_const(), - &value - ); + pypartmc::set_value(self, f_aero_data_set_frac_dim, value); } static auto get_frac_dim(const AeroData &self) { - double value; - f_aero_data_get_frac_dim( - self.ptr.f_arg(), - &value - ); - return value; + return pypartmc::get_value(self, f_aero_data_get_frac_dim); } static void set_vol_fill_factor(AeroData &self, const double value) { - f_aero_data_set_vol_fill_factor( - self.ptr.f_arg_non_const(), - &value - ); + pypartmc::set_value(self, f_aero_data_set_vol_fill_factor, value); } static auto get_prime_radius(AeroData &self) { - double value; - f_aero_data_get_prime_radius( - self.ptr.f_arg(), - &value - ); - return value; + return pypartmc::get_value(self, f_aero_data_get_prime_radius); } static void set_prime_radius(AeroData &self, const double value) { @@ -126,12 +106,7 @@ struct AeroData { } static auto get_vol_fill_factor(const AeroData &self) { - double value; - f_aero_data_get_vol_fill_factor( - self.ptr.f_arg(), - &value - ); - return value; + return pypartmc::get_value(self, f_aero_data_get_vol_fill_factor); } static auto rad2vol(const AeroData &self, const double radius) { @@ -219,11 +194,7 @@ struct AeroData { } static std::size_t n_source(const AeroData &self) { - int len; - f_aero_data_n_source( - self.ptr.f_arg(), - &len - ); + int len = pypartmc::get_value(self, f_aero_data_n_source); if (len == -1) throw std::runtime_error("No sources defined."); return len; From 80dffc4a4a791f6c64566f06448f083c7d523442 Mon Sep 17 00:00:00 2001 From: Jeff Curtis Date: Tue, 9 Dec 2025 09:18:46 -0600 Subject: [PATCH 14/15] add defined length array --- src/aero_particle.F90 | 4 +-- src/aero_particle.hpp | 75 +++++++++++-------------------------------- src/getters.hpp | 8 +++++ 3 files changed, 28 insertions(+), 59 deletions(-) diff --git a/src/aero_particle.F90 b/src/aero_particle.F90 index ea00442b..2822f8ef 100644 --- a/src/aero_particle.F90 +++ b/src/aero_particle.F90 @@ -165,8 +165,8 @@ subroutine f_aero_particle_species_mass( & subroutine f_aero_particle_species_masses( & aero_particle_ptr_c, & aero_data_ptr_c, & - size_masses, & - masses & + masses, & + size_masses & ) bind(C) type(aero_particle_t), pointer :: aero_particle_ptr_f => null() diff --git a/src/aero_particle.hpp b/src/aero_particle.hpp index cfbaf31a..a3764099 100644 --- a/src/aero_particle.hpp +++ b/src/aero_particle.hpp @@ -24,7 +24,7 @@ extern "C" void f_aero_particle_diameter(const void *aero_particle_ptr, const vo extern "C" void f_aero_particle_dry_diameter(const void *aero_particle_ptr, const void * aero_data_ptr, double *diameter) noexcept; extern "C" void f_aero_particle_mass(const void *aero_particle_ptr, const void *aero_data_ptr, double *mass) noexcept; 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; -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; +extern "C" void f_aero_particle_species_masses(const void *aero_particle_ptr, const void *aero_data_ptr, void *masses, const int *size_masses) noexcept; extern "C" void f_aero_particle_solute_kappa(const void *aero_particle_ptr, const void *aero_data_ptr, void *kappa) noexcept; extern "C" void f_aero_particle_moles(const void *aero_particle_ptr, const void *aero_data_ptr, void *moles) noexcept; 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; @@ -71,13 +71,9 @@ struct AeroParticle { static auto volumes(const AeroParticle &self) { int len = AeroData::__len__(*self.aero_data); - std::valarray data(len); - f_aero_particle_volumes( - self.ptr.f_arg(), - begin(data), - &len - ); - return data; + auto fn = f_aero_particle_volumes; + auto aero_data_ptr = self.aero_data->ptr.f_arg(); + return pypartmc::get_array_values_set_len(self, fn, len); } static auto volume(const AeroParticle &self) { @@ -85,25 +81,14 @@ struct AeroParticle { } static auto species_volume(const AeroParticle &self, const int &i_spec) { - double vol; - f_aero_particle_species_volume( - self.ptr.f_arg(), - &i_spec, - &vol - ); - return vol; + auto fn = f_aero_particle_species_volume; + return pypartmc::get_derived_value(self, fn, &i_spec); } static auto species_volume_by_name(const AeroParticle &self, const std::string &name) { - double vol; const int i_spec = AeroData::spec_by_name(*self.aero_data, name); - - f_aero_particle_species_volume( - self.ptr.f_arg(), - &i_spec, - &vol - ); - return vol; + auto fn = f_aero_particle_species_volume; + return pypartmc::get_derived_value(self, fn, &i_spec); } static auto dry_volume(const AeroParticle &self) { @@ -131,38 +116,20 @@ struct AeroParticle { } static auto species_mass(const AeroParticle &self, const int &i_spec) { - double mass; - f_aero_particle_species_mass( - self.ptr.f_arg(), - &i_spec, - self.aero_data.get(), - &mass - ); - return mass; + auto fn = f_aero_particle_species_mass; + return pypartmc::get_derived_value(self, fn, &i_spec, self.aero_data.get()); } static auto species_mass_by_name(const AeroParticle &self, const std::string &name) { - double mass; - const int i_spec = AeroData::spec_by_name(*self.aero_data, name); - f_aero_particle_species_mass( - self.ptr.f_arg(), - &i_spec, - self.aero_data.get(), - &mass - ); - return mass; + auto fn = f_aero_particle_species_mass; + int i_spec = AeroData::spec_by_name(*self.aero_data, name); + return pypartmc::get_derived_value(self, fn, &i_spec, self.aero_data.get()); } static auto species_masses(const AeroParticle &self) { int len = AeroData::__len__(*self.aero_data); - std::valarray masses(len); - f_aero_particle_species_masses( - self.ptr.f_arg(), - self.aero_data.get(), - &len, - begin(masses) - ); - return masses; + auto fn = f_aero_particle_species_masses; + return pypartmc::get_array_values_set_len(self, fn, len, self.aero_data.get()); } static auto solute_kappa(const AeroParticle &self) { @@ -274,15 +241,9 @@ struct AeroParticle { } static auto sources(const AeroParticle &self) { - int len = AeroData::n_source(*self.aero_data); - std::valarray data(len); - - f_aero_particle_get_component_sources( - self.ptr.f_arg(), - begin(data), - &len - ); - return data; + int len = AeroData::__len__(*self.aero_data); + auto fn = f_aero_particle_get_component_sources; + return pypartmc::get_array_values_set_len(self, fn, len); } static auto least_create_time(const AeroParticle &self) { diff --git a/src/getters.hpp b/src/getters.hpp index c520aca0..8f1a0950 100644 --- a/src/getters.hpp +++ b/src/getters.hpp @@ -39,4 +39,12 @@ static auto get_array_values(const SelfType &self, Func f, LenF len_fn, f(self.ptr.f_arg(), std::forward(extra)..., begin(arr), &len); return arr; } + +template +static auto get_array_values_set_len(const SelfType &self, Func f, int len, + ExtraArgs&&... extra) { + std::valarray arr(len); + f(self.ptr.f_arg(), std::forward(extra)..., begin(arr), &len); + return arr; + } } From a4bc51c1922efaf916efaf714589840b75c55c98 Mon Sep 17 00:00:00 2001 From: Jeff Curtis Date: Tue, 9 Dec 2025 10:02:37 -0600 Subject: [PATCH 15/15] add array calls for bin_grid --- src/bin_grid.hpp | 44 +++++++++----------------------------------- 1 file changed, 9 insertions(+), 35 deletions(-) diff --git a/src/bin_grid.hpp b/src/bin_grid.hpp index f22060ac..92110062 100644 --- a/src/bin_grid.hpp +++ b/src/bin_grid.hpp @@ -7,6 +7,7 @@ #pragma once #include "pmc_resource.hpp" +#include "getters.hpp" #include #include #include "nanobind/stl/string.h" @@ -107,49 +108,22 @@ struct BinGrid { self.ptr.f_arg(), &len ); - len++; - std::valarray data(len); - f_bin_grid_edges( - self.ptr.f_arg(), - begin(data), - &len - ); - - return data; + auto fn = f_bin_grid_edges; + return pypartmc::get_array_values_set_len(self, fn, len + 1); } static auto centers(const BinGrid &self) { - int len; - f_bin_grid_size( - self.ptr.f_arg(), - &len - ); - std::valarray data(len); - - f_bin_grid_centers( - self.ptr.f_arg(), - begin(data), - &len - ); - - return data; + auto len_fn = f_bin_grid_size; + auto fn = f_bin_grid_centers; + return pypartmc::get_array_values(self, fn, len_fn); } static auto widths(const BinGrid &self) { - int len; - f_bin_grid_size( - self.ptr.f_arg(), - &len - ); - std::valarray data(len); - f_bin_grid_widths( - self.ptr.f_arg(), - begin(data), - &len - ); - return data; + auto len_fn = f_bin_grid_size; + auto fn = f_bin_grid_widths; + return pypartmc::get_array_values(self, fn, len_fn); } };