diff --git a/openmc/filter.py b/openmc/filter.py index a0c777fa07..54814a6b6f 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -673,9 +673,11 @@ class Filter(object): # Assign entry to Lattice Multi-index column else: + # Reverse y index per lattice ordering in OpenCG level_dict[lat_id_key][offset] = coords._lattice._id level_dict[lat_x_key][offset] = coords._lat_x - level_dict[lat_y_key][offset] = coords._lat_y + level_dict[lat_y_key][offset] = \ + coords._lattice.dimension[1] - coords._lat_y - 1 level_dict[lat_z_key][offset] = coords._lat_z # Move to next node in LocalCoords linked list diff --git a/openmc/summary.py b/openmc/summary.py index 3e10f8edbd..d22e367c95 100644 --- a/openmc/summary.py +++ b/openmc/summary.py @@ -369,7 +369,7 @@ class Summary(object): # Set the distribcell offsets for the lattice if offsets is not None: - lattice.offsets = offsets + lattice.offsets = offsets[:, ::-1, :] # Add the Lattice to the global dictionary of all Lattices self.lattices[index] = lattice diff --git a/openmc/tallies.py b/openmc/tallies.py index 3c4d99c730..3294a1d062 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -2748,7 +2748,7 @@ class Tally(object): bin_indices.append(bin_index) num_bins += 1 - find_filter.bins = set(find_filter.bins[bin_indices]) + find_filter.bins = np.unique(find_filter.bins[bin_indices]) find_filter.num_bins = num_bins # Update the new tally's filter strides diff --git a/setup.py b/setup.py index 0bf4549c03..87fdff68cf 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ kwargs = {'name': 'openmc', if have_setuptools: kwargs.update({ # Required dependencies - 'install_requires': ['numpy', 'h5py', 'matplotlib'], + 'install_requires': ['numpy>=1.9', 'h5py', 'matplotlib'], # Optional dependencies 'extras_require': { diff --git a/tests/test_asymmetric_lattice/inputs_true.dat b/tests/test_asymmetric_lattice/inputs_true.dat new file mode 100644 index 0000000000..e3b00b185c --- /dev/null +++ b/tests/test_asymmetric_lattice/inputs_true.dat @@ -0,0 +1 @@ +b9b4222c4beea80fe6083590f6b785303d174972d80671fb661bac8e030db6f4a61648240cfad6162799361fc0e08a23c61d31aff844d978528d6dad5b5fbc63 \ No newline at end of file diff --git a/tests/test_asymmetric_lattice/results_true.dat b/tests/test_asymmetric_lattice/results_true.dat new file mode 100644 index 0000000000..ec4b883886 --- /dev/null +++ b/tests/test_asymmetric_lattice/results_true.dat @@ -0,0 +1 @@ +b5f96919ca474cd1c9c9d0acde3b8aac4a1cf636443c72a38b6c5a4221a8ce3e90182aaef2f664e44b9175ca257a89db2328b63e19388ee0e5006de4b3d92ce6 \ No newline at end of file diff --git a/tests/test_asymmetric_lattice/test_asymmetric_lattice.py b/tests/test_asymmetric_lattice/test_asymmetric_lattice.py new file mode 100644 index 0000000000..5a1d47ef85 --- /dev/null +++ b/tests/test_asymmetric_lattice/test_asymmetric_lattice.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python + +import os +import sys +import glob +import hashlib +sys.path.insert(0, os.pardir) +from testing_harness import PyAPITestHarness +import openmc +from openmc.source import Source +from openmc.stats import Box + + +class AsymmetricLatticeTestHarness(PyAPITestHarness): + + def _build_inputs(self): + """Build an axis-asymmetric lattice of fuel assemblies""" + + # Build full core geometry from underlying input set + self._input_set.build_default_materials_and_geometry() + + # Extract all universes from the full core geometry + geometry = self._input_set.geometry.geometry + all_univs = geometry.get_all_universes() + + # Extract universes encapsulating fuel and water assemblies + water = all_univs[7] + fuel = all_univs[8] + + # Construct a 3x3 lattice of fuel assemblies + core_lat = openmc.RectLattice(name='3x3 Core Lattice', lattice_id=202) + core_lat.dimension = (3, 3) + core_lat.lower_left = (-32.13, -32.13) + core_lat.pitch = (21.42, 21.42) + core_lat.universes = [[fuel, water, water], + [fuel, fuel, fuel], + [water, water, water]] + + # Create bounding surfaces + min_x = openmc.XPlane(x0=-32.13, boundary_type='reflective') + max_x = openmc.XPlane(x0=+32.13, boundary_type='reflective') + min_y = openmc.YPlane(y0=-32.13, boundary_type='reflective') + max_y = openmc.YPlane(y0=+32.13, boundary_type='reflective') + min_z = openmc.ZPlane(z0=0, boundary_type='reflective') + max_z = openmc.ZPlane(z0=+32.13, boundary_type='reflective') + + # Define root universe + root_univ = openmc.Universe(universe_id=0, name='root universe') + root_cell = openmc.Cell(cell_id=1) + root_cell.region = +min_x & -max_x & +min_y & -max_y & +min_z & -max_z + root_cell.fill = core_lat + root_univ.add_cell(root_cell) + + # Over-ride geometry in the input set with this 3x3 lattice + self._input_set.geometry.geometry.root_universe = root_univ + + # Initialize a "distribcell" filter for the fuel pin cell + distrib_filter = openmc.Filter(type='distribcell', bins=[27]) + + # Initialize the tallies + tally = openmc.Tally(name='distribcell tally', tally_id=27) + tally.add_filter(distrib_filter) + tally.add_score('nu-fission') + + # Initialize the tallies file + tallies_file = openmc.TalliesFile() + tallies_file.add_tally(tally) + + # Assign the tallies file to the input set + self._input_set.tallies = tallies_file + + # Build default settings + self._input_set.build_default_settings() + + # Specify summary output and correct source sampling box + source = Source(space=Box([-32, -32, 0], [32, 32, 32])) + source.space.only_fissionable = True + self._input_set.settings.source = source + self._input_set.settings.output = {'summary': True} + + # Write input XML files + self._input_set.export() + + def _get_results(self, hash_output=True): + """Digest info in statepoint and summary and return as a string.""" + + # Read the statepoint file + statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] + sp = openmc.StatePoint(statepoint) + + # Read the summary file + summary = glob.glob(os.path.join(os.getcwd(), 'summary.h5'))[0] + su = openmc.Summary(summary) + sp.link_with_summary(su) + + # Extract the tally of interest + tally = sp.get_tally(name='distribcell tally') + + # Create a string of all mean, std. dev. values for both tallies + outstr = '' + outstr += ', '.join(map(str, tally.mean.flatten())) + '\n' + outstr += ', '.join(map(str, tally.std_dev.flatten())) + '\n' + + # Extract fuel assembly lattices from the summary + all_cells = su.openmc_geometry.get_all_cells() + fuel = all_cells[80].fill + core = all_cells[1].fill + + # Append a string of lattice distribcell offsets to the string + outstr += ', '.join(map(str, fuel.offsets.flatten())) + '\n' + outstr += ', '.join(map(str, core.offsets.flatten())) + '\n' + + # Hash the results if necessary + if hash_output: + sha512 = hashlib.sha512() + sha512.update(outstr.encode('utf-8')) + outstr = sha512.hexdigest() + + return outstr + + def _cleanup(self): + super(AsymmetricLatticeTestHarness, self)._cleanup() + f = os.path.join(os.getcwd(), 'tallies.xml') + if os.path.exists(f): os.remove(f) + + +if __name__ == '__main__': + harness = AsymmetricLatticeTestHarness('statepoint.10.h5', True) + harness.main()