armi.reactor.parameters package¶
The parameters system holds state information for everything within ARMI’s composite structure:
Object |
Parameters |
---|---|
|
Basic Usage¶
Given an ARMI reactor model object such as r
, one may set or get a parameter just
like any other instance attribute on r.p
:
>>> r.p.cycleLength
350.0
Alternatively, dictionary-like access is supported:
>>> r.p["cycleLength"]
350.0
Note
The data themselves are stored in special hidden fields, which are typically
accessed through the Parameter
definition that describes them. The name for such
a parameter field looks like "_p_" + paramName
. For example, to get
cycleLength
one could do:
>>> r.core.p._p_cycleLength
350.0
However, it is not recommended to access parameters in this way, as it circumvents the setters and getters that may have been implemented for a given parameter. One should always use the style from the first two examples to access parameter values.
Furthermore, ParameterCollection
classes have some extra controls to make sure
that someone doesn’t try to set random extra attributes on them. Only parameters
that were defined before a particular ParameterCollection
class is instantiated
may be accessed.The rationale behind this is documented in the Design
Considerations section below.
Most parameters in ARMI are block parameters. These include flux, power, temperatures, number densities, etc. Parameters can be any basic type (float, int, str), or an array of any such types. The type within a given array should be homogeneous. Examples:
>>> b.p.flux = 2.5e13
>>> b.p.fuelTemp = numpy.array(range(217), dtype=float)
>>> b.p.fuelTemp[58] = 600
Note
There have been many discussions on what the specific name of this module/system should be. After great deliberation, the definition of parameter seemed very suitable:
One of a set of measurable factors, such as temperature and pressure, that define a system and determine its behavior and are varied in an experiment ~ thefreedictionary
any of a set of physical properties whose values determine the characteristics or behavior of something <parameters of the atmosphere such as temperature, pressure, and density> ~ Meriam-Webster
The parameters system is composed of several classes:
Parameter
:These store metadata about each parameter including the name, description, its units, etc.
Parameters
also define some behaviors such as setters/getters, and what to do when retrieving a value that has not been set, and whether or not to store the parameter in the database. TheparameterDefinitions.Parameter
object implement the Python descriptor protocol (the magic behind@property
), and are stored on correspondingparameterCollections.ParameterCollection
classes to access their underlying values.ParameterDefinitionCollection
:As the name suggests, these represent a collection of parameter definitions. Each
ParameterCollection
gets aParameterDefinitionCollection
, and there are also module-global collections, such asALL_DEFINITIONS
(containing all defined parameters over allArmiObject
classes), and others which break parameters down by their categories, associated composite types, etc.ParameterBuilder
:These are used to aid in the creation of
Parameter
instances, and store default arguments to theParameter
constructor.ParameterCollection
:These are used to store parameter values for a specific instance of an item in the ARMI composite structure, and have features for accessing those parameters and their definitions. The actual parameter values are stored in secret “_p_”+paramName fields, and accessed through the Parameter definition, which functions as a descriptor. Parameter definitions are stored as class attributes so that they can be shared amongst instances. All parameter fields are filled with an initial value in their
__init__()
to benefit from the split-key dictionaries introduced in PEP-412. This and protections to prevent setting any other attributes form a sort of “__slots__
lite”.ResolveParametersMeta
:This metaclass is used by the base
ArmiObject
class to aid in the creation of a hierarchy ofParameterCollection
classes that appropriately represent a specificArmiObject
subclass’s parameters. In short, it looks at the class attributes of anArmiObject
subclass to see if there is apDefs
attribute (which should be an instance ofParameterDefinitionCollection
). If thepDefs
attribute exists, the class will get its ownParameterCollection
class, which will itself be a subclass of the parameter collection class associated with the most immediate ancestor that also had its ownpDefs
. If anArmiObject
subclass has notpDefs
attribute of its own, it will simply be associated with the parameter collection class of its parent.
This rather roundabout approach is used to address many of the design considerations laid out below. Namely that pains be taken to minimize memory consumption, properties be used to control data access, and that it be relatively difficult to introduce programming errors related to improperly-defined or colliding parameters.
Design Considerations¶
Issue |
Resolution/Consequences |
---|---|
Metadata about parameters is necessary for determining whether a parameter should be stored in the database, and to allow the user to toggle this switch. |
Parameters must uniquely named within a Also, we need to have |
There should not be any naming restrictions between different |
Parameters must be defined or associated with a specific |
PyLint cannot find programming errors related to incorrect strings. |
We would like to use methods/functions for controlling state information. This also eliminated the possibility of using resource files to define the properties, otherwise we would be mapping names between some resource file and the associated parameter/property definition. |
Creating getters and setters for every parameter would be overwhelming and unsustainable. |
We will use Python descriptors, which have most of the functionality used in getters and setters.
|
The majority of memory consumption occurs in parameters, strings and dictionaries. Minimizing the storage requirements of the parameters is desirable. |
Python In the past, |
Parameters are just fancy properties with meta data. |
Implementing the descriptor interface on a |
- armi.reactor.parameters.reset()[source]¶
Reset the status of all parameter definintions.
This may become necessary when the state of the global parameter definitions becomes invalid. Typically this happens when running multiple cases for the same import of this module, e.g. in unit tests. In this case things like the assigned flags will persist across test cases, leading to strange and incorrect behavior.