-
Notifications
You must be signed in to change notification settings - Fork 86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Plot cartesian #71
Plot cartesian #71
Conversation
- Turned off autoformat for ANL230/703 - Moved plotting functionality from reactors to utils.plottting - Removed reactors.getAssemTypeLetters as its output was never used. - Fixed reactor.getAssemblyPitch so it returns both pitch values for reactors with cartesian blocks - Added tests for hex/cartesian getAssemblyPitch - Added functionality for plotting facemap of cartesian reactors. - Added plot functionality to page through differnt assembly depths. - Added plotting tests. - Added ability to create empty cartesian reactor.
armi/reactor/tests/test_reactors.py
Outdated
@@ -44,26 +44,54 @@ | |||
TEST_REACTOR = None # pickled string of test reactor (for fast caching) | |||
|
|||
|
|||
def buildOperatorOfEmptyBlocks(customSettings=None): | |||
def buildOperatorOfEmptyBlocks(customSettings=None, reactorType="Hex"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good to use CONSTANTS
here, like RX_TYPE_HEX
.
armi/reactor/tests/test_reactors.py
Outdated
if reactorType == "Hex": | ||
r = tests.getEmptyHexReactor() | ||
AssemClass = assemblies.HexAssembly | ||
BlockClass = blocks.HexBlock | ||
CompClass = Hexagon | ||
dims = {"op": 16.0, "ip": 1} | ||
elif reactorType == "Cartesian": | ||
r = tests.getEmptyCartesianReactor() | ||
AssemClass = assemblies.CartesianAssembly | ||
BlockClass = blocks.CartesianBlock | ||
CompClass = Rectangle | ||
dims = { | ||
"widthOuter": 16.0, | ||
"lengthOuter": 10.0, | ||
"widthInner": 1, | ||
"lengthInner": 1, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might make sense to just make these totally independent without the input conditional/switch, even though they share some code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, i had that thought after near the time I finished the switch. I can make it 2 methods. The switch contained more than I initially thought it would need to by the time it was done.
armi/utils/plotting.py
Outdated
""" | ||
|
||
if assems is None: | ||
assems = list(core.parent.blueprints.assemblies.values()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the only thing that we are using the core for is to get the blueprints, then we should probably just pass the blueprints. Looking at the call site higher in the diff, I was confused to see that core was being passed at all, prompting me to dig in farther to see this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I just moved this out of reactors and didn't change anything, so I didn't spend much time reading it.
# Get the detailed text label for the block | ||
dLabel = "" | ||
if b.hasFlags(Flags.FUEL): | ||
dLabel = " {:0.2f}%".format(b.getFissileMassEnrich() * 100) | ||
elif b.hasFlags(Flags.CONTROL): | ||
blockType = "ctrl" | ||
dLabel = " {:0.2f}%".format(b.getBoronMassEnrich() * 100) | ||
dLabel += " ({})".format(blockXsId) | ||
|
||
# Set up block rectangle | ||
blockPatch = mpatches.Rectangle( | ||
(xBlockLoc, yBlockLoc), | ||
blockWidth, | ||
blockHeight, | ||
facecolor=color, | ||
alpha=0.7, | ||
edgecolor="k", | ||
lw=1.0, | ||
ls="solid", | ||
) | ||
axis.add_patch(blockPatch) | ||
axis.text( | ||
xTextLoc, | ||
yBlockCenterLoc, | ||
blockType.upper() + dLabel, | ||
ha="left", | ||
fontsize=10, | ||
) | ||
yBlockLoc += blockHeight | ||
yBlockHeights.append(yBlockLoc) | ||
|
||
# Add location, block heights, and axial mesh points to ordered set | ||
yBlockAxMesh.add((yBlockCenterLoc, blockHeight, b.p.axMesh)) | ||
|
||
# Add the block heights, block number of axial mesh points on the far right of the plot. | ||
if isLastAssem and showBlockAxMesh: | ||
xEndLoc = 0.5 + xAssemEndLoc | ||
for bCenter, bHeight, axMeshPoints in yBlockAxMesh: | ||
axis.text( | ||
xEndLoc, | ||
bCenter, | ||
"{} cm ({})".format(bHeight, axMeshPoints), | ||
fontsize=10, | ||
ha="left", | ||
) | ||
|
||
return xBlockLoc, yBlockHeights, yBlockAxMesh | ||
|
||
def getAssemTypeLetters(self): | ||
""" | ||
Builds a list of unique capital letters for each assembly. | ||
|
||
Tries with the first letter of each word, then goes to just continuous letters. | ||
If nothing unique, just pulls from the alphabet. | ||
|
||
Returns | ||
------- | ||
assemTypeLetters : dict | ||
keys are assembly types, vals are capital letters. | ||
""" | ||
|
||
assemTypeLetters = {} | ||
doneLetters = [] | ||
candidate = None | ||
alphabet = frozenset([chr(units.ASCII_LETTER_A + i) for i in range(26)]) | ||
for a in self: | ||
aType = a.getType() | ||
|
||
if aType not in assemTypeLetters: | ||
# build list of candidate letters. Start with first letter, | ||
# then first letter of second word, then all following letters. | ||
candidates = [aType[0]] | ||
for word in aType.split()[1:]: | ||
# add first letter of each word | ||
candidates.append(word[0]) | ||
candidates.extend(aType.replace(" ", "")[1:]) # no spaces allowed | ||
# add in remaining letters in alphabet | ||
done2 = frozenset( | ||
doneLetters | ||
) # frozensets allow - to be a difference operator. Very nice. | ||
candidates.extend([a for a in alphabet - done2]) | ||
|
||
# find a unique candidate letter | ||
for candidate in candidates: | ||
candidate = candidate.upper() | ||
if candidate not in doneLetters: | ||
doneLetters.append(candidate) | ||
break | ||
|
||
if not candidate: | ||
runLog.error( | ||
"Cannot determine type letter of {0} assemblies. Are there more " | ||
"than 26 assembly types? If so, upgrade assembly type ID system." | ||
"Done letters are: {1}".format(aType, doneLetters) | ||
) | ||
raise RuntimeError("Failed to determine assembly type letter.") | ||
assemTypeLetters[aType] = candidate | ||
|
||
return assemTypeLetters | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmmmmmmmm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, everything was basically just moved (with some refactor on plot face map). the only thing that I actually got to delete was getAssemTypeLetters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good to me. Nice cleanup and cool new plot.
And make a good commit message explaining everything when you squash for the log
Holding off on removing capability of Cartesian to have two pitches for the moment. Will make ticket.