diff --git a/armi/materials/zr.py b/armi/materials/zr.py index a84b570e3a..9eeaadcee1 100644 --- a/armi/materials/zr.py +++ b/armi/materials/zr.py @@ -130,7 +130,7 @@ def linearExpansionPercent(self, Tk=None, Tc=None): Tk = getTk(Tc, Tk) self.checkPropertyTempRange("linear expansion percent", Tk) - if Tk >= 291.62 and Tk < 1137: + if Tk >= 293 and Tk < 1137: return ( -0.111 + (2.325e-4 * Tk) + (5.595e-7 * Tk ** 2) - (1.768e-10 * Tk ** 3) ) diff --git a/armi/reactor/blueprints/tests/test_blockBlueprints.py b/armi/reactor/blueprints/tests/test_blockBlueprints.py index 98f0387b95..7053983e44 100644 --- a/armi/reactor/blueprints/tests/test_blockBlueprints.py +++ b/armi/reactor/blueprints/tests/test_blockBlueprints.py @@ -321,9 +321,6 @@ def test_explicitFlags(self): # TODO: This test passes, but shouldn't. def test_densityConsistentWithComponentConstructor(self): - # when comparing to 3D density, the comparison is not quite correct. - # We need a bigger delta, this will be investigated/fixed in another PR - biggerDelta = 0.001 # g/cc a1 = self.blueprints.assemDesigns.bySpecifier["IC"].construct( self.cs, self.blueprints ) @@ -336,7 +333,6 @@ def test_densityConsistentWithComponentConstructor(self): self.assertAlmostEqual( clad.getMassDensity(), clad.material.density3(Tc=clad.temperatureInC), - delta=biggerDelta, ) self.assertAlmostEqual( diff --git a/armi/reactor/components/component.py b/armi/reactor/components/component.py index 5b1200a5ba..0ffc0d5317 100644 --- a/armi/reactor/components/component.py +++ b/armi/reactor/components/component.py @@ -232,27 +232,11 @@ def __init__( self.temperatureInC = Thot self.material = None self.setProperties(material) - self.tInputWarning(Tinput) self.applyMaterialMassFracsToNumberDensities() # not necessary when duplicating... self.setType(name) self.p.mergeWith = mergeWith self.p.customIsotopicsName = isotopics - def tInputWarning(self, Tinput): - """ - Check whether thermal expansion factor is 0.0% exactly at T=Tinput - """ - expansionFactor = ( - self.material.linearExpansionPercent(Tc=self.inputTemperatureInC) / 100.0 - ) - if not (abs(expansionFactor) < 1.0e-6): - runLog.warning( - f"Thermal expansion for {self.material} at Tinput = {Tinput} is non-zero " - f"({expansionFactor}). The modeled density for this material will be off " - f"by a factor of {(1 + expansionFactor) ** 2}.", - single=True, - ) - @property def temperatureInC(self): """Return the hot temperature in Celsius.""" @@ -360,14 +344,15 @@ def applyMaterialMassFracsToNumberDensities(self): """ # note, that this is not the actual material density, but rather 2D expanded # `density3` is 3D density + # call getProperty to cache and improve speed density = self.material.getProperty("density", Tc=self.temperatureInC) self.p.numberDensities = densityTools.getNDensFromMasses( density, self.material.p.massFrac ) - self.applyHotHeightDensityReduction() + self.applyHotHeightDensityReduction(initialColdMaterialExpansion=True) - def applyHotHeightDensityReduction(self): + def applyHotHeightDensityReduction(self, initialColdMaterialExpansion=False): """ Adjust number densities to account for hot block heights (axial expansion) (crucial for preserving 3D density). @@ -382,13 +367,24 @@ def applyHotHeightDensityReduction(self): -------- self.applyMaterialMassFracsToNumberDensities """ - # this is the same as getThermalExpansionFactor but doesn't fail - # on non-fluid materials that have 0 or undefined thermal expansion - # (we don't want materials to fail on __init__ which calls this) - axialExpansionFactor = 1.0 + self.material.linearExpansionFactor( - self.temperatureInC, self.inputTemperatureInC - ) - self.changeNDensByFactor(1.0 / axialExpansionFactor) + if initialColdMaterialExpansion: + # material needs to be expanded from the material's cold temp to hot, + # not components cold temp, so we don't use mat.linearExpansionFactor or + # component.getThermalExpansionFactor. + # materials don't typically define the temperature for which their ref dens + # is defined so linearExpansionPercent must be called + coldMatAxialExpansionFactor = ( + 1.0 + self.material.linearExpansionPercent(Tc=self.temperatureInC) / 100 + ) + self.changeNDensByFactor(1.0 / coldMatAxialExpansionFactor) + else: + # this is the same as getThermalExpansionFactor but doesn't fail + # on non-fluid materials that have 0 or undefined thermal expansion + # (we don't want materials to fail on __init__ which calls this) + # axialExpansionFactor = 1.0 + self.material.linearExpansionFactor( + # self.temperatureInC, self.inputTemperatureInC + # ) + self.changeNDensByFactor(1.0 / self.getThermalExpansionFactor()) def getProperties(self): """Return the active Material object defining thermo-mechanical properties.""" diff --git a/armi/reactor/tests/test_components.py b/armi/reactor/tests/test_components.py index b311d532a3..9b08de27c9 100644 --- a/armi/reactor/tests/test_components.py +++ b/armi/reactor/tests/test_components.py @@ -499,9 +499,9 @@ def test_changeNumberDensities(self): class TestComponentExpansion(unittest.TestCase): # when comparing to 3D density, the comparison is not quite correct. # We need a bigger delta, this will be investigated/fixed in another PR - biggerDelta = 0.01 # g/cc tWarm = 50 tHot = 500 + coldOuterDiameter = 1.0 def test_ExpansionConservationHotHeightDefined(self): """ @@ -513,9 +513,9 @@ def test_ExpansionConservationHotHeightDefined(self): inputHeightsConsideredHot = True (the default) """ hotHeight = 1.0 - coldOuterDiameter = 1.0 - circle1 = Circle("circle", "HT9", 20, self.tWarm, coldOuterDiameter) - circle2 = Circle("circle", "HT9", 20, self.tHot, coldOuterDiameter) + + circle1 = Circle("circle", "HT9", 20, self.tWarm, self.coldOuterDiameter) + circle2 = Circle("circle", "HT9", 20, self.tHot, self.coldOuterDiameter) # mass density is proportional to Fe number density and derived from # all the number densities and atomic masses @@ -547,15 +547,16 @@ def test_ExpansionConservationHotHeightDefined(self): circle.getMassDensity(), circle.material.density(Tc=circle.temperatureInC), ) - # 2D density is off by the thermal exp factor + # 2D density is off by the material thermal exp factor + percent = circle.material.linearExpansionPercent(Tc=circle.temperatureInC) + thermalExpansionFactorFromColdMatTemp = 1 + percent / 100 self.assertAlmostEqual( - circle.getMassDensity() * circle.getThermalExpansionFactor(), + circle.getMassDensity() * thermalExpansionFactorFromColdMatTemp, circle.material.density(Tc=circle.temperatureInC), ) self.assertAlmostEqual( circle.getMassDensity(), circle.material.density3(Tc=circle.temperatureInC), - delta=self.biggerDelta, ) # Change temp forward and backward and show equal oldArea = circle1.getArea() @@ -604,7 +605,6 @@ def test_ExpansionConservationHotHeightDefined(self): self.assertAlmostEqual( circle1.getMassDensity(), circle1.material.density3(Tc=circle2.temperatureInC), - delta=self.biggerDelta, ) # change back to old temp circle1.changeNDensByFactor(circle1.getThermalExpansionFactor()) @@ -628,8 +628,8 @@ def test_ExpansionConservationColdHeightDefined(self): inputHeightsConsideredHot = False """ coldHeight = 1.0 - circle1 = Circle("circle", "HT9", 20, self.tWarm, 1.0) - circle2 = Circle("circle", "HT9", 20, self.tHot, 1.0) + circle1 = Circle("circle", "HT9", 20, self.tWarm, self.coldOuterDiameter) + circle2 = Circle("circle", "HT9", 20, self.tHot, self.coldOuterDiameter) # same as 1 but we will make like 2 circle1AdjustTo2 = Circle("circle", "HT9", 20, self.tWarm, 1.0) @@ -650,7 +650,6 @@ def test_ExpansionConservationColdHeightDefined(self): self.assertAlmostEqual( circle.getMassDensity(), circle.material.density3(Tc=circle.temperatureInC), - delta=self.biggerDelta, ) # total mass consistent between hot and cold # Hot height will be taller @@ -660,7 +659,6 @@ def test_ExpansionConservationColdHeightDefined(self): * circle.getArea(cold=True) * circle.material.density3(Tc=circle.inputTemperatureInC), hotHeight * circle.getArea() * circle.getMassDensity(), - delta=self.biggerDelta, ) diff --git a/armi/tests/detailedAxialExpansion/refSmallReactorBase.yaml b/armi/tests/detailedAxialExpansion/refSmallReactorBase.yaml index 6c5a6baf1d..4173476099 100644 --- a/armi/tests/detailedAxialExpansion/refSmallReactorBase.yaml +++ b/armi/tests/detailedAxialExpansion/refSmallReactorBase.yaml @@ -23,7 +23,7 @@ blocks: grid: shape: Hexagon material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 450.0 ip: 15.277 mult: 1.0 @@ -60,7 +60,7 @@ blocks: shield: shape: Circle material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 600.0 id: 0.0 mult: 169.0 @@ -76,7 +76,7 @@ blocks: clad: shape: Circle material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 470.0 id: 1.0 mult: shield.mult @@ -84,7 +84,7 @@ blocks: wire: shape: Helix material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 450.0 axialPitch: 30.15 helixDiameter: 1.19056 @@ -95,7 +95,7 @@ blocks: duct: &component_fuel_duct shape: Hexagon material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 450.0 ip: 16.0 mult: 1.0 @@ -113,7 +113,7 @@ blocks: fuel: &component_fuel_fuel shape: Circle material: UZr - Tinput: 45.187 + Tinput: 25.0 Thot: 600.0 id: 0.0 mult: 169.0 @@ -129,7 +129,7 @@ blocks: clad: &component_fuel_clad shape: Circle material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 470.0 id: 1.0 mult: fuel.mult @@ -137,7 +137,7 @@ blocks: wire: &component_fuel_wire shape: Helix material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 450.0 axialPitch: 30.15 helixDiameter: 1.19056 @@ -160,7 +160,7 @@ blocks: clad: &component_plenum_clad shape: Circle material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 470.0 id: 1.0 mult: 169.0 @@ -168,7 +168,7 @@ blocks: wire: &component_plenum_wire shape: Helix material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 450.0 axialPitch: 30.15 helixDiameter: 1.19056 @@ -187,7 +187,7 @@ blocks: duct: shape: Hexagon material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 450.0 ip: 16.0 mult: 1.0 @@ -215,7 +215,7 @@ blocks: liner2: &component_fuel2_liner2 shape: Circle material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 600.0 id: 0.98 mergeWith: clad @@ -224,7 +224,7 @@ blocks: liner1: &component_fuel2_liner1 shape: Circle material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 600.0 id: 0.99 mergeWith: clad @@ -251,7 +251,7 @@ blocks: fuel: shape: Circle material: UZr - Tinput: 45.187 + Tinput: 25.0 Thot: 600.0 id: 0.0 isotopics: PuUZr @@ -278,7 +278,7 @@ blocks: fuel: shape: Circle material: UZr - Tinput: 45.187 + Tinput: 25.0 Thot: 600.0 id: 0.600 mult: 169.0 @@ -295,7 +295,7 @@ blocks: inner liner: shape: Circle material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 430.0 id: 0.878 mult: fuel.mult @@ -311,7 +311,7 @@ blocks: outer liner: shape: Circle material: Zr - Tinput: 18.474 + Tinput: 25.0 Thot: 430.0 id: 0.898 mult: fuel.mult @@ -327,7 +327,7 @@ blocks: clad: shape: Circle material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 430.0 id: 0.900 mult: fuel.mult @@ -344,7 +344,7 @@ blocks: duct: &component_control_duct shape: Hexagon material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 450.0 ip: 15.277 mult: 1.0 @@ -378,7 +378,7 @@ blocks: clad: shape: Circle material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 450.0 id: 1.358 mult: control.mult @@ -386,7 +386,7 @@ blocks: wire: shape: Helix material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 450.0 axialPitch: 50.0 helixDiameter: 1.771 @@ -396,7 +396,7 @@ blocks: innerDuct: shape: Hexagon material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 450.0 ip: 14.268 mult: 1.0 @@ -417,7 +417,7 @@ blocks: clad: shape: Circle material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 450.0 id: 1.358 mult: 61.0 @@ -425,7 +425,7 @@ blocks: wire: shape: Helix material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 450.0 axialPitch: 30.15 helixDiameter: 1.19056 @@ -442,7 +442,7 @@ blocks: shield: shape: Circle material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 600.0 id: 0.0 mult: 169.0 @@ -458,7 +458,7 @@ blocks: clad: shape: Circle material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 450.0 id: 0.90562 mult: shield.mult @@ -466,7 +466,7 @@ blocks: wire: shape: Helix material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 450.0 axialPitch: 30.15 helixDiameter: 16.85056 @@ -489,7 +489,7 @@ blocks: clad: &component_radial_shield_clad shape: Circle material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 450.0 id: 0.90562 mult: 169.0 @@ -497,7 +497,7 @@ blocks: wire: &component_radial_shield_plenum_wire shape: Helix material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 450.0 axialPitch: 30.15 helixDiameter: 1.19056 @@ -516,7 +516,7 @@ blocks: duct: shape: Hexagon material: HT9 - Tinput: 27.548 + Tinput: 25.0 Thot: 450.0 ip: 16.0 mult: 1.0