From f7ea5855b17ff90f793de7b9fcc5e7e4a477e1b6 Mon Sep 17 00:00:00 2001 From: jake hader Date: Tue, 30 Nov 2021 13:16:19 -0800 Subject: [PATCH 1/4] Fix to writing the lattice map as a string when saving the core map from the Grids GUI. This fixes a bug introduced in #440. --- armi/reactor/blueprints/gridBlueprint.py | 27 ++++++++++++++---------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/armi/reactor/blueprints/gridBlueprint.py b/armi/reactor/blueprints/gridBlueprint.py index 57aa8050be..4cd8859f97 100644 --- a/armi/reactor/blueprints/gridBlueprint.py +++ b/armi/reactor/blueprints/gridBlueprint.py @@ -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) + + 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() ) else: gridDesign.latticeMap = None From 4d09dd15c62b6f81c8b7f1a99a2e6b098df78837 Mon Sep 17 00:00:00 2001 From: Nick Touran Date: Wed, 1 Dec 2021 08:54:23 -0800 Subject: [PATCH 2/4] Add test to ensure lattice maps are written This test fails with code from #440 but passes given the fix associated with this PR. --- armi/reactor/blueprints/gridBlueprint.py | 2 +- .../blueprints/tests/test_gridBlueprints.py | 24 +++++++++++++++++++ armi/utils/asciimaps.py | 8 ++++--- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/armi/reactor/blueprints/gridBlueprint.py b/armi/reactor/blueprints/gridBlueprint.py index 4cd8859f97..c54061a7cd 100644 --- a/armi/reactor/blueprints/gridBlueprint.py +++ b/armi/reactor/blueprints/gridBlueprint.py @@ -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 " diff --git a/armi/reactor/blueprints/tests/test_gridBlueprints.py b/armi/reactor/blueprints/tests/test_gridBlueprints.py index e95da0f18c..a792a80a49 100644 --- a/armi/reactor/blueprints/tests/test_gridBlueprints.py +++ b/armi/reactor/blueprints/tests/test_gridBlueprints.py @@ -294,6 +294,16 @@ FP """ +TINY_GRID = """core: + geom: hex + lattice map: + grid bounds: + symmetry: full + grid contents: + ? - 0 + - 0 + : IF +""" class TestRoundTrip(unittest.TestCase): def setUp(self): @@ -309,6 +319,20 @@ 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() + #import pdb; pdb.set_trace() + 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.""" diff --git a/armi/utils/asciimaps.py b/armi/utils/asciimaps.py index 14ad9af631..6b9a5d1685 100644 --- a/armi/utils/asciimaps.py +++ b/armi/utils/asciimaps.py @@ -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") @@ -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 len(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 len(nextIWithData) else -1 if nextMaxIWithData == maxIWithData - 1: # the jagged edge is lopped off too. self._asciiLinesOffCorner += 1 From e4d71252148885b15d23d4d8a976f10d00817f3b Mon Sep 17 00:00:00 2001 From: Nick Touran Date: Wed, 1 Dec 2021 09:13:17 -0800 Subject: [PATCH 3/4] Fix formatting --- armi/reactor/blueprints/tests/test_gridBlueprints.py | 4 ++-- armi/utils/asciimaps.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/armi/reactor/blueprints/tests/test_gridBlueprints.py b/armi/reactor/blueprints/tests/test_gridBlueprints.py index a792a80a49..041a22ff8f 100644 --- a/armi/reactor/blueprints/tests/test_gridBlueprints.py +++ b/armi/reactor/blueprints/tests/test_gridBlueprints.py @@ -305,6 +305,7 @@ : IF """ + class TestRoundTrip(unittest.TestCase): def setUp(self): self.grids = Grids.load(SMALL_HEX) @@ -322,7 +323,7 @@ def test_roundTrip(self): def test_tiny_map(self): grid = Grids.load(TINY_GRID) stream = io.StringIO() - #import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() saveToStream(stream, grid, full=True, tryMap=True) stream.seek(0) text = stream.read() @@ -333,7 +334,6 @@ def test_tiny_map(self): self.assertIn("IF", gridBp["core"].latticeMap) - class TestGridBlueprintsSection(unittest.TestCase): """Tests for lattice blueprint section.""" diff --git a/armi/utils/asciimaps.py b/armi/utils/asciimaps.py index 6b9a5d1685..488cd4b282 100644 --- a/armi/utils/asciimaps.py +++ b/armi/utils/asciimaps.py @@ -435,13 +435,13 @@ def _updateDimensionsFromData(self): # assume symmetry with the other corner. # The cap is basically the distance from the (I, 0) or (0, J) loc to self._ijMax iWithData = [i for i, j in self.asciiLabelByIndices if j == 0] - maxIWithData = max(iWithData) if len(iWithData) else -1 + 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. nextIWithData = [i for i, j in self.asciiLabelByIndices if j == 1] - nextMaxIWithData = max( nextIWithData ) if len(nextIWithData) else -1 + nextMaxIWithData = max(nextIWithData) if nextIWithData else -1 if nextMaxIWithData == maxIWithData - 1: # the jagged edge is lopped off too. self._asciiLinesOffCorner += 1 From e6b75394a123530384884026535dd3ed2b4d300c Mon Sep 17 00:00:00 2001 From: Nick Touran Date: Wed, 1 Dec 2021 09:17:50 -0800 Subject: [PATCH 4/4] Update release notes --- armi/reactor/blueprints/tests/test_gridBlueprints.py | 1 - doc/release/0.2.rst | 9 +++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/armi/reactor/blueprints/tests/test_gridBlueprints.py b/armi/reactor/blueprints/tests/test_gridBlueprints.py index 041a22ff8f..4efba44350 100644 --- a/armi/reactor/blueprints/tests/test_gridBlueprints.py +++ b/armi/reactor/blueprints/tests/test_gridBlueprints.py @@ -323,7 +323,6 @@ def test_roundTrip(self): def test_tiny_map(self): grid = Grids.load(TINY_GRID) stream = io.StringIO() - # import pdb; pdb.set_trace() saveToStream(stream, grid, full=True, tryMap=True) stream.seek(0) text = stream.read() diff --git a/doc/release/0.2.rst b/doc/release/0.2.rst index 55cb6ee5ed..ecd4a6371d 100644 --- a/doc/release/0.2.rst +++ b/doc/release/0.2.rst @@ -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 `_) + ARMI v0.2.0 ===========