mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 22:26:08 -04:00
Abstracting the Python Universe class. Adding a DAGMC Universe.
This commit is contained in:
parent
0f216bc535
commit
d94710996f
2 changed files with 177 additions and 92 deletions
|
|
@ -50,7 +50,8 @@ class Geometry:
|
|||
|
||||
@root_universe.setter
|
||||
def root_universe(self, root_universe):
|
||||
check_type('root universe', root_universe, openmc.Universe)
|
||||
check_type('root universe', root_universe,
|
||||
(openmc.Universe, openmc.DAGMCUniverse))
|
||||
self._root_universe = root_universe
|
||||
|
||||
def add_volume_information(self, volume_calc):
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from abc import ABC, abstractmethod
|
||||
from collections import OrderedDict
|
||||
from collections.abc import Iterable
|
||||
from copy import copy, deepcopy
|
||||
|
|
@ -12,7 +13,119 @@ from .mixin import IDManagerMixin
|
|||
from .plots import _SVG_COLORS
|
||||
|
||||
|
||||
class Universe(IDManagerMixin):
|
||||
class UniverseBase(ABC, IDManagerMixin):
|
||||
"""A collection of cells that can be repeated.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
id : int
|
||||
Unique identifier of the universe
|
||||
name : str
|
||||
Name of the universe
|
||||
"""
|
||||
|
||||
next_id = 1
|
||||
used_ids = set()
|
||||
|
||||
def __init__(self, universe_id=None, name=''):
|
||||
# Initialize Universe class attributes
|
||||
self.id = universe_id
|
||||
self.name = name
|
||||
self._volume = None
|
||||
self._atoms = {}
|
||||
|
||||
def __repr__(self):
|
||||
string = 'Universe\n'
|
||||
string += '{: <16}=\t{}\n'.format('\tID', self._id)
|
||||
string += '{: <16}=\t{}\n'.format('\tName', self._name)
|
||||
return string
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def volume(self):
|
||||
return self._volume
|
||||
|
||||
@name.setter
|
||||
def name(self, name):
|
||||
if name is not None:
|
||||
cv.check_type('universe name', name, str)
|
||||
self._name = name
|
||||
else:
|
||||
self._name = ''
|
||||
|
||||
@volume.setter
|
||||
def volume(self, volume):
|
||||
if volume is not None:
|
||||
cv.check_type('universe volume', volume, Real)
|
||||
self._volume = volume
|
||||
|
||||
def add_volume_information(self, volume_calc):
|
||||
"""Add volume information to a universe.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
volume_calc : openmc.VolumeCalculation
|
||||
Results from a stochastic volume calculation
|
||||
|
||||
"""
|
||||
if volume_calc.domain_type == 'universe':
|
||||
if self.id in volume_calc.volumes:
|
||||
self._volume = volume_calc.volumes[self.id].n
|
||||
self._atoms = volume_calc.atoms[self.id]
|
||||
else:
|
||||
raise ValueError('No volume information found for this universe.')
|
||||
else:
|
||||
raise ValueError('No volume information found for this universe.')
|
||||
|
||||
@abstractmethod
|
||||
def create_xml_subelement(self, xml_element, memo=None):
|
||||
"""Add the universe xml representation to an incoming xml element
|
||||
|
||||
Parameters
|
||||
----------
|
||||
xml_element : xml.etree.ElementTree.Element
|
||||
XML element to be added to
|
||||
|
||||
memo : set or None
|
||||
A set of object id's representing geometry entities already
|
||||
written to the xml_element. This parameter is used internally
|
||||
and should not be specified by users.
|
||||
|
||||
Returns
|
||||
-------
|
||||
None
|
||||
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def clone(self, clone_materials=True, clone_regions=True, memo=None):
|
||||
"""Create a copy of this universe with a new unique ID, and clones
|
||||
all cells within this universe.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
clone_materials : bool
|
||||
Whether to create separates copies of the materials filling cells
|
||||
contained in this universe.
|
||||
clone_regions : bool
|
||||
Whether to create separates copies of the regions bounding cells
|
||||
contained in this universe.
|
||||
memo : dict or None
|
||||
A nested dictionary of previously cloned objects. This parameter
|
||||
is used internally and should not be specified by the user.
|
||||
|
||||
Returns
|
||||
-------
|
||||
clone : openmc.Universe
|
||||
The clone of this universe
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class Universe(UniverseBase):
|
||||
"""A collection of cells that can be repeated.
|
||||
|
||||
Parameters
|
||||
|
|
@ -44,15 +157,8 @@ class Universe(IDManagerMixin):
|
|||
|
||||
"""
|
||||
|
||||
next_id = 1
|
||||
used_ids = set()
|
||||
|
||||
def __init__(self, universe_id=None, name='', cells=None):
|
||||
# Initialize Cell class attributes
|
||||
self.id = universe_id
|
||||
self.name = name
|
||||
self._volume = None
|
||||
self._atoms = {}
|
||||
super().__init__(universe_id, name)
|
||||
|
||||
# Keys - Cell IDs
|
||||
# Values - Cells
|
||||
|
|
@ -62,24 +168,15 @@ class Universe(IDManagerMixin):
|
|||
self.add_cells(cells)
|
||||
|
||||
def __repr__(self):
|
||||
string = 'Universe\n'
|
||||
string += '{: <16}=\t{}\n'.format('\tID', self._id)
|
||||
string += '{: <16}=\t{}\n'.format('\tName', self._name)
|
||||
string = super().__repr__()
|
||||
string += '{: <16}=\t{}\n'.format('\tGeom', 'CSG')
|
||||
string += '{: <16}=\t{}\n'.format('\tCells', list(self._cells.keys()))
|
||||
return string
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def cells(self):
|
||||
return self._cells
|
||||
|
||||
@property
|
||||
def volume(self):
|
||||
return self._volume
|
||||
|
||||
@property
|
||||
def bounding_box(self):
|
||||
regions = [c.region for c in self.cells.values()
|
||||
|
|
@ -90,20 +187,6 @@ class Universe(IDManagerMixin):
|
|||
# Infinite bounding box
|
||||
return openmc.Intersection([]).bounding_box
|
||||
|
||||
@name.setter
|
||||
def name(self, name):
|
||||
if name is not None:
|
||||
cv.check_type('universe name', name, str)
|
||||
self._name = name
|
||||
else:
|
||||
self._name = ''
|
||||
|
||||
@volume.setter
|
||||
def volume(self, volume):
|
||||
if volume is not None:
|
||||
cv.check_type('universe volume', volume, Real)
|
||||
self._volume = volume
|
||||
|
||||
@classmethod
|
||||
def from_hdf5(cls, group, cells):
|
||||
"""Create universe from HDF5 group
|
||||
|
|
@ -133,24 +216,6 @@ class Universe(IDManagerMixin):
|
|||
|
||||
return universe
|
||||
|
||||
def add_volume_information(self, volume_calc):
|
||||
"""Add volume information to a universe.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
volume_calc : openmc.VolumeCalculation
|
||||
Results from a stochastic volume calculation
|
||||
|
||||
"""
|
||||
if volume_calc.domain_type == 'universe':
|
||||
if self.id in volume_calc.volumes:
|
||||
self._volume = volume_calc.volumes[self.id].n
|
||||
self._atoms = volume_calc.atoms[self.id]
|
||||
else:
|
||||
raise ValueError('No volume information found for this universe.')
|
||||
else:
|
||||
raise ValueError('No volume information found for this universe.')
|
||||
|
||||
def find(self, point):
|
||||
"""Find cells/universes/lattices which contain a given point
|
||||
|
||||
|
|
@ -481,28 +546,6 @@ class Universe(IDManagerMixin):
|
|||
return universes
|
||||
|
||||
def clone(self, clone_materials=True, clone_regions=True, memo=None):
|
||||
"""Create a copy of this universe with a new unique ID, and clones
|
||||
all cells within this universe.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
clone_materials : bool
|
||||
Whether to create separates copies of the materials filling cells
|
||||
contained in this universe.
|
||||
clone_regions : bool
|
||||
Whether to create separates copies of the regions bounding cells
|
||||
contained in this universe.
|
||||
memo : dict or None
|
||||
A nested dictionary of previously cloned objects. This parameter
|
||||
is used internally and should not be specified by the user.
|
||||
|
||||
Returns
|
||||
-------
|
||||
clone : openmc.Universe
|
||||
The clone of this universe
|
||||
|
||||
"""
|
||||
|
||||
if memo is None:
|
||||
memo = {}
|
||||
|
||||
|
|
@ -523,23 +566,6 @@ class Universe(IDManagerMixin):
|
|||
return memo[self]
|
||||
|
||||
def create_xml_subelement(self, xml_element, memo=None):
|
||||
"""Add the universe xml representation to an incoming xml element
|
||||
|
||||
Parameters
|
||||
----------
|
||||
xml_element : xml.etree.ElementTree.Element
|
||||
XML element to be added to
|
||||
|
||||
memo : set or None
|
||||
A set of object id's representing geometry entities already
|
||||
written to the xml_element. This parameter is used internally
|
||||
and should not be specified by users.
|
||||
|
||||
Returns
|
||||
-------
|
||||
None
|
||||
|
||||
"""
|
||||
# Iterate over all Cells
|
||||
for cell in self._cells.values():
|
||||
|
||||
|
|
@ -600,3 +626,61 @@ class Universe(IDManagerMixin):
|
|||
cell._num_instances += 1
|
||||
if not instances_only:
|
||||
cell._paths.append(cell_path)
|
||||
|
||||
|
||||
class DAGMCUniverse(UniverseBase):
|
||||
"""A reference to a DAGMC file to be used in the model.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
filename : str
|
||||
Path to the DAGMC file used to represent this universe.
|
||||
universe_id : int, optional
|
||||
Unique identifier of the universe. If not specified, an identifier will
|
||||
automatically be assigned
|
||||
name : str, optional
|
||||
Name of the universe. If not specified, the name is the empty string.
|
||||
cells : Iterable of openmc.Cell, optional
|
||||
Cells to add to the universe. By default no cells are added.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
id : int
|
||||
Unique identifier of the universe
|
||||
name : str
|
||||
Name of the universe
|
||||
filename : str
|
||||
Path to the DAGMC file used to represent this universe.
|
||||
"""
|
||||
|
||||
def __init__(self, filename, universe_id=None, name=''):
|
||||
super().__init__(universe_id, name)
|
||||
# Initialize class attributes
|
||||
self.filename = filename
|
||||
|
||||
def __repr__(self):
|
||||
fmt_str = '{: <16}=\t{}\n'
|
||||
string = super().__repr__()
|
||||
string += fmt_str.format('\tGeom', 'DAGMC')
|
||||
string += fmt_str.format('\tFile', self.filename)
|
||||
return string
|
||||
|
||||
@property
|
||||
def filename(self):
|
||||
return self._filename
|
||||
|
||||
@filename.setter
|
||||
def filename(self, val):
|
||||
cv.check_type('DAGMC file', val, str)
|
||||
self._filename = val
|
||||
|
||||
def clone(self, clone_materials=True, clone_regions=True, memo=None):
|
||||
pass
|
||||
|
||||
def create_xml_subelement(self, xml_element, memo=None):
|
||||
# Set xml element values
|
||||
dagmc_element = ET.Element('dagmc')
|
||||
dagmc_element.set('id', self.id)
|
||||
dagmc_element.set('name', self.name)
|
||||
dagmc_element.set('filename', self.filename)
|
||||
xml_element.append(dagmc_element)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue