Skip to content

Commit

Permalink
Merge branch 'main' into uniformMeshFix
Browse files Browse the repository at this point in the history
  • Loading branch information
jakehader committed Aug 19, 2022
2 parents fa64f14 + 44f287d commit 6b7ebaa
Show file tree
Hide file tree
Showing 17 changed files with 356 additions and 255 deletions.
23 changes: 0 additions & 23 deletions armi/__init__.py
Expand Up @@ -113,29 +113,6 @@ def isStableReleaseVersion(version=None):
return "-" not in version


def _registerUserPlugin(plugManager, userPluginName):
"""Register one individual user plugin by name."""
try:
pluginMod = importlib.import_module(userPluginName)
except ImportError:
runLog.error(
f"The plugin `{userPluginName}` could not be imported. Verify it is installed "
"in your current environment or adjust the active user plugins."
)
raise

# Each plugin must have a constant called PLUGIN pointing to the plugin class.
# This allows discoverability without being overly restrictive in class names
try:
plugManager.register(pluginMod.PLUGIN)
except AttributeError:
runLog.error(
f"The plugin `{userPluginName}` does not have a PLUGIN constant defined. "
"This constant is required in user plugins. Please adjust plugin."
)
raise


def init(choice=None, fName=None, cs=None):
"""
Scan a directory for armi inputs and load one to interact with.
Expand Down
2 changes: 0 additions & 2 deletions armi/apps.py
Expand Up @@ -259,8 +259,6 @@ def registerUserPlugins(self, pluginPaths):
because they are defined during run time, not import time. As such, we
restrict their flexibility and power as compared to the usual ArmiPlugins.
"""
self.__initNewPlugins()

for pluginPath in pluginPaths:
if ".py:" in pluginPath:
# The path is of the form: /path/to/why.py:MyPlugin
Expand Down
8 changes: 4 additions & 4 deletions armi/physics/neutronics/parameters.py
Expand Up @@ -729,7 +729,7 @@ def linPowByPinGamma(self, value):
units="n/cm^2/s",
description="Neutron flux above 100keV at hexagon block corners",
location=ParamLocation.CORNERS,
saveToDB=False,
saveToDB=True,
)

# This quantity should eventually be part of category 'detailedAxialExpansion'
Expand All @@ -739,7 +739,7 @@ def linPowByPinGamma(self, value):
units=None,
description="Fraction of flux above 100keV at points within the block",
location=ParamLocation.CHILDREN,
saveToDB=False,
saveToDB=True,
)

# This quantity should eventually be part of category 'detailedAxialExpansion'
Expand All @@ -750,7 +750,7 @@ def linPowByPinGamma(self, value):
description="displacements per atom at points within the block",
location=ParamLocation.CHILDREN,
categories=["cumulative"],
saveToDB=False,
saveToDB=True,
default=0.0,
)

Expand All @@ -761,7 +761,7 @@ def linPowByPinGamma(self, value):
units="dpa/s",
description="Current time derivative of the displacement per atoms at points within the block",
location=ParamLocation.CHILDREN,
saveToDB=False,
saveToDB=True,
)

