Skip to content

Commit 334888b

Browse files
committed
Fix conversion of repeat shortcut to handle non-integers
1 parent e7f5077 commit 334888b

2 files changed

Lines changed: 49 additions & 6 deletions

File tree

src/openmc_mcnp_adapter/parse.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,27 @@
4444
_SAB_RE = re.compile(r'\s*[Mm][Tt](\d+)((?:\s+\S+)+)')
4545
_MODE_RE = re.compile(r'\s*mode(?:\s+\S+)*')
4646
_COMPLEMENT_RE = re.compile(r'(#)[ ]*(\d+)')
47-
_REPEAT_RE = re.compile(r'(\d+)\s+(\d+)[rR]')
4847
_NUM_RE = re.compile(r'(\d)([+-])(\d)')
4948

49+
_REPEAT_RE = re.compile(r"""
50+
(?P<value> # The numeric value to be repeated
51+
[+-]? # Optional sign
52+
(?: # Mantissa
53+
\d+(?:\.\d*)? # Digits with optional fractional part (e.g., 3 or 3. or 3.0)
54+
| # or
55+
\.\d+ # Leading-dot form (e.g., .25)
56+
)
57+
(?: # Optional exponent
58+
[eEdD][+-]?\d+ # E/D exponent with optional sign (e.g., 1e-3, 2D+3)
59+
| # or MCNP "bare" exponent without E/D
60+
[+-]\d+ # appended sign+digits (e.g., 1.0-3 -> 1.0e-3)
61+
)?
62+
)
63+
\s+ # One or more spaces between value and count
64+
(?P<count>\d+) # The repeat count
65+
[rR] # The 'R' or 'r' suffix
66+
""", re.VERBOSE)
67+
5068

5169
def float_(val):
5270
"""Convert scientific notation literals that don't have an 'e' in them to float"""
@@ -346,11 +364,11 @@ def sanitize(section: str) -> str:
346364
section = re.sub('\n {5}', ' ', section)
347365

348366
# Expand repeated numbers
349-
m = _REPEAT_RE.search(section)
350-
while m is not None:
351-
section = _REPEAT_RE.sub(' '.join((int(m.group(2)) + 1)*[m.group(1)]),
352-
section, 1)
353-
m = _REPEAT_RE.search(section)
367+
section = _REPEAT_RE.sub(
368+
lambda m: ' '.join([m.group('value')] * (int(m.group('count')) + 1)),
369+
section,
370+
)
371+
354372
return section
355373

356374

tests/test_syntax.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from textwrap import dedent
2+
3+
from openmc_mcnp_adapter import mcnp_str_to_model
4+
5+
6+
def test_repeat_shortcut():
7+
mcnp_str = dedent("""
8+
title
9+
1 0 -1
10+
11+
1 gq 1.0 3r 0.0 5r
12+
13+
m1 1001.80c 3.0
14+
""")
15+
model = mcnp_str_to_model(mcnp_str)
16+
surf = model.geometry.get_all_surfaces()[1]
17+
print(surf)
18+
19+
# Make sure A, B, C, and D parameters are 1.0
20+
for attr in 'abcd':
21+
assert getattr(surf, attr) == 1.0
22+
23+
# Make sure E, F, G, H, J, and K parameters are 0.0
24+
for attr in 'efghj':
25+
assert getattr(surf, attr) == 0.0

0 commit comments

Comments
 (0)