Skip to content

Commit e2d382a

Browse files
committed
inp: added cell visualization
1 parent 74957ea commit e2d382a

115 files changed

Lines changed: 918 additions & 448 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/pymcnp/Inp.py

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import re
22

33
from . import inp
4-
from . import _show
54
from . import _file
65
from . import types
76
from . import errors
@@ -142,25 +141,6 @@ def to_mcnp(self):
142141
+ (self.other.value if self.other is not None else '')
143142
)
144143

145-
def draw(self) -> _show.Shape:
146-
"""
147-
Generates ``Visualization`` from ``Inp``.
148-
149-
Returns:
150-
``Visualization`` for ``Inp``.
151-
"""
152-
153-
surfaces = list(filter(lambda surface: isinstance(surface, inp.Surface), self.surfaces))
154-
155-
if surfaces:
156-
vis = surfaces[0].draw()
157-
for surface in surfaces[1:]:
158-
if isinstance(surface, inp.Surface):
159-
vis += surface.draw()
160-
return vis
161-
162-
return None
163-
164144
@staticmethod
165145
def _preprocess(source: str):
166146
"""

src/pymcnp/Visualize.py

Lines changed: 103 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import os
22
import pathlib
33

4+
import numpy
45
import pyvista
56

7+
from . import inp
8+
from . import _show
69
from . import _doer
710
from . import errors
811
from .Inp import Inp
@@ -13,24 +16,30 @@ class Visualize(_doer.Doer):
1316
Visualizes INP files.
1417
1518
Attributes:
16-
inp: Files to visualize.
19+
inpt: Files to visualize.
1720
"""
1821

19-
def __init__(self, inp: Inp):
22+
GRID = pyvista.ImageData(
23+
dimensions=(_show.pyvista.RESOLUTION, _show.pyvista.RESOLUTION, _show.pyvista.RESOLUTION),
24+
spacing=(_show.pyvista.BOUND / _show.pyvista.RESOLUTION, _show.pyvista.BOUND / _show.pyvista.RESOLUTION, _show.pyvista.BOUND / _show.pyvista.RESOLUTION),
25+
origin=(-_show.pyvista.BOUND / 2, -_show.pyvista.BOUND / 2, -_show.pyvista.BOUND / 2),
26+
)
27+
28+
def __init__(self, inpt: Inp):
2029
"""
2130
Initializes ``Visualize``.
2231
2332
Parameters:
24-
inp: Files to visualize.
33+
inpt: Files to visualize.
2534
2635
Raises:
2736
CliCode: RUNTIME_DOER.
2837
"""
2938

30-
if inp is None:
31-
raise errors.CliError(errors.CliCode.RUNTIME_DOER, inp)
39+
if inpt is None:
40+
raise errors.CliError(errors.CliCode.RUNTIME_DOER, inpt)
3241

33-
self.inp = inp
42+
self.inpt = inpt
3443

