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

Fixing sub-block grids #1947

Merged
merged 38 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
0a3764c
Save point
john-science Oct 10, 2024
f19ea49
linting
john-science Oct 10, 2024
b79e2e7
cleanup
john-science Oct 10, 2024
ac34bb3
Merge branch 'main' into sub_block_grids
john-science Oct 11, 2024
b244c8a
Adding release note
john-science Oct 11, 2024
55c6715
Apply suggestions from code review
john-science Oct 11, 2024
dc73342
Responding to comments
john-science Oct 11, 2024
1942ed1
responding to reviewer: test docstrings
john-science Oct 11, 2024
3facbc8
Removed unused setting autoGenerateBlockGrids
john-science Oct 11, 2024
37dd62e
Anchroring grid to block - per reviewer
john-science Oct 11, 2024
0d55251
Responding to comments - test refactor
john-science Oct 11, 2024
2f8a350
Merge branch 'main' into sub_block_grids
john-science Oct 14, 2024
349e406
Merge branch 'main' into sub_block_grids
john-science Oct 14, 2024
7d8ab19
On a hex lattice, sub-hex grids are rotated
john-science Oct 14, 2024
6141cc7
Merge branch 'main' into sub_block_grids
john-science Oct 15, 2024
e8182dd
Making unit tests more stable
john-science Oct 15, 2024
4f8242a
Merge branch 'sub_block_grids' of https://www.github.com/terrapower/a…
john-science Oct 15, 2024
86516c7
Blocks are on same grid as Core
john-science Oct 16, 2024
0b44753
Merge branch 'main' into sub_block_grids
john-science Oct 22, 2024
2fcb8ab
fixing variable name capitalization
john-science Oct 22, 2024
9c94c8a
DREW: aligning block and sub-block grids
john-science Oct 22, 2024
e20455a
MINOR tweak to release notes
john-science Oct 22, 2024
34a4f67
Merge branch 'main' into sub_block_grids
john-science Oct 23, 2024
f0d12d8
Merge branch 'main' into sub_block_grids
john-science Oct 23, 2024
1ddb78b
merging in main
john-science Oct 23, 2024
7b34c9d
Removing unused, defunct, incorrect assertion
john-science Oct 23, 2024
8a7ac33
This is no longer true
john-science Oct 23, 2024
9bac9f8
Fixing sub-block grid
john-science Oct 23, 2024
4611c8c
Fixing main merge
john-science Oct 23, 2024
5641a74
Merge branch 'main' into sub_block_grids
john-science Oct 23, 2024
b6cc050
Merge branch 'main' into sub_block_grids
john-science Oct 24, 2024
5527772
Removing cornersUp assumptions
john-science Oct 24, 2024
8e9e624
Merge branch 'main' into sub_block_grids
john-science Oct 24, 2024
b369e50
Merge branch 'main' into sub_block_grids
john-science Oct 25, 2024
3a7c9b3
Merge branch 'main' into sub_block_grids
john-science Oct 25, 2024
716ad04
mergin MAIN
john-science Oct 28, 2024
a8342ed
Merge branch 'main' into sub_block_grids
john-science Oct 28, 2024
83e6000
Mergin in MaiN
john-science Oct 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions armi/reactor/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2356,10 +2356,12 @@ def autoCreateSpatialGrids(self, cornersUp=True):

Notes
-----
If the Block meets all the conditions, we gather all components to either be a
multiIndexLocation containing all of the pin positions, or the locator is the center (0,0).
When a hex grid has another hex grid nested inside it, the nested grid has the opposite
orientation (corners vs flats up). This method takes care of that.

Also, this only works on blocks that have 'flat side up'.
If components inside this block are multiplicity 1, they get a single locator at the center
of the grid cell. If the multiplicity is greater than 1, all the components are added to a
multiIndexLocation on the hex grid.

Raises
------
Expand All @@ -2379,7 +2381,18 @@ def autoCreateSpatialGrids(self, cornersUp=True):

# build the grid, from pitch and orientation
grid = grids.HexGrid.fromPitch(
self.getPinPitch(cold=True), numRings=0, cornersUp=cornersUp
self.getPinPitch(cold=True),
numRings=0,
armiObject=self,
cornersUp=cornersUp,
)

