Add volume arguments on several methods in Material class

This commit is contained in:
Paul Romano 2023-03-03 15:03:22 -06:00
parent b44225b3d5
commit c1232a83e0
2 changed files with 50 additions and 12 deletions

View file

@ -1029,7 +1029,8 @@ class Material(IDManagerMixin):
return nuclides
def get_activity(self, units: str = 'Bq/cm3', by_nuclide: bool = False):
def get_activity(self, units: str = 'Bq/cm3', by_nuclide: bool = False,
volume: Optional[float] = None):
"""Returns the activity of the material or for each nuclide in the
material in units of [Bq], [Bq/g] or [Bq/cm3].
@ -1044,6 +1045,10 @@ class Material(IDManagerMixin):
by_nuclide : bool
Specifies if the activity should be returned for the material as a
whole or per nuclide. Default is False.
volume : float, optional
Volume of the material if not assigned directly
.. versionadded:: 0.13.3
Returns
-------
@ -1057,7 +1062,7 @@ class Material(IDManagerMixin):
cv.check_type('by_nuclide', by_nuclide, bool)
if units == 'Bq':
multiplier = self.volume
multiplier = volume if volume is not None else self.volume
elif units == 'Bq/cm3':
multiplier = 1
elif units == 'Bq/g':
@ -1070,7 +1075,8 @@ class Material(IDManagerMixin):
return activity if by_nuclide else sum(activity.values())
def get_decay_heat(self, units: str = 'W', by_nuclide: bool = False):
def get_decay_heat(self, units: str = 'W', by_nuclide: bool = False,
volume: Optional[float] = None):
"""Returns the decay heat of the material or for each nuclide in the
material in units of [W], [W/g] or [W/cm3].
@ -1085,6 +1091,10 @@ class Material(IDManagerMixin):
by_nuclide : bool
Specifies if the decay heat should be returned for the material as a
whole or per nuclide. Default is False.
volume : float, optional
Volume of the material if not assigned directly
.. versionadded:: 0.13.3
Returns
-------
@ -1098,7 +1108,7 @@ class Material(IDManagerMixin):
cv.check_type('by_nuclide', by_nuclide, bool)
if units == 'W':
multiplier = self.volume
multiplier = volume if volume is not None else self.volume
elif units == 'W/cm3':
multiplier = 1
elif units == 'W/g':
@ -1113,11 +1123,18 @@ class Material(IDManagerMixin):
return decayheat if by_nuclide else sum(decayheat.values())
def get_nuclide_atoms(self):
def get_nuclide_atoms(self, volume: Optional[float] = None):
"""Return number of atoms of each nuclide in the material
.. versionadded:: 0.13.1
Parameters
----------
volume : float, optional
Volume of the material if not assigned directly
.. versionadded:: 0.13.3
Returns
-------
dict
@ -1125,11 +1142,13 @@ class Material(IDManagerMixin):
atoms present in the material.
"""
if self.volume is None:
if volume is None:
volume = self.volume
if volume is None:
raise ValueError("Volume must be set in order to determine atoms.")
atoms = {}
for nuclide, atom_per_bcm in self.get_nuclide_atom_densities().items():
atoms[nuclide] = 1.0e24 * atom_per_bcm * self.volume
atoms[nuclide] = 1.0e24 * atom_per_bcm * volume
return atoms
def get_mass_density(self, nuclide: Optional[str] = None):
@ -1154,7 +1173,7 @@ class Material(IDManagerMixin):
mass_density += density_i
return mass_density
def get_mass(self, nuclide: Optional[str] = None):
def get_mass(self, nuclide: Optional[str] = None, volume: Optional[float] = None):
"""Return mass of one or all nuclides.
Note that this method requires that the :attr:`Material.volume` has
@ -1165,6 +1184,11 @@ class Material(IDManagerMixin):
nuclides : str, optional
Nuclide for which mass is desired. If not specified, the density
for the entire material is given.
volume : float, optional
Volume of the material if not assigned directly
.. versionadded:: 0.13.3
Returns
-------
@ -1172,9 +1196,11 @@ class Material(IDManagerMixin):
Mass of the nuclide/material in [g]
"""
if self.volume is None:
if volume is None:
volume = self.volume
if volume is None:
raise ValueError("Volume must be set in order to determine mass.")
return self.volume*self.get_mass_density(nuclide)
return volume*self.get_mass_density(nuclide)
def clone(self, memo: Optional[dict] = None):
"""Create a copy of this material with a new unique ID.

View file

@ -377,6 +377,9 @@ def test_get_nuclide_atoms():
atoms = mat.get_nuclide_atoms()
assert atoms['Li6'] == pytest.approx(mat.density * mat.volume)
atoms = mat.get_nuclide_atoms(volume=10.0)
assert atoms['Li6'] == pytest.approx(mat.density * 10.0)
def test_mass():
m = openmc.Material()
@ -394,6 +397,9 @@ def test_mass():
assert m.get_mass() == pytest.approx(20.0)
assert m.fissionable_mass == pytest.approx(10.0)
# Test with volume specified as argument
assert m.get_mass('Zr90', volume=1.0) == pytest.approx(1.0)
def test_materials(run_in_tmpdir):
m1 = openmc.Material()
@ -544,11 +550,14 @@ def test_get_activity():
m4.volume = 10.
assert pytest.approx(m4.get_activity(units='Bq')) == 355978108155965.94*3/2*10 # [Bq]
# Test with volume specified as argument
assert pytest.approx(m4.get_activity(units='Bq', volume=1.0)) == 355978108155965.94*3/2
def test_get_decay_heat():
# Set chain file for testing
openmc.config['chain_file'] = Path(__file__).parents[1] / 'chain_simple.xml'
"""Tests the decay heat of stable, metastable and active materials"""
m1 = openmc.Material()
m1.add_nuclide("U235", 0.2)
@ -589,7 +598,10 @@ def test_get_decay_heat():
# volume is required to calculate total decay heat
m4.volume = 10.
assert pytest.approx(m4.get_decay_heat(units='W')) == 40175.15720273193*3/2*10 # [W]
# Test with volume specified as argument
assert pytest.approx(m4.get_decay_heat(units='W', volume=1.0)) == 40175.15720273193*3/2
def test_decay_photon_energy():
# Set chain file for testing