Added legendre moment order to get_slice method for ScatterMatrixXS

This commit is contained in:
Will Boyd 2016-05-09 12:48:43 -04:00
parent 2dae4f9a69
commit 8f6961fec5
2 changed files with 64 additions and 32 deletions

View file

@ -2,6 +2,7 @@ import sys
import os
import copy
import pickle
import warnings
from numbers import Integral
from collections import OrderedDict
@ -57,6 +58,8 @@ class Library(object):
The spatial domain(s) for which MGXS in the Library are computed
correction : {'P0', None}
Apply the P0 correction to scattering matrices if set to 'P0'
legendre_order : int
The highest legendre moments in the scattering matrices (default is 0)
energy_groups : openmc.mgxs.EnergyGroups
Energy group structure for energy condensation
tally_trigger : openmc.Trigger
@ -89,8 +92,9 @@ class Library(object):
self._mgxs_types = []
self._domain_type = None
self._domains = 'all'
self._correction = 'P0'
self._energy_groups = None
self._correction = 'P0'
self._legendre_order = 0
self._tally_trigger = None
self._all_mgxs = OrderedDict()
self._sp_filename = None
@ -118,6 +122,7 @@ class Library(object):
clone._domain_type = self.domain_type
clone._domains = copy.deepcopy(self.domains)
clone._correction = self.correction
clone._legendre_order = self.legendre_order
clone._energy_groups = copy.deepcopy(self.energy_groups, memo)
clone._tally_trigger = copy.deepcopy(self.tally_trigger, memo)
clone._all_mgxs = copy.deepcopy(self.all_mgxs)
@ -185,13 +190,17 @@ class Library(object):
else:
return self._domains
@property
def energy_groups(self):
return self._energy_groups
@property
def correction(self):
return self._correction
@property
def energy_groups(self):
return self._energy_groups
def legendre_order(self):
return self._legendre_order
@property
def tally_trigger(self):
@ -280,15 +289,21 @@ class Library(object):
self._domains = domains
@energy_groups.setter
def energy_groups(self, energy_groups):
cv.check_type('energy groups', energy_groups, openmc.mgxs.EnergyGroups)
self._energy_groups = energy_groups
@correction.setter
def correction(self, correction):
cv.check_value('correction', correction, ('P0', None))
self._correction = correction
@energy_groups.setter
def energy_groups(self, energy_groups):
cv.check_type('energy groups', energy_groups, openmc.mgxs.EnergyGroups)
self._energy_groups = energy_groups
@legendre_order.setter
def legendre_order(self, legendre_order):
cv.check_type('legendre_order', legendre_order, Integral)
cv.check_greater_than('legendre_order', legendre_order, 0, equality=True)
self._legendre_order = legendre_order
@tally_trigger.setter
def tally_trigger(self, tally_trigger):
@ -344,6 +359,7 @@ class Library(object):
# Specify whether to use a transport ('P0') correction
if isinstance(mgxs, openmc.mgxs.ScatterMatrixXS):
mgxs.correction = self.correction
mgxs.legendre_order = self.legendre_order
self.all_mgxs[domain.id][mgxs_type] = mgxs

View file

