mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 22:26:08 -04:00
Added legendre moment order to get_slice method for ScatterMatrixXS
This commit is contained in:
parent
2dae4f9a69
commit
8f6961fec5
2 changed files with 64 additions and 32 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue