Simplifications as per comments from @wbinventor and @paulromano. Next is updating notebook

This commit is contained in:
Adam Nelson 2016-05-11 21:19:30 -04:00
parent 3079b5f6df
commit 98a02d5d50
2 changed files with 620 additions and 423 deletions

View file

@ -15,14 +15,9 @@ import openmc.checkvalue as cv
if sys.version_info[0] >= 3:
basestring = str
# The following represent the most accurate MGXS generation strategy
# for use in the MG mode of OpenMC.
OPENMC_MG_MGXS_TYPES = ['transport', 'absorption', 'nu-fission', 'chi',
'scatter matrix', 'nu-scatter matrix']
class Library(object):
"""A multi-group cross section library for some energy group structure.
'''A multi-group cross section library for some energy group structure.
This class can be used for both OpenMC input generation and tally data
post-processing to compute spatially-homogenized and energy-integrated
@ -84,7 +79,7 @@ class Library(object):
Whether or not the Library's tallies use SciPy's LIL sparse matrix
format for compressed data storage
"""
'''
def __init__(self, openmc_geometry, by_nuclide=False,
mgxs_types=None, name=''):
@ -252,7 +247,8 @@ class Library(object):
@domain_type.setter
def domain_type(self, domain_type):
cv.check_value('domain type', domain_type, tuple(openmc.mgxs.DOMAIN_TYPES))
cv.check_value('domain type', domain_type,
tuple(openmc.mgxs.DOMAIN_TYPES))
self._domain_type = domain_type
@domains.setter
@ -304,7 +300,7 @@ class Library(object):
@sparse.setter
def sparse(self, sparse):
"""Convert tally data from NumPy arrays to SciPy list of lists (LIL)
'''Convert tally data from NumPy arrays to SciPy list of lists (LIL)
sparse matrices, and vice versa.
This property may be used to reduce the amount of data in memory during
@ -312,7 +308,7 @@ class Library(object):
matrices internally within the Tally object. All tally data access
properties and methods will return data as a dense NumPy array.
"""
'''
cv.check_type('sparse', sparse, bool)
@ -325,14 +321,14 @@ class Library(object):
self._sparse = sparse
def build_library(self):
"""Initialize MGXS objects in each domain and for each reaction type
'''Initialize MGXS objects in each domain and for each reaction type
in the library.
This routine will populate the all_mgxs instance attribute dictionary
with MGXS subclass objects keyed by each domain ID (e.g., Material IDs)
and cross section type (e.g., 'nu-fission', 'total', etc.).
"""
'''
# Initialize MGXS for each domain and mgxs type and store in dictionary
for domain in self.domains:
@ -355,7 +351,7 @@ class Library(object):
self.all_mgxs[domain.id][mgxs_type] = mgxs
def add_to_tallies_file(self, tallies_file, merge=True):
"""Add all tallies from all MGXS objects to a tallies file.
'''Add all tallies from all MGXS objects to a tallies file.
NOTE: This assumes that :meth:`Library.build_library` has been called
@ -363,12 +359,12 @@ class Library(object):
----------
tallies_file : openmc.Tallies
A Tallies collection to add each MGXS' tallies to generate a
"tallies.xml" input file for OpenMC
'tallies.xml' input file for OpenMC
merge : bool
Indicate whether tallies should be merged when possible. Defaults
to True.
"""
'''
cv.check_type('tallies_file', tallies_file, openmc.Tallies)
@ -380,7 +376,7 @@ class Library(object):
tallies_file.append(tally, merge=merge)
def load_from_statepoint(self, statepoint):
"""Extracts tallies in an OpenMC StatePoint with the data needed to
'''Extracts tallies in an OpenMC StatePoint with the data needed to
compute multi-group cross sections.
This method is needed to compute cross section data from tallies
@ -399,7 +395,7 @@ class Library(object):
When this method is called with a statepoint that has not been
linked with a summary object.
"""
'''
cv.check_type('statepoint', statepoint, openmc.StatePoint)
@ -423,7 +419,7 @@ class Library(object):
mgxs.sparse = self.sparse
def get_mgxs(self, domain, mgxs_type):
"""Return the MGXS object for some domain and reaction rate type.
'''Return the MGXS object for some domain and reaction rate type.
This routine searches the library for an MGXS object for the spatial
domain and reaction rate type requested by the user.
@ -448,7 +444,7 @@ class Library(object):
If no MGXS object can be found for the requested domain or
multi-group cross section type
"""
'''
if self.domain_type == 'material':
cv.check_type('domain', domain, (openmc.Material, Integral))
@ -464,7 +460,7 @@ class Library(object):
if domain_id == domain.id:
break
else:
msg = 'Unable to find MGXS for {0} "{1}" in ' \
msg = 'Unable to find MGXS for "{0}" "{1}" in ' \
'library'.format(self.domain_type, domain_id)
raise ValueError(msg)
else:
@ -478,7 +474,7 @@ class Library(object):
return self.all_mgxs[domain_id][mgxs_type]
def get_condensed_library(self, coarse_groups):
"""Construct an energy-condensed version of this library.
'''Construct an energy-condensed version of this library.
This routine condenses each of the multi-group cross sections in the
library to a coarse energy group structure. NOTE: This routine must
@ -505,7 +501,7 @@ class Library(object):
--------
MGXS.get_condensed_xs(coarse_groups)
"""
'''
if self.sp_filename is None:
msg = 'Unable to get a condensed coarse group cross section ' \
@ -534,7 +530,7 @@ class Library(object):
return condensed_library
def get_subdomain_avg_library(self):
"""Construct a subdomain-averaged version of this library.
'''Construct a subdomain-averaged version of this library.
This routine averages each multi-group cross section across distribcell
instances. The method performs spatial homogenization to compute the
@ -557,7 +553,7 @@ class Library(object):
--------
MGXS.get_subdomain_avg_xs(subdomains)
"""
'''
if self.sp_filename is None:
msg = 'Unable to get a subdomain-averaged cross section ' \
@ -585,7 +581,7 @@ class Library(object):
def build_hdf5_store(self, filename='mgxs.h5', directory='mgxs',
subdomains='all', nuclides='all', xs_type='macro',
row_column='inout'):
"""Export the multi-group cross section library to an HDF5 binary file.
'''Export the multi-group cross section library to an HDF5 binary file.
This method constructs an HDF5 file which stores the library's
multi-group cross section data. The data is stored in a hierarchy of
@ -628,7 +624,7 @@ class Library(object):
--------
MGXS.build_hdf5_store(filename, directory, xs_type)
"""
'''
if self.sp_filename is None:
msg = 'Unable to export multi-group cross section library ' \
@ -648,7 +644,7 @@ class Library(object):
full_filename = os.path.join(directory, filename)
full_filename = full_filename.replace(' ', '-')
f = h5py.File(full_filename, 'w')
f.attrs["# groups"] = self.num_groups
f.attrs['# groups'] = self.num_groups
f.close()
# Export MGXS for each domain and mgxs type to an HDF5 file
@ -663,7 +659,7 @@ class Library(object):
nuclides=nuclides, row_column=row_column)
def dump_to_file(self, filename='mgxs', directory='mgxs'):
"""Store this Library object in a pickle binary file.
'''Store this Library object in a pickle binary file.
Parameters
----------
@ -676,7 +672,7 @@ class Library(object):
--------
Library.load_from_file(filename, directory)
"""
'''
cv.check_type('filename', filename, basestring)
cv.check_type('directory', directory, basestring)
@ -693,7 +689,7 @@ class Library(object):
@staticmethod
def load_from_file(filename='mgxs', directory='mgxs'):
"""Load a Library object from a pickle binary file.
'''Load a Library object from a pickle binary file.
Parameters
----------
@ -711,7 +707,7 @@ class Library(object):
--------
Library.dump_to_file(mgxs_lib, filename, directory)
"""
'''
cv.check_type('filename', filename, basestring)
cv.check_type('directory', directory, basestring)
@ -729,7 +725,7 @@ class Library(object):
def write_mg_library(self, xs_type='macro', domain_names=None, xs_ids=None,
filename='mg_cross_sections', directory='./',
return_names=True):
"""Creates a cross-section data library file for the Multi-Group
'''Creates a cross-section data library file for the Multi-Group
mode of OpenMC.
Parameters
@ -740,11 +736,11 @@ class Library(object):
nuclide this will be set to 'macro' regardless.
domain_names : Iterable of str
List of names to apply to the xsdata entries in the
resultant mgxs data file. Defaults to "set1", "set2", ...
resultant mgxs data file. Defaults to 'set1', 'set2', ...
xs_ids : str or Iterable of str
Cross section set identifier (i.e., "71c") for all
Cross section set identifier (i.e., '71c') for all
data sets (if only str) or for each individual one
(if iterable of str). Defaults to '1g'
(if iterable of str). Defaults to '1m'.
filename : str
Filename for the pickle file. Defaults to 'mg_cross_sections'.
directory : str
@ -772,7 +768,11 @@ class Library(object):
--------
Library.dump_to_file(mgxs_lib, filename, directory)
"""
'''
# Check to ensure the Library contains the correct
# multi-group cross section types
self.check_library_for_openmc_mgxs()
# Check the provided parameters
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
@ -786,14 +786,18 @@ class Library(object):
else:
cv.check_iterable_type('xs_ids', xs_ids, basestring)
else:
xs_ids = ['1g' for i in range(len(self.domains))]
xs_ids = ['1m' for i in range(len(self.domains))]
cv.check_type('filename', filename, basestring)
cv.check_type('directory', directory, basestring)
# Make sure statepoint has been loaded
if self._sp_filename is None:
msg = 'A StatePoint must be loaded before calling ' \
'the write_mg_library() function'
raise ValueError(msg)
# Construct the collection of the nuclides to report
if self.by_nuclide:
nuclides = self.all_mgxs[1][self.mgxs_types[-1]].get_all_nuclides()
else:
if not self.by_nuclide:
xs_type = 'macro'
# Make directory if it does not exist and build our filename
@ -813,213 +817,98 @@ class Library(object):
xsdatas = []
mat_names = {}
for i in range(len(self.domains)):
for i, domain in enumerate(self.domains):
id = self.domains[i].id
if not self.by_nuclide:
mat_names[domain.id] = {}
if self.by_nuclide:
nuclides = list(domain.get_all_nuclides().keys())
else:
nuclides = ['total']
for nuclide in nuclides:
# Build & add metadata to XSdata object
# (Use i here because k in nuclides will add chars to this)
if domain_names is None:
name = 'set' + str(i + 1)
else:
name = domain_names[i]
if nuclide is not 'total':
name += '_' + nuclide
name += '.' + xs_ids[i]
# Store the name
mat_names[domain.id][nuclide] = name
xsdata = openmc.XSdata(name, self.energy_groups)
xsdata.order = order
if nuclide is not 'total':
xsdata.zaid = self._nuclides[nuclide][0]
xsdata.awr = self._nuclides[nuclide][1]
mat_names[id] = name
nuclide = [nuclide]
# Now get xs data itself
if 'transport' in self.mgxs_types:
if self.correction == 'P0':
xsdata.set_total(self.all_mgxs[id]['transport'],
xs_type=xs_type, subdomains=(id,))
else:
msg = "The use of a transport cross section " + \
"requires the correction attribute to be" + \
"set to 'P0' to produce valid cross " + \
"section libraries"
raise ValueError(msg)
mymgxs = self.get_mgxs(domain, 'transport')
xsdata.set_total_mgxs(mymgxs, xs_type=xs_type,
nuclide=nuclide)
elif 'total' in self.mgxs_types:
xsdata.set_total(self.all_mgxs[id]['total'],
xs_type=xs_type, subdomains=(id,))
mymgxs = self.get_mgxs(domain, 'total')
xsdata.set_total_mgxs(mymgxs, xs_type=xs_type,
nuclide=nuclide)
if 'absorption' in self.mgxs_types:
xsdata.set_absorption(self.all_mgxs[id]['absorption'],
xs_type=xs_type,
subdomains=(id,))
mymgxs = self.get_mgxs(domain, 'absorption')
xsdata.set_absorption_mgxs(mymgxs, xs_type=xs_type,
nuclide=nuclide)
if 'fission' in self.mgxs_types:
xsdata.set_fission(self.all_mgxs[id]['fission'],
xs_type=xs_type, subdomains=(id,))
mymgxs = self.get_mgxs(domain, 'fission')
xsdata.set_fission_mgxs(mymgxs, xs_type=xs_type,
nuclide=nuclide)
if 'kappa-fission' in self.mgxs_types:
xsdata.set_k_fission(self.all_mgxs[id]['kappa-fission'],
xs_type=xs_type, subdomains=(id,))
mymgxs = self.get_mgxs(domain, 'kappa-fission')
xsdata.set_kappa_fission_mgxs(mymgxs, xs_type=xs_type,
nuclide=nuclide)
if 'chi' in self.mgxs_types:
xsdata.set_chi(self.all_mgxs[id]['chi'],
xs_type=xs_type, subdomains=(id,))
mymgxs = self.get_mgxs(domain, 'chi')
xsdata.set_chi_mgxs(mymgxs, xs_type=xs_type,
nuclide=nuclide)
if 'nu-fission' in self.mgxs_types:
xsdata.set_nu_fission(self.all_mgxs[id]['nu-fission'],
xs_type=xs_type,
subdomains=(id,))
mymgxs = self.get_mgxs(domain, 'nu-fission')
xsdata.set_nu_fission_mgxs(mymgxs, xs_type=xs_type,
nuclide=nuclide)
# multiplicity requires scatter and nu-scatter
if ((('scatter matrix' in self.mgxs_types) and
('nu-scatter matrix' in self.mgxs_types))):
xsdata.set_multiplicity(
self.all_mgxs[id]['nu-scatter matrix'],
self.all_mgxs[id]['scatter matrix'],
xs_type=xs_type, subdomains=(id,))
xsdata.multiplicity = np.nan_to_num(xsdata.multiplicity)
scatt_mgxs = self.get_mgxs(domain,
'scatter matrix')
nuscatt_mgxs = self.get_mgxs(domain,
'nu-scatter matrix')
xsdata.set_multiplicity_mgxs(nuscatt_mgxs, scatt_mgxs,
xs_type=xs_type,
nuclide=nuclide)
using_multiplicity = True
else:
using_multiplicity = False
if using_multiplicity:
xsdata.set_scatter(self.all_mgxs[id]['nu-scatter matrix'],
xs_type=xs_type,
subdomains=(id,))
nuscatt_mgxs = self.get_mgxs(domain,
'nu-scatter matrix')
xsdata.set_scatter_mgxs(nuscatt_mgxs, xs_type=xs_type,
nuclide=nuclide)
else:
if 'nu-scatter matrix' in self.mgxs_types:
xsdata.set_scatter(
self.all_mgxs[id]['nu-scatter matrix'],
xs_type=xs_type, subdomains=(id,))
nuscatt_mgxs = self.get_mgxs(domain,
'nu-scatter matrix')
xsdata.set_scatter_mgxs(nuscatt_mgxs, xs_type=xs_type,
nuclide=nuclide)
# Since we are not using multiplicity, then
# scattering multiplication (nu-scatter) must be
# accounted for approximately by using an adjusted
# absorption cross section.
# We can not do this with a transport x/s so check
# for that.
if 'total' in self.mgxs_types:
xsdata.absorption = \
np.subtract(xsdata.total,
np.sum(xsdata.scatter[0, :, :],
axis=1))
else:
msg = "Absorption cross section must be " + \
"provided if using a transport cross" + \
" section and while not providing a " + \
"scattering matrix"
raise ValueError(msg)
else:
msg = "No nu-scatter matrix data was provided. " + \
"This means neutron balance cannot be " + \
"achieved since (n,xn) multiplication is " + \
"ignored."
warn(msg)
xsdata.set_scatter(self.all_mgxs[id]['scatter matrix'],
xs_type=xs_type,
subdomains=(id,))
xsdatas.append(xsdata)
else:
mat_names[id] = {}
for nuclide in nuclides:
# Build & add metadata to XSdata object
if domain_names is None:
name = 'set' + str(i + 1)
else:
name = domain_names[i]
name += '_' + nuclide
name += '.' + xs_ids[i]
mat_names[id][nuclide] = name
xsdata = openmc.XSdata(name, self.energy_groups)
xsdata.order = order
xsdata.zaid = self._nuclides[nuclide][0]
xsdata.awr = self._nuclides[nuclide][1]
# Now get xs data itself
if 'transport' in self.mgxs_types:
if self.correction == 'P0':
xsdata.set_total(self.all_mgxs[id]['transport'],
xs_type=xs_type, subdomains=(id,),
nuclides=[nuclide])
else:
msg = "The use of a transport cross section " + \
"requires the correction attribute to be" + \
"set to 'P0' to produce valid cross " + \
"section libraries"
raise ValueError(msg)
elif 'total' in self.mgxs_types:
xsdata.set_total(self.all_mgxs[id]['total'],
xs_type=xs_type, subdomains=(id,),
nuclides=[nuclide])
if 'absorption' in self.mgxs_types:
xsdata.set_absorption(self.all_mgxs[id]['absorption'],
xs_type=xs_type,
subdomains=(id,),
nuclides=[nuclide])
if 'fission' in self.mgxs_types:
xsdata.set_fission(self.all_mgxs[id]['fission'],
xs_type=xs_type,
subdomains=(id,),
nuclides=[nuclide])
if 'kappa-fission' in self.mgxs_types:
xsdata.set_k_fission(
self.all_mgxs[id]['kappa-fission'],
xs_type=xs_type, subdomains=(id,),
nuclides=[nuclide])
if 'chi' in self.mgxs_types:
xsdata.set_chi(self.all_mgxs[id]['chi'],
xs_type=xs_type, subdomains=(id,),
nuclides=[nuclide])
if 'nu-fission' in self.mgxs_types:
xsdata.set_nu_fission(self.all_mgxs[id]['nu-fission'],
xs_type=xs_type,
subdomains=(id,),
nuclides=[nuclide])
# multiplicity requires scatter and nu-scatter
if ((('scatter matrix' in self.mgxs_types) and
('nu-scatter matrix' in self.mgxs_types))):
xsdata.set_multiplicity(
self.all_mgxs[id]['nu-scatter matrix'],
self.all_mgxs[id]['scatter matrix'],
xs_type=xs_type, subdomains=(id,),
nuclides=[nuclide])
xsdata.multiplicity = \
np.nan_to_num(xsdata.multiplicity)
using_multiplicity = True
else:
using_multiplicity = False
if using_multiplicity:
xsdata.set_scatter(
self.all_mgxs[id]['nu-scatter matrix'],
xs_type=xs_type, subdomains=(id,),
nuclides=[nuclide])
else:
if 'nu-scatter matrix' in self.mgxs_types:
xsdata.set_scatter(
self.all_mgxs[id]['nu-scatter matrix'],
xs_type=xs_type, subdomains=(id,),
nuclides=[nuclide])
# Since we are not using multiplicity, then
# scattering multiplication (nu-scatter) must be
# accounted for approximately by using an adjusted
# absorption cross section.
if 'total' in self.mgxs_types:
xsdata.absorption = \
np.subtract(xsdata.total,
np.sum(xsdata.scatter[0, :, :],
axis=1))
else:
msg = "Absorption cross section must be " + \
"provided if using a transport cross" + \
" section and while not providing a " + \
"scattering matrix"
raise ValueError(msg)
else:
msg = "No nu-scatter matrix data was provided. " +\
"This means neutron balance cannot be " + \
"achieved since (n,xn) multiplication is " +\
"ignored."
warn(msg)
xsdata.set_scatter(
self.all_mgxs[id]['scatter matrix'],
xs_type=xs_type,
subdomains=(id,),
nuclides=[nuclide])
xsdatas.append(xsdata)
# Add XSdatas to file
mgxs_file.add_xsdatas(xsdatas)
@ -1029,3 +918,68 @@ class Library(object):
if return_names:
return mat_names
def check_library_for_openmc_mgxs(self):
"""This routine will check the MGXS Types within the provided
Library to ensure the data types provided can be used to create
a MGXS Library for OpenMC's Multi-Group mode via the
`Library.write_mg_library` method.
The rules to check include:
- Fission is not required as a fixed source problem could be
the target.
- Absorption is required.
- A nu-scatter matrix is required.
- Having both nu-scatter (of any order) and scatter
(at least isotropic) matrices is preferred
- If only nu-scatter, need total (not transport), to
be used in adjusting absorption
(i.e., reduced_abs = tot - nuscatt)
- Either total or transport should be present.
- Both can be available if one wants, but we should
use whatever corresponds to Library.correction (if P0: transport)
Raises
------
ValueError
When the Library object is initialized with insufficient types of
cross sections for the Library.
See also
--------
Library.write_mg_library(...)
"""
error_flag = False
# Ensure absorption is present
if 'absorption' not in self.mgxs_types:
error_flag = True
msg = 'Absorption MGXS type is required but not provided.'
warn(msg)
# Ensure nu-scattering matrix is required
if 'nu-scatter matrix' not in self.mgxs_types:
error_flag = True
msg = 'Nu-Scatter Matrix MGXS type is required but not provided.'
warn(msg)
else:
# Ok, now see the status of scatter
if 'scatter matrix' not in self.mgxs_types:
# We dont have both nu-scatter and scatter, therefore
# we need total, and not transport.
if 'total' not in self.mgxs_types:
error_flag = True
msg = 'Total MGXS type is required if a ' \
'scattering matrix is not provided.'
warn(msg)
# Total or transport can be present, but if using
# self.correction=="P0", then we should use transport.
if (((self.correction is "P0") and
('transport' not in self.mgxs_types))):
error_flag = True
msg = 'Transport MGXS type is required since a "P0" correction ' \
'is applied, but a Transport MGXS is not provided.'
warn(msg)
if error_flag:
msg = "Invalid MGXS configuration encountered."
raise ValueError(msg)

