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

Explicit Fission Product Modeling #1022

Merged
merged 14 commits into from
Dec 28, 2022
Merged
Show file tree
Hide file tree
Changes from 11 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
52 changes: 26 additions & 26 deletions armi/cases/case.py
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ def _initBurnChain(self):
"""
if not self.cs["initializeBurnChain"]:
runLog.info(
"Skipping burn-chain initialization due disabling of the `initializeBurnChain` setting."
"Skipping burn-chain initialization since `initializeBurnChain` setting is disabled."
)
return

Expand All @@ -563,38 +563,38 @@ def checkInputs(self):
bool
True if the inputs are all good, False otherwise
"""
runLog.header("=========== Settings Validation Checks ===========")
with DirectoryChanger(self.cs.inputDirectory, dumpOnException=False):
operatorClass = operators.getOperatorClassFromSettings(self.cs)
inspector = operatorClass.inspector(self.cs)
inspectorIssues = [query for query in inspector.queries if query]
if context.CURRENT_MODE == context.Mode.INTERACTIVE:
# if interactive, ask user to deal with settings issues
inspector.run()
else:
# when not interactive, just print out the info in the stdout
queryData = []
for i, query in enumerate(inspectorIssues, start=1):
queryData.append(
(
i,
textwrap.fill(
query.statement, width=50, break_long_words=False
),
textwrap.fill(
query.question, width=50, break_long_words=False
),
)

# Write out the settings validation issues that will be prompted for
# resolution if in an interactive session or forced to be resolved
# otherwise.
queryData = []
for i, query in enumerate(inspectorIssues, start=1):
queryData.append(
(
i,
textwrap.fill(
query.statement, width=50, break_long_words=False
),
textwrap.fill(query.question, width=50, break_long_words=False),
)
)

if queryData and context.MPI_RANK == 0:
runLog.header("=========== Settings Input Queries ===========")
runLog.info(
tabulate.tabulate(
queryData,
headers=["Number", "Statement", "Question"],
tablefmt="armi",
)
if queryData and context.MPI_RANK == 0:
runLog.info(
tabulate.tabulate(
queryData,
headers=["Number", "Statement", "Question"],
tablefmt="armi",
)
)
if context.CURRENT_MODE == context.Mode.INTERACTIVE:
# if interactive, ask user to deal with settings issues
inspector.run()
jakehader marked this conversation as resolved.
Show resolved Hide resolved

return not any(inspectorIssues)

Expand Down
2 changes: 1 addition & 1 deletion armi/nucDirectory/nucDir.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ def getThresholdDisplacementEnergy(nuc):
nuc = getNuclide(nuc)
el = elements.byZ[nuc.z]
try:
ed = eDisplacement[el]
ed = eDisplacement[el.symbol]
jakehader marked this conversation as resolved.
Show resolved Hide resolved
except KeyError:
print(
"The element {0} of nuclide {1} does not have a displacement energy in the library. Please add one."
Expand Down
12 changes: 2 additions & 10 deletions armi/operators/settingsValidation.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
from armi.reactor import systemLayoutInput
from armi.physics import neutronics
from armi.utils import directoryChangers
from armi.settings.fwSettings import globalSettings
from armi.settings.settingsIO import (
prompt,
RunLogPromptCancel,
Expand Down Expand Up @@ -67,7 +66,6 @@ def __init__(self, condition, statement, question, correction):
self.correction = correction
# True if the query is `passed` and does not result in an immediate failure
self._passed = False
self._corrected = False
self.autoResolved = True

def __repr__(self):
Expand Down Expand Up @@ -107,9 +105,7 @@ def resolve(self):
)
if make_correction:
self.correction()
self._corrected = True
else:
self._passed = True
self._passed = True
except RunLogPromptCancel as ki:
raise KeyboardInterrupt from ki
else:
jakehader marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -191,7 +187,6 @@ def run(self, cs=None):

# the following attribute changes will alter what the queries investigate when
# resolved
correctionsMade = False
self.cs = cs or self.cs
runLog.debug("{} executing queries.".format(self.__class__.__name__))
if not any(self.queries):
Expand All @@ -203,8 +198,6 @@ def run(self, cs=None):
else:
for query in self.queries:
query.resolve()
if query._corrected: # pylint: disable=protected-access
correctionsMade = True
issues = [
query
for query in self.queries
Expand All @@ -221,8 +214,6 @@ def run(self, cs=None):
)
runLog.debug("{} has finished querying.".format(self.__class__.__name__))

return correctionsMade

def addQuery(self, condition, statement, question, correction):
"""Convenience method, query must be resolved, else run fails"""
if not callable(correction):
Expand Down Expand Up @@ -262,6 +253,7 @@ def _assignCS(self, key, value):
"""Lambda assignment workaround"""
# this type of assignment works, but be mindful of
# scoping when trying different methods
runLog.extra(f"Updating setting `{key}` to `{value}`")
self.cs[key] = value

def _raise(self): # pylint: disable=no-self-use
Expand Down
2 changes: 2 additions & 0 deletions armi/physics/fuelPerformance/executers.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
CONF_FGR_REMOVAL,
CONF_CLADDING_WASTAGE,
CONF_CLADDING_STRAIN,
CONF_FGYF,
)


Expand All @@ -53,6 +54,7 @@ def fromUserSettings(self, cs):
self.fissionGasRemoval = cs[CONF_FGR_REMOVAL]
self.claddingWastage = cs[CONF_CLADDING_WASTAGE]
self.claddingStrain = cs[CONF_CLADDING_STRAIN]
self.fissionGasYieldFraction = cs[CONF_FGYF]

def fromReactor(self, reactor):
"""Load options from reactor."""
Expand Down
24 changes: 20 additions & 4 deletions armi/physics/fuelPerformance/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,35 @@ def _getFuelPerformanceBlockParams():
" thermal and/or burn-up expansion of the fuel and cladding materials.",
)

def gasReleaseFraction(self, value):
if value < 0.0 or value > 1.0:
raise ValueError(
f"Cannot set a gas release fraction "
f"of {value} outside of the bounds of [0.0, 1.0]"
)
self._p_gasReleaseFraction = value

pb.defParam(
"gasReleaseFraction",
setter=gasReleaseFraction,
units="fraction",
description="Fraction of generated fission gas that no longer exists in the block."
" Should be between 0 and 1, inclusive.",
description="Fraction of generated fission gas that no longer exists in the block.",
categories=["eq cumulative shift"],
)

def bondRemoved(self, value):
if value < 0.0 or value > 1.0:
raise ValueError(
f"Cannot set a bond removed "
f"of {value} outside of the bounds of [0.0, 1.0]"
)
self._p_bondRemoved = value

pb.defParam(
"bondRemoved",
setter=bondRemoved,
units="fraction",
description="Fraction of thermal bond between fuel and clad that has been pushed out. "
"Should be between 0 and 1, inclusive.",
description="Fraction of thermal bond between fuel and clad that has been pushed out.",
categories=["eq cumulative shift"],
)

Expand Down
7 changes: 7 additions & 0 deletions armi/physics/fuelPerformance/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
CONF_CLADDING_STRAIN = "claddingStrain"
CONF_CLADDING_WASTAGE = "claddingWastage"
CONF_FGR_REMOVAL = "fgRemoval"
CONF_FGYF = "fissionGasYieldFraction"
CONF_FUEL_PERFORMANCE_ENGINE = "fuelPerformanceEngine"


Expand All @@ -39,6 +40,12 @@ def defineSettings():
),
options=[""],
),
setting.Setting(
CONF_FGYF,
default=0.25,
label="Fission Gas Yield Fraction",
description="The fraction of gaseous atoms produced per fission event, assuming a fission product yield of 2.0",
),
setting.Setting(
CONF_AXIAL_EXPANSION,
default=False,
Expand Down
7 changes: 6 additions & 1 deletion armi/physics/neutronics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,13 @@ def defineSettings():
def defineSettingsValidators(inspector):
"""Implementation of settings inspections for neutronics settings."""
from armi.physics.neutronics.settings import getNeutronicsSettingValidators
from armi.physics.neutronics.fissionProductModel.fissionProductModelSettings import (
getFissionProductModelSettingValidators,
)

return getNeutronicsSettingValidators(inspector)
settingsValidators = getNeutronicsSettingValidators(inspector)
settingsValidators.extend(getFissionProductModelSettingValidators(inspector))
return settingsValidators

@staticmethod
@plugins.HOOKIMPL
Expand Down
20 changes: 3 additions & 17 deletions armi/physics/neutronics/crossSectionGroupManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,15 +346,7 @@ def _getAverageFuelLFP(self):
"""Compute the average lumped fission products."""
# TODO: make do actual average of LFPs
b = self.getCandidateBlocks()[0]
lfpCollection = b.getLumpedFissionProductCollection()
if lfpCollection:
lfpCollectionCopy = lfpCollection.duplicate()
fgRemoved = self._getAverageFissionGasRemoved()
lfpCollectionCopy.setGasRemovedFrac(fgRemoved)
jakehader marked this conversation as resolved.
Show resolved Hide resolved
else:
lfpCollectionCopy = lfpCollection

return lfpCollectionCopy
return b.getLumpedFissionProductCollection()
jakehader marked this conversation as resolved.
Show resolved Hide resolved

def _getNucTempHelper(self):
"""All candidate blocks are used in the average."""
Expand Down Expand Up @@ -1012,15 +1004,9 @@ def _summarizeGroups(self, blockCollectionsByXsGroup):
xsIDGroup = self._getXsIDGroup(xsID)
if xsIDGroup == self._REPR_GROUP:
reprBlock = self.representativeBlocks.get(xsID)
lfps = reprBlock.getLumpedFissionProductCollection()
if lfps:
fissionGasRemoved = list(lfps.values())[0].getGasRemovedFrac()
else:
fissionGasRemoved = 0.0
runLog.extra(
"XS ID {} contains {:4d} blocks, represented by: {:65s}"
" Fission Gas Removal Fraction: {:.2f}".format(
xsID, len(blocks), reprBlock, fissionGasRemoved
"XS ID {} contains {:4d} blocks, represented by: {:65s}".format(
xsID, len(blocks), reprBlock
)
)
elif xsIDGroup == self._NON_REPR_GROUP:
Expand Down
4 changes: 2 additions & 2 deletions armi/physics/neutronics/fissionProductModel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"""

import os
from armi import ROOT
from armi.context import RES

REFERENCE_LUMPED_FISSION_PRODUCT_FILE = os.path.join(
ROOT, "resources", "referenceFissionProducts.dat"
RES, "referenceFissionProducts.dat"
)
Loading