Example #1
0
    def _constructAssembly(self, cs, blueprint):
        """Construct the current assembly."""
        blocks = []
        for axialIndex, bDesign in enumerate(self.blocks):
            b = self._createBlock(cs, blueprint, bDesign, axialIndex)
            blocks.append(b)

        assemblyClass = self.getAssemClass(blocks)
        a = assemblyClass(self.name)
        # set a basic grid with the right number of blocks with bounds to be adjusted.
        a.spatialGrid = grids.axialUnitGrid(len(blocks))
        a.spatialGrid.armiObject = a

        # TODO: Remove mesh points from blueprints entirely. Submeshing should be
        # handled by specific physics interfaces
        radMeshPoints = self.radialMeshPoints or 1
        a.p.RadMesh = radMeshPoints
        aziMeshPoints = self.azimuthalMeshPoints or 1
        a.p.AziMesh = aziMeshPoints

        # loop a second time because we needed all the blocks before choosing the
        # assembly class.
        for axialIndex, block in enumerate(blocks):
            b.p.assemNum = a.p.assemNum
            b.name = b.makeName(a.p.assemNum, axialIndex)
            a.add(block)

        # Assign values for the parameters if they are defined on the blueprints
        for paramDef in a.p.paramDefs.inCategory(
                parameters.Category.assignInBlueprints):
            val = getattr(self, paramDef.name)
            if val is not None:
                a.p[paramDef.name] = val

        return a
Example #2
0
    def doubleResolution(self):
        """
        Turns each block into two half-size blocks.

        Notes
        -----
        Used for mesh sensitivity studies.

        .. warning:: This is likely destined for a geometry converter rather than
            this instance method.
        """
        newBlockStack = []
        topIndex = -1
        for b in self:
            b0 = b
            b1 = copy.deepcopy(b)
            for bx in [b0, b1]:
                newHeight = bx.getHeight() / 2.0
                bx.p.height = newHeight
                bx.p.heightBOL = newHeight
                topIndex += 1
                bx.p.topIndex = topIndex
                newBlockStack.append(bx)
                bx.clearCache()

        self.removeAll()
        self.spatialGrid = grids.axialUnitGrid(len(newBlockStack))
        for b in newBlockStack:
            self.add(b)
        self.reestablishBlockOrder()
Example #3
0
    def test_setMass(self):
        """
        test:
            setMass
            setMasses
        """
        loc = locations.Location(i1=1, i2=1, axial=1)
        mass = 1.0

        aB = batch.Batch("testBatch")
        c = shapes.UnshapedVolumetricComponent(
            "batchMassAdditionComponent", custom.Custom(), 0.0, 0.0, volume=1
        )
        b = blocks.Block("testBlock", location=loc)
        b.add(c)
        a = assemblies.Assembly("testAssembly")
        a.spatialGrid = grids.axialUnitGrid(1, a)
        a.add(b)

        r = getEmptyHexReactor()
        a.spatialLocator = r.core.spatialGrid[0, 0, 0]
        r.core.add(a)

        # these armi objects have setMass implemented
        for armiObj in [aB, c, b]:
            for nucName in ["U235"]:
                masses = {nucName: mass}
                armiObj.setMasses(masses)
                self.assertAlmostEqual(armiObj.getMass(nucName), mass, 6)
Example #4
0
def buildOperatorOfEmptyHexBlocks(customSettings=None):
    """
    Builds a operator w/ a reactor object with some hex assemblies and blocks, but all are empty

    Doesn't depend on inputs and loads quickly.

    Params
    ------
    customSettings : dict
        Dictionary of off-default settings to update
    """
    settings.setMasterCs(None)  # clear
    cs = settings.getMasterCs()  # fetch new
    cs["db"] = False  # stop use of database
    if customSettings is not None:
        cs.update(customSettings)
    r = tests.getEmptyHexReactor()
    r.core.setOptionsFromCs(cs)
    o = operators.Operator(cs)
    o.initializeInterfaces(r)

    a = assemblies.HexAssembly("fuel")
    a.spatialGrid = grids.axialUnitGrid(1)
    b = blocks.HexBlock("TestBlock")
    b.setType("fuel")
    dims = {"Tinput": 600, "Thot": 600, "op": 16.0, "ip": 1, "mult": 1}
    c = Hexagon("fuel", uZr.UZr(), **dims)
    b.add(c)
    a.add(b)
    a.spatialLocator = r.core.spatialGrid[1, 0, 0]
    o.r.core.add(a)
    return o
Example #5
0
    def _constructAssembly(self, cs, blueprint):
        """Construct the current assembly."""
        blocks = []
        for axialIndex, bDesign in enumerate(self.blocks):
            b = self._createBlock(cs, blueprint, bDesign, axialIndex)
            blocks.append(b)

        assemblyClass = self.getAssemClass(blocks)
        a = assemblyClass(self.name)
        # set a basic grid with the right number of blocks with bounds to be adjusted.
        a.spatialGrid = grids.axialUnitGrid(len(blocks))
        a.spatialGrid.armiObject = a

        # loop a second time because we needed all the blocks before choosing the assembly class.
        for axialIndex, block in enumerate(blocks):
            b.p.assemNum = a.p.assemNum
            b.name = b.makeName(a.p.assemNum, axialIndex)
            a.add(block)

        # Assign values for the parameters if they are defined on the blueprints
        for paramDef in a.p.paramDefs.inCategory(
                parameters.Category.assignInBlueprints):
            val = getattr(self, paramDef.name)
            if val is not None:
                a.p[paramDef.name] = val

        return a
Example #6
0
    def setUp(self):
        r"""
        Build a dummy reactor without using input files. There are some igniters and feeds
        but none of these have any number densities.
        """
        self.o, self.r = test_reactors.loadTestReactor(
            self.directoryChanger.destination
        )
        blockList = self.r.core.getBlocks()
        for bi, b in enumerate(blockList):
            b.p.flux = 5e10
            if b.isFuel():
                b.p.percentBu = 30.0 * bi / len(blockList)
        self.nfeed = len(self.r.core.getAssemblies(Flags.FEED))
        self.nigniter = len(self.r.core.getAssemblies(Flags.IGNITER))
        self.nSfp = len(self.r.core.sfp)

        # generate a reactor with assemblies
        # generate components with materials
        nPins = 271

        fuelDims = {"Tinput": 273.0, "Thot": 273.0, "od": 1.0, "id": 0.0, "mult": nPins}
        fuel = components.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)

        interDims = {
            "Tinput": 273.0,
            "Thot": 273.0,
            "op": 16.8,
            "ip": 16.0,
            "mult": 1.0,
        }
        interSodium = components.Hexagon("interCoolant", "Sodium", **interDims)

        # generate a block
        self.block = blocks.HexBlock("TestHexBlock", self.o.cs)
        self.block.setType("fuel")
        self.block.setHeight(10.0)
        self.block.add(fuel)
        self.block.add(clad)
        self.block.add(interSodium)

        # generate an assembly
        self.assembly = assemblies.HexAssembly("TestAssemblyType")
        self.assembly.spatialGrid = grids.axialUnitGrid(1)
        for _ in range(1):
            self.assembly.add(copy.deepcopy(self.block))

        # copy the assembly to make a list of assemblies and have a reference assembly
        self.aList = []
        for _ in range(6):
            self.aList.append(copy.deepcopy(self.assembly))

        self.refAssembly = copy.deepcopy(self.assembly)
        self.directoryChanger.open()
Example #7
0
    def test_badIndices(self):
        grid = grids.hexGridFromPitch(1.0, numRings=3)

        # this is actually ok because step-defined grids are infinite
        self.assertEqual(grid.getCoordinates((-100, 2000, 5))[2], 0.0)

        grid = grids.axialUnitGrid(10)
        with self.assertRaises(IndexError):
            grid.getCoordinates((0, 5, -1))
Example #8
0
 def test_ordering(self):
     a = assemblies.Assembly("dummy")
     a.spatialGrid = grids.axialUnitGrid(2, armiObject=a)
     otherBlock = deepcopy(self.Block)
     a.add(self.Block)
     a.add(otherBlock)
     self.assertTrue(self.Block < otherBlock)
     locator = self.Block.spatialLocator
     self.Block.spatialLocator = otherBlock.spatialLocator
     otherBlock.spatialLocator = locator
     self.assertTrue(otherBlock < self.Block)
Example #9
0
    def test_addMass(self):
        """
        test:
            addMasses
            addMass
            removeMass
            getMasses

        right now it doesn't make sense to add mass to anything other than a
        component, some one else can implement addMass and update this test
        on block, assembly and reactor.
        """

        loc = locations.Location(i1=1, i2=1, axial=1)
        mass = 1.0

        aB = batch.Batch("testBatch")
        c = shapes.UnshapedVolumetricComponent("batchMassAdditionComponent",
                                               custom.Custom(),
                                               0.0,
                                               0.0,
                                               volume=1)
        b = blocks.Block("testBlock", location=loc)
        b.add(c)
        a = assemblies.Assembly("testAssembly")
        a.spatialGrid = grids.axialUnitGrid(1)
        a.add(b)

        r = getEmptyHexReactor()
        a.spatialLocator = r.core.spatialGrid[0, 0, 0]
        r.core.add(a)

        # these armi objects have addMass implemented
        for armiObj in [aB, c]:
            for nucName in ["U235"]:
                masses = {nucName: mass}
                armiObj.addMasses(masses)
                self.assertAlmostEqual(armiObj.getMass(nucName), mass, 6)

                armiObj.removeMass(nucName, mass)
                self.assertAlmostEqual(armiObj.getMass(nucName), 0, 6)

        # create a global lumped fission product collection with a single lfp
        Fpdf = test_lumpedFissionProduct.getDummyLFPFile()
        cLfps = Fpdf.createSingleLFPCollectionFromFile("LFP35")
        self.assertAlmostEqual(aB.getMass(), 0, 6)
        aB.addMass("LFP35", mass, lumpedFissionProducts=cLfps)
        self.assertAlmostEqual(aB.getMass(), mass, 6)

        self.assertAlmostEqual(c.getMass(), 0, 6)
        c.addMass("LFP35", mass, lumpedFissionProducts=cLfps)
        self.assertAlmostEqual(c.getMass(), mass, 6)
Example #10
0
    def test_summing(self):
        a = assemblies.Assembly("dummy")
        a.spatialGrid = grids.axialUnitGrid(2, armiObject=a)
        otherBlock = deepcopy(self.Block)
        a.add(self.Block)
        a.add(otherBlock)

        b = self.Block + otherBlock
        self.assertEqual(len(b), 26)
        self.assertFalse(b[0].is3D)
        self.assertIn("Circle", str(b[0]))
        self.assertFalse(b[-1].is3D)
        self.assertIn("Hexagon", str(b[-1]))
Example #11
0
    def adjustResolution(self, refA):
        """
        Split the blocks in this assembly to have the same mesh structure as refA.
        """
        newBlockStack = []

        newBlocks = 0  # number of new blocks we've added so far.
        for i, b in enumerate(self):
            refB = refA[
                i +
                newBlocks]  # pick the block that is "supposed to" line up with refB.

            # runLog.important('Dealing with {0}, ref b {1}'.format(b,refB))
            if refB.getHeight() == b.getHeight():
                # these blocks line up
                # runLog.important('They are the same.')
                newBlockStack.append(b)
                continue
            elif refB.getHeight() > b.getHeight():
                raise RuntimeError(
                    "can't split {0} ({1}cm) into larger blocks to match ref block {2} ({3}cm)"
                    "".format(b, b.getHeight(), refB, refB.getHeight()))
            else:
                # b is larger than refB. Split b up by splitting it into several smaller
                # blocks of refBs
                heightToChop = b.getHeight()
                heightChopped = 0.0
                while (abs(heightChopped - heightToChop) >
                       1e-5):  # stop when they are equal. floating point.
                    # update which ref block we're on (does nothing on the first pass)
                    refB = refA[i + newBlocks]
                    newB = copy.deepcopy(b)
                    newB.setHeight(
                        refB.getHeight())  # make block match ref mesh
                    newBlockStack.append(newB)
                    heightChopped += refB.getHeight()
                    newBlocks += 1
                    runLog.important(
                        "Added a new block {0} of height {1}".format(
                            newB, newB.getHeight()))
                    runLog.important("Chopped {0} of {1}".format(
                        heightChopped, heightToChop))
                newBlocks -= (
                    1  # subtract one because we eliminated the original b completely.
                )
        self.removeAll()
        self.spatialGrid = grids.axialUnitGrid(len(newBlockStack))
        for b in newBlockStack:
            self.add(b)
        self.reestablishBlockOrder()
Example #12
0
    def reestablishBlockOrder(self):
        """
        After children have been mixed up axially, this re-locates each block with the proper axial mesh.

        See Also
        --------
        calculateZCoords : updates the ztop/zbottom params on each block after
            reordering.
        """
        # replace grid with one that has the right number of locations
        self.spatialGrid = grids.axialUnitGrid(len(self))
        self.spatialGrid.armiObject = self
        for zi, b in enumerate(self):
            b.spatialLocator = self.spatialGrid[0, 0, zi]
            # update the name too. NOTE: You must update the history tracker.
            b.setName(b.makeName(self.p.assemNum, zi))
