From 472e156a7745e645ef5f5f38b99eb5bbf17ada6c Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Wed, 8 May 2024 16:52:01 -0500 Subject: [PATCH 1/6] Adding a memo to get_all_universes --- openmc/cell.py | 6 +++--- openmc/geometry.py | 2 +- openmc/lattice.py | 8 +++++++- openmc/universe.py | 6 +++--- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/openmc/cell.py b/openmc/cell.py index 94fac841358..29da0fe9f30 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -465,7 +465,7 @@ def get_all_materials(self, memo=None): return materials - def get_all_universes(self): + def get_all_universes(self, memo=None): """Return all universes that are contained within this one if any of its cells are filled with a universe or lattice. @@ -481,9 +481,9 @@ def get_all_universes(self): if self.fill_type == 'universe': universes[self.fill.id] = self.fill - universes.update(self.fill.get_all_universes()) + universes.update(self.fill.get_all_universes(memo)) elif self.fill_type == 'lattice': - universes.update(self.fill.get_all_universes()) + universes.update(self.fill.get_all_universes(memo)) return universes diff --git a/openmc/geometry.py b/openmc/geometry.py index 175cef2bf37..e7a12b01539 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -389,7 +389,7 @@ def get_all_universes(self) -> typing.Dict[int, openmc.Universe]: """ universes = {} universes[self.root_universe.id] = self.root_universe - universes.update(self.root_universe.get_all_universes()) + universes.update(self.root_universe.get_all_universes(memo=set())) return universes def get_all_nuclides(self) -> typing.List[str]: diff --git a/openmc/lattice.py b/openmc/lattice.py index 40b97f6cf5c..eaa0ead7eb9 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -203,7 +203,7 @@ def get_all_materials(self, memo=None): return materials - def get_all_universes(self): + def get_all_universes(self, memo): """Return all universes that are contained within the lattice Returns @@ -218,6 +218,12 @@ def get_all_universes(self): # in each nested Universe level all_universes = {} + if memo and self in memo: + return all_universes + + if memo is not None: + memo.add(self) + # Get all unique Universes contained in each of the lattice cells unique_universes = self.get_unique_universes() diff --git a/openmc/universe.py b/openmc/universe.py index 2e86ab05a9b..55bac1db523 100644 --- a/openmc/universe.py +++ b/openmc/universe.py @@ -90,7 +90,7 @@ def add_volume_information(self, volume_calc): else: raise ValueError('No volume information found for this universe.') - def get_all_universes(self): + def get_all_universes(self, memo=None): """Return all universes that are contained within this one. Returns @@ -102,8 +102,8 @@ def get_all_universes(self): """ # Append all Universes within each Cell to the dictionary universes = {} - for cell in self.get_all_cells().values(): - universes.update(cell.get_all_universes()) + for cell in self.get_all_cells(memo).values(): + universes.update(cell.get_all_universes(memo)) return universes From 9aa6d77de849cd036db8430e8223e491fb8c5595 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Thu, 9 May 2024 10:22:57 -0500 Subject: [PATCH 2/6] Employ memo at a universe level and use a new memo for get_all_cells call --- openmc/universe.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/openmc/universe.py b/openmc/universe.py index 55bac1db523..6d5d89024e0 100644 --- a/openmc/universe.py +++ b/openmc/universe.py @@ -100,9 +100,16 @@ def get_all_universes(self, memo=None): :class:`Universe` instances """ + + if memo and self in memo: + return {} + + if memo is not None: + memo.add(self) + # Append all Universes within each Cell to the dictionary universes = {} - for cell in self.get_all_cells(memo).values(): + for cell in self.get_all_cells(memo=set()).values(): universes.update(cell.get_all_universes(memo)) return universes From 6f8a079e8563e1ff951a07613b553433fca71d53 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Thu, 9 May 2024 10:23:27 -0500 Subject: [PATCH 3/6] apply memo at cell level --- openmc/cell.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/openmc/cell.py b/openmc/cell.py index 29da0fe9f30..e7eece1ae8d 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -476,9 +476,14 @@ def get_all_universes(self, memo=None): :class:`Universe` instances """ - universes = {} + if memo and self in memo: + return universes + + if memo is not None: + memo.add(self) + if self.fill_type == 'universe': universes[self.fill.id] = self.fill universes.update(self.fill.get_all_universes(memo)) From 5e5eb4eb26f0fb496bfcb1a6b70bb7f37950d776 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Thu, 9 May 2024 10:23:51 -0500 Subject: [PATCH 4/6] Make memo optional for lattices and apply memo for lattice objects --- openmc/lattice.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openmc/lattice.py b/openmc/lattice.py index eaa0ead7eb9..e55965d90ba 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -203,7 +203,7 @@ def get_all_materials(self, memo=None): return materials - def get_all_universes(self, memo): + def get_all_universes(self, memo=None): """Return all universes that are contained within the lattice Returns @@ -232,7 +232,7 @@ def get_all_universes(self, memo): # Append all Universes containing each cell to the dictionary for universe in unique_universes.values(): - all_universes.update(universe.get_all_universes()) + all_universes.update(universe.get_all_universes(memo)) return all_universes From feb57295d943a79d61c38f266f350cdc41640ffa Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Tue, 14 May 2024 12:42:15 -0500 Subject: [PATCH 5/6] Always create memo sets if memo is None --- openmc/cell.py | 32 ++++++++++++++++---------------- openmc/geometry.py | 8 ++++---- openmc/lattice.py | 36 +++++++++++++++++++++++------------- openmc/tallies.py | 1 + openmc/universe.py | 39 ++++++++++++++++++++++++--------------- 5 files changed, 68 insertions(+), 48 deletions(-) diff --git a/openmc/cell.py b/openmc/cell.py index e7eece1ae8d..ad46a27e955 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -426,15 +426,15 @@ def get_all_cells(self, memo=None): instances """ + if memo is None: + memo = set() - cells = {} - - if memo and self in memo: - return cells + if self in memo: + return {} - if memo is not None: - memo.add(self) + memo.add(self) + cells = {} if self.fill_type in ('universe', 'lattice'): cells.update(self.fill.get_all_cells(memo)) @@ -476,14 +476,13 @@ def get_all_universes(self, memo=None): :class:`Universe` instances """ - universes = {} - - if memo and self in memo: - return universes - - if memo is not None: - memo.add(self) + if memo is None: + memo = set() + if self in memo: + return {} + memo.add(self) + universes = {} if self.fill_type == 'universe': universes[self.fill.id] = self.fill universes.update(self.fill.get_all_universes(memo)) @@ -683,10 +682,11 @@ def create_xml_subelement(self, xml_element, memo=None): # thus far. def create_surface_elements(node, element, memo=None): if isinstance(node, Halfspace): - if memo and node.surface in memo: + if memo is None: + memo = set() + if node.surface in memo: return - if memo is not None: - memo.add(node.surface) + memo.add(node.surface) xml_element.append(node.surface.to_xml_element()) elif isinstance(node, Complement): diff --git a/openmc/geometry.py b/openmc/geometry.py index e7a12b01539..db927c46ec1 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -134,7 +134,7 @@ def to_xml_element(self, remove_surfs=False) -> ET.Element: # Create XML representation element = ET.Element("geometry") - self.root_universe.create_xml_subelement(element, memo=set()) + self.root_universe.create_xml_subelement(element) # Sort the elements in the file element[:] = sorted(element, key=lambda x: ( @@ -373,7 +373,7 @@ def get_all_cells(self) -> typing.Dict[int, openmc.Cell]: """ if self.root_universe is not None: - return self.root_universe.get_all_cells(memo=set()) + return self.root_universe.get_all_cells() else: return {} @@ -389,7 +389,7 @@ def get_all_universes(self) -> typing.Dict[int, openmc.Universe]: """ universes = {} universes[self.root_universe.id] = self.root_universe - universes.update(self.root_universe.get_all_universes(memo=set())) + universes.update(self.root_universe.get_all_universes()) return universes def get_all_nuclides(self) -> typing.List[str]: @@ -417,7 +417,7 @@ def get_all_materials(self) -> typing.Dict[int, openmc.Material]: """ if self.root_universe is not None: - return self.root_universe.get_all_materials(memo=set()) + return self.root_universe.get_all_materials() else: return {} diff --git a/openmc/lattice.py b/openmc/lattice.py index e55965d90ba..8ab481091b3 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -170,11 +170,13 @@ def get_all_cells(self, memo=None): """ cells = {} - if memo and self in memo: + if memo is None: + memo = set() + + if self in memo: return cells - if memo is not None: - memo.add(self) + memo.add(self) unique_universes = self.get_unique_universes() @@ -194,6 +196,9 @@ def get_all_materials(self, memo=None): """ + if memo is None: + memo = set() + materials = {} # Append all Cells in each Cell in the Universe to the dictionary @@ -213,16 +218,17 @@ def get_all_universes(self, memo=None): :class:`Universe` instances """ - # Initialize a dictionary of all Universes contained by the Lattice # in each nested Universe level all_universes = {} - if memo and self in memo: + if memo is None: + memo = set() + + if self in memo: return all_universes - if memo is not None: - memo.add(self) + memo.add(self) # Get all unique Universes contained in each of the lattice cells unique_universes = self.get_unique_universes() @@ -852,10 +858,13 @@ def create_xml_subelement(self, xml_element, memo=None): """ # If the element already contains the Lattice subelement, then return - if memo and self in memo: + if memo is None: + memo = set() + + if self in memo: return - if memo is not None: - memo.add(self) + + memo.add(self) # Make sure universes have been assigned if self.universes is None: @@ -1423,10 +1432,11 @@ def is_valid_index(self, idx): def create_xml_subelement(self, xml_element, memo=None): # If this subelement has already been written, return - if memo and self in memo: + if memo is None: + memo = set() + if self in memo: return - if memo is not None: - memo.add(self) + memo.add(self) lattice_subelement = ET.Element("hex_lattice") lattice_subelement.set("id", str(self._id)) diff --git a/openmc/tallies.py b/openmc/tallies.py index 04ae00b6a32..f39ffa0789f 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -3209,6 +3209,7 @@ def _create_derivative_subelements(self, root_element): def to_xml_element(self, memo=None): """Creates a 'tallies' element to be written to an XML file. """ + memo = memo if memo is not None else set() element = ET.Element("tallies") self._create_mesh_subelements(element, memo) self._create_filter_subelements(element) diff --git a/openmc/universe.py b/openmc/universe.py index 6d5d89024e0..ecca20617db 100644 --- a/openmc/universe.py +++ b/openmc/universe.py @@ -100,16 +100,17 @@ def get_all_universes(self, memo=None): :class:`Universe` instances """ + if memo is None: + memo = set() - if memo and self in memo: + if self in memo: return {} - if memo is not None: - memo.add(self) + memo.add(self) # Append all Universes within each Cell to the dictionary universes = {} - for cell in self.get_all_cells(memo=set()).values(): + for cell in self.get_all_cells().values(): universes.update(cell.get_all_universes(memo)) return universes @@ -646,15 +647,16 @@ def get_all_cells(self, memo=None): """ - cells = {} + if memo is None: + memo = set() - if memo and self in memo: - return cells + if self in memo: + return {} - if memo is not None: - memo.add(self) + memo.add(self) # Add this Universe's cells to the dictionary + cells = {} cells.update(self._cells) # Append all Cells in each Cell in the Universe to the dictionary @@ -674,6 +676,9 @@ def get_all_materials(self, memo=None): """ + if memo is None: + memo = set() + materials = {} # Append all Cells in each Cell in the Universe to the dictionary @@ -684,15 +689,17 @@ def get_all_materials(self, memo=None): return materials def create_xml_subelement(self, xml_element, memo=None): + if memo is None: + memo = set() + # Iterate over all Cells for cell in self._cells.values(): # If the cell was already written, move on - if memo and cell in memo: + if cell in memo: continue - if memo is not None: - memo.add(cell) + memo.add(cell) # Create XML subelement for this Cell cell_element = cell.create_xml_subelement(xml_element, memo) @@ -935,11 +942,13 @@ def n_surfaces(self): return self._n_geom_elements('surface') def create_xml_subelement(self, xml_element, memo=None): - if memo and self in memo: + if memo is None: + memo = set() + + if self in memo: return - if memo is not None: - memo.add(self) + memo.add(self) # Set xml element values dagmc_element = ET.Element('dagmc_universe') From 386b17441f56394f45f1c86eff25d5971bfee6a8 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 24 May 2024 17:37:52 -0500 Subject: [PATCH 6/6] Small simplifications in logic --- openmc/cell.py | 8 +++----- openmc/lattice.py | 14 ++++---------- openmc/universe.py | 8 ++------ 3 files changed, 9 insertions(+), 21 deletions(-) diff --git a/openmc/cell.py b/openmc/cell.py index ad46a27e955..fe3939bbe39 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -428,10 +428,8 @@ def get_all_cells(self, memo=None): """ if memo is None: memo = set() - - if self in memo: + elif self in memo: return {} - memo.add(self) cells = {} @@ -491,7 +489,7 @@ def get_all_universes(self, memo=None): return universes - def clone(self, clone_materials=True, clone_regions=True, memo=None): + def clone(self, clone_materials=True, clone_regions=True, memo=None): """Create a copy of this cell with a new unique ID, and clones the cell's region and fill. @@ -684,7 +682,7 @@ def create_surface_elements(node, element, memo=None): if isinstance(node, Halfspace): if memo is None: memo = set() - if node.surface in memo: + elif node.surface in memo: return memo.add(node.surface) xml_element.append(node.surface.to_xml_element()) diff --git a/openmc/lattice.py b/openmc/lattice.py index 8ab481091b3..6282cf21c1f 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -172,10 +172,8 @@ def get_all_cells(self, memo=None): if memo is None: memo = set() - - if self in memo: + elif self in memo: return cells - memo.add(self) unique_universes = self.get_unique_universes() @@ -224,10 +222,8 @@ def get_all_universes(self, memo=None): if memo is None: memo = set() - - if self in memo: + elif self in memo: return all_universes - memo.add(self) # Get all unique Universes contained in each of the lattice cells @@ -860,10 +856,8 @@ def create_xml_subelement(self, xml_element, memo=None): # If the element already contains the Lattice subelement, then return if memo is None: memo = set() - - if self in memo: + elif self in memo: return - memo.add(self) # Make sure universes have been assigned @@ -1434,7 +1428,7 @@ def create_xml_subelement(self, xml_element, memo=None): # If this subelement has already been written, return if memo is None: memo = set() - if self in memo: + elif self in memo: return memo.add(self) diff --git a/openmc/universe.py b/openmc/universe.py index ecca20617db..9fab9ae51b6 100644 --- a/openmc/universe.py +++ b/openmc/universe.py @@ -102,10 +102,8 @@ def get_all_universes(self, memo=None): """ if memo is None: memo = set() - - if self in memo: + elif self in memo: return {} - memo.add(self) # Append all Universes within each Cell to the dictionary @@ -649,10 +647,8 @@ def get_all_cells(self, memo=None): if memo is None: memo = set() - - if self in memo: + elif self in memo: return {} - memo.add(self) # Add this Universe's cells to the dictionary