SettingsFile now uses source property based off openmc.source.Source.

This commit is contained in:
Paul Romano 2015-12-18 09:13:41 -06:00
parent efc7d2ecbf
commit db9ac7ba2f
14 changed files with 879 additions and 253 deletions

View file

@ -1,4 +1,6 @@
import openmc
from openmc.source import Source
from openmc.stats import SpatialBox
###############################################################################
# Simulation Input File Parameters
@ -92,7 +94,7 @@ settings_file = openmc.SettingsFile()
settings_file.batches = batches
settings_file.inactive = inactive
settings_file.particles = particles
settings_file.set_source_space('box', [-4, -4, -4, 4, 4, 4])
settings_file.source = Source(space=SpatialBox([-4, -4, -4], [4, 4, 4]))
settings_file.export_to_xml()

View file

@ -1,6 +1,8 @@
import numpy as np
import openmc
from openmc.source import Source
from openmc.stats import SpatialBox
###############################################################################
# Simulation Input File Parameters
@ -117,7 +119,7 @@ settings_file = openmc.SettingsFile()
settings_file.batches = batches
settings_file.inactive = inactive
settings_file.particles = particles
settings_file.set_source_space('box', np.concatenate(outer_cube.bounding_box))
settings_file.source = Source(space=SpatialBox(*outer_cube.bounding_box))
settings_file.export_to_xml()
###############################################################################

View file

@ -1,5 +1,6 @@
import openmc
from openmc.source import Source
from openmc.stats import SpatialBox
###############################################################################
# Simulation Input File Parameters
@ -125,7 +126,8 @@ settings_file = openmc.SettingsFile()
settings_file.batches = batches
settings_file.inactive = inactive
settings_file.particles = particles
settings_file.set_source_space('box', [-1, -1, -1, 1, 1, 1])
settings_file.source = Source(space=SpatialBox(
[-1, -1, -1], [1, 1, 1]))
settings_file.keff_trigger = {'type' : 'std_dev', 'threshold' : 5E-4}
settings_file.trigger_active = True
settings_file.trigger_max_batches = 100

View file

@ -1,5 +1,6 @@
import openmc
from openmc.source import Source
from openmc.stats import SpatialBox
###############################################################################
# Simulation Input File Parameters
@ -136,7 +137,8 @@ settings_file = openmc.SettingsFile()
settings_file.batches = batches
settings_file.inactive = inactive
settings_file.particles = particles
settings_file.set_source_space('box', [-1, -1, -1, 1, 1, 1])
settings_file.source = Source(space=SpatialBox(
[-1, -1, -1], [1, 1, 1]))
settings_file.export_to_xml()

View file

@ -1,4 +1,6 @@
import openmc
from openmc.source import Source
from openmc.stats import SpatialBox
###############################################################################
# Simulation Input File Parameters
@ -125,7 +127,8 @@ settings_file = openmc.SettingsFile()
settings_file.batches = batches
settings_file.inactive = inactive
settings_file.particles = particles
settings_file.set_source_space('box', [-1, -1, -1, 1, 1, 1])
settings_file.source = Source(space=SpatialBox(
[-1, -1, -1], [1, 1, 1]))
settings_file.trigger_active = True
settings_file.trigger_max_batches = 100
settings_file.export_to_xml()

View file

@ -1,4 +1,6 @@
import openmc
from openmc.source import Source
from openmc.stats import SpatialBox
###############################################################################
# Simulation Input File Parameters
@ -168,8 +170,8 @@ settings_file = openmc.SettingsFile()
settings_file.batches = batches
settings_file.inactive = inactive
settings_file.particles = particles
settings_file.set_source_space('box', [-0.62992, -0.62992, -1, \
0.62992, 0.62992, 1])
settings_file.source = Source(space=SpatialBox(
[-0.62992, -0.62992, -1], [0.62992, 0.62992, 1]))
settings_file.entropy_lower_left = [-0.39218, -0.39218, -1.e50]
settings_file.entropy_upper_right = [0.39218, 0.39218, 1.e50]
settings_file.entropy_dimension = [10, 10, 1]

View file

