Skip to content

Commit

Permalink
Add debug messages to uniform mesh converter (#413)
Browse files Browse the repository at this point in the history
* Adding detailed debug information to verify the homogenization
of blocks within the uniform mesh converter.

* Replacing the assert statement with a ValueError.

* Fix to blocksHere list iteration

* Updating the EPS on the block height check

* Fix to allow the zUpper and zLower to extend beyond the mesh of
assembly.
  • Loading branch information
jakehader committed Sep 14, 2021
1 parent e515408 commit 5c99428
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 13 deletions.
19 changes: 19 additions & 0 deletions armi/reactor/assemblies.py
Expand Up @@ -941,8 +941,11 @@ def getBlocksBetweenElevations(self, zLower, zUpper):
"""
EPS = 1e-10
blocksHere = []
allMeshPoints = set()
for b in self:
if b.p.ztop >= zLower and b.p.zbottom <= zUpper:
allMeshPoints.add(b.p.zbottom)
allMeshPoints.add(b.p.ztop)
# at least some of this block overlaps the window of interest
top = min(b.p.ztop, zUpper)
bottom = max(b.p.zbottom, zLower)
Expand All @@ -952,6 +955,22 @@ def getBlocksBetweenElevations(self, zLower, zUpper):
if heightHere / b.getHeight() > EPS:
blocksHere.append((b, heightHere))

totalHeight = 0.0
# The expected height snaps to the minimum height that is requested
expectedHeight = min(
sorted(allMeshPoints)[-1] - sorted(allMeshPoints)[0], zUpper - zLower
)
for _b, height in blocksHere:
totalHeight += height

# Verify that the heights of all the blocks are equal to the expected
# height for the given zUpper and zLower.
if abs(totalHeight - expectedHeight) > 1e-5:
raise ValueError(
f"The cumulative height of {blocksHere} is {totalHeight} cm "
f"and does not equal the expected height of {expectedHeight} cm"
)

return blocksHere

def getBlockLengthAboveAndBelowHeight(self, height):
Expand Down
49 changes: 36 additions & 13 deletions armi/reactor/converters/uniformMesh.py
Expand Up @@ -149,6 +149,7 @@ def makeAssemWithUniformMesh(sourceAssem, newMesh):
applyStateToOriginal : basically the reverse on the way out.
"""
newAssem = UniformMeshGeometryConverter._createNewAssembly(sourceAssem)
runLog.debug(f"Creating a uniform mesh of {newAssem}")
bottom = 0.0
for topMeshPoint in newMesh:
overlappingBlockInfo = sourceAssem.getBlocksBetweenElevations(
Expand All @@ -162,37 +163,55 @@ def makeAssemWithUniformMesh(sourceAssem, newMesh):
"".format(bottom, topMeshPoint, sourceAssem)
)

# If there are FUEL or CONTROL blocks that are overlapping with the other blocks then the first
# one is selected to ensure that the correct XS ID is applied to the new block during the deepcopy.
sourceBlock = None
specialXSType = None
for potentialBlock, _overlap in overlappingBlockInfo:
runLog.debug(
f"From axial elevation {bottom:<6.2f} cm to {topMeshPoint:<6.2f} cm"
)
for potentialBlock, heightOverlap in overlappingBlockInfo:
if sourceBlock is None:
sourceBlock = potentialBlock
sourceBlockHeightOverlap = heightOverlap
if (
potentialBlock.hasFlags([Flags.FUEL, Flags.CONTROL])
and potentialBlock != sourceBlock
):
runLog.important(
"There are multiple overlapping blocks. Choosing {} for {} XS sets.".format(
potentialBlock.getType(), sourceBlock.getType()
)
totalHeight = topMeshPoint - bottom
runLog.debug(
f" - {potentialBlock} accounts for {heightOverlap/totalHeight * 100.0:<5.2f}% of the homogenized region"
)

if specialXSType is None:
sourceBlock = potentialBlock
specialXSType = sourceBlock.p.xsType
elif specialXSType == potentialBlock.p.xsType:
pass
else:
runLog.error(
"There are two special block XS types. Not sure which to choose {} {}"
"".format(sourceBlock, potentialBlock)
)
raise RuntimeError(
"There are multiple special block XS types when there should only be one"
msg = (
f"Both {sourceBlock} and {potentialBlock} have conflicting XS types "
f"and have either {[Flags.FUEL, Flags.CONTROL]} flags. One or the other flags "
f"from these blocks should be removed to produce a uniform axial mesh for {newAssem}"
)
runLog.error(msg)
raise RuntimeError(msg)
elif potentialBlock == sourceBlock:
totalHeight = topMeshPoint - bottom
runLog.debug(
f" - {sourceBlock} accounts for {sourceBlockHeightOverlap/totalHeight * 100.0:<5.2f}% of the homogenized region"
)
else:
totalHeight = topMeshPoint - bottom
runLog.debug(
f" - {potentialBlock} accounts for {heightOverlap/totalHeight * 100.0:<5.2f}% of the homogenized region"
)

newXSType = sourceBlock.p.xsType if specialXSType is None else specialXSType
runLog.debug(
f" - The XS type of `{newXSType}` will be applied to the new homogenized region."
)

block = copy.deepcopy(sourceBlock)
block.p.xsType = newXSType
block.setHeight(topMeshPoint - bottom)
block.p.axMesh = 1
_setNumberDensitiesFromOverlaps(block, overlappingBlockInfo)
Expand All @@ -210,6 +229,10 @@ def _buildAllUniformAssemblies(self):
avoid unnecessarily diffusing small blocks into huge ones (e.g. control blocks
into plenum).
"""
runLog.debug(
f"Creating new assemblies from {self._sourceReactor.core} "
f"with a uniform mesh of {self._uniformMesh}"
)
for sourceAssem in self._sourceReactor.core:
newAssem = self.makeAssemWithUniformMesh(sourceAssem, self._uniformMesh)
newAssem.r = self.convReactor
Expand Down

0 comments on commit 5c99428

Please sign in to comment.