Specifying Materials
Material specification forms a critical part of any analysis system. The OSCAR-5 provides functionality to specify
material data required for neutronics calculations, as well as additional data required by other systems (e.g thermal
hydraulics). All methods and data objects are contained in the core.material
module. The material_library
package also contains a number of pre-defined (built-in) materials.
Material Data
A core.material.Material
instance is used to represent a composition of isotopes together with additional
meta data. An instance can be created using the material.create_material method, for example,
>>> from core import *
>>> m = material.create_material()
The material container has the following parameters:
-
material.name
: string
! Descriptive name for the material instance. Although this parameter has no real impact on any sub system, it does help in model visualization and documentation.
-
material.color
: tuple
Color used to identify the material during model visualization. Tuple of three integers denoting the red green blue (RGB) value of the color. Each integer value must fall between 0 and 255. The
utilities.Palette
class defines a number of colors. For example,>>> from core import * >>> print(utilities.Palette.Blue) (0, 0, 255) >>> print(utilities.Palette.DarkGray) (169, 169, 169)
- material.type = generic
Material types is a mechanism used to conceptually group materials into units that best describe their purpose within a model. Types are also closely tied to the state perturbation mechanism. In particular, whenever a state change is triggered, all materials of the type the state is connected to will be altered. All material types are collected in
material.tags
. The following table lists available materials types, as well as the state parameters that will trigger a change in the material state.Tag
Description
State Parameters
fuel
General fissionable material.
fuel_temperature
clad
Fuel cladding material.
clad_temperature
gap
Material filling the gap between clad and fuel.
moderator
Material used to moderate (thermalize) neutrons.
moderator_temperature
moderator_density
structural
General structural material.
reflector
Material used to reflect neutrons.
reflector_temperature
control
Material used to absorb (remove) neutrons.
burnable_absorber
Material used to control initial reactivity.
soluble_absorber
Absorber solution.
moderator_temperature
moderator_density
poison_concentration
void
Very low density material.
moderator_and_structural_mixture
Mixture of moderator and structural materials. Usually used to approximate complex structures.
moderator_temperature
moderator_density
self_cooled_channel
Material that will not be affected by core wide state perturbations.
- material.temperature = 294 K
The material temperature. This parameter is usually set to some nominal value, but is frequently altered internally.
-
material.thermal_composition
: string
Sub composition within the material for which additional thermal scattering models are required. This must be one of the composition names defined in the configuration file.
-
material.thermal_isotope
: isotope
Isotope within the mixture which requires additional thermal scattering treatment.
Attention
If this parameter is set, the system will try to deduce which scattering library to use based on the isotope’s mass. This is not always reliable, since many isotopes occur in multiple thermal compositions. It is recommended to use
material.thermal_composition
instead.This parameter is mostly for legacy support, and will likely be removed in future versions.
-
material.burnable
: bool
= False Flag indicating if the material must be activated (depleted) during simulations. If False, the material will remain at it’s static composition. This flag is modified internally for materials managed in burnable bundles, but you can use it to flag stand alone materials as burnable.
Note
Burnable materials require
material.volume
to be set. The system will try to automatically calculate it based on the cells the material fill, but you can also manually specify it. Also, if you flag a material as burnable, make sure that it has a uniquematerial.name
.
-
material.volume
: volume
Volume this material fills. For burnable materials, the system will calculate it automatically. For most other materials, this parameter can be ignored.
Isotopes are added to the material mixture using the following function:
- material.add(iso, number_density)
Adds an isotope to the material mixture.
- Parameters:
iso (isotope) – Isotope to add.
number_density – Density of iso in the material. Must have number density dimensions.
Note
If iso has already been added to the mixture, it’s density will be increased by number_density.
Alternatively, the []
method can also be used. For example,
>>> from core import *
>>> m = material.create_material()
>>> m.name = 'MyMaterial'
>>> m.add('B-10', 1.0E-3 * units.number_density)
>>> m['B-11'] = 1.0E-2 * units.number_density
>>> print(m)
Material : MyMaterial
Type : generic
Mass density : 0.1994 g/cc
Isotope Wt Nd (1/b/cm)
B-10 8.34 % 1.00000e-03
B-11 91.66 % 1.00000e-02
Total 100.00 1.10000e-02
Using material mixers
If the number density is not known (which is usually the case when building materials from engineering data), the MaterialMassFractionMixer or MaterialAtomicFractionMixer utilities can be used to mix compositions from weight or atomic fractions respectively. Both mixer classes are constructed by passing the total material density. This can be a quantity of either mass, atomic or number density units. Isotopic compositions are then specified using the add method. Finally, a complete material, with isotopic compositions in number densities, are returned using the mix method.
Note
The material returned by the mix
method only contains isotopic compositions, so make sure to set some additional
meta data (e.g material.name
, material.color
, material.type
etc).
Mixing from mass fractions
- material.create_mass_fraction_mixer(density, total=None)
Create a MaterialMassFractionMixer instance.
- Parameters:
density – Total density of the final material. Usually a quantity with mass density dimensions.
total (float) – Value fractions should be normalized to. If None, the fractions will be normalized to their total.
- Returns:
mixer
This call returns a MaterialMassFractionMixer instance, which is then used to add isotopes to the composition with the following methods:
- mixer.add(iso, part)
Add an isotope to the mixture.
- mixer.add_balance(iso)
Fill the remaining mass with the specified isotope.
- Parameters:
iso (isotope) – Isotope to add.
Attention
This function requires that the total keyword was specified during the creation of the mixer.
Finally, a material is created using
- mixer.mix()
Creates the material with the correct number densities for each isotope in the mixture.
- Returns:
A material instance.
- Return type:
material.Material
A typical mass fraction example,
>>> from core import *
>>> mixer = material.create_mass_fraction_mixer(density=2.71 * units.g / units.cc, total=100.0)
>>> mixer.add('Cu', 0.1)
>>> mixer.add('Si', 1.0)
>>> mixer.add_balance('Al-27')
>>> m = mixer.mix()
>>> m.name = 'Al'
>>> m.type = material.tags.structural
>>> print(m)
Material : Al
Type : structural
Mass density : 2.7100 g/cc
Isotope Wt Nd (1/b/cm)
Al-27 98.90 % 5.98205e-02
Si-Nat 1.00 % 5.81073e-04
Cu-Nat 0.10 % 2.56822e-05
Total 100.00 6.04272e-02
Mixing from atomic fractions
- material.create_atomic_fraction_mixer(density)
Create a MaterialAtomicFractionMixer instance.
- Parameters:
density – Total density of the final material. A quantity with either mass, atomic or number density dimensions.
- Returns:
mixer
The returned mixer is then used to add isotopes to the composition:
A typical atomic fraction example is:
>>> mixer = material.create_atomic_fraction_mixer(density=0.998 * units.g / units.cc)
>>> mixer.add('H-1', 2.0)
>>> mixer.add('O-16', 1.0)
>>> m = mixer.mix()
>>> m.name = 'H2O'
>>> m.type = material.tags.moderator
>>> print(m)
Material : H2O
Type : moderator
Mass density : 0.9980 g/cc
Isotope Wt Nd (1/b/cm)
H-1 66.67 % 3.97562e-01
O-16 33.33 % 1.25250e-02
Total 100.00 4.10087e-01
Built-in materials
The material_library package contains a number of predefined materials. They are grouped into separate modules, which is listed in the following sections. Before using these materials in your model, you can check their content using the interpreter. For example:
>>> from material_library.moderators import LightWater
>>> from core.unit import units
>>> lwt = LightWater(pressure=1.8 * units.bar, temperature=20 * units.degC)
>>> print(lwt)
Material : H2O
Type : moderator
Mass density : 0.9982 g/cc
Isotope Wt (%) Nd (1/b/cm)
H-1 11.19 6.67559e-02
O-16 88.81 3.33779e-02
Total 100.00 1.00134e-01
Note
The material library is currently quite small, but expect it to grow in size and scope as thermal hydraulic modeling is added to the package.
- Moderator Materials
- Gasses
- Reflectors
- Structural Materials
material_library.structural.Al6061()
material_library.structural.Al1050()
material_library.structural.Al1200()
material_library.structural.StainlessSteel304L()
material_library.structural.StainlessSteel316L()
material_library.structural.Concrete()
material_library.structural.GenericWood()
material_library.structural.PlateGlass()
material_library.structural.SiliconCarbide()
material_library.structural.TitaniumAlloy()
- Cladding
Creating a material library for your model
The material module in the model package is intended to define common materials shared among multiple components. Although you can always build materials globally, the recommended method is to define a method for each material which return a unique instance of that material. The principle is best explained via an example:
from core import *
def al6082(mass_density = 2.71 * units.g / units.cc, color=(105, 105, 105)):
"""
Aluminium 6082-T6 used in fuel assembly end adapters and other structural components.
Args:
mass_density: Material mass density.
color : Set the material color for display purposes.
Source:
RR-FRM-0435 Rev 0.1
Notes:
- Missing mass fraction of 0.15% in composition
"""
mixer = core.material.create_mass_fraction_mixer(mass_density,
total=100.0 # avoid auto re-normalization
)
mixer.add('Al-27', 96.1)
mixer.add('Cu-Nat', 0.1)
mixer.add('Cr-Nat', 0.25)
mixer.add('Mg-Nat', 0.9)
mixer.add('Si-Nat', 1.0)
mixer.add('Fe-Nat', 0.5)
mixer.add('Mn-Nat', 0.7)
mixer.add('Ti-Nat', 0.1)
mixer.add('Zn-Nat', 0.2)
m = mixer.mix()
# Store additional meta data
m.color = color
m.type = material.tags.structural
m.name = 'Al6082'
m.__version__ = '2.0.0'
m.__source__ = 'RR-FRM-0435 Rev 0.1'
return m
In the above example the al6082
method returns an Al-6082 material instance. It accepts two arguments, the
mass_density
and color
, with defaults 2.71 * units.g / units.cc
and (105, 105, 105)
respectively. Thus,
the call al6082()
will return an instance at the default density, and
al6082(mass_density=2.8 * units.g / units.cc)
at a modified density.
The comment block (delimited by opening and closing """
) following the method declaration is a standard python
document string, describing the method’s function, arguments, and any other information pertinent to the material. This
information is useful for other users, and will be used by the documentation utility when creating model documentation.
The body of the method contains the material construction. Note how additional meta data is specified in the material
returned by the mixer. Finally, the material is returned using the return
statement.
Note
The arguments passed to a material build method frequently contain a density value. However, many fueled material specifications are given in terms of total mass. In this case, in order to calculate a density, a volume must also be passed. For example:
from core import *
def uranium_silicide(mass=17.89 * units.g,
plate_volume=6.417*59.37*0.051 * units.cc,
color=(244, 202, 22)):
"""
Nominal meat specification for fresh LEU fuel plates
Args:
mass: Total plate U-235 mass
plate_volume: Target plate volume
color: Set the material color for display purposes
"""
enrichment = 0.1975
heavy_metal_fraction = 0.786
# U-235 mass / fraction of U-235 / total volume
mass_density = mass / (heavy_metal_fraction * enrichment) / plate_volume
mixer = core.material.create_mass_fraction_mixer(mass_density)
# Composition (mass fractions in %)
mixer.add('U-235', 19.75 * heavy_metal_fraction)
mixer.add('U-234', 0.24 * heavy_metal_fraction)
mixer.add('U-236', 0.10 * heavy_metal_fraction)
mixer.add('U-238', 79.91 * heavy_metal_fraction)
mixer.add('Si-Nat', 6.4)
mixer.add('Al-27', 15.0)
m = mixer.mix()
# Store additional meta data
m.color = color
m.type = material.tags.fuel
m.name = 'U3Si-Al'
m.__version__ = '2.0.0'
m.__source__ = 'RR-FRM-0435 Rev 0.1'
return m