pb.defParam(
Expand Down
37 changes: 0 additions & 37 deletions armi/reactor/blocks.py
Expand Up @@ -2205,40 +2205,3 @@ def axialOuter(self):
def verifyBlockDims(self):
"""Perform dimension checks related to ThetaRZ blocks."""
return


class Point(Block):
"""
Points quack like blocks.
This Point object represents a single point in space within a Block.
The Point object masquerades as a Block so that any Block parameter
(such as DPA) can be assigned to it with the same functionality.
"""

def __init__(self, name=None):

super(Point, self).__init__(name)

self.xyz = [
0.0,
0.0,
0.0,
] # initialize the x,y,z coordinates of this Point object.

params = ["detailedDpaRate", "detailedDpaPeakRate"]
for param in params:
self.p[param] = 0.0

def getVolume(self):
"""points have no volume scaling; point flux are not volume-integrated"""
return 1.0

def getBurnupPeakingFactor(self):
"""peaking makes no sense for points"""
return 1.0

def getWettedPerimeter(self):
return 0.0

def getHydraulicDiameter(self):
return 0.0
10 changes: 0 additions & 10 deletions armi/reactor/blueprints/blockBlueprint.py
Expand Up @@ -119,16 +119,6 @@ def construct(
materialInput, componentDesign
)
c = componentDesign.construct(blueprint, filteredMaterialInput)
if cs["inputHeightsConsideredHot"]:
if "group" in c.name:
for component in c:
component.applyHotHeightDensityReduction()
componentBlueprint.insertDepletableNuclideKeys(
component, blueprint
)
else:
c.applyHotHeightDensityReduction()
componentBlueprint.insertDepletableNuclideKeys(c, blueprint)
components[c.name] = c
if spatialGrid:
componentLocators = gridDesign.getMultiLocator(
Expand Down
13 changes: 1 addition & 12 deletions armi/reactor/blueprints/tests/test_blockBlueprints.py
Expand Up @@ -339,20 +339,9 @@ def test_densityConsistentWithComponentConstructor(self):
delta=biggerDelta,
)

# This should be equal, but block construction calls applyHotHeightDensityReduction
# while programmatic construction allows components to exist in a state where
# their density is not consistent with material density.
self.assertNotAlmostEqual(
self.assertAlmostEqual(
clad.getMassDensity(),
programaticClad.getMassDensity(),
delta=biggerDelta,
)
# its off by a factor of thermal expansion
self.assertNotAlmostEqual(
clad.getMassDensity(),
programaticClad.getMassDensity()
* programaticClad.getThermalExpansionFactor(),
delta=biggerDelta,
)


Expand Down
14 changes: 10 additions & 4 deletions armi/reactor/components/component.py
Expand Up @@ -329,13 +329,14 @@ def setProperties(self, properties):

def applyMaterialMassFracsToNumberDensities(self):
"""
Set number densities for the component based on material mass fractions using hot temperatures.
Set the hot number densities for the component based on material mass fractions/density.
Notes
-----
- the density returned accounts for the radial expansion of the component
- the density returned accounts for the expansion of the component
due to the difference in self.inputTemperatureInC and self.temperatureInC
- axial expansion effects are not included here.
- After the expansion, the density of the component should reflect the 3d
density of the material
See Also
--------
Expand All @@ -348,10 +349,12 @@ def applyMaterialMassFracsToNumberDensities(self):
self.p.numberDensities = densityTools.getNDensFromMasses(
density, self.material.p.massFrac
)
self.applyHotHeightDensityReduction()

def applyHotHeightDensityReduction(self):
"""
Adjust number densities to account for prescribed hot block heights (axial expansion).
Adjust number densities to account for hot block heights (axial expansion)
(crucial for preserving 3D density).
Notes
-----
Expand All @@ -363,6 +366,9 @@ def applyHotHeightDensityReduction(self):
--------
self.applyMaterialMassFracsToNumberDensities
"""
# this is the same as getThermalExpansionFactor but doesn't fail
# on non-fluid materials that have 0 or undefined thermal expansion
# (we don't want materials to fail on __init__ which calls this)
axialExpansionFactor = 1.0 + self.material.linearExpansionFactor(
self.temperatureInC, self.inputTemperatureInC
)
Expand Down
34 changes: 28 additions & 6 deletions armi/reactor/converters/axialExpansionChanger.py
Expand Up @@ -125,6 +125,23 @@ def setAssembly(self, a, setFuel=True):
self.expansionData = ExpansionData(a, setFuel)
self._isTopDummyBlockPresent()

def applyColdHeightMassIncrease(self):
"""
Increase component mass because they are declared at cold dims
Notes
-----
A cold 1 cm tall component will have more mass that a component with the
same mass/length as a component with a hot height of 1 cm. This should be
called when the setting `inputHeightsConsideredHot` is used. This basically
undoes component.applyHotHeightDensityReduction
"""
for c in self.linked.a.getComponents():
axialExpansionFactor = 1.0 + c.material.linearExpansionFactor(
c.temperatureInC, c.inputTemperatureInC
)
c.changeNDensByFactor(axialExpansionFactor)

def _isTopDummyBlockPresent(self):
"""determines if top most block of assembly is a dummy block
Expand Down Expand Up @@ -175,9 +192,10 @@ def axiallyExpandAssembly(self, thermal: bool = False):
# if ib == 0, leave block bottom = 0.0
if ib > 0:
b.p.zbottom = self.linked.linkedBlocks[b][0].p.ztop
# if not in the dummy block, get expansion factor, do alignment, and modify block
if ib < (numOfBlocks - 1):
isDummyBlock = ib == (numOfBlocks - 1)
if not isDummyBlock:
for c in b:

growFrac = self.expansionData.getExpansionFactor(c)
runLog.debug(
msg=" Component {0}, growFrac = {1:.4e}".format(
Expand Down Expand Up @@ -222,8 +240,9 @@ def axiallyExpandAssembly(self, thermal: bool = False):
# see also b.setHeight()
# - the above not chosen due to call to calculateZCoords
oldComponentVolumes = [c.getVolume() for c in b]
oldHeight = b.getHeight()
oldHeight = b.p.height
b.p.height = b.p.ztop - b.p.zbottom

_checkBlockHeight(b)
_conserveComponentMass(b, oldHeight, oldComponentVolumes)
# set block mid point and redo mesh
Expand All @@ -250,6 +269,8 @@ def manageCoreMesh(self, r):
-----
- if no detailedAxialExpansion, then do "cheap" approach to uniformMesh converter.
- update average core mesh values with call to r.core.updateAxialMesh()
- oldMesh will be None during initial core construction at processLoading as it has not yet
been set.
"""
if not self._detailedAxialExpansion:
# loop through again now that the reference is adjusted and adjust the non-fuel assemblies.
Expand All @@ -258,9 +279,10 @@ def manageCoreMesh(self, r):

oldMesh = r.core.p.axialMesh
r.core.updateAxialMesh()
runLog.extra("Updated r.core.p.axialMesh (old, new)")
for old, new in zip(oldMesh, r.core.p.axialMesh):
runLog.extra(f"{old:.6e}\t{new:.6e}")
if oldMesh:
runLog.extra("Updated r.core.p.axialMesh (old, new)")
for old, new in zip(oldMesh, r.core.p.axialMesh):
runLog.extra(f"{old:.6e}\t{new:.6e}")


def _conserveComponentMass(b, oldHeight, oldVolume):
Expand Down
55 changes: 50 additions & 5 deletions armi/reactor/converters/tests/test_axialExpansionChanger.py
Expand Up @@ -17,7 +17,7 @@
import os
from statistics import mean
import unittest
from numpy import linspace, ones, array, vstack, zeros
from numpy import linspace, array, vstack, zeros
from armi.reactor.tests.test_reactors import loadTestReactor
from armi.tests import TEST_ROOT
from armi.reactor.assemblies import grids
Expand All @@ -39,6 +39,7 @@
from armi import materials
from armi.utils import units
from armi.materials import custom
from armi.tests import mockRunLogs

# set namespace order for materials so that fake HT9 material can be found
materials.setMaterialNamespaceOrder(
Expand Down Expand Up @@ -478,6 +479,12 @@ def test_NoMovementACLP(self):
msg="ACLP ztop has changed. It should not with fuel component only expansion!",
)

def test_reset(self):
self.obj.setAssembly(self.a)
self.obj.reset()
self.assertIsNone(self.obj.linked)
self.assertIsNone(self.obj.expansionData)


class TestManageCoreMesh(unittest.TestCase):
"""verify that manage core mesh unifies the mesh for detailedAxialExpansion: False"""
Expand Down Expand Up @@ -640,6 +647,15 @@ def test_determineLinked(self):
compB = UnshapedComponent("unshaped_2", "FakeMat", **compDims)
self.assertFalse(_determineLinked(compA, compB))

def test_getLinkedComponents(self):
"""test for multiple component axial linkage"""
shieldBlock = self.obj.linked.a[0]
shieldComp = shieldBlock[0]
shieldComp.setDimension("od", 0.785, cold=True)
with self.assertRaises(RuntimeError) as cm:
self.obj.linked._getLinkedComponents(shieldBlock, shieldComp)
self.assertEqual(cm.exception, 3)


class TestDetermineTargetComponent(unittest.TestCase):
"""verify determineTargetComponent method is properly updating _componentDeterminesBlockHeight"""
Expand Down Expand Up @@ -702,12 +718,14 @@ def test_specifyTargetComponet_BlueprintSpecifed(self):
the_exception = cm.exception
self.assertEqual(the_exception.error_code, 3)

# check that target component is explicitly specified
b.setAxialExpTargetComp(dummy)
self.assertEqual(
b.axialExpTargetComponent,
dummy,
)

# check that target component is stored on expansionData object correctly
self.obj.expansionData._componentDeterminesBlockHeight[
b.axialExpTargetComponent
] = True
Expand All @@ -717,25 +735,44 @@ def test_specifyTargetComponet_BlueprintSpecifed(self):
]
)

# get coverage for runLog statements on origination of target components
# axial exp changer skips formal expansion of the top most block so we
# need three blocks.
b0 = _buildTestBlock("b0", "FakeMat", 25.0, 10.0)
b2 = _buildTestBlock("b1", "FakeMat", 25.0, 10.0)
assembly = HexAssembly("testAssemblyType")
assembly.spatialGrid = grids.axialUnitGrid(numCells=1)
assembly.spatialGrid.armiObject = assembly
assembly.add(b0)
assembly.add(b)
assembly.add(b2)
assembly.calculateZCoords()
assembly.reestablishBlockOrder()
with mockRunLogs.BufferLog() as mock:
self.obj.performPrescribedAxialExpansion(assembly, [dummy], [0.01])
self.assertIn("(blueprints defined)", mock._outputStream)
self.assertIn("(inferred)", mock._outputStream)


class TestInputHeightsConsideredHot(unittest.TestCase):
"""verify thermal expansion for process loading of core"""

def setUp(self):
"""provide the base case"""
"""This test uses a different armiRun.yaml than the default"""

_o, r = loadTestReactor(
os.path.join(TEST_ROOT, "detailedAxialExpansion"),
{"inputHeightsConsideredHot": True},
customSettings={"inputHeightsConsideredHot": True},
)
self.stdAssems = [a for a in r.core.getAssemblies()]

_oCold, rCold = loadTestReactor(
os.path.join(TEST_ROOT, "detailedAxialExpansion"),
{"inputHeightsConsideredHot": False},
customSettings={"inputHeightsConsideredHot": False},
)
self.testAssems = [a for a in rCold.core.getAssemblies()]

def test_coldAssemblyHeight(self):
def test_coldAssemblyExpansion(self):
"""block heights are cold and should be expanded
Notes
Expand Down Expand Up @@ -765,6 +802,14 @@ def test_coldAssemblyHeight(self):
checkColdBlockHeight(bStd, bExp, self.assertEqual, "the same")
else:
checkColdBlockHeight(bStd, bExp, self.assertNotEqual, "different")
if bStd.hasFlags(Flags.FUEL):
# fuel mass should grow because heights are considered cold heights
# and a cold 1 cm column has more mass than a hot 1 cm column
if not isinstance(
bStd.getComponent(Flags.FUEL).material, custom.Custom
):
# custom materials don't expand
self.assertGreater(bExp.getMass("U235"), bStd.getMass("U235"))


def checkColdBlockHeight(bStd, bExp, assertType, strForAssertion):
Expand Down

0 comments on commit 6b7ebaa

Please sign in to comment.