add_elements_or_nuclides -> add_components

- changed the assumptions the function makes about the 'components'
  parameter
- added 'percent_type' parameter
- passed changes to unit test
This commit is contained in:
yardasol 2022-07-29 18:21:06 -05:00
parent 6351b49ea2
commit effc35b8ee
2 changed files with 62 additions and 36 deletions

View file

@ -35,7 +35,7 @@ class Material(IDManagerMixin):
nuclides or elements with :meth:`Material.add_nuclide` or
:meth:`Material.add_element`, respectively, and set the total material
density with :meth:`Material.set_density()`. Alternatively, you can
use :meth:`Material.add_elements_or_nuclides()` to pass a dictionary
use :meth:`Material.add_components()` to pass a dictionary
containing all the component information. The material can then be
assigned to a cell using the :attr:`Cell.fill` attribute.
@ -405,41 +405,55 @@ class Material(IDManagerMixin):
self._nuclides.append(NuclideTuple(nuclide, percent, percent_type))
def add_elements_or_nuclides(self, components: dict):
def add_components(self, components: dict, percent_type: str = 'ao'):
""" Add multiple elements or nuclides to a material
Parameters
----------
components : dict of str to tuple
Dictionary mapping element or nuclide names to a tuple containing
their atom or weight percent, as well as any other arguments.
components : dict of str to float or dict
Dictionary mapping element or nuclide names to their atom or weight
percent. To specify enrichment of an element, the entry of
``components`` for that element must instead be a dictionary
containing the keyword arguments as well as a value for
``'percent'``
percent_type : {'ao', 'wo'}
'ao' for atom percent and 'wo' for weight percent
Examples
--------
>>> mat = openmc.Material()
>>> components = {'Li': (1.0, {'enrichment': 60.0, 'enrichment_target': 'Li7'}),
>>> 'Fl': 1.0,
>>> 'Be6': (0.5, 'wo')}
>>> mat.add_elements_or_nuclides(components)
>>> components = {'Li': {'percent': 1.0,
>>> 'enrichment': 60.0,
>>> 'enrichment_target': 'Li7'},
>>> 'Fl': 1.0,
>>> 'Be6': 0.5}
>>> mat.add_components(components)
"""
for component, args in components.items():
for component, params in components.items():
cv.check_type('component', component, str)
percent_type = 'ao'
if isinstance(args, float):
args = (args,)
if isinstance(params, float):
params = {'percent': params}
else:
cv.check_type('params', params, dict)
if 'percent' not in params:
raise ValueError("An entry in the dictionary does not have "
"a required key: 'percent'")
percent = params.pop('percent')
args = (percent, percent_type)
## check if nuclide
if str.isdigit(component[-1]):
self.add_nuclide(component, *args)
else: # is element
kwargs = {}
if isinstance(args[-1], dict):
kwargs = args[-1]
args = args[:-1]
kwargs = params
self.add_element(component, *args, **kwargs)
params['percent'] = percent
def remove_nuclide(self, nuclide: str):
"""Remove a nuclide from the material

View file

@ -25,39 +25,51 @@ def test_add_nuclide():
with pytest.raises(ValueError):
m.add_nuclide('H1', 1.0, 'oa')
def test_add_elements_or_nuclides():
def test_add_components():
"""Test adding multipe elements or nuclides at once"""
m = openmc.Material()
components = {'H1': 2.0,
'O16': (1.0, 'wo'),
'Zr': 1.0,
'O': (1.0, 'wo'),
'U': (1.0, {'enrichment': 4.5}),
'Li': (1.0, 'ao', {'enrichment': 60.0, 'enrichment_target': 'Li7'}),
'H': (1.0, 'ao', {'enrichment': 50.0, 'enrichment_target': 'H2', 'enrichment_type': 'wo'})}
m.add_elements_or_nuclides(components)
'O16': 1.0,
'Zr': 1.0,
'O': 1.0,
'U': {'percent': 1.0,
'enrichment': 4.5},
'Li': {'percent': 1.0,
'enrichment': 60.0,
'enrichment_target': 'Li7'},
'H': {'percent': 1.0,
'enrichment': 50.0,
'enrichment_target': 'H2',
'enrichment_type': 'wo'}}
m.add_components(components)
with pytest.raises(ValueError):
m.add_elements_or_nuclides({'U': (1.0, 'ao', {'enrichment': 100.0})})
m.add_components({'U': {'percent': 1.0,
'enrichment': 100.0}})
with pytest.raises(ValueError):
m.add_elements_or_nuclides({'Pu': (1.0, 'ao', {'enrichment': 3.0})})
m.add_components({'Pu': {'percent': 1.0,
'enrichment': 3.0}})
with pytest.raises(ValueError):
m.add_elements_or_nuclides({'U': (1.0, 'ao', {'enrichment': 70.0, 'enrichment_target': 'U235'})})
m.add_components({'U': {'percent': 1.0,
'enrichment': 70.0,
'enrichment_target':'U235'}})
with pytest.raises(ValueError):
m.add_elements_or_nuclides({'He': (1.0, 'ao', {'enrichment': 17.0, 'enrichment_target': 'He6'})})
m.add_components({'He': {'percent': 1.0,
'enrichment': 17.0,
'enrichment_target': 'He6'}})
with pytest.raises(ValueError):
m.add_elements_or_nuclides({'li': (1.0, 'ao')}) # should fail as 1st char is lowercase
m.add_components({'li': 1.0}) # should fail as 1st char is lowercase
with pytest.raises(ValueError):
m.add_elements_or_nuclides({'LI': (1.0, 'ao')}) # should fail as 2nd char is uppercase
m.add_components({'LI': 1.0}) # should fail as 2nd char is uppercase
with pytest.raises(ValueError):
m.add_elements_or_nuclides({'Xx': (1.0, 'ao')}) # should fail as Xx is not an element
m.add_components({'Xx': 1.0}) # should fail as Xx is not an element
with pytest.raises(ValueError):
m.add_elements_or_nuclides({'n': (1.0, 'ao')}) # check to avoid n for neutron being accepted
m.add_components({'n': 1.0}) # check to avoid n for neutron being accepted
with pytest.raises(TypeError):
m.add_elements_or_nuclides({'H1': ('1.0', 'ao')})
m.add_components({'H1': '1.0'})
with pytest.raises(TypeError):
m.add_elements_or_nuclides({1.0: ('H1', 'wo')})
m.add_components({1.0: 'H1'}, percent_type = 'wo')
with pytest.raises(ValueError):
m.add_elements_or_nuclides({'H1': (1.0, 'oa')})
m.add_components({'H1': 1.0}, percent_type = 'oa')
def test_remove_nuclide():