diff --git a/docs/source/io_formats/statepoint.rst b/docs/source/io_formats/statepoint.rst index 98cc9e4b5..f0f2af59b 100644 --- a/docs/source/io_formats/statepoint.rst +++ b/docs/source/io_formats/statepoint.rst @@ -4,7 +4,7 @@ State Point File Format ======================= -The current version of the statepoint file format is 16.0. +The current version of the statepoint file format is 17.0. **/** @@ -92,6 +92,26 @@ The current version of the statepoint file format is 16.0. - **width** (*double[]*) -- Width of each mesh cell in each dimension. +**/tallies/filters/** + +:Attributes: - **n_filters** (*int*) -- Number of filters in the problem. + - **ids** (*int[]*) -- User-defined unique ID of each filter. + +**/tallies/filters/filter /** + +:Datasets: - **type** (*char[]*) -- Type of the j-th filter. Can be 'universe', + 'material', 'cell', 'cellborn', 'surface', 'mesh', 'energy', + 'energyout', 'distribcell', 'mu', 'polar', 'azimuthal', + 'delayedgroup', or 'energyfunction'. + - **n_bins** (*int*) -- Number of bins for the j-th filter. Not + present for 'energyfunction' filters. + - **bins** (*int[]* or *double[]*) -- Value for each filter bin of + this type. Not present for 'energyfunction' filters. + - **energy** (*double[]*) -- Energy grid points for energyfunction + interpolation. Only used for 'energyfunction' filters. + - **y** (*double[]*) -- Interpolant values for energyfunction + interpolation. Only used for 'energyfunction' filters. + **/tallies/derivatives/derivative /** :Datasets: - **independent variable** (*char[]*) -- Independent variable of @@ -105,6 +125,8 @@ The current version of the statepoint file format is 16.0. :Datasets: - **n_realizations** (*int*) -- Number of realizations. - **n_filters** (*int*) -- Number of filters used. + - **filters** (*int[]*) -- User-defined unique IDs of the filters on + the tally - **nuclides** (*char[][]*) -- Array of nuclides to tally. Note that if no nuclide is specified in the user input, a single 'total' nuclide appears here. @@ -126,21 +148,6 @@ The current version of the statepoint file format is 16.0. scoring bins, and the third dimension has two entries for the sum and the sum-of-squares. -**/tallies/tally /filter /** - -:Datasets: - **type** (*char[]*) -- Type of the j-th filter. Can be 'universe', - 'material', 'cell', 'cellborn', 'surface', 'mesh', 'energy', - 'energyout', 'distribcell', 'mu', 'polar', 'azimuthal', - 'delayedgroup', or 'energyfunction'. - - **n_bins** (*int*) -- Number of bins for the j-th filter. Not - present for 'energyfunction' filters. - - **bins** (*int[]* or *double[]*) -- Value for each filter bin of - this type. Not present for 'energyfunction' filters. - - **energy** (*double[]*) -- Energy grid points for energyfunction - interpolation. Only used for 'energyfunction' filters. - - **y** (*double[]*) -- Interpolant values for energyfunction - interpolation. Only used for 'energyfunction' filters. - **/runtime/** All values are given in seconds and are measured on the master process. diff --git a/docs/source/io_formats/tallies.rst b/docs/source/io_formats/tallies.rst index 89468396e..9c0a2515e 100644 --- a/docs/source/io_formats/tallies.rst +++ b/docs/source/io_formats/tallies.rst @@ -18,8 +18,8 @@ filters can be used for a tally. The following types of filter are available: cell, universe, material, surface, birth region, pre-collision energy, post-collision energy, and an arbitrary structured mesh. -The three valid elements in the tallies.xml file are ````, ````, -and ````. +The five valid elements in the tallies.xml file are ````, ````, +````, ````, and ````. .. _tally: @@ -35,42 +35,8 @@ The ```` element accepts the following sub-elements: *Default*: "" - :filter: - Specify a filter that modifies tally behavior. Most tallies (e.g. ``cell``, - ``energy``, and ``material``) restrict the tally so that only particles - within certain regions of phase space contribute to the tally. Others - (e.g. ``delayedgroup`` and ``energyfunction``) can apply some other function - to the scored values. This element and its attributes/sub-elements are - described below. - - .. note:: - You may specify zero, one, or multiple filters to apply to the tally. To - specify multiple filters, you must use multiple ```` elements. - - The ``filter`` element has the following attributes/sub-elements: - - :type: - The type of the filter. Accepted options are "cell", "cellborn", - "material", "universe", "energy", "energyout", "mu", "polar", - "azimuthal", "mesh", "distribcell", "delayedgroup", and - "energyfunction". - - :bins: - A description of the bins for each type of filter can be found in - :ref:`filter_types`. - - :energy: - ``energyfunction`` filters multiply tally scores by an arbitrary - function. The function is described by a piecewise linear-linear set of - (energy, y) values. This entry specifies the energy values. The function - will be evaluated as zero outside of the bounds of this energy grid. - (Only used for ``energyfunction`` filters) - - :y: - ``energyfunction`` filters multiply tally scores by an arbitrary - function. The function is described by a piecewise linear-linear set of - (energy, y) values. This entry specifies the y values. (Only used - for ``energyfunction`` filters) + :filters: + A space-separated list of the IDs of ``filter`` elements. :nuclides: If specified, the scores listed will be for particular nuclides, not the @@ -144,6 +110,41 @@ The ```` element accepts the following sub-elements: *Default*: None + +-------------------- +```` Element +-------------------- + +Filters can be used to modify tally behavior. Most tallies (e.g. ``cell``, +``energy``, and ``material``) restrict the tally so that only particles +within certain regions of phase space contribute to the tally. Others +(e.g. ``delayedgroup`` and ``energyfunction``) can apply some other function +to the scored values. The ``filter`` element has the following +attributes/sub-elements: + + :type: + The type of the filter. Accepted options are "cell", "cellborn", + "material", "universe", "energy", "energyout", "mu", "polar", + "azimuthal", "mesh", "distribcell", "delayedgroup", and + "energyfunction". + + :bins: + A description of the bins for each type of filter can be found in + :ref:`filter_types`. + + :energy: + ``energyfunction`` filters multiply tally scores by an arbitrary + function. The function is described by a piecewise linear-linear set of + (energy, y) values. This entry specifies the energy values. The function + will be evaluated as zero outside of the bounds of this energy grid. + (Only used for ``energyfunction`` filters) + + :y: + ``energyfunction`` filters multiply tally scores by an arbitrary + function. The function is described by a piecewise linear-linear set of + (energy, y) values. This entry specifies the y values. (Only used + for ``energyfunction`` filters) + .. _filter_types: Filter Types diff --git a/openmc/filter.py b/openmc/filter.py index fc3e3253c..6af18a103 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -13,6 +13,9 @@ import openmc import openmc.checkvalue as cv +# "Static" variable for auto-generated Filter IDs +AUTO_FILTER_ID = 10000 + _FILTER_TYPES = ['universe', 'material', 'cell', 'cellborn', 'surface', 'mesh', 'energy', 'energyout', 'mu', 'polar', 'azimuthal', 'distribcell', 'delayedgroup', 'energyfunction'] @@ -25,6 +28,12 @@ _CURRENT_NAMES = {1: 'x-min out', 2: 'x-min in', 11: 'z-max out', 12: 'z-max in'} +def reset_auto_filter_id(): + """Reset counter for auto-generated filter IDs.""" + global AUTO_FILTER_ID + AUTO_FILTER_ID = 10000 + + class FilterMeta(ABCMeta): def __new__(cls, name, bases, namespace, **kwargs): # Check the class name. @@ -73,11 +82,15 @@ class Filter(object): The bins for the filter. This takes on different meaning for different filters. See the docstrings for sublcasses of this filter or the online documentation for more details. + filter_id : int + Unique identifier for the filter Attributes ---------- bins : Integral or Iterable of Integral or Iterable of Real The bins for the filter + id : int + Unique identifier for the filter num_bins : Integral The number of filter bins stride : Integral @@ -86,8 +99,9 @@ class Filter(object): """ - def __init__(self, bins): + def __init__(self, bins, filter_id=None): self.bins = bins + self.id = filter_id self._num_bins = 0 self._stride = None @@ -120,11 +134,14 @@ class Filter(object): return not self > other def __hash__(self): - return hash(repr(self)) + string = type(self).__name__ + '\n' + string += '{: <16}=\t{}\n'.format('\tBins', self.bins) + return hash(string) def __repr__(self): string = type(self).__name__ + '\n' string += '{: <16}=\t{}\n'.format('\tBins', self.bins) + string += '{: <16}=\t{}\n'.format('\tID', self.id) return string @classmethod @@ -155,10 +172,12 @@ class Filter(object): """ + filter_id = int(group.name.split('/')[-1].lstrip('filter ')) + # If the HDF5 'type' variable matches this class's short_name, then # there is no overriden from_hdf5 method. Pass the bins to __init__. if group['type'].value.decode() == cls.short_name.lower(): - out = cls(group['bins'].value) + out = cls(group['bins'].value, filter_id) out.num_bins = group['n_bins'].value return out @@ -175,6 +194,10 @@ class Filter(object): def bins(self): return self._bins + @property + def id(self): + return self._id + @property def num_bins(self): return self._num_bins @@ -193,6 +216,17 @@ class Filter(object): self._bins = bins + @id.setter + def id(self, filter_id): + if filter_id is None: + global AUTO_FILTER_ID + self._id = AUTO_FILTER_ID + AUTO_FILTER_ID += 1 + else: + cv.check_type('filter ID', filter_id, Integral) + cv.check_greater_than('filter ID', filter_id, 0, equality=True) + self._id = filter_id + @num_bins.setter def num_bins(self, num_bins): cv.check_type('filter num_bins', num_bins, Integral) @@ -226,13 +260,19 @@ class Filter(object): Returns ------- - ElementTree.Element + element : xml.etree.ElementTree.Element + XML element containing filter data """ + element = ET.Element('filter') + element.set('id', str(self.id)) element.set('type', self.short_name.lower()) - element.set('bins', ' '.join(str(b) for b in self.bins)) + + subelement = ET.SubElement(element, 'bins') + subelement.text = ' '.join(str(b) for b in self.bins) + return element def can_merge(self, other): @@ -279,7 +319,7 @@ class Filter(object): merged_bins = np.concatenate((self.bins, other.bins)) merged_bins = np.unique(merged_bins) - # Create a new filter with these bins + # Create a new filter with these bins and a new auto-generated ID return type(self)(merged_bins) def is_subset(self, other): @@ -472,11 +512,15 @@ class UniverseFilter(WithIDFilter): bins : openmc.Universe, Integral, or iterable thereof The Universes to tally. Either openmc.Universe objects or their Integral ID numbers can be used. + filter_id : int + Unique identifier for the filter Attributes ---------- bins : Iterable of Integral openmc.Universe IDs. + id : int + Unique identifier for the filter num_bins : Integral The number of filter bins stride : Integral @@ -501,11 +545,15 @@ class MaterialFilter(WithIDFilter): bins : openmc.Material, Integral, or iterable thereof The Materials to tally. Either openmc.Material objects or their Integral ID numbers can be used. + filter_id : int + Unique identifier for the filter Attributes ---------- bins : Iterable of Integral openmc.Material IDs. + id : int + Unique identifier for the filter num_bins : Integral The number of filter bins stride : Integral @@ -530,11 +578,15 @@ class CellFilter(WithIDFilter): bins : openmc.Cell, Integral, or iterable thereof The Cells to tally. Either openmc.Cell objects or their Integral ID numbers can be used. + filter_id : int + Unique identifier for the filter Attributes ---------- bins : Iterable of Integral openmc.Cell IDs. + id : int + Unique identifier for the filter num_bins : Integral The number of filter bins stride : Integral @@ -559,11 +611,15 @@ class CellbornFilter(WithIDFilter): bins : openmc.Cell, Integral, or iterable thereof The birth Cells to tally. Either openmc.Cell objects or their Integral ID numbers can be used. + filter_id : int + Unique identifier for the filter Attributes ---------- bins : Iterable of Integral openmc.Cell IDs. + id : int + Unique identifier for the filter num_bins : Integral The number of filter bins stride : Integral @@ -588,12 +644,16 @@ class SurfaceFilter(Filter): bins : Iterable of Integral Indices corresponding to which face of a mesh cell the current is crossing. + filter_id : int + Unique identifier for the filter Attributes ---------- bins : Iterable of Integral Indices corresponding to which face of a mesh cell the current is crossing. + id : int + Unique identifier for the filter num_bins : Integral The number of filter bins stride : Integral @@ -677,6 +737,8 @@ class MeshFilter(Filter): ---------- mesh : openmc.Mesh The Mesh object that events will be tallied onto + filter_id : int + Unique identifier for the filter Attributes ---------- @@ -684,6 +746,8 @@ class MeshFilter(Filter): The Mesh ID mesh : openmc.Mesh The Mesh object that events will be tallied onto + id : int + Unique identifier for the filter num_bins : Integral The number of filter bins stride : Integral @@ -692,9 +756,9 @@ class MeshFilter(Filter): """ - def __init__(self, mesh): + def __init__(self, mesh, filter_id=None): self.mesh = mesh - super(MeshFilter, self).__init__(mesh.id) + super(MeshFilter, self).__init__(mesh.id, filter_id) @classmethod def from_hdf5(cls, group, **kwargs): @@ -709,8 +773,9 @@ class MeshFilter(Filter): mesh_id = group['bins'].value mesh_obj = kwargs['meshes'][mesh_id] + filter_id = int(group.name.split('/')[-1].lstrip('filter ')) - out = cls(mesh_obj) + out = cls(mesh_obj, filter_id) out.num_bins = group['n_bins'].value return out @@ -868,11 +933,15 @@ class RealFilter(Filter): ---------- bins : Iterable of Real A grid of bin values. + filter_id : int + Unique identifier for the filter Attributes ---------- bins : Iterable of Real A grid of bin values. + id : int + Unique identifier for the filter num_bins : Integral The number of filter bins stride : Integral @@ -922,7 +991,7 @@ class RealFilter(Filter): merged_bins = np.concatenate((self.bins, other.bins)) merged_bins = np.unique(merged_bins) - # Create a new filter with these bins + # Create a new filter with these bins and a new auto-generated ID return type(self)(sorted(merged_bins)) def is_subset(self, other): @@ -975,11 +1044,15 @@ class EnergyFilter(RealFilter): ---------- bins : Iterable of Real A grid of energy values in eV. + filter_id : int + Unique identifier for the filter Attributes ---------- bins : Iterable of Real A grid of energy values in eV. + id : int + Unique identifier for the filter num_bins : Integral The number of filter bins stride : Integral @@ -1077,11 +1150,15 @@ class EnergyoutFilter(EnergyFilter): ---------- bins : Iterable of Real A grid of energy values in eV. + filter_id : int + Unique identifier for the filter Attributes ---------- bins : Iterable of Real A grid of energy values in eV. + id : int + Unique identifier for the filter num_bins : Integral The number of filter bins stride : Integral @@ -1135,11 +1212,15 @@ class DistribcellFilter(Filter): cell : openmc.Cell or Integral The distributed cell to tally. Either an openmc.Cell or an Integral cell ID number can be used. + filter_id : int + Unique identifier for the filter Attributes ---------- bins : Iterable of Integral An iterable with one element---the ID of the distributed Cell. + id : int + Unique identifier for the filter num_bins : Integral The number of filter bins stride : Integral @@ -1151,9 +1232,9 @@ class DistribcellFilter(Filter): """ - def __init__(self, cell): + def __init__(self, cell, filter_id=None): self._paths = None - super(DistribcellFilter, self).__init__(cell) + super(DistribcellFilter, self).__init__(cell, filter_id) @classmethod def from_hdf5(cls, group, **kwargs): @@ -1162,7 +1243,9 @@ class DistribcellFilter(Filter): + cls.short_name.lower() + "' but got '" + group['type'].value.decode() + " instead") - out = cls(group['bins'].value) + filter_id = int(group.name.split('/')[-1].lstrip('filter ')) + + out = cls(group['bins'].value, filter_id) out.num_bins = group['n_bins'].value return out @@ -1372,6 +1455,8 @@ class MuFilter(RealFilter): the values will be used explicitly as grid points. If a single Integral is given, the range [-1, 1] will be divided up equally into that number of bins. + filter_id : int + Unique identifier for the filter Attributes ---------- @@ -1381,6 +1466,8 @@ class MuFilter(RealFilter): the values will be used explicitly as grid points. If a single Integral is given, the range [-1, 1] will be divided up equally into that number of bins. + id : int + Unique identifier for the filter num_bins : Integral The number of filter bins stride : Integral @@ -1475,6 +1562,8 @@ class PolarFilter(RealFilter): the values will be used explicitly as grid points. If a single Integral is given, the range [0, pi] will be divided up equally into that number of bins. + filter_id : int + Unique identifier for the filter Attributes ---------- @@ -1484,6 +1573,8 @@ class PolarFilter(RealFilter): the values will be used explicitly as grid points. If a single Integral is given, the range [0, pi] will be divided up equally into that number of bins. + id : int + Unique identifier for the filter num_bins : Integral The number of filter bins stride : Integral @@ -1578,6 +1669,8 @@ class AzimuthalFilter(RealFilter): to the z-axis. If an Iterable is given, the values will be used explicitly as grid points. If a single Integral is given, the range [-pi, pi) will be divided up equally into that number of bins. + filter_id : int + Unique identifier for the filter Attributes ---------- @@ -1587,6 +1680,8 @@ class AzimuthalFilter(RealFilter): to the z-axis. If an Iterable is given, the values will be used explicitly as grid points. If a single Integral is given, the range [-pi, pi) will be divided up equally into that number of bins. + id : int + Unique identifier for the filter num_bins : Integral The number of filter bins stride : Integral @@ -1679,6 +1774,8 @@ class DelayedGroupFilter(Filter): The delayed neutron precursor groups. For example, ENDF/B-VII.1 uses 6 precursor groups so a tally with all groups will have bins = [1, 2, 3, 4, 5, 6]. + filter_id : int + Unique identifier for the filter Attributes ---------- @@ -1686,6 +1783,8 @@ class DelayedGroupFilter(Filter): The delayed neutron precursor groups. For example, ENDF/B-VII.1 uses 6 precursor groups so a tally with all groups will have bins = [1, 2, 3, 4, 5, 6]. + id : int + Unique identifier for the filter num_bins : Integral The number of filter bins stride : Integral @@ -1730,6 +1829,8 @@ class EnergyFunctionFilter(Filter): A grid of energy values in eV. y : iterable of Real A grid of interpolant values in eV. + filter_id : int + Unique identifier for the filter Attributes ---------- @@ -1737,6 +1838,8 @@ class EnergyFunctionFilter(Filter): A grid of energy values in eV. y : iterable of Real A grid of interpolant values in eV. + id : int + Unique identifier for the filter num_bins : Integral The number of filter bins (always 1 for this filter) stride : Integral @@ -1745,9 +1848,10 @@ class EnergyFunctionFilter(Filter): """ - def __init__(self, energy, y): + def __init__(self, energy, y, filter_id=None): self.energy = energy self.y = y + self.id = filter_id self._stride = None def __eq__(self, other): @@ -1785,14 +1889,16 @@ class EnergyFunctionFilter(Filter): return False def __hash__(self): - # For some reason, it seems the __hash__ method is not inherited when we - # overwrite __repr__. - return hash(repr(self)) + string = type(self).__name__ + '\n' + string += '{: <16}=\t{}\n'.format('\tEnergy', self.energy) + string += '{: <16}=\t{}\n'.format('\tInterpolant', self.y) + return hash(string) def __repr__(self): string = type(self).__name__ + '\n' string += '{: <16}=\t{}\n'.format('\tEnergy', self.energy) string += '{: <16}=\t{}\n'.format('\tInterpolant', self.y) + string += '{: <16}=\t{}\n'.format('\tID', self.id) return string @classmethod @@ -1804,8 +1910,9 @@ class EnergyFunctionFilter(Filter): energy = group['energy'].value y = group['y'].value + filter_id = int(group.name.split('/')[-1].lstrip('filter ')) - return cls(energy, y) + return cls(energy, y, filter_id) @classmethod def from_tabulated1d(cls, tab1d): @@ -1876,9 +1983,15 @@ class EnergyFunctionFilter(Filter): def to_xml_element(self): element = ET.Element('filter') + element.set('id', str(self.id)) element.set('type', self.short_name.lower()) - element.set('energy', ' '.join(str(e) for e in self.energy)) - element.set('y', ' '.join(str(y) for y in self.y)) + + subelement = ET.SubElement(element, 'energy') + subelement.text = ' '.join(str(e) for e in self.energy) + + subelement = ET.SubElement(element, 'y') + subelement.text = ' '.join(str(y) for y in self.y) + return element def can_merge(self, other): diff --git a/openmc/statepoint.py b/openmc/statepoint.py index 28f35ba7d..543e8a302 100644 --- a/openmc/statepoint.py +++ b/openmc/statepoint.py @@ -9,7 +9,7 @@ import h5py import openmc import openmc.checkvalue as cv -_VERSION_STATEPOINT = 16 +_VERSION_STATEPOINT = 17 class StatePoint(object): @@ -51,6 +51,9 @@ class StatePoint(object): Date and time when simulation began entropy : numpy.ndarray Shannon entropy of fission source at each batch + filters : dict + Dictionary whose keys are filter IDs and whose values are Filter + objects generations_per_batch : int Number of fission generations per batch global_tallies : numpy.ndarray of compound datatype @@ -111,6 +114,7 @@ class StatePoint(object): def __init__(self, filename, autolink=True): self._f = h5py.File(filename, 'r') self._meshes = {} + self._filters = {} self._tallies = {} self._derivs = {} @@ -119,6 +123,7 @@ class StatePoint(object): # Set flags for what data has been read self._meshes_read = False + self._filters_read = False self._tallies_read = False self._summary = None self._global_tallies = None @@ -191,6 +196,20 @@ class StatePoint(object): else: return None + @property + def filters(self): + if not self._filters_read: + filters_group = self._f['tallies/filters'] + + # Iterate over all Filters + for group in filters_group.values(): + new_filter = openmc.Filter.from_hdf5(group, meshes=self.meshes) + self._filters[new_filter.id] = new_filter + + self._filters_read = True + + return self._filters + @property def generations_per_batch(self): if self.run_mode == 'eigenvalue': @@ -358,11 +377,14 @@ class StatePoint(object): # Read all filters n_filters = group['n_filters'].value - for j in range(1, n_filters + 1): - filter_group = group['filter {}'.format(j)] - new_filter = openmc.Filter.from_hdf5(filter_group, - meshes=self.meshes) - tally.filters.append(new_filter) + if n_filters > 0: + filter_ids = group['filters'].value + filters_group = self._f['tallies/filters'] + for filter_id in filter_ids: + filter_group = filters_group['filter {}'.format(filter_id)] + new_filter = openmc.Filter.from_hdf5(filter_group, + meshes=self.meshes) + tally.filters.append(new_filter) # Read nuclide bins nuclide_names = group['nuclides'].value diff --git a/openmc/tallies.py b/openmc/tallies.py index e0283571c..1641d6164 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -1076,8 +1076,9 @@ class Tally(object): element.set("name", self.name) # Optional Tally filters - for self_filter in self.filters: - element.append(self_filter.to_xml_element()) + if len(self.filters) > 0: + subelement = ET.SubElement(element, "filters") + subelement.text = ' '.join(str(f.id) for f in self.filters) # Optional Nuclides if len(self.nuclides) > 0: @@ -3522,6 +3523,18 @@ class Tallies(cv.CheckedList): root_element.append(f.mesh.to_xml_element()) already_written.add(f.mesh) + def _create_filter_subelements(self, root_element): + already_written = dict() + for tally in self: + for f in tally.filters: + if f not in already_written: + root_element.append(f.to_xml_element()) + already_written[f] = f.id + else: + # Set the IDs of identical filters with different + # user-defined IDs to the same value + f.id = already_written[f] + def _create_derivative_subelements(self, root_element): # Get a list of all derivatives referenced in a tally. derivs = [] @@ -3546,6 +3559,7 @@ class Tallies(cv.CheckedList): root_element = ET.Element("tallies") self._create_mesh_subelements(root_element) + self._create_filter_subelements(root_element) self._create_tally_subelements(root_element) self._create_derivative_subelements(root_element) diff --git a/src/cmfd_data.F90 b/src/cmfd_data.F90 index 29e164440..177f140b6 100644 --- a/src/cmfd_data.F90 +++ b/src/cmfd_data.F90 @@ -56,8 +56,8 @@ contains IN_BACK, IN_FRONT, IN_BOTTOM, IN_TOP, CMFD_NOACCEL, & ZERO, ONE, TINY_BIT use error, only: fatal_error - use global, only: cmfd, n_cmfd_tallies, cmfd_tallies, meshes,& - matching_bins + use global, only: cmfd, n_cmfd_tallies, cmfd_tallies, meshes, & + filters, filter_matches use mesh, only: mesh_indices_to_bin use mesh_header, only: RegularMesh use string, only: to_str @@ -72,14 +72,18 @@ contains integer :: k ! iteration counter for z integer :: g ! iteration counter for g integer :: h ! iteration counter for outgoing groups + integer :: l ! iteration counter for tally filters integer :: ital ! tally object index integer :: ijk(3) ! indices for mesh cell integer :: score_index ! index to pull from tally object integer :: i_mesh ! index in meshes array + integer :: i_filt ! index in filters array integer :: i_filter_mesh ! index for mesh filter integer :: i_filter_ein ! index for incoming energy filter integer :: i_filter_eout ! index for outgoing energy filter integer :: i_filter_surf ! index for surface filter + integer :: stride_surf ! stride for surface filter + logical :: energy_filters! energy filters present real(8) :: flux ! temp variable for flux type(TallyObject), pointer :: t ! pointer for tally object type(RegularMesh), pointer :: m ! pointer for mesh object @@ -96,7 +100,8 @@ contains ! Associate tallies and mesh t => cmfd_tallies(1) - select type(filt => t % filters(t % find_filter(FILTER_MESH)) % obj) + i_filt = t % filter(t % find_filter(FILTER_MESH)) + select type(filt => filters(i_filt) % obj) type is (MeshFilter) i_mesh = filt % mesh end select @@ -114,16 +119,21 @@ contains ! Associate tallies and mesh t => cmfd_tallies(ital) - select type(filt => t % filters(t % find_filter(FILTER_MESH)) % obj) + i_filt = t % filter(t % find_filter(FILTER_MESH)) + select type(filt => filters(i_filt) % obj) type is (MeshFilter) i_mesh = filt % mesh end select m => meshes(i_mesh) - i_filter_mesh = t % find_filter(FILTER_MESH) - i_filter_ein = t % find_filter(FILTER_ENERGYIN) - i_filter_eout = t % find_filter(FILTER_ENERGYOUT) - i_filter_surf = t % find_filter(FILTER_SURFACE) + ! Check for energy filters + energy_filters = (t % find_filter(FILTER_ENERGYIN) > 0) + + i_filter_mesh = t % filter(t % find_filter(FILTER_MESH)) + if (energy_filters) then + i_filter_ein = t % filter(t % find_filter(FILTER_ENERGYIN)) + i_filter_eout = t % filter(t % find_filter(FILTER_ENERGYOUT)) + end if ! Begin loop around space ZLOOP: do k = 1,nz @@ -146,22 +156,29 @@ contains TALLY: if (ital == 1) then ! Reset all bins to 1 - matching_bins(1:size(t % filters)) = 1 + do l = 1, size(t % filter) + call filter_matches(t % filter(l)) % bins % clear() + call filter_matches(t % filter(l)) % bins % push_back(1) + end do ! Set ijk as mesh indices ijk = (/ i, j, k /) ! Get bin number for mesh indices - matching_bins(i_filter_mesh) = mesh_indices_to_bin(m,ijk) + filter_matches(i_filter_mesh) % bins % data(1) = & + mesh_indices_to_bin(m,ijk) ! Apply energy in filter - if (i_filter_ein > 0) then - matching_bins(i_filter_ein) = ng - h + 1 + if (energy_filters) then + filter_matches(i_filter_ein) % bins % data(1) = ng - h + 1 end if ! Calculate score index from bins - score_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t%stride) + 1 + score_index = 1 + do l = 1, size(t % filter) + score_index = score_index + (filter_matches(t % filter(l)) & + % bins % data(1) - 1) * t % stride(l) + end do ! Get flux flux = t % results(RESULT_SUM,1,score_index) @@ -190,25 +207,32 @@ contains INGROUP: do g = 1, ng ! Reset all bins to 1 - matching_bins(1:size(t % filters)) = 1 + do l = 1, size(t % filter) + call filter_matches(t % filter(l)) % bins % clear() + call filter_matches(t % filter(l)) % bins % push_back(1) + end do ! Set ijk as mesh indices ijk = (/ i, j, k /) ! Get bin number for mesh indices - matching_bins(i_filter_mesh) = mesh_indices_to_bin(m,ijk) + filter_matches(i_filter_mesh) % bins % data(1) = & + mesh_indices_to_bin(m,ijk) - if (i_filter_ein > 0) then + if (energy_filters) then ! Apply energy in filter - matching_bins(i_filter_ein) = ng - h + 1 + filter_matches(i_filter_ein) % bins % data(1) = ng - h + 1 ! Set energy out bin - matching_bins(i_filter_eout) = ng - g + 1 + filter_matches(i_filter_eout) % bins % data(1) = ng - g + 1 end if ! Calculate score index from bins - score_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t%stride) + 1 + score_index = 1 + do l = 1, size(t % filter) + score_index = score_index + (filter_matches(t % filter(l)) & + % bins % data(1) - 1) * t % stride(l) + end do ! Get scattering cmfd % scattxs(h,g,i,j,k) = t % results(RESULT_SUM,1,score_index) /& @@ -228,81 +252,64 @@ contains else if (ital == 3) then + i_filter_surf = t % filter(t % find_filter(FILTER_SURFACE)) + stride_surf = t % stride(t % find_filter(FILTER_SURFACE)) + ! Initialize and filter for energy - matching_bins(1:size(t % filters)) = 1 - if (i_filter_ein > 0) then - matching_bins(i_filter_ein) = ng - h + 1 + do l = 1, size(t % filter) + call filter_matches(t % filter(l)) % bins % clear() + call filter_matches(t % filter(l)) % bins % push_back(1) + end do + if (energy_filters) then + filter_matches(i_filter_ein) % bins % data(1) = ng - h + 1 end if ! Get the bin for this mesh cell - matching_bins(i_filter_mesh) = mesh_indices_to_bin(m, & - (/ i, j, k /)) + filter_matches(i_filter_mesh) % bins % data(1) = & + mesh_indices_to_bin(m, (/ i, j, k /)) + + score_index = 1 + do l = 1, size(t % filter) + if (t % filter(l) == i_filter_surf) cycle + score_index = score_index + (filter_matches(t % filter(l)) & + % bins % data(1) - 1) * t % stride(l) + end do ! Left surface - matching_bins(i_filter_surf) = OUT_LEFT - score_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 - cmfd % current(1,h,i,j,k) = t % results(RESULT_SUM,1,score_index) - - matching_bins(i_filter_surf) = IN_LEFT - score_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 - cmfd % current(2,h,i,j,k) = t % results(RESULT_SUM,1,score_index) + cmfd % current(1,h,i,j,k) = t % results(RESULT_SUM, 1, & + score_index + (OUT_LEFT - 1) * stride_surf) + cmfd % current(2,h,i,j,k) = t % results(RESULT_SUM, 1, & + score_index + (IN_LEFT - 1) * stride_surf) ! Right surface - matching_bins(i_filter_surf) = IN_RIGHT - score_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 - cmfd % current(3,h,i,j,k) = t % results(RESULT_SUM,1,score_index) - - matching_bins(i_filter_surf) = OUT_RIGHT - score_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 - cmfd % current(4,h,i,j,k) = t % results(RESULT_SUM,1,score_index) + cmfd % current(3,h,i,j,k) = t % results(RESULT_SUM, 1, & + score_index + (IN_RIGHT - 1) * stride_surf) + cmfd % current(4,h,i,j,k) = t % results(RESULT_SUM, 1, & + score_index + (OUT_RIGHT - 1) * stride_surf) ! Back surface - matching_bins(i_filter_surf) = OUT_BACK - score_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 - cmfd % current(5,h,i,j,k) = t % results(RESULT_SUM,1,score_index) - - matching_bins(i_filter_surf) = IN_BACK - score_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 - cmfd % current(6,h,i,j,k) = t % results(RESULT_SUM,1,score_index) + cmfd % current(5,h,i,j,k) = t % results(RESULT_SUM, 1, & + score_index + (OUT_BACK - 1) * stride_surf) + cmfd % current(6,h,i,j,k) = t % results(RESULT_SUM, 1, & + score_index + (IN_BACK - 1) * stride_surf) ! Front surface - matching_bins(i_filter_surf) = IN_FRONT - score_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 - cmfd % current(7,h,i,j,k) = t % results(RESULT_SUM,1,score_index) - - matching_bins(i_filter_surf) = OUT_FRONT - score_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 - cmfd % current(8,h,i,j,k) = t % results(RESULT_SUM,1,score_index) + cmfd % current(7,h,i,j,k) = t % results(RESULT_SUM, 1, & + score_index + (IN_FRONT - 1) * stride_surf) + cmfd % current(8,h,i,j,k) = t % results(RESULT_SUM, 1, & + score_index + (OUT_FRONT - 1) * stride_surf) ! Bottom surface - matching_bins(i_filter_surf) = OUT_BOTTOM - score_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 - cmfd % current(9,h,i,j,k) = t % results(RESULT_SUM,1,score_index) - - matching_bins(i_filter_surf) = IN_BOTTOM - score_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 - cmfd % current(10,h,i,j,k) = t % results(RESULT_SUM,1,score_index) + cmfd % current(9,h,i,j,k) = t % results(RESULT_SUM, 1, & + score_index + (OUT_BOTTOM - 1) * stride_surf) + cmfd % current(10,h,i,j,k) = t % results(RESULT_SUM, 1, & + score_index + (IN_BOTTOM - 1) * stride_surf) ! Top surface - matching_bins(i_filter_surf) = IN_TOP - score_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 - cmfd % current(11,h,i,j,k) = t % results(RESULT_SUM,1,score_index) - - matching_bins(i_filter_surf) = OUT_TOP - score_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 - cmfd % current(12,h,i,j,k) = t % results(RESULT_SUM,1,score_index) + cmfd % current(11,h,i,j,k) = t % results(RESULT_SUM, 1, & + score_index + (IN_TOP - 1) * stride_surf) + cmfd % current(12,h,i,j,k) = t % results(RESULT_SUM, 1, & + score_index + (OUT_TOP - 1) * stride_surf) end if TALLY diff --git a/src/cmfd_input.F90 b/src/cmfd_input.F90 index 1518d710f..d57c21beb 100644 --- a/src/cmfd_input.F90 +++ b/src/cmfd_input.F90 @@ -259,16 +259,16 @@ contains type(XMLNode), intent(in) :: root ! XML root element - integer :: i, j ! loop counter + logical :: energy_filters + integer :: i ! loop counter integer :: n ! size of arrays in mesh specification integer :: ng ! number of energy groups (default 1) - integer :: n_filters ! number of filters - integer :: i_filter_mesh ! index for mesh filter + integer :: n_filter ! number of filters + integer :: i_filt ! index in filters array integer :: iarray3(3) ! temp integer array real(8) :: rarray3(3) ! temp double array - type(TallyObject), pointer :: t + type(TallyObject), pointer :: t type(RegularMesh), pointer :: m - type(TallyFilterContainer) :: filters(N_FILTER_TYPES) ! temporary filters type(XMLNode) :: node_mesh ! Set global variables if they are 0 (this can happen if there is no tally @@ -376,6 +376,91 @@ contains ! Add mesh to dictionary call mesh_dict % add_key(m % id, n_user_meshes + 1) + ! Determine number of filters + energy_filters = check_for_node(node_mesh, "energy") + n_cmfd_filters = merge(5, 3, energy_filters) + + ! Extend filters array so we can add CMFD filters + call add_filters(n_cmfd_filters) + + ! Set up mesh filter + i_filt = n_user_filters + 1 + allocate(MeshFilter :: filters(i_filt) % obj) + select type (filt => filters(i_filt) % obj) + type is (MeshFilter) + filt % id = i_filt + filt % n_bins = product(m % dimension) + filt % mesh = n_user_meshes + 1 + ! Add filter to dictionary + call filter_dict % add_key(filt % id, i_filt) + end select + + if (energy_filters) then + ! Read and set incoming energy mesh filter + i_filt = i_filt + 1 + allocate(EnergyFilter :: filters(i_filt) % obj) + select type (filt => filters(i_filt) % obj) + type is (EnergyFilter) + filt % id = i_filt + ng = node_word_count(node_mesh, "energy") + filt % n_bins = ng - 1 + allocate(filt % bins(ng)) + call get_node_array(node_mesh, "energy", filt % bins) + ! Add filter to dictionary + call filter_dict % add_key(filt % id, i_filt) + end select + + ! Read and set outgoing energy mesh filter + i_filt = i_filt + 1 + allocate(EnergyoutFilter :: filters(i_filt) % obj) + select type (filt => filters(i_filt) % obj) + type is (EnergyoutFilter) + filt % id = i_filt + ng = node_word_count(node_mesh, "energy") + filt % n_bins = ng - 1 + allocate(filt % bins(ng)) + call get_node_array(node_mesh, "energy", filt % bins) + ! Add filter to dictionary + call filter_dict % add_key(filt % id, i_filt) + end select + end if + + ! Duplicate the mesh filter for the surface current tally since other + ! tallies use this filter and we need to change the dimension + i_filt = i_filt + 1 + allocate(MeshFilter :: filters(i_filt) % obj) + select type (filt => filters(i_filt) % obj) + type is (MeshFilter) + filt % id = i_filt + ! We need to increase the dimension by one since we also need + ! currents coming into and out of the boundary mesh cells. + filt % n_bins = product(m % dimension + 1) + filt % mesh = n_user_meshes + 1 + ! Add filter to dictionary + call filter_dict % add_key(filt % id, i_filt) + end select + + ! Set up surface filter + i_filt = i_filt + 1 + allocate(SurfaceFilter :: filters(i_filt) % obj) + select type(filt => filters(i_filt) % obj) + type is(SurfaceFilter) + filt % id = i_filt + filt % n_bins = 4 * m % n_dimension + allocate(filt % surfaces(4 * m % n_dimension)) + if (m % n_dimension == 2) then + filt % surfaces = (/ OUT_LEFT, IN_LEFT, IN_RIGHT, OUT_RIGHT, & + OUT_BACK, IN_BACK, IN_FRONT, OUT_FRONT /) + elseif (m % n_dimension == 3) then + filt % surfaces = (/ OUT_LEFT, IN_LEFT, IN_RIGHT, OUT_RIGHT, & + OUT_BACK, IN_BACK, IN_FRONT, OUT_FRONT, & + OUT_BOTTOM, IN_BOTTOM, IN_TOP, OUT_TOP /) + end if + filt % current = .true. + ! Add filter to dictionary + call filter_dict % add_key(filt % id, i_filt) + end select + ! Allocate tallies call add_tallies("cmfd", n_cmfd_tallies) @@ -390,28 +475,15 @@ contains call get_node_value(root, "reset", t % reset) end if - ! Set up mesh filter - n_filters = 1 - allocate(MeshFilter :: filters(n_filters) % obj) - select type (filt => filters(n_filters) % obj) - type is (MeshFilter) - filt % n_bins = product(m % dimension) - filt % mesh = n_user_meshes + 1 - end select - t % find_filter(FILTER_MESH) = n_filters + ! Set the mesh filter index in the tally find_filter array + n_filter = 1 + t % find_filter(FILTER_MESH) = n_filter - ! Read and set incoming energy mesh filter - if (check_for_node(node_mesh, "energy")) then - n_filters = n_filters + 1 - allocate(EnergyFilter :: filters(n_filters) % obj) - select type (filt => filters(n_filters) % obj) - type is (EnergyFilter) - ng = node_word_count(node_mesh, "energy") - filt % n_bins = ng - 1 - allocate(filt % bins(ng)) - call get_node_array(node_mesh, "energy", filt % bins) - end select - t % find_filter(FILTER_ENERGYIN) = n_filters + ! Set the incoming energy mesh filter index in the tally find_filter + ! array + if (energy_filters) then + n_filter = n_filter + 1 + t % find_filter(FILTER_ENERGYIN) = n_filter end if ! Set number of nucilde bins @@ -434,10 +506,11 @@ contains t % type = TALLY_VOLUME ! Allocate and set filters - allocate(t % filters(n_filters)) - do j = 1, n_filters - call move_alloc(filters(j) % obj, t % filters(j) % obj) - end do + allocate(t % filter(n_filter)) + t % filter(1) = n_user_filters + 1 + if (energy_filters) then + t % filter(2) = n_user_filters + 2 + end if ! Allocate scoring bins allocate(t % score_bins(3)) @@ -465,25 +538,20 @@ contains ! Set tally type to volume t % type = TALLY_VOLUME - ! read and set outgoing energy mesh filter - if (check_for_node(node_mesh, "energy")) then - n_filters = n_filters + 1 - allocate(EnergyoutFilter :: filters(n_filters) % obj) - select type (filt => filters(n_filters) % obj) - type is (EnergyoutFilter) - ng = node_word_count(node_mesh, "energy") - filt % n_bins = ng - 1 - allocate(filt % bins(ng)) - call get_node_array(node_mesh, "energy", filt % bins) - end select - t % find_filter(FILTER_ENERGYOUT) = n_filters + ! Set the incoming energy mesh filter index in the tally find_filter + ! array + if (energy_filters) then + n_filter = n_filter + 1 + t % find_filter(FILTER_ENERGYOUT) = n_filter end if - ! Allocate and set filters - allocate(t % filters(n_filters)) - do j = 1, n_filters - call move_alloc(filters(j) % obj, t % filters(j) % obj) - end do + ! Allocate and set indices in filters array + allocate(t % filter(n_filter)) + t % filter(1) = n_user_filters + 1 + if (energy_filters) then + t % filter(2) = n_user_filters + 2 + t % filter(3) = n_user_filters + 3 + end if ! Allocate macro reactions allocate(t % score_bins(2)) @@ -506,29 +574,17 @@ contains ! Set tally estimator to analog t % estimator = ESTIMATOR_ANALOG - ! Add extra filter for surface - n_filters = n_filters + 1 - allocate(SurfaceFilter :: filters(n_filters) % obj) - select type(filt => filters(n_filters) % obj) - type is(SurfaceFilter) - filt % n_bins = 4 * m % n_dimension - allocate(filt % surfaces(4 * m % n_dimension)) - if (m % n_dimension == 2) then - filt % surfaces = (/ OUT_LEFT, IN_LEFT, IN_RIGHT, OUT_RIGHT, & - OUT_BACK, IN_BACK, IN_FRONT, OUT_FRONT /) - elseif (m % n_dimension == 3) then - filt % surfaces = (/ OUT_LEFT, IN_LEFT, IN_RIGHT, OUT_RIGHT, & - OUT_BACK, IN_BACK, IN_FRONT, OUT_FRONT, & - OUT_BOTTOM, IN_BOTTOM, IN_TOP, OUT_TOP /) - end if - end select - t % find_filter(FILTER_SURFACE) = n_filters + ! Set the surface filter index in the tally find_filter array + n_filter = n_filter + 1 + t % find_filter(FILTER_SURFACE) = n_filter ! Allocate and set filters - allocate(t % filters(n_filters)) - do j = 1, n_filters - call move_alloc(filters(j) % obj, t % filters(j) % obj) - end do + allocate(t % filter(n_filter)) + t % filter(1) = n_user_filters + n_cmfd_filters - 1 + t % filter(n_filter) = n_user_filters + n_cmfd_filters + if (energy_filters) then + t % filter(2) = n_user_filters + 2 + end if ! Allocate macro reactions allocate(t % score_bins(1)) @@ -542,20 +598,12 @@ contains ! Set macro bins t % score_bins(1) = SCORE_CURRENT t % type = TALLY_SURFACE_CURRENT - - ! We need to increase the dimension by one since we also need - ! currents coming into and out of the boundary mesh cells. - i_filter_mesh = t % find_filter(FILTER_MESH) - t % filters(i_filter_mesh) % obj % n_bins = product(m % dimension + 1) - end if end do ! Put cmfd tallies into active tally array and turn tallies on -!$omp parallel call setup_active_cmfdtallies() -!$omp end parallel tallies_on = .true. end subroutine create_cmfd_tally diff --git a/src/constants.F90 b/src/constants.F90 index bffd2173e..16c02d01b 100644 --- a/src/constants.F90 +++ b/src/constants.F90 @@ -16,7 +16,7 @@ module constants integer, parameter :: HDF5_VERSION(2) = [1, 0] ! Version numbers for binary files - integer, parameter :: VERSION_STATEPOINT(2) = [16, 0] + integer, parameter :: VERSION_STATEPOINT(2) = [17, 0] integer, parameter :: VERSION_PARTICLE_RESTART(2) = [2, 0] integer, parameter :: VERSION_TRACK(2) = [2, 0] integer, parameter :: VERSION_SUMMARY(2) = [5, 0] diff --git a/src/global.F90 b/src/global.F90 index 780f323f3..1d45bcbe8 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -18,9 +18,11 @@ module global use plot_header, only: ObjectPlot use sab_header, only: SAlphaBeta use set_header, only: SetInt + use stl_vector, only: VectorInt use surface_header, only: SurfaceContainer use source_header, only: SourceDistribution use tally_header, only: TallyObject, TallyDerivative + use tally_filter_header, only: TallyFilterContainer, TallyFilterMatch use trigger_header, only: KTrigger use timer_header, only: Timer use volume_header, only: VolumeCalculation @@ -57,6 +59,7 @@ module global type(DictIntInt) :: surface_dict type(DictIntInt) :: material_dict type(DictIntInt) :: mesh_dict + type(DictIntInt) :: filter_dict type(DictIntInt) :: tally_dict type(DictIntInt) :: plot_dict @@ -138,9 +141,9 @@ module global ! TALLY-RELATED VARIABLES type(RegularMesh), allocatable, target :: meshes(:) - type(TallyObject), allocatable, target :: tallies(:) - integer, allocatable :: matching_bins(:) - real(8), allocatable :: filter_weights(:) + type(TallyObject), allocatable, target :: tallies(:) + type(TallyFilterContainer), allocatable, target :: filters(:) + type(TallyFilterMatch), allocatable :: filter_matches(:) ! Pointers for different tallies type(TallyObject), pointer :: user_tallies(:) => null() @@ -151,14 +154,11 @@ module global integer :: i_cmfd_tallies = -1 ! Active tally lists - type(SetInt) :: active_analog_tallies - type(SetInt) :: active_tracklength_tallies - type(SetInt) :: active_current_tallies - type(SetInt) :: active_collision_tallies - type(SetInt) :: active_tallies -!$omp threadprivate(active_analog_tallies, active_tracklength_tallies, & -!$omp& active_current_tallies, active_collision_tallies, & -!$omp& active_tallies) + type(VectorInt) :: active_analog_tallies + type(VectorInt) :: active_tracklength_tallies + type(VectorInt) :: active_current_tallies + type(VectorInt) :: active_collision_tallies + type(VectorInt) :: active_tallies ! Global tallies ! 1) collision estimate of k-eff @@ -182,6 +182,8 @@ module global integer :: n_meshes = 0 ! # of structured meshes integer :: n_user_meshes = 0 ! # of structured user meshes + integer :: n_filters = 0 ! # of filters + integer :: n_user_filters = 0 ! # of user filters integer :: n_tallies = 0 ! # of tallies integer :: n_user_tallies = 0 ! # of user tallies @@ -373,6 +375,7 @@ module global ! User-defined tally information integer :: n_cmfd_meshes = 1 ! # of structured meshes + integer :: n_cmfd_filters = 0 ! # of filters integer :: n_cmfd_tallies = 3 ! # of user-defined tallies ! Adjoint method type @@ -436,8 +439,7 @@ module global character(10), allocatable :: res_scat_nuclides(:) !$omp threadprivate(micro_xs, material_xs, fission_bank, n_bank, & -!$omp& trace, thread_id, current_work, matching_bins, & -!$omp& filter_weights) +!$omp& trace, thread_id, current_work, filter_matches) contains @@ -490,9 +492,9 @@ contains ! Deallocate tally-related arrays if (allocated(global_tallies)) deallocate(global_tallies) if (allocated(meshes)) deallocate(meshes) + if (allocated(filters)) deallocate(filters) if (allocated(tallies)) deallocate(tallies) - if (allocated(matching_bins)) deallocate(matching_bins) - if (allocated(filter_weights)) deallocate(filter_weights) + if (allocated(filter_matches)) deallocate(filter_matches) ! Deallocate fission and source bank and entropy !$omp parallel @@ -527,6 +529,7 @@ contains call surface_dict % clear() call material_dict % clear() call mesh_dict % clear() + call filter_dict % clear() call tally_dict % clear() call plot_dict % clear() call nuclide_dict % clear() diff --git a/src/initialize.F90 b/src/initialize.F90 index 1852154e8..e9718fee1 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -107,7 +107,7 @@ contains call logarithmic_grid() end if - ! Allocate and setup tally stride, matching_bins, and tally maps + ! Allocate and setup tally stride, filter_matches, and tally maps call configure_tallies() ! Set up tally procedure pointers @@ -432,7 +432,6 @@ contains integer :: id ! user-specified id type(Cell), pointer :: c => null() class(Lattice), pointer :: lat => null() - type(TallyObject), pointer :: t => null() do i = 1, n_cells ! ======================================================================= @@ -567,26 +566,20 @@ contains end do - TALLY_LOOP: do i = 1, n_tallies - t => tallies(i) + ! ======================================================================= + ! ADJUST INDICES FOR EACH TALLY FILTER - ! ======================================================================= - ! ADJUST INDICES FOR EACH TALLY FILTER + FILTER_LOOP: do i = 1, n_filters - FILTER_LOOP: do j = 1, size(t % filters) + select type(filt => filters(i) % obj) + type is (SurfaceFilter) + ! Check if this is a surface filter only for surface currents + if (.not. filt % current) call filt % initialize() + class default + call filt % initialize() + end select - select type(filt => t % filters(j) % obj) - type is (SurfaceFilter) - ! Check if this is a surface filter only for surface currents - if (.not. any(t % score_bins == SCORE_CURRENT)) & - call filt % initialize() - class default - call filt % initialize() - end select - - end do FILTER_LOOP - - end do TALLY_LOOP + end do FILTER_LOOP end subroutine adjust_indices @@ -695,8 +688,8 @@ contains ! We need distribcell if any tallies have distribcell filters. do i = 1, n_tallies - do j = 1, size(tallies(i) % filters) - select type(filt => tallies(i) % filters(j) % obj) + do j = 1, size(tallies(i) % filter) + select type(filt => filters(tallies(i) % filter(j)) % obj) type is (DistribcellFilter) distribcell_active = .true. end select @@ -722,8 +715,8 @@ contains ! Set the number of bins in all distribcell filters. do i = 1, n_tallies - do j = 1, size(tallies(i) % filters) - select type(filt => tallies(i) % filters(j) % obj) + do j = 1, size(tallies(i) % filter) + select type(filt => filters(tallies(i) % filter(j)) % obj) type is (DistribcellFilter) ! Set the number of bins to the number of instances of the cell. filt % n_bins = cells(filt % cell) % instances @@ -787,8 +780,8 @@ contains ! List all cells referenced in distribcell filters. do i = 1, n_tallies - do j = 1, size(tallies(i) % filters) - select type(filt => tallies(i) % filters(j) % obj) + do j = 1, size(tallies(i) % filter) + select type(filt => filters(tallies(i) % filter(j)) % obj) type is (DistribcellFilter) call cell_list % add(filt % cell) end select diff --git a/src/input_xml.F90 b/src/input_xml.F90 index b05d56075..5ff4d119e 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -28,6 +28,7 @@ module input_xml starts_with, ends_with, tokenize, split_string, & zero_padded use tally_header, only: TallyObject + use tally_filter_header, only: TallyFilterContainer use tally_filter use tally_initialize, only: add_tallies use xml_interface @@ -2634,10 +2635,13 @@ contains integer :: k ! another loop index integer :: l ! another loop index integer :: id ! user-specified identifier + integer :: filter_id ! user-specified identifier for filter integer :: i_mesh ! index in meshes array + integer :: i_filt ! index in filters array + integer :: i_filter_mesh ! index of mesh filter integer :: n ! size of arrays in mesh specification integer :: n_words ! number of words read - integer :: n_filters ! number of filters + integer :: n_filter ! number of filters integer :: n_new ! number of new scores to add based on Yn/Pn tally integer :: n_scores ! number of tot scores after adjusting for Yn/Pn tally integer :: n_bins ! total new bins for this score @@ -2655,6 +2659,7 @@ contains integer :: Nangle ! Number of angular bins real(8) :: dangle ! Mu spacing if using automatic allocation integer :: iangle ! Loop counter for building mu filter bins + integer, allocatable :: temp_filter(:) ! temporary filter indices character(MAX_LINE_LEN) :: filename character(MAX_WORD_LEN) :: word character(MAX_WORD_LEN) :: score_name @@ -2662,9 +2667,9 @@ contains character(MAX_WORD_LEN), allocatable :: sarray(:) type(DictCharInt) :: trigger_scores type(ElemKeyValueCI), pointer :: pair_list - type(TallyObject), pointer :: t + type(TallyObject), pointer :: t + type(TallyFilterContainer), pointer :: f type(RegularMesh), pointer :: m - type(TallyFilterContainer), allocatable :: filters(:) ! temporary filters type(XMLDocument) :: doc type(XMLNode) :: root type(XMLNode) :: node_mesh @@ -2707,6 +2712,9 @@ contains ! Get pointer list to XML call get_node_list(root, "mesh", node_mesh_list) + ! Get pointer list to XML + call get_node_list(root, "filter", node_filt_list) + ! Get pointer list to XML call get_node_list(root, "tally", node_tal_list) @@ -2721,6 +2729,12 @@ contains ! Allocate mesh array if (n_meshes > 0) allocate(meshes(n_meshes)) + ! Check for user filters + n_user_filters = size(node_filt_list) + + ! Allocate filters array + if (n_user_filters > 0) call add_filters(n_user_filters) + ! Check for user tallies n_user_tallies = size(node_tal_list) if (n_user_tallies == 0) then @@ -2954,6 +2968,359 @@ contains end associate end do + ! ========================================================================== + ! READ FILTER DATA + + READ_FILTERS: do i = 1, n_user_filters + f => filters(i) + + ! Get pointer to filter xml node + node_filt = node_filt_list(i) + + ! Copy filter id + if (check_for_node(node_filt, "id")) then + call get_node_value(node_filt, "id", filter_id) + else + call fatal_error("Must specify id for filter in tally XML file.") + end if + + ! Check to make sure 'id' hasn't been used + if (filter_dict % has_key(filter_id)) then + call fatal_error("Two or more filters use the same unique ID: " & + // to_str(filter_id)) + end if + + ! Convert filter type to lower case + temp_str = '' + if (check_for_node(node_filt, "type")) & + call get_node_value(node_filt, "type", temp_str) + temp_str = to_lower(temp_str) + + ! Determine number of bins + select case(temp_str) + case ("energy", "energyout", "mu", "polar", "azimuthal") + if (.not. check_for_node(node_filt, "bins")) then + call fatal_error("Bins not set in filter " // trim(to_str(filter_id))) + end if + n_words = node_word_count(node_filt, "bins") + case ("mesh", "universe", "material", "cell", "distribcell", & + "cellborn", "surface", "delayedgroup") + if (.not. check_for_node(node_filt, "bins")) then + call fatal_error("Bins not set in filter " // trim(to_str(filter_id))) + end if + n_words = node_word_count(node_filt, "bins") + end select + + ! Determine type of filter + select case (temp_str) + + case ('distribcell') + ! Allocate and declare the filter type + allocate(DistribcellFilter :: f % obj) + select type (filt => f % obj) + type is (DistribcellFilter) + if (n_words /= 1) call fatal_error("Only one cell can be & + &specified per distribcell filter.") + ! Store bins + call get_node_value(node_filt, "bins", filt % cell) + end select + + case ('cell') + ! Allocate and declare the filter type + allocate(CellFilter :: f % obj) + select type (filt => f % obj) + type is (CellFilter) + ! Allocate and store bins + filt % n_bins = n_words + allocate(filt % cells(n_words)) + call get_node_array(node_filt, "bins", filt % cells) + end select + + case ('cellborn') + ! Allocate and declare the filter type + allocate(CellbornFilter :: f % obj) + select type (filt => f % obj) + type is (CellbornFilter) + ! Allocate and store bins + filt % n_bins = n_words + allocate(filt % cells(n_words)) + call get_node_array(node_filt, "bins", filt % cells) + end select + + case ('material') + ! Allocate and declare the filter type + allocate(MaterialFilter :: f % obj) + select type (filt => f % obj) + type is (MaterialFilter) + ! Allocate and store bins + filt % n_bins = n_words + allocate(filt % materials(n_words)) + call get_node_array(node_filt, "bins", filt % materials) + end select + + case ('universe') + ! Allocate and declare the filter type + allocate(UniverseFilter :: f % obj) + select type (filt => f % obj) + type is (UniverseFilter) + ! Allocate and store bins + filt % n_bins = n_words + allocate(filt % universes(n_words)) + call get_node_array(node_filt, "bins", filt % universes) + end select + + case ('surface') + call fatal_error("Surface filter is not yet supported!") + ! Allocate and declare the filter type + allocate(SurfaceFilter :: f % obj) + select type (filt => f % obj) + type is (SurfaceFilter) + ! Allocate and store bins + filt % n_bins = n_words + allocate(filt % surfaces(n_words)) + call get_node_array(node_filt, "bins", filt % surfaces) + end select + + case ('mesh') + ! Allocate and declare the filter type + allocate(MeshFilter :: f % obj) + select type (filt => f % obj) + type is (MeshFilter) + if (n_words /= 1) call fatal_error("Only one mesh can be & + &specified per mesh filter.") + + ! Determine id of mesh + call get_node_value(node_filt, "bins", id) + + ! Get pointer to mesh + if (mesh_dict % has_key(id)) then + i_mesh = mesh_dict % get_key(id) + m => meshes(i_mesh) + else + call fatal_error("Could not find mesh " // trim(to_str(id)) & + // " specified on filter " // trim(to_str(filter_id))) + end if + + ! Determine number of bins + filt % n_bins = product(m % dimension) + + ! Store the index of the mesh + filt % mesh = i_mesh + end select + + case ('energy') + + ! Allocate and declare the filter type + allocate(EnergyFilter :: f % obj) + select type (filt => f % obj) + type is (EnergyFilter) + ! Allocate and store bins + filt % n_bins = n_words - 1 + allocate(filt % bins(n_words)) + call get_node_array(node_filt, "bins", filt % bins) + + ! We can save tallying time if we know that the tally bins match + ! the energy group structure. In that case, the matching bin + ! index is simply the group (after flipping for the different + ! ordering of the library and tallying systems). + if (.not. run_CE) then + if (n_words == num_energy_groups + 1) then + if (all(filt % bins == energy_bins(num_energy_groups + 1:1:-1))) & + then + filt % matches_transport_groups = .true. + end if + end if + end if + end select + + case ('energyout') + ! Allocate and declare the filter type + allocate(EnergyoutFilter :: f % obj) + select type (filt => f % obj) + type is (EnergyoutFilter) + ! Allocate and store bins + filt % n_bins = n_words - 1 + allocate(filt % bins(n_words)) + call get_node_array(node_filt, "bins", filt % bins) + + ! We can save tallying time if we know that the tally bins match + ! the energy group structure. In that case, the matching bin + ! index is simply the group (after flipping for the different + ! ordering of the library and tallying systems). + if (.not. run_CE) then + if (n_words == num_energy_groups + 1) then + if (all(filt % bins == energy_bins(num_energy_groups + 1:1:-1))) & + then + filt % matches_transport_groups = .true. + end if + end if + end if + end select + + case ('delayedgroup') + + ! Allocate and declare the filter type + allocate(DelayedGroupFilter :: f % obj) + select type (filt => f % obj) + type is (DelayedGroupFilter) + ! Allocate and store bins + filt % n_bins = n_words + allocate(filt % groups(n_words)) + call get_node_array(node_filt, "bins", filt % groups) + + ! Check that bins are all are between 1 and MAX_DELAYED_GROUPS + do d = 1, n_words + if (filt % groups(d) < 1 .or. & + filt % groups(d) > MAX_DELAYED_GROUPS) then + call fatal_error("Encountered delayedgroup bin with index " & + // trim(to_str(filt % groups(d))) // " that is outside & + &the range of 1 to MAX_DELAYED_GROUPS ( " & + // trim(to_str(MAX_DELAYED_GROUPS)) // ")") + end if + end do + end select + + case ('mu') + ! Allocate and declare the filter type + allocate(MuFilter :: f % obj) + select type (filt => f % obj) + type is (MuFilter) + ! Allocate and store bins + filt % n_bins = n_words - 1 + allocate(filt % bins(n_words)) + call get_node_array(node_filt, "bins", filt % bins) + + ! Allow a user to input a lone number which will mean that you + ! subdivide [-1,1] evenly with the input being the number of bins + if (n_words == 1) then + Nangle = int(filt % bins(1)) + if (Nangle > 1) then + filt % n_bins = Nangle + dangle = TWO / real(Nangle,8) + deallocate(filt % bins) + allocate(filt % bins(Nangle + 1)) + do iangle = 1, Nangle + filt % bins(iangle) = -ONE + (iangle - 1) * dangle + end do + filt % bins(Nangle + 1) = ONE + else + call fatal_error("Number of bins for mu filter must be& + & greater than 1 on filter " & + // trim(to_str(filter_id)) // ".") + end if + end if + end select + + case ('polar') + ! Allocate and declare the filter type + allocate(PolarFilter :: f % obj) + select type (filt => f % obj) + type is (PolarFilter) + ! Allocate and store bins + filt % n_bins = n_words - 1 + allocate(filt % bins(n_words)) + call get_node_array(node_filt, "bins", filt % bins) + + ! Allow a user to input a lone number which will mean that you + ! subdivide [0,pi] evenly with the input being the number of bins + if (n_words == 1) then + Nangle = int(filt % bins(1)) + if (Nangle > 1) then + filt % n_bins = Nangle + dangle = PI / real(Nangle,8) + deallocate(filt % bins) + allocate(filt % bins(Nangle + 1)) + do iangle = 1, Nangle + filt % bins(iangle) = (iangle - 1) * dangle + end do + filt % bins(Nangle + 1) = PI + else + call fatal_error("Number of bins for polar filter must be& + & greater than 1 on filter " & + // trim(to_str(filter_id)) // ".") + end if + end if + end select + + case ('azimuthal') + ! Allocate and declare the filter type + allocate(AzimuthalFilter :: f % obj) + select type (filt => f % obj) + type is (AzimuthalFilter) + ! Allocate and store bins + filt % n_bins = n_words - 1 + allocate(filt % bins(n_words)) + call get_node_array(node_filt, "bins", filt % bins) + + ! Allow a user to input a lone number which will mean that you + ! subdivide [-pi,pi) evenly with the input being the number of + ! bins + if (n_words == 1) then + Nangle = int(filt % bins(1)) + if (Nangle > 1) then + filt % n_bins = Nangle + dangle = TWO * PI / real(Nangle,8) + deallocate(filt % bins) + allocate(filt % bins(Nangle + 1)) + do iangle = 1, Nangle + filt % bins(iangle) = -PI + (iangle - 1) * dangle + end do + filt % bins(Nangle + 1) = PI + else + call fatal_error("Number of bins for azimuthal filter must be& + & greater than 1 on filter " & + // trim(to_str(filter_id)) // ".") + end if + end if + end select + + case ('energyfunction') + ! Allocate and declare the filter type. + allocate(EnergyFunctionFilter :: f % obj) + select type (filt => f % obj) + type is (EnergyFunctionFilter) + filt % n_bins = 1 + ! Make sure this is continuous-energy mode. + if (.not. run_CE) then + call fatal_error("EnergyFunction filters are only supported for & + &continuous-energy transport calculations") + end if + + ! Allocate and store energy grid. + if (.not. check_for_node(node_filt, "energy")) then + call fatal_error("Energy grid not specified for EnergyFunction & + &filter on filter " // trim(to_str(filter_id))) + end if + n_words = node_word_count(node_filt, "energy") + allocate(filt % energy(n_words)) + call get_node_array(node_filt, "energy", filt % energy) + + ! Allocate and store interpolant values. + if (.not. check_for_node(node_filt, "y")) then + call fatal_error("y values not specified for EnergyFunction & + &filter on filter " // trim(to_str(filter_id))) + end if + n_words = node_word_count(node_filt, "y") + allocate(filt % y(n_words)) + call get_node_array(node_filt, "y", filt % y) + end select + + case default + ! Specified filter is invalid, raise error + call fatal_error("Unknown filter type '" & + // trim(temp_str) // "' on filter " & + // trim(to_str(filter_id)) // ".") + + end select + + ! Set filter id + f % obj % id = filter_id + + ! Add filter to dictionary + call filter_dict % add_key(filter_id, i) + + end do READ_FILTERS + ! ========================================================================== ! READ TALLY DATA @@ -2995,378 +3362,72 @@ contains ! ======================================================================= ! READ DATA FOR FILTERS - ! Get pointer list to XML and get number of filters - call get_node_list(node_tal, "filter", node_filt_list) - n_filters = size(node_filt_list) + ! Determine number of filters + if (check_for_node(node_tal, "filters")) then + n_filter = node_word_count(node_tal, "filters") + else + n_filter = 0 + end if - ! Allocate filters array - allocate(t % filters(n_filters)) + ! Allocate and store filter user ids + allocate(temp_filter(n_filter)) + if (n_filter > 0) then + call get_node_array(node_tal, "filters", temp_filter) + end if - READ_FILTERS: do j = 1, n_filters - ! Get pointer to filter xml node - node_filt = node_filt_list(j) + do j = 1, n_filter + ! Get pointer to filter + if (filter_dict % has_key(temp_filter(j))) then + i_filt = filter_dict % get_key(temp_filter(j)) + f => filters(i_filt) + else + call fatal_error("Could not find filter " & + // trim(to_str(temp_filter(j))) // " specified on tally " & + // trim(to_str(t % id))) + end if - ! Convert filter type to lower case - temp_str = '' - if (check_for_node(node_filt, "type")) & - call get_node_value(node_filt, "type", temp_str) - temp_str = to_lower(temp_str) - - ! Determine number of bins - select case(temp_str) - case ("energy", "energyout", "mu", "polar", "azimuthal") - if (.not. check_for_node(node_filt, "bins")) then - call fatal_error("Bins not set in filter on tally " & - // trim(to_str(t % id))) - end if - n_words = node_word_count(node_filt, "bins") - case ("mesh", "universe", "material", "cell", "distribcell", & - "cellborn", "surface", "delayedgroup") - if (.not. check_for_node(node_filt, "bins")) then - call fatal_error("Bins not set in filter on tally " & - // trim(to_str(t % id))) - end if - n_words = node_word_count(node_filt, "bins") - end select - - ! Determine type of filter - select case (temp_str) - - case ('distribcell') - ! Allocate and declare the filter type - allocate(DistribcellFilter::t % filters(j) % obj) - select type (filt => t % filters(j) % obj) - type is (DistribcellFilter) - if (n_words /= 1) call fatal_error("Only one cell can be & - &specified per distribcell filter.") - ! Store bins - call get_node_value(node_filt, "bins", filt % cell) - end select - ! Set the filter index in the tally find_filter array + ! Set the filter index in the tally find_filter array + select type (filt => f % obj) + type is (DistribcellFilter) t % find_filter(FILTER_DISTRIBCELL) = j - - case ('cell') - ! Allocate and declare the filter type - allocate(CellFilter::t % filters(j) % obj) - select type (filt => t % filters(j) % obj) - type is (CellFilter) - ! Allocate and store bins - filt % n_bins = n_words - allocate(filt % cells(n_words)) - call get_node_array(node_filt, "bins", filt % cells) - end select - ! Set the filter index in the tally find_filter array + type is (CellFilter) t % find_filter(FILTER_CELL) = j - - case ('cellborn') - ! Allocate and declare the filter type - allocate(CellbornFilter::t % filters(j) % obj) - select type (filt => t % filters(j) % obj) - type is (CellbornFilter) - ! Allocate and store bins - filt % n_bins = n_words - allocate(filt % cells(n_words)) - call get_node_array(node_filt, "bins", filt % cells) - end select - ! Set the filter index in the tally find_filter array + type is (CellbornFilter) t % find_filter(FILTER_CELLBORN) = j - - case ('material') - ! Allocate and declare the filter type - allocate(MaterialFilter::t % filters(j) % obj) - select type (filt => t % filters(j) % obj) - type is (MaterialFilter) - ! Allocate and store bins - filt % n_bins = n_words - allocate(filt % materials(n_words)) - call get_node_array(node_filt, "bins", filt % materials) - end select - ! Set the filter index in the tally find_filter array + type is (MaterialFilter) t % find_filter(FILTER_MATERIAL) = j - - case ('universe') - ! Allocate and declare the filter type - allocate(UniverseFilter::t % filters(j) % obj) - select type (filt => t % filters(j) % obj) - type is (UniverseFilter) - ! Allocate and store bins - filt % n_bins = n_words - allocate(filt % universes(n_words)) - call get_node_array(node_filt, "bins", filt % universes) - end select - ! Set the filter index in the tally find_filter array + type is (UniverseFilter) t % find_filter(FILTER_UNIVERSE) = j - - case ('surface') - call fatal_error("Surface filter is not yet supported!") - ! Allocate and declare the filter type - allocate(SurfaceFilter::t % filters(j) % obj) - select type (filt => t % filters(j) % obj) - type is (SurfaceFilter) - ! Allocate and store bins - filt % n_bins = n_words - allocate(filt % surfaces(n_words)) - call get_node_array(node_filt, "bins", filt % surfaces) - end select - ! Set the filter index in the tally find_filter array + type is (SurfaceFilter) t % find_filter(FILTER_SURFACE) = j - - case ('mesh') - ! Allocate and declare the filter type - allocate(MeshFilter::t % filters(j) % obj) - select type (filt => t % filters(j) % obj) - type is (MeshFilter) - if (n_words /= 1) call fatal_error("Only one mesh can be & - &specified per mesh filter.") - - ! Determine id of mesh - call get_node_value(node_filt, "bins", id) - - ! Get pointer to mesh - if (mesh_dict % has_key(id)) then - i_mesh = mesh_dict % get_key(id) - m => meshes(i_mesh) - else - call fatal_error("Could not find mesh " // trim(to_str(id)) & - // " specified on tally " // trim(to_str(t % id))) - end if - - ! Determine number of bins - filt % n_bins = product(m % dimension) - - ! Store the index of the mesh - filt % mesh = i_mesh - end select - - ! Set the filter index in the tally find_filter array + type is (MeshFilter) t % find_filter(FILTER_MESH) = j - - case ('energy') - - ! Allocate and declare the filter type - allocate(EnergyFilter::t % filters(j) % obj) - select type (filt => t % filters(j) % obj) - type is (EnergyFilter) - ! Allocate and store bins - filt % n_bins = n_words - 1 - allocate(filt % bins(n_words)) - call get_node_array(node_filt, "bins", filt % bins) - - ! We can save tallying time if we know that the tally bins match - ! the energy group structure. In that case, the matching bin - ! index is simply the group (after flipping for the different - ! ordering of the library and tallying systems). - if (.not. run_CE) then - if (n_words == num_energy_groups + 1) then - if (all(filt % bins == energy_bins(num_energy_groups + 1:1:-1))) & - then - filt % matches_transport_groups = .true. - end if - end if - end if - end select - ! Set the filter index in the tally find_filter array + type is (EnergyFilter) t % find_filter(FILTER_ENERGYIN) = j - - case ('energyout') - ! Allocate and declare the filter type - allocate(EnergyoutFilter::t % filters(j) % obj) - select type (filt => t % filters(j) % obj) - type is (EnergyoutFilter) - ! Allocate and store bins - filt % n_bins = n_words - 1 - allocate(filt % bins(n_words)) - call get_node_array(node_filt, "bins", filt % bins) - - ! We can save tallying time if we know that the tally bins match - ! the energy group structure. In that case, the matching bin - ! index is simply the group (after flipping for the different - ! ordering of the library and tallying systems). - if (.not. run_CE) then - if (n_words == num_energy_groups + 1) then - if (all(filt % bins == energy_bins(num_energy_groups + 1:1:-1))) & - then - filt % matches_transport_groups = .true. - end if - end if - end if - end select - ! Set the filter index in the tally find_filter array + type is (EnergyoutFilter) t % find_filter(FILTER_ENERGYOUT) = j - ! Set to analog estimator t % estimator = ESTIMATOR_ANALOG - - case ('delayedgroup') - - ! Allocate and declare the filter type - allocate(DelayedGroupFilter::t % filters(j) % obj) - select type (filt => t % filters(j) % obj) - type is (DelayedGroupFilter) - ! Allocate and store bins - filt % n_bins = n_words - allocate(filt % groups(n_words)) - call get_node_array(node_filt, "bins", filt % groups) - - ! Check that bins are all are between 1 and MAX_DELAYED_GROUPS - do d = 1, n_words - if (filt % groups(d) < 1 .or. & - filt % groups(d) > MAX_DELAYED_GROUPS) then - call fatal_error("Encountered delayedgroup bin with index " & - // trim(to_str(filt % groups(d))) // " that is outside & - &the range of 1 to MAX_DELAYED_GROUPS ( " & - // trim(to_str(MAX_DELAYED_GROUPS)) // ")") - end if - end do - end select - ! Set the filter index in the tally find_filter array + type is (DelayedGroupFilter) t % find_filter(FILTER_DELAYEDGROUP) = j - - case ('mu') - ! Allocate and declare the filter type - allocate(MuFilter::t % filters(j) % obj) - select type (filt => t % filters(j) % obj) - type is (MuFilter) - ! Allocate and store bins - filt % n_bins = n_words - 1 - allocate(filt % bins(n_words)) - call get_node_array(node_filt, "bins", filt % bins) - - ! Allow a user to input a lone number which will mean that you - ! subdivide [-1,1] evenly with the input being the number of bins - if (n_words == 1) then - Nangle = int(filt % bins(1)) - if (Nangle > 1) then - filt % n_bins = Nangle - dangle = TWO / real(Nangle,8) - deallocate(filt % bins) - allocate(filt % bins(Nangle + 1)) - do iangle = 1, Nangle - filt % bins(iangle) = -ONE + (iangle - 1) * dangle - end do - filt % bins(Nangle + 1) = ONE - else - call fatal_error("Number of bins for mu filter must be& - & greater than 1 on tally " & - // trim(to_str(t % id)) // ".") - end if - end if - end select - ! Set the filter index in the tally find_filter array + type is (MuFilter) t % find_filter(FILTER_MU) = j - ! Set to analog estimator t % estimator = ESTIMATOR_ANALOG - - case ('polar') - ! Allocate and declare the filter type - allocate(PolarFilter::t % filters(j) % obj) - select type (filt => t % filters(j) % obj) - type is (PolarFilter) - ! Allocate and store bins - filt % n_bins = n_words - 1 - allocate(filt % bins(n_words)) - call get_node_array(node_filt, "bins", filt % bins) - - ! Allow a user to input a lone number which will mean that you - ! subdivide [0,pi] evenly with the input being the number of bins - if (n_words == 1) then - Nangle = int(filt % bins(1)) - if (Nangle > 1) then - filt % n_bins = Nangle - dangle = PI / real(Nangle,8) - deallocate(filt % bins) - allocate(filt % bins(Nangle + 1)) - do iangle = 1, Nangle - filt % bins(iangle) = (iangle - 1) * dangle - end do - filt % bins(Nangle + 1) = PI - else - call fatal_error("Number of bins for polar filter must be& - & greater than 1 on tally " & - // trim(to_str(t % id)) // ".") - end if - end if - end select - ! Set the filter index in the tally find_filter array + type is (PolarFilter) t % find_filter(FILTER_POLAR) = j - - case ('azimuthal') - ! Allocate and declare the filter type - allocate(AzimuthalFilter::t % filters(j) % obj) - select type (filt => t % filters(j) % obj) - type is (AzimuthalFilter) - ! Allocate and store bins - filt % n_bins = n_words - 1 - allocate(filt % bins(n_words)) - call get_node_array(node_filt, "bins", filt % bins) - - ! Allow a user to input a lone number which will mean that you - ! subdivide [-pi,pi) evenly with the input being the number of - ! bins - if (n_words == 1) then - Nangle = int(filt % bins(1)) - if (Nangle > 1) then - filt % n_bins = Nangle - dangle = TWO * PI / real(Nangle,8) - deallocate(filt % bins) - allocate(filt % bins(Nangle + 1)) - do iangle = 1, Nangle - filt % bins(iangle) = -PI + (iangle - 1) * dangle - end do - filt % bins(Nangle + 1) = PI - else - call fatal_error("Number of bins for azimuthal filter must be& - & greater than 1 on tally " & - // trim(to_str(t % id)) // ".") - end if - end if - end select - ! Set the filter index in the tally find_filter array + type is (AzimuthalFilter) t % find_filter(FILTER_AZIMUTHAL) = j - - case ('energyfunction') - ! Allocate and declare the filter type. - allocate(EnergyFunctionFilter::t % filters(j) % obj) - select type (filt => t % filters(j) % obj) - type is (EnergyFunctionFilter) - filt % n_bins = 1 - ! Make sure this is continuous-energy mode. - if (.not. run_CE) then - call fatal_error("EnergyFunction filters are only supported for & - &continuous-energy transport calculations") - end if - - ! Allocate and store energy grid. - if (.not. check_for_node(node_filt, "energy")) then - call fatal_error("Energy grid not specified for EnergyFunction & - &filter on tally " // trim(to_str(t % id))) - end if - n_words = node_word_count(node_filt, "energy") - allocate(filt % energy(n_words)) - call get_node_array(node_filt, "energy", filt % energy) - - ! Allocate and store interpolant values. - if (.not. check_for_node(node_filt, "y")) then - call fatal_error("y values not specified for EnergyFunction & - &filter on tally " // trim(to_str(t % id))) - end if - n_words = node_word_count(node_filt, "y") - allocate(filt % y(n_words)) - call get_node_array(node_filt, "y", filt % y) - end select - ! Set the filter index in the tally find_filter array + type is (EnergyFunctionFilter) t % find_filter(FILTER_ENERGYFUNCTION) = j - - case default - ! Specified tally filter is invalid, raise error - call fatal_error("Unknown filter type '" & - // trim(temp_str) // "' on tally " & - // trim(to_str(t % id)) // ".") - end select - end do READ_FILTERS + ! Store the index of the filter + temp_filter(j) = i_filt + end do + + ! Store the filter indices + call move_alloc(FROM=temp_filter, TO=t % filter) ! Check that both cell and surface weren't specified if (t % find_filter(FILTER_CELL) > 0 .and. & @@ -3754,27 +3815,65 @@ contains end if ! Get index of mesh filter - k = t % find_filter(FILTER_MESH) + i_filter_mesh = t % filter(t % find_filter(FILTER_MESH)) ! Check to make sure mesh filter was specified - if (k == 0) then + if (i_filter_mesh == 0) then call fatal_error("Cannot tally surface current without a mesh & &filter.") end if - ! Copy filters to temporary array - allocate(filters(size(t % filters) + 1)) - filters(1:size(t % filters)) = t % filters + ! Get pointer to mesh + select type(filt => filters(i_filter_mesh) % obj) + type is (MeshFilter) + i_mesh = filt % mesh + m => meshes(i_mesh) + end select - ! Move allocation back -- filters becomes deallocated during + ! Copy filter indices to temporary array + allocate(temp_filter(size(t % filter) + 1)) + temp_filter(1:size(t % filter)) = t % filter + + ! Move allocation back -- temp_filter becomes deallocated during ! this call - call move_alloc(FROM=filters, TO=t%filters) + call move_alloc(FROM=temp_filter, TO=t % filter) + n_filter = size(t % filter) + + ! Extend the filters array so we can add a surface filter and mesh + ! filter + call add_filters(2) + + ! Increment number of user filters + n_user_filters = n_user_filters + 2 + + ! Get index of the new mesh filter + i_filt = n_user_filters - 1 + + ! Duplicate the mesh filter since other tallies might use this + ! filter and we need to change the dimension + allocate(MeshFilter :: filters(i_filt) % obj) + select type(filt => filters(i_filt) % obj) + type is (MeshFilter) + filt % id = i_filt + filt % mesh = i_mesh + + ! We need to increase the dimension by one since we also need + ! currents coming into and out of the boundary mesh cells. + filt % n_bins = product(m % dimension + 1) + + ! Add filter to dictionary + call filter_dict % add_key(filt % id, i_filt) + end select + t % filter(t % find_filter(FILTER_MESH)) = i_filt + + ! Get index of the new surface filter + i_filt = n_user_filters ! Add surface filter - n_filters = size(t % filters) - allocate(SurfaceFilter :: t % filters(n_filters) % obj) - select type (filt => t % filters(size(t % filters)) % obj) + allocate(SurfaceFilter :: filters(i_filt) % obj) + select type (filt => filters(i_filt) % obj) type is (SurfaceFilter) + filt % id = i_filt filt % n_bins = 4 * m % n_dimension allocate(filt % surfaces(4 * m % n_dimension)) if (m % n_dimension == 1) then @@ -3787,12 +3886,16 @@ contains OUT_BACK, IN_BACK, OUT_FRONT, IN_FRONT, OUT_BOTTOM, & IN_BOTTOM, OUT_TOP, IN_TOP /) end if + filt % current = .true. + + ! Add filter to dictionary + call filter_dict % add_key(filt % id, i_filt) end select - t % find_filter(FILTER_SURFACE) = size(t % filters) + t % find_filter(FILTER_SURFACE) = n_filter + t % filter(n_filter) = i_filt case ('events') t % score_bins(j) = SCORE_EVENTS - case ('elastic', '(n,elastic)') t % score_bins(j) = ELASTIC case ('(n,2nd)') @@ -4542,8 +4645,8 @@ contains &meshlines on plot " // trim(to_str(pl % id))) end if - select type(filt => cmfd_tallies(1) % & - filters(cmfd_tallies(1) % find_filter(FILTER_MESH)) % obj) + select type(filt => filters(cmfd_tallies(1) % & + filter(cmfd_tallies(1) % find_filter(FILTER_MESH))) % obj) type is (MeshFilter) i_mesh = filt % mesh end select diff --git a/src/output.F90 b/src/output.F90 index f3ddddae5..10d4f0511 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -690,6 +690,7 @@ contains integer :: k ! loop index for scoring bins integer :: n ! loop index for nuclides integer :: l ! loop index for user scores + integer :: h ! loop index for tally filters integer :: indent ! number of spaces to preceed output integer :: filter_index ! index in results array for filters integer :: score_index ! scoring bin index @@ -802,26 +803,31 @@ contains ! to be used for a given tally. ! Initialize bins, filter level, and indentation - matching_bins(1:size(t % filters)) = 0 + do h = 1, size(t % filter) + call filter_matches(t % filter(h)) % bins % clear() + call filter_matches(t % filter(h)) % bins % push_back(0) + end do j = 1 indent = 0 print_bin: do find_bin: do ! Check for no filters - if (size(t % filters) == 0) exit find_bin + if (size(t % filter) == 0) exit find_bin ! Increment bin combination - matching_bins(j) = matching_bins(j) + 1 + filter_matches(t % filter(j)) % bins % data(1) = & + filter_matches(t % filter(j)) % bins % data(1) + 1 ! ================================================================= ! REACHED END OF BINS FOR THIS FILTER, MOVE TO NEXT FILTER - if (matching_bins(j) > t % filters(j) % obj % n_bins) then + if (filter_matches(t % filter(j)) % bins % data(1) > & + filters(t % filter(j)) % obj % n_bins) then ! If this is the first filter, then exit if (j == 1) exit print_bin - matching_bins(j) = 0 + filter_matches(t % filter(j)) % bins % data(1) = 0 j = j - 1 indent = indent - 2 @@ -830,11 +836,12 @@ contains else ! Check if this is last filter - if (j == size(t % filters)) exit find_bin + if (j == size(t % filter)) exit find_bin ! Print current filter information write(UNIT=unit_tally, FMT='(1X,2A)') repeat(" ", indent), & - trim(t % filters(j) % obj % text_label(matching_bins(j))) + trim(filters(t % filter(j)) % obj % & + text_label(filter_matches(t % filter(j)) % bins % data(1))) indent = indent + 2 j = j + 1 end if @@ -842,25 +849,25 @@ contains end do find_bin ! Print filter information - if (size(t % filters) > 0) then + if (size(t % filter) > 0) then write(UNIT=unit_tally, FMT='(1X,2A)') repeat(" ", indent), & - trim(t % filters(j) % obj % text_label(matching_bins(j))) + trim(filters(t % filter(j)) % obj % & + text_label(filter_matches(t % filter(j)) % bins % data(1))) end if ! Determine scoring index for this bin combination -- note that unlike ! in the score_tally subroutine, we have to use max(bins,1) since all ! bins below the lowest filter level will be zeros - if (size(t % filters) > 0) then - filter_index = sum((max(matching_bins(1:size(t % filters)),1) - 1) & - * t % stride) + 1 - else - filter_index = 1 - end if + filter_index = 1 + do h = 1, size(t % filter) + filter_index = filter_index + (max(filter_matches(t % filter(h)) & + % bins % data(1),1) - 1) * t % stride(h) + end do ! Write results for this filter bin combination score_index = 0 - if (size(t % filters) > 0) indent = indent + 2 + if (size(t % filter) > 0) indent = indent + 2 do n = 1, t % n_nuclide_bins ! Write label for nuclide i_nuclide = t % nuclide_bins(n) @@ -936,7 +943,7 @@ contains end do indent = indent - 2 - if (size(t % filters) == 0) exit print_bin + if (size(t % filter) == 0) exit print_bin end do print_bin @@ -956,6 +963,7 @@ contains integer, intent(in) :: unit_tally integer :: i ! mesh index + integer :: j ! loop index over tally filters integer :: ijk(3) ! indices of mesh cells integer :: n_dim ! number of mesh dimensions integer :: n_cells ! number of mesh cells @@ -963,28 +971,37 @@ contains integer :: i_filter_mesh ! index for mesh filter integer :: i_filter_ein ! index for incoming energy filter integer :: i_filter_surf ! index for surface filter + integer :: stride_surf ! stride for surface filter integer :: n ! number of incoming energy bins integer :: filter_index ! index in results array for filters logical :: print_ebin ! should incoming energy bin be displayed? + logical :: energy_filters ! energy filters present character(MAX_LINE_LEN) :: string type(RegularMesh), pointer :: m ! Get pointer to mesh - i_filter_mesh = t % find_filter(FILTER_MESH) - i_filter_surf = t % find_filter(FILTER_SURFACE) - select type(filt => t % filters(i_filter_mesh) % obj) + i_filter_mesh = t % filter(t % find_filter(FILTER_MESH)) + select type(filt => filters(i_filter_mesh) % obj) type is (MeshFilter) m => meshes(filt % mesh) end select + ! Get surface filter index and stride + i_filter_surf = t % filter(t % find_filter(FILTER_SURFACE)) + stride_surf = t % stride(t % find_filter(FILTER_SURFACE)) + ! initialize bins array - matching_bins(1:size(t % filters)) = 1 + do j = 1, size(t % filter) + call filter_matches(t % filter(j)) % bins % clear() + call filter_matches(t % filter(j)) % bins % push_back(1) + end do ! determine how many energy in bins there are - i_filter_ein = t % find_filter(FILTER_ENERGYIN) - if (i_filter_ein > 0) then + energy_filters = (t % find_filter(FILTER_ENERGYIN) > 0) + if (energy_filters) then print_ebin = .true. - n = t % filters(i_filter_ein) % obj % n_bins + i_filter_ein = t % filter(t % find_filter(FILTER_ENERGYIN)) + n = filters(i_filter_ein) % obj % n_bins else print_ebin = .false. n = 1 @@ -999,7 +1016,7 @@ contains ! Get the indices for this cell call bin_to_mesh_indices(m, i, ijk) - matching_bins(i_filter_mesh) = i + filter_matches(i_filter_mesh) % bins % data(1) = i ! Write the header for this cell if (n_dim == 1) then @@ -1017,119 +1034,115 @@ contains do l = 1, n if (print_ebin) then ! Set incoming energy bin - matching_bins(i_filter_ein) = l + filter_matches(i_filter_ein) % bins % data(1) = l ! Write incoming energy bin write(UNIT=unit_tally, FMT='(3X,A)') & - trim(t % filters(i_filter_ein) % obj % text_label( & - matching_bins(i_filter_ein))) + trim(filters(i_filter_ein) % obj % text_label( & + filter_matches(i_filter_ein) % bins % data(1))) end if + filter_index = 1 + do j = 1, size(t % filter) + if (t % filter(j) == i_filter_surf) cycle + filter_index = filter_index + (filter_matches(t % filter(j)) & + % bins % data(1) - 1) * t % stride(j) + end do + ! Left Surface - matching_bins(i_filter_surf) = OUT_LEFT - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') & "Outgoing Current on Left", & - to_str(t % results(RESULT_SUM,1,filter_index)), & - trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index))) + to_str(t % results(RESULT_SUM,1,filter_index + & + (OUT_LEFT - 1) * stride_surf)), & + trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index + & + (OUT_LEFT - 1) * stride_surf))) - matching_bins(i_filter_surf) = IN_LEFT - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') & "Incoming Current on Left", & - to_str(t % results(RESULT_SUM,1,filter_index)), & - trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index))) + to_str(t % results(RESULT_SUM,1,filter_index + & + (IN_LEFT - 1) * stride_surf)), & + trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index + & + (IN_LEFT - 1) * stride_surf))) ! Right Surface - matching_bins(i_filter_surf) = OUT_RIGHT - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') & "Outgoing Current on Right", & - to_str(t % results(RESULT_SUM,1,filter_index)), & - trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index))) + to_str(t % results(RESULT_SUM,1,filter_index + & + (OUT_RIGHT - 1) * stride_surf)), & + trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index + & + (OUT_RIGHT - 1) * stride_surf))) - matching_bins(i_filter_surf) = IN_RIGHT - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') & "Incoming Current on Right", & - to_str(t % results(RESULT_SUM,1,filter_index)), & - trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index))) + to_str(t % results(RESULT_SUM,1,filter_index + & + (IN_RIGHT - 1) * stride_surf)), & + trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index + & + (IN_RIGHT - 1) * stride_surf))) if (n_dim >= 2) then ! Back Surface - matching_bins(i_filter_surf) = OUT_BACK - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') & "Outgoing Current on Back", & - to_str(t % results(RESULT_SUM,1,filter_index)), & - trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index))) + to_str(t % results(RESULT_SUM,1,filter_index + & + (OUT_BACK - 1) * stride_surf)), & + trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index + & + (OUT_BACK - 1) * stride_surf))) - matching_bins(i_filter_surf) = IN_BACK - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') & "Incoming Current on Back", & - to_str(t % results(RESULT_SUM,1,filter_index)), & - trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index))) + to_str(t % results(RESULT_SUM,1,filter_index + & + (IN_BACK - 1) * stride_surf)), & + trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index + & + (IN_BACK - 1) * stride_surf))) ! Front Surface - matching_bins(i_filter_surf) = OUT_FRONT - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') & "Outgoing Current on Front", & - to_str(t % results(RESULT_SUM,1,filter_index)), & - trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index))) + to_str(t % results(RESULT_SUM,1,filter_index + & + (OUT_FRONT - 1) * stride_surf)), & + trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index + & + (OUT_FRONT - 1) * stride_surf))) - matching_bins(i_filter_surf) = IN_FRONT - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') & "Incoming Current on Front", & - to_str(t % results(RESULT_SUM,1,filter_index)), & - trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index))) + to_str(t % results(RESULT_SUM,1,filter_index + & + (IN_FRONT - 1) * stride_surf)), & + trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index + & + (IN_FRONT - 1) * stride_surf))) end if if (n_dim == 3) then + ! Bottom Surface - matching_bins(i_filter_surf) = OUT_BOTTOM - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') & "Outgoing Current on Bottom", & - to_str(t % results(RESULT_SUM,1,filter_index)), & - trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index))) + to_str(t % results(RESULT_SUM,1,filter_index + & + (OUT_BOTTOM - 1) * stride_surf)), & + trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index + & + (OUT_BOTTOM - 1) * stride_surf))) - matching_bins(i_filter_surf) = IN_BOTTOM - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') & "Incoming Current on Bottom", & - to_str(t % results(RESULT_SUM,1,filter_index)), & - trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index))) + to_str(t % results(RESULT_SUM,1,filter_index + & + (IN_BOTTOM - 1) * stride_surf)), & + trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index + & + (IN_BOTTOM - 1) * stride_surf))) ! Top Surface - matching_bins(i_filter_surf) = OUT_TOP - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') & "Outgoing Current on Top", & - to_str(t % results(RESULT_SUM,1,filter_index)), & - trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index))) + to_str(t % results(RESULT_SUM,1,filter_index + & + (OUT_TOP - 1) * stride_surf)), & + trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index + & + (OUT_TOP - 1) * stride_surf))) - matching_bins(i_filter_surf) = IN_TOP - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') & "Incoming Current on Top", & - to_str(t % results(RESULT_SUM,1,filter_index)), & - trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index))) + to_str(t % results(RESULT_SUM,1,filter_index + & + (IN_TOP - 1) * stride_surf)), & + trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index + & + (IN_TOP - 1) * stride_surf))) end if end do end do diff --git a/src/relaxng/tallies.rnc b/src/relaxng/tallies.rnc index 57f5f3747..4674fd4c0 100644 --- a/src/relaxng/tallies.rnc +++ b/src/relaxng/tallies.rnc @@ -32,15 +32,10 @@ element tallies { ) }* & - element tally { + element filter { (element id { xsd:int } | attribute id { xsd:int }) & - (element name { xsd:string { maxLength="52" } } | - attribute name { xsd:string { maxLength="52" } })? & - (element estimator { ( "analog" | "tracklength" | "collision" ) } | - attribute estimator { ( "analog" | "tracklength" | "collision" ) })? & - element filter { - ( - (element type { ( "cell" | "cellborn" | "material" | "universe" | + ( + ( (element type { ( "cell" | "cellborn" | "material" | "universe" | "surface" | "distribcell" | "mesh" | "energy" | "energyout" | "mu" | "polar" | "azimuthal" | "delayedgroup" | "energyfunction") } | attribute type { ( "cell" | "cellborn" | "material" | "universe" | @@ -57,7 +52,17 @@ element tallies { (element y { list { xsd:double+ } } | attribute y { list { xsd:double+ } }) ) - }* & + ) + }* & + + element tally { + (element id { xsd:int } | attribute id { xsd:int }) & + (element name { xsd:string { maxLength="52" } } | + attribute name { xsd:string { maxLength="52" } })? & + (element estimator { ( "analog" | "tracklength" | "collision" ) } | + attribute estimator { ( "analog" | "tracklength" | "collision" ) })? & + (element filters { list { xsd:int+ } } | + attribute filters { list { xsd:int+ } })? & element nuclides { list { xsd:string { maxLength = "12" }+ } }? & diff --git a/src/relaxng/tallies.rng b/src/relaxng/tallies.rng index fde06bac6..1c68e57e8 100644 --- a/src/relaxng/tallies.rng +++ b/src/relaxng/tallies.rng @@ -151,6 +151,120 @@ + + + + + + + + + + + + + + + + + cell + cellborn + material + universe + surface + distribcell + mesh + energy + energyout + mu + polar + azimuthal + delayedgroup + energyfunction + + + + + cell + cellborn + material + universe + surface + distribcell + mesh + energy + energyout + mu + polar + azimuthal + delayedgroup + energyfunction + + + + + + + + + + + + + + + + + + + + + + + + energyfunction + + + energyfunction + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -194,110 +308,24 @@ - - - - - - - - cell - cellborn - material - universe - surface - distribcell - mesh - energy - energyout - mu - polar - azimuthal - delayedgroup - energyfunction - - - - - cell - cellborn - material - universe - surface - distribcell - mesh - energy - energyout - mu - polar - azimuthal - delayedgroup - energyfunction - - - - - - - - - - - - - - - - - - - - - - - - energyfunction - - - energyfunction - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/src/simulation.F90 b/src/simulation.F90 index 13cc9b669..0cdb4c66d 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -186,9 +186,7 @@ contains tallies_on = .true. ! Add user tallies to active tallies list -!$omp parallel call setup_active_usertallies() -!$omp end parallel end if ! check CMFD initialize batch diff --git a/src/state_point.F90 b/src/state_point.F90 index c6790a3ef..e4c9a43ae 100644 --- a/src/state_point.F90 +++ b/src/state_point.F90 @@ -44,8 +44,8 @@ contains integer, allocatable :: id_array(:) integer(HID_T) :: file_id integer(HID_T) :: cmfd_group, tallies_group, tally_group, meshes_group, & - mesh_group, filter_group, derivs_group, deriv_group, & - runtime_group + mesh_group, filters_group, filter_group, derivs_group, & + deriv_group, runtime_group character(MAX_WORD_LEN), allocatable :: str_array(:) character(MAX_FILE_LEN) :: filename type(TallyObject), pointer :: tally @@ -206,6 +206,30 @@ contains call close_group(derivs_group) end if + ! Write number of filters + filters_group = create_group(tallies_group, "filters") + call write_attribute(filters_group, "n_filters", n_filters) + + if (n_filters > 0) then + ! Write IDs of filters + allocate(id_array(n_filters)) + do i = 1, n_filters + id_array(i) = filters(i) % obj % id + end do + call write_attribute(filters_group, "ids", id_array) + deallocate(id_array) + + ! Write filter information + FILTER_LOOP: do i = 1, n_filters + filter_group = create_group(filters_group, "filter " // & + trim(to_str(filters(i) % obj % id))) + call filters(i) % obj % to_statepoint(filter_group) + call close_group(filter_group) + end do FILTER_LOOP + end if + + call close_group(filters_group) + ! Write number of tallies call write_attribute(tallies_group, "n_tallies", n_tallies) @@ -239,15 +263,17 @@ contains end select call write_dataset(tally_group, "n_realizations", & tally % n_realizations) - call write_dataset(tally_group, "n_filters", size(tally % filters)) - ! Write filter information - FILTER_LOOP: do j = 1, size(tally % filters) - filter_group = create_group(tally_group, "filter " // & - trim(to_str(j))) - call tally % filters(j) % obj % to_statepoint(filter_group) - call close_group(filter_group) - end do FILTER_LOOP + call write_dataset(tally_group, "n_filters", size(tally % filter)) + if (size(tally % filter) > 0) then + ! Write IDs of filters + allocate(id_array(size(tally % filter))) + do j = 1, size(tally % filter) + id_array(j) = filters(tally % filter(j)) % obj % id + end do + call write_dataset(tally_group, "filters", id_array) + deallocate(id_array) + end if ! Set up nuclide bin array and then write allocate(str_array(tally % n_nuclide_bins)) diff --git a/src/tally.F90 b/src/tally.F90 index 248fb1664..0ee041cbe 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -519,7 +519,7 @@ contains ! Check if the delayed group filter is present if (dg_filter > 0) then - select type(filt => t % filters(dg_filter) % obj) + select type(filt => filters(t % filter(dg_filter)) % obj) type is (DelayedGroupFilter) ! Loop over all delayed group bins and tally to them @@ -564,7 +564,7 @@ contains ! Check if the delayed group filter is present if (dg_filter > 0) then - select type(filt => t % filters(dg_filter) % obj) + select type(filt => filters(t % filter(dg_filter)) % obj) type is (DelayedGroupFilter) ! Loop over all delayed group bins and tally to them @@ -596,7 +596,7 @@ contains ! Check if the delayed group filter is present if (dg_filter > 0) then - select type(filt => t % filters(dg_filter) % obj) + select type(filt => filters(t % filter(dg_filter)) % obj) type is (DelayedGroupFilter) ! Loop over all delayed group bins and tally to them @@ -629,7 +629,7 @@ contains ! Check if the delayed group filter is present if (dg_filter > 0) then - select type(filt => t % filters(dg_filter) % obj) + select type(filt => filters(t % filter(dg_filter)) % obj) type is (DelayedGroupFilter) ! Loop over all nuclides in the current material @@ -707,7 +707,7 @@ contains ! Check if the delayed group filter is present if (dg_filter > 0) then - select type(filt => t % filters(dg_filter) % obj) + select type(filt => filters(t % filter(dg_filter)) % obj) type is (DelayedGroupFilter) ! Loop over all delayed group bins and tally to them @@ -803,7 +803,7 @@ contains if (dg_filter > 0) then ! declare the delayed group filter type - select type(filt => t % filters(dg_filter) % obj) + select type(filt => filters(t % filter(dg_filter)) % obj) type is (DelayedGroupFilter) ! loop over delayed group bins until the corresponding bin @@ -833,7 +833,7 @@ contains ! Check if the delayed group filter is present if (dg_filter > 0) then - select type(filt => t % filters(dg_filter) % obj) + select type(filt => filters(t % filter(dg_filter)) % obj) type is (DelayedGroupFilter) ! Loop over all delayed group bins and tally to them @@ -888,7 +888,7 @@ contains ! Check if the delayed group filter is present if (dg_filter > 0) then - select type(filt => t % filters(dg_filter) % obj) + select type(filt => filters(t % filter(dg_filter)) % obj) type is (DelayedGroupFilter) ! Loop over all nuclides in the current material @@ -1742,7 +1742,7 @@ contains if (matxs % get_xs('absorption', p_g, UVW=p_uvw) > ZERO) then if (dg_filter > 0) then - select type(filt => t % filters(dg_filter) % obj) + select type(filt => filters(t % filter(dg_filter)) % obj) type is (DelayedGroupFilter) ! Loop over all delayed group bins and tally to them @@ -1789,7 +1789,7 @@ contains ! Check if the delayed group filter is present if (dg_filter > 0) then - select type(filt => t % filters(dg_filter) % obj) + select type(filt => filters(t % filter(dg_filter)) % obj) type is (DelayedGroupFilter) ! Loop over all delayed group bins and tally to them @@ -1825,7 +1825,7 @@ contains ! Check if the delayed group filter is present if (dg_filter > 0) then - select type(filt => t % filters(dg_filter) % obj) + select type(filt => filters(t % filter(dg_filter)) % obj) type is (DelayedGroupFilter) ! Loop over all delayed group bins and tally to them @@ -1871,7 +1871,7 @@ contains if (matxs % get_xs('absorption', p_g, UVW=p_uvw) > ZERO) then if (dg_filter > 0) then - select type(filt => t % filters(dg_filter) % obj) + select type(filt => filters(t % filter(dg_filter)) % obj) type is (DelayedGroupFilter) ! Loop over all delayed group bins and tally to them @@ -1961,7 +1961,7 @@ contains if (dg_filter > 0) then ! declare the delayed group filter type - select type(filt => t % filters(dg_filter) % obj) + select type(filt => filters(t % filter(dg_filter)) % obj) type is (DelayedGroupFilter) ! loop over delayed group bins until the corresponding bin @@ -1994,7 +1994,7 @@ contains ! Check if the delayed group filter is present if (dg_filter > 0) then - select type(filt => t % filters(dg_filter) % obj) + select type(filt => filters(t % filter(dg_filter)) % obj) type is (DelayedGroupFilter) ! Loop over all delayed group bins and tally to them @@ -2265,14 +2265,16 @@ contains type(Particle), intent(in) :: p - integer :: i + integer :: i, j integer :: i_tally integer :: i_filt + integer :: i_bin integer :: k ! loop index for nuclide bins - ! position during the loop integer :: filter_index ! single index for single bin integer :: i_nuclide ! index in nuclides array + integer :: matching_bin ! next valid filter bin real(8) :: filter_weight ! combined weight of all filters + logical :: finished ! found all valid bin combinations type(TallyObject), pointer :: t ! A loop over all tallies is necessary because we need to simultaneously @@ -2280,17 +2282,32 @@ contains TALLY_LOOP: do i = 1, active_analog_tallies % size() ! Get index of tally and pointer to tally - i_tally = active_analog_tallies % get_item(i) + i_tally = active_analog_tallies % data(i) t => tallies(i_tally) - ! Find the first bin in each filter. There may be more than one matching - ! bin per filter, but we'll deal with those later. - do i_filt = 1, size(t % filters) - call t % filters(i_filt) % obj % get_next_bin(p, t % estimator, & - NO_BIN_FOUND, matching_bins(i_filt), filter_weights(i_filt)) + ! Find all valid bins in each filter if they have not already been found + ! for a previous tally. + do j = 1, size(t % filter) + i_filt = t % filter(j) + if (.not. filter_matches(i_filt) % bins_present) then + call filter_matches(i_filt) % bins % clear() + call filter_matches(i_filt) % weights % clear() + matching_bin = NO_BIN_FOUND + do + call filters(i_filt) % obj % get_next_bin(p, t % estimator, & + matching_bin, matching_bin, filter_weight) + if (matching_bin == NO_BIN_FOUND) exit + call filter_matches(i_filt) % bins % push_back(matching_bin) + call filter_matches(i_filt) % weights % push_back(filter_weight) + end do + filter_matches(i_filt) % bins_present = .true. + end if ! If there are no valid bins for this filter, then there is nothing to ! score and we can move on to the next tally. - if (matching_bins(i_filt) == NO_BIN_FOUND) cycle TALLY_LOOP + if (filter_matches(i_filt) % bins % size() == 0) cycle TALLY_LOOP + + ! Set the index of the bin used in the first filter combination + filter_matches(i_filt) % i_bin = 1 end do ! ======================================================================== @@ -2298,10 +2315,19 @@ contains FILTER_LOOP: do + ! Reset scoring index and weight + filter_index = 1 + filter_weight = ONE + ! Determine scoring index and weight for this filter combination - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 - filter_weight = product(filter_weights(:size(t % filters))) + do j = 1, size(t % filter) + i_filt = t % filter(j) + i_bin = filter_matches(i_filt) % i_bin + filter_index = filter_index + (filter_matches(i_filt) % bins % & + data(i_bin) - 1) * t % stride(j) + filter_weight = filter_weight * filter_matches(i_filt) % weights % & + data(i_bin) + end do ! ====================================================================== ! Nuclide logic @@ -2351,34 +2377,25 @@ contains ! ====================================================================== ! Filter logic - ! If there are no filters, then we are done. - if (size(t % filters) == 0) exit FILTER_LOOP - - ! Increment the filter bins, starting with the last filter. If we get a - ! NO_BIN_FOUND for the last filter, it means we finished all valid bins - ! for that filter, but next-to-last filter might have more than one - ! valid bin so we need to increment that one as well, and so on. - do i_filt = size(t % filters), 1, -1 - call t % filters(i_filt) % obj % get_next_bin(p, t % estimator, & - matching_bins(i_filt), matching_bins(i_filt), & - filter_weights(i_filt)) - if (matching_bins(i_filt) /= NO_BIN_FOUND) exit - end do - - ! If we got all NO_BIN_FOUNDs, then we have finished all valid bins for - ! each of the filters. Exit the loop. - if (all(matching_bins(:size(t % filters)) == NO_BIN_FOUND)) & - exit FILTER_LOOP - - ! Reset all the filters with NO_BIN_FOUND. This will set them back to - ! their first valid bin. - do i_filt = 1, size(t % filters) - if (matching_bins(i_filt) == NO_BIN_FOUND) then - call t % filters(i_filt) % obj % get_next_bin(p, t % estimator, & - matching_bins(i_filt), matching_bins(i_filt), & - filter_weights(i_filt)) + ! Increment the filter bins, starting with the last filter to find the + ! next valid bin combination + finished = .true. + do j = size(t % filter), 1, -1 + i_filt = t % filter(j) + if (filter_matches(i_filt) % i_bin < filter_matches(i_filt) % & + bins % size()) then + filter_matches(i_filt) % i_bin = filter_matches(i_filt) % i_bin + 1 + finished = .false. + exit + else + filter_matches(i_filt) % i_bin = 1 end if end do + + ! Once we have finished all valid bins for each of the filters, exit + ! the loop. + if (finished) exit FILTER_LOOP + end do FILTER_LOOP ! If the user has specified that we can assume all tallies are spatially @@ -2390,6 +2407,9 @@ contains end do TALLY_LOOP + ! Reset filter matches flag + filter_matches(:) % bins_present = .false. + ! Reset tally map positioning position = 0 @@ -2399,15 +2419,17 @@ contains type(Particle), intent(in) :: p - integer :: i, m + integer :: i, j, m integer :: i_tally integer :: i_filt + integer :: i_bin integer :: k ! loop index for nuclide bins - ! position during the loop integer :: filter_index ! single index for single bin integer :: i_nuclide ! index in nuclides array + integer :: matching_bin ! next valid filter bin real(8) :: filter_weight ! combined weight of all filters real(8) :: atom_density + logical :: finished ! found all valid bin combinations type(TallyObject), pointer :: t type(Material), pointer :: mat @@ -2416,21 +2438,36 @@ contains TALLY_LOOP: do i = 1, active_analog_tallies % size() ! Get index of tally and pointer to tally - i_tally = active_analog_tallies % get_item(i) + i_tally = active_analog_tallies % data(i) t => tallies(i_tally) ! Get pointer to current material. We need this in order to determine what ! nuclides are in the material mat => materials(p % material) - ! Find the first bin in each filter. There may be more than one matching - ! bin per filter, but we'll deal with those later. - do i_filt = 1, size(t % filters) - call t % filters(i_filt) % obj % get_next_bin(p, t % estimator, & - NO_BIN_FOUND, matching_bins(i_filt), filter_weights(i_filt)) + ! Find all valid bins in each filter if they have not already been found + ! for a previous tally. + do j = 1, size(t % filter) + i_filt = t % filter(j) + if (.not. filter_matches(i_filt) % bins_present) then + call filter_matches(i_filt) % bins % clear() + call filter_matches(i_filt) % weights % clear() + matching_bin = NO_BIN_FOUND + do + call filters(i_filt) % obj % get_next_bin(p, t % estimator, & + matching_bin, matching_bin, filter_weight) + if (matching_bin == NO_BIN_FOUND) exit + call filter_matches(i_filt) % bins % push_back(matching_bin) + call filter_matches(i_filt) % weights % push_back(filter_weight) + end do + filter_matches(i_filt) % bins_present = .true. + end if ! If there are no valid bins for this filter, then there is nothing to ! score and we can move on to the next tally. - if (matching_bins(i_filt) == NO_BIN_FOUND) cycle TALLY_LOOP + if (filter_matches(i_filt) % bins % size() == 0) cycle TALLY_LOOP + + ! Set the index of the bin used in the first filter combination + filter_matches(i_filt) % i_bin = 1 end do ! ======================================================================== @@ -2438,10 +2475,19 @@ contains FILTER_LOOP: do + ! Reset scoring index and weight + filter_index = 1 + filter_weight = ONE + ! Determine scoring index and weight for this filter combination - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 - filter_weight = product(filter_weights(:size(t % filters))) + do j = 1, size(t % filter) + i_filt = t % filter(j) + i_bin = filter_matches(i_filt) % i_bin + filter_index = filter_index + (filter_matches(i_filt) % bins % & + data(i_bin) - 1) * t % stride(j) + filter_weight = filter_weight * filter_matches(i_filt) % weights % & + data(i_bin) + end do ! ====================================================================== ! Nuclide logic @@ -2479,34 +2525,25 @@ contains ! ====================================================================== ! Filter logic - ! If there are no filters, then we are done. - if (size(t % filters) == 0) exit FILTER_LOOP - - ! Increment the filter bins, starting with the last filter. If we get a - ! NO_BIN_FOUND for the last filter, it means we finished all valid bins - ! for that filter, but next-to-last filter might have more than one - ! valid bin so we need to increment that one as well, and so on. - do i_filt = size(t % filters), 1, -1 - call t % filters(i_filt) % obj % get_next_bin(p, t % estimator, & - matching_bins(i_filt), matching_bins(i_filt), & - filter_weights(i_filt)) - if (matching_bins(i_filt) /= NO_BIN_FOUND) exit - end do - - ! If we got all NO_BIN_FOUNDs, then we have finished all valid bins for - ! each of the filters. Exit the loop. - if (all(matching_bins(:size(t % filters)) == NO_BIN_FOUND)) & - exit FILTER_LOOP - - ! Reset all the filters with NO_BIN_FOUND. This will set them back to - ! their first valid bin. - do i_filt = 1, size(t % filters) - if (matching_bins(i_filt) == NO_BIN_FOUND) then - call t % filters(i_filt) % obj % get_next_bin(p, t % estimator, & - matching_bins(i_filt), matching_bins(i_filt), & - filter_weights(i_filt)) + ! Increment the filter bins, starting with the last filter to find the + ! next valid bin combination + finished = .true. + do j = size(t % filter), 1, -1 + i_filt = t % filter(j) + if (filter_matches(i_filt) % i_bin < filter_matches(i_filt) % & + bins % size()) then + filter_matches(i_filt) % i_bin = filter_matches(i_filt) % i_bin + 1 + finished = .false. + exit + else + filter_matches(i_filt) % i_bin = 1 end if end do + + ! Once we have finished all valid bins for each of the filters, exit + ! the loop. + if (finished) exit FILTER_LOOP + end do FILTER_LOOP ! If the user has specified that we can assume all tallies are spatially @@ -2518,6 +2555,9 @@ contains end do TALLY_LOOP + ! Reset filter matches flag + filter_matches(:) % bins_present = .false. + ! Reset tally map positioning position = 0 @@ -2544,6 +2584,10 @@ contains integer :: d_bin ! delayed group bin index integer :: n ! number of energies on filter integer :: k ! loop index for bank sites + integer :: l ! loop index for tally filters + integer :: f ! index in filters array + integer :: b ! index of filter bin + integer :: i_bin ! index of matching filter bin integer :: bin_energyout ! original outgoing energy bin integer :: i_filter ! index for matching filter bin combination real(8) :: filter_weight ! combined weight of all filters @@ -2552,11 +2596,12 @@ contains integer :: g_out ! energy group of fission bank site ! save original outgoing energy bin and score index - i = t % find_filter(FILTER_ENERGYOUT) - bin_energyout = matching_bins(i) + i = t % filter(t % find_filter(FILTER_ENERGYOUT)) + i_bin = filter_matches(i) % i_bin + bin_energyout = filter_matches(i) % bins % data(i_bin) ! declare the energyout filter type - select type(eo_filt => t % filters(i) % obj) + select type(eo_filt => filters(i) % obj) type is (EnergyoutFilter) ! Get number of energies on filter @@ -2593,7 +2638,7 @@ contains g_out = size(eo_filt % bins) - g_out ! change outgoing energy bin - matching_bins(i) = g_out + filter_matches(i) % bins % data(i_bin) = g_out else @@ -2609,7 +2654,8 @@ contains if (E_out < eo_filt % bins(1) .or. E_out > eo_filt % bins(n)) cycle ! change outgoing energy bin - matching_bins(i) = binary_search(eo_filt % bins, n, E_out) + filter_matches(i) % bins % data(i_bin) = & + binary_search(eo_filt % bins, n, E_out) end if @@ -2618,8 +2664,12 @@ contains (score_bin == SCORE_PROMPT_NU_FISSION .and. g == 0)) then ! determine scoring index and weight for this filter combination - i_filter = sum((matching_bins(1:size(t%filters)) - 1) * t % stride) & - + 1 + i_filter = 1 + do l = 1, size(t % filter) + i_filter = i_filter + (filter_matches(t % filter(l)) % bins % & + data(filter_matches(t % filter(l)) % i_bin) - 1) * & + t % stride(l) + end do ! Add score to tally !$omp atomic @@ -2637,7 +2687,7 @@ contains if (j > 0) then ! declare the delayed group filter type - select type(dg_filt => t % filters(j) % obj) + select type(dg_filt => filters(t % filter(j)) % obj) type is (DelayedGroupFilter) ! loop over delayed group bins until the corresponding bin is @@ -2649,11 +2699,20 @@ contains ! the delayed group of this bin if (d == g) then + ! Reset scoring index and filter weight + i_filter = 1 + filter_weight = ONE + ! determine scoring index and weight for this filter ! combination - i_filter = sum((matching_bins(1:size(t%filters)) - 1) * & - t % stride) + 1 - filter_weight = product(filter_weights(:size(t % filters))) + do l = 1, size(t % filter) + f = t % filter(l) + b = filter_matches(f) % i_bin + i_filter = i_filter + (filter_matches(f) % bins % & + data(b) - 1) * t % stride(l) + filter_weight = filter_weight * filter_matches(f) % & + weights % data(b) + end do call score_fission_delayed_dg(t, d_bin, & score * filter_weight, i_score) @@ -2664,10 +2723,19 @@ contains ! if the delayed group filter is not present, add score to tally else + ! Reset scoring index and filter weight + i_filter = 1 + filter_weight = ONE + ! determine scoring index and weight for this filter combination - i_filter = sum((matching_bins(1:size(t%filters)) - 1) * t % stride)& - + 1 - filter_weight = product(filter_weights(:size(t % filters))) + do l = 1, size(t % filter) + f = t % filter(l) + b = filter_matches(f) % i_bin + i_filter = i_filter + (filter_matches(f) % bins % data(b) - 1) & + * t % stride(l) + filter_weight = filter_weight * filter_matches(f) % weights % & + data(b) + end do ! Add score to tally !$omp atomic @@ -2679,7 +2747,7 @@ contains end select ! reset outgoing energy bin and score index - matching_bins(i) = bin_energyout + filter_matches(i) % bins % data(i_bin) = bin_energyout end subroutine score_fission_eout @@ -2695,23 +2763,31 @@ contains real(8), intent(in) :: score ! actual score integer, intent(in) :: score_index ! index for score + integer :: i ! loop over tally filters + integer :: i_filt ! index in filters array + integer :: i_bin ! index of matching filter bin integer :: bin_original ! original bin index integer :: filter_index ! index for matching filter bin combination ! save original delayed group bin - bin_original = matching_bins(t % find_filter(FILTER_DELAYEDGROUP)) - matching_bins(t % find_filter(FILTER_DELAYEDGROUP)) = d_bin + i_filt = t % filter(t % find_filter(FILTER_DELAYEDGROUP)) + i_bin = filter_matches(i_filt) % i_bin + bin_original = filter_matches(i_filt) % bins % data(i_bin) + filter_matches(i_filt) % bins % data(i_bin) = d_bin - ! determine scoring index and weight on the modified matching_bins - filter_index = sum((matching_bins(1:size(t % filters)) - 1) * t % stride) & - + 1 + ! determine scoring index and weight on the modified matching bins + filter_index = 1 + do i = 1, size(t % filter) + filter_index = filter_index + (filter_matches(t % filter(i)) % bins % & + data(filter_matches(t % filter(i)) % i_bin) - 1) * t % stride(i) + end do !$omp atomic t % results(RESULT_VALUE, score_index, filter_index) = & t % results(RESULT_VALUE, score_index, filter_index) + score ! reset original delayed group bin - matching_bins(t % find_filter(FILTER_DELAYEDGROUP)) = bin_original + filter_matches(i_filt) % bins % data(i_bin) = bin_original end subroutine score_fission_delayed_dg @@ -2730,13 +2806,16 @@ contains integer :: i integer :: i_tally integer :: i_filt + integer :: i_bin integer :: j ! loop index for scoring bins integer :: k ! loop index for nuclide bins integer :: filter_index ! single index for single bin integer :: i_nuclide ! index in nuclides array (from bins) + integer :: matching_bin ! next valid filter bin real(8) :: flux ! tracklength estimate of flux real(8) :: atom_density ! atom density of single nuclide in atom/b-cm real(8) :: filter_weight ! combined weight of all filters + logical :: finished ! found all valid bin combinations type(TallyObject), pointer :: t type(Material), pointer :: mat @@ -2748,17 +2827,32 @@ contains TALLY_LOOP: do i = 1, active_tracklength_tallies % size() ! Get index of tally and pointer to tally - i_tally = active_tracklength_tallies % get_item(i) + i_tally = active_tracklength_tallies % data(i) t => tallies(i_tally) - ! Find the first bin in each filter. There may be more than one matching - ! bin per filter, but we'll deal with those later. - do i_filt = 1, size(t % filters) - call t % filters(i_filt) % obj % get_next_bin(p, t % estimator, & - NO_BIN_FOUND, matching_bins(i_filt), filter_weights(i_filt)) + ! Find all valid bins in each filter if they have not already been found + ! for a previous tally. + do j = 1, size(t % filter) + i_filt = t % filter(j) + if (.not. filter_matches(i_filt) % bins_present) then + call filter_matches(i_filt) % bins % clear() + call filter_matches(i_filt) % weights % clear() + matching_bin = NO_BIN_FOUND + do + call filters(i_filt) % obj % get_next_bin(p, t % estimator, & + matching_bin, matching_bin, filter_weight) + if (matching_bin == NO_BIN_FOUND) exit + call filter_matches(i_filt) % bins % push_back(matching_bin) + call filter_matches(i_filt) % weights % push_back(filter_weight) + end do + filter_matches(i_filt) % bins_present = .true. + end if ! If there are no valid bins for this filter, then there is nothing to ! score and we can move on to the next tally. - if (matching_bins(i_filt) == NO_BIN_FOUND) cycle TALLY_LOOP + if (filter_matches(i_filt) % bins % size() == 0) cycle TALLY_LOOP + + ! Set the index of the bin used in the first filter combination + filter_matches(i_filt) % i_bin = 1 end do ! ======================================================================== @@ -2766,10 +2860,19 @@ contains FILTER_LOOP: do + ! Reset scoring index and weight + filter_index = 1 + filter_weight = ONE + ! Determine scoring index and weight for this filter combination - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 - filter_weight = product(filter_weights(:size(t % filters))) + do j = 1, size(t % filter) + i_filt = t % filter(j) + i_bin = filter_matches(i_filt) % i_bin + filter_index = filter_index + (filter_matches(i_filt) % bins % & + data(i_bin) - 1) * t % stride(j) + filter_weight = filter_weight * filter_matches(i_filt) % weights % & + data(i_bin) + end do ! ====================================================================== ! Nuclide logic @@ -2820,34 +2923,25 @@ contains ! ====================================================================== ! Filter logic - ! If there are no filters, then we are done. - if (size(t % filters) == 0) exit FILTER_LOOP - - ! Increment the filter bins, starting with the last filter. If we get a - ! NO_BIN_FOUND for the last filter, it means we finished all valid bins - ! for that filter, but next-to-last filter might have more than one - ! valid bin so we need to increment that one as well, and so on. - do i_filt = size(t % filters), 1, -1 - call t % filters(i_filt) % obj % get_next_bin(p, t % estimator, & - matching_bins(i_filt), matching_bins(i_filt), & - filter_weights(i_filt)) - if (matching_bins(i_filt) /= NO_BIN_FOUND) exit - end do - - ! If we got all NO_BIN_FOUNDs, then we have finished all valid bins for - ! each of the filters. Exit the loop. - if (all(matching_bins(:size(t % filters)) == NO_BIN_FOUND)) & - exit FILTER_LOOP - - ! Reset all the filters with NO_BIN_FOUND. This will set them back to - ! their first valid bin. - do i_filt = 1, size(t % filters) - if (matching_bins(i_filt) == NO_BIN_FOUND) then - call t % filters(i_filt) % obj % get_next_bin(p, t % estimator, & - matching_bins(i_filt), matching_bins(i_filt), & - filter_weights(i_filt)) + ! Increment the filter bins, starting with the last filter to find the + ! next valid bin combination + finished = .true. + do j = size(t % filter), 1, -1 + i_filt = t % filter(j) + if (filter_matches(i_filt) % i_bin < filter_matches(i_filt) % & + bins % size()) then + filter_matches(i_filt) % i_bin = filter_matches(i_filt) % i_bin + 1 + finished = .false. + exit + else + filter_matches(i_filt) % i_bin = 1 end if end do + + ! Once we have finished all valid bins for each of the filters, exit + ! the loop. + if (finished) exit FILTER_LOOP + end do FILTER_LOOP ! If the user has specified that we can assume all tallies are spatially @@ -2859,6 +2953,9 @@ contains end do TALLY_LOOP + ! Reset filter matches flag + filter_matches(:) % bins_present = .false. + ! Reset tally map positioning position = 0 @@ -2879,14 +2976,17 @@ contains integer :: i integer :: i_tally integer :: i_filt + integer :: i_bin integer :: j ! loop index for scoring bins integer :: k ! loop index for nuclide bins integer :: filter_index ! single index for single bin integer :: i_nuclide ! index in nuclides array (from bins) + integer :: matching_bin ! next valid filter bin real(8) :: flux ! collision estimate of flux real(8) :: atom_density ! atom density of single nuclide ! in atom/b-cm real(8) :: filter_weight ! combined weight of all filters + logical :: finished ! found all valid bin combinations type(TallyObject), pointer :: t type(Material), pointer :: mat @@ -2903,17 +3003,32 @@ contains TALLY_LOOP: do i = 1, active_collision_tallies % size() ! Get index of tally and pointer to tally - i_tally = active_collision_tallies % get_item(i) + i_tally = active_collision_tallies % data(i) t => tallies(i_tally) - ! Find the first bin in each filter. There may be more than one matching - ! bin per filter, but we'll deal with those later. - do i_filt = 1, size(t % filters) - call t % filters(i_filt) % obj % get_next_bin(p, t % estimator, & - NO_BIN_FOUND, matching_bins(i_filt), filter_weights(i_filt)) + ! Find all valid bins in each filter if they have not already been found + ! for a previous tally. + do j = 1, size(t % filter) + i_filt = t % filter(j) + if (.not. filter_matches(i_filt) % bins_present) then + call filter_matches(i_filt) % bins % clear() + call filter_matches(i_filt) % weights % clear() + matching_bin = NO_BIN_FOUND + do + call filters(i_filt) % obj % get_next_bin(p, t % estimator, & + matching_bin, matching_bin, filter_weight) + if (matching_bin == NO_BIN_FOUND) exit + call filter_matches(i_filt) % bins % push_back(matching_bin) + call filter_matches(i_filt) % weights % push_back(filter_weight) + end do + filter_matches(i_filt) % bins_present = .true. + end if ! If there are no valid bins for this filter, then there is nothing to ! score and we can move on to the next tally. - if (matching_bins(i_filt) == NO_BIN_FOUND) cycle TALLY_LOOP + if (filter_matches(i_filt) % bins % size() == 0) cycle TALLY_LOOP + + ! Set the index of the bin used in the first filter combination + filter_matches(i_filt) % i_bin = 1 end do ! ======================================================================== @@ -2921,10 +3036,19 @@ contains FILTER_LOOP: do + ! Reset scoring index and weight + filter_index = 1 + filter_weight = ONE + ! Determine scoring index and weight for this filter combination - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 - filter_weight = product(filter_weights(:size(t % filters))) + do j = 1, size(t % filter) + i_filt = t % filter(j) + i_bin = filter_matches(i_filt) % i_bin + filter_index = filter_index + (filter_matches(i_filt) % bins % & + data(i_bin) - 1) * t % stride(j) + filter_weight = filter_weight * filter_matches(i_filt) % weights % & + data(i_bin) + end do ! ====================================================================== ! Nuclide logic @@ -2975,34 +3099,25 @@ contains ! ====================================================================== ! Filter logic - ! If there are no filters, then we are done. - if (size(t % filters) == 0) exit FILTER_LOOP - - ! Increment the filter bins, starting with the last filter. If we get a - ! NO_BIN_FOUND for the last filter, it means we finished all valid bins - ! for that filter, but next-to-last filter might have more than one - ! valid bin so we need to increment that one as well, and so on. - do i_filt = size(t % filters), 1, -1 - call t % filters(i_filt) % obj % get_next_bin(p, t % estimator, & - matching_bins(i_filt), matching_bins(i_filt), & - filter_weights(i_filt)) - if (matching_bins(i_filt) /= NO_BIN_FOUND) exit - end do - - ! If we got all NO_BIN_FOUNDs, then we have finished all valid bins for - ! each of the filters. Exit the loop. - if (all(matching_bins(:size(t % filters)) == NO_BIN_FOUND)) & - exit FILTER_LOOP - - ! Reset all the filters with NO_BIN_FOUND. This will set them back to - ! their first valid bin. - do i_filt = 1, size(t % filters) - if (matching_bins(i_filt) == NO_BIN_FOUND) then - call t % filters(i_filt) % obj % get_next_bin(p, t % estimator, & - matching_bins(i_filt), matching_bins(i_filt), & - filter_weights(i_filt)) + ! Increment the filter bins, starting with the last filter to find the + ! next valid bin combination + finished = .true. + do j = size(t % filter), 1, -1 + i_filt = t % filter(j) + if (filter_matches(i_filt) % i_bin < filter_matches(i_filt) % & + bins % size()) then + filter_matches(i_filt) % i_bin = filter_matches(i_filt) % i_bin + 1 + finished = .false. + exit + else + filter_matches(i_filt) % i_bin = 1 end if end do + + ! Once we have finished all valid bins for each of the filters, exit + ! the loop. + if (finished) exit FILTER_LOOP + end do FILTER_LOOP ! If the user has specified that we can assume all tallies are spatially @@ -3014,6 +3129,9 @@ contains end do TALLY_LOOP + ! Reset filter matches flag + filter_matches(:) % bins_present = .false. + ! Reset tally map positioning position = 0 @@ -3030,7 +3148,7 @@ contains integer :: i integer :: i_tally - integer :: j ! loop indices + integer :: j, k ! loop indices integer :: n_dim ! num dimensions of the mesh integer :: d1 ! dimension index integer :: d2 ! dimension index @@ -3049,9 +3167,11 @@ contains real(8) :: d(3) ! distance to each bounding surface real(8) :: distance ! actual distance traveled real(8) :: filt_score ! score applied by filters + integer :: matching_bin ! next valid filter bin logical :: start_in_mesh ! particle's starting xyz in mesh? logical :: end_in_mesh ! particle's ending xyz in mesh? logical :: cross_surface ! whether the particle crosses a surface + logical :: energy_filter ! energy filter present type(TallyObject), pointer :: t type(RegularMesh), pointer :: m @@ -3061,16 +3181,28 @@ contains xyz1 = p % coord(1) % xyz ! Get pointer to tally - i_tally = active_current_tallies % get_item(i) + i_tally = active_current_tallies % data(i) t => tallies(i_tally) + ! Check for energy filter + energy_filter = (t % find_filter(FILTER_ENERGYIN) > 0) + ! Get index for mesh, surface, and energy filters - i_filter_mesh = t % find_filter(FILTER_MESH) - i_filter_surf = t % find_filter(FILTER_SURFACE) - i_filter_energy = t % find_filter(FILTER_ENERGYIN) + i_filter_mesh = t % filter(t % find_filter(FILTER_MESH)) + i_filter_surf = t % filter(t % find_filter(FILTER_SURFACE)) + if (energy_filter) then + i_filter_energy = t % filter(t % find_filter(FILTER_ENERGYIN)) + end if + + ! Reset the matching bins arrays + call filter_matches(i_filter_mesh) % bins % resize(1) + call filter_matches(i_filter_surf) % bins % resize(1) + if (energy_filter) then + call filter_matches(i_filter_energy) % bins % resize(1) + end if ! Get pointer to mesh - select type(filt => t % filters(i_filter_mesh) % obj) + select type(filt => filters(i_filter_mesh) % obj) type is (MeshFilter) m => meshes(filt % mesh) end select @@ -3104,11 +3236,11 @@ contains ! Determine incoming energy bin. We need to tell the energy filter this ! is a tracklength tally so it uses the pre-collision energy. - if (i_filter_energy > 0) then - call t % filters(i_filter_energy) % obj % get_next_bin(p, & - ESTIMATOR_TRACKLENGTH, NO_BIN_FOUND, & - matching_bins(i_filter_energy), filt_score) - if (matching_bins(i_filter_energy) == NO_BIN_FOUND) cycle + if (energy_filter) then + call filters(i_filter_energy) % obj % get_next_bin(p, & + ESTIMATOR_TRACKLENGTH, NO_BIN_FOUND, matching_bin, filt_score) + if (matching_bin == NO_BIN_FOUND) cycle + filter_matches(i_filter_energy) % bins % data(1) = matching_bin end if ! Bounding coordinates @@ -3122,7 +3254,7 @@ contains do j = 1, n_cross ! Reset scoring bin index - matching_bins(i_filter_surf) = 0 + filter_matches(i_filter_surf) % bins % data(1) = 0 ! Set the distances to infinity d = INFINITY @@ -3164,11 +3296,14 @@ contains ! Outward current on d1 max surface if (all(ijk0(:n_dim) >= 1) .and. & all(ijk0(:n_dim) <= m % dimension)) then - matching_bins(i_filter_surf) = d1 * 4 - 1 - matching_bins(i_filter_mesh) = & + filter_matches(i_filter_surf) % bins % data(1) = d1 * 4 - 1 + filter_matches(i_filter_mesh) % bins % data(1) = & mesh_indices_to_bin(m, ijk0) - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 + filter_index = 1 + do k = 1, size(t % filter) + filter_index = filter_index + (filter_matches(t % & + filter(k)) % bins % data(1) - 1) * t % stride(k) + end do !$omp atomic t % results(RESULT_VALUE, 1, filter_index) = & t % results(RESULT_VALUE, 1, filter_index) + p % wgt @@ -3200,11 +3335,14 @@ contains ! If the particle crossed the surface, tally the current if (cross_surface) then ijk0(d1) = ijk0(d1) + 1 - matching_bins(i_filter_surf) = d1 * 4 - 2 - matching_bins(i_filter_mesh) = & + filter_matches(i_filter_surf) % bins % data(1) = d1 * 4 - 2 + filter_matches(i_filter_mesh) % bins % data(1) = & mesh_indices_to_bin(m, ijk0) - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 + filter_index = 1 + do k = 1, size(t % filter) + filter_index = filter_index + (filter_matches(t % & + filter(k)) % bins % data(1) - 1) * t % stride(k) + end do !$omp atomic t % results(RESULT_VALUE, 1, filter_index) = & t % results(RESULT_VALUE, 1, filter_index) + p % wgt @@ -3220,11 +3358,14 @@ contains ! Outward current on d1 min surface if (all(ijk0(:n_dim) >= 1) .and. & all(ijk0(:n_dim) <= m % dimension)) then - matching_bins(i_filter_surf) = d1 * 4 - 3 - matching_bins(i_filter_mesh) = & + filter_matches(i_filter_surf) % bins % data(1) = d1 * 4 - 3 + filter_matches(i_filter_mesh) % bins % data(1) = & mesh_indices_to_bin(m, ijk0) - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 + filter_index = 1 + do k = 1, size(t % filter) + filter_index = filter_index + (filter_matches(t % & + filter(k)) % bins % data(1) - 1) * t % stride(k) + end do !$omp atomic t % results(RESULT_VALUE, 1, filter_index) = & t % results(RESULT_VALUE, 1, filter_index) + p % wgt @@ -3256,11 +3397,14 @@ contains ! If the particle crossed the surface, tally the current if (cross_surface) then ijk0(d1) = ijk0(d1) - 1 - matching_bins(i_filter_surf) = d1 * 4 - matching_bins(i_filter_mesh) = & + filter_matches(i_filter_surf) % bins % data(1) = d1 * 4 + filter_matches(i_filter_mesh) % bins % data(1) = & mesh_indices_to_bin(m, ijk0) - filter_index = sum((matching_bins(1:size(t % filters)) - 1) & - * t % stride) + 1 + filter_index = 1 + do k = 1, size(t % filter) + filter_index = filter_index + (filter_matches(t % & + filter(k)) % bins % data(1) - 1) * t % stride(k) + end do !$omp atomic t % results(RESULT_VALUE, 1, filter_index) = & t % results(RESULT_VALUE, 1, filter_index) + p % wgt @@ -4082,7 +4226,7 @@ contains if (master .or. (.not. reduce_tallies)) then ! Accumulate results for each tally do i = 1, active_tallies % size() - call accumulate_tally(tallies(active_tallies % get_item(i))) + call accumulate_tally(tallies(active_tallies % data(i))) end do if (run_mode == MODE_EIGENVALUE) then @@ -4127,7 +4271,7 @@ contains type(TallyObject), pointer :: t do i = 1, active_tallies % size() - t => tallies(active_tallies % get_item(i)) + t => tallies(active_tallies % data(i)) m = t % total_score_bins n = t % total_filter_bins @@ -4271,22 +4415,28 @@ contains do i = 1, n_user_tallies ! Add tally to active tallies - call active_tallies % add(i_user_tallies + i) + call active_tallies % push_back(i_user_tallies + i) ! Check what type of tally this is and add it to the appropriate list if (user_tallies(i) % type == TALLY_VOLUME) then if (user_tallies(i) % estimator == ESTIMATOR_ANALOG) then - call active_analog_tallies % add(i_user_tallies + i) + call active_analog_tallies % push_back(i_user_tallies + i) elseif (user_tallies(i) % estimator == ESTIMATOR_TRACKLENGTH) then - call active_tracklength_tallies % add(i_user_tallies + i) + call active_tracklength_tallies % push_back(i_user_tallies + i) elseif (user_tallies(i) % estimator == ESTIMATOR_COLLISION) then - call active_collision_tallies % add(i_user_tallies + i) + call active_collision_tallies % push_back(i_user_tallies + i) end if elseif (user_tallies(i) % type == TALLY_SURFACE_CURRENT) then - call active_current_tallies % add(i_user_tallies + i) + call active_current_tallies % push_back(i_user_tallies + i) end if end do + call active_tallies % shrink_to_fit() + call active_analog_tallies % shrink_to_fit() + call active_tracklength_tallies % shrink_to_fit() + call active_collision_tallies % shrink_to_fit() + call active_current_tallies % shrink_to_fit() + end subroutine setup_active_usertallies !=============================================================================== @@ -4313,20 +4463,26 @@ contains do i = 1, n_cmfd_tallies ! Add CMFD tally to active tallies - call active_tallies % add(i_cmfd_tallies + i) + call active_tallies % push_back(i_cmfd_tallies + i) ! Check what type of tally this is and add it to the appropriate list if (cmfd_tallies(i) % type == TALLY_VOLUME) then if (cmfd_tallies(i) % estimator == ESTIMATOR_ANALOG) then - call active_analog_tallies % add(i_cmfd_tallies + i) + call active_analog_tallies % push_back(i_cmfd_tallies + i) elseif (cmfd_tallies(i) % estimator == ESTIMATOR_TRACKLENGTH) then - call active_tracklength_tallies % add(i_cmfd_tallies + i) + call active_tracklength_tallies % push_back(i_cmfd_tallies + i) end if elseif (cmfd_tallies(i) % type == TALLY_SURFACE_CURRENT) then - call active_current_tallies % add(i_cmfd_tallies + i) + call active_current_tallies % push_back(i_cmfd_tallies + i) end if end do + call active_tallies % shrink_to_fit() + call active_analog_tallies % shrink_to_fit() + call active_tracklength_tallies % shrink_to_fit() + call active_collision_tallies % shrink_to_fit() + call active_current_tallies % shrink_to_fit() + end subroutine setup_active_cmfdtallies end module tally diff --git a/src/tally_filter.F90 b/src/tally_filter.F90 index efa944d90..dfb89d433 100644 --- a/src/tally_filter.F90 +++ b/src/tally_filter.F90 @@ -103,6 +103,9 @@ module tally_filter !=============================================================================== type, extends(TallyFilter) :: SurfaceFilter integer, allocatable :: surfaces(:) + + ! True if this filter is used for surface currents + logical :: current = .false. contains procedure :: get_next_bin => get_next_bin_surface procedure :: to_statepoint => to_statepoint_surface @@ -1646,4 +1649,34 @@ contains end do end subroutine find_offset +!=============================================================================== +! ADD_FILTERS creates or extends the filters array +!=============================================================================== + + subroutine add_filters(n) + + integer, intent(in) :: n ! number of filters to add + + integer :: i ! loop counter + type(TallyFilterContainer), allocatable :: temp(:) ! temporary filters + + if (n_filters == 0) then + ! Allocate filters array + allocate(filters(n)) + else + ! Move filters to temporary array + allocate(temp(n_filters + n)) + do i = 1, n_filters + call move_alloc(filters(i) % obj, temp(i) % obj) + end do + + ! Move filters back from temporary array to filters array + call move_alloc(temp, filters) + end if + + ! Set n_filters + n_filters = size(filters) + + end subroutine add_filters + end module tally_filter diff --git a/src/tally_filter_header.F90 b/src/tally_filter_header.F90 index 8541cd334..061642545 100644 --- a/src/tally_filter_header.F90 +++ b/src/tally_filter_header.F90 @@ -2,11 +2,26 @@ module tally_filter_header use constants, only: MAX_LINE_LEN use particle_header, only: Particle + use stl_vector, only: VectorInt, VectorReal use hdf5 implicit none +!=============================================================================== +! TALLYFILTERMATCH stores every valid bin and weight for a filter +!=============================================================================== + + type TallyFilterMatch + ! Index of the bin and weight being used in the current filter combination + integer :: i_bin + type(VectorInt) :: bins + type(VectorReal) :: weights + + ! Indicates whether all valid bins for this filter have been found + logical :: bins_present = .false. + end type TallyFilterMatch + !=============================================================================== ! TALLYFILTER describes a filter that limits what events score to a tally. For ! example, a cell filter indicates that only particles in a specified cell @@ -14,6 +29,7 @@ module tally_filter_header !=============================================================================== type, abstract :: TallyFilter + integer :: id integer :: n_bins = 0 contains procedure(get_next_bin_), deferred :: get_next_bin diff --git a/src/tally_header.F90 b/src/tally_header.F90 index 1d34779ae..76e3d143f 100644 --- a/src/tally_header.F90 +++ b/src/tally_header.F90 @@ -37,7 +37,7 @@ module tally_header integer :: type ! volume, surface current integer :: estimator ! collision, track-length real(8) :: volume ! volume of region - type(TallyFilterContainer), allocatable :: filters(:) + integer, allocatable :: filter(:) ! index in filters array ! The stride attribute is used for determining the index in the results ! array for a matching_bin combination. Since multiple dimensions are diff --git a/src/tally_initialize.F90 b/src/tally_initialize.F90 index 0e7a50a9c..46c028364 100644 --- a/src/tally_initialize.F90 +++ b/src/tally_initialize.F90 @@ -29,7 +29,7 @@ contains !=============================================================================== ! SETUP_TALLY_ARRAYS allocates and populates several member arrays of the -! TallyObject derived type, including stride, matching_bins, and results. +! TallyObject derived type, including stride, filter_matches, and results. !=============================================================================== subroutine setup_tally_arrays() @@ -37,25 +37,24 @@ contains integer :: i ! loop index for tallies integer :: j ! loop index for filters integer :: n ! temporary stride - integer :: max_n_filters = 0 ! maximum number of filters + integer :: i_filt ! filter index type(TallyObject), pointer :: t TALLY_LOOP: do i = 1, n_tallies ! Get pointer to tally t => tallies(i) - ! Allocate stride and matching_bins arrays - allocate(t % stride(size(t % filters))) - max_n_filters = max(max_n_filters, size(t % filters)) + ! Allocate stride + allocate(t % stride(size(t % filter))) ! The filters are traversed in opposite order so that the last filter has ! the shortest stride in memory and the first filter has the largest ! stride - n = 1 - STRIDE: do j = size(t % filters), 1, -1 + STRIDE: do j = size(t % filter), 1, -1 + i_filt = t % filter(j) t % stride(j) = n - n = n * t % filters(j) % obj % n_bins + n = n * filters(i_filt) % obj % n_bins end do STRIDE ! Set total number of filter and scoring bins @@ -70,8 +69,7 @@ contains ! Allocate array for matching filter bins !$omp parallel - allocate(matching_bins(max_n_filters)) - allocate(filter_weights(max_n_filters)) + allocate(filter_matches(n_filters)) !$omp end parallel end subroutine setup_tally_arrays diff --git a/src/trigger.F90 b/src/trigger.F90 index 503b53ca8..9eb39e9cc 100644 --- a/src/trigger.F90 +++ b/src/trigger.F90 @@ -94,6 +94,7 @@ contains character(len=52), intent(inout) :: name ! "eigenvalue" or tally score integer :: i ! index in tallies array + integer :: j ! index in tally filters integer :: n ! loop index for nuclides integer :: s ! loop index for triggers integer :: filter_index ! index in results array for filters @@ -167,7 +168,10 @@ contains else ! Initialize bins, filter level - matching_bins(1:size(t % filters)) = 0 + do j = 1, size(t % filter) + call filter_matches(t % filter(j)) % bins % clear() + call filter_matches(t % filter(j)) % bins % push_back(0) + end do FILTER_LOOP: do filter_index = 1, t % total_filter_bins @@ -267,7 +271,7 @@ contains end if end if end do NUCLIDE_LOOP - if (size(t % filters) == 0) exit FILTER_LOOP + if (size(t % filter) == 0) exit FILTER_LOOP end do FILTER_LOOP end if end do TRIGGER_LOOP @@ -284,6 +288,7 @@ contains subroutine compute_tally_current(t, trigger) integer :: i ! mesh index + integer :: j ! loop index for tally filters integer :: ijk(3) ! indices of mesh cells integer :: n_dim ! number of mesh dimensions integer :: n_cells ! number of mesh cells @@ -301,21 +306,25 @@ contains type(RegularMesh), pointer :: m ! surface current mesh ! Get pointer to mesh - i_filter_mesh = t % find_filter(FILTER_MESH) - i_filter_surf = t % find_filter(FILTER_SURFACE) - select type(filt => t % filters(i_filter_mesh) % obj) + i_filter_mesh = t % filter(t % find_filter(FILTER_MESH)) + i_filter_surf = t % filter(t % find_filter(FILTER_SURFACE)) + select type(filt => filters(i_filter_mesh) % obj) type is (MeshFilter) m => meshes(filt % mesh) end select ! initialize bins array - matching_bins(1:size(t % filters)) = 1 + do j = 1, size(t % filter) + call filter_matches(t % filter(j)) % bins % clear() + call filter_matches(t % filter(j)) % bins % push_back(1) + end do ! determine how many energyin bins there are i_filter_ein = t % find_filter(FILTER_ENERGYIN) if (i_filter_ein > 0) then print_ebin = .true. - n = t % filters(i_filter_ein) % obj % n_bins + n = filters(t % filter(i_filter_ein)) % obj % n_bins + i_filter_ein = t % filter(i_filter_ein) else print_ebin = .false. n = 1 @@ -330,18 +339,21 @@ contains ! Get the indices for this cell call bin_to_mesh_indices(m, i, ijk) - matching_bins(i_filter_mesh) = i + filter_matches(i_filter_mesh) % bins % data(1) = i do l = 1, n if (print_ebin) then - matching_bins(i_filter_ein) = l + filter_matches(i_filter_ein) % bins % data(1) = l end if ! Left Surface - matching_bins(i_filter_surf) = OUT_LEFT - filter_index = & - sum((matching_bins(1:size(t % filters)) - 1) * t % stride) + 1 + filter_matches(i_filter_surf) % bins % data(1) = OUT_LEFT + filter_index = 1 + do j = 1, size(t % filter) + filter_index = filter_index + (filter_matches(t % filter(j)) % & + bins % data(1) - 1) * t % stride(j) + end do call get_trigger_uncertainty(std_dev, rel_err, 1, filter_index, t) if (trigger % std_dev < std_dev) then trigger % std_dev = std_dev @@ -352,9 +364,12 @@ contains trigger % variance = std_dev**2 ! Right Surface - matching_bins(i_filter_surf) = OUT_RIGHT - filter_index = & - sum((matching_bins(1:size(t % filters)) - 1) * t % stride) + 1 + filter_matches(i_filter_surf) % bins % data(1) = OUT_RIGHT + filter_index = 1 + do j = 1, size(t % filter) + filter_index = filter_index + (filter_matches(t % filter(j)) % & + bins % data(1) - 1) * t % stride(j) + end do call get_trigger_uncertainty(std_dev, rel_err, 1, filter_index, t) if (trigger % std_dev < std_dev) then trigger % std_dev = std_dev @@ -365,9 +380,12 @@ contains trigger % variance = trigger % std_dev**2 ! Back Surface - matching_bins(i_filter_surf) = OUT_BACK - filter_index = & - sum((matching_bins(1:size(t % filters)) - 1) * t % stride) + 1 + filter_matches(i_filter_surf) % bins % data(1) = OUT_BACK + filter_index = 1 + do j = 1, size(t % filter) + filter_index = filter_index + (filter_matches(t % filter(j)) % & + bins % data(1) - 1) * t % stride(j) + end do call get_trigger_uncertainty(std_dev, rel_err, 1, filter_index, t) if (trigger % std_dev < std_dev) then trigger % std_dev = std_dev @@ -378,9 +396,12 @@ contains trigger % variance = trigger % std_dev**2 ! Front Surface - matching_bins(i_filter_surf) = OUT_FRONT - filter_index = & - sum((matching_bins(1:size(t % filters)) - 1) * t % stride) + 1 + filter_matches(i_filter_surf) % bins % data(1) = OUT_FRONT + filter_index = 1 + do j = 1, size(t % filter) + filter_index = filter_index + (filter_matches(t % filter(j)) % & + bins % data(1) - 1) * t % stride(j) + end do call get_trigger_uncertainty(std_dev, rel_err, 1, filter_index, t) if (trigger % std_dev < std_dev) then trigger % std_dev = std_dev @@ -391,9 +412,12 @@ contains trigger % variance = trigger % std_dev**2 ! Bottom Surface - matching_bins(i_filter_surf) = OUT_BOTTOM - filter_index = & - sum((matching_bins(1:size(t % filters)) - 1) * t % stride) + 1 + filter_matches(i_filter_surf) % bins % data(1) = OUT_BOTTOM + filter_index = 1 + do j = 1, size(t % filter) + filter_index = filter_index + (filter_matches(t % filter(j)) % & + bins % data(1) - 1) * t % stride(j) + end do call get_trigger_uncertainty(std_dev, rel_err, 1, filter_index, t) if (trigger % std_dev < std_dev) then trigger % std_dev = std_dev @@ -404,9 +428,12 @@ contains trigger % variance = trigger % std_dev**2 ! Top Surface - matching_bins(i_filter_surf) = OUT_TOP - filter_index = & - sum((matching_bins(1:size(t % filters)) - 1) * t % stride) + 1 + filter_matches(i_filter_surf) % bins % data(1) = OUT_TOP + filter_index = 1 + do j = 1, size(t % filter) + filter_index = filter_index + (filter_matches(t % filter(j)) % & + bins % data(1) - 1) * t % stride(j) + end do call get_trigger_uncertainty(std_dev, rel_err, 1, filter_index, t) if (trigger % std_dev < std_dev) then trigger % std_dev = std_dev diff --git a/tests/test_asymmetric_lattice/inputs_true.dat b/tests/test_asymmetric_lattice/inputs_true.dat index e5ecbee27..df9ea209e 100644 --- a/tests/test_asymmetric_lattice/inputs_true.dat +++ b/tests/test_asymmetric_lattice/inputs_true.dat @@ -217,8 +217,11 @@ + + 27 + - + 10000 nu-fission diff --git a/tests/test_cmfd_feed/tallies.xml b/tests/test_cmfd_feed/tallies.xml index 37edcecc2..c86971114 100644 --- a/tests/test_cmfd_feed/tallies.xml +++ b/tests/test_cmfd_feed/tallies.xml @@ -8,8 +8,13 @@ 10 1 1 + + mesh + 1 + + - + 1 flux diff --git a/tests/test_cmfd_nofeed/tallies.xml b/tests/test_cmfd_nofeed/tallies.xml index 37edcecc2..c86971114 100644 --- a/tests/test_cmfd_nofeed/tallies.xml +++ b/tests/test_cmfd_nofeed/tallies.xml @@ -8,8 +8,13 @@ 10 1 1 + + mesh + 1 + + - + 1 flux diff --git a/tests/test_complex_cell/tallies.xml b/tests/test_complex_cell/tallies.xml index d1a7d387e..e0509e6a8 100644 --- a/tests/test_complex_cell/tallies.xml +++ b/tests/test_complex_cell/tallies.xml @@ -1,7 +1,14 @@ + + + cell + 1 2 3 4 + + - + 1 total + diff --git a/tests/test_confidence_intervals/tallies.xml b/tests/test_confidence_intervals/tallies.xml index 0e1fe213c..65ff255fb 100644 --- a/tests/test_confidence_intervals/tallies.xml +++ b/tests/test_confidence_intervals/tallies.xml @@ -1,9 +1,14 @@ + + cell + 1 + + - + 1 flux - \ No newline at end of file + diff --git a/tests/test_diff_tally/inputs_true.dat b/tests/test_diff_tally/inputs_true.dat index aaf96c768..83dfd7ff9 100644 --- a/tests/test_diff_tally/inputs_true.dat +++ b/tests/test_diff_tally/inputs_true.dat @@ -310,122 +310,123 @@ + + 1 3 + + + 0.0 0.625 20000000.0 + - + 10000 flux 1 - + 10000 flux 2 - + 10000 flux 3 - + 10000 flux 4 - + 10000 flux 5 - + 10000 total U235 total absorption scatter fission nu-fission 1 - + 10000 total U235 total absorption scatter fission nu-fission 2 - + 10000 total U235 total absorption scatter fission nu-fission 3 - + 10000 total U235 total absorption scatter fission nu-fission 4 - + 10000 total U235 total absorption scatter fission nu-fission 5 - + 10000 absorption analog 1 - + 10000 absorption analog 2 - + 10000 absorption analog 3 - + 10000 absorption analog 4 - + 10000 absorption analog 5 - - + 10000 10001 total U235 nu-fission scatter 1 - - + 10000 10001 total U235 nu-fission scatter 2 - - + 10000 10001 U235 nu-fission scatter 3 - - + 10000 10001 U235 nu-fission scatter 4 - - + 10000 10001 U235 nu-fission scatter 5 diff --git a/tests/test_energy_cutoff/inputs_true.dat b/tests/test_energy_cutoff/inputs_true.dat index 7f67288d1..a2d2967c0 100644 --- a/tests/test_energy_cutoff/inputs_true.dat +++ b/tests/test_energy_cutoff/inputs_true.dat @@ -32,8 +32,11 @@ + + 0.0 4.0 + - + 10000 flux diff --git a/tests/test_filter_distribcell/case-1/tallies.xml b/tests/test_filter_distribcell/case-1/tallies.xml index e9b952a55..1e7061f21 100644 --- a/tests/test_filter_distribcell/case-1/tallies.xml +++ b/tests/test_filter_distribcell/case-1/tallies.xml @@ -1,22 +1,24 @@ + + distribcell + 201 + + + + cell + 201 + + - - - 201 - - - total + 1 + total - - - 201 - - - total + 2 + total diff --git a/tests/test_filter_distribcell/case-2/tallies.xml b/tests/test_filter_distribcell/case-2/tallies.xml index 55738312b..b2efa76a5 100644 --- a/tests/test_filter_distribcell/case-2/tallies.xml +++ b/tests/test_filter_distribcell/case-2/tallies.xml @@ -1,13 +1,14 @@ + + cell + 201 203 205 207 + + - - - 201 203 205 207 - - - total + 1 + total diff --git a/tests/test_filter_distribcell/case-3/tallies.xml b/tests/test_filter_distribcell/case-3/tallies.xml index 30c9426e0..aed192854 100644 --- a/tests/test_filter_distribcell/case-3/tallies.xml +++ b/tests/test_filter_distribcell/case-3/tallies.xml @@ -1,58 +1,64 @@ + + cell + 1 + + + + distribcell + 1 + + + + cell + 60 + + + + distribcell + 60 + + + + cell + 27 + + + + distribcell + 27 + + - - - 1 - - - total + 1 + total - - - 1 - - - total + 2 + total - - - 60 - - - total + 3 + total - - - 60 - - - total + 4 + total - - - 27 - - - total + 5 + total - - - 27 - - - total + 6 + total diff --git a/tests/test_filter_distribcell/case-4/tallies.xml b/tests/test_filter_distribcell/case-4/tallies.xml index b46de5f4e..b923c030b 100644 --- a/tests/test_filter_distribcell/case-4/tallies.xml +++ b/tests/test_filter_distribcell/case-4/tallies.xml @@ -1,7 +1,14 @@ - - + + + distribcell + 101 + + + + 1 total - + + diff --git a/tests/test_filter_energyfun/inputs_true.dat b/tests/test_filter_energyfun/inputs_true.dat index 1593c5113..cbf6183d1 100644 --- a/tests/test_filter_energyfun/inputs_true.dat +++ b/tests/test_filter_energyfun/inputs_true.dat @@ -310,12 +310,16 @@ + + 1e-05 0.369 1000.0 100000.0 600000.0 1000000.0 2000000.0 4000000.0 30000000.0 + 0.1 0.1 0.1333 0.158 0.18467 0.25618 0.4297 0.48 0.48 + Am241 (n,gamma) - + 10000 Am241 (n,gamma) diff --git a/tests/test_filter_energyfun/results_true.dat b/tests/test_filter_energyfun/results_true.dat index d3dc3ad6a..8e48e5f3c 100644 --- a/tests/test_filter_energyfun/results_true.dat +++ b/tests/test_filter_energyfun/results_true.dat @@ -1,2 +1,2 @@ energyfunction nuclide score mean std. dev. -0 f4ae05cee02fae Am241 (n,gamma) 1.00e-01 6.22e-03 +0 ac03185c35fac8 Am241 (n,gamma) 1.00e-01 6.22e-03 diff --git a/tests/test_filter_mesh/inputs_true.dat b/tests/test_filter_mesh/inputs_true.dat index 32700c098..e5d900624 100644 --- a/tests/test_filter_mesh/inputs_true.dat +++ b/tests/test_filter_mesh/inputs_true.dat @@ -324,28 +324,37 @@ -182.07 -182.07 -183.0 182.07 182.07 183.0 + + 1 + + + 2 + + + 3 + - + 10000 total - + 10000 current - + 10001 total - + 10001 current - + 10002 total - + 10002 current diff --git a/tests/test_filter_mesh/results_true.dat b/tests/test_filter_mesh/results_true.dat index 3c25aa738..61ba50e20 100644 --- a/tests/test_filter_mesh/results_true.dat +++ b/tests/test_filter_mesh/results_true.dat @@ -1 +1 @@ -ba64175b12e3b1be70493399f6cca2319947c17e26cf5d1d73398387214b8c18c2cb842c14d838da31a7a1eee18d407b8f7a319d5d2dab6b4a7a7dffa8770f1f \ No newline at end of file +2416e74f84dd57c46a6e2fc94e8f794d9725cae964beaf4659f06aae5ed2b804b968cf2ca512b461d6e59e998f61a967db2f2fe97ce22e7607444f50ca38f646 \ No newline at end of file diff --git a/tests/test_mg_tallies/inputs_true.dat b/tests/test_mg_tallies/inputs_true.dat index e2d09ac36..9aeb28a94 100644 --- a/tests/test_mg_tallies/inputs_true.dat +++ b/tests/test_mg_tallies/inputs_true.dat @@ -102,129 +102,127 @@ 0.0 0.0 0.0 10 10 5 + + 1 + + + 10000 10001 10002 10003 10004 10005 10006 10007 10008 10009 10010 10011 + + + 0.0 20000000.0 + + + 0.0 20000000.0 + + + 1e-05 0.0635 10.0 100.0 1000.0 500000.0 1000000.0 20000000.0 + + + 1e-05 0.0635 10.0 100.0 1000.0 500000.0 1000000.0 20000000.0 + - + 10004 total absorption flux fission nu-fission analog - + 10004 total absorption flux fission nu-fission tracklength - - + 10005 10000 total absorption flux fission nu-fission scatter nu-scatter analog - - + 10005 10000 total absorption flux fission nu-fission collision - - + 10005 10000 total absorption flux fission nu-fission tracklength - - - + 10005 10000 10001 scatter nu-scatter nu-fission - - + 10005 10002 total absorption flux fission nu-fission scatter nu-scatter analog - - + 10005 10002 total absorption flux fission nu-fission collision - - + 10005 10002 total absorption flux fission nu-fission tracklength - - - + 10005 10002 10003 scatter nu-scatter nu-fission - + 10004 uo2_ang uo2_ang_mu uo2_iso uo2_iso_mu clad_ang clad_ang_mu clad_iso clad_iso_mu lwtr_ang lwtr_ang_mu lwtr_iso lwtr_iso_mu total absorption fission nu-fission analog - + 10004 uo2_ang uo2_ang_mu uo2_iso uo2_iso_mu clad_ang clad_ang_mu clad_iso clad_iso_mu lwtr_ang lwtr_ang_mu lwtr_iso lwtr_iso_mu total absorption fission nu-fission tracklength - - + 10005 10000 uo2_ang uo2_ang_mu uo2_iso uo2_iso_mu clad_ang clad_ang_mu clad_iso clad_iso_mu lwtr_ang lwtr_ang_mu lwtr_iso lwtr_iso_mu total absorption fission nu-fission scatter nu-scatter analog - - + 10005 10000 uo2_ang uo2_ang_mu uo2_iso uo2_iso_mu clad_ang clad_ang_mu clad_iso clad_iso_mu lwtr_ang lwtr_ang_mu lwtr_iso lwtr_iso_mu total absorption fission nu-fission collision - - + 10005 10000 uo2_ang uo2_ang_mu uo2_iso uo2_iso_mu clad_ang clad_ang_mu clad_iso clad_iso_mu lwtr_ang lwtr_ang_mu lwtr_iso lwtr_iso_mu total absorption fission nu-fission tracklength - - - + 10005 10000 10001 uo2_ang uo2_ang_mu uo2_iso uo2_iso_mu clad_ang clad_ang_mu clad_iso clad_iso_mu lwtr_ang lwtr_ang_mu lwtr_iso lwtr_iso_mu scatter nu-scatter nu-fission - - + 10005 10002 uo2_ang uo2_ang_mu uo2_iso uo2_iso_mu clad_ang clad_ang_mu clad_iso clad_iso_mu lwtr_ang lwtr_ang_mu lwtr_iso lwtr_iso_mu total absorption fission nu-fission scatter nu-scatter analog - - + 10005 10002 uo2_ang uo2_ang_mu uo2_iso uo2_iso_mu clad_ang clad_ang_mu clad_iso clad_iso_mu lwtr_ang lwtr_ang_mu lwtr_iso lwtr_iso_mu total absorption fission nu-fission collision - - + 10005 10002 uo2_ang uo2_ang_mu uo2_iso uo2_iso_mu clad_ang clad_ang_mu clad_iso clad_iso_mu lwtr_ang lwtr_ang_mu lwtr_iso lwtr_iso_mu total absorption fission nu-fission tracklength - - - + 10005 10002 10003 uo2_ang uo2_ang_mu uo2_iso uo2_iso_mu clad_ang clad_ang_mu clad_iso clad_iso_mu lwtr_ang lwtr_ang_mu lwtr_iso lwtr_iso_mu scatter nu-scatter nu-fission diff --git a/tests/test_mgxs_library_ce_to_mg/inputs_true.dat b/tests/test_mgxs_library_ce_to_mg/inputs_true.dat index 0ca4e0873..faddd4645 100644 --- a/tests/test_mgxs_library_ce_to_mg/inputs_true.dat +++ b/tests/test_mgxs_library_ce_to_mg/inputs_true.dat @@ -50,224 +50,197 @@ + + 10000 + + + 0.0 0.625 20000000.0 + + + 0.0 0.625 20000000.0 + + + 10001 + + + 10002 + - - + 10000 10001 total flux tracklength - - + 10000 10001 total total tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total absorption tracklength - - + 10000 10001 total flux analog - - - + 10000 10001 10006 total nu-fission analog - - + 10000 10001 total flux analog - - - + 10000 10001 10006 total nu-scatter-P3 analog - - - + 10000 10001 10006 total nu-scatter analog - - - + 10000 10001 10006 total scatter analog - - + 10013 10001 total flux tracklength - - + 10013 10001 total total tracklength - - + 10013 10001 total flux tracklength - - + 10013 10001 total absorption tracklength - - + 10013 10001 total flux analog - - - + 10013 10001 10006 total nu-fission analog - - + 10013 10001 total flux analog - - - + 10013 10001 10006 total nu-scatter-P3 analog - - - + 10013 10001 10006 total nu-scatter analog - - - + 10013 10001 10006 total scatter analog - - + 10026 10001 total flux tracklength - - + 10026 10001 total total tracklength - - + 10026 10001 total flux tracklength - - + 10026 10001 total absorption tracklength - - + 10026 10001 total flux analog - - - + 10026 10001 10006 total nu-fission analog - - + 10026 10001 total flux analog - - - + 10026 10001 10006 total nu-scatter-P3 analog - - - + 10026 10001 10006 total nu-scatter analog - - - + 10026 10001 10006 total scatter analog diff --git a/tests/test_mgxs_library_condense/inputs_true.dat b/tests/test_mgxs_library_condense/inputs_true.dat index 8059122b0..f33efe863 100644 --- a/tests/test_mgxs_library_condense/inputs_true.dat +++ b/tests/test_mgxs_library_condense/inputs_true.dat @@ -50,1361 +50,1139 @@ + + 10000 + + + 0.0 0.625 20000000.0 + + + 0.0 0.625 20000000.0 + + + 0.0 20000000.0 + + + 1 2 3 4 5 6 + + + 10001 + + + 10002 + - - + 10000 10001 total flux tracklength - - + 10000 10001 total total tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total total tracklength - - + 10000 10001 total flux analog - - + 10000 10004 total scatter-1 analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total total tracklength - - + 10000 10001 total flux analog - - + 10000 10004 total nu-scatter-1 analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total absorption tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total absorption tracklength - - + 10000 10001 total fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total nu-fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total kappa-fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total scatter tracklength - - + 10000 10001 total flux analog - - + 10000 10001 total nu-scatter analog - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total scatter-P3 analog - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total nu-scatter-P3 analog - - - + 10000 10001 10004 total nu-scatter analog - - - + 10000 10001 10004 total scatter analog - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total nu-fission analog - - - + 10000 10001 10004 total scatter analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total scatter tracklength - - - + 10000 10001 10004 total scatter-P3 analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total scatter tracklength - - - + 10000 10001 10004 total scatter-P3 analog - - - + 10000 10001 10004 total nu-scatter-0 analog - - - + 10000 10001 10004 total scatter-0 analog - - + 10000 10045 total nu-fission analog - - + 10000 10004 total nu-fission analog - - + 10000 10045 total prompt-nu-fission analog - - + 10000 10004 total prompt-nu-fission analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total inverse-velocity tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total prompt-nu-fission tracklength - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total prompt-nu-fission analog - - + 10000 10001 total flux tracklength - - - + 10000 10058 10001 total delayed-nu-fission tracklength - - - + 10000 10058 10045 total delayed-nu-fission analog - - - + 10000 10058 10004 total delayed-nu-fission analog - - + 10000 10001 total nu-fission tracklength - - - + 10000 10058 10001 total delayed-nu-fission tracklength - - - + 10000 10058 10001 total delayed-nu-fission tracklength - - - + 10000 10058 10001 total decay-rate tracklength - - + 10000 10001 total flux analog - - - - + 10000 10058 10001 10004 total delayed-nu-fission analog - - + 10073 10001 total flux tracklength - - + 10073 10001 total total tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total total tracklength - - + 10073 10001 total flux analog - - + 10073 10004 total scatter-1 analog - - + 10073 10001 total flux tracklength - - + 10073 10001 total total tracklength - - + 10073 10001 total flux analog - - + 10073 10004 total nu-scatter-1 analog - - + 10073 10001 total flux tracklength - - + 10073 10001 total absorption tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total absorption tracklength - - + 10073 10001 total fission tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total fission tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total nu-fission tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total kappa-fission tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total scatter tracklength - - + 10073 10001 total flux analog - - + 10073 10001 total nu-scatter analog - - + 10073 10001 total flux analog - - - + 10073 10001 10004 total scatter-P3 analog - - + 10073 10001 total flux analog - - - + 10073 10001 10004 total nu-scatter-P3 analog - - - + 10073 10001 10004 total nu-scatter analog - - - + 10073 10001 10004 total scatter analog - - + 10073 10001 total flux analog - - - + 10073 10001 10004 total nu-fission analog - - - + 10073 10001 10004 total scatter analog - - + 10073 10001 total flux tracklength - - + 10073 10001 total scatter tracklength - - - + 10073 10001 10004 total scatter-P3 analog - - + 10073 10001 total flux tracklength - - + 10073 10001 total scatter tracklength - - - + 10073 10001 10004 total scatter-P3 analog - - - + 10073 10001 10004 total nu-scatter-0 analog - - - + 10073 10001 10004 total scatter-0 analog - - + 10073 10045 total nu-fission analog - - + 10073 10004 total nu-fission analog - - + 10073 10045 total prompt-nu-fission analog - - + 10073 10004 total prompt-nu-fission analog - - + 10073 10001 total flux tracklength - - + 10073 10001 total inverse-velocity tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total prompt-nu-fission tracklength - - + 10073 10001 total flux analog - - - + 10073 10001 10004 total prompt-nu-fission analog - - + 10073 10001 total flux tracklength - - - + 10073 10058 10001 total delayed-nu-fission tracklength - - - + 10073 10058 10045 total delayed-nu-fission analog - - - + 10073 10058 10004 total delayed-nu-fission analog - - + 10073 10001 total nu-fission tracklength - - - + 10073 10058 10001 total delayed-nu-fission tracklength - - - + 10073 10058 10001 total delayed-nu-fission tracklength - - - + 10073 10058 10001 total decay-rate tracklength - - + 10073 10001 total flux analog - - - - + 10073 10058 10001 10004 total delayed-nu-fission analog - - + 10146 10001 total flux tracklength - - + 10146 10001 total total tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total total tracklength - - + 10146 10001 total flux analog - - + 10146 10004 total scatter-1 analog - - + 10146 10001 total flux tracklength - - + 10146 10001 total total tracklength - - + 10146 10001 total flux analog - - + 10146 10004 total nu-scatter-1 analog - - + 10146 10001 total flux tracklength - - + 10146 10001 total absorption tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total absorption tracklength - - + 10146 10001 total fission tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total fission tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total nu-fission tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total kappa-fission tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total scatter tracklength - - + 10146 10001 total flux analog - - + 10146 10001 total nu-scatter analog - - + 10146 10001 total flux analog - - - + 10146 10001 10004 total scatter-P3 analog - - + 10146 10001 total flux analog - - - + 10146 10001 10004 total nu-scatter-P3 analog - - - + 10146 10001 10004 total nu-scatter analog - - - + 10146 10001 10004 total scatter analog - - + 10146 10001 total flux analog - - - + 10146 10001 10004 total nu-fission analog - - - + 10146 10001 10004 total scatter analog - - + 10146 10001 total flux tracklength - - + 10146 10001 total scatter tracklength - - - + 10146 10001 10004 total scatter-P3 analog - - + 10146 10001 total flux tracklength - - + 10146 10001 total scatter tracklength - - - + 10146 10001 10004 total scatter-P3 analog - - - + 10146 10001 10004 total nu-scatter-0 analog - - - + 10146 10001 10004 total scatter-0 analog - - + 10146 10045 total nu-fission analog - - + 10146 10004 total nu-fission analog - - + 10146 10045 total prompt-nu-fission analog - - + 10146 10004 total prompt-nu-fission analog - - + 10146 10001 total flux tracklength - - + 10146 10001 total inverse-velocity tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total prompt-nu-fission tracklength - - + 10146 10001 total flux analog - - - + 10146 10001 10004 total prompt-nu-fission analog - - + 10146 10001 total flux tracklength - - - + 10146 10058 10001 total delayed-nu-fission tracklength - - - + 10146 10058 10045 total delayed-nu-fission analog - - - + 10146 10058 10004 total delayed-nu-fission analog - - + 10146 10001 total nu-fission tracklength - - - + 10146 10058 10001 total delayed-nu-fission tracklength - - - + 10146 10058 10001 total delayed-nu-fission tracklength - - - + 10146 10058 10001 total decay-rate tracklength - - + 10146 10001 total flux analog - - - - + 10146 10058 10001 10004 total delayed-nu-fission analog diff --git a/tests/test_mgxs_library_distribcell/inputs_true.dat b/tests/test_mgxs_library_distribcell/inputs_true.dat index 20b70b860..44b7eb1d8 100644 --- a/tests/test_mgxs_library_distribcell/inputs_true.dat +++ b/tests/test_mgxs_library_distribcell/inputs_true.dat @@ -77,455 +77,386 @@ + + 10000 + + + 0.0 20000000.0 + + + 0.0 20000000.0 + + + 1 2 3 4 5 6 + - - + 10000 10001 total flux tracklength - - + 10000 10001 total total tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total total tracklength - - + 10000 10001 total flux analog - - + 10000 10004 total scatter-1 analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total total tracklength - - + 10000 10001 total flux analog - - + 10000 10004 total nu-scatter-1 analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total absorption tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total absorption tracklength - - + 10000 10001 total fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total nu-fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total kappa-fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total scatter tracklength - - + 10000 10001 total flux analog - - + 10000 10001 total nu-scatter analog - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total scatter-P3 analog - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total nu-scatter-P3 analog - - - + 10000 10001 10004 total nu-scatter analog - - - + 10000 10001 10004 total scatter analog - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total nu-fission analog - - - + 10000 10001 10004 total scatter analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total scatter tracklength - - - + 10000 10001 10004 total scatter-P3 analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total scatter tracklength - - - + 10000 10001 10004 total scatter-P3 analog - - - + 10000 10001 10004 total nu-scatter-0 analog - - - + 10000 10001 10004 total scatter-0 analog - - + 10000 10001 total nu-fission analog - - + 10000 10004 total nu-fission analog - - + 10000 10001 total prompt-nu-fission analog - - + 10000 10004 total prompt-nu-fission analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total inverse-velocity tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total prompt-nu-fission tracklength - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total prompt-nu-fission analog - - + 10000 10001 total flux tracklength - - - + 10000 10058 10001 total delayed-nu-fission tracklength - - - + 10000 10058 10001 total delayed-nu-fission analog - - - + 10000 10058 10004 total delayed-nu-fission analog - - + 10000 10001 total nu-fission tracklength - - - + 10000 10058 10001 total delayed-nu-fission tracklength - - - + 10000 10058 10001 total delayed-nu-fission tracklength - - - + 10000 10058 10001 total decay-rate tracklength - - + 10000 10001 total flux analog - - - - + 10000 10058 10001 10004 total delayed-nu-fission analog diff --git a/tests/test_mgxs_library_hdf5/inputs_true.dat b/tests/test_mgxs_library_hdf5/inputs_true.dat index 8059122b0..f33efe863 100644 --- a/tests/test_mgxs_library_hdf5/inputs_true.dat +++ b/tests/test_mgxs_library_hdf5/inputs_true.dat @@ -50,1361 +50,1139 @@ + + 10000 + + + 0.0 0.625 20000000.0 + + + 0.0 0.625 20000000.0 + + + 0.0 20000000.0 + + + 1 2 3 4 5 6 + + + 10001 + + + 10002 + - - + 10000 10001 total flux tracklength - - + 10000 10001 total total tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total total tracklength - - + 10000 10001 total flux analog - - + 10000 10004 total scatter-1 analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total total tracklength - - + 10000 10001 total flux analog - - + 10000 10004 total nu-scatter-1 analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total absorption tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total absorption tracklength - - + 10000 10001 total fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total nu-fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total kappa-fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total scatter tracklength - - + 10000 10001 total flux analog - - + 10000 10001 total nu-scatter analog - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total scatter-P3 analog - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total nu-scatter-P3 analog - - - + 10000 10001 10004 total nu-scatter analog - - - + 10000 10001 10004 total scatter analog - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total nu-fission analog - - - + 10000 10001 10004 total scatter analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total scatter tracklength - - - + 10000 10001 10004 total scatter-P3 analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total scatter tracklength - - - + 10000 10001 10004 total scatter-P3 analog - - - + 10000 10001 10004 total nu-scatter-0 analog - - - + 10000 10001 10004 total scatter-0 analog - - + 10000 10045 total nu-fission analog - - + 10000 10004 total nu-fission analog - - + 10000 10045 total prompt-nu-fission analog - - + 10000 10004 total prompt-nu-fission analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total inverse-velocity tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total prompt-nu-fission tracklength - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total prompt-nu-fission analog - - + 10000 10001 total flux tracklength - - - + 10000 10058 10001 total delayed-nu-fission tracklength - - - + 10000 10058 10045 total delayed-nu-fission analog - - - + 10000 10058 10004 total delayed-nu-fission analog - - + 10000 10001 total nu-fission tracklength - - - + 10000 10058 10001 total delayed-nu-fission tracklength - - - + 10000 10058 10001 total delayed-nu-fission tracklength - - - + 10000 10058 10001 total decay-rate tracklength - - + 10000 10001 total flux analog - - - - + 10000 10058 10001 10004 total delayed-nu-fission analog - - + 10073 10001 total flux tracklength - - + 10073 10001 total total tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total total tracklength - - + 10073 10001 total flux analog - - + 10073 10004 total scatter-1 analog - - + 10073 10001 total flux tracklength - - + 10073 10001 total total tracklength - - + 10073 10001 total flux analog - - + 10073 10004 total nu-scatter-1 analog - - + 10073 10001 total flux tracklength - - + 10073 10001 total absorption tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total absorption tracklength - - + 10073 10001 total fission tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total fission tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total nu-fission tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total kappa-fission tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total scatter tracklength - - + 10073 10001 total flux analog - - + 10073 10001 total nu-scatter analog - - + 10073 10001 total flux analog - - - + 10073 10001 10004 total scatter-P3 analog - - + 10073 10001 total flux analog - - - + 10073 10001 10004 total nu-scatter-P3 analog - - - + 10073 10001 10004 total nu-scatter analog - - - + 10073 10001 10004 total scatter analog - - + 10073 10001 total flux analog - - - + 10073 10001 10004 total nu-fission analog - - - + 10073 10001 10004 total scatter analog - - + 10073 10001 total flux tracklength - - + 10073 10001 total scatter tracklength - - - + 10073 10001 10004 total scatter-P3 analog - - + 10073 10001 total flux tracklength - - + 10073 10001 total scatter tracklength - - - + 10073 10001 10004 total scatter-P3 analog - - - + 10073 10001 10004 total nu-scatter-0 analog - - - + 10073 10001 10004 total scatter-0 analog - - + 10073 10045 total nu-fission analog - - + 10073 10004 total nu-fission analog - - + 10073 10045 total prompt-nu-fission analog - - + 10073 10004 total prompt-nu-fission analog - - + 10073 10001 total flux tracklength - - + 10073 10001 total inverse-velocity tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total prompt-nu-fission tracklength - - + 10073 10001 total flux analog - - - + 10073 10001 10004 total prompt-nu-fission analog - - + 10073 10001 total flux tracklength - - - + 10073 10058 10001 total delayed-nu-fission tracklength - - - + 10073 10058 10045 total delayed-nu-fission analog - - - + 10073 10058 10004 total delayed-nu-fission analog - - + 10073 10001 total nu-fission tracklength - - - + 10073 10058 10001 total delayed-nu-fission tracklength - - - + 10073 10058 10001 total delayed-nu-fission tracklength - - - + 10073 10058 10001 total decay-rate tracklength - - + 10073 10001 total flux analog - - - - + 10073 10058 10001 10004 total delayed-nu-fission analog - - + 10146 10001 total flux tracklength - - + 10146 10001 total total tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total total tracklength - - + 10146 10001 total flux analog - - + 10146 10004 total scatter-1 analog - - + 10146 10001 total flux tracklength - - + 10146 10001 total total tracklength - - + 10146 10001 total flux analog - - + 10146 10004 total nu-scatter-1 analog - - + 10146 10001 total flux tracklength - - + 10146 10001 total absorption tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total absorption tracklength - - + 10146 10001 total fission tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total fission tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total nu-fission tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total kappa-fission tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total scatter tracklength - - + 10146 10001 total flux analog - - + 10146 10001 total nu-scatter analog - - + 10146 10001 total flux analog - - - + 10146 10001 10004 total scatter-P3 analog - - + 10146 10001 total flux analog - - - + 10146 10001 10004 total nu-scatter-P3 analog - - - + 10146 10001 10004 total nu-scatter analog - - - + 10146 10001 10004 total scatter analog - - + 10146 10001 total flux analog - - - + 10146 10001 10004 total nu-fission analog - - - + 10146 10001 10004 total scatter analog - - + 10146 10001 total flux tracklength - - + 10146 10001 total scatter tracklength - - - + 10146 10001 10004 total scatter-P3 analog - - + 10146 10001 total flux tracklength - - + 10146 10001 total scatter tracklength - - - + 10146 10001 10004 total scatter-P3 analog - - - + 10146 10001 10004 total nu-scatter-0 analog - - - + 10146 10001 10004 total scatter-0 analog - - + 10146 10045 total nu-fission analog - - + 10146 10004 total nu-fission analog - - + 10146 10045 total prompt-nu-fission analog - - + 10146 10004 total prompt-nu-fission analog - - + 10146 10001 total flux tracklength - - + 10146 10001 total inverse-velocity tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total prompt-nu-fission tracklength - - + 10146 10001 total flux analog - - - + 10146 10001 10004 total prompt-nu-fission analog - - + 10146 10001 total flux tracklength - - - + 10146 10058 10001 total delayed-nu-fission tracklength - - - + 10146 10058 10045 total delayed-nu-fission analog - - - + 10146 10058 10004 total delayed-nu-fission analog - - + 10146 10001 total nu-fission tracklength - - - + 10146 10058 10001 total delayed-nu-fission tracklength - - - + 10146 10058 10001 total delayed-nu-fission tracklength - - - + 10146 10058 10001 total decay-rate tracklength - - + 10146 10001 total flux analog - - - - + 10146 10058 10001 10004 total delayed-nu-fission analog diff --git a/tests/test_mgxs_library_mesh/inputs_true.dat b/tests/test_mgxs_library_mesh/inputs_true.dat index 33bab8d54..365c4a2af 100644 --- a/tests/test_mgxs_library_mesh/inputs_true.dat +++ b/tests/test_mgxs_library_mesh/inputs_true.dat @@ -314,455 +314,386 @@ -100.0 -100.0 100.0 100.0 + + 1 + + + 0.0 20000000.0 + + + 0.0 20000000.0 + + + 1 2 3 4 5 6 + - - + 10000 10001 total flux tracklength - - + 10000 10001 total total tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total total tracklength - - + 10000 10001 total flux analog - - + 10000 10004 total scatter-1 analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total total tracklength - - + 10000 10001 total flux analog - - + 10000 10004 total nu-scatter-1 analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total absorption tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total absorption tracklength - - + 10000 10001 total fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total nu-fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total kappa-fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total scatter tracklength - - + 10000 10001 total flux analog - - + 10000 10001 total nu-scatter analog - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total scatter-P3 analog - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total nu-scatter-P3 analog - - - + 10000 10001 10004 total nu-scatter analog - - - + 10000 10001 10004 total scatter analog - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total nu-fission analog - - - + 10000 10001 10004 total scatter analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total scatter tracklength - - - + 10000 10001 10004 total scatter-P3 analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total scatter tracklength - - - + 10000 10001 10004 total scatter-P3 analog - - - + 10000 10001 10004 total nu-scatter-0 analog - - - + 10000 10001 10004 total scatter-0 analog - - + 10000 10001 total nu-fission analog - - + 10000 10004 total nu-fission analog - - + 10000 10001 total prompt-nu-fission analog - - + 10000 10004 total prompt-nu-fission analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total inverse-velocity tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total prompt-nu-fission tracklength - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total prompt-nu-fission analog - - + 10000 10001 total flux tracklength - - - + 10000 10058 10001 total delayed-nu-fission tracklength - - - + 10000 10058 10001 total delayed-nu-fission analog - - - + 10000 10058 10004 total delayed-nu-fission analog - - + 10000 10001 total nu-fission tracklength - - - + 10000 10058 10001 total delayed-nu-fission tracklength - - - + 10000 10058 10001 total delayed-nu-fission tracklength - - - + 10000 10058 10001 total decay-rate tracklength - - + 10000 10001 total flux analog - - - - + 10000 10058 10001 10004 total delayed-nu-fission analog diff --git a/tests/test_mgxs_library_no_nuclides/inputs_true.dat b/tests/test_mgxs_library_no_nuclides/inputs_true.dat index 8059122b0..f33efe863 100644 --- a/tests/test_mgxs_library_no_nuclides/inputs_true.dat +++ b/tests/test_mgxs_library_no_nuclides/inputs_true.dat @@ -50,1361 +50,1139 @@ + + 10000 + + + 0.0 0.625 20000000.0 + + + 0.0 0.625 20000000.0 + + + 0.0 20000000.0 + + + 1 2 3 4 5 6 + + + 10001 + + + 10002 + - - + 10000 10001 total flux tracklength - - + 10000 10001 total total tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total total tracklength - - + 10000 10001 total flux analog - - + 10000 10004 total scatter-1 analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total total tracklength - - + 10000 10001 total flux analog - - + 10000 10004 total nu-scatter-1 analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total absorption tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total absorption tracklength - - + 10000 10001 total fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total nu-fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total kappa-fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total scatter tracklength - - + 10000 10001 total flux analog - - + 10000 10001 total nu-scatter analog - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total scatter-P3 analog - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total nu-scatter-P3 analog - - - + 10000 10001 10004 total nu-scatter analog - - - + 10000 10001 10004 total scatter analog - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total nu-fission analog - - - + 10000 10001 10004 total scatter analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total scatter tracklength - - - + 10000 10001 10004 total scatter-P3 analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total scatter tracklength - - - + 10000 10001 10004 total scatter-P3 analog - - - + 10000 10001 10004 total nu-scatter-0 analog - - - + 10000 10001 10004 total scatter-0 analog - - + 10000 10045 total nu-fission analog - - + 10000 10004 total nu-fission analog - - + 10000 10045 total prompt-nu-fission analog - - + 10000 10004 total prompt-nu-fission analog - - + 10000 10001 total flux tracklength - - + 10000 10001 total inverse-velocity tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 total prompt-nu-fission tracklength - - + 10000 10001 total flux analog - - - + 10000 10001 10004 total prompt-nu-fission analog - - + 10000 10001 total flux tracklength - - - + 10000 10058 10001 total delayed-nu-fission tracklength - - - + 10000 10058 10045 total delayed-nu-fission analog - - - + 10000 10058 10004 total delayed-nu-fission analog - - + 10000 10001 total nu-fission tracklength - - - + 10000 10058 10001 total delayed-nu-fission tracklength - - - + 10000 10058 10001 total delayed-nu-fission tracklength - - - + 10000 10058 10001 total decay-rate tracklength - - + 10000 10001 total flux analog - - - - + 10000 10058 10001 10004 total delayed-nu-fission analog - - + 10073 10001 total flux tracklength - - + 10073 10001 total total tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total total tracklength - - + 10073 10001 total flux analog - - + 10073 10004 total scatter-1 analog - - + 10073 10001 total flux tracklength - - + 10073 10001 total total tracklength - - + 10073 10001 total flux analog - - + 10073 10004 total nu-scatter-1 analog - - + 10073 10001 total flux tracklength - - + 10073 10001 total absorption tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total absorption tracklength - - + 10073 10001 total fission tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total fission tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total nu-fission tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total kappa-fission tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total scatter tracklength - - + 10073 10001 total flux analog - - + 10073 10001 total nu-scatter analog - - + 10073 10001 total flux analog - - - + 10073 10001 10004 total scatter-P3 analog - - + 10073 10001 total flux analog - - - + 10073 10001 10004 total nu-scatter-P3 analog - - - + 10073 10001 10004 total nu-scatter analog - - - + 10073 10001 10004 total scatter analog - - + 10073 10001 total flux analog - - - + 10073 10001 10004 total nu-fission analog - - - + 10073 10001 10004 total scatter analog - - + 10073 10001 total flux tracklength - - + 10073 10001 total scatter tracklength - - - + 10073 10001 10004 total scatter-P3 analog - - + 10073 10001 total flux tracklength - - + 10073 10001 total scatter tracklength - - - + 10073 10001 10004 total scatter-P3 analog - - - + 10073 10001 10004 total nu-scatter-0 analog - - - + 10073 10001 10004 total scatter-0 analog - - + 10073 10045 total nu-fission analog - - + 10073 10004 total nu-fission analog - - + 10073 10045 total prompt-nu-fission analog - - + 10073 10004 total prompt-nu-fission analog - - + 10073 10001 total flux tracklength - - + 10073 10001 total inverse-velocity tracklength - - + 10073 10001 total flux tracklength - - + 10073 10001 total prompt-nu-fission tracklength - - + 10073 10001 total flux analog - - - + 10073 10001 10004 total prompt-nu-fission analog - - + 10073 10001 total flux tracklength - - - + 10073 10058 10001 total delayed-nu-fission tracklength - - - + 10073 10058 10045 total delayed-nu-fission analog - - - + 10073 10058 10004 total delayed-nu-fission analog - - + 10073 10001 total nu-fission tracklength - - - + 10073 10058 10001 total delayed-nu-fission tracklength - - - + 10073 10058 10001 total delayed-nu-fission tracklength - - - + 10073 10058 10001 total decay-rate tracklength - - + 10073 10001 total flux analog - - - - + 10073 10058 10001 10004 total delayed-nu-fission analog - - + 10146 10001 total flux tracklength - - + 10146 10001 total total tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total total tracklength - - + 10146 10001 total flux analog - - + 10146 10004 total scatter-1 analog - - + 10146 10001 total flux tracklength - - + 10146 10001 total total tracklength - - + 10146 10001 total flux analog - - + 10146 10004 total nu-scatter-1 analog - - + 10146 10001 total flux tracklength - - + 10146 10001 total absorption tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total absorption tracklength - - + 10146 10001 total fission tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total fission tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total nu-fission tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total kappa-fission tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total scatter tracklength - - + 10146 10001 total flux analog - - + 10146 10001 total nu-scatter analog - - + 10146 10001 total flux analog - - - + 10146 10001 10004 total scatter-P3 analog - - + 10146 10001 total flux analog - - - + 10146 10001 10004 total nu-scatter-P3 analog - - - + 10146 10001 10004 total nu-scatter analog - - - + 10146 10001 10004 total scatter analog - - + 10146 10001 total flux analog - - - + 10146 10001 10004 total nu-fission analog - - - + 10146 10001 10004 total scatter analog - - + 10146 10001 total flux tracklength - - + 10146 10001 total scatter tracklength - - - + 10146 10001 10004 total scatter-P3 analog - - + 10146 10001 total flux tracklength - - + 10146 10001 total scatter tracklength - - - + 10146 10001 10004 total scatter-P3 analog - - - + 10146 10001 10004 total nu-scatter-0 analog - - - + 10146 10001 10004 total scatter-0 analog - - + 10146 10045 total nu-fission analog - - + 10146 10004 total nu-fission analog - - + 10146 10045 total prompt-nu-fission analog - - + 10146 10004 total prompt-nu-fission analog - - + 10146 10001 total flux tracklength - - + 10146 10001 total inverse-velocity tracklength - - + 10146 10001 total flux tracklength - - + 10146 10001 total prompt-nu-fission tracklength - - + 10146 10001 total flux analog - - - + 10146 10001 10004 total prompt-nu-fission analog - - + 10146 10001 total flux tracklength - - - + 10146 10058 10001 total delayed-nu-fission tracklength - - - + 10146 10058 10045 total delayed-nu-fission analog - - - + 10146 10058 10004 total delayed-nu-fission analog - - + 10146 10001 total nu-fission tracklength - - - + 10146 10058 10001 total delayed-nu-fission tracklength - - - + 10146 10058 10001 total delayed-nu-fission tracklength - - - + 10146 10058 10001 total decay-rate tracklength - - + 10146 10001 total flux analog - - - - + 10146 10058 10001 10004 total delayed-nu-fission analog diff --git a/tests/test_mgxs_library_nuclides/inputs_true.dat b/tests/test_mgxs_library_nuclides/inputs_true.dat index ec9ff4f1b..72195e90b 100644 --- a/tests/test_mgxs_library_nuclides/inputs_true.dat +++ b/tests/test_mgxs_library_nuclides/inputs_true.dat @@ -50,1127 +50,956 @@ + + 10000 + + + 0.0 0.625 20000000.0 + + + 0.0 0.625 20000000.0 + + + 0.0 20000000.0 + + + 10001 + + + 10002 + - - + 10000 10001 total flux tracklength - - + 10000 10001 U234 U235 U238 O16 total tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 U234 U235 U238 O16 total tracklength - - + 10000 10001 total flux analog - - + 10000 10004 U234 U235 U238 O16 scatter-1 analog - - + 10000 10001 total flux tracklength - - + 10000 10001 U234 U235 U238 O16 total tracklength - - + 10000 10001 total flux analog - - + 10000 10004 U234 U235 U238 O16 nu-scatter-1 analog - - + 10000 10001 total flux tracklength - - + 10000 10001 U234 U235 U238 O16 absorption tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 U234 U235 U238 O16 absorption tracklength - - + 10000 10001 U234 U235 U238 O16 fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 U234 U235 U238 O16 fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 U234 U235 U238 O16 nu-fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 U234 U235 U238 O16 kappa-fission tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 U234 U235 U238 O16 scatter tracklength - - + 10000 10001 total flux analog - - + 10000 10001 U234 U235 U238 O16 nu-scatter analog - - + 10000 10001 total flux analog - - - + 10000 10001 10004 U234 U235 U238 O16 scatter-P3 analog - - + 10000 10001 total flux analog - - - + 10000 10001 10004 U234 U235 U238 O16 nu-scatter-P3 analog - - - + 10000 10001 10004 U234 U235 U238 O16 nu-scatter analog - - - + 10000 10001 10004 U234 U235 U238 O16 scatter analog - - + 10000 10001 total flux analog - - - + 10000 10001 10004 U234 U235 U238 O16 nu-fission analog - - - + 10000 10001 10004 U234 U235 U238 O16 scatter analog - - + 10000 10001 total flux tracklength - - + 10000 10001 U234 U235 U238 O16 scatter tracklength - - - + 10000 10001 10004 U234 U235 U238 O16 scatter-P3 analog - - + 10000 10001 total flux tracklength - - + 10000 10001 U234 U235 U238 O16 scatter tracklength - - - + 10000 10001 10004 U234 U235 U238 O16 scatter-P3 analog - - - + 10000 10001 10004 U234 U235 U238 O16 nu-scatter-0 analog - - - + 10000 10001 10004 U234 U235 U238 O16 scatter-0 analog - - + 10000 10045 U234 U235 U238 O16 nu-fission analog - - + 10000 10004 U234 U235 U238 O16 nu-fission analog - - + 10000 10045 U234 U235 U238 O16 prompt-nu-fission analog - - + 10000 10004 U234 U235 U238 O16 prompt-nu-fission analog - - + 10000 10001 total flux tracklength - - + 10000 10001 U234 U235 U238 O16 inverse-velocity tracklength - - + 10000 10001 total flux tracklength - - + 10000 10001 U234 U235 U238 O16 prompt-nu-fission tracklength - - + 10000 10001 total flux analog - - - + 10000 10001 10004 U234 U235 U238 O16 prompt-nu-fission analog - - + 10056 10001 total flux tracklength - - + 10056 10001 Zr90 Zr91 Zr92 Zr94 Zr96 total tracklength - - + 10056 10001 total flux tracklength - - + 10056 10001 Zr90 Zr91 Zr92 Zr94 Zr96 total tracklength - - + 10056 10001 total flux analog - - + 10056 10004 Zr90 Zr91 Zr92 Zr94 Zr96 scatter-1 analog - - + 10056 10001 total flux tracklength - - + 10056 10001 Zr90 Zr91 Zr92 Zr94 Zr96 total tracklength - - + 10056 10001 total flux analog - - + 10056 10004 Zr90 Zr91 Zr92 Zr94 Zr96 nu-scatter-1 analog - - + 10056 10001 total flux tracklength - - + 10056 10001 Zr90 Zr91 Zr92 Zr94 Zr96 absorption tracklength - - + 10056 10001 total flux tracklength - - + 10056 10001 Zr90 Zr91 Zr92 Zr94 Zr96 absorption tracklength - - + 10056 10001 Zr90 Zr91 Zr92 Zr94 Zr96 fission tracklength - - + 10056 10001 total flux tracklength - - + 10056 10001 Zr90 Zr91 Zr92 Zr94 Zr96 fission tracklength - - + 10056 10001 total flux tracklength - - + 10056 10001 Zr90 Zr91 Zr92 Zr94 Zr96 nu-fission tracklength - - + 10056 10001 total flux tracklength - - + 10056 10001 Zr90 Zr91 Zr92 Zr94 Zr96 kappa-fission tracklength - - + 10056 10001 total flux tracklength - - + 10056 10001 Zr90 Zr91 Zr92 Zr94 Zr96 scatter tracklength - - + 10056 10001 total flux analog - - + 10056 10001 Zr90 Zr91 Zr92 Zr94 Zr96 nu-scatter analog - - + 10056 10001 total flux analog - - - + 10056 10001 10004 Zr90 Zr91 Zr92 Zr94 Zr96 scatter-P3 analog - - + 10056 10001 total flux analog - - - + 10056 10001 10004 Zr90 Zr91 Zr92 Zr94 Zr96 nu-scatter-P3 analog - - - + 10056 10001 10004 Zr90 Zr91 Zr92 Zr94 Zr96 nu-scatter analog - - - + 10056 10001 10004 Zr90 Zr91 Zr92 Zr94 Zr96 scatter analog - - + 10056 10001 total flux analog - - - + 10056 10001 10004 Zr90 Zr91 Zr92 Zr94 Zr96 nu-fission analog - - - + 10056 10001 10004 Zr90 Zr91 Zr92 Zr94 Zr96 scatter analog - - + 10056 10001 total flux tracklength - - + 10056 10001 Zr90 Zr91 Zr92 Zr94 Zr96 scatter tracklength - - - + 10056 10001 10004 Zr90 Zr91 Zr92 Zr94 Zr96 scatter-P3 analog - - + 10056 10001 total flux tracklength - - + 10056 10001 Zr90 Zr91 Zr92 Zr94 Zr96 scatter tracklength - - - + 10056 10001 10004 Zr90 Zr91 Zr92 Zr94 Zr96 scatter-P3 analog - - - + 10056 10001 10004 Zr90 Zr91 Zr92 Zr94 Zr96 nu-scatter-0 analog - - - + 10056 10001 10004 Zr90 Zr91 Zr92 Zr94 Zr96 scatter-0 analog - - + 10056 10045 Zr90 Zr91 Zr92 Zr94 Zr96 nu-fission analog - - + 10056 10004 Zr90 Zr91 Zr92 Zr94 Zr96 nu-fission analog - - + 10056 10045 Zr90 Zr91 Zr92 Zr94 Zr96 prompt-nu-fission analog - - + 10056 10004 Zr90 Zr91 Zr92 Zr94 Zr96 prompt-nu-fission analog - - + 10056 10001 total flux tracklength - - + 10056 10001 Zr90 Zr91 Zr92 Zr94 Zr96 inverse-velocity tracklength - - + 10056 10001 total flux tracklength - - + 10056 10001 Zr90 Zr91 Zr92 Zr94 Zr96 prompt-nu-fission tracklength - - + 10056 10001 total flux analog - - - + 10056 10001 10004 Zr90 Zr91 Zr92 Zr94 Zr96 prompt-nu-fission analog - - + 10112 10001 total flux tracklength - - + 10112 10001 H1 O16 B10 B11 total tracklength - - + 10112 10001 total flux tracklength - - + 10112 10001 H1 O16 B10 B11 total tracklength - - + 10112 10001 total flux analog - - + 10112 10004 H1 O16 B10 B11 scatter-1 analog - - + 10112 10001 total flux tracklength - - + 10112 10001 H1 O16 B10 B11 total tracklength - - + 10112 10001 total flux analog - - + 10112 10004 H1 O16 B10 B11 nu-scatter-1 analog - - + 10112 10001 total flux tracklength - - + 10112 10001 H1 O16 B10 B11 absorption tracklength - - + 10112 10001 total flux tracklength - - + 10112 10001 H1 O16 B10 B11 absorption tracklength - - + 10112 10001 H1 O16 B10 B11 fission tracklength - - + 10112 10001 total flux tracklength - - + 10112 10001 H1 O16 B10 B11 fission tracklength - - + 10112 10001 total flux tracklength - - + 10112 10001 H1 O16 B10 B11 nu-fission tracklength - - + 10112 10001 total flux tracklength - - + 10112 10001 H1 O16 B10 B11 kappa-fission tracklength - - + 10112 10001 total flux tracklength - - + 10112 10001 H1 O16 B10 B11 scatter tracklength - - + 10112 10001 total flux analog - - + 10112 10001 H1 O16 B10 B11 nu-scatter analog - - + 10112 10001 total flux analog - - - + 10112 10001 10004 H1 O16 B10 B11 scatter-P3 analog - - + 10112 10001 total flux analog - - - + 10112 10001 10004 H1 O16 B10 B11 nu-scatter-P3 analog - - - + 10112 10001 10004 H1 O16 B10 B11 nu-scatter analog - - - + 10112 10001 10004 H1 O16 B10 B11 scatter analog - - + 10112 10001 total flux analog - - - + 10112 10001 10004 H1 O16 B10 B11 nu-fission analog - - - + 10112 10001 10004 H1 O16 B10 B11 scatter analog - - + 10112 10001 total flux tracklength - - + 10112 10001 H1 O16 B10 B11 scatter tracklength - - - + 10112 10001 10004 H1 O16 B10 B11 scatter-P3 analog - - + 10112 10001 total flux tracklength - - + 10112 10001 H1 O16 B10 B11 scatter tracklength - - - + 10112 10001 10004 H1 O16 B10 B11 scatter-P3 analog - - - + 10112 10001 10004 H1 O16 B10 B11 nu-scatter-0 analog - - - + 10112 10001 10004 H1 O16 B10 B11 scatter-0 analog - - + 10112 10045 H1 O16 B10 B11 nu-fission analog - - + 10112 10004 H1 O16 B10 B11 nu-fission analog - - + 10112 10045 H1 O16 B10 B11 prompt-nu-fission analog - - + 10112 10004 H1 O16 B10 B11 prompt-nu-fission analog - - + 10112 10001 total flux tracklength - - + 10112 10001 H1 O16 B10 B11 inverse-velocity tracklength - - + 10112 10001 total flux tracklength - - + 10112 10001 H1 O16 B10 B11 prompt-nu-fission tracklength - - + 10112 10001 total flux analog - - - + 10112 10001 10004 H1 O16 B10 B11 prompt-nu-fission analog diff --git a/tests/test_score_current/results_true.dat b/tests/test_score_current/results_true.dat index cb1cebf24..75d61b718 100644 --- a/tests/test_score_current/results_true.dat +++ b/tests/test_score_current/results_true.dat @@ -1 +1 @@ -b08d79380540e6170000f6886a7dc97b9d0c830698ac1c1e009a2c6383d542650d37a0e307a4f82771492f73fcd654f7f5c9d01d28fb3b0e8824678656c63a85 \ No newline at end of file +4675d5101f4f829369c39cb33d654430836b934ab07c165777ba6e214bdf3a698b8082f4f9bb9e78f1f0e495b30ea02cf9b3d14622c59915d818d678a1e5b7b1 \ No newline at end of file diff --git a/tests/test_score_current/tallies.xml b/tests/test_score_current/tallies.xml index 5da08ef9d..3b8f60adb 100644 --- a/tests/test_score_current/tallies.xml +++ b/tests/test_score_current/tallies.xml @@ -8,14 +8,23 @@ 17 17 17 + + mesh + 1 + + + + energy + 0. 0.253 20.0e6 + + - + 1 current - - + 1 2 current diff --git a/tests/test_sourcepoint_restart/tallies.xml b/tests/test_sourcepoint_restart/tallies.xml index fd7ee66fb..db9b2ed75 100644 --- a/tests/test_sourcepoint_restart/tallies.xml +++ b/tests/test_sourcepoint_restart/tallies.xml @@ -8,15 +8,33 @@ 10. 4. 9. + + mesh + 1 + + + + energy + 0.0 5.0e6 10.0e6 + + + + energyout + 0.0 5.0e6 10.0e6 + + + + cell + 1 + + - - - + 1 2 3 scatter-P3 nu-fission - + 4 fission absorption total flux diff --git a/tests/test_statepoint_restart/tallies.xml b/tests/test_statepoint_restart/tallies.xml index fd7ee66fb..db9b2ed75 100644 --- a/tests/test_statepoint_restart/tallies.xml +++ b/tests/test_statepoint_restart/tallies.xml @@ -8,15 +8,33 @@ 10. 4. 9. + + mesh + 1 + + + + energy + 0.0 5.0e6 10.0e6 + + + + energyout + 0.0 5.0e6 10.0e6 + + + + cell + 1 + + - - - + 1 2 3 scatter-P3 nu-fission - + 4 fission absorption total flux diff --git a/tests/test_tallies/inputs_true.dat b/tests/test_tallies/inputs_true.dat index 3123aedaf..ed24f4652 100644 --- a/tests/test_tallies/inputs_true.dat +++ b/tests/test_tallies/inputs_true.dat @@ -314,160 +314,192 @@ -182.07 -182.07 182.07 182.07 + + -3.14159 -1.885 -0.6283 0.6283 1.885 3.14159 + + + 1 + + + 10 21 22 23 + + + 1 2 3 4 5 6 + + + 0.0 0.253 1000.0 1000000.0 20000000.0 + + + 0.0 0.253 1000.0 1000000.0 20000000.0 + + + 1 2 3 4 + + + -1.0 -0.5 0.0 0.5 1.0 + + + 0.0 0.6283 1.2566 1.885 2.5132 3.14159 + + + 1 2 3 4 6 8 + + + 10 21 22 23 60 + + + 21 22 23 27 28 29 60 + - + 10000 flux tracklength - + 10000 flux analog - - + 10000 10001 flux tracklength - + 10002 total - + 10003 delayed-nu-fission - + 10004 total - + 10005 scatter - - + 10004 10005 scatter nu-fission - + 10006 total - + 10007 scatter nu-scatter - - + 10007 10001 scatter nu-scatter - + 10008 flux tracklength - + 10008 flux analog - - + 10008 10001 flux tracklength - + 10009 total - + 10010 absorption delayed-nu-fission events fission inverse-velocity kappa-fission (n,2n) (n,n1) (n,gamma) nu-fission scatter elastic total prompt-nu-fission fission-q-prompt fission-q-recoverable tracklength - + 10010 absorption delayed-nu-fission events fission inverse-velocity kappa-fission (n,2n) (n,n1) (n,gamma) nu-fission scatter elastic total prompt-nu-fission fission-q-prompt fission-q-recoverable analog - + 10010 absorption delayed-nu-fission events fission inverse-velocity kappa-fission (n,2n) (n,n1) (n,gamma) nu-fission scatter elastic total prompt-nu-fission fission-q-prompt fission-q-recoverable collision - + 10011 flux - + 10011 flux-y5 tracklength - + 10011 flux-y5 analog - + 10011 flux-y5 collision - + 10010 scatter scatter-1 scatter-2 scatter-3 scatter-4 nu-scatter nu-scatter-1 nu-scatter-2 nu-scatter-3 nu-scatter-4 - + 10010 scatter-p4 scatter-y4 nu-scatter-p4 nu-scatter-y3 - + 10010 total - + 10010 U235 total total-y4 tracklength - + 10010 U235 total total-y4 analog - + 10010 U235 total total-y4 collision - + 10010 all total tracklength - + 10010 all total collision - + 10001 all total tracklength - + 10001 U235 total tracklength diff --git a/tests/test_tally_aggregation/inputs_true.dat b/tests/test_tally_aggregation/inputs_true.dat index a48d240ea..15071c5e4 100644 --- a/tests/test_tally_aggregation/inputs_true.dat +++ b/tests/test_tally_aggregation/inputs_true.dat @@ -309,9 +309,14 @@ + + 0.0 0.253 1000.0 1000000.0 20000000.0 + + + 60 + - - + 10000 10001 U234 U235 U238 nu-fission total diff --git a/tests/test_tally_arithmetic/inputs_true.dat b/tests/test_tally_arithmetic/inputs_true.dat index 9bacec1a1..197bc1c92 100644 --- a/tests/test_tally_arithmetic/inputs_true.dat +++ b/tests/test_tally_arithmetic/inputs_true.dat @@ -314,16 +314,25 @@ -160.0 -160.0 -183.0 160.0 160.0 183.0 + + 1 3 + + + 0.0 2.53e-07 0.001 1.0 20.0 + + + 60 + + + 1 + - - - + 10001 10000 10002 U234 U235 nu-fission total - - + 10000 10003 U238 U235 total fission diff --git a/tests/test_tally_assumesep/tallies.xml b/tests/test_tally_assumesep/tallies.xml index 2de171471..c588eb9e4 100644 --- a/tests/test_tally_assumesep/tallies.xml +++ b/tests/test_tally_assumesep/tallies.xml @@ -3,19 +3,34 @@ true + + cell + 21 + + + + cell + 22 + + + + cell + 23 + + - + 1 total - + 2 total - + 3 total - \ No newline at end of file + diff --git a/tests/test_tally_slice_merge/inputs_true.dat b/tests/test_tally_slice_merge/inputs_true.dat index 4decaa81c..3ae7d29dc 100644 --- a/tests/test_tally_slice_merge/inputs_true.dat +++ b/tests/test_tally_slice_merge/inputs_true.dat @@ -315,23 +315,32 @@ -50.0 -50.0 50.0 50.0 + + 21 27 + + + 0.0 0.625 20000000.0 + + + 21 + + + 10000 + - - + 10015 10007 U235 U238 fission nu-fission tracklength - - + 10005 10007 U235 U238 fission nu-fission tracklength - - + 10006 10007 U235 U238 fission nu-fission tracklength