diff --git a/openmc/filter.py b/openmc/filter.py index dce3d4924c..ea92f5257c 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -609,7 +609,7 @@ class Filter(object): # If this region is in Cell corresponding to the # distribcell filter bin, store it in dictionary if cell_id == self.bins[0]: - offset = openmc_geometry.get_offset(path, self.offset) + offset = openmc_geometry.get_offset(path) offsets_to_coords[offset] = coords # Each distribcell offset is a DataFrame bin diff --git a/openmc/geometry.py b/openmc/geometry.py index e848e0cddf..16f6a45e5a 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -42,7 +42,7 @@ class Geometry(object): self._root_universe = root_universe - def get_offset(self, path, filter_offset): + def get_offset(self, path): """Returns the corresponding location in the results array for a given path and filter number. This is primarily intended to post-processing result when a distribcell filter is used. @@ -55,8 +55,6 @@ class Geometry(object): lattice passed through. For the case of the lattice, a tuple should be provided to indicate which coordinates in the lattice should be entered. This should be in the form: (lat_id, i_x, i_y, i_z) - filter_offset : int - An integer that specifies which offset map the filter is using Returns ------- @@ -65,14 +63,22 @@ class Geometry(object): """ + # Find the distribcell index of the cell. + cells = self.get_all_cells() + if path[-1] in cells: + distribcell_ind = cells[path[-1]].distribcell_ind + else: + raise RuntimeError('Could not find cell {} specified in a \ + distribcell filter'.format(path[-1])) + # Return memoize'd offset if possible - if (path, filter_offset) in self._offsets: - offset = self._offsets[(path, filter_offset)] + if (path, distribcell_ind) in self._offsets: + offset = self._offsets[(path, distribcell_ind)] # Begin recursive call to compute offset starting with the base Universe else: - offset = self._root_universe.get_offset(path, filter_offset) - self._offsets[(path, filter_offset)] = offset + offset = self._root_universe.get_offset(path, distribcell_ind) + self._offsets[(path, distribcell_ind)] = offset # Return the final offset return offset diff --git a/openmc/summary.py b/openmc/summary.py index bc6551e7cb..9e2145b343 100644 --- a/openmc/summary.py +++ b/openmc/summary.py @@ -271,6 +271,11 @@ class Summary(object): cell.region = Region.from_expression( region, {s.id: s for s in self.surfaces.values()}) + # Get the distribcell index + ind = self._f['geometry/cells'][key]['distribcell_ind'].value + if ind != 0: + cell.distribcell_ind = ind + # Add the Cell to the global dictionary of all Cells self.cells[index] = cell diff --git a/openmc/universe.py b/openmc/universe.py index 98367c381b..b346ffd00d 100644 --- a/openmc/universe.py +++ b/openmc/universe.py @@ -63,6 +63,8 @@ class Cell(object): that is used to translate (shift) the universe. offsets : ndarray Array of offsets used for distributed cell searches + distribcell_ind : int + Index of this cell in distribcell arrays """ @@ -76,6 +78,7 @@ class Cell(object): self._rotation = None self._translation = None self._offsets = None + self._distribcell_ind = None def __eq__(self, other): if not isinstance(other, Cell): @@ -122,6 +125,8 @@ class Cell(object): string += '{0: <16}{1}{2}\n'.format('\tTranslation', '=\t', self._translation) string += '{0: <16}{1}{2}\n'.format('\tOffset', '=\t', self._offsets) + string += '{0: <16}{1}{2}\n'.format('\tDistribcell index', '=\t', + self._distribcell_ind) return string @@ -164,6 +169,10 @@ class Cell(object): def offsets(self): return self._offsets + @property + def distribcell_ind(self): + return self._distribcell_ind + @id.setter def id(self, cell_id): if cell_id is None: @@ -231,6 +240,11 @@ class Cell(object): cv.check_type('cell region', region, Region) self._region = region + @distribcell_ind.setter + def distribcell_ind(self, ind): + cv.check_type('distribcell index', ind, Integral) + self._distribcell_ind = ind + def add_surface(self, surface, halfspace): """Add a half-space to the list of half-spaces whose intersection defines the cell. @@ -271,7 +285,7 @@ class Cell(object): else: self.region = Intersection(self.region, region) - def get_offset(self, path, filter_offset): + def get_offset(self, path, distribcell_ind): # Get the current element and remove it from the list cell_id = path[0] path = path[1:] @@ -282,12 +296,12 @@ class Cell(object): # If the Cell is filled by a Universe elif self._type == 'fill': - offset = self._offsets[filter_offset-1] - offset += self._fill.get_offset(path, filter_offset) + offset = self._offsets[distribcell_ind-1] + offset += self._fill.get_offset(path, distribcell_ind) # If the Cell is filled by a Lattice else: - offset = self._fill.get_offset(path, filter_offset) + offset = self._fill.get_offset(path, distribcell_ind) return offset @@ -591,7 +605,7 @@ class Universe(object): self._cells.clear() - def get_offset(self, path, filter_offset): + def get_offset(self, path, distribcell_ind): # Get the current element and remove it from the list path = path[1:] @@ -599,7 +613,7 @@ class Universe(object): cell_id = path[0] # Make a recursive call to the Cell within this Universe - offset = self._cells[cell_id].get_offset(path, filter_offset) + offset = self._cells[cell_id].get_offset(path, distribcell_ind) # Return the offset computed at all nested Universe levels return offset @@ -1059,21 +1073,22 @@ class RectLattice(Lattice): cv.check_greater_than('lattice pitch', dim, 0.0) self._pitch = pitch - def get_offset(self, path, filter_offset): + def get_offset(self, path, distribcell_ind): # Get the current element and remove it from the list i = path[0] path = path[1:] # For 2D Lattices if len(self._dimension) == 2: - offset = self._offsets[i[1]-1, i[2]-1, 0, filter_offset-1] - offset += self._universes[i[1]][i[2]].get_offset(path, filter_offset) + offset = self._offsets[i[1]-1, i[2]-1, 0, distribcell_ind-1] + offset += self._universes[i[1]][i[2]].get_offset(path, + distribcell_ind) # For 3D Lattices else: - offset = self._offsets[i[1]-1, i[2]-1, i[3]-1, filter_offset-1] + offset = self._offsets[i[1]-1, i[2]-1, i[3]-1, distribcell_ind-1] offset += self._universes[i[1]-1][i[2]-1][i[3]-1].get_offset(path, - filter_offset) + distribcell_ind) return offset diff --git a/src/input_xml.F90 b/src/input_xml.F90 index abd6e29092..a4317ed8e3 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -1049,8 +1049,9 @@ contains do i = 1, n_cells c => cells(i) - ! Initialize the number of cell instances - this is a base case for distribcells + ! Initialize distribcell instances and distribcell index c % instances = 0 + c % distribcell_ind = NONE ! Get pointer to i-th cell node call get_list_item(node_cell_list, i, node_cell) diff --git a/src/output.F90 b/src/output.F90 index 8be6c09dab..5b938e98d3 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -1449,17 +1449,13 @@ contains ! Look through all cells in this universe do i = 1, n - - cell_index = univ % cells(i) - c => cells(cell_index) - - ! If the cell ID matches the goal and the offset matches final, - ! write to the geometry stack - if (cell_dict % get_key(c % id) == goal .AND. offset == final) then - path = trim(path) // "->" // to_str(c%id) + ! If the cell matches the goal and the offset matches final, write to the + ! geometry stack + if (univ % cells(i) == goal .AND. offset == final) then + c => cells(univ % cells(i)) + path = trim(path) // "->" // to_str(c % id) return end if - end do ! Find the fill cell or lattice cell that we need to enter