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.This class represents a hexagonal
StructuredGrid
, that is one where the mesh maps to real, physical coordinates. This hexagonal grid is 2D, and divides the plane up into regular hexagons. That is, each hexagon is symmetric and is precisely flush with six neighboring hexagons. This class only allows for two rotational options: flats up (where two sides of the hexagons are parallel with the X-axis), and points up (where two sides are parallel with the Y-axis).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.
When this method creates a
HexGrid
object, it can create a hexagonal grid with one of two rotations: flats up (where two sides of the hexagons are parallel with the X-axis), and points up (where two sides are parallel with the Y-axis). While it is possible to imagine the hexagons being rotated at other arbitrary angles, those are not supported here.Implementation: When creating a hexagonal grid, the user can specify the symmetry. I_ARMI_GRID_SYMMETRY1When this method creates a
HexGrid
object, it takes as an input the symmetry of the resultant grid. This symmetry can be a string (e.g. “full”) or aSymmetryType
object (e.g.FULL_CORE
). If the grid is not full- core, the methodgetSymmetricEquivalents()
will be usable to map any possible grid cell to the ones that are being modeled in the sub-grid.- 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:
- 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.
- 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:
- 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]) int | None [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.
This method takes in (I,J,K) indices, and if this
HexGrid
is full core, it returns nothing. If thisHexGrid
is 1/3-core, this method will return the 1/3-core symmetric equivalent of just (I,J). If this grid is any other kind, this method will just return an error; a hexagonal grid with any other symmetry is probably 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.
- isInFirstThird(locator, includeTopEdge=False) bool [source]
Test if the given locator is in the first 1/3 of the HexGrid.
This is a simple helper method to determine if a given locator (from an ArmiObject) is in the first 1/3 of the
HexGrid
. This method does not attempt to check if this grid is full or 1/3-core. It just does the basic math of dividing up a hex-assembly reactor core into thirds and testing if the given location is in the first 1/3 or not.
- 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)