From 243eae1244971bafd8926faac7491afda693b7ef Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 24 Aug 2018 19:06:04 -0400 Subject: [PATCH] Move all summary.h5 geometry writing to C++ --- CMakeLists.txt | 1 + src/cell.cpp | 51 +++++++++++++--- src/hdf5_interface.cpp | 2 + src/hdf5_interface.h | 2 +- src/summary.F90 | 132 +++-------------------------------------- src/summary.cpp | 36 +++++++++++ 6 files changed, 89 insertions(+), 135 deletions(-) create mode 100644 src/summary.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a449e7484..d69a7c7f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -420,6 +420,7 @@ add_library(libopenmc SHARED src/simulation.cpp src/state_point.cpp src/string_functions.cpp + src/summary.cpp src/surface.cpp src/xml_interface.cpp src/xsdata.cpp) diff --git a/src/cell.cpp b/src/cell.cpp index 30df8da55..c6f7b3ab9 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -433,13 +433,18 @@ Cell::distance(Position r, Direction u, int32_t on_surface) const //============================================================================== void -Cell::to_hdf5(hid_t cell_group) const +Cell::to_hdf5(hid_t cells_group) const { + // Create a group for this cell. + std::stringstream group_name; + group_name << "cell " << id; + auto group = create_group(cells_group, group_name); + if (!name.empty()) { - write_string(cell_group, "name", name, false); + write_string(group, "name", name, false); } - write_dataset(cell_group, "universe", global_universes[universe]->id); + write_dataset(group, "universe", global_universes[universe]->id); // Write the region specification. if (!region.empty()) { @@ -460,20 +465,48 @@ Cell::to_hdf5(hid_t cell_group) const << copysign(global_surfaces[abs(token)-1]->id, token); } } - write_string(cell_group, "region", region_spec.str(), false); + write_string(group, "region", region_spec.str(), false); } - if (type == FILL_UNIVERSE) { - write_dataset(cell_group, "fill_type", "universe"); - write_dataset(cell_group, "fill", global_universes[fill]->id); + // Write fill information. + if (type == FILL_MATERIAL) { + write_dataset(group, "fill_type", "material"); + std::vector mat_ids; + for (auto i_mat : material) { + if (i_mat != MATERIAL_VOID) { + mat_ids.push_back(global_materials[i_mat]->id); + } else { + mat_ids.push_back(MATERIAL_VOID); + } + } + if (mat_ids.size() == 1) { + write_dataset(group, "material", mat_ids[0]); + } else { + write_dataset(group, "material", mat_ids); + } + + std::vector temps; + for (auto sqrtkT_val : sqrtkT) + temps.push_back(sqrtkT_val * sqrtkT_val / K_BOLTZMANN); + write_dataset(group, "temperature", temps); + + } else if (type == FILL_UNIVERSE) { + write_dataset(group, "fill_type", "universe"); + write_dataset(group, "fill", global_universes[fill]->id); if (translation != 0) { - write_dataset(cell_group, "translation", translation); + write_dataset(group, "translation", translation); } if (!rotation.empty()) { std::array rot {rotation[0], rotation[1], rotation[2]}; - write_dataset(cell_group, "rotation", rot); + write_dataset(group, "rotation", rot); } + + } else if (type == FILL_LATTICE) { + write_dataset(group, "fill_type", "lattice"); + write_dataset(group, "lattice", lattices_c[fill]->id); } + + close_group(group); } //============================================================================== diff --git a/src/hdf5_interface.cpp b/src/hdf5_interface.cpp index 5d6926479..643859620 100644 --- a/src/hdf5_interface.cpp +++ b/src/hdf5_interface.cpp @@ -899,6 +899,8 @@ using_mpio_device(hid_t obj_id) template<> const hid_t H5TypeMap::type_id = H5T_NATIVE_INT; template<> +const hid_t H5TypeMap::type_id = H5T_NATIVE_ULONG; +template<> const hid_t H5TypeMap::type_id = H5T_NATIVE_INT64; template<> const hid_t H5TypeMap::type_id = H5T_NATIVE_DOUBLE; diff --git a/src/hdf5_interface.h b/src/hdf5_interface.h index e749a8e1b..8eccaa016 100644 --- a/src/hdf5_interface.h +++ b/src/hdf5_interface.h @@ -281,7 +281,7 @@ void read_dataset(hid_t obj_id, const char* name, xt::xarray& arr, bool indep template inline void write_attribute(hid_t obj_id, const char* name, T buffer) { - write_attr(obj_id, name, 0, nullptr, H5TypeMap::type_id, &buffer); + write_attr(obj_id, 0, nullptr, name, H5TypeMap::type_id, &buffer); } inline void diff --git a/src/summary.F90 b/src/summary.F90 index e7823a6aa..9d3b7bc8f 100644 --- a/src/summary.F90 +++ b/src/summary.F90 @@ -29,6 +29,13 @@ contains subroutine write_summary() + interface + subroutine write_geometry(file_id) bind(C) + import HID_T + integer(HID_T), intent(in), value :: file_id + end subroutine write_geometry + end interface + integer(HID_T) :: file_id ! Display output message @@ -154,131 +161,6 @@ contains end subroutine write_nuclides -!=============================================================================== -! WRITE_GEOMETRY -!=============================================================================== - - subroutine write_geometry(file_id) - integer(HID_T), intent(in) :: file_id - - integer :: i, j, cell_fill - integer, allocatable :: cell_materials(:) - real(8), allocatable :: cell_temperatures(:) - integer(HID_T) :: geom_group - integer(HID_T) :: cells_group, cell_group - integer(HID_T) :: surfaces_group - integer(HID_T) :: universes_group - integer(HID_T) :: lattices_group - type(Cell), pointer :: c - class(Lattice), pointer :: lat - - interface - subroutine universes_to_hdf5(universes_group) bind(C) - import HID_T - integer(HID_T), intent(in), value :: universes_group - end subroutine universes_to_hdf5 - end interface - - ! Use H5LT interface to write number of geometry objects - geom_group = create_group(file_id, "geometry") - call write_attribute(geom_group, "n_cells", n_cells) - call write_attribute(geom_group, "n_surfaces", n_surfaces) - call write_attribute(geom_group, "n_universes", n_universes) - call write_attribute(geom_group, "n_lattices", size(lattices)) - - ! ========================================================================== - ! WRITE INFORMATION ON CELLS - - ! Create a cell group (nothing directly written in this group) then close - cells_group = create_group(geom_group, "cells") - - ! Write information on each cell - CELL_LOOP: do i = 1, n_cells - c => cells(i) - cell_group = create_group(cells_group, "cell " // trim(to_str(c%id()))) - - call c % to_hdf5(cell_group) - - ! Write information on what fills this cell - select case (c%type()) - case (FILL_MATERIAL) - call write_dataset(cell_group, "fill_type", "material") - - if (c % material_size() == 1) then - if (c % material(1) == MATERIAL_VOID) then - call write_dataset(cell_group, "material", MATERIAL_VOID) - else - call write_dataset(cell_group, "material", & - materials(c % material(1)) % id()) - end if - else - allocate(cell_materials(c % material_size())) - do j = 1, c % material_size() - if (c % material(j) == MATERIAL_VOID) then - cell_materials(j) = MATERIAL_VOID - else - cell_materials(j) = materials(c % material(j)) % id() - end if - end do - call write_dataset(cell_group, "material", cell_materials) - deallocate(cell_materials) - end if - - allocate(cell_temperatures(c % sqrtkT_size())) - do j = 1, c % sqrtkT_size() - cell_temperatures(j) = c % sqrtkT(j-1)**2 / K_BOLTZMANN - end do - call write_dataset(cell_group, "temperature", cell_temperatures) - deallocate(cell_temperatures) - - case (FILL_LATTICE) - call write_dataset(cell_group, "fill_type", "lattice") - ! Do not access the 'lattices' array with 'c % fill() + 1' directly; it - ! causes a segfault in GCC 7.3.0 - cell_fill = c % fill() + 1 - call write_dataset(cell_group, "lattice", lattices(cell_fill)%obj%id()) - end select - - call close_group(cell_group) - end do CELL_LOOP - - call close_group(cells_group) - - ! ========================================================================== - ! WRITE INFORMATION ON SURFACES - - ! Create surfaces group - surfaces_group = create_group(geom_group, "surfaces") - - ! Write information on each surface - SURFACE_LOOP: do i = 1, n_surfaces - call surfaces(i) % to_hdf5(surfaces_group) - end do SURFACE_LOOP - - call close_group(surfaces_group) - - ! ========================================================================== - ! WRITE INFORMATION ON UNIVERSES - - universes_group = create_group(geom_group, "universes") - call universes_to_hdf5(universes_group) - call close_group(universes_group) - - ! ========================================================================== - ! WRITE INFORMATION ON LATTICES - - lattices_group = create_group(geom_group, "lattices") - - do i = 1, size(lattices) - lat => lattices(i)%obj - call lat % to_hdf5(lattices_group) - end do - - call close_group(lattices_group) - call close_group(geom_group) - - end subroutine write_geometry - !=============================================================================== ! WRITE_MATERIALS !=============================================================================== diff --git a/src/summary.cpp b/src/summary.cpp new file mode 100644 index 000000000..a7344e7b4 --- /dev/null +++ b/src/summary.cpp @@ -0,0 +1,36 @@ +#include "cell.h" +#include "hdf5_interface.h" +#include "lattice.h" +#include "surface.h" + + +namespace openmc { + +extern "C" void +write_geometry(hid_t file_id) { + auto geom_group = create_group(file_id, "geometry"); + write_attribute(geom_group, "n_cells", global_cells.size()); + write_attribute(geom_group, "n_surfaces", global_surfaces.size()); + write_attribute(geom_group, "n_universes", global_universes.size()); + write_attribute(geom_group, "n_lattices", lattices_c.size()); + + auto cells_group = create_group(geom_group, "cells"); + for (Cell* c : global_cells) c->to_hdf5(cells_group); + close_group(cells_group); + + auto surfaces_group = create_group(geom_group, "surfaces"); + for (Surface* surf : global_surfaces) surf->to_hdf5(surfaces_group); + close_group(surfaces_group); + + auto universes_group = create_group(geom_group, "universes"); + for (Universe* u : global_universes) u->to_hdf5(universes_group); + close_group(universes_group); + + auto lattices_group = create_group(geom_group, "lattices"); + for (Lattice* lat : lattices_c) lat->to_hdf5(lattices_group); + close_group(lattices_group); + + close_group(geom_group); +} + +} // namespace openmc