@ -1,6 +1,8 @@
import numpy as np
import openmc
from openmc.stats import SpatialBox
from openmc.source import Source
###############################################################################
# Simulation Input File Parameters
@ -84,5 +86,5 @@ settings_file = openmc.SettingsFile()
settings_file.batches = batches
settings_file.inactive = inactive
settings_file.particles = particles
settings_file.set_source_space('box', np.concatenate(cell.region.bounding_box))
settings_file.source = Source(space=SpatialBox(*cell.region.bounding_box))
settings_file.export_to_xml()

View file

@ -9,6 +9,7 @@ import numpy as np
from openmc.clean_xml import *
from openmc.checkvalue import (check_type, check_length, check_value,
check_greater_than, check_less_than)
from openmc.source import Source
if sys.version_info[0] >= 3:
basestring = str
@ -36,8 +37,8 @@ class SettingsFile(object):
type are 'variance', 'std_dev', and 'rel_err'. The threshold value
should be a float indicating the variance, standard deviation, or
relative error used.
source_file : str
Path to a source file
source : openmc.source.Source
Distribution of source sites in space, angle, and energy
output : dict
Dictionary indicating what files to output. Valid keys are 'summary',
'cross_sections', 'tallies', and 'distribmats'. Values corresponding to
@ -134,16 +135,7 @@ class SettingsFile(object):
self._keff_trigger = None
# Source subelement
self._source_subelement = None
self._source_file = None
self._source_space_type = None
self._source_space_params = None
self._source_angle_type = None
self._source_angle_interpolation = None
self._source_angle_params = None
self._source_energy_type = None
self._source_energy_interpolation = None
self._source_energy_params = None
self._source = None
self._confidence_intervals = None
self._cross_sections = None
@ -230,40 +222,8 @@ class SettingsFile(object):
return self._keff_trigger
@property
def source_file(self):
return self._source_file
@property
def source_space_type(self):
return self._source_space_type
@property
def source_space_params(self):
return self._source_space_params
@property
def source_angle_type(self):
return self._source_angle_type
@property
def source_angle_interpolation(self):
return self._source_angle_interpolation
@property
def source_angle_params(self):
return self._source_angle_params
@property
def source_energy_type(self):
return self._source_energy_type
@property
def source_energy_interpolation(self):
return self._source_energy_interpolation
@property
def source_energy_params(self):
return self._source_energy_params
def source(self):
return self._source
@property
def confidence_intervals(self):
@ -478,156 +438,10 @@ class SettingsFile(object):
self._keff_trigger = keff_trigger
@source_file.setter
def source_file(self, source_file):
check_type('source file', source_file, basestring)
self._source_file = source_file
def set_source_space(self, stype, params):
"""Defined the spatial bounds of the external/starting source.
Parameters
----------
stype : str
The type of spatial distribution. Valid options are "box",
"fission", and "point". A "box" spatial distribution has coordinates
sampled uniformly in a parallelepiped. A "fission" spatial
distribution samples locations from a "box" distribution but only
locations in fissionable materials are accepted. A "point" spatial
distribution has coordinates specified by a triplet.
params : Iterable of float
For a "box" or "fission" spatial distribution, ``params`` should be
given as six real numbers, the first three of which specify the
lower-left corner of a parallelepiped and the last three of which
specify the upper-right corner. Source sites are sampled uniformly
through that parallelepiped.
For a "point" spatial distribution, ``params`` should be given as
three real numbers which specify the (x,y,z) location of an
isotropic point source
"""
check_type('source space type', stype, basestring)
check_value('source space type', stype, ['box', 'fission', 'point'])
check_type('source space parameters', params, Iterable, Real)
if stype in ['box', 'fission']:
check_length('source space parameters for a '
'box/fission distribution', params, 6)
elif stype == 'point':
check_length('source space parameters for a point source',
params, 3)
self._source_space_type = stype
self._source_space_params = params
def set_source_angle(self, stype, params=[], interp='histogram'):
"""Defined the angular distribution of the external/starting source.
Parameters
----------
stype : str
The type of angular distribution. Valid options are "isotropic",
"monodirectional", and "tabular". The angle of the particle emitted
from a source site is isotropic if the "isotropic" option is
given. The angle of the particle emitted from a source site is the
direction specified in ``params`` if the "monodirectional" option is
given. The "tabular" option produces directions with polar angles
sampled from a tabulated distribution.
params : Iterable of float
For an "isotropic" angular distribution, ``params`` should not
be specified.
For a "monodirectional" angular distribution, ``params`` should
be given as three floats which specify the angular cosines
with respect to each axis.
For a "tabular" angular distribution, ``parameters`` provides the
:math:`(\mu,p)` pairs defining the tabular distribution. All
:math:`\mu` points are given first followed by corresponding
:math:`p` points.
interp : { 'histogram', 'linear-linear' }
For a "tabular" angular distribution, ``interpolation`` can be set
to "histogram" or "linear-linear" thereby specifying how tabular
points are to be interpolated.
"""
check_type('source angle type', stype, basestring)
check_value('source angle type', stype,
['isotropic', 'monodirectional', 'tabular'])
check_type('source angle parameters', params, Iterable, Real)
if stype == 'isotropic' and params is not None:
msg = 'Unable to set source angle parameters since they are not ' \
'it is not supported for isotropic type sources'
raise ValueError(msg)
elif stype == 'monodirectional':
check_length('source angle parameters for a monodirectional '
'source', params, 3)
elif stype == 'tabular':
check_type('source angle interpolation', interp, basestring)
check_value('source angle interpolation', interp,
['histogram', 'linear-linear'])
self._source_angle_interpolation = interp
self._source_angle_type = stype
self._source_angle_params = params
def set_source_energy(self, stype, params=[], interp='histogram'):
"""Defined the energy distribution of the external/starting source.
Parameters
----------
stype : str
The type of energy distribution. Valid options are "monoenergetic",
"watt", "maxwell", and "tabular". The "monoenergetic" option
produces source sites at a single energy. The "watt" option produces
source sites whose energy is sampled from a Watt fission
spectrum. The "maxwell" option produce source sites whose energy is
sampled from a Maxwell fission spectrum. The "tabular" option
produces source sites whose energy is sampled from a tabulated
distribution.
params : Iterable of float
For a "monoenergetic" energy distribution, ``params`` should be
given as the energy in MeV of the source sites.
For a "watt" energy distribution, ``params`` should be given as two
real numbers :math:`a` and :math:`b` that parameterize the
distribution :math:`p(E) dE = c e^{-E/a} \sinh \sqrt{b \, E} dE`.
For a "maxwell" energy distribution, ``params`` should be given as
one real number :math:`a` that parameterizes the distribution
:math:`p(E) dE = c E e^{-E/a} dE`.
For a "tabular" energy distribution, ``parameters`` provides the
:math:`(E,p)` pairs defining the tabular distribution. All :math:`E`
points are given first followed by corresponding :math:`p` points.
interp : { 'histogram', 'linear-linear' }
For a "tabular" energy distribution, ``interpolation`` can be set
to "histogram" or "linear-linear" thereby specifying how tabular
points are to be interpolated.
"""
check_type('source energy type', stype, basestring)
check_value('source energy type', stype,
['monoenergetic', 'watt', 'maxwell', 'tabular'])
check_type('source energy parameters', params, Iterable, Real)
if stype in ['monoenergetic', 'maxwell']:
check_length('source energy parameters for a monoenergetic '
'or Maxwell source', params, 1)
elif stype == 'watt':
check_length('source energy parameters for a Watt source',
params, 2)
elif stype == 'tabular':
check_type('source energy interpolation', interp, basestring)
check_value('source energy interpolation', interp,
['histogram', 'linear-linear'])
self._source_energy_interpolation = interp
self._source_energy_type = stype
self._source_energy_params = params
@source.setter
def source(self, source):
check_type('source distribution', source, Source)
self._source = source
@output.setter
def output(self, output):
@ -966,51 +780,8 @@ class SettingsFile(object):
subelement.text = str(self._keff_trigger[key]).lower()
def _create_source_subelement(self):
self._create_source_space_subelement()
self._create_source_energy_subelement()
self._create_source_angle_subelement()
def _create_source_space_subelement(self):
if self._source_space_params is not None:
if self._source_subelement is None:
self._source_subelement = ET.SubElement(self._settings_file,
"source")
element = ET.SubElement(self._source_subelement, "space")
element.set("type", self._source_space_type)
subelement = ET.SubElement(element, "parameters")
subelement.text = ' '.join(map(str, self._source_space_params))
def _create_source_angle_subelement(self):
if self._source_angle_params is not None:
if self._source_subelement is None:
self._source_subelement = ET.SubElement(self._settings_file,
"source")
element = ET.SubElement(self._source_subelement, "angle")
element.set("type", self._source_angle_type)
if self.source_angle_interpolation is not None:
element.set("interpolation", self.source_angle_interpolation)
subelement = ET.SubElement(element, "parameters")
subelement.text = ' '.join(map(str, self._source_angle_params))
def _create_source_energy_subelement(self):
if self._source_energy_params is not None:
if self._source_subelement is None:
self._source_subelement = ET.SubElement(self._settings_file,
"source")
element = ET.SubElement(self._source_subelement, "energy")
element.set("type", self._source_energy_type)
if self.source_energy_interpolation is not None:
element.set("interpolation", self.source_energy_interpolation)
subelement = ET.SubElement(element, "parameters")
subelement.text = ' '.join(map(str, self._source_energy_params))
if self.source is not None:
self._settings_file.append(self.source.to_xml())
def _create_output_subelement(self):
if self._output is not None:

