コード例 #1
0
ファイル: assemblyBlueprint.py プロジェクト: ntouran/armi
class ByComponentModifications(yamlize.Map):
    """
    The name of a component within the block and an associated Modifications
    object.
    """

    key_type = yamlize.Typed(str)
    value_type = Modifications
コード例 #2
0
ファイル: assemblyBlueprint.py プロジェクト: ntouran/armi
class Modifications(yamlize.Map):
    """
    The names of material modifications and lists of the modification values for
    each block in the assembly.
    """

    key_type = yamlize.Typed(str)
    value_type = yamlize.Sequence
コード例 #3
0
ファイル: assemblyBlueprint.py プロジェクト: ntouran/armi
class MaterialModifications(yamlize.Map):
    """
    A yamlize map for reading and holding material modifications.

    A user may specify material modifications directly
    as keys/values on this class, in which case these material modifications will
    be blanket applied to the entire block.

    If the user wishes to specify material modifications specific to a component
    within the block, they should use the `by component` attribute, specifying
    the keys/values underneath the name of a specific component in the block.
    """

    key_type = yamlize.Typed(str)
    value_type = yamlize.Sequence
    byComponent = yamlize.Attribute(
        key="by component",
        type=ByComponentModifications,
        default=ByComponentModifications(),
    )
