armi.physics.fuelCycle.fuelHandlers module

This module handles fuel management operations such as shuffling, rotation, and fuel processing (in fluid systems).

The FuelHandlerInterface instantiates a FuelHandler, which is typically a user-defined subclass the FuelHandler object in custom shuffle-logic input files. Users point to the code modules with their custom fuel handlers using the shuffleLogic and fuelHandlerName settings, as described in Fuel Management Input. These subclasses override chooseSwaps that determine the particular shuffling of a case.

This module also handles repeat shuffles when doing a restart.

class armi.physics.fuelCycle.fuelHandlers.FuelHandlerInterface(r, cs)[source]

Bases: armi.interfaces.Interface

Moves and/or processes fuel in a Standard Operator.

Fuel management traditionally runs at the beginning of a cycle, before power or temperatures have been updated. This allows pre-run fuel management steps for highly customized fuel loadings. In typical runs, no fuel management occurs at the beginning of the first cycle and the as-input state is left as is.

Construct an interface.

The r and cs arguments are required, but may be None, where appropriate for the specific Interface implementation.

Parameters
  • r (Reactor) – A reactor to attach to

  • cs (Settings) – Settings object to use

Raises

RuntimeError – Interfaces derived from Interface must define their name

name: Optional[str] = 'fuelHandler'

The name of the interface. This is undefined for the base class, and must be overridden by any concrete class that extends this one.

static specifyInputs(cs)[source]

Return a collection of file names that are considered input files.

This is a static method (i.e. is not called on a particular instance of the class), since it should not require an Interface to actually be constructed. This would require constructing a reactor object, which is expensive.

The files returned by an implementation should be those that one would want copied to a target location when cloning a Case or CaseSuite. These can be absolute paths, relative paths, or glob patterns that will be interpolated relative to the input directory. Aboslute paths will not be copied anywhere.

The returned dictionary should be keyed off of a descriptive string, or an actual Setting object. If a Setting is used, then the source CaseSettings object will be updated to the new file location.

Note

This existed before the advent of ARMI plugins. Perhaps it can be better served as a plugin hook. Potential future work.

See also

armi.cases.Case.clone

Parameters

cs (CaseSettings) – The case settings for a particular Case

interactBOC(cycle=None)[source]

Move and/or process fuel.

Also, if requested, first have the lattice physics system update XS.

interactEOC(cycle=None)[source]

Called at the end of each cycle.

interactEOL()[source]

Make reports at EOL

manageFuel(cycle)[source]

Perform the fuel management for this cycle.

makeShuffleReport()[source]

Create a data file listing all the shuffles that occurred in a case.

This can be used to export shuffling to an external code or to perform explicit repeat shuffling in a restart. It creates a *SHUFFLES.txt file based on the Reactor.moveList structure

See also

readMoves

reads this file and parses it.

workerOperate(cmd)[source]

Delegate mpi command to the fuel handler object.

armi.physics.fuelCycle.fuelHandlers.fuelHandlerFactory(operator)[source]

Return an instantiated FuelHandler object based on user settings.

The FuelHandler is expected to be a short-lived object that only lives for the cycle upon which it acts. At the next cycle, this factory will be called again to instantiate a new FuelHandler.

class armi.physics.fuelCycle.fuelHandlers.FuelHandler(operator)[source]

Bases: object

A fuel handling machine can move fuel around the core and reactor.

It makes decisions on how to shuffle fuel based on user specifications. It provides some supervisory data tracking, such as having the ability to print out information about all moves that happened in a cycle (without the user needing to explicitly track this information).

To use this, simply create an input Python file and point to it by path with the fuelHandler setting. In that file, subclass this object.

property cycle

Link to the current cycle number.

Notes

This retains backwards compatibility with previous fuel handler inputs.

property cs

Link to the Case Settings object.

property r

Link to the Reactor object.

outage(factor=1.0)[source]

Simulates a reactor reload outage. Moves and tracks fuel.

This sets the moveList structure.

chooseSwaps(shuffleFactors=None)[source]

Moves the fuel around or otherwise processes it between cycles.

static getFactorList(cycle, cs=None, fallBack=False)[source]

Return factors between 0 and 1 that control fuel management.

This is the default shuffle control function. Usually you would override this with your own in a custom shuffleLogic.py file. For more details about how this works, refer to Fuel Management Input.

This will get bound to the default FuelHandler as a static method below. This is done to allow a user to mix and match FuelHandler class implementations and getFactorList implementations at run time.

Notes

Ultimately, this approach will likely get replaced using the plugin framework, but we aren’t there yet.