3544
def to_show_cells(self) -> pyvista.Plotter:
3645
"""
@@ -39,8 +48,23 @@ def to_show_cells(self) -> pyvista.Plotter:
3948

4049
plot = pyvista.Plotter()
4150
plot.add_axes()
42-
# vis = self.inp.draw()
43-
# plot.add_mesh(vis.data)
51+
52+
surfaces = {str(surface.number): surface.to_show() for surface in self.inpt.surfaces if isinstance(surface, inp.Surface)}
53+
cells = {}
54+
55+
for cell in self.inpt.cells:
56+
if isinstance(cell, inp.Cell):
57+
shape = cell.to_show(surfaces, cells)
58+
elif isinstance(cell, inp.Like):
59+
shape = cells[str(cell.cell)]
60+
else:
61+
continue
62+
63+
cells[str(cell.number)] = shape
64+
65+
self.GRID['cell'] = shape.cell(self.GRID.points).astype(numpy.float32)
66+
plot.add_volume(self.GRID, scalars='cell', opacity=[0, 0, 0.01, 0.01])
67+
plot.add_mesh(shape.surface, opacity=0.9)
4468

4569
return plot
4670

@@ -51,8 +75,73 @@ def to_show_surfaces(self) -> pyvista.Plotter:
5175

5276
plot = pyvista.Plotter()
5377
plot.add_axes()
54-
vis = self.inp.draw()
55-
plot.add_mesh(vis.data)
78+
79+
for surface in self.inpt.surfaces:
80+
if not isinstance(surface, inp.Surface):
81+
continue
82+
83+
shape = surface.to_show()
84+
85+
plot.add_mesh(shape.surface)
86+
87+
return plot
88+
89+
def to_show_cell(self, number: str) -> pyvista.Plotter:
90+
"""
91+
Visualizes INP cells.
92+
93+
Parameters:
94+
number: Cell number to visualize.
95+
"""
96+
97+
plot = pyvista.Plotter()
98+
plot.add_axes()
99+
100+
surfaces = {str(surface.number): surface.to_show() for surface in self.inpt.surfaces if isinstance(surface, inp.Surface)}
101+
cells = {}
102+
103+
for cell in self.inpt.cells:
104+
if isinstance(cell, inp.Cell):
105+
shape = cell.to_show(surfaces, cells)
106+
elif isinstance(cell, inp.Like):
107+
shape = cells[str(cell.cell)]
108+
else:
109+
continue
110+
111+
cells[str(cell.number)] = shape
112+
113+
if str(cell.number) != number:
114+
continue
115+
116+
self.GRID['cell'] = shape.cell(self.GRID.points).astype(numpy.float32)
117+
plot.add_volume(self.GRID, scalars='cell', opacity=[0, 0, 0.01, 0.01])
118+
plot.add_mesh(shape.surface, opacity=0.9)
119+
120+
break
121+
else:
122+
raise errors.CliError(errors.CliCode.RUNTIME_DOER, number)
123+
124+
return plot
125+
126+
def to_show_surface(self, number: str) -> pyvista.Plotter:
127+
"""
128+
Visualizes INP surfaces.
129+
130+
Parameters:
131+
number: Surface number to visualize.
132+
"""
133+
134+
plot = pyvista.Plotter()
135+
plot.add_axes()
136+
137+
for surface in self.inpt.surfaces:
138+
if not isinstance(surface, inp.Surface) or str(surface.number) != number:
139+
continue
140+
141+
plot.add_mesh(surface.to_show().surface)
142+
break
143+
else:
144+
raise errors.CliError(errors.CliCode.RUNTIME_DOER, number)
56145

57146
return plot
58147

@@ -64,11 +153,10 @@ def to_pdf_cells(self, path: str | pathlib.Path):
64153
path: Path to new pdf file.
65154
"""
66155

67-
# plot = pyvista.Plotter()
68-
# vis = self.inp.draw()
69-
# plot.add_mesh(vis.data)
156+
plot = self.to_show_cells()
70157

71-
# plot.save_graphic(str(path))
158+
if 'PYTEST_CURRENT_TEST' not in os.environ: # pragma: no cover
159+
plot.save_graphic(str(path))
72160

73161
def to_pdf_surfaces(self, path: str | pathlib.Path):
74162
"""
@@ -78,10 +166,7 @@ def to_pdf_surfaces(self, path: str | pathlib.Path):
78166
path: Path to new pdf file.
79167
"""
80168

81-
plot = pyvista.Plotter()
82-
plot.add_axes()
83-
vis = self.inp.draw()
84-
plot.add_mesh(vis.data)
169+
plot = self.to_show_surfaces()
85170

86171
if 'PYTEST_CURRENT_TEST' not in os.environ: # pragma: no cover
87172
plot.save_graphic(str(path))

src/pymcnp/_cli/visualize.py

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
"""
22
Usage:
3-
pymcnp visualize <inp> [ options ]
3+
pymcnp visualize <inp> [ options... ]
44
55
Options:
6-
-c --cells Visualize cells.
7-
-s --surfaces Visualize surfaces.
8-
--pdf Write PDF.
6+
-c --cells Visualize all cells.
7+
-s --surfaces Visualize all surfaces.
8+
-c --cell=[<number>] Visualize cell.
9+
-s --surface=[<number>] Visualize surface.
10+
--pdf Write PDF.
911
"""
1012

1113
import os
@@ -15,6 +17,7 @@
1517

1618
from . import _io
1719
from .. import errors
20+
from .. import inp
1821
from ..Inp import Inp
1922
from ..Visualize import Visualize
2023

@@ -32,15 +35,21 @@ def main() -> None:
3235

3336
# Reading INP.
3437
try:
35-
inp = Inp.from_file(file)
36-
visualize = Visualize(inp)
38+
inpt = Inp.from_file(file)
39+
visualize = Visualize(inpt)
3740
except errors.InpError as err:
3841
_io.error(str(err))
3942
exit(1)
4043
except errors.CliError as err:
4144
_io.error(str(err))
4245
exit(2)
4346

