armi.reactor.grids.hexagonal module

class armi.reactor.grids.hexagonal.HexGrid(unitSteps=(0, 0, 0), bounds=(None, None, None), unitStepLimits=((0, 1), (0, 1), (0, 1)), offset=None, geomType='', symmetry='', armiObject=None)[source]

Bases: StructuredGrid

Has 6 neighbors in plane.

It is recommended to use fromPitch() rather than calling the __init__ constructor directly.

Notes

In an axial plane (i, j) are as follows (flats up):

         _____
        /     \
  _____/  0,1  \_____
 /     \       /     \
/ -1,1  \_____/  1,0  \
\       /     \       /
 \_____/  0,0  \_____/
 /     \       /     \
/ -1,0  \_____/  1,-1 \
\       /     \       /
 \_____/  0,-1 \_____/
       \       /
        \_____/

In an axial plane (i, j) are as follows (corners up):

       / \     / \
     /     \ /     \
    |  0,1  |  1,0  |
    |       |       |
   / \     / \     / \
 /     \ /     \ /     \
| -1,1  |  0,0  |  1,-1 |
|       |       |       |
 \     / \     / \     /
   \ /     \ /     \ /
    | -1,0  |  0,-1 |
    |       |       |
     \     / \     /
       \ /     \ /

Basic hexagon geometry:

- pitch = sqrt(3) * side
- long diagonal = 2 * side
- Area = (sqrt(3) / 4) * side^2
- perimeter = 6 * side
property cornersUp: bool

Check whether the hexagonal grid is “corners up” or “flats up”.

See the armi.reactor.grids.HexGrid class documentation for an illustration of the two types of grid indexing.

static fromPitch(pitch, numRings=25, armiObject=None, cornersUp=False, symmetry='')[source]

Build a finite step-based 2-D hex grid from a hex pitch in cm.

Parameters:
  • pitch (float) – Hex pitch (flat-to-flat) in cm

  • numRings (int, optional) – The number of rings in the grid to pre-populate with locatator objects. Even if positions are not pre-populated, locators will be generated there on the fly.

  • armiObject (ArmiObject, optional) – The object that this grid is anchored to (i.e. the reactor for a grid of assemblies)

  • cornersUp (bool, optional) – Rotate the hexagons 30 degrees so that the corners point up instead of the flat faces.

  • symmetry (string, optional) – A string representation of the symmetry options for the grid.

Returns:

A functional hexagonal grid object.

Return type:

HexGrid

property pitch: float

Get the hex-pitch of a regular hexagonal array.

See also

armi.reactor.grids.HexGrid.fromPitch

static indicesToRingPos(i: int, j: int) Tuple[int, int][source]

Convert spatialLocator indices to ring/position.

One benefit it has is that it never has negative numbers.

Notes

Ring, pos index system goes in counterclockwise hex rings.

static getMinimumRings(n: int) int[source]

Return the minimum number of rings needed to fit n objects.

Notes

self is not used because hex grids always behave the same w.r.t. rings/positions.

static getPositionsInRing(ring: int) int[source]

Return the number of positions within a ring.

getNeighboringCellIndices(i: int, j: int = 0, k: int = 0) List[Tuple[int, int, int]][source]

Return the indices of the immediate neighbors of a mesh point in the plane.

Note that these neighbors are ordered counter-clockwise beginning from the 30 or 60 degree direction. Exact direction is dependent on cornersUp arg.

getLabel(indices)[source]

Hex labels start at 1, and are ring/position based rather than i,j.

This difference is partially because ring/pos is easier to understand in hex geometry, and partially because it is used in some codes ARMI originally was focused on.

static getIndicesFromRingAndPos(ring: int, pos: int) Tuple[int, int][source]

Given the ring and position, return the (I,J) coordinates in the hex grid.

Parameters:
  • ring (int) – Starting with 1 (not zero), the ring of the grid cell.

  • position (int) – Starting with 1 (not zero), the position of the grid cell, in the ring.

