Beispiel #1
0
    def setUpClass(cls):
        cls.td = directoryChangers.TemporaryDirectoryChanger()
        cls.td.__enter__()

        # The database writes the settings object to the DB rather
        # than the original input file. This allows settings to be
        # changed in memory like this and survive for testing.
        newSettings = {"verbosity": "extra"}
        newSettings["nCycles"] = 2
        newSettings["burnSteps"] = 3
        o, _r = test_reactors.loadTestReactor(customSettings=newSettings)

        settings.setMasterCs(o.cs)

        o.interfaces = [i for i in o.interfaces if isinstance(i, (DatabaseInterface))]
        dbi = o.getInterface("database")
        dbi.enabled(True)
        dbi.initDB()  # Main Interface normally does this

        # update a few parameters
        def writeFlux(cycle, node):
            for bi, b in enumerate(o.r.core.getBlocks()):
                b.p.flux = 1e6 * bi + cycle * 100 + node
                b.p.mgFlux = numpy.repeat(b.p.flux / 33, 33)

        o.interfaces.insert(0, MockInterface(o.r, o.cs, writeFlux))
        with o:
            o.operate()

        cls.cs = o.cs
        cls.bp = o.r.blueprints
        cls.dbName = o.cs.caseTitle + ".h5"

        # needed for test_readWritten
        cls.r = o.r
Beispiel #2
0
 def setUp(self):
     self.cs = settings.Settings(fName=ARMI_RUN_PATH)
     settings.setMasterCs(self.cs)
     self.o = OperatorMPI(self.cs)
     self.action = DistributeStateAction()
     self.action.o = self.o
     self.action.r = self.o.r
Beispiel #3
0
    def setUp(self):
        cs = settings.Settings(f"{CASE_TITLE}.yaml")
        newSettings = {}
        newSettings["db"] = True
        newSettings["reloadDBName"] = pathlib.Path(
            f"{CASE_TITLE}.h5").absolute()
        newSettings["loadStyle"] = "fromDB"
        newSettings["detailAssemLocationsBOL"] = ["001-001"]
        newSettings["startNode"] = 1
        cs = cs.modified(newSettings=newSettings)

        self.td = directoryChangers.TemporaryDirectoryChanger()
        self.td.__enter__()

        c = case.Case(cs)
        case2 = c.clone(title="armiRun")
        settings.setMasterCs(case2.cs)
        self.o = case2.initializeOperator()
        self.r = self.o.r

        self.o.getInterface("main").interactBOL()

        dbi = self.o.getInterface("database")
        # Get to the database state at the end of stack of time node 1.
        # The end of the interface stack is when history tracker tends to run.
        dbi.loadState(0, 1)
Beispiel #4
0
def getSimpleDBOperator(cs):
    """
    Return a very simple operator that covers most of the database interactions.

    Notes
    -----
    This reactor has only 1 assembly with 1 type of block.
    It's used to make the db unit tests run very quickly.
    """
    cs["loadingFile"] = "refOneBlockReactor.yaml"
    cs["verbosity"] = "important"
    cs["db"] = True
    cs["runType"] = "Standard"
    cs["geomFile"] = "geom1Assem.xml"
    cs["nCycles"] = 2
    genDBCase = case.Case(cs)
    settings.setMasterCs(cs)
    runLog.setVerbosity("info")

    o = genDBCase.initializeOperator()
    o.interfaces = [
        interface for interface in o.interfaces
        if interface.name in ["database", "main"]
    ]
    return o
Beispiel #5
0
def bootstrapArmiTestEnv():
    """
    Perform ARMI config appropriate for running unit tests

    .. tip:: This can be imported and run from other ARMI applications
        for test support.
    """
    from armi.nucDirectory import nuclideBases

    cs = caseSettings.Settings()

    context.Mode.setMode(context.Mode.BATCH)
    settings.setMasterCs(cs)
    # Need to init burnChain.
    # see armi.cases.case.Case._initBurnChain
    with open(cs["burnChainFileName"]) as burnChainStream:
        nuclideBases.imposeBurnChain(burnChainStream)

    # turn on a non-interactive mpl backend to minimize errors related to
    # initializing Tcl in parallel tests
    matplotlib.use("agg")

    # set and create a test-specific FAST_PATH for parallel unit testing
    # Not all unit tests have operators, and operators are usually
    # responsible for making FAST_PATH, so we make it here.
    # It will be deleted by the atexit hook.
    context.activateLocalFastPath()
    if not os.path.exists(context.getFastPath()):
        os.makedirs(context.getFastPath())

    # some tests need to find the TEST_ROOT via an env variable when they're
    # filling in templates with ``$ARMITESTBASE`` in them or opening
    # input files use the variable in an `!include` tag. Thus
    # we provide it here.
    os.environ["ARMITESTBASE"] = TEST_ROOT