@ -1840,7 +1840,7 @@ class ScatterMatrixXS(MGXS):
----------
correction : 'P0' or None
Apply the P0 correction to scattering matrices if set to 'P0'
order : int
legendre_order : int
The highest legendre moment in the scattering matrix (default is 0)
"""
@ -1851,11 +1851,12 @@ class ScatterMatrixXS(MGXS):
groups, by_nuclide, name)
self._rxn_type = 'scatter matrix'
self._correction = 'P0'
self._order = 0
self._legendre_order = 0
def __deepcopy__(self, memo):
clone = super(ScatterMatrixXS, self).__deepcopy__(memo)
clone._correction = self.correction
clone._legendre_order = self.legendre_order
return clone
@property
@ -1863,8 +1864,8 @@ class ScatterMatrixXS(MGXS):
return self._correction
@property
def order(self):
return self._order
def legendre_order(self):
return self._legendre_order
@property
def tallies(self):
@ -1888,12 +1889,12 @@ class ScatterMatrixXS(MGXS):
filters = [[energy]]
# Create separate tallies for each moment
for moment in range(self.order+1):
for moment in range(self.legendre_order+1):
scores.append('scatter-{}'.format(moment))
filters.append([energy, energyout])
# Append to the lists for the P0 approximation if needed
if self.correction == 'P0' and self.order == 0:
if self.correction == 'P0' and self.legendre_order == 0:
scores.append('scatter-1')
filters.append([energyout])
@ -1911,7 +1912,7 @@ class ScatterMatrixXS(MGXS):
if self._rxn_rate_tally is None:
# If using P0 correction subtract scatter-P1 from the diagonal
if self.correction == 'P0' and self.order == 0:
if self.correction == 'P0' and self.legendre_order == 0:
scatter_p1 = self.tallies['scatter-1']
scatter_p1 = scatter_p1.get_slice(scores=['scatter-1'])
energy_filter = self.tallies['scatter-0'].find_filter('energy')
@ -1922,7 +1923,7 @@ class ScatterMatrixXS(MGXS):
# Merge all scattering moments into a single reaction rate Tally
else:
rxn_rate_tally = self.tallies['scatter-0']
for moment in range(1, self.order+1):
for moment in range(1, self.legendre_order+1):
scatter_key = 'scatter-{}'.format(moment)
scatter_pn = self.tallies[scatter_key]
rxn_rate_tally = rxn_rate_tally.merge(scatter_pn)
@ -1937,26 +1938,27 @@ class ScatterMatrixXS(MGXS):
def correction(self, correction):
cv.check_value('correction', correction, ('P0', None))
if correction == 'P0' and self.order > 0:
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.order)
'order {} is greater than zero'.format(self.legendre_order)
warnings.warn(msg)
self._correction = correction
@order.setter
def order(self, order):
cv.check_type('order', order, Integral)
cv.check_greater_than('order', order, 0, equality=True)
@legendre_order.setter
def legendre_order(self, legendre_order):
cv.check_type('legendre_order', legendre_order, Integral)
cv.check_greater_than('legendre_order', legendre_order, 0, equality=True)
if self.correction == 'P0' and self.order > 0:
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.order)
'order {} is greater than zero'.format(self.legendre_order)
warnings.warn(msg, RuntimeWarning)
self._order = order
self._legendre_order = legendre_order
def get_slice(self, nuclides=[], in_groups=[], out_groups=[]):
def get_slice(self, nuclides=[], in_groups=[], out_groups=[],
legendre_order='same'):
"""Build a sliced ScatterMatrix for the specified nuclides and
energy groups.
@ -1976,6 +1978,12 @@ class ScatterMatrixXS(MGXS):
out_groups : list of int
A list of outgoing energy group indices starting at 1 for the high
energies (e.g., [1, 2, 3]; default is [])
legendre_order : int or 'same'
The highest Legendre moment in the sliced MGXS. If order is 'same'
then the sliced MGXS will have the same Legendre moments as the
original MGXS (default). If order is an integer less than the
original MGXS' order, then only those Legendre moments up to that
order will be included in the sliced MGXS.
Returns
-------
@ -1990,6 +1998,16 @@ class ScatterMatrixXS(MGXS):
slice_xs._rxn_rate_tally = None
slice_xs._xs_tally = None
# Slice the Legendre order if needed
if legendre_order != 'same':
cv.check_type('legendre_order', legendre_order, Integral)
cv.check_less_than('legendre_order', legendre_order,
self.legendre_order, equality=True)
slice_xs.legendre_order = legendre_order
for moment in range(legendre_order+1, self.legendre_order+1):
del slice_xs.tallies['scatter-{}'.format(moment)]
# Slice outgoing energy groups if needed
if len(out_groups) != 0:
filter_bins = []
@ -2089,7 +2107,7 @@ class ScatterMatrixXS(MGXS):
if moment != 'all':
cv.check_type('moment', moment, Integral)
cv.check_greater_than('moment', moment, 0, equality=True)
cv.check_less_than('moment', moment, self.order, equality=True)
cv.check_less_than('moment', moment, 10, equality=True)
scores = [self.xs_tally.scores[moment]]
else:
scores = []
@ -2203,7 +2221,7 @@ class ScatterMatrixXS(MGXS):
if moment != 'all':
cv.check_type('moment', moment, Integral)
cv.check_greater_than('moment', moment, 0, equality=True)
cv.check_less_than('moment', moment, self.order, equality=True)
cv.check_less_than('moment', moment, 10, equality=True)
df = df[df['score'] == str(self.xs_tally.scores[moment])]
return df
@ -2253,7 +2271,7 @@ class ScatterMatrixXS(MGXS):
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
if self.correction != 'P0':
rxn_type= '{0} (moment {1})'.format(self.rxn_type, moment)
rxn_type= '{0} (P{1})'.format(self.rxn_type, moment)
else:
rxn_type = self.rxn_type
@ -2321,8 +2339,6 @@ class ScatterMatrixXS(MGXS):
print(string)
# FIXME: Add order property to Library
class NuScatterMatrixXS(ScatterMatrixXS):
"""A scattering production matrix multi-group cross section."""
@ -2355,13 +2371,13 @@ class NuScatterMatrixXS(ScatterMatrixXS):
keys = ['flux']
# Create separate tallies for each moment
for moment in range(self.order+1):
for moment in range(self.legendre_order+1):
scores.append('nu-scatter-{}'.format(moment))
filters.append([energy, energyout])
keys.append('scatter-{}'.format(moment))
# Append to the lists for the P0 approximation if needed
if self.correction == 'P0' and self.order == 0:
if self.correction == 'P0' and self.legendre_order == 0:
scores.append('scatter-1')
filters.append([energyout])
keys.append('scatter-1')