Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(API Breaking) Finish removal of block.r #1425

Merged
merged 20 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from 14 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
6 changes: 3 additions & 3 deletions armi/mpiActions.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def _mpiOperationHelper(self, obj, mpiFunction):
self.o = self.r = self.cs = None
try:
return mpiFunction(obj, root=0)
except (cPickle.PicklingError) as error:
except cPickle.PicklingError as error:
runLog.error("Failed to {} {}.".format(mpiFunction.__name__, obj))
runLog.error(error)
raise
Expand Down Expand Up @@ -553,8 +553,8 @@ def invokeHook(self):
self.r.core.regenAssemblyLists()

# check to make sure that everything has been properly reattached
if self.r.core.getFirstBlock().r is not self.r:
raise RuntimeError("Block.r is not self.r. Reattach the blocks!")
if self.r.core.getFirstBlock().core.r is not self.r:
raise RuntimeError("Block.core.r is not self.r. Reattach the blocks!")

beforeCollection = timeit.default_timer()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,8 @@ def test_calcReactionRates(self):
"""
b = test_blocks.loadTestBlock()
test_blocks.applyDummyData(b)
self.assertEqual(b.p.rateAbs, 0.0)
globalFluxInterface.calcReactionRates(b, 1.01, b.r.core.lib)
self.assertAlmostEqual(b.p.rateAbs, 0.0)
globalFluxInterface.calcReactionRates(b, 1.01, b.core.lib)
self.assertGreater(b.p.rateAbs, 0.0)
vfrac = b.getComponentAreaFrac(Flags.FUEL)
self.assertEqual(b.p.fisDens, b.p.rateFis / vfrac)
Expand Down
22 changes: 12 additions & 10 deletions armi/physics/neutronics/tests/test_crossSectionManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@
class TestBlockCollection(unittest.TestCase):
def setUp(self):
self.blockList = makeBlocks()
self.bc = BlockCollection(self.blockList[0].r.blueprints.allNuclidesInProblem)
self.bc = BlockCollection(
self.blockList[0].core.r.blueprints.allNuclidesInProblem
)
self.bc.extend(self.blockList)

def test_add(self):
Expand Down Expand Up @@ -88,7 +90,7 @@ def setUp(self):
b.p.percentBu = bi / 4.0 * 100
self.blockList[0], self.blockList[2] = self.blockList[2], self.blockList[0]
self.bc = MedianBlockCollection(
self.blockList[0].r.blueprints.allNuclidesInProblem
self.blockList[0].core.r.blueprints.allNuclidesInProblem
)
self.bc.extend(self.blockList)

Expand Down Expand Up @@ -125,7 +127,7 @@ def setUpClass(cls):

def setUp(self):
self.bc = AverageBlockCollection(
self.blockList[0].r.blueprints.allNuclidesInProblem
self.blockList[0].core.r.blueprints.allNuclidesInProblem
)
self.bc.extend(self.blockList)
self.bc.averageByComponent = True
Expand Down Expand Up @@ -160,7 +162,7 @@ def test_createRepresentativeBlock(self):
# check that a new block collection of the representative block has right temperatures
# this is required for Doppler coefficient calculations
newBc = AverageBlockCollection(
self.blockList[0].r.blueprints.allNuclidesInProblem
self.blockList[0].core.r.blueprints.allNuclidesInProblem
)
newBc.append(avgB)
newBc.calcAvgNuclideTemperatures()
Expand Down Expand Up @@ -199,7 +201,7 @@ def test_createRepresentativeBlockDissimilar(self):

# U35 has different average temperature because blocks have different U235 content
newBc = AverageBlockCollection(
self.blockList[0].r.blueprints.allNuclidesInProblem
self.blockList[0].core.r.blueprints.allNuclidesInProblem
)
newBc.append(avgB)
newBc.calcAvgNuclideTemperatures()
Expand Down Expand Up @@ -251,7 +253,7 @@ def setUpClass(cls):

def setUp(self):
self.bc = AverageBlockCollection(
self.blockList[0].r.blueprints.allNuclidesInProblem
self.blockList[0].core.r.blueprints.allNuclidesInProblem
)
blockCopies = [copy.deepcopy(b) for b in self.blockList]
self.bc.extend(blockCopies)
Expand Down Expand Up @@ -675,7 +677,7 @@ def setUpClass(cls):

def setUp(self):
self.bc = FluxWeightedAverageBlockCollection(
self.blockList[0].r.blueprints.allNuclidesInProblem
self.blockList[0].core.r.blueprints.allNuclidesInProblem
)
self.bc.extend(self.blockList)

Expand All @@ -696,7 +698,7 @@ class TestCrossSectionGroupManager(unittest.TestCase):
def setUp(self):
cs = settings.Settings()
self.blockList = makeBlocks(20)
self.csm = CrossSectionGroupManager(self.blockList[0].r, cs)
self.csm = CrossSectionGroupManager(self.blockList[0].core.r, cs)
for bi, b in enumerate(self.blockList):
b.p.percentBu = bi / 19.0 * 100
self.csm._setBuGroupBounds([3, 10, 30, 100])
Expand Down Expand Up @@ -858,7 +860,7 @@ def test_interactBOL(self):
:tests: R_ARMI_XSGM_FREQ
"""
self.assertFalse(self.csm.representativeBlocks)
self.blockList[0].r.p.timeNode = 0
self.blockList[0].core.r.p.timeNode = 0
self.csm.cs[CONF_LATTICE_PHYSICS_FREQUENCY] = "BOL"
self.csm.interactBOL()
self.assertTrue(self.csm.representativeBlocks)
Expand All @@ -871,7 +873,7 @@ def test_interactBOC(self):
:tests: R_ARMI_XSGM_FREQ
"""
self.assertFalse(self.csm.representativeBlocks)
self.blockList[0].r.p.timeNode = 0
self.blockList[0].core.r.p.timeNode = 0
self.csm.cs[CONF_LATTICE_PHYSICS_FREQUENCY] = "BOC"
self.csm.interactBOL()
self.csm.interactBOC()
Expand Down
41 changes: 2 additions & 39 deletions armi/reactor/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
from armi.utils import units
from armi.utils.plotting import plotBlockFlux
from armi.utils.units import TRACE_NUMBER_DENSITY
from armi.nuclearDataIO import xsCollections

PIN_COMPONENTS = [
Flags.CONTROL,
Expand Down Expand Up @@ -176,42 +177,6 @@ def core(self):
c = self.getAncestor(lambda c: isinstance(c, Core))
return c
john-science marked this conversation as resolved.
Show resolved Hide resolved

@property
def r(self):
"""
Look through the ancestors of the Block to find a Reactor, and return it.