Beispiel #6
0
def createReportFromSettings(cs):
    """
    Create BEGINNING reports, given a settings file.

    This will construct a reactor from the given settings and create BOL reports for
    that reactor/settings.
    """
    # not sure if this is necessary, but need to investigate more to understand possible
    # side-effects before removing. Probably better to get rid of all uses of
    # getMasterCs(), then we can remove all setMasterCs() calls without worrying.
    settings.setMasterCs(cs)

    blueprint = blueprints.loadFromCs(cs)
    r = reactors.factory(cs, blueprint)
    report = reports.ReportContent("Overview")
    pm = getPluginManagerOrFail()
    report.title = r.name

    with directoryChangers.ForcedCreationDirectoryChanger("{}-reports".format(
            cs.caseTitle)):
        _ = pm.hook.getReportContents(
            r=r,
            cs=cs,
            report=report,
            stage=reports.ReportStage.Begin,
            blueprint=blueprint,
        )
        site = report.writeReports()

    return site
Beispiel #7
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
Beispiel #8
0
def pytest_sessionstart(session):
    import armi
    from armi import apps

    print("Initializing generic ARMI Framework application")
    armi.configure(apps.App())
    cs = caseSettings.Settings()
    settings.setMasterCs(cs)
Beispiel #9
0
        def setUp(self):
            self.cs = settings.Settings(fName=ARMI_RUN_PATH)
            bp = blueprints.loadFromCs(self.cs)

            settings.setMasterCs(self.cs)
            self.o = OperatorMPI(self.cs)
            self.o.r = reactors.factory(self.cs, bp)
            self.action = DistributeStateAction()
            self.action.o = self.o
            self.action.r = self.o.r
Beispiel #10
0
def pytest_sessionstart(session):
    import armi
    from armi import apps
    from armi.nucDirectory import nuclideBases

    print("Initializing generic ARMI Framework application")
    armi.configure(apps.App())
    cs = caseSettings.Settings()
    settings.setMasterCs(cs)
    # Need to init burnChain.
    # see armi.cases.case.Case._initBurnChain
    with open(cs["burnChainFileName"]) as burnChainStream:
        nuclideBases.imposeBurnChain(burnChainStream)
Beispiel #11
0
    def load(self, cycle, node, cs=None, bp=None, geom=None):
        cs = cs or self.loadCS()
        settings.setMasterCs(cs)
        bp = bp or self.loadBlueprints()
        geom = geom or self.loadGeometry()

        if self._reactor is None:
            self._reactor = reactors.factory(cs, bp, geom)

        dbTimeStep = utils.getTimeStepNum(cycle, node, cs)

        self.updateFromDB(self._reactor, dbTimeStep)

        return self._reactor
Beispiel #12
0
    def _distributeSettings(self):
        if armi.MPI_RANK == 0:
            runLog.debug("Sending the settings object")
        self.cs = cs = self.broadcast(self.o.cs)
        if isinstance(cs, settings.Settings):
            runLog.setVerbosity(cs["verbosity"] if armi.MPI_RANK ==
                                0 else cs["branchVerbosity"])
            runLog.debug("Received settings object")
        else:
            raise RuntimeError(
                "Failed to transmit settings, received: {}".format(cs))

        if armi.MPI_RANK != 0:
            settings.setMasterCs(cs)
            self.o.cs = cs
        return cs
Beispiel #13
0
    def __init__(self):
        if self.name is None:
            raise AttributeError(
                "Subclasses of EntryPoint must define a `name` class attribute"
            )

        self.parser = argparse.ArgumentParser(
            prog="armi {}".format(self.name),
            description=self.description or self.__doc__,
        )

        self.args = argparse.Namespace()

        self.cs = settings.Settings()
        settings.setMasterCs(self.cs)
        self.settingsProvidedOnCommandLine = []
