Continue adding docstrings and updating modules.

This commit is contained in:
Paul Romano 2015-06-02 19:22:33 +07:00
parent 7ed1dd17e6
commit c8e176a9f7
17 changed files with 760 additions and 635 deletions

View file

@ -6,4 +6,3 @@ OpenCG Compatibility
.. automodule:: openmc.opencg_compatible
:members:
:undoc-members:

View file

@ -6,4 +6,3 @@ Particle Restart
.. automodule:: openmc.particle_restart
:members:
:undoc-members:

View file

@ -6,4 +6,3 @@ Plots
.. automodule:: openmc.plots
:members:
:undoc-members:

View file

@ -6,4 +6,3 @@ Settings
.. automodule:: openmc.settings
:members:
:undoc-members:

View file

@ -6,4 +6,3 @@ Statepoint
.. automodule:: openmc.statepoint
:members:
:undoc-members:

View file

@ -6,4 +6,3 @@ Summary
.. automodule:: openmc.summary
:members:
:undoc-members:

View file

@ -6,4 +6,3 @@ Surface
.. automodule:: openmc.surface
:members:
:undoc-members:

View file

@ -6,4 +6,3 @@ Tallies
.. automodule:: openmc.tallies
:members:
:undoc-members:

View file

@ -6,4 +6,3 @@ Trigger
.. automodule:: openmc.trigger
:members:
:undoc-members:

View file

@ -6,4 +6,3 @@ Universe
.. automodule:: openmc.universe
:members:
:undoc-members:

View file

@ -481,7 +481,7 @@ attributes/sub-elements:
:parameters:
For an "isotropic" angular distribution, ``parameters`` should not be
specified
specified.
For a "monodirectional" angular distribution, ``parameters`` should be
given as three real numbers which specify the angular cosines with respect
@ -605,8 +605,6 @@ survival biasing, otherwise known as implicit capture or absorption.
*Default*: false
.. _trace:
``<threads>`` Element
---------------------
@ -615,6 +613,8 @@ a simulation. It has no attributes and accepts a positive integer value.
*Default*: None (Determined by environment variable :envvar:`OMP_NUM_THREADS`)
.. _trace:
``<trace>`` Element
-------------------
@ -631,9 +631,9 @@ integers: the batch number, generation number, and particle number.
The ``<track>`` element specifies particles for which OpenMC will output binary
files describing particle position at every step of its transport. This element
should be followed by triplets of integers. Each triplet describes one particle
. The integers in each triplet specify the batch number, generation number, and
particle number, respectively.
should be followed by triplets of integers. Each triplet describes one
particle. The integers in each triplet specify the batch number, generation
number, and particle number, respectively.
*Default*: None

View file

