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

Implement more detailed __lt__ for components. #1882

Draft
wants to merge 37 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
707aa88
Implement more detailed __lt__ for components.
mgjarrett Sep 11, 2024
35b63a8
Add a unit test for component sorting.
mgjarrett Sep 16, 2024
6bc7dc1
Update release notes.
mgjarrett Sep 16, 2024
1265d7c
Address linting error
mgjarrett Sep 16, 2024
dbed10f
Catch NotImplementedError
mgjarrett Sep 16, 2024
0fd1632
Remove all of the circular imports in components.
mgjarrett Sep 16, 2024
cca4a14
Fix broken unit tests.
mgjarrett Sep 16, 2024
06f1ec1
Fix unit test reference result.
mgjarrett Sep 16, 2024
37e8f0b
Register RadialSegment component type.
mgjarrett Sep 16, 2024
af44807
Black formatting.
mgjarrett Sep 16, 2024
c65a0c3
Merge branch 'main' into component_sort
mgjarrett Sep 16, 2024
9cb98e5
Refactor more unit tests.
mgjarrett Sep 16, 2024
d50b6dc
Ignore unused import
mgjarrett Sep 16, 2024
d1db895
Revert "Refactor more unit tests."
mgjarrett Sep 16, 2024
6c891fd
Revert "Fix broken unit tests."
mgjarrett Sep 16, 2024
914fe58
Revert "Remove all of the circular imports in components."
mgjarrett Sep 16, 2024
88feb80
Clear merge conflict.
mgjarrett Sep 16, 2024
0b1b6ef
Revert trivial change.
mgjarrett Sep 16, 2024
12980cd
Add getCircleInnerDiameter for UnshapedComponent.
mgjarrett Sep 16, 2024
a62fd41
Fix circular import.
mgjarrett Sep 16, 2024
acbf2fc
Black formatting.
mgjarrett Sep 16, 2024
53780e4
Update docstring.
mgjarrett Sep 16, 2024
2a7e4a1
Address review comments.
mgjarrett Sep 16, 2024
64d1d09
One more review comment.
mgjarrett Sep 16, 2024
37e4310
Remove commented code.
mgjarrett Sep 16, 2024
80d57ab
Remove kwargs
mgjarrett Sep 16, 2024
9457b49
Black formatting
mgjarrett Sep 16, 2024
6dca45a
Fix namespace errors.
mgjarrett Sep 16, 2024
4e2234b
Add getCircleInnerDiameter to RadialSegment.
mgjarrett Sep 16, 2024
48603a4
Update armi/reactor/components/__init__.py
mgjarrett Sep 16, 2024
3ccdc5b
Update doc/release/0.4.rst
mgjarrett Sep 16, 2024
2075f3a
Revert to main blocks.py
mgjarrett Sep 16, 2024
5b601f9
Revert import change.
mgjarrett Sep 16, 2024
15155be
Merge branch 'component_sort' of https://github.com/terrapower/armi i…
mgjarrett Sep 16, 2024
7733ad8
Revert more import changes.
mgjarrett Sep 16, 2024
9b61363
Revert more imports.
mgjarrett Sep 16, 2024
b87c1d1
Fix an import.
mgjarrett Sep 16, 2024
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
4 changes: 2 additions & 2 deletions armi/reactor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ def defineBlockTypes():
@staticmethod
@plugins.HOOKIMPL
def defineAssemblyTypes():
from armi.reactor.blocks import HexBlock, CartesianBlock, ThRZBlock
from armi.reactor.assemblies import HexAssembly, CartesianAssembly, ThRZAssembly
from armi.reactor.blocks import CartesianBlock, HexBlock, ThRZBlock
from armi.reactor.assemblies import CartesianAssembly, HexAssembly, ThRZAssembly

return [
(HexBlock, HexAssembly),
Expand Down
35 changes: 15 additions & 20 deletions armi/reactor/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,30 @@

Assemblies are made of blocks. Blocks are made of components.
"""
from typing import Optional, Type, Tuple, ClassVar
import collections
import copy
import math
from typing import ClassVar, Optional, Tuple, Type

import numpy as np

from armi import nuclideBases
from armi import runLog
from armi import nuclideBases, runLog
from armi.bookkeeping import report
from armi.nucDirectory import elements
from armi.nuclearDataIO import xsCollections
from armi.physics.neutronics import GAMMA
from armi.physics.neutronics import NEUTRON
from armi.reactor import blockParameters
from armi.reactor import components
from armi.reactor import composites
from armi.reactor import geometry
from armi.reactor import grids
from armi.reactor import parameters
from armi.physics.neutronics import GAMMA, NEUTRON
from armi.reactor import (
blockParameters,
components,
composites,
geometry,
grids,
parameters,
)
from armi.reactor.components import basicShapes
from armi.reactor.components.basicShapes import Hexagon, Circle
from armi.reactor.components.complexShapes import Helix
from armi.reactor.flags import Flags
from armi.reactor.parameters import ParamLocation
from armi.utils import densityTools
from armi.utils import hexagon
from armi.utils import iterables
from armi.utils import units
from armi.utils import densityTools, hexagon, iterables, units
from armi.utils.plotting import plotBlockFlux
from armi.utils.units import TRACE_NUMBER_DENSITY

Expand Down Expand Up @@ -1844,7 +1839,7 @@ def createHomogenizedCopy(self, pinSpatialLocators=False):
b._lumpedFissionProducts = self._lumpedFissionProducts
b.p.buGroup = self.p.buGroup

hexComponent = Hexagon(
hexComponent = components.Hexagon(
"homogenizedHex",
"_Mixture",
self.getAverageTempInC(),
Expand All @@ -1861,7 +1856,7 @@ def createHomogenizedCopy(self, pinSpatialLocators=False):
if self.hasComponents(Flags.CLAD):
cladComponents = self.getComponents(Flags.CLAD)
for i, clad in enumerate(cladComponents):
pinComponent = Circle(
pinComponent = components.Circle(
f"voidPin{i}",
"Void",
self.getAverageTempInC(),
Expand Down Expand Up @@ -2532,7 +2527,7 @@ def getWettedPerimeter(self):
wettedPinPerimeter = 0.0
for c in wettedPinComponents:
correctionFactor = 1.0
if isinstance(c, Helix):
if isinstance(c, components.Helix):
# account for the helical wire wrap
correctionFactor = np.hypot(
1.0,
Expand Down
19 changes: 18 additions & 1 deletion armi/reactor/components/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@
import numpy as np

from armi import runLog
from armi.reactor.components.component import * # noqa: F403
from armi.reactor.components.basicShapes import * # noqa: F403
from armi.reactor.components.complexShapes import * # noqa: F403
from armi.reactor.components.component import * # noqa: F403
from armi.reactor.components.volumetricShapes import * # noqa: F403


Expand Down Expand Up @@ -186,6 +186,23 @@ def getBoundingCircleOuterDiameter(self, Tc=None, cold=False):
"""
return 2 * math.sqrt(self.getComponentArea(cold=cold) / math.pi)

def getCircleInnerDiameter(self, Tc=None, cold=False):
"""
Component is unshaped; assume it is circular and there is no ID (return 0.0).

Parameters
----------
Tc : float
Ignored for this component
cold : bool, optional
If True, compute the area with as-input dimensions, instead of thermally-expanded.
mgjarrett marked this conversation as resolved.
Show resolved Hide resolved

Notes
-----
Tc is not used in this method for this particular component.
"""
return 0.0

@staticmethod
def fromComponent(otherComponent):
"""
Expand Down
3 changes: 1 addition & 2 deletions armi/reactor/components/basicShapes.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
"""
import math

from armi.reactor.components import ShapedComponent
from armi.reactor.components import componentParameters
from armi.reactor.components.component import ShapedComponent, componentParameters
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mike, can we fix your IDE?

I don't particularly like these changes, and they make your PRs more muddled to read. Like... you didn't actually touch this file.

#sorry

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing. I was able to turn it off, so I'll go through and revert these import changes.



class Circle(ShapedComponent):
Expand Down
40 changes: 25 additions & 15 deletions armi/reactor/components/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,11 @@

import numpy as np

from armi import materials
from armi import runLog
from armi import materials, runLog
from armi.bookkeeping import report
from armi.materials import custom
from armi.materials import material
from armi.materials import void
from armi.materials import custom, material, void
from armi.nucDirectory import nuclideBases
from armi.reactor import composites
from armi.reactor import flags
from armi.reactor import parameters
from armi.reactor import composites, flags, parameters
from armi.reactor.components import componentParameters
from armi.utils import densityTools
from armi.utils.units import C_TO_K
Expand Down Expand Up @@ -273,19 +268,34 @@ def __lt__(self, other):
"""
True if a circle encompassing this object has a smaller diameter than one encompassing another component.

If the bounding circles for both components have identical size, then revert to checking the inner
diameter of each component for sorting.

This allows sorting because the Python sort functions only use this method.
"""
thisOD = self.getBoundingCircleOuterDiameter(cold=True)
thatOD = other.getBoundingCircleOuterDiameter(cold=True)
try:
return thisOD < thatOD
except Exception:
raise ValueError(
"Components 1 ({} with OD {}) and 2 ({} and OD {}) cannot be ordered because their "
"bounding circle outer diameters are not comparable.".format(
self, thisOD, other, thatOD
if thisOD == thatOD:
thisID = self.getCircleInnerDiameter(cold=True)
thatID = other.getCircleInnerDiameter(cold=True)
return thisID < thatID
else:
return thisOD < thatOD
mgjarrett marked this conversation as resolved.
Show resolved Hide resolved
except (NotImplementedError, Exception) as e:
if isinstance(e, NotImplementedError):
raise NotImplementedError(
"getCircleInnerDiameter not implemented for at least one of {}, {}".format(
self, other
)
)
else:
raise ValueError(
"Components 1 ({} with OD {}) and 2 ({} and OD {}) cannot be ordered because their "
"bounding circle outer diameters are not comparable.".format(
self, thisOD, other, thatOD
)
)
)

def __setstate__(self, state):
composites.Composite.__setstate__(self, state)
Expand Down
8 changes: 5 additions & 3 deletions armi/reactor/components/volumetricShapes.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@

import math

from armi.reactor.components import componentParameters
from armi.reactor.components import ShapedComponent
from armi.reactor.components import ShapedComponent, componentParameters


class Sphere(ShapedComponent):
Expand Down Expand Up @@ -250,7 +249,10 @@ def getComponentVolume(self):
return vol

def getBoundingCircleOuterDiameter(self, Tc=None, cold=False):
return self.getDimension("outer_radius", Tc, cold)
return 2.0 * self.getDimension("outer_radius", Tc, cold)
mgjarrett marked this conversation as resolved.
Show resolved Hide resolved

def getCircleInnerDiameter(self, Tc=None, cold=False):
return 2.0 * self.getDimension("inner_radius", Tc, cold)


class DifferentialRadialSegment(RadialSegment):
Expand Down
77 changes: 61 additions & 16 deletions armi/reactor/tests/test_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,31 @@

from armi.materials import air, alloy200
from armi.materials.material import Material
from armi.reactor import components
from armi.reactor import flags
from armi.reactor import components, flags
from armi.reactor.components import (
Component,
UnshapedComponent,
NullComponent,
Circle,
Component,
ComponentType,
Cube,
DerivedShape,
DifferentialRadialSegment,
Helix,
Hexagon,
HoledHexagon,
HexHoledCircle,
HoledHexagon,
HoledRectangle,
HoledSquare,
Helix,
Sphere,
Cube,
NullComponent,
RadialSegment,
Rectangle,
SolidRectangle,
Sphere,
Square,
Triangle,
RadialSegment,
DifferentialRadialSegment,
DerivedShape,
UnshapedComponent,
UnshapedVolumetricComponent,
ComponentType,
materials,
)
from armi.reactor.components import materials
from armi.reactor.tests.test_reactors import loadTestReactor


Expand Down Expand Up @@ -508,6 +507,52 @@ def test_getAreaColdTrue(self):
self.assertAlmostEqual(totalAreaCold, totalAreaHot, delta=1e-10)


class TestComponentSort(unittest.TestCase):
def setUp(self):
self.components = []
pinComp = components.Circle(
"pin", "UZr", Tinput=273.0, Thot=273.0, od=0.08, mult=169.0
)
gapComp = components.Circle(
"gap", "Sodium", Tinput=273.0, Thot=273.0, id=0.08, od=0.08, mult=169.0
)
ductComp = components.Hexagon(
"duct", "HT9", Tinput=273.0, Thot=273.0, op=2.6, ip=2.0, mult=1.0
)
cladComp = components.Circle(
"clad", "HT9", Tinput=273.0, Thot=273.0, id=0.08, od=0.1, mult=169.0
)
wireComp = components.Helix(
"wire",
"HT9",
Tinput=273.0,
Thot=273.0,
axialPitch=10.0,
helixDiameter=0.11,
od=0.01,
mult=169.0,
)
self.components = [
wireComp,
cladComp,
ductComp,
pinComp,
gapComp,
]

def test_sorting(self):
"""Test that components are sorted as expected."""
sortedComps = sorted(self.components)
currentMaxOd = 0.0
for c in sortedComps:
self.assertGreaterEqual(
c.getBoundingCircleOuterDiameter(cold=True), currentMaxOd
)
currentMaxOd = c.getBoundingCircleOuterDiameter(cold=True)
self.assertEqual(sortedComps[1].name, "gap")
self.assertEqual(sortedComps[2].name, "clad")


class TestCircle(TestShapedComponent):
"""Test circle shaped component."""

Expand Down Expand Up @@ -1613,7 +1658,7 @@ def test_thermallyExpands(self):

def test_getBoundingCircleOuterDiameter(self):
self.assertEqual(
self.component.getBoundingCircleOuterDiameter(cold=True), 170.0
self.component.getBoundingCircleOuterDiameter(cold=True), 340.0
)


Expand Down Expand Up @@ -1660,7 +1705,7 @@ def test_thermallyExpands(self):
self.assertFalse(self.component.THERMAL_EXPANSION_DIMS)

def test_getBoundingCircleOuterDiameter(self):
self.assertEqual(self.component.getBoundingCircleOuterDiameter(cold=True), 170)
self.assertEqual(self.component.getBoundingCircleOuterDiameter(cold=True), 340)


class TestMaterialAdjustments(unittest.TestCase):
Expand Down
1 change: 1 addition & 0 deletions doc/release/0.4.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ New Features
:func:`armi.utils.hexagon.getIndexOfRotatedCell`
(`PR#1846 <https://github.com/terrapower/armi/1846`)
#. Allow merging a component with zero area into another component (`PR#1858 <https://github.com/terrapower/armi/pull/1858>`_)
#. Use inner diameter for sorting components when outer diameter is identical (`PR#1882 <https://github.com/terrapower/armi/pull/1882>`_)
mgjarrett marked this conversation as resolved.
Show resolved Hide resolved
#. TBD

API Changes
Expand Down
Loading