simpleAssemblyRotation()[source]

Rotate all pin-detail assemblies that were just shuffled by 60 degrees

Notes

Also, optionally rotate stationary (non-shuffled) assemblies if the setting is set. Obviously, only pin-detail assemblies can be rotated, because homogenized assemblies are isotropic.

Examples

>>> fh.simpleAssemblyRotation()

See also

buReducingAssemblyRotation

an alternative rotation algorithm

outage

calls this method based on a user setting

buReducingAssemblyRotation()[source]

Rotates all detail assemblies to put the highest bu pin in the lowest power orientation

See also

simpleAssemblyRotation

an alternative rotation algorithm

outage

calls this method based on a user setting

static getOptimalAssemblyOrientation(a, aPrev)[source]

Get optimal assembly orientation/rotation to minimize peak burnup.

Notes

Works by placing the highest-BU 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, which is the previous assembly located here. If aPrev has no pin detail, then we must use its corner fast fluxes to make an estimate.

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, then “aPrev” = “a”.

    If “aPrev” has pin detail, then we will determine the orientation of “a” based on the pin powers of “aPrev” when it was located here.

    If “aPrev” does NOT have pin detail, then we will determine the orientation of “a” based on the corner fast fluxes in “aPrev” when it was located here.

Returns

rot – An integer from 0 to 5 representing the “orientation” of the assembly. This orientation is relative to the current assembly orientation. rot = 0 corresponds to no rotation. rot represents the number of pi/3 counterclockwise rotations for the default orientation.

Return type

int

Examples

>>> fh.getOptimalAssemblyOrientation(a,aPrev)
4

See also

rotateAssemblies

calls this to figure out how to rotate

prepCore()[source]

Aux. function to run before XS generation (do moderation, etc. here)

prepSearch(*args, **kwargs)[source]

Optional method that can be implemented in preparation of shuffling.

Often used to prepare the scope of a shuffling branch search.

Notes

This was used historically to keep a long-lived fuel handler in sync with the reactor and can now technically be removed from the API, but many historical fuel management inputs still expect it to be called by the framework, so here it remains. New developments should avoid using it. Most code using it has been refactored to just use a _prepSearch private method.

It now should not be used and will trigger a DeprecationWarning in the constructor. It’s still here because old user-input code calls the parent’s prepSearch, which is this.

findAssembly(targetRing=None, width=(0, 0), param=None, compareTo=None, forceSide=None, exclusions=None, typeSpec=None, mandatoryLocations=None, zoneList=None, excludedLocations=None, minParam=None, minVal=None, maxParam=None, maxVal=None, findMany=False, coords=None, exactType=False, acceptFirstCandidateRing=False, blockLevelMax=False, findFromSfp=False, maxNumAssems=None, circularRingFlag=False)[source]

Search reactor for assemblies with various criterion. Primarily for shuffling.

