armi.reactor.flags module

Handles flags that formally bind certain categories to reactor parts.

Flags are used to formally categorize the various ArmiObject objects that make up a reactor model. These categories allow parts of the ARMI system to treat different Assemblies, Blocks, Components, etc. differently.

By default, the specific Flags that are bound to each object are derived by that object’s name when constructed; if the name contains any valid flag names, those Flags will be assigned to the object. However, specific Flags may be specified within blueprints, in which case the name is ignored and only the explicitly-requested Flags are applied (see /user/inputs/blueprints for more details).

Individual Flags tend to be various nouns and adjectives that describe common objects that go into a reactor (e.g. “fuel”, “shield”, “control”, “duct”, “plenum”, etc.). In addition, there are some generic Flags (e.g., “A”, “B”, “C”, etc.) that aid in disambiguating between objects that need to be targeted separately but would otherwise have the same Flags. Flags are stored as integer bitfields within the parameter system, allowing them to be combined arbitrarily on any ARMI object. Since they are stored in bitfields, each new flag definition requires widening this bitfield; therefore, the number of defined Flags should be kept relatively small, and each flag should provide maximum utility.

Within the code, Flags are usually combined into a “type specification (TypeSpec)”, which is either a single combination of Flags, or a list of Flag combinations. More information about how TypeSpec is interpreted can be found in armi.reactor.composites.ArmiObject.hasFlags().

Flags are intended to describe what something is, rather than what something should do. Historically, Flags have been used to do both, which has led to confusion. The binding of specific behavior to certain Flags should ideally be controlled through settings with reasonable defaults, rather than being hard-coded. Currently, much of the code still uses hard-coded TypeSpecs, and certain Flags are clearly saying what something should do (e.g., Flags.DEPLETABLE).

Note

Flags have a rather storied history. Way back when, code that needed to operate on specific objects would do substring searches against object names to decide if they were relevant. This was very prone to error, and led to all sorts of surprising behavior based on the names used in input files. To improve the situation, Flags were developed to better formalize which strings mattered, and to define canonical names for things. Still almost all flag checks were hard-coded, and aside from up-front error checks, many of the original issues persisted. For instance, developing a comprehensive manual of which Flags lead to which behavior was very difficult.

Migrating the meaning of Flags into settings will allow us to better document how those Flags/settings affect ARMI’s behavior.

As mentioned above, plenty of code still hard-codes Flag TypeSpecs, and certain Flags do not follow the what something is convention. Future work should improve upon this as possible.

Things that Flags are used for include:

  • Fuel management: Different kinds of assemblies (LTAs, fuel, reflectors) have different shuffling operations and must be distinguished. Certain blocks in an assembly are stationary, and shouldn’t be moved along with the rest of the assembly when shuffling is performed. Filtering for stationary blocks can also be done using Flags (e.g., Flags.GRID_PLATE).

  • Fuel performance: Knowing what’s fuel (Flags.FUEL) and what isn’t (e.g., Flags.PLENUM) is important to figure out what things to grow and where to move fission gas to.

  • Fluid fuel reactors need to find all the fuel that ever circulates through the reactor so it can be depleted with the average flux.

  • Core Mechanical analyses often need to know if an object is solid, fluid, or void (material subclassing can handle this).

  • T/H needs to find the pin bundle in different kinds of assemblies (radial shield block in radial shield assemblies, fuel in fuel, etc.). Also needs to generate 3-layer pin models with pin (fuel/control/shield/slug), then gap (liners/gap/bond), then clad.

Examples

>>> block.hasFlags(Flags.PRIMARY | Flags.TEST | Flags.FUEL)
True
>>> block.hasFlags([Flags.PRIMARY, Flags.TEST, Flags.FUEL])
True
>>> block.getComponent(Flags.INTERDUCTCOOLANT)
<component InterDuctCoolant>
>>> block.getComponents(Flags.FUEL)
[<component fuel1>, <component fuel2>, ...]
class armi.reactor.flags.Flags(init=0)[source]

Bases: Flag

Defines the valid flags used in the framework.

