armi.reactor.grids.structuredgrid module
- class armi.reactor.grids.structuredgrid.GridParameters(unitSteps, bounds, unitStepLimits, offset, geomType, symmetry)
Bases:
tuple
Create new instance of GridParameters(unitSteps, bounds, unitStepLimits, offset, geomType, symmetry)
- bounds
Alias for field number 1
- geomType
Alias for field number 4
- offset
Alias for field number 3
- symmetry
Alias for field number 5
- unitStepLimits
Alias for field number 2
- unitSteps
Alias for field number 0
- class armi.reactor.grids.structuredgrid.StructuredGrid(unitSteps=(0, 0, 0), bounds=(None, None, None), unitStepLimits=((0, 1), (0, 1), (0, 1)), offset=None, geomType='', symmetry='', armiObject=None)[source]
Bases:
Grid
A connected set of cells characterized by indices mapping to space and vice versa.
The cells may be characterized by any mixture of regular repeating steps and user-defined steps in any direction.
For example, a 2-D hex lattice has constant, regular steps whereas a 3-D hex mesh may have user-defined axial meshes. Similar for Cartesian, RZT, etc.
- Parameters:
unitSteps (tuple of tuples, optional) –
Describes the grid spatially as a function on indices. Each tuple describes how each
(x,y,or z)
dimension is influenced by(i,j,k)
. In other words, it is:(dxi, dxj, jxk), (dyi, dyj, dyk), (dzi, dzj, dzk)
where
dmn
is the distance (in cm) that dimensionm
will change as a function of indexn
.Unit steps are used as a generic method for defining repetitive grids in a variety of geometries, including hexagonal and Cartesian. The tuples are not vectors in the direction of the translation, but rather grouped by direction. If the bounds argument is described for a direction, the bounds will be used rather than the unit step information. The default of (0, 0, 0) makes all dimensions insensitive to indices since the coordinates are calculated by the dot product of this and the indices. With this default, any dimension that is desired to change with indices should be defined with bounds. RZtheta grids are created exclusively with bounds.
bounds (3-tuple) – Absolute increasing bounds in cm including endpoints of a non-uniform grid. Each item represents the boundaries in the associated direction. Use Nones when unitSteps should be applied instead. Most useful for thetaRZ grids or other non-uniform grids.
unitStepLimits (3-tuple) – The limit of the steps in all three directions. This constrains step-defined grids to be finite so we can populate them with SpatialLocator objects.
offset (3-tuple, optional) – Offset in cm for each axis. By default the center of the (0,0,0)-th object is in the center of the grid. Offsets can move it so that the (0,0,0)-th object can be fully within a quadrant (i.e. in a Cartesian grid).
armiObject (ArmiObject, optional) – The ArmiObject that this grid describes. For example if it’s a 1-D assembly grid, the armiObject is the assembly. Note that
self.armiObject.spatialGrid
isself
.
Examples
A 2D a rectangular grid with width (x) 2 and height (y) 3 would be:
>>> grid = Grid(unitSteps=((2, 0, 0), (0, 3, 0),(0, 0, 0)))
A regular hex grid with pitch 1 is:
>>> grid = Grid(unitSteps= ((sqrt(3)/2, 0.0, 0.0), (0.5, 1.0, 0.0), (0, 0, 0))
Note
For this unit hex the magnitude of the vector constructed using the 0th index of each tuple is 1.0.
Notes
Each dimension must either be defined through unitSteps or bounds. The combination of unitSteps with bounds was settled upon after some struggle to have one unified definition of a grid (i.e. just bounds). A hexagonal grid is somewhat challenging to represent with bounds because the axes are not orthogonal, so a unit-direction vector plus bounds would be required. And then the bounds would be wasted space because they can be derived simply by unit steps. Memory efficiency is important in this object so the compact representation of unitSteps-when-possible, bounds-otherwise was settled upon.
Design considerations include:
unitSteps are more intuitive as operations starting from the center of a cell, particularly with hexagons and rectangles. Otherwise the 0,0 position of a hexagon in the center of 1/3-symmetric hexagon is at the phantom bottom left of the hexagon.
Users generally prefer to input mesh bounds rather than centers (e.g. starting at 0.5 instead of 0.0 in a unit mesh is weird).
If we store bounds, computing bounds is simple and computing centers takes ~2x the effort. If we store centers, it’s the opposite.
Regardless of how we store things, we’ll need a Grid that has the lower-left assembly fully inside the problem (i.e. for full core Cartesian) as well as another one that has the lower-left assembly half-way or quarter-way sliced off (for 1/2, 1/4, and 1/8 symmetries). The
offset
parameter handles this.Looking up mesh boundaries (to define a mesh in another code) is generally more common than looking up centers (for plotting or measuring distance).
A grid can be anchored to the object that it is in with a backreference. This gives it the ability to traverse the composite tree and map local to global locations without having to duplicate the composite pattern on grids. This remains optional so grids can be used for non-reactor-package reasons. It may seem slightly cleaner to set the armiObject to the parent’s spatialLocator itself but the major disadvantage of this is that when an object moves, the armiObject would have to be updated. By anchoring directly to Composite objects, the parent is always up to date no matter where or how things get moved.
Unit step calculations use dot products and must not be polluted by the bound indices. Thus we reduce the size of the unitSteps tuple accordingly.
- reduce() GridParameters [source]
Recreate the parameter necessary to create this grid.
- property offset: ndarray
Offset in cm for each axis.
- getCoordinates(indices, nativeCoords=False) ndarray [source]
Return the coordinates of the center of the mesh cell at the given indices in cm.
- static getNeighboringCellIndices(i, j=0, k=0)[source]
Return the indices of the immediate neighbors of a mesh point in the plane.
- getIndexBounds()[source]
Get min index and number of indices in this grid.
Step-defined grids would be infinite but for the step limits defined in the constructor.
Notes
This produces output that is intended to be passed to a
range
statement.
- getBounds() Tuple[Optional[Sequence[float]], Optional[Sequence[float]], Optional[Sequence[float]]] [source]
Return the grid bounds for each dimension, if present.
- getLocatorFromRingAndPos(ring, pos, k=0)[source]
Return the location based on ring and position.
- Parameters:
See also
getIndicesFromRingAndPos
This implements the transform into i, j indices based on ring and position.
- abstract static getIndicesFromRingAndPos(ring: int, pos: int)[source]
Return i, j indices given ring and position.
Note
This should be implemented as a staticmethod, since no Grids currently in exsistence actually need any instance data to perform this task, and staticmethods provide the convenience of calling the method without an instance of the class in the first place.
- abstract getMinimumRings(n: int) int [source]
Return the minimum number of rings needed to fit
n
objects.Warning
While this is useful and safe for answering the question of “how many rings do I need to hold N things?”, is generally not safe to use it to answer “I have N things; within how many rings are they distributed?”. This function provides a lower bound, assuming that objects are densely-packed. If they are not actually densely packed, this may be unphysical.
- getRingPos(indices) Tuple[int, int] [source]
Get ring and position number in this grid.
For non-hex grids this is just i and j.
A tuple is returned so that it is easy to compare pairs of indices.