From 0c616c8b22b846132fc69645dc1231c877b4a6bb Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 17 Feb 2017 14:29:34 -0600 Subject: [PATCH] Handle HDF5 format versions consistently --- openmc/checkvalue.py | 33 ++++++++ openmc/particle_restart.py | 16 ++-- openmc/statepoint.py | 45 ++++------- openmc/summary.py | 22 ++---- openmc/volume.py | 4 + src/constants.F90 | 18 +++-- src/hdf5_interface.F90 | 79 +++++++++++++++++-- src/initialize.F90 | 12 +-- src/input_xml.F90 | 6 +- src/multipole.F90 | 9 ++- src/particle_restart.F90 | 5 +- src/particle_restart_write.F90 | 12 ++- src/state_point.F90 | 36 ++++----- src/summary.F90 | 57 ++----------- src/track_output.F90 | 8 +- src/volume_calc.F90 | 21 +++-- .../results_true.dat | 2 +- 17 files changed, 218 insertions(+), 167 deletions(-) diff --git a/openmc/checkvalue.py b/openmc/checkvalue.py index fe5683c06a..06e5240048 100644 --- a/openmc/checkvalue.py +++ b/openmc/checkvalue.py @@ -239,6 +239,39 @@ def check_greater_than(name, value, minimum, equality=False): raise ValueError(msg) +def check_filetype_version(obj, expected_type, expected_version): + """Check filetype and version of an HDF5 file. + + Parameters + ---------- + obj : h5py.File + HDF5 file to check + expected_type + Expected file type, e.g. 'statepoint' + expected_version + Expected major version number. + + """ + try: + this_filetype = obj.attrs['filetype'].decode() + this_version = obj.attrs['version'] + + # Check filetype + if this_filetype != expected_type: + raise IOError('{} is not a {} file.'.format( + obj.filename, expected_type)) + + # Check version + if this_version[0] != expected_version: + raise IOError('Statepoint file has a version of {} which is not ' + 'consistent with the version expected by OpenMC, {}' + .format('.'.join(this_version), expected_version)) + except AttributeError: + raise IOError('Could not read {} file. This most likely means the {} ' + 'file was produced by a different version of OpenMC than ' + 'the one you are using.'.format(expected_type)) + + class CheckedList(list): """A list for which each element is type-checked as it's added diff --git a/openmc/particle_restart.py b/openmc/particle_restart.py index cb13265860..651855a878 100644 --- a/openmc/particle_restart.py +++ b/openmc/particle_restart.py @@ -1,5 +1,9 @@ import h5py +import openmc.checkvalue as cv + +_VERSION_PARTICLE_RESTART = 2 + class Particle(object): """Information used to restart a specific particle that caused a simulation to fail. @@ -37,15 +41,9 @@ class Particle(object): def __init__(self, filename): self._f = h5py.File(filename, 'r') - # Ensure filetype and revision are correct - if 'filetype' not in self._f or self._f[ - 'filetype'].value.decode() != 'particle restart': - raise IOError('{} is not a particle restart file.'.format(filename)) - if self._f['revision'].value != 1: - raise IOError('Particle restart file has a file revision of {} ' - 'which is not consistent with the revision this ' - 'version of OpenMC expects ({}).'.format( - self._f['revision'].value, 1)) + # Ensure filetype and version are correct + cv.check_filetype_version(self._f, 'particle restart', + _VERSION_PARTICLE_RESTART) @property def current_batch(self): diff --git a/openmc/statepoint.py b/openmc/statepoint.py index 144146ba3a..89eabdfd71 100644 --- a/openmc/statepoint.py +++ b/openmc/statepoint.py @@ -10,6 +10,8 @@ import h5py import openmc import openmc.checkvalue as cv +_VERSION_STATEPOINT = 16 + class StatePoint(object): """State information on a simulation at a certain point in time (at the end @@ -78,7 +80,7 @@ class StatePoint(object): path : str Working directory for simulation run_mode : str - Simulation run mode, e.g. 'k-eigenvalue' + Simulation run mode, e.g. 'eigenvalue' runtime : dict Dictionary whose keys are strings describing various runtime metrics and whose values are time values in seconds. @@ -110,21 +112,8 @@ class StatePoint(object): def __init__(self, filename, autolink=True): self._f = h5py.File(filename, 'r') - # Ensure filetype and revision are correct - try: - if 'filetype' not in self._f or self._f[ - 'filetype'].value.decode() != 'statepoint': - raise IOError('{} is not a statepoint file.'.format(filename)) - except AttributeError: - raise IOError('Could not read statepoint file. This most likely ' - 'means the statepoint file was produced by a ' - 'different version of OpenMC than the one you are ' - 'using.') - if self._f['revision'].value != 15: - raise IOError('Statepoint file has a file revision of {} ' - 'which is not consistent with the revision this ' - 'version of OpenMC expects ({}).'.format( - self._f['revision'].value, 15)) + # Check filetype and version + cv.check_filetype_version(self._f, 'statepoint', _VERSION_STATEPOINT) # Set flags for what data has been read self._meshes_read = False @@ -188,18 +177,18 @@ class StatePoint(object): @property def date_and_time(self): - return self._f['date_and_time'].value.decode() + return self._f.attrs['date_and_time'].decode() @property def entropy(self): - if self.run_mode == 'k-eigenvalue': + if self.run_mode == 'eigenvalue': return self._f['entropy'].value else: return None @property def gen_per_batch(self): - if self.run_mode == 'k-eigenvalue': + if self.run_mode == 'eigenvalue': return self._f['gen_per_batch'].value else: return None @@ -234,35 +223,35 @@ class StatePoint(object): @property def k_generation(self): - if self.run_mode == 'k-eigenvalue': + if self.run_mode == 'eigenvalue': return self._f['k_generation'].value else: return None @property def k_combined(self): - if self.run_mode == 'k-eigenvalue': + if self.run_mode == 'eigenvalue': return self._f['k_combined'].value else: return None @property def k_col_abs(self): - if self.run_mode == 'k-eigenvalue': + if self.run_mode == 'eigenvalue': return self._f['k_col_abs'].value else: return None @property def k_col_tra(self): - if self.run_mode == 'k-eigenvalue': + if self.run_mode == 'eigenvalue': return self._f['k_col_tra'].value else: return None @property def k_abs_tra(self): - if self.run_mode == 'k-eigenvalue': + if self.run_mode == 'eigenvalue': return self._f['k_abs_tra'].value else: return None @@ -321,7 +310,7 @@ class StatePoint(object): @property def n_inactive(self): - if self.run_mode == 'k-eigenvalue': + if self.run_mode == 'eigenvalue': return self._f['n_inactive'].value else: return None @@ -336,7 +325,7 @@ class StatePoint(object): @property def path(self): - return self._f['path'].value.decode() + return self._f.attrs['path'].decode() @property def run_mode(self): @@ -501,9 +490,7 @@ class StatePoint(object): @property def version(self): - return (self._f['version_major'].value, - self._f['version_minor'].value, - self._f['version_release'].value) + return self._f.attrs['version'] @property def summary(self): diff --git a/openmc/summary.py b/openmc/summary.py index 5bc4c56a2e..b219e2aafc 100644 --- a/openmc/summary.py +++ b/openmc/summary.py @@ -5,8 +5,11 @@ import numpy as np import h5py import openmc +import openmc.checkvalue as cv from openmc.region import Region +_VERSION_SUMMARY = 5 + class Summary(object): """Information summarizing the geometry, materials, and tallies used in a @@ -31,6 +34,8 @@ class Summary(object): raise ValueError(msg) self._f = h5py.File(filename, 'r') + cv.check_filetype_version(self._f, 'summary', _VERSION_SUMMARY) + self._openmc_geometry = None self._opencg_geometry = None @@ -53,22 +58,9 @@ class Summary(object): def _read_metadata(self): # Read OpenMC version - self.version = [self._f['version_major'].value, - self._f['version_minor'].value, - self._f['version_release'].value] + self.version = self._f.attrs['openmc_version'] # Read date and time - self.date_and_time = self._f['date_and_time'][...] - - # Read if continuous-energy or multi-group - self.run_CE = (self._f['run_CE'].value == 1) - - self.n_batches = self._f['n_batches'].value - self.n_particles = self._f['n_particles'].value - if 'n_inactive' in self._f: - self.n_active = self._f['n_active'].value - self.n_inactive = self._f['n_inactive'].value - self.gen_per_batch = self._f['gen_per_batch'].value - self.n_procs = self._f['n_procs'].value + self.date_and_time = self._f.attrs['date_and_time'] def _read_nuclides(self): self.nuclides = {} diff --git a/openmc/volume.py b/openmc/volume.py index b1391c687c..d85a9a17cc 100644 --- a/openmc/volume.py +++ b/openmc/volume.py @@ -10,6 +10,8 @@ import h5py import openmc import openmc.checkvalue as cv +_VERSION_VOLUME = 1 + class VolumeCalculation(object): """Stochastic volume calculation specifications and results. @@ -189,6 +191,8 @@ class VolumeCalculation(object): """ with h5py.File(filename, 'r') as f: + cv.check_filetype_version(f, "volume", _VERSION_VOLUME) + domain_type = f.attrs['domain_type'].decode() samples = f.attrs['samples'] lower_left = f.attrs['lower_left'] diff --git a/src/constants.F90 b/src/constants.F90 index 43ba2c223c..7f3cf87f83 100644 --- a/src/constants.F90 +++ b/src/constants.F90 @@ -9,17 +9,19 @@ module constants integer, parameter :: VERSION_MAJOR = 0 integer, parameter :: VERSION_MINOR = 8 integer, parameter :: VERSION_RELEASE = 0 + integer, parameter :: & + VERSION(3) = [VERSION_MAJOR, VERSION_MINOR, VERSION_RELEASE] ! HDF5 data format - integer, parameter :: HDF5_VERSION_MAJOR = 1 - integer, parameter :: HDF5_VERSION_MINOR = 0 + integer, parameter :: HDF5_VERSION(2) = [1, 0] - ! Revision numbers for binary files - integer, parameter :: REVISION_STATEPOINT = 15 - integer, parameter :: REVISION_PARTICLE_RESTART = 1 - integer, parameter :: REVISION_TRACK = 1 - integer, parameter :: REVISION_SUMMARY = 4 - character(10), parameter :: MULTIPOLE_VERSION = "v0.2" + ! Version numbers for binary files + integer, parameter :: VERSION_STATEPOINT(2) = [16, 0] + integer, parameter :: VERSION_PARTICLE_RESTART(2) = [2, 0] + integer, parameter :: VERSION_TRACK(2) = [2, 0] + integer, parameter :: VERSION_SUMMARY(2) = [5, 0] + integer, parameter :: VERSION_VOLUME(2) = [1, 0] + character(10), parameter :: VERSION_MULTIPOLE = "v0.2" ! ============================================================================ ! ADJUSTABLE PARAMETERS diff --git a/src/hdf5_interface.F90 b/src/hdf5_interface.F90 index e588cda146..6ca39e0001 100644 --- a/src/hdf5_interface.F90 +++ b/src/hdf5_interface.F90 @@ -75,6 +75,8 @@ module hdf5_interface module procedure write_attribute_double module procedure write_attribute_double_1D module procedure write_attribute_integer + module procedure write_attribute_integer_1D + module procedure write_attribute_string end interface write_attribute public :: write_dataset @@ -93,7 +95,6 @@ module hdf5_interface public :: close_dataset public :: get_shape public :: get_ndims - public :: write_attribute_string public :: get_groups public :: get_datasets public :: get_name @@ -2046,15 +2047,46 @@ contains ! WRITE_ATTRIBUTE_STRING !=============================================================================== - subroutine write_attribute_string(group_id, var, attr_type, attr_str) - integer(HID_T), intent(in) :: group_id - character(*), intent(in) :: var ! variable name for attr - character(*), intent(in) :: attr_type ! attr identifier type - character(*), intent(in) :: attr_str ! string for attr id type + subroutine write_attribute_string(obj_id, name, buffer) + integer(HID_T), intent(in) :: obj_id ! object to write attribute to + character(*), intent(in) :: name ! name of attribute + character(*), intent(in), target :: buffer ! string to write - integer :: hdf5_err + integer :: hdf5_err + integer(HID_T) :: dspace_id + integer(HID_T) :: attr_id + integer(HID_T) :: filetype + integer(SIZE_T) :: i + integer(SIZE_T) :: n + character(kind=C_CHAR), allocatable, target :: temp_buffer(:) + type(c_ptr) :: f_ptr - call h5ltset_attribute_string_f(group_id, var, attr_type, attr_str, hdf5_err) + ! Create datatype for HDF5 file based on C char + n = len_trim(buffer) + if (n > 0) then + call h5tcopy_f(H5T_C_S1, filetype, hdf5_err) + call h5tset_size_f(filetype, n, hdf5_err) + + ! Crate memory space and attribute + call h5screate_f(H5S_SCALAR_F, dspace_id, hdf5_err) + call h5acreate_f(obj_id, trim(name), filetype, dspace_id, & + attr_id, hdf5_err) + + ! Copy string to temporary buffer + allocate(temp_buffer(n)) + do i = 1, n + temp_buffer(i) = buffer(i:i) + end do + + ! Write attribute + f_ptr = c_loc(buffer(1:1)) + call h5awrite_f(attr_id, filetype, f_ptr, hdf5_err) + + ! Close attribute + call h5aclose_f(attr_id, hdf5_err) + call h5sclose_f(dspace_id, hdf5_err) + call h5tclose_f(filetype, hdf5_err) + end if end subroutine write_attribute_string subroutine read_attribute_double(buffer, obj_id, name) @@ -2270,6 +2302,37 @@ contains call h5aread_f(attr_id, H5T_NATIVE_INTEGER, f_ptr, hdf5_err) end subroutine read_attribute_integer_1D_explicit + subroutine write_attribute_integer_1D(obj_id, name, buffer) + integer(HID_T), intent(in) :: obj_id + character(*), intent(in) :: name + integer, target, intent(in) :: buffer(:) + + integer(HSIZE_T) :: dims(1) + + dims(:) = shape(buffer) + call write_attribute_integer_1D_explicit(obj_id, dims, name, buffer) + end subroutine write_attribute_integer_1D + + subroutine write_attribute_integer_1D_explicit(obj_id, dims, name, buffer) + integer(HID_T), intent(in) :: obj_id + integer(HSIZE_T), intent(in) :: dims(1) + character(*), intent(in) :: name + integer, target, intent(in) :: buffer(dims(1)) + + integer :: hdf5_err + integer(HID_T) :: dspace_id + integer(HID_T) :: attr_id + type(C_PTR) :: f_ptr + + call h5screate_simple_f(1, dims, dspace_id, hdf5_err) + call h5acreate_f(obj_id, trim(name), H5T_NATIVE_INTEGER, dspace_id, & + attr_id, hdf5_err) + f_ptr = c_loc(buffer) + call h5awrite_f(attr_id, H5T_NATIVE_INTEGER, f_ptr, hdf5_err) + call h5aclose_f(attr_id, hdf5_err) + call h5sclose_f(dspace_id, hdf5_err) + end subroutine write_attribute_integer_1D_explicit + subroutine read_attribute_integer_2D(buffer, obj_id, name) integer, target, allocatable, intent(inout) :: buffer(:,:) integer(HID_T), intent(in) :: obj_id diff --git a/src/initialize.F90 b/src/initialize.F90 index d30f1e0144..ed1e663fdb 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -18,8 +18,8 @@ module initialize use geometry_header, only: Cell, Universe, Lattice, RectLattice, HexLattice,& &BASE_UNIVERSE use global - use hdf5_interface, only: file_open, read_dataset, file_close, hdf5_bank_t,& - hdf5_integer8_t + use hdf5_interface, only: file_open, read_attribute, file_close, & + hdf5_bank_t, hdf5_integer8_t use input_xml, only: read_input_xml, cells_in_univ_dict, read_plots_xml use material_header, only: Material use message_passing @@ -307,11 +307,11 @@ contains ! Check what type of file this is file_id = file_open(argv(i), 'r', parallel=.true.) - call read_dataset(filetype, file_id, 'filetype') + call read_attribute(filetype, file_id, 'filetype') call file_close(file_id) ! Set path and flag for type of run - select case (filetype) + select case (trim(filetype)) case ('statepoint') path_state_point = argv(i) restart_run = .true. @@ -319,7 +319,7 @@ contains path_particle_restart = argv(i) particle_restart_run = .true. case default - call fatal_error("Unrecognized file after restart flag.") + call fatal_error("Unrecognized file after restart flag: " // filetype // ".") end select ! If its a restart run check for additional source file @@ -333,7 +333,7 @@ contains ! Check file type is a source file file_id = file_open(argv(i), 'r', parallel=.true.) - call read_dataset(filetype, file_id, 'filetype') + call read_attribute(filetype, file_id, 'filetype') call file_close(file_id) if (filetype /= 'source') then call fatal_error("Second file after restart flag must be a & diff --git a/src/input_xml.F90 b/src/input_xml.F90 index fa2e9881c0..b1d62e6283 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -5412,16 +5412,16 @@ contains if (attribute_exists(file_id, 'version')) then call read_attribute(version, file_id, 'version') - if (version(1) /= HDF5_VERSION_MAJOR) then + if (version(1) /= HDF5_VERSION(1)) then call fatal_error("HDF5 data format uses version " // trim(to_str(& version(1))) // "." // trim(to_str(version(2))) // " whereas & &your installation of OpenMC expects version " // trim(to_str(& - HDF5_VERSION_MAJOR)) // ".x data.") + HDF5_VERSION(1))) // ".x data.") end if else call fatal_error("HDF5 data does not indicate a version. Your & &installation of OpenMC expects version " // trim(to_str(& - HDF5_VERSION_MAJOR)) // ".x data.") + HDF5_VERSION(1))) // ".x data.") end if end subroutine check_data_version diff --git a/src/multipole.F90 b/src/multipole.F90 index a099e50476..c59f947272 100644 --- a/src/multipole.F90 +++ b/src/multipole.F90 @@ -1,8 +1,9 @@ module multipole + use hdf5 + use constants use global - use hdf5 use hdf5_interface use multipole_header, only: MultipoleArray, FIT_T, FIT_A, FIT_F, & MP_FISS, FORM_MLBW, FORM_RM @@ -39,9 +40,9 @@ contains ! Check the file version number. call read_dataset(version, file_id, "version") - if (version /= MULTIPOLE_VERSION) call fatal_error("The current multipole& - & format version is " // trim(MULTIPOLE_VERSION) // " but the file "& - // trim(filename) // " uses version " // trim(version)) + if (version /= VERSION_MULTIPOLE) call fatal_error("The current multipole& + & format version is " // trim(VERSION_MULTIPOLE) // " but the file "& + // trim(filename) // " uses version " // trim(version) // ".") ! Load in all the array size scalars call read_dataset(multipole % length, group_id, "length") diff --git a/src/particle_restart.F90 b/src/particle_restart.F90 index a1c32f723e..e0174d05f8 100644 --- a/src/particle_restart.F90 +++ b/src/particle_restart.F90 @@ -69,7 +69,6 @@ contains type(Particle), intent(inout) :: p integer, intent(inout) :: previous_run_mode - integer :: int_scalar integer(HID_T) :: file_id character(MAX_WORD_LEN) :: tempstr @@ -81,15 +80,13 @@ contains file_id = file_open(path_particle_restart, 'r') ! Read data from file - call read_dataset(tempstr, file_id, 'filetype') - call read_dataset(int_scalar, file_id, 'revision') call read_dataset(current_batch, file_id, 'current_batch') call read_dataset(gen_per_batch, file_id, 'gen_per_batch') call read_dataset(current_gen, file_id, 'current_gen') call read_dataset(n_particles, file_id, 'n_particles') call read_dataset(tempstr, file_id, 'run_mode') select case (tempstr) - case ('k-eigenvalue') + case ('eigenvalue') previous_run_mode = MODE_EIGENVALUE case ('fixed source') previous_run_mode = MODE_FIXEDSOURCE diff --git a/src/particle_restart_write.F90 b/src/particle_restart_write.F90 index d983b3db8a..a2e01a7a6d 100644 --- a/src/particle_restart_write.F90 +++ b/src/particle_restart_write.F90 @@ -39,9 +39,15 @@ contains ! Get information about source particle src => source_bank(current_work) + ! Write filetype and version info + call write_attribute(file_id, 'filetype', 'particle restart') + call write_attribute(file_id, 'version', VERSION_PARTICLE_RESTART) + call write_attribute(file_id, "openmc_version", VERSION) +#ifdef GIT_SHA1 + call write_attribute(file_id, "git_sha1", GIT_SHA1) +#endif + ! Write data to file - call write_dataset(file_id, 'filetype', 'particle restart') - call write_dataset(file_id, 'revision', REVISION_PARTICLE_RESTART) call write_dataset(file_id, 'current_batch', current_batch) call write_dataset(file_id, 'gen_per_batch', gen_per_batch) call write_dataset(file_id, 'current_gen', current_gen) @@ -50,7 +56,7 @@ contains case (MODE_FIXEDSOURCE) call write_dataset(file_id, 'run_mode', 'fixed source') case (MODE_EIGENVALUE) - call write_dataset(file_id, 'run_mode', 'k-eigenvalue') + call write_dataset(file_id, 'run_mode', 'eigenvalue') case (MODE_PARTICLE) call write_dataset(file_id, 'run_mode', 'particle restart') end select diff --git a/src/state_point.F90 b/src/state_point.F90 index 5872fbadf4..cb4ae5157a 100644 --- a/src/state_point.F90 +++ b/src/state_point.F90 @@ -68,39 +68,37 @@ contains file_id = file_create(filename) ! Write file type - call write_dataset(file_id, "filetype", 'statepoint') + call write_attribute(file_id, "filetype", "statepoint") ! Write revision number for state point file - call write_dataset(file_id, "revision", REVISION_STATEPOINT) + call write_attribute(file_id, "version", VERSION_STATEPOINT) ! Write OpenMC version - call write_dataset(file_id, "version_major", VERSION_MAJOR) - call write_dataset(file_id, "version_minor", VERSION_MINOR) - call write_dataset(file_id, "version_release", VERSION_RELEASE) + call write_attribute(file_id, "openmc_version", VERSION) #ifdef GIT_SHA1 - call write_dataset(file_id, "git_sha1", GIT_SHA1) + call write_attribute(file_id, "git_sha1", GIT_SHA1) #endif ! Write current date and time - call write_dataset(file_id, "date_and_time", time_stamp()) + call write_attribute(file_id, "date_and_time", time_stamp()) ! Write path to input - call write_dataset(file_id, "path", path_input) + call write_attribute(file_id, "path", path_input) ! Write out random number seed call write_dataset(file_id, "seed", seed) ! Write run information if (run_CE) then - call write_dataset(file_id, "run_CE", 1) + call write_dataset(file_id, "energy_mode", "continuous-energy") else - call write_dataset(file_id, "run_CE", 0) + call write_dataset(file_id, "energy_mode", "multi-group") end if select case(run_mode) case (MODE_FIXEDSOURCE) call write_dataset(file_id, "run_mode", "fixed source") case (MODE_EIGENVALUE) - call write_dataset(file_id, "run_mode", "k-eigenvalue") + call write_dataset(file_id, "run_mode", "eigenvalue") end select call write_dataset(file_id, "n_particles", n_particles) call write_dataset(file_id, "n_batches", n_batches) @@ -670,13 +668,13 @@ contains integer :: i integer :: int_array(3) + integer, allocatable :: array(:) integer(HID_T) :: file_id integer(HID_T) :: cmfd_group integer(HID_T) :: tallies_group integer(HID_T) :: tally_group real(8) :: real_array(3) logical :: source_present - integer :: sp_run_CE character(MAX_WORD_LEN) :: word type(TallyObject), pointer :: tally @@ -688,15 +686,15 @@ contains file_id = file_open(path_state_point, 'r', parallel=.true.) ! Read filetype - call read_dataset(word, file_id, "filetype") + call read_attribute(word, file_id, "filetype") if (word /= 'statepoint') then call fatal_error("OpenMC tried to restart from a non-statepoint file.") end if ! Read revision number for state point file and make sure it matches with ! current version - call read_dataset(int_array(1), file_id, "revision") - if (int_array(1) /= REVISION_STATEPOINT) then + call read_attribute(array, file_id, "version") + if (any(array /= VERSION_STATEPOINT)) then call fatal_error("State point version does not match current version & &in OpenMC.") end if @@ -706,11 +704,11 @@ contains ! It is not impossible for a state point to be generated from a CE run but ! to be loaded in to an MG run (or vice versa), check to prevent that. - call read_dataset(sp_run_CE, file_id, "run_CE") - if (sp_run_CE == 0 .and. run_CE) then + call read_dataset(word, file_id, "energy_mode") + if (word == "multi-group" .and. run_CE) then call fatal_error("State point file is from multi-group run but & & current run is continous-energy!") - else if (sp_run_CE == 1 .and. .not. run_CE) then + else if (word == "continuous-energy" .and. .not. run_CE) then call fatal_error("State point file is from continuous-energy run but & & current run is multi-group!") end if @@ -720,7 +718,7 @@ contains select case(word) case ('fixed source') run_mode = MODE_FIXEDSOURCE - case ('k-eigenvalue') + case ('eigenvalue') run_mode = MODE_EIGENVALUE end select call read_dataset(n_particles, file_id, "n_particles") diff --git a/src/summary.F90 b/src/summary.F90 index a17aa5210d..10b26d0e0c 100644 --- a/src/summary.F90 +++ b/src/summary.F90 @@ -1,5 +1,7 @@ module summary + use hdf5 + use constants use endf, only: reaction_name use geometry_header, only: BASE_UNIVERSE, Cell, Universe, Lattice, & @@ -16,8 +18,6 @@ module summary use tally_header, only: TallyObject use tally_filter, only: find_offset - use hdf5 - implicit none private @@ -39,36 +39,6 @@ contains ! Write header information call write_header(file_id) - if (run_CE) then - call write_dataset(file_id, "run_CE", 1) - else - call write_dataset(file_id, "run_CE", 0) - end if - - ! Write number of particles - call write_dataset(file_id, "n_particles", n_particles) - call write_dataset(file_id, "n_batches", n_batches) - call write_attribute_string(file_id, "n_particles", & - "description", "Number of particles per generation") - call write_attribute_string(file_id, "n_batches", & - "description", "Total number of batches") - - ! Write eigenvalue information - if (run_mode == MODE_EIGENVALUE) then - ! write number of inactive/active batches and generations/batch - call write_dataset(file_id, "n_inactive", n_inactive) - call write_dataset(file_id, "n_active", n_active) - call write_dataset(file_id, "gen_per_batch", gen_per_batch) - - ! Add description of each variable - call write_attribute_string(file_id, "n_inactive", & - "description", "Number of inactive batches") - call write_attribute_string(file_id, "n_active", & - "description", "Number of active batches") - call write_attribute_string(file_id, "gen_per_batch", & - "description", "Number of generations per batch") - end if - call write_nuclides(file_id) call write_geometry(file_id) call write_materials(file_id) @@ -88,25 +58,16 @@ contains subroutine write_header(file_id) integer(HID_T), intent(in) :: file_id - ! Write filetype and revision - call write_dataset(file_id, "filetype", "summary") - call write_dataset(file_id, "revision", REVISION_SUMMARY) - - ! Write version information - call write_dataset(file_id, "version_major", VERSION_MAJOR) - call write_dataset(file_id, "version_minor", VERSION_MINOR) - call write_dataset(file_id, "version_release", VERSION_RELEASE) + ! Write filetype and version info + call write_attribute(file_id, "filetype", "summary") + call write_attribute(file_id, "version", VERSION_SUMMARY) + call write_attribute(file_id, "openmc_version", VERSION) #ifdef GIT_SHA1 - call write_dataset(file_id, "git_sha1", GIT_SHA1) + call write_attribute(file_id, "git_sha1", GIT_SHA1) #endif ! Write current date and time - call write_dataset(file_id, "date_and_time", time_stamp()) - - ! Write MPI information - call write_dataset(file_id, "n_procs", n_procs) - call write_attribute_string(file_id, "n_procs", "description", & - "Number of MPI processes") + call write_attribute(file_id, "date_and_time", time_stamp()) end subroutine write_header @@ -553,8 +514,6 @@ contains ! Write atom density with units call write_dataset(material_group, "atom_density", m % density) - call write_attribute_string(material_group, "atom_density", "units", & - "atom/b-cm") ! Copy ZAID for each nuclide to temporary array allocate(nucnames(m%n_nuclides)) diff --git a/src/track_output.F90 b/src/track_output.F90 index 1411738622..bdef9579c2 100644 --- a/src/track_output.F90 +++ b/src/track_output.F90 @@ -114,10 +114,10 @@ contains !$omp critical (FinalizeParticleTrack) file_id = file_create(fname) - call write_dataset(file_id, 'filetype', 'track') - call write_dataset(file_id, 'revision', REVISION_TRACK) - call write_dataset(file_id, 'n_particles', n_particle_tracks) - call write_dataset(file_id, 'n_coords', n_coords) + call write_attribute(file_id, 'filetype', 'track') + call write_attribute(file_id, 'version', VERSION_TRACK) + call write_attribute(file_id, 'n_particles', n_particle_tracks) + call write_attribute(file_id, 'n_coords', n_coords) do i = 1, n_particle_tracks call write_dataset(file_id, 'coordinates_' // trim(to_str(i)), & tracks(i)%coords) diff --git a/src/volume_calc.F90 b/src/volume_calc.F90 index a9584d672f..5fb4cb5b4d 100644 --- a/src/volume_calc.F90 +++ b/src/volume_calc.F90 @@ -9,8 +9,8 @@ module volume_calc use geometry, only: find_cell use global use hdf5_interface, only: file_create, file_close, write_attribute, & - create_group, close_group, write_dataset, write_attribute_string - use output, only: write_message, header + create_group, close_group, write_dataset + use output, only: write_message, header, time_stamp use message_passing use particle_header, only: Particle use random_lcg, only: prn, prn_set_stream, set_particle_seed @@ -426,14 +426,25 @@ contains ! Create HDF5 file file_id = file_create(filename) + ! Write header info + call write_attribute(file_id, "filetype", "volume") + call write_attribute(file_id, "version", VERSION_VOLUME) + call write_attribute(file_id, "openmc_version", VERSION) +#ifdef GIT_SHA1 + call write_attribute(file_id, "git_sha1", GIT_SHA1) +#endif + + ! Write current date and time + call write_attribute(file_id, "date_and_time", time_stamp()) + ! Write basic metadata select case (this % domain_type) case (FILTER_CELL) - call write_attribute_string(file_id, ".", "domain_type", "cell") + call write_attribute(file_id, "domain_type", "cell") case (FILTER_MATERIAL) - call write_attribute_string(file_id, ".", "domain_type", "material") + call write_attribute(file_id, "domain_type", "material") case (FILTER_UNIVERSE) - call write_attribute_string(file_id, ".", "domain_type", "universe") + call write_attribute(file_id, "domain_type", "universe") end select call write_attribute(file_id, "samples", this % samples) call write_attribute(file_id, "lower_left", this % lower_left) diff --git a/tests/test_particle_restart_eigval/results_true.dat b/tests/test_particle_restart_eigval/results_true.dat index e0a9864a07..5b548bca7c 100644 --- a/tests/test_particle_restart_eigval/results_true.dat +++ b/tests/test_particle_restart_eigval/results_true.dat @@ -5,7 +5,7 @@ current gen: particle id: 1.030000E+03 run mode: -k-eigenvalue +eigenvalue particle weight: 1.000000E+00 particle energy: