Skip to content

Commit

Permalink
Add axial expansion nuclide adjust list fn
Browse files Browse the repository at this point in the history
  • Loading branch information
youngmit committed Jan 22, 2020
1 parent e85560b commit b7ce9da
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 21 deletions.
8 changes: 5 additions & 3 deletions armi/bookkeeping/db/xtviewDB.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,10 +572,12 @@ def _updateAxialMesh(self, reactor, blockList, dbTimeStep):
"""
Update block heights and reactor axial mesh based on block param values in database.
This must be done before the number densities are read in so the dimensions of the core are consistent.
This must be done before the number densities are read in so the dimensions of
the core are consistent.
The refAssem writes the neutronics mesh. This method is necessary in case the refAssem
has been removed. Assume all fuel assemblies have the same mesh unless there is ``detailedAxialExpansion``.
The refAssem writes the neutronics mesh. This method is necessary in case the
refAssem has been removed. Assume all fuel assemblies have the same mesh unless
there is ``detailedAxialExpansion``.
Mass must be conserved of the fuel, even in the BOL assemblies, especially if
shuffling and depletion is to occur after loading.
Expand Down
61 changes: 43 additions & 18 deletions armi/reactor/converters/meshConverters.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

from armi import runLog
from armi.reactor import grids
from armi.reactor.flags import Flags
from armi.reactor.flags import Flags, TypeSpec


class MeshConverter(object):
Expand Down Expand Up @@ -220,8 +220,9 @@ class _RZThetaReactorMeshConverterByAxialBins(RZThetaReactorMeshConverter):
Notes
-----
The new mesh structure is formed by merging multiply "bins" together (i.e. numPerBin = 2 and the original mesh is
[1, 2, 3, 4, 5, 6, 7, 8], the new mesh structure will be [2, 4, 6, 8]).
The new mesh structure is formed by merging multiply "bins" together (i.e. numPerBin
= 2 and the original mesh is [1, 2, 3, 4, 5, 6, 7, 8], the new mesh structure will
be [2, 4, 6, 8]).
"""

def setAxialMesh(self):
Expand Down Expand Up @@ -419,23 +420,23 @@ def convert(self, r=None, converterSettings=None):
Notes
-----
This loops through the fuel blocks, making their height larger by a fraction
of maxPercent. It reduces the homogenized actinide number densities to conserve atoms.
This is a first approximation, adjusting the whole core uniformly and adjusting fuel
with structure and everything.
When fuel is locked to clad, this only expands the actinides! So the structural materials
and sodium stay as they are in terms of density. By growing the mesh, we are introducing
NEW ATOMS of these guys, thus violating conservation of atoms. However, the new ones are
effectively piled up on top of the reactor where they are neutronically uninteresting.
This approximates fuel movement without clad/duct movement.
This loops through the fuel blocks, making their height larger by a fraction of
maxPercent. It reduces the homogenized actinide number densities to conserve
atoms.
This is a first approximation, adjusting the whole core uniformly and adjusting
fuel with structure and everything.
When fuel is locked to clad, this only expands the actinides! So the structural
materials and sodium stay as they are in terms of density. By growing the mesh,
we are introducing NEW ATOMS of these guys, thus violating conservation of
atoms. However, the new ones are effectively piled up on top of the reactor
where they are neutronically uninteresting. This approximates fuel movement
without clad/duct movement.
"""
from terrapower.physics.fuelPerformance.crucible import crucible
adjustFlags = Flags.FUEL | Flags.CLAD if self._fuelLockedToClad else Flags.FUEL
adjustList = getAxialExpansionNuclideAdjustList(r, adjustFlags)

adjustList = crucible.getAxialExpansionNuclideAdjustList(
r, locked=self._fuelLockedToClad
)
runLog.extra(
"Conserving mass during axial expansion for: {0}".format(str(adjustList))
)
Expand Down Expand Up @@ -463,3 +464,27 @@ def convert(self, r=None, converterSettings=None):
"Adjusted full core fuel axial mesh uniformly "
"{0}% from {1} cm to {2} cm.".format(self._percent, oldMesh, newMesh)
)


def getAxialExpansionNuclideAdjustList(r, componentFlags: TypeSpec = None):
r"""
Determine which nuclides should have their mass conserved during axial expansion
Parameters
----------
r : Reactor
The Reactor object to search for nuclide instances
componentFlags : TypeSpec, optional
A type specification to use for filtering components that should conserve mass.
If None, Flags.FUEL is used.
"""

if componentFlags is None:
componentFlags = [Flags.FUEL]

adjustSet = {nuc for b in r.core.getBlocks() for c in
b.getComponents(componentFlags) for nuc in c.getNuclides()}

return list(adjustSet)
115 changes: 115 additions & 0 deletions armi/reactor/converters/tests/test_meshConverters.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import math

from armi.reactor.tests.test_reactors import loadTestReactor
from armi.reactor.flags import Flags
from armi.reactor.converters import meshConverters, geometryConverters
from armi.tests import TEST_ROOT

Expand Down Expand Up @@ -107,6 +108,120 @@ def test_meshByRingCompositionAxialCoordinatesLargeCore(self):
self.assertListEqual(meshConvert.thetaMesh, expectedThetaMesh)


class AxialExpandNucs(unittest.TestCase):
def setUp(self):
self.o, self.r = loadTestReactor(TEST_ROOT)

def test_getAxialExpansionNuclideAdjustList(self):
nucs = meshConverters.getAxialExpansionNuclideAdjustList(self.r)
expected = [
"NP238",
"LFP35",
"PU242",
"LFP39",
"ZR94",
"LFP38",
"CM245",
"PU241",
"U235",
"CM244",
"ZR96",
"AM243",
"U236",
"NP237",
"U238",
"AM242",
"PU236",
"ZR90",
"LFP40",
"DUMP2",
"DUMP1",
"CM242",
"LFP41",
"PU240",
"CM246",
"CM243",
"PU238",
"ZR92",
"CM247",
"AM241",
"U234",
"PU239",
"ZR91",
]
self.assertEqual(sorted(nucs), sorted(expected))

nucs = meshConverters.getAxialExpansionNuclideAdjustList(
self.r, [Flags.FUEL, Flags.CLAD]
)
expected = [
"U235",
"U238",
"ZR90",
"ZR91",
"ZR92",
"ZR94",
"ZR96",
"NP237",
"LFP38",
"DUMP1",
"PU239",
"NP238",
"PU236",
"U236",
"DUMP2",
"PU238",
"LFP35",
"LFP39",
"PU240",
"LFP40",
"PU241",
"LFP41",
"PU242",
"AM241",
"CM242",
"AM242",
"CM243",
"U234",
"AM243",
"CM244",
"CM245",
"CM246",
"CM247",
"C",
"V",
"CR50",
"CR52",
"CR53",
"CR54",
"FE54",
"FE56",
"FE57",
"FE58",
"MO92",
"MO94",
"MO95",
"MO96",
"MO97",
"MO98",
"MO100",
"NI58",
"NI60",
"NI61",
"NI62",
"NI64",
"SI28",
"SI29",
"SI30",
"MN55",
"W182",
"W183",
"W184",
"W186",
]
self.assertEqual(sorted(nucs), sorted(expected))


if __name__ == "__main__":
# import sys;sys.argv = ['', 'TestRZReactorMeshConverter.test_meshByRingCompositionAxialBinsSmallCore']
unittest.main()

0 comments on commit b7ce9da

Please sign in to comment.