From 54c4b737d67bd7f0d9894828d2b58860063e99a6 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 27 Apr 2022 17:15:46 -0500 Subject: [PATCH 1/2] Implement support for CellInstanceFilter tally plotting --- openmc_plotter/docks.py | 7 +++-- openmc_plotter/plotmodel.py | 56 ++++++++++++++++++++++++++----------- 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/openmc_plotter/docks.py b/openmc_plotter/docks.py index 052eac7..a4ea302 100644 --- a/openmc_plotter/docks.py +++ b/openmc_plotter/docks.py @@ -406,8 +406,11 @@ def _createFilterTree(self, spatial_filters): continue def _bin_sort_val(bin): - if isinstance(bin, Iterable) and all([isinstance(val, float) for val in bin]): - return np.sum(bin) + if isinstance(bin, Iterable): + if all([isinstance(val, float) for val in bin]): + return np.sum(bin) + else: + return tuple(bin) else: return bin diff --git a/openmc_plotter/plotmodel.py b/openmc_plotter/plotmodel.py index dda042c..33455e4 100644 --- a/openmc_plotter/plotmodel.py +++ b/openmc_plotter/plotmodel.py @@ -34,6 +34,7 @@ openmc.MaterialFilter, openmc.CellFilter, openmc.DistribcellFilter, + openmc.CellInstanceFilter, openmc.MeshFilter) _PRODUCTIONS = ('delayed-nu-fission', 'prompt-nu-fission', 'nu-fission', @@ -330,6 +331,9 @@ def create_tally_image(self, view=None): units_out = list(units)[0] + contains_distribcell = tally.contains_filter(openmc.DistribcellFilter) + contains_cellinstance = tally.contains_filter(openmc.CellInstanceFilter) + if tally.contains_filter(openmc.MeshFilter): if tally_value == 'rel_err': # get both the std. dev. data and mean data @@ -360,28 +364,26 @@ def create_tally_image(self, view=None): nuclides, view) return image + (units_out,) - elif tally.contains_filter(openmc.DistribcellFilter): + elif contains_distribcell or contains_cellinstance: + # Select appropriate function + if contains_distribcell: + create_image = self._create_distribcell_image + else: + create_image = self._create_cellinstance_image + if tally_value == 'rel_err': - mean_data = self._create_distribcell_image(tally, - 'mean', - scores, - nuclides) - std_dev_data = self._create_distribcell_image(tally, - 'std_dev', - scores, - nuclides) - image_data = 100 * np.divide(std_dev_data[0], - mean_data[0], - out=np.zeros_like(mean_data[0]), - where=mean_data != 0) + mean_data = create_image(tally, 'mean', scores, nuclides) + std_dev_data = create_image(tally, 'std_dev', scores, nuclides) + image_data = 100 * np.divide( + std_dev_data[0], mean_data[0], + out=np.zeros_like(mean_data[0]), + where=mean_data != 0 + ) data_min = np.min(image_data) data_max = np.max(image_data) return image_data, None, data_min, data_max, '% error' else: - image = self._create_distribcell_image(tally, - tally_value, - scores, - nuclides) + image = create_image(tally, tally_value, scores, nuclides) return image + (units_out,) else: # same as above, get the std. dev. data @@ -522,6 +524,26 @@ def _create_distribcell_image(self, tally, tally_value, scores, nuclides): return image_data, None, data_min, data_max + def _create_cellinstance_image(self, tally, tally_value, scores, nuclides): + cellinst_filter = tally.find_filter(openmc.CellInstanceFilter) + + data = tally.get_values(scores=scores, nuclides=nuclides, value=tally_value) + data = data.flatten() + + # create a mask for ids that match the cell + image_data = np.full_like(self.ids, np.nan, dtype=float) + + for v, (cell_id, instance) in zip(data, cellinst_filter.bins): + cell_id_mask = self.cell_ids == cell_id + instance_mask = self.instances == instance + image_data[cell_id_mask & instance_mask] = v + + data_min = np.min(data) + data_max = np.max(data) + image_data = np.ma.masked_where(image_data < 0.0, image_data) + + return image_data, None, data_min, data_max + def _create_tally_mesh_image(self, tally, tally_value, scores, nuclides, view=None): # some variables used throughout if view is None: From 258a5030c0d0b5d7a09c61241518a63f8f8d5f31 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 27 Apr 2022 17:25:37 -0500 Subject: [PATCH 2/2] Combine separate functions for distribcell / cell instance plotting --- openmc_plotter/plotmodel.py | 59 ++++++++++++++----------------------- 1 file changed, 22 insertions(+), 37 deletions(-) diff --git a/openmc_plotter/plotmodel.py b/openmc_plotter/plotmodel.py index 33455e4..d5c092b 100644 --- a/openmc_plotter/plotmodel.py +++ b/openmc_plotter/plotmodel.py @@ -365,15 +365,11 @@ def create_tally_image(self, view=None): view) return image + (units_out,) elif contains_distribcell or contains_cellinstance: - # Select appropriate function - if contains_distribcell: - create_image = self._create_distribcell_image - else: - create_image = self._create_cellinstance_image - if tally_value == 'rel_err': - mean_data = create_image(tally, 'mean', scores, nuclides) - std_dev_data = create_image(tally, 'std_dev', scores, nuclides) + mean_data = self._create_distribcell_image( + tally, 'mean', scores, nuclides, contains_cellinstance) + std_dev_data = self._create_distribcell_image( + tally, 'std_dev', scores, nuclides) image_data = 100 * np.divide( std_dev_data[0], mean_data[0], out=np.zeros_like(mean_data[0]), @@ -383,7 +379,8 @@ def create_tally_image(self, view=None): data_max = np.max(image_data) return image_data, None, data_min, data_max, '% error' else: - image = create_image(tally, tally_value, scores, nuclides) + image = self._create_distribcell_image( + tally, tally_value, scores, nuclides, contains_cellinstance) return image + (units_out,) else: # same as above, get the std. dev. data @@ -503,39 +500,27 @@ def _do_op(array, tally_value, ax=0): return image_data, None, data_min, data_max - def _create_distribcell_image(self, tally, tally_value, scores, nuclides): - dfilter = tally.find_filter(openmc.DistribcellFilter) - - data = tally.get_values(scores=scores, nuclides=nuclides, value=tally_value) - data = data.flatten() - - cell_id = dfilter.bins[0] - # create a mask for ids that match the cell - image_data = np.full_like(self.ids, np.nan, dtype=float) - - cell_id_mask = self.cell_ids == cell_id - for i, v in enumerate(data): - instance_mask = self.instances == i - image_data[cell_id_mask & instance_mask] = v - - data_min = np.min(data) - data_max = np.max(data) - image_data = np.ma.masked_where(image_data < 0.0, image_data) - - return image_data, None, data_min, data_max - - def _create_cellinstance_image(self, tally, tally_value, scores, nuclides): - cellinst_filter = tally.find_filter(openmc.CellInstanceFilter) - + def _create_distribcell_image(self, tally, tally_value, scores, nuclides, cellinstance=False): + # Get flattened array of tally results data = tally.get_values(scores=scores, nuclides=nuclides, value=tally_value) data = data.flatten() - # create a mask for ids that match the cell + # Create an empty array of appropriate shape for image image_data = np.full_like(self.ids, np.nan, dtype=float) - for v, (cell_id, instance) in zip(data, cellinst_filter.bins): - cell_id_mask = self.cell_ids == cell_id - instance_mask = self.instances == instance + # Determine appropriate set of bins depending on filter type + if cellinstance: + f = tally.find_filter(openmc.CellInstanceFilter) + bins = f.bins + else: + f = tally.find_filter(openmc.DistribcellFilter) + bins = [(f.bins[0], i) for i in range(data.size)] + + # Iterate over tally bins, setting any pixels that have matching (cell + # ID, instance) each time + for v, (cell_id, instance) in zip(data, bins): + cell_id_mask = (self.cell_ids == cell_id) + instance_mask = (self.instances == instance) image_data[cell_id_mask & instance_mask] = v data_min = np.min(data)