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 12 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
13 changes: 5 additions & 8 deletions armi/bookkeeping/visualization/tests/test_vis.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@

from armi import settings
from armi.bookkeeping.db import Database3
from armi.bookkeeping.visualization import utils
from armi.bookkeeping.visualization import vtk
from armi.bookkeeping.visualization import xdmf
from armi.bookkeeping.visualization import utils, vtk, xdmf
from armi.reactor import blocks
from armi.reactor import components
from armi.reactor.components.basicShapes import Circle
from armi.reactor.components.complexShapes import HoledSquare
from armi.reactor.tests import test_reactors
from armi.utils.directoryChangers import TemporaryDirectoryChanger

Expand Down Expand Up @@ -74,7 +73,7 @@ def setUpClass(cls):
cls.hexBlock = cls.r.core.getBlocks()[0]

cls.cartesianBlock = blocks.CartesianBlock("TestCartesianBlock", caseSetting)
cartesianComponent = components.HoledSquare(
cartesianComponent = HoledSquare(
"duct",
"UZr",
Tinput=273.0,
Expand All @@ -85,9 +84,7 @@ def setUpClass(cls):
)
cls.cartesianBlock.add(cartesianComponent)
cls.cartesianBlock.add(
components.Circle(
"clad", "HT9", Tinput=273.0, Thot=273.0, od=68.0, mult=169.0
)
Circle("clad", "HT9", Tinput=273.0, Thot=273.0, od=68.0, mult=169.0)
)

def test_dumpReactorVtk(self):
Expand Down
10 changes: 5 additions & 5 deletions armi/nucDirectory/tests/test_thermalScattering.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

from armi.nucDirectory import nuclideBases as nb
from armi.nucDirectory import thermalScattering as ts
from armi.reactor import blocks
from armi.reactor import components
from armi.reactor import blocks, components
from armi.reactor.components.basicShapes import Circle


def buildBlockWithTSL():
Expand All @@ -28,8 +28,8 @@ def buildBlockWithTSL():
cladDims = {"Tinput": 25.0, "Thot": 450, "od": 0.80, "id": 0.77, "mult": 127.0}
coolDims = {"Tinput": 25.0, "Thot": 400}

fuel = components.Circle("fuel", "UZr", **fuelDims)
clad = components.Circle("clad", "Graphite", **cladDims)
fuel = Circle("fuel", "UZr", **fuelDims)
clad = Circle("clad", "Graphite", **cladDims)
coolant = components.DerivedShape("coolant", "Sodium", **coolDims)

b.add(fuel)
Expand Down Expand Up @@ -96,7 +96,7 @@ def test_failOnMultiple(self):
"""HT9 has carbon in it with no TSL, while graphite has C with TSL. This should crash."""
b = buildBlockWithTSL()
cladDims = {"Tinput": 25.0, "Thot": 450, "od": 0.80, "id": 0.79, "mult": 127.0}
clad2 = components.Circle("clad", "HT9", **cladDims)
clad2 = Circle("clad", "HT9", **cladDims)
b.add(clad2)
with self.assertRaises(RuntimeError):
getNuclideThermalScatteringData(b)
Expand Down
13 changes: 6 additions & 7 deletions armi/physics/fuelCycle/tests/test_fuelHandlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,13 @@
from armi.physics.neutronics.latticePhysics.latticePhysicsInterface import (
LatticePhysicsInterface,
)
from armi.reactor import assemblies, blocks, components, grids
from armi.reactor import assemblies, blocks, grids
from armi.reactor.components.basicShapes import Circle, Hexagon
from armi.reactor.flags import Flags
from armi.reactor.tests import test_reactors
from armi.reactor.zones import Zone
from armi.settings import caseSettings
from armi.tests import ArmiTestHelper
from armi.tests import mockRunLogs
from armi.tests import TEST_ROOT
from armi.tests import TEST_ROOT, ArmiTestHelper, mockRunLogs
from armi.utils import directoryChangers


Expand Down Expand Up @@ -86,10 +85,10 @@ def setUp(self):
nPins = 271

fuelDims = {"Tinput": 273.0, "Thot": 273.0, "od": 1.0, "id": 0.0, "mult": nPins}
fuel = components.Circle("fuel", "UZr", **fuelDims)
fuel = Circle("fuel", "UZr", **fuelDims)

cladDims = {"Tinput": 273.0, "Thot": 273.0, "od": 1.1, "id": 1.0, "mult": nPins}
clad = components.Circle("clad", "HT9", **cladDims)
clad = Circle("clad", "HT9", **cladDims)

interDims = {
"Tinput": 273.0,
Expand All @@ -98,7 +97,7 @@ def setUp(self):
"ip": 16.0,
"mult": 1.0,
}
interSodium = components.Hexagon("interCoolant", "Sodium", **interDims)
interSodium = Hexagon("interCoolant", "Sodium", **interDims)

# generate a block
self.block = blocks.HexBlock("TestHexBlock")
Expand Down
8 changes: 4 additions & 4 deletions armi/physics/neutronics/tests/test_crossSectionManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,10 +621,10 @@ def test_checkComponentConsistency(self):
blockCollection._checkComponentConsistency(refBlock, b)

def _makeComponents(self, multiplicity, densities):
from armi.reactor import components
from armi.reactor.components.basicShapes import Circle

baseComponents = self.r.core.getFirstBlock(Flags.CONTROL).getComponents()
controlComponent = components.Circle(
controlComponent = Circle(
"control",
baseComponents[0].material,
20.0,
Expand All @@ -633,7 +633,7 @@ def _makeComponents(self, multiplicity, densities):
od=0.6,
mult=multiplicity,
)
cladComponent = components.Circle(
cladComponent = Circle(
"clad",
baseComponents[2].material,
20.0,
Expand All @@ -642,7 +642,7 @@ def _makeComponents(self, multiplicity, densities):
od=0.7,
mult=multiplicity,
)
coolantComponent = components.Circle(
coolantComponent = Circle(
"coolant",
baseComponents[4].material,
20.0,
Expand Down
12 changes: 7 additions & 5 deletions armi/reactor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
See :doc:`/developer/index`.
"""

from typing import Dict, Callable, Union, TYPE_CHECKING
from typing import TYPE_CHECKING, Callable, Dict, Union
mgjarrett marked this conversation as resolved.
Show resolved Hide resolved

from armi import plugins

Expand All @@ -66,9 +66,11 @@ class ReactorPlugin(plugins.ArmiPlugin):
@staticmethod
@plugins.HOOKIMPL
def defineBlockTypes():
from armi.reactor.components.basicShapes import Rectangle, Hexagon
from armi.reactor.components.volumetricShapes import RadialSegment
from armi.reactor import blocks
from armi.reactor.components.basicShapes import Hexagon, Rectangle
from armi.reactor.components.volumetricShapes import (
RadialSegment,
)

return [
(Rectangle, blocks.CartesianBlock),
Expand All @@ -79,8 +81,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
46 changes: 22 additions & 24 deletions armi/reactor/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,31 @@

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.reactor.components import basicShapes
from armi.reactor.components.basicShapes import Hexagon, Circle
from armi.reactor.components.complexShapes import Helix
from armi.physics.neutronics import GAMMA, NEUTRON
from armi.reactor import (
blockParameters,
components,
composites,
geometry,
grids,
parameters,
)
from armi.reactor.components.basicShapes import Circle, Hexagon, Rectangle
from armi.reactor.components.complexShapes import Helix, HoledHexagon

# this unused import is required so that the RadialSegment component type is registered
from armi.reactor.components.volumetricShapes import RadialSegment
mgjarrett marked this conversation as resolved.
Show resolved Hide resolved
from armi.reactor.flags import Flags
from armi.reactor.parameters import ParamLocation
from armi.utils import densityTools
Expand Down Expand Up @@ -232,7 +234,7 @@ def getSmearDensity(self, cold=True):
if not fuels:
return 0.0 # Smear density is not computed for non-fuel blocks

circles = self.getComponentsOfShape(components.Circle)
circles = self.getComponentsOfShape(Circle)
if not circles:
raise ValueError(
"Cannot get smear density of {}. There are no circular components.".format(
Expand Down Expand Up @@ -1066,11 +1068,7 @@ def getNumPins(self):
nPins = [
sum(
[
(
int(c.getDimension("mult"))
if isinstance(c, basicShapes.Circle)
else 0
)
(int(c.getDimension("mult")) if isinstance(c, Circle) else 0)
for c in self.iterComponents(compType)
]
)
Expand Down Expand Up @@ -1756,7 +1754,7 @@ class HexBlock(Block):
pitch, pin linear power densities, hydraulic diameter, and retrieving inner and outer pitch.
"""

PITCH_COMPONENT_TYPE: ClassVar[_PitchDefiningComponent] = (components.Hexagon,)
PITCH_COMPONENT_TYPE: ClassVar[_PitchDefiningComponent] = (Hexagon,)

def __init__(self, name, height=1.0):
Block.__init__(self, name, height)
Expand Down Expand Up @@ -2246,11 +2244,11 @@ def getPinToDuctGap(self, cold=False):
duct = None
if any(ducts):
duct = ducts[0]
if not isinstance(duct, components.Hexagon):
if not isinstance(duct, Hexagon):
# getPinCenterFlatToFlat only works for hexes
# inner most duct might be circle or some other shape
duct = None
elif isinstance(duct, components.HoledHexagon):
elif isinstance(duct, HoledHexagon):
# has no ip and is circular on inside so following
# code will not work
duct = None
Expand Down Expand Up @@ -2596,7 +2594,7 @@ def getHydraulicDiameter(self):

class CartesianBlock(Block):
PITCH_DIMENSION = "widthOuter"
PITCH_COMPONENT_TYPE = components.Rectangle
PITCH_COMPONENT_TYPE = Rectangle

def getMaxArea(self):
"""Get area of this block if it were totally full."""
Expand Down
11 changes: 5 additions & 6 deletions armi/reactor/blueprints/componentBlueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@
"""
import yamlize

from armi import runLog
from armi import materials
from armi.reactor import components
from armi.reactor import composites
from armi import materials, runLog
from armi.nucDirectory import nuclideBases
from armi.reactor import components, composites
from armi.reactor.components import component
from armi.reactor.flags import Flags
from armi.utils import densityTools
from armi.nucDirectory import nuclideBases

COMPONENT_GROUP_SHAPE = "group"

Expand All @@ -42,7 +41,7 @@ def __init__(self, value):
# note: yamlizable does not call an __init__ method, instead it uses __new__ and setattr
self.value = value
if isinstance(value, str):
if not components.COMPONENT_LINK_REGEX.search(value):
if not component.COMPONENT_LINK_REGEX.search(value):
mgjarrett marked this conversation as resolved.
Show resolved Hide resolved
raise ValueError(
"Bad component link `{}`, must be in form `name.dimension`".format(
value
Expand Down
26 changes: 22 additions & 4 deletions armi/reactor/components/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@
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.volumetricShapes import * # noqa: F403
drewj-tp marked this conversation as resolved.
Show resolved Hide resolved
from armi.reactor.components.component import (
Component,
ComponentType,
componentParameters,
)


def factory(shape, bcomps, kwargs):
Expand Down Expand Up @@ -186,6 +187,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):
"""
Approximate the component as circular; i.e., inner diameter is zero.

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
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems like an okay thing for a shaped component to have to define on their own. Maybe a DerivedShape is the only exception.

Saying this because we try/catch a NotImplementedError below so if Component.getCircleInnerDiameter is required for components, we'd be okay in that context.

But that could be a larger change that is likely better served outside this PR.

Non-blocking comment. If there's traction I can make a ticket

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The assumption for the unshaped component is to return the smallest possible bounding circle outer diameter, i.e., assume the component has a disk shape. It seems consistent with that assumption to assume that the inner diameter is 0.0.

The exception is caught in __lt__, but only for the purpose of producing a clearer error message. The error is still raised and the code crashes. So we still need to be able to sort UnshapedComponents.


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

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


class Circle(ShapedComponent):
Expand Down
5 changes: 2 additions & 3 deletions armi/reactor/components/complexShapes.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@

import math

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


class HoledHexagon(basicShapes.Hexagon):
Expand Down
Loading
Loading