Remove unnecessary tally data from summary.h5

This commit is contained in:
Sterling Harper 2016-09-22 22:52:16 -04:00
parent fe9c97c051
commit e8aa4f2f10
8 changed files with 65 additions and 304 deletions

View file

@ -4,7 +4,7 @@
Summary File Format
===================
The current revision of the summary file format is 1.
The current revision of the summary file format is 4.
**/filetype** (*char[]*)
@ -129,7 +129,16 @@ The current revision of the summary file format is 1.
**/geometry/cells/cell <uid>/distribcell_index** (*int*)
Index of this cell in distribcell filter arrays.
Index of this cell in distribcell arrays. Only present if this cell is
listed in a distribcell filter or if it uses distributed materials.
**/geometry/cells/cell <uid>/distribcell_index** (*char[][]*)
The paths traversed through the CSG tree to reach each distribcell
instance. This consists of the integer IDs for each universe, cell and
lattice delimited by '->'. Each lattice cell is specified by its (x,y) or
(x,y,z) indices. Only present if this cell is listed in a distribcell filter
or if it uses distributed materials.
**/geometry/surfaces/surface <uid>/index** (*int*)
@ -244,90 +253,6 @@ The current revision of the summary file format is 1.
Names of S(:math:`\alpha`,:math:`\beta`) tables assigned to the material.
**/tallies/n_tallies** (*int*)
Number of tallies in the problem.
**/tallies/n_meshes** (*int*)
Number of meshes in the problem.
**/tallies/mesh <uid>/index** (*int*)
Index in the meshes array used internally in OpenMC.
**/tallies/mesh <uid>/type** (*char[]*)
Type of the mesh. The only valid option is currently 'regular'.
**/tallies/mesh <uid>/dimension** (*int[]*)
Number of mesh cells in each direction.
**/tallies/mesh <uid>/lower_left** (*double[]*)
Coordinates of the lower-left corner of the mesh.
**/tallies/mesh <uid>/upper_right** (*double[]*)
Coordinates of the upper-right corner of the mesh.
**/tallies/mesh <uid>/width** (*double[]*)
Width of a single mesh cell in each direction.
**/tallies/tally <uid>/index** (*int*)
Index in tallies array used internally in OpenMC.
**/tallies/tally <uid>/name** (*char[]*)
Name of the tally.
**/tallies/tally <uid>/n_filters** (*int*)
Number of filters applied to the tally.
**/tallies/tally <uid>/filter <j>/type** (*char[]*)
Type of the j-th filter. Can be 'universe', 'material', 'cell', 'cellborn',
'surface', 'mesh', 'energy', 'energyout', or 'distribcell'.
**/tallies/tally <uid>/filter <j>/offset** (*int*)
Filter offset (used for distribcell filter).
**/tallies/tally <uid>/filter <j>/paths** (*char[][]*)
The paths traversed through the CSG tree to reach each distribcell
instance (for 'distribcell' filters only). This consists of the integer
IDs for each universe, cell and lattice delimited by '->'. Each lattice
cell is specified by its (x,y) or (x,y,z) indices.
**/tallies/tally <uid>/filter <j>/n_bins** (*int*)
Number of bins for the j-th filter.
**/tallies/tally <uid>/filter <j>/bins** (*int[]* or *double[]*)
Value for each filter bin of this type.
**/tallies/tally <uid>/nuclides** (*char[][]*)
Array of nuclides to tally. Note that if no nuclide is specified in the user
input, a single 'total' nuclide appears here.
**/tallies/tally <uid>/n_score_bins** (*int*)
Number of scoring bins for a single nuclide. In general, this can be greater
than the number of user-specified scores since each score might have
multiple scoring bins, e.g., scatter-PN.
**/tallies/tally <uid>/moment_orders** (*char[][]*)
Tallying moment orders for Legendre and spherical harmonic tally expansions
(*e.g.*, 'P2', 'Y1,2', etc.).
**/tallies/tally <uid>/score_bins** (*char[][]*)
Scoring bins for the tally.

View file

