diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 0c5ff2aa3..dc50c7ec7 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -21,7 +21,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v2 with: - python-version: 3.9 + python-version: 3.13 - name: Update package index run: sudo apt-get update - name: Install mpi libs diff --git a/armi/nucDirectory/nuclideBases.py b/armi/nucDirectory/nuclideBases.py index d9e1130fc..2821e116d 100644 --- a/armi/nucDirectory/nuclideBases.py +++ b/armi/nucDirectory/nuclideBases.py @@ -800,22 +800,6 @@ def getMcnpId(self): """ return "{0:d}000".format(self.z) - def getAAAZZZSId(self): - """Gets the AAAZZZS ID for a few elements. - - Notes - ----- - the natural nuclides 'C' and 'V' do not have isotopic nuclide data for MC2 so sometimes they tag along in the - list of active nuclides. This method is designed to fail in the same as if there was not getAAAZZZSId method - defined. - """ - if self.element.symbol == "C": - return "120060" - elif self.element.symbol == "V": - return "510230" - else: - return None - def getMcc2Id(self): """Return the MC2-2 nuclide identification label based on the ENDF/B-V.2 cross section library.""" return self.mcc2id @@ -1442,6 +1426,8 @@ def addGlobalNuclide(nuclide: NuclideBase): f"{nuclide} with McnpId {nuclide.getMcnpId()} has already been added and cannot be duplicated." ) byMcnpId[nuclide.getMcnpId()] = nuclide + if not isinstance(nuclide, (NaturalNuclideBase, LumpNuclideBase, DummyNuclideBase)): + # There are no AZS ID for elements / natural nuclides, or ficticious lump or dummy nuclides byAAAZZZSId[nuclide.getAAAZZZSId()] = nuclide diff --git a/armi/nucDirectory/tests/test_nuclideBases.py b/armi/nucDirectory/tests/test_nuclideBases.py index 1ef1b5900..066d0f5b7 100644 --- a/armi/nucDirectory/tests/test_nuclideBases.py +++ b/armi/nucDirectory/tests/test_nuclideBases.py @@ -466,11 +466,9 @@ def test_AAAZZZSNameGenerator(self): :tests: R_ARMI_ND_ISOTOPES """ referenceNucNames = [ - ("C", "120060"), + ("C12", "120060"), ("U235", "2350920"), ("AM242M", "2420951"), - ("LFP35", None), - ("DUMP1", None), ] for nucName, refAaazzzs in referenceNucNames: diff --git a/armi/physics/neutronics/crossSectionGroupManager.py b/armi/physics/neutronics/crossSectionGroupManager.py index 1eca9a382..f049890bb 100644 --- a/armi/physics/neutronics/crossSectionGroupManager.py +++ b/armi/physics/neutronics/crossSectionGroupManager.py @@ -63,7 +63,6 @@ from armi.physics.neutronics.const import CONF_CROSS_SECTION from armi.reactor import flags from armi.reactor.components import basicShapes -from armi.reactor.converters.blockConverters import stripComponents from armi.reactor.flags import Flags from armi.utils import safeCopy from armi.utils.units import C_TO_K, TRACE_NUMBER_DENSITY @@ -710,6 +709,8 @@ def _makeRepresentativeBlock(self): def _getNucTempHelper(self): """All candidate blocks are used in the average.""" + from armi.reactor.converters.blockConverters import stripComponents + nvt = np.zeros(len(self.allNuclidesInProblem)) nv = np.zeros(len(self.allNuclidesInProblem)) for block in self.getCandidateBlocks(): diff --git a/armi/reactor/__init__.py b/armi/reactor/__init__.py index 3536b698c..85bddbb21 100644 --- a/armi/reactor/__init__.py +++ b/armi/reactor/__init__.py @@ -16,36 +16,6 @@ The reactor package houses the data model used in ARMI to represent the reactor during its simulation. It contains definitions of the reactor, assemblies, blocks, components, etc. -The key classes of the reactor package are shown below: - -.. _reactor-class-diagram: - -.. pyreverse:: armi.reactor -A -k --ignore= - assemblyParameters.py, - basicShapes.py, - blockParameters.py, - blueprints, - complexShapes.py, - componentParameters.py, - converters, - excoreStructure.py, - flags.py, - geometry.py, - grids.py, - parameters, - plugins.py, - reactorParameters.py, - shapes.py, - spentFuelPool.py, - tests, - volumetricShapes.py, - zones.py - :align: center - :alt: Reactor class diagram - :width: 90% - - Class inheritance diagram for :py:mod:`armi.reactor`. - See :doc:`/developer/index`. """ diff --git a/armi/reactor/blueprints/componentBlueprint.py b/armi/reactor/blueprints/componentBlueprint.py index 54676cbea..838c55253 100644 --- a/armi/reactor/blueprints/componentBlueprint.py +++ b/armi/reactor/blueprints/componentBlueprint.py @@ -378,10 +378,18 @@ def _constructMaterial(self, blueprint, matMods): try: # update material with updated input params from blueprints file. mat.applyInputParams(**matMods) - except TypeError: - # This component does not accept material modification inputs of the names passed in - # Keep going since the modification could work for another component - pass + except TypeError as ee: + errorMessage = ee.args[0] + if "got an unexpected keyword argument" in errorMessage: + # This component does not accept material modification inputs of the names passed in + # Keep going since the modification could work for another component + pass + else: + raise ValueError( + f"Something went wrong in applying the material modifications {matMods} " + f"to component {self.name}.\n" + f"Error message is: \n{errorMessage}." + ) expandElementals(mat, blueprint) diff --git a/armi/reactor/blueprints/tests/test_materialModifications.py b/armi/reactor/blueprints/tests/test_materialModifications.py index 52ada251e..eaccb00db 100644 --- a/armi/reactor/blueprints/tests/test_materialModifications.py +++ b/armi/reactor/blueprints/tests/test_materialModifications.py @@ -259,7 +259,7 @@ def test_filterMaterialInput(self): def test_invalidMatModName(self): """ - This test shows proves that we can detect invalid material modification + This test shows that we can detect invalid material modification names when they are specified on an assembly blueprint. We happen to know that ZR_wt_frac is a valid modification for the UZr material class, so we use that in the first call to prove that things initially work fine. @@ -299,6 +299,35 @@ def test_invalidMatModName(self): """ ) + def test_invalidMatModType(self): + """ + This test shows that we can detect material modifications that are invalid + because of their values, not just their names. + We happen to know that ZR_wt_frac is a valid modification for UZr, so we + use that in the first call to prove that things initially work fine. + """ + a = self.loadUZrAssembly( + """ + material modifications: + ZR_wt_frac: [1] + """ + ) + # just to prove that the above works fine before we modify it + self.assertAlmostEqual(a[0][0].getMassFrac("ZR"), 1) + + with self.assertRaises(ValueError) as ee: + a = self.loadUZrAssembly( + """ + material modifications: + ZR_wt_frac: [this_is_a_value_of_incompatible_type] + """ + ) + + self.assertIn( + "Something went wrong in applying the material modifications", + ee.args[0], + ) + def test_matModsUpTheMRO(self): """ Make sure that valid/invalid material modifications are searched up diff --git a/armi/runLog.py b/armi/runLog.py index 484672dfd..b7393bd66 100644 --- a/armi/runLog.py +++ b/armi/runLog.py @@ -572,7 +572,7 @@ def __init__(self, *args, **kwargs): handler.setFormatter(form) self.addHandler(handler) - def log(self, msgType, msg, single=False, label=None, **kwargs): + def log(self, msgType, msg, single=False, label=None, *args, **kwargs): """ This is a wrapper around logger.log() that does most of the work. diff --git a/doc/conf.py b/doc/conf.py index aa8745d2c..9a5d4be47 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -24,6 +24,7 @@ All configuration values have a default; values that are commented out serve to show the default. """ + # ruff: noqa: E402 import datetime import inspect @@ -35,7 +36,7 @@ import sys import warnings -import sphinx_rtd_theme +import sphinx_rtd_theme # noqa: F401 from docutils import nodes, statemachine from docutils.parsers.rst import Directive, directives from sphinx.domains.python import PythonDomain @@ -97,14 +98,13 @@ class ExecDirective(Directive): def run(self): try: - code = inspect.cleandoc( - """ - def usermethod(): - {} - """ - ).format("\n ".join(self.content)) - exec(code) - result = locals()["usermethod"]() + # clean the content, then put back into a list + cleancode = inspect.cleandoc("\n".join(self.content)).split("\n") + code = "def usermethod():\n " + "\n ".join(cleancode) + globals = {} + exec(code, globals) + + result = globals["usermethod"]() if result is None: raise self.error( @@ -119,9 +119,7 @@ def usermethod(): except Exception as e: docname = self.state.document.settings.env.docname raise self.error( - "Unable to execute embedded doc code at {}:{} ... {}\n{}".format( - docname, self.lineno, datetime.datetime.now(), str(e) - ) + f"Unable to execute embedded doc code at {docname}:{self.lineno}\n{str(e)}" ) @@ -337,6 +335,12 @@ def setup(app): # looking for source files. exclude_patterns = [ "**.ipynb", + "**/Python27*", + "**/ccl*", + "gallery/**/*.ipynb", # prevent sphinx-gallery from causing duplicate source file errors + "gallery/**/*.md5", + "gallery/**/*.zip", + "gallery/**/*.json", "**.ipynb_checkpoints", "**/ccl*", "**/Python27*", @@ -389,9 +393,6 @@ def setup(app): "titles_only": False, } -# Add any paths that contain custom themes here, relative to this directory. -html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] - # as long as this file @import's the theme's main css it won't break anything html_style = "css/theme_fixes.css" diff --git a/doc/gallery-src/framework/run_chartOfNuclides.py b/doc/gallery-src/framework/run_chartOfNuclides.py index f0818d7e4..5a4516ffc 100644 --- a/doc/gallery-src/framework/run_chartOfNuclides.py +++ b/doc/gallery-src/framework/run_chartOfNuclides.py @@ -22,7 +22,9 @@ Our :ref:`extended tutorial for nuclides ` and detailed :py:mod:`nucDirectory docs ` may also be of interest. + """ + import matplotlib.pyplot as plt from armi import configure diff --git a/doc/gallery-src/framework/run_computeReactionRates.py b/doc/gallery-src/framework/run_computeReactionRates.py index 1a7c2d52b..2c2578e2e 100644 --- a/doc/gallery-src/framework/run_computeReactionRates.py +++ b/doc/gallery-src/framework/run_computeReactionRates.py @@ -28,7 +28,7 @@ from armi import configure, nuclideBases, settings from armi.materials import ht9, sodium, uZr from armi.nuclearDataIO.cccc import isotxs -from armi.reactor import assemblies, blocks, blueprints, geometry, grids, reactors +from armi.reactor import assemblies, blocks, geometry, grids, reactors from armi.reactor.components import Circle, DerivedShape, Hexagon from armi.reactor.flags import Flags from armi.tests import ISOAA_PATH @@ -56,7 +56,9 @@ def createDummyReactor(): Often, a reactor model like this is built directly from input files rather than from code as done here. """ - bp = blueprints.Blueprints() + from armi.reactor.blueprints import Blueprints + + bp = Blueprints() cs = settings.Settings() r = reactors.Reactor("Reactor", bp) diff --git a/doc/gallery-src/framework/run_fuelManagement.py b/doc/gallery-src/framework/run_fuelManagement.py index a55adcab2..7512f8c17 100644 --- a/doc/gallery-src/framework/run_fuelManagement.py +++ b/doc/gallery-src/framework/run_fuelManagement.py @@ -13,6 +13,7 @@ # limitations under the License. """ Fuel management in a LWR. +========================= Demo of locating and swapping assemblies in a core with Cartesian geometry. Given a burnup distribution, this swaps high burnup assemblies with low ones. @@ -26,6 +27,7 @@ ARMI to do fuel management. Thus, this example applies a dummy burnup distribution for demonstration purposes. """ + # Tell the gallery to feature the 2nd image # sphinx_gallery_thumbnail_number = 2 import math diff --git a/doc/release/0.5.rst b/doc/release/0.5.rst index 130031b1f..f96c79b23 100644 --- a/doc/release/0.5.rst +++ b/doc/release/0.5.rst @@ -28,8 +28,9 @@ Bug Fixes Quality Work ------------ -#. Adding PDF versions of the ARMI docs. (`PR#2072 `_) #. Open-Sourcing the ARMI requirements. (`PR#2076 `_) +#. Update docs build to occur with python 3.13 and updated docs dependencies. (`PR#2050 `_) +#. Adding PDF versions of the ARMI docs. (`PR#2072 `_) #. TBD diff --git a/pyproject.toml b/pyproject.toml index e18eb030b..2c273a7c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -92,33 +92,30 @@ test = [ docs = [ ####################################################################### # These are most specified that usual, because Sphinx docs seem to be -# quite fragile limited <7 by sphinx-rtd-theme at the moment. +# quite fragile. # -# sphinx-rtd-theme requires docutils <0.19 but sphinx dropped support -# for 0.18 in 6.0.0 so we're stuck at these versions. -# -# We are only building our docs with Python 3.9. +# We are only building our docs with Python 3.13. ####################################################################### - "Sphinx==5.3.0", # central library used to build our docs - "docutils==0.18.1", # Needed by sphinx-rtd-them - "sphinx-rtd-theme==1.2.2", # Read-The-Docs theme for Sphinx - "nbsphinx==0.9.2", # Parses Jupyter notebooks + "docutils==0.21.2", # Needed by sphinx-rtd-them + "ipykernel", # iPython kernel to run Jupyter notebooks + "Jinja2", # Used in numpydoc and nbconvert + "nbsphinx", # Parses Jupyter notebooks "nbsphinx-link==1.3.0", # Adds Jupyter NBs to Sphinx source root + "nbsphinx==0.9.2", # Parses Jupyter notebooks + "pandoc", # Must be in the path (to convert file formats) + "pylint", # Generates UML diagrams + "setuptools", # needed for conf.py tooling "sphinx-gallery==0.13.0", # Builds an HTML version of a Python script and puts it into a gallery - "sphinxcontrib-apidoc==0.3.0", # More easily document our API - "sphinxext-opengraph==0.8.2", # Generates OpenGraph metadata to make good-looking cards on social media - "sphinx-needs==2.1.0", # Requirements traceability matrices for QA + "sphinx-needs==4.1.0", # Requirements traceability matrices for QA + "sphinx-rtd-theme==3.0.2", # Read-The-Docs theme for Sphinx + "sphinx-simplepdf==1.6.0", # Used to make PDF versions of the docs "sphinx-test-reports", - "sphinxcontrib-plantuml==0.25", # UML support in sphinx-needs - "unittest-xml-reporting", - "pandoc", # Must be in the path (to convert file formats) - "ipykernel==6.25.1", # iPython kernel to run Jupyter notebooks - "pylint==2.17.5", # Generates UML diagrams - "Jinja2==3.0.3", # Used in numpydoc and nbconvert + "Sphinx==8.1.3", # central library used to build our docs + "sphinxcontrib-apidoc==0.5.0", # More easily document our API "sphinxcontrib-jquery==4.1", # Handle missing jquery errors - "jupyter-contrib-nbextensions", # A collections of JS extensions for jupyter notebooks - "lxml<5.0.0", # Needed because the dep above is no longer an active project - "sphinx-simplepdf==1.6.0", # Used to make PDF versions of the docs + "sphinxcontrib-plantuml==0.30", # UML support in sphinx-needs + "sphinxext-opengraph==0.8.2", # Generates OpenGraph metadata to make cards for social media + "unittest-xml-reporting", ] [project.scripts]