mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-26 05:05:30 -04:00
added chi-prompt, velocity, and prompt-neutron-lifetime mgxs
This commit is contained in:
parent
4198b6b514
commit
710f8a75b8
3 changed files with 865 additions and 19 deletions
|
|
@ -213,7 +213,7 @@ def check_less_than(name, value, maximum, equality=False):
|
|||
raise ValueError(msg)
|
||||
|
||||
def check_greater_than(name, value, minimum, equality=False):
|
||||
"""Ensure that an object's value is less than a given value.
|
||||
"""Ensure that an object's value is greater than a given value.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
|
|||
|
|
@ -564,7 +564,7 @@ class Filter(object):
|
|||
# Initialize dictionary to build Pandas Multi-index column
|
||||
filter_dict = {}
|
||||
|
||||
# Append Mesh ID as outermost index of mult-index
|
||||
# Append Mesh ID as outermost index of multi-index
|
||||
mesh_key = 'mesh {0}'.format(self.mesh.id)
|
||||
|
||||
# Find mesh dimensions - use 3D indices for simplicity
|
||||
|
|
|
|||
|
|
@ -34,7 +34,10 @@ MGXS_TYPES = ['total',
|
|||
'nu-scatter matrix',
|
||||
'multiplicity matrix',
|
||||
'nu-fission matrix',
|
||||
'chi']
|
||||
'chi',
|
||||
'chi-prompt',
|
||||
'velocity',
|
||||
'prompt-neutron-lifetime']
|
||||
|
||||
|
||||
# Supported domain types
|
||||
|
|
@ -427,7 +430,11 @@ class MGXS(object):
|
|||
|
||||
Parameters
|
||||
----------
|
||||
mgxs_type : {'total', 'transport', 'nu-transport', 'absorption', 'capture', 'fission', 'nu-fission', 'kappa-fission', 'scatter', 'nu-scatter', 'scatter matrix', 'nu-scatter matrix', 'multiplicity matrix', 'nu-fission matrix', chi'}
|
||||
mgxs_type : {'total', 'transport', 'nu-transport', 'absorption',
|
||||
'capture', 'fission', 'nu-fission', 'kappa-fission', 'scatter',
|
||||
'nu-scatter', 'scatter matrix', 'nu-scatter matrix',
|
||||
'multiplicity matrix', 'nu-fission matrix', 'chi', 'chi-prompt',
|
||||
'velocity', 'prompt-neutron-lifetime'}
|
||||
The type of multi-group cross section object to return
|
||||
domain : openmc.Material or openmc.Cell or openmc.Universe
|
||||
The domain for spatial homogenization
|
||||
|
|
@ -482,6 +489,12 @@ class MGXS(object):
|
|||
mgxs = NuFissionMatrixXS(domain, domain_type, energy_groups)
|
||||
elif mgxs_type == 'chi':
|
||||
mgxs = Chi(domain, domain_type, energy_groups)
|
||||
elif mgxs_type == 'chi-prompt':
|
||||
mgxs = ChiPrompt(domain, domain_type, energy_groups)
|
||||
elif mgxs_type == 'velocity':
|
||||
mgxs = Velocity(domain, domain_type, energy_groups)
|
||||
elif mgxs_type == 'prompt-neutron-lifetime':
|
||||
mgxs = PromptNeutronLifetime(domain, domain_type, energy_groups)
|
||||
|
||||
mgxs.by_nuclide = by_nuclide
|
||||
mgxs.name = name
|
||||
|
|
@ -1935,7 +1948,7 @@ class MatrixMGXS(MGXS):
|
|||
|
||||
|
||||
class TotalXS(MGXS):
|
||||
r"""A total multi-group cross section.
|
||||
"""A total multi-group cross section.
|
||||
|
||||
This class can be used for both OpenMC input generation and tally data
|
||||
post-processing to compute spatially-homogenized and energy-integrated
|
||||
|
|
@ -2044,7 +2057,7 @@ class TotalXS(MGXS):
|
|||
|
||||
|
||||
class TransportXS(MGXS):
|
||||
r"""A transport-corrected total multi-group cross section.
|
||||
"""A transport-corrected total multi-group cross section.
|
||||
|
||||
This class can be used for both OpenMC input generation and tally data
|
||||
post-processing to compute spatially-homogenized and energy-integrated
|
||||
|
|
@ -2187,7 +2200,7 @@ class TransportXS(MGXS):
|
|||
|
||||
|
||||
class NuTransportXS(TransportXS):
|
||||
r"""A transport-corrected total multi-group cross section which
|
||||
"""A transport-corrected total multi-group cross section which
|
||||
accounts for neutron multiplicity in scattering reactions.
|
||||
|
||||
This class can be used for both OpenMC input generation and tally data
|
||||
|
|
@ -2300,7 +2313,7 @@ class NuTransportXS(TransportXS):
|
|||
|
||||
|
||||
class AbsorptionXS(MGXS):
|
||||
r"""An absorption multi-group cross section.
|
||||
"""An absorption multi-group cross section.
|
||||
|
||||
Absorption is defined as all reactions that do not produce secondary
|
||||
neutrons (disappearance) plus fission reactions.
|
||||
|
|
@ -2413,7 +2426,7 @@ class AbsorptionXS(MGXS):
|
|||
|
||||
|
||||
class CaptureXS(MGXS):
|
||||
r"""A capture multi-group cross section.
|
||||
"""A capture multi-group cross section.
|
||||
|
||||
The neutron capture reaction rate is defined as the difference between
|
||||
OpenMC's 'absorption' and 'fission' reaction rate score types. This includes
|
||||
|
|
@ -2541,7 +2554,7 @@ class CaptureXS(MGXS):
|
|||
|
||||
|
||||
class FissionXS(MGXS):
|
||||
r"""A fission multi-group cross section.
|
||||
"""A fission multi-group cross section.
|
||||
|
||||
This class can be used for both OpenMC input generation and tally data
|
||||
post-processing to compute spatially-homogenized and energy-integrated
|
||||
|
|
@ -2651,7 +2664,7 @@ class FissionXS(MGXS):
|
|||
|
||||
|
||||
class NuFissionXS(MGXS):
|
||||
r"""A fission neutron production multi-group cross section.
|
||||
"""A fission neutron production multi-group cross section.
|
||||
|
||||
This class can be used for both OpenMC input generation and tally data
|
||||
post-processing to compute spatially-homogenized and energy-integrated
|
||||
|
|
@ -2762,7 +2775,7 @@ class NuFissionXS(MGXS):
|
|||
|
||||
|
||||
class KappaFissionXS(MGXS):
|
||||
r"""A recoverable fission energy production rate multi-group cross section.
|
||||
"""A recoverable fission energy production rate multi-group cross section.
|
||||
|
||||
The recoverable energy per fission, :math:`\kappa`, is defined as the
|
||||
fission product kinetic energy, prompt and delayed neutron kinetic energies,
|
||||
|
|
@ -2878,7 +2891,7 @@ class KappaFissionXS(MGXS):
|
|||
|
||||
|
||||
class ScatterXS(MGXS):
|
||||
r"""A scattering multi-group cross section.
|
||||
"""A scattering multi-group cross section.
|
||||
|
||||
The scattering cross section is defined as the difference between the total
|
||||
and absorption cross sections.
|
||||
|
|
@ -2991,7 +3004,7 @@ class ScatterXS(MGXS):
|
|||
|
||||
|
||||
class NuScatterXS(MGXS):
|
||||
r"""A scattering neutron production multi-group cross section.
|
||||
"""A scattering neutron production multi-group cross section.
|
||||
|
||||
The neutron production from scattering is defined as the average number of
|
||||
neutrons produced from all neutron-producing reactions except for fission.
|
||||
|
|
@ -3110,7 +3123,7 @@ class NuScatterXS(MGXS):
|
|||
|
||||
|
||||
class ScatterMatrixXS(MatrixMGXS):
|
||||
r"""A scattering matrix multi-group cross section for one or more Legendre
|
||||
"""A scattering matrix multi-group cross section for one or more Legendre
|
||||
moments.
|
||||
|
||||
This class can be used for both OpenMC input generation and tally data
|
||||
|
|
@ -3444,7 +3457,7 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
subdomains='all', nuclides='all', moment='all',
|
||||
xs_type='macro', order_groups='increasing',
|
||||
row_column='inout', value='mean', **kwargs):
|
||||
r"""Returns an array of multi-group cross sections.
|
||||
"""Returns an array of multi-group cross sections.
|
||||
|
||||
This method constructs a 2D NumPy array for the requested scattering
|
||||
matrix data data for one or more energy groups and subdomains.
|
||||
|
|
@ -3890,7 +3903,7 @@ class NuScatterMatrixXS(ScatterMatrixXS):
|
|||
|
||||
|
||||
class MultiplicityMatrixXS(MatrixMGXS):
|
||||
r"""The scattering multiplicity matrix.
|
||||
"""The scattering multiplicity matrix.
|
||||
|
||||
This class can be used for both OpenMC input generation and tally data
|
||||
post-processing to compute spatially-homogenized and energy-integrated
|
||||
|
|
@ -4044,7 +4057,7 @@ class MultiplicityMatrixXS(MatrixMGXS):
|
|||
|
||||
|
||||
class NuFissionMatrixXS(MatrixMGXS):
|
||||
r"""A fission production matrix multi-group cross section.
|
||||
"""A fission production matrix multi-group cross section.
|
||||
|
||||
This class can be used for both OpenMC input generation and tally data
|
||||
post-processing to compute spatially-homogenized and energy-integrated
|
||||
|
|
@ -4159,7 +4172,7 @@ class NuFissionMatrixXS(MatrixMGXS):
|
|||
|
||||
|
||||
class Chi(MGXS):
|
||||
r"""The fission spectrum.
|
||||
"""The fission spectrum.
|
||||
|
||||
This class can be used for both OpenMC input generation and tally data
|
||||
post-processing to compute spatially-homogenized and energy-integrated
|
||||
|
|
@ -4615,3 +4628,836 @@ class Chi(MGXS):
|
|||
df['std. dev.'] *= np.tile(densities, tile_factor)
|
||||
|
||||
return df
|
||||
|
||||
|
||||
class ChiPrompt(Chi):
|
||||
"""The prompt fission spectrum.
|
||||
|
||||
This class can be used for both OpenMC input generation and tally data
|
||||
post-processing to compute spatially-homogenized and energy-integrated
|
||||
multi-group cross sections for multi-group neutronics calculations. At a
|
||||
minimum, one needs to set the :attr:`ChiPrompt.energy_groups` and
|
||||
:attr:`ChiPrompt.domain` properties. Tallies for the flux and appropriate
|
||||
reaction rates over the specified domain are generated automatically via the
|
||||
:attr:`ChiPrompt.tallies` property, which can then be appended to a
|
||||
:class:`openmc.Tallies` instance.
|
||||
|
||||
For post-processing, the :meth:`MGXS.load_from_statepoint` will pull in the
|
||||
necessary data to compute multi-group cross sections from a
|
||||
:class:`openmc.StatePoint` instance. The derived multi-group cross section
|
||||
can then be obtained from the :attr:`ChiPrompt.xs_tally` property.
|
||||
|
||||
For a spatial domain :math:`V` and energy group :math:`[E_g,E_{g-1}]`, the
|
||||
fission spectrum is calculated as:
|
||||
|
||||
.. math::
|
||||
|
||||
\langle \nu\sigma_{f,\rightarrow g}^p \phi \rangle &= \int_{r \in V} dr
|
||||
\int_{4\pi} d\Omega' \int_0^\infty dE' \int_{E_g}^{E_{g-1}} dE \; \chi(E)
|
||||
\nu\sigma_f (r, E') \psi(r, E', \Omega')\\
|
||||
\langle \nu\sigma_f^p \phi \rangle &= \int_{r \in V} dr \int_{4\pi}
|
||||
d\Omega' \int_0^\infty dE' \int_0^\infty dE \; \chi(E) \nu\sigma_f^p (r,
|
||||
E') \psi(r, E', \Omega') \\
|
||||
\chi_g^p &= \frac{\langle \nu\sigma_{f,\rightarrow g}^p \phi \rangle}{\langle
|
||||
\nu\sigma_f^p \phi \rangle}
|
||||
|
||||
Parameters
|
||||
----------
|
||||
domain : openmc.Material or openmc.Cell or openmc.Universe
|
||||
The domain for spatial homogenization
|
||||
domain_type : {'material', 'cell', 'distribcell', 'universe'}
|
||||
The domain type for spatial homogenization
|
||||
groups : openmc.mgxs.EnergyGroups
|
||||
The energy group structure for energy condensation
|
||||
by_nuclide : bool
|
||||
If true, computes cross sections for each nuclide in domain
|
||||
name : str, optional
|
||||
Name of the multi-group cross section. Used as a label to identify
|
||||
tallies in OpenMC 'tallies.xml' file.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
name : str, optional
|
||||
Name of the multi-group cross section
|
||||
rxn_type : str
|
||||
Reaction type (e.g., 'total', 'nu-fission', etc.)
|
||||
by_nuclide : bool
|
||||
If true, computes cross sections for each nuclide in domain
|
||||
domain : Material or Cell or Universe
|
||||
Domain for spatial homogenization
|
||||
domain_type : {'material', 'cell', 'distribcell', 'universe'}
|
||||
Domain type for spatial homogenization
|
||||
energy_groups : openmc.mgxs.EnergyGroups
|
||||
Energy group structure for energy condensation
|
||||
tally_trigger : openmc.Trigger
|
||||
An (optional) tally precision trigger given to each tally used to
|
||||
compute the cross section
|
||||
scores : list of str
|
||||
The scores in each tally used to compute the multi-group cross section
|
||||
filters : list of openmc.Filter
|
||||
The filters in each tally used to compute the multi-group cross section
|
||||
tally_keys : list of str
|
||||
The keys into the tallies dictionary for each tally used to compute
|
||||
the multi-group cross section
|
||||
estimator : {'tracklength', 'analog'}
|
||||
The tally estimator used to compute the multi-group cross section
|
||||
tallies : collections.OrderedDict
|
||||
OpenMC tallies needed to compute the multi-group cross section. The keys
|
||||
are strings listed in the :attr:`ChiPrompt.tally_keys` property and
|
||||
values are instances of :class:`openmc.Tally`.
|
||||
rxn_rate_tally : openmc.Tally
|
||||
Derived tally for the reaction rate tally used in the numerator to
|
||||
compute the multi-group cross section. This attribute is None
|
||||
unless the multi-group cross section has been computed.
|
||||
xs_tally : openmc.Tally
|
||||
Derived tally for the multi-group cross section. This attribute
|
||||
is None unless the multi-group cross section has been computed.
|
||||
num_subdomains : int
|
||||
The number of subdomains is unity for 'material', 'cell' and 'universe'
|
||||
domain types. When the This is equal to the number of cell instances
|
||||
for 'distribcell' domain types (it is equal to unity prior to loading
|
||||
tally data from a statepoint file).
|
||||
num_nuclides : int
|
||||
The number of nuclides for which the multi-group cross section is
|
||||
being tracked. This is unity if the by_nuclide attribute is False.
|
||||
nuclides : Iterable of str or 'sum'
|
||||
The optional user-specified nuclides for which to compute cross
|
||||
sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides
|
||||
are not specified by the user, all nuclides in the spatial domain
|
||||
are included. This attribute is 'sum' if by_nuclide is false.
|
||||
sparse : bool
|
||||
Whether or not the MGXS' tallies use SciPy's LIL sparse matrix format
|
||||
for compressed data storage
|
||||
loaded_sp : bool
|
||||
Whether or not a statepoint file has been loaded with tally data
|
||||
derived : bool
|
||||
Whether or not the MGXS is merged from one or more other MGXS
|
||||
hdf5_key : str
|
||||
The key used to index multi-group cross sections in an HDF5 data store
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, domain=None, domain_type=None,
|
||||
groups=None, by_nuclide=False, name=''):
|
||||
super(ChiPrompt, self).__init__(domain, domain_type, groups, by_nuclide, name)
|
||||
self._rxn_type = 'chi-prompt'
|
||||
|
||||
@property
|
||||
def scores(self):
|
||||
return ['delayed-nu-fission', 'delayed-nu-fission',
|
||||
'nu-fission', 'nu-fission']
|
||||
|
||||
@property
|
||||
def filters(self):
|
||||
# Create the non-domain specific Filters for the Tallies
|
||||
group_edges = self.energy_groups.group_edges
|
||||
energyout = openmc.Filter('energyout', group_edges)
|
||||
energyin = openmc.Filter('energy', [group_edges[0], group_edges[-1]])
|
||||
return [[energyin], [energyout], [energyin], [energyout]]
|
||||
|
||||
@property
|
||||
def tally_keys(self):
|
||||
return ['delayed-nu-fission-in', 'delayed-nu-fission-out',
|
||||
'nu-fission-in', 'nu-fission-out']
|
||||
|
||||
@property
|
||||
def rxn_rate_tally(self):
|
||||
if self._rxn_rate_tally is None:
|
||||
self._rxn_rate_tally = self.tallies['nu-fission-out'] - \
|
||||
self.tallies['delayed-nu-fission-out']
|
||||
self._rxn_rate_tally.sparse = self.sparse
|
||||
return self._rxn_rate_tally
|
||||
|
||||
@property
|
||||
def xs_tally(self):
|
||||
|
||||
if self._xs_tally is None:
|
||||
delayed_nu_fission_in = self.tallies['delayed-nu-fission-in']
|
||||
nu_fission_in = self.tallies['nu-fission-in']
|
||||
prompt_nu_fission_in = nu_fission_in - delayed_nu_fission_in
|
||||
|
||||
# Remove coarse energy filter to keep it out of tally arithmetic
|
||||
energy_filter = prompt_nu_fission_in.find_filter('energy')
|
||||
prompt_nu_fission_in.remove_filter(energy_filter)
|
||||
|
||||
# Compute chi
|
||||
self._xs_tally = self.rxn_rate_tally / prompt_nu_fission_in
|
||||
super(ChiPrompt, self)._compute_xs()
|
||||
|
||||
# Add the coarse energy filter back to the nu-fission tally
|
||||
prompt_nu_fission_in.filters.append(energy_filter)
|
||||
|
||||
return self._xs_tally
|
||||
|
||||
def get_slice(self, nuclides=[], groups=[]):
|
||||
"""Build a sliced ChiDelayed for the specified nuclides and energy
|
||||
groups.
|
||||
|
||||
This method constructs a new MGXS to encapsulate a subset of the data
|
||||
represented by this MGXS. The subset of data to include in the tally
|
||||
slice is determined by the nuclides and energy groups specified in
|
||||
the input parameters.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nuclides : list of str
|
||||
A list of nuclide name strings
|
||||
(e.g., ['U-235', 'U-238']; default is [])
|
||||
groups : list of Integral
|
||||
A list of energy group indices starting at 1 for the high energies
|
||||
(e.g., [1, 2, 3]; default is [])
|
||||
|
||||
Returns
|
||||
-------
|
||||
openmc.mgxs.MGXS
|
||||
A new MGXS which encapsulates the subset of data requested
|
||||
for the nuclide(s) and/or energy group(s) requested in the
|
||||
parameters.
|
||||
|
||||
"""
|
||||
|
||||
# Temporarily remove energy filter from delayed-nu-fission-in since its
|
||||
# group structure will work in super MGXS.get_slice(...) method
|
||||
delayed_nu_fission_in = self.tallies['delayed-nu-fission-in']
|
||||
nu_fission_in = self.tallies['nu-fission-in']
|
||||
prompt_nu_fission_in = nu_fission_in - delayed_nu_fission_in
|
||||
energy_filter = prompt_nu_fission_in.find_filter('energy')
|
||||
prompt_nu_fission_in.remove_filter(energy_filter)
|
||||
|
||||
# Call super class method and null out derived tallies
|
||||
slice_xs = super(ChiPrompt, self).get_slice(nuclides, groups)
|
||||
slice_xs._rxn_rate_tally = None
|
||||
slice_xs._xs_tally = None
|
||||
|
||||
# Slice energy groups if needed
|
||||
if len(groups) != 0:
|
||||
filter_bins = []
|
||||
for group in groups:
|
||||
group_bounds = self.energy_groups.get_group_bounds(group)
|
||||
filter_bins.append(group_bounds)
|
||||
filter_bins = [tuple(filter_bins)]
|
||||
|
||||
# Slice nu-fission-out tally along energyout filter
|
||||
prompt_nu_fission_out = slice_xs.tallies['nu-fission-out'] - \
|
||||
slice_xs.tallies['delayed-nu-fission-out']
|
||||
tally_slice = prompt_nu_fission_out\
|
||||
.get_slice(filters=['energyout'],
|
||||
filter_bins=filter_bins)
|
||||
slice_xs._tallies['prompt-nu-fission-out'] = tally_slice
|
||||
|
||||
# Add energy filter back to nu-fission-in tallies
|
||||
slice_xs._tallies['prompt-nu-fission-in'].add_filter(energy_filter)
|
||||
|
||||
slice_xs.sparse = self.sparse
|
||||
return slice_xs
|
||||
|
||||
def merge(self, other):
|
||||
"""Merge another ChiPrompt with this one
|
||||
|
||||
If results have been loaded from a statepoint, then ChiPrompt are only
|
||||
mergeable along one and only one of energy groups or nuclides.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
other : openmc.mgxs.MGXS
|
||||
MGXS to merge with this one
|
||||
|
||||
Returns
|
||||
-------
|
||||
merged_mgxs : openmc.mgxs.MGXS
|
||||
Merged MGXS
|
||||
"""
|
||||
|
||||
if not self.can_merge(other):
|
||||
raise ValueError('Unable to merge ChiPrompt')
|
||||
|
||||
return super(ChiPrompt, self).merge(other)
|
||||
|
||||
def get_xs(self, groups='all', subdomains='all', nuclides='all',
|
||||
xs_type='macro', order_groups='increasing',
|
||||
value='mean', **kwargs):
|
||||
"""Returns an array of the fission spectrum.
|
||||
|
||||
This method constructs a 2D NumPy array for the requested multi-group
|
||||
cross section data data for one or more energy groups and subdomains.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
groups : Iterable of Integral or 'all'
|
||||
Energy groups of interest. Defaults to 'all'.
|
||||
subdomains : Iterable of Integral or 'all'
|
||||
Subdomain IDs of interest. Defaults to 'all'.
|
||||
nuclides : Iterable of str or 'all' or 'sum'
|
||||
A list of nuclide name strings (e.g., ['U-235', 'U-238']). The
|
||||
special string 'all' will return the cross sections for all nuclides
|
||||
in the spatial domain. The special string 'sum' will return the
|
||||
cross section summed over all nuclides. Defaults to 'all'.
|
||||
xs_type: {'macro', 'micro'}
|
||||
This parameter is not relevant for chi but is included here to
|
||||
mirror the parent MGXS.get_xs(...) class method
|
||||
order_groups: {'increasing', 'decreasing'}
|
||||
Return the cross section indexed according to increasing or
|
||||
decreasing energy groups (decreasing or increasing energies).
|
||||
Defaults to 'increasing'.
|
||||
value : {'mean', 'std_dev', 'rel_err'}
|
||||
A string for the type of value to return. Defaults to 'mean'.
|
||||
|
||||
Returns
|
||||
-------
|
||||
numpy.ndarray
|
||||
A NumPy array of the multi-group cross section indexed in the order
|
||||
each group, subdomain and nuclide is listed in the parameters.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
When this method is called before the multi-group cross section is
|
||||
computed from tally data.
|
||||
|
||||
"""
|
||||
|
||||
cv.check_value('value', value, ['mean', 'std_dev', 'rel_err'])
|
||||
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
|
||||
|
||||
filters = []
|
||||
filter_bins = []
|
||||
|
||||
# Construct a collection of the domain filter bins
|
||||
if not isinstance(subdomains, basestring):
|
||||
cv.check_iterable_type('subdomains', subdomains, Integral, max_depth=2)
|
||||
for subdomain in subdomains:
|
||||
filters.append(self.domain_type)
|
||||
filter_bins.append((subdomain,))
|
||||
|
||||
# Construct list of energy group bounds tuples for all requested groups
|
||||
if not isinstance(groups, basestring):
|
||||
cv.check_iterable_type('groups', groups, Integral)
|
||||
for group in groups:
|
||||
filters.append('energyout')
|
||||
filter_bins.append((self.energy_groups.get_group_bounds(group),))
|
||||
|
||||
# If chi delayed was computed for each nuclide in the domain
|
||||
if self.by_nuclide:
|
||||
|
||||
# Get the sum as the fission source weighted average chi for all
|
||||
# nuclides in the domain
|
||||
if nuclides == 'sum' or nuclides == ['sum']:
|
||||
|
||||
# Retrieve the fission production tallies
|
||||
prompt_nu_fission_in = self.tallies['nu-fission-in'] - \
|
||||
self.tallies['delayed-nu-fission-in']
|
||||
prompt_nu_fission_out = self.tallies['nu-fission-out'] - \
|
||||
self.tallies['delayed-nu-fission-out']
|
||||
|
||||
# Sum out all nuclides
|
||||
nuclides = self.get_all_nuclides()
|
||||
prompt_nu_fission_in = prompt_nu_fission_in.summation\
|
||||
(nuclides=nuclides)
|
||||
prompt_nu_fission_out = prompt_nu_fission_out.summation\
|
||||
(nuclides=nuclides)
|
||||
|
||||
# Remove coarse energy filter to keep it out of tally arithmetic
|
||||
energy_filter = prompt_nu_fission_in.find_filter('energy')
|
||||
prompt_nu_fission_in.remove_filter(energy_filter)
|
||||
|
||||
# Compute chi and store it as the xs_tally attribute so we can
|
||||
# use the generic get_xs(...) method
|
||||
xs_tally = prompt_nu_fission_out / prompt_nu_fission_in
|
||||
|
||||
# Add the coarse energy filter back to the nu-fission tally
|
||||
prompt_nu_fission_in.filters.append(energy_filter)
|
||||
|
||||
xs = xs_tally.get_values(filters=filters,
|
||||
filter_bins=filter_bins, value=value)
|
||||
|
||||
# Get chi delayed for all nuclides in the domain
|
||||
elif nuclides == 'all':
|
||||
nuclides = self.get_all_nuclides()
|
||||
xs = self.xs_tally.get_values(filters=filters,
|
||||
filter_bins=filter_bins,
|
||||
nuclides=nuclides, value=value)
|
||||
|
||||
# Get chi prompt for user-specified nuclides in the domain
|
||||
else:
|
||||
cv.check_iterable_type('nuclides', nuclides, basestring)
|
||||
xs = self.xs_tally.get_values(filters=filters,
|
||||
filter_bins=filter_bins,
|
||||
nuclides=nuclides, value=value)
|
||||
|
||||
# If chi prompt was computed as an average of nuclides in the domain
|
||||
else:
|
||||
xs = self.xs_tally.get_values(filters=filters,
|
||||
filter_bins=filter_bins, value=value)
|
||||
|
||||
# Reverse data if user requested increasing energy groups since
|
||||
# tally data is stored in order of increasing energies
|
||||
if order_groups == 'increasing':
|
||||
|
||||
# Reshape tally data array with separate axes for domain and energy
|
||||
if groups == 'all':
|
||||
num_groups = self.num_groups
|
||||
else:
|
||||
num_groups = len(groups)
|
||||
num_subdomains = int(xs.shape[0] / num_groups)
|
||||
new_shape = (num_subdomains, num_groups) + xs.shape[1:]
|
||||
xs = np.reshape(xs, new_shape)
|
||||
|
||||
# Reverse energies to align with increasing energy groups
|
||||
xs = xs[:, ::-1, :]
|
||||
|
||||
# Eliminate trivial dimensions
|
||||
xs = np.squeeze(xs)
|
||||
xs = np.atleast_1d(xs)
|
||||
|
||||
xs = np.nan_to_num(xs)
|
||||
return xs
|
||||
|
||||
|
||||
class Velocity(MGXS):
|
||||
"""A velocity multi-group cross section.
|
||||
|
||||
This class can be used for both OpenMC input generation and tally data
|
||||
post-processing to compute spatially-homogenized and energy-integrated
|
||||
multi-group velocity cross sections for multi-group neutronics
|
||||
calculations. At a minimum, one needs to set the
|
||||
:attr:`Velocity.energy_groups` and :attr:`Velocity.domain`
|
||||
properties. Tallies for the flux and appropriate reaction rates over the
|
||||
specified domain are generated automatically via the
|
||||
:attr:`Velocity.tallies` property, which can then be appended to a
|
||||
:class:`openmc.Tallies` instance.
|
||||
|
||||
For post-processing, the :meth:`MGXS.load_from_statepoint` will pull in the
|
||||
necessary data to compute multi-group cross sections from a
|
||||
:class:`openmc.StatePoint` instance. The derived multi-group cross section
|
||||
can then be obtained from the :attr:`Velocity.xs_tally` property.
|
||||
|
||||
For a spatial domain :math:`V` and energy group :math:`[E_g,E_{g-1}]`, the
|
||||
velocity cross section is calculated as:
|
||||
|
||||
.. math::
|
||||
|
||||
\frac{\int_{r \in V} dr \int_{4\pi} d\Omega \int_{E_g}^{E_{g-1}} dE \;
|
||||
\psi (r, E, \Omega)}{\int_{r \in V} dr \int_{4\pi}
|
||||
d\Omega \int_{E_g}^{E_{g-1}} dE \; \frac{\psi (r, E, \Omega)}{v (r, E)}}.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
domain : openmc.Material or openmc.Cell or openmc.Universe
|
||||
The domain for spatial homogenization
|
||||
domain_type : {'material', 'cell', 'distribcell', 'universe'}
|
||||
The domain type for spatial homogenization
|
||||
groups : openmc.mgxs.EnergyGroups
|
||||
The energy group structure for energy condensation
|
||||
by_nuclide : bool
|
||||
If true, computes cross sections for each nuclide in domain
|
||||
name : str, optional
|
||||
Name of the multi-group cross section. Used as a label to identify
|
||||
tallies in OpenMC 'tallies.xml' file.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
name : str, optional
|
||||
Name of the multi-group cross section
|
||||
rxn_type : str
|
||||
Reaction type (e.g., 'total', 'nu-fission', etc.)
|
||||
by_nuclide : bool
|
||||
If true, computes cross sections for each nuclide in domain
|
||||
domain : Material or Cell or Universe
|
||||
Domain for spatial homogenization
|
||||
domain_type : {'material', 'cell', 'distribcell', 'universe'}
|
||||
Domain type for spatial homogenization
|
||||
energy_groups : openmc.mgxs.EnergyGroups
|
||||
Energy group structure for energy condensation
|
||||
tally_trigger : openmc.Trigger
|
||||
An (optional) tally precision trigger given to each tally used to
|
||||
compute the cross section
|
||||
scores : list of str
|
||||
The scores in each tally used to compute the multi-group cross section
|
||||
filters : list of openmc.Filter
|
||||
The filters in each tally used to compute the multi-group cross section
|
||||
tally_keys : list of str
|
||||
The keys into the tallies dictionary for each tally used to compute
|
||||
the multi-group cross section
|
||||
estimator : {'tracklength', 'analog'}
|
||||
The tally estimator used to compute the multi-group cross section
|
||||
tallies : collections.OrderedDict
|
||||
OpenMC tallies needed to compute the multi-group cross section. The keys
|
||||
are strings listed in the :attr:`AbsorptionXS.tally_keys` property and
|
||||
values are instances of :class:`openmc.Tally`.
|
||||
rxn_rate_tally : openmc.Tally
|
||||
Derived tally for the reaction rate tally used in the numerator to
|
||||
compute the multi-group cross section. This attribute is None
|
||||
unless the multi-group cross section has been computed.
|
||||
xs_tally : openmc.Tally
|
||||
Derived tally for the multi-group cross section. This attribute
|
||||
is None unless the multi-group cross section has been computed.
|
||||
num_subdomains : int
|
||||
The number of subdomains is unity for 'material', 'cell' and 'universe'
|
||||
domain types. This is equal to the number of cell instances
|
||||
for 'distribcell' domain types (it is equal to unity prior to loading
|
||||
tally data from a statepoint file).
|
||||
num_nuclides : int
|
||||
The number of nuclides for which the multi-group cross section is
|
||||
being tracked. This is unity if the by_nuclide attribute is False.
|
||||
nuclides : Iterable of str or 'sum'
|
||||
The optional user-specified nuclides for which to compute cross
|
||||
sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides
|
||||
are not specified by the user, all nuclides in the spatial domain
|
||||
are included. This attribute is 'sum' if by_nuclide is false.
|
||||
sparse : bool
|
||||
Whether or not the MGXS' tallies use SciPy's LIL sparse matrix format
|
||||
for compressed data storage
|
||||
loaded_sp : bool
|
||||
Whether or not a statepoint file has been loaded with tally data
|
||||
derived : bool
|
||||
Whether or not the MGXS is merged from one or more other MGXS
|
||||
hdf5_key : str
|
||||
The key used to index multi-group cross sections in an HDF5 data store
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, domain=None, domain_type=None,
|
||||
groups=None, by_nuclide=False, name=''):
|
||||
super(Velocity, self).__init__(domain, domain_type,
|
||||
groups, by_nuclide, name)
|
||||
self._rxn_type = 'velocity'
|
||||
|
||||
@property
|
||||
def scores(self):
|
||||
return ['inverse-velocity', 'flux']
|
||||
|
||||
@property
|
||||
def tally_keys(self):
|
||||
return ['inverse-velocity', 'flux']
|
||||
|
||||
@property
|
||||
def rxn_rate_tally(self):
|
||||
if self._rxn_rate_tally is None:
|
||||
self._rxn_rate_tally = self.tallies['flux']
|
||||
self._rxn_rate_tally.sparse = self.sparse
|
||||
return self._rxn_rate_tally
|
||||
|
||||
@property
|
||||
def xs_tally(self):
|
||||
|
||||
if self._xs_tally is None:
|
||||
inverse_velocity = self.tallies['inverse-velocity']
|
||||
|
||||
# Compute the velocity
|
||||
self._xs_tally = self.rxn_rate_tally / inverse_velocity
|
||||
super(Velocity, self)._compute_xs()
|
||||
|
||||
return self._xs_tally
|
||||
|
||||
def print_xs(self, subdomains='all', nuclides='all', xs_type='macro'):
|
||||
"""Print a string representation for the multi-group cross section.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
subdomains : Iterable of Integral or 'all'
|
||||
The subdomain IDs of the cross sections to include in the report.
|
||||
Defaults to 'all'.
|
||||
nuclides : Iterable of str or 'all' or 'sum'
|
||||
The nuclides of the cross-sections to include in the report. This
|
||||
may be a list of nuclide name strings (e.g., ['U-235', 'U-238']).
|
||||
The special string 'all' will report the cross sections for all
|
||||
nuclides in the spatial domain. The special string 'sum' will report
|
||||
the cross sections summed over all nuclides. Defaults to 'all'.
|
||||
xs_type: {'macro', 'micro'}
|
||||
Return the macro or micro cross section in units of cm^-1 or barns.
|
||||
Defaults to 'macro'.
|
||||
|
||||
"""
|
||||
|
||||
# Construct a collection of the subdomains to report
|
||||
if not isinstance(subdomains, basestring):
|
||||
cv.check_iterable_type('subdomains', subdomains, Integral)
|
||||
elif self.domain_type == 'distribcell':
|
||||
subdomains = np.arange(self.num_subdomains, dtype=np.int)
|
||||
else:
|
||||
subdomains = [self.domain.id]
|
||||
|
||||
# Construct a collection of the nuclides to report
|
||||
if self.by_nuclide:
|
||||
if nuclides == 'all':
|
||||
nuclides = self.get_all_nuclides()
|
||||
elif nuclides == 'sum':
|
||||
nuclides = ['sum']
|
||||
else:
|
||||
cv.check_iterable_type('nuclides', nuclides, basestring)
|
||||
else:
|
||||
nuclides = ['sum']
|
||||
|
||||
cv.check_value('xs_type', xs_type, ['macro'])
|
||||
|
||||
# Build header for string with type and domain info
|
||||
string = 'Multi-Group XS\n'
|
||||
string += '{0: <16}=\t{1}\n'.format('\tReaction Type', self.rxn_type)
|
||||
string += '{0: <16}=\t{1}\n'.format('\tDomain Type', self.domain_type)
|
||||
string += '{0: <16}=\t{1}\n'.format('\tDomain ID', self.domain.id)
|
||||
|
||||
# If cross section data has not been computed, only print string header
|
||||
if self.tallies is None:
|
||||
print(string)
|
||||
return
|
||||
|
||||
# Loop over all subdomains
|
||||
for subdomain in subdomains:
|
||||
|
||||
if self.domain_type == 'distribcell':
|
||||
string += '{0: <16}=\t{1}\n'.format('\tSubdomain', subdomain)
|
||||
|
||||
# Loop over all Nuclides
|
||||
for nuclide in nuclides:
|
||||
|
||||
# Build header for nuclide type
|
||||
if nuclide != 'sum':
|
||||
string += '{0: <16}=\t{1}\n'.format('\tNuclide', nuclide)
|
||||
|
||||
# Build header for cross section type
|
||||
string += '{0: <16}\n'.format\
|
||||
('\tVelocity [cm/second]:')
|
||||
|
||||
template = '{0: <12}Group {1} [{2: <10} - {3: <10}MeV]:\t'
|
||||
|
||||
# Loop over energy groups ranges
|
||||
for group in range(1, self.num_groups+1):
|
||||
bounds = self.energy_groups.get_group_bounds(group)
|
||||
string += template.format('', group, bounds[0], bounds[1])
|
||||
average = self.get_xs([group], [subdomain], [nuclide],
|
||||
xs_type=xs_type, value='mean')
|
||||
rel_err = self.get_xs([group], [subdomain], [nuclide],
|
||||
xs_type=xs_type, value='rel_err')
|
||||
average = average.flatten()[0]
|
||||
rel_err = rel_err.flatten()[0] * 100.
|
||||
string += '{:.2e} +/- {:1.2e}%'.format(average, rel_err)
|
||||
string += '\n'
|
||||
string += '\n'
|
||||
string += '\n'
|
||||
|
||||
print(string)
|
||||
|
||||
|
||||
class PromptNeutronLifetime(MGXS):
|
||||
"""The prompt neutron lifetime.
|
||||
|
||||
This class can be used for both OpenMC input generation and tally data
|
||||
post-processing to compute spatially-homogenized and energy-integrated
|
||||
multi-group cross sections for multi-group neutronics calculations. At a
|
||||
minimum, one needs to set the :attr:`PromptNeutronLifetime.energy_groups`
|
||||
and :attr:`PromptNeutronLifetime.domain` properties. Tallies for the flux
|
||||
and appropriate reaction rates over the specified domain are generated
|
||||
automatically via the :attr:`PromptNeutronLifetime.tallies` property, which
|
||||
can then be appended to a :class:`openmc.Tallies` instance.
|
||||
|
||||
For post-processing, the :meth:`MGXS.load_from_statepoint` will pull in the
|
||||
necessary data to compute multi-group cross sections from a
|
||||
:class:`openmc.StatePoint` instance. The derived multi-group cross section
|
||||
can then be obtained from the :attr:`PromptNeutronLifetime.xs_tally`
|
||||
property.
|
||||
|
||||
For a spatial domain :math:`V` and energy group :math:`[E_g,E_{g-1}]`, the
|
||||
fission spectrum is calculated as:
|
||||
|
||||
.. math::
|
||||
|
||||
\frac{\int_{r \in V} dr \int_{4\pi} d\Omega \int_{E_g}^{E_{g-1}} dE \;
|
||||
\frac{\psi (r, E, \Omega)}{v (r, E)}}{\int_{r \in V} dr \int_{4\pi}
|
||||
d\Omega \int_{E_g}^{E_{g-1}} dE \; \nu\sigma_f (r, E') \psi(r, E', \Omega')}.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
domain : openmc.Material or openmc.Cell or openmc.Universe
|
||||
The domain for spatial homogenization
|
||||
domain_type : {'material', 'cell', 'distribcell', 'universe'}
|
||||
The domain type for spatial homogenization
|
||||
groups : openmc.mgxs.EnergyGroups
|
||||
The energy group structure for energy condensation
|
||||
by_nuclide : bool
|
||||
If true, computes cross sections for each nuclide in domain
|
||||
name : str, optional
|
||||
Name of the multi-group cross section. Used as a label to identify
|
||||
tallies in OpenMC 'tallies.xml' file.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
name : str, optional
|
||||
Name of the multi-group cross section
|
||||
rxn_type : str
|
||||
Reaction type (e.g., 'total', 'nu-fission', etc.)
|
||||
by_nuclide : bool
|
||||
If true, computes cross sections for each nuclide in domain
|
||||
domain : Material or Cell or Universe
|
||||
Domain for spatial homogenization
|
||||
domain_type : {'material', 'cell', 'distribcell', 'universe'}
|
||||
Domain type for spatial homogenization
|
||||
energy_groups : openmc.mgxs.EnergyGroups
|
||||
Energy group structure for energy condensation
|
||||
tally_trigger : openmc.Trigger
|
||||
An (optional) tally precision trigger given to each tally used to
|
||||
compute the cross section
|
||||
scores : list of str
|
||||
The scores in each tally used to compute the multi-group cross section
|
||||
filters : list of openmc.Filter
|
||||
The filters in each tally used to compute the multi-group cross section
|
||||
tally_keys : list of str
|
||||
The keys into the tallies dictionary for each tally used to compute
|
||||
the multi-group cross section
|
||||
estimator : {'tracklength', 'analog'}
|
||||
The tally estimator used to compute the multi-group cross section
|
||||
tallies : collections.OrderedDict
|
||||
OpenMC tallies needed to compute the multi-group cross section. The keys
|
||||
are strings listed in the :attr:`ChiDelayed.tally_keys` property and
|
||||
values are instances of :class:`openmc.Tally`.
|
||||
rxn_rate_tally : openmc.Tally
|
||||
Derived tally for the reaction rate tally used in the numerator to
|
||||
compute the multi-group cross section. This attribute is None
|
||||
unless the multi-group cross section has been computed.
|
||||
xs_tally : openmc.Tally
|
||||
Derived tally for the multi-group cross section. This attribute
|
||||
is None unless the multi-group cross section has been computed.
|
||||
num_subdomains : int
|
||||
The number of subdomains is unity for 'material', 'cell' and 'universe'
|
||||
domain types. When the This is equal to the number of cell instances
|
||||
for 'distribcell' domain types (it is equal to unity prior to loading
|
||||
tally data from a statepoint file).
|
||||
num_nuclides : int
|
||||
The number of nuclides for which the multi-group cross section is
|
||||
being tracked. This is unity if the by_nuclide attribute is False.
|
||||
nuclides : Iterable of str or 'sum'
|
||||
The optional user-specified nuclides for which to compute cross
|
||||
sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides
|
||||
are not specified by the user, all nuclides in the spatial domain
|
||||
are included. This attribute is 'sum' if by_nuclide is false.
|
||||
sparse : bool
|
||||
Whether or not the MGXS' tallies use SciPy's LIL sparse matrix format
|
||||
for compressed data storage
|
||||
loaded_sp : bool
|
||||
Whether or not a statepoint file has been loaded with tally data
|
||||
derived : bool
|
||||
Whether or not the MGXS is merged from one or more other MGXS
|
||||
hdf5_key : str
|
||||
The key used to index multi-group cross sections in an HDF5 data store
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, domain=None, domain_type=None,
|
||||
groups=None, by_nuclide=False, name=''):
|
||||
super(PromptNeutronLifetime, self).__init__(domain, domain_type, groups,
|
||||
by_nuclide, name)
|
||||
self._rxn_type = 'prompt-neutron-lifetime'
|
||||
|
||||
@property
|
||||
def scores(self):
|
||||
return ['nu-fission', 'inverse-velocity']
|
||||
|
||||
@property
|
||||
def tally_keys(self):
|
||||
return ['nu-fission', 'inverse-velocity']
|
||||
|
||||
@property
|
||||
def rxn_rate_tally(self):
|
||||
if self._rxn_rate_tally is None:
|
||||
self._rxn_rate_tally = self.tallies['inverse-velocity']
|
||||
self._rxn_rate_tally.sparse = self.sparse
|
||||
return self._rxn_rate_tally
|
||||
|
||||
@property
|
||||
def xs_tally(self):
|
||||
|
||||
if self._xs_tally is None:
|
||||
nu_fission = self.tallies['nu-fission']
|
||||
|
||||
# Compute the prompt neutron lifetime
|
||||
self._xs_tally = self.rxn_rate_tally / nu_fission
|
||||
super(PromptNeutronLifetime, self)._compute_xs()
|
||||
|
||||
return self._xs_tally
|
||||
|
||||
def print_xs(self, subdomains='all', nuclides='all', xs_type='macro'):
|
||||
"""Print a string representation for the multi-group cross section.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
subdomains : Iterable of Integral or 'all'
|
||||
The subdomain IDs of the cross sections to include in the report.
|
||||
Defaults to 'all'.
|
||||
nuclides : Iterable of str or 'all' or 'sum'
|
||||
The nuclides of the cross-sections to include in the report. This
|
||||
may be a list of nuclide name strings (e.g., ['U-235', 'U-238']).
|
||||
The special string 'all' will report the cross sections for all
|
||||
nuclides in the spatial domain. The special string 'sum' will report
|
||||
the cross sections summed over all nuclides. Defaults to 'all'.
|
||||
xs_type: {'macro', 'micro'}
|
||||
Return the macro or micro cross section in units of cm^-1 or barns.
|
||||
Defaults to 'macro'.
|
||||
|
||||
"""
|
||||
|
||||
# Construct a collection of the subdomains to report
|
||||
if not isinstance(subdomains, basestring):
|
||||
cv.check_iterable_type('subdomains', subdomains, Integral)
|
||||
elif self.domain_type == 'distribcell':
|
||||
subdomains = np.arange(self.num_subdomains, dtype=np.int)
|
||||
else:
|
||||
subdomains = [self.domain.id]
|
||||
|
||||
# Construct a collection of the nuclides to report
|
||||
if self.by_nuclide:
|
||||
if nuclides == 'all':
|
||||
nuclides = self.get_all_nuclides()
|
||||
elif nuclides == 'sum':
|
||||
nuclides = ['sum']
|
||||
else:
|
||||
cv.check_iterable_type('nuclides', nuclides, basestring)
|
||||
else:
|
||||
nuclides = ['sum']
|
||||
|
||||
cv.check_value('xs_type', xs_type, ['macro'])
|
||||
|
||||
# Build header for string with type and domain info
|
||||
string = 'Multi-Group XS\n'
|
||||
string += '{0: <16}=\t{1}\n'.format('\tReaction Type', self.rxn_type)
|
||||
string += '{0: <16}=\t{1}\n'.format('\tDomain Type', self.domain_type)
|
||||
string += '{0: <16}=\t{1}\n'.format('\tDomain ID', self.domain.id)
|
||||
|
||||
# If cross section data has not been computed, only print string header
|
||||
if self.tallies is None:
|
||||
print(string)
|
||||
return
|
||||
|
||||
# Loop over all subdomains
|
||||
for subdomain in subdomains:
|
||||
|
||||
if self.domain_type == 'distribcell':
|
||||
string += '{0: <16}=\t{1}\n'.format('\tSubdomain', subdomain)
|
||||
|
||||
# Loop over all Nuclides
|
||||
for nuclide in nuclides:
|
||||
|
||||
# Build header for nuclide type
|
||||
if nuclide != 'sum':
|
||||
string += '{0: <16}=\t{1}\n'.format('\tNuclide', nuclide)
|
||||
|
||||
# Build header for cross section type
|
||||
string += '{0: <16}\n'.format\
|
||||
('\tPrompt Neutron Lifetime [seconds]:')
|
||||
|
||||
template = '{0: <12}Group {1} [{2: <10} - {3: <10}MeV]:\t'
|
||||
|
||||
# Loop over energy groups ranges
|
||||
for group in range(1, self.num_groups+1):
|
||||
bounds = self.energy_groups.get_group_bounds(group)
|
||||
string += template.format('', group, bounds[0], bounds[1])
|
||||
average = self.get_xs([group], [subdomain], [nuclide],
|
||||
xs_type=xs_type, value='mean')
|
||||
rel_err = self.get_xs([group], [subdomain], [nuclide],
|
||||
xs_type=xs_type, value='rel_err')
|
||||
average = average.flatten()[0]
|
||||
rel_err = rel_err.flatten()[0] * 100.
|
||||
string += '{:.2e} +/- {:1.2e}%'.format(average, rel_err)
|
||||
string += '\n'
|
||||
string += '\n'
|
||||
string += '\n'
|
||||
|
||||
print(string)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue