Adds general element enrichment to Material

Adds an option to specify an enrichment of an element composed of two
isotopes to Material.add_element
This commit is contained in:
Mikolaj Adam Kowalski 2020-02-14 18:55:50 +00:00
parent 98253ab9b4
commit d5f9a962e5
3 changed files with 56 additions and 9 deletions

View file

@ -4,6 +4,7 @@ import os
from xml.etree import ElementTree as ET
import openmc.checkvalue as cv
from numbers import Real
from openmc.data import NATURAL_ABUNDANCE, atomic_mass
@ -57,6 +58,7 @@ class Element(str):
If enrichment_taget is not supplied then it is enrichment for U235
in weight percent. For example, input 4.95 for 4.95 weight percent
enriched U. Default is None (natural composition).
Value must be in <0;100>
enrichment_target: str, optional
Single nuclide name to enrich from a natural composition e.g. O16
enrichment_type: {'ao', 'wo'}, optional
@ -89,6 +91,16 @@ class Element(str):
Enrichment is requested of the element that is not composed of
two isotopes.
ValueError
If `enrichment_type` is not 'ao' or 'wo'
ValueError
If `enrichment` is outside <0;100> range
ValueError
If enrichment procedure for Uranium is used when element is not
Uranium.
Notes
-----
When the `enrichment` argument is specified, a correlation from
@ -98,12 +110,20 @@ class Element(str):
respectively, of the U235 weight fraction. The remainder of the
isotopic weight is assigned to U238.
Function does not check if enrichment value is in a valid range <0;100>
When the `enrichment` argument is specified with `enrichment_target` a
general enrichment procedure is used. It will raise exception unless
element is composed of excatly 2 isotopes. `enrichment` is interpreted
as percent. By default it is atomic. Can be controlled by variable
`enrichment_type`.
"""
# Check input
cv.check_value('enrichment_type', enrichment_type, {'ao', 'wo'})
if enrichment is not None:
cv.check_less_than('enrichment', enrichment, 100.0, equality=True)
cv.check_greater_than('enrichment', enrichment, 0., equality=True)
# Get the nuclides present in nature
natural_nuclides = set()
for nuclide in sorted(NATURAL_ABUNDANCE.keys()):

View file

@ -499,7 +499,8 @@ class Material(IDManagerMixin):
if macroscopic == self._macroscopic:
self._macroscopic = None
def add_element(self, element, percent, percent_type='ao', enrichment=None):
def add_element(self, element, percent, percent_type='ao', enrichment=None,
enrichment_target=None, enrichment_type='ao'):
"""Add a natural element to the material
Parameters
@ -512,9 +513,24 @@ class Material(IDManagerMixin):
'ao' for atom percent and 'wo' for weight percent. Defaults to atom
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).
Enrichment of an enrichment_taget nuclide in percent (ao or wo).
If enrichment_taget is not supplied then it is enrichment for U235
in weight percent. For example, input 4.95 for 4.95 weight percent
enriched U.
Default is None (natural composition).
Value must be in <0;100> for general nuclide
Value must be in <0;100./1.008) for Uranium
enrichment_target: str, optional
Single nuclide name to enrich from a natural composition e.g. O16
enrichment_type: {'ao', 'wo'}, optional
'ao' for enrichment as atom percent and 'wo' for weight percent.
Default is 'ao'
Notes
-----
General enrichment procedure is allowed only for elements composed of
two isotopes. If `enrichment_target` is given withou `enrichment`
natural composition is added to the material.
"""
cv.check_type('nuclide', element, str)
@ -526,7 +542,7 @@ class Material(IDManagerMixin):
'macroscopic data-set has already been added'.format(self._id)
raise ValueError(msg)
if enrichment is not None:
if enrichment is not None and enrichment_target is None:
if not isinstance(enrichment, Real):
msg = 'Unable to add an Element to Material ID="{}" with a ' \
'non-floating point enrichment value "{}"'\
@ -558,7 +574,11 @@ class Material(IDManagerMixin):
# Add naturally-occuring isotopes
element = openmc.Element(element)
for nuclide in element.expand(percent, percent_type, enrichment):
for nuclide in element.expand(percent,
percent_type,
enrichment,
enrichment_target,
enrichment_type):
self.add_nuclide(*nuclide)
def add_s_alpha_beta(self, name, fraction=1.0):
@ -927,7 +947,7 @@ class Material(IDManagerMixin):
Fractions of each material to be combined
percent_type : {'ao', 'wo', 'vo'}
Type of percentage, must be one of 'ao', 'wo', or 'vo', to signify atom
percent (molar percent), weight percent, or volume percent,
percent (molar percent), weight percent, or volume percent,
optional. Defaults to 'ao'
name : str
The name for the new material, optional. Defaults to concatenated
@ -996,7 +1016,7 @@ class Material(IDManagerMixin):
zip(materials, fracs)])
new_mat = openmc.Material(name=name)
# Compute atom fractions of nuclides and add them to the new material
# Compute atom fractions of nuclides and add them to the new material
tot_nuclides_per_cc = np.sum([dens for dens in nuclides_per_cc.values()])
for nuc, atom_dens in nuclides_per_cc.items():
new_mat.add_nuclide(nuc, atom_dens/tot_nuclides_per_cc, 'ao')

View file

@ -29,10 +29,17 @@ def test_elements():
m = openmc.Material()
m.add_element('Zr', 1.0)
m.add_element('U', 1.0, enrichment=4.5)
m.add_element('Li', 1.0, enrichment=60.0, enrichment_target='Li7')
m.add_element('H', 1.0, enrichment=50.0, enrichment_target='H2',
enrichment_type='wo')
with pytest.raises(ValueError):
m.add_element('U', 1.0, enrichment=100.0)
with pytest.raises(ValueError):
m.add_element('Pu', 1.0, enrichment=3.0)
with pytest.raises(ValueError):
m.add_element('U', 1.0, enrichment=70.0, enrichment_target='U235')
with pytest.raises(ValueError):
m.add_element('He', 1.0, enrichment=17.0, enrichment_target='He6')
def test_density():