diff --git a/docs/Makefile b/docs/Makefile index e84aadd33c..2f3c029db1 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -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 diff --git a/docs/source/pythonapi/index.rst b/docs/source/pythonapi/index.rst index d07cf60d3e..a1ce6b2b18 100644 --- a/docs/source/pythonapi/index.rst +++ b/docs/source/pythonapi/index.rst @@ -188,6 +188,7 @@ Running OpenMC openmc.run openmc.calculate_volumes openmc.plot_geometry + openmc.plot_inline Post-processing --------------- diff --git a/docs/source/usersguide/input.rst b/docs/source/usersguide/input.rst index 6be692a21e..b8629f1801 100644 --- a/docs/source/usersguide/input.rst +++ b/docs/source/usersguide/input.rst @@ -2056,13 +2056,12 @@ sub-elements: *Default*: "plot" - :color: - Keyword for plot coloring. This can only be either ``cell`` or ``mat``, - which colors regions by cells and materials, respectively. For voxel plots, - this determines which id (cell or material) is associated with each - position. + :color_by: + Keyword for plot coloring. This can be either "cell" or "material", which + colors regions by cells and materials, respectively. For voxel plots, this + determines which id (cell or material) is associated with each position. - *Default*: ``cell`` + *Default*: "cell" :level: Universe depth to plot at (optional). This parameter controls how many @@ -2148,10 +2147,10 @@ attributes or sub-elements. These are not used in "voxel" plots: *Default*: 0 0 0 (black) - :col_spec: + :color: Any number of this optional tag may be included in each ```` element, which can override the default random colors for cells or materials. Each - ``col_spec`` element must contain ``id`` and ``rgb`` sub-elements. + ``color`` element must contain ``id`` and ``rgb`` sub-elements. :id: Specifies the cell or material unique id for the color specification. @@ -2161,11 +2160,11 @@ attributes or sub-elements. These are not used in "voxel" plots: separated by spaces. As an example, if your plot is colored by material and you want material 23 - to be blue, the corresponding ``col_spec`` element would look like: + to be blue, the corresponding ``color`` element would look like: .. code-block:: xml - + *Default*: None @@ -2181,10 +2180,10 @@ attributes or sub-elements. These are not used in "voxel" plots: :background: Color to apply to all cells or materials not in the ``components`` list of - cells or materials to plot. This overrides any ``col_spec`` color + 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 diff --git a/examples/python/boxes/build-xml.py b/examples/python/boxes/build-xml.py index 03e81b073b..d04f0f67a3 100644 --- a/examples/python/boxes/build-xml.py +++ b/examples/python/boxes/build-xml.py @@ -118,7 +118,7 @@ plot = openmc.Plot(plot_id=1) plot.origin = [0, 0, 0] plot.width = [20, 20] plot.pixels = [200, 200] -plot.color = 'cell' +plot.color_by = 'cell' # Instantiate a Plots collection and export to XML plot_file = openmc.Plots([plot]) diff --git a/examples/python/lattice/hexagonal/build-xml.py b/examples/python/lattice/hexagonal/build-xml.py index 8d124930fe..1065e6e069 100644 --- a/examples/python/lattice/hexagonal/build-xml.py +++ b/examples/python/lattice/hexagonal/build-xml.py @@ -132,7 +132,7 @@ plot_xy.filename = 'plot_xy' plot_xy.origin = [0, 0, 0] plot_xy.width = [6, 6] plot_xy.pixels = [400, 400] -plot_xy.color = 'mat' +plot_xy.color_by = 'material' plot_yz = openmc.Plot(plot_id=2) plot_yz.filename = 'plot_yz' @@ -140,7 +140,7 @@ plot_yz.basis = 'yz' plot_yz.origin = [0, 0, 0] plot_yz.width = [8, 8] plot_yz.pixels = [400, 400] -plot_yz.color = 'mat' +plot_yz.color_by = 'material' # Instantiate a Plots collection, add plots, and export to XML plot_file = openmc.Plots((plot_xy, plot_yz)) diff --git a/examples/python/lattice/nested/build-xml.py b/examples/python/lattice/nested/build-xml.py index 363d0db90c..ef74173f54 100644 --- a/examples/python/lattice/nested/build-xml.py +++ b/examples/python/lattice/nested/build-xml.py @@ -138,7 +138,7 @@ plot = openmc.Plot(plot_id=1) plot.origin = [0, 0, 0] plot.width = [4, 4] plot.pixels = [400, 400] -plot.color = 'mat' +plot.color_by = 'material' # Instantiate a Plots object and export to XML plot_file = openmc.Plots([plot]) diff --git a/examples/python/lattice/simple/build-xml.py b/examples/python/lattice/simple/build-xml.py index 354ce9cc49..6222cd366e 100644 --- a/examples/python/lattice/simple/build-xml.py +++ b/examples/python/lattice/simple/build-xml.py @@ -131,7 +131,7 @@ plot = openmc.Plot(plot_id=1) plot.origin = [0, 0, 0] plot.width = [4, 4] plot.pixels = [400, 400] -plot.color = 'mat' +plot.color_by = 'material' # Instantiate a Plots collection and export to XML plot_file = openmc.Plots([plot]) diff --git a/examples/xml/boxes/plots.xml b/examples/xml/boxes/plots.xml index b7a3093d25..0a75f574eb 100644 --- a/examples/xml/boxes/plots.xml +++ b/examples/xml/boxes/plots.xml @@ -1,7 +1,7 @@ - cell + cell 0. 0. 0. 20. 20. 200 200 diff --git a/examples/xml/lattice/nested/plots.xml b/examples/xml/lattice/nested/plots.xml index a8c6fbb7c5..0f92e06211 100644 --- a/examples/xml/lattice/nested/plots.xml +++ b/examples/xml/lattice/nested/plots.xml @@ -1,7 +1,7 @@ - + 0. 0. 0. 4.0 4.0 400 400 diff --git a/examples/xml/lattice/simple/plots.xml b/examples/xml/lattice/simple/plots.xml index a25a5a8280..0f92e06211 100644 --- a/examples/xml/lattice/simple/plots.xml +++ b/examples/xml/lattice/simple/plots.xml @@ -1,11 +1,10 @@ - + 0. 0. 0. 4.0 4.0 400 400 - diff --git a/examples/xml/pincell_multigroup/plots.xml b/examples/xml/pincell_multigroup/plots.xml index cbb8e532c1..92ab1c2cac 100644 --- a/examples/xml/pincell_multigroup/plots.xml +++ b/examples/xml/pincell_multigroup/plots.xml @@ -4,21 +4,21 @@ 1 mat - material + material 0 0 0 1.26 1.26 slice 1000 1000 - - - - + + + + 2 cell - cell + cell 0 0 0 1.26 1.26 slice diff --git a/openmc/cell.py b/openmc/cell.py index 0adc640836..b578702bba 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -218,6 +218,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) @@ -267,22 +275,23 @@ class Cell(object): @rotation.setter def rotation(self, rotation): if not isinstance(self.fill, openmc.Universe): - raise RuntimeError('Cell rotation can only be applied if the cell ' - 'is filled with a Universe') + raise TypeError('Cell rotation can only be applied if the cell ' + 'is filled with a Universe.') cv.check_type('cell rotation', rotation, Iterable, Real) cv.check_length('cell rotation', rotation, 3) self._rotation = np.asarray(rotation) - # Save rotation matrix + # Save rotation matrix -- the reason we do this instead of having it be + # automatically calculated when the rotation_matrix property is accessed + # is so that plotting on a rotated geometry can be done faster. phi, theta, psi = self.rotation*(-pi/180.) c3, s3 = cos(phi), sin(phi) c2, s2 = cos(theta), sin(theta) c1, s1 = cos(psi), sin(psi) - self._rotation_matrix = np.array([ - [c1*c2, c1*s2*s3 - c3*s1, s1*s3 + c1*c3*s2], - [c2*s1, c1*c3 + s1*s2*s3, c3*s1*s2 - c1*s3], - [-s2, c2*s3, c2*c3]]) + return np.array([[c1*c2, c1*s2*s3 - c3*s1, s1*s3 + c1*c3*s2], + [c2*s1, c1*c3 + s1*s2*s3, c3*s1*s2 - c1*s3], + [-s2, c2*s3, c2*c3]]) @translation.setter def translation(self, translation): diff --git a/openmc/executor.py b/openmc/executor.py index 1fc00b998c..51215e8b74 100644 --- a/openmc/executor.py +++ b/openmc/executor.py @@ -1,9 +1,11 @@ from __future__ import print_function +from collections import Iterable import subprocess from numbers import Integral from six import string_types +import openmc from openmc import VolumeCalculation @@ -32,17 +34,60 @@ def plot_geometry(output=True, openmc_exec='openmc', cwd='.'): Parameters ---------- - output : bool + output : bool, optional Capture OpenMC output from standard out - openmc_exec : str + openmc_exec : str, optional Path to OpenMC executable cwd : str, optional - Path to working directory to run in. Defaults to the current working directory. + Path to working directory to run in """ return _run([openmc_exec, '-p'], output, cwd) +def plot_inline(plots, openmc_exec='openmc', cwd='.', convert_exec='convert'): + """Display plots inline in a Jupyter notebook. + + This function requires that you have a program installed to convert PPM + files to PNG files. Typically, that would be `ImageMagick + `_ which includes a `convert` command. + + Parameters + ---------- + plots : Iterable of openmc.Plot + Plots to display + openmc_exec : str + Path to OpenMC executable + cwd : str, optional + Path to working directory to run in + convert_exec : str, optional + Command that can convert PPM files into PNG files + + """ + from IPython.display import Image, display + + if not isinstance(plots, Iterable): + plots = [plots] + + # Create plots.xml + openmc.Plots(plots).export_to_xml() + + # Run OpenMC in geometry plotting mode + plot_geometry(False, openmc_exec, cwd) + + images = [] + if plots is not None: + for p in plots: + if p.filename is not None: + ppm_file = '{}.ppm'.format(p.filename) + else: + ppm_file = 'plot_{}.ppm'.format(p.id) + png_file = ppm_file.replace('.ppm', '.png') + subprocess.check_call([convert_exec, ppm_file, png_file]) + images.append(Image(png_file)) + display(*images) + + def calculate_volumes(threads=None, output=True, cwd='.', openmc_exec='openmc', mpi_args=None): """Run stochastic volume calculations in OpenMC. diff --git a/openmc/geometry.py b/openmc/geometry.py index 5cb7cf1679..4bb6e23e46 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -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) diff --git a/openmc/material.py b/openmc/material.py index 7ffa899a19..cd19225364 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -464,16 +464,16 @@ class Material(object): Nuclide to remove """ + cv.check_type('nuclide', nuclide, string_types + (openmc.Nuclide,)) - if not isinstance(nuclide, openmc.Nuclide): - msg = 'Unable to remove a Nuclide "{}" in Material ID="{}" ' \ - 'since it is not a Nuclide'.format(self._id, nuclide) - raise ValueError(msg) + if isinstance(nuclide, string_types): + nuclide = openmc.Nuclide(nuclide) # If the Material contains the Nuclide, delete it for nuc in self._nuclides: - if nuclide == nuc: + if nuclide == nuc[0]: self._nuclides.remove(nuc) + break def add_macroscopic(self, macroscopic): """Add a macroscopic to the material. This will also set the @@ -625,15 +625,14 @@ class Material(object): Element to remove """ + cv.check_type('element', element, string_types + (openmc.Element,)) - if not isinstance(element, openmc.Element): - msg = 'Unable to remove "{}" in Material ID="{}" ' \ - 'since it is not an Element'.format(self.id, element) - raise ValueError(msg) + if isinstance(element, string_types): + element = openmc.Element(element) # If the Material contains the Element, delete it for elm in self._elements: - if element == elm: + if element == elm[0]: self._elements.remove(elm) def add_s_alpha_beta(self, name): diff --git a/openmc/plots.py b/openmc/plots.py index bbefb10768..2ba5d9758e 100644 --- a/openmc/plots.py +++ b/openmc/plots.py @@ -1,4 +1,4 @@ -from collections import Iterable +from collections import Iterable, Mapping from numbers import Real, Integral from xml.etree import ElementTree as ET import sys @@ -22,12 +22,166 @@ def reset_auto_plot_id(): AUTO_PLOT_ID = 10000 -BASES = ['xy', 'xz', 'yz'] +_BASES = ['xy', 'xz', 'yz'] + +_SVG_COLORS = { + 'aliceblue': (240, 248, 255), + 'antiquewhite': (250, 235, 215), + 'aqua': (0, 255, 255), + 'aquamarine': (127, 255, 212), + 'azure': (240, 255, 255), + 'beige': (245, 245, 220), + 'bisque': (255, 228, 196), + 'black': (0, 0, 0), + 'blanchedalmond': (255, 235, 205), + 'blue': (0, 0, 255), + 'blueviolet': (138, 43, 226), + 'brown': (165, 42, 42), + 'burlywood': (222, 184, 135), + 'cadetblue': (95, 158, 160), + 'chartreuse': (127, 255, 0), + 'chocolate': (210, 105, 30), + 'coral': (255, 127, 80), + 'cornflowerblue': (100, 149, 237), + 'cornsilk': (255, 248, 220), + 'crimson': (220, 20, 60), + 'cyan': (0, 255, 255), + 'darkblue': (0, 0, 139), + 'darkcyan': (0, 139, 139), + 'darkgoldenrod': (184, 134, 11), + 'darkgray': (169, 169, 169), + 'darkgreen': (0, 100, 0), + 'darkgrey': (169, 169, 169), + 'darkkhaki': (189, 183, 107), + 'darkmagenta': (139, 0, 139), + 'darkolivegreen': (85, 107, 47), + 'darkorange': (255, 140, 0), + 'darkorchid': (153, 50, 204), + 'darkred': (139, 0, 0), + 'darksalmon': (233, 150, 122), + 'darkseagreen': (143, 188, 143), + 'darkslateblue': (72, 61, 139), + 'darkslategray': (47, 79, 79), + 'darkslategrey': (47, 79, 79), + 'darkturquoise': (0, 206, 209), + 'darkviolet': (148, 0, 211), + 'deeppink': (255, 20, 147), + 'deepskyblue': (0, 191, 255), + 'dimgray': (105, 105, 105), + 'dimgrey': (105, 105, 105), + 'dodgerblue': (30, 144, 255), + 'firebrick': (178, 34, 34), + 'floralwhite': (255, 250, 240), + 'forestgreen': (34, 139, 34), + 'fuchsia': (255, 0, 255), + 'gainsboro': (220, 220, 220), + 'ghostwhite': (248, 248, 255), + 'gold': (255, 215, 0), + 'goldenrod': (218, 165, 32), + 'gray': (128, 128, 128), + 'green': (0, 128, 0), + 'greenyellow': (173, 255, 47), + 'grey': (128, 128, 128), + 'honeydew': (240, 255, 240), + 'hotpink': (255, 105, 180), + 'indianred': (205, 92, 92), + 'indigo': (75, 0, 130), + 'ivory': (255, 255, 240), + 'khaki': (240, 230, 140), + 'lavender': (230, 230, 250), + 'lavenderblush': (255, 240, 245), + 'lawngreen': (124, 252, 0), + 'lemonchiffon': (255, 250, 205), + 'lightblue': (173, 216, 230), + 'lightcoral': (240, 128, 128), + 'lightcyan': (224, 255, 255), + 'lightgoldenrodyellow': (250, 250, 210), + 'lightgray': (211, 211, 211), + 'lightgreen': (144, 238, 144), + 'lightgrey': (211, 211, 211), + 'lightpink': (255, 182, 193), + 'lightsalmon': (255, 160, 122), + 'lightseagreen': (32, 178, 170), + 'lightskyblue': (135, 206, 250), + 'lightslategray': (119, 136, 153), + 'lightslategrey': (119, 136, 153), + 'lightsteelblue': (176, 196, 222), + 'lightyellow': (255, 255, 224), + 'lime': (0, 255, 0), + 'limegreen': (50, 205, 50), + 'linen': (250, 240, 230), + 'magenta': (255, 0, 255), + 'maroon': (128, 0, 0), + 'mediumaquamarine': (102, 205, 170), + 'mediumblue': (0, 0, 205), + 'mediumorchid': (186, 85, 211), + 'mediumpurple': (147, 112, 219), + 'mediumseagreen': (60, 179, 113), + 'mediumslateblue': (123, 104, 238), + 'mediumspringgreen': (0, 250, 154), + 'mediumturquoise': (72, 209, 204), + 'mediumvioletred': (199, 21, 133), + 'midnightblue': (25, 25, 112), + 'mintcream': (245, 255, 250), + 'mistyrose': (255, 228, 225), + 'moccasin': (255, 228, 181), + 'navajowhite': (255, 222, 173), + 'navy': (0, 0, 128), + 'oldlace': (253, 245, 230), + 'olive': (128, 128, 0), + 'olivedrab': (107, 142, 35), + 'orange': (255, 165, 0), + 'orangered': (255, 69, 0), + 'orchid': (218, 112, 214), + 'palegoldenrod': (238, 232, 170), + 'palegreen': (152, 251, 152), + 'paleturquoise': (175, 238, 238), + 'palevioletred': (219, 112, 147), + 'papayawhip': (255, 239, 213), + 'peachpuff': (255, 218, 185), + 'peru': (205, 133, 63), + 'pink': (255, 192, 203), + 'plum': (221, 160, 221), + 'powderblue': (176, 224, 230), + 'purple': (128, 0, 128), + 'red': (255, 0, 0), + 'rosybrown': (188, 143, 143), + 'royalblue': (65, 105, 225), + 'saddlebrown': (139, 69, 19), + 'salmon': (250, 128, 114), + 'sandybrown': (244, 164, 96), + 'seagreen': (46, 139, 87), + 'seashell': (255, 245, 238), + 'sienna': (160, 82, 45), + 'silver': (192, 192, 192), + 'skyblue': (135, 206, 235), + 'slateblue': (106, 90, 205), + 'slategray': (112, 128, 144), + 'slategrey': (112, 128, 144), + 'snow': (255, 250, 250), + 'springgreen': (0, 255, 127), + 'steelblue': (70, 130, 180), + 'tan': (210, 180, 140), + 'teal': (0, 128, 128), + 'thistle': (216, 191, 216), + 'tomato': (255, 99, 71), + 'turquoise': (64, 224, 208), + 'violet': (238, 130, 238), + 'wheat': (245, 222, 179), + 'white': (255, 255, 255), + 'whitesmoke': (245, 245, 245), + 'yellow': (255, 255, 0), + 'yellowgreen': (154, 205, 50) +} 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 `_. Parameters ---------- @@ -50,22 +204,21 @@ class Plot(object): Origin (center) of the plot filename : Path to write the plot to - color : {'cell', 'mat'} + color_by : {'cell', 'material'} Indicate whether the plot should be colored by cell or by material type : {'slice', 'voxel'} The type of the plot basis : {'xy', 'xz', 'yz'} The basis directions for the plot - background : tuple or list of ndarray - Color of the background defined by RGB - mask_components : Iterable of int - Unique id numbers of the cells or materials to plot - mask_background : Iterable of int + background : Iterable of int or str + Color of the background + mask_components : Iterable of openmc.Cell or openmc.Material + The cells or materials to plot + mask_background : Iterable of int or str Color to apply to all cells/materials not listed in mask_components - defined by RGB - col_spec : dict + 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 @@ -79,16 +232,16 @@ 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 = 'plot' - self._color = 'cell' + self._filename = None + self._color_by = 'cell' self._type = 'slice' self._basis = 'xy' self._background = None self._mask_components = None self._mask_background = None - self._col_spec = None + self._colors = {} self._level = None self._meshlines = None @@ -117,8 +270,8 @@ class Plot(object): return self._filename @property - def color(self): - return self._color + def color_by(self): + return self._color_by @property def type(self): @@ -141,8 +294,8 @@ class Plot(object): return self._mask_background @property - def col_spec(self): - return self._col_spec + def colors(self): + return self._colors @property def level(self): @@ -193,70 +346,69 @@ class Plot(object): cv.check_type('filename', filename, string_types) self._filename = filename - @color.setter - def color(self, color): - cv.check_type('plot color', color, string_types) - cv.check_value('plot color', color, ['cell', 'mat']) - self._color = color + @color_by.setter + def color_by(self, color_by): + cv.check_value('plot color_by', color_by, ['cell', 'material']) + self._color_by = color_by @type.setter def type(self, plottype): - cv.check_type('plot type', plottype, string_types) cv.check_value('plot type', plottype, ['slice', 'voxel']) self._type = plottype @basis.setter def basis(self, basis): - cv.check_type('plot basis', basis, string_types) - cv.check_value('plot basis', basis, ['xy', 'xz', 'yz']) + cv.check_value('plot basis', basis, _BASES) self._basis = basis @background.setter def background(self, background): - cv.check_type('plot background', background, Iterable, Integral) - cv.check_length('plot background', background, 3) - for rgb in background: - cv.check_greater_than('plot background', rgb, 0, True) - cv.check_less_than('plot background', rgb, 256) + cv.check_type('plot background', background, Iterable) + if isinstance(background, string_types): + if background.lower() not in _SVG_COLORS: + raise ValueError("'{}' is not a valid color.".format(background)) + else: + cv.check_length('plot background', background, 3) + for rgb in background: + cv.check_greater_than('plot background', rgb, 0, True) + cv.check_less_than('plot background', rgb, 256) self._background = background - @col_spec.setter - def col_spec(self, col_spec): - cv.check_type('plot col_spec parameter', col_spec, dict, Integral) + @colors.setter + def colors(self, colors): + cv.check_type('plot colors', colors, Mapping) + for key, value in colors.items(): + cv.check_type('plot color key', key, (openmc.Cell, openmc.Material)) + cv.check_type('plot color value', value, Iterable) + if isinstance(value, string_types): + if value.lower() not in _SVG_COLORS: + raise ValueError("'{}' is not a valid color.".format(value)) + else: + cv.check_length('plot color (RGB)', value, 3) + for component in value: + cv.check_type('RGB component', component, Real) + cv.check_greater_than('RGB component', component, 0, True) + cv.check_less_than('RGB component', component, 255, True) - for key in col_spec: - if key < 0: - msg = 'Unable to create Plot ID="{0}" with col_spec ID "{1}" ' \ - 'which is less than 0'.format(self._id, key) - raise ValueError(msg) - - elif not isinstance(col_spec[key], Iterable): - msg = 'Unable to create Plot ID="{0}" with col_spec RGB values' \ - ' "{1}" which is not iterable'.format(self._id, col_spec[key]) - raise ValueError(msg) - - elif len(col_spec[key]) != 3: - msg = 'Unable to create Plot ID="{0}" with col_spec RGB ' \ - 'values of length "{1}" since 3 values must be ' \ - 'input'.format(self._id, len(col_spec[key])) - raise ValueError(msg) - - self._col_spec = col_spec + self._colors = colors @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 mask_background.lower() not in _SVG_COLORS: + 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 @@ -300,27 +452,70 @@ class Plot(object): def __repr__(self): string = 'Plot\n' - string += '{0: <16}{1}{2}\n'.format('\tID', '=\t', self._id) - string += '{0: <16}{1}{2}\n'.format('\tName', '=\t', self._name) - string += '{0: <16}{1}{2}\n'.format('\tFilename', '=\t', self._filename) - string += '{0: <16}{1}{2}\n'.format('\tType', '=\t', self._type) - string += '{0: <16}{1}{2}\n'.format('\tBasis', '=\t', self._basis) - string += '{0: <16}{1}{2}\n'.format('\tWidth', '=\t', self._width) - string += '{0: <16}{1}{2}\n'.format('\tOrigin', '=\t', self._origin) - string += '{0: <16}{1}{2}\n'.format('\tPixels', '=\t', self._origin) - string += '{0: <16}{1}{2}\n'.format('\tColor', '=\t', self._color) - string += '{0: <16}{1}{2}\n'.format('\tBackground', '=\t', - self._background) - string += '{0: <16}{1}{2}\n'.format('\tMask components', '=\t', + string += '{: <16}=\t{}\n'.format('\tID', self._id) + string += '{: <16}=\t{}\n'.format('\tName', self._name) + string += '{: <16}=\t{}\n'.format('\tFilename', self._filename) + string += '{: <16}=\t{}\n'.format('\tType', self._type) + string += '{: <16}=\t{}\n'.format('\tBasis', self._basis) + string += '{: <16}=\t{}\n'.format('\tWidth', self._width) + string += '{: <16}=\t{}\n'.format('\tOrigin', self._origin) + string += '{: <16}=\t{}\n'.format('\tPixels', self._origin) + string += '{: <16}=\t{}\n'.format('\tColor by', self._color) + string += '{: <16}=\t{}\n'.format('\tBackground', self._background) + string += '{: <16}=\t{}\n'.format('\tMask components', self._mask_components) - string += '{0: <16}{1}{2}\n'.format('\tMask background', '=\t', + string += '{: <16}=\t{}\n'.format('\tMask background', self._mask_background) - string += '{0: <16}{1}{2}\n'.format('\tCol Spec', '=\t', self._col_spec) - string += '{0: <16}{1}{2}\n'.format('\tLevel', '=\t', self._level) - string += '{0: <16}{1}{2}\n'.format('\tMeshlines', '=\t', - self._meshlines) + string += '{: <16}=\t{}\n'.format('\tColors', self._colors) + string += '{: <16}=\t{}\n'.format('\tLevel', self._level) + 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 the z value 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. @@ -341,78 +536,70 @@ class Plot(object): cv.check_greater_than('seed', seed, 1, equality=True) # Get collections of the domains which will be plotted - if self.color is 'mat': - domains = geometry.get_all_materials() + if self.color_by == 'material': + domains = geometry.get_all_materials().values() else: - domains = geometry.get_all_cells() + domains = geometry.get_all_cells().values() # Set the seed for the random number generator np.random.seed(seed) # Generate random colors for each feature - self.col_spec = {} - for domain_id in domains: - r = np.random.randint(0, 256) - g = np.random.randint(0, 256) - b = np.random.randint(0, 256) - self.col_spec[domain_id] = (r, g, b) + for domain in domains: + self.colors[domain] = np.random.randint(0, 256, (3,)) def highlight_domains(self, geometry, domains, seed=1, alpha=0.5, background='gray'): """Use alpha compositing to highlight one or more domains in the plot. - This routine generates a color scheme and applies alpha compositing - to make all domains except the highlighted ones appear partially + This routine generates a color scheme and applies alpha compositing to + make all domains except the highlighted ones appear partially transparent. Parameters ---------- geometry : openmc.Geometry The geometry for which the plot is defined - domains : Iterable of Integral + domains : Iterable of openmc.Cell or openmc.Material A collection of the domain IDs to highlight in the plot - seed : Integral + seed : int The random number seed used to generate the color scheme - alpha : Real in [0,1] - The value to apply in alpha compisiting - background : 3-tuple of Integral or 'white' or 'black' or 'gray' + alpha : float + The value between 0 and 1 to apply in alpha compisiting + background : 3-tuple of int or str The background color to apply in alpha compisiting """ - cv.check_iterable_type('domains', domains, Integral) + cv.check_type('domains', domains, Iterable, + (openmc.Cell, openmc.Material)) cv.check_type('alpha', alpha, Real) cv.check_greater_than('alpha', alpha, 0., equality=True) cv.check_less_than('alpha', alpha, 1., equality=True) + cv.check_type('background', background, Iterable) # Get a background (R,G,B) tuple to apply in alpha compositing if isinstance(background, string_types): - if background == 'white': - background = (255, 255, 255) - elif background == 'black': - background = (0, 0, 0) - elif background == 'gray': - background = (160, 160, 160) - else: - msg = 'The background "{}" is not defined'.format(background) - raise ValueError(msg) - - cv.check_iterable_type('background', background, Integral) + if background.lower() not in _SVG_COLORS: + raise ValueError("'{}' is not a valid color.".format(background)) + background = _SVG_COLORS[background.lower()] # Generate a color scheme self.colorize(geometry, seed) # Apply alpha compositing to the colors for all domains # other than those the user wishes to highlight - for domain_id in self.col_spec: - if domain_id not in domains: - r, g, b = self.col_spec[domain_id] + for domain, color in self.colors.items(): + if domain not in domains: + if isinstance(color, string_types): + color = _SVG_COLORS[color.lower()] + r, g, b = color r = int(((1-alpha) * background[0]) + (alpha * r)) g = int(((1-alpha) * background[1]) + (alpha * g)) b = int(((1-alpha) * background[2]) + (alpha * b)) - self._col_spec[domain_id] = (r, g, b) + self._colors[domain] = (r, g, b) - def get_plot_xml(self): + def to_xml_element(self): """Return XML representation of the plot Returns @@ -424,8 +611,9 @@ class Plot(object): element = ET.Element("plot") element.set("id", str(self._id)) - element.set("filename", self._filename) - element.set("color", self._color) + if self._filename is not None: + element.set("filename", self._filename) + element.set("color_by", self._color_by) element.set("type", self._type) if self._type is 'slice': @@ -442,21 +630,29 @@ class Plot(object): if self._background is not None: subelement = ET.SubElement(element, "background") - subelement.text = ' '.join(map(str, self._background)) + color = self._background + if isinstance(color, string_types): + color = _SVG_COLORS[color.lower()] + subelement.text = ' '.join(str(x) for x in color) - if self._col_spec is not None: - for key in self._col_spec: - subelement = ET.SubElement(element, "col_spec") - subelement.set("id", str(key)) - subelement.set("rgb", ' '.join(map( - str, self._col_spec[key]))) + if self._colors: + for domain, color in self._colors.items(): + subelement = ET.SubElement(element, "color") + subelement.set("id", str(domain.id)) + if isinstance(color, string_types): + color = _SVG_COLORS[color.lower()] + subelement.set("rgb", ' '.join(str(x) for x in color)) 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 = _SVG_COLORS[color.lower()] + subelement.set("background", ' '.join( + str(x) for x in color)) if self._level is not None: subelement = ET.SubElement(element, "level") @@ -585,20 +781,21 @@ class Plots(cv.CheckedList): alpha=0.5, background='gray'): """Use alpha compositing to highlight one or more domains in the plot. - This routine generates a color scheme and applies alpha compositing - to make all domains except the highlighted ones partially transparent. + This routine generates a color scheme and applies alpha compositing to + make all domains except the highlighted ones appear partially + transparent. Parameters ---------- geometry : openmc.Geometry The geometry for which the plot is defined - domains : Iterable of Integral + domains : Iterable of openmc.Cell or openmc.Material A collection of the domain IDs to highlight in the plot - seed : Integral + seed : int The random number seed used to generate the color scheme - alpha : Real in [0,1] - The value to apply in alpha compisiting - background : 3-tuple of Integral or 'white' or 'black' or 'gray' + alpha : float + The value between 0 and 1 to apply in alpha compisiting + background : 3-tuple of int or str The background color to apply in alpha compisiting """ @@ -608,7 +805,7 @@ class Plots(cv.CheckedList): def _create_plot_subelements(self): for plot in self: - xml_element = plot.get_plot_xml() + xml_element = plot.to_xml_element() if len(plot.name) > 0: self._plots_file.append(ET.Comment(plot.name)) diff --git a/openmc/region.py b/openmc/region.py index 8fd7e5181d..4494a3f622 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -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 """ diff --git a/openmc/summary.py b/openmc/summary.py index c30f004cbb..82275007c0 100644 --- a/openmc/summary.py +++ b/openmc/summary.py @@ -49,7 +49,7 @@ class Summary(object): @property def date_and_time(self): - return self._f.attrs['date_and_time'] + return self._f.attrs['date_and_time'].decode() @property def geometry(self): @@ -185,6 +185,8 @@ class Summary(object): for idx in fill._natural_indices: univ = fill.get_universe(idx) fill_univ_ids.add(univ.id) + if fill.outer is not None: + fill_univ_ids.add(fill.outer.id) # Set the fill for the Cell cells[cell_id].fill = fill diff --git a/openmc/universe.py b/openmc/universe.py index 4cc3f482e9..12bef012b9 100644 --- a/openmc/universe.py +++ b/openmc/universe.py @@ -1,3 +1,5 @@ +from __future__ import division +from copy import copy from collections import OrderedDict, Iterable from numbers import Integral, Real import random @@ -8,6 +10,7 @@ import numpy as np import openmc import openmc.checkvalue as cv +from openmc.plots import _SVG_COLORS # A static variable for auto-generated Lattice (Universe) IDs @@ -46,6 +49,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 +111,16 @@ class Universe(object): def volume(self): return self._volume + @property + def bounding_box(self): + regions = [c.region for c in self.cells.values() + if c.region is not None] + if regions: + return openmc.Union(*regions).bounding_box + else: + # Infinite bounding box + return openmc.Intersection().bounding_box + @id.setter def id(self, universe_id): if universe_id is None: @@ -207,15 +223,15 @@ class Universe(object): return [self, cell] + cell.fill.find(p) return [] - def plot(self, center=(0., 0., 0.), width=(1., 1.), pixels=(200, 200), + def plot(self, origin=(0., 0., 0.), width=(1., 1.), pixels=(200, 200), basis='xy', color_by='cell', colors=None, filename=None, seed=None, **kwargs): """Display a slice plot of the universe. Parameters ---------- - center : Iterable of float - Coordinates at the center of the plot + origin : Iterable of float + Coordinates at the origin of the plot width : Iterable of float Width of the plot in each basis direction pixels : Iterable of int @@ -225,11 +241,10 @@ class Universe(object): color_by : {'cell', 'material'} Indicate whether the plot should be colored by cell or by material colors : dict - Assigns colors to specific materials or cells. Keys are instances of - :class:`Cell` or :class:`Material` and values are RGB 3-tuples or - RGBA 4-tuples. Red, green, blue, and alpha should all be floats in - the range [0.0, 1.0], for example: + :class:`Cell` or :class:`Material` and values are RGB 3-tuples, RGBA + 4-tuples, or strings indicating SVG color names. Red, green, blue, + and alpha should all be floats in the range [0.0, 1.0], for example: .. code-block:: python @@ -260,28 +275,35 @@ class Universe(object): colors = {} else: # Convert to RGBA if necessary - for obj, rgb in colors.items(): - if len(rgb) == 3: - colors[obj] = rgb + (1.0,) + colors = copy(colors) + for obj, color in colors.items(): + if isinstance(color, string_types): + if color.lower() not in _SVG_COLORS: + raise ValueError("'{}' is not a valid color." + .format(color)) + colors[obj] = [x/255 for x in + _SVG_COLORS[color.lower()]] + [1.0] + elif len(color) == 3: + colors[obj] = list(color) + [1.0] if basis == 'xy': - x_min = center[0] - 0.5*width[0] - x_max = center[0] + 0.5*width[0] - y_min = center[1] - 0.5*width[1] - y_max = center[1] + 0.5*width[1] + x_min = origin[0] - 0.5*width[0] + x_max = origin[0] + 0.5*width[0] + y_min = origin[1] - 0.5*width[1] + y_max = origin[1] + 0.5*width[1] elif basis == 'yz': # The x-axis will correspond to physical y and the y-axis will # correspond to physical z - x_min = center[1] - 0.5*width[0] - x_max = center[1] + 0.5*width[0] - y_min = center[2] - 0.5*width[1] - y_max = center[2] + 0.5*width[1] + x_min = origin[1] - 0.5*width[0] + x_max = origin[1] + 0.5*width[0] + y_min = origin[2] - 0.5*width[1] + y_max = origin[2] + 0.5*width[1] elif basis == 'xz': # The y-axis will correspond to physical z - x_min = center[0] - 0.5*width[0] - x_max = center[0] + 0.5*width[0] - y_min = center[2] - 0.5*width[1] - y_max = center[2] + 0.5*width[1] + x_min = origin[0] - 0.5*width[0] + x_max = origin[0] + 0.5*width[0] + y_min = origin[2] - 0.5*width[1] + y_max = origin[2] + 0.5*width[1] # Determine locations to determine cells at x_coords = np.linspace(x_min, x_max, pixels[0], endpoint=False) + \ @@ -295,11 +317,11 @@ class Universe(object): for i, x in enumerate(x_coords): for j, y in enumerate(y_coords): if basis == 'xy': - path = self.find((x, y, center[2])) + path = self.find((x, y, origin[2])) elif basis == 'yz': - path = self.find((center[0], x, y)) + path = self.find((origin[0], x, y)) elif basis == 'xz': - path = self.find((x, center[1], y)) + path = self.find((x, origin[1], y)) if len(path) > 0: try: @@ -318,7 +340,8 @@ class Universe(object): img[j, i, :] = colors[obj] # Display image - plt.imshow(img, extent=(x_min, x_max, y_min, y_max), **kwargs) + plt.imshow(img, extent=(x_min, x_max, y_min, y_max), + interpolation='nearest', **kwargs) # Show or save the plot if filename is None: diff --git a/openmc/volume.py b/openmc/volume.py index f7bad73b4c..c9e1a5afa6 100644 --- a/openmc/volume.py +++ b/openmc/volume.py @@ -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 diff --git a/src/input_xml.F90 b/src/input_xml.F90 index e7365330cf..163dcf9013 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -4364,8 +4364,8 @@ contains ! Copy plot color type and initialize all colors randomly temp_str = "cell" - if (check_for_node(node_plot, "color")) & - call get_node_value(node_plot, "color", temp_str) + if (check_for_node(node_plot, "color_by")) & + call get_node_value(node_plot, "color_by", temp_str) temp_str = to_lower(temp_str) select case (trim(temp_str)) case ("cell") @@ -4378,7 +4378,7 @@ contains pl % colors(j) % rgb(3) = int(prn()*255) end do - case ("mat", "material") + case ("material") pl % color_by = PLOT_COLOR_MATS allocate(pl % colors(n_materials)) @@ -4393,8 +4393,8 @@ contains // "' in plot " // trim(to_str(pl % id))) end select - ! Get the number of nodes and get a list of them - call get_node_list(node_plot, "col_spec", node_col_list) + ! Get the number of nodes and get a list of them + call get_node_list(node_plot, "color", node_col_list) n_cols = size(node_col_list) ! Copy user specified colors @@ -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 in mask of plot " & - // trim(to_str(pl % id))) + pl % colors(j) % rgb(:) = [255, 255, 255] end if end if end do diff --git a/src/relaxng/plots.rnc b/src/relaxng/plots.rnc index 5ef14f2297..e53cc15f72 100644 --- a/src/relaxng/plots.rnc +++ b/src/relaxng/plots.rnc @@ -5,8 +5,8 @@ element plots { attribute filename { xsd:string { maxLength = "50" } })? & (element type { "slice" | "voxel" } | attribute type { "slice" | "voxel" })? & - (element color { ( "cell" | "mat" | "material" ) } | - attribute color { ( "cell" | "mat" | "material" ) })? & + (element color_by { ( "cell" | "material" ) } | + attribute color_by { ( "cell" | "material" ) })? & (element level { xsd:int } | attribute level { xsd:int })? & (element origin { list { xsd:double+ } } | attribute origin { list { xsd:double+ } })? & @@ -18,7 +18,7 @@ element plots { attribute pixels { list { xsd:int+ } })? & (element background { list { xsd:int+ } } | attribute background { list { xsd:int+ } })? & - element col_spec { + element color { (element id { xsd:int } | attribute id { xsd:int }) & (element rgb { list { xsd:int+ } } | attribute rgb { list { xsd:int+ } }) diff --git a/src/relaxng/plots.rng b/src/relaxng/plots.rng index a21f4d141e..55d69008ee 100644 --- a/src/relaxng/plots.rng +++ b/src/relaxng/plots.rng @@ -45,17 +45,15 @@ - + cell - mat material - + cell - mat material @@ -162,7 +160,7 @@ - + diff --git a/tests/input_set.py b/tests/input_set.py index 7971a8a4cc..ce5e3d5bc6 100644 --- a/tests/input_set.py +++ b/tests/input_set.py @@ -471,7 +471,7 @@ class InputSet(object): plot.origin = (125, 125, 0) plot.width = (250, 250) plot.pixels = (3000, 3000) - plot.color = 'mat' + plot.color_by = 'material' self.plots.add_plot(plot) @@ -563,7 +563,7 @@ class PinCellInputSet(object): plot.origin = (0.0, 0.0, 0) plot.width = (1.26, 1.26) plot.pixels = (300, 300) - plot.color = 'mat' + plot.color_by = 'material' self.plots.add_plot(plot) @@ -714,7 +714,7 @@ class AssemblyInputSet(object): plot.origin = (0.0, 0.0, 0) plot.width = (21.42, 21.42) plot.pixels = (300, 300) - plot.color = 'mat' + plot.color_by = 'material' self.plots.add_plot(plot) @@ -793,6 +793,6 @@ class MGInputSet(InputSet): plot.width = (2.5, 2.5) plot.basis = 'xz' plot.pixels = (3000, 3000) - plot.color = 'mat' + plot.color_by = 'material' self.plots.add_plot(plot) diff --git a/tests/test_distribmat/inputs_true.dat b/tests/test_distribmat/inputs_true.dat index 746bb8bef5..2d3e39a65d 100644 --- a/tests/test_distribmat/inputs_true.dat +++ b/tests/test_distribmat/inputs_true.dat @@ -52,12 +52,12 @@ - + 0 0 0 7 7 400 400 - + 0 0 0 7 7 400 400 diff --git a/tests/test_distribmat/test_distribmat.py b/tests/test_distribmat/test_distribmat.py index 6c1c5f79cf..2816bbfbc3 100644 --- a/tests/test_distribmat/test_distribmat.py +++ b/tests/test_distribmat/test_distribmat.py @@ -95,7 +95,7 @@ class DistribmatTestHarness(PyAPITestHarness): plot = openmc.Plot(plot_id=1) plot.basis = 'xy' - plot.color = 'cell' + plot.color_by = 'cell' plot.filename = 'cellplot' plot.origin = (0, 0, 0) plot.width = (7, 7) @@ -104,7 +104,7 @@ class DistribmatTestHarness(PyAPITestHarness): plot = openmc.Plot(plot_id=2) plot.basis = 'xy' - plot.color = 'mat' + plot.color_by = 'material' plot.filename = 'matplot' plot.origin = (0, 0, 0) plot.width = (7, 7) diff --git a/tests/test_lattice_hex/plots.xml b/tests/test_lattice_hex/plots.xml index 651c811443..903d69aef2 100644 --- a/tests/test_lattice_hex/plots.xml +++ b/tests/test_lattice_hex/plots.xml @@ -1,28 +1,28 @@ - + xy_cell 0 0 0 30 30 500 500 - + xy_material 0 0 0 30 30 500 500 - + yz_cell 0 0 0 50 400 500 4000 - + yz_material 0 0 0 5 5 diff --git a/tests/test_lattice_mixed/plots.xml b/tests/test_lattice_mixed/plots.xml index 651c811443..903d69aef2 100644 --- a/tests/test_lattice_mixed/plots.xml +++ b/tests/test_lattice_mixed/plots.xml @@ -1,28 +1,28 @@ - + xy_cell 0 0 0 30 30 500 500 - + xy_material 0 0 0 30 30 500 500 - + yz_cell 0 0 0 50 400 500 4000 - + yz_material 0 0 0 5 5 diff --git a/tests/test_multipole/inputs_true.dat b/tests/test_multipole/inputs_true.dat index 2a1e865ada..ee1ba636e2 100644 --- a/tests/test_multipole/inputs_true.dat +++ b/tests/test_multipole/inputs_true.dat @@ -51,12 +51,12 @@ - + 0 0 0 7 7 400 400 - + 0 0 0 7 7 400 400 diff --git a/tests/test_multipole/test_multipole.py b/tests/test_multipole/test_multipole.py index 85c360e734..33a9295dbc 100644 --- a/tests/test_multipole/test_multipole.py +++ b/tests/test_multipole/test_multipole.py @@ -79,7 +79,7 @@ class MultipoleTestHarness(PyAPITestHarness): plot = openmc.Plot(plot_id=1) plot.basis = 'xy' - plot.color = 'cell' + plot.color_by = 'cell' plot.filename = 'cellplot' plot.origin = (0, 0, 0) plot.width = (7, 7) @@ -88,7 +88,7 @@ class MultipoleTestHarness(PyAPITestHarness): plot = openmc.Plot(plot_id=2) plot.basis = 'xy' - plot.color = 'mat' + plot.color_by = 'material' plot.filename = 'matplot' plot.origin = (0, 0, 0) plot.width = (7, 7) diff --git a/tests/test_plot/plots.xml b/tests/test_plot/plots.xml index d5e03f598f..ecfe69125b 100644 --- a/tests/test_plot/plots.xml +++ b/tests/test_plot/plots.xml @@ -5,7 +5,7 @@ 0. 0. 0. 25 25 200 200 - + @@ -16,7 +16,7 @@ - + 0. 0. 0. 25 25 200 200 diff --git a/tests/test_triso/inputs_true.dat b/tests/test_triso/inputs_true.dat index 43b15b037c..12dd4e7a64 100644 --- a/tests/test_triso/inputs_true.dat +++ b/tests/test_triso/inputs_true.dat @@ -442,7 +442,7 @@ - diff --git a/tests/test_triso/plots.xml b/tests/test_triso/plots.xml index 60ae7d9d8f..eafe3206b3 100644 --- a/tests/test_triso/plots.xml +++ b/tests/test_triso/plots.xml @@ -1,6 +1,6 @@ -