Skip to content

Commit 57abab5

Browse files
committed
component accounts for material props changing
1 parent bd5db9f commit 57abab5

File tree

3 files changed

+74
-16
lines changed

3 files changed

+74
-16
lines changed

armi/reactor/blocks.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2441,10 +2441,18 @@ def getWettedPerimeter(self):
24412441
)
24422442

24432443
# flags pertaining to circular pin components where the exterior of the circle is wetted
2444-
wettedPinComponentFlags = (Flags.CLAD, Flags.WIRE, Flags.CLAD | Flags.DEPLETABLE, Flags.WIRE | Flags.DEPLETABLE)
2444+
wettedPinComponentFlags = (
2445+
Flags.CLAD,
2446+
Flags.WIRE,
2447+
Flags.CLAD | Flags.DEPLETABLE,
2448+
Flags.WIRE | Flags.DEPLETABLE,
2449+
)
24452450

24462451
# flags pertaining to components where both the interior and exterior are wetted
2447-
wettedHollowComponentFlags = (Flags.DUCT | Flags.INNER, Flags.DUCT | Flags.INNER | Flags.DEPLETABLE,)
2452+
wettedHollowComponentFlags = (
2453+
Flags.DUCT | Flags.INNER,
2454+
Flags.DUCT | Flags.INNER | Flags.DEPLETABLE,
2455+
)
24482456

24492457
# obtain all wetted components based on type
24502458
wettedHollowHexagonComponents = []

armi/reactor/components/component.py

Lines changed: 63 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -369,11 +369,20 @@ def applyMaterialMassFracsToNumberDensities(self):
369369
# `density` is 3D density
370370
# call getProperty to cache and improve speed
371371
density = self.material.getProperty("pseudoDensity", Tc=self.temperatureInC)
372-
373372
self.p.numberDensities = densityTools.getNDensFromMasses(
374373
density, self.material.massFrac
375374
)
376375

376+
# Sometimes the material thermal expansion depends on its parents composition (eg Pu frac) so
377+
# setting number densities can sometimes change thermal expansion behavior.
378+
# so call again so that the material has access to its parents comp when providing the reference initial density.
379+
densityBasedOnParentComposition = self.material.getProperty(
380+
"pseudoDensity", Tc=self.temperatureInC
381+
)
382+
self.p.numberDensities = densityTools.getNDensFromMasses(
383+
densityBasedOnParentComposition, self.material.massFrac
384+
)
385+
377386
# material needs to be expanded from the material's cold temp to hot,
378387
# not components cold temp, so we don't use mat.linearExpansionFactor or
379388
# component.getThermalExpansionFactor.
@@ -694,7 +703,7 @@ def setPuFrac(self, prevPuFrac):
694703
dLLprev = prevMaterial.linearExpansionPercent(Tc=self.temperatureInC) / 100.0
695704
dLLnew = self.material.linearExpansionPercent(Tc=self.temperatureInC) / 100.0
696705
expansionRatio = (1.0 + dLLnew) / (1.0 + dLLprev)
697-
f = 1.0 / expansionRatio ** 2
706+
f = 1.0 / expansionRatio**2
698707
self.changeNDensByFactor(f)
699708
self.clearLinkedCache()
700709