47+
if not (args['--cells'] or args['--surfaces'] or args['--cell'] or args['--surface']):
48+
args['--cells'] = True
49+
args['--surfaces'] = True
50+
args['--cell'] = [str(cell.number) for cell in inpt.cells if isinstance(cell, inp.Cell)]
51+
args['--surface'] = [str(surface.number) for surface in inpt.surfaces if isinstance(surface, inp.Surface)]
52+
4453
# Visualizing!
4554
if args['--cells']:
4655
if args['--pdf']:
@@ -51,7 +60,7 @@ def main() -> None:
5160
if 'PYTEST_CURRENT_TEST' not in os.environ: # pragma: no cover
5261
plot.show()
5362

54-
else:
63+
if args['--surfaces']:
5564
if args['--pdf']:
5665
visualize.to_pdf_surfaces(_io.get_outfile(file, 'pdf', 'surfaces'))
5766
else:
@@ -60,4 +69,22 @@ def main() -> None:
6069
if 'PYTEST_CURRENT_TEST' not in os.environ: # pragma: no cover
6170
plot.show()
6271

72+
for number in args['--cell']:
73+
if args['--pdf']:
74+
visualize.to_pdf_cells(_io.get_outfile(file, 'pdf', f'cell_{number}'))
75+
else:
76+
plot = visualize.to_show_cell(number)
77+
78+
if 'PYTEST_CURRENT_TEST' not in os.environ: # pragma: no cover
79+
plot.show()
80+
81+
for number in args['--surface']:
82+
if args['--pdf']:
83+
visualize.to_pdf_cells(_io.get_outfile(file, 'pdf', f'surface_{number}'))
84+
else:
85+
plot = visualize.to_show_surface(number)
86+
87+
if 'PYTEST_CURRENT_TEST' not in os.environ: # pragma: no cover
88+
plot.show()
89+
6390
_io.done()

src/pymcnp/_show/_shape.py

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,24 @@ class Shape(metaclass=abc.ABCMeta):
88
Represents generic visualizations.
99
1010
Attributes:
11-
data: Underlying visualization.
11+
surface: Underlying surface visualization.
12+
cell: Underlying cell visualization.
1213
"""
1314

14-
def __init__(self, data):
15+
def __init__(self, surface, cell):
1516
"""
1617
Initializes ``Shape``.
1718
1819
Parameters:
19-
data: Underlying visualization.
20+
surface: Underlying surface visualization.
21+
cell: Underlying cell visualization.
2022
2123
Returns:
2224
``Shape``
2325
"""
2426

25-
self.data = data
27+
self.surface = surface
28+
self.cell = cell
2629

2730
@abc.abstractmethod
2831
def __add__(a, b): # pragma: no cover
@@ -54,34 +57,34 @@ def __and__(a, b): # pragma: no cover
5457

5558
raise NotImplementedError
5659

57-
# @abc.abstractmethod
58-
# def __or__(a, b): # pragma: no cover
59-
# """
60-
# Intersects ``Shape``.
60+
@abc.abstractmethod
61+
def __or__(a, b): # pragma: no cover
62+
"""
63+
Intersects ``Shape``.
6164
62-
# Parameters:
63-
# a: Operand #1.
64-
# b: Operand #2.
65+
Parameters:
66+
a: Operand #1.
67+
b: Operand #2.
6568
66-
# Returns:
67-
# ``Shape`` intersection.
68-
# """
69+
Returns:
70+
``Shape`` intersection.
71+
"""
6972

70-
# raise NotImplementedError
73+
raise NotImplementedError
7174

72-
# @abc.abstractmethod
73-
# def __invert__(a): # pragma: no cover
74-
# """
75-
# Inverts ``Shape``.
75+
@abc.abstractmethod
76+
def __invert__(a): # pragma: no cover
77+
"""
78+
Complements ``Shape``.
7679
77-
# Parameters:
78-
# a: Operand #1.
80+
Parameters:
81+
a: Operand #1.
7982
80-
# Returns:
81-
# ``Shape`` complement.
82-
# """
83+
Returns:
84+
``Shape`` complement.
85+
"""
8386

84-
# raise NotImplementedError
87+
raise NotImplementedError
8588

8689
@abc.abstractmethod
8790
def rotate(self, axis: numpy.ndarray): # pragma: no cover

src/pymcnp/_show/pyvista/Box.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import numpy
12
import pyvista
23

34
from . import _shape
@@ -19,7 +20,6 @@ def __init__(self, a: float, b: float, c: float):
1920
"""
2021

2122
super().__init__(
22-
pyvista.Box(
23-
bounds=(0, a, 0, b, 0, c),
24-
)
23+
pyvista.Box((0, a, 0, b, 0, c)),
24+
lambda p: ~numpy.all((p >= 0) & (p <= [a, b, c]), axis=1),
2525
)

0 commit comments

Comments
 (0)