Refactor handling of cell fill types. Fix Geometry.get_* methods

This commit is contained in:
Paul Romano 2016-05-31 08:41:05 -05:00
parent 0ee6a6169c
commit 2b219ae15f
5 changed files with 92 additions and 120 deletions

View file

@ -36,7 +36,7 @@ class Cell(object):
automatically be assigned.
name : str, optional
Name of the cell. If not specified, the name is the empty string.
fill : openmc.Material or openmc.Universe or openmc.Lattice or 'void' or iterable of openmc.Material, optional
fill : openmc.Material or openmc.Universe or openmc.Lattice or None or iterable of openmc.Material, optional
Indicates what the region of space is filled with
region : openmc.Region, optional
Region of space that is assigned to the cell.
@ -47,9 +47,13 @@ class Cell(object):
Unique identifier for the cell
name : str
Name of the cell
fill : openmc.Material or openmc.Universe or openmc.Lattice or 'void' or iterable of openmc.Material
Indicates what the region of space is filled with
region : openmc.Region
fill : openmc.Material or openmc.Universe or openmc.Lattice or None or iterable of openmc.Material
Indicates what the region of space is filled with. If None, the cell is
treated as a void. An iterable of materials is used to fill repeated
instances of a cell with different materials.
fill_type : {'material', 'universe', 'lattice', 'distribmat', 'void'}
Indicates what the cell is filled with.
region : openmc.Region or None
Region of space that is assigned to the cell.
rotation : Iterable of float
If the cell is filled with a universe, this array specifies the angles
@ -68,6 +72,9 @@ class Cell(object):
\sin\theta \sin\psi \\ -\sin\theta & \sin\phi \cos\theta & \cos\phi
\cos\theta \end{array} \right ]
rotation_matrix : numpy.ndarray
The rotation matrix defined by the angles specified in the
:attr:`Cell.rotation` property.
translation : Iterable of float
If the cell is filled with a universe, this array specifies a vector
that is used to translate (shift) the universe.
@ -82,20 +89,14 @@ class Cell(object):
# Initialize Cell class attributes
self.id = cell_id
self.name = name
self._fill = None
self._type = None
self._region = None
self.fill = fill
self.region = region
self._rotation = None
self._rotation_matrix = None
self._translation = None
self._offsets = None
self._distribcell_index = None
if fill is not None:
self.fill = fill
if region is not None:
self.region = region
def __contains__(self, point):
if self.region is None:
return True
@ -128,35 +129,24 @@ class Cell(object):
def __repr__(self):
string = 'Cell\n'
string += '{0: <16}{1}{2}\n'.format('\tID', '=\t', self._id)
string += '{0: <16}{1}{2}\n'.format('\tName', '=\t', self._name)
string += '{: <16}=\t{}\n'.format('\tID', self.id)
string += '{: <16}=\t{}\n'.format('\tName', self.name)
if isinstance(self._fill, openmc.Material):
string += '{0: <16}{1}{2}\n'.format('\tMaterial', '=\t',
self._fill._id)
elif isinstance(self._fill, basestring):
string += '{0: <16}=\tvoid\n'.format('\tMaterial')
elif isinstance(self._fill, Iterable):
string += '{0: <16}{1}'.format('\tMaterial', '=\t')
string += '['
string += ', '.join(['void' if m == 'void' else str(m.id)
for m in self.fill])
string += ']\n'
elif isinstance(self._fill, (openmc.Universe, openmc.Lattice)):
string += '{0: <16}{1}{2}\n'.format('\tFill', '=\t',
self._fill._id)
if self.fill_type == 'material':
string += '{: <16}=\tMaterial {}\n'.format('\tFill', self.fill.id)
elif self.fill_type == 'void':
string += '{: <16}=\tNone\n'.format('\tFill')
elif self.fill_type == 'distribmat':
string += '{: <16}=\t{}\n'.format('\tFill', list(map(
lambda m: m if m is None else m.id, self.fill)))
else:
string += '{0: <16}{1}{2}\n'.format('\tFill', '=\t', self._fill)
string += '{: <16}=\t{}\n'.format('\tFill', self.fill.id)
string += '{0: <16}{1}{2}\n'.format('\tRegion', '=\t', self._region)
string += '{0: <16}{1}{2}\n'.format('\tRotation', '=\t',
self._rotation)
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_index)
string += '{: <16}=\t{}\n'.format('\tRegion', self.region)
string += '{: <16}=\t{}\n'.format('\tRotation', self.rotation)
string += '{: <16}=\t{}\n'.format('\tTranslation', self.translation)
string += '{: <16}=\t{}\n'.format('\tOffset', self.offsets)
string += '{: <16}=\t{}\n'.format('\tDistribcell index', self.distribcell_index)
return string
@ -180,8 +170,10 @@ class Cell(object):
return 'universe'
elif isinstance(self.fill, openmc.Lattice):
return 'lattice'
elif isinstance(self.fill, Iterable):
return 'distribmat'
else:
return None
return 'void'
@property
def region(self):
@ -228,33 +220,25 @@ class Cell(object):
@fill.setter
def fill(self, fill):
if isinstance(fill, basestring):
if fill.strip().lower() == 'void':
self._type = 'void'
else:
if fill is not None:
if isinstance(fill, basestring):
if fill.strip().lower() != 'void':
msg = 'Unable to set Cell ID="{0}" to use a non-Material ' \
'or Universe fill "{1}"'.format(self._id, fill)
raise ValueError(msg)
fill = None
elif isinstance(fill, Iterable):
for i, f in enumerate(fill):
if f is not None:
cv.check_type('cell.fill[i]', f, openmc.Material)
elif not isinstance(fill, (openmc.Material, openmc.Lattice,
openmc.Universe)):
msg = 'Unable to set Cell ID="{0}" to use a non-Material or ' \
'Universe fill "{1}"'.format(self._id, fill)
'Universe fill "{1}"'.format(self._id, fill)
raise ValueError(msg)
elif isinstance(fill, openmc.Material):
self._type = 'normal'
elif isinstance(fill, Iterable):
cv.check_type('cell.fill', fill, Iterable,
(openmc.Material, basestring))
self._type = 'normal'
elif isinstance(fill, openmc.Universe):
self._type = 'fill'
elif isinstance(fill, openmc.Lattice):
self._type = 'lattice'
else:
msg = 'Unable to set Cell ID="{0}" to use a non-Material or ' \
'Universe fill "{1}"'.format(self._id, fill)
raise ValueError(msg)
self._fill = fill
@rotation.setter
@ -290,7 +274,8 @@ class Cell(object):
@region.setter
def region(self, region):
cv.check_type('cell region', region, Region)
if region is not None:
cv.check_type('cell region', region, Region)
self._region = region
@distribcell_index.setter
@ -345,11 +330,11 @@ class Cell(object):
def get_cell_instance(self, path, distribcell_index):
# If the Cell is filled by a Material
if self._type == 'normal' or self._type == 'void':
if self.fill_type in ('material', 'distribmat', 'void'):
offset = 0
# If the Cell is filled by a Universe
elif self._type == 'fill':
elif self.fill_type == 'universe':
offset = self.offsets[distribcell_index-1]
offset += self.fill.get_cell_instance(path, distribcell_index)
@ -372,8 +357,8 @@ class Cell(object):
nuclides = OrderedDict()
if self._type != 'void':
nuclides.update(self._fill.get_all_nuclides())
if self.fill_type != 'void':
nuclides.update(self.fill.get_all_nuclides())
return nuclides
@ -391,8 +376,8 @@ class Cell(object):
cells = OrderedDict()
if self._type == 'fill' or self._type == 'lattice':
cells.update(self._fill.get_all_cells())
if self.fill_type in ('universe', 'lattice'):
cells.update(self.fill.get_all_cells())
return cells
@ -432,11 +417,11 @@ class Cell(object):
universes = OrderedDict()
if self._type == 'fill':
universes[self._fill._id] = self._fill
universes.update(self._fill.get_all_universes())
elif self._type == 'lattice':
universes.update(self._fill.get_all_universes())
if self.fill_type == 'universe':
universes[self.fill.id] = self.fill
universes.update(self.fill.get_all_universes())
elif self.fill_type == 'lattice':
universes.update(self.fill.get_all_universes())
return universes
@ -447,24 +432,20 @@ class Cell(object):
if len(self._name) > 0:
element.set("name", str(self.name))
if isinstance(self.fill, basestring):
if self.fill_type == 'void':
element.set("material", "void")
elif isinstance(self.fill, openmc.Material):
elif self.fill_type == 'material':
element.set("material", str(self.fill.id))
elif isinstance(self.fill, Iterable):
element.set("material", ' '.join([m if m == 'void' else str(m.id)
elif self.fill_type == 'distribmat':
element.set("material", ' '.join(['void' if m is None else str(m.id)
for m in self.fill]))
elif isinstance(self.fill, (openmc.Universe, openmc.Lattice)):
elif self.fill_type in ('universe', 'lattice'):
element.set("fill", str(self.fill.id))
self.fill.create_xml_subelement(xml_element)
else:
element.set("fill", str(self.fill))
self.fill.create_xml_subelement(xml_element)
if self.region is not None:
# Set the region attribute with the region specification
element.set("region", str(self.region))

View file

@ -144,14 +144,8 @@ class Geometry(object):
"""
all_cells = self._root_universe.get_all_cells()
cells = set()
for cell in all_cells.values():
if cell._type == 'normal':
cells.add(cell)
cells = list(cells)
all_cells = self.root_universe.get_all_cells()
cells = list(set(all_cells.values()))
cells.sort(key=lambda x: x.id)
return cells
@ -166,12 +160,7 @@ class Geometry(object):
"""
all_universes = self._root_universe.get_all_universes()
universes = set()
for universe in all_universes.values():
universes.add(universe)
universes = list(universes)
universes = list(set(all_universes.values()))
universes.sort(key=lambda x: x.id)
return universes
@ -204,15 +193,17 @@ class Geometry(object):
"""
material_cells = self.get_all_material_cells()
materials = set()
materials = []
for cell in material_cells:
if isinstance(cell.fill, Iterable):
for m in cell.fill: materials.add(m)
else:
materials.add(cell.fill)
if cell.fill_type == 'distribmat':
for m in cell.fill:
if m is not None and m not in materials:
materials.append(m)
elif cell.fill_type == 'material':
if cell.fill not in materials:
materials.append(cell.fill)
materials = list(materials)
materials.sort(key=lambda x: x.id)
return materials
@ -227,13 +218,13 @@ class Geometry(object):
"""
all_cells = self.get_all_cells()
material_cells = set()
material_cells = []
for cell in all_cells:
if cell._type == 'normal':
material_cells.add(cell)
if cell.fill_type in ('material', 'distribmat'):
if cell not in material_cells:
material_cells.append(cell)
material_cells = list(material_cells)
material_cells.sort(key=lambda x: x.id)
return material_cells
@ -248,15 +239,15 @@ class Geometry(object):
"""
all_universes = self.get_all_universes()
material_universes = set()
material_universes = []
for universe in all_universes:
cells = universe.cells
for cell in cells:
if cell._type == 'normal':
material_universes.add(universe)
if cell.fill_type in ('material', 'distribmat', 'void'):
if universe not in material_universes:
material_universes.append(universe)
material_universes = list(material_universes)
material_universes.sort(key=lambda x: x.id)
return material_universes
@ -271,13 +262,13 @@ class Geometry(object):
"""
cells = self.get_all_cells()
lattices = set()
lattices = []
for cell in cells:
if isinstance(cell.fill, openmc.Lattice):
lattices.add(cell.fill)
if cell.fill_type == 'lattice':
if cell.fill not in lattices:
lattices.append(cell.fill)
lattices = list(lattices)
lattices.sort(key=lambda x: x.id)
return lattices

View file

@ -493,13 +493,13 @@ class Summary(object):
# Retrieve the object corresponding to the fill type and ID
if fill_type == 'normal':
if isinstance(fill_id, Iterable):
fill = [self.get_material_by_id(mat) if mat > 0 else 'void'
fill = [self.get_material_by_id(mat) if mat > 0 else None
for mat in fill_id]
else:
if fill_id > 0:
fill = self.get_material_by_id(fill_id)
else:
fill = 'void'
fill = None
elif fill_type == 'universe':
fill = self.get_universe_by_id(fill_id)
else:

View file

@ -3,7 +3,7 @@ k-combined:
Cell
ID = 11
Name =
Material = [2, 3, void, 2]
Fill = [2, 3, None, 2]
Region = -10000
Rotation = None
Translation = None

View file

@ -45,7 +45,7 @@ class DistribmatTestHarness(PyAPITestHarness):
r0 = openmc.ZCylinder(R=0.3)
c11 = openmc.Cell(cell_id=11)
c11.region = -r0
c11.fill = [dense_fuel, light_fuel, 'void', dense_fuel]
c11.fill = [dense_fuel, light_fuel, None, dense_fuel]
c12 = openmc.Cell(cell_id=12)
c12.region = +r0
c12.fill = moderator