Updating per the latest round of comments. This includes simplifying the notebook significantly, and adding a get_xsdata method to Library.

This commit is contained in:
Adam Nelson 2016-05-13 22:32:48 -04:00
parent e9fc744ba5
commit eb20de6a51
6 changed files with 393 additions and 1551 deletions

File diff suppressed because one or more lines are too long

View file

@ -8,10 +8,10 @@ OpenMC can be run in continuous-energy mode or multi-group mode, provided the
nuclear data is available. In continuous-energy mode, the
``cross_sections.xml`` file contains necessary meta-data for each data set,
including the name and a file system location where the complete library
can be found. In multi-group mode, this ``cross_sections.xml`` file contains
can be found. In multi-group mode, this ``mgxs.xml`` file contains
this same meta-data describing the nuclide or material, but also contains the
group-wise nuclear data. This portion of the manual describes the format of
the multi-group data library required to be used in the ``cross_sections.xml``
the multi-group data library required to be used in the ``mgxs.xml``
file.
Similar to the other input file types, the multi-group library is provided in
@ -23,7 +23,7 @@ materials.
.. _XML: http://www.w3.org/XML/
------------------------------------------------
MGXS Library Specification -- cross_sections.xml
MGXS Library Specification -- mgxs.xml
------------------------------------------------
The multi-group library meta-data is contained within the groups_,

View file