Notes
-----
Typical hierarchy: Reactor <- Core <- Assembly <- Block
A block should only have a reactor through a parent assembly.
It may make sense to try to factor out usage of ``b.r``.

Returns
-------
core.parent : armi.reactor.reactors.Reactor
ARMI reactor object that is an ancestor of the block.

Raises
------
ValueError
If the parent of the block's ``core`` is not an ``armi.reactor.reactors.Reactor``.
"""
from armi.reactor.reactors import Reactor

core = self.core
if core is None:
return self.getAncestor(lambda o: isinstance(o, Reactor))

if not isinstance(core.parent, Reactor):
raise TypeError(
"Parent of Block ({}) core is not a Reactor. Got {} instead".format(
core.parent, type(core.parent)
)
)

return core.parent

def makeName(self, assemNum, axialIndex):
"""
Generate a standard block from assembly number.
Expand Down Expand Up @@ -748,7 +713,6 @@ def adjustDensity(self, frac, adjustList, returnMass=False):
numDensities = self.getNuclideNumberDensities(adjustList)

for nuclideName, dens in zip(adjustList, numDensities):

if not dens:
# don't modify zeros.
continue
Expand All @@ -773,7 +737,7 @@ def _updateDetailedNdens(self, frac, adjustList):
# BOL assems get expanded to a reference so the first check is needed so it
# won't call .blueprints on None since BOL assems don't have a core/r
return
if any(nuc in self.r.blueprints.activeNuclides for nuc in adjustList):
if any(nuc in self.core.r.blueprints.activeNuclides for nuc in adjustList):
self.p.detailedNDens *= frac
# Other power densities do not need to be updated as they are calculated in
# the global flux interface, which occurs after axial expansion from crucible
Expand Down Expand Up @@ -2527,7 +2491,6 @@ def getHydraulicDiameter(self):


class CartesianBlock(Block):

PITCH_DIMENSION = "widthOuter"
PITCH_COMPONENT_TYPE = components.Rectangle

Expand Down
119 changes: 0 additions & 119 deletions armi/reactor/composites.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
from armi import utils
from armi.nucDirectory import elements
from armi.nucDirectory import nucDir, nuclideBases
from armi.nuclearDataIO import xsCollections
from armi.physics.neutronics.fissionProductModel import fissionProductModel
from armi.reactor import grids
from armi.reactor import parameters
Expand Down Expand Up @@ -1351,124 +1350,6 @@ def getNumberDensities(self, expandFissionProducts=False):
return self._expandLFPs(numberDensities)
return numberDensities