# build the sub-grid, with opposite orientation to the block
subGrid = grids.HexGrid.fromPitch(
self.getPinPitch(cold=True),
numRings=0,
armiObject=self,
cornersUp=not cornersUp,
john-science marked this conversation as resolved.
Show resolved Hide resolved
john-science marked this conversation as resolved.
Show resolved Hide resolved
)

ringNumber = hexagon.numRingsToHoldNumCells(self.getNumPins())
Expand All @@ -2389,17 +2402,17 @@ def autoCreateSpatialGrids(self, cornersUp=True):

if numLocations != self.getNumPins():
raise ValueError(
"Cannot create spatialGrid, number of locations in rings{} not equal to pin number{}".format(
"Cannot create spatialGrid, number of locations in rings {} not equal to pin number {}".format(
numLocations, self.getNumPins()
)
)

# set the spatial position of the sub-block components
spatialLocators = grids.MultiIndexLocation(grid=grid)
spatialLocators = grids.MultiIndexLocation(grid=subGrid)
for ring in range(ringNumber):
for pos in range(grid.getPositionsInRing(ring + 1)):
i, j = grid.getIndicesFromRingAndPos(ring + 1, pos + 1)
spatialLocators.append(grid[i, j, 0])
for pos in range(subGrid.getPositionsInRing(ring + 1)):
i, j = subGrid.getIndicesFromRingAndPos(ring + 1, pos + 1)
spatialLocators.append(subGrid[i, j, 0])

# finally, fill the spatial grid, and put the sub-block components on it
if self.spatialGrid is None:
Expand Down
4 changes: 4 additions & 0 deletions armi/reactor/grids/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ def __setstate__(self, state: Dict):
def isAxialOnly(self) -> bool:
"""Indicate to parts of ARMI if this Grid handles only axial cells."""

@property
def cornersUp(self) -> bool:
return False

drewj-tp marked this conversation as resolved.
Show resolved Hide resolved
@abstractmethod
def __len__(self) -> int:
"""Number of items in the grid."""
Expand Down
11 changes: 8 additions & 3 deletions armi/reactor/grids/tests/test_grids.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ class TestHexGrid(unittest.TestCase):
"""A set of tests for the Hexagonal Grid."""

def test_getCoordinatesFlatsUp(self):
"""Test getCoordinates() for flats up hex grids."""
grid = grids.HexGrid.fromPitch(1.0, cornersUp=False)
self.assertAlmostEqual(grid.pitch, 1.0)
side = 1.0 / math.sqrt(3)
Expand All @@ -262,6 +263,7 @@ def test_getCoordinatesFlatsUp(self):
assert_allclose(grid.getCoordinates((0, 1, 0)), jDirection)

def test_getCoordinatesCornersUp(self):
"""Test getCoordinates() for corners up hex grids."""
grid = grids.HexGrid.fromPitch(1.0, cornersUp=True)
self.assertAlmostEqual(grid.pitch, 1.0)
side = 1.0 / math.sqrt(3)
Expand All @@ -284,7 +286,8 @@ def test_getCoordinatesCornersUp(self):
assert_allclose(grid.getCoordinates((1, 0, 0)), iDirection)
assert_allclose(grid.getCoordinates((0, 1, 0)), jDirection)

def test_getLocalCoordinates(self):
def test_getLocalCoordinatesHex(self):
"""Test getLocalCoordinates() is different for corners up vs flats up hex grids."""
grid0 = grids.HexGrid.fromPitch(1.0, cornersUp=True)
grid1 = grids.HexGrid.fromPitch(1.0, cornersUp=False)
for i in range(3):
Expand All @@ -298,7 +301,8 @@ def test_getLocalCoordinates(self):
self.assertEqual(coords0[2], coords1[2], msg=f"Z @ ({i}, {j})")

def test_getLocalCoordinatesCornersUp(self):
# validate the first ring of a corners-up hex gric
"""Test getLocalCoordinates() for corners up hex grids."""
# validate the first ring of a corners-up hex grid
grid = grids.HexGrid.fromPitch(1.0, cornersUp=True)
vals = []
for pos in range(grid.getPositionsInRing(2)):
Expand All @@ -318,7 +322,8 @@ def test_getLocalCoordinatesCornersUp(self):
self.assertAlmostEqual(minX, -1)

def test_getLocalCoordinatesFlatsUp(self):
# validate the first ring of a flats-up hex gric
"""Test getLocalCoordinates() for flats up hex grids."""
# validate the first ring of a flats-up hex grid
grid = grids.HexGrid.fromPitch(1.0, cornersUp=False)
vals = []
for pos in range(grid.getPositionsInRing(2)):
Expand Down
2 changes: 1 addition & 1 deletion armi/reactor/spentFuelPool.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def add(self, assem, loc=None):
loc = self._getNextLocation()

# orient the blocks to match this grid
cornerUp = self.spatialGrid._unitSteps[0][1] == 0
cornerUp = self.spatialGrid.cornersUp
assem.orientBlocks(cornerUp)
drewj-tp marked this conversation as resolved.
Show resolved Hide resolved

super().add(assem, loc)
Expand Down
91 changes: 49 additions & 42 deletions armi/reactor/tests/test_blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
import io
import math
import os
import shutil
import unittest
from glob import glob
from unittest.mock import MagicMock, patch

import numpy as np
Expand All @@ -34,9 +36,9 @@
from armi.reactor import blocks, blueprints, components, geometry, grids
from armi.reactor.components import basicShapes, complexShapes
from armi.reactor.flags import Flags
from armi.reactor.tests.test_reactors import loadTestReactor
from armi.reactor.tests.test_assemblies import makeTestAssembly
from armi.reactor.tests.test_reactors import loadTestReactor, TEST_ROOT
from armi.reactor.tests.test_reactors import loadTestReactor
from armi.reactor.tests.test_reactors import TEST_ROOT
from armi.tests import ISOAA_PATH
from armi.utils import hexagon, units
from armi.utils.directoryChangers import TemporaryDirectoryChanger
Expand Down Expand Up @@ -2092,10 +2094,11 @@ def test_getPinCoords(self):
side = hexagon.side(blockPitch)
xyz = self.HexBlock.getPinCoordinates()
x, y, _z = zip(*xyz)
self.assertAlmostEqual(
y[1], y[2]
) # first two pins should be side by side on top.
self.assertNotAlmostEqual(x[1], x[2])

# these two pins should be side by side on top
self.assertTrue(self.HexBlock.spatialGrid.cornersUp)
self.assertAlmostEqual(y[1], y[3])
self.assertNotAlmostEqual(x[1], x[3])
self.assertEqual(len(xyz), self.HexBlock.getNumPins())

# ensure all pins are within the proper bounds of a
Expand Down Expand Up @@ -2288,18 +2291,9 @@ def setUp(self):
def tearDown(self):
self.td.__exit__(None, None, None)

def test_validateCornersUp(self):
# load a corners up reactor
_o, r = loadTestReactor(
os.path.join(TEST_ROOT, "smallestTestReactor"),
inputFileName="armiRunSmallest.yaml",
)

# grab a pinned fuel block, and verify it is corners up
b = r.core.getFirstBlock(Flags.FUEL)
self.assertTrue(b.spatialGrid.cornersUp)

# for corners up, the hex centroids should stretch more in X than Y
@staticmethod
def getLocalCoordinatesBlockBounds(b: blocks.HexBlock):
"""Call getLocalCoordinates() for every Component in the Block and find the X/Y bounds."""
maxX = -111
minX = 999
maxY = -111
Expand All @@ -2308,6 +2302,7 @@ def test_validateCornersUp(self):
locs = comp.spatialLocator
if not isinstance(locs, grids.MultiIndexLocation):
locs = [locs]

for loc in locs:
x, y, _ = loc.getLocalCoordinates()
if x > maxX:
Expand All @@ -2320,38 +2315,50 @@ def test_validateCornersUp(self):
elif y < minY:
minY = y

self.assertGreater(maxX - minX, maxY - minY)
return minX, maxX, minY, maxY

def test_validateCornersUp(self):
"""Validate the spatial grid for a corners up HexBlock and its children."""
john-science marked this conversation as resolved.
Show resolved Hide resolved
# load a corners up reactor
_o, r = loadTestReactor(
os.path.join(TEST_ROOT, "smallestTestReactor"),
inputFileName="armiRunSmallest.yaml",
)

# grab a pinned fuel block, and verify it is corners up
b = r.core.getFirstBlock(Flags.FUEL)
self.assertTrue(b.spatialGrid.cornersUp)
drewj-tp marked this conversation as resolved.
Show resolved Hide resolved

# for a flats up sub-grid, the hex centroids should stretch more in Y than X
drewj-tp marked this conversation as resolved.
Show resolved Hide resolved
minX, maxX, minY, maxY = self.getLocalCoordinatesBlockBounds(b)
self.assertGreater(maxY - minY, maxX - minX)

def test_validateFlatsUp(self):
"""Validate the spatial grid for a flats up HexBlock and its children."""
# copy the files over
inDir = os.path.join(TEST_ROOT, "smallestTestReactor")
for filePath in glob(os.path.join(inDir, "*.yaml")):
outPath = os.path.join(self.td.destination, os.path.basename(filePath))
shutil.copyfile(filePath, outPath)

# modify the reactor to make it flats up
testFile = os.path.join(self.td.destination, "refSmallestReactor.yaml")
txt = open(testFile, "r").read()
txt = txt.replace("geom: hex_corners_up", "geom: hex")
open(testFile, "w").write(txt)

# load a flats up reactor
_o, r = loadTestReactor(TEST_ROOT, inputFileName="armiRun.yaml")
_o, r = loadTestReactor(
self.td.destination, inputFileName="armiRunSmallest.yaml"
)

# grab a pinned fuel block, and verify it is flats up
b = r.core.getFirstBlock(Flags.FUEL)
self.assertFalse(b.spatialGrid.cornersUp)
drewj-tp marked this conversation as resolved.
Show resolved Hide resolved

# for flats up, the hex centroids should stretch more in Y than X
maxX = -111
minX = 999
maxY = -111
minY = 999
for comp in b:
locs = comp.spatialLocator
if not isinstance(locs, grids.MultiIndexLocation):
locs = [locs]
for loc in locs:
x, y, _ = loc.getLocalCoordinates()
if x > maxX:
maxX = x
elif x < minX:
minX = x

if y > maxY:
maxY = y
elif y < minY:
minY = y

self.assertGreater(maxY - minY, maxX - minX)
# for a corners up sub-grid, the hex centroids should stretch more in X than Y
drewj-tp marked this conversation as resolved.
Show resolved Hide resolved
minX, maxX, minY, maxY = self.getLocalCoordinatesBlockBounds(b)
self.assertGreater(maxX - minX, maxY - minY)


class ThRZBlock_TestCase(unittest.TestCase):
Expand Down
10 changes: 0 additions & 10 deletions armi/settings/fwSettings/globalSettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
CONF_AVAILABILITY_FACTORS = "availabilityFactors"
CONF_AXIAL_MESH_REFINEMENT_FACTOR = "axialMeshRefinementFactor"
CONF_BETA = "beta"
CONF_BLOCK_AUTO_GRID = "autoGenerateBlockGrids"
CONF_BRANCH_VERBOSITY = "branchVerbosity"
CONF_BU_GROUPS = "buGroups"
CONF_BURN_CHAIN_FILE_NAME = "burnChainFileName"
Expand Down Expand Up @@ -828,15 +827,6 @@ def defineSettings() -> List[setting.Setting]:
"than from the framework."
),
),
# It may make sense to remove this setting when MILs become more stable.
setting.Setting(
CONF_BLOCK_AUTO_GRID,
default=True,
label="Auto-generate Block grids",
description="Should block blueprints attempt to auto-generate a spatial "
"grid upon construction? This feature makes heavy use of multi-index "
"locations, which are not yet universally supported.",
),
setting.Setting(
CONF_CYCLES,
default=[],
Expand Down
1 change: 1 addition & 0 deletions doc/release/0.4.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ API Changes
#. Removing ``assemblyLists.py`` and the ``AssemblyList`` class. (`PR#1891 <https://github.com/terrapower/armi/pull/1891>`_)
#. Removing ``Assembly.rotatePins`` and ``Block.rotatePins``. Prefer ``Assembly.rotate`` and ``Block.rotate``. (`PR#1846 <https://github.com/terrapower/armi/1846`_)
#. Transposing ``pinMgFluxes`` parameters so that leading dimension is pin index (`PR#1937 <https://github.com/terrapower/armi/pull/1937>`)
#. Removed unused setting ``autoGenerateBlockGrids``. (`PR#1947 <https://github.com/terrapower/armi/pull/1947>`_)
#. Removing ``globalFluxInterface.DoseResultsMapper`` class (`PR#1952 <https://github.com/terrapower/armi/pull/1952>`)
#. TBD

Expand Down
Loading