mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-26 13:15:39 -04:00
cleaned up mdgxs.py
This commit is contained in:
commit
bc8a346a97
18 changed files with 422 additions and 182 deletions
|
|
@ -574,7 +574,7 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Now we must specify the type of domain over which we would like the `Library` to compute multi-group cross sections. The domain type corresponds to the type of tally filter to be used in the tallies created to compute multi-group cross sections. At the present time, the `Library` supports `\"material,\"` `\"cell,\"` and `\"universe\"` domain types. We will use a `\"cell\"` domain type here to compute cross sections in each of the cells in the fuel assembly geometry.\n",
|
||||
"Now we must specify the type of domain over which we would like the `Library` to compute multi-group cross sections. The domain type corresponds to the type of tally filter to be used in the tallies created to compute multi-group cross sections. At the present time, the `Library` supports `\"material\"`, `\"cell\"`, `\"universe\"`, and `\"mesh\"` domain types. We will use a `\"cell\"` domain type here to compute cross sections in each of the cells in the fuel assembly geometry.\n",
|
||||
"\n",
|
||||
"**Note:** By default, the `Library` class will instantiate `MGXS` objects for each and every domain (material, cell or universe) in the geometry of interest. However, one may specify a subset of these domains to the `Library.domains` property. In our case, we wish to compute multi-group cross sections in each and every cell since they will be needed in our downstream OpenMOC calculation on the identical combinatorial geometry mesh."
|
||||
]
|
||||
|
|
|
|||
|
|
@ -519,9 +519,9 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Now we must specify the type of domain over which we would like the `Library` to compute multi-group cross sections. The domain type corresponds to the type of tally filter to be used in the tallies created to compute multi-group cross sections. At the present time, the `Library` supports \"material,\" \"cell,\" and \"universe\" domain types. In this simple example, we wish to compute multi-group cross sections only for each material andtherefore will use a \"material\" domain type.\n",
|
||||
"Now we must specify the type of domain over which we would like the `Library` to compute multi-group cross sections. The domain type corresponds to the type of tally filter to be used in the tallies created to compute multi-group cross sections. At the present time, the `Library` supports \"material\" \"cell\", \"universe\", and \"mesh\" domain types. In this simple example, we wish to compute multi-group cross sections only for each material andtherefore will use a \"material\" domain type.\n",
|
||||
"\n",
|
||||
"**Note:** By default, the `Library` class will instantiate `MGXS` objects for each and every domain (material, cell or universe) in the geometry of interest. However, one may specify a subset of these domains to the `Library.domains` property."
|
||||
"**Note:** By default, the `Library` class will instantiate `MGXS` objects for each and every domain (material, cell, universe, or mesh cell) in the geometry of interest. However, one may specify a subset of these domains to the `Library.domains` property."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -1437,21 +1437,21 @@
|
|||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"display_name": "Python 2",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
"name": "python2"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
"version": 2
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.5.2"
|
||||
"pygments_lexer": "ipython2",
|
||||
"version": "2.7.11"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
|
|
|||
|
|
@ -269,13 +269,16 @@ Multi-group Cross Sections
|
|||
openmc.mgxs.AbsorptionXS
|
||||
openmc.mgxs.CaptureXS
|
||||
openmc.mgxs.Chi
|
||||
openmc.mgxs.ChiPrompt
|
||||
openmc.mgxs.FissionXS
|
||||
openmc.mgxs.InverseVelocity
|
||||
openmc.mgxs.KappaFissionXS
|
||||
openmc.mgxs.MultiplicityMatrixXS
|
||||
openmc.mgxs.NuFissionXS
|
||||
openmc.mgxs.NuFissionMatrixXS
|
||||
openmc.mgxs.NuScatterXS
|
||||
openmc.mgxs.NuScatterMatrixXS
|
||||
openmc.mgxs.PromptNuFissionXS
|
||||
openmc.mgxs.ScatterXS
|
||||
openmc.mgxs.ScatterMatrixXS
|
||||
openmc.mgxs.TotalXS
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from collections import Iterable
|
||||
from numbers import Real
|
||||
from numbers import Real, Integral
|
||||
import copy
|
||||
import sys
|
||||
|
||||
|
|
@ -370,7 +370,7 @@ class DelayedGroups(object):
|
|||
|
||||
@groups.setter
|
||||
def groups(self, groups):
|
||||
cv.check_type('groups', groups, Iterable, Int)
|
||||
cv.check_type('groups', groups, Iterable, Integral)
|
||||
cv.check_greater_than('number of delayed groups', len(groups), 0)
|
||||
|
||||
# Check that the groups are within [1, MAX_DELAYED_GROUPS]
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class Library(object):
|
|||
The types of cross sections in the library (e.g., ['total', 'scatter'])
|
||||
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
|
||||
Domain type for spatial homogenization
|
||||
domains : Iterable of openmc.Material, openmc.Cell, openmc.Universe, or
|
||||
domains : Iterable of openmc.Material, openmc.Cell, openmc.Universe or
|
||||
openmc.Mesh
|
||||
The spatial domain(s) for which MGXS in the Library are computed
|
||||
correction : {'P0', None}
|
||||
|
|
@ -184,10 +184,8 @@ class Library(object):
|
|||
return self.openmc_geometry.get_all_material_cells()
|
||||
elif self.domain_type == 'universe':
|
||||
return self.openmc_geometry.get_all_universes()
|
||||
# FIXME: Change to get tuples of all domain cells
|
||||
elif self.domain_type == 'mesh':
|
||||
raise ValueError('Unable to get all domains for a mesh domain ' +
|
||||
'type. The domains must be set to [openmc.Mesh]')
|
||||
raise ValueError('Unable to get domains for Mesh domain type')
|
||||
else:
|
||||
raise ValueError('Unable to get domains without a domain type')
|
||||
else:
|
||||
|
|
@ -290,6 +288,9 @@ class Library(object):
|
|||
all_domains = self.openmc_geometry.get_all_universes()
|
||||
elif self.domain_type == 'mesh':
|
||||
cv.check_iterable_type('domain', domains, openmc.Mesh)
|
||||
|
||||
# The mesh and geometry are independent, so set all_domains
|
||||
# to the input domains
|
||||
all_domains = domains
|
||||
else:
|
||||
raise ValueError('Unable to set domains with domain '
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ import numpy as np
|
|||
from mgxs import MGXS, MGXS_TYPES, DOMAIN_TYPES, _DOMAINS
|
||||
from openmc.mgxs import EnergyGroups, DelayedGroups
|
||||
from openmc import Mesh
|
||||
import openmc
|
||||
import openmc.checkvalue as cv
|
||||
|
||||
# Supported cross section types
|
||||
MDGXS_TYPES = ['delayed-nu-fission',
|
||||
|
|
@ -145,19 +147,23 @@ class MDGXS(MGXS):
|
|||
|
||||
@delayed_groups.setter
|
||||
def delayed_groups(self, delayed_groups):
|
||||
cv.check_type('delayed groups', delayed_groups, openmc.mgxs.DelayedGroups)
|
||||
cv.check_type('delayed groups', delayed_groups,
|
||||
openmc.mgxs.DelayedGroups)
|
||||
self._delayed_groups = delayed_groups
|
||||
|
||||
@property
|
||||
def filters(self):
|
||||
|
||||
# Create the non-domain specific Filters for the Tallies
|
||||
group_edges = self.energy_groups.group_edges
|
||||
energy_filter = openmc.Filter('energy', group_edges)
|
||||
|
||||
if self.delayed_groups != None:
|
||||
delayed_groups = self.delayed_groups.groups
|
||||
delayed_filter = openmc.Filter('delayedgroup', delayed_groups)
|
||||
return [[delayed_filter, energy_filter]] * len(self.scores)
|
||||
return [[energy_filter], [delayed_filter, energy_filter]]
|
||||
else:
|
||||
return [[energy]] * len(self.scores)
|
||||
return [[energy_filter], [energy_filter]]
|
||||
|
||||
@staticmethod
|
||||
def get_mgxs(mdgxs_type, domain=None, domain_type=None,
|
||||
|
|
@ -171,10 +177,10 @@ class MDGXS(MGXS):
|
|||
|
||||
Parameters
|
||||
----------
|
||||
mdgxs_type : {'delayed-nu-fission', 'chi-prompt', 'chi-delayed',
|
||||
'beta'}
|
||||
mdgxs_type : {'delayed-nu-fission', 'chi-delayed', 'beta'}
|
||||
The type of multi-delayed-group cross section object to return
|
||||
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
|
||||
domain : openmc.Material or openmc.Cell or openmc.Universe or
|
||||
openmc.Mesh
|
||||
The domain for spatial homogenization
|
||||
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
|
||||
The domain type for spatial homogenization
|
||||
|
|
@ -200,7 +206,7 @@ class MDGXS(MGXS):
|
|||
cv.check_value('mdgxs_type', mdgxs_type, MDGXS_TYPES)
|
||||
|
||||
if mdgxs_type == 'delayed-nu-fission':
|
||||
mdgxs = DelayedNuFission(domain, domain_type, energy_groups)
|
||||
mdgxs = DelayedNuFissionXS(domain, domain_type, energy_groups)
|
||||
elif mdgxs_type == 'chi-delayed':
|
||||
mdgxs = ChiDelayed(domain, domain_type, energy_groups)
|
||||
elif mdgxs_type == 'beta':
|
||||
|
|
@ -260,12 +266,20 @@ class MDGXS(MGXS):
|
|||
cv.check_value('value', value, ['mean', 'std_dev', 'rel_err'])
|
||||
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
|
||||
|
||||
# FIXME: Unable to get microscopic xs for mesh domain because the mesh
|
||||
# cells do not know the nuclide densities in each mesh cell.
|
||||
if self.domain_type == 'mesh' and xs_type == 'micro':
|
||||
msg = 'Unable to get micro xs for mesh domain since the mesh ' \
|
||||
'cells do not know the nuclide densities in each mesh cell.'
|
||||
raise ValueError(msg)
|
||||
|
||||
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=3)
|
||||
cv.check_iterable_type('subdomains', subdomains, Integral,
|
||||
max_depth=3)
|
||||
for subdomain in subdomains:
|
||||
filters.append(self.domain_type)
|
||||
filter_bins.append((subdomain,))
|
||||
|
|
@ -275,13 +289,14 @@ class MDGXS(MGXS):
|
|||
cv.check_iterable_type('groups', groups, Integral)
|
||||
for group in groups:
|
||||
filters.append('energy')
|
||||
filter_bins.append((self.energy_groups.get_group_bounds(group),))
|
||||
filter_bins.append(
|
||||
(self.energy_groups.get_group_bounds(group),))
|
||||
|
||||
# Construct list of delayed group tuples for all requested groups
|
||||
if not isinstance(delayed_groups, basestring):
|
||||
cv.check_iterable_type('delayed_groups', delayed_groups, Integral)
|
||||
for delayed_group in delayed_groups:
|
||||
filters.append('delayedgroups')
|
||||
filters.append('delayedgroup')
|
||||
filter_bins.append((delayed_group,))
|
||||
|
||||
# Construct a collection of the nuclides to retrieve from the xs tally
|
||||
|
|
@ -299,7 +314,8 @@ class MDGXS(MGXS):
|
|||
xs = xs_tally.get_values(filters=filters,
|
||||
filter_bins=filter_bins, value=value)
|
||||
else:
|
||||
xs = self.xs_tally.get_values(filters=filters, filter_bins=filter_bins,
|
||||
xs = self.xs_tally.get_values(filters=filters,
|
||||
filter_bins=filter_bins,
|
||||
nuclides=query_nuclides, value=value)
|
||||
|
||||
# Divide by atom number densities for microscopic cross sections
|
||||
|
|
@ -460,12 +476,12 @@ class MDGXS(MGXS):
|
|||
|
||||
"""
|
||||
|
||||
|
||||
merged_mdgxs = super(MDGXS, self).merge(other)
|
||||
|
||||
# Merge delayed groups
|
||||
if self.delayed_groups != other.delayed_groups:
|
||||
merged_delayed_groups = self.delayed_groups.merge(other.delayed_groups)
|
||||
merged_delayed_groups = self.delayed_groups.merge(
|
||||
other.delayed_groups)
|
||||
merged_mdgxs.delayed_groups = merged_delayed_groups
|
||||
|
||||
return merged_mdgxs
|
||||
|
|
@ -490,7 +506,7 @@ class MDGXS(MGXS):
|
|||
|
||||
"""
|
||||
|
||||
if self.delayed_groups != None:
|
||||
if self.delayed_groups == None:
|
||||
super(MDGXS, self).print_xs(subdomains, nuclides, xs_type)
|
||||
return
|
||||
|
||||
|
|
@ -500,18 +516,8 @@ class MDGXS(MGXS):
|
|||
elif self.domain_type == 'distribcell':
|
||||
subdomains = np.arange(self.num_subdomains, dtype=np.int)
|
||||
elif self.domain_type == 'mesh':
|
||||
subdomains = []
|
||||
if (len(self.domain.dimension) == 3):
|
||||
nx, ny, nz = self.domain.dimension
|
||||
for x in range(1,nx+1):
|
||||
for y in range(1,ny+1):
|
||||
for z in range(1,nz+1):
|
||||
subdomains.append((x, y, z))
|
||||
else:
|
||||
nx, ny = self.domain.dimension
|
||||
for x in range(1,nx+1):
|
||||
for y in range(1,ny+1):
|
||||
subdomains.append((x, y, 1))
|
||||
xyz = [range(1, x+1) for x in self.domain.dimension]
|
||||
subdomains = list(itertools.product(*xyz))
|
||||
else:
|
||||
subdomains = [self.domain.id]
|
||||
|
||||
|
|
@ -534,6 +540,9 @@ class MDGXS(MGXS):
|
|||
string += '{0: <16}=\t{1}\n'.format('\tDomain Type', self.domain_type)
|
||||
string += '{0: <16}=\t{1}\n'.format('\tDomain ID', self.domain.id)
|
||||
|
||||
# Generate the header for an individual XS
|
||||
xs_header = '\tCross Sections [{0}]:'.format(self.get_units(xs_type))
|
||||
|
||||
# If cross section data has not been computed, only print string header
|
||||
if self.tallies is None:
|
||||
print(string)
|
||||
|
|
@ -542,7 +551,7 @@ class MDGXS(MGXS):
|
|||
# Loop over all subdomains
|
||||
for subdomain in subdomains:
|
||||
|
||||
if self.domain_type == 'distribcell':
|
||||
if self.domain_type == 'distribcell' or self.domain_type == 'mesh':
|
||||
string += '{0: <16}=\t{1}\n'.format('\tSubdomain', subdomain)
|
||||
|
||||
# Loop over all Nuclides
|
||||
|
|
@ -552,11 +561,8 @@ class MDGXS(MGXS):
|
|||
if nuclide != 'sum':
|
||||
string += '{0: <16}=\t{1}\n'.format('\tNuclide', nuclide)
|
||||
|
||||
# Build header for cross section type
|
||||
if xs_type == 'macro':
|
||||
string += '{0: <16}\n'.format('\tCross Sections [cm^-1]:')
|
||||
else:
|
||||
string += '{0: <16}\n'.format('\tCross Sections [barns]:')
|
||||
# Add the cross section header
|
||||
string += '{0: <16}\n'.format(xs_header)
|
||||
|
||||
for delayed_group in self.delayed_groups.groups:
|
||||
|
||||
|
|
@ -628,15 +634,14 @@ class MDGXS(MGXS):
|
|||
df = self.get_pandas_dataframe(groups=groups, xs_type=xs_type,
|
||||
delayed_groups=delayed_groups)
|
||||
|
||||
# Capitalize column label strings
|
||||
#df.columns = df.columns.astype(str)
|
||||
#df.columns = map(str.title, df.columns)
|
||||
|
||||
# Export the data using Pandas IO API
|
||||
if format == 'csv':
|
||||
df.to_csv(filename + '.csv', index=False)
|
||||
elif format == 'excel':
|
||||
df.to_excel(filename + '.xls', index=False)
|
||||
if self.domain_type == 'mesh':
|
||||
df.to_excel(filename + '.xls')
|
||||
else:
|
||||
df.to_excel(filename + '.xls', index=False)
|
||||
elif format == 'pickle':
|
||||
df.to_pickle(filename + '.pkl')
|
||||
elif format == 'latex':
|
||||
|
|
@ -664,7 +669,7 @@ class MDGXS(MGXS):
|
|||
def get_pandas_dataframe(self, groups='all', nuclides='all',
|
||||
xs_type='macro', distribcell_paths=True,
|
||||
delayed_groups='all'):
|
||||
"""Build a Pandas DataFrame for the MGXS data.
|
||||
"""Build a Pandas DataFrame for the MDGXS data.
|
||||
|
||||
This method leverages :meth:`openmc.Tally.get_pandas_dataframe`, but
|
||||
renames the columns with terminology appropriate for cross section data.
|
||||
|
|
@ -699,8 +704,8 @@ class MDGXS(MGXS):
|
|||
Raises
|
||||
------
|
||||
ValueError
|
||||
When this method is called before the multi-group cross section is
|
||||
computed from tally data.
|
||||
When this method is called before the multi-delayed-group cross
|
||||
section is computed from tally data.
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -719,35 +724,35 @@ class MDGXS(MGXS):
|
|||
|
||||
|
||||
class ChiDelayed(MDGXS):
|
||||
"""The delayed fission spectrum.
|
||||
r"""The delayed 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:`ChiDelayed.energy_groups` and
|
||||
:attr:`ChiDelayed.domain` properties. Tallies for the flux and appropriate
|
||||
reaction rates over the specified domain are generated automatically via the
|
||||
:attr:`ChiDelayed.tallies` property, which can then be appended to a
|
||||
:class:`openmc.Tallies` instance.
|
||||
multi-group and multi-delayed-group cross sections for multi-group
|
||||
neutronics calculations. At a minimum, one needs to set the
|
||||
:attr:`ChiDelayed.energy_groups` and :attr:`ChiDelayed.domain` properties.
|
||||
Tallies for the flux and appropriate reaction rates over the specified
|
||||
domain are generated automatically via the :attr:`ChiDelayed.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
|
||||
For post-processing, the :meth:`MDGXS.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:`ChiDelayed.xs_tally` property.
|
||||
:class:`openmc.StatePoint` instance. The derived multi-group cross
|
||||
section can then be obtained from the :attr:`ChiDelayed.xs_tally` property.
|
||||
|
||||
For a spatial domain :math:`V` and energy group :math:`[E_g,E_{g-1}]`, the
|
||||
fission spectrum is calculated as:
|
||||
For a spatial domain :math:`V`, energy group :math:`[E_g,E_{g-1}]`, and
|
||||
delayed group :math:`d`, the delayed fission spectrum is calculated as:
|
||||
|
||||
.. math::
|
||||
|
||||
\langle \nu\sigma_{f,\rightarrow g} \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 \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 (r,
|
||||
\langle \nu^d \sigma_{f,g' \rightarrow g} \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^d \sigma_f (r, E') \psi(r, E', \Omega')\\
|
||||
\langle \nu^d \sigma_f \phi \rangle &= \int_{r \in V} dr \int_{4\pi}
|
||||
d\Omega' \int_0^\infty dE' \int_0^\infty dE \; \chi(E) \nu^d \sigma_f (r,
|
||||
E') \psi(r, E', \Omega') \\
|
||||
\chi_g &= \frac{\langle \nu\sigma_{f,\rightarrow g} \phi \rangle}{\langle
|
||||
\nu\sigma_f \phi \rangle}
|
||||
\chi_g^d &= \frac{\langle \nu^d \sigma_{f,g' \rightarrow g} \phi \rangle}
|
||||
{\langle \nu^d \sigma_f \phi \rangle}
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
@ -948,8 +953,8 @@ class ChiDelayed(MDGXS):
|
|||
|
||||
# Slice nu-fission-out tally along energyout filter
|
||||
delayed_nu_fission_out = slice_xs.tallies['delayed-nu-fission-out']
|
||||
tally_slice = delayed_nu_fission_out.get_slice(filters=filters,
|
||||
filter_bins=filter_bins)
|
||||
tally_slice = delayed_nu_fission_out.get_slice\
|
||||
(filters=filters, filter_bins=filter_bins)
|
||||
slice_xs._tallies['delayed-nu-fission-out'] = tally_slice
|
||||
|
||||
# Add energy filter back to nu-fission-in tallies
|
||||
|
|
@ -967,32 +972,33 @@ class ChiDelayed(MDGXS):
|
|||
|
||||
Parameters
|
||||
----------
|
||||
other : openmc.mgxs.MGXS
|
||||
MGXS to merge with this one
|
||||
other : openmc.mdgxs.MDGXS
|
||||
MDGXS to merge with this one
|
||||
|
||||
Returns
|
||||
-------
|
||||
merged_mgxs : openmc.mgxs.MGXS
|
||||
Merged MGXS
|
||||
merged_mdgxs : openmc.mgxs.MDGXS
|
||||
Merged MDGXS
|
||||
"""
|
||||
|
||||
if not self.can_merge(other):
|
||||
raise ValueError('Unable to merge ChiDelayed')
|
||||
|
||||
# Create deep copy of tally to return as merged tally
|
||||
merged_mgxs = copy.deepcopy(self)
|
||||
merged_mgxs._derived = True
|
||||
merged_mgxs._rxn_rate_tally = None
|
||||
merged_mgxs._xs_tally = None
|
||||
merged_mdgxs = copy.deepcopy(self)
|
||||
merged_mdgxs._derived = True
|
||||
merged_mdgxs._rxn_rate_tally = None
|
||||
merged_mdgxs._xs_tally = None
|
||||
|
||||
# Merge energy groups
|
||||
if self.energy_groups != other.energy_groups:
|
||||
merged_groups = self.energy_groups.merge(other.energy_groups)
|
||||
merged_mgxs.energy_groups = merged_groups
|
||||
merged_mdgxs.energy_groups = merged_groups
|
||||
|
||||
# Merge delayed groups
|
||||
if self.delayed_groups != other.delayed_groups:
|
||||
merged_delayed_groups = self.delayed_groups.merge(other.delayed_groups)
|
||||
merged_delayed_groups = self.delayed_groups.merge\
|
||||
(other.delayed_groups)
|
||||
merged_mdgxs.delayed_groups = merged_delayed_groups
|
||||
|
||||
# Merge nuclides
|
||||
|
|
@ -1005,22 +1011,24 @@ class ChiDelayed(MDGXS):
|
|||
raise ValueError(msg)
|
||||
|
||||
# Concatenate lists of nuclides for the merged MGXS
|
||||
merged_mgxs.nuclides = self.nuclides + other.nuclides
|
||||
merged_mdgxs.nuclides = self.nuclides + other.nuclides
|
||||
|
||||
# Merge tallies
|
||||
for tally_key in self.tallies:
|
||||
merged_tally = self.tallies[tally_key].merge(other.tallies[tally_key])
|
||||
merged_mgxs.tallies[tally_key] = merged_tally
|
||||
merged_tally = self.tallies[tally_key].merge\
|
||||
(other.tallies[tally_key])
|
||||
merged_mdgxs.tallies[tally_key] = merged_tally
|
||||
|
||||
return merged_mgxs
|
||||
return merged_mdgxs
|
||||
|
||||
def get_xs(self, groups='all', subdomains='all', nuclides='all',
|
||||
xs_type='macro', order_groups='increasing',
|
||||
value='mean', delayed_groups='all', **kwargs):
|
||||
"""Returns an array of the fission spectrum.
|
||||
"""Returns an array of the delayed 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.
|
||||
and multi-delayed group cross section data data for one or more energy
|
||||
groups and subdomains.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
@ -1037,7 +1045,7 @@ class ChiDelayed(MDGXS):
|
|||
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
|
||||
mirror the parent MDGXS.get_xs(...) class method
|
||||
order_groups: {'increasing', 'decreasing'}
|
||||
Return the cross section indexed according to increasing or
|
||||
decreasing energy groups (decreasing or increasing energies).
|
||||
|
|
@ -1048,8 +1056,9 @@ class ChiDelayed(MDGXS):
|
|||
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.
|
||||
A NumPy array of the multi-group and multi-delayed-group cross
|
||||
section indexed in the order each group, subdomain and nuclide is
|
||||
listed in the parameters.
|
||||
|
||||
Raises
|
||||
------
|
||||
|
|
@ -1062,12 +1071,20 @@ class ChiDelayed(MDGXS):
|
|||
cv.check_value('value', value, ['mean', 'std_dev', 'rel_err'])
|
||||
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
|
||||
|
||||
# FIXME: Unable to get microscopic xs for mesh domain because the mesh
|
||||
# cells do not know the nuclide densities in each mesh cell.
|
||||
if self.domain_type == 'mesh' and xs_type == 'micro':
|
||||
msg = 'Unable to get micro xs for mesh domain since the mesh ' \
|
||||
'cells do not know the nuclide densities in each mesh cell.'
|
||||
raise ValueError(msg)
|
||||
|
||||
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=3)
|
||||
cv.check_iterable_type('subdomains', subdomains, Integral,
|
||||
max_depth=3)
|
||||
for subdomain in subdomains:
|
||||
filters.append(self.domain_type)
|
||||
filter_bins.append((subdomain,))
|
||||
|
|
@ -1077,13 +1094,14 @@ class ChiDelayed(MDGXS):
|
|||
cv.check_iterable_type('groups', groups, Integral)
|
||||
for group in groups:
|
||||
filters.append('energyout')
|
||||
filter_bins.append((self.energy_groups.get_group_bounds(group),))
|
||||
filter_bins.append(
|
||||
(self.energy_groups.get_group_bounds(group),))
|
||||
|
||||
# Construct list of delayed group tuples for all requested groups
|
||||
if not isinstance(delayed_groups, basestring):
|
||||
cv.check_iterable_type('delayed_groups', delayed_groups, Integral)
|
||||
for delayed_group in delayed_groups:
|
||||
filters.append('delayedgroups')
|
||||
filters.append('delayedgroup')
|
||||
filter_bins.append((delayed_group,))
|
||||
|
||||
# If chi delayed was computed for each nuclide in the domain
|
||||
|
|
@ -1099,8 +1117,10 @@ class ChiDelayed(MDGXS):
|
|||
|
||||
# Sum out all nuclides
|
||||
nuclides = self.get_all_nuclides()
|
||||
delayed_nu_fission_in = delayed_nu_fission_in.summation(nuclides=nuclides)
|
||||
delayed_nu_fission_out = delayed_nu_fission_out.summation(nuclides=nuclides)
|
||||
delayed_nu_fission_in = delayed_nu_fission_in.summation\
|
||||
(nuclides=nuclides)
|
||||
delayed_nu_fission_out = delayed_nu_fission_out.summation\
|
||||
(nuclides=nuclides)
|
||||
|
||||
# Remove coarse energy filter to keep it out of tally arithmetic
|
||||
energy_filter = delayed_nu_fission_in.find_filter('energy')
|
||||
|
|
@ -1160,7 +1180,7 @@ class ChiDelayed(MDGXS):
|
|||
|
||||
|
||||
class DelayedNuFissionXS(MDGXS):
|
||||
"""A fission delayed neutron production multi-group cross section.
|
||||
r"""A fission delayed 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
|
||||
|
|
@ -1172,18 +1192,19 @@ class DelayedNuFissionXS(MDGXS):
|
|||
:attr:`DelayedNuFissionXS.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
|
||||
For post-processing, the :meth:`MDGXS.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:`DelayedNuFissionXS.xs_tally` property.
|
||||
|
||||
For a spatial domain :math:`V` and energy group :math:`[E_g,E_{g-1}]`, the
|
||||
fission neutron production cross section is calculated as:
|
||||
For a spatial domain :math:`V`, energy group :math:`[E_g,E_{g-1}]`, and
|
||||
delayed group :math:`d`, the fission delayed neutron production cross
|
||||
section is calculated as:
|
||||
|
||||
.. math::
|
||||
|
||||
\frac{\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)}{\int_{r \in V} dr \int_{4\pi}
|
||||
\nu^d \sigma_f (r, E) \psi (r, E, \Omega)}{\int_{r \in V} dr \int_{4\pi}
|
||||
d\Omega \int_{E_g}^{E_{g-1}} dE \; \psi (r, E, \Omega)}.
|
||||
|
||||
|
||||
|
|
@ -1233,8 +1254,8 @@ class DelayedNuFissionXS(MDGXS):
|
|||
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:`NuFissionXS.tally_keys` property and
|
||||
values are instances of :class:`openmc.Tally`.
|
||||
are strings listed in the :attr:`DelayedNuFissionXS.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
|
||||
|
|
@ -1276,35 +1297,35 @@ class DelayedNuFissionXS(MDGXS):
|
|||
|
||||
|
||||
class Beta(MDGXS):
|
||||
"""The delayed neutron fraction.
|
||||
r"""The delayed neutron fraction.
|
||||
|
||||
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:`ChiDelayed.energy_groups` and
|
||||
:attr:`ChiDelayed.domain` properties. Tallies for the flux and appropriate
|
||||
reaction rates over the specified domain are generated automatically via the
|
||||
:attr:`ChiDelayed.tallies` property, which can then be appended to a
|
||||
:class:`openmc.Tallies` instance.
|
||||
multi-group and multi-delayed group cross sections for multi-group
|
||||
neutronics calculations. At a minimum, one needs to set the
|
||||
:attr:`Beta.energy_groups` and :attr:`Beta.domain` properties. Tallies for
|
||||
the flux and appropriate reaction rates over the specified domain are
|
||||
generated automatically via the :attr:`Beta.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
|
||||
For post-processing, the :meth:`MDGXS.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:`ChiDelayed.xs_tally` property.
|
||||
can then be obtained from the :attr:`Beta.xs_tally` property.
|
||||
|
||||
For a spatial domain :math:`V` and energy group :math:`[E_g,E_{g-1}]`, the
|
||||
fission spectrum is calculated as:
|
||||
For a spatial domain :math:`V`, energy group :math:`[E_g,E_{g-1}]`, and
|
||||
delayed group :math:`d`, the delayed neutron fraction is calculated as:
|
||||
|
||||
.. math::
|
||||
|
||||
\langle \nu\sigma_{f,\rightarrow g} \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 \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 (r,
|
||||
E') \psi(r, E', \Omega') \\
|
||||
\chi_g &= \frac{\langle \nu\sigma_{f,\rightarrow g} \phi \rangle}{\langle
|
||||
\nu\sigma_f \phi \rangle}
|
||||
\langle \nu^d \sigma_f \phi \rangle &= \int_{r \in V} dr \int_{4\pi}
|
||||
d\Omega' \int_0^\infty dE' \int_0^\infty dE \; \chi(E) \nu^d
|
||||
\sigma_f (r, E') \psi(r, E', \Omega') \\
|
||||
\langle \nu \sigma_f \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 (r, E') \psi(r, E', \Omega') \\
|
||||
\beta_{d,g} &= \frac{\langle \nu^d \sigma_f \phi \rangle}
|
||||
{\langle \nu \sigma_f \phi \rangle}
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
@ -1352,7 +1373,7 @@ class Beta(MDGXS):
|
|||
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
|
||||
are strings listed in the :attr:`Beta.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
|
||||
|
|
@ -1394,23 +1415,11 @@ class Beta(MDGXS):
|
|||
|
||||
@property
|
||||
def scores(self):
|
||||
return ['delayed-nu-fission', 'nu-fission']
|
||||
|
||||
@property
|
||||
def filters(self):
|
||||
# Create the non-domain specific Filters for the Tallies
|
||||
group_edges = self.energy_groups.group_edges
|
||||
energy = openmc.Filter('energy', [group_edges[0], group_edges[-1]])
|
||||
if self.delayed_groups != None:
|
||||
delayed_groups = self.delayed_groups.groups
|
||||
delayed_filter = openmc.Filter('delayedgroup', delayed_groups)
|
||||
return [[delayed_filter, energy], [energy]]
|
||||
else:
|
||||
return [[energy], [energy]]
|
||||
return ['nu-fission', 'delayed-nu-fission']
|
||||
|
||||
@property
|
||||
def tally_keys(self):
|
||||
return ['delayed-nu-fission', 'nu-fission']
|
||||
return ['nu-fission', 'delayed-nu-fission']
|
||||
|
||||
@property
|
||||
def rxn_rate_tally(self):
|
||||
|
|
@ -1425,7 +1434,7 @@ class Beta(MDGXS):
|
|||
if self._xs_tally is None:
|
||||
nu_fission = self.tallies['nu-fission']
|
||||
|
||||
# Compute chi
|
||||
# Compute beta
|
||||
self._xs_tally = self.rxn_rate_tally / nu_fission
|
||||
super(Beta, self)._compute_xs()
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import numpy as np
|
|||
import openmc
|
||||
import openmc.checkvalue as cv
|
||||
from openmc.mgxs import EnergyGroups
|
||||
from openmc import Mesh
|
||||
|
||||
if sys.version_info[0] >= 3:
|
||||
basestring = str
|
||||
|
|
@ -694,7 +693,7 @@ class MGXS(object):
|
|||
# NOTE: This is important if tally merging was used
|
||||
if self.domain_type == 'mesh':
|
||||
filters = [self.domain_type]
|
||||
xyz = map(lambda x: np.arange(1, x+1), self.domain.dimension)
|
||||
xyz = [range(1, x+1) for x in self.domain.dimension]
|
||||
filter_bins = [tuple(itertools.product(*xyz))]
|
||||
elif self.domain_type != 'distribcell':
|
||||
filters = [self.domain_type]
|
||||
|
|
@ -717,8 +716,6 @@ class MGXS(object):
|
|||
sp_tally = statepoint.get_tally(
|
||||
tally.scores, tally.filters, tally.nuclides,
|
||||
estimator=tally.estimator, exact_filters=True)
|
||||
print(filters)
|
||||
print(filter_bins)
|
||||
sp_tally = sp_tally.get_slice(
|
||||
tally.scores, filters, filter_bins, tally.nuclides)
|
||||
sp_tally.sparse = self.sparse
|
||||
|
|
@ -1159,7 +1156,7 @@ class MGXS(object):
|
|||
elif self.domain_type == 'distribcell':
|
||||
subdomains = np.arange(self.num_subdomains, dtype=np.int)
|
||||
elif self.domain_type == 'mesh':
|
||||
xyz = map(lambda x: np.arange(1, x+1), self.domain.dimension)
|
||||
xyz = [range(1, x+1) for x in self.domain.dimension]
|
||||
subdomains = list(itertools.product(*xyz))
|
||||
else:
|
||||
subdomains = [self.domain.id]
|
||||
|
|
@ -1194,7 +1191,7 @@ class MGXS(object):
|
|||
# Loop over all subdomains
|
||||
for subdomain in subdomains:
|
||||
|
||||
if self.domain_type == 'distribcell':
|
||||
if self.domain_type == 'distribcell' or self.domain_type == 'mesh':
|
||||
string += '{0: <16}=\t{1}\n'.format('\tSubdomain', subdomain)
|
||||
|
||||
# Loop over all Nuclides
|
||||
|
|
@ -1297,7 +1294,7 @@ class MGXS(object):
|
|||
domain_filter = self.xs_tally.find_filter('avg(distribcell)')
|
||||
subdomains = domain_filter.bins
|
||||
elif self.domain_type == 'mesh':
|
||||
xyz = map(lambda x: np.arange(1, x+1), self.domain.dimension)
|
||||
xyz = [range(1, x+1) for x in self.domain.dimension]
|
||||
subdomains = list(itertools.product(*xyz))
|
||||
else:
|
||||
subdomains = [self.domain.id]
|
||||
|
|
@ -1409,7 +1406,10 @@ class MGXS(object):
|
|||
if format == 'csv':
|
||||
df.to_csv(filename + '.csv', index=False)
|
||||
elif format == 'excel':
|
||||
df.to_excel(filename + '.xls', index=False)
|
||||
if self.domain_type == 'mesh':
|
||||
df.to_excel(filename + '.xls')
|
||||
else:
|
||||
df.to_excel(filename + '.xls', index=False)
|
||||
elif format == 'pickle':
|
||||
df.to_pickle(filename + '.pkl')
|
||||
elif format == 'latex':
|
||||
|
|
@ -1750,6 +1750,13 @@ class MatrixMGXS(MGXS):
|
|||
cv.check_value('value', value, ['mean', 'std_dev', 'rel_err'])
|
||||
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
|
||||
|
||||
# FIXME: Unable to get microscopic xs for mesh domain because the mesh
|
||||
# cells do not know the nuclide densities in each mesh cell.
|
||||
if self.domain_type == 'mesh' and xs_type == 'micro':
|
||||
msg = 'Unable to get micro xs for mesh domain since the mesh ' \
|
||||
'cells do not know the nuclide densities in each mesh cell.'
|
||||
raise ValueError(msg)
|
||||
|
||||
filters = []
|
||||
filter_bins = []
|
||||
|
||||
|
|
@ -1919,7 +1926,7 @@ class MatrixMGXS(MGXS):
|
|||
elif self.domain_type == 'distribcell':
|
||||
subdomains = np.arange(self.num_subdomains, dtype=np.int)
|
||||
elif self.domain_type == 'mesh':
|
||||
xyz = map(lambda x: np.arange(1, x+1), self.domain.dimension)
|
||||
xyz = [range(1, x+1) for x in self.domain.dimension]
|
||||
subdomains = list(itertools.product(*xyz))
|
||||
else:
|
||||
subdomains = [self.domain.id]
|
||||
|
|
@ -3568,6 +3575,13 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
cv.check_value('value', value, ['mean', 'std_dev', 'rel_err'])
|
||||
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
|
||||
|
||||
# FIXME: Unable to get microscopic xs for mesh domain because the mesh
|
||||
# cells do not know the nuclide densities in each mesh cell.
|
||||
if self.domain_type == 'mesh' and xs_type == 'micro':
|
||||
msg = 'Unable to get micro xs for mesh domain since the mesh ' \
|
||||
'cells do not know the nuclide densities in each mesh cell.'
|
||||
raise ValueError(msg)
|
||||
|
||||
filters = []
|
||||
filter_bins = []
|
||||
|
||||
|
|
@ -3718,9 +3732,12 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
df['moment'] = moments
|
||||
|
||||
# Place the moment column before the mean column
|
||||
mean_index = df.columns.get_loc('mean')
|
||||
columns = df.columns.tolist()
|
||||
df = df[columns[:mean_index] + ['moment'] + columns[mean_index:-1]]
|
||||
mean_index = [i for i, s in enumerate(columns) if 'mean' in s][0]
|
||||
if self.domain_type == 'mesh':
|
||||
df = df[columns[:mean_index] + [('moment', '')] + columns[mean_index:-1]]
|
||||
else:
|
||||
df = df[columns[:mean_index] + ['moment'] + columns[mean_index:-1]]
|
||||
|
||||
# Select rows corresponding to requested scattering moment
|
||||
if moment != 'all':
|
||||
|
|
@ -3761,7 +3778,7 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
elif self.domain_type == 'distribcell':
|
||||
subdomains = np.arange(self.num_subdomains, dtype=np.int)
|
||||
elif self.domain_type == 'mesh':
|
||||
xyz = map(lambda x: np.arange(1, x+1), self.domain.dimension)
|
||||
xyz = [range(1, x+1) for x in self.domain.dimension]
|
||||
subdomains = list(itertools.product(*xyz))
|
||||
else:
|
||||
subdomains = [self.domain.id]
|
||||
|
|
@ -4249,14 +4266,14 @@ class Chi(MGXS):
|
|||
|
||||
.. math::
|
||||
|
||||
\langle \nu\sigma_{f,\rightarrow g} \phi \rangle &= \int_{r \in V} dr
|
||||
\langle \nu\sigma_{f,g' \rightarrow g} \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 \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 (r,
|
||||
E') \psi(r, E', \Omega') \\
|
||||
\chi_g &= \frac{\langle \nu\sigma_{f,\rightarrow g} \phi \rangle}{\langle
|
||||
\nu\sigma_f \phi \rangle}
|
||||
\chi_g &= \frac{\langle \nu\sigma_{f,g' \rightarrow g} \phi \rangle}
|
||||
{\langle \nu\sigma_f \phi \rangle}
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
@ -4539,6 +4556,13 @@ class Chi(MGXS):
|
|||
cv.check_value('value', value, ['mean', 'std_dev', 'rel_err'])
|
||||
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
|
||||
|
||||
# FIXME: Unable to get microscopic xs for mesh domain because the mesh
|
||||
# cells do not know the nuclide densities in each mesh cell.
|
||||
if self.domain_type == 'mesh' and xs_type == 'micro':
|
||||
msg = 'Unable to get micro xs for mesh domain since the mesh ' \
|
||||
'cells do not know the nuclide densities in each mesh cell.'
|
||||
raise ValueError(msg)
|
||||
|
||||
filters = []
|
||||
filter_bins = []
|
||||
|
||||
|
|
@ -4732,14 +4756,14 @@ class ChiPrompt(Chi):
|
|||
|
||||
.. 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^p (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,
|
||||
\langle \nu^p \sigma_{f,g' \rightarrow g} \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)^p \nu^p \sigma_f (r, E') \psi(r, E', \Omega')\\
|
||||
\langle \nu^p \sigma_f \phi \rangle &= \int_{r \in V} dr \int_{4\pi}
|
||||
d\Omega' \int_0^\infty dE' \int_0^\infty dE \; \chi(E) \nu^p \sigma_f (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}
|
||||
\chi_g^p &= \frac{\langle \nu^p \sigma_{f,g' \rightarrow g} \phi \rangle}
|
||||
{\langle \nu^p \sigma_f \phi \rangle}
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
@ -4958,17 +4982,6 @@ class InverseVelocity(MGXS):
|
|||
|
||||
"""
|
||||
|
||||
# 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)
|
||||
elif self.domain_type == 'mesh':
|
||||
xyz = map(lambda x: np.arange(1, x+1), self.domain.dimension)
|
||||
subdomains = list(itertools.product(*xyz))
|
||||
else:
|
||||
subdomains = [self.domain.id]
|
||||
|
||||
if xs_type == 'macro':
|
||||
return 'second/cm'
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -1293,7 +1293,7 @@ class Tally(object):
|
|||
# Create list of 2- or 3-tuples tuples for mesh cell bins
|
||||
if self_filter.type == 'mesh':
|
||||
dimension = self_filter.mesh.dimension
|
||||
xyz = map(lambda x: np.arange(1, x+1), dimension)
|
||||
xyz = [range(1, x+1) for x in dimension]
|
||||
bins = list(itertools.product(*xyz))
|
||||
|
||||
# Create list of 2-tuples for energy boundary bins
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
e2cdca7ea5b3532050af5b12fac26d7ef212d2696bb1b73cdd00929b2243c40d100ad02438c7b090555b49815d0de6c48cf1b4ebf437a48bc80c2d2b4bad292e
|
||||
e2cdca7ea5b3532050af5b12fac26d7ef212d2696bb1b73cdd00929b2243c40d100ad02438c7b090555b49815d0de6c48cf1b4ebf437a48bc80c2d2b4bad292e
|
||||
|
|
@ -1 +1 @@
|
|||
2d948f3b12293294eaeca231a3df9d51195379e8bb38dd3e68d3bc512a7d08ed52a1109054ca381684ec127268710f6d6e9210ac8154c9b379608e996627624a
|
||||
2d948f3b12293294eaeca231a3df9d51195379e8bb38dd3e68d3bc512a7d08ed52a1109054ca381684ec127268710f6d6e9210ac8154c9b379608e996627624a
|
||||
|
|
@ -1 +1 @@
|
|||
e2cdca7ea5b3532050af5b12fac26d7ef212d2696bb1b73cdd00929b2243c40d100ad02438c7b090555b49815d0de6c48cf1b4ebf437a48bc80c2d2b4bad292e
|
||||
e2cdca7ea5b3532050af5b12fac26d7ef212d2696bb1b73cdd00929b2243c40d100ad02438c7b090555b49815d0de6c48cf1b4ebf437a48bc80c2d2b4bad292e
|
||||
1
tests/test_mgxs_library_mesh/inputs_true.dat
Normal file
1
tests/test_mgxs_library_mesh/inputs_true.dat
Normal file
|
|
@ -0,0 +1 @@
|
|||
a4cd030bea212e45fdb159e75a7fb3d1947e9bf3d0384ac5d37a72298d67dcfdd1b9eb5c6af8ac6e5983bd5b47de9c17a2ea472b467b7222a4909ee070bf1ca3
|
||||
132
tests/test_mgxs_library_mesh/results_true.dat
Normal file
132
tests/test_mgxs_library_mesh/results_true.dat
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
mesh 1 group in nuclide mean std. dev.
|
||||
x y z
|
||||
0 1 1 1 1 total 0.640786 0.044177
|
||||
1 1 2 1 1 total 0.660597 0.128423
|
||||
2 2 1 1 1 total 0.615276 0.104046
|
||||
3 2 2 1 1 total 0.646999 0.186709
|
||||
mesh 1 group in nuclide mean std. dev.
|
||||
x y z
|
||||
0 1 1 1 1 total 0.36665 0.048814
|
||||
1 1 2 1 1 total 0.40784 0.096486
|
||||
2 2 1 1 1 total 0.36356 0.074111
|
||||
3 2 2 1 1 total 0.41456 0.160443
|
||||
mesh 1 group in nuclide mean std. dev.
|
||||
x y z
|
||||
0 1 1 1 1 total 0.366650 0.048814
|
||||
1 1 2 1 1 total 0.407840 0.096486
|
||||
2 2 1 1 1 total 0.363560 0.074111
|
||||
3 2 2 1 1 total 0.414593 0.160436
|
||||
mesh 1 group in nuclide mean std. dev.
|
||||
x y z
|
||||
0 1 1 1 1 total 0.025749 0.002863
|
||||
1 1 2 1 1 total 0.028400 0.005275
|
||||
2 2 1 1 1 total 0.022988 0.004099
|
||||
3 2 2 1 1 total 0.027589 0.010350
|
||||
mesh 1 group in nuclide mean std. dev.
|
||||
x y z
|
||||
0 1 1 1 1 total 0.015861 0.002876
|
||||
1 1 2 1 1 total 0.017280 0.004371
|
||||
2 2 1 1 1 total 0.014403 0.003542
|
||||
3 2 2 1 1 total 0.018061 0.010110
|
||||
mesh 1 group in nuclide mean std. dev.
|
||||
x y z
|
||||
0 1 1 1 1 total 0.009888 0.001077
|
||||
1 1 2 1 1 total 0.011121 0.002456
|
||||
2 2 1 1 1 total 0.008585 0.001552
|
||||
3 2 2 1 1 total 0.009527 0.003659
|
||||
mesh 1 group in nuclide mean std. dev.
|
||||
x y z
|
||||
0 1 1 1 1 total 0.026065 0.002907
|
||||
1 1 2 1 1 total 0.029084 0.006430
|
||||
2 2 1 1 1 total 0.022596 0.004062
|
||||
3 2 2 1 1 total 0.025066 0.009687
|
||||
mesh 1 group in nuclide mean std. dev.
|
||||
x y z
|
||||
0 1 1 1 1 total 1.938476 0.211550
|
||||
1 1 2 1 1 total 2.177360 0.480780
|
||||
2 2 1 1 1 total 1.682799 0.303764
|
||||
3 2 2 1 1 total 1.864890 0.715661
|
||||
mesh 1 group in nuclide mean std. dev.
|
||||
x y z
|
||||
0 1 1 1 1 total 0.615037 0.041754
|
||||
1 1 2 1 1 total 0.632196 0.123878
|
||||
2 2 1 1 1 total 0.592288 0.100439
|
||||
3 2 2 1 1 total 0.619410 0.177190
|
||||
mesh 1 group in nuclide mean std. dev.
|
||||
x y z
|
||||
0 1 1 1 1 total 0.584014 0.054315
|
||||
1 1 2 1 1 total 0.622514 0.111323
|
||||
2 2 1 1 1 total 0.587256 0.084833
|
||||
3 2 2 1 1 total 0.613792 0.168612
|
||||
mesh 1 group in group out nuclide moment mean std. dev.
|
||||
x y z
|
||||
0 1 1 1 1 1 total P0 0.584014 0.054315
|
||||
1 1 1 1 1 1 total P1 0.243427 0.025488
|
||||
2 1 1 1 1 1 total P2 0.089236 0.007357
|
||||
3 1 1 1 1 1 total P3 0.008994 0.005768
|
||||
4 1 2 1 1 1 total P0 0.622514 0.111323
|
||||
5 1 2 1 1 1 total P1 0.239376 0.042594
|
||||
6 1 2 1 1 1 total P2 0.088386 0.017200
|
||||
7 1 2 1 1 1 total P3 -0.001243 0.005639
|
||||
8 2 1 1 1 1 total P0 0.587256 0.084833
|
||||
9 2 1 1 1 1 total P1 0.245120 0.041033
|
||||
10 2 1 1 1 1 total P2 0.086784 0.016255
|
||||
11 2 1 1 1 1 total P3 0.008660 0.004755
|
||||
12 2 2 1 1 1 total P0 0.612950 0.167940
|
||||
13 2 2 1 1 1 total P1 0.226176 0.061882
|
||||
14 2 2 1 1 1 total P2 0.086593 0.026126
|
||||
15 2 2 1 1 1 total P3 0.009672 0.011995
|
||||
mesh 1 group in group out nuclide moment mean std. dev.
|
||||
x y z
|
||||
0 1 1 1 1 1 total P0 0.584014 0.054315
|
||||
1 1 1 1 1 1 total P1 0.243427 0.025488
|
||||
2 1 1 1 1 1 total P2 0.089236 0.007357
|
||||
3 1 1 1 1 1 total P3 0.008994 0.005768
|
||||
4 1 2 1 1 1 total P0 0.622514 0.111323
|
||||
5 1 2 1 1 1 total P1 0.239376 0.042594
|
||||
6 1 2 1 1 1 total P2 0.088386 0.017200
|
||||
7 1 2 1 1 1 total P3 -0.001243 0.005639
|
||||
8 2 1 1 1 1 total P0 0.587256 0.084833
|
||||
9 2 1 1 1 1 total P1 0.245120 0.041033
|
||||
10 2 1 1 1 1 total P2 0.086784 0.016255
|
||||
11 2 1 1 1 1 total P3 0.008660 0.004755
|
||||
12 2 2 1 1 1 total P0 0.613792 0.168612
|
||||
13 2 2 1 1 1 total P1 0.226142 0.061856
|
||||
14 2 2 1 1 1 total P2 0.086174 0.025979
|
||||
15 2 2 1 1 1 total P3 0.009721 0.012027
|
||||
mesh 1 group in group out nuclide mean std. dev.
|
||||
x y z
|
||||
0 1 1 1 1 1 total 1.000000 0.088094
|
||||
1 1 2 1 1 1 total 1.000000 0.160891
|
||||
2 2 1 1 1 1 total 1.000000 0.126864
|
||||
3 2 2 1 1 1 total 1.001374 0.305883
|
||||
mesh 1 group in group out nuclide mean std. dev.
|
||||
x y z
|
||||
0 1 1 1 1 1 total 0.027395 0.004680
|
||||
1 1 2 1 1 1 total 0.022914 0.006025
|
||||
2 2 1 1 1 1 total 0.019384 0.002846
|
||||
3 2 2 1 1 1 total 0.029629 0.006292
|
||||
mesh 1 group out nuclide mean std. dev.
|
||||
x y z
|
||||
0 1 1 1 1 total 1.0 0.220956
|
||||
1 1 2 1 1 total 1.0 0.316565
|
||||
2 2 1 1 1 total 1.0 0.132140
|
||||
3 2 2 1 1 total 1.0 0.181577
|
||||
mesh 1 group out nuclide mean std. dev.
|
||||
x y z
|
||||
0 1 1 1 1 total 1.0 0.222246
|
||||
1 1 2 1 1 total 1.0 0.316565
|
||||
2 2 1 1 1 total 1.0 0.132140
|
||||
3 2 2 1 1 total 1.0 0.181577
|
||||
mesh 1 group in nuclide mean std. dev.
|
||||
x y z
|
||||
0 1 1 1 1 total 3.610522e-07 3.169931e-08
|
||||
1 1 2 1 1 total 3.942353e-07 8.459167e-08
|
||||
2 2 1 1 1 total 3.097784e-07 5.252025e-08
|
||||
3 2 2 1 1 total 3.799163e-07 1.806470e-07
|
||||
mesh 1 group in nuclide mean std. dev.
|
||||
x y z
|
||||
0 1 1 1 1 total 0.025735 0.002840
|
||||
1 1 2 1 1 total 0.028773 0.006349
|
||||
2 2 1 1 1 total 0.022306 0.004010
|
||||
3 2 2 1 1 total 0.024549 0.009379
|
||||
81
tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py
Normal file
81
tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
import glob
|
||||
import hashlib
|
||||
sys.path.insert(0, os.pardir)
|
||||
from testing_harness import PyAPITestHarness
|
||||
import openmc
|
||||
import openmc.mgxs
|
||||
|
||||
|
||||
class MGXSTestHarness(PyAPITestHarness):
|
||||
def _build_inputs(self):
|
||||
# Generate inputs using parent class routine
|
||||
super(MGXSTestHarness, self)._build_inputs()
|
||||
|
||||
# Initialize a one-group structure
|
||||
energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 20.])
|
||||
|
||||
# Initialize MGXS Library for a few cross section types
|
||||
# for one material-filled cell in the geometry
|
||||
self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry)
|
||||
self.mgxs_lib.by_nuclide = False
|
||||
|
||||
# Test all MGXS types
|
||||
self.mgxs_lib.mgxs_types = openmc.mgxs.MGXS_TYPES
|
||||
self.mgxs_lib.energy_groups = energy_groups
|
||||
self.mgxs_lib.legendre_order = 3
|
||||
self.mgxs_lib.domain_type = 'mesh'
|
||||
|
||||
# Instantiate a tally mesh
|
||||
mesh = openmc.Mesh(mesh_id=1)
|
||||
mesh.type = 'regular'
|
||||
mesh.dimension = [2, 2]
|
||||
mesh.lower_left = [-100., -100.]
|
||||
mesh.width = [100., 100.]
|
||||
|
||||
self.mgxs_lib.domains = [mesh]
|
||||
self.mgxs_lib.build_library()
|
||||
|
||||
# Initialize a tallies file
|
||||
self._input_set.tallies = openmc.Tallies()
|
||||
self.mgxs_lib.add_to_tallies_file(self._input_set.tallies, merge=False)
|
||||
self._input_set.tallies.export_to_xml()
|
||||
|
||||
def _get_results(self, hash_output=False):
|
||||
"""Digest info in the statepoint and return as a string."""
|
||||
|
||||
# Read the statepoint file.
|
||||
statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0]
|
||||
sp = openmc.StatePoint(statepoint)
|
||||
|
||||
# Load the MGXS library from the statepoint
|
||||
self.mgxs_lib.load_from_statepoint(sp)
|
||||
|
||||
# Build a string from Pandas Dataframe for each 1-group MGXS
|
||||
outstr = ''
|
||||
for domain in self.mgxs_lib.domains:
|
||||
for mgxs_type in self.mgxs_lib.mgxs_types:
|
||||
mgxs = self.mgxs_lib.get_mgxs(domain, mgxs_type)
|
||||
df = mgxs.get_pandas_dataframe()
|
||||
outstr += df.to_string() + '\n'
|
||||
|
||||
# Hash the results if necessary
|
||||
if hash_output:
|
||||
sha512 = hashlib.sha512()
|
||||
sha512.update(outstr.encode('utf-8'))
|
||||
outstr = sha512.hexdigest()
|
||||
|
||||
return outstr
|
||||
|
||||
def _cleanup(self):
|
||||
super(MGXSTestHarness, self)._cleanup()
|
||||
f = os.path.join(os.getcwd(), 'tallies.xml')
|
||||
if os.path.exists(f): os.remove(f)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
harness = MGXSTestHarness('statepoint.10.*', True)
|
||||
harness.main()
|
||||
|
|
@ -1 +1 @@
|
|||
e2cdca7ea5b3532050af5b12fac26d7ef212d2696bb1b73cdd00929b2243c40d100ad02438c7b090555b49815d0de6c48cf1b4ebf437a48bc80c2d2b4bad292e
|
||||
e2cdca7ea5b3532050af5b12fac26d7ef212d2696bb1b73cdd00929b2243c40d100ad02438c7b090555b49815d0de6c48cf1b4ebf437a48bc80c2d2b4bad292e
|
||||
|
|
@ -1 +1 @@
|
|||
e4a5f03ab6167e96462c4ef537533fe33b98d7878ae00824c5619356bda8d548b3c71af01ba8c88d5a9b46dd1471d331e6f678a164af922200f2ee3642be6340
|
||||
e4a5f03ab6167e96462c4ef537533fe33b98d7878ae00824c5619356bda8d548b3c71af01ba8c88d5a9b46dd1471d331e6f678a164af922200f2ee3642be6340
|
||||
|
|
@ -1 +1 @@
|
|||
e494320a213b5704a2ac915a2ba504857be91961ceb6735b6ad05d81eb31c44c9584d5bd9d40baececf1dcb5b030e6ecec63cfbd20639baf69bcb596c5c46591
|
||||
e494320a213b5704a2ac915a2ba504857be91961ceb6735b6ad05d81eb31c44c9584d5bd9d40baececf1dcb5b030e6ecec63cfbd20639baf69bcb596c5c46591
|
||||
|
|
@ -1 +1 @@
|
|||
ca47172a42f6c13b244a763c990cbe4811662708ee03307d810a4542ee34bb5db7cc29d66aea313dad95b9f38a4ff7943ded527cfd0c7c8825372fec40cfc0d0
|
||||
ca47172a42f6c13b244a763c990cbe4811662708ee03307d810a4542ee34bb5db7cc29d66aea313dad95b9f38a4ff7943ded527cfd0c7c8825372fec40cfc0d0
|
||||
Loading…
Add table
Add a link
Reference in a new issue