mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 22:26:08 -04:00
Got the python interface for the collision filter tentatively working
This commit is contained in:
parent
7ebc36b4a5
commit
55fb5de01b
2 changed files with 124 additions and 2 deletions
|
|
@ -23,7 +23,7 @@ public:
|
|||
//----------------------------------------------------------------------------
|
||||
// Methods
|
||||
|
||||
std::string type() const override { return "numCollisions"; }
|
||||
std::string type() const override { return "collision"; }
|
||||
|
||||
void from_xml(pugi::xml_node node) override;
|
||||
|
||||
|
|
|
|||
124
openmc/filter.py
124
openmc/filter.py
|
|
@ -22,7 +22,8 @@ _FILTER_TYPES = (
|
|||
'universe', 'material', 'cell', 'cellborn', 'surface', 'mesh', 'energy',
|
||||
'energyout', 'mu', 'polar', 'azimuthal', 'distribcell', 'delayedgroup',
|
||||
'energyfunction', 'cellfrom', 'legendre', 'spatiallegendre',
|
||||
'sphericalharmonics', 'zernike', 'zernikeradial', 'particle', 'cellinstance'
|
||||
'sphericalharmonics', 'zernike', 'zernikeradial', 'particle', 'cellinstance',
|
||||
'collision'
|
||||
)
|
||||
|
||||
_CURRENT_NAMES = (
|
||||
|
|
@ -964,6 +965,127 @@ class MeshSurfaceFilter(MeshFilter):
|
|||
return pd.concat([df, pd.DataFrame(filter_dict)])
|
||||
|
||||
|
||||
class CollisionFilter(Filter):
|
||||
"""Bins tally events based on the number of collisions.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
values : Iterable of Int
|
||||
A list or iterable of the number of collisions, as integer values.
|
||||
The events whose post-scattering collision number equals one of
|
||||
the provided values will be counted.
|
||||
filter_id : int
|
||||
Unique identifier for the filter
|
||||
|
||||
Attributes
|
||||
----------
|
||||
values : numpy.ndarray
|
||||
An array of integer values representing the number of collisions events
|
||||
by which to filter
|
||||
id : int
|
||||
Unique identifier for the filter
|
||||
bins : numpy.ndarray
|
||||
An array of integer values representing the number of collisions events
|
||||
by which to filter
|
||||
num_bins : Integral
|
||||
The number of filter bins
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, values, filter_id=None):
|
||||
self.values = np.asarray(values)
|
||||
self.bins = self.values
|
||||
self.id = filter_id
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
string = type(self).__name__ + '\n'
|
||||
string += '{: <16}=\t{}\n'.format('\tValues', self.values)
|
||||
string += '{: <16}=\t{}\n'.format('\tID', self.id)
|
||||
return string
|
||||
|
||||
@Filter.bins.setter
|
||||
def bins(self, bins):
|
||||
Filter.bins.__set__(self, np.asarray(bins))
|
||||
|
||||
def check_bins(self, bins):
|
||||
for x in bins:
|
||||
# Values should be integers
|
||||
cv.check_type('filter value', x, Integral)
|
||||
cv.check_greater_than('filter value', x, 0, equality=True)
|
||||
|
||||
def get_bin_index(self, filter_bin):
|
||||
i = np.where(self.bins[:, 1] == filter_bin[1])[0]
|
||||
if len(i) == 0:
|
||||
msg = 'Unable to get the bin index for Filter since "{0}" ' \
|
||||
'is not one of the bins'.format(filter_bin)
|
||||
raise ValueError(msg)
|
||||
else:
|
||||
return i[0]
|
||||
|
||||
def get_pandas_dataframe(self, data_size, stride, **kwargs):
|
||||
"""Builds a Pandas DataFrame for the Filter's bins.
|
||||
|
||||
This method constructs a Pandas DataFrame object for the filter with
|
||||
columns annotated by filter bin information. This is a helper method for
|
||||
:meth:`Tally.get_pandas_dataframe`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
data_size : int
|
||||
The total number of bins in the tally corresponding to this filter
|
||||
stride : int
|
||||
Stride in memory for the filter
|
||||
|
||||
Returns
|
||||
-------
|
||||
pandas.DataFrame
|
||||
A Pandas DataFrame with one column of the lower energy bound and one
|
||||
column of upper energy bound for each filter bin. The number of
|
||||
rows in the DataFrame is the same as the total number of bins in the
|
||||
corresponding tally, with the filter bin appropriately tiled to map
|
||||
to the corresponding tally bins.
|
||||
|
||||
See also
|
||||
--------
|
||||
Tally.get_pandas_dataframe(), CrossFilter.get_pandas_dataframe()
|
||||
|
||||
"""
|
||||
# Initialize Pandas DataFrame
|
||||
df = pd.DataFrame()
|
||||
|
||||
# Extract the lower and upper energy bounds, then repeat and tile
|
||||
# them as necessary to account for other filters.
|
||||
bins = np.repeat(self.bins[:], stride)
|
||||
tile_factor = data_size // len(bins)
|
||||
bins = np.tile(bins, tile_factor)
|
||||
|
||||
# Add the new energy columns to the DataFrame.
|
||||
if hasattr(self, 'units'):
|
||||
units = ' [{}]'.format(self.units)
|
||||
else:
|
||||
units = ''
|
||||
|
||||
df.loc[:, self.short_name.lower() + ' collisions' ] = bins
|
||||
|
||||
return df
|
||||
|
||||
def to_xml_element(self):
|
||||
"""Return XML Element representing the Filter.
|
||||
|
||||
Returns
|
||||
-------
|
||||
element : xml.etree.ElementTree.Element
|
||||
XML element containing filter data
|
||||
|
||||
"""
|
||||
element = super().to_xml_element()
|
||||
element[0].text = ' '.join(str(x) for x in self.values)
|
||||
return element
|
||||
|
||||
|
||||
|
||||
|
||||
class RealFilter(Filter):
|
||||
"""Tally modifier that describes phase-space and other characteristics
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue