diff --git a/openmc/cell.py b/openmc/cell.py index a062702011..033972a38c 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -104,6 +104,7 @@ class Cell(object): self._temperature = None self._translation = None self._paths = [] + self._num_instances = None self._volume = None self._atoms = None @@ -229,7 +230,7 @@ class Cell(object): @property def num_instances(self): - return len(self.paths) + return self._num_instances @id.setter def id(self, cell_id): @@ -528,11 +529,12 @@ class Cell(object): # If no nemoize'd clone exists, instantiate one if self not in memo: # Temporarily remove paths - paths = self.paths + paths = self._paths self._paths = None clone = deepcopy(self) clone.id = None + clone._num_instances = None # Restore paths on original instance self._paths = paths diff --git a/openmc/geometry.py b/openmc/geometry.py index 27fee65739..642b3ce96c 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -258,7 +258,7 @@ class Geometry(object): lattices[cell.fill.id] = cell.fill return lattices - + def get_all_surfaces(self): """ Return all surfaces used in the geometry @@ -270,11 +270,11 @@ class Geometry(object): """ surfaces = OrderedDict() - + for cell in self.get_all_cells().values(): surfaces = cell.region.get_surfaces(surfaces) return surfaces - + def get_materials_by_name(self, name, case_sensitive=False, matching=False): """Return a list of materials with matching names. @@ -482,22 +482,30 @@ class Geometry(object): lattices.sort(key=lambda x: x.id) return lattices - def determine_paths(self): + def determine_paths(self, instances_only=False): """Determine paths through CSG tree for cells and materials. This method recursively traverses the CSG tree to determine each unique path that reaches every cell and material. The paths are stored in the :attr:`Cell.paths` and :attr:`Material.paths` attributes. + Parameters + ---------- + instances_only : bool + If true, this method will only determine the number of instances of + each cell and material. + """ # (Re-)initialize all cell instances to 0 for cell in self.get_all_cells().values(): cell._paths = [] + cell._num_instances = 0 for material in self.get_all_materials().values(): material._paths = [] + material._num_instances = 0 # Recursively traverse the CSG tree to count all cell instances - self.root_universe._determine_paths() + self.root_universe._determine_paths(instances_only=instances_only) def clone(self): """Create a copy of this geometry with new unique IDs for all of its diff --git a/openmc/material.py b/openmc/material.py index f7ca9c9fde..f4c30da81d 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -98,6 +98,7 @@ class Material(object): self._density_units = '' self._depletable = False self._paths = [] + self._num_instances = None self._volume = None self._atoms = {} @@ -216,7 +217,7 @@ class Material(object): @property def num_instances(self): - return len(self.paths) + return self._num_instances @property def elements(self): @@ -298,11 +299,6 @@ class Material(object): cv.check_type('material volume', volume, Real) self._volume = volume - @num_instances.setter - def num_instances(self, num_instances): - cv.check_type('num_instances', num_instances, Integral) - self._num_instances = num_instances - @classmethod def from_hdf5(cls, group): """Create material from HDF5 group @@ -823,11 +819,12 @@ class Material(object): # Temporarily remove paths -- this is done so that when the clone is # made, it doesn't create a copy of the paths (which are specific to # an instance) - paths = self.paths + paths = self._paths self._paths = None clone = deepcopy(self) clone.id = None + clone._num_instances = None # Restore paths on original instance self._paths = paths diff --git a/openmc/universe.py b/openmc/universe.py index d36b167a51..a03e8ba873 100644 --- a/openmc/universe.py +++ b/openmc/universe.py @@ -566,7 +566,7 @@ class Universe(object): cell_element.set("universe", str(self._id)) xml_element.append(cell_element) - def _determine_paths(self, path=''): + def _determine_paths(self, path='', instances_only=False): """Count the number of instances for each cell in the universe, and record the count in the :attr:`Cell.num_instances` properties.""" @@ -577,7 +577,7 @@ class Universe(object): # If universe-filled, recursively count cells in filling universe if cell.fill_type == 'universe': - cell.fill._determine_paths(cell_path + '->') + cell.fill._determine_paths(cell_path + '->', instances_only) # If lattice-filled, recursively call for all universes in lattice elif cell.fill_type == 'lattice': @@ -588,18 +588,22 @@ class Universe(object): latt_path = '{}->l{}({})->'.format( cell_path, latt.id, ",".join(str(x) for x in index)) univ = latt.get_universe(index) - univ._determine_paths(latt_path) + univ._determine_paths(latt_path, instances_only) else: if cell.fill_type == 'material': mat = cell.fill elif cell.fill_type == 'distribmat': - mat = cell.fill[len(cell._paths)] + mat = cell.fill[cell._num_instances] else: mat = None if mat is not None: - mat._paths.append('{}->m{}'.format(cell_path, mat.id)) + mat._num_instances += 1 + if not instances_only: + mat._paths.append('{}->m{}'.format(cell_path, mat.id)) # Append current path - cell._paths.append(cell_path) + cell._num_instances += 1 + if not instances_only: + cell._paths.append(cell_path)