Forgot universe_id=0 for root in example nb (fixed), resolved comments from @paulromano, and made sure the example problem worked still (it did, but I simplified it a bit since data doesnt need to be numpy arrays anymore.

This commit is contained in:
Adam Nelson 2016-05-15 14:26:54 -04:00
parent 4bec584ddb
commit 071e8d3e30
6 changed files with 172 additions and 133 deletions

File diff suppressed because one or more lines are too long

View file

@ -22,9 +22,9 @@ materials.
.. _XML: http://www.w3.org/XML/
------------------------------------------------
--------------------------------------
MGXS Library Specification -- mgxs.xml
------------------------------------------------
--------------------------------------
The multi-group library meta-data is contained within the groups_,
group_structure_, and inverse_velocities_ elements.
@ -33,7 +33,7 @@ The actual multi-group data itself is contained within the xsdata_ element.
.. _groups:
``<groups>`` Element
----------------------------------
--------------------
The ``<groups>`` element has no attributes and simply provides the number of
energy groups contained within the library.

View file

@ -1,4 +1,3 @@
import numpy as np
import openmc
import openmc.mgxs
@ -12,7 +11,7 @@ inactive = 10
particles = 1000
###############################################################################
# Exporting to OpenMC mg_cross_sections.xml file
# Exporting to OpenMC mgxs.xml file
###############################################################################
# Instantiate the energy group data
@ -22,45 +21,43 @@ groups = openmc.mgxs.EnergyGroups(group_edges=[1E-11, 0.0635E-6, 10.0E-6,
# Instantiate the 7-group (C5G7) cross section data
uo2_xsdata = openmc.XSdata('UO2.300K', groups)
uo2_xsdata.order = 0
uo2_xsdata.total = np.array([0.1779492, 0.3298048, 0.4803882, 0.5543674,
0.3118013, 0.3951678, 0.5644058])
uo2_xsdata.absorption = np.array([8.0248E-03, 3.7174E-03, 2.6769E-02, 9.6236E-02,
3.0020E-02, 1.1126E-01, 2.8278E-01])
scatter = [[[0.1275370, 0.0423780, 0.0000094, 0.0000000, 0.0000000, 0.0000000, 0.0000000],
[0.0000000, 0.3244560, 0.0016314, 0.0000000, 0.0000000, 0.0000000, 0.0000000],
[0.0000000, 0.0000000, 0.4509400, 0.0026792, 0.0000000, 0.0000000, 0.0000000],
[0.0000000, 0.0000000, 0.0000000, 0.4525650, 0.0055664, 0.0000000, 0.0000000],
[0.0000000, 0.0000000, 0.0000000, 0.0001253, 0.2714010, 0.0102550, 0.0000000],
[0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0012968, 0.2658020, 0.0168090],
[0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0085458, 0.2730800]]]
uo2_xsdata.scatter = np.array(scatter[:][:])
uo2_xsdata.fission = np.array([7.21206E-03, 8.19301E-04, 6.45320E-03,
1.85648E-02, 1.78084E-02, 8.30348E-02,
2.16004E-01])
uo2_xsdata.nu_fission = np.array([2.005998E-02, 2.027303E-03, 1.570599E-02,
4.518301E-02, 4.334208E-02, 2.020901E-01,
5.257105E-01])
uo2_xsdata.chi = np.array([5.8791E-01, 4.1176E-01, 3.3906E-04, 1.1761E-07,
0.0000E+00, 0.0000E+00, 0.0000E+00])
uo2_xsdata.total = [0.1779492, 0.3298048, 0.4803882, 0.5543674,
0.3118013, 0.3951678, 0.5644058]
uo2_xsdata.absorption = [8.0248E-03, 3.7174E-03, 2.6769E-02, 9.6236E-02,
3.0020E-02, 1.1126E-01, 2.8278E-01]
uo2_xsdata.scatter = [[[0.1275370, 0.0423780, 0.0000094, 0.0000000, 0.0000000, 0.0000000, 0.0000000],
[0.0000000, 0.3244560, 0.0016314, 0.0000000, 0.0000000, 0.0000000, 0.0000000],
[0.0000000, 0.0000000, 0.4509400, 0.0026792, 0.0000000, 0.0000000, 0.0000000],
[0.0000000, 0.0000000, 0.0000000, 0.4525650, 0.0055664, 0.0000000, 0.0000000],
[0.0000000, 0.0000000, 0.0000000, 0.0001253, 0.2714010, 0.0102550, 0.0000000],
[0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0012968, 0.2658020, 0.0168090],
[0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0085458, 0.2730800]]]
uo2_xsdata.fission = [7.21206E-03, 8.19301E-04, 6.45320E-03,
1.85648E-02, 1.78084E-02, 8.30348E-02,
2.16004E-01]
uo2_xsdata.nu_fission = [2.005998E-02, 2.027303E-03, 1.570599E-02,
4.518301E-02, 4.334208E-02, 2.020901E-01,
5.257105E-01]
uo2_xsdata.chi = [5.8791E-01, 4.1176E-01, 3.3906E-04, 1.1761E-07,
0.0000E+00, 0.0000E+00, 0.0000E+00]
h2o_xsdata = openmc.XSdata('LWTR.300K', groups)
h2o_xsdata.order = 0
h2o_xsdata.total = np.array([0.15920605, 0.412969593, 0.59030986, 0.58435,
0.718, 1.2544497, 2.650379])
h2o_xsdata.absorption = np.array([6.0105E-04, 1.5793E-05, 3.3716E-04,
1.9406E-03, 5.7416E-03, 1.5001E-02,
3.7239E-02])
scatter = [[[0.0444777, 0.1134000, 0.0007235, 0.0000037, 0.0000001, 0.0000000, 0.0000000],
[0.0000000, 0.2823340, 0.1299400, 0.0006234, 0.0000480, 0.0000074, 0.0000010],
[0.0000000, 0.0000000, 0.3452560, 0.2245700, 0.0169990, 0.0026443, 0.0005034],
[0.0000000, 0.0000000, 0.0000000, 0.0910284, 0.4155100, 0.0637320, 0.0121390],
[0.0000000, 0.0000000, 0.0000000, 0.0000714, 0.1391380, 0.5118200, 0.0612290],
[0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0022157, 0.6999130, 0.5373200],
[0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.1324400, 2.4807000]]]
h2o_xsdata.scatter = np.array(scatter)
h2o_xsdata.total = [0.15920605, 0.412969593, 0.59030986, 0.58435,
0.718, 1.2544497, 2.650379]
h2o_xsdata.absorption = [6.0105E-04, 1.5793E-05, 3.3716E-04,
1.9406E-03, 5.7416E-03, 1.5001E-02,
3.7239E-02]
h2o_xsdata.scatter = [[[0.0444777, 0.1134000, 0.0007235, 0.0000037, 0.0000001, 0.0000000, 0.0000000],
[0.0000000, 0.2823340, 0.1299400, 0.0006234, 0.0000480, 0.0000074, 0.0000010],
[0.0000000, 0.0000000, 0.3452560, 0.2245700, 0.0169990, 0.0026443, 0.0005034],
[0.0000000, 0.0000000, 0.0000000, 0.0910284, 0.4155100, 0.0637320, 0.0121390],
[0.0000000, 0.0000000, 0.0000000, 0.0000714, 0.1391380, 0.5118200, 0.0612290],
[0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0022157, 0.6999130, 0.5373200],
[0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.1324400, 2.4807000]]]
mg_cross_sections_file = openmc.MGXSLibrary(groups)
mg_cross_sections_file.add_xsdatas([uo2_xsdata,h2o_xsdata])
mg_cross_sections_file.add_xsdatas([uo2_xsdata, h2o_xsdata])
mg_cross_sections_file.export_to_xml()
@ -134,7 +131,7 @@ geometry.export_to_xml()
# Instantiate a Settings object, set all runtime parameters, and export to XML
settings_file = openmc.Settings()
settings_file.energy_mode = "multi-group"
settings_file.cross_sections = "./mg_cross_sections.xml"
settings_file.cross_sections = "./mgxs.xml"
settings_file.batches = batches
settings_file.inactive = inactive
settings_file.particles = particles

View file

@ -247,8 +247,7 @@ 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, openmc.mgxs.DOMAIN_TYPES)
self._domain_type = domain_type
@domains.setter
@ -722,8 +721,8 @@ class Library(object):
# Load and return pickled Library object
return pickle.load(open(full_filename, 'rb'))
def get_xsdata(self, domain, domain_name, nuclide='total', xs_type='macro',
xs_id='1m', order=-1):
def get_xsdata(self, domain, xsdata_name, nuclide='total', xs_type='macro',
xs_id='1m', order=None):
"""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).
@ -732,7 +731,7 @@ class Library(object):
----------
domain : openmc.Material or openmc.Cell or openmc.Universe
The domain for spatial homogenization
domain_name : str
xsdata_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
@ -743,7 +742,7 @@ class Library(object):
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,
order : Scattering order for this dataset entry. Default is None,
which will force the XSdata object to use whatever the maximum
order available.
@ -766,11 +765,11 @@ class Library(object):
cv.check_type('domain', domain, (openmc.Material, openmc.Cell,
openmc.Cell))
cv.check_type('domain_name', domain_name, basestring)
cv.check_type('xsdata_name', xsdata_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_type('order', order, (type(None), Integral))
cv.check_greater_than('order', order, -1, equality=True)
# Make sure statepoint has been loaded
@ -784,12 +783,18 @@ class Library(object):
xs_type = 'macro'
# Build & add metadata to XSdata object
name = domain_name
name = xsdata_name
if nuclide is not 'total':
name += '_' + nuclide
name += '.' + xs_id
xsdata = openmc.XSdata(name, self.energy_groups)
xsdata.order = order
if order is 0:
xsdata.order = order
else:
msg = 'Generating anisotropic scattering from openmc.Library' \
'objects has not yet been implemented.'
raise NotImplementedError(msg)
if nuclide is not 'total':
xsdata.zaid = self._nuclides[nuclide][0]
xsdata.awr = self._nuclides[nuclide][1]
@ -852,7 +857,7 @@ class Library(object):
return xsdata
def create_mg_library(self, xs_type='macro', domain_names=None,
def create_mg_library(self, xs_type='macro', xsdata_names=None,
xs_ids=None):
"""Creates an openmc.MGXSLibrary object to contain the MGXS data for the
Multi-Group mode of OpenMC.
@ -863,7 +868,7 @@ class Library(object):
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.
domain_names : Iterable of str
xsdata_names : Iterable of str
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
@ -894,8 +899,8 @@ class Library(object):
self.check_library_for_openmc_mgxs()
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
if domain_names is not None:
cv.check_iterable_type('domain_names', domain_names, basestring)
if xsdata_names is not None:
cv.check_iterable_type('xsdata_names', xsdata_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
@ -927,14 +932,14 @@ class Library(object):
nuclides = ['total']
for nuclide in nuclides:
# Build & add metadata to XSdata object
if domain_names is None:
name = 'set' + str(i + 1)
if xsdata_names is None:
xsdata_name = 'set' + str(i + 1)
else:
name = domain_names[i]
xsdata_name = xsdata_names[i]
if nuclide is not 'total':
name += '_' + nuclide
xsdata_name += '_' + nuclide
xsdata = self.get_xsdata(domain, name, nuclide=nuclide,
xsdata = self.get_xsdata(domain, xsdata_name, nuclide=nuclide,
xs_type=xs_type, xs_id=xs_ids[i],
order=order)
@ -952,14 +957,17 @@ class Library(object):
The rules to check include:
- 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)
- Absorption and total (or transport) are required.
- A nu-fission cross section and chi values are not required as a
fixed source problem could be the target.
- Fission and kappa-fission are not required as they are only
needed to support tallies the user may wish to request.
- 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

View file

@ -283,7 +283,7 @@ class MGXS(object):
@domain_type.setter
def domain_type(self, domain_type):
cv.check_value('domain type', domain_type, tuple(DOMAIN_TYPES))
cv.check_value('domain type', domain_type, DOMAIN_TYPES)
self._domain_type = domain_type
@energy_groups.setter

View file

@ -346,6 +346,16 @@ class XSdata(object):
self.energy_groups.num_groups,
self.energy_groups.num_groups)
@property
def pn_matrix_shape(self):
if self.representation is 'isotropic':
return (self.num_orders, self.energy_groups.num_groups,
self.energy_groups.num_groups)
elif self.representation is 'angle':
return (self.num_polar, self.num_azimuthal, self.num_orders,
self.energy_groups.num_groups,
self.energy_groups.num_groups)
@name.setter
def name(self, name):
check_type('name for XSdata', name, basestring)
@ -449,38 +459,49 @@ class XSdata(object):
@total.setter
def total(self, total):
check_type('total', total, np.ndarray, expected_iter_type=Real)
check_value('total shape', total.shape, self.vector_shape)
check_type('total', total, Iterable, expected_iter_type=Real)
# Convert to a numpy array so we can easily get the shape for
# checking
nptotal = np.array(total)
check_value('total shape', nptotal.shape, [self.vector_shape])
self._total = total
self._total = nptotal
@absorption.setter
def absorption(self, absorption):
check_type('absorption', absorption, np.ndarray,
expected_iter_type=Real)
check_value('absorption shape', absorption.shape, self.vector_shape)
check_type('absorption', absorption, Iterable, expected_iter_type=Real)
# Convert to a numpy array so we can easily get the shape for
# checking
npabsorption = np.array(absorption)
check_value('absorption shape', npabsorption.shape,
[self.vector_shape])
self._absorption = absorption
self._absorption = npabsorption
@fission.setter
def fission(self, fission):
check_type('fission', fission, np.ndarray,
expected_iter_type=Real)
check_value('fission shape', fission.shape, self.vector_shape)
check_type('fission', fission, Iterable, expected_iter_type=Real)
# Convert to a numpy array so we can easily get the shape for
# checking
npfission = np.array(fission)
check_value('fission shape', npfission.shape, [self.vector_shape])
self._fission = fission
self._fission = npfission
if np.sum(self._fission) > 0.0:
self._fissionable = True
@kappa_fission.setter
def kappa_fission(self, kappa_fission):
check_type('kappa_fission', kappa_fission, np.ndarray,
check_type('kappa_fission', kappa_fission, Iterable,
expected_iter_type=Real)
check_value('kappa fission shape', kappa_fission.shape,
self.vector_shape)
# Convert to a numpy array so we can easily get the shape for
# checking
npkappa_fission = np.array(kappa_fission)
check_value('kappa fission shape', npkappa_fission.shape,
[self.vector_shape])
self._kappa_fission = kappa_fission
self._kappa_fission = npkappa_fission
if np.sum(self._kappa_fission) > 0.0:
self._fissionable = True
@ -493,30 +514,39 @@ class XSdata(object):
'matrix'
raise ValueError(msg)
check_type('chi', chi, np.ndarray, expected_iter_type=Real)
check_value('chi shape', chi.shape, self.vector_shape)
check_type('chi', chi, Iterable, expected_iter_type=Real)
# Convert to a numpy array so we can easily get the shape for
# checking
npchi = np.array(chi)
check_value('chi shape', npchi.shape, [self.vector_shape])
self._chi = chi
self._chi = npchi
if self._use_chi is not None:
self._use_chi = True
@scatter.setter
def scatter(self, scatter):
check_type('scatter', scatter, np.ndarray, expected_iter_type=Real,
max_depth=len(scatter.shape))
check_value('scatter shape', scatter.shape, self.pn_matrix_shape)
# Convert to a numpy array so we can easily get the shape for
# checking
npscatter = np.array(scatter)
check_iterable_type('scatter', npscatter, Real,
max_depth=len(npscatter.shape))
check_value('scatter shape', npscatter.shape, [self.pn_matrix_shape])
self._scatter = scatter
self._scatter = npscatter
@multiplicity.setter
def multiplicity(self, multiplicity):
check_type('multiplicity', multiplicity, np.ndarray,
expected_iter_type=Real, max_depth=len(multiplicity.shape))
check_value('multiplicity shape', multiplicity.shape,
self.matrix_shape)
# Convert to a numpy array so we can easily get the shape for
# checking
npmultiplicity = np.array(multiplicity)
check_iterable_type('multiplicity', npmultiplicity, Real,
max_depth=len(npmultiplicity.shape))
check_value('multiplicity shape', npmultiplicity.shape,
[self.matrix_shape])
self._multiplicity = multiplicity
self._multiplicity = npmultiplicity
@nu_fission.setter
def nu_fission(self, nu_fission):
@ -530,27 +560,31 @@ class XSdata(object):
# chi already has been set. If not, we just check that this is OK
# and set the use_chi flag accordingly
check_type('nu_fission', nu_fission, np.ndarray,
expected_iter_type=Real, max_depth=len(nu_fission.shape))
# Convert to a numpy array so we can easily get the shape for
# checking
npnu_fission = np.array(nu_fission)
check_iterable_type('nu_fission', npnu_fission, Real,
max_depth=len(npnu_fission.shape))
if self._use_chi is not None:
if self._use_chi:
check_value('nu_fission shape', nu_fission.shape,
self.vector_shape)
check_value('nu_fission shape', npnu_fission.shape,
[self.vector_shape])
else:
check_value('nu_fission shape', nu_fission.shape,
self.matrix_shape)
check_value('nu_fission shape', npnu_fission.shape,
[self.matrix_shape])
else:
check_value('nu_fission shape', nu_fission.shape,
(self.vector_shape, self.matrix_shape))
check_value('nu_fission shape', npnu_fission.shape,
[self.vector_shape, self.matrix_shape])
# 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:
if npnu_fission.shape == self.vector_shape:
self._use_chi = True
else:
self._use_chi = False
self._nu_fission = nu_fission
self._nu_fission = npnu_fission
if np.sum(self._nu_fission) > 0.0:
self._fissionable = True