From c6348700cec052b4c8c0eb328d7b4518104281f2 Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Fri, 3 Mar 2017 16:47:36 -0500 Subject: [PATCH] Refactored cell/material instance counting into recursive methods defined on Universe class per request by @paulromano --- openmc/cell.py | 19 ++++---- openmc/geometry.py | 108 ++++++--------------------------------------- openmc/lattice.py | 16 +------ openmc/material.py | 10 +++-- openmc/universe.py | 50 +++++++++++++++++++++ 5 files changed, 81 insertions(+), 122 deletions(-) diff --git a/openmc/cell.py b/openmc/cell.py index d39816a6a8..ca57987734 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -86,14 +86,14 @@ class Cell(object): distribcell_paths : list of str The paths traversed through the CSG tree to reach each distribcell instance + num_instances : int + The number of instances of this cell throughout the geometry. This + property is initialized by calling the + :meth:`Geometry.count_cell_instances` method. volume : float Volume of the cell in cm^3. This can either be set manually or calculated in a stochastic volume calculation and added via the :meth:`Cell.add_volume_information` method. - num_instances : int - The number of instances of this cell throughout the geometry. This - property is initialized by calling the - :meth:`Geometry.count_cell_instances()` method. """ @@ -235,7 +235,11 @@ class Cell(object): @property def num_instances(self): - return self._num_instances + if self._num_instances is None: + raise ValueError('The number of cell instances is unknown. Call ' + 'the Geometry.count_cell_instances() method.') + else: + return self._num_instances @id.setter def id(self, cell_id): @@ -353,11 +357,6 @@ class Cell(object): string_types) self._distribcell_paths = distribcell_paths - @num_instances.setter - def num_instances(self, num_instances): - cv.check_type('num_instances', num_instances, Integral) - self._num_instances = num_instances - def add_surface(self, surface, halfspace): """Add a half-space to the list of half-spaces whose intersection defines the cell. diff --git a/openmc/geometry.py b/openmc/geometry.py index 22c4307bda..408c253e3a 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -450,104 +450,24 @@ class Geometry(object): lattices.sort(key=lambda x: x.id) return lattices - def count_cell_instances(self, universe=None): + def count_cell_instances(self): """Count the number of instances for each cell in the Geometry, and - record the count in the :attr:`Cell.num_instances` properties. + record the count in the :attr:`Cell.num_instances` properties.""" - Parameters - ---------- - universe : openmc.Universe or None - The Universe to use at each recursive call of this method. - This parameter defaults to None and should not be set - by the user. + # (Re-)initialize all cell instances to 0 + for cell in self.get_all_cells().values(): + cell._num_instances = 0 - """ + # Recursively traverse the CSG tree to count all cell instances + self.root_universe._count_cell_instances() - if universe is None: - universe = self.root_universe - - # (Re-)initialize all cell instances to 0 - for cell in self.get_all_cells().values(): - cell.num_instances = 0 - - if universe is None: - raise RuntimeError( - 'Unable to count cell instances without a root universe') - - for cell in universe.cells.values(): - # Increment the number of cell instances - cell.num_instances += 1 - - # If material-filled, we are finished with all levels - if cell.fill_type == 'material': - continue - - # If universe-filled, recursively count cells in filling universe - elif cell.fill_type == 'universe': - self.count_cell_instances(cell.fill) - - # If lattice-filled, recursively call for all universes in lattice - elif cell.fill_type == 'lattice': - latt = cell.fill - - # Extract a list of tuples of the valid indices - # into this Lattice's universes array - valid_indices = latt.indices - - # Count instances in each Universe in the Lattice - for index in valid_indices: - if latt.ndim == 3: - univ = latt.universes[index[0]][index[1]][index[2]] - else: - univ = latt.universes[index[0]][index[1]] - self.count_cell_instances(univ) - - def count_material_instances(self, universe=None): + def count_material_instances(self): """Count the number of instances for each material in the Geometry, and - record the count in the :attr:`Material.num_instances` properties. + record the count in the :attr:`Material.num_instances` properties.""" - Parameters - ---------- - universe : openmc.Universe or None - The Universe to use at each recursive call of this method. - This parameter defaults to None and should not be set - by the user. + # (Re-)initialize all material instances to 0 + for material in self.get_all_materials().values(): + material._num_instances = 0 - """ - - if universe is None: - universe = self.root_universe - - # (Re-)initialize all material instances to 0 - for material in self.get_all_materials().values(): - material.num_instances = 0 - - if universe is None: - raise RuntimeError( - 'Unable to count material instances without a root universe') - - for cell in universe.cells.values(): - - # If material-filled, we are finished with all levels - if cell.fill_type == 'material': - cell.fill.num_instances += 1 - - # If universe-filled, recursively count materials in filling universe - elif cell.fill_type == 'universe': - self.count_material_instances(cell.fill) - - # If lattice-filled, recursively call for all universes in lattice - elif cell.fill_type == 'lattice': - latt = cell.fill - - # Extract a list of tuples of the valid indices - # into this Lattice's universes array - valid_indices = latt.indices - - # Count instances in each Universe in the Lattice - for index in valid_indices: - if latt.ndim == 3: - univ = latt.universes[index[0]][index[1]][index[2]] - else: - univ = latt.universes[index[0]][index[1]] - self.count_material_instances(univ) + # Recursively traverse the CSG tree to count all cell instances + self.root_universe._count_material_instances() \ No newline at end of file diff --git a/openmc/lattice.py b/openmc/lattice.py index cba1cdece7..298b5842a3 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -924,10 +924,7 @@ class HexLattice(Lattice): @property def ndim(self): - if isinstance(self.universes[0][0], openmc.Universe): - return 2 - else: - return 3 + return 2 if isinstance(self.universes[0][0], openmc.Universe) else 3 @center.setter def center(self, center): @@ -955,17 +952,6 @@ class HexLattice(Lattice): # The Universes within each sub-list are ordered from the "top" in a # clockwise fashion. - # Check to see if the given universes look like a 2D or a 3D array. - if isinstance(self._universes[0][0], openmc.Universe): - pass - elif isinstance(self._universes[0][0][0], openmc.Universe): - pass - else: - msg = 'HexLattice ID={0:d} does not appear to be either 2D or ' \ - '3D. Make sure set_universes was given a two-deep or ' \ - 'three-deep iterable of universes.'.format(self._id) - raise RuntimeError(msg) - # Set the number of axial positions. if self.ndim == 3: self._num_axial = len(self._universes) diff --git a/openmc/material.py b/openmc/material.py index c0a1f59254..007e015914 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -76,9 +76,9 @@ class Material(object): calculated in a stochastic volume calculation and added via the :meth:`Material.add_volume_information` method. num_instances : int - The number of instances of this cell throughout the geometry. This + The number of instances of this material throughout the geometry. This property is initialized by calling the - :meth:`Geometry.count_cell_instances()` method. + :meth:`Geometry.count_material_instances` method. """ @@ -202,7 +202,11 @@ class Material(object): @property def num_instances(self): - return self._num_instances + if self._num_instances is None: + raise ValueError('The number of cell instances is unknown. Call ' + 'the Geometry.count_cell_instances() method.') + else: + return self._num_instances @property def elements(self): diff --git a/openmc/universe.py b/openmc/universe.py index 5e001ae6ac..4257c1d155 100644 --- a/openmc/universe.py +++ b/openmc/universe.py @@ -519,3 +519,53 @@ class Universe(object): # Append the Universe ID to the subelement and add to Element cell_element.set("universe", str(self._id)) xml_element.append(cell_element) + + def _count_cell_instances(self): + """Count the number of instances for each cell in the universe, and + record the count in the :attr:`Cell.num_instances` properties.""" + + for cell in self.cells.values(): + # Increment the number of cell instances + cell._num_instances += 1 + + # If universe-filled, recursively count cells in filling universe + if cell.fill_type == 'universe': + cell.fill._count_cell_instances() + + # If lattice-filled, recursively call for all universes in lattice + elif cell.fill_type == 'lattice': + latt = cell.fill + + # Count instances in each universe in the lattice + for index in latt.indices: + if latt.ndim == 3: + univ = latt.universes[index[0]][index[1]][index[2]] + else: + univ = latt.universes[index[0]][index[1]] + univ._count_cell_instances() + + def _count_material_instances(self): + """Count the number of instances for each material in the Universe, and + record the count in the :attr:`Material.num_instances` properties.""" + + for cell in self.cells.values(): + + # If material-filled, we are finished with all levels + if cell.fill_type == 'material': + cell.fill._num_instances += 1 + + # If universe-filled, recursively count materials in filling universe + elif cell.fill_type == 'universe': + cell.fill._count_material_instances() + + # If lattice-filled, recursively call for all universes in lattice + elif cell.fill_type == 'lattice': + latt = cell.fill + + # Count instances in each universe in the lattice + for index in latt.indices: + if latt.ndim == 3: + univ = latt.universes[index[0]][index[1]][index[2]] + else: + univ = latt.universes[index[0]][index[1]] + univ._count_material_instances()