diff --git a/CMakeLists.txt b/CMakeLists.txt index ba70e68b..c9bc81f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,7 +44,8 @@ set(PyPartMC_sources pypartmc.cpp gimmicks.cpp fake_netcdf.cpp fake_spec_file.cpp sys.cpp run_part.F90 run_part_opt.F90 util.F90 aero_data.F90 aero_state.F90 env_state.F90 gas_data.F90 gas_state.F90 scenario.F90 condense.F90 aero_particle.F90 bin_grid.F90 - camp_core.F90 photolysis.F90 aero_mode.F90 aero_dist.F90 + camp_core.F90 photolysis.F90 aero_mode.F90 aero_dist.F90 bin_grid.cpp condense.cpp run_part.cpp + scenario.cpp util.cpp ) add_prefix(src/ PyPartMC_sources) @@ -291,12 +292,13 @@ target_link_libraries(partmclib PRIVATE klulib) add_subdirectory(gitmodules/pybind11) pybind11_add_module(_PyPartMC ${PyPartMC_sources}) add_dependencies(_PyPartMC partmclib) -target_include_directories(_PyPartMC PRIVATE - ${CMAKE_SOURCE_DIR}/gitmodules/json/include - ${CMAKE_SOURCE_DIR}/gitmodules/pybind11_json/include - ${CMAKE_SOURCE_DIR}/gitmodules/span/include - ${CMAKE_SOURCE_DIR}/gitmodules/string_view-standalone/include +set(PYPARTMC_INCLUDE_DIRS + "${CMAKE_SOURCE_DIR}/gitmodules/json/include;" + "${CMAKE_SOURCE_DIR}/gitmodules/pybind11_json/include;" + "${CMAKE_SOURCE_DIR}/gitmodules/span/include;" + "${CMAKE_SOURCE_DIR}/gitmodules/string_view-standalone/include;" ) +target_include_directories(_PyPartMC PRIVATE ${PYPARTMC_INCLUDE_DIRS}) target_compile_definitions(_PyPartMC PRIVATE VERSION_INFO=${VERSION_INFO}) target_link_libraries(_PyPartMC PRIVATE partmclib) if (APPLE) @@ -319,3 +321,24 @@ foreach(target _PyPartMC) ) endforeach() +include(CheckCXXSourceCompiles) +file(GLOB PyPartMC_headers ${CMAKE_SOURCE_DIR}/src/*.hpp) +if (NOT "${CMAKE_REQUIRED_INCLUDES}" STREQUAL "") + message("CMAKE_REQUIRED_INCLUDES not empty! (${CMAKE_REQUIRED_INCLUDES})") +endif() +foreach(file ${PyPartMC_headers}) + set(CMAKE_REQUIRED_INCLUDES "${PYPARTMC_INCLUDE_DIRS};${pybind11_INCLUDE_DIRS}") + check_cxx_source_compiles(" + // https://github.com/nlohmann/json/issues/1408 + #define HAVE_SNPRINTF + #include \"${file}\" + int main() { return 0;} + " + _header_self_contained_${file} + ) + unset(CMAKE_REQUIRED_INCLUDES) + if (NOT _header_self_contained_${file}) + message(SEND_ERROR "non-self-contained header: ${file}") + endif() +endforeach() + diff --git a/src/aero_mode.hpp b/src/aero_mode.hpp index 3c8c3a1b..c2392324 100644 --- a/src/aero_mode.hpp +++ b/src/aero_mode.hpp @@ -8,6 +8,8 @@ #include "pmc_resource.hpp" #include "pybind11/stl.h" +#include "aero_data.hpp" +#include "bin_grid.hpp" extern "C" void f_aero_mode_ctor( void *ptr diff --git a/src/bin_grid.cpp b/src/bin_grid.cpp new file mode 100644 index 00000000..446539a7 --- /dev/null +++ b/src/bin_grid.cpp @@ -0,0 +1,72 @@ +/*################################################################################################## +# 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 # +##################################################################################################*/ + +#include "bin_grid.hpp" + +std::valarray histogram_1d( + const BinGrid &bin_grid, + std::valarray values, + std::valarray weights +) { + int len; + f_bin_grid_size( + bin_grid.ptr.f_arg(), + &len + ); + int data_size = values.size(); + std::valarray data(len); + f_bin_grid_histogram_1d( + bin_grid.ptr.f_arg(), + begin(values), + begin(weights), + &data_size, + begin(data), + &len + ); + + return data; +} + +std::vector> histogram_2d( + const BinGrid &x_bin_grid, + std::valarray x_values, + const BinGrid &y_bin_grid, + std::valarray y_values, + std::valarray weights +) { + int x_len; + f_bin_grid_size(x_bin_grid.ptr.f_arg(), &x_len); + + int y_len; + f_bin_grid_size(y_bin_grid.ptr.f_arg(), &y_len); + + const int data_size = x_values.size(); + + std::vector> data( + x_len, + std::vector(y_len, 0) + ); + std::valarray data_flat(x_len * y_len); + f_bin_grid_histogram_2d( + x_bin_grid.ptr.f_arg(), + begin(x_values), + y_bin_grid.ptr.f_arg(), + begin(y_values), + begin(weights), + &data_size, + begin(data_flat), + &x_len, + &y_len + ); + + for(int i = 0; i < x_len; i++) { + for(int j = 0; j < y_len; j++) { + data[i][j] = data_flat[i*y_len + j]; + } + } + + return data; +} diff --git a/src/bin_grid.hpp b/src/bin_grid.hpp index 80d53ece..2db09e01 100644 --- a/src/bin_grid.hpp +++ b/src/bin_grid.hpp @@ -117,67 +117,16 @@ struct BinGrid { } }; -auto histogram_1d( +std::valarray histogram_1d( const BinGrid &bin_grid, std::valarray values, std::valarray weights -) { - int len; - f_bin_grid_size( - bin_grid.ptr.f_arg(), - &len - ); - int data_size = values.size(); - std::valarray data(len); - f_bin_grid_histogram_1d( - bin_grid.ptr.f_arg(), - begin(values), - begin(weights), - &data_size, - begin(data), - &len - ); - - return data; -} - -auto histogram_2d( +); + +std::vector> histogram_2d( const BinGrid &x_bin_grid, std::valarray x_values, const BinGrid &y_bin_grid, std::valarray y_values, std::valarray weights -) { - int x_len; - f_bin_grid_size(x_bin_grid.ptr.f_arg(), &x_len); - - int y_len; - f_bin_grid_size(y_bin_grid.ptr.f_arg(), &y_len); - - const int data_size = x_values.size(); - - std::vector> data( - x_len, - std::vector(y_len, 0) - ); - std::valarray data_flat(x_len * y_len); - f_bin_grid_histogram_2d( - x_bin_grid.ptr.f_arg(), - begin(x_values), - y_bin_grid.ptr.f_arg(), - begin(y_values), - begin(weights), - &data_size, - begin(data_flat), - &x_len, - &y_len - ); - - for(int i = 0; i < x_len; i++) { - for(int j = 0; j < y_len; j++) { - data[i][j] = data_flat[i*y_len + j]; - } - } - - return data; -} +); diff --git a/src/condense.cpp b/src/condense.cpp new file mode 100644 index 00000000..059c66aa --- /dev/null +++ b/src/condense.cpp @@ -0,0 +1,31 @@ +/*################################################################################################## +# 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 # +##################################################################################################*/ + +#include "condense.hpp" + +void condense_equilib_particle( + const EnvState &env_state, + const AeroData &aero_data, + const AeroParticle &aero_particle +) { + f_condense_equilib_particle( + env_state.ptr.f_arg(), + aero_data.ptr.f_arg(), + aero_particle.ptr.f_arg() + ); +} + +void condense_equilib_particles( + const EnvState &env_state, + const AeroData &aero_data, + const AeroState &aero_state +) { + f_condense_equilib_particles( + env_state.ptr.f_arg(), + aero_data.ptr.f_arg(), + aero_state.ptr.f_arg() + ); +} diff --git a/src/condense.hpp b/src/condense.hpp index 51ecabc9..a9556f65 100644 --- a/src/condense.hpp +++ b/src/condense.hpp @@ -26,23 +26,10 @@ void condense_equilib_particle( const EnvState &env_state, const AeroData &aero_data, const AeroParticle &aero_particle -) { - f_condense_equilib_particle( - env_state.ptr.f_arg(), - aero_data.ptr.f_arg(), - aero_particle.ptr.f_arg() - ); -} +); void condense_equilib_particles( const EnvState &env_state, const AeroData &aero_data, const AeroState &aero_state -) { - f_condense_equilib_particles( - env_state.ptr.f_arg(), - aero_data.ptr.f_arg(), - aero_state.ptr.f_arg() - ); -} - +); diff --git a/src/gas_data.hpp b/src/gas_data.hpp index dc3203cf..e063f60b 100644 --- a/src/gas_data.hpp +++ b/src/gas_data.hpp @@ -8,6 +8,8 @@ #include "gimmicks.hpp" // TODO #119: rename to something like json_resource.hpp? #include "pmc_resource.hpp" +#include "pybind11/stl.h" +#include "pybind11_json/pybind11_json.hpp" extern "C" void f_gas_data_ctor(void *ptr) noexcept; extern "C" void f_gas_data_dtor(void *ptr) noexcept; @@ -21,7 +23,7 @@ struct GasData { PMCResource ptr; const nlohmann::json json; - GasData(const py::tuple &tpl) : + GasData(const pybind11::tuple &tpl) : ptr(f_gas_data_ctor, f_gas_data_dtor), json(tpl) { diff --git a/src/run_part.cpp b/src/run_part.cpp new file mode 100644 index 00000000..8c6f2824 --- /dev/null +++ b/src/run_part.cpp @@ -0,0 +1,89 @@ +/*################################################################################################## +# 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 # +##################################################################################################*/ + +#include "run_part.hpp" + +void run_part( + const Scenario &scenario, + EnvState &env_state, + const AeroData &aero_data, + AeroState &aero_state, + const GasData &gas_data, + GasState &gas_state, + const RunPartOpt &run_part_opt, + const CampCore &camp_core, + const Photolysis &photolysis +) { + f_run_part( + scenario.ptr.f_arg(), + env_state.ptr.f_arg_non_const(), + aero_data.ptr.f_arg(), + aero_state.ptr.f_arg_non_const(), + gas_data.ptr.f_arg(), + gas_state.ptr.f_arg_non_const(), + run_part_opt.ptr.f_arg(), + camp_core.ptr.f_arg(), + photolysis.ptr.f_arg() + ); +} + +void run_part_timestep( + const Scenario &scenario, + EnvState &env_state, + const AeroData &aero_data, + AeroState &aero_state, + const GasData &gas_data, + GasState &gas_state, + const RunPartOpt &run_part_opt, + const CampCore &camp_core, + const Photolysis &photolysis, + const int &i_time, + const double &t_start +) { + f_run_part_timestep( + scenario.ptr.f_arg(), + env_state.ptr.f_arg_non_const(), + aero_data.ptr.f_arg(), + aero_state.ptr.f_arg_non_const(), + gas_data.ptr.f_arg(), + gas_state.ptr.f_arg_non_const(), + run_part_opt.ptr.f_arg(), + camp_core.ptr.f_arg(), + photolysis.ptr.f_arg(), + &i_time, + &t_start + ); +} + +void run_part_timeblock( + const Scenario &scenario, + EnvState &env_state, + const AeroData &aero_data, + AeroState &aero_state, + const GasData &gas_data, + GasState &gas_state, + const RunPartOpt &run_part_opt, + const CampCore &camp_core, + const Photolysis &photolysis, + const int &i_time, + const int &i_next, + const double &t_start +) { + f_run_part_timeblock( + scenario.ptr.f_arg(), + env_state.ptr.f_arg_non_const(), + aero_data.ptr.f_arg(), + aero_state.ptr.f_arg_non_const(), + gas_data.ptr.f_arg(), + gas_state.ptr.f_arg_non_const(), + run_part_opt.ptr.f_arg(), + camp_core.ptr.f_arg(), + photolysis.ptr.f_arg(), + &i_time, + &i_next, + &t_start + ); +} diff --git a/src/run_part.hpp b/src/run_part.hpp index 2b4290aa..64b87879 100644 --- a/src/run_part.hpp +++ b/src/run_part.hpp @@ -66,19 +66,7 @@ void run_part( const RunPartOpt &run_part_opt, const CampCore &camp_core, const Photolysis &photolysis -) { - f_run_part( - scenario.ptr.f_arg(), - env_state.ptr.f_arg_non_const(), - aero_data.ptr.f_arg(), - aero_state.ptr.f_arg_non_const(), - gas_data.ptr.f_arg(), - gas_state.ptr.f_arg_non_const(), - run_part_opt.ptr.f_arg(), - camp_core.ptr.f_arg(), - photolysis.ptr.f_arg() - ); -} +); void run_part_timestep( const Scenario &scenario, @@ -92,21 +80,7 @@ void run_part_timestep( const Photolysis &photolysis, const int &i_time, const double &t_start -) { - f_run_part_timestep( - scenario.ptr.f_arg(), - env_state.ptr.f_arg_non_const(), - aero_data.ptr.f_arg(), - aero_state.ptr.f_arg_non_const(), - gas_data.ptr.f_arg(), - gas_state.ptr.f_arg_non_const(), - run_part_opt.ptr.f_arg(), - camp_core.ptr.f_arg(), - photolysis.ptr.f_arg(), - &i_time, - &t_start - ); -} +); void run_part_timeblock( const Scenario &scenario, @@ -121,19 +95,4 @@ void run_part_timeblock( const int &i_time, const int &i_next, const double &t_start -) { - f_run_part_timeblock( - scenario.ptr.f_arg(), - env_state.ptr.f_arg_non_const(), - aero_data.ptr.f_arg(), - aero_state.ptr.f_arg_non_const(), - gas_data.ptr.f_arg(), - gas_state.ptr.f_arg_non_const(), - run_part_opt.ptr.f_arg(), - camp_core.ptr.f_arg(), - photolysis.ptr.f_arg(), - &i_time, - &i_next, - &t_start - ); -} +); diff --git a/src/run_part_opt.hpp b/src/run_part_opt.hpp index 94ad2ece..3ec7d359 100644 --- a/src/run_part_opt.hpp +++ b/src/run_part_opt.hpp @@ -7,6 +7,8 @@ #pragma once #include "pmc_resource.hpp" +#include "gimmicks.hpp" +#include "pybind11_json/pybind11_json.hpp" extern "C" void f_run_part_opt_ctor(void *ptr) noexcept; extern "C" void f_run_part_opt_dtor(void *ptr) noexcept; diff --git a/src/scenario.cpp b/src/scenario.cpp new file mode 100644 index 00000000..1e6bb1cf --- /dev/null +++ b/src/scenario.cpp @@ -0,0 +1,43 @@ +/*################################################################################################## +# 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 # +##################################################################################################*/ + +#include "scenario.hpp" + +double loss_rate( + const Scenario &scenario, + const double vol, + const double density, + const AeroData &aero_data, + const EnvState &env_state +) { + double rate; + f_scenario_loss_rate( + &scenario.ptr, + &vol, + &density, + &aero_data.ptr, + &env_state.ptr, + &rate + ); + return rate; +} + +double loss_rate_dry_dep( + const double vol, + const double density, + const AeroData &aero_data, + const EnvState &env_state +) { + double rate; + f_scenario_loss_rate_dry_dep( + &vol, + &density, + &aero_data.ptr, + &env_state.ptr, + &rate + ); + return rate; +} diff --git a/src/scenario.hpp b/src/scenario.hpp index 14c646f3..e2a03d63 100644 --- a/src/scenario.hpp +++ b/src/scenario.hpp @@ -83,38 +83,17 @@ static void init_env_state( }; -auto loss_rate( +double loss_rate( const Scenario &scenario, const double vol, const double density, const AeroData &aero_data, const EnvState &env_state -) { - double rate; - f_scenario_loss_rate( - &scenario.ptr, - &vol, - &density, - &aero_data.ptr, - &env_state.ptr, - &rate - ); - return rate; -} +); -auto loss_rate_dry_dep( +double loss_rate_dry_dep( const double vol, const double density, const AeroData &aero_data, const EnvState &env_state -) { - double rate; - f_scenario_loss_rate_dry_dep( - &vol, - &density, - &aero_data.ptr, - &env_state.ptr, - &rate - ); - return rate; -} +); diff --git a/src/util.cpp b/src/util.cpp new file mode 100644 index 00000000..9734529a --- /dev/null +++ b/src/util.cpp @@ -0,0 +1,37 @@ +/*################################################################################################## +# 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 # +##################################################################################################*/ + +#include "util.hpp" + +int pow2_above(int n) { + int res; + py_pow2_above(&n, &res); + return res; +} + +double sphere_vol2rad(double v) { + double rad; + f_sphere_vol2rad(&v, &rad); + return rad; +} + +double rad2diam(double rad) { + double d; + f_rad2diam(&rad, &d); + return d; +} + +double sphere_rad2vol(double rad) { + double v; + f_sphere_rad2vol(&rad, &v); + return v; +} + +double diam2rad(double d) { + double rad; + f_diam2rad(&d, &rad); + return rad; +} diff --git a/src/util.hpp b/src/util.hpp index ab7b2d50..ed230e92 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -12,35 +12,11 @@ extern "C" void f_rad2diam(const double*, double*); extern "C" void f_sphere_rad2vol(const double*, double*); extern "C" void f_diam2rad(const double*, double*); -auto pow2_above(int n) { - int res; - py_pow2_above(&n, &res); - return res; -} - -auto sphere_vol2rad(double v) { - double rad; - f_sphere_vol2rad(&v, &rad); - return rad; -} - -auto rad2diam(double rad) { - double d; - f_rad2diam(&rad, &d); - return d; -} - -auto sphere_rad2vol(double rad) { - double v; - f_sphere_rad2vol(&rad, &v); - return v; -} - -auto diam2rad(double d) { - double rad; - f_diam2rad(&d, &rad); - return rad; -} +int pow2_above(int n); +double sphere_vol2rad(double v); +double rad2diam(double rad); +double sphere_rad2vol(double rad); +double diam2rad(double d); extern "C" double py_deg2rad(double);