@@ -753,12 +762,7 @@ def setNumberDensity(self, nucName, val):
753762
val : float
754763
Number density to set in atoms/bn-cm (heterogeneous)
755764
"""
756-
self.p.numberDensities[nucName] = val
757-
self.p.assigned = parameters.SINCE_ANYTHING
758-
# necessary for syncMpiState
759-
parameters.ALL_DEFINITIONS[
760-
"numberDensities"
761-
].assigned = parameters.SINCE_ANYTHING
765+
self.updateNumberDensities({nucName: val})
762766

763767
def setNumberDensities(self, numberDensities):
764768
"""
@@ -777,12 +781,18 @@ def setNumberDensities(self, numberDensities):
777781
numberDensities : dict
778782
nucName: ndens pairs.
779783
780-
Notes
781-
-----
782-
We don't just call setNumberDensity for each nuclide because we don't want to call ``getVolumeFractions``
783-
for each nuclide (it's inefficient).
784+
Note that sometimes volume/dimensions can change due to the number density change when the material thermal
785+
expansion depends on the component's composition (eg its plutonium fraction). In this case, changing the
786+
density will implicitly change the area/volume. Since it its very difficult to predict the new dims ahead of time,
787+
and perturbation/depletion calculations are almost exclusively done assuming constant volume,
788+
the densities sent are automatically perturbed to conserve mass with the original dimensions.
789+
That is, the components densities are not exactly as passed, but whatever they would need to be to preserve volume
790+
integrated number densities (moles) from the pre-perturbed components volume/dims.
791+
Note this has no effect if the material thermal expansion has no dependence on component composition fracs.
792+
If this is not desired, `self.p.numberDensities` can be set directly.
784793
"""
785-
self.p.numberDensities = numberDensities
794+
self.p.numberDensities = {} # clear things not passed
795+
self.updateNumberDensities(numberDensities)
786796

787797
def updateNumberDensities(self, numberDensities):
788798
"""
@@ -793,9 +803,48 @@ def updateNumberDensities(self, numberDensities):
793803
numberDensities : dict
794804
nucName: ndens pairs.
795805
806+
Notes
807+
-----
808+
Note that sometimes volume/dimensions can change due to the number density change when the material thermal
809+
expansion depends on the component's composition (eg its plutonium fraction). In this case, changing the
810+
density will implicitly change the area/volume. Since it its very difficult to predict the new dims ahead of time,
811+
and perturbation/depletion calculations are almost exclusively done assuming constant volume,
812+
the densities sent are automatically perturbed to conserve mass with the original dimensions.
813+
That is, the components densities are not exactly as passed, but whatever they would need to be to preserve volume
814+
integrated number densities (moles) from the pre-perturbed components volume/dims.
815+
Note this has no effect if the material thermal expansion has no dependence on component composition fracs.
816+
If this is not desired, `self.p.numberDensities` can be set directly.
796817
"""
818+
# prepare to change the densities with knowledge that dims could change due to
819+
# material thermal expansion dependence on composition
820+
dLLprev = self.material.linearExpansionPercent(Tc=self.temperatureInC) / 100.0
821+
try:
822+
vol = self.getVolume()
823+
except:
824+
# either no parent to get height or parent's height is None
825+
# which would be AttributeError and TypeError respectively, but other errors could be possible
826+
vol = None
827+
area = self.getArea()
828+
829+
# change the densities
797830
self.p.numberDensities.update(numberDensities)
798-
# since we're updating the object the param points to but not the param itself, we have to inform
831+
832+
# check if thermal expansion changed
833+
dLLnew = self.material.linearExpansionPercent(Tc=self.temperatureInC) / 100.0
834+
if dLLprev != dLLnew:
835+
# the thermal expansion changed so the volume change is happening at same time as
836+
# density change was requested. Attempt to make mass consistent with old dims
837+
# (since the density change was for the old volume and otherwise mass wouldn't be conserved)
838+
839+
# enable recalculation of volume, otherwise it uses stored.
840+
self.clearLinkedCache()
841+
if vol is not None:
842+
factor = vol / self.getVolume()
843+
else:
844+
factor = area / self.getArea()
845+
self.changeNDensByFactor(factor)
846+
847+
# since we're calling update on the object the param points to, but not the param itself, we have to inform
799848
# the param system to flag it as modified so it properly syncs during ``syncMpiState``.
800849
self.p.assigned = parameters.SINCE_ANYTHING
801850
self.p.paramDefs["numberDensities"].assigned = parameters.SINCE_ANYTHING

armi/reactor/converters/geometryConverters.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,6 +1568,7 @@ def scaleParamsRelatedToSymmetry(core, paramsToScaleSubset=None):
15681568
for b, bSymmetric in zip(a, aSymmetric):
15691569
_scaleParamsInBlock(b, bSymmetric, completeListOfParamsToScale)
15701570

1571+
15711572
def _generateListOfParamsToScale(core, paramsToScaleSubset):
15721573
fluxParamsToScale = (
15731574
core.getFirstBlock()

0 commit comments

Comments
 (0)