mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 22:26:08 -04:00
Add support for 'distribmat' cells to Cell.atoms
Provide missing atoms entry in Cell Attributes Create docstring for Cell.atoms
This commit is contained in:
parent
36512e3096
commit
023f9e4690
2 changed files with 77 additions and 24 deletions
|
|
@ -86,7 +86,12 @@ class Cell(IDManagerMixin):
|
|||
volume : float
|
||||
Volume of the cell in cm^3. This can either be set manually or
|
||||
calculated in a stochastic volume calculation and added via the
|
||||
:meth:`Cell.add_volume_information` method.
|
||||
:meth:`Cell.add_volume_information` method. For 'distribmat' cells
|
||||
it is a total volume of all instances.
|
||||
atoms : dict
|
||||
Mapping of nuclides to total number of atoms for each nuclide present
|
||||
in the cell, or all its instances for 'sdistribmat' fill. For example,
|
||||
{'U235': 1.0e22, 'U238': 5.0e22, ...}.
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -189,6 +194,21 @@ class Cell(IDManagerMixin):
|
|||
|
||||
@property
|
||||
def atoms(self):
|
||||
""" Get total number of atoms of each nuclide in the cell
|
||||
|
||||
Returns
|
||||
-------
|
||||
atoms: collections.OrderedDict
|
||||
Dictionary which keys are nuclides and values the number of atoms.
|
||||
For example, {'H1':1.0e22, 'O16':0.5e22, ...}
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If total volume of the cell is not set
|
||||
ValueError
|
||||
If cell is filled with Universe, Lattice or Void
|
||||
"""
|
||||
if self._atoms is None:
|
||||
if self._volume is None:
|
||||
msg = ('Cannot calculate atoms content becouse no volume '
|
||||
|
|
@ -201,10 +221,10 @@ class Cell(IDManagerMixin):
|
|||
'Material must be set to calculate atoms content.')
|
||||
raise ValueError(msg)
|
||||
|
||||
elif self.fill_type != 'material':
|
||||
msg = ('Universe, Lattice and Distributed Material cells can '
|
||||
'contain multiple materials. Atoms content must be '
|
||||
'calculated with stochastic volume calculation')
|
||||
elif self.fill_type in ['lattice', 'universe']:
|
||||
msg = ('Universe and Lattice cells can contain multiple '
|
||||
'materials in diffrent proportions. Atoms content must '
|
||||
'be calculated with stochastic volume calculation')
|
||||
raise ValueError(msg)
|
||||
|
||||
elif self.fill_type == 'material':
|
||||
|
|
@ -213,8 +233,23 @@ class Cell(IDManagerMixin):
|
|||
|
||||
# Convert to total number of atoms
|
||||
for key, nuclide in self._atoms.items():
|
||||
atom_num = nuclide[1] * self._volume * 1.0E+24
|
||||
self._atoms[key] = (nuclide[0], atom_num)
|
||||
atom = nuclide[1] * self._volume * 1.0e+24
|
||||
self._atoms[key] = atom
|
||||
|
||||
elif self.fill_type == 'distribmat':
|
||||
# Assumes that volume is total volume of all instances
|
||||
# Also assumes that all instances have the same volume
|
||||
partial_volume = self.volume / len(self.fill)
|
||||
self._atoms = OrderedDict()
|
||||
for mat in self.fill:
|
||||
for key, nuclide in mat.get_nuclide_atom_densities().items():
|
||||
# To account for overlap of nuclides between distribmat
|
||||
# we need to append new atoms # to any existing value
|
||||
# hence it is necessary to ask for default.
|
||||
atom = self._atoms.setdefault(key, 0)
|
||||
atom += nuclide[1] * partial_volume * 1.0e+24
|
||||
self._atoms[key] = atom
|
||||
|
||||
else:
|
||||
msg = 'Unrecognised fill_type:{}'.format(self.fill_type)
|
||||
raise ValueError(msg)
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ def test_volume_setting():
|
|||
c.volume = u.ufloat(-0.05, 0.1)
|
||||
|
||||
|
||||
def test_atoms_of_material_cell(uo2, water):
|
||||
def test_atoms_material_cell(uo2, water):
|
||||
""" Test if correct number of atoms is returned.
|
||||
Also check if Cell.atoms still works after volume/material was changed
|
||||
"""
|
||||
|
|
@ -153,12 +153,12 @@ def test_atoms_of_material_cell(uo2, water):
|
|||
expected_nucs = ['U235', 'O16']
|
||||
|
||||
# Precalculate the expected number of atoms
|
||||
molarMass = ((atomic_mass('U235') + 2 * atomic_mass('O16'))/3)
|
||||
M = ((atomic_mass('U235') + 2 * atomic_mass('O16'))/3)
|
||||
expected_atoms = list()
|
||||
expected_atoms.append(1/3 * uo2.density/molarMass * AVOGADRO * 2.0) # U235
|
||||
expected_atoms.append(2/3 * uo2.density/molarMass * AVOGADRO * 2.0) # O16
|
||||
expected_atoms.append(1/3 * uo2.density/M * AVOGADRO * 2.0) # U235
|
||||
expected_atoms.append(2/3 * uo2.density/M * AVOGADRO * 2.0) # O16
|
||||
|
||||
tuples = list(c.atoms.values())
|
||||
tuples = list(c.atoms.items())
|
||||
for nuc, atom_num, t in zip(expected_nucs, expected_atoms, tuples):
|
||||
assert nuc == t[0]
|
||||
assert atom_num == t[1]
|
||||
|
|
@ -166,10 +166,10 @@ def test_atoms_of_material_cell(uo2, water):
|
|||
# Change volume and check if OK
|
||||
c.volume = 3.0
|
||||
expected_atoms = list()
|
||||
expected_atoms.append(1/3 * uo2.density/molarMass * AVOGADRO * 3.0) # U235
|
||||
expected_atoms.append(2/3 * uo2.density/molarMass * AVOGADRO * 3.0) # O16
|
||||
expected_atoms.append(1/3 * uo2.density/M * AVOGADRO * 3.0) # U235
|
||||
expected_atoms.append(2/3 * uo2.density/M * AVOGADRO * 3.0) # O16
|
||||
|
||||
tuples = list(c.atoms.values())
|
||||
tuples = list(c.atoms.items())
|
||||
for nuc, atom_num, t in zip(expected_nucs, expected_atoms, tuples):
|
||||
assert nuc == t[0]
|
||||
assert atom_num == pytest.approx(t[1], rel=TOL)
|
||||
|
|
@ -177,12 +177,35 @@ def test_atoms_of_material_cell(uo2, water):
|
|||
# Change material and check if OK
|
||||
c.fill = water
|
||||
expected_nucs = ['H1', 'O16']
|
||||
molarMass = ((2 * atomic_mass('H1') + atomic_mass('O16'))/3)
|
||||
M = ((2 * atomic_mass('H1') + atomic_mass('O16'))/3)
|
||||
expected_atoms = list()
|
||||
expected_atoms.append(2/3 * water.density/molarMass * AVOGADRO * 3.0) # H1
|
||||
expected_atoms.append(1/3 * water.density/molarMass * AVOGADRO * 3.0) # O16
|
||||
expected_atoms.append(2/3 * water.density/M * AVOGADRO * 3.0) # H1
|
||||
expected_atoms.append(1/3 * water.density/M * AVOGADRO * 3.0) # O16
|
||||
|
||||
tuples = list(c.atoms.values())
|
||||
tuples = list(c.atoms.items())
|
||||
for nuc, atom_num, t in zip(expected_nucs, expected_atoms, tuples):
|
||||
assert nuc == t[0]
|
||||
assert atom_num == pytest.approx(t[1], rel=TOL)
|
||||
|
||||
|
||||
def test_atoms_distribmat_cell(uo2, water):
|
||||
""" Test if correct number of atoms is returned for a cell with
|
||||
'distribmat' fill
|
||||
"""
|
||||
c = openmc.Cell(fill=[uo2, water])
|
||||
c.volume = 6.0
|
||||
|
||||
# Calculate the expected number of atoms
|
||||
expected_nucs = ['U235', 'O16', 'H1']
|
||||
M_uo2 = ((atomic_mass('U235') + 2 * atomic_mass('O16'))/3)
|
||||
M_water = ((2 * atomic_mass('H1') + atomic_mass('O16'))/3)
|
||||
expected_atoms = list()
|
||||
expected_atoms.append(1/3 * uo2.density/M_uo2 * AVOGADRO * 3.0) # U235
|
||||
expected_atoms.append(2/3 * uo2.density/M_uo2 * AVOGADRO * 3.0 +
|
||||
1/3 * water.density/M_water * AVOGADRO * 3.0) # O16
|
||||
expected_atoms.append(2/3 * water.density/M_water * AVOGADRO * 3.0) # H1
|
||||
|
||||
tuples = list(c.atoms.items())
|
||||
for nuc, atom_num, t in zip(expected_nucs, expected_atoms, tuples):
|
||||
assert nuc == t[0]
|
||||
assert atom_num == pytest.approx(t[1], rel=TOL)
|
||||
|
|
@ -191,11 +214,6 @@ def test_atoms_of_material_cell(uo2, water):
|
|||
def test_atoms_errors(cell_with_lattice):
|
||||
cells, mats, univ, lattice = cell_with_lattice
|
||||
|
||||
# Distributed Material
|
||||
with pytest.raises(ValueError):
|
||||
cells[0].volume = 2
|
||||
cells[0].atoms
|
||||
|
||||
# Material Cell with no Volume
|
||||
with pytest.raises(ValueError):
|
||||
cells[1].atoms
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue