mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 21:55:41 -04:00
Merge pull request #854 from wbinventor/clone
Cloning of geometry and materials
This commit is contained in:
commit
7f41ab2bab
7 changed files with 315 additions and 2 deletions
|
|
@ -1,4 +1,5 @@
|
|||
from collections import OrderedDict, Iterable
|
||||
from copy import deepcopy
|
||||
from math import cos, sin, pi
|
||||
from numbers import Real, Integral
|
||||
from xml.etree import ElementTree as ET
|
||||
|
|
@ -504,6 +505,44 @@ class Cell(object):
|
|||
|
||||
return universes
|
||||
|
||||
def clone(self, memo=None):
|
||||
"""Create a copy of this cell with a new unique ID, and clones
|
||||
the cell's region and fill.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
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.Cell
|
||||
The clone of this cell
|
||||
|
||||
"""
|
||||
|
||||
if memo is None:
|
||||
memo = {}
|
||||
|
||||
# If no nemoize'd clone exists, instantiate one
|
||||
if self not in memo:
|
||||
clone = deepcopy(self)
|
||||
clone.id = None
|
||||
if self.region is not None:
|
||||
clone.region = self.region.clone(memo)
|
||||
if self.fill is not None:
|
||||
if self.fill_type == 'distribmat':
|
||||
clone.fill = [fill.clone(memo) if fill is not None else None
|
||||
for fill in self.fill]
|
||||
else:
|
||||
clone.fill = self.fill.clone(memo)
|
||||
|
||||
# Memoize the clone
|
||||
memo[self] = clone
|
||||
|
||||
return memo[self]
|
||||
|
||||
def create_xml_subelement(self, xml_element):
|
||||
element = ET.Element("cell")
|
||||
element.set("id", str(self.id))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from collections import OrderedDict, Iterable
|
||||
from copy import deepcopy
|
||||
from xml.etree import ElementTree as ET
|
||||
|
||||
from six import string_types
|
||||
|
|
@ -497,3 +498,11 @@ class Geometry(object):
|
|||
|
||||
# Recursively traverse the CSG tree to count all cell instances
|
||||
self.root_universe._determine_paths()
|
||||
|
||||
def clone(self):
|
||||
"""Create a copy of this geometry with new unique IDs for all of its
|
||||
enclosed materials, surfaces, cells, universes and lattices."""
|
||||
|
||||
clone = deepcopy(self)
|
||||
clone.root_universe = self.root_universe.clone()
|
||||
return clone
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ from __future__ import division
|
|||
|
||||
from abc import ABCMeta
|
||||
from collections import OrderedDict, Iterable
|
||||
from copy import deepcopy
|
||||
from math import sqrt, floor
|
||||
from numbers import Real, Integral
|
||||
from xml.etree import ElementTree as ET
|
||||
|
|
@ -414,6 +415,51 @@ class Lattice(object):
|
|||
return []
|
||||
return [(self, idx)] + u.find(p)
|
||||
|
||||
def clone(self, memo=None):
|
||||
"""Create a copy of this lattice with a new unique ID, and clones
|
||||
all universes within this lattice.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
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.Lattice
|
||||
The clone of this lattice
|
||||
|
||||
"""
|
||||
|
||||
if memo is None:
|
||||
memo = {}
|
||||
|
||||
# If no nemoize'd clone exists, instantiate one
|
||||
if self not in memo:
|
||||
clone = deepcopy(self)
|
||||
clone.id = None
|
||||
|
||||
if self.outer is not None:
|
||||
clone.outer = self.outer.clone(memo)
|
||||
|
||||
# Assign universe clones to the lattice clone
|
||||
for i in self.indices:
|
||||
if isinstance(self, RectLattice):
|
||||
clone.universes[i] = self.universes[i].clone(memo)
|
||||
else:
|
||||
if self.ndim == 2:
|
||||
clone.universes[i[0]][i[1]] = \
|
||||
self.universes[i[0]][i[1]].clone(memo)
|
||||
else:
|
||||
clone.universes[i[0]][i[1]][i[2]] = \
|
||||
self.universes[i[0]][i[1]][i[2]].clone(memo)
|
||||
|
||||
# Memoize the clone
|
||||
memo[self] = clone
|
||||
|
||||
return memo[self]
|
||||
|
||||
|
||||
class RectLattice(Lattice):
|
||||
"""A lattice consisting of rectangular prisms.
|
||||
|
|
|
|||
|
|
@ -799,6 +799,35 @@ class Material(object):
|
|||
|
||||
return nuclides
|
||||
|
||||
def clone(self, memo=None):
|
||||
"""Create a copy of this material with a new unique ID.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
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.Material
|
||||
The clone of this material
|
||||
|
||||
"""
|
||||
|
||||
if memo is None:
|
||||
memo = {}
|
||||
|
||||
# If no nemoize'd clone exists, instantiate one
|
||||
if self not in memo:
|
||||
clone = deepcopy(self)
|
||||
clone.id = None
|
||||
|
||||
# Memoize the clone
|
||||
memo[self] = clone
|
||||
|
||||
return memo[self]
|
||||
|
||||
def _get_nuclide_xml(self, nuclide, distrib=False):
|
||||
xml_element = ET.Element("nuclide")
|
||||
xml_element.set("name", nuclide[0].name)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
from abc import ABCMeta, abstractmethod
|
||||
from collections import Iterable, OrderedDict
|
||||
from copy import deepcopy
|
||||
|
||||
from six import add_metaclass
|
||||
import numpy as np
|
||||
|
|
@ -221,6 +222,31 @@ class Region(object):
|
|||
# at the end
|
||||
return output[0]
|
||||
|
||||
@abstractmethod
|
||||
def clone(self, memo=None):
|
||||
"""Create a copy of this region - each of the surfaces in the
|
||||
region's nodes will be cloned and will have new unique IDs.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
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.Region
|
||||
The clone of this region
|
||||
|
||||
Raises
|
||||
------
|
||||
NotImplementedError
|
||||
This method is not implemented for the abstract region class.
|
||||
|
||||
"""
|
||||
raise NotImplementedError('The clone method is not implemented for '
|
||||
'the abstract region class.')
|
||||
|
||||
|
||||
class Intersection(Region):
|
||||
r"""Intersection of two or more regions.
|
||||
|
|
@ -300,6 +326,30 @@ class Intersection(Region):
|
|||
check_type('nodes', nodes, Iterable, Region)
|
||||
self._nodes = nodes
|
||||
|
||||
def clone(self, memo=None):
|
||||
"""Create a copy of this region - each of the surfaces in the
|
||||
intersection's nodes will be cloned and will have new unique IDs.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
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.Intersection
|
||||
The clone of this intersection
|
||||
|
||||
"""
|
||||
|
||||
if memo is None:
|
||||
memo = {}
|
||||
|
||||
clone = deepcopy(self)
|
||||
clone.nodes = [n.clone(memo) for n in self.nodes]
|
||||
return clone
|
||||
|
||||
|
||||
class Union(Region):
|
||||
r"""Union of two or more regions.
|
||||
|
|
@ -377,6 +427,30 @@ class Union(Region):
|
|||
check_type('nodes', nodes, Iterable, Region)
|
||||
self._nodes = nodes
|
||||
|
||||
def clone(self, memo=None):
|
||||
"""Create a copy of this region - each of the surfaces in the
|
||||
union's nodes will be cloned and will have new unique IDs.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
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.Union
|
||||
The clone of this union
|
||||
|
||||
"""
|
||||
|
||||
if memo is None:
|
||||
memo = {}
|
||||
|
||||
clone = copy.deepcopy(self)
|
||||
clone.nodes = [n.clone(memo) for n in self.nodes]
|
||||
return clone
|
||||
|
||||
|
||||
class Complement(Region):
|
||||
"""Complement of a region.
|
||||
|
|
@ -473,3 +547,27 @@ class Complement(Region):
|
|||
for region in self.node:
|
||||
surfaces = region.get_surfaces(surfaces)
|
||||
return surfaces
|
||||
|
||||
def clone(self, memo=None):
|
||||
"""Create a copy of this region - each of the surfaces in the
|
||||
complement's node will be cloned and will have new unique IDs.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
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.Complement
|
||||
The clone of this complement
|
||||
|
||||
"""
|
||||
|
||||
if memo is None:
|
||||
memo = {}
|
||||
|
||||
clone = copy.deepcopy(self)
|
||||
clone.node = self.node.clone(memo)
|
||||
return clone
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
from abc import ABCMeta
|
||||
from collections import Iterable, OrderedDict
|
||||
from copy import deepcopy
|
||||
from numbers import Real, Integral
|
||||
from xml.etree import ElementTree as ET
|
||||
from math import sqrt
|
||||
|
|
@ -82,6 +83,9 @@ class Surface(object):
|
|||
def __pos__(self):
|
||||
return Halfspace(self, '+')
|
||||
|
||||
def __hash__(self):
|
||||
return hash(repr(self))
|
||||
|
||||
def __repr__(self):
|
||||
string = 'Surface\n'
|
||||
string += '{0: <16}{1}{2}\n'.format('\tID', '=\t', self._id)
|
||||
|
|
@ -171,6 +175,35 @@ class Surface(object):
|
|||
return (np.array([-np.inf, -np.inf, -np.inf]),
|
||||
np.array([np.inf, np.inf, np.inf]))
|
||||
|
||||
def clone(self, memo=None):
|
||||
"""Create a copy of this surface with a new unique ID.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
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.Surface
|
||||
The clone of this surface
|
||||
|
||||
"""
|
||||
|
||||
if memo is None:
|
||||
memo = {}
|
||||
|
||||
# If no nemoize'd clone exists, instantiate one
|
||||
if self not in memo:
|
||||
clone = deepcopy(self)
|
||||
clone.id = None
|
||||
|
||||
# Memoize the clone
|
||||
memo[self] = clone
|
||||
|
||||
return memo[self]
|
||||
|
||||
def to_xml_element(self):
|
||||
"""Return XML representation of the surface
|
||||
|
||||
|
|
@ -1821,7 +1854,7 @@ class Halfspace(Region):
|
|||
def __init__(self, surface, side):
|
||||
self.surface = surface
|
||||
self.side = side
|
||||
|
||||
|
||||
def __and__(self, other):
|
||||
if isinstance(other, Intersection):
|
||||
return Intersection(self, *other.nodes)
|
||||
|
|
@ -1902,6 +1935,30 @@ class Halfspace(Region):
|
|||
surfaces[self.surface.id] = self.surface
|
||||
return surfaces
|
||||
|
||||
def clone(self, memo=None):
|
||||
"""Create a copy of this halfspace, with a cloned surface with a
|
||||
unique ID.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
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.Halfspace
|
||||
The clone of this halfspace
|
||||
|
||||
"""
|
||||
|
||||
if memo is None:
|
||||
memo = dict
|
||||
|
||||
clone = deepcopy(self)
|
||||
clone.surface = self.surface.clone(memo)
|
||||
return clone
|
||||
|
||||
|
||||
def get_rectangular_prism(width, height, axis='z', origin=(0., 0.),
|
||||
boundary_type='transmission'):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from __future__ import division
|
||||
from copy import copy
|
||||
from collections import OrderedDict, Iterable
|
||||
from copy import copy, deepcopy
|
||||
from numbers import Integral, Real
|
||||
import random
|
||||
import sys
|
||||
|
|
@ -517,6 +517,41 @@ class Universe(object):
|
|||
|
||||
return universes
|
||||
|
||||
def clone(self, memo=None):
|
||||
"""Create a copy of this universe with a new unique ID, and clones
|
||||
all cells within this universe.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
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 = {}
|
||||
|
||||
# If no nemoize'd clone exists, instantiate one
|
||||
if self not in memo:
|
||||
clone = deepcopy(self)
|
||||
clone.id = None
|
||||
|
||||
# Clone all cells for the universe clone
|
||||
clone._cells = OrderedDict()
|
||||
for cell in self._cells.values():
|
||||
clone.add_cell(cell.clone(memo))
|
||||
|
||||
# Memoize the clone
|
||||
memo[self] = clone
|
||||
|
||||
return memo[self]
|
||||
|
||||
def create_xml_subelement(self, xml_element):
|
||||
# Iterate over all Cells
|
||||
for cell_id, cell in self._cells.items():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue