armi.operators.operator module

The standard ARMI operator.

This builds and maintains the interface stack and loops through it for a certain number of cycles with a certain number of timenodes per cycle.

This is analogous to a real reactor operating over some period of time, often from initial startup, through the various cycles, and out to the end of plant life.

class armi.operators.operator.Operator(cs)[source]

Bases: object

Orchestrates an ARMI run, building all the pieces, looping through the interfaces, and manipulating the reactor.

This Standard Operator loops over a user-input number of cycles, each with a user-input number of subcycles (called time nodes). It calls a series of interaction hooks on each of the Interface in the Interface Stack.

../_images/armi_general_flowchart.png

Figure 1. The computational flow of the interface hooks in a Standard Operator

Note

The Framework Architecture has some additional narrative on this topic.

Variables
  • cs (CaseSettings object) – Global settings that define the run.

  • cycleLengths (list) – The duration of each individual cycle in a run (in days). This is the entire cycle, from startup to startup and includes outage time.

  • availabilityFactors (list) – The fraction of time in a cycle that the plant is producing power. Note that capacity factor is always less than or equal to this, depending on the power fraction achieved during each cycle.

  • powerFractions (list) – The fraction of full rated capacity that the plant achieves while it is online in each cycle. Zero power fraction can indicate decay-only cycles.

  • interfaces (list) – The Interface objects that will operate upon the reactor

Constructor for operator.

Parameters

cs (CaseSettings object) – Global settings that define the run.

Raises

OSError – If unable to create the FAST_PATH directory.

inspector

alias of armi.operators.settingsValidation.Inspector

static _initFastPath()[source]

Create the FAST_PATH directory for fast local operations

Notes

The FAST_PATH was once created at import-time in order to support modules that use FAST_PATH without operators (e.g. Database). However, we decided to leave FAST_PATH as the CWD in INTERACTIVE mode, so this should not be a problem anymore, and we can safely move FAST_PATH creation back into the Operator.

If the operator is being used interactively (e.g. at a prompt) we will still use a temporary local fast path (in case the user is working on a slow network path).

_getCycleLengths()[source]

Return the cycle length for each cycle of the system as a list.

_getAvailabilityFactors()[source]

Return the availability factors (capacity factor) for each cycle of the system as a list.

_getPowerFractions()[source]

Return the power fractions for each cycle of the system as a list.

_checkReactorCycleAttrs()[source]
property atEOL

Return whether we are approaching EOL.

For the standard operator, this will return true when the current cycle is the last cycle (cs[“nCycles”] - 1). Other operators may need to impose different logic.

initializeInterfaces(r)[source]

Attach the reactor to the operator and initialize all interfaces.

This does not occur in __init__ so that the ARMI operator can be initialized before a reactor is created, which is useful for summarizing the case information quickly.

Parameters

r (Reactor) – The Reactor object to attach to this Operator.

operate()[source]

Run the operation loop.

See also

mainOperator()

run the operator loop on the primary MPI node (for parallel runs)

workerOperate()

run the operator loop for the worker MPI nodes

_mainOperate()[source]

Main loop for a standard ARMI run. Steps through time interacting with the interfaces.

_cycleLoop(cycle, startingCycle)[source]

Run the portion of the main loop that happens each cycle.

_timeNodeLoop(cycle, timeNode)[source]

Run the portion of the main loop that happens each subcycle.

_interactAll(interactionName, activeInterfaces, *args)[source]

Loop over the supplied activeInterfaces and perform the supplied interaction on each.

Notes

This is the base method for the other interactAll methods.

printInterfaceSummary(interface, interactionName, statePointIndex, *args)[source]

Log which interaction point is about to be executed.

This looks better as multiple lines but it’s a lot easier to grep as one line. We leverage newlines instead of long banners to save disk space.

static _expandCycleAndTimeNodeArgs(*args)[source]

Return text annotating the (cycle, time node) args for each that are present.

_debugDB(interactionName, interfaceName, statePointIndex=0)[source]

Write state to DB with a unique “statePointName”, or label.

Notes

Used within _interactAll to write details between each physics interaction when cs[‘debugDB’] is enabled.

Parameters
  • interactionName (str) – name of the interaction (e.g. BOL, BOC, EveryNode)

  • interfaceName (str) – name of the interface that is interacting (e.g. globalflux, lattice, th)

  • statePointIndex (int (optional)) – used as a counter to make labels that increment throughout an _interactAll call. The result should be fed into the next call to ensure labels increment.

_checkCsConsistency()[source]

Debugging check to verify that CS objects are not unexpectedly multiplying.

interactAllInit()[source]

Call interactInit on all interfaces in the stack after they are initialized.

interactAllBOL(excludedInterfaceNames=())[source]

Call interactBOL for all interfaces in the interface stack at beginning-of-life.

All enabled or bolForce interfaces will be called excluding interfaces with excludedInterfaceNames.

interactAllBOC(cycle)[source]

Interact at beginning of cycle of all enabled interfaces.

interactAllEveryNode(cycle, tn, excludedInterfaceNames=None)[source]

Call the interactEveryNode hook for all enabled interfaces.

All enabled interfaces will be called excluding interfaces with excludedInterfaceNames.

Parameters
  • cycle (int) – The cycle that is currently being run. Starts at 0

  • tn (int) – The time node that is currently being run (0 for BOC, etc.)

  • excludedInterfaceNames (list, optional) – Names of interface names that will not be interacted with.

interactAllEOC(cycle, excludedInterfaceNames=None)[source]

Interact end of cycle for all enabled interfaces.

interactAllEOL()[source]

Run interactEOL for all enabled interfaces.

Notes

If the interfaces are flagged to be reversed at EOL, they are separated from the main stack and appended at the end in reverse order. This allows, for example, an interface that must run first to also run last.

interactAllCoupled(coupledIteration)[source]

Interact for tight physics coupling over all enabled interfaces.

Tight coupling implies operator-split iterations between two or more physics solvers at the same solution point in time. For example, a flux solution might be computed, then a temperature solution, and then another flux solution based on updated temperatures (which updated densities, dimensions, and Doppler).

This is distinct from loose coupling, which would simply uses the temperature values from the previous timestep in the current flux solution. It’s also distinct from full coupling where all fields are solved simultaneously. ARMI supports tight and loose coupling.

interactAllError()[source]

Interact when an error is raised by any other interface. Provides a wrap-up option on the way to a crash.

createInterfaces()[source]

Dynamically discover all available interfaces and call their factories, potentially adding them to the stack.

An operator contains an ordered list of interfaces. These communicate between the core ARMI structure and auxiliary computational modules and/or external codes. At specified interaction points in a run, the list of interfaces is executed.

Each interface optionally defines interaction “hooks” for each of the interaction points. The normal interaction points are BOL, BOC, every node, EOC, and EOL. If an interface defines an interactBOL method, that will run at BOL, and so on.

The majority of ARMI capabilities lie within interfaces, and this architecture provides much of the flexibility of ARMI.

See also

addInterface()

Adds a particular interface to the interface stack.

armi.interfaces.STACK_ORDER()

A system to determine the required order of interfaces.

armi.interfaces.getActiveInterfaceInfo()

Collects the interface classes from relevant packages.

addInterface(interface, index=None, reverseAtEOL=False, enabled=True, bolForce=False)[source]

Attach an interface to this operator.

Notes

Order matters.

Parameters
  • interface (Interface) – the interface to add

  • index (int, optional. Will insert the interface at this index rather than appending it to the end of) – the list

  • reverseAtEOL (bool, optional.) – The interactEOL hooks will run in reverse order if True. All interfaces with this flag will be run as a group after all other interfaces. This allows something to run first at BOL and last at EOL, etc.

  • enabled (bool, optional) – If enabled, will run at all hooks. If not, won’t run any (with possible exception at BOL, see bolForce). Whenever possible, Interfaces that are needed during runtime for some peripheral operation but not during the main loop should be instantiated by the part of the code that actually needs the interface.

  • bolForce (bool, optional) – If true, will run at BOL hook even if disabled. This is often a sign that the interface in question should be ephemerally instantiated on demand rather than added to the interface stack at all.