@ -85,6 +85,9 @@ class Cell(object):
Array of offsets used for distributed cell searches
distribcell_index : int
Index of this cell in distribcell arrays
distribcell_paths : list of str
The paths traversed through the CSG tree to reach each distribcell
instance
volume_information : dict
Estimate of the volume and total number of atoms of each nuclide from a
stochastic volume calculation. This information is set with the
@ -104,6 +107,7 @@ class Cell(object):
self._translation = None
self._offsets = None
self._distribcell_index = None
self._distribcell_paths = None
self._volume_information = None
def __contains__(self, point):
@ -217,6 +221,10 @@ class Cell(object):
def distribcell_index(self):
return self._distribcell_index
@property
def distribcell_paths(self):
return self._distribcell_paths
@property
def volume_information(self):
return self._volume_information
@ -316,6 +324,12 @@ class Cell(object):
cv.check_type('distribcell index', ind, Integral)
self._distribcell_index = ind
@distribcell_paths.setter
def distribcell_paths(self, distribcell_paths):
cv.check_iterable_type('distribcell_paths', distribcell_paths,
basestring)
self._distribcell_paths = distribcell_paths
def add_surface(self, surface, halfspace):
"""Add a half-space to the list of half-spaces whose intersection defines the
cell.

View file

@ -691,19 +691,10 @@ class StatePoint(object):
raise ValueError(msg)
for tally_id, tally in self.tallies.items():
summary_tally = summary.tallies[tally_id]
tally.name = summary_tally.name
tally.name = summary.tally_names[tally_id]
tally.with_summary = True
for tally_filter in tally.filters:
summary_filter = summary_tally.find_filter(tally_filter.type)
if tally_filter.type == 'surface':
surface_ids = []
for bin in tally_filter.bins:
surface_ids.append(bin)
tally_filter.bins = surface_ids
if tally_filter.type in ['cell', 'distribcell']:
distribcell_ids = []
for bin in tally_filter.bins:
@ -711,8 +702,9 @@ class StatePoint(object):
tally_filter.bins = distribcell_ids
if tally_filter.type == 'distribcell':
tally_filter.distribcell_paths = \
summary_filter.distribcell_paths
cell_id = tally_filter.bins[0]
cell = summary.get_cell_by_id(cell_id)
tally_filter.distribcell_paths = cell.distribcell_paths
if tally_filter.type == 'universe':
universe_ids = []

View file

@ -297,10 +297,13 @@ class Summary(object):
cell.region = Region.from_expression(
region, {s.id: s for s in self.surfaces.values()})
# Get the distribcell index
ind = self._f['geometry/cells'][key]['distribcell_index'].value
if ind != 0:
# Get the distribcell data
if 'distribcell_index' in self._f['geometry/cells'][key]:
ind = self._f['geometry/cells'][key]['distribcell_index'].value
cell.distribcell_index = ind
paths = self._f['geometry/cells'][key]['paths'][...]
paths = [str(path.decode()) for path in paths]
cell.distribcell_paths = paths
# Add the Cell to the global dictionary of all Cells
self.cells[index] = cell
@ -520,18 +523,15 @@ class Summary(object):
self.openmc_geometry.root_universe = root_universe
def _read_tallies(self):
# Initialize dictionaries for the Tallies
# Initialize a dictionary for the tally names
# Keys - Tally IDs
# Values - Tally objects
self.tallies = {}
# Values - Tally names
self.tally_names = {}
# Read the number of tallies
if 'tallies' not in self._f:
self.n_tallies = 0
return
self.n_tallies = self._f['tallies/n_tallies'].value
# OpenMC Tally keys
all_keys = self._f['tallies/'].keys()
tally_keys = [key for key in all_keys if 'tally' in key]
@ -545,52 +545,7 @@ class Summary(object):
# Read Tally name metadata
tally_name = self._f['{0}/name'.format(subbase)].value.decode()
# Create Tally object and assign basic properties
tally = openmc.Tally(tally_id, tally_name)
# Read scattering moment order strings (e.g., P3, Y1,2, etc.)
moments = self._f['{0}/moment_orders'.format(subbase)].value
# Read score metadata
scores = self._f['{0}/score_bins'.format(subbase)].value
for j, score in enumerate(scores):
score = score.decode()
# If this is a moment, use generic moment order
pattern = r'-n$|-pn$|-yn$'
score = re.sub(pattern, '-' + moments[j].decode(), score)
tally.scores.append(score)
# Read filter metadata
num_filters = self._f['{0}/n_filters'.format(subbase)].value
# Initialize all Filters
for j in range(1, num_filters+1):
subsubbase = '{0}/filter {1}'.format(subbase, j)
# Read filter type (e.g., "cell", "energy", etc.)
filter_type = self._f['{0}/type'.format(subsubbase)].value.decode()
# Read the filter bins
num_bins = self._f['{0}/n_bins'.format(subsubbase)].value
bins = self._f['{0}/bins'.format(subsubbase)][...]
# Create Filter object
new_filter = openmc.Filter(filter_type, bins)
new_filter.num_bins = num_bins
# Read in distribcell paths
if filter_type == 'distribcell':
paths = self._f['{0}/paths'.format(subsubbase)][...]
paths = [str(path.decode()) for path in paths]
new_filter.distribcell_paths = paths
# Add Filter to the Tally
tally.filters.append(new_filter)
# Add Tally to the global dictionary of all Tallies
self.tallies[tally_id] = tally
self.tally_names[tally_id] = tally_name
def add_volume_information(self, volume_calc):
"""Add volume information to the geometry within the summary file

