From 58d57060a7e663c38742f821a05ec2627c63c9d5 Mon Sep 17 00:00:00 2001 From: Michael Jarrett Date: Tue, 27 Feb 2024 09:35:21 -0800 Subject: [PATCH 01/12] Add hex attribute to lattice pitch. --- armi/reactor/blueprints/gridBlueprint.py | 32 ++++++++++++++++++------ 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/armi/reactor/blueprints/gridBlueprint.py b/armi/reactor/blueprints/gridBlueprint.py index 0fe012454..f09ebde83 100644 --- a/armi/reactor/blueprints/gridBlueprint.py +++ b/armi/reactor/blueprints/gridBlueprint.py @@ -134,6 +134,26 @@ def __init__(self, x=0.0, y=0.0, z=0.0): self.z = z +class Pitch(yamlize.Object): + """A x, y, z triplet or triangular hex pitch for coordinates or lattice pitch.""" + + hex = yamlize.Attribute(type=float, default=0.0) + x = yamlize.Attribute(type=float, default=0.0) + y = yamlize.Attribute(type=float, default=0.0) + z = yamlize.Attribute(type=float, default=0.0) + + def __init__(self, hex=0.0, x=0.0, y=0.0, z=0.0): + self.hex = hex or x + self.x = x + self.y = y + self.z = z + + if not any(self.hex, self.x, self.y, self.z): + raise InputError( + "`lattice pitch` must have at least one non-zero attribute! Check the blueprints." + ) + + class GridBlueprint(yamlize.Object): """ A grid input blueprint. @@ -174,9 +194,9 @@ class GridBlueprint(yamlize.Object): The geometry of the grid (e.g. 'cartesian') latticeMap : str An asciimap representation of the lattice contents - latticeDimensions : Triplet - An x/y/z Triplet with grid dimensions in cm. This is used to specify a uniform - grid, such as Cartesian or Hex. Mutually exclusive with gridBounds. + latticeDimensions : Pitch + An x/y/z Triplet or hex pitch with grid dimensions in cm. This is used to specify a + uniform grid, such as Cartesian or Hex. Mutually exclusive with gridBounds. gridBounds : dict A dictionary containing explicit grid boundaries. Specific keys used will depend on the type of grid being defined. Mutually exclusive with latticeDimensions. @@ -190,9 +210,7 @@ class GridBlueprint(yamlize.Object): name = yamlize.Attribute(key="name", type=str) geom = yamlize.Attribute(key="geom", type=str, default=geometry.HEX) latticeMap = yamlize.Attribute(key="lattice map", type=str, default=None) - latticeDimensions = yamlize.Attribute( - key="lattice pitch", type=Triplet, default=None - ) + latticeDimensions = yamlize.Attribute(key="lattice pitch", type=Pitch, default=None) gridBounds = yamlize.Attribute(key="grid bounds", type=dict, default=None) symmetry = yamlize.Attribute( key="symmetry", @@ -313,7 +331,7 @@ def _constructSpatialGrid(self): ) spatialGrid = grids.ThetaRZGrid(bounds=(theta, radii, (0.0, 0.0))) if geom in (geometry.HEX, geometry.HEX_CORNERS_UP): - pitch = self.latticeDimensions.x if self.latticeDimensions else 1.0 + pitch = self.latticeDimensions.hex if self.latticeDimensions else 1.0 # add 2 for potential dummy assems spatialGrid = grids.HexGrid.fromPitch( pitch, From 92a3d8e2bb4ddd57ecfb8f72fba28b0427fcc4b1 Mon Sep 17 00:00:00 2001 From: Michael Jarrett Date: Tue, 27 Feb 2024 10:17:07 -0800 Subject: [PATCH 02/12] Fix hex pitch property. --- armi/reactor/grids/hexagonal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armi/reactor/grids/hexagonal.py b/armi/reactor/grids/hexagonal.py index 2365b1001..3973a8c3c 100644 --- a/armi/reactor/grids/hexagonal.py +++ b/armi/reactor/grids/hexagonal.py @@ -158,7 +158,7 @@ def pitch(self) -> float: -------- armi.reactor.grids.HexGrid.fromPitch """ - return self._unitSteps[1][1] + return sqrt(self._unitSteps[0][0] ** 2 + self._unitSteps[1][0] ** 2) @staticmethod def indicesToRingPos(i: int, j: int) -> Tuple[int, int]: From 89336dd84edc6617b56d12baa89b9f03871d0b38 Mon Sep 17 00:00:00 2001 From: Michael Jarrett Date: Tue, 27 Feb 2024 10:23:28 -0800 Subject: [PATCH 03/12] Add docstring. --- armi/reactor/blueprints/gridBlueprint.py | 32 ++++++++++++++++++++---- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/armi/reactor/blueprints/gridBlueprint.py b/armi/reactor/blueprints/gridBlueprint.py index f09ebde83..a308f24b3 100644 --- a/armi/reactor/blueprints/gridBlueprint.py +++ b/armi/reactor/blueprints/gridBlueprint.py @@ -143,16 +143,38 @@ class Pitch(yamlize.Object): z = yamlize.Attribute(type=float, default=0.0) def __init__(self, hex=0.0, x=0.0, y=0.0, z=0.0): - self.hex = hex or x - self.x = x - self.y = y - self.z = z + """ + hex : float, optional + Triangular/hex lattice pitch + x : float, optional + Cartesian grid: pitch in the x direction + Hexagonal grid: interpreted as hex lattice pitch + y : float, optional + Cartesian grid: pitch in the y direction + z : float, optional + Pitch in the z direction + + Raises + ------ + InputError + * If a `hex` pitch and `x` or `y` pitch are provided simultaneously. + * If no non-zero value is provided for any parameter + """ + if hex and (x or y): + raise InputError( + "Cannot mix `hex` with `x` and `y` attributes of `latticePitch`." + ) if not any(self.hex, self.x, self.y, self.z): raise InputError( "`lattice pitch` must have at least one non-zero attribute! Check the blueprints." ) + self.hex = hex or x + self.x = x + self.y = y + self.z = z + class GridBlueprint(yamlize.Object): """ @@ -195,7 +217,7 @@ class GridBlueprint(yamlize.Object): latticeMap : str An asciimap representation of the lattice contents latticeDimensions : Pitch - An x/y/z Triplet or hex pitch with grid dimensions in cm. This is used to specify a + An x/y/z pitch or hex pitch with grid dimensions in cm. This is used to specify a uniform grid, such as Cartesian or Hex. Mutually exclusive with gridBounds. gridBounds : dict A dictionary containing explicit grid boundaries. Specific keys used will depend From 3109298b861736ce64d681239bafac3783285e84 Mon Sep 17 00:00:00 2001 From: Michael Jarrett Date: Tue, 27 Feb 2024 10:39:16 -0800 Subject: [PATCH 04/12] Add unit test for hexGrid pitch property. --- armi/reactor/grids/tests/test_grids.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/armi/reactor/grids/tests/test_grids.py b/armi/reactor/grids/tests/test_grids.py index 4c1f2634b..944066b1c 100644 --- a/armi/reactor/grids/tests/test_grids.py +++ b/armi/reactor/grids/tests/test_grids.py @@ -366,6 +366,9 @@ def test_pointsUpFlatsUp(self): self.assertEqual(tipsUp._unitSteps[0][0], 0.5) self.assertAlmostEqual(flatsUp._unitSteps[0][0], 0.8660254037844388) + self.assertAlmostEqual(tipsUp.pitch, 1.0) + self.assertAlmostEqual(flatsUp.pitch, 1.0) + def test_triangleCoords(self): g = grids.HexGrid.fromPitch(8.15) indices1 = g.getIndicesFromRingAndPos(5, 3) + (0,) From f88d936f2f7434dde656ba0da8ca3db1ea97ca9f Mon Sep 17 00:00:00 2001 From: Michael Jarrett Date: Tue, 27 Feb 2024 11:40:29 -0800 Subject: [PATCH 05/12] Add unit test for gridBlueprints. --- armi/reactor/blueprints/gridBlueprint.py | 2 +- armi/reactor/blueprints/tests/test_gridBlueprints.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/armi/reactor/blueprints/gridBlueprint.py b/armi/reactor/blueprints/gridBlueprint.py index a308f24b3..8f815ba9a 100644 --- a/armi/reactor/blueprints/gridBlueprint.py +++ b/armi/reactor/blueprints/gridBlueprint.py @@ -165,7 +165,7 @@ def __init__(self, hex=0.0, x=0.0, y=0.0, z=0.0): "Cannot mix `hex` with `x` and `y` attributes of `latticePitch`." ) - if not any(self.hex, self.x, self.y, self.z): + if not any(hex, x, y, z): raise InputError( "`lattice pitch` must have at least one non-zero attribute! Check the blueprints." ) diff --git a/armi/reactor/blueprints/tests/test_gridBlueprints.py b/armi/reactor/blueprints/tests/test_gridBlueprints.py index 61f1bf0d5..4f8691ca9 100644 --- a/armi/reactor/blueprints/tests/test_gridBlueprints.py +++ b/armi/reactor/blueprints/tests/test_gridBlueprints.py @@ -30,6 +30,7 @@ control: geom: hex_corners_up symmetry: full + lattice pitch: {{hex: 1.2}} lattice map: | - - - - - - - - - 1 1 1 1 1 1 1 1 1 4 - - - - - - - - 1 1 1 1 1 1 1 1 1 1 1 @@ -360,7 +361,8 @@ def tearDown(self): def test_simpleRead(self): gridDesign = self.grids["control"] - _ = gridDesign.construct() + grid = gridDesign.construct() + self.assertAlmostEqual(grid.pitch, 1.2) self.assertEqual(gridDesign.gridContents[0, -8], "6") # Cartesian full, odd From 99a8c5db388b2d090cf0da18fc31351cb975aa84 Mon Sep 17 00:00:00 2001 From: Michael Jarrett Date: Tue, 27 Feb 2024 11:55:08 -0800 Subject: [PATCH 06/12] Address linting errors. --- armi/reactor/blueprints/gridBlueprint.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/armi/reactor/blueprints/gridBlueprint.py b/armi/reactor/blueprints/gridBlueprint.py index 8f815ba9a..60fde5e68 100644 --- a/armi/reactor/blueprints/gridBlueprint.py +++ b/armi/reactor/blueprints/gridBlueprint.py @@ -144,6 +144,8 @@ class Pitch(yamlize.Object): def __init__(self, hex=0.0, x=0.0, y=0.0, z=0.0): """ + Parameters + ---------- hex : float, optional Triangular/hex lattice pitch x : float, optional @@ -158,7 +160,7 @@ def __init__(self, hex=0.0, x=0.0, y=0.0, z=0.0): ------ InputError * If a `hex` pitch and `x` or `y` pitch are provided simultaneously. - * If no non-zero value is provided for any parameter + * If no non-zero value is provided for any parameter. """ if hex and (x or y): raise InputError( From 37e1fff205f1475976fe687b597e9084bbfc1402 Mon Sep 17 00:00:00 2001 From: Michael Jarrett Date: Tue, 27 Feb 2024 12:32:35 -0800 Subject: [PATCH 07/12] Change assertEqual to assertAlmostEqual for pitch Calculating the pitch with a square root creates a machine precision error. --- armi/reactor/grids/tests/test_grids.py | 4 ++-- armi/reactor/tests/test_blocks.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/armi/reactor/grids/tests/test_grids.py b/armi/reactor/grids/tests/test_grids.py index 944066b1c..09b8a83e8 100644 --- a/armi/reactor/grids/tests/test_grids.py +++ b/armi/reactor/grids/tests/test_grids.py @@ -437,7 +437,7 @@ def test_is_pickleable(self): assert_allclose(loc.indices, newLoc.indices) def test_adjustPitch(self): - """Adjust the pich of a hexagonal lattice. + """Adjust the pitch of a hexagonal lattice. .. test:: Construct a hexagonal lattice with three rings. :id: T_ARMI_GRID_HEX @@ -461,7 +461,7 @@ def test_adjustPitch(self): grid.changePitch(2.0) v2 = grid.getCoordinates((1, 0, 0)) assert_allclose(2 * v1 - offset, v2) - self.assertEqual(grid.pitch, 2.0) + self.assertAlmostEqual(grid.pitch, 2.0) # basic sanity: test number of rings has changed self.assertEqual(grid._unitStepLimits[0][1], 3) diff --git a/armi/reactor/tests/test_blocks.py b/armi/reactor/tests/test_blocks.py index 257a2d400..ff61a120f 100644 --- a/armi/reactor/tests/test_blocks.py +++ b/armi/reactor/tests/test_blocks.py @@ -1963,7 +1963,7 @@ def test_retainState(self): with self.HexBlock.retainState(): self.HexBlock.setType("fuel") self.HexBlock.spatialGrid.changePitch(2.0) - self.assertEqual(self.HexBlock.spatialGrid.pitch, 1.0) + self.assertAlmostEqual(self.HexBlock.spatialGrid.pitch, 1.0) self.assertTrue(self.HexBlock.hasFlags(Flags.INTERCOOLANT)) def test_getPinCoords(self): From f83297aae9f690a7db4185baedbbbf640319b17d Mon Sep 17 00:00:00 2001 From: Michael Jarrett Date: Tue, 27 Feb 2024 19:52:56 -0800 Subject: [PATCH 08/12] Use x pitch if hex is not available. --- armi/reactor/blueprints/gridBlueprint.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/armi/reactor/blueprints/gridBlueprint.py b/armi/reactor/blueprints/gridBlueprint.py index 60fde5e68..caaec9c58 100644 --- a/armi/reactor/blueprints/gridBlueprint.py +++ b/armi/reactor/blueprints/gridBlueprint.py @@ -355,7 +355,21 @@ def _constructSpatialGrid(self): ) spatialGrid = grids.ThetaRZGrid(bounds=(theta, radii, (0.0, 0.0))) if geom in (geometry.HEX, geometry.HEX_CORNERS_UP): - pitch = self.latticeDimensions.hex if self.latticeDimensions else 1.0 + if not self.latticeDimensions: + pitch = 1.0 + else: + ld = self.latticeDimensions + if ld.hex and (ld.x or ld.y): + raise InputError( + "Cannot mix `hex` with `x` and `y` attributes of `latticePitch`." + ) + + if not any([ld.hex, ld.x, ld.y, ld.z]): + raise InputError( + "`lattice pitch` must have at least one non-zero attribute! Check the blueprints." + ) + + pitch = ld.hex or ld.x # add 2 for potential dummy assems spatialGrid = grids.HexGrid.fromPitch( pitch, From 9837a283e6d78c518f1aba5a91319defe58f39dc Mon Sep 17 00:00:00 2001 From: Michael Jarrett Date: Tue, 19 Mar 2024 09:42:16 -0700 Subject: [PATCH 09/12] Revert "Change assertEqual to assertAlmostEqual for pitch" This reverts commit 37e1fff205f1475976fe687b597e9084bbfc1402. --- armi/reactor/grids/tests/test_grids.py | 4 ++-- armi/reactor/tests/test_blocks.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/armi/reactor/grids/tests/test_grids.py b/armi/reactor/grids/tests/test_grids.py index 09b8a83e8..944066b1c 100644 --- a/armi/reactor/grids/tests/test_grids.py +++ b/armi/reactor/grids/tests/test_grids.py @@ -437,7 +437,7 @@ def test_is_pickleable(self): assert_allclose(loc.indices, newLoc.indices) def test_adjustPitch(self): - """Adjust the pitch of a hexagonal lattice. + """Adjust the pich of a hexagonal lattice. .. test:: Construct a hexagonal lattice with three rings. :id: T_ARMI_GRID_HEX @@ -461,7 +461,7 @@ def test_adjustPitch(self): grid.changePitch(2.0) v2 = grid.getCoordinates((1, 0, 0)) assert_allclose(2 * v1 - offset, v2) - self.assertAlmostEqual(grid.pitch, 2.0) + self.assertEqual(grid.pitch, 2.0) # basic sanity: test number of rings has changed self.assertEqual(grid._unitStepLimits[0][1], 3) diff --git a/armi/reactor/tests/test_blocks.py b/armi/reactor/tests/test_blocks.py index ff61a120f..257a2d400 100644 --- a/armi/reactor/tests/test_blocks.py +++ b/armi/reactor/tests/test_blocks.py @@ -1963,7 +1963,7 @@ def test_retainState(self): with self.HexBlock.retainState(): self.HexBlock.setType("fuel") self.HexBlock.spatialGrid.changePitch(2.0) - self.assertAlmostEqual(self.HexBlock.spatialGrid.pitch, 1.0) + self.assertEqual(self.HexBlock.spatialGrid.pitch, 1.0) self.assertTrue(self.HexBlock.hasFlags(Flags.INTERCOOLANT)) def test_getPinCoords(self): From b43cffa5618be75b360dd51c9936e61b6df675a3 Mon Sep 17 00:00:00 2001 From: Michael Jarrett Date: Tue, 19 Mar 2024 09:42:26 -0700 Subject: [PATCH 10/12] Revert "Add unit test for hexGrid pitch property." This reverts commit 3109298b861736ce64d681239bafac3783285e84. --- armi/reactor/grids/tests/test_grids.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/armi/reactor/grids/tests/test_grids.py b/armi/reactor/grids/tests/test_grids.py index 944066b1c..4c1f2634b 100644 --- a/armi/reactor/grids/tests/test_grids.py +++ b/armi/reactor/grids/tests/test_grids.py @@ -366,9 +366,6 @@ def test_pointsUpFlatsUp(self): self.assertEqual(tipsUp._unitSteps[0][0], 0.5) self.assertAlmostEqual(flatsUp._unitSteps[0][0], 0.8660254037844388) - self.assertAlmostEqual(tipsUp.pitch, 1.0) - self.assertAlmostEqual(flatsUp.pitch, 1.0) - def test_triangleCoords(self): g = grids.HexGrid.fromPitch(8.15) indices1 = g.getIndicesFromRingAndPos(5, 3) + (0,) From 80a275af22b1a8e74f6591c2502432cd3cbb53af Mon Sep 17 00:00:00 2001 From: Michael Jarrett Date: Tue, 19 Mar 2024 09:42:41 -0700 Subject: [PATCH 11/12] Revert "Fix hex pitch property." This reverts commit 92a3d8e2bb4ddd57ecfb8f72fba28b0427fcc4b1. --- armi/reactor/grids/hexagonal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armi/reactor/grids/hexagonal.py b/armi/reactor/grids/hexagonal.py index 3973a8c3c..2365b1001 100644 --- a/armi/reactor/grids/hexagonal.py +++ b/armi/reactor/grids/hexagonal.py @@ -158,7 +158,7 @@ def pitch(self) -> float: -------- armi.reactor.grids.HexGrid.fromPitch """ - return sqrt(self._unitSteps[0][0] ** 2 + self._unitSteps[1][0] ** 2) + return self._unitSteps[1][1] @staticmethod def indicesToRingPos(i: int, j: int) -> Tuple[int, int]: From 86b24685f965b37f62b20c19ad302397b3609c96 Mon Sep 17 00:00:00 2001 From: Michael Jarrett Date: Wed, 20 Mar 2024 11:26:17 -0700 Subject: [PATCH 12/12] Fix an error in merge conflict resolution --- armi/reactor/blueprints/tests/test_gridBlueprints.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armi/reactor/blueprints/tests/test_gridBlueprints.py b/armi/reactor/blueprints/tests/test_gridBlueprints.py index 9227df078..6ac7b12bb 100644 --- a/armi/reactor/blueprints/tests/test_gridBlueprints.py +++ b/armi/reactor/blueprints/tests/test_gridBlueprints.py @@ -361,7 +361,7 @@ def tearDown(self): def test_simpleRead(self): gridDesign = self.grids["control"] - _ = gridDesign.construct() + grid = gridDesign.construct() self.assertAlmostEqual(grid.pitch, 1.2) self.assertEqual(gridDesign.gridContents[-8, 0], "6")