Beispiel #14
0
    def summarizeDesign(self, generateFullCoreMap=True, showBlockAxialMesh=True):
        """Uses the ReportInterface to create a fancy HTML page describing the design inputs."""
        settings.setMasterCs(self.cs)
        o = self.initializeOperator()
        with DirectoryChanger(self.cs.inputDirectory):
            # There are global variables that are modified when a report is
            # generated, so reset it all
            six.moves.reload_module(report)  # pylint: disable=too-many-function-args
            self.cs.setSettingsReport()
            rpi = o.getInterface("report")

            if rpi is None:
                rpi = reportInterface.ReportInterface(o.r, o.cs)

            rpi.generateDesignReport(generateFullCoreMap, showBlockAxialMesh)
            report.DESIGN.writeHTML()
            runLog.important("Design report summary was successfully generated")
Beispiel #15
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
Beispiel #16
0
def buildCase():
    """Build input components and a case."""
    bp = blueprints.Blueprints()
    bp.customIsotopics = isotopicOptions.CustomIsotopics()
    bp.nuclideFlags = isotopicOptions.genDefaultNucFlags()

    components = buildComponents()
    bp.blockDesigns = buildBlocks(components)
    bp.assemDesigns = buildAssemblies(bp.blockDesigns)
    bp.gridDesigns = buildGrids()
    bp.systemDesigns = buildSystems()

    cs = caseSettings.Settings()
    settings.setMasterCs(cs)  # remove once we eliminate masterCs
    cs.path = None
    cs.caseTitle = "scripted-case"
    case = cases.Case(cs=cs, bp=bp)

    return case
Beispiel #17
0
def init(choice=None, fName=None, cs=None):
    """
    Scan a directory for armi inputs and load one to interact with.

    Parameters
    ----------
    choice : int, optional
        Automatically run with this item out of the menu
        that would be produced of existing xml files.

    fName : str, optional
        An actual case name to load. e.g. ntTwr1.xml

    cs : object, optional
        If supplied, supercede the other case input methods and use the object directly

    Examples
    --------
    >>> o = armi.init()

    """
    from armi import cases
    from armi import settings

    if cs is None:
        if fName is None:
            fName = settings.promptForSettingsFile(choice)
        cs = settings.Settings(fName)
    # clear out any old masterCs objects
    settings.setMasterCs(cs)

    armiCase = cases.Case(cs=cs)
    armiCase.checkInputs()

    try:
        return armiCase.initializeOperator()
    except:  # Catch any and all errors. Naked exception on purpose.
        # Concatenate errors to the master log file.
        runLog.LOG.close()
        raise
Beispiel #18
0
    def setUp(self):
        cs = settings.Settings(os.path.join(TUTORIAL_DIR,
                                            f"{CASE_TITLE}.yaml"))
        cs["db"] = True
        cs["reloadDBName"] = os.path.join(TUTORIAL_DIR, f"{CASE_TITLE}.h5")
        cs["loadStyle"] = "fromDB"
        cs["detailAssemLocationsBOL"] = ["A1001"]
        cs["startNode"] = 1

        self.td = directoryChangers.TemporaryDirectoryChanger()
        self.td.__enter__()

        c = case.Case(cs)
        case2 = c.clone(title="armiRun")
        settings.setMasterCs(case2.cs)
        self.o = case2.initializeOperator()
        self.r = self.o.r

        self.o.getInterface("main").interactBOL()

        dbi = self.o.getInterface("database")
        # Get to the database state at the end of stack of time node 1.
        # The end of the interface stack is when history tracker tends to run.
        dbi.loadState(0, 1)
Beispiel #19
0
    def setUp(self):
        self.cs = settings.Settings()
        newSettings = {"xsKernel": "MC2v2"}  # don't try to expand elementals
        self.cs = self.cs.modified(newSettings=newSettings)

        settings.setMasterCs(self.cs)
        bp = blueprints.Blueprints()
        self.r = reactors.Reactor("test", bp)
        self.r.add(reactors.Core("Core"))

        inputStr = """blocks:
    ann fuel: &block_ann_fuel
        gap:
            shape: Circle
            material: Void
            Tinput: 20.0
            Thot: 435.0
            id: 0.0
            mult: fuel.mult
            od: fuel.id
        fuel:
            shape: Circle
            material: UZr
            Tinput: 20.0
            Thot: 600.0
            id: 0.1
            mult: 127
            od: 0.8
        gap1:
            shape: Circle
            material: Void
            Tinput: 20.0
            Thot: 435.0
            id: fuel.od
            mult: fuel.mult
            od: clad.id
        clad:
            shape: Circle
            material: HT9
            Tinput: 20.0
            Thot: 435.0
            id: .85
            mult: fuel.mult
            od: .95
        duct: &component_type2_fuel_duct
            shape: Hexagon
            material: HT9
            Tinput: 20.0
            Thot: 435.0
            ip: 13.00
            op: 13.9
            mult: 1
        intercoolant: &component_type2_fuel_intercoolant
            shape: Hexagon
            material: Sodium
            Tinput: 435.0
            Thot: 435.0
            ip: duct.op
            mult: 1
            op: 16
        coolant: &component_type2_fuel_coolant
            shape: DerivedShape
            material: Sodium
            Tinput: 435.0
            Thot: 435.0
assemblies:
    heights: &standard_heights [30.0]
    axial mesh points: &standard_axial_mesh_points [2]
    ann fuel:
        specifier: FA
        blocks: &inner_igniter_fuel_blocks [*block_ann_fuel]
        height: *standard_heights
        axial mesh points: *standard_axial_mesh_points
        hotChannelFactors: TWRPclad
        xs types:  &inner_igniter_fuel_xs_types [D]
"""
        self.blueprints = blueprints.Blueprints.load(inputStr)
        self.blueprints._prepConstruction(self.cs)