101
openmc/source.py Normal file
View file

@ -0,0 +1,101 @@
import sys
from xml.etree import ElementTree as ET
from openmc.stats.univariate import Univariate
from openmc.stats.multivariate import UnitSphere, Spatial
import openmc.checkvalue as cv
if sys.version_info[0] >= 3:
basestring = str
class Source(object):
"""Distribution of phase space coordinates for source sites.
Parameters
----------
space : openmc.stats.Spatial, optional
Spatial distribution of source sites
angle : openmc.stats.UnitSphere, optional
Angular distribution of source sites
energy : openmc.stats.Univariate, optional
Energy distribution of source sites
filename : str, optional
Source file from which sites should be sampled
Attributes
----------
space : openmc.stats.Spatial or None
Spatial distribution of source sites
angle : openmc.stats.UnitSphere or None
Angular distribution of source sites
energy : openmc.stats.Univariate or None
Energy distribution of source sites
file : str or None
Source file from which sites should be sampled
"""
def __init__(self, space=None, angle=None, energy=None, filename=None):
self._space = None
self._angle = None
self._energy = None
self._probability = None
self._file = None
if space is not None:
self.space = space
if angle is not None:
self.angle = angle
if energy is not None:
self.energy = energy
if filename is not None:
self.file = filename
@property
def file(self):
return self._file
@property
def space(self):
return self._space
@property
def angle(self):
return self._angle
@property
def energy(self):
return self._energy
@file.setter
def file(self, filename):
cv.check_type('source file', filename, basestring)
self._file = filename
@space.setter
def space(self, space):
cv.check_type('spatial distribution', space, Spatial)
self._space = space
@angle.setter
def angle(self, angle):
cv.check_type('angular distribution', angle, UnitSphere)
self._angle = angle
@energy.setter
def energy(self, energy):
cv.check_type('energy distribution', energy, Univariate)
self._energy = energy
def to_xml(self):
element = ET.Element("source")
if self.file is not None:
element.set("file", self.file)
if self.space is not None:
element.append(self.space.to_xml())
if self.angle is not None:
element.append(self.angle.to_xml())
if self.energy is not None:
element.append(self.energy.to_xml())
return element