def createDummyReactor():
    """
    Create a dummy reactor with a single fuel assembly and a single fuel block.

    Often, a reactor model like this is built directly from input files rather
    than from code as done here.
    """
    bp = blueprints.Blueprints()
    cs = settings.Settings()

    r = reactors.Reactor("Reactor", bp)
    r.add(reactors.Core("Core"))
    r.core.spatialGrid = grids.HexGrid.fromPitch(1.0)
    r.core.spatialGrid.symmetry = geometry.SymmetryType(
        geometry.DomainType.THIRD_CORE, geometry.BoundaryType.PERIODIC)
    r.core.spatialGrid.geomType = geometry.GeomType.HEX
    r.core.spatialGrid.armiObject = r.core
    r.core.setOptionsFromCs(cs)

    # Create a single fuel assembly
    a = assemblies.HexAssembly("fuel assembly")
    a.spatialGrid = grids.axialUnitGrid(1)
    a.spatialLocator = r.core.spatialGrid[1, 0, 0]

    # Create a single fuel block
    b = blocks.HexBlock("fuel block")
    b.setType("fuel")

    # Create a single fuel component with UZr fuel.
    dims = {"Tinput": 20, "Thot": 900, "id": 0.0, "od": 2.9, "mult": 7}
    c = Circle("fuel", uZr.UZr(), **dims)
    b.add(c)

    # Create a single structure component with HT9.
    dims = {"Tinput": 20, "Thot": 600, "op": 16.0, "ip": 15.0, "mult": 1}
    c = Hexagon("structure", ht9.HT9(), **dims)
    b.add(c)

    # Fill in the rest of the block with sodium coolant.
    dims = {"Tinput": 600, "Thot": 600}
    c = DerivedShape("coolant", sodium.Sodium(), **dims)
    b.add(c)

    a.add(b)
    r.core.add(a)
    _addFlux(b)
    return r
Example #14
0
def buildOperatorOfEmptyCartesianBlocks(customSettings=None):
    """
    Builds a operator w/ a reactor object with some Cartesian assemblies and blocks, but all are empty

    Doesn't depend on inputs and loads quickly.

    Params
    ------
    customSettings : dict
        Dictionary of off-default settings to update
    """
    settings.setMasterCs(None)  # clear
    cs = settings.getMasterCs()  # fetch new

    if customSettings is None:
        customSettings = {}

    customSettings["db"] = False  # stop use of database
    cs = cs.modified(newSettings=customSettings)
    settings.setMasterCs(cs)  # reset

    r = tests.getEmptyCartesianReactor()
    r.core.setOptionsFromCs(cs)
    o = operators.Operator(cs)
    o.initializeInterfaces(r)

    a = assemblies.CartesianAssembly("fuel")
    a.spatialGrid = grids.axialUnitGrid(1)
    b = blocks.CartesianBlock("TestBlock")
    b.setType("fuel")
    dims = {
        "Tinput": 600,
        "Thot": 600,
        "widthOuter": 16.0,
        "lengthOuter": 10.0,
        "widthInner": 1,
        "lengthInner": 1,
        "mult": 1,
    }
    c = Rectangle("fuel", uZr.UZr(), **dims)
    b.add(c)
    a.add(b)
    a.spatialLocator = r.core.spatialGrid[1, 0, 0]
    o.r.core.add(a)
    return o
Example #15
0
 def _createNewAssembly(sourceAssembly):
     a = sourceAssembly.__class__(sourceAssembly.getType())
     a.spatialGrid = grids.axialUnitGrid(len(sourceAssembly))
     a.setName(sourceAssembly.getName())
     return a