Beispiel #20
0
def buildTestAssemblies():
    """
    Build some assembly objects that will be used in testing.

    This builds 2 HexBlocks:
        * One with half UZr pins and half UTh pins
        * One with all UThZr pins
    """
    caseSetting = settings.Settings()
    settings.setMasterCs(caseSetting)

    temperature = 273.0
    fuelID = 0.0
    fuelOD = 1.0
    cladOD = 1.1
    # generate a reactor with assemblies
    # generate components with materials
    nPins = 100

    fuelDims = {
        "Tinput": temperature,
        "Thot": temperature,
        "od": fuelOD,
        "id": fuelID,
        "mult": nPins,
    }

    fuelUZr = components.Circle("fuel", "UZr", **fuelDims)
    fuelUTh = components.Circle("fuel UTh", "ThU", **fuelDims)

    fuelDims2nPins = {
        "Tinput": temperature,
        "Thot": temperature,
        "od": fuelOD,
        "id": fuelID,
        "mult": 2 * nPins,
    }

    fuelUThZr = components.Circle("fuel B", "UThZr", **fuelDims2nPins)

    cladDims = {
        "Tinput": temperature,
        "Thot": temperature,
        "od": cladOD,
        "id": fuelOD,
        "mult": 2 * nPins,
    }

    clad = components.Circle("clad", "HT9", **cladDims)

    interDims = {
        "Tinput": temperature,
        "Thot": temperature,
        "op": 16.8,
        "ip": 16.0,
        "mult": 1.0,
    }

    interSodium = components.Hexagon("interCoolant", "Sodium", **interDims)

    block = blocks.HexBlock("fuel")
    block2 = blocks.HexBlock("fuel")
    block.setType("fuel")
    block.setHeight(10.0)
    block.add(fuelUZr)
    block.add(fuelUTh)
    block.add(clad)
    block.add(interSodium)
    block.p.axMesh = 1
    block.p.molesHmBOL = 1.0
    block.p.molesHmNow = 1.0

    block2.setType("fuel")
    block2.setHeight(10.0)
    block2.add(fuelUThZr)
    block2.add(clad)
    block2.add(interSodium)
    block2.p.axMesh = 1
    block2.p.molesHmBOL = 2
    block2.p.molesHmNow = 1.0

    assemblieObjs = []
    for numBlocks, blockTemplate in zip([1, 1, 5, 4],
                                        [block, block2, block, block]):
        assembly = assemblies.HexAssembly("testAssemblyType")
        assembly.spatialGrid = grids.axialUnitGrid(numBlocks)
        assembly.spatialGrid.armiObject = assembly
        for _i in range(numBlocks):
            newBlock = copy.deepcopy(blockTemplate)
            assembly.add(newBlock)
        assembly.calculateZCoords()
        assembly.reestablishBlockOrder()
        assemblieObjs.append(assembly)

    return assemblieObjs
Beispiel #21
0
 def setUp(self):
     self.cs = settings.Settings(fName=ARMI_RUN_PATH)
     settings.setMasterCs(self.cs)
     self.o = OperatorMPI(cs=self.cs)