コード例 #4
0
ファイル: isotopicOptions.py プロジェクト: crisobg1/Framework
class CustomIsotopic(yamlize.Map):
    """
    User specified, custom isotopics input defined by a name (such as MOX), and key/pairs of nuclide names and numeric
    values consistent with the ``input format``.
    """

    key_type = yamlize.Typed(str)
    value_type = yamlize.Typed(float)
    name = yamlize.Attribute(type=str)
    inputFormat = yamlize.Attribute(key="input format", type=str)

    @inputFormat.validator
    def inputFormat(self, value):
        if value not in self._allowedFormats:
            raise ValueError(
                "Cannot set `inputFormat` to `{}`, must be one of: {}".format(
                    value, self._allowedFormats))

    _density = yamlize.Attribute(key="density", type=float, default=None)

    _allowedFormats = {
        "number fractions", "number densities", "mass fractions"
    }

    def __new__(cls, *args):
        self = yamlize.Map.__new__(cls, *args)

        # the density as computed by source number densities
        self._computedDensity = None
        return self

    def __init__(self, name, inputFormat, density):
        # note: yamlize does not call an __init__ method, instead it uses __new__ and setattr
        self._name = None
        self.name = name
        self._inputFormat = None
        self.inputFormat = inputFormat
        self.density = density
        self.massFracs = {}

    def __setitem__(self, key, value):
        if key not in ALLOWED_KEYS:
            raise ValueError(
                "Key `{}` is not valid, must be one of: {}".format(
                    key, ALLOWED_KEYS))

        yamlize.Map.__setitem__(self, key, value)

    @property
    def density(self):
        return self._computedDensity or self._density

    @density.setter
    def density(self, value):
        if self._computedDensity is not None:
            raise AttributeError(
                "Density was computed from number densities, and should not be "
                "set directly.")
        self._density = value
        if value is not None and value < 0:
            raise ValueError(
                "Cannot set `density` to `{}`, must greater than 0".format(
                    value))

    @classmethod
    def from_yaml(cls, loader, node, rtd):
        """
        Override the ``Yamlizable.from_yaml`` to inject custom data validation logic, and complete initialization of the
        object.
        """
        self = yamlize.Map.from_yaml.__func__(cls, loader, node, rtd)

        try:
            self._initializeMassFracs()
            self._expandElementMassFracs()
        except Exception as ex:
            # use a YamlizingError to get line/column of erroneous input
            raise yamlize.YamlizingError(str(ex), node)

        return self

    @classmethod
    def from_yaml_key_val(cls, loader, key_node, val_node, key_attr, rtd):
        """
        Override the ``Yamlizable.from_yaml`` to inject custom data validation logic, and complete initialization of the
        object.
        """
        self = yamlize.Map.from_yaml_key_val.__func__(cls, loader, key_node,
                                                      val_node, key_attr, rtd)

        try:
            self._initializeMassFracs()
            self._expandElementMassFracs()
        except Exception as ex:
            # use a YamlizingError to get line/column of erroneous input
            raise yamlize.YamlizingError(str(ex), val_node)

        return self

    def _initializeMassFracs(self):
        self.massFracs = dict()  # defaults to 0.0, __init__ is not called

        if any(v < 0.0 for v in self.values()):
            raise ValueError("Custom isotopic input for {} is negative".format(
                self.name))

        valSum = sum(self.values())
        if not abs(valSum - 1.0) < 1e-5 and "fractions" in self.inputFormat:
            raise ValueError(
                "Fractional custom isotopic input values must sum to 1.0 in: {}"
                .format(self.name))

        if self.inputFormat == "number fractions":
            sumNjAj = 0.0

            for nuc, nj in self.items():
                if nj:
                    sumNjAj += nj * nucDir.getAtomicWeight(nuc)

            for nuc, value in self.items():
                massFrac = value * nucDir.getAtomicWeight(nuc) / sumNjAj
                self.massFracs[nuc] = massFrac

        elif self.inputFormat == "number densities":
            if self._density is not None:
                raise exceptions.InputError(
                    "Custom isotopic `{}` is over-specified. It was provided as number "
                    "densities, and but density ({}) was also provided. Is the input format "
                    "correct?".format(self.name, self.density))

            M = {
                nuc: Ni / units.MOLES_PER_CC_TO_ATOMS_PER_BARN_CM *
                nucDir.getAtomicWeight(nuc)
                for nuc, Ni in self.items()
            }
            densityTotal = sum(M.values())
            if densityTotal < 0:
                raise ValueError("Computed density is negative")

            for nuc, Mi in M.items():
                self.massFracs[nuc] = Mi / densityTotal

            self._computedDensity = densityTotal

        elif self.inputFormat == "mass fractions":
            self.massFracs = dict(self)  # as input

        else:
            raise ValueError(
                "Unrecognized custom isotopics input format {}.".format(
                    self.inputFormat))

    def _expandElementMassFracs(self):
        """
        Expand the custom isotopics input entries that are elementals to isotopics.

        This is necessary when the element name is not a elemental nuclide.
        Most everywhere else expects Nuclide objects (or nuclide names). This input allows a
        user to enter "U" which would expand to the naturally occurring uranium isotopics.

        This is different than the isotopic expansion done for meeting user-specified
        modeling options (such as an MC**2, or MCNP expecting elements or isotopes),
        because it translates the user input into something that can be used later on.
        """
        elementsToExpand = []
        for nucName in self.massFracs:
            if nucName not in nuclideBases.byName:
                element = elements.bySymbol.get(nucName)
                if element is not None:
                    runLog.info(
                        "Expanding custom isotopic `{}` element `{}` to natural isotopics"
                        .format(self.name, nucName))
                    # include all natural isotopes with None flag
                    elementsToExpand.append((element, None))
                else:
                    raise exceptions.InputError(
                        "Unrecognized nuclide/isotope/element in input: {}".
                        format(nucName))

        densityTools.expandElementalMassFracsToNuclides(
            self.massFracs, elementsToExpand)

    def apply(self, material):
        """
        Apply specific isotopic compositions to a component.

        Generically, materials have composition-dependent bulk properties such as mass density.
        Note that this operation does not update these material properties. Use with care.

        Parameters
        ----------
        material : Material
            An ARMI Material instance.

        """
        material.p.massFrac = dict(self.massFracs)
        if self.density is not None:
            if not isinstance(material, materials.Custom):
                runLog.warning(
                    "You specified a custom mass density on `{}` with custom isotopics `{}`. "
                    "This has no effect; you can only set this on `Custom` "
                    "materials. Continuing to use {} mass density.".format(
                        material, self.name, material))
                return  # specifically, non-Custom materials only use refDensity and dLL, .p.density has no effect
            material.p.density = self.density
コード例 #5
0
class MaterialModifications(yamlize.Map):
    key_type = yamlize.Typed(str)
    value_type = yamlize.Sequence