Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions armi/physics/neutronics/crossSectionGroupManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,13 +451,15 @@ def _getAverageComponentTemperature(self, compIndex):
weights = np.array([self.getWeight(b) / b.getHeight() for b in blocks])
weights /= weights.sum() # normalize by total weight
components = [sorted(b.getComponents())[compIndex] for b in blocks]
weightedAvgComponentMass = sum(w * c.getMass() for w, c in zip(weights, components))
weightedMass = [w * c.getMass() for w, c in zip(weights, components)]
weightedAvgComponentMass = sum(m for m in weightedMass if m > 0.0)
if weightedAvgComponentMass == 0.0:
# if there is no component mass (e.g., gap), do a regular average
return np.mean(np.array([c.temperatureInC for c in components]))
else:
return (
weights.dot(np.array([c.temperatureInC * c.getMass() for c in components])) / weightedAvgComponentMass
sum([c.temperatureInC * mass if mass > 0.0 else 0.0 for c, mass in zip(components, weightedMass)])
/ weightedAvgComponentMass
)

def _performAverageByComponent(self):
Expand Down Expand Up @@ -844,7 +846,10 @@ def _getAverageComponentNucs(self, components, bWeights):
densities = np.zeros(len(allNucNames))
totalWeight = 0.0
for c, bWeight in zip(components, bWeights):
weight = bWeight * c.getArea()
compArea = c.getArea()
if compArea <= 0.0:
continue
weight = bWeight * compArea
totalWeight += weight
densities += weight * np.array(c.getNuclideNumberDensities(allNucNames))
if totalWeight > 0.0:
Expand Down
42 changes: 42 additions & 0 deletions armi/physics/neutronics/tests/test_crossSectionManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

from armi import settings
from armi.context import PLATFORM, Platform
from armi.materials.water import Water
from armi.physics.neutronics import crossSectionGroupManager
from armi.physics.neutronics.const import CONF_CROSS_SECTION
from armi.physics.neutronics.crossSectionGroupManager import (
Expand Down Expand Up @@ -585,6 +586,47 @@ def test_ComponentAverageDuctHet1DCylinder(self):
f"{nuc} temperature should be different from {compTemp} for component {c}",
)

def test_compAverageNegativeVolume(self):
"""Test creation of a representative block when negative-volume components are present.

.. test:: Create representative blocks using a volume-weighted averaging.
:id: T_ARMI_XSGM_CREATE_REPR_BLOCKS2
:tests: R_ARMI_XSGM_CREATE_REPR_BLOCKS
"""
xsgm = self.o.getInterface("xsGroups")
xsgm.interactBOL()

annularFuel = self.r.core.getAssemblies(Flags.FUEL | Flags.ANNULAR, includeBolAssems=True)[0]
# set temperatures of each gap component before performing average
# give the gaps some mass (material is arbitrary)
for i, b in enumerate(annularFuel.getBlocks(Flags.FUEL)):
gaps = b.getComponents(Flags.GAP)
for c in gaps:
c.temperatureInC = 500.0 + 100.0 * i
c.material = Water()
c.setNumberDensities({"H": 0.5, "O": 0.25})
# make some of the negative-volume gaps have positive volume by adjusting liner temperature
liner = b.getComponent(Flags.LINER | Flags.OUTER)
liner.setTemperature(500.0 + 100.0 * i)

xsgm.createRepresentativeBlocks()
xsgm.updateNuclideTemperatures()

reprBlock = xsgm.representativeBlocks["UA"]
for c in reprBlock.getComponents(Flags.GAP):
if c.getName() == "gap3":
# gap3 temp is 700 C because the 500 C and 600 C components have negative volume
self.assertAlmostEqual(c.temperatureInC, 700.0)
elif c.getName() == "gap4":
# gap4 temp is between 500 C and 600 C because the 700C component has negative volume
self.assertLess(c.temperatureInC, 600.0)
self.assertGreater(c.temperatureInC, 500.0)
else:
# other gap components all have positive volume
self.assertAlmostEqual(c.temperatureInC, 600.0)
outerLiner = reprBlock.getComponent(Flags.LINER | Flags.OUTER)
self.assertAlmostEqual(outerLiner.temperatureInC, 600.0)

def test_checkComponentConsistency(self):
xsgm = self.o.getInterface("xsGroups")
xsgm.interactBOL()
Expand Down
Loading