Beispiel #22
0
def loadOperator(pathToDb, loadCycle, loadNode):
    """
    Return an operator given the path to a database.

    Parameters
    ----------
    pathToDb : str
        The path of the database to load from.
    loadCycle : int
        The cycle to load the reactor state from.
    loadNode : int
        The time node to load the reactor from.

    See Also
    --------
    armi.operator.Operator.loadState:
        A method for loading reactor state that is useful if you already have an
        operator and a reactor object. loadOperator varies in that it supplies these
        given only a database file. loadState should be used if you are in the
        middle of an ARMI calculation and need load a different time step.

    Notes
    -----
    The operator will have a reactor attached that is loaded to the specified cycle
    and node. The operator will not be in the same state that it was at that cycle and
    node, only the reactor.

    Examples
    --------
    >>> o = db.loadOperator(r"pathToDatabase", 0, 1)
    >>> r = o.r
    >>> cs = o.cs
    >>> r.p.timeNode
    1
    >>> r.getFPMass()  # Note since it is loaded from step 1 there are fission products.
    12345.67
    """
    # `import armi` doesn't work if imported at top
    from armi import cases
    from armi import settings

    if not os.path.exists(pathToDb):
        raise ValueError(
            f"Specified database at path {pathToDb} does not exist. \n\n"
            "Double check that escape characters were correctly processed.\n"
            "Consider sending the full path, or change directory to be the directory "
            "of the database."
        )

    db = Database3(pathToDb, "r")
    with db:
        # init Case here as it keeps track of execution time and assigns a reactor
        # attribute. This attribute includes the time it takes to initialize the reactor
        # so creating a reactor from the database should be included.
        cs = db.loadCS()
        thisCase = cases.Case(cs)

        r = db.load(loadCycle, loadNode)
    settings.setMasterCs(cs)

    # Update the global assembly number because, if the user is loading a reactor from
    # blueprints and does not have access to an operator, it is unlikely that there is
    # another reactor that has alter the global assem num. Fresh cases typically want
    # this updated.
    database3.updateGlobalAssemblyNum(r)

    o = thisCase.initializeOperator(r=r)
    runLog.warning(
        "The operator provided is not in the same state as the operator was.\n"
        "When the reactor was at the prescribed cycle and node, it should have\n"
        "access to the same interface stack, but the interfaces will also not be in the "
        "same state.\n"
        "ARMI does not support loading operator states, as they are not stored."
    )
    return o
Beispiel #23
0
def loadTestReactor(inputFilePath=TEST_ROOT,
                    customSettings=None,
                    inputFileName="armiRun.yaml"):
    r"""
    Loads a test reactor. Can be used in other test modules.

    Parameters
    ----------
    inputFilePath : str
        Path to the directory of the armiRun.yaml input file.

    customSettings : dict with str keys and values of any type
        For each key in customSettings, the cs which is loaded from the
        armiRun.yaml will be overwritten to the value given in customSettings
        for that key.

    Returns
    -------
    o : Operator
    r : Reactor
    """
    # TODO: it would be nice to have this be more stream-oriented. Juggling files is
    # devilishly difficult.
    global TEST_REACTOR
    fName = os.path.join(inputFilePath, inputFileName)
    customSettings = customSettings or {}
    isPickeledReactor = fName == ARMI_RUN_PATH and customSettings == {}
    assemblies.resetAssemNumCounter()

    if isPickeledReactor and TEST_REACTOR:
        # return test reactor only if no custom settings are needed.
        o, r, assemNum = cPickle.loads(TEST_REACTOR)
        assemblies.setAssemNumCounter(assemNum)
        settings.setMasterCs(o.cs)
        o.reattach(r, o.cs)
        return o, r

    cs = settings.Settings(fName=fName)

    # Overwrite settings if desired
    if customSettings:
        for settingKey, settingVal in customSettings.items():
            cs[settingKey] = settingVal

    if "verbosity" not in customSettings:
        runLog.setVerbosity("error")
    settings.setMasterCs(cs)
    cs["stationaryBlocks"] = []
    cs["nCycles"] = 3

    o = operators.factory(cs)
    r = reactors.loadFromCs(cs)
    o.initializeInterfaces(r)

    # put some stuff in the SFP too.
    for a in range(10):
        a = o.r.blueprints.constructAssem(o.cs, name="feed fuel")
        o.r.core.sfp.add(a)

    o.r.core.regenAssemblyLists()

    if isPickeledReactor:
        # cache it for fast load for other future tests
        # protocol=2 allows for classes with __slots__ but not __getstate__ to be pickled
        TEST_REACTOR = cPickle.dumps((o, o.r, assemblies.getAssemNum()),
                                     protocol=2)
    return o, o.r