diff --git a/.github/workflows/tests+pypi.yml b/.github/workflows/tests+pypi.yml index 00f936c9..9bc2741a 100644 --- a/.github/workflows/tests+pypi.yml +++ b/.github/workflows/tests+pypi.yml @@ -142,7 +142,7 @@ jobs: - run: | unset CI python -m build 2>&1 | tee build.log - exit `fgrep -i warning build.log | grep -v "WARNING setuptools_scm" | wc -l` + exit `fgrep -i warning build.log | grep -v "WARNING setuptools_scm" | grep -v "-warnings" | grep -v "All Warnings are enabled" | wc -l` - if: startsWith(matrix.platform, 'macos-') && matrix.python-version == '3.11' run: | @@ -206,10 +206,10 @@ jobs: GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} python -m pytest --durations=10 -v -s -We -p no:unraisableexception gitmodules/devops_tests ### uncomment to gain ssh access in case of failure -# - if: ${{ failure() }} -# uses: mxschmitt/action-tmate@v3 -# with: -# limit-access-to-actor: true + - if: ${{ failure() }} + uses: mxschmitt/action-tmate@v3 + with: + limit-access-to-actor: true dist_check: runs-on: ubuntu-latest diff --git a/.gitmodules b/.gitmodules index a250302a..6e6650ca 100644 --- a/.gitmodules +++ b/.gitmodules @@ -53,3 +53,8 @@ [submodule "gitmodules/optional"] path = gitmodules/optional url = https://github.com/TartanLlama/optional.git + shallow = true +[submodule "gitmodules/hdf5"] + path = gitmodules/hdf5 + url = https://github.com/HDFGroup/hdf5.git + shallow = true diff --git a/CMakeLists.txt b/CMakeLists.txt index f2c32f5a..2cd7da34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,6 +132,9 @@ set(camp_SOURCES ) add_prefix(gitmodules/camp/src/ camp_SOURCES) +set(hdf5_GENERATED_HEADERS H5Edefin.h H5Einit.h H5Epubgen.h H5Eterm.h H5version.h H5overflow.h) +add_prefix(gitmodules/hdf5/src/ hdf5_GENERATED_HEADERS) + set(netcdf_c_dispatch_SOURCES dvar.c ddim.c dvarput.c dvarget.c ddispatch.c dcompound.c denum.c daux.c dvlen.c nc.c dfile.c dnotnc4.c dstring.c nclist.c nchashmap.c dinstance_intern.c dtype.c dgroup.c nclistmgr.c dattget.c dattinq.c dvarinq.c dfilter.c derror.c doffsets.c datt.c dattput.c dcopy.c drc.c @@ -140,13 +143,21 @@ set(netcdf_c_dispatch_SOURCES dvar.c ddim.c dvarput.c dvarget.c ddispatch.c dcom ) add_prefix(gitmodules/netcdf-c/libdispatch/ netcdf_c_dispatch_SOURCES) +set(netcdf_c_libhdf5_SOURCES hdf5dispatch.c hdf5create.c hdf5open.c hdf5file.c + hdf5attr.c hdf5debug.c hdf5dim.c hdf5filter.c hdf5grp.c hdf5internal.c hdf5set_format_compatibility.c + hdf5type.c hdf5var.c nc4hdf.c nc4info.c nc4mem.c nc4memcb.c +) +add_prefix(gitmodules/netcdf-c/libhdf5/ netcdf_c_libhdf5_SOURCES) + set(netcdf_c_lib_SOURCES nc_initialize.c) add_prefix(gitmodules/netcdf-c/liblib/ netcdf_c_lib_SOURCES) set(netcdf_c_src_SOURCES nc3dispatch.c nc3internal.c dim.c var.c ncio.c v1hpg.c memio.c posixio.c) add_prefix(gitmodules/netcdf-c/libsrc/ netcdf_c_src_SOURCES) -set(netcdf_c_src4_SOURCES nc4internal.c ncindex.c nc4cache.c nc4dispatch.c nc4type.c nc4grp.c nc4var.c) +set(netcdf_c_src4_SOURCES nc4internal.c ncindex.c nc4cache.c nc4dispatch.c nc4type.c nc4grp.c nc4var.c + ncfunc.c nc4dim.c nc4filters.c nc4attr.c +) add_prefix(gitmodules/netcdf-c/libsrc4/ netcdf_c_src4_SOURCES) set(netcdf_f_SOURCES typeSizes.F90 module_netcdf_nf_data.F90 module_netcdf_nc_data.F90 @@ -176,7 +187,7 @@ set(partmclib_SOURCES condense_solver.c aero_state.F90 integer_varray.F90 intege gas_state.F90 coagulation.F90 exact_soln.F90 coagulation_dist.F90 coag_kernel.F90 spec_line.F90 rand.F90 aero_particle.F90 aero_particle_array.F90 mpi.F90 netcdf.F90 aero_info.F90 aero_info_array.F90 nucleate.F90 condense.F90 fractal.F90 chamber.F90 camp_interface.F90 - photolysis.F90 + photolysis.F90 aero_component.F90 ) add_prefix(gitmodules/partmc/src/ partmclib_SOURCES) list(APPEND partmclib_SOURCES src/spec_file_pypartmc.F90 src/sys.F90) @@ -321,6 +332,29 @@ execute_process( OUTPUT_FILE ${CMAKE_BINARY_DIR}/include/camp/version.h ) +### HDF5 ########################################################################################### + +set(HDF5_EXTERNALLY_CONFIGURED 1) +set(BUILD_STATIC_LIBS ON) +set(HDF5_BUILD_HL_LIB ON) +set(BUILD_SHARED_LIBS OFF) +set(BUILD_TESTING OFF) +set(HDF5_BUILD_TOOLS OFF) +set(HDF5_BUILD_EXAMPLES OFF) +set(HDF5_ENABLE_Z_LIB_SUPPORT OFF) +set(HDF5_ENABLE_SZIP_SUPPORT OFF) + +add_subdirectory(${CMAKE_SOURCE_DIR}/gitmodules/hdf5) + +foreach(file ${hdf5_GENERATED_HEADERS}) + execute_process( + COMMAND ${PYTHON_EXECUTABLE} "-c" "import re;open(1,'wb').write(re.sub(b'\\r',b'',open(0,'rb').read()))" + INPUT_FILE ${CMAKE_SOURCE_DIR}/${file} + OUTPUT_FILE ${CMAKE_BINARY_DIR}/${file} + ) + file(REMOVE ${CMAKE_SOURCE_DIR}/${file}) +endforeach() + ### netCDF ######################################################################################### file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/netcdf) @@ -328,6 +362,8 @@ string(CONCAT cmd "import sys; print(''.join([line for line in sys.stdin" " if ('VERSION' in line and line.strip().startswith('SET'))" " or 'CHUNK_' in line" + " or '_CHUNKS_' in line" + " or '_CACHE_SIZE' in line" " or line.strip().startswith('CHECK_INCLUDE_FILE')" " or line.strip().startswith('CHECK_TYPE_SIZE')" " or line.strip().startswith('CHECK_FUNCTION_EXISTS')" @@ -349,6 +385,7 @@ LIST(APPEND netcdf_c_SOURCES ${netcdf_c_lib_SOURCES}) LIST(APPEND netcdf_c_SOURCES ${netcdf_c_dispatch_SOURCES}) LIST(APPEND netcdf_c_SOURCES ${netcdf_c_src_SOURCES}) LIST(APPEND netcdf_c_SOURCES ${netcdf_c_src4_SOURCES}) +LIST(APPEND netcdf_c_SOURCES ${netcdf_c_libhdf5_SOURCES}) foreach (f ${m4_SOURCES}) set(tmp ${CMAKE_BINARY_DIR}/netcdf/${f}.c) add_custom_command( @@ -380,15 +417,22 @@ target_include_directories(netcdf_clib PRIVATE ${CMAKE_BINARY_DIR}/netcdf ${CMAKE_SOURCE_DIR}/gitmodules/netcdf-c/include ${CMAKE_SOURCE_DIR}/gitmodules/netcdf-c/libsrc + ${CMAKE_SOURCE_DIR}/gitmodules/hdf5/src + ${CMAKE_BINARY_DIR}/gitmodules/hdf5/src + ${CMAKE_SOURCE_DIR}/gitmodules/hdf5/hl/src + ${CMAKE_SOURCE_DIR}/gitmodules/hdf5/src/H5FDsubfiling ) target_compile_definitions(netcdf_clib PRIVATE HAVE_CONFIG_H USE_NETCDF4 + USE_HDF5 ) target_compile_options(netcdf_clib PRIVATE $<$:-Wno-unused-result -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast> $<$:-Wno-pointer-to-int-cast -Wno-int-to-void-pointer-cast> ) +target_link_libraries(netcdf_clib PRIVATE hdf5-static) +target_link_libraries(netcdf_clib PRIVATE hdf5_hl-static) ### netCDF-FORTRAN ################################################################################# @@ -435,7 +479,7 @@ add_dependencies(partmclib ${SUNDIALS_items}) string(CONCAT cmd "import sys;" - "print(''.join([f'#define {line.split()[3]} {line.split()[5]}\\n' for line in sys.stdin if 'parameter ::' in line]))" + "print(''.join([line if line.startswith('#') else f'#define {line.split()[3]} {line.split()[5]}\\n' for line in sys.stdin if 'parameter ::' in line or line.startswith('#')]))" ) include(CheckFunctionExists) foreach(file aero_data;gas_data;output) diff --git a/MANIFEST.in b/MANIFEST.in index b922b931..7b347077 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -122,6 +122,9 @@ include gitmodules/netcdf-c/include/nchttp.h include gitmodules/netcdf-c/include/netcdf_mem.h include gitmodules/netcdf-c/include/netcdf_filter.h include gitmodules/netcdf-c/include/netcdf_aux.h +include gitmodules/netcdf-c/include/hdf5internal.h +include gitmodules/netcdf-c/include/hdf5dispatch.h +include gitmodules/netcdf-c/include/ncdimscale.h include gitmodules/netcdf-c/libdispatch/utf8proc_data.c include gitmodules/netcdf-c/libdispatch/utf8proc.h include gitmodules/netcdf-c/libdispatch/dvar.c @@ -188,6 +191,12 @@ include gitmodules/netcdf-c/libsrc4/nc4dispatch.c include gitmodules/netcdf-c/libsrc4/nc4type.c include gitmodules/netcdf-c/libsrc4/nc4grp.c include gitmodules/netcdf-c/libsrc4/nc4var.c +include gitmodules/netcdf-c/libsrc4/nc4dim.c +include gitmodules/netcdf-c/libsrc4/nc4attr.c +include gitmodules/netcdf-c/libsrc4/nc4filters.c +include gitmodules/netcdf-c/libsrc4/ncfunc.c + +graft gitmodules/netcdf-c/libhdf5 include gitmodules/netcdf-fortran/COPYRIGHT include gitmodules/netcdf-fortran/CMakeExtras/MatchNetCDFFortranTypes.cmake @@ -230,3 +239,12 @@ include gitmodules/netcdf-fortran/fortran/netcdf_text_variables.F90 include gitmodules/netcdf-fortran/fortran/netcdf_expanded.F90 include gitmodules/netcdf-fortran/fortran/netcdf4_eightbyte.F90 include gitmodules/netcdf-fortran/fortran/netcdf4_func.F90 + +include gitmodules/hdf5/COPYING +include gitmodules/hdf5/CMakeLists.txt +include gitmodules/hdf5/*.cmake +graft gitmodules/hdf5/src +graft gitmodules/hdf5/bin +graft gitmodules/hdf5/config +include gitmodules/hdf5/hl/CMakeLists.txt +graft gitmodules/hdf5/hl/src diff --git a/README.md b/README.md index 38e378f4..b68732a7 100644 --- a/README.md +++ b/README.md @@ -289,7 +289,7 @@ MOSAIC_HOME=<> pip install --force-reinstall --no-binary=PyP ``` - Q: Why `pip install PyPartMC` triggers compilation on my brand new Apple machine, while it quickly downloads and installs binary packages when executed on older Macs, Windows or Linux? - A: We are not yet providing binary wheels on PyPI for Apple-silicon (arm64) machines. Cross-compilation with gfortran is only supported with experimental unofficial builds [and is tricky](https://github.com/iains/gcc-12-branch/issues/23), while Github Actions ARM64 virtual machines are [costly](https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#minute-multipliers). + A: We are providing binary wheels on PyPI for Apple-silicon (arm64) machines for selected macOS version made available by Github. In case the macOS version you are using is newer, compilation from source is triggered. - Q: Why some of the constructors expect data to be passed as **lists of single-entry dictionaries** instead of multi-element dictionaries? A: This is intentional and related with PartMC relying on the order of elements within spec-file input; while Python dictionaries preserve ordering (insertion order), JSON format does not, and we intend to make these data structures safe to be [de]serialized using JSON. @@ -301,6 +301,9 @@ import PyPartMC PyPartMC.__versions_of_build_time_dependencies__['PartMC'] ``` +- Q: Why m4 and perl are required at compile time? + A: PyPartMC includes parts of netCDF and HDF5 codebases which depend on m4 and perl, respectively, for generating source files before compilation. + ## Troubleshooting #### Common installation issues diff --git a/gitmodules/hdf5 b/gitmodules/hdf5 new file mode 160000 index 00000000..bbf1e26c --- /dev/null +++ b/gitmodules/hdf5 @@ -0,0 +1 @@ +Subproject commit bbf1e26cda5654fe9e6ea08c57029fa0c1007f53 diff --git a/gitmodules/partmc b/gitmodules/partmc index e73f6534..e9451e51 160000 --- a/gitmodules/partmc +++ b/gitmodules/partmc @@ -1 +1 @@ -Subproject commit e73f6534160abeda86d6d58ab43ba4dc0934e602 +Subproject commit e9451e51d845542bb4f586d2d194bf41e7f19af0 diff --git a/readme_fortran/CMakeLists.txt b/readme_fortran/CMakeLists.txt index d384ad77..962d8347 100644 --- a/readme_fortran/CMakeLists.txt +++ b/readme_fortran/CMakeLists.txt @@ -7,6 +7,7 @@ add_executable(main $ENV{PARTMC_HOME}/src/spec_line.F90 $ENV{PARTMC_HOME}/src/util.F90 $ENV{PARTMC_HOME}/src/constants.F90 + $ENV{PARTMC_HOME}/src/aero_component.F90 $ENV{PARTMC_HOME}/src/aero_data.F90 $ENV{PARTMC_HOME}/src/aero_mode.F90 $ENV{PARTMC_HOME}/src/aero_dist.F90 diff --git a/readme_fortran/main.f90 b/readme_fortran/main.f90 index 0365b343..26eddfcb 100644 --- a/readme_fortran/main.f90 +++ b/readme_fortran/main.f90 @@ -20,7 +20,7 @@ program main call spec_file_close(f_aero_data) call spec_file_open("aero_dist.dat", f_aero_dist) - call spec_file_read_aero_dist(f_aero_dist, aero_data, aero_dist) + call spec_file_read_aero_dist(f_aero_dist, aero_data, .false., aero_dist) call spec_file_close(f_aero_dist) call aero_state_zero(aero_state) @@ -29,7 +29,7 @@ program main AERO_STATE_WEIGHT_NUMMASS_SOURCE) call aero_state_set_n_part_ideal(aero_state, dble(n_part)) call aero_state_add_aero_dist_sample(aero_state, aero_data, & - aero_dist, 1d0, 0d0, .true., .true., n_part_add) + aero_dist, 1d0, 1d0, 0d0, .true., .true., n_part_add) num_concs = aero_state_num_concs(aero_state, aero_data) masses = aero_state_masses(aero_state, aero_data) diff --git a/src/aero_dist.F90 b/src/aero_dist.F90 index 4d729cfb..aa8764a6 100644 --- a/src/aero_dist.F90 +++ b/src/aero_dist.F90 @@ -38,7 +38,7 @@ subroutine f_aero_dist_from_json(ptr_c, aero_data_ptr_c) bind(C) 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) + call spec_file_read_aero_dist(file, aero_data_ptr_f, .false., aero_dist) end subroutine subroutine f_aero_dist_n_mode(ptr_c, n_mode) bind(C) diff --git a/src/aero_mode.F90 b/src/aero_mode.F90 index 416eb399..1b514205 100644 --- a/src/aero_mode.F90 +++ b/src/aero_mode.F90 @@ -179,7 +179,7 @@ subroutine f_aero_mode_from_json(ptr_c, aero_data_ptr_c) bind(C) call c_f_pointer(ptr_c, ptr_f) call c_f_pointer(aero_data_ptr_c, aero_data_ptr_f) - call spec_file_read_aero_mode(file, aero_data_ptr_f, ptr_f, eof) + call spec_file_read_aero_mode(file, aero_data_ptr_f, .false., ptr_f, eof) end subroutine diff --git a/src/aero_particle.F90 b/src/aero_particle.F90 index 31ed8e9d..ce0c9c06 100644 --- a/src/aero_particle.F90 +++ b/src/aero_particle.F90 @@ -389,12 +389,14 @@ subroutine f_aero_particle_set_vols( & subroutine f_aero_particle_absorb_cross_sect( & aero_particle_ptr_c, & - absorb_cross_sect & + absorb_cross_sect, & + n_wavelengths & ) bind(C) type(aero_particle_t), pointer :: aero_particle_ptr_f => null() type(c_ptr), intent(in) :: aero_particle_ptr_c - real(c_double), intent(out) :: absorb_cross_sect + integer(c_int), intent(in) :: n_wavelengths + real(c_double), dimension(n_wavelengths), intent(out) :: absorb_cross_sect call c_f_pointer(aero_particle_ptr_c, aero_particle_ptr_f) @@ -404,12 +406,14 @@ subroutine f_aero_particle_absorb_cross_sect( & subroutine f_aero_particle_scatter_cross_sect( & aero_particle_ptr_c, & - scatter_cross_sect & + scatter_cross_sect, & + n_wavelengths & ) bind(C) type(aero_particle_t), pointer :: aero_particle_ptr_f => null() type(c_ptr), intent(in) :: aero_particle_ptr_c - real(c_double), intent(out) :: scatter_cross_sect + integer(c_int), intent(in) :: n_wavelengths + real(c_double), dimension(n_wavelengths), intent(out) :: scatter_cross_sect call c_f_pointer(aero_particle_ptr_c, aero_particle_ptr_f) @@ -419,12 +423,14 @@ subroutine f_aero_particle_scatter_cross_sect( & subroutine f_aero_particle_asymmetry( & aero_particle_ptr_c, & - asymmetry & + asymmetry, & + n_wavelengths & ) bind(C) type(aero_particle_t), pointer :: aero_particle_ptr_f => null() type(c_ptr), intent(in) :: aero_particle_ptr_c - real(c_double), intent(out) :: asymmetry + integer(c_int), intent(in) :: n_wavelengths + real(c_double), dimension(n_wavelengths), intent(out) :: asymmetry call c_f_pointer(aero_particle_ptr_c, aero_particle_ptr_f) @@ -475,7 +481,24 @@ subroutine f_aero_particle_n_orig_part( & call c_f_pointer(aero_particle_ptr_c, aero_particle_ptr_f) - n_orig_part = aero_particle_ptr_f%n_orig_part + n_orig_part = 1 !aero_particle_ptr_f%n_orig_part + + end subroutine + + subroutine f_aero_particle_get_component_sources( & + aero_particle_ptr_c, & + source_list, & + n_sources & + ) bind(C) + + type(aero_particle_t), pointer :: aero_particle_ptr_f => null() + type(c_ptr), intent(in) :: aero_particle_ptr_c + integer(c_int), intent(in) :: n_sources + integer(c_int), dimension(n_sources), intent(inout) :: source_list + + call c_f_pointer(aero_particle_ptr_c, aero_particle_ptr_f) + + call aero_particle_get_component_sources(aero_particle_ptr_f, source_list) end subroutine @@ -486,7 +509,7 @@ subroutine f_aero_particle_id( & type(aero_particle_t), pointer :: aero_particle_ptr_f => null() type(c_ptr), intent(in) :: aero_particle_ptr_c - integer(c_int), intent(out) :: id + integer(c_int64_t), intent(out) :: id call c_f_pointer(aero_particle_ptr_c, aero_particle_ptr_f) @@ -496,12 +519,14 @@ subroutine f_aero_particle_id( & subroutine f_aero_particle_refract_shell( & aero_particle_ptr_c, & - refract_shell & + refract_shell, & + n_wavelengths & ) bind(C) type(aero_particle_t), pointer :: aero_particle_ptr_f => null() type(c_ptr), intent(in) :: aero_particle_ptr_c - complex(c_double_complex), intent(out) :: refract_shell + integer(c_int), intent(in) :: n_wavelengths + complex(c_double_complex), dimension(n_wavelengths), intent(out) :: refract_shell call c_f_pointer(aero_particle_ptr_c, aero_particle_ptr_f) @@ -511,12 +536,14 @@ subroutine f_aero_particle_refract_shell( & subroutine f_aero_particle_refract_core( & aero_particle_ptr_c, & - refract_core & + refract_core, & + n_wavelengths & ) bind(C) type(aero_particle_t), pointer :: aero_particle_ptr_f => null() type(c_ptr), intent(in) :: aero_particle_ptr_c - complex(c_double_complex), intent(out) :: refract_core + integer(c_int), intent(in) :: n_wavelengths + complex(c_double_complex), dimension(n_wavelengths), intent(out) :: refract_core call c_f_pointer(aero_particle_ptr_c, aero_particle_ptr_f) diff --git a/src/aero_particle.hpp b/src/aero_particle.hpp index f02458ff..eca3cc48 100644 --- a/src/aero_particle.hpp +++ b/src/aero_particle.hpp @@ -36,15 +36,15 @@ extern "C" void f_aero_particle_crit_diameter(const void *aero_particle_ptr, con extern "C" void f_aero_particle_coagulate(const void *aero_particle_1_ptr, const void *aero_particle_2_ptr, void *new_particle_ptr) noexcept; extern "C" void f_aero_particle_zero(void *aero_particle_ptr, const void *aero_data_ptr) noexcept; extern "C" void f_aero_particle_set_vols(void *aero_particle_ptr, const int *vol_size, const void *volumes) noexcept; -extern "C" void f_aero_particle_absorb_cross_sect(const void *aero_particle_ptr, double *val) noexcept; -extern "C" void f_aero_particle_scatter_cross_sect(const void *aero_particle_ptr, double *val) noexcept; -extern "C" void f_aero_particle_asymmetry(const void *aero_particle_ptr, double *val) noexcept; +extern "C" void f_aero_particle_absorb_cross_sect(const void *aero_particle_ptr, double *val, const int *arr_size) noexcept; +extern "C" void f_aero_particle_scatter_cross_sect(const void *aero_particle_ptr, double *val, const int *arr_size) noexcept; +extern "C" void f_aero_particle_asymmetry(const void *aero_particle_ptr, double *val, const int *arr_size) noexcept; extern "C" void f_aero_particle_greatest_create_time(const void *aero_particle_ptr, double *val) noexcept; extern "C" void f_aero_particle_least_create_time(const void *aero_particle_ptr, double *val) noexcept; -extern "C" void f_aero_particle_n_orig_part(const void *aero_particle_ptr, void *arr_data, const int *arr_size) noexcept; -extern "C" void f_aero_particle_id(const void *aero_particle_ptr, int *val) noexcept; -extern "C" void f_aero_particle_refract_shell(const void *aero_particle_ptr, std::complex *val) noexcept; -extern "C" void f_aero_particle_refract_core(const void *aero_particle_ptr, std::complex *val) noexcept; +extern "C" void f_aero_particle_get_component_sources(const void *aero_particle_ptr, void *arr_data, const int *arr_size) noexcept; +extern "C" void f_aero_particle_id(const void *aero_particle_ptr, int64_t *val) noexcept; +extern "C" void f_aero_particle_refract_shell(const void *aero_particle_ptr, std::complex *val, const int *arr_size) noexcept; +extern "C" void f_aero_particle_refract_core(const void *aero_particle_ptr, std::complex *val, const int *arr_size) noexcept; namespace py = pybind11; struct AeroParticle { @@ -307,37 +307,43 @@ struct AeroParticle { } static auto scatter_cross_sect(const AeroParticle &self) { + int len = n_swbands; double val; f_aero_particle_scatter_cross_sect( self.ptr.f_arg(), - &val + &val, + &len ); return val; } static auto absorb_cross_sect(const AeroParticle &self) { + int len = n_swbands; double val; f_aero_particle_absorb_cross_sect( self.ptr.f_arg(), - &val + &val, + &len ); return val; } static auto asymmetry(const AeroParticle &self) { + int len = n_swbands; double val; f_aero_particle_asymmetry( self.ptr.f_arg(), - &val + &val, + &len ); return val; } - static auto n_orig_part(const AeroParticle &self) { + static auto sources(const AeroParticle &self) { int len = AeroData::n_source(*self.aero_data); std::valarray data(len); - f_aero_particle_n_orig_part( + f_aero_particle_get_component_sources( self.ptr.f_arg(), begin(data), &len @@ -364,7 +370,7 @@ struct AeroParticle { } static auto id(const AeroParticle &self) { - int val; + int64_t val; f_aero_particle_id( self.ptr.f_arg(), &val @@ -373,19 +379,23 @@ struct AeroParticle { } static auto refract_shell(const AeroParticle &self) { + int len = n_swbands; std::complex refract_shell; f_aero_particle_refract_shell( self.ptr.f_arg(), - &refract_shell + &refract_shell, + &len ); return refract_shell; } static auto refract_core(const AeroParticle &self) { + int len = n_swbands; std::complex refract_core; f_aero_particle_refract_core( self.ptr.f_arg(), - &refract_core + &refract_core, + &len ); return refract_core; } diff --git a/src/aero_state.F90 b/src/aero_state.F90 index 24e220e9..72991192 100644 --- a/src/aero_state.F90 +++ b/src/aero_state.F90 @@ -495,8 +495,8 @@ subroutine f_aero_state_add_aero_dist_sample(ptr_c, ptr_aero_data_c, & call c_f_pointer(ptr_aero_dist_c,ptr_aero_dist_f) call aero_state_add_aero_dist_sample(ptr_f, ptr_aero_data_f, & - ptr_aero_dist_f, sample_prop, create_time, LOGICAL(allow_doubling), & - logical(allow_halving), n_part_add) + ptr_aero_dist_f, sample_prop, 1.0d0, create_time, LOGICAL(allow_doubling), & + logical(allow_halving), n_part_add) end subroutine @@ -555,7 +555,7 @@ subroutine f_aero_state_zero(ptr_c) bind(C) subroutine f_aero_state_ids(ptr_c, ids, n_parts) bind(C) type(c_ptr), intent(in) :: ptr_c integer(c_int), intent(in) :: n_parts - integer(c_int), intent(out) :: ids(n_parts) + integer(c_int64_t), intent(out) :: ids(n_parts) type(aero_state_t), pointer :: ptr_f => null() call c_f_pointer(ptr_c, ptr_f) diff --git a/src/aero_state.hpp b/src/aero_state.hpp index c99f90c9..a3c86399 100644 --- a/src/aero_state.hpp +++ b/src/aero_state.hpp @@ -178,7 +178,7 @@ extern "C" void f_aero_state_zero( extern "C" void f_aero_state_ids( const void *ptr_c, - int *ids, + int64_t *ids, const int *n_parts ) noexcept; @@ -480,7 +480,7 @@ struct AeroState { self.ptr.f_arg(), &len ); - std::valarray ids(len); + std::valarray ids(len); f_aero_state_ids( self.ptr.f_arg(), diff --git a/src/pypartmc.cpp b/src/pypartmc.cpp index 37e08dcc..900b4726 100644 --- a/src/pypartmc.cpp +++ b/src/pypartmc.cpp @@ -167,7 +167,7 @@ PYBIND11_MODULE(_PyPartMC, m) { "Refractive index of the shell (1).") .def_property_readonly("refract_core", AeroParticle::refract_core, "Refractive index of the core (1).") - .def_property_readonly("n_orig_part", AeroParticle::n_orig_part, + .def_property_readonly("sources", AeroParticle::sources, "Number of original particles from each source that coagulated to form particle.") .def_property_readonly("least_create_time", AeroParticle::least_create_time, "First time a constituent was created (s).") diff --git a/src/scenario.F90 b/src/scenario.F90 index d7e18527..a832300e 100644 --- a/src/scenario.F90 +++ b/src/scenario.F90 @@ -36,7 +36,7 @@ subroutine f_scenario_from_json(gas_ptr_c, aer_ptr_c, ptr_c) bind(C) call c_f_pointer(gas_ptr_c, gas_ptr_f) call c_f_pointer(aer_ptr_c, aer_ptr_f) call c_f_pointer(ptr_c, ptr_f) - call spec_file_read_scenario(file, gas_ptr_f, aer_ptr_f, ptr_f) + call spec_file_read_scenario(file, gas_ptr_f, aer_ptr_f, .false., ptr_f) end subroutine subroutine f_scenario_loss_rate( & diff --git a/tests/test_aero_particle.py b/tests/test_aero_particle.py index 14cadbd6..eda32db3 100644 --- a/tests/test_aero_particle.py +++ b/tests/test_aero_particle.py @@ -570,7 +570,7 @@ def test_refract_core(): assert isinstance(value, complex) @staticmethod - def test_n_orig_part(): + def test_sources(): # arrange aero_data = ppmc.AeroData(AERO_DATA_CTOR_ARG_MINIMAL) aero_dist = ppmc.AeroDist(aero_data, AERO_DIST_CTOR_ARG_MINIMAL) @@ -578,11 +578,11 @@ def test_n_orig_part(): _ = aero_state.dist_sample(aero_dist, 1.0, 0.0) sut = aero_state.particle(0) # act - n_orig_part = sut.n_orig_part + sources = sut.sources # assert - assert len(n_orig_part) == aero_dist.n_mode - assert isinstance(n_orig_part[0], int) + assert len(sources) == aero_dist.n_mode + assert isinstance(sources[0], int) @staticmethod def test_least_create_time(): diff --git a/tests/test_aero_state.py b/tests/test_aero_state.py index f8b56210..85217bd6 100644 --- a/tests/test_aero_state.py +++ b/tests/test_aero_state.py @@ -432,6 +432,7 @@ def test_sample_particles(sut_minimal): # arrange aero_data = ppmc.AeroData(AERO_DATA_CTOR_ARG_MINIMAL) sut = ppmc.AeroState(aero_data, *AERO_STATE_CTOR_ARG_MINIMAL) + sut.copy_weight(sut_minimal) # act num_conc = sut_minimal.total_num_conc