View file

@ -122,12 +122,23 @@ class XSdata(object):
Legendre polynomial form). Dict contains two keys: 'enable' and
'num_points'. 'enable' is a boolean and 'num_points' is the
number of points to use, if 'enable' is True.
representation : {'isotropic', 'angle'}
Method used in generating the MGXS (isotropic or angle-dependent flux
weighting).
num_azimuthal : int
Number of equal width angular bins that the azimuthal angular domain is
subdivided into. This only applies when ``representation`` is "angle".
num_polar : int
Number of equal width angular bins that the polar angular domain is
subdivided into. This only applies when ``representation`` is "angle".
vector_shape : iterable of int
Dimensionality of vector multi-group cross sections (e.g., the total
cross section). The return result depends on the value of
``representation``.
matrix_shape : iterable of int
Dimensionality of matrix multi-group cross sections (e.g., the
scattering matrix cross section). The return result depends on the
value of ``representation``.
total : numpy.ndarray
Group-wise total cross section ordered by increasing group index (i.e.,
fast to thermal). If ``representation`` is "isotropic", then the length
@ -173,7 +184,7 @@ class XSdata(object):
azimuthal angles times the number of polar angles, with the
inner-dimension being groups, intermediate-dimension being azimuthal
angles and outer-dimension being the polar angles.
k_fission : numpy.ndarray
kappa_fission : numpy.ndarray
Group-wise kappa-fission cross section ordered by increasing group
index (i.e., fast to thermal). If ``representation`` is "isotropic",
then the length of this list should equal the number of groups in the
@ -225,7 +236,7 @@ class XSdata(object):
self._multiplicity = None
self._fission = None
self._nu_fission = None
self._k_fission = None
self._kappa_fission = None
self._chi = None
self._use_chi = None
@ -302,8 +313,8 @@ class XSdata(object):
return self._nu_fission
@property
def k_fission(self):
return self._k_fission
def kappa_fission(self):
return self._kappa_fission
@property
def chi(self):
@ -317,6 +328,24 @@ class XSdata(object):
else:
return self._order
@property
def vector_shape(self):
if self.representation is 'isotropic':
return (self.energy_groups.num_groups,)
elif self.representation is 'angle':
return (self.num_polar, self.num_azimuthal,
self.energy_groups.num_groups)
@property
def matrix_shape(self):
if self.representation is 'isotropic':
return (self.energy_groups.num_groups,
self.energy_groups.num_groups)
elif self.representation is 'angle':
return (self.num_polar, self.num_azimuthal,
self.energy_groups.num_groups,
self.energy_groups.num_groups)
@name.setter
def name(self, name):
check_type('name for XSdata', name, basestring)
@ -326,6 +355,11 @@ class XSdata(object):
def energy_groups(self, energy_groups):
# Check validity of energy_groups
check_type('energy_groups', energy_groups, openmc.mgxs.EnergyGroups)
if energy_group.group_edges is None:
msg = 'Unable to assign an EnergyGroups object ' + \
'with uninitialized group edges'
raise ValueError(msg)
self._energy_groups = energy_groups
@representation.setter
@ -414,141 +448,196 @@ class XSdata(object):
@total.setter
def total(self, total):
if self._representation is 'isotropic':
shape = (self._energy_groups.num_groups,)
elif self._representation is 'angle':
shape = (self._num_polar, self._num_azimuthal,
self._energy_groups.num_groups)
"""This method sets the total cross section by performing a
deep-copy of the provided ndarray.
Parameters
----------
total: ndarray
Array of group-wise cross sections to apply
Raises
------
ValueError
When invalid parameters are passed.
"""
# check we have a numpy list
check_type('total', total, np.ndarray, expected_iter_type=Real)
if total.shape == shape:
self._total = np.copy(total)
else:
msg = 'Shape of provided total "{0}" does not match shape ' \
'required, "{1}"'.format(total.shape, shape)
raise ValueError(msg)
# Check the dimensions of the data
check_value('total shape', total.shape, self.vector_shape)
self._total = np.copy(total)
@absorption.setter
def absorption(self, absorption):
if self._representation is 'isotropic':
shape = (self._energy_groups.num_groups,)
elif self._representation is 'angle':
shape = (self._num_polar, self._num_azimuthal,
self._energy_groups.num_groups)
"""This method sets the absorption cross section by performing a
deep-copy of the provided ndarray.
Parameters
----------
absorption: ndarray
Array of group-wise cross sections to apply
Raises
------
ValueError
When invalid parameters are passed.
"""
# check we have a numpy list
check_type('absorption', absorption, np.ndarray,
expected_iter_type=Real)
if absorption.shape == shape:
self._absorption = np.copy(absorption)
else:
msg = 'Shape of provided absorption "{0}" does not match shape ' \
'required, "{1}"'.format(absorption.shape, shape)
raise ValueError(msg)
# Check the dimensions of the data
check_value('absorption shape', absorption.shape, self.vector_shape)
self._absorption = np.copy(absorption)
@fission.setter
def fission(self, fission):
if self._representation is 'isotropic':
shape = (self._energy_groups.num_groups,)
elif self._representation is 'angle':
shape = (self._num_polar, self._num_azimuthal,
self._energy_groups.num_groups)
# check we have a numpy list
check_type('fission', fission, np.ndarray, expected_iter_type=Real)
if fission.shape == shape:
self._fission = np.copy(fission)
if np.sum(self._fission) > 0.0:
self._fissionable = True
else:
msg = 'Shape of provided fission "{0}" does not match shape ' \
'required, "{1}"'.format(fission.shape, shape)
raise ValueError(msg)
"""This method sets the fission cross section by performing a
deep-copy of the provided ndarray.
@k_fission.setter
def k_fission(self, k_fission):
if self._representation is 'isotropic':
shape = (self._energy_groups.num_groups,)
elif self._representation is 'angle':
shape = (self._num_polar, self._num_azimuthal,
self._energy_groups.num_groups)
Parameters
----------
fission: ndarray
Array of group-wise cross sections to apply
Raises
------
ValueError
When invalid parameters are passed.
"""
# check we have a numpy list
check_type('k_fission', k_fission, np.ndarray,
check_type('fission', fission, np.ndarray,
expected_iter_type=Real)
if k_fission.shape == shape:
self._k_fission = np.copy(k_fission)
if np.sum(self._k_fission) > 0.0:
self._fissionable = True
else:
msg = 'Shape of provided k_fission "{0}" does not match ' \
'shape required, "{1}"'.format(k_fission.shape, shape)
raise ValueError(msg)
# Check the dimensions of the data
check_value('fission shape', fission.shape, self.vector_shape)
self._fission = np.copy(fission)
if np.sum(self._fission) > 0.0:
self._fissionable = True
@kappa_fission.setter
def kappa_fission(self, kappa_fission):
"""This method sets the kappa_fission cross section by performing a
deep-copy of the provided ndarray.
Parameters
----------
kappa_fission: ndarray
Array of group-wise cross sections to apply
Raises
------
ValueError
When invalid parameters are passed.
"""
# check we have a numpy list
check_type('kappa_fission', fission, np.ndarray,
expected_iter_type=Real)
# Check the dimensions of the data
check_value('kappa fission shape', kappa_fission.shape,
self.vector_shape)
self._kappa_fission = np.copy(fission)
if np.sum(self._kappa_fission) > 0.0:
self._fissionable = True
@chi.setter
def chi(self, chi):
"""This method sets the chi cross section by performing a
deep-copy of the provided ndarray.
Parameters
----------
chi: ndarray
Array of group-wise cross sections to apply
Raises
------
ValueError
When invalid parameters are passed.
"""
if self._use_chi is not None:
if not self._use_chi:
msg = 'Providing chi when nu_fission already provided as matrix!'
msg = 'Providing chi when nu_fission already provided as a' \
'matrix'
raise ValueError(msg)
if self._representation is 'isotropic':
shape = (self._energy_groups.num_groups,)
elif self._representation is 'angle':
shape = (self._num_polar, self._num_azimuthal,
self._energy_groups.num_groups)
# check we have a numpy list
check_type('chi', chi, np.ndarray, expected_iter_type=Real)
if chi.shape == shape:
self._chi = np.copy(chi)
else:
msg = 'Shape of provided chi "{0}" does not match shape ' \
'required, "{1}"'.format(chi.shape, shape)
raise ValueError(msg)
# Check the dimensions of the data
check_value('chi shape', chi.shape, self.vector_shape)
self._chi = np.copy(chi)
if self._use_chi is not None:
self._use_chi = True
@scatter.setter
def scatter(self, scatter):
if self._representation is 'isotropic':
shape = (self.num_orders, self._energy_groups.num_groups,
self._energy_groups.num_groups)
max_depth = 3
elif self._representation is 'angle':
shape = (self._num_polar, self._num_azimuthal, self.num_orders,
self._energy_groups.num_groups,
self._energy_groups.num_groups)
max_depth = 5
"""This method sets the scattering matrix cross sections
by performing a deep-copy of the provided ndarray.
Parameters
----------
scatter : ndarrays
Array of group-wise cross sections to apply
Raises
------
ValueError
When invalid parameters are passed.
"""
# check we have a numpy list
check_iterable_type('scatter', scatter, expected_type=Real,
max_depth=max_depth)
if scatter.shape == shape:
self._scatter = np.copy(scatter)
else:
msg = 'Shape of provided scatter "{0}" does not match shape ' \
'required, "{1}"'.format(scatter.shape, shape)
raise ValueError(msg)
check_type('scatter', scatter, np.ndarray, expected_iter_type=Real,
max_depth=len(scatter.shape))
# Check the dimensions of the data
check_value('scatter shape', scatter.shape, self.matrix_shape)
self._scatter = np.copy(scatter)
@multiplicity.setter
def multiplicity(self, multiplicity):
if self._representation is 'isotropic':
shape = (self._energy_groups.num_groups,
self._energy_groups.num_groups)
max_depth = 2
elif self._representation is 'angle':
shape = (self._num_polar, self._num_azimuthal,
self._energy_groups.num_groups,
self._energy_groups.num_groups)
max_depth = 4
"""This method sets the scattering multiplicity matrix cross sections
by performing a deep-copy of the provided ndarray.
Parameters
----------
multiplicity : ndarrays
Array of group-wise cross sections to apply
Raises
------
ValueError
When invalid parameters are passed.
"""
# check we have a numpy list
check_iterable_type('multiplicity', multiplicity, expected_type=Real,
max_depth=max_depth)
if multiplicity.shape == shape:
self._multiplicity = np.copy(multiplicity)
else:
msg = 'Shape of provided multiplicity "{0}" does not match shape' \
' required, "{1}"'.format(multiplicity.shape, shape)
raise ValueError(msg)
check_type('multiplicity', multiplicity, np.ndarray,
expected_iter_type=Real, max_depth=len(multiplicity.shape))
# Check the dimensions of the data
check_value('multiplicity shape', multiplicity.shape,
self.matrix_shape)
self._multiplicity = np.copy(multiplicity)
@nu_fission.setter
def nu_fission(self, nu_fission):
"""This method sets the nu_fission cross section by performing a
deep-copy of the provided ndarray.
Parameters
----------
nu_fission: ndarray
Array of group-wise cross sections to apply
Raises
------
ValueError
When invalid parameters are passed.
"""
# The NuFissionXS class does not have the capability to produce
# a fission matrix and therefore if this path is pursued, we know
# chi must be used.
@ -559,47 +648,54 @@ class XSdata(object):
# chi already has been set. If not, we just check that this is OK
# and set the use_chi flag accordingly
# First lets set our dimensions here since they get used repeatedly
# throughout this code.
if self._representation is 'isotropic':
shape_vec = (self._energy_groups.num_groups,)
shape_mat = (self._energy_groups.num_groups,
self._energy_groups.num_groups)
elif self._representation is 'angle':
shape_vec = (self._num_polar, self._num_azimuthal,
self._energy_groups.num_groups)
shape_mat = (self._num_polar, self._num_azimuthal,
self._energy_groups.num_groups,
self._energy_groups.num_groups)
# Begin by checking the case when chi has already been given and
# thus the rules for filling in nu_fission are set.
if self._use_chi is not None:
if self._use_chi:
shape = shape_vec
else:
shape = shape_mat
if nu_fission.shape != shape:
msg = 'Invalid Shape of Nu_fission!'
raise ValueError(msg)
else:
# Get shape of nu_fission to determine if we need chi or not
if nu_fission.shape == shape_vec:
self._use_chi = True
elif nu_fission.shape == shape_mat:
self._use_chi = False
else:
msg = 'Invalid Shape of Nu_fission!'
raise ValueError(msg)
# check we have a numpy list
# First, check we have a numpy list
check_type('nu_fission', nu_fission, np.ndarray,
expected_iter_type=Real)
expected_iter_type=Real, max_depth=len(nu_fission.shape))
if self._use_chi is not None:
# Check the dimensions of the data
if self._use_chi:
check_value('nu_fission shape', nu_fission.shape,
self.vector_shape)
else:
check_value('nu_fission shape', nu_fission.shape,
self.matrix_shape)
else:
# Make sure the dimensions are at least right
check_value('nu_fission shape', nu_fission.shape,
(self.vector_shape, self.matrix_shape))
# Then find out which one we have so we can set use_chi
if nu_fission.shape == self.vector_shape:
self._use_chi = True
else:
self._use_chi = False
self._nu_fission = np.copy(nu_fission)
if np.sum(self._nu_fission) > 0.0:
self._fissionable = True
def set_total(self, total, subdomain, nuclide='sum', xs_type='macro'):
def set_total_mgxs(self, total, nuclide='total', xs_type='macro'):
"""This method allows for an openmc.mgxs.TotalXS or
openmc.mgxs.TransportXS to be used to set the total cross section
for this XSdata object.
Parameters
----------
total: {openmc.mgxs.TotalXS, openmc.mgxs.TransportXS}
MGXS Object containing the total or transport cross section
for the domain of interest.
nuclide : str
Individual nuclide (or 'total' if obtaining material-wise data)
to gather data for. Defaults to 'total'.
xs_type: {'macro', 'micro'}
Provide the macro or micro cross section in units of cm^-1 or
barns. Defaults to 'macro'.
Raises
------
ValueError
When invalid parameters are passed.
"""
if not isinstance(total, (openmc.mgxs.TotalXS,
openmc.mgxs.TransportXS)):
msg = 'Method must be passed an openmc.mgxs.TotalXS or ' \
@ -607,59 +703,119 @@ class XSdata(object):
raise TypeError(msg)
# Make sure passed MGXS object contains correct group structure
if self.energy_groups != total.energy_groups:
msg = 'Group structure of provided data does not match' \
' group structure of XSdata object'
raise ValueError(msg)
check_value('energy_groups', total.energy_groups, [self.energy_groups])
# Make sure passed MGXS object has correct domain type
check_value('domain_type', total.domain_type,
['universe', 'cell', 'material'])
if self._representation is 'isotropic':
self._total = total.get_xs(subdomain=subdomains, nuclides=nuclide,
xs_type=xs_type)
self._total = total.get_xs(nuclides=nuclide, xs_type=xs_type)
elif self._representation is 'angle':
msg = 'Angular-Dependent MGXS have not yet been implemented'
raise ValueError(msg)
def set_absorption(self, absorption, subdomain, nuclide='sum',
xs_type='macro'):
def set_absorption_mgxs(self, absorption, nuclide='total', xs_type='macro'):
"""This method allows for an openmc.mgxs.AbsorptionXS
to be used to set the absorption cross section for this XSdata object.
Parameters
----------
absorption: openmc.mgxs.AbsorptionXS
MGXS Object containing the absorption cross section
for the domain of interest.
nuclide : str
Individual nuclide (or 'total' if obtaining material-wise data)
to gather data for. Defaults to 'total'.
xs_type: {'macro', 'micro'}
Provide the macro or micro cross section in units of cm^-1 or
barns. Defaults to 'macro'.
Raises
------
ValueError
When invalid parameters are passed.
"""
if not isinstance(absorption, openmc.mgxs.AbsorptionXS):
msg = 'Method must be passed an openmc.mgxs.AbsorptionXS'
raise TypeError(msg)
# Make sure passed MGXS object contains correct group structure
if self.energy_groups != absorption.energy_groups:
msg = 'Group structure of provided data does not match' \
' group structure of XSdata object'
raise ValueError(msg)
check_value('energy_groups', absorption.energy_groups,
[self.energy_groups])
# Make sure passed MGXS object has correct domain type
check_value('domain_type', absorption.domain_type,
['universe', 'cell', 'material'])
if self._representation is 'isotropic':
self._absorption = absorption.get_xs(subdomains=subdomain,
nuclides=nuclide,
self._absorption = absorption.get_xs(nuclides=nuclide,
xs_type=xs_type)
elif self._representation is 'angle':
msg = 'Angular-Dependent MGXS have not yet been implemented'
raise ValueError(msg)
def set_fission(self, fission, subdomain, nuclide='sum', xs_type='macro'):
def set_fission_mgxs(self, fission, nuclide='total', xs_type='macro'):
"""This method allows for an openmc.mgxs.FissionXS
to be used to set the fission cross section for this XSdata object.
Parameters
----------
fission: openmc.mgxs.FissionXS
MGXS Object containing the fission cross section
for the domain of interest.
nuclide : str
Individual nuclide (or 'total' if obtaining material-wise data)
to gather data for. Defaults to 'total'.
xs_type: {'macro', 'micro'}
Provide the macro or micro cross section in units of cm^-1 or
barns. Defaults to 'macro'.
Raises
------
ValueError
When invalid parameters are passed.
"""
if not isinstance(fission, openmc.mgxs.FissionXS):
msg = 'Method must be passed an openmc.mgxs.FissionXS'
raise TypeError(msg)
# Make sure passed MGXS object contains correct group structure
if self.energy_groups != fission.energy_groups:
msg = 'Group structure of provided data does not match' \
' group structure of XSdata object'
raise ValueError(msg)
check_value('energy_groups', fission.energy_groups,
[self.energy_groups])
# Make sure passed MGXS object has correct domain type
check_value('domain_type', fission.domain_type,
['universe', 'cell', 'material'])
if self._representation is 'isotropic':
self._fission = fission.get_xs(subdomains=subdomain,
nuclides=nuclide,
self._fission = fission.get_xs(nuclides=nuclide,
xs_type=xs_type)
elif self._representation is 'angle':
msg = 'Angular-Dependent MGXS have not yet been implemented'
raise ValueError(msg)
def set_nu_fission(self, nu_fission, subdomain, nuclide='sum',
xs_type='macro'):
def set_nu_fission_mgxs(self, nu_fission, nuclide='total', xs_type='macro'):
"""This method allows for an openmc.mgxs.NuFissionXS
to be used to set the nu-fission cross section for this XSdata object.
Parameters
----------
nu_fission: openmc.mgxs.NuFissionXS
MGXS Object containing the nu-fission cross section
for the domain of interest.
nuclide : str
Individual nuclide (or 'total' if obtaining material-wise data)
to gather data for. Defaults to 'total'.
xs_type: {'macro', 'micro'}
Provide the macro or micro cross section in units of cm^-1 or
barns. Defaults to 'macro'.
Raises
------
ValueError
When invalid parameters are passed.
"""
# The NuFissionXS class does not have the capability to produce
# a fission matrix and therefore if this path is pursued, we know
# chi must be used.
@ -668,14 +824,15 @@ class XSdata(object):
raise TypeError(msg)
# Make sure passed MGXS object contains correct group structure
if self.energy_groups != nu_fission.energy_groups:
msg = 'Group structure of provided data does not match' \
' group structure of XSdata object'
raise ValueError(msg)
check_value('energy_groups', nu_fission.energy_groups,
[self.energy_groups])
# Make sure passed MGXS object has correct domain type
check_value('domain_type', nu_fission.domain_type,
['universe', 'cell', 'material'])
if self._representation is 'isotropic':
self._nu_fission = nu_fission.get_xs(subdomains=subdomain,
nuclides=nuclide,
self._nu_fission = nu_fission.get_xs(nuclides=nuclide,
xs_type=xs_type)
elif self._representation is 'angle':
msg = 'Angular-Dependent MGXS have not yet been implemented'
@ -686,27 +843,68 @@ class XSdata(object):
if np.sum(self._nu_fission) > 0.0:
self._fissionable = True
def set_k_fission(self, k_fission, subdomain, nuclide='sum',
xs_type='macro'):
def set_kappa_fission_mgxs(self, k_fission, nuclide='total',
xs_type='macro'):
"""This method allows for an openmc.mgxs.KappaFissionXS
to be used to set the kappa-fission cross section for this XSdata
object.
Parameters
----------
kappa_fission: openmc.mgxs.KappaFissionXS
MGXS Object containing the kappa-fission cross section
for the domain of interest.
nuclide : str
Individual nuclide (or 'total' if obtaining material-wise data)
to gather data for. Defaults to 'total'.
xs_type: {'macro', 'micro'}
Provide the macro or micro cross section in units of cm^-1 or
barns. Defaults to 'macro'.
Raises
------
ValueError
When invalid parameters are passed.
"""
if not isinstance(k_fission, openmc.mgxs.KappaFissionXS):
msg = 'Method must be passed an openmc.mgxs.KappaFissionXS'
raise TypeError(msg)
# Make sure passed MGXS object contains correct group structure
if self.energy_groups != k_fission.energy_groups:
msg = 'Group structure of provided data does not match' \
' group structure of XSdata object'
raise ValueError(msg)
check_value('energy_groups', k_fission.energy_groups,
[self.energy_groups])
# Make sure passed MGXS object has correct domain type
check_value('domain_type', k_fission.domain_type,
['universe', 'cell', 'material'])
if self._representation is 'isotropic':
self._k_fission = k_fission.get_xs(subdomains=subdomain,
nuclides=nuclide,
xs_type=xs_type)
self._kappa_fission = k_fission.get_xs(nuclides=nuclide,
xs_type=xs_type)
elif self._representation is 'angle':
msg = 'Angular-Dependent MGXS have not yet been implemented'
raise ValueError(msg)
def set_chi(self, chi, subdomain, nuclide='sum', xs_type='macro'):
def set_chi_mgxs(self, chi, nuclide='total', xs_type='macro'):
"""This method allows for an openmc.mgxs.Chi
to be used to set chi for this XSdata object.
Parameters
----------
chi: openmc.mgxs.Chi
MGXS Object containing chi for the domain of interest.
nuclide : str
Individual nuclide (or 'total' if obtaining material-wise data)
to gather data for. Defaults to 'total'.
xs_type: {'macro', 'micro'}
Provide the macro or micro cross section in units of cm^-1 or
barns. Defaults to 'macro'.
Raises
------
ValueError
When invalid parameters are passed.
"""
if self._use_chi is not None:
if not self._use_chi:
msg = 'Providing chi when nu_fission already provided as a ' \
@ -718,14 +916,14 @@ class XSdata(object):
raise TypeError(msg)
# Make sure passed MGXS object contains correct group structure
if self.energy_groups != chi.energy_groups:
msg = 'Group structure of provided data does not match' \
' group structure of XSdata object'
raise ValueError(msg)
check_value('energy_groups', chi.energy_groups, [self.energy_groups])
# Make sure passed MGXS object has correct domain type
check_value('domain_type', chi.domain_type,
['universe', 'cell', 'material'])
if self._representation is 'isotropic':
self._chi = chi.get_xs(subdomains=subdomain,
nuclides=nuclide,
self._chi = chi.get_xs(nuclides=nuclide,
xs_type=xs_type)
elif self._representation is 'angle':
msg = 'Angular-Dependent MGXS have not yet been implemented'
@ -734,55 +932,102 @@ class XSdata(object):
if self._use_chi is not None:
self._use_chi = True
def set_scatter(self, scatter, subdomain, nuclide='sum', xs_type='macro'):
def set_scatter_mgxs(self, scatter, nuclide='total', xs_type='macro'):
"""This method allows for an openmc.mgxs.ScatterMatrixXS
to be used to set the scatter matrix cross section for this XSdata
object.
Parameters
----------
scatter: openmc.mgxs.ScatterMatrixXS
MGXS Object containing the scatter matrix cross section
for the domain of interest.
nuclide : str
Individual nuclide (or 'total' if obtaining material-wise data)
to gather data for. Defaults to 'total'.
xs_type: {'macro', 'micro'}
Provide the macro or micro cross section in units of cm^-1 or
barns. Defaults to 'macro'.
Raises
------
ValueError
When invalid parameters are passed.
"""
if not isinstance(scatter, openmc.mgxs.ScatterMatrixXS):
msg = 'Method must be passed an openmc.mgxs.ScatterMatrixXS'
raise TypeError(msg)
# Make sure passed MGXS object contains correct group structure
if self.energy_groups != scatter.energy_groups:
msg = 'Group structure of provided data does not match' \
' group structure of XSdata object'
raise ValueError(msg)
check_value('energy_groups', scatter.energy_groups,
[self.energy_groups])
# Make sure passed MGXS object has correct domain type
check_value('domain_type', scatter.domain_type,
['universe', 'cell', 'material'])
if self._representation is 'isotropic':
self._scatter = scatter.get_xs(subdomains=subdomain,
nuclides=nuclide,
self._scatter = scatter.get_xs(nuclides=nuclide,
xs_type=xs_type)
elif self._representation is 'angle':
msg = 'Angular-Dependent MGXS have not yet been implemented'
raise ValueError(msg)
def set_multiplicity(self, multiplicity, scatter, subdomain,
nuclide='sum', xs_type='macro'):
if not isinstance(multiplicity, openmc.mgxs.ScatterMatrixXS):
def set_multiplicity_mgxs(self, nuscatter, scatter, nuclide='total',
xs_type='macro'):
"""This method allows for an openmc.mgxs.NuScatterMatrixXS and
openmc.mgxs.ScatterMatrixXS to be used to set the scattering
multiplicity for this XSdata object.
Parameters
----------
nuscatter: openmc.mgxs.NuScatterMatrixXS
MGXS Object containing the nu-scattering matrix cross section
for the domain of interest.
scatter: openmc.mgxs.ScatterMatrixXS
MGXS Object containing the scattering matrix cross section
for the domain of interest.
nuclide : str
Individual nuclide (or 'total' if obtaining material-wise data)
to gather data for. Defaults to 'total'.
xs_type: {'macro', 'micro'}
Provide the macro or micro cross section in units of cm^-1 or
barns. Defaults to 'macro'.
Raises
------
ValueError
When invalid parameters are passed.
"""
if not isinstance(nuscatter, openmc.mgxs.NuScatterMatrixXS):
msg = 'Method must be passed an openmc.mgxs.ScatterMatrixXS'
raise TypeError(msg)
if not isinstance(scatter, openmc.mgxs.ScatterMatrixXS):
msg = 'Method must be passed an openmc.mgxs.ScatterMatrixXS'
raise TypeError(msg)
# Make sure passed MGXS objects contain correct group structure
if self.energy_groups != multiplicity.energy_groups:
msg = 'Group structure of "multiplicity" does not match' \
' group structure of XSdata object'
raise ValueError(msg)
if self.energy_groups != scatter.energy_groups:
msg = 'Group structure of "scatter" does not match' \
' group structure of XSdata object'
raise ValueError(msg)
# Make sure passed MGXS object contains correct group structure
check_value('energy_groups', nuscatter.energy_groups,
[self.energy_groups])
check_value('energy_groups', scatter.energy_groups,
[self.energy_groups])
# Make sure passed MGXS object has correct domain type
check_value('domain_type', nuscatter.domain_type,
['universe', 'cell', 'material'])
check_value('domain_type', scatter.domain_type,
['universe', 'cell', 'material'])
if self._representation is 'isotropic':
nuscatt = multiplicity.get_xs(subdomains=subdomain,
nuclides=nuclide,
xs_type=xs_type)
scatt = scatter.get_xs(subdomains=subdomain,
nuclides=nuclide,
nuscatt = nuscatter.get_xs(nuclides=nuclide,
xs_type=xs_type)
scatt = scatter.get_xs(nuclides=nuclide,
xs_type=xs_type)
self._multiplicity = np.divide(nuscatt, scatt)
elif self._representation is 'angle':
msg = 'Angular-Dependent MGXS have not yet been implemented'
raise ValueError(msg)
self._multiplicity = np.nan_to_num(self._multiplicity)
def _get_xsdata_xml(self):
element = ET.Element('xsdata')
@ -858,9 +1103,9 @@ class XSdata(object):
subelement = ET.SubElement(element, 'fission')
subelement.text = ndarray_to_string(self._fission)
if self._k_fission is not None:
if self._kappa_fission is not None:
subelement = ET.SubElement(element, 'k_fission')
subelement.text = ndarray_to_string(self._k_fission)
subelement.text = ndarray_to_string(self._kappa_fission)
if self._nu_fission is not None:
subelement = ET.SubElement(element, 'nu_fission')
@ -947,10 +1192,8 @@ class MGXSLibrary(object):
"""
if not isinstance(xsdatas, Iterable):
msg = 'Unable to create OpenMC xsdatas.xml file from "{0}" which' \
' is not iterable'.format(xsdatas)
raise ValueError(msg)
# Check we have an iterable of XSdatas
check_iterable_type('xsdatas', xsdatas, XSdata)
for xsdata in xsdatas:
self.add_xsdata(xsdata)