@ -62,8 +62,20 @@ OPENMC_LATTICES = {}
OPENCG_LATTICES = {}
def get_opencg_material(openmc_material):
"""Return an OpenCG material corresponding to an OpenMC material.
Parameters
----------
openmc_material : openmc.material.Material
OpenMC material
Returns
-------
opencg_material : opencg.Material
Equivalent OpenCG material
"""
if not isinstance(openmc_material, openmc.Material):
msg = 'Unable to create an OpenCG Material from {0} ' \
@ -91,6 +103,19 @@ def get_opencg_material(openmc_material):
def get_openmc_material(opencg_material):
"""Return an OpenMC material corresponding to an OpenCG material.
Parameters
----------
opencg_material : opencg.Material
OpenCG material
Returns
-------
openmc_material : openmc.material.Material
Equivalent OpenMC material
"""
if not isinstance(opencg_material, opencg.Material):
msg = 'Unable to create an OpenMC Material from {0} ' \
@ -118,6 +143,19 @@ def get_openmc_material(opencg_material):
def is_opencg_surface_compatible(opencg_surface):
"""Determine whether OpenCG surface is compatible with OpenMC geometry
Parameters
----------
opencg_surface : opencg.Surface
OpenCG surface
Returns
-------
bool
Whether OpenCG surface is compatible with OpenMC
"""
if not isinstance(opencg_surface, opencg.Surface):
msg = 'Unable to check if OpenCG Surface is compatible' \
@ -132,6 +170,19 @@ def is_opencg_surface_compatible(opencg_surface):
def get_opencg_surface(openmc_surface):
"""Return an OpenCG surface corresponding to an OpenMC surface.
Parameters
----------
openmc_surface : openmc.surface.Surface
OpenMC surface
Returns
-------
opencg_surface : opencg.Surface
Equivalent OpenCG surface
"""
if not isinstance(openmc_surface, openmc.Surface):
msg = 'Unable to create an OpenCG Surface from {0} ' \
@ -205,6 +256,19 @@ def get_opencg_surface(openmc_surface):
def get_openmc_surface(opencg_surface):
"""Return an OpenMC surface corresponding to an OpenCG surface.
Parameters
----------
opencg_surface : opencg.Surface
OpenCG surface
Returns
-------
openmc_surface : openmc.surface.Surface
Equivalent OpenMC surface
"""
if not isinstance(opencg_surface, opencg.Surface):
msg = 'Unable to create an OpenMC Surface from {0} which ' \
@ -280,6 +344,21 @@ def get_openmc_surface(opencg_surface):
def get_compatible_opencg_surfaces(opencg_surface):
"""Generate OpenCG surfaces that are compatible with OpenMC equivalent to an
OpenCG surface that is not compatible.
Parameters
----------
opencg_surface : opencg.Surface
OpenCG surface that is incompatible with OpenMC
Returns
-------
surfaces : list of opencg.Surface
Collection of surfaces equivalent to the original one but compatible
with OpenMC
"""
if not isinstance(opencg_surface, opencg.Surface):
msg = 'Unable to create an OpenMC Surface from {0} which ' \
@ -349,6 +428,19 @@ def get_compatible_opencg_surfaces(opencg_surface):
def get_opencg_cell(openmc_cell):
"""Return an OpenCG cell corresponding to an OpenMC cell.
Parameters
----------
openmc_cell : openmc.universe.Cell
OpenMC cell
Returns
-------
opencg_cell : opencg.Cell
Equivalent OpenCG cell
"""
if not isinstance(openmc_cell, openmc.Cell):
msg = 'Unable to create an OpenCG Cell from {0} which ' \
@ -398,7 +490,26 @@ def get_opencg_cell(openmc_cell):
def get_compatible_opencg_cells(opencg_cell, opencg_surface, halfspace):
"""Generate OpenCG cells that are compatible with OpenMC equivalent to an OpenCG
cell that is not compatible.
Parameters
----------
opencg_cell : opencg.Cell
OpenCG cell
opencg_surface : opencg.Surface
OpenCG surface that causes the incompatibility, e.g. an x-squareprism
surface
halfspace : {-1, 1}
Which halfspace defined by the surface is contained in the cell
Returns
-------
compatible_cells : list of opencg.Cell
Collection of cells equivalent to the original one but compatible with
OpenMC
"""
if not isinstance(opencg_cell, opencg.Cell):
msg = 'Unable to create compatible OpenMC Cell from {0} which ' \
'is not an OpenCG Cell'.format(opencg_cell)
@ -418,8 +529,8 @@ def get_compatible_opencg_cells(opencg_cell, opencg_surface, halfspace):
compatible_cells = []
# SquarePrism Surfaces
if opencg_surface._type in ['x-squareprism',
'y-squareprism', 'z-squareprism']:
if opencg_surface._type in ['x-squareprism', 'y-squareprism',
'z-squareprism']:
# Get the compatible Surfaces (XPlanes and YPlanes)
compatible_surfaces = get_compatible_opencg_surfaces(opencg_surface)
@ -436,13 +547,11 @@ def get_compatible_opencg_cells(opencg_cell, opencg_surface, halfspace):
# If Cell is outside SquarePrism, add "outside" of Surface halfspaces
else:
# Create 8 Cell clones to represent each of the disjoint planar
# Surface halfspace intersections
num_clones = 8
for clone_id in range(num_clones):
# Create a cloned OpenCG Cell with Surfaces compatible with OpenMC
clone = opencg_cell.clone()
compatible_cells.append(clone)
@ -500,6 +609,14 @@ def get_compatible_opencg_cells(opencg_cell, opencg_surface, halfspace):
def make_opencg_cells_compatible(opencg_universe):
"""Make all cells in an OpenCG universe compatible with OpenMC.
Parameters
----------
opencg_universe : opencg.Universe
Universe to check
"""
if not isinstance(opencg_universe, opencg.Universe):
msg = 'Unable to make compatible OpenCG Cells for {0} which ' \
@ -545,8 +662,20 @@ def make_opencg_cells_compatible(opencg_universe):
return
def get_openmc_cell(opencg_cell):
"""Return an OpenMC cell corresponding to an OpenCG cell.
Parameters
----------
opencg_cell : opencg.Cell
OpenCG cell
Returns
-------
openmc_cell : openmc.universe.Cell
Equivalent OpenMC cell
"""
if not isinstance(opencg_cell, opencg.Cell):
msg = 'Unable to create an OpenMC Cell from {0} which ' \
@ -597,8 +726,20 @@ def get_openmc_cell(opencg_cell):
return openmc_cell
def get_opencg_universe(openmc_universe):
"""Return an OpenCG universe corresponding to an OpenMC universe.
Parameters
----------
openmc_universe : openmc.universe.Universe
OpenMC universe
Returns
-------
opencg_universe : opencg.Universe
Equivalent OpenCG universe
"""
if not isinstance(openmc_universe, openmc.Universe):
msg = 'Unable to create an OpenCG Universe from {0} which ' \
@ -633,6 +774,19 @@ def get_opencg_universe(openmc_universe):
def get_openmc_universe(opencg_universe):
"""Return an OpenMC universe corresponding to an OpenCG universe.
Parameters
----------
opencg_universe : opencg.Universe
OpenCG universe
Returns
-------
openmc_universe : openmc.universe.Universe
Equivalent OpenMC universe
"""
if not isinstance(opencg_universe, opencg.Universe):
msg = 'Unable to create an OpenMC Universe from {0} which ' \
@ -670,6 +824,19 @@ def get_openmc_universe(opencg_universe):
def get_opencg_lattice(openmc_lattice):
"""Return an OpenCG lattice corresponding to an OpenMC lattice.
Parameters
----------
openmc_lattice : openmc.universe.Lattice
OpenMC lattice
Returns
-------
opencg_lattice : opencg.Lattice
Equivalent OpenCG lattice
"""
if not isinstance(openmc_lattice, openmc.Lattice):
msg = 'Unable to create an OpenCG Lattice from {0} which ' \
@ -737,6 +904,19 @@ def get_opencg_lattice(openmc_lattice):
def get_openmc_lattice(opencg_lattice):
"""Return an OpenMC lattice corresponding to an OpenCG lattice.
Parameters
----------
opencg_lattice : opencg.Lattice
OpenCG lattice
Returns
-------
openmc_lattice : openmc.universe.Lattice
Equivalent OpenMC lattice
"""
if not isinstance(opencg_lattice, opencg.Lattice):
msg = 'Unable to create an OpenMC Lattice from {0} which ' \
@ -822,6 +1002,19 @@ def get_opencg_geometry(openmc_geometry):
def get_openmc_geometry(opencg_geometry):
"""Return an OpenMC geometry corresponding to an OpenCG geometry.
Parameters
----------
opencg_geometry : opencg.Geometry
OpenCG geometry
Returns
-------
openmc_geometry : openmc.universe.Geometry
Equivalent OpenMC geometry
"""
if not isinstance(opencg_geometry, opencg.Geometry):
msg = 'Unable to get OpenMC geometry from {0} which is ' \

