Skip to content

Commit 36e3a0e

Browse files
committed
inp: added like-but cell cards
1 parent 7be17c2 commit 36e3a0e

File tree

13 files changed

+227
-12
lines changed

13 files changed

+227
-12
lines changed

src/pymcnp/Inp.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class Inp(_object.McnpFile):
3333
def __init__(
3434
self,
3535
title: types.String,
36-
cells: types.Tuple[inp.Cell],
36+
cells: types.Tuple[inp.Cell | inp.Like],
3737
surfaces: types.Tuple[inp.Surface],
3838
data: types.Tuple[inp.Data],
3939
cells_comments: types.Tuple[inp.Comment] = None,
@@ -127,6 +127,13 @@ def from_mcnp(source: str):
127127
except errors.InpError:
128128
pass
129129

130+
try:
131+
cells.append(inp.Like.from_mcnp(line))
132+
continue
133+
except errors.InpError as err:
134+
print(err)
135+
pass
136+
130137
cells.append(inp.Cell.from_mcnp(line))
131138

132139
surfaces = []

src/pymcnp/inp/Cell.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ class Cell(Card):
1515
Represents INP cell cards.
1616
1717
Attributes:
18-
InpError: SEMANTICS_CARD.
18+
number: cell number.
19+
material: cell material.
20+
density: cell density.
21+
geometry: cell geometry.
22+
options: cell options.
1923
"""
2024

2125
_ATTRS = {
@@ -50,11 +54,11 @@ def __init__(
5054
InpError: SEMANTICS_CARD.
5155
"""
5256

53-
if number is None or not (1 <= number.value <= 99_999_999):
57+
if number is None or not (1 <= number <= 99_999_999):
5458
raise errors.InpError(errors.InpCode.SEMANTICS_CARD, number)
55-
if material is None or not (0 <= material.value <= 99_999_999):
59+
if material is None or not (0 <= material <= 99_999_999):
5660
raise errors.InpError(errors.InpCode.SEMANTICS_CARD, material)
57-
if (density is not None and material.value == 0) or (density is None and material.value != 0):
61+
if (density is not None and material == 0) or (density is None and material != 0):
5862
raise errors.InpError(errors.InpCode.SEMANTICS_CARD, density)
5963
if geometry is None:
6064
raise errors.InpError(errors.InpCode.SEMANTICS_CARD, geometry)

src/pymcnp/inp/Data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class Data(Card):
1414
Represents INP data elements.
1515
1616
Attributes:
17-
InpError: SEMANTICS_CARD.
17+
option: data option.
1818
"""
1919

2020
_ATTRS = {'option': data.DataOption}

src/pymcnp/inp/Like.py

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import re
2+
import copy
3+
import dataclasses
4+
5+
6+
from . import cell
7+
from ._card import Card
8+
from ..utils import types
9+
from ..utils import errors
10+
from ..utils import _parser
11+
12+
13+
class Like(Card):
14+
"""
15+
Represents INP cell cards.
16+
17+
Attributes:
18+
number: cell number.
19+
original: cell similar.
20+
options: cell options.
21+
"""
22+
23+
_ATTRS = {
24+
'number': types.Integer,
25+
'original': types.Integer,
26+
'options': types.Tuple[cell.CellOption],
27+
}
28+
29+
_REGEX = re.compile(rf'\A(\S+) like (\S+) but( ({cell.CellOption._REGEX.pattern[2:-2]}))*\Z')
30+
31+
def __init__(
32+
self,
33+
number: types.Integer,
34+
original: types.Integer,
35+
options: types.Tuple[cell.CellOption] = None,
36+
):
37+
"""
38+
Initializes ``Like``.
39+
40+
Parameters:
41+
number: cell number.
42+
original: cell similar.
43+
options: cell options.
44+
45+
Raises:
46+
InpError: SEMANTICS_CARD.
47+
"""
48+
49+
if number is None or not (1 <= number <= 99_999_999):
50+
raise errors.InpError(errors.InpCode.SEMANTICS_CARD, number)
51+
if original is None or not (1 <= original <= 99_999_999):
52+
raise errors.InpError(errors.InpCode.SEMANTICS_CARD, original)
53+
if options is not None and None in options:
54+
raise errors.InpError(errors.InpCode.SEMANTICS_CARD, options)
55+
56+
self.number: types.Integer = number
57+
self.original: types.Integer = original
58+
self.options: types.Tuple[cell.CellOption] = options
59+
60+
def to_mcnp(self):
61+
"""
62+
Generates INP from ``Like``.
63+
64+
Returns:
65+
INP cell card.
66+
"""
67+
68+
source = f'{self.number} like {self.original} but {self.options or ""}'
69+
source, comments = _parser.preprocess_inp(source)
70+
source = _parser.postprocess_inp(source)
71+
72+
return source
73+
74+
75+
@dataclasses.dataclass
76+
class LikeBuilder:
77+
"""
78+
Builds ``Like``.
79+
80+
Attributes:
81+
number: cell number.
82+
original: cell similar.
83+
options: cell options.
84+
"""
85+
86+
number: str | int | types.Integer
87+
original: str | int | types.Integer
88+
options: list[str] | list[cell.CellOption] | list[cell.CellOptionBuilder] = None
89+
90+
def build(self):
91+
"""
92+
Builds ``LikeBuilder`` into ``Like``.
93+
94+
Returns:
95+
``Like`` for ``LikeBuilder``.
96+
"""
97+
98+
number = self.number
99+
if isinstance(self.number, types.Integer):
100+
number = self.number
101+
elif isinstance(self.number, int):
102+
number = types.Integer(self.number)
103+
elif isinstance(self.number, str):
104+
number = types.Integer.from_mcnp(self.number)
105+
106+
original = self.original
107+
if isinstance(self.original, types.Integer):
108+
original = self.original
109+
elif isinstance(self.original, int):
110+
original = types.Integer(self.original)
111+
elif isinstance(self.original, str):
112+
original = types.Integer.from_mcnp(self.original)
113+
114+
if self.options:
115+
options = []
116+
for item in self.options:
117+
if isinstance(item, cell.CellOption):
118+
options.append(item)
119+
elif isinstance(item, str):
120+
options.append(cell.CellOption.from_mcnp(item))
121+
elif isinstance(item, cell.CellOptionBuilder):
122+
options.append(item.build())
123+
options = types.Tuple(options)
124+
else:
125+
options = None
126+
127+
return Like(
128+
number=number,
129+
original=original,
130+
options=options,
131+
)
132+
133+
@staticmethod
134+
def unbuild(ast: Like):
135+
"""
136+
Unbuilds ``Like`` into ``LikeBuilder``
137+
138+
Returns:
139+
``LikeBuilder`` for ``Like``.
140+
"""
141+
142+
return LikeBuilder(
143+
number=copy.deepcopy(ast.number),
144+
original=copy.deepcopy(ast.original),
145+
options=copy.deepcopy(ast.options),
146+
)

src/pymcnp/inp/Surface.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ def __init__(
5353
InpError: SEMANTICS_CARD.
5454
"""
5555

56-
if number is None or not (1 <= number.value <= 99_999_999 if not transform else 999):
56+
if number is None or not (1 <= number <= 99_999_999 if not transform else 999):
5757
raise errors.InpError(errors.InpCode.SEMANTICS_CARD, number)
58-
if transform is not None and not (0 <= transform.value <= 999):
58+
if transform is not None and not (0 <= transform <= 999):
5959
raise errors.InpError(errors.InpCode.SEMANTICS_CARD, transform)
6060
if option is None:
6161
raise errors.InpError(errors.InpCode.SEMANTICS_CARD, option)

src/pymcnp/inp/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
from . import surface
55
from . import data
66
from .Cell import Cell
7+
from .Like import Like
78
from .Surface import Surface
89
from .Data import Data
910
from .Comment import Comment
1011
from .Cell import CellBuilder
12+
from .Like import LikeBuilder
1113
from .Surface import SurfaceBuilder
1214
from .Data import DataBuilder
1315
from .Comment import CommentBuilder
@@ -19,10 +21,12 @@
1921
'surface',
2022
'data',
2123
'Cell',
24+
'Like',
2225
'Surface',
2326
'Data',
2427
'Comment',
2528
'CellBuilder',
29+
'LikeBuilder',
2630
'SurfaceBuilder',
2731
'DataBuilder',
2832
'CommentBuilder',

tests/consts.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class type:
3939

4040
class inp:
4141
CELL = '1 1 3.1 1 (2:(+3 -4) #5) imp:@=1'
42+
LIKE = '2 like 1 but imp:@=2'
4243
SURFACE = '1 SO 1'
4344
DATA = 'vol no 3.1 3.1 3.1'
4445
COMMENT = 'c hello'
@@ -1338,6 +1339,7 @@ class type:
13381339

13391340
class inp:
13401341
CELL = pymcnp.inp.Cell.from_mcnp(string.inp.CELL)
1342+
LIKE = pymcnp.inp.Like.from_mcnp(string.inp.LIKE)
13411343
SURFACE = pymcnp.inp.Surface.from_mcnp(string.inp.SURFACE)
13421344
DATA = pymcnp.inp.Data.from_mcnp(string.inp.DATA)
13431345
COMMENT = pymcnp.inp.Comment.from_mcnp(string.inp.COMMENT)
@@ -2032,6 +2034,7 @@ class type:
20322034

20332035
class inp:
20342036
CELL = pymcnp.inp.CellBuilder.unbuild(ast.inp.CELL)
2037+
LIKE = pymcnp.inp.LikeBuilder.unbuild(ast.inp.LIKE)
20352038
SURFACE = pymcnp.inp.SurfaceBuilder.unbuild(ast.inp.SURFACE)
20362039
DATA = pymcnp.inp.DataBuilder.unbuild(ast.inp.DATA)
20372040
COMMENT = pymcnp.inp.CommentBuilder.unbuild(ast.inp.COMMENT)

tests/files/inp/valid_4_1c.i

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
lattice example 18
22
1 1 -0.5 -7 #2 #3 #4 #5 #6 imp:n=1
33
2 0 1 -2 -3 4 5 -6 imp:n=2 trcl=2 fill=1
4-
c 3 like 2 but trcl=3
4+
3 like 2 but trcl=3
55
c 4 like 2 but trcl=4
66
c 5 like 2 but trcl=5 imp:n=1
77
c 6 like 2 but trcl=6

tests/test_pymcnp/test_inp/test_Cell.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,18 @@ class Test_Mcnp(classes.Test_Mcnp):
2424
'5 0 #(-1 2 -4)',
2525
'5 0 (+1 : -2 : +4)',
2626
'2 3 -3.7 -1 IMP:N=2 IMP:P=4',
27-
#'3 LIKE 2 BUT IMP:N=10 TRCL=1',
2827
'10 16 -4.2 1 -2 3 IMP:N=4 IMP:P=8 EXT:N=-0.4',
2928
'3 0 -1.2 -1.1 1.4 -1.5 -1.6 99',
3029
'4 0 1.1 -2001.1 -5.3 -5.5 -5.6 -5.4',
3130
'5 0 -5',
3231
'1 0 -1',
33-
#'2 like 1 but trcl = (2 0 0)',
3432
'9 0 (-5.1:1.3:2001.1:-99:5.5:5.6) #5',
3533
'3 0 5.1 -1.1 -5.3 -5.5 -5.6 99',
3634
'3 0 5.1 -1.1 1.4 -5.5 -5.6 -5.4',
3735
'3 0 -1.2 -1.1 -5.3 -5.5 -5.6 -5.4',
3836
'1 0 1 -2 3 $ cell 1',
3937
# 3.3
4038
'1 0 -17 $ rcc can',
41-
#'21 like 1 but *tracl=(20 0 0 45 -45 90 135 45 90 90 90 0)',
4239
'1 0 1 -2 -3 4 -5 6 fill=1',
4340
'2 0 -7 1 -3 8 u=1 fill=2 lat=1',
4441
'3 0 -11 u=-2',
@@ -112,6 +109,7 @@ class Test_Mcnp(classes.Test_Mcnp):
112109
'10 0 #1 #2 #3 #4 #5 #6 #7 #8 #9 -28',
113110
'3 0 8 -9 -10 11 -12 13 #2 #1',
114111
'4 0 -11 12 -14 13 imp:n=1 lat=1 u=1 fill=3',
112+
consts.string.inp.CELL,
115113
]
116114
EXAMPLES_INVALID = [
117115
'hello',

tests/test_pymcnp/test_inp/test_Comment.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class Test_Mcnp(classes.Test_Mcnp):
2121
# 4.1
2222
'c cell cards',
2323
'c surface cards',
24+
consts.string.inp.COMMENT,
2425
]
2526
EXAMPLES_INVALID = [
2627
'hello',

0 commit comments

Comments
 (0)