diff --git a/docs/source/pythonapi/examples/mgxs-part-iii.ipynb b/docs/source/pythonapi/examples/mgxs-part-iii.ipynb index 39980a8fd..a1eaa7ad8 100644 --- a/docs/source/pythonapi/examples/mgxs-part-iii.ipynb +++ b/docs/source/pythonapi/examples/mgxs-part-iii.ipynb @@ -574,7 +574,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now we must specify the type of domain over which we would like the `Library` to compute multi-group cross sections. The domain type corresponds to the type of tally filter to be used in the tallies created to compute multi-group cross sections. At the present time, the `Library` supports `\"material,\"` `\"cell,\"` and `\"universe\"` domain types. We will use a `\"cell\"` domain type here to compute cross sections in each of the cells in the fuel assembly geometry.\n", + "Now we must specify the type of domain over which we would like the `Library` to compute multi-group cross sections. The domain type corresponds to the type of tally filter to be used in the tallies created to compute multi-group cross sections. At the present time, the `Library` supports `\"material\"`, `\"cell\"`, `\"universe\"`, and `\"mesh\"` domain types. We will use a `\"cell\"` domain type here to compute cross sections in each of the cells in the fuel assembly geometry.\n", "\n", "**Note:** By default, the `Library` class will instantiate `MGXS` objects for each and every domain (material, cell or universe) in the geometry of interest. However, one may specify a subset of these domains to the `Library.domains` property. In our case, we wish to compute multi-group cross sections in each and every cell since they will be needed in our downstream OpenMOC calculation on the identical combinatorial geometry mesh." ] diff --git a/docs/source/pythonapi/examples/mgxs-part-iv.ipynb b/docs/source/pythonapi/examples/mgxs-part-iv.ipynb index ae015b0a6..5b3bae495 100644 --- a/docs/source/pythonapi/examples/mgxs-part-iv.ipynb +++ b/docs/source/pythonapi/examples/mgxs-part-iv.ipynb @@ -519,9 +519,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now we must specify the type of domain over which we would like the `Library` to compute multi-group cross sections. The domain type corresponds to the type of tally filter to be used in the tallies created to compute multi-group cross sections. At the present time, the `Library` supports \"material,\" \"cell,\" and \"universe\" domain types. In this simple example, we wish to compute multi-group cross sections only for each material andtherefore will use a \"material\" domain type.\n", + "Now we must specify the type of domain over which we would like the `Library` to compute multi-group cross sections. The domain type corresponds to the type of tally filter to be used in the tallies created to compute multi-group cross sections. At the present time, the `Library` supports \"material\" \"cell\", \"universe\", and \"mesh\" domain types. In this simple example, we wish to compute multi-group cross sections only for each material andtherefore will use a \"material\" domain type.\n", "\n", - "**Note:** By default, the `Library` class will instantiate `MGXS` objects for each and every domain (material, cell or universe) in the geometry of interest. However, one may specify a subset of these domains to the `Library.domains` property." + "**Note:** By default, the `Library` class will instantiate `MGXS` objects for each and every domain (material, cell, universe, or mesh cell) in the geometry of interest. However, one may specify a subset of these domains to the `Library.domains` property." ] }, { @@ -1437,21 +1437,21 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 2", "language": "python", - "name": "python3" + "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", - "version": 3 + "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.5.2" + "pygments_lexer": "ipython2", + "version": "2.7.11" } }, "nbformat": 4, diff --git a/docs/source/pythonapi/index.rst b/docs/source/pythonapi/index.rst index 36f161b3c..df50eee0b 100644 --- a/docs/source/pythonapi/index.rst +++ b/docs/source/pythonapi/index.rst @@ -269,13 +269,16 @@ Multi-group Cross Sections openmc.mgxs.AbsorptionXS openmc.mgxs.CaptureXS openmc.mgxs.Chi + openmc.mgxs.ChiPrompt openmc.mgxs.FissionXS + openmc.mgxs.InverseVelocity openmc.mgxs.KappaFissionXS openmc.mgxs.MultiplicityMatrixXS openmc.mgxs.NuFissionXS openmc.mgxs.NuFissionMatrixXS openmc.mgxs.NuScatterXS openmc.mgxs.NuScatterMatrixXS + openmc.mgxs.PromptNuFissionXS openmc.mgxs.ScatterXS openmc.mgxs.ScatterMatrixXS openmc.mgxs.TotalXS diff --git a/openmc/mgxs/groups.py b/openmc/mgxs/groups.py index 1b17cf7a8..881597c7b 100644 --- a/openmc/mgxs/groups.py +++ b/openmc/mgxs/groups.py @@ -1,5 +1,5 @@ from collections import Iterable -from numbers import Real +from numbers import Real, Integral import copy import sys @@ -370,7 +370,7 @@ class DelayedGroups(object): @groups.setter def groups(self, groups): - cv.check_type('groups', groups, Iterable, Int) + cv.check_type('groups', groups, Iterable, Integral) cv.check_greater_than('number of delayed groups', len(groups), 0) # Check that the groups are within [1, MAX_DELAYED_GROUPS] diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index 3c0ec5439..e25339bc0 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -56,7 +56,7 @@ class Library(object): The types of cross sections in the library (e.g., ['total', 'scatter']) domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'} Domain type for spatial homogenization - domains : Iterable of openmc.Material, openmc.Cell, openmc.Universe, or + domains : Iterable of openmc.Material, openmc.Cell, openmc.Universe or openmc.Mesh The spatial domain(s) for which MGXS in the Library are computed correction : {'P0', None} @@ -184,10 +184,8 @@ class Library(object): return self.openmc_geometry.get_all_material_cells() elif self.domain_type == 'universe': return self.openmc_geometry.get_all_universes() - # FIXME: Change to get tuples of all domain cells elif self.domain_type == 'mesh': - raise ValueError('Unable to get all domains for a mesh domain ' + - 'type. The domains must be set to [openmc.Mesh]') + raise ValueError('Unable to get domains for Mesh domain type') else: raise ValueError('Unable to get domains without a domain type') else: @@ -290,6 +288,9 @@ class Library(object): all_domains = self.openmc_geometry.get_all_universes() elif self.domain_type == 'mesh': cv.check_iterable_type('domain', domains, openmc.Mesh) + + # The mesh and geometry are independent, so set all_domains + # to the input domains all_domains = domains else: raise ValueError('Unable to set domains with domain ' diff --git a/openmc/mgxs/mdgxs.py b/openmc/mgxs/mdgxs.py index 202950ec3..d36b29f7f 100644 --- a/openmc/mgxs/mdgxs.py +++ b/openmc/mgxs/mdgxs.py @@ -13,6 +13,8 @@ import numpy as np from mgxs import MGXS, MGXS_TYPES, DOMAIN_TYPES, _DOMAINS from openmc.mgxs import EnergyGroups, DelayedGroups from openmc import Mesh +import openmc +import openmc.checkvalue as cv # Supported cross section types MDGXS_TYPES = ['delayed-nu-fission', @@ -145,19 +147,23 @@ class MDGXS(MGXS): @delayed_groups.setter def delayed_groups(self, delayed_groups): - cv.check_type('delayed groups', delayed_groups, openmc.mgxs.DelayedGroups) + cv.check_type('delayed groups', delayed_groups, + openmc.mgxs.DelayedGroups) self._delayed_groups = delayed_groups @property def filters(self): + + # Create the non-domain specific Filters for the Tallies group_edges = self.energy_groups.group_edges energy_filter = openmc.Filter('energy', group_edges) + if self.delayed_groups != None: delayed_groups = self.delayed_groups.groups delayed_filter = openmc.Filter('delayedgroup', delayed_groups) - return [[delayed_filter, energy_filter]] * len(self.scores) + return [[energy_filter], [delayed_filter, energy_filter]] else: - return [[energy]] * len(self.scores) + return [[energy_filter], [energy_filter]] @staticmethod def get_mgxs(mdgxs_type, domain=None, domain_type=None, @@ -171,10 +177,10 @@ class MDGXS(MGXS): Parameters ---------- - mdgxs_type : {'delayed-nu-fission', 'chi-prompt', 'chi-delayed', - 'beta'} + mdgxs_type : {'delayed-nu-fission', 'chi-delayed', 'beta'} The type of multi-delayed-group cross section object to return - domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh + domain : openmc.Material or openmc.Cell or openmc.Universe or + openmc.Mesh The domain for spatial homogenization domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'} The domain type for spatial homogenization @@ -200,7 +206,7 @@ class MDGXS(MGXS): cv.check_value('mdgxs_type', mdgxs_type, MDGXS_TYPES) if mdgxs_type == 'delayed-nu-fission': - mdgxs = DelayedNuFission(domain, domain_type, energy_groups) + mdgxs = DelayedNuFissionXS(domain, domain_type, energy_groups) elif mdgxs_type == 'chi-delayed': mdgxs = ChiDelayed(domain, domain_type, energy_groups) elif mdgxs_type == 'beta': @@ -260,12 +266,20 @@ class MDGXS(MGXS): cv.check_value('value', value, ['mean', 'std_dev', 'rel_err']) cv.check_value('xs_type', xs_type, ['macro', 'micro']) + # FIXME: Unable to get microscopic xs for mesh domain because the mesh + # cells do not know the nuclide densities in each mesh cell. + if self.domain_type == 'mesh' and xs_type == 'micro': + msg = 'Unable to get micro xs for mesh domain since the mesh ' \ + 'cells do not know the nuclide densities in each mesh cell.' + raise ValueError(msg) + filters = [] filter_bins = [] # Construct a collection of the domain filter bins if not isinstance(subdomains, basestring): - cv.check_iterable_type('subdomains', subdomains, Integral, max_depth=3) + cv.check_iterable_type('subdomains', subdomains, Integral, + max_depth=3) for subdomain in subdomains: filters.append(self.domain_type) filter_bins.append((subdomain,)) @@ -275,13 +289,14 @@ class MDGXS(MGXS): cv.check_iterable_type('groups', groups, Integral) for group in groups: filters.append('energy') - filter_bins.append((self.energy_groups.get_group_bounds(group),)) + filter_bins.append( + (self.energy_groups.get_group_bounds(group),)) # Construct list of delayed group tuples for all requested groups if not isinstance(delayed_groups, basestring): cv.check_iterable_type('delayed_groups', delayed_groups, Integral) for delayed_group in delayed_groups: - filters.append('delayedgroups') + filters.append('delayedgroup') filter_bins.append((delayed_group,)) # Construct a collection of the nuclides to retrieve from the xs tally @@ -299,7 +314,8 @@ class MDGXS(MGXS): xs = xs_tally.get_values(filters=filters, filter_bins=filter_bins, value=value) else: - xs = self.xs_tally.get_values(filters=filters, filter_bins=filter_bins, + xs = self.xs_tally.get_values(filters=filters, + filter_bins=filter_bins, nuclides=query_nuclides, value=value) # Divide by atom number densities for microscopic cross sections @@ -460,12 +476,12 @@ class MDGXS(MGXS): """ - merged_mdgxs = super(MDGXS, self).merge(other) # Merge delayed groups if self.delayed_groups != other.delayed_groups: - merged_delayed_groups = self.delayed_groups.merge(other.delayed_groups) + merged_delayed_groups = self.delayed_groups.merge( + other.delayed_groups) merged_mdgxs.delayed_groups = merged_delayed_groups return merged_mdgxs @@ -490,7 +506,7 @@ class MDGXS(MGXS): """ - if self.delayed_groups != None: + if self.delayed_groups == None: super(MDGXS, self).print_xs(subdomains, nuclides, xs_type) return @@ -500,18 +516,8 @@ class MDGXS(MGXS): elif self.domain_type == 'distribcell': subdomains = np.arange(self.num_subdomains, dtype=np.int) elif self.domain_type == 'mesh': - subdomains = [] - if (len(self.domain.dimension) == 3): - nx, ny, nz = self.domain.dimension - for x in range(1,nx+1): - for y in range(1,ny+1): - for z in range(1,nz+1): - subdomains.append((x, y, z)) - else: - nx, ny = self.domain.dimension - for x in range(1,nx+1): - for y in range(1,ny+1): - subdomains.append((x, y, 1)) + xyz = [range(1, x+1) for x in self.domain.dimension] + subdomains = list(itertools.product(*xyz)) else: subdomains = [self.domain.id] @@ -534,6 +540,9 @@ class MDGXS(MGXS): string += '{0: <16}=\t{1}\n'.format('\tDomain Type', self.domain_type) string += '{0: <16}=\t{1}\n'.format('\tDomain ID', self.domain.id) + # Generate the header for an individual XS + xs_header = '\tCross Sections [{0}]:'.format(self.get_units(xs_type)) + # If cross section data has not been computed, only print string header if self.tallies is None: print(string) @@ -542,7 +551,7 @@ class MDGXS(MGXS): # Loop over all subdomains for subdomain in subdomains: - if self.domain_type == 'distribcell': + if self.domain_type == 'distribcell' or self.domain_type == 'mesh': string += '{0: <16}=\t{1}\n'.format('\tSubdomain', subdomain) # Loop over all Nuclides @@ -552,11 +561,8 @@ class MDGXS(MGXS): if nuclide != 'sum': string += '{0: <16}=\t{1}\n'.format('\tNuclide', nuclide) - # Build header for cross section type - if xs_type == 'macro': - string += '{0: <16}\n'.format('\tCross Sections [cm^-1]:') - else: - string += '{0: <16}\n'.format('\tCross Sections [barns]:') + # Add the cross section header + string += '{0: <16}\n'.format(xs_header) for delayed_group in self.delayed_groups.groups: @@ -628,15 +634,14 @@ class MDGXS(MGXS): df = self.get_pandas_dataframe(groups=groups, xs_type=xs_type, delayed_groups=delayed_groups) - # Capitalize column label strings - #df.columns = df.columns.astype(str) - #df.columns = map(str.title, df.columns) - # Export the data using Pandas IO API if format == 'csv': df.to_csv(filename + '.csv', index=False) elif format == 'excel': - df.to_excel(filename + '.xls', index=False) + if self.domain_type == 'mesh': + df.to_excel(filename + '.xls') + else: + df.to_excel(filename + '.xls', index=False) elif format == 'pickle': df.to_pickle(filename + '.pkl') elif format == 'latex': @@ -664,7 +669,7 @@ class MDGXS(MGXS): def get_pandas_dataframe(self, groups='all', nuclides='all', xs_type='macro', distribcell_paths=True, delayed_groups='all'): - """Build a Pandas DataFrame for the MGXS data. + """Build a Pandas DataFrame for the MDGXS data. This method leverages :meth:`openmc.Tally.get_pandas_dataframe`, but renames the columns with terminology appropriate for cross section data. @@ -699,8 +704,8 @@ class MDGXS(MGXS): Raises ------ ValueError - When this method is called before the multi-group cross section is - computed from tally data. + When this method is called before the multi-delayed-group cross + section is computed from tally data. """ @@ -719,35 +724,35 @@ class MDGXS(MGXS): class ChiDelayed(MDGXS): - """The delayed fission spectrum. + r"""The delayed fission spectrum. This class can be used for both OpenMC input generation and tally data post-processing to compute spatially-homogenized and energy-integrated - multi-group cross sections for multi-group neutronics calculations. At a - minimum, one needs to set the :attr:`ChiDelayed.energy_groups` and - :attr:`ChiDelayed.domain` properties. Tallies for the flux and appropriate - reaction rates over the specified domain are generated automatically via the - :attr:`ChiDelayed.tallies` property, which can then be appended to a - :class:`openmc.Tallies` instance. + multi-group and multi-delayed-group cross sections for multi-group + neutronics calculations. At a minimum, one needs to set the + :attr:`ChiDelayed.energy_groups` and :attr:`ChiDelayed.domain` properties. + Tallies for the flux and appropriate reaction rates over the specified + domain are generated automatically via the :attr:`ChiDelayed.tallies` + property, which can then be appended to a :class:`openmc.Tallies` instance. - For post-processing, the :meth:`MGXS.load_from_statepoint` will pull in the + For post-processing, the :meth:`MDGXS.load_from_statepoint` will pull in the necessary data to compute multi-group cross sections from a - :class:`openmc.StatePoint` instance. The derived multi-group cross section - can then be obtained from the :attr:`ChiDelayed.xs_tally` property. + :class:`openmc.StatePoint` instance. The derived multi-group cross + section can then be obtained from the :attr:`ChiDelayed.xs_tally` property. - For a spatial domain :math:`V` and energy group :math:`[E_g,E_{g-1}]`, the - fission spectrum is calculated as: + For a spatial domain :math:`V`, energy group :math:`[E_g,E_{g-1}]`, and + delayed group :math:`d`, the delayed fission spectrum is calculated as: .. math:: - \langle \nu\sigma_{f,\rightarrow g} \phi \rangle &= \int_{r \in V} dr - \int_{4\pi} d\Omega' \int_0^\infty dE' \int_{E_g}^{E_{g-1}} dE \; \chi(E) - \nu\sigma_f (r, E') \psi(r, E', \Omega')\\ - \langle \nu\sigma_f \phi \rangle &= \int_{r \in V} dr \int_{4\pi} - d\Omega' \int_0^\infty dE' \int_0^\infty dE \; \chi(E) \nu\sigma_f (r, + \langle \nu^d \sigma_{f,g' \rightarrow g} \phi \rangle &= \int_{r \in V} + dr \int_{4\pi} d\Omega' \int_0^\infty dE' \int_{E_g}^{E_{g-1}} dE \; + \chi(E) \nu^d \sigma_f (r, E') \psi(r, E', \Omega')\\ + \langle \nu^d \sigma_f \phi \rangle &= \int_{r \in V} dr \int_{4\pi} + d\Omega' \int_0^\infty dE' \int_0^\infty dE \; \chi(E) \nu^d \sigma_f (r, E') \psi(r, E', \Omega') \\ - \chi_g &= \frac{\langle \nu\sigma_{f,\rightarrow g} \phi \rangle}{\langle - \nu\sigma_f \phi \rangle} + \chi_g^d &= \frac{\langle \nu^d \sigma_{f,g' \rightarrow g} \phi \rangle} + {\langle \nu^d \sigma_f \phi \rangle} Parameters ---------- @@ -948,8 +953,8 @@ class ChiDelayed(MDGXS): # Slice nu-fission-out tally along energyout filter delayed_nu_fission_out = slice_xs.tallies['delayed-nu-fission-out'] - tally_slice = delayed_nu_fission_out.get_slice(filters=filters, - filter_bins=filter_bins) + tally_slice = delayed_nu_fission_out.get_slice\ + (filters=filters, filter_bins=filter_bins) slice_xs._tallies['delayed-nu-fission-out'] = tally_slice # Add energy filter back to nu-fission-in tallies @@ -967,32 +972,33 @@ class ChiDelayed(MDGXS): Parameters ---------- - other : openmc.mgxs.MGXS - MGXS to merge with this one + other : openmc.mdgxs.MDGXS + MDGXS to merge with this one Returns ------- - merged_mgxs : openmc.mgxs.MGXS - Merged MGXS + merged_mdgxs : openmc.mgxs.MDGXS + Merged MDGXS """ if not self.can_merge(other): raise ValueError('Unable to merge ChiDelayed') # Create deep copy of tally to return as merged tally - merged_mgxs = copy.deepcopy(self) - merged_mgxs._derived = True - merged_mgxs._rxn_rate_tally = None - merged_mgxs._xs_tally = None + merged_mdgxs = copy.deepcopy(self) + merged_mdgxs._derived = True + merged_mdgxs._rxn_rate_tally = None + merged_mdgxs._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 + merged_mdgxs.energy_groups = merged_groups # Merge delayed groups if self.delayed_groups != other.delayed_groups: - merged_delayed_groups = self.delayed_groups.merge(other.delayed_groups) + merged_delayed_groups = self.delayed_groups.merge\ + (other.delayed_groups) merged_mdgxs.delayed_groups = merged_delayed_groups # Merge nuclides @@ -1005,22 +1011,24 @@ class ChiDelayed(MDGXS): raise ValueError(msg) # Concatenate lists of nuclides for the merged MGXS - merged_mgxs.nuclides = self.nuclides + other.nuclides + merged_mdgxs.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 + merged_tally = self.tallies[tally_key].merge\ + (other.tallies[tally_key]) + merged_mdgxs.tallies[tally_key] = merged_tally - return merged_mgxs + return merged_mdgxs def get_xs(self, groups='all', subdomains='all', nuclides='all', xs_type='macro', order_groups='increasing', value='mean', delayed_groups='all', **kwargs): - """Returns an array of the fission spectrum. + """Returns an array of the delayed fission spectrum. This method constructs a 2D NumPy array for the requested multi-group - cross section data data for one or more energy groups and subdomains. + and multi-delayed group cross section data data for one or more energy + groups and subdomains. Parameters ---------- @@ -1037,7 +1045,7 @@ class ChiDelayed(MDGXS): cross section summed over all nuclides. Defaults to 'all'. xs_type: {'macro', 'micro'} This parameter is not relevant for chi but is included here to - mirror the parent MGXS.get_xs(...) class method + mirror the parent MDGXS.get_xs(...) class method order_groups: {'increasing', 'decreasing'} Return the cross section indexed according to increasing or decreasing energy groups (decreasing or increasing energies). @@ -1048,8 +1056,9 @@ class ChiDelayed(MDGXS): Returns ------- numpy.ndarray - A NumPy array of the multi-group cross section indexed in the order - each group, subdomain and nuclide is listed in the parameters. + A NumPy array of the multi-group and multi-delayed-group cross + section indexed in the order each group, subdomain and nuclide is + listed in the parameters. Raises ------ @@ -1062,12 +1071,20 @@ class ChiDelayed(MDGXS): cv.check_value('value', value, ['mean', 'std_dev', 'rel_err']) cv.check_value('xs_type', xs_type, ['macro', 'micro']) + # FIXME: Unable to get microscopic xs for mesh domain because the mesh + # cells do not know the nuclide densities in each mesh cell. + if self.domain_type == 'mesh' and xs_type == 'micro': + msg = 'Unable to get micro xs for mesh domain since the mesh ' \ + 'cells do not know the nuclide densities in each mesh cell.' + raise ValueError(msg) + filters = [] filter_bins = [] # Construct a collection of the domain filter bins if not isinstance(subdomains, basestring): - cv.check_iterable_type('subdomains', subdomains, Integral, max_depth=3) + cv.check_iterable_type('subdomains', subdomains, Integral, + max_depth=3) for subdomain in subdomains: filters.append(self.domain_type) filter_bins.append((subdomain,)) @@ -1077,13 +1094,14 @@ class ChiDelayed(MDGXS): cv.check_iterable_type('groups', groups, Integral) for group in groups: filters.append('energyout') - filter_bins.append((self.energy_groups.get_group_bounds(group),)) + filter_bins.append( + (self.energy_groups.get_group_bounds(group),)) # Construct list of delayed group tuples for all requested groups if not isinstance(delayed_groups, basestring): cv.check_iterable_type('delayed_groups', delayed_groups, Integral) for delayed_group in delayed_groups: - filters.append('delayedgroups') + filters.append('delayedgroup') filter_bins.append((delayed_group,)) # If chi delayed was computed for each nuclide in the domain @@ -1099,8 +1117,10 @@ class ChiDelayed(MDGXS): # Sum out all nuclides nuclides = self.get_all_nuclides() - delayed_nu_fission_in = delayed_nu_fission_in.summation(nuclides=nuclides) - delayed_nu_fission_out = delayed_nu_fission_out.summation(nuclides=nuclides) + delayed_nu_fission_in = delayed_nu_fission_in.summation\ + (nuclides=nuclides) + delayed_nu_fission_out = delayed_nu_fission_out.summation\ + (nuclides=nuclides) # Remove coarse energy filter to keep it out of tally arithmetic energy_filter = delayed_nu_fission_in.find_filter('energy') @@ -1160,7 +1180,7 @@ class ChiDelayed(MDGXS): class DelayedNuFissionXS(MDGXS): - """A fission delayed neutron production multi-group cross section. + r"""A fission delayed neutron production multi-group cross section. This class can be used for both OpenMC input generation and tally data post-processing to compute spatially-homogenized and energy-integrated @@ -1172,18 +1192,19 @@ class DelayedNuFissionXS(MDGXS): :attr:`DelayedNuFissionXS.tallies` property, which can then be appended to a :class:`openmc.Tallies` instance. - For post-processing, the :meth:`MGXS.load_from_statepoint` will pull in the + For post-processing, the :meth:`MDGXS.load_from_statepoint` will pull in the necessary data to compute multi-group cross sections from a :class:`openmc.StatePoint` instance. The derived multi-group cross section can then be obtained from the :attr:`DelayedNuFissionXS.xs_tally` property. - For a spatial domain :math:`V` and energy group :math:`[E_g,E_{g-1}]`, the - fission neutron production cross section is calculated as: + For a spatial domain :math:`V`, energy group :math:`[E_g,E_{g-1}]`, and + delayed group :math:`d`, the fission delayed neutron production cross + section is calculated as: .. math:: \frac{\int_{r \in V} dr \int_{4\pi} d\Omega \int_{E_g}^{E_{g-1}} dE \; - \nu\sigma_f (r, E) \psi (r, E, \Omega)}{\int_{r \in V} dr \int_{4\pi} + \nu^d \sigma_f (r, E) \psi (r, E, \Omega)}{\int_{r \in V} dr \int_{4\pi} d\Omega \int_{E_g}^{E_{g-1}} dE \; \psi (r, E, \Omega)}. @@ -1233,8 +1254,8 @@ class DelayedNuFissionXS(MDGXS): The tally estimator used to compute the multi-group cross section tallies : collections.OrderedDict OpenMC tallies needed to compute the multi-group cross section. The keys - are strings listed in the :attr:`NuFissionXS.tally_keys` property and - values are instances of :class:`openmc.Tally`. + are strings listed in the :attr:`DelayedNuFissionXS.tally_keys` property + and values are instances of :class:`openmc.Tally`. rxn_rate_tally : openmc.Tally Derived tally for the reaction rate tally used in the numerator to compute the multi-group cross section. This attribute is None @@ -1276,35 +1297,35 @@ class DelayedNuFissionXS(MDGXS): class Beta(MDGXS): - """The delayed neutron fraction. + r"""The delayed neutron fraction. This class can be used for both OpenMC input generation and tally data post-processing to compute spatially-homogenized and energy-integrated - multi-group cross sections for multi-group neutronics calculations. At a - minimum, one needs to set the :attr:`ChiDelayed.energy_groups` and - :attr:`ChiDelayed.domain` properties. Tallies for the flux and appropriate - reaction rates over the specified domain are generated automatically via the - :attr:`ChiDelayed.tallies` property, which can then be appended to a - :class:`openmc.Tallies` instance. + multi-group and multi-delayed group cross sections for multi-group + neutronics calculations. At a minimum, one needs to set the + :attr:`Beta.energy_groups` and :attr:`Beta.domain` properties. Tallies for + the flux and appropriate reaction rates over the specified domain are + generated automatically via the :attr:`Beta.tallies` property, which can + then be appended to a :class:`openmc.Tallies` instance. - For post-processing, the :meth:`MGXS.load_from_statepoint` will pull in the + For post-processing, the :meth:`MDGXS.load_from_statepoint` will pull in the necessary data to compute multi-group cross sections from a :class:`openmc.StatePoint` instance. The derived multi-group cross section - can then be obtained from the :attr:`ChiDelayed.xs_tally` property. + can then be obtained from the :attr:`Beta.xs_tally` property. - For a spatial domain :math:`V` and energy group :math:`[E_g,E_{g-1}]`, the - fission spectrum is calculated as: + For a spatial domain :math:`V`, energy group :math:`[E_g,E_{g-1}]`, and + delayed group :math:`d`, the delayed neutron fraction is calculated as: .. math:: - \langle \nu\sigma_{f,\rightarrow g} \phi \rangle &= \int_{r \in V} dr - \int_{4\pi} d\Omega' \int_0^\infty dE' \int_{E_g}^{E_{g-1}} dE \; \chi(E) - \nu\sigma_f (r, E') \psi(r, E', \Omega')\\ - \langle \nu\sigma_f \phi \rangle &= \int_{r \in V} dr \int_{4\pi} - d\Omega' \int_0^\infty dE' \int_0^\infty dE \; \chi(E) \nu\sigma_f (r, - E') \psi(r, E', \Omega') \\ - \chi_g &= \frac{\langle \nu\sigma_{f,\rightarrow g} \phi \rangle}{\langle - \nu\sigma_f \phi \rangle} + \langle \nu^d \sigma_f \phi \rangle &= \int_{r \in V} dr \int_{4\pi} + d\Omega' \int_0^\infty dE' \int_0^\infty dE \; \chi(E) \nu^d + \sigma_f (r, E') \psi(r, E', \Omega') \\ + \langle \nu \sigma_f \phi \rangle &= \int_{r \in V} dr \int_{4\pi} + d\Omega' \int_0^\infty dE' \int_0^\infty dE \; \chi(E) \nu + \sigma_f (r, E') \psi(r, E', \Omega') \\ + \beta_{d,g} &= \frac{\langle \nu^d \sigma_f \phi \rangle} + {\langle \nu \sigma_f \phi \rangle} Parameters ---------- @@ -1352,7 +1373,7 @@ class Beta(MDGXS): The tally estimator used to compute the multi-group cross section tallies : collections.OrderedDict OpenMC tallies needed to compute the multi-group cross section. The keys - are strings listed in the :attr:`ChiDelayed.tally_keys` property and + are strings listed in the :attr:`Beta.tally_keys` property and values are instances of :class:`openmc.Tally`. rxn_rate_tally : openmc.Tally Derived tally for the reaction rate tally used in the numerator to @@ -1394,23 +1415,11 @@ class Beta(MDGXS): @property def scores(self): - return ['delayed-nu-fission', 'nu-fission'] - - @property - def filters(self): - # Create the non-domain specific Filters for the Tallies - group_edges = self.energy_groups.group_edges - energy = openmc.Filter('energy', [group_edges[0], group_edges[-1]]) - if self.delayed_groups != None: - delayed_groups = self.delayed_groups.groups - delayed_filter = openmc.Filter('delayedgroup', delayed_groups) - return [[delayed_filter, energy], [energy]] - else: - return [[energy], [energy]] + return ['nu-fission', 'delayed-nu-fission'] @property def tally_keys(self): - return ['delayed-nu-fission', 'nu-fission'] + return ['nu-fission', 'delayed-nu-fission'] @property def rxn_rate_tally(self): @@ -1425,7 +1434,7 @@ class Beta(MDGXS): if self._xs_tally is None: nu_fission = self.tallies['nu-fission'] - # Compute chi + # Compute beta self._xs_tally = self.rxn_rate_tally / nu_fission super(Beta, self)._compute_xs() diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 59bd82b07..7997b0265 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -14,7 +14,6 @@ import numpy as np import openmc import openmc.checkvalue as cv from openmc.mgxs import EnergyGroups -from openmc import Mesh if sys.version_info[0] >= 3: basestring = str @@ -694,7 +693,7 @@ class MGXS(object): # NOTE: This is important if tally merging was used if self.domain_type == 'mesh': filters = [self.domain_type] - xyz = map(lambda x: np.arange(1, x+1), self.domain.dimension) + xyz = [range(1, x+1) for x in self.domain.dimension] filter_bins = [tuple(itertools.product(*xyz))] elif self.domain_type != 'distribcell': filters = [self.domain_type] @@ -717,8 +716,6 @@ class MGXS(object): sp_tally = statepoint.get_tally( tally.scores, tally.filters, tally.nuclides, estimator=tally.estimator, exact_filters=True) - print(filters) - print(filter_bins) sp_tally = sp_tally.get_slice( tally.scores, filters, filter_bins, tally.nuclides) sp_tally.sparse = self.sparse @@ -1159,7 +1156,7 @@ class MGXS(object): elif self.domain_type == 'distribcell': subdomains = np.arange(self.num_subdomains, dtype=np.int) elif self.domain_type == 'mesh': - xyz = map(lambda x: np.arange(1, x+1), self.domain.dimension) + xyz = [range(1, x+1) for x in self.domain.dimension] subdomains = list(itertools.product(*xyz)) else: subdomains = [self.domain.id] @@ -1194,7 +1191,7 @@ class MGXS(object): # Loop over all subdomains for subdomain in subdomains: - if self.domain_type == 'distribcell': + if self.domain_type == 'distribcell' or self.domain_type == 'mesh': string += '{0: <16}=\t{1}\n'.format('\tSubdomain', subdomain) # Loop over all Nuclides @@ -1297,7 +1294,7 @@ class MGXS(object): domain_filter = self.xs_tally.find_filter('avg(distribcell)') subdomains = domain_filter.bins elif self.domain_type == 'mesh': - xyz = map(lambda x: np.arange(1, x+1), self.domain.dimension) + xyz = [range(1, x+1) for x in self.domain.dimension] subdomains = list(itertools.product(*xyz)) else: subdomains = [self.domain.id] @@ -1409,7 +1406,10 @@ class MGXS(object): if format == 'csv': df.to_csv(filename + '.csv', index=False) elif format == 'excel': - df.to_excel(filename + '.xls', index=False) + if self.domain_type == 'mesh': + df.to_excel(filename + '.xls') + else: + df.to_excel(filename + '.xls', index=False) elif format == 'pickle': df.to_pickle(filename + '.pkl') elif format == 'latex': @@ -1750,6 +1750,13 @@ class MatrixMGXS(MGXS): cv.check_value('value', value, ['mean', 'std_dev', 'rel_err']) cv.check_value('xs_type', xs_type, ['macro', 'micro']) + # FIXME: Unable to get microscopic xs for mesh domain because the mesh + # cells do not know the nuclide densities in each mesh cell. + if self.domain_type == 'mesh' and xs_type == 'micro': + msg = 'Unable to get micro xs for mesh domain since the mesh ' \ + 'cells do not know the nuclide densities in each mesh cell.' + raise ValueError(msg) + filters = [] filter_bins = [] @@ -1919,7 +1926,7 @@ class MatrixMGXS(MGXS): elif self.domain_type == 'distribcell': subdomains = np.arange(self.num_subdomains, dtype=np.int) elif self.domain_type == 'mesh': - xyz = map(lambda x: np.arange(1, x+1), self.domain.dimension) + xyz = [range(1, x+1) for x in self.domain.dimension] subdomains = list(itertools.product(*xyz)) else: subdomains = [self.domain.id] @@ -3568,6 +3575,13 @@ class ScatterMatrixXS(MatrixMGXS): cv.check_value('value', value, ['mean', 'std_dev', 'rel_err']) cv.check_value('xs_type', xs_type, ['macro', 'micro']) + # FIXME: Unable to get microscopic xs for mesh domain because the mesh + # cells do not know the nuclide densities in each mesh cell. + if self.domain_type == 'mesh' and xs_type == 'micro': + msg = 'Unable to get micro xs for mesh domain since the mesh ' \ + 'cells do not know the nuclide densities in each mesh cell.' + raise ValueError(msg) + filters = [] filter_bins = [] @@ -3718,9 +3732,12 @@ class ScatterMatrixXS(MatrixMGXS): df['moment'] = moments # Place the moment column before the mean column - mean_index = df.columns.get_loc('mean') columns = df.columns.tolist() - df = df[columns[:mean_index] + ['moment'] + columns[mean_index:-1]] + mean_index = [i for i, s in enumerate(columns) if 'mean' in s][0] + if self.domain_type == 'mesh': + df = df[columns[:mean_index] + [('moment', '')] + columns[mean_index:-1]] + else: + df = df[columns[:mean_index] + ['moment'] + columns[mean_index:-1]] # Select rows corresponding to requested scattering moment if moment != 'all': @@ -3761,7 +3778,7 @@ class ScatterMatrixXS(MatrixMGXS): elif self.domain_type == 'distribcell': subdomains = np.arange(self.num_subdomains, dtype=np.int) elif self.domain_type == 'mesh': - xyz = map(lambda x: np.arange(1, x+1), self.domain.dimension) + xyz = [range(1, x+1) for x in self.domain.dimension] subdomains = list(itertools.product(*xyz)) else: subdomains = [self.domain.id] @@ -4249,14 +4266,14 @@ class Chi(MGXS): .. math:: - \langle \nu\sigma_{f,\rightarrow g} \phi \rangle &= \int_{r \in V} dr + \langle \nu\sigma_{f,g' \rightarrow g} \phi \rangle &= \int_{r \in V} dr \int_{4\pi} d\Omega' \int_0^\infty dE' \int_{E_g}^{E_{g-1}} dE \; \chi(E) \nu\sigma_f (r, E') \psi(r, E', \Omega')\\ \langle \nu\sigma_f \phi \rangle &= \int_{r \in V} dr \int_{4\pi} d\Omega' \int_0^\infty dE' \int_0^\infty dE \; \chi(E) \nu\sigma_f (r, E') \psi(r, E', \Omega') \\ - \chi_g &= \frac{\langle \nu\sigma_{f,\rightarrow g} \phi \rangle}{\langle - \nu\sigma_f \phi \rangle} + \chi_g &= \frac{\langle \nu\sigma_{f,g' \rightarrow g} \phi \rangle} + {\langle \nu\sigma_f \phi \rangle} Parameters ---------- @@ -4539,6 +4556,13 @@ class Chi(MGXS): cv.check_value('value', value, ['mean', 'std_dev', 'rel_err']) cv.check_value('xs_type', xs_type, ['macro', 'micro']) + # FIXME: Unable to get microscopic xs for mesh domain because the mesh + # cells do not know the nuclide densities in each mesh cell. + if self.domain_type == 'mesh' and xs_type == 'micro': + msg = 'Unable to get micro xs for mesh domain since the mesh ' \ + 'cells do not know the nuclide densities in each mesh cell.' + raise ValueError(msg) + filters = [] filter_bins = [] @@ -4732,14 +4756,14 @@ class ChiPrompt(Chi): .. math:: - \langle \nu\sigma_{f,\rightarrow g}^p \phi \rangle &= \int_{r \in V} dr - \int_{4\pi} d\Omega' \int_0^\infty dE' \int_{E_g}^{E_{g-1}} dE \; \chi(E) - \nu\sigma_f^p (r, E') \psi(r, E', \Omega')\\ - \langle \nu\sigma_f^p \phi \rangle &= \int_{r \in V} dr \int_{4\pi} - d\Omega' \int_0^\infty dE' \int_0^\infty dE \; \chi(E) \nu\sigma_f^p (r, + \langle \nu^p \sigma_{f,g' \rightarrow g} \phi \rangle &= \int_{r \in V} + dr \int_{4\pi} d\Omega' \int_0^\infty dE' \int_{E_g}^{E_{g-1}} dE \; + \chi(E)^p \nu^p \sigma_f (r, E') \psi(r, E', \Omega')\\ + \langle \nu^p \sigma_f \phi \rangle &= \int_{r \in V} dr \int_{4\pi} + d\Omega' \int_0^\infty dE' \int_0^\infty dE \; \chi(E) \nu^p \sigma_f (r, E') \psi(r, E', \Omega') \\ - \chi_g^p &= \frac{\langle \nu\sigma_{f,\rightarrow g}^p \phi \rangle}{\langle - \nu\sigma_f^p \phi \rangle} + \chi_g^p &= \frac{\langle \nu^p \sigma_{f,g' \rightarrow g} \phi \rangle} + {\langle \nu^p \sigma_f \phi \rangle} Parameters ---------- @@ -4958,17 +4982,6 @@ class InverseVelocity(MGXS): """ - # Construct a collection of the subdomains to report - if not isinstance(subdomains, basestring): - cv.check_iterable_type('subdomains', subdomains, Integral) - elif self.domain_type == 'distribcell': - subdomains = np.arange(self.num_subdomains, dtype=np.int) - elif self.domain_type == 'mesh': - xyz = map(lambda x: np.arange(1, x+1), self.domain.dimension) - subdomains = list(itertools.product(*xyz)) - else: - subdomains = [self.domain.id] - if xs_type == 'macro': return 'second/cm' else: diff --git a/openmc/tallies.py b/openmc/tallies.py index 79e7c56bc..c68b0faac 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -1293,7 +1293,7 @@ class Tally(object): # Create list of 2- or 3-tuples tuples for mesh cell bins if self_filter.type == 'mesh': dimension = self_filter.mesh.dimension - xyz = map(lambda x: np.arange(1, x+1), dimension) + xyz = [range(1, x+1) for x in dimension] bins = list(itertools.product(*xyz)) # Create list of 2-tuples for energy boundary bins diff --git a/tests/test_mgxs_library_condense/inputs_true.dat b/tests/test_mgxs_library_condense/inputs_true.dat index 181c5c59c..0c648376e 100644 --- a/tests/test_mgxs_library_condense/inputs_true.dat +++ b/tests/test_mgxs_library_condense/inputs_true.dat @@ -1 +1 @@ -e2cdca7ea5b3532050af5b12fac26d7ef212d2696bb1b73cdd00929b2243c40d100ad02438c7b090555b49815d0de6c48cf1b4ebf437a48bc80c2d2b4bad292e +e2cdca7ea5b3532050af5b12fac26d7ef212d2696bb1b73cdd00929b2243c40d100ad02438c7b090555b49815d0de6c48cf1b4ebf437a48bc80c2d2b4bad292e \ No newline at end of file diff --git a/tests/test_mgxs_library_distribcell/inputs_true.dat b/tests/test_mgxs_library_distribcell/inputs_true.dat index 4ad63a947..055ce35a5 100644 --- a/tests/test_mgxs_library_distribcell/inputs_true.dat +++ b/tests/test_mgxs_library_distribcell/inputs_true.dat @@ -1 +1 @@ -2d948f3b12293294eaeca231a3df9d51195379e8bb38dd3e68d3bc512a7d08ed52a1109054ca381684ec127268710f6d6e9210ac8154c9b379608e996627624a +2d948f3b12293294eaeca231a3df9d51195379e8bb38dd3e68d3bc512a7d08ed52a1109054ca381684ec127268710f6d6e9210ac8154c9b379608e996627624a \ No newline at end of file diff --git a/tests/test_mgxs_library_hdf5/inputs_true.dat b/tests/test_mgxs_library_hdf5/inputs_true.dat index 181c5c59c..0c648376e 100644 --- a/tests/test_mgxs_library_hdf5/inputs_true.dat +++ b/tests/test_mgxs_library_hdf5/inputs_true.dat @@ -1 +1 @@ -e2cdca7ea5b3532050af5b12fac26d7ef212d2696bb1b73cdd00929b2243c40d100ad02438c7b090555b49815d0de6c48cf1b4ebf437a48bc80c2d2b4bad292e +e2cdca7ea5b3532050af5b12fac26d7ef212d2696bb1b73cdd00929b2243c40d100ad02438c7b090555b49815d0de6c48cf1b4ebf437a48bc80c2d2b4bad292e \ No newline at end of file diff --git a/tests/test_mgxs_library_mesh/inputs_true.dat b/tests/test_mgxs_library_mesh/inputs_true.dat new file mode 100644 index 000000000..e036b49a2 --- /dev/null +++ b/tests/test_mgxs_library_mesh/inputs_true.dat @@ -0,0 +1 @@ +a4cd030bea212e45fdb159e75a7fb3d1947e9bf3d0384ac5d37a72298d67dcfdd1b9eb5c6af8ac6e5983bd5b47de9c17a2ea472b467b7222a4909ee070bf1ca3 \ No newline at end of file diff --git a/tests/test_mgxs_library_mesh/results_true.dat b/tests/test_mgxs_library_mesh/results_true.dat new file mode 100644 index 000000000..e3d7ca647 --- /dev/null +++ b/tests/test_mgxs_library_mesh/results_true.dat @@ -0,0 +1,132 @@ + mesh 1 group in nuclide mean std. dev. + x y z +0 1 1 1 1 total 0.640786 0.044177 +1 1 2 1 1 total 0.660597 0.128423 +2 2 1 1 1 total 0.615276 0.104046 +3 2 2 1 1 total 0.646999 0.186709 + mesh 1 group in nuclide mean std. dev. + x y z +0 1 1 1 1 total 0.36665 0.048814 +1 1 2 1 1 total 0.40784 0.096486 +2 2 1 1 1 total 0.36356 0.074111 +3 2 2 1 1 total 0.41456 0.160443 + mesh 1 group in nuclide mean std. dev. + x y z +0 1 1 1 1 total 0.366650 0.048814 +1 1 2 1 1 total 0.407840 0.096486 +2 2 1 1 1 total 0.363560 0.074111 +3 2 2 1 1 total 0.414593 0.160436 + mesh 1 group in nuclide mean std. dev. + x y z +0 1 1 1 1 total 0.025749 0.002863 +1 1 2 1 1 total 0.028400 0.005275 +2 2 1 1 1 total 0.022988 0.004099 +3 2 2 1 1 total 0.027589 0.010350 + mesh 1 group in nuclide mean std. dev. + x y z +0 1 1 1 1 total 0.015861 0.002876 +1 1 2 1 1 total 0.017280 0.004371 +2 2 1 1 1 total 0.014403 0.003542 +3 2 2 1 1 total 0.018061 0.010110 + mesh 1 group in nuclide mean std. dev. + x y z +0 1 1 1 1 total 0.009888 0.001077 +1 1 2 1 1 total 0.011121 0.002456 +2 2 1 1 1 total 0.008585 0.001552 +3 2 2 1 1 total 0.009527 0.003659 + mesh 1 group in nuclide mean std. dev. + x y z +0 1 1 1 1 total 0.026065 0.002907 +1 1 2 1 1 total 0.029084 0.006430 +2 2 1 1 1 total 0.022596 0.004062 +3 2 2 1 1 total 0.025066 0.009687 + mesh 1 group in nuclide mean std. dev. + x y z +0 1 1 1 1 total 1.938476 0.211550 +1 1 2 1 1 total 2.177360 0.480780 +2 2 1 1 1 total 1.682799 0.303764 +3 2 2 1 1 total 1.864890 0.715661 + mesh 1 group in nuclide mean std. dev. + x y z +0 1 1 1 1 total 0.615037 0.041754 +1 1 2 1 1 total 0.632196 0.123878 +2 2 1 1 1 total 0.592288 0.100439 +3 2 2 1 1 total 0.619410 0.177190 + mesh 1 group in nuclide mean std. dev. + x y z +0 1 1 1 1 total 0.584014 0.054315 +1 1 2 1 1 total 0.622514 0.111323 +2 2 1 1 1 total 0.587256 0.084833 +3 2 2 1 1 total 0.613792 0.168612 + mesh 1 group in group out nuclide moment mean std. dev. + x y z +0 1 1 1 1 1 total P0 0.584014 0.054315 +1 1 1 1 1 1 total P1 0.243427 0.025488 +2 1 1 1 1 1 total P2 0.089236 0.007357 +3 1 1 1 1 1 total P3 0.008994 0.005768 +4 1 2 1 1 1 total P0 0.622514 0.111323 +5 1 2 1 1 1 total P1 0.239376 0.042594 +6 1 2 1 1 1 total P2 0.088386 0.017200 +7 1 2 1 1 1 total P3 -0.001243 0.005639 +8 2 1 1 1 1 total P0 0.587256 0.084833 +9 2 1 1 1 1 total P1 0.245120 0.041033 +10 2 1 1 1 1 total P2 0.086784 0.016255 +11 2 1 1 1 1 total P3 0.008660 0.004755 +12 2 2 1 1 1 total P0 0.612950 0.167940 +13 2 2 1 1 1 total P1 0.226176 0.061882 +14 2 2 1 1 1 total P2 0.086593 0.026126 +15 2 2 1 1 1 total P3 0.009672 0.011995 + mesh 1 group in group out nuclide moment mean std. dev. + x y z +0 1 1 1 1 1 total P0 0.584014 0.054315 +1 1 1 1 1 1 total P1 0.243427 0.025488 +2 1 1 1 1 1 total P2 0.089236 0.007357 +3 1 1 1 1 1 total P3 0.008994 0.005768 +4 1 2 1 1 1 total P0 0.622514 0.111323 +5 1 2 1 1 1 total P1 0.239376 0.042594 +6 1 2 1 1 1 total P2 0.088386 0.017200 +7 1 2 1 1 1 total P3 -0.001243 0.005639 +8 2 1 1 1 1 total P0 0.587256 0.084833 +9 2 1 1 1 1 total P1 0.245120 0.041033 +10 2 1 1 1 1 total P2 0.086784 0.016255 +11 2 1 1 1 1 total P3 0.008660 0.004755 +12 2 2 1 1 1 total P0 0.613792 0.168612 +13 2 2 1 1 1 total P1 0.226142 0.061856 +14 2 2 1 1 1 total P2 0.086174 0.025979 +15 2 2 1 1 1 total P3 0.009721 0.012027 + mesh 1 group in group out nuclide mean std. dev. + x y z +0 1 1 1 1 1 total 1.000000 0.088094 +1 1 2 1 1 1 total 1.000000 0.160891 +2 2 1 1 1 1 total 1.000000 0.126864 +3 2 2 1 1 1 total 1.001374 0.305883 + mesh 1 group in group out nuclide mean std. dev. + x y z +0 1 1 1 1 1 total 0.027395 0.004680 +1 1 2 1 1 1 total 0.022914 0.006025 +2 2 1 1 1 1 total 0.019384 0.002846 +3 2 2 1 1 1 total 0.029629 0.006292 + mesh 1 group out nuclide mean std. dev. + x y z +0 1 1 1 1 total 1.0 0.220956 +1 1 2 1 1 total 1.0 0.316565 +2 2 1 1 1 total 1.0 0.132140 +3 2 2 1 1 total 1.0 0.181577 + mesh 1 group out nuclide mean std. dev. + x y z +0 1 1 1 1 total 1.0 0.222246 +1 1 2 1 1 total 1.0 0.316565 +2 2 1 1 1 total 1.0 0.132140 +3 2 2 1 1 total 1.0 0.181577 + mesh 1 group in nuclide mean std. dev. + x y z +0 1 1 1 1 total 3.610522e-07 3.169931e-08 +1 1 2 1 1 total 3.942353e-07 8.459167e-08 +2 2 1 1 1 total 3.097784e-07 5.252025e-08 +3 2 2 1 1 total 3.799163e-07 1.806470e-07 + mesh 1 group in nuclide mean std. dev. + x y z +0 1 1 1 1 total 0.025735 0.002840 +1 1 2 1 1 total 0.028773 0.006349 +2 2 1 1 1 total 0.022306 0.004010 +3 2 2 1 1 total 0.024549 0.009379 diff --git a/tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py b/tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py new file mode 100644 index 000000000..df7a0a5ae --- /dev/null +++ b/tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python + +import os +import sys +import glob +import hashlib +sys.path.insert(0, os.pardir) +from testing_harness import PyAPITestHarness +import openmc +import openmc.mgxs + + +class MGXSTestHarness(PyAPITestHarness): + def _build_inputs(self): + # Generate inputs using parent class routine + super(MGXSTestHarness, self)._build_inputs() + + # Initialize a one-group structure + energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 20.]) + + # Initialize MGXS Library for a few cross section types + # for one material-filled cell in the geometry + self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) + self.mgxs_lib.by_nuclide = False + + # Test all MGXS types + self.mgxs_lib.mgxs_types = openmc.mgxs.MGXS_TYPES + self.mgxs_lib.energy_groups = energy_groups + self.mgxs_lib.legendre_order = 3 + self.mgxs_lib.domain_type = 'mesh' + + # Instantiate a tally mesh + mesh = openmc.Mesh(mesh_id=1) + mesh.type = 'regular' + mesh.dimension = [2, 2] + mesh.lower_left = [-100., -100.] + mesh.width = [100., 100.] + + self.mgxs_lib.domains = [mesh] + self.mgxs_lib.build_library() + + # Initialize a tallies file + self._input_set.tallies = openmc.Tallies() + self.mgxs_lib.add_to_tallies_file(self._input_set.tallies, merge=False) + self._input_set.tallies.export_to_xml() + + def _get_results(self, hash_output=False): + """Digest info in the statepoint and return as a string.""" + + # Read the statepoint file. + statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] + sp = openmc.StatePoint(statepoint) + + # Load the MGXS library from the statepoint + self.mgxs_lib.load_from_statepoint(sp) + + # Build a string from Pandas Dataframe for each 1-group MGXS + outstr = '' + for domain in self.mgxs_lib.domains: + for mgxs_type in self.mgxs_lib.mgxs_types: + mgxs = self.mgxs_lib.get_mgxs(domain, mgxs_type) + df = mgxs.get_pandas_dataframe() + outstr += df.to_string() + '\n' + + # Hash the results if necessary + if hash_output: + sha512 = hashlib.sha512() + sha512.update(outstr.encode('utf-8')) + outstr = sha512.hexdigest() + + return outstr + + def _cleanup(self): + super(MGXSTestHarness, self)._cleanup() + f = os.path.join(os.getcwd(), 'tallies.xml') + if os.path.exists(f): os.remove(f) + + +if __name__ == '__main__': + harness = MGXSTestHarness('statepoint.10.*', True) + harness.main() diff --git a/tests/test_mgxs_library_no_nuclides/inputs_true.dat b/tests/test_mgxs_library_no_nuclides/inputs_true.dat index 181c5c59c..0c648376e 100644 --- a/tests/test_mgxs_library_no_nuclides/inputs_true.dat +++ b/tests/test_mgxs_library_no_nuclides/inputs_true.dat @@ -1 +1 @@ -e2cdca7ea5b3532050af5b12fac26d7ef212d2696bb1b73cdd00929b2243c40d100ad02438c7b090555b49815d0de6c48cf1b4ebf437a48bc80c2d2b4bad292e +e2cdca7ea5b3532050af5b12fac26d7ef212d2696bb1b73cdd00929b2243c40d100ad02438c7b090555b49815d0de6c48cf1b4ebf437a48bc80c2d2b4bad292e \ No newline at end of file diff --git a/tests/test_mgxs_library_nuclides/inputs_true.dat b/tests/test_mgxs_library_nuclides/inputs_true.dat index 0bf12fbb2..a15bbee4c 100644 --- a/tests/test_mgxs_library_nuclides/inputs_true.dat +++ b/tests/test_mgxs_library_nuclides/inputs_true.dat @@ -1 +1 @@ -e4a5f03ab6167e96462c4ef537533fe33b98d7878ae00824c5619356bda8d548b3c71af01ba8c88d5a9b46dd1471d331e6f678a164af922200f2ee3642be6340 +e4a5f03ab6167e96462c4ef537533fe33b98d7878ae00824c5619356bda8d548b3c71af01ba8c88d5a9b46dd1471d331e6f678a164af922200f2ee3642be6340 \ No newline at end of file diff --git a/tests/test_mgxs_library_nuclides/results_true.dat b/tests/test_mgxs_library_nuclides/results_true.dat index e89776fe8..3da814604 100644 --- a/tests/test_mgxs_library_nuclides/results_true.dat +++ b/tests/test_mgxs_library_nuclides/results_true.dat @@ -1 +1 @@ -e494320a213b5704a2ac915a2ba504857be91961ceb6735b6ad05d81eb31c44c9584d5bd9d40baececf1dcb5b030e6ecec63cfbd20639baf69bcb596c5c46591 +e494320a213b5704a2ac915a2ba504857be91961ceb6735b6ad05d81eb31c44c9584d5bd9d40baececf1dcb5b030e6ecec63cfbd20639baf69bcb596c5c46591 \ No newline at end of file diff --git a/tests/test_tallies/inputs_true.dat b/tests/test_tallies/inputs_true.dat index f961821aa..17f04238c 100644 --- a/tests/test_tallies/inputs_true.dat +++ b/tests/test_tallies/inputs_true.dat @@ -1 +1 @@ -ca47172a42f6c13b244a763c990cbe4811662708ee03307d810a4542ee34bb5db7cc29d66aea313dad95b9f38a4ff7943ded527cfd0c7c8825372fec40cfc0d0 +ca47172a42f6c13b244a763c990cbe4811662708ee03307d810a4542ee34bb5db7cc29d66aea313dad95b9f38a4ff7943ded527cfd0c7c8825372fec40cfc0d0 \ No newline at end of file