mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 14:15:42 -04:00
Changes in mgxs.py/mgdxs.py from PullRequest Inc. review
This commit is contained in:
parent
5d07976924
commit
0a34fcd600
3 changed files with 116 additions and 100 deletions
|
|
@ -47,7 +47,7 @@ class MDGXS(MGXS):
|
|||
name : str, optional
|
||||
Name of the multi-group cross section. Used as a label to identify
|
||||
tallies in OpenMC 'tallies.xml' file.
|
||||
delayed_groups : list of int
|
||||
delayed_groups : list of int, optional
|
||||
Delayed groups to filter out the xs
|
||||
num_polar : Integral, optional
|
||||
Number of equi-width polar angle bins for angle discretization;
|
||||
|
|
@ -70,7 +70,7 @@ class MDGXS(MGXS):
|
|||
Domain type for spatial homogenization
|
||||
energy_groups : openmc.mgxs.EnergyGroups
|
||||
Energy group structure for energy condensation
|
||||
delayed_groups : list of int
|
||||
delayed_groups : list of int, optional
|
||||
Delayed groups to filter out the xs
|
||||
num_polar : Integral
|
||||
Number of equi-width polar angle bins for angle discretization
|
||||
|
|
@ -246,7 +246,7 @@ class MDGXS(MGXS):
|
|||
name : str, optional
|
||||
Name of the multi-group cross section. Used as a label to identify
|
||||
tallies in OpenMC 'tallies.xml' file. Defaults to the empty string.
|
||||
delayed_groups : list of int
|
||||
delayed_groups : list of int, optional
|
||||
Delayed groups to filter out the xs
|
||||
num_polar : Integral, optional
|
||||
Number of equi-width polar angle bins for angle discretization;
|
||||
|
|
@ -1316,10 +1316,10 @@ class ChiDelayed(MDGXS):
|
|||
|
||||
# Sum out all nuclides
|
||||
nuclides = self.get_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(
|
||||
|
|
@ -2169,6 +2169,8 @@ class MatrixMDGXS(MDGXS):
|
|||
|
||||
# Eliminate the trivial score dimension
|
||||
xs = np.squeeze(xs, axis=len(xs.shape) - 1)
|
||||
|
||||
# Eliminate NaNs which may have been produced by dividing by density
|
||||
xs = np.nan_to_num(xs)
|
||||
|
||||
if in_groups == 'all':
|
||||
|
|
|
|||
|
|
@ -15,51 +15,67 @@ from openmc.mgxs import EnergyGroups
|
|||
|
||||
|
||||
# Supported cross section types
|
||||
MGXS_TYPES = ['total',
|
||||
'transport',
|
||||
'nu-transport',
|
||||
'absorption',
|
||||
'capture',
|
||||
'fission',
|
||||
'nu-fission',
|
||||
'kappa-fission',
|
||||
'scatter',
|
||||
'nu-scatter',
|
||||
'scatter matrix',
|
||||
'nu-scatter matrix',
|
||||
'multiplicity matrix',
|
||||
'nu-fission matrix',
|
||||
'scatter probability matrix',
|
||||
'consistent scatter matrix',
|
||||
'consistent nu-scatter matrix',
|
||||
'chi',
|
||||
'chi-prompt',
|
||||
'inverse-velocity',
|
||||
'prompt-nu-fission',
|
||||
'prompt-nu-fission matrix']
|
||||
MGXS_TYPES = [
|
||||
'total',
|
||||
'transport',
|
||||
'nu-transport',
|
||||
'absorption',
|
||||
'capture',
|
||||
'fission',
|
||||
'nu-fission',
|
||||
'kappa-fission',
|
||||
'scatter',
|
||||
'nu-scatter',
|
||||
'scatter matrix',
|
||||
'nu-scatter matrix',
|
||||
'multiplicity matrix',
|
||||
'nu-fission matrix',
|
||||
'scatter probability matrix',
|
||||
'consistent scatter matrix',
|
||||
'consistent nu-scatter matrix',
|
||||
'chi',
|
||||
'chi-prompt',
|
||||
'inverse-velocity',
|
||||
'prompt-nu-fission',
|
||||
'prompt-nu-fission matrix'
|
||||
]
|
||||
|
||||
# Supported domain types
|
||||
DOMAIN_TYPES = ['cell',
|
||||
'distribcell',
|
||||
'universe',
|
||||
'material',
|
||||
'mesh']
|
||||
DOMAIN_TYPES = [
|
||||
'cell',
|
||||
'distribcell',
|
||||
'universe',
|
||||
'material',
|
||||
'mesh'
|
||||
]
|
||||
|
||||
# Filter types corresponding to each domain
|
||||
_DOMAIN_TO_FILTER = {'cell': openmc.CellFilter,
|
||||
'distribcell': openmc.DistribcellFilter,
|
||||
'universe': openmc.UniverseFilter,
|
||||
'material': openmc.MaterialFilter,
|
||||
'mesh': openmc.MeshFilter}
|
||||
_DOMAIN_TO_FILTER = {
|
||||
'cell': openmc.CellFilter,
|
||||
'distribcell': openmc.DistribcellFilter,
|
||||
'universe': openmc.UniverseFilter,
|
||||
'material': openmc.MaterialFilter,
|
||||
'mesh': openmc.MeshFilter
|
||||
}
|
||||
|
||||
# Supported domain classes
|
||||
_DOMAINS = (openmc.Cell,
|
||||
openmc.Universe,
|
||||
openmc.Material,
|
||||
openmc.RegularMesh)
|
||||
_DOMAINS = (
|
||||
openmc.Cell,
|
||||
openmc.Universe,
|
||||
openmc.Material,
|
||||
openmc.RegularMesh
|
||||
)
|
||||
|
||||
# Supported ScatterMatrixXS angular distribution types
|
||||
MU_TREATMENTS = ('legendre', 'histogram')
|
||||
# Supported ScatterMatrixXS angular distribution types. Note that 'histogram' is
|
||||
# defined here and used in mgxs_library.py, but it is not used for the current
|
||||
# module
|
||||
SCATTER_TABULAR = 'tabular'
|
||||
SCATTER_LEGENDRE = 'legendre'
|
||||
SCATTER_HISTOGRAM = 'histogram'
|
||||
MU_TREATMENTS = (
|
||||
SCATTER_LEGENDRE,
|
||||
SCATTER_HISTOGRAM
|
||||
)
|
||||
|
||||
# Maximum Legendre order supported by OpenMC
|
||||
_MAX_LEGENDRE = 10
|
||||
|
|
@ -245,38 +261,37 @@ class MGXS(metaclass=ABCMeta):
|
|||
def __deepcopy__(self, memo):
|
||||
existing = memo.get(id(self))
|
||||
|
||||
# If this is the first time we have tried to copy this object, copy it
|
||||
if existing is None:
|
||||
clone = type(self).__new__(type(self))
|
||||
clone._name = self.name
|
||||
clone._rxn_type = self.rxn_type
|
||||
clone._by_nuclide = self.by_nuclide
|
||||
clone._nuclides = copy.deepcopy(self._nuclides, memo)
|
||||
clone._domain = self.domain
|
||||
clone._domain_type = self.domain_type
|
||||
clone._energy_groups = copy.deepcopy(self.energy_groups, memo)
|
||||
clone._num_polar = self._num_polar
|
||||
clone._num_azimuthal = self._num_azimuthal
|
||||
clone._tally_trigger = copy.deepcopy(self.tally_trigger, memo)
|
||||
clone._rxn_rate_tally = copy.deepcopy(self._rxn_rate_tally, memo)
|
||||
clone._xs_tally = copy.deepcopy(self._xs_tally, memo)
|
||||
clone._sparse = self.sparse
|
||||
clone._loaded_sp = self._loaded_sp
|
||||
clone._derived = self.derived
|
||||
clone._hdf5_key = self._hdf5_key
|
||||
|
||||
clone._tallies = OrderedDict()
|
||||
for tally_type, tally in self.tallies.items():
|
||||
clone.tallies[tally_type] = copy.deepcopy(tally, memo)
|
||||
|
||||
memo[id(self)] = clone
|
||||
|
||||
return clone
|
||||
|
||||
# If this object has been copied before, return the first copy made
|
||||
else:
|
||||
if existing is not None:
|
||||
return existing
|
||||
|
||||
# If this is the first time we have tried to copy this object, copy it
|
||||
clone = type(self).__new__(type(self))
|
||||
clone._name = self.name
|
||||
clone._rxn_type = self.rxn_type
|
||||
clone._by_nuclide = self.by_nuclide
|
||||
clone._nuclides = copy.deepcopy(self._nuclides, memo)
|
||||
clone._domain = self.domain
|
||||
clone._domain_type = self.domain_type
|
||||
clone._energy_groups = copy.deepcopy(self.energy_groups, memo)
|
||||
clone._num_polar = self._num_polar
|
||||
clone._num_azimuthal = self._num_azimuthal
|
||||
clone._tally_trigger = copy.deepcopy(self.tally_trigger, memo)
|
||||
clone._rxn_rate_tally = copy.deepcopy(self._rxn_rate_tally, memo)
|
||||
clone._xs_tally = copy.deepcopy(self._xs_tally, memo)
|
||||
clone._sparse = self.sparse
|
||||
clone._loaded_sp = self._loaded_sp
|
||||
clone._derived = self.derived
|
||||
clone._hdf5_key = self._hdf5_key
|
||||
|
||||
clone._tallies = OrderedDict()
|
||||
for tally_type, tally in self.tallies.items():
|
||||
clone.tallies[tally_type] = copy.deepcopy(tally, memo)
|
||||
|
||||
memo[id(self)] = clone
|
||||
|
||||
return clone
|
||||
|
||||
def _add_angle_filters(self, filters):
|
||||
"""Add the azimuthal and polar bins to the MGXS filters if needed.
|
||||
Filters will be provided as a ragged 2D list of openmc.Filter objects.
|
||||
|
|
@ -2170,6 +2185,7 @@ class MatrixMGXS(MGXS):
|
|||
if not isinstance(in_groups, str):
|
||||
cv.check_iterable_type('groups', in_groups, Integral)
|
||||
filters.append(openmc.EnergyFilter)
|
||||
energy_bins = []
|
||||
for group in in_groups:
|
||||
energy_bins.append((self.energy_groups.get_group_bounds(group),))
|
||||
filter_bins.append(tuple(energy_bins))
|
||||
|
|
@ -3725,7 +3741,7 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
num_polar, num_azimuthal)
|
||||
self._formulation = 'simple'
|
||||
self._correction = 'P0'
|
||||
self._scatter_format = 'legendre'
|
||||
self._scatter_format = SCATTER_LEGENDRE
|
||||
self._legendre_order = 0
|
||||
self._histogram_bins = 16
|
||||
self._estimator = 'analog'
|
||||
|
|
@ -3748,12 +3764,12 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
process
|
||||
"""
|
||||
if self.num_polar > 1 or self.num_azimuthal > 1:
|
||||
if self.scatter_format == 'histogram':
|
||||
if self.scatter_format == SCATTER_HISTOGRAM:
|
||||
return (0, 1, 3, 4, 5)
|
||||
else:
|
||||
return (0, 1, 3, 4)
|
||||
else:
|
||||
if self.scatter_format == 'histogram':
|
||||
if self.scatter_format == SCATTER_HISTOGRAM:
|
||||
return (1, 2, 3)
|
||||
else:
|
||||
return (1, 2)
|
||||
|
|
@ -3857,13 +3873,13 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
energy = openmc.EnergyFilter(group_edges)
|
||||
energyout = openmc.EnergyoutFilter(group_edges)
|
||||
|
||||
if self.scatter_format == 'legendre':
|
||||
if self.scatter_format == SCATTER_LEGENDRE:
|
||||
if self.correction == 'P0' and self.legendre_order == 0:
|
||||
angle_filter = openmc.LegendreFilter(order=1)
|
||||
else:
|
||||
angle_filter = \
|
||||
openmc.LegendreFilter(order=self.legendre_order)
|
||||
elif self.scatter_format == 'histogram':
|
||||
elif self.scatter_format == SCATTER_HISTOGRAM:
|
||||
bins = np.linspace(-1., 1., num=self.histogram_bins + 1,
|
||||
endpoint=True)
|
||||
angle_filter = openmc.MuFilter(bins)
|
||||
|
|
@ -3878,9 +3894,9 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
filters = [[energy], [energy]]
|
||||
|
||||
# Group-to-group scattering probability matrix
|
||||
if self.scatter_format == 'legendre':
|
||||
if self.scatter_format == SCATTER_LEGENDRE:
|
||||
angle_filter = openmc.LegendreFilter(order=self.legendre_order)
|
||||
elif self.scatter_format == 'histogram':
|
||||
elif self.scatter_format == SCATTER_HISTOGRAM:
|
||||
bins = np.linspace(-1., 1., num=self.histogram_bins + 1,
|
||||
endpoint=True)
|
||||
angle_filter = openmc.MuFilter(bins)
|
||||
|
|
@ -3903,7 +3919,7 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
if self._rxn_rate_tally is None:
|
||||
|
||||
if self.formulation == 'simple':
|
||||
if self.scatter_format == 'legendre':
|
||||
if self.scatter_format == SCATTER_LEGENDRE:
|
||||
# If using P0 correction subtract P1 scatter from the diag.
|
||||
if self.correction == 'P0' and self.legendre_order == 0:
|
||||
scatter_p0 = self.tallies[self.rxn_type].get_slice(
|
||||
|
|
@ -3937,7 +3953,7 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
# Otherwise, extract scattering moment reaction rate Tally
|
||||
else:
|
||||
self._rxn_rate_tally = self.tallies[self.rxn_type]
|
||||
elif self.scatter_format == 'histogram':
|
||||
elif self.scatter_format == SCATTER_HISTOGRAM:
|
||||
# Extract scattering rate distribution tally
|
||||
self._rxn_rate_tally = self.tallies[self.rxn_type]
|
||||
|
||||
|
|
@ -3967,14 +3983,14 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
tally_key = 'scatter matrix'
|
||||
|
||||
# Compute normalization factor summed across outgoing energies
|
||||
if self.scatter_format == 'legendre':
|
||||
if self.scatter_format == SCATTER_LEGENDRE:
|
||||
norm = self.tallies[tally_key].get_slice(
|
||||
scores=['scatter'],
|
||||
filters=[openmc.LegendreFilter],
|
||||
filter_bins=[('P0',)], squeeze=True)
|
||||
|
||||
# Compute normalization factor summed across outgoing mu bins
|
||||
elif self.scatter_format == 'histogram':
|
||||
elif self.scatter_format == SCATTER_HISTOGRAM:
|
||||
norm = self.tallies[tally_key].get_slice(
|
||||
scores=['scatter'])
|
||||
norm = norm.summation(
|
||||
|
|
@ -3994,14 +4010,14 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
if self.nu:
|
||||
numer = self.tallies['nu-scatter']
|
||||
# Get the denominator
|
||||
if self.scatter_format == 'legendre':
|
||||
if self.scatter_format == SCATTER_LEGENDRE:
|
||||
denom = self.tallies[tally_key].get_slice(
|
||||
scores=['scatter'],
|
||||
filters=[openmc.LegendreFilter],
|
||||
filter_bins=[('P0',)], squeeze=True)
|
||||
|
||||
# Compute normalization factor summed across mu bins
|
||||
elif self.scatter_format == 'histogram':
|
||||
elif self.scatter_format == SCATTER_HISTOGRAM:
|
||||
denom = self.tallies[tally_key].get_slice(
|
||||
scores=['scatter'])
|
||||
|
||||
|
|
@ -4048,7 +4064,7 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
self._compute_xs()
|
||||
|
||||
# Force the angle filter to be the last filter
|
||||
if self.scatter_format == 'histogram':
|
||||
if self.scatter_format == SCATTER_HISTOGRAM:
|
||||
angle_filter = self._xs_tally.find_filter(openmc.MuFilter)
|
||||
else:
|
||||
angle_filter = \
|
||||
|
|
@ -4105,13 +4121,13 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
def correction(self, correction):
|
||||
cv.check_value('correction', correction, ('P0', None))
|
||||
|
||||
if self.scatter_format == 'legendre':
|
||||
if self.scatter_format == SCATTER_LEGENDRE:
|
||||
if correction == 'P0' and self.legendre_order > 0:
|
||||
msg = 'The P0 correction will be ignored since the ' \
|
||||
'scattering order {} is greater than '\
|
||||
'zero'.format(self.legendre_order)
|
||||
warnings.warn(msg)
|
||||
elif self.scatter_format == 'histogram':
|
||||
elif self.scatter_format == SCATTER_HISTOGRAM:
|
||||
msg = 'The P0 correction will be ignored since the ' \
|
||||
'scatter format is set to histogram'
|
||||
warnings.warn(msg)
|
||||
|
|
@ -4131,14 +4147,14 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
cv.check_less_than('legendre_order', legendre_order, _MAX_LEGENDRE,
|
||||
equality=True)
|
||||
|
||||
if self.scatter_format == 'legendre':
|
||||
if self.scatter_format == SCATTER_LEGENDRE:
|
||||
if self.correction == 'P0' and legendre_order > 0:
|
||||
msg = 'The P0 correction will be ignored since the ' \
|
||||
'scattering order {} is greater than '\
|
||||
'zero'.format(self.legendre_order)
|
||||
warnings.warn(msg, RuntimeWarning)
|
||||
self.correction = None
|
||||
elif self.scatter_format == 'histogram':
|
||||
elif self.scatter_format == SCATTER_HISTOGRAM:
|
||||
msg = 'The legendre order will be ignored since the ' \
|
||||
'scatter format is set to histogram'
|
||||
warnings.warn(msg)
|
||||
|
|
@ -4226,7 +4242,7 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
slice_xs._xs_tally = None
|
||||
|
||||
# Slice the Legendre order if needed
|
||||
if legendre_order != 'same' and self.scatter_format == 'legendre':
|
||||
if legendre_order != 'same' and self.scatter_format == SCATTER_LEGENDRE:
|
||||
cv.check_type('legendre_order', legendre_order, Integral)
|
||||
cv.check_less_than('legendre_order', legendre_order,
|
||||
self.legendre_order, equality=True)
|
||||
|
|
@ -4363,7 +4379,7 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
filter_bins.append((self.energy_groups.get_group_bounds(group),))
|
||||
|
||||
# Construct CrossScore for requested scattering moment
|
||||
if self.scatter_format == 'legendre':
|
||||
if self.scatter_format == SCATTER_LEGENDRE:
|
||||
if moment != 'all':
|
||||
cv.check_type('moment', moment, Integral)
|
||||
cv.check_greater_than('moment', moment, 0, equality=True)
|
||||
|
|
@ -4508,7 +4524,7 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
paths=paths)
|
||||
|
||||
# If the matrix is P0, remove the legendre column
|
||||
if self.scatter_format == 'legendre' and self.legendre_order == 0:
|
||||
if self.scatter_format == SCATTER_LEGENDRE and self.legendre_order == 0:
|
||||
df = df.drop(axis=1, labels=['legendre'])
|
||||
|
||||
return df
|
||||
|
|
@ -4560,7 +4576,7 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
|
||||
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
|
||||
|
||||
if self.correction != 'P0' and self.scatter_format == 'legendre':
|
||||
if self.correction != 'P0' and self.scatter_format == SCATTER_LEGENDRE:
|
||||
rxn_type = '{0} (P{1})'.format(self.rxn_type, moment)
|
||||
else:
|
||||
rxn_type = self.rxn_type
|
||||
|
|
@ -4648,7 +4664,7 @@ class ScatterMatrixXS(MatrixMGXS):
|
|||
return to_print
|
||||
|
||||
# Set the number of histogram bins
|
||||
if self.scatter_format == 'histogram':
|
||||
if self.scatter_format == SCATTER_HISTOGRAM:
|
||||
num_mu_bins = self.histogram_bins
|
||||
else:
|
||||
num_mu_bins = 0
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from scipy.special import eval_legendre
|
|||
|
||||
import openmc
|
||||
import openmc.mgxs
|
||||
from openmc.mgxs import SCATTER_TABULAR, SCATTER_LEGENDRE, SCATTER_HISTOGRAM
|
||||
from openmc.checkvalue import check_type, check_value, check_greater_than, \
|
||||
check_iterable_type, check_less_than, check_filetype_version
|
||||
|
||||
|
|
@ -24,9 +25,6 @@ _REPRESENTATIONS = [
|
|||
]
|
||||
|
||||
# Supported scattering angular distribution representations
|
||||
SCATTER_TABULAR = 'tabular'
|
||||
SCATTER_LEGENDRE = 'legendre'
|
||||
SCATTER_HISTOGRAM = 'histogram'
|
||||
_SCATTER_TYPES = [
|
||||
SCATTER_TABULAR,
|
||||
SCATTER_LEGENDRE,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue