1. Inputs
ARMI input files define the initial state of the reactor model and tell ARMI what kind of analysis should be performed on it.
Note
We have a Building input files for a fast reactor tutorial for a quick overview of the inputs.
There are several input files:
- Settings file
Contains simulation parameters (like full power, cycle length, and which physics modules to activate) and all kind of modeling approximation settings (e.g. convergence criteria)
- Blueprints file
Contains dimensions and composition of the components/blocks/assemblies in your reactor systems, from fuel pins to heat exchangers
- Fuel management file
Describes how fuel moves around during a simulation
Depending on the type of analysis, developers may create other input files for things like: control logic, ex-core models for transients and shielding, etc.
1.1. YAML Files
ARMI’s input files all use the YAML format. This is a well- known file format, chosen because it is human-readable and easy to hand-write. That being said, there are two details about the YAML format that are important to know:
- Ordering
YAML is not order specific; however, one of the techniques used to limit the size of the input includes using YAML anchors to resuse block and component definitions. YAML anchors (e.g.
&block_name
) must be defined before their corresponding alias (e.g.*block_name
) used.- Duplicate Keys
YAML allows for duplicate keys. However, in ARMI, duplicates might be erroneous. Unfortunately, because the international YAML specification allows for duplicates, none of the YAML-parsing libraries see it as an error. You will have to hand-verify your inputs are correct.
1.2. The Settings Input File
The settings input file defines a series of key/value pairs the define various information about the system you are modeling as well as which modules to run and various modeling/approximation settings. For example, it includes:
The case title
The reactor power
The number of cycles to run
Which physics solvers to activate
Whether or not to perform a critical control search
Whether or not to do tight coupling iterations
What neutronics approximations specific to the chosen physics solver to apply
Environment settings (paths to external codes)
How many CPUs to use on a computer cluster
This file is a YAML file that you can edit manually with a text editor or with the ARMI GUI.
Here is an excerpt from a settings file:
availabilityFactor: 1
beta: 0.003454
branchVerbosity: debug
buGroups:
- 100
burnSteps: 2
comment: Simple test input.
cycleLength: 2000.0
detailAssemLocationsBOL:
- 002-001
freshFeedType: igniter fuel
loadingFile: refSmallReactor.yaml
moduleVerbosity:
A full listing of settings available in the framework may be found in the Table of all global settings .
Many settings are provided by the ARMI Framework, and others are defined by various plugins.
1.2.1. The ARMI GUI
The ARMI GUI may be used to manipulate many common settings (though the GUI can’t change all of the settings). The GUI also enables the graphical manipulation of a reactor core map, and convenient automation of commands required to submit to a cluster. The GUI is a front-end to these files. You can choose to use the GUI or not, ARMI doesn’t know or care — it just reads these files and runs them.
Note that one settings input file is required for each ARMI case, though many ARMI cases can refer to the same Blueprints, Core Map, and Fuel Management inputs.
Tip
The ARMI GUI is not yet included in the open-source ARMI framework, but a simple grid editor GUI is, as described in Grids
1.2.1.1. The assembly clicker
The assembly clicker (aka the Grid Editor
) allows users to define the 2-D layout of the assemblies defined in the
The Blueprints Input File. This can be done in hexagon or cartesian. The results of this arrangement get written to
grids in blueprints. Click on the assembly palette on the right and click on the locations where you want to put the
assembly. By default, the input assumes a 1/3 core model, but you can create a full core model through the menu.
If you want one assembly type to fill all positions in a ring, right click it once it is placed and choose Make ring
like this hex
. Once you submit the job or save the settings file (File -> Save), you will be prompted for a new name
of the geometry file before the settings file is saved. The geometry setting in the main tab will also be updated.
1.2.1.2. The ARMI Environment Tab
The environment tab contains important settings about which version of ARMI you will run
and with which version of Python, etc. Most important is the ARMI location
setting. This
points to the codebase that will run. If you want to run the released version of ARMI,
ensure that it is set in this setting. If you want to run a developer version, then be sure
to update this setting.
Other settings on this tab may need to be updated depending on your computational environment. Talk to your system admins to determine which settings are best.
1.2.2. Some special settings
A few settings warrant additional discussion.
1.2.2.1. Detail assemblies
Many plugins perform more detailed analysis on certain regions of the reactor. Since the analyses often take longer, ARMI has a feature, called detail assemblies to help. Different plugins may treat detail assemblies differently, so it’s important to read the plugin documentation as well. For example, a depletion plugin may perform pin-level depletion and rotation analysis only on the detail assemblies. Or perhaps CFD thermal/hydraulics will be run on detail assemblies, while subchannel T/H is run on the others.
Detail assemblies are specified by the user in a variety of ways, through the GUI or the settings system.
Warning
The Detail Assemblies mechanism has begun to be too broad of a brush for serious multiphysics calculations with each plugin treating them differently. It is likely that this feature will be extended to be more flexible and less surprising in the future.
- Detail Assembly Locations BOL
The
detailAssemLocationsBOL
setting is a list of assembly location strings (e.g.004-003
for ring 4, position 3). Assemblies that are in these locations at the beginning-of-life will be activated as detail assemblies.- Detail assembly numbers
The
detailAssemNums
setting is a list ofassemNum
s that can be inferred from a previous case and specified, regardless of when the assemblies enter the core. This is useful for activating detailed treatment of assemblies that enter the core at a later cycle.- Detail all assemblies
The
detailAllAssems
setting makes all assemblies in the problem detail assemblies
1.2.2.2. Kinetics settings
In reactor physics analyses it is standard practice to represent reactivity
in either absolute units (i.e., dk/kk’ or pcm) or in dollars or cents. To
support this functionality, the framework supplies the beta
and
decayConstants
settings to apply the delayed neutron fraction and
precursor decay constants to the Core parameters during initialization.
These settings come with a few caveats:
The
beta
setting supports two different meanings depending on the type that is provided. If a single value is given, then this setting is interpreted as the effective delayed neutron fraction for the system. If a list of values is provided, then this setting is interpreted as the group-wise (precursor family) delayed neutron fractions (useful for reactor kinetics simulations).The
decayConstants
setting is used to define the precursor decay constants for each group. When set, it must be provided with a correspondingbeta
setting that has the same number of groups. For example, if six-group delayed neutron fractions are provided, the decay constants must also be provided in the same six-group structure.If
beta
is interpreted as the effective delayed neutron fraction for the system, then thedecayConstants
setting will not be utilized.If both the group-wise
beta
anddecayConstants
are provided and their number of groups are consistent, then the effective delayed neutron fraction for the system is calculated as the summation of the group-wise delayed neutron fractions.
1.2.2.3. Cycle history
For all cases, nCycles
and power
must be specified by the user.
In the case that only a single state is to be examined (i.e. no burnup), the user need only additionally specify nCycles = 1
.
In the case of burnup, the reactor cycle history may be specified using either the simple or detailed option. The simple cycle history consists of the following case settings:
power
nCycles
(default = 1)
burnSteps
(default = 4)
availabilityFactor(s)
(default = 1.0)
cycleLength(s)
(default = 365.2425)
In addition, one may optionally use the powerFractions
setting to change the reactor
power between each cycle.
With these settings, a user can define a history in which each cycle may vary
in power, length, and uptime.
The history is restricted, however, to each cycle having a constant power, to
each cycle having the same number of burnup nodes, and to those burnup nodes being
evenly spaced within each cycle.
An example simple cycle history might look like
power: 1000000
nCycles: 3
burnSteps: 2
cycleLengths: [100, R2]
powerFractions: [1.0, 0.5, 1.0]
availabilityFactors: [0.9, 0.3, 0.93]
Note the use of the special shorthand list notation, where repeated values in a list can be specified using an “R” followed by the number of times the value is to be repeated.
The above scheme would represent 3 cycles of operation:
100% power for 90 days, split into two segments of 45 days each, followed by 10 days shutdown (i.e. 90% capacity)
50% power for 30 days, split into two segments of 15 days each, followed by 70 days shutdown (i.e. 15% capacity)
100% power for 93 days, split into two segments of 46.5 days each, followed by 7 days shutdown (i.e. 93% capacity)
In each cycle, criticality calculations will be performed at 3 nodes evenly-spaced through the uptime portion of the cycle (i.e. availabilityFactor``*``powerFraction
), without option for changing node spacing or frequency.
This input format can be useful for quick scoping and certain types of real analyses, but clearly has its limitations.
To overcome these limitations, the detailed cycle history, consisting of the cycles
setting may be specified instead.
For each cycle, an entry to the cycles
list is made with the following optional fields:
name
power fractions
cumulative days
,step days
, orburn steps
+cycle length
availability factor
An example detailed cycle history employing all of these fields could look like
power: 1000000
nCycles: 4
cycles:
- name: A
step days: [1, 1, 98]
power fractions: [0.1, 0.2, 1]
availability factor: 0.1
- name: B
cumulative days: [2, 72, 78, 86]
power fractions: [0.2, 1.0, 0.95, 0.93]
- name: C
step days: [5, R5]
power fractions: [1, R5]
- cycle length: 100
burn steps: 2
availability factor: 0.9
Note that repeated values in a list may be again be entered using the shorthand notation for step days
, power fractions
, and availability factors
(though not cumulative days
because entries must be monotonically increasing).
Such a scheme would define the following cycles:
A 2 day power ramp followed by full power operations for 98 days, with three nodes clustered during the ramp and another at the end of the cycle, followed by 900 days of shutdown
A 2 day power ramp followed by a prolonged period at full power and then a slight power reduction for the last 14 days in the cycle
Constant full-power operation for 30 days split into six even increments
Constant full-power operation for 90 days, split into two equal-length 45 day segments, followed by 10 days of downtime
As can be seen, the detailed cycle history option provides much greated flexibility for simulating realistic operations, particularly power ramps or scenarios that call for unevenly spaced burnup nodes, such as xenon buildup in the early period of thermal reactor operations.
Note
Although the detailed cycle history option allows for powers to change within each cycle, it should be noted that the power over each step is still considered to be constant.
Note
The name
field of the detailed cycle history is not yet used for anything, but this information will still be accessible on the operator during runtime.
Note
Cycles without names will be given the name None
Warning
When a detailed cycle history is combined with tight coupling, a subclass of LatticePhysicsInterface.interactCoupled
should be used.
1.2.2.4. Restart cases
Oftentimes the user is interested in re-examining just a specific set of time nodes from an existing run. In these cases, it is sometimes not necessary to rerun an entire reactor history, and one may instead use one of the following options:
Snapshot, where the reactor state is loaded from a database and just a single time node is run.
Restart, where the cycle history is loaded from a database and the calculation continues through the remaining specified time history.
For either of these options, it is possible to alter the specific settings applied to the run by simply adjusting the case settings for the run. For instance, a run that originally had only neutronics may incorporate thermal hydraulics during a snapshot run by adding in the relevant TH settings.
Note
For either of these options, it is advisable to first create a new case settings file with a name different than the one from which you will be restarting off of, so as to not overwrite those results.
To run a snapshot, the following settings must be added to your case settings:
Set
runType
toSnapshots
Add a list of cycle/node pairs corresponding to the desired snapshots to
dumpSnapshot
formatted as'CCCNNN'
Set
reloadDBName
to the existing database file that you would like to load the reactor state from
An example of a snapshot run input:
runType: Snapshots
reloadDBName: my-old-results.h5
dumpSnapshot: ['000000', '001002'] # would produce 2 snapshots, at BOL and at node 2 of cycle 1
To run a restart, the following settings must be added to your case settings:
Set
runType
toStandard
Set
loadStyle
tofromDB
Set
startCycle
andstartNode
to the cycle/node that you would like to continue the calculation from (inclusive).startNode
may use negative indexing.Set
reloadDBName
to the existing database file from which you would like to load the reactor history up to the restart pointIf you would like to change the specified reactor history (see Restart cases), keep the history up to the restarting cycle/node unchanged, and just alter the history after that point. This means that the cycle history specified in your restart run should include all cycles/nodes up to the end of the simulation. For complicated restarts, it may be necessary to use the detailed
cycles
setting, even if the original case only used the simple history option.
A few examples of restart cases:
- Restarting a calculation at a specific cycle/node and continuing for the remainder of the originally-specified cycle history:
# old settings nCycles: 2 burnSteps: 2 cycleLengths: [100, 100] runType: Standard loadStyle: fromInput loadingFile: my-blueprints.yaml# restart settings nCycles: 2 burnSteps: 2 cycleLengths: [100, 100] runType: Standard loadStyle: fromDB startCycle: 1 startNode: 0 reloadDBName: my-original-results.h5
- Add an additional cycle to the end of a case:
# old settings nCycles: 1 burnSteps: 2 cycleLengths: [100] runType: Standard loadStyle: fromInput loadingFile: my-blueprints.yaml# restart settings nCycles: 2 burnSteps: 2 cycleLengths: [100, 100] runType: Standard loadStyle: fromDB startCycle: 0 startNode: -1 reloadDBName: my-original-results.h5
- Restart but cut the reactor history short:
# old settings nCycles: 3 burnSteps: 2 cycleLengths: [100, 100, 100] runType: Standard loadStyle: fromInput loadingFile: my-blueprints.yaml# restart settings nCycles: 2 burnSteps: 2 cycleLengths: [100, 100] runType: Standard loadStyle: fromDB startCycle: 1 startNode: 0 reloadDBName: my-original-results.h5
- Restart with a different number of steps in the third cycle using the detailed
cycles
setting: # old settings nCycles: 3 burnSteps: 2 cycleLengths: [100, 100, 100] runType: Standard loadStyle: fromInput loadingFile: my-blueprints.yaml# restart settings nCycles: 3 cycles: - cycle length: 100 burn steps: 2 - cycle length: 100 burn steps: 2 - cycle length: 100 burn steps: 4 runType: Standard loadStyle: fromDB startCycle: 2 startNode: 0 reloadDBName: my-original-results.h5
Note
The skipCycles
setting is related to skipping the lattice physics calculation specifically, it is not required to do a restart run.
Note
The X-SHUFFLES.txt file is required to do explicit repeated fuel management.
Note
The restart.dat file is required to repeat the exact fuel management methods during a branch search. These can potentially modify the reactor state in ways that cannot be captures with the SHUFFLES.txt file.
Note
The ISO binary cross section libraries are required to run cases that skip the lattice physics calculation (e.g. MC^2)
Note
The multigroup flux is not yet stored on the output databases. If you need to do a restart with these values (e.g. for depletion), then you need to reload from neutronics outputs.
Note
Restarting a calculation with an different version of ARMI than what was used to produce the restarting database may result in undefined behavior.
1.3. The Blueprints Input File
The blueprints input defines the dimensions of structures in the reactor, as well as their material makeup. In a typical case, pin dimensions, isotopic composition, control definitions, coolant type, etc. are defined here. The specifics of each assembly type are then overlayed, possibly including enrichment distributions and other material modifications.
Note
See the blueprints
module for implementation and more detail.
This input file is formatted using YAML, which allows text-based change tracking for design control. ARMI does not have a blueprints-editing GUI yet, but may in the future.
Note
You can point many ARMI runs to the same Blueprints input file using full paths in loadingFile
setting.
ARMI adds an !include
YAML tag, which can be used to include the
contents of an external YAML file in any part of a blueprints file. The can be useful
for sharing core or assembly pin layouts amongst multiple cases.
For example:
grids:
core: !include path/to/core_grid.yaml
would have the effect of copy-pasting the contents of path/to/core_grid.yaml
into
the main blueprints file. The rules that ARMI uses to handle things like indentation of
the included text are usually rather intuitive, but sometimes it can be useful to
witness the behavior first-hand. The expand-bp
command can be used to do a dry run
for testing inputs with !includes.
ARMI models are built hierarchically, first by defining components, and then by larger and larger collections of the levels of the reactor.
1.3.1. Blueprint sections
The blueprints input file has several sections that corresponds to different levels of the reactor hierarchy. You will generally build inputs “bottoms up”, first by defining elementary pieces (like pins) and then collecting them into the core and reactor.
The ARMI data model is represented schematically below, and the blueprints are defined accordingly:
- blocks:
- assemblies:
Defines vertical stacks of blocks used to define the axial profile of an
Assembly
.- systems:
Reactor-level structures like the core, the spent fuel pool, pumps, the head, etc.
- grids:
Lattice definitions for the core map or pin maps
- nuclide flags:
Special setting: Specifies nuclide modeling options, whether a nuclide is being modeled for cross sections and/or depletion. For instance, it allows you to ignore nuclides above Curium for depletion speed. This also allows you to expand elements to a subset of nuclides. For example, you can choose to expand Oxygen to just Oxygen-16 and neglect Oxygen-17 and 18.
- custom isotopics:
Special setting: defines user-specified isotopic compositions.
The core map input files can be graphically manipulated with the
Grid editor
.
1.3.2. Blocks and Components
Blocks and components are defined together in the blueprints input.
We will start with a component, and then define the whole blocks:
input. The structure will be something like:
blocks:
block name 1:
component name 1:
...
component name 2:
block name 2:
component name 1:
...
component name 2:
...
Note
You can also define components at the top level of the blueprints file under
the components:
top level section, but bringing anything defined there into
the reactor model must currently be done programatically. We are currently
developing additional input capabilities to use these more flexibly.
Associated with this is a component groups:
section which can collect
different free components with different volume fractions. This also
is not fully implemented yet.
1.3.2.1. Defining a Component
The Components section defines the pin (if modeling a pin-type reactor) and assembly in-plane
dimensions (axial dimensions are defined in the Assemblies input) and the material makeups of
each Component
. Blocks
are
defined here as collections of geometric components that have specific temperatures, dimensions,
material properties, and isotopic compositions.
An component may be defined as:
fuel:
shape: Circle
material: UZr
Tinput: 20.0
Thot: 450.0
mult: 169
id: 0.0
od: 0.757
Here we have provided the following information:
- Component name
The component name (
fuel
) is specified at the top. Some physics kernels interpret names specially, so pay attention to any naming conventions. As a general rule, you can expect that people will be doing regex on your name, so you should not use any of these characters in your component names:. ^ $ * + ? { } [ ] \ | ( ) :
.- shape
The shape will be extruded to the length specified in the
assemblies
input section below. ARMI contains a variety of built-in simple shapes, and plugins can define their own design-specific/proprietary shapes.- material
The material links the component to a certain set of thermo-physical properties (e.g. temperature-dependent thermal expansion coefficients, density, thermal conductivity, etc., which are used in the various physics kernels. Natural isotopic composition is determined from this material specification as well (unless custom isotopics are supplied). The entry here should either be a class name of a valid material (
UZr
) or amodule:className
pair for specifying specific material (e.g.armi.materials.uZr:UZr
). Materials are handled through thematerial library
.- Tinput
The temperature (in C) that corresponds to the input dimensions given here. This facilitates automatic thermal expansion.
- Thot
The temperature (in C) that the component dimensions will be thermal expanded to (using material properties based on the
material
input). To disable automatic thermal expansion, set Tinput and Thot both to the same value- mult
Multiplicity specifies how many duplicates of this component exist in this block. If you want 169 pins per assembly, this would be 169. This does not explicitly describe the location of the pins. Note that many fast-neutron systems only need volume fractions, not precise spatial locations, at least for pre-conceptual/simple studies.
- id
Inner diameter (in cm). Each shape has different required input dimension keys. For annulus, set id to non-zero.
- od
Outer diameter (in cm).
1.3.2.2. Component Types
Each component has a variety of dimensions to define the shape and composition. All dimensions are in cm. The following is a list of included component shapes and their dimension inputs. Again, additional/custom components with arbitrary dimensions may be provided by the user via plugins.
Component Name |
Dimensions |
---|---|
Component |
|
ShapedComponent |
|
Circle |
od, id, mult, modArea |
Hexagon |
op, ip, mult, modArea |
Rectangle |
lengthOuter, lengthInner, widthOuter, widthInner, mult, modArea |
SolidRectangle |
lengthOuter, widthOuter, mult, modArea |
Square |
widthOuter, widthInner, mult, modArea |
Triangle |
base, height, mult, modArea |
HoledHexagon |
op, holeOD, nHoles, mult, modArea |
HexHoledCircle |
od, holeOP, mult, modArea |
HoledRectangle |
holeOD, lengthOuter, widthOuter, mult, modArea |
HoledSquare |
holeOD, widthOuter, mult, modArea |
Helix |
od, axialPitch, helixDiameter, mult, id, modArea |
Sphere |
od, id, mult, modArea |
Cube |
lengthOuter, lengthInner, widthOuter, widthInner, heightOuter, heightInner, mult, modArea |
RadialSegment |
inner_radius, outer_radius, height, mult, inner_theta, outer_theta |
DifferentialRadialSegment |
inner_radius, radius_differential, inner_axial, height, inner_theta, azimuthal_differential, mult |
NullComponent |
|
UnshapedComponent |
modArea |
UnshapedVolumetricComponent |
op, volume |
ZeroMassComponent |
op, volume |
PositiveOrNegativeVolumeComponent |
op, volume |
DerivedShape |
modArea |
When a DerivedShape
is specified as the final component in a block, its area is inferred from
the difference between the area of the block and the sum of the areas
comprised by the other components in the block. This is useful for complex shapes like coolant surrounding
a lattice of pins.
1.3.2.3. Component Links
Dimensions of a component may depend on the dimensions of a previously-defined component in the same
block. For instance, the sodium bond between fuel and cladding. The format is simply
<componentName>.<dimensionName>
. The dimension names are available in the table above.
blocks:
fuel: # block name
fuel: # component name
shape: Circle
material: UZr
Tinput: 25.0
Thot: 600.0
id: 0.0
isotopics: LABEL1
mult: 169.0
od: 0.757
bond:
shape: Circle
material: Sodium
Tinput: 450.0
Thot: 450.0
mult: fuel.mult
id: fuel.od # bond is connected to the ouside of fuel
od: clad.id # and the inside of the clad
clad:
shape: Circle
material: HT9
Tinput: 25.0
Thot: 450.0
id: 0.905
mult: fuel.mult
od: 1.045
Linked component dimensions (such as bond.id
being linked to fuel.od
) remain linked
as dimensions change. For example when the above defined fuel is expanded from cold temperature of
25 to the hot temperature of 600 the bond.id
will still be whatever the fuel.od
is. This can
result in the displacement of material. For example, in the above case, if the fuel expansion
removes more cross sectional area than the clad expansion creates, the amount of thermal bond will be
reduced. This is physical since, in reality, the fluid would be displaced as dimensions
change.
1.3.2.4. Pin lattices
Pin lattices may be explicitly defined in the block/component input in conjunction with the grids
input
section. A block may assigned a grid name, and then each component may be assigned one or more
grid specifiers.
For example, the following input section specifies that fuel pins will occupy all grid positions
marked with a 1
and cladding components will occupy all grid positions marked with either
a 1
or a 2
. This situation may be desirable when some burnable poison pins use the same
cladding as the fuel pins.
blocks:
fuel: &block_fuel
grid name: fuelgrid
fuel:
flags: fuel test
shape: Circle
material: UZr
Tinput: 25.0
Thot: 600.0
id: 0.0
mult: 169.0
od: 0.86602
latticeIDs: [1]
clad:
shape: Circle
material: HT9
Tinput: 25.0
Thot: 470.0
id: 1.0
mult: fuel.mult
od: 1.09
latticeIDs: [1,2]
Note
A grid
with the name fuelgrid
must be defined as well in the grid input section.
1.3.3. Flags and naming
All objects in the ARMI Reactor Model possess a set of
armi.reactor.flags.Flags
, which can be used to affect the way that the
various physics kernels treat each object. Most flags are named after common reactor
components, like FUEL
, or CLAD
, and are used to declare what something is in the
reactor model. Various physics or other framework operations can then be
parameterized to target specific types of things. For instance, the fuel handling code
can infer that blocks with the GRID_PLATE
flag should be considered stationary and
not move them with the rest of the block stack in an assembly.
Historically, flags have also been used to describe directly what should be done with
an object in the reactor model. For instance, an object with the DEPLETABLE
flag set
will participate in isotopic depletion analysis, whereas objects without the
DEPLETION
flag set will not. This has led to a lot of confusion, as the meaning of
various flags is buried deep within the code, and can conflict from place to place. We
are trying to align around a what something is interpretation, and bind those to
specific behaviors with settings. For more details, see armi.reactor.flags
.
The set of specific flags that should be set on an object can be specified in one of two
ways for each object defined in the blueprints. The most precise way is to use include a
flags:
entry for the object blueprint in question. In the example above, the
fuel
component sets the FUEL
and TEST
flags. When specifying flags in this
way, the value specified must be completely and unambiguously convertible into valid
Flags. If it cannot, it will lead to an error when constructing the object.
If flags:
is empty, or not specified, then the name of the object blueprint will be
used to infer as many flags as possible. In the above example, the clad
component
will get the CLAD
flag from its name.
Note
Additional flags may be specified from plugins, but this should be done with care;
see the armi.reactor.flags
module and
armi.plugins.ArmiPlugin.defineFlags()
plugin hook for more details.
1.3.4. Assemblies
Once components and blocks are defined, Assemblies can be created as extruded stacks of blocks from bottom to top. The assemblies use YAML anchors to refer to the blocks defined in the previous section.
Note
We aren’t happy with the use of anchors to refer to blocks, and plan to change it (back) to just using the block names directly. However, the use of anchors for input to be applied to multiple assemblies (e.g. heights) is quite nice.
A complete definition of an inner-core assembly may be seen below:
assemblies:
heights: &standard_heights [10.05, 20.10, 30.15, 20.10, 20.10, 30.15]
axial mesh points: &standard_axial_mesh_points [1, 2, 3, 4, 5, 6]
inner core:
specifier: IC
blocks: &inner_core_blocks [*block_shield, *block_fuel, *block_fuel, *block_fuel, *block_fuel, *block_plenum]
height: *standard_heights
axial mesh points: *standard_axial_mesh_points
hotChannelFactors: TWRPclad
material modifications:
U235_wt_frac: ['', '', 0.001, 0.002, 0.03, '']
ZR_wt_frac: ['', '', 0.1, 0.1, 0.1, 0.1]
nozzleType: Inner
xs types: [A, B, C, D, E, F]
Note
While component dimensions are entered as cold dimensions, axial heights may be entered as
either cold or hot dimensions. In older versions of ARMI, it was required to enter heights
in the hot dimension (this behavior is preserved by setting inputHeightsConsideredHot: True).
However, with the
axial expansion changer
,
heights may be entered at cold temperatures (inputHeightsConsideredHot: False). Each Assembly will then
be expanded to its hot dimensions upon construction.
For many cases, a shared height and axial mesh point definition is sufficient. These can be included globally as shown above and linked with anchors, or specified explicitly.
- specifier
The Geometry Assembly Specifier, which is a two-letter ID, such as “IC” (for inner core), “SH” (for shield), etc. correspond with labels in the geometry input file that is created by the GUI hex dragger.
- xs types
The cross-section type is usually a single capital letter that identifies which cross section (XS) set will be applied to the block. Each cross section set must be defined for at least one block with fissile fuel. When the lattice physics code executes in ARMI, it determines the representative blocks from each cross section type and burnup group and runs it to create the cross section set for all blocks of the same type and in the same burnup group. Generally, it is best to set blocks that have much different compositions to have separate cross section types. The tradeoff is that the more XS types you define, the more CPU time the case will take to run.
Representing xsType by a single letter (A-Z) or number (0-9) limits users to 36 groups. So ARMI will allow 2-letter xsType designations if and only if the
buGroups
setting has length 1 (i.e. no burnup groups are defined). This is useful for high-fidelity XS modeling.- axial mesh points
Blocks will be broken up into this many uniform mesh points in the deterministic neutronics solvers (e.g. DIF3D). This allows you to define large blocks that have multiple flux points within them. You have to keep the neutronic mesh somewhat uniform in order to maintain numerical stability of the solvers. It is important to note that the axial mesh must be uniform throughout the core for many physics kernels, so be sure all block interfaces are consistent among all assemblies in the core. Blocks deplete and get most state variables on the block mesh defined by the height specification. Provisions for multiple meshes for different physics are being planned.
- hotChannelFactors
A label to define which set of hot channel factors (HCFs) get applied to this block in the thermal/hydraulic calculations. There are various valid sets included with ARMI.
- nozzleType
This is a string that identifies what type of inlet nozzle an assembly has. This parameter could be used in an implementation of a thermal-hydraulics solver with flow orificing to apply different pressure loss coefficients and/or flow rates to different types of assemblies.
- material modifications
These are a variety of modifications that are made to the materials in blocks in these locations. It may include the fuel enrichment (mass frac.), poison enrichment (mass frac.), zirconium mass frac, and any additional options required to fully define the material loaded in the component. The material definitions in the material library define valid modifications for them.
Material Name
Available Modifications
B4C
B10_wt_frac, theoretical_density, TD_frac
FuelMaterial
class1_custom_isotopics, class2_custom_isotopics, class1_wt_frac, customIsotopics
Lithium
LI_wt_frac, LI6_wt_frac
Sulfur
sulfur_density_frac, TD_frac
ThU
U233_wt_frac, class1_custom_isotopics, class2_custom_isotopics, class1_wt_frac, customIsotopics
Thorium
class1_custom_isotopics, class2_custom_isotopics, class1_wt_frac, customIsotopics, class1_custom_isotopics, class2_custom_isotopics, class1_wt_frac, customIsotopics
ThoriumOxide
TD_frac, class1_custom_isotopics, class1_wt_frac, class2_custom_isotopics, customIsotopics
UThZr
U235_wt_frac, ZR_wt_frac, class1_custom_isotopics, class2_custom_isotopics, class1_wt_frac, customIsotopics
UZr
U235_wt_frac, ZR_wt_frac, class1_custom_isotopics, class2_custom_isotopics, class1_wt_frac, customIsotopics
Uranium
U235_wt_frac, TD_frac, class1_custom_isotopics, class2_custom_isotopics, class1_wt_frac, customIsotopics
UraniumOxide
TD_frac, U235_wt_frac, class1_custom_isotopics, class1_wt_frac, class2_custom_isotopics, customIsotopics
The class 1/class 2 modifications in fuel materials are used to identify mixtures of custom isotopics labels for input scenarios where a varying blend of a high-reactivity feed with a low-reactivity feed. This is often useful for closed fuel cycles. For example, you can define any fuel material as being made of LWR-derived TRU plus depleted uranium at various weight fractions. Note that this input style only adjusts the heavy metal.
To enable the application of different values for the same material modification type on different components within a block, the user may specify material modifications by component. This is useful, for instance, when two pins within an assembly made of the same base material have different fuel enrichments. This is done using the
by component
attribute to the material modifications as in:blocks: fuel: &block_fuel fuel1: &component_fuel_fuel1 shape: Hexagon material: UZr Tinput: 600.0 Thot: 600.0 ip: 0.0 mult: 1 op: 10.0 fuel2: &component_fuel_fuel2 shape: Hexagon material: UZr Tinput: 600.0 Thot: 600.0 ip: 0.0 mult: 1 op: 10.0 assemblies: fuel a: &assembly_a specifier: IC blocks: [*block_fuel] height: [1.0] axial mesh points: [1] xs types: [A] material modifications: by component: fuel1: U235_wt_frac: [0.20] fuel2: Zr_wt_frac: [0.02] U235_wt_frac: [0.30]
Material modifications specified on the
material modifications
level are referred to as “block default” values and apply to all components on the block not associated with a by-component value. This example would apply an enrichment of 20% to thefuel1
component and an enrichment of 30% to all other components in the block that accept theU235_wt_frac
material modification.All by-component material modifications override any block default material modifications of the same type. In addition, any by-component entries omitted for a given axial block will revert to the block default (or material class default, if no block default value is provided and a material class default exists) value:
blocks: fuel: &block_fuel fuel1: &component_fuel_fuel1 shape: Hexagon material: UZr Tinput: 600.0 Thot: 600.0 ip: 0.0 mult: 1 op: 10.0 fuel2: &component_fuel_fuel2 shape: Hexagon material: UZr Tinput: 600.0 Thot: 600.0 ip: 0.0 mult: 1 op: 10.0 assemblies: fuel a: &assembly_a specifier: IC blocks: [*block_fuel, *block_fuel] height: [0.5, 0.5] axial mesh points: [1, 1] xs types: [A, A] material modifications: by component: fuel1: U235_wt_frac: [0.20, ''] # <-- the U235_wt_frac for the second block will go to the block defaul value fuel2: # the U235_wt_frac for fuel2 component in both axial blocks will go to the block default values Zr_wt_frac: [0.02, ''] # <-- the Zr_wt_frac for the second block will go to the material class default because there is no block default value U235_wt_frac: [0.30, 0.30]
The first block listed is defined at the bottom of the core. This is typically a grid plate or some other structure.
1.3.5. Systems
Once assemblies are defined they can be grouped together into the Core, the spent fuel pool (SFP), etc.
A complete reactor structure with a core and a SFP may be seen below:
systems:
core:
grid name: core
origin:
x: 0.0
y: 10.1
z: 1.1
Spent Fuel Pool:
type: sfp
grid name: sfp
origin:
x: 1000.0
y: 12.1
z: 1.1
The origin
defines the point of origin in global space
in units of cm. This allows you to define the relative position of the various structures.
The grid name
inputs are string mappings to the grid definitions described below.
1.3.5.1. Plugin Behavior
The armi.plugins.ArmiPlugin.defineSystemBuilders()
method can be provided by plugins to
control how ARMI converts the systems
section into Composite
s to be modeled. By default,
the type
field is used to determine what object is created. The default
armi.reactor.ReactorPlugin
provides the following mapping:
|
Builds |
---|---|
|
|
|
|
|
Plugins are able to provide a superset (e.g., core
, excore
, and sfp
) and new mappings of
values to builders.
1.3.6. Grids
Grids are described inside a blueprint file using lattice map
or grid contents
fields to
define arrangements in Hex, Cartesian, or R-Z-Theta. The optional lattice pitch
entry allows
you to specify spacing between objects that is different from tight packing. This input is required
in mixed geometry cases, for example if Hexagonal assemblies are to be loaded into a Cartesian
arrangement. The contents of a grid may defined using one of the following:
lattice map:
A ASCII map representing the grid contents
grid contents:
a direct YAML representation of the contents
Example grid definitions are shown below:
grids:
control:
geom: hex
symmetry: full
lattice map: |
- - - - - - - - - 1 1 1 1 1 1 1 1 1 4
- - - - - - - - 1 1 1 1 1 1 1 1 1 1 1
- - - - - - - 1 8 1 1 1 1 1 1 1 1 1 1
- - - - - - 1 1 1 1 1 1 1 1 1 1 1 1 1
- - - - - 1 1 1 1 1 1 1 1 1 1 1 1 1 1
- - - - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
- - - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
- - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
- 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
7 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 3 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1
1 6 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
sfp:
symmetry: full
geom: cartesian
lattice pitch:
x: 50.0
y: 50.0
grid contents:
[0,0]: MC
[1,0]: MC
[0,1]: MC
[1,1]: MC
Tip
We have gone through some effort to allow both pin and core grid definitions to share this input and it may improve in the future.
You may set up some kinds of grids (e.g. 1/3 and full core hex or Cartesian core
loadings) using our interactive graphical grid editor described more in
armi.utils.gridEditor
.
1.3.7. Custom Isotopics
In some cases (such as benchmarking a previous reactor), the default mass fractions from the
material library are not what you want to model. In these cases, you may override the isotopic
composition provided by the material library in this section. There are three ways to specify
the isotopics: mass fractions
(sum to 1.0), number densities
(in atoms/barn-cm), or
number fractions
(sum to 1.0). For example:
custom isotopics:
LABEL1:
input format: mass fractions
density: 7.79213903298633
C: 0.000664847887388523
CR: 0.182466356404319
CU: 0.00323253628006144
FE: 0.705266053783901
MN: 0.0171714161260001
MO: 0.00233843050046998
NI: 0.0831976890804466
SI: 0.00566266993741259
See the List of Nuclides
for all valid entries. Note that
ARMI will expand elemental nuclides to their natural isotopics in most cases (to correspond with the
nuclear data library).
The (mass) density
input is invalid when specifying number densities
; the code will present an error message.
Material density may be specified in custom isotopics either explicitly in a mass fractions
input
format (shown above) or implicitly with number densities
. This is fairly straightforward for the
Custom
material, as it has no baseline density. Density may also be specified for components using
materials which have entries in the materials library. Users should be aware of the following interactions
when specifying a custom density for components using a library material:
1. The library material density will not be changed. Only the component(s) with the custom isotopics entry will have the density modification.
2. Density specified by custom isotopics will override all other density modifications in the component construction phase (e.g.
TD_frac
entries).3. Only the component density is changed, not other material properties are altered to account for the change in composition/density.
4. Density can only be specified using custom isotopics for non-
Custom
materials that have some initial density. Don’t try to makeVoid
have mass!
Densities specified using Custom Isotopics
are applied in component construction, and should be specified
at the input temperature for the component. Note that when overriding the density of a library material, all
other properties of that material (e.g. expansion coefficients) will continue to be used as if the component
consisted of the library material. In other words, ARMI will still think the component is made out of the
original material!
1.3.8. Advanced topics
1.3.8.1. Overlapping shapes
Solids of different compositions in contact with each other present complications during thermal
expansion. The ARMI Framework does not perform calculations to see exactly how such
scenarios will behave mechanically; it instead focuses on conserving mass. To do this, users should
input a zero-dimension component linking the 2 solid components made of the special Void
material.
This gap will allow the 2 components to thermally expand
independently while keeping track of the overlapping area.
It is important to keep track of the areas
when a DerivedShape is included in a block design because ARMI calculates the
derived area by taking the full area of the block and subtracting the total area of
the non-DerivedShapes. If area between thermally-expanding solids was not accounted for, this
would non-physically add or subtract coolant into these gaps. To model overlapping components
heterogeneously, it is suggested to use a block converter
.
Additionally, it should be noted that assigning mult: fuel.mult
will be ever-so-slightly slower
than just defining the actual value. This is because ARMI needs to find the sibling
component and get the siblings mult
. If you are concerned about performance at that level and don’t expect
mult
to change much in your case, you can replace the constant link (i.e. it does not change over time)
with a YAML anchor and alias.
1.3.8.2. Component area modifications
In some scenarios, it is desired to have one component’s area be subtracted or added to another. For
example, the area of the skids in a skid duct design needs to be subtracted from the interstitial
coolant. The mechanism to handle this involves adding a parameter to the component to be
modified after all the required ones in the form of <componentName>.add
or
<componentName>.sub
. The component to be added or subtracted must be defined before the
component that is being modified. This allows fairly complicated configurations to be modeled
without explicitly defining new components.
blocks:
rect with 100 holes:
holes:
shape: Cicle
material: Sodium
Tinput: 600
Thot: 600
mult: 100
od: 0.05
square of steel:
shape: Square
material: Iron
Tinput: 25.0
Thot: 600.0
widthOuter: 3.0
modArea: holes.sub # "holes" is the name of the other component
1.3.8.3. Putting it all together to make a Block
Here is a complete fuel block definition:
blocks:
fuel: &block_fuel
bond:
shape: Circle
material: Sodium
Tinput: 450.0
Thot: 450.0
id: fuel.od
mult: fuel.mult
od: cladding.id
clad:
shape: Circle
material: HT9
Tinput: 25.0
Thot: 450.0
id: 0.905
mult: fuel.mult
od: 1.045
coolant:
shape: DerivedShape
material: Sodium
Tinput: 450.0
Thot: 450.0
duct:
shape: Hexagon
material: HT9
Tinput: 25.0
Thot: 450.0
ip: 15.2
mult: 1.0
op: 16.2
fuel:
shape: Circle
material: UZr
Tinput: 25.0
Thot: 600.0
id: 0.0
isotopics: LABEL1
mult: 169.0
od: 0.757
intercoolant:
shape: Hexagon
material: Sodium
Tinput: 450.0
Thot: 450.0
ip: duct.op
mult: 1.0
op: 16.79
wire:
shape: Helix
material: HT9
Tinput: 25.0
Thot: 450.0
axialPitch: 30.0
helixDiameter: 1.145
id: 0.0
mult: fuel.mult
od: 0.1
1.3.8.4. Making blocks with unshaped components
Sometimes you will want to make a homogenous block, which is a mixture of multiple materials, and will not want to define an exact shape for each of the components in the block. In this case unshaped components can be used, but ARMI still requires there to be at least one component with shape to define the pitch of the block.
In the example below, the block is a rectangular pitch so one of the components is defined as a rectangle to indicate this. Its outer dimensions determine the pitch of the block. The inner dimensions can be whatever is necessary to preserve the area fraction. Note that rectangular blocks have pitch defined by two numbers, since they may not be a square. In this case the rectangle component is half the area fraction and the other two components are one quarter:
blocks:
fuel:
clad:
shape: Rectangle
material: HT9
Tinput: 25.0
Thot: 25.0
lengthOuter: 3.0
lengthInner: 2.4
widthOuter: 2.0
widthInner: 1.25
mult:1.0
fuel:
shape: UnshapedComponent
material: UZr
Tinput: 25.0
Thot: 25.0
area = 1.5
coolant:
shape: UnshapedComponent
material: Sodium
Tinput: 25.0
Thot: 25.0
area = 1.5
Warning
When using this method avoid thermal expansion by setting TInput=THot, or your pitch component dimensions might change, thus changing your pitch.
Alternatively, a void (empty) component with zero area can be added for defining the pitch, and then all three components can be defined as unshaped. The downside, is there are now four components, but only three that have actual area and composition:
blocks:
fuel:
clad:
shape: UnshapedComponent
material: HT9
Tinput: 25.0
Thot: 25.0
area: 3.0
fuel:
shape: UnshapedComponent
material: UZr
Tinput: 25.0
Thot: 25.0
area = 1.5
coolant:
shape: UnshapedComponent
material: Sodium
Tinput: 25.0
Thot: 25.0
area = 1.5
PitchDefiningComponent:
shape: Rectangle
material: Void
lengthOuter: 3.0
lengthInner: 3.0
widthOuter: 2.0
widthInner: 2.0
mult:1.0
This can similarly be done for hex geometry and and a hexagon with Outer Pitch (op
).
Warning
The rest of the input described below are scheduled to be moved into the settings input file, since their nature is that of a setting.
1.3.9. Nuclide Flags
The nuclide flags
setting allows the user to choose which nuclides they
would like to consider in the problem, and whether or not each nuclide should
transmute and decay. For example, sometimes you may not want to deplete trace
elements in structural materials, but in other analysis you might. If the
nuclide should deplete, it must have burn: true
. If it is to be included
in the problem at all, it must be have xs: true
All nuclides that will be
produced via transmutation/decay must also have burn: true
, so if you add
Thorium, make sure to add all other actinides in its chain. You can use the
expandTo:
section to list a subset of natural nuclides to expand
into. If you leave this section out, a default set of nuclide flags will be
applied to your problem. Remember this
section when you start changing which nuclides are modeled and which ones
deplete.:
# this is a YAML comment
nuclide flags:
AL: {burn: false, xs: true}
AM241: {burn: true, xs: true}
C: &carbon_flags {burn: false, xs: true} # an anchor to "carbon_flags"
CA: *carbon_flags
CL: *carbon_flags
CO: *carbon_flags # the alias back to "carbon_flags"
CR: *carbon_flags
CU: *carbon_flags
FE: *carbon_flags
H: {burn: false, xs: true}
MN: {burn: false, xs: true}
MO: {burn: false, xs: true}
N: {burn: false, xs: true}
NA: {burn: false, xs: true}
NI: {burn: false, xs: true}
O: {burn: false, xs: true, expandTo: ["O16", "O17"]}
P: {burn: false, xs: true}
PU238: {burn: true, xs: true}
PU239: {burn: true, xs: true}
PU240: {burn: true, xs: true}
PU241: {burn: true, xs: true}
PU242: {burn: true, xs: true}
S: {burn: false, xs: true}
SI: {burn: false, xs: true}
U234: {burn: false, xs: true}
U235: {burn: true, xs: true}
U236: {burn: true, xs: true}
U238: {burn: true, xs: true}
The code will crash if materials used in Blocks and Components contain nuclides not defined in
nuclide flags
. A failure can also occur if the burn chain is missing a nuclide.
Tip
We plan to upgrade the default behavior of this to inherit from all defined materials in a problem to reduce the user-input burden.
1.4. Fuel Management Input
Fuel management in ARMI is specified through custom Python scripts that often reside in the working directory of a run (but can be anywhere if you use full paths). During a normal run, ARMI checks for two fuel management settings:
shuffleLogic
The path to the Python source file that contains the user’s custom fuel management logic
fuelHandlerName
The name of a FuelHandler class that ARMI will look for in the Fuel Management Input file pointed to by the
shuffleLogic
path. Since it’s input, it’s the user’s responsibility to design and place that object in that file.
Note
We consider the limited syntax needed to express fuel management in Python code itself to be sufficiently expressive and simple for non-programmers to actually use. Indeed, this has been our experience.
The ARMI Operator will call its fuel handler’s outage
method before each cycle (and, if requested, during branch
search calculations). The outage()
method
will perform bookkeeping operations, and eventually
call the user-defined chooseSwaps
method (located in Fuel Management Input). chooseSwaps
will
generally contain calls to findAssembly()
,
swapAssemblies()
,
swapCascade()
, and
dischargeSwap()
, which are the primary
fuel management operations and can be found in the fuel management module.
Also found in the user-defined Fuel Management Input module is a getFactors
method, which is used to control which
shuffling routines get called and at which time.
Note
See the fuelHandlers module
for more details.
1.4.1. Fuel Management Operations
In the ARMI, the assemblies can be moved as units around the reactor with swapAssemblies,
dischargeSwap, and swapCascade of a FuelHandler
interface.
1.4.1.1. swapAssemblies
swapAssemblies is the simplest fuel management operation. Given two assembly objects, this method will switch their locations.
self.swapAssemblies(a1,a2)
1.4.1.2. dischargeSwap
A discharge swap is a simple operation that puts a new assembly into the reactor while discharging an outgoing one.
self.dischargeSwap(newIncoming,oldOutgoing)
This operation keeps track of the outgoing assembly in a SpentFuelPool object that the Reactor object has access to so you can see how much of what you discharged.
1.4.1.3. swapCascade
SwapCascade is a more powerful swapping function that can swap a list of assemblies in a “daisy-chain” type of operation. These are useful for doing the main overtone shuffling operations such as convergent shuffling and/or convergent-divergent shuffling. If we load up the list of assemblies, the first one will be put in the last one’s position, and all others will shift accordingly.
As an example, consider assemblies 1 through 5 in core positions A through E.:
self.swapCascade([a1,a2,a3,a4,a5])
This table shows the positions of the assemblies before and after the swap cascade.
Assembly |
Position Before Swap Cascade |
Position After Swap Cascade |
---|---|---|
1 |
A |
E |
2 |
B |
A |
3 |
C |
B |
4 |
D |
C |
5 |
E |
D |
Arbitrarily complex cascades can thusly be assembled by choosing the order of the assemblies passed into swapCascade.
1.4.2. Choosing Assemblies to Move
The methods described in the previous section require known assemblies to shuffle. Choosing these assemblies is
the essence of fuel shuffling design. The single method used for these purposes is the FuelHandler’s findAssembly
method. This method is very general purpose, and ranks in the top 3 most important
methods of the ARMI altogether.
To use it, just say:
a = self.findAssembly(param='maxPercentBu',compareTo=20)
This will return the assembly in the reactor that has a maximum burnup closest to 20%.
Other inputs to findAssembly are summarized in the API docs of
findAssembly()
.
1.4.3. Fuel Management Examples
1.4.3.1. Convergent-Divergent
Convergent-divergent shuffling is when fresh assemblies march in from the outside until they approach the jump ring, at which point they jump to the center and diverge until they reach the jump ring again, where they now jump to the outer periphery of the core, or become discharged.
If the jump ring is 6, the order of target rings is:
[6, 5, 4, 3, 2, 1, 6, 7, 8, 9, 10, 11, 12, 13]
In this case, assemblies converge from ring 13 to 12, to 11, to 10, …, to 6, and then jump to 1 and diverge until they get back to 6. In a discharging equilibrium case, the highest burned assembly in the jumpRing should get discharged and the lowest should jump by calling a dischargeSwap on cascade[0] and a fresh feed after this cascade is run.
The convergent rings in this case are 7 through 13 and the divergent ones are 1 through 5 are the divergent ones.
1.4.4. Fuel Management Tips
Some mistakes are common. Follow these tips.
Always make sure your assembly-level types in the settings file are up to date with the grids in your bluepints file. Otherwise you’ll be moving feeds when you want to move igniters, or something.
Use the exclusions list! If you move a cascade and then the next cascade tries to run, it will choose your newly-moved assemblies if they fit your criteria in
findAssemblies
. This leads to very confusing results. Therefore, once you move assemblies, you should default to adding them to the exclusions list.Print cascades during debugging. After you’ve built a cascade to swap, print it out and check the locations and types of each assembly in it. Is it what you want?
Watch
typeNum
in the database. You can get good intuition about what is getting moved by viewing this parameter.
1.4.5. Running a branch search
ARMI can perform a branch search where a number of fuel management operations are performed in parallel and the preferred one is chosen and proceeded with. The key to any branch search is writing a fuel handler that can interpret fuel management factors, defined as keyed values between 0 and 1.
As an example, a fuel handler may be written to interpret two factors, numDischarges
and chargeEnrich
. One method in the fuel handler would then take
the value of factors['numDischarges']
and multiply it by the maximum
number of discharges (often set by another user setting) and then discharge
this many assemblies. Similarly, another method would take the factors['chargeEnrich']
value (between 0 and 1) and multiply it by the maximum allowable enrichment
(again, usually controlled by a user setting) to determine which enrichment
should be used to fabricate new assemblies.
Given a fuel handler that can thusly interpret factors between 0 and 1, the concept of branch searches is simple. They simply build uniformly distributed lists between 0 and 1 across however many CPUs are available and cases on all of them, passing one of each of the factors to each CPU in parallel. When the cases finish, the branch search determines the optimal result and selects the corresponding value of the factor to proceed.
Branch searches are controlled by custom getFactorList methods specified in the shuffleLogic input files. This method should return two things:
A
defaultFactors
; a dictionary with user-defined keys and values between 0 and 1 for each key. These factors will be passed to thechooseSwaps
method, which is typically overridden by the user in custom fuel handling code. The fuel handling code should interpret the values and move the fuel according to what is sent.A
factorSearchFlags
list, which lists the keys to be branch searched. The search will optimize the first key first, and then do a second pass on the second key, holding the optimal first value constant, and so on.
Such a method may look like this:
def getFactorList(cycle,cs=None):
# init default shuffling factors
defaultFactors = {'chargeEnrich':0,'numDischarges':1}
factorSearchFlags=[] # init factors to run branch searches on
# determine when to activate various factors / searches
if cycle not in [0,5,6]:
# shuffling happens before neutronics so skip the first cycle.
defaultFactors['chargeEnrich']=1
else:
defaultFactors['numDischarges']=0
factorSearchFlags = ['chargeEnrich']
return defaultFactors,factorSearchFlags
Once a proper getFactorList
method exists and a fuel handler object
exists that can interpret the factors, activate a branch search
during a regular run by selecting the Branch Search option on the GUI.
The best result from the branch search is determined by comparing the keff values
with the targetK
setting, which is available for setting in the GUI. The branch
with keff closest to the setting, while still being above 1.0 is chosen.
1.5. Settings Report
This document lists all the settings in ARMI.
They are all accessible to developers
through the armi.settings.caseSettings.Settings
object, which is typically
stored in a variable named cs
. Interfaces have access to a simulation’s settings
through self.cs
.
Name |
Description |
Default |
Options |
---|---|---|---|
Tin |
The inlet temperature of the reactor in C |
|
|
Tout |
The outlet temperature of the reactor in C |
|
|
acceptableBlockAreaError |
The limit of error between a block’s cross- sectional area and the reference block used during the assembly area consistency check |
|
|
aclpDoseLimit |
Dose limit in dpa used to position the above-core load pad(if one exists) |
|
|
assemFlagsToSkipAxialExpa nsion |
Assemblies that match a flag on this list will not be axially expanded. |
|
|
assemPowSummary |
Print a summary of how much power is in each assembly type at every timenode |
|
|
assemblyRotationAlgorithm |
The algorithm to use to rotate the detail assemblies while shuffling |
|
|
assemblyRotationStationar y |
Whether or not to rotate assemblies that are not shuffled.This can only be True if ‘rotation’ is true. |
|
|
automaticVariableMesh |
Flag to let ARMI add additional mesh points if the neutronics mesh is too irregular |
|
|
availabilityFactor |
Availability factor of the plant. This is the fraction of the time that the plant is operating. If variable, use availabilityFactors setting. |
|
|
availabilityFactors |
List of availability factor of each cycle as a fraction (fraction of time plant is not in an outage). R is repeat. For example [0.5, 1.0, ‘9R’] is 1 50% followed by 10 100%. Empty list is constant duration set by availabilityFactor. |
|
|
axialExpansion |
Perform axial fuel expansion. This will adjust fuel block lengths. |
|
|
axialMeshRefinementFactor |
Multiplicative factor on the Global Flux number of mesh per block. Used for axial mesh refinement. |
|
|
bcCoefficient |
Value for the parameter A of the generalized boundary condition. |
|
|
beta |
Individual precursor group delayed neutron fractions |
|
|
bondRemoval |
Toggles fuel performance bond removal. This will remove thermal bond from the fuel. |
|
|
boundaries |
External Neutronic Boundary Conditions. Reflective does not include axial. |
|
|
branchVerbosity |
Verbosity of the non- primary MPI nodes |
|
|
buGroups |
The range of burnups where cross-sections will be the same for a given cross section type (units of %FIMA) |
|
|
burnChainFileName |
Path to YAML file that has the depletion chain defined in it |
|
|
burnSteps |
Number of depletion substeps, n, in one cycle. Note: There will be n+1 time nodes and the burnup step time will be computed as cycle length/n when the simple cycles input format is used. |
|
|
burnupPeakingFactor |
The peak/avg factor for burnup and DPA. If it is not set the current flux peaking is used (this is typically conservatively high). |
|
|
circularRingMode |
Toggle between circular ring definitions to hexagonal ring definitions |
|
|
circularRingOrder |
Order by which locations are sorted in circular rings for equilibrium shuffling |
|
|
circularRingPitch |
The relative pitch to be used to define a single circular ring in circular shuffling |
|
|
claddingStrain |
Evaluate cladding strain. |
|
|
claddingWastage |
Evaluate cladding wastage. |
|
|
clearXS |
Delete all cross section libraries before regenerating them. |
|
|
comment |
A comment describing this case |
||
copyFilesFrom |
A list of files that need to be copied at the start of a run. |
|
|
copyFilesTo |
A list of directories to copy provided files into at the start of a run.This list can be of length zero (copy to working dir), 1 (copy all files to the same place), or it must be the same length as copyFilesFrom |
|
|
coverage |
Turn on coverage report generation which tracks all the lines of code that execute during a run |
|
|
coverageConfigFile |
User-defined coverage configuration file |
||
crossSectionControl |
Data structure defining how cross sections are created |
|
|
customFuelManagementIndex |
An index that determines which of various options is used in management. Useful for optimization sweeps. |
|
|
cycleLength |
Duration of one single cycle in days. If availabilityFactor is below 1, the reactor will be at power less than this. If variable, use cycleLengths setting. |
|
|
cycleLengths |
List of durations of each cycle in days. The at- power duration will be affected by availabilityFactor. R is repeat. For example [100, 150, ‘9R’] is 1 100 day cycle followed by 10 150 day cycles. Empty list is constant duration set by cycleLength. |
|
|
cycles |
YAML list defining the cycle history of the case. Options at each cycle include: name, cumulative days, step days, availability factor, cycle length, burn steps, and power fractions. If specified, do not use any of the case settings cycleLength(s), availabilityFactor(s), powerFractions, or burnSteps. Must also specify nCycles and power. |
|
|
cyclesSkipTightCouplingIn teraction |
List of cycle numbers skip tight coupling interaction for. Will still update component temps, etc during these cycles, will just not iterate a second (or more) time. |
|
|
db |
Write the state information to a database at every timestep |
|
|
dbStorageAfterCycle |
Only store cycles after this cycle in the database (to save storage space) |
|
|
debugDB |
Write state to DB with a unique timestamp or label. |
|
|
debugMem |
Turn on memory debugging options to help find problems with the code |
|
|
debugMemSize |
Show size of objects during memory debugging |
|
|
decayConstants |
Individual precursor group delayed neutron decay constants |
|
|
defaultSnapshots |
Generate snapshots at BOL, MOL, and EOL. |
|
|
deferredInterfaceNames |
Interfaces to delay the normal operations of for special circumstance problem avoidance |
|
|
deferredInterfacesCycle |
The supplied list of interface names in deferredInterfaceNames will begin normal operations on this cycle number |
|
|
detailAllAssems |
All assemblies will have ‘detailed’ treatment. Note: This option is interpreted differently by different modules. |
|
|
detailAssemLocationsBOL |
Assembly locations for assemblies that will have ‘detailed’ treatment. This option will track assemblies in the core at BOL. Note: This option is interpreted differently by different modules. |
|
|
detailAssemNums |
Assembly numbers(IDs) for assemblies that will have ‘detailed’ treatment. This option will track assemblies that not in the core at BOL. Note: This option is interpreted differently by different modules. |
|
|
detailedAxialExpansion |
Allow each assembly to expand independently of the others. Results in non-uniform axial mesh. Neutronics kernel must be able to handle. |
|
|
disableBlockTypeExclusion InXsGeneration |
Use all blocks in a cross section group when generating a representative block. When this is disabled only fuel blocks will be considered |
|
|
doTH |
Activate thermal hydraulics calculations using the physics module defined in thKernel |
|
|
dpaPerFluence |
A quick and dirty conversion that is used to get dpaPeak by multiplying the factor and fastFluencePeak |
|
|
dpaXsSet |
The cross sections to use when computing displacements per atom. |
|
|
dumpSnapshot |
List of snapshots to perform detailed reactor analysis, such as reactivity coefficient generation. |
|
|
eigenProb |
Is this a eigenvalue problem or a fixed source problem? |
|
|
epsEig |
Convergence criteria for calculating the eigenvalue in the global flux solver |
|
|
epsFSAvg |
Convergence criteria for average fission source |
|
|
epsFSPoint |
Convergence criteria for point fission source |
|
|
eqDirect |
Does the equilibrium search with repetitive shuffing but with direct shuffling rather than the fast way |
|
|
existingFixedSource |
Specify an exiting fixed source input file. |
|
|
explicitRepeatShuffles |
Path to file that contains a detailed shuffling history that is to be repeated exactly. |
||
fgRemoval |
Toggles fuel performance fission gas removal. This will remove fission gas from the fuel. |
|
|
fissionGasYieldFraction |
The fraction of gaseous atoms produced per fission event, assuming a fission product yield of 2.0 |
|
|
fluxRecon |
Perform detailed flux and power reconstruction |
|
|
forceDbParams |
A list of parameter names that should always be written to the database, regardless of their Parameter Definition’s typical saveToDB status. This is only honored if the DatabaseInterface is used. |
|
|
fpModel |
This setting is used to determine how fission products are treated in an analysis. By choosing noFissionProducts, no fission products will be added. By selecting, infinitelyDilute, lumped fission products will be initialized to a very small number on the blocks/components that require them. By choosing MO99, the fission products will be represented only by Mo-99. This is a simplistic assumption that is commonly used by fast reactor analyses in scoping calculations and is not necessarily a great assumption for depletion evaluations. Finally, by choosing explicitFissionProducts the fission products will be added explicitly to the blocks/components that are depletable. This is useful for detailed tracking of fission products. |
|
|
fpModelLibrary |
This setting should be used when fpModel is set to explicitFissionPr oducts. It is used in conjunction with any nuclideFlags defined in the blueprints to configure all the nuclides that are modeled within the core. Selecting any library option will add all nuclides from the selected library to the model so that analysts do not need to change their inputs when modifying the fission product treatment for calculations. |
|
|
freshFeedType |
The type of fresh fuel added to the core, used in certain pre-defined fuel shuffling logic sequences. |
|
|
fuelHandlerName |
The name of the FuelHandler class in the shuffle logic module to activate |
||
fuelPerformanceEngine |
Fuel performance engine that determines fission gas removal, bond removal, axial growth, wastage, and cladding strain. |
|
|
genReports |
Employ the use of the reporting utility for ARMI, generating HTML and ASCII summaries of the run |
|
|
genXS |
Generate multigroup cross sections for the selected particle type(s) using the specified lattice physics kernel (see Lattice Physics tab). When not set, the XS library will be auto- loaded from an existing ISOTXS in the working directory, but fail if there is no ISOTXS. |
|
|
geomFile |
Input file containing BOL core map |
||
globalFluxActive |
Calculate the global flux at each timestep for the selected particle type(s) using the specified neutronics kernel (see Global Flux tab). |
|
|
gridPlateDpaXsSet |
The cross sections to use for grid plate blocks DPA when computing displacements per atom. |
|
|
groupStructure |
Energy group structure to use in neutronics simulations |
|
|
growToFullCoreAfterLoad |
Grows from 1/3 to full core after loading a 1/3 symmetric snapshot. Note: This is needed when a full core model is needed and the database was produced using a third core model. |
|
|
independentVariables |
List of (independentVarName, value) tuples to inform optimization post- processing |
|
|
infiniteDiluteCutoff |
Do not model nuclides with density less than this cutoff. Used with PARTISN and SERPENT. |
|
|
initializeBurnChain |
This setting is paired with the burnChainFileName setting. When enabled, this will initialize the burn-chain on initializing the case and is required for running depletion calculations where the transmutations and decays are controlled by the framework. If an external software, such as ORIGEN, contains data for the burn-chain already embedded then this may be disabled. |
|
|
inners |
XY and Axial partial current sweep inner iterations. 0 lets the neutronics code pick a default. |
|
|
inputHeightsConsideredHot |
This is a flag to determine if block heights, as provided in blueprints, are at hot dimensions. If false, block heights are at cold/as-built dimensions and will be thermally expanded as appropriate. |
|
|
jumpRingNum |
The number of hex rings jumped when distributing the feed assemblies in the alternating concentric rings or checkerboard shuffle patterns (convergent / divergent shuffling). |
|
|
latticePhysicsFrequency |
Define the frequency at which cross sections are updated with new lattice physics interactions. |
|
|
levelsPerCascade |
The number of moves made per cascade when performing convergent or divergent shuffle patterns. |
|
|
lfpCompositionFilePath |
Path to the file that contains lumped fission product composition definitions (e.g. equilibrium yields). This is unused when the explicitFissionProducts or MO99 modeling options are selected. |
|
|
loadFromDBEveryNode |
Every node loaded from reference database |
|
|
loadPadElevation |
The elevation of the bottom of the above-core load pad (ACLP) in cm from the bottom of the upper grid plate. Used for calculating the load pad dose |
|
|
loadPadLength |
The length of the load pad. Used to compute average and peak dose. |
|
|
loadStyle |
Description of how the ARMI case will be initialized |
|
|
loadingFile |
The blueprints/loading input file path containing component dimensions, materials, etc. |
||
lowPowerRegionFraction |
Description needed |
|
|
makeAllBlockLFPsIndepende nt |
Flag to make all blocks have independent lumped fission products. Note that this is forced to be True when the explicitFissionProducts modeling option is selected or an interface named mcnp is on registered on the operator stack. |
|
|
materialNamespaceOrder |
Ordered list of Python namespaces for finding materials by class name. This allows users to choose between different implementations of reactor materials. For example, the framework comes with a basic UZr material, but power users will want to override it with their own UZr subclass. This allows users to specify to get materials out of a plugin rather than from the framework. |
|
|
mcnpLibraryVersion |
Library name for MCNP cross sections. ENDF/B-VII.1 is the default library. |
|
|
minMeshSizeRatio |
This is the minimum ratio of mesh sizes (dP1/(dP1 + dP2)) allowable – only active if automaticVariableMesh flag is set to True |
|
|
minimumFissileFraction |
Minimum fissile fraction (fissile number densities / heavy metal number densities). |
|
|
minimumNuclideDensity |
Density to use for nuclides and fission products at infinite dilution. This is also used as the minimum density considered for computing macroscopic cross sections. It can also be passed to physics plugins. |
|
|
moduleVerbosity |
Verbosity of any module- specific loggers that are set |
|
|
nCycles |
Number of cycles that will be simulated. Fuel management happens at the beginning of each cycle. Can include active (full- power) cycles as well as post-shutdown decay-heat steps. For restart cases, this value should include both cycles from the restart plus any additional cycles to be run after startCycle. |
|
|
nTasks |
Number of parallel tasks to request on the cluster |
|
|
neutronicsKernel |
The neutronics / depletion solver for global flux solve. |
||
neutronicsType |
The type of neutronics solution that is desired. |
|
|
nonUniformAssemFlags |
Assemblies that match a flag group on this list will not have their mesh changed with the reference mesh of the core for uniform mesh cases (non-detailed axial expansion). Another plugin may need to make the mesh uniform if necessary. |
|
|
numberMeshPerEdge |
Number of mesh per block edge for finite- difference planar mesh refinement. |
|
|
operatorLocation |
The path to the operator code to execute for this run (for custom behavior) |
||
outers |
XY and Axial partial current sweep max outer iterations. |
|
|
outputCacheLocation |
Location where cached calculations are stored and retrieved if exactly the same as the calculation requested. Empty string will not cache. |
||
outputFileExtension |
The default extension for plots |
|
|
plotShuffleArrows |
Make plots with arrows showing each move. |
|
|
plots |
Generate additional plots throughout the ARMI analysis |
|
|
power |
Nameplate thermal power of the reactor. Can be varied by setting the powerFractions setting. |
|
|
powerDensity |
Thermal power of the Reactor, per gram of Heavy metal mass. Ignore this setting if the power setting is non- zero. |
|
|
powerFractions |
List of power fractions at each cycle (fraction of rated thermal power the plant achieves). R is repeat. For example [0.5, 1.0, ‘9R’] is 1 50% followed by 10 100%. Specify zeros to indicate decay-only cycles (i.e. for decay heat analysis). None implies always full rated power. |
|
|
profile |
Turn on the profiler for the submitted case. The profiler results will not include all import times. |
|
|
reallySmallRun |
Clean up files at the beginning of each cycle (BOC) |
|
|
reloadDBName |
Name of the database file to load initial conditions from |
||
removePerCycle |
The number of fuel assemblies removed per cycle at equilibrium. |
|
|
restartNeutronics |
Restart global flux case using outputs from last time as a guess |
|
|
runLatticePhysicsBeforeSh uffling |
Forces the Generation of Cross Sections Prior to Shuffling the Fuel Assemblies. Note: This is recommended when performing equilibrium shuffling branching searches. |
|
|
runType |
Type of run that this is, e.g. a normal run through all cycles, a snapshot- loaded reactivity coefficient run, etc. |
|
|
savePhysicsFiles |
List of snapshots to dump reactor physics kernel input and output files. Can be used to perform follow-on analysis. |
|
|
shuffleLogic |
Python script written to handle the fuel shuffling for this case. This is user-defined per run as a dynamic input. |
||
skipCycles |
Number of cycles to be skipped during the calculation. Note: This is typically used when repeating only a portion of a calculation or repeating a run. |
|
|
smallRun |
Clean up intermediate files after the run completes (EOL) |
|
|
sortReactor |
Deprecation Warning! This setting will be remove by 2024. |
|
|
startCycle |
Cycle number to continue calculation from. Database will load from the time step just before. For snapshots use dumpSnapshot. |
|
|
startNode |
Timenode number (0 for BOC, etc.) to continue calulation from. Database will load from the time step just before. |
|
|
stationaryBlockFlags |
Blocks with these flags will not move in moves. Used for fuel management. |
|
|
summarizeAssemDesign |
Print a summary of the assembly design details at BOL |
|
|
syncDbAfterWrite |
Copy the output database from the fast scratch space to the shared network drive after each write. |
|
|
targetK |
Target criticality (k-effective) for cycle length, branch, and equilibrium search |
|
|
tempGroups |
The range of fuel temperatures where cross- sections will be the same for a given cross section type (units of degrees C) |
|
|
thKernel |
Name of primary T/H solver in this run |
||
tightCoupling |
Boolean to turn on/off tight coupling |
|
|
tightCouplingMaxNumIters |
Maximum number of iterations for tight coupling. |
|
|
tightCouplingSettings |
Data structure defining the tight coupling parameters and convergence criteria for each interface. |
|
|
timelineInclusionCutoff |
Timers who are not active for this percent of the run will not be presented in the timeline graphic |
|
|
tolerateBurnupChange |
Burnup window for computing cross sections. If the prior cross sections were computed within the window, new cross sections will not be generated and the prior calculated cross sections will be used. |
|
|
trace |
Activate Python trace module to print out each line as it’s executed |
|
|
trackAssems |
Track assemblies for detailed fuel histories. For instance, assemblies are tracked after they come out of a reactor by putting them in a Spent Fuel Pool. This might be necessary for your work, but it certainly increases the memory usage of the program. |
|
|
uniformMeshMinimumSize |
Minimum mesh size used when generating an axial mesh for the uniform mesh converter. Providing a value for this setting allows fuel and control material boundaries to be enforced better in uniform mesh. |
|
|
userPlugins |
YAML list defining the locations of UserPlugin subclasses. You can enter the full armi import path: armi.test.test_wha t.MyPlugin, or you can enter the full file path: /path/to/my/pluginz.py:My Plugin |
|
|
verbosity |
How verbose the output will be |
|
|
versions |
Versions of ARMI, and any Apps or Plugins that register a version here. |
|
|
xsBlockRepresentation |
The type of averaging to perform when creating cross sections for a group of blocks |
|
|
xsBucklingConvergence |
Convergence criteria for the buckling iteration if it is available in the lattice physics solver |
|
|
xsEigenvalueConvergence |
Convergence criteria for the eigenvalue in the lattice physics kernel |
|
|
xsKernel |
Method to determine broad group cross sections for assemblies |
|
|
xsScatteringOrder |
Scattering order for the lattice physics calculation |
|
|
zeroOutNuclidesNotInDB |
If a nuclide was added to the problem after a previous case was run, deactivate this to let it survive in a restart run |
|
|
zoneDefinitions |
Manual definitions of zones as lists of assembly locations (e.g. ‘zoneName: loc1, loc2, loc3’) . Zones are groups of assemblies used by various summary and calculation routines. |
|