def getNeutronEnergyDepositionConstants(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we moving this over to the other file?

How is this related to the block.r change?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the commit message for #1425 (comment).

TL/DR: Those methods called self.r.core which blocked the PR from going through. After grepping ARMI and one major downstream project, those methods never get called on any Composite other than Block. So those methods can safely be moved over to the Block class and self.r.core can get replaced with self.core.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay! As long as we call this out in the "API changes" section of the release notes!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"""
Get the neutron energy deposition group constants for a composite.

Returns
-------
energyDepConstants: numpy.array
Neutron energy generation group constants (in Joules/cm)

Raises
------
RuntimeError:
Reports if a cross section library is not assigned to a reactor.
"""
if not self.r.core.lib:
raise RuntimeError(
"Cannot get neutron energy deposition group constants without "
"a library. Please ensure a library exists."
)

return xsCollections.computeNeutronEnergyDepositionConstants(
self.getNumberDensities(), self.r.core.lib, self.getMicroSuffix()
)

def getGammaEnergyDepositionConstants(self):
"""
Get the gamma energy deposition group constants for a composite.

Returns
-------
energyDepConstants: numpy.array
Energy generation group constants (in Joules/cm)

Raises
------
RuntimeError:
Reports if a cross section library is not assigned to a reactor.
"""
if not self.r.core.lib:
raise RuntimeError(
"Cannot get gamma energy deposition group constants without "
"a library. Please ensure a library exists."
)

return xsCollections.computeGammaEnergyDepositionConstants(
self.getNumberDensities(), self.r.core.lib, self.getMicroSuffix()
)

def getTotalEnergyGenerationConstants(self):
"""
Get the total energy generation group constants for a composite.

Gives the total energy generation rates when multiplied by the multigroup flux.

Returns
-------
totalEnergyGenConstant: numpy.array
Total (fission + capture) energy generation group constants (Joules/cm)
"""
return (
self.getFissionEnergyGenerationConstants()
+ self.getCaptureEnergyGenerationConstants()
)

def getFissionEnergyGenerationConstants(self):
"""
Get the fission energy generation group constants for a composite.

Gives the fission energy generation rates when multiplied by the multigroup
flux.

Returns
-------
fissionEnergyGenConstant: numpy.array
Energy generation group constants (Joules/cm)

Raises
------
RuntimeError:
Reports if a cross section library is not assigned to a reactor.
"""
if not self.r.core.lib:
raise RuntimeError(
"Cannot compute energy generation group constants without a library"
". Please ensure a library exists."
)

return xsCollections.computeFissionEnergyGenerationConstants(
self.getNumberDensities(), self.r.core.lib, self.getMicroSuffix()
)

def getCaptureEnergyGenerationConstants(self):
"""
Get the capture energy generation group constants for a composite.

Gives the capture energy generation rates when multiplied by the multigroup
flux.

Returns
-------
fissionEnergyGenConstant: numpy.array
Energy generation group constants (Joules/cm)

Raises
------
RuntimeError:
Reports if a cross section library is not assigned to a reactor.
"""
if not self.r.core.lib:
raise RuntimeError(
"Cannot compute energy generation group constants without a library"
". Please ensure a library exists."
)

return xsCollections.computeCaptureEnergyGenerationConstants(
self.getNumberDensities(), self.r.core.lib, self.getMicroSuffix()
)

def _expandLFPs(self, numberDensities):
"""
Expand the LFPs on the numberDensities dictionary using this composite's
Expand Down
6 changes: 2 additions & 4 deletions armi/reactor/tests/test_assemblies.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,6 @@ def test_makeAxialSnapList(self):

# add some blocks with a component
for _i in range(assemNum2):

self.hexDims = {
"Tinput": 273.0,
"Thot": 273.0,
Expand Down Expand Up @@ -665,9 +664,9 @@ def test_duplicate(self):
else:
self.assertEqual(cur, ref)

# Block level reactor and parent
# Block level core and parent
for b in assembly2:
self.assertEqual(b.r, None)
self.assertEqual(b.core, None)
self.assertEqual(b.parent, assembly2)

def test_hasFlags(self):
Expand Down Expand Up @@ -728,7 +727,6 @@ def test_getBlockData(self):
self.assertAlmostEqual(cur, ref, places=places)

def test_getMaxParam(self):

for bi, b in enumerate(self.assembly):
b.p.power = bi
self.assertAlmostEqual(
Expand Down
Loading
Loading