From 7de33eb4ba87846764e73895044ab1cbd3ae8539 Mon Sep 17 00:00:00 2001 From: John Stilley <1831479+john-science@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:38:05 -0800 Subject: [PATCH] Adding impl/test crumbs for requirements (#1507) --- armi/physics/neutronics/energyGroups.py | 11 ++++++++++- .../neutronics/globalFlux/globalFluxInterface.py | 9 +++++++-- .../globalFlux/tests/test_globalFluxInterface.py | 5 ++--- armi/physics/neutronics/tests/test_energyGroups.py | 11 ++++++++++- armi/reactor/assemblies.py | 9 +++++++-- armi/reactor/blueprints/componentBlueprint.py | 4 ++++ armi/reactor/blueprints/isotopicOptions.py | 4 ++++ armi/reactor/blueprints/tests/test_blockBlueprints.py | 2 +- armi/reactor/blueprints/tests/test_blueprints.py | 7 ++++++- armi/reactor/converters/axialExpansionChanger.py | 4 ++++ armi/reactor/converters/geometryConverters.py | 10 +++++++--- .../converters/tests/test_geometryConverters.py | 10 ++++++++-- armi/reactor/grids/structuredgrid.py | 4 ++-- 13 files changed, 72 insertions(+), 18 deletions(-) diff --git a/armi/physics/neutronics/energyGroups.py b/armi/physics/neutronics/energyGroups.py index 5ecda047df..3f430326a5 100644 --- a/armi/physics/neutronics/energyGroups.py +++ b/armi/physics/neutronics/energyGroups.py @@ -30,7 +30,12 @@ def getFastFluxGroupCutoff(eGrpStruc): - """Given a constant "fast" energy threshold, return which ARMI energy group index contains this threshold.""" + """Given a constant "fast" energy threshold, return which ARMI energy group index contains this threshold. + + .. impl:: Return the energy group index which contains a given energy threshold. + :id: I_ARMI_EG_FE + :implements: R_ARMI_EG_FE + """ gThres = -1 for g, eV in enumerate(eGrpStruc): if eV < FAST_FLUX_THRESHOLD_EV: @@ -67,6 +72,10 @@ def getGroupStructure(name): """ Return descending neutron energy group upper bounds in eV for a given structure name. + .. impl:: Provide the neutron energy group bounds for a given group structure. + :id: I_ARMI_EG_NE + :implements: R_ARMI_EG_NE + Notes ----- Copy of the group structure is return so that modifications of the energy bounds does diff --git a/armi/physics/neutronics/globalFlux/globalFluxInterface.py b/armi/physics/neutronics/globalFlux/globalFluxInterface.py index d4ace8ff99..8f4a293dc4 100644 --- a/armi/physics/neutronics/globalFlux/globalFluxInterface.py +++ b/armi/physics/neutronics/globalFlux/globalFluxInterface.py @@ -119,8 +119,13 @@ def interactEOC(self, cycle=None): * units.ABS_REACTIVITY_TO_PCM ) - def _checkEnergyBalance(self): - """Check that there is energy balance between the power generated and the specified power is the system.""" + def checkEnergyBalance(self): + """Check that there is energy balance between the power generated and the specified power. + + .. impl:: Validate the energy generate matches user specifications. + :id: I_ARMI_FLUX_CHECK_POWER + :implements: R_ARMI_FLUX_CHECK_POWER + """ powerGenerated = ( self.r.core.calcTotalParam( "power", calcBasedOnFullObj=False, generationNum=2 diff --git a/armi/physics/neutronics/globalFlux/tests/test_globalFluxInterface.py b/armi/physics/neutronics/globalFlux/tests/test_globalFluxInterface.py index a7726ba262..2fd627a342 100644 --- a/armi/physics/neutronics/globalFlux/tests/test_globalFluxInterface.py +++ b/armi/physics/neutronics/globalFlux/tests/test_globalFluxInterface.py @@ -180,8 +180,7 @@ def test_getHistoryParams(self): self.assertIn("detailedDpa", params) def test_checkEnergyBalance(self): - """ - Test energy balance check. + """Test energy balance check. .. test:: Block-wise power is consistent with reactor data model power. :id: T_ARMI_FLUX_CHECK_POWER @@ -190,7 +189,7 @@ def test_checkEnergyBalance(self): cs = settings.Settings() _o, r = test_reactors.loadTestReactor() gfi = MockGlobalFluxInterface(r, cs) - gfi._checkEnergyBalance() + gfi.checkEnergyBalance() class TestGlobalFluxInterfaceWithExecuters(unittest.TestCase): diff --git a/armi/physics/neutronics/tests/test_energyGroups.py b/armi/physics/neutronics/tests/test_energyGroups.py index 23f7d903f8..6cb2b9673b 100644 --- a/armi/physics/neutronics/tests/test_energyGroups.py +++ b/armi/physics/neutronics/tests/test_energyGroups.py @@ -20,7 +20,12 @@ class TestEnergyGroups(unittest.TestCase): def test_invalidGroupStructureType(self): - """Test that the reverse lookup fails on non-existent energy group bounds.""" + """Test that the reverse lookup fails on non-existent energy group bounds. + + .. test:: Check the neutron energy group bounds logic fails correctly for the wrong structure. + :id: T_ARMI_EG_NE0 + :tests: R_ARMI_EG_NE + """ modifier = 1e-5 for groupStructureType in energyGroups.GROUP_STRUCTURE: energyBounds = energyGroups.getGroupStructure(groupStructureType) @@ -32,6 +37,10 @@ def test_consistenciesBetweenGroupStructureAndGroupStructureType(self): """ Test that the reverse lookup of the energy group structures work. + .. test:: Check the neutron energy group bounds for a given group structure. + :id: T_ARMI_EG_NE1 + :tests: R_ARMI_EG_NE + Notes ----- Several group structures point to the same energy group structure so the reverse lookup will fail to diff --git a/armi/reactor/assemblies.py b/armi/reactor/assemblies.py index bff1866e9b..66e3c14590 100644 --- a/armi/reactor/assemblies.py +++ b/armi/reactor/assemblies.py @@ -180,7 +180,6 @@ def add(self, obj: blocks.Block): .. impl:: Assemblies are made up of type Block. :id: I_ARMI_ASSEM_BLOCKS :implements: R_ARMI_ASSEM_BLOCKS - """ composites.Composite.add(self, obj) obj.spatialLocator = self.spatialGrid[0, 0, len(self) - 1] @@ -227,7 +226,6 @@ def getLocation(self): .. impl:: Assembly location is retrievable. :id: I_ARMI_ASSEM_POSI0 :implements: R_ARMI_ASSEM_POSI - """ # just use ring and position, not axial (which is 0) if not self.parent: @@ -1229,6 +1227,13 @@ def rotate(self, rad): class HexAssembly(Assembly): + """Placeholder, so users can explicitly define a hex-based assembly. + + .. impl:: Assembly of hex blocks. + :id: I_ARMI_ASSEM_HEX + :implements: R_ARMI_ASSEM_HEX + """ + pass diff --git a/armi/reactor/blueprints/componentBlueprint.py b/armi/reactor/blueprints/componentBlueprint.py index 2442295179..f37e2f8a3f 100644 --- a/armi/reactor/blueprints/componentBlueprint.py +++ b/armi/reactor/blueprints/componentBlueprint.py @@ -291,6 +291,10 @@ def insertDepletableNuclideKeys(c, blueprint): """ Auto update number density keys on all DEPLETABLE components. + .. impl:: Insert any depletable blueprint flags onto this component. + :id: I_ARMI_BP_NUC_FLAGS0 + :implements: R_ARMI_BP_NUC_FLAGS + Notes ----- This should be moved to a neutronics/depletion plugin hook but requires some diff --git a/armi/reactor/blueprints/isotopicOptions.py b/armi/reactor/blueprints/isotopicOptions.py index 0e37b4cfbd..ead85253fa 100644 --- a/armi/reactor/blueprints/isotopicOptions.py +++ b/armi/reactor/blueprints/isotopicOptions.py @@ -61,6 +61,10 @@ class NuclideFlag(yamlize.Object): physics option. However, restarting from that case with different cross section needs is challenging. + .. impl:: The blueprint object that represents a nuclide flag. + :id: I_ARMI_BP_NUC_FLAGS1 + :implements: R_ARMI_BP_NUC_FLAGS + Attributes ---------- nuclideName : str diff --git a/armi/reactor/blueprints/tests/test_blockBlueprints.py b/armi/reactor/blueprints/tests/test_blockBlueprints.py index cbab444fd5..a06964b598 100644 --- a/armi/reactor/blueprints/tests/test_blockBlueprints.py +++ b/armi/reactor/blueprints/tests/test_blockBlueprints.py @@ -310,7 +310,7 @@ def test_explicitFlags(self): Test flags are created from blueprint file. .. test:: Nuc flags can define depletable objects. - :id: T_ARMI_BP_NUC_FLAGS + :id: T_ARMI_BP_NUC_FLAGS0 :tests: R_ARMI_BP_NUC_FLAGS """ a1 = self.blueprints.assemDesigns.bySpecifier["IC"].construct( diff --git a/armi/reactor/blueprints/tests/test_blueprints.py b/armi/reactor/blueprints/tests/test_blueprints.py index 9661ad8201..a96fceadda 100644 --- a/armi/reactor/blueprints/tests/test_blueprints.py +++ b/armi/reactor/blueprints/tests/test_blueprints.py @@ -102,7 +102,12 @@ def test_componentDimensions(self): self.assertAlmostEqual(fuel.getDimension("mult"), 169) def test_traceNuclides(self): - """Ensure that armi.reactor.blueprints.componentBlueprint.insertDepletableNuclideKeys runs.""" + """Ensure that armi.reactor.blueprints.componentBlueprint.insertDepletableNuclideKeys runs. + + .. test:: Users marking components as depletable will affect number densities. + :id: T_ARMI_BP_NUC_FLAGS1 + :tests: R_ARMI_BP_NUC_FLAGS + """ fuel = ( self.blueprints.constructAssem(self.cs, "igniter fuel") .getFirstBlock(Flags.FUEL) diff --git a/armi/reactor/converters/axialExpansionChanger.py b/armi/reactor/converters/axialExpansionChanger.py index aed698541f..3b5f391bc7 100644 --- a/armi/reactor/converters/axialExpansionChanger.py +++ b/armi/reactor/converters/axialExpansionChanger.py @@ -114,6 +114,10 @@ class AxialExpansionChanger: :id: I_ARMI_AXIAL_EXP :implements: R_ARMI_AXIAL_EXP + .. impl:: Preserve the total height of an ARMI assembly, during expansion. + :id: I_ARMI_ASSEM_HEIGHT_PRES + :implements: R_ARMI_ASSEM_HEIGHT_PRES + Attributes ---------- linked : :py:class:`AssemblyAxialLinkage` diff --git a/armi/reactor/converters/geometryConverters.py b/armi/reactor/converters/geometryConverters.py index e9b8777c65..418f320a9b 100644 --- a/armi/reactor/converters/geometryConverters.py +++ b/armi/reactor/converters/geometryConverters.py @@ -1194,11 +1194,15 @@ def reset(self): class HexToRZConverter(HexToRZThetaConverter): - r""" + """ Create a new reactor with R-Z coordinates from the Hexagonal-Z reactor. - This is a subclass of the HexToRZThetaConverter. See the HexToRZThetaConverter for explanation and setup of - the converterSettings. + This is a subclass of the HexToRZThetaConverter. See the HexToRZThetaConverter for + explanation and setup of the converterSettings. + + .. impl:: Tool to convert a hex core to an RZTheta core. + :id: I_ARMI_CONV_3DHEX_TO_2DRZ + :implements: R_ARMI_CONV_3DHEX_TO_2DRZ """ _GEOMETRY_TYPE = geometry.GeomType.RZ diff --git a/armi/reactor/converters/tests/test_geometryConverters.py b/armi/reactor/converters/tests/test_geometryConverters.py index f704262b7e..5a1b52c974 100644 --- a/armi/reactor/converters/tests/test_geometryConverters.py +++ b/armi/reactor/converters/tests/test_geometryConverters.py @@ -40,7 +40,7 @@ def setUp(self): self.cs = self.o.cs def test_addRing(self): - r"""Tests that the addRing method adds the correct number of fuel assemblies to the test reactor.""" + """Tests that the addRing method adds the correct number of fuel assemblies to the test reactor.""" converter = geometryConverters.FuelAssemNumModifier(self.cs) converter.numFuelAssems = 7 converter.ringsToAdd = 1 * ["radial shield"] @@ -65,7 +65,7 @@ def test_addRing(self): ) # should wind up with 11 reflector assemblies per 1/3rd core def test_setNumberOfFuelAssems(self): - r"""Tests that the setNumberOfFuelAssems method properly changes the number of fuel assemblies.""" + """Tests that the setNumberOfFuelAssems method properly changes the number of fuel assemblies.""" # tests ability to add fuel assemblies converter = geometryConverters.FuelAssemNumModifier(self.cs) converter.numFuelAssems = 60 @@ -142,6 +142,12 @@ def tearDown(self): del self.r def test_convert(self): + """Test the HexToRZConverter. + + .. test:: Convert a 3D hex reactor core to an RZ-Theta core. + :id: T_ARMI_CONV_3DHEX_TO_2DRZ + :tests: R_ARMI_CONV_3DHEX_TO_2DRZ + """ # make the reactor smaller, because of a test parallelization edge case for ring in [9, 8, 7, 6, 5, 4, 3]: self.r.core.removeAssembliesInRing(ring, self.o.cs) diff --git a/armi/reactor/grids/structuredgrid.py b/armi/reactor/grids/structuredgrid.py index 7b74eaadd6..f37c954330 100644 --- a/armi/reactor/grids/structuredgrid.py +++ b/armi/reactor/grids/structuredgrid.py @@ -292,9 +292,9 @@ def restoreBackup(self): def getCoordinates(self, indices, nativeCoords=False) -> numpy.ndarray: """Return the coordinates of the center of the mesh cell at the given indices in cm. - .. test:: Get the coordinates from a location in a grid. + .. impl:: Get the coordinates from a location in a grid. :id: I_ARMI_GRID_GLOBAL_POS - :tests: R_ARMI_GRID_GLOBAL_POS + :implements: R_ARMI_GRID_GLOBAL_POS """ indices = numpy.array(indices) return self._evaluateMesh(