diff --git a/docs/source/usersguide/install.rst b/docs/source/usersguide/install.rst
index 1a0569148b..457c5efd8f 100644
--- a/docs/source/usersguide/install.rst
+++ b/docs/source/usersguide/install.rst
@@ -204,20 +204,22 @@ should be used:
Compiling with MPI
++++++++++++++++++
-To compile with MPI, set the :envvar:`FC` environment variable to the path to
-the MPI Fortran wrapper. For example, in a bash shell:
+To compile with MPI, set the :envvar:`FC` and :envvar:`CC` environment variables
+to the path to the MPI Fortran and C wrappers, respectively. For example, in a
+bash shell:
.. code-block:: sh
export FC=mpif90
+ export CC=mpicc
cmake /path/to/openmc
-Note that in many shells, an environment variable can be set for a single
-command, i.e.
+Note that in many shells, environment variables can be set for a single command,
+i.e.
.. code-block:: sh
- FC=mpif90 cmake /path/to/openmc
+ FC=mpif90 CC=mpicc cmake /path/to/openmc
Selecting HDF5 Installation
+++++++++++++++++++++++++++
@@ -343,7 +345,7 @@ compiler, it is necessary to specify that all objects be compiled with the
.. code-block:: sh
mkdir build && cd build
- FC=ifort FFLAGS=-mmic cmake -Dopenmp=on ..
+ FC=ifort CC=icc FFLAGS=-mmic cmake -Dopenmp=on ..
make
Note that unless an HDF5 build for the Intel Xeon Phi is already on your target
diff --git a/openmc/data/thermal.py b/openmc/data/thermal.py
index d729e41ecc..34981e566b 100644
--- a/openmc/data/thermal.py
+++ b/openmc/data/thermal.py
@@ -34,6 +34,7 @@ _THERMAL_NAMES = {'al': 'c_Al27', 'al27': 'c_Al27',
'orthod': 'c_ortho_D', 'dortho': 'c_ortho_D',
'orthoh': 'c_ortho_H', 'hortho': 'c_ortho_H',
'ouo2': 'c_O_in_UO2', 'o2-u': 'c_O_in_UO2', 'o2/u': 'c_O_in_UO2',
+ 'sio2': 'c_SiO2',
'parad': 'c_para_D', 'dpara': 'c_para_D',
'parah': 'c_para_H', 'hpara': 'c_para_H',
'sch4': 'c_solid_CH4', 'smeth': 'c_solid_CH4',
diff --git a/openmc/filter.py b/openmc/filter.py
index 256674af3e..9b4eb67dd2 100644
--- a/openmc/filter.py
+++ b/openmc/filter.py
@@ -376,7 +376,7 @@ class Filter(object):
cell instance ID for 'distribcell' Filters. The bin is a 2-tuple of
floats for 'energy' and 'energyout' filters corresponding to the
energy boundaries of the bin of interest. The bin is an (x,y,z)
- 3-tuple for 'mesh' filters corresponding to the mesh cell
+ 3-tuple for 'mesh' filters corresponding to the mesh cell of
interest.
Returns
diff --git a/openmc/macroscopic.py b/openmc/macroscopic.py
index 1dd087903f..9f55998e3a 100644
--- a/openmc/macroscopic.py
+++ b/openmc/macroscopic.py
@@ -30,7 +30,7 @@ class Macroscopic(object):
self._name = ''
self._xs = None
- # Set the Material class attributes
+ # Set the Macroscopic class attributes
self.name = name
if xs is not None:
diff --git a/openmc/mesh.py b/openmc/mesh.py
index 169e7705cc..58b9c7c0e5 100644
--- a/openmc/mesh.py
+++ b/openmc/mesh.py
@@ -6,6 +6,7 @@ import sys
import numpy as np
import openmc.checkvalue as cv
+import openmc
if sys.version_info[0] >= 3:
@@ -181,6 +182,33 @@ class Mesh(object):
string += '{0: <16}{1}{2}\n'.format('\tPixels', '=\t', self._width)
return string
+ def cell_generator(self):
+ """Generator function to traverse through every [i,j,k] index
+ of the mesh.
+
+ For example the following code:
+ for mesh_index in mymesh.cell_generator():
+ print mesh_index
+
+ will produce the following output for a 3-D 2x2x2 mesh in mymesh:
+ [1, 1, 1]
+ [1, 1, 2]
+ [1, 2, 1]
+ [1, 2, 2]
+ ...
+
+ """
+
+ if len(self.dimension) == 2:
+ for x in range(self.dimension[0]):
+ for y in range(self.dimension[1]):
+ yield [x + 1, y + 1, 1]
+ else:
+ for x in range(self.dimension[0]):
+ for y in range(self.dimension[1]):
+ for z in range(self.dimension[2]):
+ yield [x + 1, y + 1, z + 1]
+
def get_mesh_xml(self):
"""Return XML representation of the mesh
@@ -210,3 +238,99 @@ class Mesh(object):
subelement.text = ' '.join(map(str, self._width))
return element
+
+ def build_cells(self, bc=['reflective'] * 6):
+ """Generates a lattice of universes with the same dimensionality
+ as the mesh object. The individual cells/universes produced
+ will not have material definitions applied and so downstream code
+ will have to apply that information.
+
+ Parameters
+ ----------
+ bc : iterable of {'reflective', 'periodic', 'transmission', or 'vacuum'}
+ Boundary conditions for each of the four faces of a rectangle
+ (if aplying to a 2D mesh) or six faces of a parallelepiped
+ (if applying to a 3D mesh) provided in the following order:
+ [x min, x max, y min, y max, z min, z max]. 2-D cells do not
+ contain the z min and z max entries.
+
+ Returns
+ -------
+ root_cell : openmc.Cell
+ The cell containing the lattice representing the mesh geometry;
+ this cell is a single parallelepiped with boundaries matching
+ the outermost mesh boundary with the boundary conditions from bc
+ applied.
+ cells : iterable of openmc.Cell
+ The list of cells within each lattice position mimicking the mesh
+ geometry.
+
+ """
+
+ twod = len(self.dimension) == 2
+ cv.check_length('bc', bc, length_min=4, length_max=6)
+ for entry in bc:
+ cv.check_value('bc', entry, ['transmission', 'vacuum',
+ 'reflective', 'periodic'])
+
+ # Build the cell which will contain the lattice
+ xplanes = [openmc.XPlane(x0=self.lower_left[0],
+ boundary_type=bc[0]),
+ openmc.XPlane(x0=self.upper_right[0],
+ boundary_type=bc[1])]
+ yplanes = [openmc.YPlane(y0=self.lower_left[1],
+ boundary_type=bc[2]),
+ openmc.YPlane(y0=self.upper_right[1],
+ boundary_type=bc[3])]
+ if twod:
+ zplanes = [openmc.ZPlane(z0=np.finfo(np.float).min,
+ boundary_type='reflective'),
+ openmc.ZPlane(z0=np.finfo(np.float).max,
+ boundary_type='reflective')]
+ else:
+ zplanes = [openmc.ZPlane(z0=self.lower_left[2],
+ boundary_type=bc[4]),
+ openmc.ZPlane(z0=self.upper_right[2],
+ boundary_type=bc[5])]
+ root_cell = openmc.Cell()
+ root_cell.region = ((+xplanes[0] & -xplanes[1]) &
+ (+yplanes[0] & -yplanes[1]) &
+ (+zplanes[0] & -zplanes[1]))
+
+ # Build the universes which will be used for each of the [i,j,k]
+ # locations within the mesh.
+ # We will also have to build cells to assign to these universes
+ universes = np.ndarray(self.dimension[::-1], dtype=np.object)
+ cells = []
+ for [i, j, k] in self.cell_generator():
+ if twod:
+ universes[j - 1, i - 1] = openmc.Universe()
+ cells.append(openmc.Cell())
+ universes[j - 1, i - 1].add_cells([cells[-1]])
+ else:
+ universes[k - 1, j - 1, i - 1] = openmc.Universe()
+ cells.append(openmc.Cell())
+ universes[k - 1, j - 1, i - 1].add_cells([cells[-1]])
+
+ lattice = openmc.RectLattice()
+ lattice.lower_left = self.lower_left
+
+ if self.width is not None:
+ lattice.pitch = self.width
+ else:
+ dx = ((self.upper_right[0] - self.lower_left[0]) /
+ self.dimension[0])
+ dy = ((self.upper_right[1] - self.lower_left[1]) /
+ self.dimension[1])
+ if twod:
+ lattice.pitch = [dx, dy]
+ else:
+ dz = ((self.upper_right[2] - self.lower_left[2]) /
+ self.dimension[2])
+ lattice.pitch = [dx, dy, dz]
+ lattice.universes = universes
+
+ # Fill Cell with the Lattice
+ root_cell.fill = lattice
+
+ return root_cell, cells
diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py
index bf1195f1a9..9e5dba310c 100644
--- a/openmc/mgxs/library.py
+++ b/openmc/mgxs/library.py
@@ -823,7 +823,7 @@ class Library(object):
def get_xsdata(self, domain, xsdata_name, nuclide='total', xs_type='macro',
xs_id='1m', order=None, tabular_legendre=None,
- tabular_points=33):
+ tabular_points=33, subdomain=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).
@@ -859,6 +859,12 @@ class Library(object):
parameter is set to `True`. In this case, this parameter sets the
number of equally-spaced points in the domain of [-1,1] to be used
in building the tabular distribution. Default is `33`.
+ subdomain : iterable of int
+ This parameter is not used unless using a mesh domain. In that
+ case, the subdomain is an [i,j,k] index (1-based indexing) of the
+ mesh cell of interest in the openmc.Mesh object. Note:
+ this parameter currently only supports subdomains within a mesh,
+ and not the subdomains of a distribcell.
Returns
-------
@@ -878,7 +884,7 @@ class Library(object):
"""
cv.check_type('domain', domain, (openmc.Material, openmc.Cell,
- openmc.Cell, openmc.Mesh))
+ openmc.Universe, openmc.Mesh))
cv.check_type('xsdata_name', xsdata_name, basestring)
cv.check_type('nuclide', nuclide, basestring)
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
@@ -891,6 +897,9 @@ class Library(object):
(type(None), bool))
if tabular_points is not None:
cv.check_greater_than('tabular_points', tabular_points, 1)
+ if subdomain is not None:
+ cv.check_iterable_type('subdomain', subdomain, Integral,
+ max_depth=3)
# Make sure statepoint has been loaded
if self._sp_filename is None:
@@ -926,52 +935,66 @@ class Library(object):
xsdata.zaid = self._nuclides[nuclide][0]
xsdata.awr = self._nuclides[nuclide][1]
+ if subdomain is None:
+ subdomain = 'all'
+ else:
+ subdomain = [subdomain]
+
# Now get xs data itself
if 'nu-transport' in self.mgxs_types and self.correction == 'P0':
mymgxs = self.get_mgxs(domain, 'nu-transport')
- xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide])
+ xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide],
+ subdomains=subdomain)
elif 'total' in self.mgxs_types:
mymgxs = self.get_mgxs(domain, 'total')
- xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide])
+ xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide],
+ subdomain=subdomain)
if 'absorption' in self.mgxs_types:
mymgxs = self.get_mgxs(domain, 'absorption')
xsdata.set_absorption_mgxs(mymgxs, xs_type=xs_type,
- nuclide=[nuclide])
+ nuclide=[nuclide],
+ subdomain=subdomain)
if 'fission' in self.mgxs_types:
mymgxs = self.get_mgxs(domain, 'fission')
xsdata.set_fission_mgxs(mymgxs, xs_type=xs_type,
- nuclide=[nuclide])
+ nuclide=[nuclide], subdomain=subdomain)
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])
+ nuclide=[nuclide],
+ subdomain=subdomain)
# For chi and nu-fission we can either have only a nu-fission matrix
# provided, or vectors of chi and nu-fission provided
if 'nu-fission matrix' in self.mgxs_types:
mymgxs = self.get_mgxs(domain, 'nu-fission matrix')
xsdata.set_nu_fission_mgxs(mymgxs, xs_type=xs_type,
- nuclide=[nuclide])
+ nuclide=[nuclide],
+ subdomain=subdomain)
else:
if 'chi' in self.mgxs_types:
mymgxs = self.get_mgxs(domain, 'chi')
- xsdata.set_chi_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide])
+ xsdata.set_chi_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide],
+ subdomain=subdomain)
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])
+ nuclide=[nuclide],
+ subdomain=subdomain)
# If multiplicity matrix is available, prefer that
if 'multiplicity matrix' in self.mgxs_types:
mymgxs = self.get_mgxs(domain, 'multiplicity matrix')
xsdata.set_multiplicity_mgxs(mymgxs, xs_type=xs_type,
- nuclide=[nuclide])
+ nuclide=[nuclide],
+ subdomain=subdomain)
using_multiplicity = True
- # multiplicity wil fall back to using scatter and nu-scatter
+ # multiplicity will fall back to using scatter and nu-scatter
elif ((('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])
+ xs_type=xs_type, nuclide=[nuclide],
+ subdomain=subdomain)
using_multiplicity = True
else:
using_multiplicity = False
@@ -979,12 +1002,13 @@ class Library(object):
if using_multiplicity:
nuscatt_mgxs = self.get_mgxs(domain, 'nu-scatter matrix')
xsdata.set_scatter_mgxs(nuscatt_mgxs, xs_type=xs_type,
- nuclide=[nuclide])
+ nuclide=[nuclide], subdomain=subdomain)
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])
+ nuclide=[nuclide],
+ subdomain=subdomain)
# Since we are not using multiplicity, then
# scattering multiplication (nu-scatter) must be
@@ -1055,15 +1079,6 @@ class Library(object):
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
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
- # of strings.
- xs_ids = [xs_ids for i in range(len(self.domains))]
- else:
- cv.check_iterable_type('xs_ids', xs_ids, basestring)
- else:
- xs_ids = ['1m' for i in range(len(self.domains))]
# If gathering material-specific data, set the xs_type to macro
if not self.by_nuclide:
@@ -1072,32 +1087,78 @@ class Library(object):
# Initialize file
mgxs_file = openmc.MGXSLibrary(self.energy_groups)
- # Create the xsdata object and add it to the mgxs_file
- for i, domain in enumerate(self.domains):
- if self.by_nuclide:
- nuclides = domain.get_nuclides()
+ # Get the number of domains to size arrays with
+ if self.domain_type is 'mesh':
+ num_domains = np.sum(d.num_mesh_cells for d in self.domains)
+ else:
+ num_domains = len(self.domains)
+
+ # Set id names
+ if xs_ids is not None:
+ if isinstance(xs_ids, basestring):
+ # If we only have a string lets convert it now to a list
+ # of strings.
+ all_xs_ids = [xs_ids] * num_domains
else:
- nuclides = ['total']
- for nuclide in nuclides:
- # Build & add metadata to XSdata object
- if xsdata_names is None:
- xsdata_name = 'set' + str(i + 1)
+ cv.check_iterable_type('xs_ids', xs_ids, basestring)
+ cv.check_length('xs_ids', xs_ids, num_domains, num_domains)
+ all_xs_ids = xs_ids
+
+ else:
+ all_xs_ids = ['1m'] * num_domains
+
+ if self.domain_type == 'mesh':
+ # Create the xsdata objects and add to the mgxs_file
+ i = 0
+ for domain in self.domains:
+ if self.by_nuclide:
+ raise NotImplementedError("Mesh domains do not currently "
+ "support nuclidic tallies")
+ for subdomain in domain.cell_generator():
+ # Build & add metadata to XSdata object
+ if xsdata_names is None:
+ xsdata_name = 'set' + str(i + 1)
+ else:
+ xsdata_name = xsdata_names[i]
+
+ # Create XSdata and Macroscopic for this domain
+ xsdata = self.get_xsdata(domain, xsdata_name,
+ xs_id=all_xs_ids[i],
+ tabular_legendre=tabular_legendre,
+ tabular_points=tabular_points,
+ subdomain=subdomain)
+ mgxs_file.add_xsdata(xsdata)
+ i += 1
+
+ else:
+ # Create the xsdata object and add it to the mgxs_file
+ for i, domain in enumerate(self.domains):
+ if self.by_nuclide:
+ nuclides = domain.get_nuclides()
else:
- xsdata_name = xsdata_names[i]
- if nuclide is not 'total':
- xsdata_name += '_' + nuclide
+ nuclides = ['total']
+ for nuclide in nuclides:
+ # Build & add metadata to XSdata object
+ if xsdata_names is None:
+ xsdata_name = 'set' + str(i + 1)
+ else:
+ xsdata_name = xsdata_names[i]
+ if nuclide is not 'total':
+ xsdata_name += '_' + nuclide
- xsdata = self.get_xsdata(domain, xsdata_name, nuclide=nuclide,
- xs_type=xs_type, xs_id=xs_ids[i],
- tabular_legendre=tabular_legendre,
- tabular_points=tabular_points)
+ xsdata = self.get_xsdata(domain, xsdata_name,
+ nuclide=nuclide, xs_type=xs_type,
+ xs_id=all_xs_ids[i],
+ tabular_legendre=tabular_legendre,
+ tabular_points=tabular_points)
- mgxs_file.add_xsdata(xsdata)
+ mgxs_file.add_xsdata(xsdata)
return mgxs_file
def create_mg_mode(self, xsdata_names=None, xs_ids=None,
- tabular_legendre=None, tabular_points=33):
+ tabular_legendre=None, tabular_points=33,
+ bc=['reflective'] * 6):
"""Creates an openmc.MGXSLibrary object to contain the MGXS data for the
Multi-Group mode of OpenMC as well as the associated openmc.Materials
and openmc.Geometry objects. The created Geometry is the same as that
@@ -1127,6 +1188,12 @@ class Library(object):
parameter is set to `True`. In this case, this parameter sets the
number of equally-spaced points in the domain of [-1,1] to be used
in building the tabular distribution. Default is `33`.
+ bc : iterable of {'reflective', 'periodic', 'transmission', or 'vacuum'}
+ Boundary conditions for each of the four faces of a rectangle
+ (if applying to a 2D mesh) or six faces of a parallelepiped
+ (if applying to a 3D mesh) provided in the following order:
+ [x min, x max, y min, y max, z min, z max]. 2-D cells do not
+ contain the z min and z max entries.
Returns
-------
@@ -1157,62 +1224,77 @@ class Library(object):
# multi-group cross section types
self.check_library_for_openmc_mgxs()
- 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
- # of strings.
- xs_ids = [xs_ids for i in range(len(self.domains))]
- else:
- cv.check_iterable_type('xs_ids', xs_ids, basestring)
+ # If the domain type is a mesh, then there can only be one domain for
+ # this method. This is because we can build a model automatically if
+ # the user provided multiple mesh domains for library generation since
+ # the multiple meshes could be overlapping or in disparate regions
+ # of the continuous energy model. The next step makes sure there is
+ # only one before continuing.
+ if self.domain_type == 'mesh':
+ cv.check_length("domains", self.domains, 1, 1)
+
+ # Get the MGXS File Data
+ mgxs_file = self.create_mg_library('macro', xsdata_names, xs_ids,
+ tabular_legendre, tabular_points)
+
+ # Now move on the creating the geometry and assigning materials
+ if self.domain_type == 'mesh':
+ root = openmc.Universe(name='root', universe_id=0)
+
+ # Add cells representative of the mesh with reflective BC
+ root_cell, cells = \
+ self.domains[0].build_cells(bc)
+ root.add_cell(root_cell)
+ geometry = openmc.Geometry()
+ geometry.root_universe = root
+ materials = openmc.Materials()
+
+ for i, subdomain in enumerate(self.domains[0].cell_generator()):
+ xsdata = mgxs_file.xsdatas[i]
+ [name, id] = xsdata.name.split('.')
+ # Build the macroscopic and assign it to the cell of
+ # interest
+ macroscopic = openmc.Macroscopic(name=name, xs=id)
+
+ # Create Material and add to collection
+ material = openmc.Material(name=xsdata.name)
+ material.add_macroscopic(macroscopic)
+ materials.append(material)
+
+ # Set the materials for each of the universes
+ cells[i].fill = materials[i]
+
else:
- xs_ids = ['1m' for i in range(len(self.domains))]
- xs_type = 'macro'
+ # Create a copy of the Geometry for these Macroscopics
+ geometry = copy.deepcopy(self.openmc_geometry)
+ materials = openmc.Materials()
- # Initialize MGXS File
- mgxs_file = openmc.MGXSLibrary(self.energy_groups)
+ # Get all Cells from the Geometry for differentiation
+ all_cells = geometry.get_all_material_cells()
- # Create a copy of the Geometry to differentiate for these Macroscopics
- geometry = copy.deepcopy(self.openmc_geometry)
- materials = openmc.Materials()
+ # Create the xsdata object and add it to the mgxs_file
+ for i, domain in enumerate(self.domains):
+ xsdata = mgxs_file.xsdatas[i]
+ [name, id] = xsdata.name.split('.')
- # Get all Cells from the Geometry for differentiation
- all_cells = geometry.get_all_material_cells()
+ macroscopic = openmc.Macroscopic(name=name, xs=id)
- # Create the xsdata object and add it to the mgxs_file
- for i, domain in enumerate(self.domains):
+ # Create Material and add to collection
+ material = openmc.Material(name=xsdata.name)
+ material.add_macroscopic(macroscopic)
+ materials.append(material)
- # Build & add metadata to XSdata object
- if xsdata_names is None:
- xsdata_name = 'set' + str(i + 1)
- else:
- xsdata_name = xsdata_names[i]
+ # Differentiate Geometry with new Material
+ if self.domain_type == 'material':
+ # Fill all appropriate Cells with new Material
+ for cell in all_cells:
+ if cell.fill.id == domain.id:
+ cell.fill = material
- # Create XSdata and Macroscopic for this domain
- xsdata = self.get_xsdata(domain, xsdata_name, nuclide='total',
- xs_type=xs_type, xs_id=xs_ids[i],
- tabular_legendre=tabular_legendre,
- tabular_points=tabular_points)
- mgxs_file.add_xsdata(xsdata)
- macroscopic = openmc.Macroscopic(name=xsdata_name, xs=xs_ids[i])
-
- # Create Material and add to collection
- material = openmc.Material(name=xsdata_name + '.' + xs_ids[i])
- material.add_macroscopic(macroscopic)
- materials.append(material)
-
- # Differentiate Geometry with new Material
- if self.domain_type == 'material':
- # Fill all appropriate Cells with new Material
- for cell in all_cells:
- if cell.fill.id == domain.id:
- cell.fill = material
-
- elif self.domain_type == 'cell':
- for cell in all_cells:
- if cell.id == domain.id:
- cell.fill = material
+ elif self.domain_type == 'cell':
+ for cell in all_cells:
+ if cell.id == domain.id:
+ cell.fill = material
return mgxs_file, materials, geometry
diff --git a/openmc/mgxs/mdgxs.py b/openmc/mgxs/mdgxs.py
index 0a2f898c07..5e5d840b6c 100644
--- a/openmc/mgxs/mdgxs.py
+++ b/openmc/mgxs/mdgxs.py
@@ -793,7 +793,8 @@ class MDGXS(MGXS):
df.rename(columns={'energyout low [MeV]': 'group out'},
inplace=True)
- out_groups = np.tile(all_groups, int(df.shape[0] / all_groups.size))
+ out_groups = np.repeat(all_groups, self.xs_tally.num_scores)
+ out_groups = np.tile(out_groups, int(df.shape[0] / out_groups.size))
df['group out'] = out_groups
del df['energyout high [MeV]']
columns = ['group in', 'group out']
diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py
index 5d12be0b0a..de7475308c 100644
--- a/openmc/mgxs/mgxs.py
+++ b/openmc/mgxs/mgxs.py
@@ -548,12 +548,6 @@ class MGXS(object):
float
The atomic number density (atom/b-cm) for the nuclide of interest
- Raises
- -------
- ValueError
- When the density is requested for a nuclide which is not found in
- the spatial domain.
-
"""
cv.check_type('nuclide', nuclide, basestring)
@@ -561,13 +555,7 @@ class MGXS(object):
# Get list of all nuclides in the spatial domain
nuclides = self.domain.get_nuclide_densities()
- if nuclide not in nuclides:
- msg = 'Unable to get density for nuclide "{0}" which is not in ' \
- '{1} "{2}"'.format(nuclide, self.domain_type, self.domain.id)
- ValueError(msg)
-
- density = nuclides[nuclide][1]
- return density
+ return nuclides[nuclide][1] if nuclide in nuclides else 0.0
def get_nuclide_densities(self, nuclides='all'):
"""Get an array of atomic number densities in units of atom/b-cm for all
@@ -789,7 +777,8 @@ class MGXS(object):
# Construct a collection of the domain filter bins
if not isinstance(subdomains, basestring):
- cv.check_iterable_type('subdomains', subdomains, Integral, max_depth=3)
+ cv.check_iterable_type('subdomains', subdomains, Integral,
+ max_depth=3)
for subdomain in subdomains:
filters.append(self.domain_type)
filter_bins.append((subdomain,))
@@ -1535,7 +1524,8 @@ class MGXS(object):
df.rename(columns={'energyout low [MeV]': 'group out'},
inplace=True)
- out_groups = np.tile(all_groups, int(df.shape[0] / all_groups.size))
+ out_groups = np.repeat(all_groups, self.xs_tally.num_scores)
+ out_groups = np.tile(out_groups, int(df.shape[0] / out_groups.size))
df['group out'] = out_groups
del df['energyout high [MeV]']
columns = ['group in', 'group out']
@@ -1573,6 +1563,10 @@ class MGXS(object):
df['mean'] /= np.tile(densities, tile_factor)
df['std. dev.'] /= np.tile(densities, tile_factor)
+ # Replace NaNs by zeros (happens if nuclide density is zero)
+ df['mean'].replace(np.nan, 0.0, inplace=True)
+ df['std. dev.'].replace(np.nan, 0.0, inplace=True)
+
# Sort the dataframe by domain type id (e.g., distribcell id) and
# energy groups such that data is from fast to thermal
if self.domain_type == 'mesh':
diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py
index 6f8188b101..a3a2187b75 100644
--- a/openmc/mgxs_library.py
+++ b/openmc/mgxs_library.py
@@ -603,7 +603,8 @@ class XSdata(object):
if np.sum(self._nu_fission) > 0.0:
self._fissionable = True
- def set_total_mgxs(self, total, nuclide='total', xs_type='macro'):
+ def set_total_mgxs(self, total, nuclide='total', xs_type='macro',
+ subdomain='all'):
"""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.
@@ -619,6 +620,9 @@ class XSdata(object):
xs_type: {'macro', 'micro'}
Provide the macro or micro cross section in units of cm^-1 or
barns. Defaults to 'macro'.
+ subdomain : iterable of int
+ If the MGXS contains a mesh domain type, the subdomain parameter
+ specifies which mesh cell (i.e., [i, j, k] index) to use.
See also
--------
@@ -631,16 +635,17 @@ class XSdata(object):
openmc.mgxs.TransportXS))
check_value('energy_groups', total.energy_groups, [self.energy_groups])
check_value('domain_type', total.domain_type,
- ['universe', 'cell', 'material'])
+ ['universe', 'cell', 'material', 'mesh'])
if self.representation is 'isotropic':
- self._total = total.get_xs(nuclides=nuclide, xs_type=xs_type)
+ self._total = total.get_xs(nuclides=nuclide, xs_type=xs_type,
+ subdomains=subdomain)
elif self.representation is 'angle':
msg = 'Angular-Dependent MGXS have not yet been implemented'
raise ValueError(msg)
def set_absorption_mgxs(self, absorption, nuclide='total',
- xs_type='macro'):
+ xs_type='macro', subdomain=None):
"""This method allows for an openmc.mgxs.AbsorptionXS
to be used to set the absorption cross section for this XSdata object.
@@ -655,6 +660,9 @@ class XSdata(object):
xs_type: {'macro', 'micro'}
Provide the macro or micro cross section in units of cm^-1 or
barns. Defaults to 'macro'.
+ subdomain : iterable of int
+ If the MGXS contains a mesh domain type, the subdomain parameter
+ specifies which mesh cell (i.e., [i, j, k] index) to use.
See also
--------
@@ -667,16 +675,18 @@ class XSdata(object):
check_value('energy_groups', absorption.energy_groups,
[self.energy_groups])
check_value('domain_type', absorption.domain_type,
- ['universe', 'cell', 'material'])
+ ['universe', 'cell', 'material', 'mesh'])
if self.representation is 'isotropic':
self._absorption = absorption.get_xs(nuclides=nuclide,
- xs_type=xs_type)
+ xs_type=xs_type,
+ subdomains=subdomain)
elif self.representation is 'angle':
msg = 'Angular-Dependent MGXS have not yet been implemented'
raise ValueError(msg)
- def set_fission_mgxs(self, fission, nuclide='total', xs_type='macro'):
+ def set_fission_mgxs(self, fission, nuclide='total', xs_type='macro',
+ subdomain=None):
"""This method allows for an openmc.mgxs.FissionXS
to be used to set the fission cross section for this XSdata object.
@@ -691,6 +701,9 @@ class XSdata(object):
xs_type: {'macro', 'micro'}
Provide the macro or micro cross section in units of cm^-1 or
barns. Defaults to 'macro'.
+ subdomain : iterable of int
+ If the MGXS contains a mesh domain type, the subdomain parameter
+ specifies which mesh cell (i.e., [i, j, k] index) to use.
See also
--------
@@ -703,17 +716,18 @@ class XSdata(object):
check_value('energy_groups', fission.energy_groups,
[self.energy_groups])
check_value('domain_type', fission.domain_type,
- ['universe', 'cell', 'material'])
+ ['universe', 'cell', 'material', 'mesh'])
if self.representation is 'isotropic':
self._fission = fission.get_xs(nuclides=nuclide,
- xs_type=xs_type)
+ xs_type=xs_type,
+ subdomains=subdomain)
elif self.representation is 'angle':
msg = 'Angular-Dependent MGXS have not yet been implemented'
raise ValueError(msg)
def set_nu_fission_mgxs(self, nu_fission, nuclide='total',
- xs_type='macro'):
+ xs_type='macro', subdomain=None):
"""This method allows for an openmc.mgxs.NuFissionXS
to be used to set the nu-fission cross section for this XSdata object.
@@ -728,6 +742,9 @@ class XSdata(object):
xs_type: {'macro', 'micro'}
Provide the macro or micro cross section in units of cm^-1 or
barns. Defaults to 'macro'.
+ subdomain : iterable of int
+ If the MGXS contains a mesh domain type, the subdomain parameter
+ specifies which mesh cell (i.e., [i, j, k] index) to use.
See also
--------
@@ -741,11 +758,12 @@ class XSdata(object):
check_value('energy_groups', nu_fission.energy_groups,
[self.energy_groups])
check_value('domain_type', nu_fission.domain_type,
- ['universe', 'cell', 'material'])
+ ['universe', 'cell', 'material', 'mesh'])
if self.representation is 'isotropic':
self._nu_fission = nu_fission.get_xs(nuclides=nuclide,
- xs_type=xs_type)
+ xs_type=xs_type,
+ subdomains=subdomain)
elif self.representation is 'angle':
msg = 'Angular-Dependent MGXS have not yet been implemented'
raise ValueError(msg)
@@ -759,7 +777,7 @@ class XSdata(object):
self._fissionable = True
def set_kappa_fission_mgxs(self, k_fission, nuclide='total',
- xs_type='macro'):
+ xs_type='macro', subdomain=None):
"""This method allows for an openmc.mgxs.KappaFissionXS
to be used to set the kappa-fission cross section for this XSdata
object.
@@ -775,6 +793,9 @@ class XSdata(object):
xs_type: {'macro', 'micro'}
Provide the macro or micro cross section in units of cm^-1 or
barns. Defaults to 'macro'.
+ subdomain : iterable of int
+ If the MGXS contains a mesh domain type, the subdomain parameter
+ specifies which mesh cell (i.e., [i, j, k] index) to use.
See also
--------
@@ -787,16 +808,18 @@ class XSdata(object):
check_value('energy_groups', k_fission.energy_groups,
[self.energy_groups])
check_value('domain_type', k_fission.domain_type,
- ['universe', 'cell', 'material'])
+ ['universe', 'cell', 'material', 'mesh'])
if self.representation is 'isotropic':
self._kappa_fission = k_fission.get_xs(nuclides=nuclide,
- xs_type=xs_type)
+ xs_type=xs_type,
+ subdomains=subdomain)
elif self.representation is 'angle':
msg = 'Angular-Dependent MGXS have not yet been implemented'
raise ValueError(msg)
- def set_chi_mgxs(self, chi, nuclide='total', xs_type='macro'):
+ def set_chi_mgxs(self, chi, nuclide='total', xs_type='macro',
+ subdomain=None):
"""This method allows for an openmc.mgxs.Chi
to be used to set chi for this XSdata object.
@@ -810,6 +833,9 @@ class XSdata(object):
xs_type: {'macro', 'micro'}
Provide the macro or micro cross section in units of cm^-1 or
barns. Defaults to 'macro'.
+ subdomain : iterable of int
+ If the MGXS contains a mesh domain type, the subdomain parameter
+ specifies which mesh cell (i.e., [i, j, k] index) to use.
See also
--------
@@ -827,11 +853,11 @@ class XSdata(object):
check_type('chi', chi, openmc.mgxs.Chi)
check_value('energy_groups', chi.energy_groups, [self.energy_groups])
check_value('domain_type', chi.domain_type,
- ['universe', 'cell', 'material'])
+ ['universe', 'cell', 'material', 'mesh'])
if self.representation is 'isotropic':
self._chi = chi.get_xs(nuclides=nuclide,
- xs_type=xs_type)
+ xs_type=xs_type, subdomains=subdomain)
elif self.representation is 'angle':
msg = 'Angular-Dependent MGXS have not yet been implemented'
raise ValueError(msg)
@@ -839,7 +865,8 @@ class XSdata(object):
if self.use_chi is not None:
self.use_chi = True
- def set_scatter_mgxs(self, scatter, nuclide='total', xs_type='macro'):
+ def set_scatter_mgxs(self, scatter, nuclide='total', xs_type='macro',
+ subdomain=None):
"""This method allows for an openmc.mgxs.ScatterMatrixXS
to be used to set the scatter matrix cross section for this XSdata
object. If the XSdata.order attribute has not yet been set, then
@@ -856,6 +883,9 @@ class XSdata(object):
xs_type: {'macro', 'micro'}
Provide the macro or micro cross section in units of cm^-1 or
barns. Defaults to 'macro'.
+ subdomain : iterable of int
+ If the MGXS contains a mesh domain type, the subdomain parameter
+ specifies which mesh cell (i.e., [i, j, k] index) to use.
See also
--------
@@ -868,7 +898,7 @@ class XSdata(object):
check_value('energy_groups', scatter.energy_groups,
[self.energy_groups])
check_value('domain_type', scatter.domain_type,
- ['universe', 'cell', 'material'])
+ ['universe', 'cell', 'material', 'mesh'])
if self.scatt_type != 'legendre':
msg = 'Anisotropic scattering representations other than ' \
@@ -892,16 +922,16 @@ class XSdata(object):
self.energy_groups.num_groups,
self.energy_groups.num_groups))
for moment in range(self.num_orders):
- self._scatter[moment, :, :] = scatter.get_xs(nuclides=nuclide,
- xs_type=xs_type,
- moment=moment)
+ self._scatter[moment, :, :] = \
+ scatter.get_xs(nuclides=nuclide, xs_type=xs_type,
+ moment=moment, subdomains=subdomain)
elif self.representation is 'angle':
msg = 'Angular-Dependent MGXS have not yet been implemented'
raise ValueError(msg)
def set_multiplicity_mgxs(self, nuscatter, scatter=None, nuclide='total',
- xs_type='macro'):
+ xs_type='macro', subdomain=None):
"""This method allows for either the direct use of only an
openmc.mgxs.MultiplicityMatrixXS OR an openmc.mgxs.NuScatterMatrixXS and
openmc.mgxs.ScatterMatrixXS to be used to set the scattering
@@ -926,6 +956,9 @@ class XSdata(object):
xs_type: {'macro', 'micro'}
Provide the macro or micro cross section in units of cm^-1 or
barns. Defaults to 'macro'.
+ subdomain : iterable of int
+ If the MGXS contains a mesh domain type, the subdomain parameter
+ specifies which mesh cell (i.e., [i, j, k] index) to use.
See also
--------
@@ -939,7 +972,7 @@ class XSdata(object):
check_value('energy_groups', nuscatter.energy_groups,
[self.energy_groups])
check_value('domain_type', nuscatter.domain_type,
- ['universe', 'cell', 'material'])
+ ['universe', 'cell', 'material', 'mesh'])
if scatter is not None:
check_type('scatter', scatter, openmc.mgxs.ScatterMatrixXS)
if isinstance(nuscatter, openmc.mgxs.MultiplicityMatrixXS):
@@ -950,16 +983,18 @@ class XSdata(object):
check_value('energy_groups', scatter.energy_groups,
[self.energy_groups])
check_value('domain_type', scatter.domain_type,
- ['universe', 'cell', 'material'])
+ ['universe', 'cell', 'material', 'mesh'])
if self.representation is 'isotropic':
nuscatt = nuscatter.get_xs(nuclides=nuclide,
- xs_type=xs_type, moment=0)
+ xs_type=xs_type, moment=0,
+ subdomains=subdomain)
if isinstance(nuscatter, openmc.mgxs.MultiplicityMatrixXS):
self._multiplicity = nuscatt
else:
scatt = scatter.get_xs(nuclides=nuclide,
- xs_type=xs_type, moment=0)
+ xs_type=xs_type, moment=0,
+ subdomains=subdomain)
self._multiplicity = np.divide(nuscatt, scatt)
elif self.representation is 'angle':
msg = 'Angular-Dependent MGXS have not yet been implemented'
@@ -1085,6 +1120,10 @@ class MGXSLibrary(object):
def energy_groups(self):
return self._energy_groups
+ @property
+ def xsdatas(self):
+ return self._xsdatas
+
@inverse_velocities.setter
def inverse_velocities(self, inverse_velocities):
check_type('inverse_velocities', inverse_velocities, Iterable, Real)
diff --git a/openmc/opencg_compatible.py b/openmc/opencg_compatible.py
index 58ce0d0c29..8983f5fa05 100644
--- a/openmc/opencg_compatible.py
+++ b/openmc/opencg_compatible.py
@@ -997,13 +997,17 @@ def get_opencg_geometry(openmc_geometry):
return opencg_geometry
-def get_openmc_geometry(opencg_geometry):
+def get_openmc_geometry(opencg_geometry, compatible=False):
"""Return an OpenMC geometry corresponding to an OpenCG geometry.
Parameters
----------
opencg_geometry : opencg.Geometry
OpenCG geometry
+ compatible : bool
+ Whether the OpenCG geometry is compatible with OpenMC's geometric
+ primitives. This should be set to False if the OpenCG geometry
+ uses SquarePrism surfaces. False by default.
Returns
-------
@@ -1019,9 +1023,6 @@ def get_openmc_geometry(opencg_geometry):
opencg_geometry.assign_auto_ids()
opencg_geometry = copy.deepcopy(opencg_geometry)
- # Update Cell bounding boxes in Geometry
- opencg_geometry.update_bounding_boxes()
-
# Clear dictionaries and auto-generated ID
OPENMC_SURFACES.clear()
OPENCG_SURFACES.clear()
@@ -1033,12 +1034,13 @@ def get_openmc_geometry(opencg_geometry):
OPENCG_LATTICES.clear()
# Make the entire geometry "compatible" before assigning auto IDs
- universes = opencg_geometry.get_all_universes()
- for universe in universes.values():
- if not isinstance(universe, opencg.Lattice):
- make_opencg_cells_compatible(universe)
+ if not compatible:
+ universes = opencg_geometry.get_all_universes()
+ for universe in universes.values():
+ if not isinstance(universe, opencg.Lattice):
+ make_opencg_cells_compatible(universe)
- opencg_geometry.assign_auto_ids()
+ opencg_geometry.assign_auto_ids()
opencg_root_universe = opencg_geometry.root_universe
openmc_root_universe = get_openmc_universe(opencg_root_universe)
diff --git a/openmc/volume.py b/openmc/volume.py
index e9b1dac1d3..2a2a92f61e 100644
--- a/openmc/volume.py
+++ b/openmc/volume.py
@@ -1,6 +1,7 @@
from collections import Iterable, Mapping
from numbers import Real, Integral
from xml.etree import ElementTree as ET
+from warnings import warn
import numpy as np
import pandas as pd
@@ -68,10 +69,26 @@ class VolumeCalculation(object):
self.samples = samples
if lower_left is not None:
- self.lower_left = lower_left
if upper_right is None:
raise ValueError('Both lower-left and upper-right coordinates '
'should be specified')
+
+ # For cell domains, try to compute bounding box and make sure
+ # user-specified one is valid
+ if self.domain_type == 'cell':
+ for c in domains:
+ if c.region is None:
+ continue
+ ll, ur = c.region.bounding_box
+ if np.any(np.isinf(ll)) or np.any(np.isinf(ur)):
+ continue
+ if (np.any(np.asarray(lower_left) > ll) or
+ np.any(np.asarray(upper_right) < ur)):
+ warn("Specified bounding box is smaller than computed "
+ "bounding box for cell {}. Volume calculation may "
+ "be incorrect!".format(c.id))
+
+ self.lower_left = lower_left
self.upper_right = upper_right
else:
if self.domain_type == 'cell':
diff --git a/src/constants.F90 b/src/constants.F90
index 182be97725..6d5f2fc107 100644
--- a/src/constants.F90
+++ b/src/constants.F90
@@ -54,7 +54,8 @@ module constants
! Maximum number of external source spatial resamples to encounter before an
! error is thrown.
- integer, parameter :: MAX_EXTSRC_RESAMPLES = 10000
+ integer, parameter :: EXTSRC_REJECT_THRESHOLD = 10000
+ real(8), parameter :: EXTSRC_REJECT_FRACTION = 0.05
! ============================================================================
! PHYSICAL CONSTANTS
diff --git a/src/relaxng/settings.rnc b/src/relaxng/settings.rnc
index e23cbdd6cd..742e137738 100644
--- a/src/relaxng/settings.rnc
+++ b/src/relaxng/settings.rnc
@@ -153,7 +153,7 @@ element settings {
attribute lower_left { list { xsd:double+ } }) &
(element upper_right { list { xsd:double+ } } |
attribute upper_right { list { xsd:double+ } })
- }+ &
+ }* &
element uniform_fs{
(element dimension { list { xsd:positiveInteger+ } } |
diff --git a/src/relaxng/settings.rng b/src/relaxng/settings.rng
index 38acea5985..39bed4a62f 100644
--- a/src/relaxng/settings.rng
+++ b/src/relaxng/settings.rng
@@ -625,7 +625,7 @@
-
+
@@ -694,7 +694,7 @@
-
+
diff --git a/src/source.F90 b/src/source.F90
index 194c8c6add..452d8ddfce 100644
--- a/src/source.F90
+++ b/src/source.F90
@@ -107,7 +107,8 @@ contains
real(8) :: r(3) ! sampled coordinates
logical :: found ! Does the source particle exist within geometry?
type(Particle) :: p ! Temporary particle for using find_cell
- integer, save :: num_resamples = 0 ! Number of resamples encountered
+ integer, save :: n_accept = 0 ! Number of samples accepted
+ integer, save :: n_reject = 0 ! Number of samples rejected
! Set weight to one by default
site % wgt = ONE
@@ -143,13 +144,6 @@ contains
! Now search to see if location exists in geometry
call find_cell(p, found)
- if (.not. found) then
- num_resamples = num_resamples + 1
- if (num_resamples == MAX_EXTSRC_RESAMPLES) then
- call fatal_error("Maximum number of external source spatial &
- &resamples reached!")
- end if
- end if
! Check if spatial site is in fissionable material
select type (space => external_source(i) % space)
@@ -162,8 +156,21 @@ contains
end if
end if
end select
+
+ ! Check for rejection
+ if (.not. found) then
+ n_reject = n_reject + 1
+ if (n_reject >= EXTSRC_REJECT_THRESHOLD .and. &
+ real(n_accept, 8)/n_reject <= EXTSRC_REJECT_FRACTION) then
+ call fatal_error("More than 95% of external source sites sampled &
+ &were rejected. Please check your external source definition.")
+ end if
+ end if
end do
+ ! Increment number of accepted samples
+ n_accept = n_accept + 1
+
call p % clear()
! Sample angle
diff --git a/tests/test_mgxs_library_no_nuclides/results_true.dat b/tests/test_mgxs_library_no_nuclides/results_true.dat
index 3563f141b1..edd99b44c5 100644
--- a/tests/test_mgxs_library_no_nuclides/results_true.dat
+++ b/tests/test_mgxs_library_no_nuclides/results_true.dat
@@ -29,39 +29,39 @@
1 10000 1 total 0.385188 0.026946
0 10000 2 total 0.412389 0.015425
material group in group out nuclide moment mean std. dev.
-9 10000 1 1 total P0 -0.000207 0.000149
-11 10000 1 1 total P1 0.000234 0.000128
-13 10000 1 1 total P2 0.051870 0.006983
+12 10000 1 1 total P0 0.384199 0.027001
+13 10000 1 1 total P1 0.051870 0.006983
+14 10000 1 1 total P2 0.020069 0.002846
15 10000 1 1 total P3 0.009478 0.002234
8 10000 1 2 total P0 0.000989 0.000482
-10 10000 1 2 total P1 -0.000103 0.000184
-12 10000 1 2 total P2 0.384199 0.027001
-14 10000 1 2 total P3 0.020069 0.002846
-1 10000 2 1 total P0 0.016482 0.004502
-3 10000 2 1 total P1 -0.010499 0.010438
-5 10000 2 1 total P2 -0.000768 0.000768
+9 10000 1 2 total P1 -0.000207 0.000149
+10 10000 1 2 total P2 -0.000103 0.000184
+11 10000 1 2 total P3 0.000234 0.000128
+4 10000 2 1 total P0 0.000925 0.000925
+5 10000 2 1 total P1 -0.000768 0.000768
+6 10000 2 1 total P2 0.000494 0.000494
7 10000 2 1 total P3 -0.000171 0.000172
0 10000 2 2 total P0 0.411465 0.015245
-2 10000 2 2 total P1 0.006371 0.010551
-4 10000 2 2 total P2 0.000925 0.000925
-6 10000 2 2 total P3 0.000494 0.000494
+1 10000 2 2 total P1 0.016482 0.004502
+2 10000 2 2 total P2 0.006371 0.010551
+3 10000 2 2 total P3 -0.010499 0.010438
material group in group out nuclide moment mean std. dev.
-9 10000 1 1 total P0 -0.000207 0.000149
-11 10000 1 1 total P1 0.000234 0.000128
-13 10000 1 1 total P2 0.051870 0.006983
+12 10000 1 1 total P0 0.384199 0.027001
+13 10000 1 1 total P1 0.051870 0.006983
+14 10000 1 1 total P2 0.020069 0.002846
15 10000 1 1 total P3 0.009478 0.002234
8 10000 1 2 total P0 0.000989 0.000482
-10 10000 1 2 total P1 -0.000103 0.000184
-12 10000 1 2 total P2 0.384199 0.027001
-14 10000 1 2 total P3 0.020069 0.002846
-1 10000 2 1 total P0 0.016482 0.004502
-3 10000 2 1 total P1 -0.010499 0.010438
-5 10000 2 1 total P2 -0.000768 0.000768
+9 10000 1 2 total P1 -0.000207 0.000149
+10 10000 1 2 total P2 -0.000103 0.000184
+11 10000 1 2 total P3 0.000234 0.000128
+4 10000 2 1 total P0 0.000925 0.000925
+5 10000 2 1 total P1 -0.000768 0.000768
+6 10000 2 1 total P2 0.000494 0.000494
7 10000 2 1 total P3 -0.000171 0.000172
0 10000 2 2 total P0 0.411465 0.015245
-2 10000 2 2 total P1 0.006371 0.010551
-4 10000 2 2 total P2 0.000925 0.000925
-6 10000 2 2 total P3 0.000494 0.000494
+1 10000 2 2 total P1 0.016482 0.004502
+2 10000 2 2 total P2 0.006371 0.010551
+3 10000 2 2 total P3 -0.010499 0.010438
material group in group out nuclide mean std. dev.
3 10000 1 1 total 1.0 0.078516
2 10000 1 2 total 1.0 0.687184
@@ -154,39 +154,39 @@
1 10001 1 total 0.310121 0.033788
0 10001 2 total 0.296264 0.043792
material group in group out nuclide moment mean std. dev.
-9 10001 1 1 total P0 0.000000 0.000000
-11 10001 1 1 total P1 0.000000 0.000000
-13 10001 1 1 total P2 0.038230 0.008484
+12 10001 1 1 total P0 0.310121 0.033788
+13 10001 1 1 total P1 0.038230 0.008484
+14 10001 1 1 total P2 0.020745 0.004696
15 10001 1 1 total P3 0.007964 0.003732
8 10001 1 2 total P0 0.000000 0.000000
-10 10001 1 2 total P1 0.000000 0.000000
-12 10001 1 2 total P2 0.310121 0.033788
-14 10001 1 2 total P3 0.020745 0.004696
-1 10001 2 1 total P0 -0.011214 0.016180
-3 10001 2 1 total P1 -0.003270 0.007329
-5 10001 2 1 total P2 0.000000 0.000000
+9 10001 1 2 total P1 0.000000 0.000000
+10 10001 1 2 total P2 0.000000 0.000000
+11 10001 1 2 total P3 0.000000 0.000000
+4 10001 2 1 total P0 0.000000 0.000000
+5 10001 2 1 total P1 0.000000 0.000000
+6 10001 2 1 total P2 0.000000 0.000000
7 10001 2 1 total P3 0.000000 0.000000
0 10001 2 2 total P0 0.296264 0.043792
-2 10001 2 2 total P1 0.008837 0.011504
-4 10001 2 2 total P2 0.000000 0.000000
-6 10001 2 2 total P3 0.000000 0.000000
+1 10001 2 2 total P1 -0.011214 0.016180
+2 10001 2 2 total P2 0.008837 0.011504
+3 10001 2 2 total P3 -0.003270 0.007329
material group in group out nuclide moment mean std. dev.
-9 10001 1 1 total P0 0.000000 0.000000
-11 10001 1 1 total P1 0.000000 0.000000
-13 10001 1 1 total P2 0.038230 0.008484
+12 10001 1 1 total P0 0.310121 0.033788
+13 10001 1 1 total P1 0.038230 0.008484
+14 10001 1 1 total P2 0.020745 0.004696
15 10001 1 1 total P3 0.007964 0.003732
8 10001 1 2 total P0 0.000000 0.000000
-10 10001 1 2 total P1 0.000000 0.000000
-12 10001 1 2 total P2 0.310121 0.033788
-14 10001 1 2 total P3 0.020745 0.004696
-1 10001 2 1 total P0 -0.011214 0.016180
-3 10001 2 1 total P1 -0.003270 0.007329
-5 10001 2 1 total P2 0.000000 0.000000
+9 10001 1 2 total P1 0.000000 0.000000
+10 10001 1 2 total P2 0.000000 0.000000
+11 10001 1 2 total P3 0.000000 0.000000
+4 10001 2 1 total P0 0.000000 0.000000
+5 10001 2 1 total P1 0.000000 0.000000
+6 10001 2 1 total P2 0.000000 0.000000
7 10001 2 1 total P3 0.000000 0.000000
0 10001 2 2 total P0 0.296264 0.043792
-2 10001 2 2 total P1 0.008837 0.011504
-4 10001 2 2 total P2 0.000000 0.000000
-6 10001 2 2 total P3 0.000000 0.000000
+1 10001 2 2 total P1 -0.011214 0.016180
+2 10001 2 2 total P2 0.008837 0.011504
+3 10001 2 2 total P3 -0.003270 0.007329
material group in group out nuclide mean std. dev.
3 10001 1 1 total 1.0 0.108779
2 10001 1 2 total 0.0 0.000000
@@ -279,39 +279,39 @@
1 10002 1 total 0.671269 0.026186
0 10002 2 total 2.035388 0.258060
material group in group out nuclide moment mean std. dev.
-9 10002 1 1 total P0 0.008758 0.000926
-11 10002 1 1 total P1 -0.003785 0.000817
-13 10002 1 1 total P2 0.381167 0.016243
+12 10002 1 1 total P0 0.639901 0.024709
+13 10002 1 1 total P1 0.381167 0.016243
+14 10002 1 1 total P2 0.152392 0.008156
15 10002 1 1 total P3 0.009148 0.003889
8 10002 1 2 total P0 0.031368 0.001728
-10 10002 1 2 total P1 -0.002568 0.001014
-12 10002 1 2 total P2 0.639901 0.024709
-14 10002 1 2 total P3 0.152392 0.008156
-1 10002 2 1 total P0 0.509941 0.051236
-3 10002 2 1 total P1 0.024988 0.008312
-5 10002 2 1 total P2 0.000400 0.000401
+9 10002 1 2 total P1 0.008758 0.000926
+10 10002 1 2 total P2 -0.002568 0.001014
+11 10002 1 2 total P3 -0.003785 0.000817
+4 10002 2 1 total P0 0.000443 0.000445
+5 10002 2 1 total P1 0.000400 0.000401
+6 10002 2 1 total P2 0.000320 0.000321
7 10002 2 1 total P3 0.000214 0.000215
0 10002 2 2 total P0 2.034945 0.257800
-2 10002 2 2 total P1 0.111175 0.013020
-4 10002 2 2 total P2 0.000443 0.000445
-6 10002 2 2 total P3 0.000320 0.000321
+1 10002 2 2 total P1 0.509941 0.051236
+2 10002 2 2 total P2 0.111175 0.013020
+3 10002 2 2 total P3 0.024988 0.008312
material group in group out nuclide moment mean std. dev.
-9 10002 1 1 total P0 0.008758 0.000926
-11 10002 1 1 total P1 -0.003785 0.000817
-13 10002 1 1 total P2 0.381167 0.016243
+12 10002 1 1 total P0 0.639901 0.024709
+13 10002 1 1 total P1 0.381167 0.016243
+14 10002 1 1 total P2 0.152392 0.008156
15 10002 1 1 total P3 0.009148 0.003889
8 10002 1 2 total P0 0.031368 0.001728
-10 10002 1 2 total P1 -0.002568 0.001014
-12 10002 1 2 total P2 0.639901 0.024709
-14 10002 1 2 total P3 0.152392 0.008156
-1 10002 2 1 total P0 0.509941 0.051236
-3 10002 2 1 total P1 0.024988 0.008312
-5 10002 2 1 total P2 0.000400 0.000401
+9 10002 1 2 total P1 0.008758 0.000926
+10 10002 1 2 total P2 -0.002568 0.001014
+11 10002 1 2 total P3 -0.003785 0.000817
+4 10002 2 1 total P0 0.000443 0.000445
+5 10002 2 1 total P1 0.000400 0.000401
+6 10002 2 1 total P2 0.000320 0.000321
7 10002 2 1 total P3 0.000214 0.000215
0 10002 2 2 total P0 2.034945 0.257800
-2 10002 2 2 total P1 0.111175 0.013020
-4 10002 2 2 total P2 0.000443 0.000445
-6 10002 2 2 total P3 0.000320 0.000321
+1 10002 2 2 total P1 0.509941 0.051236
+2 10002 2 2 total P2 0.111175 0.013020
+3 10002 2 2 total P3 0.024988 0.008312
material group in group out nuclide mean std. dev.
3 10002 1 1 total 1.0 0.038609
2 10002 1 2 total 1.0 0.067667
diff --git a/tests/test_mgxs_library_nuclides/results_true.dat b/tests/test_mgxs_library_nuclides/results_true.dat
index d3e3235ccc..3da8146042 100644
--- a/tests/test_mgxs_library_nuclides/results_true.dat
+++ b/tests/test_mgxs_library_nuclides/results_true.dat
@@ -1 +1 @@
-8142ae4e107002a835999e4ace85c17376f262a7059fc224f3756a2de19aba6ca4c4fa14ca2085c87d7729aa8d6d6f78fdae21ac6dfe33ca303449c769076074
\ No newline at end of file
+e494320a213b5704a2ac915a2ba504857be91961ceb6735b6ad05d81eb31c44c9584d5bd9d40baececf1dcb5b030e6ecec63cfbd20639baf69bcb596c5c46591
\ No newline at end of file