Example #16
0
    def test_getReactionRates(self):

        """
        test:
            getReactionRates
            getReactionRates
        """

        mgFlux1 = [
            0.0860473241399844,
            0.104859413902775,
            0.958730499751868,
            0.0608613995961131,
            0.286847241591555,
            0.255889308191141,
            0.0116901206385536,
            0.713409716738126,
            0.430296361167501,
            0.807797711781478,
            0.0337645123548413,
            0.486499349955704,
            0.734614285636136,
            0.74230952191973,
            0.262181249681019,
            0.499163237742064,
            0.522320530090222,
            0.269684933319214,
            0.286697941919085,
            0.173049285638012,
            0.881264543688633,
            0.99461769495224,
            0.267737005223648,
            0.957400117341211,
            0.767927939604005,
            0.149702253058259,
            0.332924880721111,
            0.611969570430789,
            0.227989279697323,
            0.411852641375799,
            0.500275641106796,
            0.654655431372318,
            0.223981131922656,
        ]

        lib = isotxs.readBinary(ISOAA_PATH)

        loc = locations.Location(i1=1, i2=1, axial=1)

        nDens = 0.02  # arbitrary number density for U235

        c = UnshapedVolumetricComponent("testComponent", "Custom", 0.0, 0.0, volume=1)
        c.setNumberDensity("U235", nDens)
        b = blocks.Block("testBlock", location=loc)
        b.add(c)
        b.p.mgFlux = mgFlux1[:33]
        b.p.xsType = "A"
        a = assemblies.Assembly("testAssembly")
        a.spatialGrid = grids.axialUnitGrid(1, a)
        a.add(b)

        r = getEmptyHexReactor()
        a.spatialLocator = r.core.spatialGrid[0, 0, 0]
        r.core.add(a)
        r.core.lib = lib

        aB = batch.Batch("testBatch")
        aB.add(b)

        # reference data made with this ISOTXS and this MG flux spectrum
        referenceRxRateData = {
            "nG": 2.10693674,
            "nF": 6.500339249,
            "n2n": 0.001446367,
            "nA": 0,
            "nP": 0,
            "n3n": 0,
        }
        referenceXsData = {
            "nG": 7.162060679,
            "nF": 22.09645085,
            "n2n": 0.004916601,
            "nA": 0,
            "nP": 0,
            "n3n": 0,
        }

        u235 = lib["U235AA"]
        assert not hasattr(u235.micros, "n3n")

        for armiObject in [c, b, a, r, aB]:
            rxnRates = armiObject.getReactionRates("U235")
            for rxName, rxRate in rxnRates.items():
                self.assertAlmostEqual(rxRate, referenceRxRateData[rxName], 6)
            xsTable = armiObject.getCrossSectionTable(nuclides=["U235"])
            u235Zaid = 92235
            for rxName, rxRate in xsTable[u235Zaid].items():
                self.assertAlmostEqual(rxRate, referenceXsData[rxName], 6)
Example #17
0
    def test_getMgFluxes(self):
        """
        test:
            getMgFlux
            getIntegratedMgFlux
        """

        mgFlux1 = [
            0.0860473241399844,
            0.104859413902775,
            0.958730499751868,
            0.0608613995961131,
            0.286847241591555,
            0.255889308191141,
            0.0116901206385536,
            0.713409716738126,
            0.430296361167501,
            0.807797711781478,
            0.0337645123548413,
            0.486499349955704,
            0.734614285636136,
            0.74230952191973,
            0.262181249681019,
            0.499163237742064,
            0.522320530090222,
            0.269684933319214,
            0.286697941919085,
            0.173049285638012,
            0.881264543688633,
            0.99461769495224,
            0.267737005223648,
            0.957400117341211,
            0.767927939604005,
            0.149702253058259,
            0.332924880721111,
            0.611969570430789,
            0.227989279697323,
            0.411852641375799,
            0.500275641106796,
            0.654655431372318,
            0.223981131922656,
        ]

        loc = locations.Location(i1=1, i2=1, axial=1)

        c = UnshapedVolumetricComponent("testComponent", "Custom", 0.0, 0.0, volume=1)
        b = blocks.Block("testBlock", location=loc)
        b.add(c)
        b.p.mgFlux = mgFlux1
        a = assemblies.Assembly("testAssembly")
        a.spatialGrid = grids.axialUnitGrid(1, a)
        a.add(b)

        r = getEmptyHexReactor()
        a.spatialLocator = r.core.spatialGrid[0, 0, 0]
        r.core.add(a)

        aB = batch.Batch("testBatch")
        aB.add(b)

        for armiObject in [c, b, a, r, aB]:
            for refFlux, testFlux in zip(mgFlux1, armiObject.getIntegratedMgFlux()):
                err = math.fabs((testFlux - refFlux) / refFlux)
                try:
                    assert err < 1e-6
                except AssertionError:
                    raise AssertionError(
                        "Integrated MgFlux test is failing for {}".format(
                            type(armiObject)
                        )
                    )

            for refFlux, testFlux in zip(mgFlux1, armiObject.getMgFlux()):
                err = math.fabs((testFlux - refFlux) / refFlux)
                try:
                    assert err < 1e-6
                except AssertionError:
                    raise AssertionError(
                        "Integrated MgFlux test is failing for {}".format(
                            type(armiObject)
                        )
                    )
Example #18
0
    def test_isAxialOnly(self):
        grid = grids.hexGridFromPitch(1.0, numRings=3)
        self.assertEqual(grid.isAxialOnly, False)

        grid2 = grids.axialUnitGrid(10)
        self.assertEqual(grid2.isAxialOnly, True)