Skip to content

Commit

Permalink
Adding 3 test crumbs for requirements (#1510)
Browse files Browse the repository at this point in the history
  • Loading branch information
john-science authored Dec 4, 2023
1 parent 77623d5 commit 457ca15
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 25 deletions.
52 changes: 51 additions & 1 deletion armi/materials/tests/test_materials.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@

from numpy import testing

from armi import materials, settings
from armi import context, materials, settings
from armi.materials import _MATERIAL_NAMESPACE_ORDER, setMaterialNamespaceOrder
from armi.nucDirectory import nuclideBases
from armi.reactor import blueprints
from armi.tests import mockRunLogs
Expand Down Expand Up @@ -108,6 +109,10 @@ class MaterialFindingTests(unittest.TestCase):
def test_findMaterial(self):
"""Test resolveMaterialClassByName() function.
.. test:: Materials can be grabbed from a list of namespaces.
:id: T_ARMI_MAT_NAMESPACE0
:tests: R_ARMI_MAT_NAMESPACE
.. test:: You can find a material by name.
:id: T_ARMI_MAT_NAME
:tests: R_ARMI_MAT_NAME
Expand Down Expand Up @@ -139,6 +144,51 @@ def test_findMaterial(self):
"Unobtanium", namespaceOrder=["armi.materials"]
)

def __validateMaterialNamespace(self):
"""Helper method to validate the material namespace a little."""
self.assertTrue(isinstance(_MATERIAL_NAMESPACE_ORDER, list))
self.assertGreater(len(_MATERIAL_NAMESPACE_ORDER), 0)
for nameSpace in _MATERIAL_NAMESPACE_ORDER:
self.assertTrue(isinstance(nameSpace, str))

@unittest.skipUnless(context.MPI_RANK == 0, "test only on root node")
def test_namespacing(self):
"""Test loading materials with different material namespaces, to cover how they work.
.. test:: Material can be found in defined packages.
:id: T_ARMI_MAT_NAMESPACE1
:tests: R_ARMI_MAT_NAMESPACE
.. test:: Material namespaces register materials with an order of priority.
:id: T_ARMI_MAT_ORDER
:tests: R_ARMI_MAT_ORDER
"""
# let's do a quick test of getting a material from the default namespace
setMaterialNamespaceOrder(["armi.materials"])
uo2 = materials.resolveMaterialClassByName(
"UO2", namespaceOrder=["armi.materials"]
)
self.assertGreater(uo2().density(500), 0)

# validate the default namespace in ARMI
self.__validateMaterialNamespace()

# show you can add a material namespace
newMats = "armi.utils.tests.test_densityTools"
setMaterialNamespaceOrder(["armi.materials", newMats])
self.__validateMaterialNamespace()

# show that adding a name material namespace provides access to new materials
testMatIgnoreFake = materials.resolveMaterialClassByName(
"TestMaterialIgnoreFake", namespaceOrder=["armi.materials", newMats]
)
for t in range(200, 600):
self.assertEqual(testMatIgnoreFake().density(t), 0)
self.assertEqual(testMatIgnoreFake().pseudoDensity(t), 0)

# for safety, reset the material namespace list and order
setMaterialNamespaceOrder(["armi.materials"])


class Californium_TestCase(_Material_Test, unittest.TestCase):

Expand Down
4 changes: 2 additions & 2 deletions armi/nuclearDataIO/xsNuclides.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def updateBaseNuclide(self):
self._base = nuclideBase

def getMicroXS(self, interaction, group):
r"""Returns the microscopic xs as the ISOTXS value if it exists or a 0 since it doesn't."""
"""Returns the microscopic xs as the ISOTXS value if it exists or a 0 since it doesn't."""
if interaction in self.micros.__dict__:
try:
return self.micros[interaction][group]
Expand All @@ -109,7 +109,7 @@ def getMicroXS(self, interaction, group):
return 0

def getXS(self, interaction):
r"""Get the cross section of a particular interaction.
"""Get the cross section of a particular interaction.
See Also
--------
Expand Down
2 changes: 0 additions & 2 deletions armi/physics/neutronics/macroXSGenerationInterface.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ def __reduce__(self):
)

def invokeHook(self):

# logic here gets messy due to all the default arguments in the calling
# method. There exists a large number of permutations to be handled.

Expand Down Expand Up @@ -169,7 +168,6 @@ def buildMacros(
libType : str, optional
The block attribute containing the desired microscopic XS for this block:
either "micros" for neutron XS or "gammaXS" for gamma XS.
"""
cycle = self.r.p.cycle
self.macrosLastBuiltAt = (
Expand Down
39 changes: 35 additions & 4 deletions armi/physics/neutronics/tests/test_macroXSGenerationInterface.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,51 @@
# limitations under the License.
"""MacroXSGenerationInterface tests."""
import unittest
from collections import defaultdict

from armi.nuclearDataIO import isotxs
from armi.nuclearDataIO.xsCollections import XSCollection
from armi.physics.neutronics.macroXSGenerationInterface import (
MacroXSGenerationInterface,
)
from armi.reactor.tests.test_reactors import loadTestReactor
from armi.reactor.tests.test_reactors import loadTestReactor, reduceTestReactorRings
from armi.settings import Settings
from armi.tests import ISOAA_PATH


class TestMacroXSGenerationInterface(unittest.TestCase):
def test_macroXSGenerationInterface(self):
def test_macroXSGenerationInterfaceBasics(self):
"""Test the macroscopic XS generating interfaces.
.. test::Build macroscopic cross sections for all blocks in the reactor.
:id: T_ARMI_MACRO_XS
:tests: R_ARMI_MACRO_XS
"""
cs = Settings()
_o, r = loadTestReactor()
i = MacroXSGenerationInterface(r, cs)
reduceTestReactorRings(r, cs, 2)

self.assertIsNone(i.macrosLastBuiltAt)
# Before: verify there are no macro XS on each block
for b in r.core.getBlocks():
self.assertIsNone(b.macros)

# create the macro XS interface
i = MacroXSGenerationInterface(r, cs)
self.assertEqual(i.minimumNuclideDensity, 1e-15)
self.assertEqual(i.name, "macroXsGen")

# Mock up a nuclide library
mockLib = isotxs.readBinary(ISOAA_PATH)
mockLib.__dict__["_nuclides"] = defaultdict(
lambda: mockLib.__dict__["_nuclides"]["CAA"], mockLib.__dict__["_nuclides"]
)

# This is the meat of it: build the macro XS
self.assertIsNone(i.macrosLastBuiltAt)
i.buildMacros(mockLib, buildScatterMatrix=False)
self.assertEqual(i.macrosLastBuiltAt, 0)

# After: verify there are macro XS on each block
for b in r.core.getBlocks():
self.assertIsNotNone(b.macros)
self.assertTrue(isinstance(b.macros, XSCollection))
68 changes: 60 additions & 8 deletions armi/physics/tests/test_executers.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,33 @@

"""This module provides tests for the generic Executers."""
import os
import subprocess
import unittest

from armi.physics import executers
from armi.reactor import geometry
from armi.utils import directoryChangers
from armi.physics import executers


class MockReactorParams:
class MockParams:
def __init__(self):
self.cycle = 1
self.timeNode = 2


class MockCoreParams:
pass


class MockCore:
def __init__(self):
# just pick a random geomType
self.geomType = geometry.GeomType.CARTESIAN
self.symmetry = "full"
self.p = MockCoreParams()
self.p = MockParams()


class MockReactor:
def __init__(self):
self.core = MockCore()
self.o = None
self.p = MockReactorParams()
self.p = MockParams()


class TestExecutionOptions(unittest.TestCase):
Expand Down Expand Up @@ -106,3 +103,58 @@ def test_updateRunDir(self):
self.executer.dcType = directoryChangers.ForcedCreationDirectoryChanger
self.executer._updateRunDir("notThisString")
self.assertEqual(self.executer.options.runDir, "runDir")

def test_runExternalExecutable(self):
"""Run an external executable with an Executer.
.. test:: Run an external executable with an Executer.
:id: T_ARMI_EX
:tests: R_ARMI_EX
"""
filePath = "test_runExternalExecutable.py"
outFile = "tmp.txt"

class TestSillyExecuter(executers.Executer):
def run(self, args):
subprocess.run(["python", filePath, args])

with directoryChangers.TemporaryDirectoryChanger():
# build a mock external program (a little Python script)
self.__makeALittleTestProgram(filePath, outFile)

# make sure the output file doesn't exist yet
self.assertFalse(os.path.exists(outFile))

# set up an executer for our little test program
exe = TestSillyExecuter(None, None)
exe.run("")

# make sure the output file exists now
self.assertTrue(os.path.exists(outFile))

# run the executer with options
testString = "some options"
exe.run(testString)

# make sure the output file exists now
self.assertTrue(os.path.exists(outFile))
newTxt = open(outFile, "r").read()
self.assertIn(testString, newTxt)

@staticmethod
def __makeALittleTestProgram(filePath, outFile):
"""Helper method to write a tiny Python script.
We need "an external program" for testing.
"""
txt = f"""import sys
def main():
with open("{outFile}", "w") as f:
f.write(str(sys.argv))
if __name__ == "__main__":
main()
"""
with open(filePath, "w") as f:
f.write(txt)
1 change: 0 additions & 1 deletion armi/tests/test_apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import copy
import unittest

from armi import cli
from armi import configure
from armi import context
from armi import getApp
Expand Down
7 changes: 1 addition & 6 deletions armi/tests/test_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,11 @@

import yamlize

from armi import getPluginManagerOrFail
from armi import interfaces
from armi import plugins
from armi import settings
from armi.physics.neutronics import NeutronicsPlugin
from armi.reactor import parameters
from armi.reactor.blocks import Block, HexBlock
from armi.reactor.parameters import ParamLocation
from armi.reactor.parameters.parameterCollections import collectPluginParameters
from armi.utils import units
from armi.reactor.blocks import Block


class TestPluginBasics(unittest.TestCase):
Expand Down
15 changes: 14 additions & 1 deletion armi/utils/tests/test_densityTools.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,25 @@
"""Test densityTools."""
import unittest

from armi.materials.material import Material
from armi.materials.uraniumOxide import UO2
from armi.nucDirectory import elements, nuclideBases
from armi.utils import densityTools


class TestMaterialIgnoreFake(Material):
"""A test material that needs to be stored in a different namespace.
For tests in: armi.materials.tests.test_materials.py
"""

def pseudoDensity(self, Tk=None, Tc=None):
return 0.0

def density(self, Tk=None, Tc=None):
return 0.0


class TestDensityTools(unittest.TestCase):
def test_expandElementalMassFracsToNuclides(self):
"""
Expand Down Expand Up @@ -50,7 +64,6 @@ def test_expandElementalZeroMassFrac(self):
self.assertAlmostEqual(sum(mass.values()), 1.0)

def test_getChemicals(self):

u235 = nuclideBases.byName["U235"]
u238 = nuclideBases.byName["U238"]
o16 = nuclideBases.byName["O16"]
Expand Down

0 comments on commit 457ca15

Please sign in to comment.