From 21f737cf055d5cde05089bf3b74d670997463be3 Mon Sep 17 00:00:00 2001 From: jstilley Date: Tue, 23 Jan 2024 15:25:42 -0800 Subject: [PATCH 1/2] Adding implementation text for Utils dir --- armi/utils/densityTools.py | 44 ++++++++++++++++++++++++++++++++------ armi/utils/flags.py | 23 +++++++++++++++----- armi/utils/hexagon.py | 7 +++++- 3 files changed, 62 insertions(+), 12 deletions(-) diff --git a/armi/utils/densityTools.py b/armi/utils/densityTools.py index 5f98e20f9..65fc853ea 100644 --- a/armi/utils/densityTools.py +++ b/armi/utils/densityTools.py @@ -28,13 +28,17 @@ def getNDensFromMasses(rho, massFracs, normalize=False): :id: I_ARMI_UTIL_MASS2N_DENS :implements: R_ARMI_UTIL_MASS2N_DENS + Loops over all provided nuclides (given as keys in the ``massFracs`` vector) and calculates + number densities of each, at a given material ``density``. Mass fractions can be provided + either as normalized to 1, or as unnormalized with subsequent normalization calling + ``normalizeNuclideList`` via the ``normalize`` flag. + Parameters ---------- rho : float density in (g/cc) massFracs : dict - vector of mass fractions -- normalized to 1 -- keyed by their nuclide - name + vector of mass fractions -- normalized to 1 -- keyed by their nuclide name Returns ------- @@ -176,6 +180,21 @@ def formatMaterialCard( :id: I_ARMI_UTIL_MCNP_MAT_CARD :implements: R_ARMI_UTIL_MCNP_MAT_CARD + Loops over a vector of nuclides (of type ``nuclideBase``) provided in ``densities`` and + formats them into a list of strings consistent with MCNP material card syntax, skipping + dummy nuclides and LFPs. + + A ``matNum`` may optionally be provided for the created material card: if not provided, it + is left blank. The desired number of significant figures for the created card can be + optionally provided by ``sigFigs``. Nuclides whose number density falls below a threshold + (optionally specified by ``minDens``) are set to the threshold value. + + The boolean ``mcnp6Compatible`` may optionally be provided to include the nuclide library at + the end of the vector of individual nuclides using the "nlib=" syntax leveraged by MCNP. If + this boolean is turned on, the associated value ``mcnpLibrary`` should generally also be + provided, as otherwise, the library will be left blank in the resulting material card + string. + Parameters ---------- densities : dict @@ -266,6 +285,9 @@ def normalizeNuclideList(nuclideVector, normalization=1.0): :id: I_ARMI_UTIL_DENS_TOOLS :implements: R_ARMI_UTIL_DENS_TOOLS + Given a vector of nuclides ``nuclideVector`` indexed by nuclide identifiers (``nuNames`` or ``nuclideBases``), + normalizes to the provided ``normalization`` value. + Parameters ---------- nuclideVector : dict @@ -303,15 +325,25 @@ def expandElementalMassFracsToNuclides( :id: I_ARMI_UTIL_EXP_MASS_FRACS :implements: R_ARMI_UTIL_EXP_MASS_FRACS + Given a vector of elements and nuclides with associated mass factions (``massFracs``), + expands the elements in-place into a set of nuclides using + ``expandElementalNuclideMassFracs``. Isotopes to expand into are provided for each element + by specifying them with ``elementExpansionPairs``, which maps each element to a list of + particular NuclideBases; if left unspecified, all naturally-occurring isotopes are included. + + Explicitly specifying the expansion isotopes provides a way for particular + naturally-occurring isotopes to be excluded from the expansion, e.g. excluding O-18 from an + expansion of elemental oxygen. + Parameters ---------- massFracs : dict(str, float) - dictionary of nuclide or element names with mass fractions. - Elements will be expanded in place using natural isotopics. + dictionary of nuclide or element names with mass fractions. Elements will be expanded in + place using natural isotopics. elementExpansionPairs : (Element, [NuclideBase]) pairs - element objects to expand (from nuclidBase.element) and list - of NuclideBases to expand into (or None for all natural) + element objects to expand (from nuclidBase.element) and list of NuclideBases to expand into + (or None for all natural) """ # expand elements for element, isotopicSubset in elementExpansionPairs: diff --git a/armi/utils/flags.py b/armi/utils/flags.py index 55f60c5cd..08ca04532 100644 --- a/armi/utils/flags.py +++ b/armi/utils/flags.py @@ -119,14 +119,23 @@ class Flag(metaclass=_FlagMeta): """ A collection of bitwise flags. - This is intended to emulate ``enum.Flag``, except with the possibility of extension - after the class has been defined. Most docs for ``enum.Flag`` should be relevant here, - but there are sure to be occasional differences. + This is intended to emulate ``enum.Flag``, except with the possibility of extension after the + class has been defined. Most docs for ``enum.Flag`` should be relevant here, but there are sure + to be occasional differences. .. impl:: No two flags have equivalence. :id: I_ARMI_FLAG_DEFINE :implements: R_ARMI_FLAG_DEFINE + A bitwise flag class intended to emulate the standard library's ``enum.Flag``, with the + added functionality that it allows for extension after the class has been defined. Each Flag + is unique; no two Flags are equivalent. + + Note that while Python allows for arbitrary-width integers, exceeding the system-native + integer size can lead to challenges in storing data, e.g. in an HDF5 file. In this case, the + ``from_bytes()`` and ``to_bytes()`` methods are provided to represent a Flag's values in + smaller chunks so that writeability can be maintained. + .. warning:: Python features arbitrary-width integers, allowing one to represent an practically unlimited number of fields. *However*, including more flags than can @@ -224,11 +233,15 @@ def extend(cls, fields: Dict[str, Union[int, auto]]): :id: I_ARMI_FLAG_EXTEND0 :implements: R_ARMI_FLAG_EXTEND + A class method to extend a ``Flag`` with a vector of provided additional ``fields``, + with field names as keys, without loss of uniqueness. Values for the additional + ``fields`` can be explicitly specified, or an instance of ``auto`` can be supplied. + Parameters ---------- fields : dict - A dictionary containing field names as keys, and their desired values, or - an instance of ``auto`` as values. + A dictionary containing field names as keys, and their desired values, or an instance of + ``auto`` as values. Example ------- diff --git a/armi/utils/hexagon.py b/armi/utils/hexagon.py index dc4e706f3..3831d43be 100644 --- a/armi/utils/hexagon.py +++ b/armi/utils/hexagon.py @@ -36,6 +36,8 @@ def area(pitch): :id: I_ARMI_UTIL_HEXAGON0 :implements: R_ARMI_UTIL_HEXAGON + Computes the area of a hexagon given the flat-to-flat ``pitch``. + Notes ----- The pitch is the distance between the center of the hexagons in the lattice. @@ -135,8 +137,11 @@ def numRingsToHoldNumCells(numCells): def numPositionsInRing(ring): """Number of positions in ring (starting at 1) of a hex lattice. - .. impl:: Compute hexagonal area + .. impl:: Compute number of positions in a ring of a hex lattice :id: I_ARMI_UTIL_HEXAGON1 :implements: R_ARMI_UTIL_HEXAGON + + In a hexagonal lattice, calculate the number of positions in a given ``ring``. The number of + rings is indexed to 1, i.e. the centermost position in the lattice is ``ring=1``. """ return (ring - 1) * 6 if ring != 1 else 1 From 86bd4badfc8869cf3f240ed01383fda4656a1f16 Mon Sep 17 00:00:00 2001 From: Arrielle Opotowsky Date: Tue, 23 Jan 2024 19:55:58 -0600 Subject: [PATCH 2/2] Apply suggestions from code review --- armi/utils/densityTools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armi/utils/densityTools.py b/armi/utils/densityTools.py index 65fc853ea..94b46a82d 100644 --- a/armi/utils/densityTools.py +++ b/armi/utils/densityTools.py @@ -285,7 +285,7 @@ def normalizeNuclideList(nuclideVector, normalization=1.0): :id: I_ARMI_UTIL_DENS_TOOLS :implements: R_ARMI_UTIL_DENS_TOOLS - Given a vector of nuclides ``nuclideVector`` indexed by nuclide identifiers (``nuNames`` or ``nuclideBases``), + Given a vector of nuclides ``nuclideVector`` indexed by nuclide identifiers (``nucNames`` or ``nuclideBases``), normalizes to the provided ``normalization`` value. Parameters @@ -325,7 +325,7 @@ def expandElementalMassFracsToNuclides( :id: I_ARMI_UTIL_EXP_MASS_FRACS :implements: R_ARMI_UTIL_EXP_MASS_FRACS - Given a vector of elements and nuclides with associated mass factions (``massFracs``), + Given a vector of elements and nuclides with associated mass fractions (``massFracs``), expands the elements in-place into a set of nuclides using ``expandElementalNuclideMassFracs``. Isotopes to expand into are provided for each element by specifying them with ``elementExpansionPairs``, which maps each element to a list of