Repository: terrapower/armi
Pull request #1881 (2024-09-16 01:35:45)

Renaming Reactor.moveList to Reactor.moves
## What is the change?

I am renaming `Reactor.moveList` to `Reactor.moves`. 

(There is only one downstream project that I can find that might be affected by this change.)

## Why is the change being made?

The attribute is actually a `dict` and not a `list`. And this is one of the main reasons we don't inject the variable type into the variable name when we write code.

---

## Checklist

- [x] This PR has only [one purpose or idea](https://terrapower.github.io/armi/developer/tooling.html#one-idea-one-pr).
- [x] [Tests](https://terrapower.github.io/armi/developer/tooling.html#test-it) have been added/updated to verify any new/changed code.

<!-- Check the code quality -->

- [x] The code style follows [good practices](https://terrapower.github.io/armi/developer/standards_and_practices.html).
- [x] The commit message(s) follow [good practices](https://terrapower.github.io/armi/developer/tooling.html).

<!-- Check the project-level cruft -->

- [x] The [release notes](https://terrapower.github.io/armi/developer/tooling.html#add-release-notes) have been updated if necessary.
- [x] The [documentation](https://terrapower.github.io/armi/developer/tooling.html#document-it) is still up-to-date in the `doc` folder.
- [x] The dependencies are still up-to-date in `pyproject.toml`.


Patch:
diff --git a/armi/physics/fuelCycle/fuelHandlerInterface.py b/armi/physics/fuelCycle/fuelHandlerInterface.py
index c99047c9..511dc185 100644
--- a/armi/physics/fuelCycle/fuelHandlerInterface.py
+++ b/armi/physics/fuelCycle/fuelHandlerInterface.py
@@ -142,7 +142,7 @@ class FuelHandlerInterface(interfaces.Interface):
 
         This can be used to export shuffling to an external code or to
         perform explicit repeat shuffling in a restart.
-        It creates a ``*SHUFFLES.txt`` file based on the Reactor.moveList structure
+        It creates a ``*SHUFFLES.txt`` file based on the Reactor.moves structure
 
         See Also
         --------
@@ -155,7 +155,7 @@ class FuelHandlerInterface(interfaces.Interface):
             # remember, we put cycle 0 in so we could do BOL branch searches.
             # This also syncs cycles up with external physics kernel cycles.
             out.write("Before cycle {0}:\n".format(cycle + 1))
-            movesThisCycle = self.r.core.moveList.get(cycle)
+            movesThisCycle = self.r.core.moves.get(cycle)
             if movesThisCycle is not None:
                 for (
                     fromLoc,
diff --git a/armi/reactor/reactors.py b/armi/reactor/reactors.py
index a0a29945..f18f048d 100644
--- a/armi/reactor/reactors.py
+++ b/armi/reactor/reactors.py
@@ -293,7 +293,7 @@ class Core(composites.Composite):
         self.timeOfStart = time.time()
         self.zones = zones.Zones()  # initialize with empty Zones object
         # initialize the list that holds all shuffles
-        self.moveList = {}
+        self.moves = {}
         self.scalarVals = {}
         self._nuclideCategories = {}
         self.typeList = []  # list of block types to convert name - to -number.
@@ -1886,13 +1886,12 @@ class Core(composites.Composite):
     def setMoveList(self, cycle, oldLoc, newLoc, enrichList, assemblyType, assemName):
         """Tracks the movements in terms of locations and enrichments."""
         data = (oldLoc, newLoc, enrichList, assemblyType, assemName)
-        # NOTE: moveList is actually a moveDict (misnomer)
-        if self.moveList.get(cycle) is None:
-            self.moveList[cycle] = []
-        if data in self.moveList[cycle]:
+        if self.moves.get(cycle) is None:
+            self.moves[cycle] = []
+        if data in self.moves[cycle]:
             # remove the old version and throw the new on at the end.
-            self.moveList[cycle].remove(data)
-        self.moveList[cycle].append(data)
+            self.moves[cycle].remove(data)
+        self.moves[cycle].append(data)
 
     def createFreshFeed(self, cs=None):
         """
diff --git a/armi/utils/plotting.py b/armi/utils/plotting.py
index c640cdcf..8e713eeb 100644
--- a/armi/utils/plotting.py
+++ b/armi/utils/plotting.py
@@ -425,7 +425,7 @@ def close(fig=None):
 
 
 def _makeAssemPatches(core):
-    """Return a list of assembly shaped patch for each assembly."""
+    """Return a list of assembly shaped patches for each assembly."""
     patches = []
 
     if isinstance(core.spatialGrid, grids.HexGrid):
@@ -441,8 +441,12 @@ def _makeAssemPatches(core):
     for a in core:
         x, y, _ = a.spatialLocator.getLocalCoordinates()
         if nSides == 6:
+            if core.spatialGrid.cornersUp:
+                orientation = 0
+            else:
+                orientation = math.pi / 2.0
             assemPatch = matplotlib.patches.RegularPolygon(
-                (x, y), nSides, radius=pitch / math.sqrt(3), orientation=math.pi / 2.0
+                (x, y), nSides, radius=pitch / math.sqrt(3), orientation=orientation
             )
         elif nSides == 4:
             # for rectangle x, y is defined as sides instead of center
@@ -942,10 +946,6 @@ def plotBlockFlux(core, fName=None, bList=None, peak=False, adjoint=False, bList
     bList2 :
         a separate list of blocks that will also be plotted on a separate axis on the same plot.
         This is useful for comparing flux in some blocks with flux in some other blocks.
-
-    Notes
-    -----
-    This is not a great method. It should be cleand up and migrated into ``utils.plotting``.
     """
 
     class BlockListFlux:
diff --git a/doc/release/0.4.rst b/doc/release/0.4.rst
index 2515ce43..16203254 100644
--- a/doc/release/0.4.rst
+++ b/doc/release/0.4.rst
@@ -11,10 +11,8 @@ New Features
 #. ARMI now supports Python 3.12. (`PR#1813 <https://github.com/terrapower/armi/pull/1813>`_)
 #. Removing the ``tabulate`` dependency by ingesting it to ``armi.utils.tabulate``. (`PR#1811 <https://github.com/terrapower/armi/pull/1811>`_)
 #. Adding ``--skip-inspection`` flag to ``CompareCases`` CLI. (`PR#1842 <https://github.com/terrapower/armi/pull/1842>`_)
-#. Provide utilities for determining location of a rotated object in a hexagonal lattice:
-   :func:`armi.utils.hexagon.getIndexOfRotatedCell`
-   (`PR#1846 <https://github.com/terrapower/armi/1846`)
-#. Allow merging a component with zero area into another component (`PR#1858 <https://github.com/terrapower/armi/pull/1858>`_)
+#. Provide utilities for determining location of a rotated object in a hexagonal lattice (``getIndexOfRotatedCell``). (`PR#1846 <https://github.com/terrapower/armi/1846`)
+#. Allow merging a component with zero area into another component. (`PR#1858 <https://github.com/terrapower/armi/pull/1858>`_)
 #. TBD
 
 API Changes
@@ -23,9 +21,8 @@ API Changes
 #. Removing deprecated method ``prepSearch``. (`PR#1845 <https://github.com/terrapower/armi/pull/1845>`_)
 #. Removing unused function ``SkippingXsGen_BuChangedLessThanTolerance``. (`PR#1845 <https://github.com/terrapower/armi/pull/1845>`_)
 #. Allow for unknown Flags when opening a DB. (`PR#1844 <https://github.com/terrapower/armi/pull/1835>`_)
-#. ``Assembly.rotatePins`` and ``Block.rotatePins`` have been removed. Prefer to use
-   :meth:`armi.reactor.assemblies.Assembly.rotate` and meth:`armi.reactor.block.Block.rotate`
-   (`PR#1846 <https://github.com/terrapower/armi/1846`)
+#. ``Assembly.rotatePins`` and ``Block.rotatePins`` have been removed. Prefer to use ``Assembly.rotate`` and ``Block.rotate``. (`PR#1846 <https://github.com/terrapower/armi/1846`)
+#. Renaming ``Reactor.moveList`` to ``Reactor.moves``. (`PR#1881 <https://github.com/terrapower/armi/pull/1881>`_)
 #. TBD
 
 Bug Fixes
@@ -35,13 +32,14 @@ Bug Fixes
 #. Fixed ``PermissionError`` when using ``syncDbAfterWrite``. (`PR#1857 <https://github.com/terrapower/armi/pull/1857>`_)
 #. Fixed ``MpiDirectoryChanger``. (`PR#1853 <https://github.com/terrapower/armi/pull/1853>`_)
 #. Changed data type of ``thKernel`` setting from ``bool`` to ``str`` in ``ThermalHydraulicsPlugin``. (`PR#1855 <https://github.com/terrapower/armi/pull/1855>`_)
+#. Rotate hexagonal assembly patches correctly on facemap plots. (`PR#1883 <https://github.com/terrapower/armi/pull/1883>`_)
 #. Update height of fluid components after axial expansion (`PR#1828 <https://github.com/terrapower/armi/pull/1828>`_)
 #. TBD
 
 Quality Work
 ------------
-#. Removing deprecated code (``axialUnitGrid``) (`PR#1809 <https://github.com/terrapower/armi/pull/1809>`_)
-#. Refactoring (``axialExpansionChanger``) (`PR#1861 <https://github.com/terrapower/armi/pull/1861>`_)
+#. Removing deprecated code ``axialUnitGrid``. (`PR#1809 <https://github.com/terrapower/armi/pull/1809>`_)
+#. Refactoring ``axialExpansionChanger``. (`PR#1861 <https://github.com/terrapower/armi/pull/1861>`_)
 #. TBD
 
 Changes that Affect Requirements


Test patch:
diff --git a/armi/tests/smallestTestReactor/refSmallestReactor.yaml b/armi/tests/smallestTestReactor/refSmallestReactor.yaml
index 83f05f7f..8b9396b5 100644
--- a/armi/tests/smallestTestReactor/refSmallestReactor.yaml
+++ b/armi/tests/smallestTestReactor/refSmallestReactor.yaml
@@ -15,7 +15,7 @@ systems:
             z: 6000.0
 grids:
     core:
-      geom: hex
+      geom: hex_corners_up
       lattice map: |
         IC
       symmetry: full
\ No newline at end of file
diff --git a/armi/utils/tests/test_plotting.py b/armi/utils/tests/test_plotting.py
index f4a7b4e9..0fdb9e1c 100644
--- a/armi/utils/tests/test_plotting.py
+++ b/armi/utils/tests/test_plotting.py
@@ -16,6 +16,8 @@
 import os
 import unittest
 
+import numpy as np
+
 from armi.nuclearDataIO.cccc import isotxs
 from armi.reactor.flags import Flags
 from armi.reactor.tests import test_reactors
@@ -127,3 +129,57 @@ class TestPlotting(unittest.TestCase):
 
     def _checkExists(self, fName):
         self.assertTrue(os.path.exists(fName))
+
+
+class TestPatches(unittest.TestCase):
+    """Test the ability to correctly make patches."""
+
+    def test_makeAssemPatches(self):
+        # this one is flats-up with many assemblies in the core
+        _, rHexFlatsUp = test_reactors.loadTestReactor()
+
+        nAssems = len(rHexFlatsUp.core)
+        self.assertGreater(nAssems, 1)
+        patches = plotting._makeAssemPatches(rHexFlatsUp.core)
+        self.assertEqual(len(patches), nAssems)
+
+        # find the patch corresponding to the center assembly
+        for patch in patches:
+            if np.allclose(patch.xy, (0, 0)):
+                break
+
+        vertices = patch.get_verts()
+        # there should be 1 more than the number of points in the shape
+        self.assertEqual(len(vertices), 7)
+        # for flats-up, the first vertex should have a y position of ~zero
+        self.assertAlmostEqual(vertices[0][1], 0)
+
+        # this one is corners-up, with only a single assembly
+        _, rHexCornersUp = test_reactors.loadTestReactor(
+            inputFileName="smallestTestReactor/armiRunSmallest.yaml"
+        )
+
+        nAssems = len(rHexCornersUp.core)
+        self.assertEqual(nAssems, 1)
+        patches = plotting._makeAssemPatches(rHexCornersUp.core)
+        self.assertEqual(len(patches), 1)
+
+        vertices = patches[0].get_verts()
+        self.assertEqual(len(vertices), 7)
+        # for corners-up, the first vertex should have an x position of ~zero
+        self.assertAlmostEqual(vertices[0][0], 0)
+
+        # this one is cartestian, with many assemblies in the core
+        _, rCartesian = test_reactors.loadTestReactor(
+            inputFileName="refTestCartesian.yaml"
+        )
+
+        nAssems = len(rCartesian.core)
+        self.assertGreater(nAssems, 1)
+        patches = plotting._makeAssemPatches(rCartesian.core)
+        self.assertEqual(nAssems, len(patches))
+
+        # just pick a given patch and ensure that it is square-like. orientation
+        # is not important here.
+        vertices = patches[0].get_verts()
+        self.assertEqual(len(vertices), 5)