Nucleide

Build Materials

This tutorial shows you how to build materials from chemical formulas and the PNNL Materials Compendium, mix them by mass or volume, and export them with the Python API. Nucleide models materials as maps from canonical nuclide identifiers to masses, with optional density and metadata. Materials live in the material crate and are exposed through nucleide.material.MaterialsCompendium, from_formula, and related helpers.

Build from a chemical formula

from nucleide.material import from_formula

comp = from_formula("UO2")
print(comp)

Load the PNNL Materials Compendium

The compendium ships as a standalone JSON file; it is not bundled in the Python wheel. Download it with nucleide.data, which pins the download to the installed version’s tag (in a source checkout, the same file is already under fixtures/data/):

from nucleide.material import MaterialsCompendium


path = "fixtures/data/MaterialsCompendium.json"
lib = MaterialsCompendium.load(path)
print(len(lib), "materials")
print(lib.names()[:5])

The equivalent one-liner with curl:

curl -LO https://raw.githubusercontent.com/nukehub-dev/nucleide/main/fixtures/data/MaterialsCompendium.json

Mix materials

mix_by_mass combines (composition, weight) streams by relative mass; mix_by_volume combines (composition, volume, density) triples through each stream’s density:

from nucleide.material import mix_by_mass, mix_by_volume

mass = mix_by_mass([({"U235": 19.0}, 1.0), ({"U238": 1.0}, 1.0)])
vol = mix_by_volume([({"U235": 19.0}, 1.0, 19.1), ({"U238": 1.0}, 1.0, 19.1)])
print(mass, vol)

Specific activity and multi-material documents

specific_activity returns the whole-material Bq/g; materials_doc_to_xml bundles named materials (each with its density) into one <materials> document, and expand_elements / collapse_elements convert between natural-element placeholders (bare symbols such as "U") and isotopic breakdowns:

from nucleide.material import (
    collapse_elements,
    expand_elements,
    materials_doc_to_xml,
    specific_activity,
)

print(specific_activity({"U235": 1.0}))
xml = materials_doc_to_xml([("fuel", {"U235": 19.0}, 10.0)], cross_sections="xs.xml")
print(expand_elements({"U": 20.0}))
print(collapse_elements({"U235": 19.0, "U238": 1.0}))  # {"U": 20.0}

Export materials XML

A composition dictionary can be serialized to an OpenMC-style <material> XML fragment. to_xml takes a name, density, and optional density units:

from nucleide.material import from_formula, to_xml

comp = from_formula("UO2")
xml = to_xml(comp, "fuel", 10.0, "g/cm3")
print(xml)

Dose per gram

dose_per_g maps a composition in grams through the vendored dose-factor tables (nucleide.nuclei.dose_factor over the HNF-5636 / PyNE dbgen/dosefactors basis: 93 folded nuclides × 4 pathways × 3 sources; +D daughters fold into the parent, GENII/DOE air cells are -1 sentinels and error). The pathway is one of air, soil, ingest, or inhale; the source defaults to EPA (DOE and GENII also resolve). Units follow the table — air in mrem/h per g per m³, soil in mrem/h per g per m², ingest/inhale in mrem per g — following PyNE’s Material::dose_per_g equations with per-gram map semantics. Results are screening-level only, never for safety decisions:

from nucleide.material import dose_per_g

print(dose_per_g({"Co60": 1.0}, "ingest"))  # mrem per g
print(dose_per_g({"Co60": 1.0}, "air"))  # mrem/h per g per m^3

Nuclides lacking mass data are errors, as are radioactive nuclides lacking dose data (including the -1 sentinels). Stable nuclides — known mass but no decay constant — contribute exactly 0.

For external-exposure screening, nucleide.nuclei.fgr15_dose_rate serves the EPA FGR 15 tables (ground surface, soil depths, air submersion, water immersion; downloaded hash-pinned at runtime). It is external exposure only and complements — never silently overrides — dose_per_g; compare units before combining.

See also