Returns:

(int, int)

Return type:

I coordinate, J coordinate

Notes

In an axial plane, the (ring, position) coordinates are as follows:

     Flat-to-Flat                    Corners Up
         _____
        /     \                      / \     / \
  _____/  2,2  \_____              /     \ /     \
 /     \       /     \            |  2,2  |  2,1  |
/  2,3  \_____/  2,1  \           |       |       |
\       /     \       /          / \     / \     / \
 \_____/  1,1  \_____/         /     \ /     \ /     \
 /     \       /     \        |  2,3  |  1,1  |  2,6  |
/  2,4  \_____/  2,6  \       |       |       |       |
\       /     \       /        \     / \     / \     /
 \_____/  2,5  \_____/           \ /     \ /     \ /
       \       /                  |  2,4  |  2,5  |
        \_____/                   |       |       |
                                   \     / \     /
                                     \ /     \ /
getRingPos(indices: Tuple[int, int, int]) Tuple[int, int][source]

Get 1-based ring and position from normal indices.

See also

getIndicesFromRingAndPos

does the reverse

overlapsWhichSymmetryLine(indices: Tuple[int, int]) Optional[int][source]

Return a list of which lines of symmetry this is on.

Parameters:

indices (tuple of [int, int]) – Indices for the requested object

Returns:

None if not line of symmetry goes through the object at the requested index. Otherwise, some grid constants like BOUNDARY_CENTER will be returned.

Return type:

None or int

Notes

  • Only the 1/3 core view geometry is actually coded in here right now.

  • Being “on” a symmetry line means the line goes through the middle of you.

getSymmetricEquivalents(indices: Tuple[int, int, int]) List[Tuple[int, int]][source]

Retrieve the equivalent indices. If full core return nothing, if 1/3-core grid, return the symmetric equivalents, if any other grid, raise an error.

triangleCoords(indices: Tuple[int, int, int]) ndarray[source]

Return 6 coordinate pairs representing the centers of the 6 triangles in a hexagon centered here.

Ignores z-coordinate and only operates in 2D for now.

changePitch(newPitchCm: float)[source]

Change the hex pitch.

locatorInDomain(locator, symmetryOverlap: Optional[bool] = False) bool[source]
isInFirstThird(locator, includeTopEdge=False) bool[source]

Test if the given locator is in the first 1/3 of the HexGrid.

generateSortedHexLocationList(nLocs: int)[source]

Generate a list IndexLocations, sorted based on their distance from the center.

IndexLocation are taken from a full core.

Ties between locations with the same distance (e.g. A3001 and A3003) are broken by ring number then position number.

rotateIndex(loc: IndexLocation, rotations: int) IndexLocation[source]

Find the new location of an index after some number of CCW rotations.

Parameters:
  • loc (IndexLocation) – Starting index

  • rotations (int) – Number of counter clockwise rotations

Returns:

Index in the grid after rotation

Return type:

IndexLocation

Notes

Rotation uses a three-dimensional index in what can be known elsewhere by the confusing name of “cubic” coordinate system for a hexagon. Cubic stems from the notion of using three dimensions, (q, r, s) to describe a point in the hexagonal grid. The conversion from the indexing used in the ARMI framework follows:

q = i
r = j
# s = - q - r = - (q + r)
s = -(i + j)

The motivation for the cubic notation is rotation is far simpler: a clockwise rotation by 60 degrees results in a shifting and negating of the coordinates. So the first rotation of (q, r, s) would produce a new coordinate (-r, -s, -q). Another rotation would produce (s, q, r), and so on.

Raises:

TypeError – If loc.grid is populated and not consistent with this grid. For example, it doesn’t make sense to rotate an index from a Cartesian grid in a hexagonal coordinate system, nor hexagonal grid with different orientation (flats up vs. corners up)

armiObject: Optional[ArmiObject]