Moving to memoization pattern instead of singleton class.

This commit is contained in:
Patrick Shriwise 2019-03-05 10:21:11 -06:00
parent cc826a7db3
commit 4b654c2be0
5 changed files with 44 additions and 95 deletions

View file

@ -16,8 +16,6 @@ from openmc.region import Region, Intersection, Complement
from openmc._xml import get_text
from .mixin import IDManagerMixin
from .geomtrack import ElementTracker
class Cell(IDManagerMixin):
r"""A region of space defined as the intersection of half-space created by
quadric surfaces.
@ -464,8 +462,8 @@ class Cell(IDManagerMixin):
return memo[self]
def create_xml_subelement(self, xml_element):
et = ElementTracker()
def create_xml_subelement(self, xml_element, memo=None):
element = ET.Element("cell")
element.set("id", str(self.id))
@ -484,7 +482,7 @@ class Cell(IDManagerMixin):
elif self.fill_type in ('universe', 'lattice'):
element.set("fill", str(self.fill.id))
self.fill.create_xml_subelement(xml_element)
self.fill.create_xml_subelement(xml_element, memo)
if self.region is not None:
# Set the region attribute with the region specification
@ -500,22 +498,23 @@ class Cell(IDManagerMixin):
# tree. When it reaches a leaf (a Halfspace), it creates a <surface>
# element for the corresponding surface if none has been created
# thus far.
def create_surface_elements(node, element):
et = ElementTracker()
def create_surface_elements(node, element, memo=None):
if isinstance(node, Halfspace):
path = "./surface[@id='{}']".format(node.surface.id)
if node.surface.id not in et.surfaces:
et.add_surface(node.surface.id)
xml_element.append(node.surface.to_xml_element())
if memo and node.surface.id in memo['surfaces']:
return
if memo:
memo['surfaces'].add(node.surface.id)
xml_element.append(node.surface.to_xml_element())
elif isinstance(node, Complement):
create_surface_elements(node.node, element)
create_surface_elements(node.node, element, memo)
else:
for subnode in node:
create_surface_elements(subnode, element)
create_surface_elements(subnode, element, memo)
# Call the recursive function from the top node
create_surface_elements(self.region, xml_element)
create_surface_elements(self.region, xml_element, memo)
if self.temperature is not None:
if isinstance(self.temperature, Iterable):

View file

@ -10,8 +10,6 @@ import openmc
import openmc._xml as xml
from openmc.checkvalue import check_type
from .geomtrack import ElementTracker
class Geometry(object):
"""Geometry representing a collection of surfaces, cells, and universes.
@ -89,11 +87,13 @@ class Geometry(object):
"""
# Create XML representation
et = ElementTracker()
et.reset()
memo = {'cells' : set(),
'surfaces' : set(),
'lattices' : set(),
'universes' : set()}
root_element = ET.Element("geometry")
self.root_universe.create_xml_subelement(root_element)
self.root_universe.create_xml_subelement(root_element, memo)
# Sort the elements in the file
root_element[:] = sorted(root_element, key=lambda x: (

View file

@ -1,46 +0,0 @@
class ElementTracker:
class __ElementTracker:
def __init__(self):
self.cells = set()
self.surfaces = set()
self.lattices = set()
self.universes = set()
def update(self, element_type, element_id):
if element_type == "cell":
self.cells.add(element_id)
elif element_type == "surface":
self.surfaces.add(element_id)
elif element_type == "lattice":
self.lattices.add(element_id)
elif element_type == "universe":
self.universes.add(element_id)
def add_cell(self, cell_id):
self.update("cell", cell_id)
def add_surface(self, surface_id):
self.update("surface", surface_id)
def add_lattice(self, lattice_id):
self.update("lattice", lattice_id)
def add_universe(self, universe_id):
self.update("universe", universe_id)
def reset(self):
self.cells = set()
self.surfaces = set()
self.lattices = set()
self.universes = set()
instance = None
def __init__(self):
if not ElementTracker.instance:
ElementTracker.instance = ElementTracker.__ElementTracker()
else:
pass
def __getattr__(self, name):
return getattr(self.instance, name)

View file

@ -13,8 +13,6 @@ import openmc
from openmc._xml import get_text
from openmc.mixin import IDManagerMixin
from .geomtrack import ElementTracker
class Lattice(IDManagerMixin, metaclass=ABCMeta):
"""A repeating structure wherein each element is a universe.
@ -754,17 +752,16 @@ class RectLattice(Lattice):
0 <= idx[1] < self.shape[1] and
0 <= idx[2] < self.shape[2])
def create_xml_subelement(self, xml_element):
et = ElementTracker()
def create_xml_subelement(self, xml_element, memo=None):
# Determine if XML element already contains subelement for this Lattice
path = './lattice[@id=\'{0}\']'.format(self._id)
test = xml_element.find(path)
# If the element does contain the Lattice subelement, then return
if self._id in et.lattices:
if memo and self._id in memo['lattices']:
return
else:
et.add_lattice(self._id)
if memo:
memo['lattices'].add(self._id)
lattice_subelement = ET.Element("lattice")
lattice_subelement.set("id", str(self._id))
@ -780,7 +777,7 @@ class RectLattice(Lattice):
if self._outer is not None:
outer = ET.SubElement(lattice_subelement, "outer")
outer.text = '{0}'.format(self._outer._id)
self._outer.create_xml_subelement(xml_element)
self._outer.create_xml_subelement(xml_element, memo)
# Export Lattice cell dimensions
dimension = ET.SubElement(lattice_subelement, "dimension")
@ -804,7 +801,7 @@ class RectLattice(Lattice):
universe_ids += '{0} '.format(universe._id)
# Create XML subelement for this Universe
universe.create_xml_subelement(xml_element)
universe.create_xml_subelement(xml_element, memo)
# Add newline character when we reach end of row of cells
universe_ids += '\n'
@ -822,7 +819,7 @@ class RectLattice(Lattice):
universe_ids += '{0} '.format(universe._id)
# Create XML subelement for this Universe
universe.create_xml_subelement(xml_element)
universe.create_xml_subelement(xml_element, memo)
# Add newline character when we reach end of row of cells
universe_ids += '\n'
@ -1277,17 +1274,16 @@ class HexLattice(Lattice):
else:
return g < self.num_rings and 0 <= idx[2] < self.num_axial
def create_xml_subelement(self, xml_element):
et = ElementTracker()
def create_xml_subelement(self, xml_element, memo=None):
# Determine if XML element already contains subelement for this Lattice
path = './hex_lattice[@id=\'{0}\']'.format(self._id)
test = xml_element.find(path)
# If the element does contain the Lattice subelement, then return
if self._id in et.lattices:
if memo and self._id in memo['lattices']:
return
else:
et.add_lattice(self._id)
if memo:
memo['lattices'].add(self._id)
lattice_subelement = ET.Element("hex_lattice")
lattice_subelement.set("id", str(self._id))
@ -1303,7 +1299,7 @@ class HexLattice(Lattice):
if self._outer is not None:
outer = ET.SubElement(lattice_subelement, "outer")
outer.text = '{0}'.format(self._outer._id)
self._outer.create_xml_subelement(xml_element)
self._outer.create_xml_subelement(xml_element, memo)
lattice_subelement.set("n_rings", str(self._num_rings))
# If orientation is "x" export it to XML
@ -1325,13 +1321,13 @@ class HexLattice(Lattice):
for z in range(self._num_axial):
# Initialize the center universe.
universe = self._universes[z][-1][0]
universe.create_xml_subelement(xml_element)
universe.create_xml_subelement(xml_element, memo)
# Initialize the remaining universes.
for r in range(self._num_rings-1):
for theta in range(6*(self._num_rings - 1 - r)):
universe = self._universes[z][r][theta]
universe.create_xml_subelement(xml_element)
universe.create_xml_subelement(xml_element, memo)
# Get a string representation of the universe IDs.
slices.append(self._repr_axial_slice(self._universes[z]))
@ -1343,13 +1339,13 @@ class HexLattice(Lattice):
else:
# Initialize the center universe.
universe = self._universes[-1][0]
universe.create_xml_subelement(xml_element)
universe.create_xml_subelement(xml_element, memo)
# Initialize the remaining universes.
for r in range(self._num_rings - 1):
for theta in range(6*(self._num_rings - 1 - r)):
universe = self._universes[r][theta]
universe.create_xml_subelement(xml_element)
universe.create_xml_subelement(xml_element, memo)
# Get a string representation of the universe IDs.
universe_ids = self._repr_axial_slice(self._universes)

