Example #1
0
    def _makeBlockMesh(self, r: reactors.Reactor, indexMap) -> ET.Element:
        cycle = r.p.cycle
        node = r.p.timeNode

        blks = r.getChildren(deep=True,
                             predicate=lambda o: isinstance(o, blocks.Block))
        blks = sorted(blks, key=lambda b: indexMap[b.p.serialNum])

        groupName = "c{}n{}".format(cycle, node)

        # VTK stuff turns out to be pretty flexible
        blockMesh = utils.VtkMesh.empty()
        for b in blks:
            blockMesh.append(utils.createBlockMesh(b))

        verts = blockMesh.vertices

        verticesInH5 = groupName + "/blk_vertices"
        self._meshH5[verticesInH5] = verts

        topoValues = numpy.array([], dtype=numpy.int32)
        offset = 0
        for b in blks:
            nVerts, cellTopo = _getTopologyFromShape(b, offset)
            topoValues = numpy.append(topoValues, cellTopo)
            offset += nVerts

        topoInH5 = groupName + "/blk_topology"
        self._meshH5[topoInH5] = topoValues

        return self._makeGenericMesh("Blocks", len(blks),
                                     self._meshH5[verticesInH5],
                                     self._meshH5[topoInH5])
Example #2
0
    def _makeAssemblyMesh(self, r: reactors.Reactor, indexMap) -> ET.Element:
        cycle = r.p.cycle
        node = r.p.timeNode
        asys = r.getChildren(
            deep=True, predicate=lambda o: isinstance(o, assemblies.Assembly))
        asys = sorted(asys, key=lambda b: indexMap[b.p.serialNum])

        groupName = "c{}n{}".format(cycle, node)

        # VTK stuff turns out to be pretty flexible
        assemMesh = utils.VtkMesh.empty()
        for assem in asys:
            assemMesh.append(utils.createAssemMesh(assem))

        verts = assemMesh.vertices

        verticesInH5 = groupName + "/asy_vertices"
        self._meshH5[verticesInH5] = verts

        topoValues = numpy.array([], dtype=numpy.int32)
        offset = 0
        for a in asys:
            nVerts, cellTopo = _getTopologyFromShape(a[0], offset)
            topoValues = numpy.append(topoValues, cellTopo)
            offset += nVerts

        topoInH5 = groupName + "/asy_topology"
        self._meshH5[topoInH5] = topoValues

        return self._makeGenericMesh("Assemblies", len(asys),
                                     self._meshH5[verticesInH5],
                                     self._meshH5[topoInH5])
Example #3
0
    def dumpState(
        self,
        r: reactors.Reactor,
        includeParams: Optional[Set[str]] = None,
        excludeParams: Optional[Set[str]] = None,
    ):
        """
        Produce a ``<Grid>`` for a single timestep, as well as supporting HDF5 datasets.
        """
        cycle = r.p.cycle
        node = r.p.timeNode

        timeGroupName = database3.getH5GroupName(cycle, node)
        dbVersion = self._inputDb.version

        # careful here! we are trying to use the database datasets as the source of hard
        # data without copying, so the order that we make the mesh needs to be the same
        # order as the data in the database. There is no guarantee that the way a loaded
        # reactor is ordered is the same way that it was ordered in the database (though
        # perhaps we should do some work to specify that better). We need to look at the
        # layout in the input database to re-order the objects.
        with self._inputDb as db:
            layout = db.getLayout(cycle, node)

        snToIdx = {
            sn: i
            for i, sn in zip(layout.indexInData, layout.serialNum)
        }

        blks = r.getChildren(deep=True,
                             predicate=lambda o: isinstance(o, blocks.Block))
        blks = sorted(blks, key=lambda b: snToIdx[b.p.serialNum])

        assems = r.getChildren(
            deep=True, predicate=lambda o: isinstance(o, assemblies.Assembly))
        assems = sorted(assems, key=lambda a: snToIdx[a.p.serialNum])

        blockGrid = self._makeBlockMesh(r, snToIdx)
        self._collectObjectData(blks, timeGroupName, blockGrid)

        assemGrid = self._makeAssemblyMesh(r, snToIdx)
        self._collectObjectData(assems, timeGroupName, assemGrid)

        self._blockGrids.append(blockGrid)
        self._assemGrids.append(assemGrid)
        self._times.append(r.p.time)
