mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 22:26:08 -04:00
Add Plot.from_geometry() classmethod
This commit is contained in:
parent
3913d55e2c
commit
61f0138555
9 changed files with 107 additions and 31 deletions
|
|
@ -55,7 +55,8 @@ images: $(PDFS) $(PNGS)
|
|||
|
||||
clean:
|
||||
-rm -rf $(BUILDDIR)/*
|
||||
-rm $(PDFS)
|
||||
-rm -rf $(PDFS)
|
||||
-rm -rf source/pythonapi/generated/
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
|
|
|
|||
|
|
@ -2178,7 +2178,7 @@ attributes or sub-elements. These are not used in "voxel" plots:
|
|||
cells or materials to plot. This overrides any ``color`` color
|
||||
specifications.
|
||||
|
||||
*Default*: None
|
||||
*Default*: 255 255 255 (white)
|
||||
|
||||
:meshlines:
|
||||
The ``meshlines`` sub-element allows for plotting the boundaries of a
|
||||
|
|
|
|||
|
|
@ -224,6 +224,14 @@ class Cell(object):
|
|||
'Call the Geometry.determine_paths() method.')
|
||||
return self._paths
|
||||
|
||||
@property
|
||||
def bounding_box(self):
|
||||
if self.region is not None:
|
||||
return self.region.bounding_box
|
||||
else:
|
||||
return (np.array([-np.inf, -np.inf, -np.inf]),
|
||||
np.array([np.inf, np.inf, np.inf]))
|
||||
|
||||
@property
|
||||
def num_instances(self):
|
||||
return len(self.paths)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ class Geometry(object):
|
|||
----------
|
||||
root_universe : openmc.Universe
|
||||
Root universe which contains all others
|
||||
bounding_box : 2-tuple of numpy.array
|
||||
Lower-left and upper-right coordinates of an axis-aligned bounding box
|
||||
of the universe.
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -41,6 +44,10 @@ class Geometry(object):
|
|||
def root_universe(self):
|
||||
return self._root_universe
|
||||
|
||||
@property
|
||||
def bounding_box(self):
|
||||
return self.root_universe.bounding_box
|
||||
|
||||
@root_universe.setter
|
||||
def root_universe(self, root_universe):
|
||||
check_type('root universe', root_universe, openmc.Universe)
|
||||
|
|
|
|||
|
|
@ -23,12 +23,16 @@ def reset_auto_plot_id():
|
|||
AUTO_PLOT_ID = 10000
|
||||
|
||||
|
||||
BASES = ['xy', 'xz', 'yz']
|
||||
_BASES = ['xy', 'xz', 'yz']
|
||||
|
||||
|
||||
class Plot(object):
|
||||
"""Definition of a finite region of space to be plotted, either as a slice plot
|
||||
in two dimensions or as a voxel plot in three dimensions.
|
||||
"""Definition of a finite region of space to be plotted.
|
||||
|
||||
OpenMC is capable of generating two-dimensional slice plots and
|
||||
three-dimensional voxel plots. Colors that are used in plots can be given as
|
||||
RGB tuples, e.g. (255, 255, 255) would be white, or by a string indicating a
|
||||
valid `SVG color <https://www.w3.org/TR/SVG/types.html#ColorKeywords>`_.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
@ -58,15 +62,14 @@ class Plot(object):
|
|||
basis : {'xy', 'xz', 'yz'}
|
||||
The basis directions for the plot
|
||||
background : Iterable of int or str
|
||||
Color of the background defined by RGB
|
||||
Color of the background
|
||||
mask_components : Iterable of openmc.Cell or openmc.Material
|
||||
The cells or materials to plot
|
||||
mask_background : Iterable of int
|
||||
mask_background : Iterable of int or str
|
||||
Color to apply to all cells/materials not listed in mask_components
|
||||
defined by RGB
|
||||
colors : dict
|
||||
Dictionary indicating that certain cells/materials (keys) should be
|
||||
colored with a specific RGB (values)
|
||||
displayed with a particular color.
|
||||
level : int
|
||||
Universe depth to plot at
|
||||
meshlines : dict
|
||||
|
|
@ -80,7 +83,7 @@ class Plot(object):
|
|||
self.id = plot_id
|
||||
self.name = name
|
||||
self._width = [4.0, 4.0]
|
||||
self._pixels = [1000, 1000]
|
||||
self._pixels = [400, 400]
|
||||
self._origin = [0., 0., 0.]
|
||||
self._filename = None
|
||||
self._color_by = 'cell'
|
||||
|
|
@ -206,7 +209,7 @@ class Plot(object):
|
|||
|
||||
@basis.setter
|
||||
def basis(self, basis):
|
||||
cv.check_value('plot basis', basis, ['xy', 'xz', 'yz'])
|
||||
cv.check_value('plot basis', basis, _BASES)
|
||||
self._basis = basis
|
||||
|
||||
@background.setter
|
||||
|
|
@ -242,18 +245,21 @@ class Plot(object):
|
|||
|
||||
@mask_components.setter
|
||||
def mask_components(self, mask_components):
|
||||
cv.check_type('plot mask components', mask_components, Iterable, Integral)
|
||||
for component in mask_components:
|
||||
cv.check_greater_than('plot mask components', component, 0, True)
|
||||
cv.check_type('plot mask components', mask_components, Iterable,
|
||||
(openmc.Cell, openmc.Material))
|
||||
self._mask_components = mask_components
|
||||
|
||||
@mask_background.setter
|
||||
def mask_background(self, mask_background):
|
||||
cv.check_type('plot mask background', mask_background, Iterable, Integral)
|
||||
cv.check_length('plot mask background', mask_background, 3)
|
||||
for rgb in mask_background:
|
||||
cv.check_greater_than('plot mask background', rgb, 0, True)
|
||||
cv.check_less_than('plot mask background', rgb, 256)
|
||||
cv.check_type('plot mask background', mask_background, Iterable)
|
||||
if isinstance(mask_background, string_types):
|
||||
if not is_color_like(mask_background):
|
||||
raise ValueError("'{}' is not a valid color.".format(mask_background))
|
||||
else:
|
||||
cv.check_length('plot mask_background', mask_background, 3)
|
||||
for rgb in mask_background:
|
||||
cv.check_greater_than('plot mask background', rgb, 0, True)
|
||||
cv.check_less_than('plot mask background', rgb, 256)
|
||||
self._mask_background = mask_background
|
||||
|
||||
@level.setter
|
||||
|
|
@ -316,6 +322,51 @@ class Plot(object):
|
|||
string += '{: <16}=\t{}\n'.format('\tMeshlines', self._meshlines)
|
||||
return string
|
||||
|
||||
@classmethod
|
||||
def from_geometry(cls, geometry, basis='xy', slice_coord=0.):
|
||||
"""Return plot that encompasses a geometry.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
geometry : openmc.Geometry
|
||||
The geometry the base the plot off of
|
||||
basis : {'xy', 'xz', 'yz'}
|
||||
The basis directions for the plot
|
||||
slice_coord : float
|
||||
The level at which the slice plot should be plotted. For example, if
|
||||
the basis is 'xy', this would indicate at what z value is used in
|
||||
the origin.
|
||||
|
||||
"""
|
||||
cv.check_type('geometry', geometry, openmc.Geometry)
|
||||
cv.check_value('basis', basis, _BASES)
|
||||
|
||||
# Decide which axes to keep
|
||||
if basis == 'xy':
|
||||
pick_index = (0, 1)
|
||||
slice_index = 2
|
||||
elif basis == 'yz':
|
||||
pick_index = (1, 2)
|
||||
slice_index = 0
|
||||
elif basis == 'xz':
|
||||
pick_index = (0, 2)
|
||||
slice_index = 1
|
||||
|
||||
# Get lower-left and upper-right coordinates for desired axes
|
||||
lower_left, upper_right = geometry.bounding_box
|
||||
lower_left = lower_left[np.array(pick_index)]
|
||||
upper_right = upper_right[np.array(pick_index)]
|
||||
|
||||
if np.any(np.isinf((lower_left, upper_right))):
|
||||
raise ValueError('The geometry does not appear to be bounded '
|
||||
'in the {} plane.'.format(basis))
|
||||
|
||||
plot = cls()
|
||||
plot.origin = np.insert((lower_left + upper_right)/2,
|
||||
slice_index, slice_coord)
|
||||
plot.width = upper_right - lower_left
|
||||
return plot
|
||||
|
||||
def colorize(self, geometry, seed=1):
|
||||
"""Generate a color scheme for each domain in the plot.
|
||||
|
||||
|
|
@ -446,10 +497,14 @@ class Plot(object):
|
|||
|
||||
if self._mask_components is not None:
|
||||
subelement = ET.SubElement(element, "mask")
|
||||
subelement.set("components", ' '.join(map(
|
||||
str, self._mask_components)))
|
||||
subelement.set("background", ' '.join(map(
|
||||
str, self._mask_background)))
|
||||
subelement.set("components", ' '.join(
|
||||
str(d.id) for d in self._mask_components))
|
||||
color = self._mask_background
|
||||
if color is not None:
|
||||
if isinstance(color, string_types):
|
||||
color = [int(255*x) for x in to_rgb(color)]
|
||||
subelement.set("background", ' '.join(
|
||||
str(x) for x in color))
|
||||
|
||||
if self._level is not None:
|
||||
subelement = ET.SubElement(element, "level")
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ class Union(Region):
|
|||
----------
|
||||
nodes : tuple of openmc.Region
|
||||
Regions to take the union of
|
||||
bounding_box : tuple of numpy.array
|
||||
bounding_box : 2-tuple of numpy.array
|
||||
Lower-left and upper-right coordinates of an axis-aligned bounding box
|
||||
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -46,6 +46,9 @@ class Universe(object):
|
|||
Volume of the universe in cm^3. This can either be set manually or
|
||||
calculated in a stochastic volume calculation and added via the
|
||||
:meth:`Universe.add_volume_information` method.
|
||||
bounding_box : 2-tuple of numpy.array
|
||||
Lower-left and upper-right coordinates of an axis-aligned bounding box
|
||||
of the universe.
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -105,6 +108,11 @@ class Universe(object):
|
|||
def volume(self):
|
||||
return self._volume
|
||||
|
||||
@property
|
||||
def bounding_box(self):
|
||||
regions = [c.region for c in self.cells.values()]
|
||||
return openmc.Union(*regions).bounding_box
|
||||
|
||||
@id.setter
|
||||
def id(self, universe_id):
|
||||
if universe_id is None:
|
||||
|
|
|
|||
|
|
@ -80,9 +80,7 @@ class VolumeCalculation(object):
|
|||
# user-specified one is valid
|
||||
if self.domain_type == 'cell':
|
||||
for c in domains:
|
||||
if c.region is None:
|
||||
continue
|
||||
ll, ur = c.region.bounding_box
|
||||
ll, ur = c.bounding_box
|
||||
if np.any(np.isinf(ll)) or np.any(np.isinf(ur)):
|
||||
continue
|
||||
if (np.any(np.asarray(lower_left) > ll) or
|
||||
|
|
|
|||
|
|
@ -4634,13 +4634,12 @@ contains
|
|||
end do
|
||||
|
||||
! Alter colors based on mask information
|
||||
do j=1,size(pl % colors)
|
||||
if (.not. any(j .eq. iarray)) then
|
||||
do j = 1, size(pl % colors)
|
||||
if (.not. any(j == iarray)) then
|
||||
if (check_for_node(node_mask, "background")) then
|
||||
call get_node_array(node_mask, "background", pl % colors(j) % rgb)
|
||||
else
|
||||
call fatal_error("Missing <background> in mask of plot " &
|
||||
// trim(to_str(pl % id)))
|
||||
pl % colors(j) % rgb(:) = [255, 255, 255]
|
||||
end if
|
||||
end if
|
||||
end do
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue