Skip to content

Commit

Permalink
Adding implementation information to the materials package (#1587)
Browse files Browse the repository at this point in the history
  • Loading branch information
john-science committed Jan 22, 2024
1 parent 6fd8402 commit 4d45672
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 25 deletions.
72 changes: 48 additions & 24 deletions armi/materials/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,48 @@
As the fundamental macroscopic building blocks of any physical object,
these are highly important to reactor analysis.
This module handles the dynamic importing of all the materials defined here at the framework
level as well as in all the attached plugins. It is expected that most teams will
have special material definitions that they will want to define.
This module handles the dynamic importing of all the materials defined here at the
framework level as well as in all the attached plugins. It is expected that most teams
will have special material definitions that they will want to define.
It may also make sense in the future to support user-input materials that are not
hard-coded into the app.
The base class for all materials is in :py:mod:`armi.materials.material`.
"""
import pkgutil
import importlib
from typing import List
import importlib
import inspect
import pkgutil

from armi.materials.material import Material

# this will frequently be updated by the CONF_MATERIAL_NAMESPACE_ORDER setting
# during reactor construction (see armi.reactor.reactors.factory)
# This may also be replaced by a more global material registry at some point.
# This will frequently be updated by the CONF_MATERIAL_NAMESPACE_ORDER setting
# during reactor construction (see armi.reactor.reactors.factory).
_MATERIAL_NAMESPACE_ORDER = ["armi.materials"]


def setMaterialNamespaceOrder(order):
"""
Set the material namespace order at the Python interpreter, global level.
.. impl:: Materials can be searched across packages in a defined namespace.
:id: I_ARMI_MAT_NAMESPACE
:implements: R_ARMI_MAT_NAMESPACE
.. impl:: Material collections are defined with an order of precedence in the case
of duplicates.
:id: I_ARMI_MAT_ORDER
:implements: R_ARMI_MAT_ORDER
An ARMI application will need materials. Materials can be imported from
any code the application has access to, like plugin packages. This leads to
the situation where one ARMI application will want to import multiple
collections of materials. To handle this, ARMI keeps a list of material
namespaces. This is an ordered list of importable packages that ARMI
can search for a particular material by name.
This automatic exploration of an importable package saves the user the
tedium have having to import or include hundreds of materials manually somehow.
But it comes with a caveat; the list is ordered. If two different namespaces in
the list include a material with the same name, the first one found in the list
is chosen, i.e. earlier namespaces in the list have precedence.
"""
global _MATERIAL_NAMESPACE_ORDER
_MATERIAL_NAMESPACE_ORDER = order
Expand Down Expand Up @@ -120,30 +133,41 @@ def resolveMaterialClassByName(name: str, namespaceOrder: List[str] = None):
Find the first material class that matches a name in an ordered namespace.
Names can either be fully resolved class paths (e.g. ``armi.materials.uZr:UZr``)
or simple class names (e.g. ``UZr``). In the latter case, the ``CONF_MATERIAL_NAMESPACE_ORDER``
setting to allows users to choose which particular material of a common name (like UO2 or HT9)
gets used.
or simple class names (e.g. ``UZr``). In the latter case, the
``CONF_MATERIAL_NAMESPACE_ORDER`` setting to allows users to choose which
particular material of a common name (like UO2 or HT9) gets used.
Input files usually specify a material like UO2. Which particular implementation
gets used (Framework's UO2 vs. a user plugins UO2 vs. the Kentucky Transportation
Cabinet's UO2) is up to the user at runtime.
.. impl:: Material collections are defined with an order of precedence in the case of duplicates.
:id: I_ARMI_MAT_ORDER
:implements: R_ARMI_MAT_ORDER
.. impl:: Materials can be searched across packages in a defined namespace.
:id: I_ARMI_MAT_NAMESPACE
:implements: R_ARMI_MAT_NAMESPACE
During the runtime of an ARMI application, but particularly during the
construction of the reactor in memory, materials will be requested by name. At
that point, this code is called to search for that material name. The search
goes through the ordered list of Python namespaces provided. The first time an
instance of that material is found, it is returned. In this way, the first
items in the material namespace list take precedence.
When a material name is passed to this function, it may be either a simple
name like the string ``"UO2"`` or it may be much more specific, like
``armi.materials.uraniumOxide:UO2``.
Parameters
----------
name : str
The material class name to find, e.g. ``"UO2"``. Optionally, a module path
and class name can be provided with a colon separator as ``module:className``, e.g.
``armi.materials.uraniumOxide:UO2`` for direct specification.
and class name can be provided with a colon separator as ``module:className``,
e.g. ``armi.materials.uraniumOxide:UO2`` for direct specification.
namespaceOrder : list of str, optional
A list of namespaces in order of preference in which to search for the material.
If not passed, the value in the global ``MATERIAL_NAMESPACE_ORDER`` will be used,
which is often set by the ``CONF_MATERIAL_NAMESPACE_ORDER`` setting (e.g.
during reactor construction). Any value passed into this argument will be ignored
if the ``name`` is provided with a ``modulePath``.
A list of namespaces in order of preference in which to search for the
material. If not passed, the value in the global ``MATERIAL_NAMESPACE_ORDER``
will be used, which is often set by the ``CONF_MATERIAL_NAMESPACE_ORDER``
setting (e.g. during reactor construction). Any value passed into this argument
will be ignored if the ``name`` is provided with a ``modulePath``.
Returns
-------
Expand Down
25 changes: 24 additions & 1 deletion armi/materials/material.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,29 @@

class Material:
"""
A material is made up of elements or isotopes. It has bulk properties like mass density.
A material is made up of elements or isotopes. It has bulk properties like density.
.. impl:: The abstract material class.
:id: I_ARMI_MAT_PROPERTIES
:implements: R_ARMI_MAT_PROPERTIES
The ARMI Materials library is based on the Object-Oriented Programming design
approach, and uses this generic ``Material`` base class. In this class we
define a large number of material properties like density, heat capacity, or
linear expansion coefficient. Specific materials then subclass this base class to
assign particular values to those properties.
.. impl:: Materials generate nuclide mass fractions at instantiation.
:id: I_ARMI_MAT_FRACS
:implements: R_ARMI_MAT_FRACS
An ARMI material is meant to be able to represent real world materials that
might be used in the construction of a nuclear reactor. As such, they are
not just individual nuclides, but practical materials like a particular
concrete, steel, or water. One of the main things that will be needed to
describe such a material is the exact nuclide fractions. As such, the
constructor of every Material subclass attempts to set these mass fractions.
Attributes
----------
parent : Component
Expand Down Expand Up @@ -108,6 +121,11 @@ def name(self):
.. impl:: The name of a material is accessible.
:id: I_ARMI_MAT_NAME
:implements: R_ARMI_MAT_NAME
Every instance of an ARMI material must have a simple, human-readable
string name. And, if possible, we want this string to match the class
name. (This, of course, puts some limits on both the string and the
class name.) These names are easily retrievable as a class property.
"""
return self._name

Expand Down Expand Up @@ -725,6 +743,11 @@ def linearExpansion(self, Tk=None, Tc=None):
.. impl:: Fluid materials are not thermally expandable.
:id: I_ARMI_MAT_FLUID
:implements: R_ARMI_MAT_FLUID
ARMI does not model thermal expansion of fluids. The ``Fluid`` superclass
therefore sets the thermal expansion coefficient to zero. All fluids
subclassing the ``Fluid`` material will inherit this method which sets the
linear expansion coefficient to zero at all temperatures.
"""
return 0.0

Expand Down
6 changes: 6 additions & 0 deletions armi/materials/void.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ class Void(material.Fluid):
.. impl:: Define a void material with zero density.
:id: I_ARMI_MAT_VOID
:implements: R_ARMI_MAT_VOID
To help with expansion, it is sometimes useful to put a small section of void
material into the reactor model. This is not meant to represent a true void,
that would cause negative pressure in a system, but just as a bookkeeping tool.
Sometimes this helps users define the geometry of an expanding and conctracting
reactor. It is called a "void" because it has zero density at all temperatures.
"""

def pseudoDensity(self, Tk: float = None, Tc: float = None) -> float:
Expand Down

0 comments on commit 4d45672

Please sign in to comment.