Example #4
0
def createReactorAssemMesh(r: reactors.Reactor) -> VtkMesh:
    mesh = VtkMesh.empty()
    assems = r.getChildren(
        deep=True, predicate=lambda o: isinstance(o, assemblies.Assembly))
    for a in assems:
        mesh.append(createAssemMesh(a))

    return mesh
Example #5
0
def createReactorBlockMesh(r: reactors.Reactor) -> VtkMesh:
    mesh = VtkMesh.empty()
    blks = r.getChildren(deep=True,
                         predicate=lambda o: isinstance(o, blocks.Block))
    for b in blks:
        mesh.append(createBlockMesh(b))

    return mesh
Example #6
0
    def initNewReactor(sourceReactor):
        """Build a new, yet empty, reactor with the same settings as sourceReactor

        Parameters
        ----------
        sourceReactor : :py:class:`Reactor <armi.reactor.reactors.Reactor>` object.
            original reactor to be copied
        """
        # developer note: deepcopy on the blueprint object ensures that all relevant blueprints
        # attributes are set. Simply calling blueprints.loadFromCs() just initializes
        # a blueprints object and may not set all necessary attributes. E.g., some
        # attributes are set when assemblies are added in coreDesign.construct(), however
        # since we skip that here, they never get set; therefore the need for the deepcopy.
        bp = copy.deepcopy(sourceReactor.blueprints)
        newReactor = Reactor(sourceReactor.o.cs.caseTitle, bp)
        coreDesign = bp.systemDesigns["core"]
        coreDesign.construct(sourceReactor.o.cs,
                             bp,
                             newReactor,
                             loadAssems=False)
        newReactor.core.lib = sourceReactor.core.lib
        newReactor.core.setPitchUniform(sourceReactor.core.getAssemblyPitch())
        return newReactor
Example #7
0
    def dumpState(
        self,
        r: reactors.Reactor,
        includeParams: Optional[Set[str]] = None,
        excludeParams: Optional[Set[str]] = None,
    ):
        """
        Dump a reactor to a VTK file.

        Parameters
        ----------
        r : reactors.Reactor
            The reactor state to visualize
        includeParams : list of str, optional
            A list of parameter names to include in the viz file. Defaults to all
            params.
        excludeParams : list of str, optional
            A list of parameter names to exclude from the output. Defaults to no params.
        """

        cycle = r.p.cycle
        timeNode = r.p.timeNode

        # you never know...
        assert cycle < 1000
        assert timeNode < 1000

        # We avoid using cXnY, since VisIt doesn't support .pvd files, but *does* know
        # to lump data with similar file names and integers at the end.
        blockPath = "{}_blk_{:0>3}{:0>3}".format(self._baseName, cycle,
                                                 timeNode)
        assemPath = "{}_asy_{:0>3}{:0>3}".format(self._baseName, cycle,
                                                 timeNode)

        # include and exclude params are mutually exclusive
        if includeParams is not None and excludeParams is not None:
            raise ValueError(
                "includeParams and excludeParams can not both be used at the same time"
            )

        blks = r.getChildren(deep=True,
                             predicate=lambda o: isinstance(o, blocks.Block))
        assems = r.getChildren(
            deep=True, predicate=lambda o: isinstance(o, assemblies.Assembly))

        blockMesh = utils.createReactorBlockMesh(r)
        assemMesh = utils.createReactorAssemMesh(r)

        # collect param data
        blockData = _collectObjectData(blks, includeParams, excludeParams)
        assemData = _collectObjectData(assems, includeParams, excludeParams)
        # block number densities are special, since they arent stored as params
        blockNdens = database3.collectBlockNumberDensities(blks)
        # we need to copy the number density vectors to guarantee unit stride, which
        # pyevtk requires. Kinda seems like something it could do for us, but oh well.
        blockNdens = {
            key: numpy.array(value)
            for key, value in blockNdens.items()
        }
        blockData.update(blockNdens)

        fullPath = blockMesh.write(blockPath, blockData)
        self._blockFiles.append((fullPath, r.p.time))

        fullPath = assemMesh.write(assemPath, assemData)
        self._assemFiles.append((fullPath, r.p.time))