2
openmc/stats/__init__.py Normal file
View file

@ -0,0 +1,2 @@
from openmc.stats.univariate import *
from openmc.stats.multivariate import *

View file

@ -0,0 +1,409 @@
from abc import ABCMeta, abstractmethod
from collections import Iterable
from math import pi
from numbers import Real
import sys
from xml.etree import ElementTree as ET
import numpy as np
from numpy.linalg import norm
import openmc.checkvalue as cv
from openmc.stats.univariate import Univariate, Uniform
if sys.version_info[0] >= 3:
basestring = str
class UnitSphere(object):
"""Distribution of points on the unit sphere.
This abstract class is used for angular distributions, since a direction is
represented as a unit vector (i.e., vector on the unit sphere).
Parameters
----------
name : str
Name of the distribution
reference_uvw : Iterable of Real
Direction from which polar angle is measured
Attributes
----------
name : str
Name of the distribution
reference_uvw : Iterable of Real
Direction from which polar angle is measured
"""
__metaclass__ = ABCMeta
def __init__(self, name, reference_uvw=None):
self.name = name
self._reference_uvw = None
if reference_uvw is not None:
self.reference_uvw = reference_uvw
@property
def name(self):
return self._name
@property
def reference_uvw(self):
return self._reference_uvw
@name.setter
def name(self, name):
cv.check_type('name', name, basestring)
self._name = name
@reference_uvw.setter
def reference_uvw(self, uvw):
cv.check_type('reference direction', uvw, Iterable, Real)
uvw = np.asarray(uvw)
self._reference_uvw = uvw/norm(uvw)
@abstractmethod
def to_xml(self):
return ''
class PolarAzimuthal(UnitSphere):
"""Angular distribution represented by polar and azimuthal angles
This distribution allows one to specify the distribution of the cosine of
the polar angle and the azimuthal angle independently of once another.
Parameters
----------
mu : openmc.stats.Univariate
Distribution of the cosine of the polar angle
phi : openmc.stats.Univariate
Distribution of the azimuthal angle
name : str, optional
Name of the distribution. Defaults to 'angle'.
reference_uvw : Iterable of Real
Direction from which polar angle is measured. Defaults to the positive
z-direction.
Attributes
----------
mu : openmc.stats.Univariate
Distribution of the cosine of the polar angle
phi : openmc.stats.Univariate
Distribution of the azimuthal angle
"""
def __init__(self, mu=None, phi=None, name='angle',reference_uvw=[0., 0., 1.]):
super(PolarAzimuthal, self).__init__(name, reference_uvw)
if mu is not None:
self.mu = mu
else:
self.mu = Uniform('mu', -1., 1.)
if phi is not None:
self.phi = phi
else:
self.phi = Uniform('phi', 0., 2*pi)
@property
def mu(self):
return self._mu
@property
def phi(self):
return self._phi
@mu.setter
def mu(self, mu):
cv.check_type('cosine of polar angle', mu, Univariate)
self._mu = mu
@phi.setter
def phi(self, phi):
cv.check_type('azimuthal angle', phi, Univariate)
self._phi = phi
def to_xml(self):
element = ET.Element(self.name)
element.set("type", "mu-phi")
if self.reference_uvw is not None:
element.set("reference_uvw", ' '.join(map(str, self.reference_uvw)))
element.append(self.mu.to_xml())
element.append(self.phi.to_xml())
return element
class Isotropic(UnitSphere):
"""Isotropic angular distribution.
Parameters
----------
name : str, optional
Name of the distribution. Defaults to 'angle'.
"""
def __init__(self, name='angle'):
super(Isotropic, self).__init__(name)
def to_xml(self):
element = ET.Element(self.name)
element.set("type", "isotropic")
return element
class Monodirectional(UnitSphere):
"""Monodirectional angular distribution.
A monodirectional angular distribution is one for which the polar and
azimuthal angles are always the same. It is completely specified by the
reference direction vector.
Parameters
----------
name : str, optional
Name of the distribution. Defaults to 'angle'.
reference_uvw : Iterable of Real
Direction from which polar angle is measured. Defaults to the positive
x-direction.
"""
def __init__(self, name='angle', reference_uvw=[1., 0., 0.]):
super(Monodirectional, self).__init__(name, reference_uvw)
def to_xml(self):
element = ET.Element(self.name)
element.set("type", "monodirectional")
if self.reference_uvw is not None:
element.set("reference_uvw", ' '.join(map(str, self.reference_uvw)))
return element
class Spatial(object):
"""Distribution of locations in three-dimensional Euclidean space.
Classes derived from this abstract class can be used for spatial
distributions of source sites.
Parameters
----------
name : str
Name of the distribution
Attributes
----------
name : str
Name of the distribution
"""
__metaclass__ = ABCMeta
def __init__(self, name):
self.name = name
@property
def name(self):
return self._name
@name.setter
def name(self, name):
cv.check_type('name', name, basestring)
self._name = name
@abstractmethod
def to_xml(self):
return ''
class SpatialIndependent(Spatial):
"""Spatial distribution with independent x, y, and z distributions.
This distribution allows one to specify a coordinates whose x-, y-, and z-
components are sampled independently from one another.
Parameters
----------
x : openmc.stats.Univariate
Distribution of x-coordinates
y : openmc.stats.Univariate
Distribution of y-coordinates
z : openmc.stats.Univariate
Distribution of z-coordinates
name : str
Name of the distribution
Attributes
----------
x : openmc.stats.Univariate
Distribution of x-coordinates
y : openmc.stats.Univariate
Distribution of y-coordinates
z : openmc.stats.Univariate
Distribution of z-coordinates
"""
def __init__(self, x, y, z, name='space'):
super(SpatialIndependent, self).__init__(name)
self.x = x
self.y = y
self.z = z
@property
def x(self):
return self._x
@property
def y(self):
return self._y
@property
def z(self):
return self._z
@x.setter
def x(self, x):
cv.check_type('x coordinate', x, Univariate)
self._x = x
@y.setter
def y(self, y):
cv.check_type('y coordinate', y, Univariate)
self._y = y
@x.setter
def z(self, z):
cv.check_type('z coordinate', z, Univariate)
self._z = z
def to_xml(self):
element = ET.Element(self.name)
element.set("type", "independent")
element.append(self.x.to_xml())
element.append(self.y.to_xml())
element.append(self.z.to_xml())
return element
class SpatialBox(Spatial):
"""Uniform distribution of coordinates in a rectangular cuboid.
Parameters
----------
lower_left : Iterable of Real
Lower-left coordinates of cuboid
upper_right : Iterable of Real
Upper-right coordinates of cuboid
name : str, optional
Name of the distribution
only_fissionable : bool, optional
Whether spatial sites should only be accepted if they occur in
fissionable materials
Attributes
----------
lower_left : Iterable of Real
Lower-left coordinates of cuboid
upper_right : Iterable of Real
Upper-right coordinates of cuboid
only_fissionable : bool, optional
Whether spatial sites should only be accepted if they occur in
fissionable materials
"""
def __init__(self, lower_left, upper_right, name='space', only_fissionable=False):
super(SpatialBox, self).__init__(name)
self.lower_left = lower_left
self.upper_right = upper_right
self.only_fissionable = only_fissionable
@property
def lower_left(self):
return self._lower_left
@property
def upper_right(self):
return self._upper_right
@property
def only_fissionable(self):
return self._only_fissionable
@lower_left.setter
def lower_left(self, lower_left):
cv.check_type('lower left coordinate', lower_left, Iterable, Real)
cv.check_length('lower left coordinate', lower_left, 3)
self._lower_left = lower_left
@upper_right.setter
def upper_right(self, upper_right):
cv.check_type('upper right coordinate', upper_right, Iterable, Real)
cv.check_length('upper right coordinate', upper_right, 3)
self._upper_right = upper_right
@only_fissionable.setter
def only_fissionable(self, only_fissionable):
cv.check_type('only fissionable', only_fissionable, bool)
self._only_fissionable = only_fissionable
def to_xml(self):
element = ET.Element(self.name)
if self.only_fissionable:
element.set("type", "fission")
else:
element.set("type", "box")
params = ET.SubElement(element, "parameters")
params.text = ' '.join(map(str, self.lower_left)) + ' ' + \
' '.join(map(str, self.upper_right))
return element
class SpatialPoint(Spatial):
"""Delta function in three dimensions.
This spatial distribution can be used for a point source where sites are
emitted at a specific location given by its Cartesian coordinates.
Parameters
----------
xyz : Iterable of Real
Cartesian coordinates of location
name : str, optional
Name of the distribution
Attributes
----------
xyz : Iterable of Real
Cartesian coordinates of location
"""
def __init__(self, xyz, name='space'):
super(SpatialPoint, self).__init__(name)
self.xyz = xyz
@property
def xyz(self):
return self._xyz
@xyz.setter
def xyz(self, xyz):
cv.check_type('coordinate', xyz, Iterable, Real)
cv.check_length('coordinate', xyz, 3)
self._xyz = xyz
def to_xml(self):
element = ET.Element(self.name)
element.set("type", "point")
params = ET.SubElement(element, "parameters")
params.text = ' '.join(map(str, self.xyz))
return element

325
openmc/stats/univariate.py Normal file
View file

@ -0,0 +1,325 @@
from abc import ABCMeta, abstractmethod
from collections import Iterable
from numbers import Real
from xml.etree import ElementTree as ET
import openmc.checkvalue as cv
class Univariate(object):
"""Probability distribution of a single random variable.
The Univariate class is an abstract class that can be derived to implement a
specific probability distribution.
Parameters
----------
name : str
Name of the distribution
Attributes
----------
name : str
Name of the distributions
"""
__metaclass__ = ABCMeta
def __init__(self, name):
self.name = name
@property
def name(self):
return self._name
@name.setter
def name(self, name):
cv.check_type('name', name, basestring)
self._name = name
@abstractmethod
def to_xml(self):
return ''
class Discrete(Univariate):
"""Distribution characterized by a probability mass function.
The Discrete distribution assigns probability values to discrete values of a
random variable, rather than expressing the distribution as a continuous
random variable.
Parameters
----------
x : Iterable of Real
Values of the random variable
p : Iterable of Real
Discrete probability for each value
Attributes
----------
x : Iterable of Real
Values of the random variable
p : Iterable of Real
Discrete probability for each value
"""
def __init__(self, name, x, p):
super(Discrete, self).__init__(name)
self.x = x
self.p = p
@property
def x(self):
return self._x
@property
def p(self):
return self._p
@x.setter
def x(self, x):
cv.check_type('discrete values', x, Iterable, Real)
self._x = x
@p.setter
def p(self, p):
cv.check_type('discrete probabilities', p, Iterable, Real)
for pk in p:
cv.check_greater_than('discrete probability', pk, 0.0, True)
self._p = p
def to_xml(self):
element = ET.Element(self.name)
element.set("type", "discrete")
params = ET.SubElement(element, "parameters")
params.text = ' '.join(map(str, self.x)) + ' ' + ' '.join(map(str, self.p))
return element
class Uniform(Univariate):
"""Distribution with constant probability over a finite interval [a,b]
Parameters
----------
a : float, optional
Lower bound of the sampling interval. Defaults to zero.
b : float, optional
Upper bound of the sampling interval. Defaults to unity.
Attributes
----------
a : float
Lower bound of the sampling interval
b : float
Upper bound of the sampling interval
"""
def __init__(self, name, a=0.0, b=1.0):
super(Uniform, self).__init__(name)
self.a = a
self.b = b
@property
def a(self):
return self._a
@property
def b(self):
return self._b
@a.setter
def a(self, a):
cv.check_type('Uniform a', a, Real)
self._a = a
@b.setter
def b(self, b):
cv.check_type('Uniform b', b, Real)
self._b = b
def to_xml(self):
element = ET.Element(self.name)
element.set("type", "uniform")
element.set("parameters", '{} {}'.format(self.a, self.b))
return element
class Maxwell(Univariate):
"""Maxwellian distribution in energy.
The Maxwellian distribution in energy is characterized by a single parameter
:math:`\theta` and has a density function :math:`p(E) dE = c E e^{-E/\theta}
dE`.
Parameters
----------
theta : float
Effective temperature for distribution
Attributes
----------
theta : float
Effective temperature for distribution
"""
def __init__(self, theta, name='energy'):
super(Maxwell, self).__init__(name)
self.theta = theta
@property
def theta(self):
return self._theta
@theta.setter
def theta(self, theta):
cv.check_type('Maxwell temperature', theta, Real)
cv.check_greater_than('Maxwell temperature', theta, 0.0)
self._theta = theta
def to_xml(self):
element = ET.Element(self.name)
element.set("type", "uniform")
element.set("parameters", str(self.theta))
return element
class Watt(Univariate):
"""Watt fission energy spectrum.
The Watt fission energy spectrum is characterized by two parameters
:math:`a` and :math:`b` and has density function :math:`p(E) dE = c e^{-E/a}
\sinh \sqrt{b \, E} dE`.
Parameters
----------
a : float
First parameter of distribution
b : float
Second parameter of distribution
name : str, optional
Name of the distribution. Defaults to 'energy'.
Attributes
----------
a : float
First parameter of distribution
b : float
Second parameter of distribution
"""
def __init__(self, a, b, name='energy'):
super(Watt, self).__init__(name)
self.a = a
self.b = b
@property
def a(self):
return self._a
@property
def b(self):
return self._b
@a.setter
def a(self, a):
cv.check_type('Watt a', a, Real)
cv.check_greater_than('Watt a', a, 0.0)
self._a = a
@b.setter
def b(self, b):
cv.check_type('Watt b', b, Real)
cv.check_greater_than('Watt b', b, 0.0)
self._b = b
def to_xml(self):
element = ET.Element(self.name)
element.set("type", "watt")
element.set("parameters", '{} {}'.format(self.a, self.b))
return element
class Tabular(Univariate):
"""Piecewise continuous probability distribution.
This class is used to represent a probability distribution whose density
function is tabulated at specific values and is either histogram or linearly
interpolated between points.
Parameters
----------
name : str
Name of the distribution
x : Iterable of Real
Tabulated values of the random variable
p : Iterable of Real
Tabulated probabilities
interpolation : {'histogram', 'linear-linear'}, optional
Indicate whether the density function is constant between tabulated
points or linearly-interpolated.
Attributes
----------
x : Iterable of Real
Tabulated values of the random variable
p : Iterable of Real
Tabulated probabilities
interpolation : {'histogram', 'linear-linear'}, optional
Indicate whether the density function is constant between tabulated
points or linearly-interpolated.
"""
def __init__(self, name, x, p, interpolation='linear-linear'):
super(Tabular, self).__init__(name)
self.x = x
self.p = p
self.interpolation = interpolation
@property
def x(self):
return self._x
@property
def p(self):
return self._p
@property
def interpolation(self):
return self._interpolation
@x.setter
def x(self, x):
cv.check_type('tabulated values', x, Iterable, Real)
self._x = x
@p.setter
def p(self, p):
cv.check_type('tabulated probabilities', p, Iterable, Real)
for pk in p:
cv.check_greater_than('tabulated probability', pk, 0.0, True)
self._p = p
@interpolation.setter
def interpolation(self, interpolation):
cv.check_value('interpolation', interpolation,
['linear-linear', 'histogram'])
self._interpolation = interpolation
def to_xml(self):
element = ET.Element(self.name)
element.set("type", "tabular")
element.set("interpolation", self.interpolation)
params = ET.SubElement(element, "parameters")
params.text = ' '.join(map(str, self.x)) + ' ' + ' '.join(map(str, self.p))
return element

View file

@ -11,7 +11,7 @@ except ImportError:
kwargs = {'name': 'openmc',
'version': '0.7.1',
'packages': ['openmc', 'openmc.mgxs'],
'packages': ['openmc', 'openmc.mgxs', 'openmc.stats'],
'scripts': glob.glob('scripts/openmc-*'),
# Metadata

View file

@ -1,4 +1,6 @@
import openmc
from openmc.source import Source
from openmc.stats import SpatialBox
class InputSet(object):
@ -558,7 +560,8 @@ class InputSet(object):
self.settings.batches = 10
self.settings.inactive = 5
self.settings.particles = 100
self.settings.set_source_space('box', (-160, -160, -183, 160, 160, 183))
self.settings.source = Source(space=SpatialBox(
[-160, -160, -183], [160, 160, 183]))
def build_defualt_plots(self):
plot = openmc.Plot()