# Copyright 2019 TerraPower, LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for the composite pattern."""
from copy import deepcopy
import unittest
from armi import nuclearDataIO
from armi import runLog
from armi import settings
from armi import utils
from armi.nucDirectory import nucDir, nuclideBases
from armi.physics.neutronics.fissionProductModel.tests.test_lumpedFissionProduct import (
getDummyLFPFile,
)
from armi.reactor import assemblies
from armi.reactor import components
from armi.reactor import composites
from armi.reactor import grids
from armi.reactor import parameters
from armi.reactor.blueprints import assemblyBlueprint
from armi.reactor.components import basicShapes
from armi.reactor.composites import getReactionRateDict
from armi.reactor.flags import Flags, TypeSpec
from armi.reactor.tests.test_blocks import loadTestBlock
from armi.tests import ISOAA_PATH
[docs]class MockBP:
allNuclidesInProblem = set(nuclideBases.byName.keys())
""":meta hide-value:"""
activeNuclides = allNuclidesInProblem
""":meta hide-value:"""
inactiveNuclides = set()
elementsToExpand = set()
customIsotopics = {}
[docs]def getDummyParamDefs():
dummyDefs = parameters.ParameterDefinitionCollection()
with dummyDefs.createBuilder() as pb:
pb.defParam("type", units=utils.units.UNITLESS, description="Fake type")
return dummyDefs
_testGrid = grids.CartesianGrid.fromRectangle(0.01, 0.01)
[docs]class DummyComposite(composites.Composite):
pDefs = getDummyParamDefs()
def __init__(self, name, i=0):
composites.Composite.__init__(self, name)
self.p.type = name
self.spatialLocator = grids.IndexLocation(i, i, i, _testGrid)
[docs]class DummyLeaf(composites.Composite):
pDefs = getDummyParamDefs()
def __init__(self, name, i=0):
composites.Composite.__init__(self, name)
self.p.type = name
self.spatialLocator = grids.IndexLocation(i, i, i, _testGrid)
[docs] def getChildren(
self, deep=False, generationNum=1, includeMaterials=False, predicate=None
):
"""Return empty list, representing that this object has no children."""
return []
[docs] def getChildrenWithFlags(self, typeSpec: TypeSpec, exactMatch=True):
"""Return empty list, representing that this object has no children."""
return []
[docs] def getBoundingCircleOuterDiameter(self, Tc=None, cold=False):
return 1.0
[docs] def iterComponents(self, typeSpec=None, exact=False):
if self.hasFlags(typeSpec, exact):
yield self
[docs]class TestCompositePattern(unittest.TestCase):
def setUp(self):
self.cs = settings.Settings()
runLog.setVerbosity("error")
container = DummyComposite("inner test fuel", 99)
for i in range(5):
leaf = DummyLeaf("duct {}".format(i), i + 100)
leaf.setType("duct")
container.add(leaf)
nested = DummyComposite("clad", 98)
nested.setType("clad")
self.secondGen = DummyComposite("liner", 97)
self.thirdGen = DummyLeaf("pin 77", 33)
self.secondGen.add(self.thirdGen)
nested.add(self.secondGen)
container.add(nested)
self.container = container
[docs] def test_composite(self):
"""Test basic Composite things.
.. test:: Composites are part of a hierarchical model.
:id: T_ARMI_CMP0
:tests: R_ARMI_CMP
"""
container = self.container
children = container.getChildren()
for child in children:
self.assertEqual(child.parent, container)
allChildren = container.getChildren(deep=True)
self.assertEqual(len(allChildren), 8)
[docs] def test_iterComponents(self):
self.assertIn(self.thirdGen, list(self.container.iterComponents()))
[docs] def test_getChildren(self):
"""Test the get children method.
.. test:: Composites are part of a hierarchical model.
:id: T_ARMI_CMP1
:tests: R_ARMI_CMP
"""
# There are 5 leaves and 1 composite in container. The composite has one leaf.
firstGen = self.container.getChildren()
self.assertEqual(len(firstGen), 6)
secondGen = self.container.getChildren(generationNum=2)
self.assertEqual(len(secondGen), 1)
self.assertIs(secondGen[0], self.secondGen)
third = self.container.getChildren(generationNum=3)
self.assertEqual(len(third), 1)
self.assertIs(third[0], self.thirdGen)
allC = self.container.getChildren(deep=True)
self.assertEqual(len(allC), 8)
onlyLiner = self.container.getChildren(
deep=True, predicate=lambda o: o.p.type == "liner"
)
self.assertEqual(len(onlyLiner), 1)
[docs] def test_getName(self):
"""Test the getName method.
.. test:: Composites names should be accessible.
:id: T_ARMI_CMP_GET_NAME
:tests: R_ARMI_CMP_GET_NAME
"""
self.assertEqual(self.secondGen.getName(), "liner")
self.assertEqual(self.thirdGen.getName(), "pin 77")
self.assertEqual(self.secondGen.getName(), "liner")
self.assertEqual(self.container.getName(), "inner test fuel")
[docs] def test_sort(self):
# in this case, the children should start sorted
c0 = [c.name for c in self.container.getChildren()]
self.container.sort()
c1 = [c.name for c in self.container.getChildren()]
self.assertNotEqual(c0, c1)
# verify repeated sortings behave
for _ in range(3):
self.container.sort()
ci = [c.name for c in self.container.getChildren()]
self.assertEqual(c1, ci)
# break the order
children = self.container.getChildren()
self.container._children = children[2:] + children[:2]
c2 = [c.name for c in self.container.getChildren()]
self.assertNotEqual(c1, c2)
# verify the sort order
self.container.sort()
c3 = [c.name for c in self.container.getChildren()]
self.assertEqual(c1, c3)
[docs] def test_areChildernOfType(self):
expectedResults = [False, False, False, False, False, True]
for i, b in enumerate(self.container.doChildrenHaveFlags(Flags.CLAD)):
self.assertEqual(b, expectedResults[i])
[docs] def test_containsAtLeastOneChildOfType(self):
c = self.container
self.assertTrue(c.containsAtLeastOneChildWithFlags(Flags.DUCT))
self.assertTrue(c.containsAtLeastOneChildWithFlags(Flags.CLAD))
[docs] def test_containsOnlyChildrenOfType(self):
c = self.container
for b in c:
b.setType("bond")
self.assertTrue(c.containsOnlyChildrenWithFlags(Flags.BOND))
[docs] def test_nameContains(self):
c = self.container
c.setName("test one two three")
self.assertTrue(c.nameContains("one"))
self.assertTrue(c.nameContains("One"))
self.assertTrue(c.nameContains("THREE"))
self.assertFalse(c.nameContains("nope"))
self.assertFalse(c.nameContains(["nope"]))
self.assertTrue(c.nameContains(["one", "TWO", "three"]))
self.assertTrue(c.nameContains(["nope", "dope", "three"]))
[docs] def test_nucSpec(self):
self.assertEqual(self.container._getNuclidesFromSpecifier("U235"), ["U235"])
uNucs = self.container._getNuclidesFromSpecifier("U")
self.assertIn("U235", uNucs)
self.assertIn("U241", uNucs)
self.assertIn("U227", uNucs)
self.assertEqual(
self.container._getNuclidesFromSpecifier(["U238", "U235"]), ["U235", "U238"]
)
uzr = self.container._getNuclidesFromSpecifier(["U238", "U235", "ZR"])
self.assertIn("U235", uzr)
self.assertIn("ZR92", uzr)
self.assertNotIn("ZR", uzr)
puIsos = self.container._getNuclidesFromSpecifier(
["PU"]
) # PU is special because it has no natural isotopics
self.assertIn("PU239", puIsos)
self.assertNotIn("PU", puIsos)
self.assertEqual(
self.container._getNuclidesFromSpecifier(["FE", "FE56"]).count("FE56"), 1
)
[docs] def test_hasFlags(self):
"""Ensure flags are queryable.
.. test:: Flags can be queried.
:id: T_ARMI_CMP_FLAG
:tests: R_ARMI_CMP_FLAG
"""
self.container.setType("fuel")
self.assertFalse(self.container.hasFlags(Flags.SHIELD | Flags.FUEL, exact=True))
self.assertTrue(self.container.hasFlags(Flags.FUEL))
self.assertTrue(self.container.hasFlags(None))
[docs] def test_hasFlagsSubstring(self):
"""Make sure typespecs with the same word in them no longer match."""
self.container.setType("intercoolant")
self.assertFalse(self.container.hasFlags(Flags.COOLANT))
self.assertFalse(self.container.hasFlags(Flags.COOLANT, exact=True))
self.assertTrue(self.container.hasFlags(Flags.INTERCOOLANT, exact=True))
self.container.setType("innerduct")
self.assertFalse(self.container.hasFlags(Flags.DUCT, exact=True))
[docs] def test_hasFlagsNoTypeSpecified(self):
self.container.setType("fuel")
types = [None, [], [None]]
for t in types:
self.assertTrue(self.container.hasFlags(t))
self.assertFalse(self.container.hasFlags(t, exact=True))
[docs] def test_getBoundingCirlceOuterDiameter(self):
od = self.container.getBoundingCircleOuterDiameter()
self.assertAlmostEqual(od, len(list(self.container.iterComponents())))
[docs] def test_getParamNames(self):
params = self.container.getParamNames()
self.assertEqual(len(params), 3)
self.assertIn("flags", params)
self.assertIn("serialNum", params)
self.assertIn("type", params)
[docs] def test_updateVolume(self):
self.assertAlmostEqual(self.container.getVolume(), 0)
self.container._updateVolume()
self.assertAlmostEqual(self.container.getVolume(), 0)
[docs] def test_expandLFPs(self):
# simple test, with no lumped fission product mappings
numDens = {"NA23": 1.0}
numDens = self.container._expandLFPs(numDens)
self.assertEqual(len(numDens), 1)
# set the lumped fission product mapping
fpd = getDummyLFPFile()
lfps = fpd.createLFPsFromFile()
self.container.setLumpedFissionProducts(lfps)
# get back the lumped fission product mapping, just to check
lfp = self.container.getLumpedFissionProductCollection()
self.assertEqual(len(lfp), 3)
self.assertIn("LFP35", lfp)
self.assertIn("LFP38", lfp)
self.assertIn("LFP39", lfp)
# quick test WITH some lumped fission products in the mix
numDens = {"NA23": 1.0, "LFP35": 2.0}
numDens = self.container._expandLFPs(numDens)
self.assertEqual(len(numDens), 9)
self.assertEqual(numDens["MO99"], 0)
[docs] def test_getIntegratedMgFlux(self):
mgFlux = self.container.getIntegratedMgFlux()
self.assertEqual(mgFlux, [0.0])
[docs] def test_getReactionRates(self):
rRates = self.container.getReactionRates("U235")
self.assertEqual(len(rRates), 6)
self.assertEqual(sum([r for r in rRates.values()]), 0)
[docs] def test_syncParameters(self):
data = [{"serialNum": 123}, {"flags": "FAKE"}]
numSynced = self.container._syncParameters(data, {})
self.assertEqual(numSynced, 2)
[docs]class TestCompositeTree(unittest.TestCase):
blueprintYaml = """
name: test assembly
height: [1, 1] # 2 blocks
axial mesh points: [1, 1]
xs types: [A, A]
specifier: AA
blocks:
- &block_metal_fuel
name: metal fuel
fuel: &component_metal_fuel_fuel
shape: Circle
material: UZr
Tinput: 500
Thot: 500.0
id: 0.0
od: 1.0
mult: 7
clad: &component_metal_fuel_clad
shape: Circle
material: HT9
Tinput: 450.0
Thot: 450.0
id: 1.09
od: 1.1
mult: 7
bond: &component_metal_fuel_bond
shape: Circle
material: Sodium
Tinput: 450.0
Thot: 450.0
id: fuel.od
od: clad.id
mult: 7
coolant: &component_metal_fuel_coolant
shape: DerivedShape
material: Sodium
Tinput: 450.0
Thot: 450.0
duct: &component_metal_fuel_duct
shape: Hexagon
material: HT9
Tinput: 25.0
Thot: 450.0
ip: 16.0
mult: 1.0
op: 16.6
- &block_oxide_fuel
name: mox fuel
fuel:
<<: *component_metal_fuel_fuel
material: MOX
clad: *component_metal_fuel_clad
bond: *component_metal_fuel_bond
coolant: *component_metal_fuel_coolant
duct: *component_metal_fuel_duct
"""
def __init__(self, *args, **kwargs):
unittest.TestCase.__init__(self, *args, **kwargs)
self.Block = None
self.r = None
def setUp(self):
self.Block = loadTestBlock()
self.r = self.Block.core.r
self.Block.setHeight(100.0)
self.refDict = {
"U235": 0.00275173784234,
"U238": 0.0217358415457,
"W182": 1.09115150103e-05,
"W183": 5.89214392093e-06,
"W184": 1.26159558164e-05,
"W186": 1.17057432664e-05,
"V": 2e-2,
"NA23": 2e-2,
"ZR": 0.00709003962772,
}
self.Block.setNumberDensities(self.refDict)
[docs] def test_ordering(self):
a = assemblies.Assembly("dummy")
a.spatialGrid = grids.axialUnitGrid(2, armiObject=a)
otherBlock = deepcopy(self.Block)
a.add(self.Block)
a.add(otherBlock)
self.assertTrue(self.Block < otherBlock)
locator = self.Block.spatialLocator
self.Block.spatialLocator = otherBlock.spatialLocator
otherBlock.spatialLocator = locator
self.assertTrue(otherBlock < self.Block)
[docs] def test_summing(self):
a = assemblies.Assembly("dummy")
a.spatialGrid = grids.axialUnitGrid(2, armiObject=a)
otherBlock = deepcopy(self.Block)
a.add(self.Block)
a.add(otherBlock)
b = self.Block + otherBlock
self.assertEqual(len(b), 26)
self.assertFalse(b[0].is3D)
self.assertIn("Circle", str(b[0]))
self.assertFalse(b[-1].is3D)
self.assertIn("Hexagon", str(b[-1]))
[docs] def test_constituentReport(self):
runLog.info(self.r.core.constituentReport())
runLog.info(self.r.core.getFirstAssembly().constituentReport())
runLog.info(self.r.core.getFirstBlock().constituentReport())
runLog.info(self.r.core.getFirstBlock().getComponents()[0].constituentReport())
[docs] def test_getNuclides(self):
"""
The getNuclides should return all keys that have ever been in this block, including values
that are at trace.
"""
cur = self.Block.getNuclides()
ref = self.refDict.keys()
for key in ref:
self.assertIn(key, cur)
self.assertIn("FE", cur) # this is in at trace value.
[docs] def test_getFuelMass(self):
"""
This test creates a dummy assembly and ensures that the assembly, block, and fuel component
masses are consistent. `getFuelMass` ensures that the fuel component is used to `getMass`.
"""
cs = settings.Settings()
assemDesign = assemblyBlueprint.AssemblyBlueprint.load(self.blueprintYaml)
a = assemDesign.construct(cs, MockBP)
fuelMass = 0.0
for b in a:
fuel = b.getComponent(Flags.FUEL)
fuelMass += fuel.getMass()
self.assertEqual(b.getFuelMass(), fuel.getMass())
self.assertEqual(fuelMass, a.getFuelMass())
[docs] def test_getChildrenIncludeMaterials(self):
"""Test that the ``StateRetainer`` retains material properties when they are modified."""
cs = settings.Settings()
assemDesign = assemblyBlueprint.AssemblyBlueprint.load(self.blueprintYaml)
a = assemDesign.construct(cs, MockBP)
component = a[0][0]
referenceDensity = component.material.pseudoDensity(Tc=200)
self.assertEqual(component.material.pseudoDensity(Tc=200), referenceDensity)
[docs] def test_getHMMass(self):
fuelDims = {"Tinput": 273.0, "Thot": 273.0, "od": 0.76, "id": 0.0, "mult": 1.0}
self.fuelComponent = components.Circle("fuel", "UZr", **fuelDims)
self.Block.add(self.fuelComponent)
self.Block.clearNumberDensities()
self.refDict = {
"U235": 0.00275173784234,
"U238": 0.0217358415457,
"W182": 1.09115150103e-05,
"W183": 5.89214392093e-06,
"W184": 1.26159558164e-05,
"W186": 1.17057432664e-05,
"V": 3e-2,
"NA23": 2e-2,
"ZR": 0.00709003962772,
}
self.Block.setNumberDensities(self.refDict)
cur = self.Block.getHMMass()
mass = 0.0
for nucName in self.refDict.keys():
if nucDir.isHeavyMetal(nucName):
mass += self.Block.getMass(nucName)
places = 6
self.assertAlmostEqual(cur, mass, places=places)
[docs] def test_getFPMass(self):
fuelDims = {"Tinput": 273.0, "Thot": 273.0, "od": 0.76, "id": 0.0, "mult": 1.0}
self.fuelComponent = components.Circle("fuel", "UZr", **fuelDims)
self.fuelComponent.material.setMassFrac("LFP38", 0.25)
self.Block.add(self.fuelComponent)
refDict = {"LFP35": 0.1, "LFP38": 0.05, "LFP39": 0.7}
self.fuelComponent.setNumberDensities(refDict)
cur = self.Block.getFPMass()
mass = 0.0
for nucName in refDict.keys():
mass += self.Block.getMass(nucName)
ref = mass
places = 6
self.assertAlmostEqual(cur, ref, places=places)
[docs] def test_getFissileMass(self):
cur = self.Block.getFissileMass()
mass = 0.0
for nucName in self.refDict.keys():
if nucName in nuclideBases.NuclideBase.fissile:
mass += self.Block.getMass(nucName)
ref = mass
places = 6
self.assertAlmostEqual(cur, ref, places=places)
[docs] def test_getMaxParam(self):
"""Test getMaxParam().
.. test:: Composites have parameter collections.
:id: T_ARMI_CMP_PARAMS0
:tests: R_ARMI_CMP_PARAMS
"""
for ci, c in enumerate(self.Block):
if isinstance(c, basicShapes.Circle):
c.p.id = ci
lastSeen = c
lastIndex = ci
cMax, comp = self.Block.getMaxParam("id", returnObj=True)
self.assertEqual(cMax, lastIndex)
self.assertIs(comp, lastSeen)
[docs] def test_getMinParam(self):
"""Test getMinParam().
.. test:: Composites have parameter collections.
:id: T_ARMI_CMP_PARAMS1
:tests: R_ARMI_CMP_PARAMS
"""
for ci, c in reversed(list(enumerate(self.Block))):
if isinstance(c, basicShapes.Circle):
c.p.id = ci
lastSeen = c
lastIndex = ci
cMax, comp = self.Block.getMinParam("id", returnObj=True)
self.assertEqual(cMax, lastIndex)
self.assertIs(comp, lastSeen)
[docs]class TestFlagSerializer(unittest.TestCase):
[docs] class TestFlagsA(utils.Flag):
A = utils.flags.auto()
B = utils.flags.auto()
C = utils.flags.auto()
D = utils.flags.auto()
[docs] class TestFlagsB(utils.Flag):
A = utils.flags.auto()
B = utils.flags.auto()
BPRIME = utils.flags.auto()
C = utils.flags.auto()
D = utils.flags.auto()
[docs] def test_flagSerialization(self):
data = [
Flags.FUEL,
Flags.FUEL | Flags.INNER,
Flags.A | Flags.B | Flags.CONTROL,
]
flagsArray, attrs = composites.FlagSerializer.pack(data)
data2 = composites.FlagSerializer.unpack(
flagsArray, composites.FlagSerializer.version, attrs
)
self.assertEqual(data, data2)
# discrepant versions
with self.assertRaises(ValueError):
data2 = composites.FlagSerializer.unpack(flagsArray, "0", attrs)
# missing flags in current version Flags
attrs["flag_order"].append("NONEXISTANTFLAG")
with self.assertRaises(ValueError):
data2 = composites.FlagSerializer.unpack(
flagsArray, composites.FlagSerializer.version, attrs
)
[docs] def test_flagConversion(self):
data = [
self.TestFlagsA.A,
self.TestFlagsA.A | self.TestFlagsA.C,
self.TestFlagsA.A | self.TestFlagsA.C | self.TestFlagsA.D,
]
serialized, attrs = composites.FlagSerializer._packImpl(data, self.TestFlagsA)
data2 = composites.FlagSerializer._unpackImpl(
serialized, composites.FlagSerializer.version, attrs, self.TestFlagsB
)
expected = [
self.TestFlagsB.A,
self.TestFlagsB.A | self.TestFlagsB.C,
self.TestFlagsB.A | self.TestFlagsB.C | self.TestFlagsB.D,
]
self.assertEqual(data2, expected)
[docs]class TestMiscMethods(unittest.TestCase):
"""
Test a variety of methods on the composite.
these may get moved to composted classes in the future.
"""
def setUp(self):
self.obj = loadTestBlock()
[docs] def test_setMass(self):
"""Test setting and retrieving mass.
.. test:: Mass of a composite is retrievable.
:id: T_ARMI_CMP_GET_MASS
:tests: R_ARMI_CMP_GET_MASS
"""
masses = {"U235": 5.0, "U238": 3.0}
self.obj.setMasses(masses)
self.assertAlmostEqual(self.obj.getMass("U235"), 5.0)
self.assertAlmostEqual(self.obj.getMass("U238"), 3.0)
self.assertAlmostEqual(self.obj.getMass(), 8.0)
self.obj.addMasses(masses)
self.assertAlmostEqual(self.obj.getMass("U238"), 6.0)
# make sure it works with groups of groups
group = composites.Composite("group")
group.add(self.obj)
group.add(loadTestBlock())
group.setMass("U235", 5)
self.assertAlmostEqual(group.getMass("U235"), 5)
# ad a second block, and confirm it works
group.add(loadTestBlock())
self.assertGreater(group.getMass("U235"), 5)
self.assertAlmostEqual(group.getMass("U235"), 1364.28376185)
[docs] def test_getNumberDensities(self):
"""Get number densities from composite.
.. test:: Number density of composite is retrievable.
:id: T_ARMI_CMP_GET_NDENS0
:tests: R_ARMI_CMP_GET_NDENS
"""
# verify the number densities from the composite
ndens = self.obj.getNumberDensities()
self.assertAlmostEqual(0.0001096, ndens["SI"], 7)
self.assertAlmostEqual(0.0000368, ndens["W"], 7)
ndens = self.obj.getNumberDensity("SI")
self.assertAlmostEqual(0.0001096, ndens, 7)
# sum nuc densities from children components
totalVolume = self.obj.getVolume()
childDensities = {}
for o in self.obj.getChildren():
m = o.getVolume()
d = o.getNumberDensities()
for nuc, val in d.items():
if nuc not in childDensities:
childDensities[nuc] = val * (m / totalVolume)
else:
childDensities[nuc] += val * (m / totalVolume)
# verify the children match this composite
for nuc in ["FE", "SI"]:
self.assertAlmostEqual(
self.obj.getNumberDensity(nuc), childDensities[nuc], 4, msg=nuc
)
[docs] def test_getNumberDensitiesWithExpandedFissionProducts(self):
"""Get number densities from composite.
.. test:: Get number densities.
:id: T_ARMI_CMP_NUC
:tests: R_ARMI_CMP_NUC
"""
# verify the number densities from the composite
ndens = self.obj.getNumberDensities(expandFissionProducts=True)
self.assertAlmostEqual(0.0001096, ndens["SI"], 7)
self.assertAlmostEqual(0.0000368, ndens["W"], 7)
ndens = self.obj.getNumberDensity("SI")
self.assertAlmostEqual(0.0001096, ndens, 7)
# set the lumped fission product mapping
fpd = getDummyLFPFile()
lfps = fpd.createLFPsFromFile()
self.obj.setLumpedFissionProducts(lfps)
# sum nuc densities from children components
totalVolume = self.obj.getVolume()
childDensities = {}
for o in self.obj.getChildren():
# get the number densities with and without fission products
d0 = o.getNumberDensities(expandFissionProducts=False)
d = o.getNumberDensities(expandFissionProducts=True)
# prove that the expanded fission products have more isotopes
if len(d0) > 0:
self.assertGreater(len(d), len(d0))
# sum the child nuclide densites (weighted by mass fraction)
m = o.getVolume()
for nuc, val in d.items():
if nuc not in childDensities:
childDensities[nuc] = val * (m / totalVolume)
else:
childDensities[nuc] += val * (m / totalVolume)
# verify the children match this composite
for nuc in ["FE", "SI"]:
self.assertAlmostEqual(
self.obj.getNumberDensity(nuc), childDensities[nuc], 4, msg=nuc
)
[docs] def test_dimensionReport(self):
report = self.obj.setComponentDimensionsReport()
self.assertEqual(len(report), len(self.obj))
[docs] def test_getAtomicWeight(self):
weight = self.obj.getAtomicWeight()
self.assertTrue(50 < weight < 100)
[docs] def test_copyParamsToChildren(self):
self.obj.p.percentBu = 5
self.obj.copyParamsToChildren(["percentBu"])
for child in self.obj:
self.assertEqual(child.p.percentBu, self.obj.p.percentBu)
[docs] def test_copyParamsFrom(self):
obj2 = loadTestBlock()
obj2.p.percentBu = 15.2
self.obj.copyParamsFrom(obj2)
self.assertEqual(obj2.p.percentBu, self.obj.p.percentBu)
[docs]class TestGetReactionRateDict(unittest.TestCase):
[docs] def test_getReactionRateDict(self):
lib = nuclearDataIO.isotxs.readBinary(ISOAA_PATH)
rxRatesDict = getReactionRateDict(
nucName="PU239", lib=lib, xsSuffix="AA", mgFlux=1, nDens=1
)
self.assertEqual(rxRatesDict["nG"], sum(lib["PU39AA"].micros.nGamma))