Source code for armi.utils.hexagon

# Copyright 2019 TerraPower, LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

r"""
Generic hexagon math.

Hexagons are fundamental to advanced reactors.

.. image:: /.static/hexagon.png
    :width: 100%
"""

import math

import numpy

SQRT3 = math.sqrt(3.0)


[docs]def area(pitch): """ Area of a hex given the flat-to-flat pitch. .. impl:: Compute hexagonal area :id: I_ARMI_UTIL_HEXAGON0 :implements: R_ARMI_UTIL_HEXAGON Computes the area of a hexagon given the flat-to-flat ``pitch``. Notes ----- The pitch is the distance between the center of the hexagons in the lattice. """ return SQRT3 / 2.0 * pitch**2
[docs]def side(pitch): r""" Side length of a hex given the flat-to-flat pitch. Pythagorean theorem says: .. math:: \frac{s}{2}^2 + \frac{p}{2}^2 = s^2 which you can solve to find p = sqrt(3)*s Notes ----- The pitch is the distance between the center of the hexagons in the lattice. """ return pitch / SQRT3
[docs]def corners(rotation=0): """ Return the coordinates of a unit hexagon, rotated as requested. Zero rotation implies flat-to-flat aligned with y-axis. Origin in the center. """ points = numpy.array( [ (1.0 / (2.0 * math.sqrt(3.0)), 0.5), (1.0 / math.sqrt(3.0), 0.0), (1.0 / (2.0 * math.sqrt(3.0)), -0.5), (-1.0 / (2.0 * math.sqrt(3.0)), -0.5), (-1.0 / math.sqrt(3.0), 0.0), (-1.0 / (2.0 * math.sqrt(3.0)), 0.5), ] ) rotation = rotation / 180.0 * math.pi rotation = numpy.array( [ [math.cos(rotation), -math.sin(rotation)], [math.sin(rotation), math.cos(rotation)], ] ) return numpy.array([tuple(rotation.dot(point)) for point in points])
[docs]def pitch(side): """ Calculate the pitch from the length of a hexagon side. Notes ----- The pitch is the distance between the center of the hexagons in the lattice. """ return side * SQRT3
[docs]def numRingsToHoldNumCells(numCells): """ Determine the number of rings in a hexagonal grid with this many hex cells. If the number of pins don't fit exactly into any ring, returns the ring just large enough to fit them. Parameters ---------- numCells : int The number of hex cells in a hex lattice Returns ------- numRings : int Number of rings required to contain numCells items. Notes ----- The first hex ring (center) holds 1 position. Each subsequent hex ring contains 6 more positions than the last. This method works by incrementing ring numbers until the number of items is reached or exceeded. It could easily be replaced by a lookup table if so desired. """ if numCells == 0: return 0 nPinRings = int(math.ceil(0.5 * (1 + math.sqrt(1 + 4 * (numCells - 1) // 3)))) return nPinRings
[docs]def numPositionsInRing(ring): """Number of positions in ring (starting at 1) of a hex lattice. .. impl:: Compute number of positions in a ring of a hex lattice :id: I_ARMI_UTIL_HEXAGON1 :implements: R_ARMI_UTIL_HEXAGON In a hexagonal lattice, calculate the number of positions in a given ``ring``. The number of rings is indexed to 1, i.e. the centermost position in the lattice is ``ring=1``. """ return (ring - 1) * 6 if ring != 1 else 1