1.. _usersguide_materials:
2
3.. currentmodule:: openmc
4
5=====================
6Material Compositions
7=====================
8
9Materials in OpenMC are defined as a set of nuclides/elements at specified
10densities and are created using the :class:`openmc.Material` class. Once a
11material has been instantiated, nuclides can be added with
12:meth:`Material.add_nuclide` and elements can be added with
13:meth:`Material.add_element`. Densities can be specified using atom fractions or
14weight fractions. For example, to create a material and add Gd152 at 0.5 atom
15percent, you'd run::
16
17   mat = openmc.Material()
18   mat.add_nuclide('Gd152', 0.5, 'ao')
19
20The third argument to :meth:`Material.add_nuclide` can also be 'wo' for weight
21percent. The densities specified for each nuclide/element are relative and are
22renormalized based on the total density of the material. The total density is
23set using the :meth:`Material.set_density` method. The density can be specified
24in gram per cubic centimeter ('g/cm3'), atom per barn-cm ('atom/b-cm'), or
25kilogram per cubic meter ('kg/m3'), e.g.,
26
27::
28
29   mat.set_density('g/cm3', 4.5)
30
31----------------
32Natural Elements
33----------------
34
35The :meth:`Material.add_element` method works exactly the same as
36:meth:`Material.add_nuclide`, except that instead of specifying a single isotope
37of an element, you specify the element itself. For example,
38
39::
40
41   mat.add_element('C', 1.0)
42
43This method can also accept case-insensitive element names such as
44
45::
46
47  mat.add_element('aluminium', 1.0)
48
49Internally, OpenMC stores data on the atomic masses and natural abundances of
50all known isotopes and then uses this data to determine what isotopes should be
51added to the material. When the material is later exported to XML for use by the
52:ref:`scripts_openmc` executable, you'll see that any natural elements were
53expanded to the naturally-occurring isotopes.
54
55The :meth:`Material.add_element` method can also be used to add uranium at a
56specified enrichment through the `enrichment` argument. For example, the
57following would add 3.2% enriched uranium to a material::
58
59   mat.add_element('U', 1.0, enrichment=3.2)
60
61In addition to U235 and U238, concentrations of U234 and U236 will be present
62and are determined through a correlation based on measured data.
63
64It is also possible to perform enrichment of any element that is composed
65of two naturally-occurring isotopes (e.g., Li or B) in terms of atomic percent.
66To invoke this, provide the additional argument `enrichment_target` to
67:meth:`Material.add_element`. For example the following would enrich B10
68to 30ao%::
69
70   mat.add_element('B', 1.0, enrichment=30.0, enrichment_target='B10')
71
72In order to enrich an isotope in terms of mass percent (wo%), provide the extra
73argument `enrichment_type`. For example the following would enrich Li6 to 15wo%::
74
75   mat.add_element('Li', 1.0, enrichment=15.0, enrichment_target='Li6',
76                   enrichment_type='wo')
77
78Often, cross section libraries don't actually have all naturally-occurring
79isotopes for a given element. For example, in ENDF/B-VII.1, cross section
80evaluations are given for O16 and O17 but not for O18. If OpenMC is aware of
81what cross sections you will be using (through the
82:envvar:`OPENMC_CROSS_SECTIONS` environment variable), it will attempt to only
83put isotopes in your model for which you have cross section data. In the case of
84oxygen in ENDF/B-VII.1, the abundance of O18 would end up being lumped with O16.
85
86-----------------------
87Thermal Scattering Data
88-----------------------
89
90If you have a moderating material in your model like water or graphite, you
91should assign thermal scattering data (so-called :math:`S(\alpha,\beta)`) using
92the :meth:`Material.add_s_alpha_beta` method. For example, to model light water,
93you would need to add hydrogen and oxygen to a material and then assign the
94``c_H_in_H2O`` thermal scattering data::
95
96   water = openmc.Material()
97   water.add_nuclide('H1', 2.0)
98   water.add_nuclide('O16', 1.0)
99   water.add_s_alpha_beta('c_H_in_H2O')
100   water.set_density('g/cm3', 1.0)
101
102.. _usersguide_naming:
103
104------------------
105Naming Conventions
106------------------
107
108OpenMC uses the GNDS_ naming convention for nuclides, metastable states, and
109compounds:
110
111:Nuclides: ``SymA`` where "A" is the mass number (e.g., ``Fe56``)
112:Elements: ``Sym0`` (e.g., ``Fe0`` or ``C0``)
113:Excited states: ``SymA_eN`` (e.g., ``V51_e1`` for the first excited state of
114                 Vanadium-51.) This is only used in decay data.
115:Metastable states: ``SymA_mN`` (e.g., ``Am242_m1`` for the first excited state
116                    of Americium-242).
117:Compounds: ``c_String_Describing_Material`` (e.g., ``c_H_in_H2O``). Used for
118            thermal scattering data.
119
120.. important:: The element syntax, e.g., ``C0``, is only used when the cross
121               section evaluation is an elemental evaluation, like carbon in
122               ENDF/B-VII.1! If you are adding an element via
123               :meth:`Material.add_element`, just use ``Sym``.
124
125.. _GNDS: https://www.oecd-nea.org/jcms/pl_39689/specifications-for-the-generalised-nuclear-database-structure-gnds
126
127-----------
128Temperature
129-----------
130
131Some Monte Carlo codes define temperature implicitly through the cross section
132data, which is itself given only at a particular temperature. In OpenMC, the
133material definition is decoupled from the specification of temperature. Instead,
134temperatures are assigned to :ref:`cells <usersguide_cells>`
135directly. Alternatively, a default temperature can be assigned to a material
136that is to be applied to any cell where the material is used. In the absence of
137any cell or material temperature specification, a global default temperature can
138be set that is applied to all cells and materials. Anytime a material
139temperature is specified, it will override the global default
140temperature. Similarly, anytime a cell temperatures is specified, it will
141override the material or global default temperature. All temperatures should be
142given in units of Kelvin.
143
144To assign a default material temperature, one should use the ``temperature``
145attribute, e.g.,
146
147::
148
149   hot_fuel = openmc.Material()
150   hot_fuel.temperature = 1200.0  # temperature in Kelvin
151
152.. warning:: MCNP_ users should be aware that OpenMC does not use the concept of
153             cross section suffixes like "71c" or "80c". Temperatures in Kelvin
154             should be assigned directly per material or per cell using the
155             :attr:`Material.temperature` or :attr:`Cell.temperature`
156             attributes, respectively.
157
158-----------------
159Material Mixtures
160-----------------
161
162In OpenMC it is possible to mix any number of materials to create a new material
163with the correct nuclide composition and density. The
164:meth:`Material.mix_materials` method takes a list of materials and
165a list of their mixing fractions. Mixing fractions can be provided as atomic
166fractions, weight fractions, or volume fractions. The fraction type
167can be specified by passing 'ao', 'wo', or 'vo' as the third argument, respectively.
168For example, assuming the required materials have already been defined, a MOX
169material with 3% plutonium oxide by weight could be created using the following:
170
171::
172
173   mox = openmc.Material.mix_materials([uo2, puo2], [0.97, 0.03], 'wo')
174
175It should be noted that, if mixing fractions are specifed as atomic or weight
176fractions, the supplied fractions should sum to one. If the fractions are specified
177as volume fractions, and the sum of the fractions is less than one, then the remaining
178fraction is set as void material.
179
180.. warning:: Materials with :math:`S(\alpha,\beta)` thermal scattering data
181             cannot be used in :meth:`Material.mix_materials`. However, thermal
182             scattering data can be added to a material created by
183             :meth:`Material.mix_materials`.
184
185--------------------
186Material Collections
187--------------------
188
189The :ref:`scripts_openmc` executable expects to find a ``materials.xml`` file
190when it is run. To create this file, one needs to instantiate the
191:class:`openmc.Materials` class and add materials to it. The :class:`Materials`
192class acts like a list (in fact, it is a subclass of Python's built-in
193:class:`list` class), so materials can be added by passing a list to the
194constructor, using methods like ``append()``, or through the operator
195``+=``. Once materials have been added to the collection, it can be exported
196using the :meth:`Materials.export_to_xml` method.
197
198::
199
200   materials = openmc.Materials()
201   materials.append(water)
202   materials += [uo2, zircaloy]
203   materials.export_to_xml()
204
205   # This is equivalent
206   materials = openmc.Materials([water, uo2, zircaloy])
207   materials.export_to_xml()
208
209Cross Sections
210--------------
211
212OpenMC uses a file called :ref:`cross_sections.xml <io_cross_sections>` to
213indicate where cross section data can be found on the filesystem. This file
214serves the same role that ``xsdir`` does for MCNP_ or ``xsdata`` does for
215Serpent. Information on how to generate a cross section listing file can be
216found in :ref:`create_xs_library`. Once you have a cross sections file that has
217been generated, you can tell OpenMC to use this file either by setting
218:attr:`Materials.cross_sections` or by setting the
219:envvar:`OPENMC_CROSS_SECTIONS` environment variable to the path of the
220``cross_sections.xml`` file. The former approach would look like::
221
222   materials.cross_sections = '/path/to/cross_sections.xml'
223
224.. _MCNP: https://mcnp.lanl.gov/
225