PRIMARY = <Flags.PRIMARY: 1>
SECONDARY = <Flags.SECONDARY: 2>
TERTIARY = <Flags.TERTIARY: 4>
ANNULAR = <Flags.ANNULAR: 8>
A = <Flags.A: 16>
B = <Flags.B: 32>
C = <Flags.C: 64>
D = <Flags.D: 128>
E = <Flags.E: 256>
HIGH = <Flags.HIGH: 512>
MEDIUM = <Flags.MEDIUM: 1024>
LOW = <Flags.LOW: 2048>
CORE = <Flags.CORE: 4096>
REACTOR = <Flags.REACTOR: 8192>
MATERIAL = <Flags.MATERIAL: 16384>
FUEL = <Flags.FUEL: 32768>
TEST = <Flags.TEST: 65536>
CONTROL = <Flags.CONTROL: 131072>
ULTIMATE = <Flags.ULTIMATE: 262144>
SHUTDOWN = <Flags.SHUTDOWN: 524288>
SHIELD = <Flags.SHIELD: 1048576>
SHIELD_BLOCK = <Flags.SHIELD_BLOCK: 2097152>
SLUG = <Flags.SLUG: 4194304>
REFLECTOR = <Flags.REFLECTOR: 8388608>
DRIVER = <Flags.DRIVER: 16777216>
IGNITER = <Flags.IGNITER: 33554432>
FEED = <Flags.FEED: 67108864>
STARTER = <Flags.STARTER: 134217728>
BLANKET = <Flags.BLANKET: 268435456>
BOOSTER = <Flags.BOOSTER: 536870912>
TARGET = <Flags.TARGET: 1073741824>
MOX = <Flags.MOX: 2147483648>
INNER = <Flags.INNER: 4294967296>
MIDDLE = <Flags.MIDDLE: 8589934592>
OUTER = <Flags.OUTER: 17179869184>
RADIAL = <Flags.RADIAL: 34359738368>
AXIAL = <Flags.AXIAL: 68719476736>
UPPER = <Flags.UPPER: 137438953472>
LOWER = <Flags.LOWER: 274877906944>
DUCT = <Flags.DUCT: 549755813888>
GRID_PLATE = <Flags.GRID_PLATE: 1099511627776>
HANDLING_SOCKET = <Flags.HANDLING_SOCKET: 2199023255552>
INLET_NOZZLE = <Flags.INLET_NOZZLE: 4398046511104>
PLENUM = <Flags.PLENUM: 8796093022208>
BOND = <Flags.BOND: 17592186044416>
LINER = <Flags.LINER: 35184372088832>
CLAD = <Flags.CLAD: 70368744177664>
PIN = <Flags.PIN: 140737488355328>
GAP = <Flags.GAP: 281474976710656>
WIRE = <Flags.WIRE: 562949953421312>
COOLANT = <Flags.COOLANT: 1125899906842624>
INTERCOOLANT = <Flags.INTERCOOLANT: 2251799813685248>
LOAD_PAD = <Flags.LOAD_PAD: 4503599627370496>
ACLP = <Flags.ACLP: 9007199254740992>
SKID = <Flags.SKID: 18014398509481984>
VOID = <Flags.VOID: 36028797018963968>
INTERDUCTCOOLANT = <Flags.INTERDUCTCOOLANT: 72057594037927936>
DSPACERINSIDE = <Flags.DSPACERINSIDE: 144115188075855872>
GUIDE_TUBE = <Flags.GUIDE_TUBE: 288230376151711744>
FISSION_CHAMBER = <Flags.FISSION_CHAMBER: 576460752303423488>
MODERATOR = <Flags.MODERATOR: 1152921504606846976>
CORE_BARREL = <Flags.CORE_BARREL: 2305843009213693952>
DUMMY = <Flags.DUMMY: 4611686018427387904>
BATCHMASSADDITION = <Flags.BATCHMASSADDITION: 9223372036854775808>
POISON = <Flags.POISON: 18446744073709551616>
STRUCTURE = <Flags.STRUCTURE: 36893488147419103232>
DEPLETABLE = <Flags.DEPLETABLE: 73786976294838206464>
MOVEABLE = <Flags.MOVEABLE: 147573952589676412928>
classmethod fromStringIgnoreErrors(typeSpec)[source]
classmethod fromString(typeSpec)[source]

Retrieve flag from a string.

classmethod toString(typeSpec)[source]

Convert a flag to a string.

exception armi.reactor.flags.InvalidFlagsError[source]

Bases: KeyError

Raised when code attempts to look for an undefined flag.