Skip to content

Commit

Permalink
Correcting volume integrated parameters in the conversion from 1/3 to…
Browse files Browse the repository at this point in the history
… full core (#742)
  • Loading branch information
keckler committed Jul 1, 2022
1 parent 281c753 commit 0cead00
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 5 deletions.
57 changes: 52 additions & 5 deletions armi/reactor/converters/geometryConverters.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
import collections
import copy
import math
import os

import matplotlib
import matplotlib.pyplot as plt
import numpy
import operator
import os

from armi import materials
from armi import runLog
Expand Down Expand Up @@ -1180,6 +1180,27 @@ class ThirdCoreHexToFullCoreChanger(GeometryChanger):
geometry.DomainType.THIRD_CORE, geometry.BoundaryType.PERIODIC
)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.listOfVolIntegratedParamsToScale = []

def _scaleBlockVolIntegratedParams(self, b, direction):
if direction == "up":
op = operator.mul
elif direction == "down":
op = operator.truediv

for param in self.listOfVolIntegratedParamsToScale:
print(param)
print(b.p[param])
if b.p[param] is None:
continue
if type(b.p[param]) == list:
# some params like volume-integrated mg flux are lists
b.p[param] = [op(val, 3) for val in b.p[param]]
else:
b.p[param] = op(b.p[param], 3)

def convert(self, r=None):
"""
Run the conversion.
Expand Down Expand Up @@ -1233,23 +1254,49 @@ def convert(self, r=None):
r.core.add(newAssem, r.core.spatialGrid[i, j, 0])
self._newAssembliesAdded.append(newAssem)

if a.getLocation() == "001-001":
runLog.extra(
f"Modifying parameters in central assembly {a} to convert from 1/3 to full core"
)

if not self.listOfVolIntegratedParamsToScale:
# populate the list with all parameters that are VOLUME_INTEGRATED
(
self.listOfVolIntegratedParamsToScale,
_,
) = _generateListOfParamsToScale(r, paramsToScaleSubset=[])

for b in a:
self._scaleBlockVolIntegratedParams(b, "up")

# set domain after expanding, because it isnt actually full core until it's
# full core; setting the domain causes the core to clear its caches.
r.core.symmetry = geometry.SymmetryType(
geometry.DomainType.FULL_CORE, geometry.BoundaryType.NO_SYMMETRY
)

def restorePreviousGeometry(self, cs, reactor):
def restorePreviousGeometry(self, cs, r):
"""Undo the changes made by convert by going back to 1/3 core."""
# remove the assemblies that were added when the conversion happened.
if bool(self.getNewAssembliesAdded()):
for a in self.getNewAssembliesAdded():
reactor.core.removeAssembly(a, discharge=False)
r.core.removeAssembly(a, discharge=False)

reactor.core.symmetry = geometry.SymmetryType.fromAny(
r.core.symmetry = geometry.SymmetryType.fromAny(
self.EXPECTED_INPUT_SYMMETRY
)

# clear the list for next time
self._newAssembliesAdded = []

# change the central assembly params back to 1/3
a = r.core.getAssemblyWithStringLocation("001-001")
runLog.extra(
f"Modifying parameters in central assembly {a} to revert from full to 1/3 core"
)
for b in a:
self._scaleBlockVolIntegratedParams(b, "down")


class EdgeAssemblyChanger(GeometryChanger):
"""
Expand Down
40 changes: 40 additions & 0 deletions armi/reactor/converters/tests/test_geometryConverters.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,25 @@ class TestThirdCoreHexToFullCoreChanger(unittest.TestCase):
def setUp(self):
self.o, self.r = loadTestReactor(TEST_ROOT)

# initialize the block powers to a uniform power profile, accounting for
# the loaded reactor being 1/3 core
numBlocksInFullCore = 0
for a in self.r.core:
if a.getLocation() == "001-001":
for b in a:
numBlocksInFullCore += 1
else:
for b in a:
# account for the 1/3 symmetry
numBlocksInFullCore += 3
for a in self.r.core:
if a.getLocation() == "001-001":
for b in a:
b.p["power"] = self.o.cs["power"] / numBlocksInFullCore / 3
else:
for b in a:
b.p["power"] = self.o.cs["power"] / numBlocksInFullCore

def tearDown(self):
del self.o
del self.r
Expand All @@ -327,6 +346,14 @@ def test_growToFullCoreFromThirdCore(self):
)
initialNumBlocks = len(self.r.core.getBlocks())

self.assertAlmostEqual(
self.r.core.getTotalBlockParam("power"), self.o.cs["power"] / 3, places=5
)
self.assertGreater(
self.r.core.getTotalBlockParam("power", calcBasedOnFullObj=True),
self.o.cs["power"] / 3,
)

# Perform reactor conversion
changer = geometryConverters.ThirdCoreHexToFullCoreChanger(self.o.cs)
changer.convert(self.r)
Expand All @@ -336,6 +363,16 @@ def test_growToFullCoreFromThirdCore(self):
self.assertGreater(len(self.r.core.getBlocks()), initialNumBlocks)
self.assertEqual(self.r.core.symmetry.domain, geometry.DomainType.FULL_CORE)

# ensure that block power is handled correctly
self.assertAlmostEqual(
self.r.core.getTotalBlockParam("power"), self.o.cs["power"], places=5
)
self.assertAlmostEqual(
self.r.core.getTotalBlockParam("power", calcBasedOnFullObj=True),
self.o.cs["power"],
places=5,
)

# Check that the geometry can be restored to a third core
changer.restorePreviousGeometry(self.o.cs, self.r)
self.assertEqual(initialNumBlocks, len(self.r.core.getBlocks()))
Expand All @@ -346,6 +383,9 @@ def test_growToFullCoreFromThirdCore(self):
),
)
self.assertFalse(self.r.core.isFullCore)
self.assertAlmostEqual(
self.r.core.getTotalBlockParam("power"), self.o.cs["power"] / 3, places=5
)

def test_initNewFullReactor(self):
"""Test that initNewReactor will growToFullCore if necessary."""
Expand Down

0 comments on commit 0cead00

Please sign in to comment.