Implemented new scatter MGXS library specification on python side and fixed python2 bug in writing strings to hdf5 file

This commit is contained in:
Adam Nelson 2016-09-07 04:23:05 -04:00
parent 88abdfb5ce
commit 1ef9acb8bd
2 changed files with 162 additions and 52 deletions

View file

@ -56,17 +56,18 @@ data for the nuclide or material that it represents.
that the azimuthal angular domain is subdivided if the
`representation` attribute is "angle". This parameter is
ignored otherwise.
- **num-polar** (*int*) -- Number of equal width angular bins
- **num-polar** (*int*) -- Number of equal width angular bins
that the polar angular domain is subdivided if the
`representation` attribute is "angle". This parameter is
ignored otherwise.
- **scatter-type** (*char[]*) -- The representation of the
scattering angular distribution. The options are either
"legendre", "histogram", or "tabular". If not provided, the
default of "legendre" will be assumed.
- **order** (*int*) -- Either the Legendre order, number of bins,
or number of points (depending on the value of `scatter-type`)
used to describe the angular distribution associated with each group-to-group transfer probability.
- **scatter-type** (*char[]*) -- The representation of the
scattering angular distribution. The options are either
"legendre", "histogram", or "tabular". If not provided, the
default of "legendre" will be assumed.
- **order** (*int*) -- Either the Legendre order, number of bins,
or number of points (depending on the value of `scatter-type`)
used to describe the angular distribution associated with each
group-to-group transfer probability.
**/<library name>/kTs/**
@ -86,30 +87,6 @@ Temperature-dependent data, provided for temperature <TTT>K.
This is a 1-D vector if `representation` is "isotropic", or a 3-D
vector if `representation` is "angle" with dimensions of
[groups, azimuthal, polar].
- **scatter matrix** (*double[][][]* or *double[][][][][]*) --
Scattering moment matrices. This dataset requires the scattering
moment matrices presented with the columns representing incoming
group and rows representing the outgoing group. That is,
down-scatter will be above the diagonal of the resultant matrix.
This matrix is repeated for every Legendre order (in order of
increasing orders) if `scatter-type` is "legendre"; otherwise, this
matrix is repeated for every bin of the histogram or tabular
representation. Finally, if ``representation`` is "angle", the
above is repeated for every azimuthal angle and every polar angle,
in that order.
- **multiplicity matrix** (*double[][]* or *double[][][][]*) --
Scattering multiplicity matrices.
This dataset provides the ratio of neutrons produced in scattering
collisions to the neutrons which undergo scattering collisions;
that is, the multiplicity provides the code with a scaling factor
to account for neutrons being produced in (n,xn) reactions. This
information is assumed isotropic and therefore is not repeated for
every Legendre moment or histogram/tabular bin. This matrix
follows the same arrangement as described for the `scatter`
dataset, with the exception of the data needed to provide the
scattering type information.
This dataset is optional, if it is not provided no multiplication
(i.e., values of 1.0) will be assumed.
- **fission** (*double[]* or *double[][][]*) -- Fission
cross section.
This is a 1-D vector if `representation` is "isotropic", or a 3-D
@ -135,4 +112,46 @@ Temperature-dependent data, provided for temperature <TTT>K.
the `nu-fission` data must represent the fission neutron energy
spectra as well and thus will have one additional dimension
for the outgoing energy group. In this case, `nu-fission` has the
same dimensionality as `multiplicity matrix`.
same dimensionality as `multiplicity matrix`.
**/<library name>/<TTT>K/scatter data/**
Data specific to neutron scattering for the temperature <TTT>K
:Datasets: - **g_out bounds** (*int[2]* or *int[][][2]) --
Minimum (most energetic) and maximum (most thermal) outgoing groups
with non-zero values of the scattering matrix. These group numbers
use the standard ordering where the fastest neutron energy group
is group 1 while the most thermal neutron energy group is group G.
The dimensionality of `g_out bounds` is:
`g_out bounds][g_in][g_out]`, or
`g_out bounds[num-polar][num-azimuthal][g_in][g_out]`.
The former is used when `representation` is "isotropic", and the
latter when `representation` is "angle".
- **scatter matrix** (*double[][]* or *double[][][][]*) --
Flattened representation of the scattering moment matrices where
the [g_in] and [g_out] indices are flattened. The pre-flattened
array is shaped as follows (in row-major format):
`scatter matrix[order(+1)][g_in][g_out]`, or
`scatter matrix[num-polar][num-azimuthal][order(+1)][g_in][g_out]`
The former is used when `representation` is "isotropic", and the
latter when `representation` is "angle". Note that if the value of
`scatter-type` is "legendre", the order dimension will be one
larger than the value of `order`, otherwise it will match `order`.
Finally, the g_out dimension has a dimensionality of
`g_out bounds`[0] to `g_out bounds`[1].
- **multiplicity matrix** (*double[]*) -- Flattened representation of
the scattering moment matrices where the [g_in] and [g_out] indices
are flattened. This dataset provides the code with a scaling factor
to account for neutrons being produced in (n,xn) reactions. This
is assumed isotropic and therefore is not repeated for every
Legendre moment or histogram/tabular bin. This dataset is optional,
if it is not provided no multiplication (i.e., values of 1.0) will
be assumed.
The pre-flattened array is shaped as follows (in row-major format):
`multiplicity matrix[g_in][g_out]`, or
`multiplicity matrix[num-polar][num-azimuthal][g_in][g_out]`
The former is used when `representation` is "isotropic", and the
latter when `representation` is "angle". Finally, the g_out
dimension has a dimensionality of `g_out bounds`[0] to
`g_out bounds`[1].

View file

@ -1137,14 +1137,15 @@ class XSdata(object):
if self.fissionable is not None:
grp.attrs['fissionable'] = self.fissionable
if self.representation is not None:
grp.attrs['representation'] = np.string_(self.representation)
grp.attrs['representation'] = np.array(self.representation,
dtype='S')
if self.representation == 'angle':
if self.num_azimuthal is not None:
grp.attrs['num-azimuthal'] = self.num_azimuthal
if self.num_polar is not None:
grp.attrs['num-polar'] = self.num_polar
if self.scatter_type is not None:
grp.attrs['scatter-type'] = np.string_(self.scatter_type)
grp.attrs['scatter-type'] = np.array(self.scatter_type, dtype='S')
if self.order is not None:
grp.attrs['order'] = self.order
@ -1157,20 +1158,16 @@ class XSdata(object):
# Create the temperature datasets
for i, temperature in enumerate(self.temperatures):
xsgrp = grp.create_group(str(int(np.round(temperature))) + "K")
if self._total[i] is not None:
xsgrp.create_dataset("total", data=self._total[i],
compression=compression)
if self._absorption[i] is not None:
xsgrp.create_dataset("absorption", data=self._absorption[i],
compression=compression)
if self._scatter_matrix[i] is not None:
xsgrp.create_dataset("scatter matrix",
data=self._scatter_matrix[i],
compression=compression)
if self._multiplicity_matrix[i] is not None:
xsgrp.create_dataset("multiplicity matrix",
data=self._multiplicity_matrix[i],
compression=compression)
if self._total[i] is None:
raise ValueError('total data must be provided when writing '
'the HDF5 library')
xsgrp.create_dataset("total", data=self._total[i],
compression=compression)
if self._absorption[i] is None:
raise ValueError('absorption data must be provided when '
'writing the HDF5 library')
xsgrp.create_dataset("absorption", data=self._absorption[i],
compression=compression)
if self.fissionable:
if self._fission[i] is not None:
xsgrp.create_dataset("fission", data=self._fission[i],
@ -1182,9 +1179,103 @@ class XSdata(object):
if self._chi[i] is not None:
xsgrp.create_dataset("chi", data=self._chi[i],
compression=compression)
if self._nu_fission[i] is not None:
xsgrp.create_dataset("nu-fission",
data=self._nu_fission[i],
if self._nu_fission[i] is None:
raise ValueError('nu-fission data must be provided when '
'writing the HDF5 library')
xsgrp.create_dataset("nu-fission",
data=self._nu_fission[i],
compression=compression)
if self._scatter_matrix[i] is None:
raise ValueError('Scatter matrix must be provided when '
'writing the HDF5 library')
# Get the sparse scattering data to print to the library
G = self.energy_groups.num_groups
if self.representation is 'isotropic':
g_out_bounds = np.zeros((G, 2), dtype=np.int)
for g_in in range(G):
nz = np.nonzero(self._scatter_matrix[i][0, g_in, :])
g_out_bounds[g_in, 0] = nz[0]
g_out_bounds[g_in, 1] = nz[-1]
# Now create the flattened scatter matrix array
flat_scatt = []
for l in range(self._scatter_matrix[i].shape[0]):
for g_in in range(G):
matrix = self._scatter_matrix[i][l, g_in, :]
for g_out in range(g_out_bounds[g_in, 0],
g_out_bounds[g_in, 1] + 1):
flat_scatt.append(matrix[g_out])
# And write it.
scatt_grp = xsgrp.create_group('scatter data')
scatt_grp.create_dataset("scatter matrix",
data=np.array(flat_scatt),
compression=compression)
# Repeat for multiplicity
if self._multiplicity_matrix[i] is not None:
# Now create the flattened scatter matrix array
flat_mult = []
for g_in in range(G):
matrix = self._multiplicity_matrix[i][g_in, :]
for g_out in range(g_out_bounds[g_in, 0],
g_out_bounds[g_in, 1] + 1):
flat_mult.append(matrix[g_out])
scatt_grp.create_dataset("multiplicity matrix",
data=np.array(flat_mult),
compression=compression)
# And finally, adjust g_out_bounds for 1-based group counting
# and write it.
g_out_bounds[:, :] += 1
scatt_grp.create_dataset("g_out bounds", data=g_out_bounds,
compression=compression)
else:
Np = self.num_polar
Na = self.num_azimuthal
g_out_bounds = np.zeros((Np, Na, G, 2), dtype=np.int)
for p in range(Np):
for a in range(Na):
for g_in in range(G):
matrix = self._scatter_matrix[i][p, a, 0, g_in, :]
nz = np.nonzero(matrix)
g_out_bounds[p, a, g_in, 0] = nz[0]
g_out_bounds[p, a, g_in, 1] = nz[-1]
# Now create the flattened scatter matrix array
flat_scatt = [[[] for a in range(Na)] for p in range(Np)]
for p in range(Np):
for a in range(Na):
for l in range(self._scatter_matrix[i].shape[2]):
for g_in in range(G):
matrix = \
self._scatter_matrix[i][p, a, 0, g_in, :]
for g_out in range(g_out_bounds[p, a, g_in, 0],
g_out_bounds[p, a, g_in, 1]
+ 1):
flat_scatt[p][a].append(matrix[g_out])
# And write it.
scatt_grp = xsgrp.create_group('scatter data')
scatt_grp.create_dataset("scatter matrix",
data=np.array(flat_scatt).flatten(),
compression=compression)
# Repeat for multiplicity
if self._multiplicity_matrix[i] is not None:
# Now create the flattened scatter matrix array
flat_mult = [[[] for a in range(Na)] for p in range(Np)]
for p in range(Np):
for a in range(Na):
for l in range(self._scatter_matrix[i].shape[2]):
for g_in in range(G):
matrix = \
self._multiplicity_matrix[i][p, a, g_in, :]
for g_out in range(g_out_bounds[p, a, g_in, 0],
g_out_bounds[p, a, g_in, 1] + 1):
flat_mult[p][a].append(matrix[g_out])
scatt_grp.create_dataset("multiplicity matrix",
data=np.array(flat_mult).flatten(),
compression=compression)
# And finally, adjust g_out_bounds for 1-based group counting
# and write it.
g_out_bounds[:, :, :, :] += 1
scatt_grp.create_dataset("g_out bounds", data=g_out_bounds,
compression=compression)