View file

@ -12,8 +12,6 @@ import openmc.checkvalue as cv
from openmc.plots import _SVG_COLORS
from openmc.mixin import IDManagerMixin
from .geomtrack import ElementTracker
class Universe(IDManagerMixin):
"""A collection of cells that can be repeated.
@ -513,21 +511,23 @@ class Universe(IDManagerMixin):
return memo[self]
def create_xml_subelement(self, xml_element):
et = ElementTracker()
def create_xml_subelement(self, xml_element, memo=None):
# Iterate over all Cells
for cell_id, cell in self._cells.items():
path = "./cell[@id='{}']".format(cell_id)
# If the cell was not already written, write it
if cell_id not in et.cells:
et.add_cell(cell_id)
# Create XML subelement for this Cell
cell_element = cell.create_xml_subelement(xml_element)
if memo and cell_id in memo['cells']:
continue
if memo:
memo['cells'].add(cell_id)
# Append the Universe ID to the subelement and add to Element
cell_element.set("universe", str(self._id))
xml_element.append(cell_element)
# Create XML subelement for this Cell
cell_element = cell.create_xml_subelement(xml_element, memo)
# Append the Universe ID to the subelement and add to Element
cell_element.set("universe", str(self._id))
xml_element.append(cell_element)
def _determine_paths(self, path='', instances_only=False):
"""Count the number of instances for each cell in the universe, and