View file

@ -14,7 +14,7 @@ module constants
integer, parameter :: REVISION_STATEPOINT = 15
integer, parameter :: REVISION_PARTICLE_RESTART = 1
integer, parameter :: REVISION_TRACK = 1
integer, parameter :: REVISION_SUMMARY = 3
integer, parameter :: REVISION_SUMMARY = 4
character(10), parameter :: MULTIPOLE_VERSION = "v0.2"
! ============================================================================

View file

@ -2,8 +2,8 @@ module summary
use constants
use endf, only: reaction_name
use geometry_header, only: Cell, Universe, Lattice, RectLattice, &
&HexLattice
use geometry_header, only: BASE_UNIVERSE, Cell, Universe, Lattice, &
RectLattice, HexLattice
use global
use hdf5_interface
use material_header, only: Material
@ -13,6 +13,7 @@ module summary
use surface_header
use string, only: to_str
use tally_header, only: TallyObject
use tally_filter, only: find_offset
use hdf5
@ -150,7 +151,7 @@ contains
subroutine write_geometry(file_id)
integer(HID_T), intent(in) :: file_id
integer :: i, j, k, m
integer :: i, j, k, m, offset
integer, allocatable :: lattice_universes(:,:,:)
integer, allocatable :: cell_materials(:)
real(8), allocatable :: cell_temperatures(:)
@ -161,6 +162,8 @@ contains
integer(HID_T) :: lattices_group, lattice_group
real(8), allocatable :: coeffs(:)
character(REGION_SPEC_LEN) :: region_spec
character(MAX_LINE_LEN), allocatable :: paths(:)
character(MAX_LINE_LEN) :: path
type(Cell), pointer :: c
class(Surface), pointer :: s
type(Universe), pointer :: u
@ -266,7 +269,21 @@ contains
end do
call write_dataset(cell_group, "region", adjustl(region_spec))
call write_dataset(cell_group, "distribcell_index", c % distribcell_index)
! Write distribcell data
if (c % distribcell_index /= NONE) then
call write_dataset(cell_group, "distribcell_index", &
c % distribcell_index)
allocate(paths(c % instances))
do k = 1, c % instances
path = ''
offset = 1
call find_offset(i, universes(BASE_UNIVERSE), k, offset, path)
paths(k) = path
end do
call write_dataset(cell_group, "paths", paths)
deallocate(paths)
end if
call close_group(cell_group)
end do CELL_LOOP
@ -566,119 +583,21 @@ contains
subroutine write_tallies(file_id)
integer(HID_T), intent(in) :: file_id
integer :: i, j, k
integer :: n_order ! loop index for moment orders
integer :: nm_order ! loop index for Ynm moment orders
integer :: i
integer(HID_T) :: tallies_group
integer(HID_T) :: mesh_group
integer(HID_T) :: tally_group
integer(HID_T) :: filter_group
character(20), allocatable :: str_array(:)
type(RegularMesh), pointer :: m
type(TallyObject), pointer :: t
tallies_group = create_group(file_id, "tallies")
! Write total number of meshes
call write_dataset(tallies_group, "n_meshes", n_meshes)
! Write information for meshes
MESH_LOOP: do i = 1, n_meshes
m => meshes(i)
mesh_group = create_group(tallies_group, "mesh " // trim(to_str(m%id)))
! Write internal OpenMC index for this mesh
call write_dataset(mesh_group, "index", i)
! Write type and number of dimensions
call write_dataset(mesh_group, "type", "regular")
! Write mesh information
call write_dataset(mesh_group, "dimension", m%dimension)
call write_dataset(mesh_group, "lower_left", m%lower_left)
call write_dataset(mesh_group, "upper_right", m%upper_right)
call write_dataset(mesh_group, "width", m%width)
call close_group(mesh_group)
end do MESH_LOOP
! Write number of tallies
call write_dataset(tallies_group, "n_tallies", n_tallies)
TALLY_METADATA: do i = 1, n_tallies
! Get pointer to tally
t => tallies(i)
tally_group = create_group(tallies_group, "tally " // trim(to_str(t%id)))
! Write internal OpenMC index for this tally
call write_dataset(tally_group, "index", i)
tally_group = create_group(tallies_group, "tally " &
// trim(to_str(t % id)))
! Write the name for this tally
call write_dataset(tally_group, "name", t%name)
! Write number of filters
call write_dataset(tally_group, "n_filters", size(t % filters))
FILTER_LOOP: do j = 1, size(t % filters)
filter_group = create_group(tally_group, "filter " // trim(to_str(j)))
call t % filters(j) % obj % to_summary(filter_group)
call close_group(filter_group)
end do FILTER_LOOP
! Create temporary array for nuclide bins
allocate(str_array(t%n_nuclide_bins))
NUCLIDE_LOOP: do j = 1, t%n_nuclide_bins
if (t%nuclide_bins(j) > 0) then
str_array(j) = nuclides(t % nuclide_bins(j)) % name
else
str_array(j) = 'total'
end if
end do NUCLIDE_LOOP
! Write and deallocate nuclide bins
call write_dataset(tally_group, "nuclides", str_array)
deallocate(str_array)
! Write number of score bins
call write_dataset(tally_group, "n_score_bins", t%n_score_bins)
allocate(str_array(size(t%score_bins)))
do j = 1, size(t%score_bins)
str_array(j) = reaction_name(t%score_bins(j))
end do
call write_dataset(tally_group, "score_bins", str_array)
deallocate(str_array)
! Write explicit moment order strings for each score bin
k = 1
allocate(str_array(t%n_score_bins))
MOMENT_LOOP: do j = 1, t%n_user_score_bins
select case(t%score_bins(k))
case (SCORE_SCATTER_N, SCORE_NU_SCATTER_N)
str_array(k) = 'P' // trim(to_str(t%moment_order(k)))
k = k + 1
case (SCORE_SCATTER_PN, SCORE_NU_SCATTER_PN)
do n_order = 0, t%moment_order(k)
str_array(k) = 'P' // trim(to_str(n_order))
k = k + 1
end do
case (SCORE_SCATTER_YN, SCORE_NU_SCATTER_YN, SCORE_FLUX_YN, &
SCORE_TOTAL_YN)
do n_order = 0, t%moment_order(k)
do nm_order = -n_order, n_order
str_array(k) = 'Y' // trim(to_str(n_order)) // ',' // &
trim(to_str(nm_order))
k = k + 1
end do
end do
case default
str_array(k) = ''
k = k + 1
end select
end do MOMENT_LOOP
call write_dataset(tally_group, "moment_orders", str_array)
deallocate(str_array)
call write_dataset(tally_group, "name", t % name)
call close_group(tally_group)
end do TALLY_METADATA

View file

@ -80,7 +80,6 @@ module tally_filter
contains
procedure :: get_next_bin => get_next_bin_distribcell
procedure :: to_statepoint => to_statepoint_distribcell
procedure :: to_summary => to_summary_distribcell
procedure :: text_label => text_label_distribcell
procedure :: initialize => initialize_distribcell
end type DistribcellFilter
@ -714,36 +713,6 @@ contains
call write_dataset(filter_group, "bins", this % cell )
end subroutine to_statepoint_distribcell
subroutine to_summary_distribcell(this, filter_group)
class(DistribcellFilter), intent(in) :: this
integer(HID_T), intent(in) :: filter_group
integer :: offset, k
character(MAX_LINE_LEN), allocatable :: paths(:)
character(MAX_LINE_LEN) :: path
call write_dataset(filter_group, "type", "distribcell")
call write_dataset(filter_group, "n_bins", this % n_bins)
call write_dataset(filter_group, "bins", this % cell )
! Write paths to reach each distribcell instance
! Allocate array of strings for each distribcell path
allocate(paths(this % n_bins))
! Store path for each distribcell instance
do k = 1, this % n_bins
path = ''
offset = 1
call find_offset(this % cell, universes(BASE_UNIVERSE), k, offset, path)
paths(k) = path
end do
! Write array of distribcell paths to summary file
call write_dataset(filter_group, "paths", paths)
deallocate(paths)
end subroutine to_summary_distribcell
subroutine initialize_distribcell(this)
class(DistribcellFilter), intent(inout) :: this

View file

@ -18,7 +18,6 @@ module tally_filter_header
contains
procedure(get_next_bin_), deferred :: get_next_bin
procedure(to_statepoint_), deferred :: to_statepoint
procedure :: to_summary => filter_to_summary
procedure(text_label_), deferred :: text_label
procedure :: initialize => filter_initialize
end type TallyFilter
@ -82,18 +81,6 @@ module tally_filter_header
contains
!===============================================================================
! TO_SUMMARY writes all the information needed to reconstruct the filter to the
! given filter_group. If this procedure is not overridden by the derived class,
! then it will call to_statepoint by default.
subroutine filter_to_summary(this, filter_group)
class(TallyFilter), intent(in) :: this
integer(HID_T), intent(in) :: filter_group
call this % to_statepoint(filter_group)
end subroutine filter_to_summary
!===============================================================================
! INITIALIZE sets up any internal data, as necessary. If this procedure is not
! overriden by the derived class, then it will do nothing by default.