Parameters
  • targetRing (int, optional) – The ring in which to search

  • width (tuple of integers) – A (size, side) tuple where size is the number of rings on either side to also check. side=1: only look in higher, -1: only look lower, 0: both sides

  • param (string, optional) – A block (if blockLevelMax) or assem level param name such as ‘power’ or ‘percentBu’ (requires compareTo).

  • compareTo (float or Assembly instance) – an assembly to be compared to. Alternatively, a floating point number to compare to. Even more alternatively, an (assembly,mult) or (float,mult) tuple where mult is a multiplier. For example, if you wanted an assembly that had a bu close to half of assembly bob, you’d give param=’percentBu’, compareTo=(bob,0.5) If you want one with a bu close to 0.3, you’d do param=’percentBu’,compareTo=0.3. Yes, if you give a (float, multiplier) tuple, the code will make fun of you for not doing your own math, but will still operate as expected.

  • forceSide (bool, optional) –

    requires the found assembly to have either 1: higher, -1: lower, None: any param than

    compareTo

  • exclusions (list, optional) – List of assemblies that will be excluded from the search

  • minParam (float or list, optional) – a parameter to compare to minVal for setting lower bounds. If list, must correspond to parameters in minVal in order.

  • maxParam (float or list, optional) – a parameter to compare to maxVal for setting upper bounds of acceptable assemblies. If list, must correspond to parameters in maxVal in order.

  • minVal (float or list, optional) –

    a value or a (parameter, multiplier) tuple for setting lower bounds

    For instance, if minParam = ‘timeToLimit’ and minVal=10, only assemblies with timeToLimit higher than 10 will be returned. (Of course, there is also maxParam and maxVal)

  • maxVal (float or list, optional) – a value or a (parameter, multiplier) tuple for setting upper bounds

  • mandatoryLocations (list, optional) –

    a list of string-representations of locations in the core for limiting the search to several places

    Any locations also included in excludedLocations will be excluded.

  • excludedLocations (list, optional) – a list of string-representations of locations in the core that will be excluded from the search

  • zoneList (list, optional) – name of a zone defined in settings.py that will be picked from. Under development

  • findMany (bool, optional) – If True, will return a list of assembies that match. Don’t give a param.

  • typeSpec (Flags or list of Flags, optional) – only assemblies with this type list will be returned. If none, only fuel will be found.

  • coords (tuple, optional) – x,y tuple in cm. the fuel handler will try to find an assembly with a center closest to that point

  • exactType (bool, optional) – require type to be exactly equal to what’s in the type list. So Flags.IGNITER | Flags.FUEL is not Flags.INNER | Flags.IGNITER | Flags.FUEL

  • acceptFirstCandidateRing (bool, optional) – takes the first assembly found in the earliest ring (without searching all rings for a maxBu, for example) So if the candidate rings are 1-10 and we’re looking for igniter fuel with a maxBurnup, we don’t get the max burnup in all those rings, but rather the igniter with the max burnup in the ring closest to 1. If there are no igniters until ring 4, you will get an igniter in ring 4.

  • blockLevelMax (bool, optional) – If true, the param to search for will be built as the maximum block-level param of this name instead of the assembly param. This avoids the need to assign assembly level params sometimes. default: false.

  • findFromSfp (bool, optional) – if true, will look in the spent-fuel pool instead of in the core.

  • maxNumAssems (int, optional) – The maximum number of assemblies to return. Only relevant if findMany==True

  • circularRingFlag (bool, optional) – A flag to toggle on using rings that are based on distance from the center of the reactor

Notes

The call signature on this method may have gotten slightly out of hand as valuable capabilities were added in fuel management studies. For additional expansion, it may be worth reconsidering the design of these query operations ;).

Returns

  • Assembly instance or assemList of assembly instances that match criteria, or None if none

  • match

Examples

feed = self.findAssembly(targetRing=4,

width=(0,0), param=’maxPercentBu’, compareTo=100, typeSpec=Flags.FEED | Flags.FUEL)

returns the feed fuel assembly in ring 4 that has a burnup closest to 100% (the highest burnup assembly)

buildRingSchedule(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
  • 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])

See also

findAssembly

buildConvergentRingSchedule(dischargeRing=1, chargeRing=None, coarseFactor=0.0)[source]

Builds a ring schedule for convergent shuffling from chargeRing to dischargeRing

Parameters
  • 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

  • chargeRing (int, optional) – The peripheral ring into which an assembly enters the core. Default is outermost 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

Examples

See also

findAssembly

swapAssemblies(a1, a2)[source]

Moves a whole assembly from one place to another

Parameters
  • a1 (Assembly) – The first assembly

  • a2 (Assembly) – The second assembly

See also

dischargeSwap

swap assemblies where one is outside the core and the other is inside

dischargeSwap(incoming, outgoing)[source]

Removes one assembly from the core and replace it with another assembly.

See also

swapAssemblies

swaps assemblies that are already in the core

swapCascade(assemList)[source]

Perform swaps on a list of assemblies.

Notes

[goingOut,inter1,inter2,goingIn] will go to [inter1, inter2, goingIn, goingOut] in terms of positions or, in ASCII art:

 >---------------v
 |               |
[A  <- B <- C <- D]
repeatShufflePattern(explicitRepeatShuffles)[source]

Repeats the fuel management from a previous ARMI run

Parameters

explicitRepeatShuffles (str) – The file name that contains the shuffling history from a previous run

Returns

moved – list of assemblies that moved this cycle

Return type

list

Notes

typically the explicitRepeatShuffles will be “caseName”+”-SHUFFLES.txt”

See also

doRepeatShuffle

Performs moves as processed by this method

processMoveList

Converts a stored list of moves into a functional list of assemblies to swap

makeShuffleReport

Creates the file that is processed here

static readMoves(fname)[source]

reads a shuffle output file and sets up the moves dictionary

Parameters

fname (str) – The shuffles file to read

Returns

moves – A dictionary of all the moves. Keys are the cycle number. Values are a list of tuples, one tuple for each individual move that happened in the cycle. The items in the tuple are (oldLoc, newLoc, enrichList, assemType). Where oldLoc and newLoc are str representations of the locations and enrichList is a list of mass enrichments from bottom to top.

