def generateMesh(self, r=None): core = r.core converterSettings = self._converterSettings self._useUniformThetaMesh = converterSettings["uniformThetaMesh"] self._numThetaMeshBins = converterSettings["thetaBins"] self._converterSettings = converterSettings self._numRingsInCore = core.getNumHexRings() self._assemsInCore = core.getAssemblies() self._coreAxialMeshCoords = core.findAllAxialMeshPoints( applySubMesh=False) self.setAxialMesh() self._checkAxialMeshList() self.setThetaMesh() self._checkThetaMeshList() self.setRingsToConvert(core) self._checkRingList(core) self.numRingBins = len(self.radialMesh) self.numAxialMeshBins = len(self.axialMesh) self.numThetaMeshBins = len(self.thetaMesh) self.writeMeshData() # Build mesh reactor mesh # thetaMesh doesn't include the zero point so add it back in. # axial mesh is handled on assemblies so make this 2-D. mesh = grids.ThetaRZGrid(bounds=([0.0] + self.thetaMesh, self.radialMesh, (0.0, 0.0))) return mesh
def testPositions(self): grid = grids.ThetaRZGrid( bounds=(numpy.linspace(0, 2 * math.pi, 13), [0, 2, 2.5, 3], [0, 10, 20, 30]) ) assert_allclose( grid.getCoordinates((1, 0, 1)), (math.sqrt(2) / 2, math.sqrt(2) / 2, 15.0) )
def _constructSpatialGrid(self): """ Build spatial grid. If you do not enter latticeDimensions, a unit grid will be produced which must be adjusted to the proper dimensions (often by inspection of children) at a later time. """ geom = self.geom maxIndex = self._getMaxIndex() runLog.extra("Creating the spatial grid") if geom in (geometry.RZT, geometry.RZ): if self.gridBounds is None: # This check is regrattably late. It would be nice if we could validate # that bounds are provided if R-Theta mesh is being used. raise InputError( "Grid bounds must be provided for `{}` to specify a grid with " "r-theta components.".format(self.name)) for key in ("theta", "r"): if key not in self.gridBounds: raise InputError( "{} grid bounds were not provided for `{}`.".format( key, self.name)) # convert to list, otherwise it is a CommentedSeq theta = numpy.array(self.gridBounds["theta"]) radii = numpy.array(self.gridBounds["r"]) for l, name in ((theta, "theta"), (radii, "radii")): if not _isMonotonicUnique(l): raise InputError( "Grid bounds for {}:{} is not sorted or contains " "duplicates. Check blueprints.".format( self.name, name)) spatialGrid = grids.ThetaRZGrid(bounds=(theta, radii, (0.0, 0.0))) if geom == geometry.HEX: pitch = self.latticeDimensions.x if self.latticeDimensions else 1.0 # add 2 for potential dummy assems spatialGrid = grids.HexGrid.fromPitch(pitch, numRings=maxIndex + 2) elif geom == geometry.CARTESIAN: # if full core or not cut-off, bump the first assembly from the center of # the mesh into the positive values. xw, yw = ((self.latticeDimensions.x, self.latticeDimensions.y) if self.latticeDimensions else (1.0, 1.0)) isOffset = (self.symmetry and geometry.THROUGH_CENTER_ASSEMBLY not in self.symmetry) spatialGrid = grids.CartesianGrid.fromRectangle(xw, yw, numRings=maxIndex + 1, isOffset=isOffset) runLog.debug("Built grid: {}".format(spatialGrid)) # set geometric metadata on spatialGrid. This information is needed in various # parts of the code and is best encapsulated on the grid itself rather than on # the container state. spatialGrid.geomType = self.geom spatialGrid.symmetry = self.symmetry return spatialGrid
def testPositions(self): grid = grids.ThetaRZGrid(bounds=(numpy.linspace(0, 2 * math.pi, 13), [0, 2, 2.5, 3], [0, 10, 20, 30])) assert_allclose(grid.getCoordinates((1, 0, 1)), (math.sqrt(2) / 2, math.sqrt(2) / 2, 15.0)) # test round trip ring position ringPos = (1, 1) indices = grid.getIndicesFromRingAndPos(*ringPos) ringPosFromIndices = grid.getRingPos(indices) self.assertEqual(ringPos, ringPosFromIndices)
def _constructSpatialGrid(self): """ Build spatial grid. If you do not enter latticeDimensions, a unit grid will be produced which must be adjusted to the proper dimensions (often by inspection of children) at a later time. """ symmetry = ( geometry.SymmetryType.fromStr(self.symmetry) if self.symmetry else None ) geom = self.geom maxIndex = self._getMaxIndex() runLog.extra("Creating the spatial grid") if geom in (geometry.RZT, geometry.RZ): if self.gridBounds is None: # This check is regrettably late. It would be nice if we could validate # that bounds are provided if R-Theta mesh is being used. raise InputError( "Grid bounds must be provided for `{}` to specify a grid with " "r-theta components.".format(self.name) ) for key in ("theta", "r"): if key not in self.gridBounds: raise InputError( "{} grid bounds were not provided for `{}`.".format( key, self.name ) ) # convert to list, otherwise it is a CommentedSeq theta = numpy.array(self.gridBounds["theta"]) radii = numpy.array(self.gridBounds["r"]) for l, name in ((theta, "theta"), (radii, "radii")): if not _isMonotonicUnique(l): raise InputError( "Grid bounds for {}:{} is not sorted or contains " "duplicates. Check blueprints.".format(self.name, name) ) 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 # add 2 for potential dummy assems spatialGrid = grids.HexGrid.fromPitch( pitch, numRings=maxIndex + 2, pointedEndUp=geom == geometry.HEX_CORNERS_UP, ) elif geom == geometry.CARTESIAN: # if full core or not cut-off, bump the first assembly from the center of # the mesh into the positive values. xw, yw = ( (self.latticeDimensions.x, self.latticeDimensions.y) if self.latticeDimensions else (1.0, 1.0) ) # Specifically in the case of grid blueprints, where we have grid contents # available, we can also infer "through center" based on the contents. # Note that the "through center" symmetry check cannot be performed when # the grid contents has not been provided (i.e., None or empty). if self.gridContents and symmetry.domain == geometry.DomainType.FULL_CORE: nx, ny = _getGridSize(self.gridContents.keys()) if nx == ny and nx % 2 == 1: symmetry.isThroughCenterAssembly = True isOffset = symmetry is not None and not symmetry.isThroughCenterAssembly spatialGrid = grids.CartesianGrid.fromRectangle( xw, yw, numRings=maxIndex + 1, isOffset=isOffset ) runLog.debug("Built grid: {}".format(spatialGrid)) # set geometric metadata on spatialGrid. This information is needed in various # parts of the code and is best encapsulated on the grid itself rather than on # the container state. spatialGrid._geomType: str = str(self.geom) self.symmetry = str(symmetry) spatialGrid._symmetry: str = self.symmetry return spatialGrid
Learn more about :py:mod:`grids <armi.reactor.grids>`. """ import itertools import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np from armi.reactor import grids import armi armi.configure() fig = plt.figure() theta = np.linspace(0, 2 * np.pi, 10) rad = np.linspace(0, 10, 10) z = np.linspace(5, 25, 6) rz_grid = grids.ThetaRZGrid(bounds=(theta, rad, z)) xyz = [] for i, j, k in itertools.product( range(len(theta) - 1), range(len(rad) - 1), range(len(z) - 1) ): xyz.append(rz_grid[i, j, k].getGlobalCoordinates()) ax = fig.add_subplot(1, 1, 1, projection="3d") x, y, z = zip(*xyz) ax.scatter(x, y, z) plt.show()