armi.physics.fuelCycle.hexAssemblyFuelMgmtUtils module
This is a selection of fuel management utilities that seem generally useful enough to keep in ARMI, but they still only apply to hex assembly reactors.
Notes
We are keeping these in ARMI even if they appear unused internally.
- armi.physics.fuelCycle.hexAssemblyFuelMgmtUtils.getOptimalAssemblyOrientation(a: HexAssembly, aPrev: HexAssembly) int [source]
Get optimal hex assembly orientation/rotation to minimize peak burnup.
Works by placing the highest-burnup pin in the location (of 6 possible locations) with lowest expected pin power. We evaluated “expected pin power” based on the power distribution in
aPrev
, the previous assembly located wherea
is going. The algorithm goes as follows.Get all the pin powers and
IndexLocation
s from the block at the previous location/timenode.Obtain the
IndexLocation
of the pin with the highest burnup in the current assembly.For each possible rotation,
Find the new location with
HexGrid.rotateIndex
Find the index where that location occurs in previous locations
Find the previous power at that location
Return the rotation with the lowest previous power
This algorithm assumes a few things.
len(HexBlock.getPinCoordinates()) == len(HexBlock.p.linPowByPin)
and, by extension,linPowByPin[i]
is found atgetPinCoordinates()[i]
.Your assembly has at least 60 degree symmetry of fuel pins and powers. This means if we find a fuel pin and rotate it 60 degrees, there should be another fuel pin at that lattice site. This is mostly a safe assumption since many hexagonal reactors have at least 60 degree symmetry of fuel pin layout. This assumption holds if you have a full hexagonal lattice of fuel pins as well.
Fuel pins in
a
have similar locations inaPrev
. This is mostly a safe assumption in that most fuel assemblies have similar layouts so it’s plausible that ifa
has a fuel pin at(1, 0, 0)
, so doesaPrev
.
- Parameters:
a (Assembly object) – The assembly that is being rotated.
aPrev (Assembly object) – The assembly that previously occupied this location (before the last shuffle). If the assembly “a” was not shuffled, it’s sufficient to pass
a
.
- Returns:
An integer from 0 to 5 representing the number of pi/3 (60 degree) counterclockwise rotations from where
a
is currently oriented to the “optimal” orientation- Return type:
- Raises:
ValueError – If there is insufficient information to determine the rotation of
a
. This could be due to a lack of fuel blocks or parameters likelinPowByPin
.
- armi.physics.fuelCycle.hexAssemblyFuelMgmtUtils.buildRingSchedule(maxRingInCore, chargeRing=None, dischargeRing=None, jumpRingFrom=None, jumpRingTo=None, coarseFactor=0.0)[source]
Build a ring schedule for shuffling.
Notes
General enough to do convergent, divergent, or any combo, plus jumprings.
The center of the core is ring 1, based on the DIF3D numbering scheme.
Jump ring behavior can be generalized by first building a base ring list where assemblies get charged to H and discharge from A:
[A,B,C,D,E,F,G,H]
If a jump should be placed where it jumps from ring G to C, reversed back to F, and then discharges from A, we simply reverse the sublist [C,D,E,F], leaving us with:
[A,B,F,E,D,C,G,H]
A less-complex, more standard convergent-divergent scheme is a subcase of this, where the sublist [A,B,C,D,E] or so is reversed, leaving:
[E,D,C,B,A,F,G,H]
So the task of this function is simply to determine what subsection, if any, to reverse of the baselist.
- Parameters:
maxRingInCore (int) – The number of rings in the hex assembly reactor.
chargeRing (int, optional) – The peripheral ring into which an assembly enters the core. Default is outermost ring.
dischargeRing (int, optional) – The last ring an assembly sits in before discharging. Default is jumpRing-1
jumpRingFrom (int) – The last ring an assembly sits in before jumping to the center
jumpRingTo (int, optional) – The inner ring into which a jumping assembly jumps. Default is 1.
coarseFactor (float, optional) – A number between 0 and 1 where 0 hits all rings and 1 only hits the outer, rJ, center, and rD rings. This allows coarse shuffling, with large jumps. Default: 0
- Returns:
ringSchedule (list) – A list of rings in order from discharge to charge.
ringWidths (list) – A list of integers corresponding to the ringSchedule determining the widths of each ring area
Examples
>>> f.buildRingSchedule(17,1,jumpRingFrom=14) ([13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 14, 15, 16, 17], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
- armi.physics.fuelCycle.hexAssemblyFuelMgmtUtils.buildConvergentRingSchedule(chargeRing, dischargeRing=1, coarseFactor=0.0)[source]
Builds a ring schedule for convergent shuffling from
chargeRing
todischargeRing
.- Parameters:
chargeRing (int) – The peripheral ring into which an assembly enters the core. A good default is outermost ring:
r.core.getNumRings()
.dischargeRing (int, optional) – The last ring an assembly sits in before discharging. If no discharge, this is the one that gets placed where the charge happens. Default: Innermost ring
coarseFactor (float, optional) – A number between 0 and 1 where 0 hits all rings and 1 only hits the outer, rJ, center, and rD rings. This allows coarse shuffling, with large jumps. Default: 0
- Returns:
convergent (list) – A list of rings in order from discharge to charge.
conWidths (list) – A list of integers corresponding to the ringSchedule determining the widths of each ring area