From b17a724cf38dd7b20892b1e3466055b6c18a6758 Mon Sep 17 00:00:00 2001 From: Sylwester Arabas Date: Sat, 3 Dec 2022 12:34:11 +0100 Subject: [PATCH] adding basic AeroDist wrapper (#186) --- CMakeLists.txt | 2 +- src/aero_dist.F90 | 43 +++++++++++++++++++++++++++++++++++++++++ src/aero_dist.hpp | 34 ++++++++++++++++++++++++++++++++ src/aero_mode.F90 | 10 ---------- src/aero_mode.hpp | 7 ------- src/gimmicks.hpp | 8 +++++--- src/pypartmc.cpp | 6 ++++++ tests/test_aero_dist.py | 28 +++++++++++++++++++++++++++ 8 files changed, 117 insertions(+), 21 deletions(-) create mode 100644 src/aero_dist.F90 create mode 100644 src/aero_dist.hpp create mode 100644 tests/test_aero_dist.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 2735f72a..3ee10c15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,7 @@ 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 + camp_core.F90 photolysis.F90 aero_mode.F90 aero_dist.F90 ) add_prefix(src/ PyPartMC_sources) diff --git a/src/aero_dist.F90 b/src/aero_dist.F90 new file mode 100644 index 00000000..65faec8d --- /dev/null +++ b/src/aero_dist.F90 @@ -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 # +!################################################################################################### + +module PyPartMC_aero_dist + use iso_c_binding + use pmc_aero_dist + implicit none + + contains + + subroutine f_aero_dist_ctor(ptr_c) bind(C) + type(aero_dist_t), pointer :: ptr_f => null() + type(c_ptr), intent(out) :: ptr_c + + allocate(ptr_f) + + ptr_c = c_loc(ptr_f) + end subroutine + + subroutine f_aero_dist_dtor(ptr_c) bind(C) + type(aero_dist_t), pointer :: ptr_f => null() + type(c_ptr), intent(in) :: ptr_c + + call c_f_pointer(ptr_c, ptr_f) + + deallocate(ptr_f) + end subroutine + + subroutine f_aero_dist_from_json(ptr_c, aero_data_ptr_c) bind(C) + type(aero_dist_t), pointer :: aero_dist => null() + type(aero_data_t), pointer :: aero_data_ptr_f => null() + type(c_ptr), intent(inout) :: ptr_c, aero_data_ptr_c + type(spec_file_t) :: file + + call c_f_pointer(ptr_c, aero_dist) + call c_f_pointer(aero_data_ptr_c, aero_data_ptr_f) + + call spec_file_read_aero_dist(file, aero_data_ptr_f, aero_dist) + end subroutine +end module diff --git a/src/aero_dist.hpp b/src/aero_dist.hpp new file mode 100644 index 00000000..f2058283 --- /dev/null +++ b/src/aero_dist.hpp @@ -0,0 +1,34 @@ +/*################################################################################################## +# 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 + +#include "pmc_resource.hpp" + +extern "C" void f_aero_dist_ctor( + void *ptr +) noexcept; + +extern "C" void f_aero_dist_dtor( + void *ptr +) noexcept; + +extern "C" void f_aero_dist_from_json( + void *ptr, + void *aero_data_ptr +) noexcept; + +struct AeroDist { + PMCResource ptr; + + AeroDist(AeroData &aero_data, const nlohmann::json &json): + ptr(f_aero_dist_ctor, f_aero_dist_dtor) + { + gimmick_ptr() = std::make_unique(json, "", "mode_name", 1); + f_aero_dist_from_json(ptr.f_arg_non_const(), aero_data.ptr.f_arg_non_const()); + gimmick_ptr().reset(); + } +}; diff --git a/src/aero_mode.F90 b/src/aero_mode.F90 index 59a6205e..f064bf90 100644 --- a/src/aero_mode.F90 +++ b/src/aero_mode.F90 @@ -29,16 +29,6 @@ subroutine f_aero_mode_dtor(ptr_c) bind(C) deallocate(ptr_f) end subroutine - subroutine f_aero_mode_init(ptr_c, aero_data_ptr_c) bind(C) - type(c_ptr), intent(inout) :: ptr_c - type(c_ptr), intent(in) :: aero_data_ptr_c - type(aero_mode_t), pointer :: aero_mode => null() - type(aero_data_t), pointer :: aero_data => null() - - call c_f_pointer(ptr_c, aero_mode) - call c_f_pointer(aero_data_ptr_c, aero_data) - end subroutine - subroutine f_aero_mode_set_num_conc(ptr_c, val) bind(C) type(c_ptr), intent(in) :: ptr_c type(aero_mode_t), pointer :: aero_mode => null() diff --git a/src/aero_mode.hpp b/src/aero_mode.hpp index 0be26193..a5bfd2e0 100644 --- a/src/aero_mode.hpp +++ b/src/aero_mode.hpp @@ -17,11 +17,6 @@ extern "C" void f_aero_mode_dtor( void *ptr ) noexcept; -extern "C" void f_aero_mode_init( - void *ptr, - const void *aero_data_ptr -) noexcept; - extern "C" void f_aero_mode_get_num_conc( const void *ptr, double *val @@ -117,8 +112,6 @@ struct AeroMode { AeroMode(AeroData &aero_data, const nlohmann::json &json) : ptr(f_aero_mode_ctor, f_aero_mode_dtor) { - f_aero_mode_init(ptr.f_arg_non_const(), aero_data.ptr.f_arg()); - gimmick_ptr() = std::make_unique(json, "", "mode_name"); f_aero_mode_from_json(ptr.f_arg_non_const(), aero_data.ptr.f_arg_non_const()); gimmick_ptr().reset(); diff --git a/src/gimmicks.hpp b/src/gimmicks.hpp index a3276acf..85899bc5 100644 --- a/src/gimmicks.hpp +++ b/src/gimmicks.hpp @@ -203,13 +203,15 @@ struct InputGimmick: Gimmick { private: std::string key_cond, key_name; std::string last_read_line_key = ""; + std::size_t max_zoom_level; public: InputGimmick( const nlohmann::json &json, const std::string key_cond = "", - const std::string key_name = "" - ) : Gimmick(json), key_cond(key_cond), key_name(key_name) + const std::string key_name = "", + const std::size_t max_zoom_level = 3 + ) : Gimmick(json), key_cond(key_cond), key_name(key_name), max_zoom_level(max_zoom_level) {} std::string str() const { @@ -219,7 +221,7 @@ struct InputGimmick: Gimmick { bool read_line(std::string &name, std::string &data) { bool eof = this->is_empty(); - if (this->zoom_level() == 3) { // TODO #112 + if (this->zoom_level() == this->max_zoom_level) { // TODO #112 eof = true; this->zoom_out(); } diff --git a/src/pypartmc.cpp b/src/pypartmc.cpp index 92d9558d..d09c5482 100644 --- a/src/pypartmc.cpp +++ b/src/pypartmc.cpp @@ -12,6 +12,7 @@ #include "run_part.hpp" #include "run_part_opt.hpp" #include "aero_data.hpp" +#include "aero_dist.hpp" #include "aero_mode.hpp" #include "aero_state.hpp" #include "env_state.hpp" @@ -312,6 +313,10 @@ PYBIND11_MODULE(_PyPartMC, m) { .def_property("type", &AeroMode::get_type, &AeroMode::set_type) ; + py::class_(m,"AeroDist") + .def(py::init()) + ; + m.def( "histogram_1d", &histogram_1d, py::return_value_policy::copy, "Return a 1D histogram with of the given weighted data, scaled by the bin sizes." @@ -363,6 +368,7 @@ PYBIND11_MODULE(_PyPartMC, m) { m.attr("__all__") = py::make_tuple( "__version__", "AeroData", + "AeroDist", "AeroMode", "AeroState", "AeroParticle", diff --git a/tests/test_aero_dist.py b/tests/test_aero_dist.py new file mode 100644 index 00000000..0760da3f --- /dev/null +++ b/tests/test_aero_dist.py @@ -0,0 +1,28 @@ +#################################################################################################### +# 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 # +#################################################################################################### + +import PyPartMC as ppmc + +from .test_aero_data import AERO_DATA_CTOR_ARG_MINIMAL +from .test_aero_mode import AERO_MODE_CTOR_LOG_NORMAL + +AERO_DIST_CTOR_ARG_MINIMAL = [ + AERO_MODE_CTOR_LOG_NORMAL, +] + + +# pylint: disable=too-few-public-methods +class TestAeroDist: + @staticmethod + def test_ctor(): + # arrange + aero_data = ppmc.AeroData(AERO_DATA_CTOR_ARG_MINIMAL) + + # act + sut = ppmc.AeroDist(aero_data, AERO_DIST_CTOR_ARG_MINIMAL) + + # assert + assert sut is not None