Skip to content

Commit

Permalink
Merge branch 'main' into zones_overhaul
Browse files Browse the repository at this point in the history
  • Loading branch information
john-science committed Oct 22, 2022
2 parents 72a9f3a + 001c827 commit 70743d8
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 56 deletions.
21 changes: 14 additions & 7 deletions armi/bookkeeping/db/database3.py
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,7 @@ def load(
statePointName=None,
allowMissing=False,
updateGlobalAssemNum=True,
updateMasterCs=True,
):
"""Load a new reactor from (cycle, node).
Expand All @@ -1100,18 +1101,23 @@ def load(
cycle number
node : int
time node
cs : armi.settings.Settings (optional)
cs : armi.settings.Settings, optional
if not provided one is read from the database
bp : armi.reactor.Blueprints (optional)
bp : armi.reactor.Blueprints, optional
if not provided one is read from the database
statePointName : str
statePointName : str, optional
Optional arbitrary statepoint name (e.g., "special" for "c00n00-special/")
allowMissing : bool
allowMissing : bool, optional
Whether to emit a warning, rather than crash if reading a database
with undefined parameters. Default False.
updateGlobalAssemNum : bool
updateGlobalAssemNum : bool, optional
Whether to update the global assembly number to the value stored in
r.core.p.maxAssemNum. Default True.
updateMasterCs : bool, optional
Whether to apply the cs (whether provided as an argument or read from
the database) as the primary for the case. Default True. Can be useful
if you don't intend to use the loaded reactor as the basis for further
computations in the current operator.
Returns
-------
Expand All @@ -1121,8 +1127,9 @@ def load(
runLog.info("Loading reactor state for time node ({}, {})".format(cycle, node))

cs = cs or self.loadCS()
# apply to avoid defaults in getMasterCs calls
settings.setMasterCs(cs)
if updateMasterCs:
# apply to avoid defaults in getMasterCs calls
settings.setMasterCs(cs)
bp = bp or self.loadBlueprints()

h5group = self.h5db[getH5GroupName(cycle, node, statePointName)]
Expand Down
2 changes: 1 addition & 1 deletion armi/bookkeeping/report/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def writeHTML(self):
runLog.debug("Writing HTML document {}.".format(filename))

with html.HTMLFile(filename, "w") as f:
html.writeStandardReportTemplate(f, self)
html.writeStandardReportTemplate(f, self, self.title)

runLog.info("HTML document {} written".format(filename))

Expand Down
16 changes: 7 additions & 9 deletions armi/bookkeeping/report/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,15 +199,14 @@ def encode64(file_path):
# ---------------------------


def writeStandardReportTemplate(f, report):
def writeStandardReportTemplate(f, report, caseTitle=""):
f.write(r"<!DOCTYPE html>" + "\n")
cs = settings.getMasterCs()
with Html(f):

with Head(f):
f.write(r'<meta charset="UTF-8">' + "\n")
with Title(f):
f.write(cs.caseTitle)
if caseTitle:
with Title(f):
f.write(caseTitle)

with Body(f):

Expand Down Expand Up @@ -244,8 +243,9 @@ def writeStandardReportTemplate(f, report):
"style": "color: #d9230f;",
},
):
with B(f):
f.write(cs.caseTitle)
if caseTitle:
with B(f):
f.write(caseTitle)

with Span(
f, attrs={"class": "navbar-text navbar-version pull-left"}
Expand All @@ -264,8 +264,6 @@ def writeStandardReportTemplate(f, report):
with Div(f, attrs={"class": "page-header"}):
with H1(f):
f.write(report.title)
with P(f):
f.write(cs["comment"])

report.writeGroupsHTML(f)

Expand Down
27 changes: 16 additions & 11 deletions armi/materials/b4c.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,18 +159,23 @@ def getMassEnrichmentFromNumEnrich(naturalB10NumberFraction: float) -> float:

def density(self, Tk: float = None, Tc: float = None) -> float:
"""
mass density
Return density that preserves mass when thermally expanded in 2D.
Notes
-----
- applies theoretical density of B4C to parent method
"""
density = material.Material.density(self, Tk, Tc)
theoreticalDensityFrac = self.p.theoreticalDensityFrac
if theoreticalDensityFrac is None:
theoreticalDensityFrac = 1.0
runLog.warning(
"Assumption: 100% theoretical density",
label="Assumption: B4C is at 100% theoretical density",
single=True,
)
return density * theoreticalDensityFrac # g/cc
return material.Material.density(self, Tk, Tc) * self.p.theoreticalDensityFrac

def density3(self, Tk: float = None, Tc: float = None) -> float:
"""
Return density that preserves mass when thermally expanded in 3D.
Notes
-----
- applies theoretical density of B4C to parent method
"""
return material.Material.density3(self, Tk, Tc) * self.p.theoreticalDensityFrac

def linearExpansionPercent(self, Tk: float = None, Tc: float = None) -> float:
"""Boron carbide expansion. Very preliminary"""
Expand Down
7 changes: 4 additions & 3 deletions armi/reactor/reactors.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,15 +436,16 @@ def removeAssembly(self, a1, discharge=True):
else:
self._removeListFromAuxiliaries(a1)

def removeAssembliesInRing(self, ringNum, overrideCircularRingMode=False):
def removeAssembliesInRing(self, ringNum, cs, overrideCircularRingMode=False):
"""
Removes all of the assemblies in a given ring
Parameters
----------
ringNum : int
The ring to remove
cs: CaseSettings
A relevant settings object
overrideCircularRingMode : bool, optional
False ~ default: use circular/square/hex rings, just as the reactor defines them
True ~ If you know you don't want to use the circular ring mode, and instead want square or hex.
Expand All @@ -458,7 +459,7 @@ def removeAssembliesInRing(self, ringNum, overrideCircularRingMode=False):
):
self.removeAssembly(a)

self.processLoading(settings.getMasterCs())
self.processLoading(cs)

def _removeListFromAuxiliaries(self, assembly):
"""
Expand Down
47 changes: 30 additions & 17 deletions armi/reactor/tests/test_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,28 +494,39 @@ 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
tCold = 20
tWarm = 50
tHot = 500
coldOuterDiameter = 1.0

def test_ComponentMassIndependentOfInputTemp(self):
coldT = 20
circle1 = Circle("circle", "HT9", coldT, self.tHot, self.coldOuterDiameter)
coldT += 200
def test_HT9Expansion(self):
self.runExpansionTests(mat="HT9", isotope="FE")

def test_UZrExpansion(self):
self.runExpansionTests(mat="UZr", isotope="U235")

def test_B4CExpansion(self):
self.runExpansionTests(mat="B4C", isotope="B10")

def runExpansionTests(self, mat: str, isotope: str):
self.componentMassIndependentOfInputTemp(mat)
self.expansionConservationHotHeightDefined(mat, isotope)
self.expansionConservationColdHeightDefined(mat)

def componentMassIndependentOfInputTemp(self, mat: str):
circle1 = Circle("circle", mat, self.tCold, self.tHot, self.coldOuterDiameter)
# pick the input dimension to get the same hot component
hotterDim = self.coldOuterDiameter * (
1 + circle1.material.linearExpansionFactor(coldT, 20)
1 + circle1.material.linearExpansionFactor(self.tCold + 200, self.tCold)
)
circle2 = Circle("circle", "HT9", coldT, self.tHot, hotterDim)
circle2 = Circle("circle", mat, self.tCold + 200, self.tHot, hotterDim)
self.assertAlmostEqual(circle1.getDimension("od"), circle2.getDimension("od"))
self.assertAlmostEqual(circle1.getArea(), circle2.getArea())
self.assertAlmostEqual(circle1.getMassDensity(), circle2.getMassDensity())

def test_ExpansionConservationHotHeightDefined(self):
def expansionConservationHotHeightDefined(self, mat: str, isotope: str):
"""
Demonstrate tutorial for how to expand and relation ships conserved at during expansion.
Demonstrate tutorial for how to expand and relationships conserved at during expansion.
Notes
-----
Expand All @@ -524,13 +535,13 @@ def test_ExpansionConservationHotHeightDefined(self):
"""
hotHeight = 1.0

circle1 = Circle("circle", "HT9", 20, self.tWarm, self.coldOuterDiameter)
circle2 = Circle("circle", "HT9", 20, self.tHot, self.coldOuterDiameter)
circle1 = Circle("circle", mat, self.tCold, self.tWarm, self.coldOuterDiameter)
circle2 = Circle("circle", mat, self.tCold, self.tHot, self.coldOuterDiameter)

# mass density is proportional to Fe number density and derived from
# all the number densities and atomic masses
self.assertAlmostEqual(
circle1.p.numberDensities["FE"] / circle2.p.numberDensities["FE"],
circle1.p.numberDensities[isotope] / circle2.p.numberDensities[isotope],
circle1.getMassDensity() / circle2.getMassDensity(),
)

Expand Down Expand Up @@ -615,7 +626,7 @@ def test_ExpansionConservationHotHeightDefined(self):
mass1, circle1.getMassDensity() * circle1.getArea() * hotHeight
)

def test_ExpansionConservationColdHeightDefined(self):
def expansionConservationColdHeightDefined(self, mat: str):
"""
Demonstrate that material is conserved at during expansion
Expand All @@ -625,10 +636,12 @@ def test_ExpansionConservationColdHeightDefined(self):
inputHeightsConsideredHot = False
"""
coldHeight = 1.0
circle1 = Circle("circle", "HT9", 20, self.tWarm, self.coldOuterDiameter)
circle2 = Circle("circle", "HT9", 20, self.tHot, self.coldOuterDiameter)
circle1 = Circle("circle", mat, self.tCold, self.tWarm, self.coldOuterDiameter)
circle2 = Circle("circle", mat, self.tCold, self.tHot, self.coldOuterDiameter)
# same as 1 but we will make like 2
circle1AdjustTo2 = Circle("circle", "HT9", 20, self.tWarm, 1.0)
circle1AdjustTo2 = Circle(
"circle", mat, self.tCold, self.tWarm, self.coldOuterDiameter
)

# make it hot like 2
circle1AdjustTo2.adjustDensityForHeightExpansion(self.tHot)
Expand Down
16 changes: 9 additions & 7 deletions armi/reactor/tests/test_reactors.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,25 @@
import os
import unittest

from six.moves import cPickle
from numpy.testing import assert_allclose, assert_equal
from six.moves import cPickle

from armi import operators
from armi import runLog
from armi import settings
from armi import tests
from armi.materials import uZr
from armi.reactor.flags import Flags
from armi.reactor import assemblies
from armi.reactor import blocks
from armi.reactor import grids
from armi.reactor import geometry
from armi.reactor import grids
from armi.reactor import reactors
from armi.reactor.components import Hexagon, Rectangle
from armi.reactor.converters import geometryConverters
from armi.reactor.converters.axialExpansionChanger import AxialExpansionChanger
from armi.reactor.flags import Flags
from armi.tests import ARMI_RUN_PATH, mockRunLogs, TEST_ROOT
from armi.utils import directoryChangers
from armi.reactor.converters.axialExpansionChanger import AxialExpansionChanger

TEST_REACTOR = None # pickled string of test reactor (for fast caching)

Expand Down Expand Up @@ -719,14 +719,14 @@ def test_removeAssembliesInRing(self):
for i, loc in enumerate(aLoc)
if loc in self.r.core.childrenByLocator
}
self.r.core.removeAssembliesInRing(3)
self.r.core.removeAssembliesInRing(3, self.o.cs)
for i, a in assems.items():
self.assertNotEqual(aLoc[i], a.spatialLocator)
self.assertEqual(a.spatialLocator.grid, self.r.core.sfp.spatialGrid)

def test_removeAssembliesInRingByCount(self):
self.assertEqual(self.r.core.getNumRings(), 9)
self.r.core.removeAssembliesInRing(9)
self.r.core.removeAssembliesInRing(9, self.o.cs)
self.assertEqual(self.r.core.getNumRings(), 8)

def test_removeAssembliesInRingHex(self):
Expand All @@ -736,7 +736,9 @@ def test_removeAssembliesInRingHex(self):
"""
self.assertEqual(self.r.core.getNumRings(), 9)
for ringNum in range(6, 10):
self.r.core.removeAssembliesInRing(ringNum, overrideCircularRingMode=True)
self.r.core.removeAssembliesInRing(
ringNum, self.o.cs, overrideCircularRingMode=True
)
self.assertEqual(self.r.core.getNumRings(), 5)