Return type

dict

See also

repeatShufflePattern

reads this file and repeats the shuffling

outage

creates the moveList in the first place.

makeShuffleReport

writes the file that is read here.

trackChain(moveList, startingAt, alreadyDone=None)[source]

builds a chain of locations based on starting location

Notes

Takes a moveList and extracts chains. Remembers all it touches. If A moved to B, C moved to D, and B moved to C, this returns A, B, C ,D.

Used in some monte carlo physics writers and in repeatShufflePattern

Parameters
  • moveList (list) – a list of (fromLoc,toLoc,enrichList,assemType,assemName) tuples that occurred at a single outage.

  • startingAt (str) – A location label where the chain would start. This is important because the discharge moves are built when the SFP is found in a move. This method must find all assemblies in the chain leading up to this particular discharge.

  • alreadyDone (list) – A list of locations that have already been tracked.

Returns

  • chain (list) – The chain as a location list in order

  • enrich (list) – The axial enrichment distribution of the load assembly.

  • loadName (str) – The assembly name of the load assembly

See also

repeatShufflePattern, mcnpInterface.getMoveCards, processMoveList

processMoveList(moveList)[source]

Processes a move list and extracts fuel management loops and charges.

Parameters

moveList (list) –

A list of information about fuel management from a previous case. Each entry represents a move and includes the following items as a tuple:

fromLoc

the label of where the assembly was before the move

toLoc

the label of where the assembly was after the move

enrichList

a list of block enrichments for the assembly

assemType

the type of assembly that this is

movingAssemName

the name of the assembly that is moving from to

Returns

  • loadChains (list) – list of lists of location labels for each load chain (with charge/discharge). These DO NOT include special location labels like LoadQueue or SFP

  • loopChains (list) – list of lists of location labels for each loop chain (no charge/discharge)

  • enriches (list) – The block enrichment distribution of each load assembly

  • loadChargeTypes (list) – The types of assemblies that get charged.

  • loadNames (list) – The assembly names of assemblies that get brought into the core from the SFP (useful for pulling out of SFP for round 2, etc.). Will be None for anything else.

  • alreadyDone (list) – All the locations that were read.

Notes

Used in the some Monte Carlo interfaces to convert ARMI moves to their format moves. Also used in repeat shuffling.

See also

makeShuffleReport

writes the file that is being processed

repeatShufflePattern

uses this to repeat shuffles

doRepeatShuffle(loadChains, loopChains, enriches, loadChargeTypes, loadNames)[source]

Actually does the fuel movements required to repeat a shuffle order

Parameters
  • loadChains (list) – list of lists of location labels for each load chain (with charge/discharge)

  • loopChains (list) – list of lists of location labels for each loop chain (no charge/discharge)

  • enriches (list) – The block enrichment distribution of each load assembly

  • loadChargeTypes (list) – The types of assemblies that get charged.

  • loadNames (list) – The assembly names of assemblies that get brought into the core (useful for pulling out of SFP for round 2, etc.)

See also

repeatShufflePattern

coordinates the moves for this cycle

processMoveList

builds the input lists

Notes

This is a helper function for repeatShufflePattern

buildEqRingSchedule(ringSchedule)[source]

Expands simple ringSchedule input into full-on location schedule

Parameters
  • ringSchedule

  • r

  • cs

Returns

locationSchedule

Return type

list

buildEqRingScheduleHelper(ringSchedule)[source]

turns ringScheduler into explicit list of rings

Pulled out of buildEqRingSchedule for testing.

Parameters

ringSchedule (list) – List of ring bounds that is required to be an even number of entries. These entries then are used in a from - to approach to add the rings. The from ring will always be included.

Returns

ringList – List of all rings in the order they should be shuffled.

Return type

list

Examples

>>> buildEqRingScheduleHelper([1,5])
[1,2,3,4,5]
>>> buildEqRingScheduleHelper([1,5,9,6])
[1,2,3,4,5,9,8,7,6]
>>> buildEqRingScheduleHelper([9,5,3,4,1,2])
[9,8,7,6,5,3,4,1,2]
>>> buildEqRingScheduleHelper([2,5,1,1])
[2,3,4,5,1]
workerOperate(cmd)[source]

Handle a mpi command on the worker nodes.

prepShuffleMap()[source]

Prepare a table of current locations for plotting shuffle maneuvers.

makeShuffleArrows()[source]

Build data for plotting all the previous shuffles as arrows.

Returns

arrows – Values are (currentCoords, oldCoords) tuples

Return type

list