diff --git a/src/hdf5_interface.F90 b/src/hdf5_interface.F90 index 5320ec9f5..752ce062d 100644 --- a/src/hdf5_interface.F90 +++ b/src/hdf5_interface.F90 @@ -1342,7 +1342,7 @@ contains ! Allocate a C char array to get strings n = attribute_typesize(obj_id, to_c_string(name)) m = size(buffer) - allocate(buffer_(n*m)) + allocate(buffer_((n+1)*m)) ! Read attribute call read_attr_string_c(obj_id, to_c_string(name), n, buffer_) @@ -1351,7 +1351,7 @@ contains do i = 1, m buffer(i) = '' do j = 1, n - k = (i-1)*n + j + k = (i-1)*(n+1) + j if (buffer_(k) == C_NULL_CHAR) exit buffer(i)(j:j) = buffer_(k) end do diff --git a/src/hdf5_interface.cpp b/src/hdf5_interface.cpp index 935ef084a..ddc2dcdfc 100644 --- a/src/hdf5_interface.cpp +++ b/src/hdf5_interface.cpp @@ -350,6 +350,26 @@ read_complex(hid_t obj_id, const char* name, double _Complex* buffer, bool indep } +void +read_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score, double* results) +{ + // Create dataspace for hyperslab in memory + hsize_t dims[] {n_filter, n_score, 3}; + hsize_t start[] {0, 0, 1}; + hsize_t count[] {n_filter, n_score, 2}; + hid_t memspace = H5Screate_simple(3, dims, nullptr); + H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, nullptr, count, nullptr); + + // Create and write dataset + hid_t dset = H5Dopen(group_id, "results", H5P_DEFAULT); + H5Dread(dset, H5T_NATIVE_DOUBLE, memspace, H5S_ALL, H5P_DEFAULT, results); + + // Free resources + H5Dclose(dset); + H5Sclose(memspace); +} + + void write_attr(hid_t obj_id, int ndim, const hsize_t* dims, const char* name, hid_t mem_type_id, const void* buffer) @@ -488,9 +508,34 @@ write_string(hid_t group_id, int ndim, const hsize_t* dims, size_t slen, void -write_string(hid_t group_id, char const* name, const std::string& buffer, bool indep) +write_string(hid_t group_id, const char* name, const std::string& buffer, bool indep) { write_string(group_id, 0, nullptr, buffer.length(), name, buffer.c_str(), indep); } + +void +write_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score, const double* results) +{ + // Set dimensions of sum/sum_sq hyperslab to store + hsize_t count[] {n_filter, n_score, 2}; + hid_t dspace = H5Screate_simple(3, count, nullptr); + + // Set dimensions of results array + hsize_t dims[] {n_filter, n_score, 3}; + hsize_t start[] {0, 0, 1}; + hid_t memspace = H5Screate_simple(3, dims, nullptr); + H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, nullptr, count, nullptr); + + // Create and write dataset + hid_t dset = H5Dcreate(group_id, "results", H5T_NATIVE_DOUBLE, dspace, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + H5Dwrite(dset, H5T_NATIVE_DOUBLE, memspace, H5S_ALL, H5P_DEFAULT, results); + + // Free resources + H5Dclose(dset); + H5Sclose(memspace); + H5Sclose(dspace); +} + } // namespace openmc diff --git a/src/hdf5_interface.h b/src/hdf5_interface.h index 9ea170c6c..57f56f5c2 100644 --- a/src/hdf5_interface.h +++ b/src/hdf5_interface.h @@ -68,6 +68,9 @@ extern "C" void read_string(hid_t obj_id, const char* name, size_t slen, extern "C" void read_complex(hid_t obj_id, const char* name, double _Complex* buffer, bool indep); +extern "C" void read_tally_results(hid_t group_id, hsize_t n_filter, + hsize_t n_score, double* results); + void write_attr(hid_t obj_id, int ndim, const hsize_t* dims, const char* name, hid_t mem_type_id, const void* buffer); extern "C" void write_attr_double(hid_t obj_id, int ndim, const hsize_t* dims, @@ -90,5 +93,9 @@ extern "C" void write_string(hid_t group_id, int ndim, const hsize_t* dims, size const char* name, char const* buffer, bool indep); void write_string(hid_t group_id, const char* name, const std::string& buffer, bool indep); + +extern "C" void write_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score, + const double* results); + } // namespace openmc #endif //HDF5_INTERFACE_H diff --git a/src/tallies/tally_header.F90 b/src/tallies/tally_header.F90 index 413464b7b..cbfa4f048 100644 --- a/src/tallies/tally_header.F90 +++ b/src/tallies/tally_header.F90 @@ -2,11 +2,10 @@ module tally_header use, intrinsic :: ISO_C_BINDING - use hdf5 - use constants use error use dict_header, only: DictIntInt + use hdf5_interface, only: HID_T, HSIZE_T use message_passing, only: n_procs use nuclide_header, only: nuclide_dict use settings, only: reduce_tallies, run_mode @@ -200,67 +199,42 @@ contains class(TallyObject), intent(in) :: this integer(HID_T), intent(in) :: group_id - integer :: hdf5_err - integer(HID_T) :: dset, dspace - integer(HID_T) :: memspace - integer(HSIZE_T) :: dims(3) - integer(HSIZE_T) :: dims_slab(3) - integer(HSIZE_T) :: offset(3) = [1,0,0] + integer(HSIZE_T) :: n_filter, n_score + interface + subroutine write_tally_results(group_id, n_filter, n_score, results) & + bind(C) + import HID_T, HSIZE_T, C_DOUBLE + integer(HID_T), value :: group_id + integer(HSIZE_T), value :: n_filter + integer(HSIZE_T), value :: n_score + real(C_DOUBLE), intent(in) :: results(*) + end subroutine write_tally_results + end interface - ! Create file dataspace - dims_slab(:) = shape(this % results) - dims_slab(1) = 2 - call h5screate_simple_f(3, dims_slab, dspace, hdf5_err) - - ! Create memory dataspace that contains only SUM and SUM_SQ values - dims(:) = shape(this % results) - call h5screate_simple_f(3, dims, memspace, hdf5_err) - call h5sselect_hyperslab_f(memspace, H5S_SELECT_SET_F, offset, dims_slab, & - hdf5_err) - - ! Create and write to dataset - call h5dcreate_f(group_id, "results", H5T_NATIVE_DOUBLE, dspace, dset, & - hdf5_err) - call h5dwrite_f(dset, H5T_NATIVE_DOUBLE, this % results, dims_slab, & - hdf5_err, mem_space_id=memspace) - - ! Close identifiers - call h5dclose_f(dset, hdf5_err) - call h5sclose_f(memspace, hdf5_err) - call h5sclose_f(dspace, hdf5_err) + n_filter = size(this % results, 3) + n_score = size(this % results, 2) + call write_tally_results(group_id, n_filter, n_score, this % results) end subroutine tally_write_results_hdf5 subroutine tally_read_results_hdf5(this, group_id) class(TallyObject), intent(inout) :: this integer(HID_T), intent(in) :: group_id - integer :: hdf5_err - integer(HID_T) :: dset, dspace - integer(HID_T) :: memspace - integer(HSIZE_T) :: dims(3) - integer(HSIZE_T) :: dims_slab(3) - integer(HSIZE_T) :: offset(3) = [1,0,0] + integer(HSIZE_T) :: n_filter, n_score + interface + subroutine read_tally_results(group_id, n_filter, n_score, results) & + bind(C) + import HID_T, HSIZE_T, C_DOUBLE + integer(HID_T), value :: group_id + integer(HSIZE_T), value :: n_filter + integer(HSIZE_T), value :: n_score + real(C_DOUBLE), intent(out) :: results(*) + end subroutine read_tally_results + end interface - ! Create file dataspace - dims_slab(:) = shape(this % results) - dims_slab(1) = 2 - call h5screate_simple_f(3, dims_slab, dspace, hdf5_err) - - ! Create memory dataspace that contains only SUM and SUM_SQ values - dims(:) = shape(this % results) - call h5screate_simple_f(3, dims, memspace, hdf5_err) - call h5sselect_hyperslab_f(memspace, H5S_SELECT_SET_F, offset, dims_slab, & - hdf5_err) - - ! Create and write to dataset - call h5dopen_f(group_id, "results", dset, hdf5_err) - call h5dread_f(dset, H5T_NATIVE_DOUBLE, this % results, dims_slab, & - hdf5_err, mem_space_id=memspace) - - ! Close identifiers - call h5dclose_f(dset, hdf5_err) - call h5sclose_f(memspace, hdf5_err) - call h5sclose_f(dspace, hdf5_err) + n_filter = size(this % results, 3) + n_score = size(this % results, 2) + call read_tally_results(group_id, n_filter, n_score, this % results) end subroutine tally_read_results_hdf5 !===============================================================================