def test_getNozzleTypes(self):
Expand Down
14 changes: 13 additions & 1 deletion doc/release/0.2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,33 @@
ARMI v0.2 Release Notes
=======================

ARMI v0.2.5
ARMI v0.2.6
===========
Release Date: TBD

What's new in ARMI
------------------
#. TBD

Bug fixes
---------
#. TBD


ARMI v0.2.5
===========
Release Date: 2022-10-24

What's new in ARMI
------------------
#. Cleanup of stale ``coveragerc`` file (`PR#923 <https://github.com/terrapower/armi/pull/923>`_)
#. Added `medium` writer style option to ``SettingsWriter``. Added it as arg to modify CLI (`PR#924 <https://github.com/terrapower/armi/pull/924>`_), and to clone CLI (`PR#932 <https://github.com/terrapower/armi/pull/932>`_).
#. Update the EntryPoint class to provide user feedback on required positional arguments (`PR#922 <https://github.com/terrapower/armi/pull/922>`_)
#. Overhaul ``reactor.zones`` tooling and remove application-specific zoning logic (`PR#943 <https://github.com/terrapower/armi/pull/943>`_)

Bug fixes
---------
#. Adjusted density3 in armi/materials/b4C.py to include the theoretical density. (`PR#942 <https://github.com/terrapower/armi/pull/942>`_)
#. Fixed bug in ``fastFlux`` block parameter mapping in the ``UniformMeshConverter`` by applying it to the ``detailedAxialExpansion`` category.


Expand Down

0 comments on commit 70743d8

Please sign in to comment.