Raises

RuntimeError – If an interface of the same name or function is already attached to the Operator.

_processInterfaceDependencies()[source]

Check all interfaces’ dependencies and adds missing ones.

Notes

Order does not matter here because the interfaces added here are disabled and playing supporting role so it is not intended to run on the interface stack. They will be called by other interfaces.

As mentioned in addInterface(), it may be better to just insantiate utility code when its needed rather than rely on this system.

removeAllInterfaces()[source]

Removes all of the interfaces

removeInterface(interface=None, interfaceName=None)[source]

Remove a single interface from the interface stack.

Parameters
  • interface (Interface, optional) – An actual interface object to remove.

  • interfaceName (str, optional) – The name of the interface to remove.

Returns

success – True if the interface was removed False if it was not (because it wasn’t there to be removed)

Return type

boolean

getInterface(name=None, function=None)[source]

Returns a specific interface from the stack by its name or more generic function.

Parameters
  • name (str, optional) – Interface name

  • function (str) – Interface function (general, like ‘globalFlux’,’th’,etc.). This is useful when you need the ___ solver (e.g. globalFlux) but don’t care which particular one is active (e.g. SERPENT vs. DIF3D)

Raises

RuntimeError – If there are more than one interfaces of the given name or function.

interfaceIsActive(name)[source]

True if named interface exists and is active.

getInterfaces()[source]

Get list of interfaces in interface stack.

Notes

Returns a copy so you can manipulate the list in an interface, like dependencies.

reattach(r, cs=None)[source]

Add links to globally-shared objects to this operator and all interfaces.

Notes

Could be a good opportunity for weakrefs.

detach()[source]

Break links to globally-shared objects to this operator and all interfaces.

May be required prior to copying these objects over the network.

Notes

Could be a good opportunity for weakrefs.

_attachInterfaces()[source]

Links all the interfaces in the interface stack to the operator, reactor, and cs.

See also

createInterfaces()

creates all interfaces

addInterface()

adds a single interface to the stack

dumpRestartData(cycle, time_, factorList)[source]

Write some information about the cycle and shuffling to a auxiliary file for potential restarting.

Notes

This is old and can be deprecated now that the database contains the entire state. This was historically needed to have complete information regarding shuffling when figuring out ideal fuel management operations.

_loadRestartData()[source]

Read a restart.dat file which contains all the fuel management factorLists and cycle lengths.

Notes

This allows the ARMI to do the same shuffles that it did last time, assuming fuel management logic has not changed. Note, it would be better if the moves were just read from a table in the database.

loadState(cycle, timeNode, timeStepName='', fileName=None, updateMassFractions=None)[source]

Convenience method reroute to the database interface state reload method

See also

armi.bookeeping.db.loadOperator()

A method for loading an operator given a database. loadOperator does not require an operator prior to loading the state of the reactor. loadState does, and therefore armi.init must be called which requires access to the blueprints, settings, and geometry files. These files are stored implicitly on the database, so loadOperator creates the reactor first, and then attaches it to the operator. loadState should be used if you are in the middle of an ARMI calculation and need load a different time step. If you are loading from a fresh ARMI session, either method is sufficient if you have access to all the input files.

snapshotRequest(cycle, node)[source]

Process a snapshot request at this time.

This copies various physics input and output files to a special folder that follow-on analysis be executed upon later.

Notes

This was originally used to produce MC2/DIF3D inputs for external parties (who didn’t have ARMI) to review. Since then, the concept of snapshots has evolved with respect to the OperatorSnapshots.

static setStateToDefault(cs)[source]

Update the state of ARMI to fit the kind of run this operator manages

couplingIsActive()[source]

True if any kind of physics coupling is active.