From b74c0cc18f26255cfd16c40e95cc1d1c19c7f5b8 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Tue, 20 Oct 2020 16:50:35 -0500 Subject: [PATCH] Storing state --- openmc/mgxs/mgxs.py | 135 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 2 deletions(-) diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 0fc6716f35..bbcfef576e 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -8,6 +8,7 @@ import h5py import numpy as np import openmc +from openmc.data import REACTION_MT import openmc.checkvalue as cv from ..tallies import ESTIMATOR_TYPES from . import EnergyGroups @@ -698,7 +699,7 @@ class MGXS: Parameters ---------- - mgxs_type : {'total', 'transport', 'nu-transport', 'absorption', 'capture', 'fission', 'nu-fission', 'kappa-fission', 'scatter', 'nu-scatter', 'scatter matrix', 'nu-scatter matrix', 'multiplicity matrix', 'nu-fission matrix', 'chi', 'chi-prompt', 'inverse-velocity', 'prompt-nu-fission', 'prompt-nu-fission matrix', 'current', 'diffusion-coefficient', 'nu-diffusion-coefficient'} + mgxs_type : {'total', 'transport', 'nu-transport', 'absorption', 'capture', 'fission', 'nu-fission', 'kappa-fission', 'scatter', 'nu-scatter', 'scatter matrix', 'nu-scatter matrix', 'multiplicity matrix', 'nu-fission matrix', 'chi', 'chi-prompt', 'inverse-velocity', 'prompt-nu-fission', 'prompt-nu-fission matrix', 'current', 'diffusion-coefficient', 'nu-diffusion-coefficient', mt} The type of multi-group cross section object to return domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh The domain for spatial homogenization @@ -782,7 +783,18 @@ class MGXS: mgxs = DiffusionCoefficient(domain, domain_type, energy_groups) elif mgxs_type == 'nu-diffusion-coefficient': mgxs = DiffusionCoefficient(domain, domain_type, energy_groups, nu=True) - + else: + if mgxs_type in REACTION_MT.keys() + REACTION_MT.values(): + # Then it is a reaction not covered by the above that is + # supported by the ArbitraryMTXS Class + mgxs = ArbitraryMTXS(mgxs_type, domain, domain_type, + energy_groups) + else: + # This is an invalid type so let the user know. + msg = 'Unable to set "{0}" to "{1}"'.format("mgxs_type", + mgxs_type) + \ + " as it is not an accepted MGXS type." + raise ValueError(msg) mgxs.by_nuclide = by_nuclide mgxs.name = name mgxs.num_polar = num_polar @@ -3850,6 +3862,125 @@ class ScatterXS(MGXS): self._valid_estimators = ['analog'] + +class ArbitraryMTXS(MGXS): + r"""A multi-group cross section for an arbitrary reaction type. + + This class can be used for both OpenMC input generation and tally data + post-processing to compute spatially-homogenized and energy-integrated + multi-group total cross sections for multi-group neutronics calculations. At + a minimum, one needs to set the :attr:`TotalXS.energy_groups` and + :attr:`TotalXS.domain` properties. Tallies for the flux and appropriate + reaction rates over the specified domain are generated automatically via the + :attr:`TotalXS.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 + 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:`TotalXS.xs_tally` property. + + For a spatial domain :math:`V` and energy group :math:`[E_g,E_{g-1}]`, the + total cross section is calculated as: + + .. math:: + + \frac{\int_{r \in V} dr \int_{4\pi} d\Omega \int_{E_g}^{E_{g-1}} dE \; + \sigma_t (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)}. + + Parameters + ---------- + domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh + The domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'} + The domain type for spatial homogenization + groups : openmc.mgxs.EnergyGroups + The energy group structure for energy condensation + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + name : str, optional + Name of the multi-group cross section. Used as a label to identify + tallies in OpenMC 'tallies.xml' file. + num_polar : Integral, optional + Number of equi-width polar angle bins for angle discretization; + defaults to one bin + num_azimuthal : Integral, optional + Number of equi-width azimuthal angle bins for angle discretization; + defaults to one bin + + Attributes + ---------- + name : str, optional + Name of the multi-group cross section + rxn_type : str + Reaction type (e.g., 'total', 'nu-fission', etc.) + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh + Domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'} + Domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + Energy group structure for energy condensation + num_polar : Integral + Number of equi-width polar angle bins for angle discretization + num_azimuthal : Integral + Number of equi-width azimuthal angle bins for angle discretization + tally_trigger : openmc.Trigger + An (optional) tally precision trigger given to each tally used to + compute the cross section + scores : list of str + The scores in each tally used to compute the multi-group cross section + filters : list of openmc.Filter + The filters in each tally used to compute the multi-group cross section + tally_keys : list of str + The keys into the tallies dictionary for each tally used to compute + the multi-group cross section + estimator : {'tracklength', 'collision', 'analog'} + 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:`TotalXS.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 + unless the multi-group cross section has been computed. + xs_tally : openmc.Tally + Derived tally for the multi-group cross section. This attribute + is None unless the multi-group cross section has been computed. + num_subdomains : int + The number of subdomains is unity for 'material', 'cell' and 'universe' + domain types. This is equal to the number of cell instances + for 'distribcell' domain types (it is equal to unity prior to loading + tally data from a statepoint file). + num_nuclides : int + The number of nuclides for which the multi-group cross section is + being tracked. This is unity if the by_nuclide attribute is False. + nuclides : Iterable of str or 'sum' + The optional user-specified nuclides for which to compute cross + sections (e.g., 'U238', 'O16'). If by_nuclide is True but nuclides + are not specified by the user, all nuclides in the spatial domain + are included. This attribute is 'sum' if by_nuclide is false. + sparse : bool + Whether or not the MGXS' tallies use SciPy's LIL sparse matrix format + for compressed data storage + loaded_sp : bool + Whether or not a statepoint file has been loaded with tally data + derived : bool + Whether or not the MGXS is merged from one or more other MGXS + hdf5_key : str + The key used to index multi-group cross sections in an HDF5 data store + + """ + + def __init__(self, rxn_type, domain=None, domain_type=None, groups=None, + by_nuclide=False, name='', num_polar=1, num_azimuthal=1): + super().__init__(domain, domain_type, groups, by_nuclide, name, + num_polar, num_azimuthal) + self._rxn_type = rxn_type + class ScatterMatrixXS(MatrixMGXS): r"""A scattering matrix multi-group cross section with the cosine of the change-in-angle represented as one or more Legendre moments or a histogram.