diff --git a/src/openmc_mcnp_adapter/parse.py b/src/openmc_mcnp_adapter/parse.py index b02dfc1..05060e0 100644 --- a/src/openmc_mcnp_adapter/parse.py +++ b/src/openmc_mcnp_adapter/parse.py @@ -241,13 +241,28 @@ def parse_data(section): for line in lines: if _MATERIAL_RE.match(line): g = _MATERIAL_RE.match(line).groups() - spec = g[1].split() + spec_text = g[1] + + # Extract keywords (key=value) and remove them from spec + keyword_pattern = re.compile(r'(\S+)\s*=\s*(\S+)') + keywords = {} + def extract_keyword(match): + keywords[match.group(1).lower()] = match.group(2) + return '' + spec_text = keyword_pattern.sub(extract_keyword, spec_text) + + # Parse remaining nuclide-density pairs + spec = spec_text.split() try: nuclides = list(zip(spec[::2], map(float_, spec[1::2]))) except Exception: raise ValueError('Invalid material specification?') + uid = int(g[0]) - data['materials'][uid].update({'id': uid, 'nuclides': nuclides}) + material_data = {'id': uid, 'nuclides': nuclides} + if keywords: + material_data['keywords'] = keywords + data['materials'][uid].update(material_data) elif _SAB_RE.match(line): g = _SAB_RE.match(line).groups() uid = int(g[0]) diff --git a/tests/test_geometry.py b/tests/test_geometry.py index 87524ac..05e045d 100644 --- a/tests/test_geometry.py +++ b/tests/test_geometry.py @@ -106,12 +106,19 @@ def test_likenbut(): (1.0, 0.0, 0.2), ], ), - param( + ( "1 0 -1 TRCL=(0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 -1)", ("1 rpp -0.5 0.5 -0.25 0.25 -0.1 0.1",), - [], - [], - marks=mark.xfail(reason="13-parameter TRCL not yet supported"), + [ + (-0.4, 0.1, 0.0), + (0.0, 0.0, 0.0), + (0.49, -0.24, -0.05), + ], + [ + (-0.6, 0.0, 0.0), + (0.0, 0.5, 0.0), + (0.0, 0.0, 0.2), + ], ), ], ) diff --git a/tests/test_material.py b/tests/test_material.py index 12dff0a..dc3f7da 100644 --- a/tests/test_material.py +++ b/tests/test_material.py @@ -109,3 +109,50 @@ def test_density_no_whitespace(): model = mcnp_str_to_model(mcnp_model) m = model.materials[0] assert m.get_mass_density() == approx(4.5) + + +def test_material_keywords_at_beginning(): + """Test material card with keywords at the beginning""" + mat_card = "m1 NLIB=70c PLIB=04p 92235.70c 1.0 92238.70c 0.5" + m = convert_material(mat_card, -1.0) + nd = m.get_nuclide_densities() + assert 'U235' in nd and nd['U235'].percent == approx(1.0) + assert 'U238' in nd and nd['U238'].percent == approx(0.5) + + +def test_material_keywords_in_middle(): + """Test material card with keywords interspersed with nuclide pairs""" + mat_card = "m1 92235.70c 1.0 NLIB=70c 92238.70c 0.5 PLIB=04p 92234.70c 0.3" + m = convert_material(mat_card, -1.0) + nd = m.get_nuclide_densities() + assert 'U235' in nd and nd['U235'].percent == approx(1.0) + assert 'U238' in nd and nd['U238'].percent == approx(0.5) + assert 'U234' in nd and nd['U234'].percent == approx(0.3) + + +def test_material_keywords_with_spaces(): + """Test material card with keywords that have spaces around equals sign""" + mat_card = "m1 92235.70c 1.5 NLIB = 80c 92238.70c 0.5 GAS = 0" + m = convert_material(mat_card, -2.0) + nd = m.get_nuclide_densities() + assert 'U235' in nd and nd['U235'].percent == approx(1.5) + assert 'U238' in nd and nd['U238'].percent == approx(0.5) + assert m.get_mass_density() == approx(2.0) + + +def test_material_keywords_at_end(): + """Test material card with keywords at the end""" + mat_card = "m1 92235.70c 2.0 92238.70c 1.0 NLIB=70c PLIB=04p" + m = convert_material(mat_card, -1.0) + nd = m.get_nuclide_densities() + assert 'U235' in nd and nd['U235'].percent == approx(2.0) + assert 'U238' in nd and nd['U238'].percent == approx(1.0) + + +def test_material_without_keywords(): + """Test that material cards without keywords still work correctly""" + mat_card = "m1 92235.70c 1.0 92238.70c 0.5" + m = convert_material(mat_card, -1.0) + nd = m.get_nuclide_densities() + assert 'U235' in nd and nd['U235'].percent == approx(1.0) + assert 'U238' in nd and nd['U238'].percent == approx(0.5)