Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix to saving lattice map using the Grids GUI #494

Merged
merged 4 commits into from Dec 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 17 additions & 12 deletions armi/reactor/blueprints/gridBlueprint.py
Expand Up @@ -265,7 +265,7 @@ def _constructSpatialGrid(self):
runLog.extra("Creating the spatial grid")
if geom in (geometry.RZT, geometry.RZ):
if self.gridBounds is None:
# This check is regrattably late. It would be nice if we could validate
# This check is regrettably late. It would be nice if we could validate
# that bounds are provided if R-Theta mesh is being used.
raise InputError(
"Grid bounds must be provided for `{}` to specify a grid with "
Expand Down Expand Up @@ -580,27 +580,32 @@ def saveToStream(stream, bluep, full=False, tryMap=False):
if gridDesign.readFromLatticeMap or tryMap:
geomType = geometry.GeomType.fromStr(gridDesign.geom)
symmetry = geometry.SymmetryType.fromStr(gridDesign.symmetry)

john-science marked this conversation as resolved.
Show resolved Hide resolved
aMap = asciimaps.asciiMapFromGeomAndDomain(
gridDesign.geom, symmetry.domain
)()
aMap.asciiLabelByIndices = {
(key[0], key[1]): val for key, val in gridDesign.gridContents.items()
}
try:
aMap = asciimaps.asciiMapFromGeomAndDomain(
gridDesign.geom, symmetry.domain
)()
aMap.asciiLabelByIndices = {
(key[0], key[1]): val
for key, val in gridDesign.gridContents.items()
}
aMap.gridContentsToAscii()
except Exception as e:
runLog.warning(
"Cannot write geometry with asciimap. Defaulting to dict. Issue: {}".format(
e
)
f"The `lattice map` for the current assembly arrangement cannot be written. "
f"Defaulting to using the `grid contents` dictionary instead. Exception: {e}"
)
aMap = None

if aMap is not None:
# If there is an ascii map available then use it to fill out
# the contents of the lattice map section of the grid design.
# This also clears out the grid contents so there is not duplicate
# data.
gridDesign.gridContents = None
mapString = StringIO()
aMap.writeAscii(mapString)
gridDesign.latticeMap = scalarstring.LiteralScalarString(
gridDesign.latticeMap
mapString.getvalue()
jakehader marked this conversation as resolved.
Show resolved Hide resolved
)
else:
gridDesign.latticeMap = None
Expand Down
23 changes: 23 additions & 0 deletions armi/reactor/blueprints/tests/test_gridBlueprints.py
Expand Up @@ -294,6 +294,17 @@
FP
"""

TINY_GRID = """core:
geom: hex
lattice map:
grid bounds:
symmetry: full
grid contents:
? - 0
- 0
: IF
"""


class TestRoundTrip(unittest.TestCase):
def setUp(self):
Expand All @@ -309,6 +320,18 @@ def test_roundTrip(self):
gridBp = Grids.load(stream)
self.assertIn("third", gridBp["core"].symmetry)

def test_tiny_map(self):
grid = Grids.load(TINY_GRID)
stream = io.StringIO()
saveToStream(stream, grid, full=True, tryMap=True)
stream.seek(0)
text = stream.read()
self.assertIn("IF", text)
stream.seek(0)
gridBp = Grids.load(stream)
self.assertIn("full", gridBp["core"].symmetry)
self.assertIn("IF", gridBp["core"].latticeMap)


class TestGridBlueprintsSection(unittest.TestCase):
"""Tests for lattice blueprint section."""
Expand Down
8 changes: 5 additions & 3 deletions armi/utils/asciimaps.py
Expand Up @@ -215,7 +215,7 @@ def gridContentsToAscii(self):
# doing pure rows from data is made programmatically.
# newLines.append(line)
raise ValueError(
"Cannot write asciimaps with blank rows from pure data yet."
f"Cannot write asciimaps with blank rows from pure data yet."
)
if not newLines:
raise ValueError("No data found")
Expand Down Expand Up @@ -434,12 +434,14 @@ def _updateDimensionsFromData(self):
# Check the j=0 ray to see how many peripheral locations are blank.
# assume symmetry with the other corner.
# The cap is basically the distance from the (I, 0) or (0, J) loc to self._ijMax
maxIWithData = max(i for i, j in self.asciiLabelByIndices if j == 0)
iWithData = [i for i, j in self.asciiLabelByIndices if j == 0]
maxIWithData = max(iWithData) if iWithData else -1
self._asciiLinesOffCorner = (self._ijMax - maxIWithData) * 2 - 1

# in jagged systems we have to also check the neighbor.
# TODO: maybe even more corner positions could be left out in very large maps.
nextMaxIWithData = max(i for i, j in self.asciiLabelByIndices if j == 1)
nextIWithData = [i for i, j in self.asciiLabelByIndices if j == 1]
nextMaxIWithData = max(nextIWithData) if nextIWithData else -1
if nextMaxIWithData == maxIWithData - 1:
# the jagged edge is lopped off too.
self._asciiLinesOffCorner += 1
Expand Down
9 changes: 9 additions & 0 deletions doc/release/0.2.rst
Expand Up @@ -3,6 +3,15 @@ ARMI v0.2 Release Notes
=======================


ARMI v0.2.1
===========
Release Date: TBD


Bug fixes
---------
* Fixed issue where grid GUI was not saving lattice maps (`#490 <https://github.com/terrapower/armi/issues/490>`_)


ARMI v0.2.0
===========
Expand Down