mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 05:35:49 -04:00
Merge pull request #741 from samuelshaner/element-wo
Natural element expansion for wo and uranium enrichment option
This commit is contained in:
commit
244da85bb8
32 changed files with 700 additions and 1561 deletions
File diff suppressed because one or more lines are too long
|
|
@ -105,19 +105,6 @@ standard deviation.
|
|||
|
||||
*Default*: false
|
||||
|
||||
.. _cross_sections:
|
||||
|
||||
``<cross_sections>`` Element
|
||||
----------------------------
|
||||
|
||||
The ``<cross_sections>`` element has no attributes and simply indicates the path
|
||||
to an XML cross section listing file (usually named cross_sections.xml). If this
|
||||
element is absent from the settings.xml file, the
|
||||
:envvar:`OPENMC_CROSS_SECTIONS` environment variable will be used to find the
|
||||
path to the XML cross section listing when in continuous-energy mode, and the
|
||||
:envvar:`OPENMC_MG_CROSS_SECTIONS` environment variable will be used in
|
||||
multi-group mode.
|
||||
|
||||
``<cutoff>`` Element
|
||||
--------------------
|
||||
|
||||
|
|
@ -289,20 +276,6 @@ based on the recommended value in LA-UR-14-24530_.
|
|||
|
||||
.. note:: This element is not used in the multi-group :ref:`energy_mode`.
|
||||
|
||||
.. _multipole_library:
|
||||
|
||||
``<multipole_library>`` Element
|
||||
-------------------------------
|
||||
|
||||
The ``<multipole_library>`` element indicates the directory containing a
|
||||
windowed multipole library. If a windowed multipole library is available,
|
||||
OpenMC can use it for on-the-fly Doppler-broadening of resolved resonance range
|
||||
cross sections. If this element is absent from the settings.xml file, the
|
||||
:envvar:`OPENMC_MULTIPOLE_LIBRARY` environment variable will be used.
|
||||
|
||||
.. note:: The <temperature_multipole> element must also be set to "true" for
|
||||
windowed multipole functionality.
|
||||
|
||||
``<max_order>`` Element
|
||||
---------------------------
|
||||
|
||||
|
|
@ -316,29 +289,6 @@ then, OpenMC will only use up to the :math:`P_1` data.
|
|||
.. note:: This element is not used in the continuous-energy
|
||||
:ref:`energy_mode`.
|
||||
|
||||
.. _natural_elements:
|
||||
|
||||
``<natural_elements>`` Element
|
||||
------------------------------
|
||||
|
||||
The ``<natural_elements>`` element indicates to OpenMC what nuclides are
|
||||
available in the cross section library when expanding an ``<element>`` into
|
||||
separate isotopes (see :ref:`material`). The accepted values are:
|
||||
|
||||
- ENDF/B-VII.0
|
||||
- ENDF/B-VII.1
|
||||
- JEFF-3.1.1
|
||||
- JEFF-3.1.2
|
||||
- JEFF-3.2
|
||||
- JENDL-3.2
|
||||
- JENDL-3.3
|
||||
- JENDL-4.0
|
||||
|
||||
Note that the value is case-insensitive, so "ENDF/B-VII.1" is equivalent to
|
||||
"endf/b-vii.1".
|
||||
|
||||
*Default*: ENDF/B-VII.1
|
||||
|
||||
``<no_reduce>`` Element
|
||||
-----------------------
|
||||
|
||||
|
|
@ -1368,6 +1318,33 @@ Here is an example of a properly defined 2d hexagonal lattice:
|
|||
Materials Specification -- materials.xml
|
||||
----------------------------------------
|
||||
|
||||
.. _cross_sections:
|
||||
|
||||
``<cross_sections>`` Element
|
||||
----------------------------
|
||||
|
||||
The ``<cross_sections>`` element has no attributes and simply indicates the path
|
||||
to an XML cross section listing file (usually named cross_sections.xml). If this
|
||||
element is absent from the settings.xml file, the
|
||||
:envvar:`OPENMC_CROSS_SECTIONS` environment variable will be used to find the
|
||||
path to the XML cross section listing when in continuous-energy mode, and the
|
||||
:envvar:`OPENMC_MG_CROSS_SECTIONS` environment variable will be used in
|
||||
multi-group mode.
|
||||
|
||||
.. _multipole_library:
|
||||
|
||||
``<multipole_library>`` Element
|
||||
-------------------------------
|
||||
|
||||
The ``<multipole_library>`` element indicates the directory containing a
|
||||
windowed multipole library. If a windowed multipole library is available,
|
||||
OpenMC can use it for on-the-fly Doppler-broadening of resolved resonance range
|
||||
cross sections. If this element is absent from the settings.xml file, the
|
||||
:envvar:`OPENMC_MULTIPOLE_LIBRARY` environment variable will be used.
|
||||
|
||||
.. note:: The <temperature_multipole> element must also be set to "true" for
|
||||
windowed multipole functionality.
|
||||
|
||||
.. _material:
|
||||
|
||||
``<material>`` Element
|
||||
|
|
@ -1440,43 +1417,6 @@ Each ``material`` element can have the following attributes or sub-elements:
|
|||
.. note:: The ``scattering`` attribute/sub-element is not used in the
|
||||
multi-group :ref:`energy_mode`.
|
||||
|
||||
:element:
|
||||
|
||||
Specifies that a natural element is present in the material. The natural
|
||||
element is split up into individual isotopes based on `IUPAC Isotopic
|
||||
Compositions of the Elements 2009`_. This element has
|
||||
attributes/sub-elements called ``name``, and ``ao``. The ``name``
|
||||
attribute is the atomic symbol of the element. Finally, the ``ao``
|
||||
attribute specifies the atom percent of the element within the material,
|
||||
respectively. One example would be as follows:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<element name="Al" ao="8.7115e-03" />
|
||||
<element name="Mg" ao="1.5498e-04" />
|
||||
<element name="Mn" ao="2.7426e-05" />
|
||||
<element name="Cu" ao="1.6993e-04" />
|
||||
|
||||
In some cross section libraries, certain naturally occurring isotopes do not
|
||||
have cross sections. The :ref:`natural_elements` option determines how a
|
||||
natural element is split into isotopes in these cases.
|
||||
|
||||
*Default*: None
|
||||
|
||||
An optional attribute/sub-element for each element is ``scattering``. This
|
||||
attribute may be set to "data" to use the scattering laws specified by the
|
||||
cross section library (default). Alternatively, when set to "iso-in-lab",
|
||||
the scattering laws are used to sample the outgoing energy but an
|
||||
isotropic-in-lab distribution is used to sample the outgoing angle at each
|
||||
scattering interaction. The ``scattering`` attribute may be most useful
|
||||
when using OpenMC to compute multi-group cross-sections for deterministic
|
||||
transport codes and to quantify the effects of anisotropic scattering.
|
||||
|
||||
*Default*: None
|
||||
|
||||
.. note:: The ``scattering`` attribute/sub-element is not used in the
|
||||
multi-group :ref:`energy_mode`.
|
||||
|
||||
:sab:
|
||||
Associates an S(a,b) table with the material. This element has one
|
||||
attribute/sub-element called ``name``. The ``name`` attribute
|
||||
|
|
@ -1503,9 +1443,6 @@ Each ``material`` element can have the following attributes or sub-elements:
|
|||
|
||||
*Default*: None
|
||||
|
||||
.. _IUPAC Isotopic Compositions of the Elements 2009:
|
||||
http://pac.iupac.org/publications/pac/pdf/2011/pdf/8302x0397.pdf
|
||||
|
||||
------------------------------------
|
||||
Tallies Specification -- tallies.xml
|
||||
------------------------------------
|
||||
|
|
|
|||
|
|
@ -45,18 +45,14 @@ sn119 = openmc.Nuclide('Sn119')
|
|||
sn120 = openmc.Nuclide('Sn120')
|
||||
sn122 = openmc.Nuclide('Sn122')
|
||||
sn124 = openmc.Nuclide('Sn124')
|
||||
u234 = openmc.Nuclide('U234')
|
||||
u235 = openmc.Nuclide('U235')
|
||||
u238 = openmc.Nuclide('U238')
|
||||
u = openmc.Element('U')
|
||||
o = openmc.Element('O')
|
||||
|
||||
# Instantiate some Materials and register the appropriate Nuclides
|
||||
uo2 = openmc.Material(material_id=1, name='UO2 fuel at 2.4% wt enrichment')
|
||||
uo2.set_density('g/cm3', 10.29769)
|
||||
uo2.add_nuclide(u234, 4.4843e-6)
|
||||
uo2.add_nuclide(u235, 5.5815e-4)
|
||||
uo2.add_nuclide(u238, 2.2408e-2)
|
||||
uo2.add_nuclide(o16, 4.5829e-2)
|
||||
uo2.add_nuclide(o17, 1.1164e-4)
|
||||
uo2.add_element(u, 1., enrichment=0.024)
|
||||
uo2.add_element(o, 2.)
|
||||
|
||||
helium = openmc.Material(material_id=2, name='Helium for gap')
|
||||
helium.set_density('g/cm3', 0.001598)
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ water.add_macroscopic(h2o_data)
|
|||
|
||||
# Instantiate a Materials collection and export to XML
|
||||
materials_file = openmc.Materials([uo2, water])
|
||||
materials_file.cross_sections = "./mgxs.h5"
|
||||
materials_file.export_to_xml()
|
||||
|
||||
|
||||
|
|
@ -132,7 +133,6 @@ 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 = "./mgxs.h5"
|
||||
settings_file.batches = batches
|
||||
settings_file.inactive = inactive
|
||||
settings_file.particles = particles
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<materials>
|
||||
|
||||
<cross_sections>./mgxs.h5</cross_sections>
|
||||
|
||||
<!-- UO2 -->
|
||||
<material id="1">
|
||||
<density units="macro" value="1.0" />
|
||||
|
|
|
|||
|
|
@ -34,6 +34,4 @@
|
|||
|
||||
<survival_biasing>false</survival_biasing>
|
||||
|
||||
<cross_sections>./mgxs.h5</cross_sections>
|
||||
|
||||
</settings>
|
||||
|
|
|
|||
|
|
@ -1,17 +1,21 @@
|
|||
from collections import OrderedDict
|
||||
import re
|
||||
import sys
|
||||
import os
|
||||
|
||||
from six import string_types
|
||||
from xml.etree import ElementTree as ET
|
||||
|
||||
import openmc
|
||||
from openmc.checkvalue import check_type, check_length
|
||||
from openmc.data import NATURAL_ABUNDANCE
|
||||
from openmc.data import NATURAL_ABUNDANCE, atomic_mass
|
||||
|
||||
|
||||
class Element(object):
|
||||
"""A natural element used in a material via <element>. Internally, OpenMC will
|
||||
expand the natural element into isotopes based on the known natural
|
||||
abundances.
|
||||
"""A natural element that auto-expands to add the isotopes of an element to
|
||||
a material in their natural abundance. Internally, the OpenMC Python API
|
||||
expands the natural element into isotopes only when the materials.xml file
|
||||
is created.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
@ -83,16 +87,37 @@ class Element(object):
|
|||
@scattering.setter
|
||||
def scattering(self, scattering):
|
||||
|
||||
if not scattering in ['data', 'iso-in-lab']:
|
||||
msg = 'Unable to set scattering for Element to {0} ' \
|
||||
'which is not "data" or "iso-in-lab"'.format(scattering)
|
||||
if not scattering in ['data', 'iso-in-lab', None]:
|
||||
msg = 'Unable to set scattering for Element to {0} which ' \
|
||||
'is not "data", "iso-in-lab", or None'.format(scattering)
|
||||
raise ValueError(msg)
|
||||
|
||||
self._scattering = scattering
|
||||
|
||||
def expand(self):
|
||||
def expand(self, percent, percent_type, enrichment=None,
|
||||
cross_sections=None):
|
||||
"""Expand natural element into its naturally-occurring isotopes.
|
||||
|
||||
An optional cross_sections argument or the OPENMC_CROSS_SECTIONS
|
||||
environment variable is used to specify a cross_sections.xml file.
|
||||
If the cross_sections.xml file is found, the element is expanded only
|
||||
into the isotopes/nuclides present in cross_sections.xml. If no
|
||||
cross_sections.xml file is found, the element is expanded based on its
|
||||
naturally occurring isotopes.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
percent : float
|
||||
Atom or weight percent
|
||||
percent_type : {'ao', 'wo'}
|
||||
'ao' for atom percent and 'wo' for weight percent
|
||||
enrichment : float, optional
|
||||
Enrichment for U235 in weight percent. For example, input 4.95 for
|
||||
4.95 weight percent enriched U. Default is None
|
||||
(natural composition).
|
||||
cross_sections : str, optional
|
||||
Location of cross_sections.xml file. Default is None.
|
||||
|
||||
Returns
|
||||
-------
|
||||
isotopes : list
|
||||
|
|
@ -102,9 +127,133 @@ class Element(object):
|
|||
|
||||
"""
|
||||
|
||||
# Get the nuclides present in nature
|
||||
natural_nuclides = set()
|
||||
for nuclide in sorted(NATURAL_ABUNDANCE.keys()):
|
||||
if re.match(r'{}\d+'.format(self.name), nuclide):
|
||||
natural_nuclides.add(nuclide)
|
||||
|
||||
# Create dict to store the expanded nuclides and abundances
|
||||
abundances = OrderedDict()
|
||||
|
||||
# If cross_sections is None, get the cross sections from the
|
||||
# OPENMC_CROSS_SECTIONS environment variable
|
||||
if cross_sections is None:
|
||||
cross_sections = os.environ.get('OPENMC_CROSS_SECTIONS')
|
||||
|
||||
# If a cross_sections library is present, check natural nuclides
|
||||
# against the nuclides in the library
|
||||
if cross_sections is not None:
|
||||
|
||||
library_nuclides = set()
|
||||
tree = ET.parse(cross_sections)
|
||||
root = tree.getroot()
|
||||
for child in root:
|
||||
nuclide = child.attrib['materials']
|
||||
if re.match(r'{}\d+'.format(self.name), nuclide) and \
|
||||
'_m' not in nuclide:
|
||||
library_nuclides.add(nuclide)
|
||||
|
||||
# Get a set of the mutual and absent nuclides. Convert to lists
|
||||
# and sort to avoid different ordering between Python 2 and 3.
|
||||
mutual_nuclides = natural_nuclides.intersection(library_nuclides)
|
||||
absent_nuclides = natural_nuclides.difference(mutual_nuclides)
|
||||
mutual_nuclides = sorted(list(mutual_nuclides))
|
||||
absent_nuclides = sorted(list(absent_nuclides))
|
||||
|
||||
# If all natural nuclides are present in the library, expand element
|
||||
# using all natural nuclides
|
||||
if len(absent_nuclides) == 0:
|
||||
for nuclide in mutual_nuclides:
|
||||
abundances[nuclide] = NATURAL_ABUNDANCE[nuclide]
|
||||
|
||||
# If no natural elements are present in the library, check if the
|
||||
# 0 nuclide is present. If so, set the abundance to 1 for this
|
||||
# nuclide. Else, raise an error.
|
||||
elif len(mutual_nuclides) == 0:
|
||||
nuclide_0 = self.name + '0'
|
||||
if nuclide_0 in library_nuclides:
|
||||
abundances[nuclide_0] = 1.0
|
||||
else:
|
||||
msg = 'Unable to expand element {0} because the cross '\
|
||||
'section library provided does not contain any of '\
|
||||
'the natural isotopes for that element.'\
|
||||
.format(self.name)
|
||||
raise ValueError(msg)
|
||||
|
||||
# If some, but not all, natural nuclides are in the library, add
|
||||
# the mutual nuclides. For the absent nuclides, add them based on
|
||||
# our knowledge of the common cross section libraries
|
||||
# (ENDF, JEFF, and JENDL)
|
||||
else:
|
||||
|
||||
# Add the mutual isotopes
|
||||
for nuclide in mutual_nuclides:
|
||||
abundances[nuclide] = NATURAL_ABUNDANCE[nuclide]
|
||||
|
||||
# Adjust the abundances for the absent nuclides
|
||||
for nuclide in absent_nuclides:
|
||||
|
||||
if nuclide in ['O17', 'O18'] and 'O16' in mutual_nuclides:
|
||||
abundances['O16'] += NATURAL_ABUNDANCE[nuclide]
|
||||
elif nuclide == 'Ta180' and 'Ta181' in mutual_nuclides:
|
||||
abundances['Ta181'] += NATURAL_ABUNDANCE[nuclide]
|
||||
elif nuclide == 'W180' and 'W182' in mutual_nuclides:
|
||||
abundances['W182'] += NATURAL_ABUNDANCE[nuclide]
|
||||
else:
|
||||
msg = 'Unsure how to partition natural abundance of ' \
|
||||
'isotope {0} into other natural isotopes of ' \
|
||||
'this element that are present in the cross ' \
|
||||
'section library provided. Consider adding ' \
|
||||
'the isotopes of this element individually.'
|
||||
raise ValueError(msg)
|
||||
|
||||
# If a cross_section library is not present, expand the element into
|
||||
# its natural nuclides
|
||||
else:
|
||||
for nuclide in natural_nuclides:
|
||||
abundances[nuclide] = NATURAL_ABUNDNACE[nuclide]
|
||||
|
||||
# Modify mole fractions if enrichment provided
|
||||
if enrichment is not None:
|
||||
|
||||
# Calculate the mass fractions of isotopes
|
||||
abundances['U234'] = 0.008 * enrichment
|
||||
abundances['U235'] = enrichment
|
||||
abundances['U238'] = 100.0 - 1.008 * enrichment
|
||||
|
||||
# Convert the mass fractions to mole fractions
|
||||
for nuclide in abundances.keys():
|
||||
abundances[nuclide] /= atomic_mass(nuclide)
|
||||
|
||||
# Normalize the mole fractions to one
|
||||
sum_abundances = sum(abundances.values())
|
||||
for nuclide in abundances.keys():
|
||||
abundances[nuclide] /= sum_abundances
|
||||
|
||||
# Compute the ratio of the nuclide atomic masses to the element
|
||||
# atomic mass
|
||||
if percent_type == 'wo':
|
||||
|
||||
# Compute the element atomic mass
|
||||
element_am = 0.
|
||||
for nuclide in abundances.keys():
|
||||
element_am += atomic_mass(nuclide) * abundances[nuclide]
|
||||
|
||||
# Convert the molar fractions to mass fractions
|
||||
for nuclide in abundances.keys():
|
||||
abundances[nuclide] *= atomic_mass(nuclide) / element_am
|
||||
|
||||
# Normalize the mass fractions to one
|
||||
sum_abundances = sum(abundances.values())
|
||||
for nuclide in abundances.keys():
|
||||
abundances[nuclide] /= sum_abundances
|
||||
|
||||
# Create a list of the isotopes in this element
|
||||
isotopes = []
|
||||
for isotope, abundance in sorted(NATURAL_ABUNDANCE.items()):
|
||||
if re.match(r'{}\d+'.format(self.name), isotope):
|
||||
nuc = openmc.Nuclide(isotope)
|
||||
isotopes.append((nuc, abundance))
|
||||
for nuclide, abundance in abundances.items():
|
||||
nuc = openmc.Nuclide(nuclide)
|
||||
nuc.scattering = self.scattering
|
||||
isotopes.append((nuc, percent*abundance, percent_type))
|
||||
|
||||
return isotopes
|
||||
|
|
|
|||
|
|
@ -57,9 +57,9 @@ class Material(object):
|
|||
'atom/b-cm', 'atom/cm3', 'sum', or 'macro'. The 'macro' unit only
|
||||
applies in the case of a multi-group calculation.
|
||||
elements : list of tuple
|
||||
List in which each item is a 3-tuple consisting of an
|
||||
:class:`openmc.Element` instance, the percent density, and the percent
|
||||
type ('ao' or 'wo').
|
||||
List in which each item is a 4-tuple consisting of an
|
||||
:class:`openmc.Element` instance, the percent density, the percent
|
||||
type ('ao' or 'wo'), and enrichment.
|
||||
nuclides : list of tuple
|
||||
List in which each item is a 3-tuple consisting of an
|
||||
:class:`openmc.Nuclide` instance, the percent density, and the percent
|
||||
|
|
@ -82,7 +82,7 @@ class Material(object):
|
|||
# (only one is allowed, hence this is different than _nuclides, etc)
|
||||
self._macroscopic = None
|
||||
|
||||
# A list of tuples (element, percent, percent type)
|
||||
# A list of tuples (element, percent, percent type, enrichment)
|
||||
self._elements = []
|
||||
|
||||
# If specified, a list of table names
|
||||
|
|
@ -148,9 +148,13 @@ class Material(object):
|
|||
|
||||
string += '{0: <16}\n'.format('\tElements')
|
||||
|
||||
for element, percent, percent_type in self._elements:
|
||||
for element, percent, percent_type, enr in self._elements:
|
||||
string += '{0: <16}'.format('\t{0.name}'.format(element))
|
||||
string += '=\t{0: <12} [{1}]\n'.format(percent, percent_type)
|
||||
if enr is None:
|
||||
string += '=\t{0: <12} [{1}]\n'.format(percent, percent_type)
|
||||
else:
|
||||
string += '=\t{0: <12} [{1}] @ {2} w/o enrichment\n'\
|
||||
.format(percent, percent_type, enr)
|
||||
|
||||
return string
|
||||
|
||||
|
|
@ -401,7 +405,7 @@ class Material(object):
|
|||
if macroscopic.name == self._macroscopic.name:
|
||||
self._macroscopic = None
|
||||
|
||||
def add_element(self, element, percent, percent_type='ao', expand=False):
|
||||
def add_element(self, element, percent, percent_type='ao', enrichment=None):
|
||||
"""Add a natural element to the material
|
||||
|
||||
Parameters
|
||||
|
|
@ -413,9 +417,10 @@ class Material(object):
|
|||
percent_type : {'ao', 'wo'}, optional
|
||||
'ao' for atom percent and 'wo' for weight percent. Defaults to atom
|
||||
percent.
|
||||
expand : bool, optional
|
||||
Whether to expand the natural element into its naturally-occurring
|
||||
isotopes. Defaults to False.
|
||||
enrichment : float, optional
|
||||
Enrichment for U235 in weight percent. For example, input 4.95 for
|
||||
4.95 weight percent enriched U. Default is None
|
||||
(natural composition).
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -445,14 +450,33 @@ class Material(object):
|
|||
else:
|
||||
element = openmc.Element(element)
|
||||
|
||||
if expand:
|
||||
if percent_type == 'wo':
|
||||
raise NotImplementedError('Expanding natural element based on '
|
||||
'weight percent is not yet supported.')
|
||||
for isotope, abundance in element.expand():
|
||||
self._nuclides.append((isotope, percent*abundance, percent_type))
|
||||
else:
|
||||
self._elements.append((element, percent, percent_type))
|
||||
if enrichment is not None:
|
||||
if not isinstance(enrichment, Real):
|
||||
msg = 'Unable to add an Element to Material ID="{0}" with a ' \
|
||||
'non-floating point enrichment value "{1}"'\
|
||||
.format(self._id, enrichment)
|
||||
raise ValueError(msg)
|
||||
|
||||
elif element.name != 'U':
|
||||
msg = 'Unable to use enrichment for element {0} which is not ' \
|
||||
'uranium for Material ID="{1}"'.format(element.name,
|
||||
self._id)
|
||||
raise ValueError(msg)
|
||||
|
||||
# Check that the enrichment is in the valid range
|
||||
cv.check_less_than('enrichment', enrichment, 100./1.008)
|
||||
cv.check_greater_than('enrichment', enrichment, 0., equality=True)
|
||||
|
||||
if enrichment > 5.0:
|
||||
msg = 'A uranium enrichment of {0} was given for Material ID='\
|
||||
'"{1}". OpenMC assumes the U234/U235 mass ratio is '\
|
||||
'constant at 0.008, which is only valid at low ' \
|
||||
'enrichments. Consider setting the isotopic ' \
|
||||
'composition manually for enrichments over 5%.'.\
|
||||
format(enrichment, self._id)
|
||||
warnings.warn(msg)
|
||||
|
||||
self._elements.append((element, percent, percent_type, enrichment))
|
||||
|
||||
def remove_element(self, element):
|
||||
"""Remove a natural element from the material
|
||||
|
|
@ -469,10 +493,10 @@ class Material(object):
|
|||
'since it is not an Element'.format(self.id, element)
|
||||
raise ValueError(msg)
|
||||
|
||||
# If the Material contains the Nuclide, delete it
|
||||
# If the Material contains the Element, delete it
|
||||
for elm in self._elements:
|
||||
if element == elm:
|
||||
self._nuclides.remove(elm)
|
||||
self._elements.remove(elm)
|
||||
|
||||
def add_s_alpha_beta(self, name):
|
||||
r"""Add an :math:`S(\alpha,\beta)` table to the material
|
||||
|
|
@ -502,7 +526,6 @@ class Material(object):
|
|||
|
||||
self._sab.append(new_name)
|
||||
|
||||
|
||||
def make_isotropic_in_lab(self):
|
||||
for nuclide, percent, percent_type in self._nuclides:
|
||||
nuclide.scattering = 'iso-in-lab'
|
||||
|
|
@ -521,13 +544,15 @@ class Material(object):
|
|||
|
||||
nuclides = []
|
||||
|
||||
for nuclide, density, density_type in self._nuclides:
|
||||
for nuclide, percent, percent_type in self._nuclides:
|
||||
nuclides.append(nuclide.name)
|
||||
|
||||
for element, density, density_type in self._elements:
|
||||
for ele, ele_pct, ele_pct_type, enr in self._elements:
|
||||
|
||||
# Expand natural element into isotopes
|
||||
for isotope, abundance in element.expand():
|
||||
nuclides.append(isotope.name)
|
||||
isotopes = ele.expand(ele_pct, ele_pct_type, enr)
|
||||
for iso, iso_pct, iso_pct_type in isotopes:
|
||||
nuclides.append(iso.name)
|
||||
|
||||
return nuclides
|
||||
|
||||
|
|
@ -537,8 +562,8 @@ class Material(object):
|
|||
Returns
|
||||
-------
|
||||
nuclides : dict
|
||||
Dictionary whose keys are nuclide names and values are 2-tuples of
|
||||
(nuclide, density)
|
||||
Dictionary whose keys are nuclide names and values are 3-tuples of
|
||||
(nuclide, density percent, density percent type)
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -547,10 +572,12 @@ class Material(object):
|
|||
for nuclide, density, density_type in self._nuclides:
|
||||
nuclides[nuclide.name] = (nuclide, density)
|
||||
|
||||
for element, density, density_type in self._elements:
|
||||
for ele, ele_pct, ele_pct_type, enr in self._elements:
|
||||
|
||||
# Expand natural element into isotopes
|
||||
for isotope, abundance in element.expand():
|
||||
nuclides[isotope.name] = (isotope, density*abundance)
|
||||
isotopes = ele.expand(ele_pct, ele_pct_type, enr)
|
||||
for iso, iso_pct, iso_pct_type in isotopes:
|
||||
nuclides[iso.name] = (iso, iso_pct, iso_pct_type)
|
||||
|
||||
return nuclides
|
||||
|
||||
|
|
@ -575,22 +602,20 @@ class Material(object):
|
|||
|
||||
return xml_element
|
||||
|
||||
def _get_element_xml(self, element, distrib=False):
|
||||
xml_element = ET.Element("element")
|
||||
xml_element.set("name", str(element[0].name))
|
||||
def _get_element_xml(self, element, cross_sections, distrib=False):
|
||||
|
||||
if not distrib:
|
||||
if element[2] == 'ao':
|
||||
xml_element.set("ao", str(element[1]))
|
||||
else:
|
||||
xml_element.set("wo", str(element[1]))
|
||||
# Get the nuclides in this element
|
||||
nuclides = element[0].expand(element[1], element[2], element[3],
|
||||
cross_sections)
|
||||
|
||||
if not element[0].scattering is None:
|
||||
xml_element.set("scattering", element[0].scattering)
|
||||
xml_elements = []
|
||||
for nuclide in nuclides:
|
||||
xml_elements.append(self._get_nuclide_xml(nuclide, distrib))
|
||||
|
||||
return xml_element
|
||||
return xml_elements
|
||||
|
||||
def _get_nuclides_xml(self, nuclides, distrib=False):
|
||||
|
||||
xml_elements = []
|
||||
|
||||
for nuclide in nuclides:
|
||||
|
|
@ -598,15 +623,19 @@ class Material(object):
|
|||
|
||||
return xml_elements
|
||||
|
||||
def _get_elements_xml(self, elements, distrib=False):
|
||||
def _get_elements_xml(self, elements, cross_sections, distrib=False):
|
||||
|
||||
xml_elements = []
|
||||
|
||||
for element in elements:
|
||||
xml_elements.append(self._get_element_xml(element, distrib))
|
||||
nuclide_elements = self._get_element_xml(element, cross_sections,
|
||||
distrib)
|
||||
for nuclide_element in nuclide_elements:
|
||||
xml_elements.append(nuclide_element)
|
||||
|
||||
return xml_elements
|
||||
|
||||
def get_material_xml(self):
|
||||
def get_material_xml(self, cross_sections):
|
||||
"""Return XML representation of the material
|
||||
|
||||
Returns
|
||||
|
|
@ -642,7 +671,8 @@ class Material(object):
|
|||
element.append(subelement)
|
||||
|
||||
# Create element XML subelements
|
||||
subelements = self._get_elements_xml(self._elements)
|
||||
subelements = self._get_elements_xml(self._elements,
|
||||
cross_sections)
|
||||
for subelement in subelements:
|
||||
element.append(subelement)
|
||||
else:
|
||||
|
|
@ -656,12 +686,12 @@ class Material(object):
|
|||
comps = []
|
||||
allnucs = self._nuclides + self._elements
|
||||
dist_per_type = allnucs[0][2]
|
||||
for nuc, per, typ in allnucs:
|
||||
if not typ == dist_per_type:
|
||||
for nuc in allnucs:
|
||||
if nuc[2] != dist_per_type:
|
||||
msg = 'All nuclides and elements in a distributed ' \
|
||||
'material must have the same type, either ao or wo'
|
||||
raise ValueError(msg)
|
||||
comps.append(per)
|
||||
comps.append(nuc[1])
|
||||
|
||||
if self._distrib_otf_file is None:
|
||||
# Create values and units subelements
|
||||
|
|
@ -676,12 +706,15 @@ class Material(object):
|
|||
|
||||
if self._macroscopic is None:
|
||||
# Create nuclide XML subelements
|
||||
subelements = self._get_nuclides_xml(self._nuclides, distrib=True)
|
||||
subelements = self._get_nuclides_xml(self._nuclides,
|
||||
distrib=True)
|
||||
for subelement_nuc in subelements:
|
||||
subelement.append(subelement_nuc)
|
||||
|
||||
# Create element XML subelements
|
||||
subelements = self._get_elements_xml(self._elements, distrib=True)
|
||||
subelements = self._get_elements_xml(self._elements,
|
||||
cross_sections,
|
||||
distrib=True)
|
||||
for subsubelement in subelements:
|
||||
subelement.append(subsubelement)
|
||||
else:
|
||||
|
|
@ -716,15 +749,49 @@ class Materials(cv.CheckedList):
|
|||
----------
|
||||
materials : Iterable of openmc.Material
|
||||
Materials to add to the collection
|
||||
cross_sections : str
|
||||
Indicates the path to an XML cross section listing file (usually named
|
||||
cross_sections.xml). If it is not set, the
|
||||
:envvar:`OPENMC_CROSS_SECTIONS` environment variable will be used for
|
||||
continuous-energy calculations and
|
||||
:envvar:`OPENMC_MG_CROSS_SECTIONS` will be used for multi-group
|
||||
calculations to find the path to the XML cross section file.
|
||||
multipole_library : str
|
||||
Indicates the path to a directory containing a windowed multipole
|
||||
cross section library. If it is not set, the
|
||||
:envvar:`OPENMC_MULTIPOLE_LIBRARY` environment variable will be used. A
|
||||
multipole library is optional.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, materials=None):
|
||||
super(Materials, self).__init__(Material, 'materials collection')
|
||||
|
||||
self._materials_file = ET.Element("materials")
|
||||
self._cross_sections = None
|
||||
self._multipole_library = None
|
||||
|
||||
if materials is not None:
|
||||
self += materials
|
||||
|
||||
@property
|
||||
def cross_sections(self):
|
||||
return self._cross_sections
|
||||
|
||||
@property
|
||||
def multipole_library(self):
|
||||
return self._multipole_library
|
||||
|
||||
@cross_sections.setter
|
||||
def cross_sections(self, cross_sections):
|
||||
cv.check_type('cross sections', cross_sections, string_types)
|
||||
self._cross_sections = cross_sections
|
||||
|
||||
@multipole_library.setter
|
||||
def multipole_library(self, multipole_library):
|
||||
cv.check_type('cross sections', multipole_library, string_types)
|
||||
self._multipole_library = multipole_library
|
||||
|
||||
def add_material(self, material):
|
||||
"""Append material to collection
|
||||
|
||||
|
|
@ -807,9 +874,19 @@ class Materials(cv.CheckedList):
|
|||
|
||||
def _create_material_subelements(self):
|
||||
for material in self:
|
||||
xml_element = material.get_material_xml()
|
||||
xml_element = material.get_material_xml(self.cross_sections)
|
||||
self._materials_file.append(xml_element)
|
||||
|
||||
def _create_cross_sections_subelement(self):
|
||||
if self._cross_sections is not None:
|
||||
element = ET.SubElement(self._materials_file, "cross_sections")
|
||||
element.text = str(self._cross_sections)
|
||||
|
||||
def _create_multipole_library_subelement(self):
|
||||
if self._multipole_library is not None:
|
||||
element = ET.SubElement(self._materials_file, "multipole_library")
|
||||
element.text = str(self._multipole_library)
|
||||
|
||||
def export_to_xml(self, path='materials.xml'):
|
||||
"""Export material collection to an XML file.
|
||||
|
||||
|
|
@ -824,6 +901,8 @@ class Materials(cv.CheckedList):
|
|||
self._materials_file.clear()
|
||||
|
||||
self._create_material_subelements()
|
||||
self._create_cross_sections_subelement()
|
||||
self._create_multipole_library_subelement()
|
||||
|
||||
# Clean the indentation in the file to be user-readable
|
||||
sort_xml_elements(self._materials_file)
|
||||
|
|
|
|||
|
|
@ -87,9 +87,9 @@ class Nuclide(object):
|
|||
|
||||
@scattering.setter
|
||||
def scattering(self, scattering):
|
||||
if not scattering in ['data', 'iso-in-lab']:
|
||||
msg = 'Unable to set scattering for Nuclide to {0} ' \
|
||||
'which is not "data" or "iso-in-lab"'.format(scattering)
|
||||
if not scattering in ['data', 'iso-in-lab', None]:
|
||||
msg = 'Unable to set scattering for Nuclide to {0} which ' \
|
||||
'is not "data", "iso-in-lab", or None'.format(scattering)
|
||||
raise ValueError(msg)
|
||||
|
||||
self._scattering = scattering
|
||||
|
|
|
|||
|
|
@ -603,12 +603,19 @@ class Settings(object):
|
|||
|
||||
@cross_sections.setter
|
||||
def cross_sections(self, cross_sections):
|
||||
warnings.warn('Settings.cross_sections has been deprecated and will be '
|
||||
'removed in a future version. Materials.cross_sections '
|
||||
'should defined instead.', DeprecationWarning)
|
||||
cv.check_type('cross sections', cross_sections, string_types)
|
||||
self._cross_sections = cross_sections
|
||||
|
||||
@multipole_library.setter
|
||||
def multipole_library(self, multipole_library):
|
||||
cv.check_type('cross sections', multipole_library, string_types)
|
||||
warnings.warn('Settings.multipole_library has been deprecated and will '
|
||||
'be removed in a future version. '
|
||||
'Materials.multipole_library should defined instead.',
|
||||
DeprecationWarning)
|
||||
cv.check_type('multipole library', multipole_library, string_types)
|
||||
self._multipole_library = multipole_library
|
||||
|
||||
@ptables.setter
|
||||
|
|
@ -713,6 +720,7 @@ class Settings(object):
|
|||
|
||||
@temperature.setter
|
||||
def temperature(self, temperature):
|
||||
|
||||
cv.check_type('temperature settings', temperature, Mapping)
|
||||
for key, value in temperature.items():
|
||||
cv.check_value('temperature key', key,
|
||||
|
|
|
|||
|
|
@ -257,17 +257,6 @@ module constants
|
|||
! Maximum number of partial fission reactions
|
||||
integer, parameter :: PARTIAL_FISSION_MAX = 4
|
||||
|
||||
! Major cross section libraries
|
||||
integer, parameter :: &
|
||||
ENDF_BVII0 = 1, &
|
||||
ENDF_BVII1 = 2, &
|
||||
JEFF_311 = 3, &
|
||||
JEFF_312 = 4, &
|
||||
JEFF_32 = 5, &
|
||||
JENDL_32 = 6, &
|
||||
JENDL_33 = 7, &
|
||||
JENDL_40 = 8
|
||||
|
||||
! Temperature treatment method
|
||||
integer, parameter :: &
|
||||
TEMPERATURE_NEAREST = 1, &
|
||||
|
|
|
|||
|
|
@ -96,9 +96,6 @@ module global
|
|||
! Unreoslved resonance probablity tables
|
||||
logical :: urr_ptables_on = .true.
|
||||
|
||||
! What to assume for expanding natural elements
|
||||
integer :: default_expand = ENDF_BVII1
|
||||
|
||||
! Default temperature and method for choosing temperatures
|
||||
integer :: temperature_method = TEMPERATURE_NEAREST
|
||||
logical :: temperature_multipole = .false.
|
||||
|
|
@ -320,14 +317,14 @@ module global
|
|||
logical :: restart_run = .false.
|
||||
integer :: restart_batch
|
||||
|
||||
character(MAX_FILE_LEN) :: path_input ! Path to input file
|
||||
character(MAX_FILE_LEN) :: path_cross_sections ! Path to cross_sections.xml
|
||||
character(MAX_FILE_LEN) :: path_multipole ! Path to wmp library
|
||||
character(MAX_FILE_LEN) :: path_source = '' ! Path to binary source
|
||||
character(MAX_FILE_LEN) :: path_state_point ! Path to binary state point
|
||||
character(MAX_FILE_LEN) :: path_source_point ! Path to binary source point
|
||||
character(MAX_FILE_LEN) :: path_particle_restart ! Path to particle restart
|
||||
character(MAX_FILE_LEN) :: path_output = '' ! Path to output directory
|
||||
character(MAX_FILE_LEN) :: path_input ! Path to input file
|
||||
character(MAX_FILE_LEN) :: path_cross_sections = '' ! Path to cross_sections.xml
|
||||
character(MAX_FILE_LEN) :: path_multipole ! Path to wmp library
|
||||
character(MAX_FILE_LEN) :: path_source = '' ! Path to binary source
|
||||
character(MAX_FILE_LEN) :: path_state_point ! Path to binary state point
|
||||
character(MAX_FILE_LEN) :: path_source_point ! Path to binary source point
|
||||
character(MAX_FILE_LEN) :: path_particle_restart ! Path to particle restart
|
||||
character(MAX_FILE_LEN) :: path_output = '' ! Path to output directory
|
||||
|
||||
! The verbosity controls how much information will be printed to the
|
||||
! screen and in logs
|
||||
|
|
|
|||
1162
src/input_xml.F90
1162
src/input_xml.F90
File diff suppressed because it is too large
Load diff
|
|
@ -42,4 +42,8 @@ element materials {
|
|||
(element name { xsd:string } | attribute name { xsd:string })
|
||||
}*
|
||||
}+
|
||||
|
||||
element cross_sections { xsd:string { maxLength = "255" } }? &
|
||||
|
||||
element multipole_library { xsd:string { maxLength = "255" } }? &
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,10 +25,6 @@ element settings {
|
|||
}
|
||||
) &
|
||||
|
||||
element cross_sections { xsd:string { maxLength = "255" } }? &
|
||||
|
||||
element multipole_library { xsd:string { maxLength = "255" } }? &
|
||||
|
||||
element cutoff {
|
||||
(element weight { xsd:double } | attribute weight { xsd:double })? &
|
||||
(element weight_avg { xsd:double } | attribute weight_avg { xsd:double })?
|
||||
|
|
|
|||
|
|
@ -524,31 +524,22 @@ class PinCellInputSet(object):
|
|||
# Instantiate ZCylinder surfaces
|
||||
fuel_or = openmc.ZCylinder(x0=0, y0=0, R=0.39218, name='Fuel OR')
|
||||
clad_or = openmc.ZCylinder(x0=0, y0=0, R=0.45720, name='Clad OR')
|
||||
left = openmc.XPlane(x0=-0.63, name='left')
|
||||
right = openmc.XPlane(x0=0.63, name='right')
|
||||
bottom = openmc.YPlane(y0=-0.63, name='bottom')
|
||||
top = openmc.YPlane(y0=0.63, name='top')
|
||||
|
||||
left.boundary_type = 'reflective'
|
||||
right.boundary_type = 'reflective'
|
||||
top.boundary_type = 'reflective'
|
||||
bottom.boundary_type = 'reflective'
|
||||
left = openmc.XPlane(x0=-0.63, name='left', boundary_type='reflective')
|
||||
right = openmc.XPlane(x0=0.63, name='right', boundary_type='reflective')
|
||||
bottom = openmc.YPlane(y0=-0.63, name='bottom',
|
||||
boundary_type='reflective')
|
||||
top = openmc.YPlane(y0=0.63, name='top', boundary_type='reflective')
|
||||
|
||||
# Instantiate Cells
|
||||
fuel_pin = openmc.Cell(name='cell 1')
|
||||
cladding = openmc.Cell(name='cell 3')
|
||||
water = openmc.Cell(name='cell 2')
|
||||
fuel_pin = openmc.Cell(name='cell 1', fill=fuel)
|
||||
cladding = openmc.Cell(name='cell 3', fill=clad)
|
||||
water = openmc.Cell(name='cell 2', fill=hot_water)
|
||||
|
||||
# Use surface half-spaces to define regions
|
||||
fuel_pin.region = -fuel_or
|
||||
cladding.region = +fuel_or & -clad_or
|
||||
water.region = +clad_or & +left & -right & +bottom & -top
|
||||
|
||||
# Register Materials with Cells
|
||||
fuel_pin.fill = fuel
|
||||
cladding.fill = clad
|
||||
water.fill = hot_water
|
||||
|
||||
# Instantiate Universe
|
||||
root = openmc.Universe(universe_id=0, name='root universe')
|
||||
|
||||
|
|
@ -757,6 +748,7 @@ class MGInputSet(InputSet):
|
|||
# Define the materials file
|
||||
self.xs_data = xs
|
||||
self.materials += mats
|
||||
self.materials.cross_sections = "../1d_mgxs.h5"
|
||||
|
||||
# Define surfaces.
|
||||
# Assembly/Problem Boundary
|
||||
|
|
@ -793,7 +785,6 @@ class MGInputSet(InputSet):
|
|||
self.settings.source = Source(space=Box([0.0, 0.0, 0.0],
|
||||
[10.0, 10.0, 5.]))
|
||||
self.settings.energy_mode = "multi-group"
|
||||
self.settings.cross_sections = "../1d_mgxs.h5"
|
||||
|
||||
def build_defualt_plots(self):
|
||||
plot = openmc.Plot()
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@
|
|||
</material>
|
||||
<material id="3">
|
||||
<density value="2.0" units="g/cc" />
|
||||
<element name="Zr" ao="1.0" />
|
||||
<nuclide name="Zr90" ao="1.0" />
|
||||
</material>
|
||||
<material id="4">
|
||||
<density value="0.1" units="g/cc" />
|
||||
<element name="N" ao="1.0" />
|
||||
<nuclide name="N14" ao="1.0" />
|
||||
</material>
|
||||
|
||||
</materials>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
k-combined:
|
||||
2.531110E-01 3.041974E-03
|
||||
2.511523E-01 2.296777E-03
|
||||
tally 1:
|
||||
2.594626E+00
|
||||
1.346701E+00
|
||||
2.683653E+00
|
||||
1.440725E+00
|
||||
9.933862E-01
|
||||
1.977011E-01
|
||||
1.112289E-01
|
||||
2.476655E-03
|
||||
2.578905E+00
|
||||
1.331155E+00
|
||||
2.688693E+00
|
||||
1.447930E+00
|
||||
9.863774E-01
|
||||
1.948549E-01
|
||||
1.123802E-01
|
||||
2.527538E-03
|
||||
|
|
|
|||
43
tests/test_element_wo/test_element_wo.py
Normal file
43
tests/test_element_wo/test_element_wo.py
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import numpy as np
|
||||
|
||||
sys.path.insert(0, os.pardir)
|
||||
sys.path.insert(0, os.path.join(os.pardir, os.pardir))
|
||||
from openmc import Material
|
||||
from openmc.data import NATURAL_ABUNDANCE, atomic_mass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# This test doesn't require an OpenMC run. We just need to make sure the
|
||||
# element.expand() method expands elements with the proper nuclide
|
||||
# compositions.
|
||||
|
||||
h_am = (NATURAL_ABUNDANCE['H1'] * atomic_mass('H1') +
|
||||
NATURAL_ABUNDANCE['H2'] * atomic_mass('H2'))
|
||||
o_am = (NATURAL_ABUNDANCE['O17'] * atomic_mass('O17') +
|
||||
(NATURAL_ABUNDANCE['O16'] + NATURAL_ABUNDANCE['O18'])
|
||||
* atomic_mass('O16'))
|
||||
water_am = 2 * h_am + o_am
|
||||
|
||||
water = Material()
|
||||
water.add_element('O', o_am / water_am, 'wo')
|
||||
water.add_element('H', 2 * h_am / water_am, 'wo')
|
||||
densities = water.get_nuclide_densities()
|
||||
|
||||
for nuc in densities.keys():
|
||||
assert nuc in ('H1', 'H2', 'O16', 'O17')
|
||||
|
||||
if nuc in ('H1', 'H2'):
|
||||
val = 2 * NATURAL_ABUNDANCE[nuc] * atomic_mass(nuc) / water_am
|
||||
assert np.isclose(densities[nuc][1], val, rtol=1.e-8)
|
||||
if nuc == 'O16':
|
||||
val = (NATURAL_ABUNDANCE[nuc] + NATURAL_ABUNDANCE['O18']) \
|
||||
* atomic_mass(nuc) / water_am
|
||||
assert np.isclose(densities[nuc][1], val, rtol=1.e-8)
|
||||
if nuc == 'O17':
|
||||
val = NATURAL_ABUNDANCE[nuc] * atomic_mass(nuc) / water_am
|
||||
assert np.isclose(densities[nuc][1], val, rtol=1.e-8)
|
||||
33
tests/test_enrichment/test_enrichment.py
Normal file
33
tests/test_enrichment/test_enrichment.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import numpy as np
|
||||
|
||||
sys.path.insert(0, os.pardir)
|
||||
sys.path.insert(0, os.path.join(os.pardir, os.pardir))
|
||||
from openmc import Material
|
||||
from openmc.data import NATURAL_ABUNDANCE, atomic_mass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# This test doesn't require an OpenMC run. We just need to make sure the
|
||||
# element.expand() method expands Uranium to the proper enrichment.
|
||||
|
||||
uranium = Material()
|
||||
uranium.add_element('U', 1.0, 'wo', 4.95)
|
||||
densities = uranium.get_nuclide_densities()
|
||||
|
||||
sum_densities = 0.
|
||||
for nuc in densities.keys():
|
||||
assert nuc in ('U234', 'U235', 'U238')
|
||||
sum_densities += densities[nuc][1]
|
||||
|
||||
# Compute the weight percent U235
|
||||
enrichment = densities['U235'][1] / sum_densities
|
||||
assert np.isclose(enrichment, 0.0495, rtol=1.e-8)
|
||||
|
||||
# Compute the ratio of U234/U235
|
||||
u234_to_u235 = densities['U234'][1] / densities['U235'][1]
|
||||
assert np.isclose(u234_to_u235, 0.008, rtol=1.e-8)
|
||||
|
|
@ -1 +1 @@
|
|||
115218221500e60ea43145875324a9a6800366fcc97357ef4cd8182f9253e114cbe1c7481dd3bdd8d7dce5983e2cb757ae0a2e05ede236d94cba7909703ba7f7
|
||||
12abd69924751d1cf2a296ce799bfb2a6a4e744ffc49eef5a5cee8b764254caa3783c406cff71238c5608b454f451953479fb4caad45460a013225ab8de2271e
|
||||
|
|
@ -1 +1 @@
|
|||
139d760cd83eab001ed3fd52d7146fb5f30b7021b26ada6a1e425f5446185ac6fa61ac2ac58aa9e895981e10540160b7ae7428c833024679ef1ca762715e2d51
|
||||
1f82e622b36562a0a14536fe24c95ee9c901c428f7f082f245afae5c699ccd647aaf31a49790822ceb7ec136bdb75f8e25c3677642f73702ca2e30b058f6b440
|
||||
|
|
@ -1 +1 @@
|
|||
6d03b988671fe21dfe2a908685536edb3059e5bdda7974ddfa65c7f63cecb7f6b3fce49bc1533ef2787e284121779653cb14a66cfd709258e4b07d8bd7571843
|
||||
ec7f0697d22668dcc4cdaf134c58b9f84137730d52cb44264ee9205369abcf995b2f66847d620715cd609bd2f5f865294374978f8fb89f182962e40801171cba
|
||||
|
|
@ -1 +1 @@
|
|||
8c496e13f9456bedcc0789ffdca81913596cca3c7867717ced38c3063b6cdc8949bd204c98723b72c1b456e3fc85fc90e6710482b0c74e5e29283902a5d9ed50
|
||||
54cd9db30bc8e671591d76e8da2b5dead54eb4cead1eef09a005e96ca2c0fd707872e0cc21f31d198915b156605de78322fbb7957698ea8febceb23f048e44ad
|
||||
|
|
@ -60,8 +60,8 @@ class MGXSTestHarness(PyAPITestHarness):
|
|||
self._input_set.mgxs_file, self._input_set.materials, \
|
||||
self._input_set.geometry = self.mgxs_lib.create_mg_mode()
|
||||
|
||||
# Modify settings so we can run in MG mode
|
||||
self._input_set.settings.cross_sections = './mgxs.h5'
|
||||
# Modify materials and settings so we can run in MG mode
|
||||
self._input_set.materials.cross_sections = './mgxs.h5'
|
||||
self._input_set.settings.energy_mode = 'multi-group'
|
||||
|
||||
# Write modified input files
|
||||
|
|
|
|||
|
|
@ -1,94 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<geometry>
|
||||
|
||||
<!-- pu-met-fast-021 case 2 -->
|
||||
|
||||
<surface id="1" type="z-plane" coeffs="-17.51" boundary="vacuum" />
|
||||
<surface id="2" type="z-plane" coeffs="-2.57" />
|
||||
<!-- Bottom Plutonium Core -->
|
||||
<surface id="3" type="z-plane" coeffs="-2.55" />
|
||||
<surface id="4" type="z-plane" coeffs="-2.37" />
|
||||
<surface id="5" type="z-plane" coeffs="-2.1" />
|
||||
<surface id="6" type="z-plane" coeffs="-2.06" />
|
||||
<surface id="7" type="z-plane" coeffs="-1.61" />
|
||||
<surface id="8" type="z-plane" coeffs="-1.57" />
|
||||
<surface id="9" type="z-plane" coeffs="-1.12" />
|
||||
<surface id="10" type="z-plane" coeffs="-1.08" />
|
||||
<surface id="11" type="z-plane" coeffs="-0.63" />
|
||||
<surface id="12" type="z-plane" coeffs="-0.59" />
|
||||
<surface id="13" type="z-plane" coeffs="-0.14" />
|
||||
<!-- Middle Gap -->
|
||||
<surface id="14" type="z-plane" coeffs="-0.12" />
|
||||
<surface id="15" type="z-plane" coeffs="0.12" />
|
||||
<!-- Top Plutonium Core -->
|
||||
<surface id="16" type="z-plane" coeffs="0.14" />
|
||||
<surface id="17" type="z-plane" coeffs="0.59" />
|
||||
<surface id="18" type="z-plane" coeffs="0.63" />
|
||||
<surface id="19" type="z-plane" coeffs="1.08" />
|
||||
<surface id="20" type="z-plane" coeffs="1.12" />
|
||||
<surface id="21" type="z-plane" coeffs="1.57" />
|
||||
<surface id="22" type="z-plane" coeffs="1.61" />
|
||||
<surface id="23" type="z-plane" coeffs="2.06" />
|
||||
<surface id="24" type="z-plane" coeffs="2.1" />
|
||||
<surface id="25" type="z-plane" coeffs="2.37" />
|
||||
<surface id="26" type="z-plane" coeffs="2.55" />
|
||||
<surface id="27" type="z-plane" coeffs="2.57" />
|
||||
<!-- Top Beryllium Reflector -->
|
||||
<surface id="28" type="z-plane" coeffs="2.59" />
|
||||
<surface id="29" type="z-plane" coeffs="17.51" boundary="vacuum" />
|
||||
|
||||
<!-- Cylinders -->
|
||||
<surface id="30" type="z-cylinder" coeffs="0 0 9.995" boundary="vacuum" />
|
||||
<surface id="31" type="z-cylinder" coeffs="0 0 6.263" />
|
||||
<surface id="32" type="z-cylinder" coeffs="0 0 6.063" />
|
||||
<surface id="33" type="z-cylinder" coeffs="0 0 5.995" />
|
||||
|
||||
|
||||
<!-- Beryllium Reflector -->
|
||||
<cell id="1" material="2" region=" 1 -2 -30" />
|
||||
<cell id="2" material="2" region="28 -29 -30" />
|
||||
|
||||
<!-- Duralumin base and top -->
|
||||
<cell id="3" material="4" region=" 2 -4 -30 31" />
|
||||
<cell id="4" material="4" region="25 -28 -30 31" />
|
||||
|
||||
<!-- Duralumin top cylindrical shell -->
|
||||
<cell id="6" material="5" region="15 -28 -31 32" />
|
||||
|
||||
<!-- Duralumin bottom cylindrical shell -->
|
||||
<cell id="7" material="6" region=" 2 -14 -31 32" />
|
||||
|
||||
<!-- Steel Cover -->
|
||||
<cell id="8" material="3" region=" 2 -3 -33" />
|
||||
<cell id="9" material="3" region=" 5 -6 -33" />
|
||||
<cell id="10" material="3" region=" 7 -8 -33" />
|
||||
<cell id="11" material="3" region=" 9 -10 -33" />
|
||||
<cell id="12" material="3" region="11 -12 -33" />
|
||||
<cell id="13" material="3" region="13 -14 -33" />
|
||||
<cell id="14" material="3" region="15 -16 -33" />
|
||||
<cell id="15" material="3" region="17 -18 -33" />
|
||||
<cell id="16" material="3" region="19 -20 -33" />
|
||||
<cell id="17" material="3" region="21 -22 -33" />
|
||||
<cell id="18" material="3" region="23 -24 -33" />
|
||||
<cell id="19" material="3" region="26 -27 -33" />
|
||||
<cell id="20" material="3" region=" 2 -14 33 -32" />
|
||||
<cell id="21" material="3" region="15 -27 33 -32" />
|
||||
|
||||
<!-- Plutonium -->
|
||||
<cell id="22" material="1" region=" 3 -5 -33" />
|
||||
<cell id="23" material="1" region=" 6 -7 -33" />
|
||||
<cell id="24" material="1" region=" 8 -9 -33" />
|
||||
<cell id="25" material="1" region="10 -11 -33" />
|
||||
<cell id="26" material="1" region="12 -13 -33" />
|
||||
<cell id="27" material="1" region="16 -17 -33" />
|
||||
<cell id="28" material="1" region="18 -19 -33" />
|
||||
<cell id="29" material="1" region="20 -21 -33" />
|
||||
<cell id="30" material="1" region="22 -23 -33" />
|
||||
<cell id="31" material="1" region="24 -26 -33" />
|
||||
|
||||
<!-- Void -->
|
||||
<cell id="32" material="void" region="14 -15 -31" />
|
||||
<cell id="33" material="void" region=" 4 -25 31 -30" />
|
||||
<cell id="34" material="void" region="27 -28 -30" />
|
||||
|
||||
</geometry>
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<materials>
|
||||
|
||||
<!-- pu-met-fast-021 case 2 -->
|
||||
|
||||
<!-- Plutonium -->
|
||||
<material id="1">
|
||||
<density value="18.5345" units="g/cm3" />
|
||||
<nuclide name="Pu239" ao="4.4422e-02" />
|
||||
<nuclide name="Pu240" ao="2.1326e-03" />
|
||||
<nuclide name="Pu241" ao="9.2538e-05" />
|
||||
<element name="C" ao="1.9515e-04" />
|
||||
<element name="Fe" ao="8.1943e-05" />
|
||||
</material>
|
||||
|
||||
<!-- Berylium-oxide Reflector -->
|
||||
<material id="2">
|
||||
<density value="2.86750" units="g/cm3" />
|
||||
<nuclide name="Be9" ao="6.9041e-02" />
|
||||
<element name="O" ao="6.9041e-02" />
|
||||
</material>
|
||||
|
||||
<!-- Steel Cover -->
|
||||
<material id="3">
|
||||
<density value="6.9323" units="g/cm3" />
|
||||
<element name="Fe" ao="5.1280e-02" />
|
||||
<element name="C" ao="3.4757e-04" />
|
||||
<element name="Si" ao="8.9185e-04" />
|
||||
<element name="Ti" ao="6.1034e-04" />
|
||||
<element name="Cr" ao="1.4452e-02" />
|
||||
<element name="Mn" ao="1.5198e-03" />
|
||||
<element name="Ni" ao="7.1131e-03" />
|
||||
</material>
|
||||
|
||||
<!-- Duralumin base and top -->
|
||||
<material id="4">
|
||||
<density value="2.78" units="g/cm3" />
|
||||
<element name="Al" ao="5.8077e-02" />
|
||||
<element name="Mg" ao="1.0332e-03" />
|
||||
<element name="Mn" ao="1.8284e-04" />
|
||||
<element name="Cu" ao="1.1329e-03" />
|
||||
</material>
|
||||
|
||||
<!-- Duralumin top cylindrical shell -->
|
||||
<material id="5">
|
||||
<density value="0.417" units="g/cm3" />
|
||||
<element name="Al" ao="8.7115e-03" />
|
||||
<element name="Mg" ao="1.5498e-04" />
|
||||
<element name="Mn" ao="2.7426e-05" />
|
||||
<element name="Cu" ao="1.6993e-04" />
|
||||
</material>
|
||||
|
||||
<!-- Duralumin bottom cylindrical shell -->
|
||||
<material id="6">
|
||||
<density value="1.8155" units="g/cm3" />
|
||||
<element name="Al" ao="3.7928e-02" />
|
||||
<element name="Mg" ao="6.7475e-04" />
|
||||
<element name="Mn" ao="1.1941e-04" />
|
||||
<element name="Cu" ao="7.3982e-04" />
|
||||
</material>
|
||||
|
||||
</materials>
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
k-combined:
|
||||
1.034427E+00 1.583807E-02
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<settings>
|
||||
|
||||
<!-- pu-met-fast-021 case 2 -->
|
||||
|
||||
<eigenvalue>
|
||||
<batches>10</batches>
|
||||
<inactive>5</inactive>
|
||||
<particles>400</particles>
|
||||
</eigenvalue>
|
||||
|
||||
<natural_elements>endf/b-vii.1</natural_elements>
|
||||
|
||||
<source>
|
||||
<space>
|
||||
<type>box</type>
|
||||
<parameters>0 0 0 1 1 1</parameters>
|
||||
</space>
|
||||
</source>
|
||||
|
||||
</settings>
|
||||
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.pardir)
|
||||
from testing_harness import TestHarness
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
harness = TestHarness('statepoint.10.*')
|
||||
harness.main()
|
||||
|
|
@ -122,7 +122,7 @@ class TalliesTestHarness(PyAPITestHarness):
|
|||
t.filters = [cell_filter]
|
||||
t.scores = ['absorption', 'delayed-nu-fission', 'events', 'fission',
|
||||
'inverse-velocity', 'kappa-fission', '(n,2n)', '(n,n1)',
|
||||
'(n,gamma)', 'nu-fission', 'scatter', 'elastic',
|
||||
'(n,gamma)', 'nu-fission', 'scatter', 'elastic',
|
||||
'total', 'prompt-nu-fission', 'fission-q-prompt',
|
||||
'fission-q-recoverable']
|
||||
score_tallies[0].estimator = 'tracklength'
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
b22973093e2b0690b30fb1262a11e27004555b796c446d256cb58a1d7329888ab60c1b93729b3d74bb015b98aa434416daa2dc2aee526eb8df0e9052911f94b4
|
||||
3a356b5b6d0aaa3db8c601521e1837a6870c5e5f6d1068f4f3e9b896c0107517d99ff9676311221633169b4d79dc1c4076bff84130e6de16df7ace4da5481a60
|
||||
Loading…
Add table
Add a link
Reference in a new issue