mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 21:55:41 -04:00
Subdomain-averaged multi-group cross-section calculation now working
This commit is contained in:
parent
665b8226e8
commit
ecda3bef5e
2 changed files with 62 additions and 46 deletions
|
|
@ -217,7 +217,7 @@ class MultiGroupXS(object):
|
|||
"""Finds and stores the offset of the domain tally filter"""
|
||||
|
||||
tally = self.tallies.values()[0]
|
||||
domain_filter = tally.find_filter(self.domain_type, [self.domain.id])
|
||||
domain_filter = tally.find_filter(self.domain_type)
|
||||
self._offset = domain_filter.offset
|
||||
|
||||
def set_subdomain_index(self, subdomain_id, index):
|
||||
|
|
@ -280,7 +280,9 @@ class MultiGroupXS(object):
|
|||
cv.check_type('subdomains', subdomains, Iterable, Integral)
|
||||
|
||||
if subdomains == 'all':
|
||||
num_subdomains = len(self.subdomain_indices)
|
||||
tally = self.tallies.values()[0]
|
||||
domain_filter = tally.find_filter(self.domain_type)
|
||||
num_subdomains = domain_filter.num_bins
|
||||
indices = np.arange(num_subdomains)
|
||||
else:
|
||||
indices = np.zeros(len(subdomains), dtype=np.int64)
|
||||
|
|
@ -329,19 +331,22 @@ class MultiGroupXS(object):
|
|||
cv.check_type('offsets', indices, Iterable, Integral)
|
||||
|
||||
if indices == 'all':
|
||||
indices = self.get_subdomain_indices()
|
||||
tally = self.tallies.values()[0]
|
||||
domain_filter = tally.find_filter(self.domain_type)
|
||||
num_subdomains = domain_filter.num_bins
|
||||
subdomains = np.arange(num_subdomains)
|
||||
else:
|
||||
subdomains = np.zeros(len(indices), dtype=np.int64)
|
||||
keys = self.subdomain_indices.keys()
|
||||
values = self.subdomain_indices.values()
|
||||
|
||||
subdomains = np.zeros(len(indices), dtype=np.int64)
|
||||
keys = self.subdomain_indices.keys()
|
||||
values = self.subdomain_indices.values()
|
||||
|
||||
for i, index in enumerate(indices):
|
||||
if index in values:
|
||||
subdomains[i] = keys[values.index(index)]
|
||||
else:
|
||||
msg = 'Unable to get subdomain for index "{0}" since it ' \
|
||||
'is not a valid index'.format(index)
|
||||
raise ValueError(msg)
|
||||
for i, index in enumerate(indices):
|
||||
if index in values:
|
||||
subdomains[i] = keys[values.index(index)]
|
||||
else:
|
||||
msg = 'Unable to get subdomain for index "{0}" since it ' \
|
||||
'is not a valid index'.format(index)
|
||||
raise ValueError(msg)
|
||||
|
||||
return subdomains
|
||||
|
||||
|
|
@ -520,11 +525,11 @@ class MultiGroupXS(object):
|
|||
if subdomains != 'all':
|
||||
cv.check_iterable_type('subdomains', subdomains, Integral)
|
||||
subdomain_indices = self.get_subdomain_indices(subdomains)
|
||||
subdomain_indices = [(index,) for index in subdomain_indices]
|
||||
# subdomain_indices = [(index,) for index in subdomain_indices]
|
||||
|
||||
# Clone this MultiGroupXS to initialize the condensed version
|
||||
avg_xs = copy.deepcopy(self)
|
||||
avg_xs.domain_type = 'avg. ' + avg_xs.domain_type
|
||||
avg_xs._domain_type = 'avg. ' + avg_xs.domain_type
|
||||
|
||||
# Reset subdomain indices and offsets for distribcell domains
|
||||
if self.domain_type == 'distribcell':
|
||||
|
|
@ -534,7 +539,7 @@ class MultiGroupXS(object):
|
|||
# Overwrite tallies with new subdomain-averaged versions
|
||||
avg_xs._tallies = {}
|
||||
for tally_type, tally in self.tallies.items():
|
||||
tally_sum = tally.summation(filters=[self.domain_type],
|
||||
tally_sum = tally.summation(filter=self.domain_type,
|
||||
filter_bins=subdomain_indices)
|
||||
tally_sum /= len(subdomains)
|
||||
avg_xs.tallies[tally_type] = tally_sum
|
||||
|
|
@ -1281,13 +1286,19 @@ class Chi(MultiGroupXS):
|
|||
# FIXME: Make filter bins simpler in Tally.summation(...)
|
||||
|
||||
# Construct energy group filter bins to sum across
|
||||
'''
|
||||
filter_bins = []
|
||||
for group in range(1, self.num_groups+1):
|
||||
group_bounds = self.energy_groups.get_group_bounds(group)
|
||||
filter_bins.append((group_bounds,))
|
||||
energy_bins = [filter_bins]
|
||||
'''
|
||||
|
||||
sum_nu_fission_in = nu_fission_in.summation(filters=['energy'],
|
||||
energy_bins = []
|
||||
for group in range(1, self.num_groups+1):
|
||||
energy_bins.append(self.energy_groups.get_group_bounds(group))
|
||||
|
||||
sum_nu_fission_in = nu_fission_in.summation(filter='energy',
|
||||
filter_bins=energy_bins)
|
||||
|
||||
# FIXME: Need ability to override energy groups with group numbers
|
||||
|
|
@ -1299,7 +1310,7 @@ class Chi(MultiGroupXS):
|
|||
self._xs_tally = nu_fission_out / sum_nu_fission_in
|
||||
|
||||
# Normalize chi to 1.0
|
||||
norm = self.xs_tally.summation(filters=['energyout'],
|
||||
norm = self.xs_tally.summation(filter='energyout',
|
||||
filter_bins=energy_bins)
|
||||
|
||||
# FIXME: CrossFilter for energy + energy messes up tally arithmetic
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import sys
|
|||
|
||||
import numpy as np
|
||||
|
||||
from openmc import Mesh, Filter, Trigger, Nuclide
|
||||
from openmc import Mesh, Filter, Trigger, Nuclide, FILTER_TYPES
|
||||
from openmc.cross import CrossScore, CrossNuclide, CrossFilter
|
||||
from openmc.summary import Summary
|
||||
import openmc.checkvalue as cv
|
||||
|
|
@ -78,8 +78,8 @@ class Tally(object):
|
|||
mean : ndarray
|
||||
An array containing the sample mean for each bin
|
||||
std_dev : ndarray
|
||||
|
||||
An array containing the sample standard deviation for each bin
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, tally_id=None, name=''):
|
||||
|
|
@ -713,7 +713,7 @@ class Tally(object):
|
|||
filter_type : str
|
||||
The type of Filter (e.g., 'cell', 'energy', etc.)
|
||||
|
||||
filter_bin : int, list
|
||||
filter_bin : int, tuple
|
||||
The bin is an integer ID for 'material', 'surface', 'cell',
|
||||
'cellborn', and 'universe' Filters. The bin is an integer for the
|
||||
cell instance ID for 'distribcell' Filters. The bin is a 2-tuple of
|
||||
|
|
@ -2277,6 +2277,8 @@ class Tally(object):
|
|||
if filter_type in ['energy', 'energyout']:
|
||||
bin_indices.append(bin_index)
|
||||
bin_indices.append(bin_index+1)
|
||||
elif filter_type == 'distribcell':
|
||||
bin_indices.append(0)
|
||||
else:
|
||||
bin_indices.append(bin_index)
|
||||
|
||||
|
|
@ -2292,13 +2294,13 @@ class Tally(object):
|
|||
|
||||
return new_tally
|
||||
|
||||
def summation(self, scores=[], filters=[], filter_bins=[], nuclides=[]):
|
||||
"""Build a sliced tally for the specified filters, scores and nuclides.
|
||||
def summation(self, scores=[], filter=None, filter_bins=[], nuclides=[]):
|
||||
"""Build a sliced tally for the specified filter bins, nuclides, scores.
|
||||
|
||||
This method constructs a new tally to encapsulate a subset of the data
|
||||
represented by this tally. The subset of data to include in the tally
|
||||
slice is determined by the scores, filters and nuclides specified in
|
||||
the input parameters.
|
||||
slice is determined by the scores, filter bins and nuclides specified
|
||||
in the input parameters.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
@ -2306,21 +2308,19 @@ class Tally(object):
|
|||
A list of one or more score strings to sum across
|
||||
(e.g., ['absorption', 'nu-fission']; default is [])
|
||||
|
||||
filters : list
|
||||
A list of filter type strings to sum across
|
||||
(e.g., ['mesh', 'energy']; default is [])
|
||||
filter : str
|
||||
A filter type string (e.g., 'cell', 'energy') corresponding to the
|
||||
filter bins to sum across
|
||||
|
||||
filter_bins : list of Iterables
|
||||
A list of the filter bins corresponding to the filter_types
|
||||
parameter (e.g., [(1,), (0., 0.625e-6)]; default is []). Each bin
|
||||
in the list is the integer ID for 'material', 'surface', 'cell',
|
||||
'cellborn', and 'universe' Filters. Each bin is an integer for the
|
||||
cell instance ID for 'distribcell Filters. Each bin is a 2-tuple of
|
||||
floats for 'energy' and 'energyout' filters corresponding to the
|
||||
energy boundaries of the bin of interest. The bin is a (x,y,z)
|
||||
3-tuple for 'mesh' filters corresponding to the mesh cell of
|
||||
interest. The order of the bins in the list must correspond to the
|
||||
filter_types parameter.
|
||||
filter_bins : Iterable of Integral or tuple
|
||||
A list of the filter bins corresponding to the filters parameter
|
||||
Each bin in the list is the integer ID for 'material', 'surface',
|
||||
'cell', 'cellborn', and 'universe' Filters. Each bin is an integer
|
||||
for the cell instance ID for 'distribcell Filters. Each bin is a
|
||||
2-tuple of floats for 'energy' and 'energyout' filters corresponding
|
||||
to the energy boundaries of the bin of interest. Each bin is an
|
||||
(x,y,z) 3-tuple for 'mesh' filters corresponding to the mesh cell of
|
||||
interest.
|
||||
|
||||
nuclides : list
|
||||
A list of nuclide name strings to sum across
|
||||
|
|
@ -2347,15 +2347,20 @@ class Tally(object):
|
|||
else:
|
||||
nuclides = [[nuclide] for nuclide in nuclides]
|
||||
|
||||
# If user did not specify any filter bins, do not sum across filter bins
|
||||
if len(filters) == 0:
|
||||
# Sum across any filter bins specified by the user
|
||||
if filter in FILTER_TYPES.values():
|
||||
filter_bins = [[(filter_bin,)] for filter_bin in filter_bins]
|
||||
filters = [[filter]]
|
||||
# If user did not specify a filter type, do not sum across filter bins
|
||||
else:
|
||||
filter_bins = [[]]
|
||||
filters = [[]]
|
||||
# Sum across any filter bins specified by the user
|
||||
'''
|
||||
else:
|
||||
filter_bins = list(itertools.product(*filter_bins))
|
||||
filter_bins = [list(filter_bin) for filter_bin in filter_bins]
|
||||
filters = [filters]
|
||||
# filter_bins = list(itertools.product(*filter_bins))
|
||||
filter_bins = [[filter_bin] for filter_bin in filter_bins]
|
||||
filters = [[filter]]
|
||||
'''
|
||||
|
||||
# Initialize Tally sum
|
||||
tally_sum = 0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue