Skip to content

Commit

Permalink
Merge ad5f37d into 108e321
Browse files Browse the repository at this point in the history
  • Loading branch information
onufer committed Apr 23, 2020
2 parents 108e321 + ad5f37d commit 3872650
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 55 deletions.
48 changes: 11 additions & 37 deletions armi/reactor/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -1846,20 +1846,16 @@ def getPitch(self, returnComp=False):
setPitch : sets pitch
"""
c, p = self._pitchDefiningComponent
c, _p = self._pitchDefiningComponent

# Admittedly awkward here, but allows for a clean comparison when adding components to the
# block as opposed to initializing _pitchDefiningComponent to (None, None)
if c is None:
p = None
else:
# ask component for dimensions, since they could have changed
p = c.getDimension("op")
raise ValueError("{} has no valid pitch defining component".format(self))

if returnComp:
return p, c
else:
return p
# ask component for dimensions, since they could have changed,
# due to temperature, for example.
p = c.getPitchData()

return (p, c) if returnComp else p

def hasPinPitch(self):
"""Return True if the block has enough information to calculate pin pitch."""
Expand Down Expand Up @@ -2343,7 +2339,8 @@ def breakFuelComponentsIntoIndividuals(self):
# update moles at BOL for each pin
self.p.molesHmBOLByPin = []
for pinNum, pin in enumerate(self.iterComponents(Flags.FUEL)):
pin.p.flags = fuelFlags # Update the fuel component flags to be the same as before the split (i.e., DEPLETABLE)
# Update the fuel component flags to be the same as before the split (i.e., DEPLETABLE)
pin.p.flags = fuelFlags
self.p.molesHmBOLByPin.append(pin.getHMMoles())
pin.p.massHmBOL /= nPins

Expand Down Expand Up @@ -2702,7 +2699,8 @@ def getPinToDuctGap(self, cold=False):
face to face in cm.
"""
if self.LOCATION_CLASS is None:
return None # can't assume anything about dimensions if there is no location type
# can't assume anything about dimensions if there is no location type
return None

wire = self.getComponent(Flags.WIRE)
ducts = sorted(self.getChildrenWithFlags(Flags.DUCT))
Expand Down Expand Up @@ -2895,30 +2893,6 @@ def setPitch(self, val, updateBolParams=False, updateNumberDensityParams=True):
"not supported"
)

def getPitch(self, returnComp=False):
"""
Get xw and yw of the block.
See Also
--------
Block.getPitch
"""
c, _p = self._pitchDefiningComponent

# Admittedly awkward here, but allows for a clean comparison when adding components to the
# block as opposed to initializing _pitchDefiningComponent to (None, None)
if c is None:
raise ValueError("{} has no valid pitch".format(self))
else:
# ask component for dimensions, since they could have changed
maxLength = c.getDimension("lengthOuter")
maxWidth = c.getDimension("widthOuter")

if returnComp:
return (maxLength, maxWidth), c
else:
return (maxLength, maxWidth)

def getSymmetryFactor(self):
"""
Return a factor between 1 and N where 1/N is how much cut-off by symmetry lines this mesh
Expand Down
39 changes: 39 additions & 0 deletions armi/reactor/components/basicShapes.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,18 @@ def getPerimeter(self, Tc=None):
perimeter = 6 * (ip / math.sqrt(3)) * mult
return perimeter

def getPitchData(self):
"""
Return the pitch data that should be used to determine block pitch.
Notes
-----
This pitch data should only be used if this is the pitch defining component in
a block. The block is responsible for determining which component in it is the
pitch defining component.
"""
return self.getDimension("op")


class Rectangle(ShapedComponent):
"""A rectangle component."""
Expand Down Expand Up @@ -209,6 +221,19 @@ def isLatticeComponent(self):
"""Return true if the component is a `lattice component` containing void material and zero area."""
return self.containsVoidMaterial() and self.getArea() == 0.0

def getPitchData(self):
"""
Return the pitch data that should be used to determine block pitch.
Notes
-----
For rectangular components there are two pitches, one for each dimension.
This pitch data should only be used if this is the pitch defining component in
a block. The block is responsible for determining which component in it is the
pitch defining component.
"""
return (self.getDimension("lengthOuter"), self.getDimension("widthOuter"))


class SolidRectangle(Rectangle):
"""Solid rectangle component."""
Expand Down Expand Up @@ -318,6 +343,20 @@ def getBoundingCircleOuterDiameter(self, Tc=None, cold=False):
widthO = self.getDimension("widthOuter", Tc, cold=cold)
return math.sqrt(widthO ** 2 + widthO ** 2)

def getPitchData(self):
"""
Return the pitch data that should be used to determine block pitch.
Notes
-----
For rectangular components there are two pitches, one for each dimension.
This pitch data should only be used if this is the pitch defining component in
a block. The block is responsible for determining which component in it is the
pitch defining component.
"""
# both dimensions are the same for a square.
return (self.getDimension("widthOuter"), self.getDimension("widthOuter"))


class Triangle(ShapedComponent):
"""
Expand Down
15 changes: 15 additions & 0 deletions armi/reactor/components/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,21 @@ def makeCrossSectionTable(self, nuclides=None):
def getMicroSuffix(self):
return self.parent.getMicroSuffix()

def getPitchData(self):
"""
Return the pitch data that should be used to determine block pitch.
Notes
-----
This pitch data should only be used if this is the pitch defining component in
a block. The block is responsible for determining which component in it is the
pitch defining component.
"""
raise NotImplementedError(
f"Method not implemented on component {self}. "
"Please implement if this component type can be a pitch defining component."
)


class ShapedComponent(Component):
"""A component with well-defined dimensions."""
Expand Down
42 changes: 24 additions & 18 deletions armi/reactor/tests/test_blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -1118,20 +1118,6 @@ def test102_setPitch(self):
self.Block.getComponent(Flags.INTERCOOLANT).getDimension("op"), pitch
)

def test_UnshapedGetPitch(self):
"""
Test that a homogenous block can be created with a specific pitch.
This functionality is necessary for making simple homogenous reactors.
"""
block = blocks.HexBlock("TestHexBlock", location=None)
outerPitch = 2.0
block.addComponent(
UnshapedComponent(
"TestComponent", "Void", Tinput=25.0, Thot=25.0, op=outerPitch
)
)
self.assertEqual(block.getPitch(), outerPitch)

def test106_getAreaFractions(self):

cur = self.Block.getVolumeFractions()
Expand Down Expand Up @@ -1524,11 +1510,32 @@ def test_getPinCoords(self):


class CartesianBlock_TestCase(unittest.TestCase):
"""Tests for blocks with rectangular/square outer shape."""

PITCH = 70

def setUp(self):
caseSetting = settings.Settings()
caseSetting["xw"] = 5.0
caseSetting["yw"] = 3.0
self.CartesianBlock = blocks.CartesianBlock("TestCartesianBlock", caseSetting)
self.cartesianBlock = blocks.CartesianBlock("TestCartesianBlock", caseSetting)

self.cartesianComponent = components.HoledSquare(
"duct",
"UZr",
Tinput=273.0,
Thot=273.0,
holeOD=68.0,
widthOuter=self.PITCH,
mult=1.0,
)
self.cartesianBlock.addComponent(self.cartesianComponent)
self.cartesianBlock.addComponent(
components.Circle(
"clad", "HT9", Tinput=273.0, Thot=273.0, od=68.0, mult=169.0
)
)

def test_getPitch(self):
self.assertEqual(self.cartesianBlock.getPitch(), (self.PITCH, self.PITCH))


class MassConservationTests(unittest.TestCase):
Expand All @@ -1538,7 +1545,6 @@ class MassConservationTests(unittest.TestCase):

def setUp(self):
# build a block that has some basic components in it.
cs = settings.Settings()
self.b = blocks.HexBlock("fuel", height=10.0)

fuelDims = {"Tinput": 25.0, "Thot": 600, "od": 0.76, "id": 0.00, "mult": 127.0}
Expand Down

0 comments on commit 3872650

Please sign in to comment.