mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 22:26:08 -04:00
Implemented MGXS merging
This commit is contained in:
parent
184ed3733b
commit
ef60d9d2f5
4 changed files with 157 additions and 24 deletions
|
|
@ -289,24 +289,6 @@ class Filter(object):
|
|||
else:
|
||||
return True
|
||||
|
||||
'''
|
||||
# FIXME: Should all bins be completely separate???
|
||||
# FIMXE: This is necessary if merging will choose out unique bins
|
||||
else:
|
||||
# None of the bins in this filter should match in the other filter
|
||||
for bin in self.bins:
|
||||
if bin in other.bins:
|
||||
return False
|
||||
|
||||
# None of the bins in the other filter should match in this filter
|
||||
for bin in other.bins:
|
||||
if bin in self.bins:
|
||||
return False
|
||||
|
||||
# If all conditional checks pass then filters are mergeable
|
||||
return True
|
||||
'''
|
||||
|
||||
def merge(self, other):
|
||||
"""Merge this filter with another.
|
||||
|
||||
|
|
|
|||
|
|
@ -54,10 +54,12 @@ class EnergyGroups(object):
|
|||
def __eq__(self, other):
|
||||
if not isinstance(other, EnergyGroups):
|
||||
return False
|
||||
elif self.group_edges != other.group_edges:
|
||||
elif self.num_groups != other.num_groups:
|
||||
return False
|
||||
else:
|
||||
elif np.allclose(self.group_edges, other.group_edges):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self == other
|
||||
|
|
@ -236,3 +238,64 @@ class EnergyGroups(object):
|
|||
condensed_groups.group_edges = group_edges
|
||||
|
||||
return condensed_groups
|
||||
|
||||
def can_merge(self, other):
|
||||
"""Determine if energy groups can be merged with another.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
other : EnergyGroups
|
||||
EnergyGroups to compare with
|
||||
|
||||
Returns
|
||||
-------
|
||||
bool
|
||||
Whether the energy groups can be merged
|
||||
|
||||
"""
|
||||
|
||||
if not isinstance(other, EnergyGroups):
|
||||
return False
|
||||
|
||||
# If the energy group structures match then groups are mergeable
|
||||
if self == other:
|
||||
return True
|
||||
|
||||
# This low energy edge coincides with other's high energy edge
|
||||
if self.group_edges[0] == other.group_edges[-1]:
|
||||
return True
|
||||
# This high energy edge coincides with other's low energy edge
|
||||
elif self.group_edges[-1] == other.group_edges[0]:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def merge(self, other):
|
||||
"""Merge this energy groups with another.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
other : EnergyGroups
|
||||
EnergyGroups to merge with
|
||||
|
||||
Returns
|
||||
-------
|
||||
merged_groups : EnergyGroups
|
||||
EnergyGroups resulting from the merge
|
||||
|
||||
"""
|
||||
|
||||
if not self.can_merge(other):
|
||||
raise ValueError('Unable to merge energy groups')
|
||||
|
||||
# Create deep copy to return as merged energy groups
|
||||
merged_groups = copy.deepcopy(self)
|
||||
|
||||
# Merge unique filter bins
|
||||
merged_edges = np.concatenate((self.group_edges, other.group_edges))
|
||||
merged_edges = np.unique(merged_edges)
|
||||
merged_edges = sorted(merged_edges)
|
||||
|
||||
# Assign merged edges to merged groups
|
||||
merged_groups.group_edges = list(merged_edges)
|
||||
return merged_groups
|
||||
|
|
@ -155,7 +155,7 @@ class MGXS(object):
|
|||
clone._name = self.name
|
||||
clone._rxn_type = self.rxn_type
|
||||
clone._by_nuclide = self.by_nuclide
|
||||
clone._nuclides = self._nuclides
|
||||
clone._nuclides = copy.deepcopy(self._nuclides)
|
||||
clone._domain = self.domain
|
||||
clone._domain_type = self.domain_type
|
||||
clone._energy_groups = copy.deepcopy(self.energy_groups, memo)
|
||||
|
|
@ -953,9 +953,93 @@ class MGXS(object):
|
|||
slice_xs.sparse = self.sparse
|
||||
return slice_xs
|
||||
|
||||
# FIXME
|
||||
def can_merge(self, other):
|
||||
"""Determine if another MGXS can be merged with this one
|
||||
|
||||
If results have been loaded from a statepoint, then MGXS are only
|
||||
mergeable along one and only one of enegy groups or nuclides.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
other : MGXS
|
||||
MGXS to check for merging
|
||||
|
||||
"""
|
||||
|
||||
if not isinstance(other, type(self)):
|
||||
return False
|
||||
|
||||
# Compare reaction type, energy groups, nuclides, domain type
|
||||
if self.rxn_type != other.rxn_type:
|
||||
return False
|
||||
elif not self.energy_groups.can_merge(other.energy_groups):
|
||||
return False
|
||||
elif self.by_nuclide != other.by_nuclide:
|
||||
return False
|
||||
elif self.domain_type != other.domain_type:
|
||||
return False
|
||||
elif 'distribcell' not in self.domain_type and self.domain != other.domain:
|
||||
return False
|
||||
elif len(self.tallies) != len(other.tallies):
|
||||
return False
|
||||
|
||||
# See if each individual tally is mergeable
|
||||
for tally_key in self.tallies:
|
||||
if not self.tallies[tally_key].can_merge(other.tallies[tally_key]):
|
||||
return False
|
||||
|
||||
# If all conditionals pass then MGXS are mergeable
|
||||
return True
|
||||
|
||||
def merge(self, other):
|
||||
raise NotImplementedError('not yet implemented')
|
||||
"""Merge another MGXS with this one
|
||||
|
||||
If results have been loaded from a statepoint, then MGXS are only
|
||||
mergeable along one and only one of energy groups or nuclides.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
other : MGXS
|
||||
MGXS to merge with this one
|
||||
|
||||
Returns
|
||||
-------
|
||||
merged_mgxs : MGXS
|
||||
Merged MGXS
|
||||
|
||||
"""
|
||||
|
||||
if not self.can_merge(other):
|
||||
raise ValueError('Unable to merge MGXS')
|
||||
|
||||
# Create deep copy of tally to return as merged tally
|
||||
merged_mgxs = copy.deepcopy(self)
|
||||
merged_mgxs._rxn_rate_tally = None
|
||||
merged_mgxs._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
|
||||
|
||||
# Merge nuclides
|
||||
if self.nuclides != other.nuclides:
|
||||
|
||||
# The nuclides must be mutually exclusive
|
||||
for nuclide in self.nuclides:
|
||||
if nuclide in other.nuclides:
|
||||
msg = 'Unable to merge MGXS with shared nuclides'
|
||||
raise ValueError(msg)
|
||||
|
||||
# Concatenate lists of nuclides for the merged MGXS
|
||||
merged_mgxs.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
|
||||
|
||||
return merged_mgxs
|
||||
|
||||
def print_xs(self, subdomains='all', nuclides='all', xs_type='macro'):
|
||||
"""Print a string representation for the multi-group cross section.
|
||||
|
|
|
|||
|
|
@ -859,7 +859,7 @@ class Tally(object):
|
|||
|
||||
Parameters
|
||||
----------
|
||||
tally : Tally
|
||||
other : Tally
|
||||
Tally to merge with this one
|
||||
|
||||
Returns
|
||||
|
|
@ -880,6 +880,10 @@ class Tally(object):
|
|||
# Differentiate Tally with a new auto-generated Tally ID
|
||||
merged_tally.id = None
|
||||
|
||||
# If the two tallies are equal, simpy return copy
|
||||
if self == other:
|
||||
return merged_tally
|
||||
|
||||
# Create deep copy of other tally to use for array concatenation
|
||||
other_copy = copy.deepcopy(other)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue