|
44 | 44 | openmc.CellFilter, |
45 | 45 | openmc.DistribcellFilter, |
46 | 46 | openmc.CellInstanceFilter, |
47 | | - openmc.MeshFilter) |
| 47 | + openmc.MeshFilter, |
| 48 | + openmc.MeshMaterialFilter) |
48 | 49 |
|
49 | 50 | _PRODUCTIONS = ('delayed-nu-fission', 'prompt-nu-fission', 'nu-fission', |
50 | 51 | 'nu-scatter', 'H1-production', 'H2-production', |
@@ -672,6 +673,13 @@ def create_tally_image(self, view: Optional[PlotView] = None): |
672 | 673 | nuclides, |
673 | 674 | view) |
674 | 675 | return image + (units_out,) |
| 676 | + |
| 677 | + elif tally.contains_filter(openmc.MeshMaterialFilter): |
| 678 | + image = self._create_tally_filter_image( |
| 679 | + tally, tally_value, openmc.MeshMaterialFilter, scores, nuclides, view) |
| 680 | + return image + (units_out,) |
| 681 | + |
| 682 | + |
675 | 683 | elif contains_distribcell or contains_cellinstance: |
676 | 684 | if tally_value == 'rel_err': |
677 | 685 | mean_data = self._create_distribcell_image( |
@@ -944,6 +952,87 @@ def _do_op(array, tally_value, ax=0): |
944 | 952 |
|
945 | 953 | return image_data, None, data_min, data_max |
946 | 954 |
|
| 955 | + def _create_tally_filter_image( |
| 956 | + self, tally: openmc.Tally, tally_value: TallyValueType, filter_class, |
| 957 | + scores: Tuple[str], nuclides: Tuple[str], view: PlotView = None |
| 958 | + ): |
| 959 | + # some variables used throughout |
| 960 | + if view is None: |
| 961 | + view = self.currentView |
| 962 | + |
| 963 | + def _do_op(array, tally_value, ax=0): |
| 964 | + if tally_value == 'mean': |
| 965 | + return np.sum(array, axis=ax) |
| 966 | + elif tally_value == 'std_dev': |
| 967 | + return np.sqrt(np.sum(array**2, axis=ax)) |
| 968 | + |
| 969 | + # start with reshaped data |
| 970 | + data = tally.get_reshaped_data(tally_value) |
| 971 | + |
| 972 | + # move mesh axes to the end of the filters |
| 973 | + filter_idx = [type(filter) for filter in tally.filters].index(filter_class) |
| 974 | + data = np.moveaxis(data, filter_idx, -1) |
| 975 | + |
| 976 | + # sum over the rest of the tally filters |
| 977 | + for tally_filter in tally.filters: |
| 978 | + if type(tally_filter) is filter_class: |
| 979 | + continue |
| 980 | + |
| 981 | + selected_bins = self.appliedFilters[tally_filter] |
| 982 | + if selected_bins: |
| 983 | + # sum filter data for the selected bins |
| 984 | + data = data[np.array(selected_bins)].sum(axis=0) |
| 985 | + else: |
| 986 | + # if the filter is completely unselected, |
| 987 | + # set all of its data to zero and remove the axis |
| 988 | + data[:] = 0.0 |
| 989 | + data = _do_op(data, tally_value) |
| 990 | + |
| 991 | + # filter by selected nuclides |
| 992 | + if not nuclides: |
| 993 | + data = 0.0 |
| 994 | + |
| 995 | + selected_nuclides = [] |
| 996 | + for idx, nuclide in enumerate(tally.nuclides): |
| 997 | + if nuclide in nuclides: |
| 998 | + selected_nuclides.append(idx) |
| 999 | + data = _do_op(data[np.array(selected_nuclides)], tally_value) |
| 1000 | + |
| 1001 | + # filter by selected scores |
| 1002 | + if not scores: |
| 1003 | + data = 0.0 |
| 1004 | + |
| 1005 | + selected_scores = [] |
| 1006 | + for idx, score in enumerate(tally.scores): |
| 1007 | + if score in scores: |
| 1008 | + selected_scores.append(idx) |
| 1009 | + data = _do_op(data[np.array(selected_scores)], tally_value) |
| 1010 | + |
| 1011 | + # Get mesh bins from openmc.lib |
| 1012 | + filter = tally.find_filter(filter_class) |
| 1013 | + filter_cpp = openmc.lib.filters[filter.id] |
| 1014 | + |
| 1015 | + if view is None: |
| 1016 | + view = self.currentView |
| 1017 | + |
| 1018 | + bins = filter_cpp.get_plot_bins( |
| 1019 | + origin=view.origin, |
| 1020 | + width=(view.width, view.height), |
| 1021 | + basis=view.basis, |
| 1022 | + pixels=(view.h_res, view.v_res), |
| 1023 | + ) |
| 1024 | + |
| 1025 | + # set image data |
| 1026 | + image_data = np.full_like(self.ids, np.nan, dtype=float) |
| 1027 | + mask = (bins >= 0) |
| 1028 | + image_data[mask] = data[bins[mask]] |
| 1029 | + |
| 1030 | + # get dataset's min/max |
| 1031 | + data_min = np.min(data) |
| 1032 | + data_max = np.max(data) |
| 1033 | + |
| 1034 | + return image_data, None, data_min, data_max |
| 1035 | + |
947 | 1036 | @property |
948 | 1037 | def cell_ids(self): |
949 | 1038 | return self.ids_map[:, :, 0] |
|
0 commit comments