Skip to content

Commit a9dc84f

Browse files
shimwelljon-proximafusionpaulromano
authored
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>
1 parent 8e06ed8 commit a9dc84f

File tree

2 files changed

+95
-4
lines changed

2 files changed

+95
-4
lines changed

openmc/material.py

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,26 @@ class Material(IDManagerMixin):
6060
temperature : float, optional
6161
Temperature of the material in Kelvin. If not specified, the material
6262
inherits the default temperature applied to the model.
63+
density : float, optional
64+
Density of the material (units defined separately)
65+
density_units : str
66+
Units used for `density`. Can be one of 'g/cm3', 'g/cc', 'kg/m3',
67+
'atom/b-cm', 'atom/cm3', 'sum', or 'macro'. The 'macro' unit only
68+
applies in the case of a multi-group calculation. Defaults to 'sum'.
69+
depletable : bool, optional
70+
Indicate whether the material is depletable. Defaults to False.
71+
volume : float, optional
72+
Volume of the material in cm^3. This can either be set manually or
73+
calculated in a stochastic volume calculation and added via the
74+
:meth:`Material.add_volume_information` method.
75+
components : dict of str to float or dict
76+
Dictionary mapping element or nuclide names to their atom or weight
77+
percent. To specify enrichment of an element, the entry of
78+
``components`` for that element must instead be a dictionary containing
79+
the keyword arguments as well as a value for ``'percent'``
80+
percent_type : {'ao', 'wo'}
81+
Whether the values in `components` should be interpreted as atom percent
82+
('ao') or weight percent ('wo').
6383
6484
Attributes
6585
----------
@@ -111,17 +131,28 @@ class Material(IDManagerMixin):
111131
next_id = 1
112132
used_ids = set()
113133

114-
def __init__(self, material_id=None, name='', temperature=None):
134+
def __init__(
135+
self,
136+
material_id: int | None = None,
137+
name: str = "",
138+
temperature: float | None = None,
139+
density: float | None = None,
140+
density_units: str = "sum",
141+
depletable: bool | None = False,
142+
volume: float | None = None,
143+
components: dict | None = None,
144+
percent_type: str = "ao",
145+
):
115146
# Initialize class attributes
116147
self.id = material_id
117148
self.name = name
118149
self.temperature = temperature
119150
self._density = None
120-
self._density_units = 'sum'
121-
self._depletable = False
151+
self._density_units = density_units
152+
self._depletable = depletable
122153
self._paths = None
123154
self._num_instances = None
124-
self._volume = None
155+
self._volume = volume
125156
self._atoms = {}
126157
self._isotropic = []
127158
self._ncrystal_cfg = None
@@ -136,6 +167,15 @@ def __init__(self, material_id=None, name='', temperature=None):
136167
# If specified, a list of table names
137168
self._sab = []
138169

170+
# Set density if provided
171+
if density is not None:
172+
self.set_density(density_units, density)
173+
174+
# Add components if provided
175+
if components is not None:
176+
self.add_components(components, percent_type=percent_type)
177+
178+
139179
def __repr__(self) -> str:
140180
string = 'Material\n'
141181
string += '{: <16}=\t{}\n'.format('\tID', self._id)

tests/unit_tests/test_material.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,3 +768,54 @@ def test_mean_free_path():
768768
mat2.add_nuclide('Pb208', 1.0)
769769
mat2.set_density('g/cm3', 11.34)
770770
assert mat2.mean_free_path(energy=14e6) == pytest.approx(5.65, abs=1e-2)
771+
772+
773+
def test_material_from_constructor():
774+
# Test that components and percent_type work in the constructor
775+
components = {
776+
'Li': {'percent': 0.5, 'enrichment': 60.0, 'enrichment_target': 'Li7'},
777+
'O16': 1.0,
778+
'Be': 0.5
779+
}
780+
mat = openmc.Material(
781+
material_id=123,
782+
name="test-mat",
783+
components=components,
784+
percent_type="ao"
785+
)
786+
# Check that nuclides were added
787+
nuclide_names = [nuc.name for nuc in mat.nuclides]
788+
assert 'O16' in nuclide_names
789+
assert 'Be9' in nuclide_names
790+
assert 'Li7' in nuclide_names
791+
assert 'Li6' in nuclide_names
792+
assert mat.id == 123
793+
assert mat.name == "test-mat"
794+
795+
mat1 = openmc.Material(
796+
**{
797+
"material_id": 1,
798+
"name": "neutron_star",
799+
"density": 1e17,
800+
"density_units": "kg/m3",
801+
}
802+
)
803+
assert mat1.id == 1
804+
assert mat1.name == "neutron_star"
805+
assert mat1._density == 1e17
806+
assert mat1._density_units == "kg/m3"
807+
assert mat1.nuclides == []
808+
809+
mat2 = openmc.Material(
810+
material_id=42,
811+
name="plasma",
812+
temperature=None,
813+
density=1e-7,
814+
density_units="g/cm3",
815+
)
816+
assert mat2.id == 42
817+
assert mat2.name == "plasma"
818+
assert mat2.temperature is None
819+
assert mat2.density == 1e-7
820+
assert mat2.density_units == "g/cm3"
821+
assert mat2.nuclides == []

0 commit comments

Comments
 (0)