Allowing material making from class constructor (#3649)

Co-authored-by: Jon Shimwell <jon@proximafusion.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
This commit is contained in:
Jonathan Shimwell 2025-12-08 20:43:30 +01:00 committed by GitHub
parent 8e06ed8998
commit a9dc84f75a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 95 additions and 4 deletions

View file

@ -60,6 +60,26 @@ class Material(IDManagerMixin):
temperature : float, optional
Temperature of the material in Kelvin. If not specified, the material
inherits the default temperature applied to the model.
density : float, optional
Density of the material (units defined separately)
density_units : str
Units used for `density`. Can be one of 'g/cm3', 'g/cc', 'kg/m3',
'atom/b-cm', 'atom/cm3', 'sum', or 'macro'. The 'macro' unit only
applies in the case of a multi-group calculation. Defaults to 'sum'.
depletable : bool, optional
Indicate whether the material is depletable. Defaults to False.
volume : float, optional
Volume of the material in cm^3. This can either be set manually or
calculated in a stochastic volume calculation and added via the
:meth:`Material.add_volume_information` method.
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'}
Whether the values in `components` should be interpreted as atom percent
('ao') or weight percent ('wo').
Attributes
----------
@ -111,17 +131,28 @@ class Material(IDManagerMixin):
next_id = 1
used_ids = set()
def __init__(self, material_id=None, name='', temperature=None):
def __init__(
self,
material_id: int | None = None,
name: str = "",
temperature: float | None = None,
density: float | None = None,
density_units: str = "sum",
depletable: bool | None = False,
volume: float | None = None,
components: dict | None = None,
percent_type: str = "ao",
):
# Initialize class attributes
self.id = material_id
self.name = name
self.temperature = temperature
self._density = None
self._density_units = 'sum'
self._depletable = False
self._density_units = density_units
self._depletable = depletable
self._paths = None
self._num_instances = None
self._volume = None
self._volume = volume
self._atoms = {}
self._isotropic = []
self._ncrystal_cfg = None
@ -136,6 +167,15 @@ class Material(IDManagerMixin):
# If specified, a list of table names
self._sab = []
# Set density if provided
if density is not None:
self.set_density(density_units, density)
# Add components if provided
if components is not None:
self.add_components(components, percent_type=percent_type)
def __repr__(self) -> str:
string = 'Material\n'
string += '{: <16}=\t{}\n'.format('\tID', self._id)

View file

@ -768,3 +768,54 @@ def test_mean_free_path():
mat2.add_nuclide('Pb208', 1.0)
mat2.set_density('g/cm3', 11.34)
assert mat2.mean_free_path(energy=14e6) == pytest.approx(5.65, abs=1e-2)
def test_material_from_constructor():
# Test that components and percent_type work in the constructor
components = {
'Li': {'percent': 0.5, 'enrichment': 60.0, 'enrichment_target': 'Li7'},
'O16': 1.0,
'Be': 0.5
}
mat = openmc.Material(
material_id=123,
name="test-mat",
components=components,
percent_type="ao"
)
# Check that nuclides were added
nuclide_names = [nuc.name for nuc in mat.nuclides]
assert 'O16' in nuclide_names
assert 'Be9' in nuclide_names
assert 'Li7' in nuclide_names
assert 'Li6' in nuclide_names
assert mat.id == 123
assert mat.name == "test-mat"
mat1 = openmc.Material(
**{
"material_id": 1,
"name": "neutron_star",
"density": 1e17,
"density_units": "kg/m3",
}
)
assert mat1.id == 1
assert mat1.name == "neutron_star"
assert mat1._density == 1e17
assert mat1._density_units == "kg/m3"
assert mat1.nuclides == []
mat2 = openmc.Material(
material_id=42,
name="plasma",
temperature=None,
density=1e-7,
density_units="g/cm3",
)
assert mat2.id == 42
assert mat2.name == "plasma"
assert mat2.temperature is None
assert mat2.density == 1e-7
assert mat2.density_units == "g/cm3"
assert mat2.nuclides == []