View file

@ -1,9 +1,44 @@
#!/usr/bin/env python
import struct
class Particle(object):
"""Information used to restart a specific particle that caused a simulation to
fail.
Parameters
----------
filename : str
Path to the particle restart file
Attributes
----------
filetype : int
Integer indicating the file type
revision : int
Revision of the particle restart format
current_batch : int
The batch containing the particle
gen_per_batch : int
Number of generations per batch
current_gen : int
The generation containing the particle
n_particles : int
Number of particles per generation
run_mode : int
Type of simulation (criticality or fixed source)
id : long
Identifier of the particle
weight : float
Weight of the particle
energy : float
Energy of the particle in MeV
xyz : list of float
Position of the particle
uvw : list of float
Directional cosines of the particle
"""
def __init__(self, filename):
if filename.endswith('.h5'):
import h5py

View file

@ -18,9 +18,50 @@ 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.
Parameters
----------
plot_id : int
Unique identifier for the plot
name : str
Name of the plot
Attributes
----------
id : int
Unique identifier
name : str
Name of the plot
width : tuple or list or ndarray
Width of the plot in each basis direction
pixels : tuple or list or ndarray
Number of pixels to use in each basis direction
origin : tuple or list of ndarray
Origin (center) of the plot
filename :
Path to write the plot to
color : {'cell', 'mat'}
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 : tuple or list or ndarray
Unique id numbers of the cells or materials to plot
mask_background : tuple or list or ndarray
Color to apply to all cells/materials not listed in mask_components
defined by RGB
col_spec : dict
Dictionary indicating that certain cells/materials (keys) should be
colored with a specific RGB (values)
"""
def __init__(self, plot_id=None, name=''):
# Initialize Plot class attributes
self.id = plot_id
self.name = name
@ -36,75 +77,60 @@ class Plot(object):
self._mask_background = None
self._col_spec = None
@property
def id(self):
return self._id
@property
def name(self):
return self._name
@property
def width(self):
return self._width
@property
def pixels(self):
return self._pixels
@property
def origin(self):
return self._origin
@property
def filename(self):
return self._filename
@property
def color(self):
return self._color
@property
def type(self):
return self._type
@property
def basis(self):
return self._basis
@property
def background(self):
return self._background
@property
def mask_componenets(self):
return self._mask_components
@property
def mask_background(self):
return self._mask_background
@property
def col_spec(self):
return self._col_spec
@id.setter
def id(self, plot_id):
if plot_id is None:
global AUTO_PLOT_ID
self._id = AUTO_PLOT_ID
@ -123,7 +149,6 @@ class Plot(object):
else:
self._id = plot_id
@name.setter
def name(self, name):
@ -135,10 +160,8 @@ class Plot(object):
else:
self._name = name
@width.setter
def width(self, width):
if not isinstance(width, (tuple, list, np.ndarray)):
msg = 'Unable to create Plot ID={0} with width {1} which is not ' \
'a Python tuple/list or NumPy array'.format(self._id, width)
@ -158,10 +181,8 @@ class Plot(object):
self._width = width
@origin.setter
def origin(self, origin):
if not isinstance(origin, (tuple, list, np.ndarray)):
msg = 'Unable to create Plot ID={0} with origin {1} which is not ' \
'a Python tuple/list or NumPy array'.format(self._id, origin)
@ -172,7 +193,6 @@ class Plot(object):
'a 3D coordinate must be input'.format(self._id, origin)
raise ValueError(msg)
for dim in origin:
if not is_integer(dim) and not is_float(dim):
msg = 'Unable to create Plot ID={0} with origin {1} since ' \
@ -182,10 +202,8 @@ class Plot(object):
self._origin = origin
@pixels.setter
def pixels(self, pixels):
if not isinstance(pixels, (tuple, list, np.ndarray)):
msg = 'Unable to create Plot ID={0} with pixels {1} which is not ' \
'a Python tuple/list or NumPy array'.format(self._id, pixels)
@ -197,7 +215,6 @@ class Plot(object):
raise ValueError(msg)
for dim in pixels:
if not is_integer(dim):
msg = 'Unable to create Plot ID={0} with pixel value {1} ' \
'which is not an integer'.format(self._id, dim)
@ -210,10 +227,8 @@ class Plot(object):
self._pixels = pixels
@filename.setter
def filename(self, filename):
if not is_string(filename):
msg = 'Unable to create Plot ID={0} with filename {1} which is ' \
'not a string'.format(self._id, filename)
@ -221,10 +236,8 @@ class Plot(object):
self._filename = filename
@color.setter
def color(self, color):
if not is_string(color):
msg = 'Unable to create Plot ID={0} with color {1} which is not ' \
'a string'.format(self._id, color)
@ -237,10 +250,8 @@ class Plot(object):
self._color = color
@type.setter
def type(self, type):
if not is_string(type):
msg = 'Unable to create Plot ID={0} with type {1} which is not ' \
'a string'.format(self._id, type)
@ -253,10 +264,8 @@ class Plot(object):
self._type = type
@basis.setter
def basis(self, basis):
if not is_string(basis):
msg = 'Unable to create Plot ID={0} with basis {1} which is not ' \
'a string'.format(self._id, basis)
@ -269,10 +278,8 @@ class Plot(object):
self._basis = basis
@background.setter
def background(self, background):
if not isinstance(background, (tuple, list, np.ndarray)):
msg = 'Unable to create Plot ID={0} with background {1} ' \
'which is not a Python tuple/list or NumPy ' \
@ -286,7 +293,6 @@ class Plot(object):
raise ValueError(msg)
for rgb in background:
if not is_integer(rgb):
msg = 'Unable to create Plot ID={0} with background RGB ' \
'value {1} which is not an integer'.format(self._id, rgb)
@ -299,10 +305,8 @@ class Plot(object):
self._background = background
@col_spec.setter
def col_spec(self, col_spec):
if not isinstance(col_spec, dict):
msg= 'Unable to create Plot ID={0} with col_spec parameter {1} ' \
'which is not a Python dictionary of IDs to ' \
@ -310,7 +314,6 @@ class Plot(object):
raise ValueError(msg)
for key in col_spec:
if not is_integer(key):
msg = 'Unable to create Plot ID={0} with col_spec ID {1} ' \
'which is not an integer'.format(self._id, key)
@ -335,10 +338,8 @@ class Plot(object):
self._col_spec = col_spec
@mask_componenets.setter
def mask_components(self, mask_components):
if not isinstance(mask_components, (list, tuple, np.ndarray)):
msg = 'Unable to create Plot ID={0} with mask components {1} ' \
'which is not a Python tuple/list or NumPy ' \
@ -358,10 +359,8 @@ class Plot(object):
self._mask_components = mask_components
@mask_background.setter
def mask_background(self, mask_background):
if not isinstance(mask_background, (list, tuple, np.ndarray)):
msg = 'Unable to create Plot ID={0} with mask background {1} ' \
'which is not a Python tuple/list or NumPy ' \
@ -389,9 +388,7 @@ class Plot(object):
self._mask_background = mask_background
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)
@ -409,8 +406,15 @@ class Plot(object):
string += '{0: <16}{1}{2}\n'.format('\tCol Spec', '=\t', self._col_spec)
return string
def get_plot_xml(self):
"""Return XML representation of the plot
Returns
-------
element : xml.etree.ElementTree.Element
XML element containing plot data
"""
element = ET.Element("plot")
element.set("id", str(self._id))
@ -422,64 +426,55 @@ class Plot(object):
element.set("basis", self._basis)
subelement = ET.SubElement(element, "origin")
text = ''
for coord in self._origin:
text += str(coord) + ' '
subelement.text = text.rstrip(' ')
subelement.text = ' '.join(map(str, self._origin))
subelement = ET.SubElement(element, "width")
text = ''
for dim in self._width:
text += str(dim) + ' '
subelement.text = text.rstrip(' ')
subelement.text = ' '.join(map(str, self._width))
subelement = ET.SubElement(element, "pixels")
text = ''
for dim in self._pixels:
text += str(dim) + ' '
subelement.text = text.rstrip(' ')
subelement.text = ' '.join(map(str, self._pixels))
if not self._mask_background is None:
subelement = ET.SubElement(element, "background")
text = ''
for rgb in self._background:
text += str(rgb) + ' '
subelement.text = text.rstrip(' ')
subelement.text = ' '.join(map(str, self._background))
if not self._col_spec is None:
for key in self._col_spec:
subelement = ET.SubElement(element, "col_spec")
subelement.set("id", '{0}'.format(key))
value = self._col_spec[key]
subelement.set("rgb",'{0} {1} {2}'.format(value[0],
value[1], value[2]))
subelement.set("id", str(key))
subelement.set("rgb", ' '.join(map(
str, self._col_spec[key])))
if not self._mask_components is None:
subelement = ET.SubElement(element, "mask")
text = ''
for id in self._mask_components:
text += str(id) + ' '
subelement.set("components", text.rstrip(' '))
rgb = self._mask_background
subelement.set("background", '{0} {1} {2}'.format(rgb[0],
rgb[1], rgb[2]))
subelement.set("components", ' '.join(map(
str, self._mask_components)))
subelement.set("background", ' '.join(map(
str, self._mask_background)))
return element
class PlotsFile(object):
"""Plots file used for an OpenMC simulation. Corresponds directly to the
plots.xml input file.
"""
def __init__(self):
# Initialize PlotsFile class attributes
self._plots = []
self._plots_file = ET.Element("plots")
def add_plot(self, plot):
"""Add a plot to the file.
Parameters
----------
plot : Plot
Plot to add
"""
if not isinstance(plot, Plot):
msg = 'Unable to add a non-Plot {0} to the PlotsFile'.format(plot)
@ -487,15 +482,20 @@ class PlotsFile(object):
self._plots.append(plot)
def remove_plot(self, plot):
"""Remove a plot from the file.
Parameters
----------
plot : Plot
Plot to remove
"""
self._plots.remove(plot)
def create_plot_subelements(self):
def _create_plot_subelements(self):
for plot in self._plots:
xml_element = plot.get_plot_xml()
if len(plot._name) > 0:
@ -503,10 +503,12 @@ class PlotsFile(object):
self._plots_file.append(xml_element)
def export_to_xml(self):
"""Create a plots.xml file that can be used by OpenMC.
self.create_plot_subelements()
"""
self._create_plot_subelements()
# Clean the indentation in the file to be user-readable
clean_xml_indentation(self._plots_file)

File diff suppressed because it is too large Load diff

View file

@ -13,17 +13,28 @@ if sys.version > '3':
class SourceSite(object):
"""A single source site, usually resulting from fission.
Attributes
----------
weight : float
Weight of the particle arising from the site
xyz : list of float
Cartesian coordinates of the site
uvw : list of float
Directional cosines for particles emerging from the site
E : float
Energy of the emerging particle in MeV
"""
def __init__(self):
self._weight = None
self._xyz = None
self._uvw = None
self._E = None
def __repr__(self):
string = 'SourceSite\n'
string += '{0: <16}{1}{2}\n'.format('\tweight', '=\t', self._weight)
string += '{0: <16}{1}{2}\n'.format('\tE', '=\t', self._E)
@ -31,32 +42,56 @@ class SourceSite(object):
string += '{0: <16}{1}{2}\n'.format('\t(u,v,w)', '=\t', self._uvw)
return string
@property
def weight(self):
return self._weight
@property
def xyz(self):
return self._xyz
@property
def uvw(self):
return self._uvw
@property
def E(self):
return self._E
class StatePoint(object):
"""State information on a simulation at a certain point in time (at the end of a
given batch). Statepoints can be used to analyze tally results as well as
restart a simulation.
Attributes
----------
k_combined : list
Combined estimator for k-effective and its uncertainty
n_particles : int
Number of particles per generation
n_batches : int
Number of batches
current_batch :
Number of batches simulated
results : bool
Indicate whether tally results have been read
source : ndarray of SourceSite
Array of source sites
with_summary : bool
Indicate whether statepoint data has been linked against a summary file
tallies : dict
Dictionary whose keys are tally IDs and whose values are Tally objects
tallies_present : bool
Indicate whether user-defined tallies are present
global_tallies : ndarray
Global tallies and their uncertainties
n_realizations : int
Number of tally realizations
"""
def __init__(self, filename):
if filename.endswith('.h5'):
import h5py
self._f = h5py.File(filename, 'r')
@ -79,7 +114,6 @@ class StatePoint(object):
# Read tally metadata
self._read_tallies()
def close(self):
self._f.close()
@ -128,7 +162,6 @@ class StatePoint(object):
return self._n_realizations
def _read_metadata(self):
# Read filetype
self._filetype = self._get_int(path='filetype')[0]
@ -169,9 +202,7 @@ class StatePoint(object):
if self._run_mode == 2:
self._read_criticality()
def _read_criticality(self):
# Read criticality information
if self._run_mode == 2:
@ -191,9 +222,7 @@ class StatePoint(object):
# Read CMFD information (if used)
self._read_cmfd()
def _read_cmfd(self):
base = 'cmfd'
# Read CMFD information
@ -217,9 +246,7 @@ class StatePoint(object):
self._cmfd_srccmp = self._get_double(self._current_batch,
path='{0}/cmfd_srccmp'.format(base))
def _read_meshes(self):
# Initialize dictionaries for the Meshes
# Keys - Mesh IDs
# Values - Mesh objects
@ -284,7 +311,6 @@ class StatePoint(object):
def _read_tallies(self):
# Initialize dictionaries for the Tallies
# Keys - Tally IDs
# Values - Tally objects
@ -423,7 +449,6 @@ class StatePoint(object):
# Add the scores to the Tally
for j, score in enumerate(scores):
# If this is a scattering moment, insert the scattering order
if '-n' in score:
score = score.replace('-n', '-' + str(moments[j]))
@ -437,8 +462,11 @@ class StatePoint(object):
# Add Tally to the global dictionary of all Tallies
self.tallies[tally_key] = tally
def read_results(self):
"""Read tally results and store them in the ``tallies`` attribute. By default,
when the statepoint is first loaded, no results are read.
"""
# Number of realizations for global Tallies
self._n_realizations = self._get_int(path='n_realizations')[0]
@ -499,8 +527,11 @@ class StatePoint(object):
# Indicate that Tally results have been read
self._results = True
def read_source(self):
"""Read and store source sites from the statepoint file. By default, source
sites are not loaded upon initialization.
"""
# Check whether Tally results have been read
if not self._results:
@ -520,7 +551,6 @@ class StatePoint(object):
# Initialize SourceSite object for each particle
for i in range(self._n_particles):
# Initialize new source site
site = SourceSite()
@ -536,9 +566,15 @@ class StatePoint(object):
# Store the source site in the NumPy array
self._source[i] = site
def compute_ci(self, confidence=0.95):
"""Computes confidence intervals for each Tally bin."""
"""Computes confidence intervals for each Tally bin.
Parameters
----------
confidence : float, optional
Confidence level. Defaults to 0.95.
"""
# Determine significance level and percentile for two-sided CI
alpha = 1 - confidence
@ -548,11 +584,16 @@ class StatePoint(object):
t_value = scipy.stats.t.ppf(percentile, self._n_realizations - 1)
self.compute_stdev(t_value)
def compute_stdev(self, t_value=1.0):
"""
Computes the sample mean and the standard deviation of the mean
"""Computes the sample mean and the standard deviation of the mean
for each Tally bin.
Parameters
----------
t_value : float, optional
Student's t-value applied to the uncertainty. Defaults to 1.0,
meaning the reported value is the sample standard deviation.
"""
# Determine number of realizations
@ -572,12 +613,10 @@ class StatePoint(object):
if s != 0.0:
self._global_tallies[i, 1] = t_value * np.sqrt((s2 / n - s**2) / (n-1))
# Calculate sample mean and standard deviation for user-defined Tallies
for tally_id, tally in self.tallies.items():
tally.compute_std_dev(t_value)
def get_tally(self, scores=[], filters=[], nuclides=[],
name=None, id=None, estimator=None):
"""Finds and returns a Tally object with certain properties.
@ -589,32 +628,30 @@ class StatePoint(object):
Parameters
----------
scores : list
A list of one or more score strings (default is []).
filters : list
A list of Filter objects (default is []).
nuclides : list
A list of Nuclide objects (default is []).
name : str
The name specified for the Tally (default is None).
id : int
The id specified for the Tally (default is None).
estimator: str
The type of estimator ('tracklength', 'analog'; default is None).
scores : list, optional
A list of one or more score strings (default is []).
filters : list, optional
A list of Filter objects (default is []).
nuclides : list, optional
A list of Nuclide objects (default is []).
name : str, optional
The name specified for the Tally (default is None).
id : int, optional
The id specified for the Tally (default is None).
estimator: str, optional
The type of estimator ('tracklength', 'analog'; default is None).
Returns
-------
A Tally object.
tally : Tally
A tally matching the specified criteria
Raises
------
LookupError : An error when a Tally meeting all of the input
parameters cannot be found in the statepoint.
LookupError
If a Tally meeting all of the input parameters cannot be found in
the statepoint.
"""
tally = None
@ -683,7 +720,6 @@ class StatePoint(object):
return tally
def link_with_summary(self, summary):
"""Links Tallies and Filters with Summary model information.
@ -699,8 +735,10 @@ class StatePoint(object):
Raises
------
ValueError : An error when the argument passed to the 'summary'
parameter is not an openmc.Summary object.
ValueError
An error when the argument passed to the 'summary' parameter is not
an openmc.Summary object.
"""
if not isinstance(summary, openmc.summary.Summary):
@ -709,7 +747,6 @@ class StatePoint(object):
raise ValueError(msg)
for tally_id, tally in self.tallies.items():
# Get the Tally name from the summary file
tally.name = summary.tallies[tally_id].name
tally.with_summary = True
@ -717,7 +754,6 @@ class StatePoint(object):
nuclide_zaids = copy.deepcopy(tally.nuclides)
for nuclide_zaid in nuclide_zaids:
tally.remove_nuclide(nuclide_zaid)
if nuclide_zaid == -1:
tally.add_nuclide(openmc.Nuclide('total'))
@ -725,7 +761,6 @@ class StatePoint(object):
tally.add_nuclide(summary.nuclides[nuclide_zaid])
for filter in tally.filters:
if filter.type == 'surface':
surface_ids = []
for bin in filter.bins:
@ -749,9 +784,8 @@ class StatePoint(object):
for bin in filter.bins:
material_ids.append(summary.materials[bin].id)
filter.bins = material_ids
self._with_summary = True
self._with_summary = True
def _get_data(self, n, typeCode, size):
return list(struct.unpack('={0}{1}'.format(n,typeCode),

View file

@ -10,9 +10,12 @@ except ImportError:
class Summary(object):
"""Information summarizing the geometry, materials, and tallies used in a
simulation.
"""
def __init__(self, filename):
openmc.reset_auto_ids()
if not filename.endswith(('.h5', '.hdf5')):
@ -27,9 +30,7 @@ class Summary(object):
self._read_geometry()
self._read_tallies()
def _read_metadata(self):
# Read OpenMC version
self.version = [self._f['version_major'][0],
self._f['version_minor'][0],
@ -44,9 +45,7 @@ class Summary(object):
self.gen_per_batch = self._f['gen_per_batch'][0]
self.n_procs = self._f['n_procs'][0]
def _read_geometry(self):
# Read in and initialize the Materials and Geometry
self._read_nuclides()
self._read_materials()
@ -56,9 +55,7 @@ class Summary(object):
self._read_lattices()
self._finalize_geometry()
def _read_nuclides(self):
self.n_nuclides = self._f['nuclides/n_nuclides'][0]
# Initialize dictionary for each Nuclide
@ -67,7 +64,6 @@ class Summary(object):
self.nuclides = {}
for key in self._f['nuclides'].keys():
if key == 'n_nuclides':
continue
@ -88,9 +84,7 @@ class Summary(object):
self.nuclides[zaid] = openmc.Nuclide(name=name, xs=xs)
self.nuclides[zaid].zaid = zaid
def _read_materials(self):
self.n_materials = self._f['materials/n_materials'][0]
# Initialize dictionary for each Material
@ -99,7 +93,6 @@ class Summary(object):
self.materials = {}
for key in self._f['materials'].keys():
if key == 'n_materials':
continue
@ -116,7 +109,6 @@ class Summary(object):
# Read the names of the S(a,b) tables for this Material
for i in range(1, n_sab+1):
sab_table = self._f['materials'][key]['sab_tables'][str(i)][0]
# Read the cross-section identifiers for each S(a,b) table
@ -148,9 +140,7 @@ class Summary(object):
# Add the Material to the global dictionary of all Materials
self.materials[index] = material
def _read_surfaces(self):
self.n_surfaces = self._f['geometry/n_surfaces'][0]
# Initialize dictionary for each Surface
@ -159,7 +149,6 @@ class Summary(object):
self.surfaces = {}
for key in self._f['geometry/surfaces'].keys():
if key == 'n_surfaces':
continue
@ -171,7 +160,6 @@ class Summary(object):
coeffs = self._f['geometry/surfaces'][key]['coefficients'][...]
# Create the Surface based on its type
if surf_type == 'X Plane':
x0 = coeffs[0]
surface = openmc.XPlane(surface_id, bc, x0, name)
@ -232,9 +220,7 @@ class Summary(object):
# Add Surface to global dictionary of all Surfaces
self.surfaces[index] = surface
def _read_cells(self):
self.n_cells = self._f['geometry/n_cells'][0]
# Initialize dictionary for each Cell
@ -251,7 +237,6 @@ class Summary(object):
self._cell_fills = {}
for key in self._f['geometry/cells'].keys():
if key == 'n_cells':
continue
@ -310,9 +295,7 @@ class Summary(object):
# Add the Cell to the global dictionary of all Cells
self.cells[index] = cell
def _read_universes(self):
self.n_universes = self._f['geometry/n_universes'][0]
# Initialize dictionary for each Universe
@ -321,7 +304,6 @@ class Summary(object):
self.universes = {}
for key in self._f['geometry/universes'].keys():
if key == 'n_universes':
continue
@ -340,9 +322,7 @@ class Summary(object):
# Add the Universe to the global list of Universes
self.universes[index] = universe
def _read_lattices(self):
self.n_lattices = self._f['geometry/n_lattices'][0]
# Initialize lattices for each Lattice
@ -351,7 +331,6 @@ class Summary(object):
self.lattices = {}
for key in self._f['geometry/lattices'].keys():
if key == 'n_lattices':
continue
@ -451,15 +430,12 @@ class Summary(object):
# Add the Lattice to the global dictionary of all Lattices
self.lattices[index] = lattice
def _finalize_geometry(self):
# Initialize Geometry object
self.openmc_geometry = openmc.Geometry()
# Iterate over all Cells and add fill Materials, Universes and Lattices
for cell_key in self._cell_fills.keys():
# Determine fill type ('normal', 'universe', or 'lattice') and ID
fill_type = self._cell_fills[cell_key][0]
fill_id = self._cell_fills[cell_key][1]
@ -482,9 +458,7 @@ class Summary(object):
root_universe = self.get_universe_by_id(0)
self.openmc_geometry.root_universe = root_universe
def _read_tallies(self):
# Initialize dictionaries for the Tallies
# Keys - Tally IDs
# Values - Tally objects
@ -554,9 +528,7 @@ class Summary(object):
# Add Tally to the global dictionary of all Tallies
self.tallies[tally_id] = tally
def make_opencg_geometry(self):
try:
from openmc.opencg_compatible import get_opencg_geometry
except ImportError:
@ -567,54 +539,42 @@ class Summary(object):
if self.opencg_geometry is None:
self.opencg_geometry = get_opencg_geometry(self.openmc_geometry)
def get_nuclide_by_zaid(self, zaid):
for index, nuclide in self.nuclides.items():
if nuclide._zaid == zaid:
return nuclide
return None
def get_material_by_id(self, material_id):
for index, material in self.materials.items():
if material._id == material_id:
return material
return None
def get_surface_by_id(self, surface_id):
for index, surface in self.surfaces.items():
if surface._id == surface_id:
return surface
return None
def get_cell_by_id(self, cell_id):
for index, cell in self.cells.items():
if cell._id == cell_id:
return cell
return None
def get_universe_by_id(self, universe_id):
for index, universe in self.universes.items():
if universe._id == universe_id:
return universe
return None
def get_lattice_by_id(self, lattice_id):
for index, lattice in self.lattices.items():
if lattice._id == lattice_id:
return lattice