@ -348,7 +348,9 @@ class Material(object):
del self._nuclides[nuclide._name]
def add_macroscopic(self, macroscopic):
"""Add a macroscopic to the material
"""Add a macroscopic to the material. This will also set the
density of the material to 1.0, unless it has been otherwise set,
as a default for Macroscopic cross sections.
Parameters
----------
@ -386,6 +388,14 @@ class Material(object):
'Material!'.format(self._id, macroscopic)
raise ValueError(msg)
# Generally speaking, the density for a macroscopic object will
# be 1.0. Therefore, lets set density to 1.0 so that the user
# doesnt need to set it unless its needed.
# Of course, if the user has already set a value of density,
# then we will not override it.
if self._density is None:
self.set_density('macro', 1.0)
def remove_macroscopic(self, macroscopic):
"""Remove a macroscopic from the material

View file

@ -722,11 +722,140 @@ class Library(object):
# Load and return pickled Library object
return pickle.load(open(full_filename, 'rb'))
def write_mg_library(self, xs_type='macro', domain_names=None, xs_ids=None,
filename='mg_cross_sections', directory='./',
return_names=False):
"""Creates a cross-section data library file for the Multi-Group
mode of OpenMC.
def get_xsdata(self, domain, domain_name, nuclide='total', xs_type='macro',
xs_id='1m', order=-1):
"""Generates an openmc.XSdata object describing a multi-group cross section
data set for eventual combination in to an openmc.MGXSLibrary object
(i.e., the library).
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe
The domain for spatial homogenization
domain_name : str
Name to apply to the "xsdata" entry produced by this method
nuclide : str
A nuclide name string (e.g., 'U-235'). Defaults to 'total' to
obtain a material-wise macroscopic cross section.
xs_type: {'macro', 'micro'}
Provide the macro or micro cross section in units of cm^-1 or
barns. Defaults to 'macro'. If the Library object is not tallied by
nuclide this will be set to 'macro' regardless.
xs_ids : str
Cross section set identifier. Defaults to '1m'.
order : Scattering order for this dataset entry. Default is -1,
which will force the XSdata object to use whatever the maximum
order available.
Returns
-------
xsdata : openmc.XSdata
Multi-Group Cross Section data set object.
Raises
------
ValueError
When the Library object is initialized with insufficient types of
cross sections for the Library.
See also
--------
Library.create_mg_library(...)
"""
cv.check_type('domain', domain, (openmc.Material, openmc.Cell,
openmc.Cell))
cv.check_type('domain_name', domain_name, basestring)
cv.check_type('nuclide', nuclide, basestring)
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
cv.check_type('xs_id', xs_id, basestring)
cv.check_type('order', order, Integral)
cv.check_greater_than('order', order, -1, equality=True)
# Make sure statepoint has been loaded
if self._sp_filename is None:
msg = 'A StatePoint must be loaded before calling ' \
'the create_mg_library() function'
raise ValueError(msg)
# If gathering material-specific data, set the xs_type to macro
if not self.by_nuclide:
xs_type = 'macro'
# Build & add metadata to XSdata object
name = domain_name
if nuclide is not 'total':
name += '_' + nuclide
name += '.' + xs_id
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]
# Now get xs data itself
if 'transport' in self.mgxs_types:
mymgxs = self.get_mgxs(domain, 'transport')
xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide])
elif 'total' in self.mgxs_types:
mymgxs = self.get_mgxs(domain, 'total')
xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide])
if 'absorption' in self.mgxs_types:
mymgxs = self.get_mgxs(domain, 'absorption')
xsdata.set_absorption_mgxs(mymgxs, xs_type=xs_type,
nuclide=[nuclide])
if 'fission' in self.mgxs_types:
mymgxs = self.get_mgxs(domain, 'fission')
xsdata.set_fission_mgxs(mymgxs, xs_type=xs_type,
nuclide=[nuclide])
if 'kappa-fission' in self.mgxs_types:
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:
mymgxs = self.get_mgxs(domain, 'chi')
xsdata.set_chi_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide])
if 'nu-fission' in self.mgxs_types:
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))):
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:
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:
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.
if 'total' in self.mgxs_types:
xsdata._absorption = \
np.subtract(xsdata.total,
np.sum(xsdata.scatter[0, :, :], axis=1))
return xsdata
def create_mg_library(self, xs_type='macro', domain_names=None,
xs_ids=None):
"""Creates an openmc.MGXSLibrary object to contain the MGXS data for the
Multi-Group mode of OpenMC.
Parameters
----------
@ -735,28 +864,18 @@ class Library(object):
barns. Defaults to 'macro'. If the Library object is not tallied by
nuclide this will be set to 'macro' regardless.
domain_names : Iterable of str
List of names to apply to the xsdata entries in the
List of names to apply to the "xsdata" entries in the
resultant mgxs data file. Defaults to 'set1', 'set2', ...
xs_ids : str or Iterable of str
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 '1m'.
filename : str
Filename for the pickle file. Defaults to 'mg_cross_sections'.
directory : str
Directory for the pickle file. Defaults to './' (the
current working directory).
return_names : bool
Flag to indicate if the user would like the names of the
materials generated by this function returned with completion.
Defaults to False, indicating that no names will be returned.
Returns
-------
mat_names : Iterable of str
Iterable of material names generated during this routine and
applies to the cross section library. Note this is returned if
the return_names parameter is provided.
mgxs_file : openmc.MGXSLibrary
Multi-Group Cross Section File that is ready to be printed to the
file of choice by the user.
Raises
------
@ -774,10 +893,9 @@ class Library(object):
# multi-group cross section types
self.check_library_for_openmc_mgxs()
# Check the provided parameters
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
if domain_names is not None:
cv.check_iterable_type('domain_names', filename, basestring)
cv.check_iterable_type('domain_names', domain_names, basestring)
if xs_ids is not None:
if isinstance(xs_ids, basestring):
# If we only have a string lets convert it now to a list
@ -787,25 +905,11 @@ class Library(object):
cv.check_iterable_type('xs_ids', xs_ids, basestring)
else:
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 gathering material-specific data, set the xs_type to macro
if not self.by_nuclide:
xs_type = 'macro'
# Make directory if it does not exist and build our filename
if not os.path.exists(directory):
os.makedirs(directory)
full_filename = os.path.join(directory, filename + '.xml')
full_filename = full_filename.replace(' ', '-')
# Initialize file
mgxs_file = openmc.MGXSLibrary(self.energy_groups)
@ -813,13 +917,10 @@ class Library(object):
# support for higher orders are included in openmc.mgxs
order = 0
# Build XSdata objects
# Build storage for our XSdata objects
xsdatas = []
mat_names = {}
for i, domain in enumerate(self.domains):
mat_names[domain.id] = {}
if self.by_nuclide:
nuclides = list(domain.get_all_nuclides().keys())
else:
@ -832,99 +933,23 @@ class Library(object):
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]
nuclide = [nuclide]
# Now get xs data itself
if 'transport' in self.mgxs_types:
mymgxs = self.get_mgxs(domain, 'transport')
xsdata.set_total_mgxs(mymgxs, xs_type=xs_type,
nuclide=nuclide)
elif 'total' in self.mgxs_types:
mymgxs = self.get_mgxs(domain, 'total')
xsdata.set_total_mgxs(mymgxs, xs_type=xs_type,
nuclide=nuclide)
if 'absorption' in self.mgxs_types:
mymgxs = self.get_mgxs(domain, 'absorption')
xsdata.set_absorption_mgxs(mymgxs, xs_type=xs_type,
nuclide=nuclide)
if 'fission' in self.mgxs_types:
mymgxs = self.get_mgxs(domain, 'fission')
xsdata.set_fission_mgxs(mymgxs, xs_type=xs_type,
nuclide=nuclide)
if 'kappa-fission' in self.mgxs_types:
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:
mymgxs = self.get_mgxs(domain, 'chi')
xsdata.set_chi_mgxs(mymgxs, xs_type=xs_type,
nuclide=nuclide)
if 'nu-fission' in self.mgxs_types:
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))):
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:
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:
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.
if 'total' in self.mgxs_types:
xsdata._absorption = \
np.subtract(xsdata.total,
np.sum(xsdata.scatter[0, :, :],
axis=1))
xsdata = self.get_xsdata(domain, name, nuclide=nuclide,
xs_type=xs_type, xs_id=xs_ids[i],
order=order)
xsdatas.append(xsdata)
# Add XSdatas to file
mgxs_file.add_xsdatas(xsdatas)
# Finally, write the file
mgxs_file.export_to_xml(full_filename)
if return_names:
return mat_names
return mgxs_file
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.
"""This routine will check the MGXS Types within a Library
to ensure the MGXS types provided can be used to create
a MGXS Library for OpenMC's Multi-Group mode.
The rules to check include:
- Either total or transport should be present.
- Both can be available if one wants, but we should
@ -943,7 +968,7 @@ class Library(object):
See also
--------
Library.write_mg_library(...)
Library.create_mg_library(...)
"""

View file

@ -420,7 +420,8 @@ class XSdata(object):
enable = tabular_legendre['enable']
check_type('enable', enable, bool)
else:
msg = 'enable must be provided in tabular_legendre'
msg = 'The tabular_legendre dict must include a value keyed by ' \
'"enable"'
raise ValueError(msg)
if 'num_points' in tabular_legendre:
num_points = tabular_legendre['num_points']
@ -448,217 +449,77 @@ class XSdata(object):
@total.setter
def total(self, total):
"""This method sets the total cross section by performing a
deep-copy of the provided ndarray. If the angular
representation is "isotropic" the shape of the input array
must be the number of energy groups. If the angular
representation is "angle" then the shape of the input
array must be the number of polar angles, number azimuthal
angles and energy groups.
Parameters
----------
total: ndarray
Array of group-wise cross sections to apply
"""
# check we have a numpy list
check_type('total', total, np.ndarray, expected_iter_type=Real)
# Check the dimensions of the data
check_value('total shape', total.shape, self.vector_shape)
self._total = np.copy(total)
self._total = total
@absorption.setter
def absorption(self, absorption):
"""This method sets the absorption cross section by performing a
deep-copy of the provided ndarray. If the angular
representation is "isotropic" the shape of the input array
must be the number of energy groups. If the angular
representation is "angle" then the shape of the input
array must be the number of polar angles, number azimuthal
angles and energy groups.
Parameters
----------
absorption: ndarray
Array of group-wise cross sections to apply
"""
# check we have a numpy list
check_type('absorption', absorption, np.ndarray,
expected_iter_type=Real)
# Check the dimensions of the data
check_value('absorption shape', absorption.shape, self.vector_shape)
self._absorption = np.copy(absorption)
self._absorption = absorption
@fission.setter
def fission(self, fission):
"""This method sets the fission cross section by performing a
deep-copy of the provided ndarray. If the angular
representation is "isotropic" the shape of the input array
must be the number of energy groups. If the angular
representation is "angle" then the shape of the input
array must be the number of polar angles, number azimuthal
angles and energy groups.
Parameters
----------
fission: ndarray
Array of group-wise cross sections to apply
"""
# check we have a numpy list
check_type('fission', fission, np.ndarray,
expected_iter_type=Real)
# Check the dimensions of the data
check_value('fission shape', fission.shape, self.vector_shape)
self._fission = np.copy(fission)
self._fission = 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. If the angular
representation is "isotropic" the shape of the input array
must be the number of energy groups. If the angular
representation is "angle" then the shape of the input
array must be the number of polar angles, number azimuthal
angles and energy groups.
Parameters
----------
kappa_fission: ndarray
Array of group-wise cross sections to apply
"""
# check we have a numpy list
check_type('kappa_fission', fission, np.ndarray,
check_type('kappa_fission', kappa_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)
self._kappa_fission = kappa_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. If the angular
representation is "isotropic" the shape of the input array
must be the number of energy groups. If the angular
representation is "angle" then the shape of the input
array must be the number of polar angles, number azimuthal
angles and energy groups.
Parameters
----------
chi: ndarray
Array of group-wise chi values to apply
"""
if self._use_chi is not None:
if not self._use_chi:
msg = 'Providing chi when nu_fission already provided as a' \
'matrix'
raise ValueError(msg)
# check we have a numpy list
check_type('chi', chi, np.ndarray, expected_iter_type=Real)
# Check the dimensions of the data
check_value('chi shape', chi.shape, self.vector_shape)
self._chi = np.copy(chi)
self._chi = chi
if self._use_chi is not None:
self._use_chi = True
@scatter.setter
def scatter(self, scatter):
"""This method sets the scattering matrix cross sections
by performing a deep-copy of the provided ndarray.
If the angular representation is "isotropic" the shape of
the input array must be the number of scattering orders, the
number of energy groups, and the number of energy groups. If
the angular representation is "angle" then the shape of the input
array must be the number of polar angles, number azimuthal
angles, number of scattering orders, energy groups, and energy groups.
Parameters
----------
scatter : ndarrays
Array of cross sections to apply
"""
# check we have a numpy list
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.pn_matrix_shape)
self._scatter = np.copy(scatter)
self._scatter = scatter
@multiplicity.setter
def multiplicity(self, multiplicity):
"""This method sets the scattering multiplicity matrix cross sections
by performing a deep-copy of the provided ndarray. Multiplicity,
in OpenMC parlance, is a factor used to account for the production
of neutrons introduced by scattering multiplication reactions, i.e.,
(n,xn) events. In this sense, the multiplication matrix is simply
defined as the ratio of the nu-scatter and scatter matrices.
If the angular representation is "isotropic" the shape of
the input array must be the number of energy groups and the number
of energy groups. If the angular representation is "angle" then the
shape of the input array must be the number of polar angles,
number azimuthal angles, number of scattering orders, energy groups,
and energy groups.
Parameters
----------
multiplicity : ndarrays
Array of scattering multiplications to apply
"""
# check we have a numpy list
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)
self._multiplicity = 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. If the angular
representation is "isotropic" the shape of the input array
must be the number of energy groups. If the angular
representation is "angle" then the shape of the input
array must be the number of polar angles, number azimuthal
angles and energy groups.
Parameters
----------
nu_fission: ndarray
Array of group-wise cross sections to apply
"""
# 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.
@ -669,12 +530,10 @@ 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, check we have a numpy list
check_type('nu_fission', nu_fission, np.ndarray,
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)
@ -682,16 +541,16 @@ class XSdata(object):
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
# Find out if we have a nu-fission matrix or vector
# and set a flag to allow other methods to check this later.
if nu_fission.shape == self.vector_shape:
self._use_chi = True
else:
self._use_chi = False
self._nu_fission = np.copy(nu_fission)
self._nu_fission = nu_fission
if np.sum(self._nu_fission) > 0.0:
self._fissionable = True
@ -716,11 +575,7 @@ class XSdata(object):
check_type('total', total, (openmc.mgxs.TotalXS,
openmc.mgxs.TransportXS))
# Make sure passed MGXS object contains correct group structure
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'])
@ -750,12 +605,8 @@ class XSdata(object):
"""
check_type('absorption', absorption, openmc.mgxs.AbsorptionXS)
# Make sure passed MGXS object contains correct group structure
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'])
@ -785,12 +636,8 @@ class XSdata(object):
"""
check_type('fission', fission, openmc.mgxs.FissionXS)
# Make sure passed MGXS object contains correct group structure
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'])
@ -824,12 +671,8 @@ class XSdata(object):
# a fission matrix and therefore if this path is pursued, we know
# chi must be used.
check_type('nu_fission', nu_fission, openmc.mgxs.NuFissionXS)
# Make sure passed MGXS object contains correct group structure
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'])
@ -866,12 +709,8 @@ class XSdata(object):
"""
check_type('k_fission', k_fission, openmc.mgxs.KappaFissionXS)
# Make sure passed MGXS object contains correct group structure
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'])
@ -906,11 +745,7 @@ class XSdata(object):
raise ValueError(msg)
check_type('chi', chi, openmc.mgxs.Chi)
# Make sure passed MGXS object contains correct group structure
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'])
@ -944,12 +779,8 @@ class XSdata(object):
"""
check_type('scatter', scatter, openmc.mgxs.ScatterMatrixXS)
# Make sure passed MGXS object contains correct group structure
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'])
@ -990,14 +821,10 @@ class XSdata(object):
check_type('nuscatter', nuscatter, openmc.mgxs.NuScatterMatrixXS)
check_type('scatter', scatter, openmc.mgxs.ScatterMatrixXS)
# 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,
@ -1153,14 +980,10 @@ class MGXSLibrary(object):
MGXS information to add
"""
# Check the type
if not isinstance(xsdata, XSdata):
msg = 'Unable to add a non-XSdata "{0}" to the ' \
'MGXSLibrary instance'.format(xsdata)
raise ValueError(msg)
# Make sure energy groups match.
if xsdata.energy_groups != self._energy_groups:
msg = 'Energy groups of XSdata do not match that of MGXSLibrary.'
raise ValueError(msg)
@ -1176,8 +999,6 @@ class MGXSLibrary(object):
XSdatas to add
"""
# Check we have an iterable of XSdatas
check_iterable_type('xsdatas', xsdatas, XSdata)
for xsdata in xsdatas:
@ -1222,14 +1043,14 @@ class MGXSLibrary(object):
xml_element = xsdata._get_xsdata_xml()
self._cross_sections_file.append(xml_element)
def export_to_xml(self, filename='mg_cross_sections.xml'):
"""Create an mg_cross_sections.xml file that can be used for a
def export_to_xml(self, filename='mgxs.xml'):
"""Create an mgxs.xml file that can be used for a
simulation.
Parameters
----------
filename : str, optional
filename of file, default is mg_cross_sections.xml
filename of file, default is mgxs.xml
"""

View file

@ -153,7 +153,7 @@ contains
else
call get_environment_variable("OPENMC_MG_CROSS_SECTIONS", env_variable)
if (len_trim(env_variable) == 0) then
call fatal_error("No cross_sections.xml file was specified in &
call fatal_error("No mgxs.xml file was specified in &
&settings.xml or in the OPENMC_MG_CROSS_SECTIONS environment &
&variable. OpenMC needs such a file to identify where to &
&find the cross section libraries. Please consult the user's &
@ -4537,24 +4537,24 @@ contains
subroutine read_mg_cross_sections_xml()
integer :: i ! loop index
logical :: file_exists ! does cross_sections.xml exist?
logical :: file_exists ! does mgxs.xml exist?
type(XsListing), pointer :: listing => null()
type(Node), pointer :: doc => null()
type(Node), pointer :: node_xsdata => null()
type(NodeList), pointer :: node_xsdata_list => null()
real(8), allocatable :: rev_energy_bins(:)
! Check if cross_sections.xml exists
! Check if mgxs.xml exists
inquire(FILE=path_cross_sections, EXIST=file_exists)
if (.not. file_exists) then
! Could not find cross_sections.xml file
! Could not find mgxs.xml file
call fatal_error("Cross sections XML file '" &
// trim(path_cross_sections) // "' does not exist!")
end if
call write_message("Reading cross sections XML file...", 5)
! Parse cross_sections.xml file
! Parse mgxs.xml file
call open_xmldoc(doc, path_cross_sections)
if (check_for_node(doc, "groups")) then
@ -4602,7 +4602,7 @@ contains
! Allocate xs_listings array
if (n_listings == 0) then
call fatal_error("At least one <xsdata> element must be present in &
&cross_sections.xml file!")
&mgxs.xml file!")
else
allocate(xs_listings(n_listings))
end if