.. _usersguide_data:

==================
Data Configuration
==================

OpenMC relies on a variety of physical data in order to carry out transport
simulations, depletion simulations, and other common tasks. As a user, you are
responsible for specifying one or more of the following:

- **Cross sections (XML)** -- A :ref:`cross sections XML <io_cross_sections>`
  file (commonly named ``cross_sections.xml``) contains a listing of other data
  files, in particular neutron cross sections, photon cross sections, and
  windowed multipole data. Each of those files, in turn, uses a `HDF5
  <https://www.hdfgroup.org/solutions/hdf5/>`_ format (see
  :ref:`io_nuclear_data`). In order to run transport simulations with
  continuous-energy cross sections, you need to specify this file.

- **Depletion chain (XML)** -- A :ref:`depletion chain XML <io_depletion_chain>`
  file contains decay data, fission product yields, and information on what
  neutron reactions can result in transmutation. This file is needed for
  depletion/activation calculations as well as some basic functions in the
  :mod:`openmc.data` module.

- **Multigroup cross sections (HDF5)** -- OpenMC can also perform transport
  simulations using multigroup data. In this case, multigroup cross sections are
  stored in a single :ref:`HDF5 file <io_mgxs_library>`. Thus, in order to run a
  multigroup transport simulation, this file needs to be specified.

Each of the above files can specified in several ways. In the Python API, a
:ref:`runtime configuration variable <usersguide_data_runtime>`
:data:`openmc.config` can be used to specify any of the above and is initialized
using a set of environment variables. Data configuration paths set in
:data:`openmc.config` will be expanded to absolute paths.

.. _usersguide_data_runtime:

---------------------
Runtime Configuration
---------------------

Data sources for OpenMC can be specified at runtime in Python using the
:data:`openmc.config` variable. This variable acts like a dictionary and stores
key-values pairs, where the values are file paths (strings or path-like objects)
and the key can be one of the following:

``"cross_sections"``
  Indicates the path to the :ref:`cross sections XML <io_cross_sections>` file
  that lists HDF5 format neutron cross sections, photon cross sections, and
  windowed multipole data. At startup, this is initialized with the value of the
  :envvar:`OPENMC_CROSS_SECTIONS` environment variable. Note that the
  :attr:`openmc.Materials.cross_sections` attribute will override this, if
  specified.

``"chain_file"``
  Indicates the path to the :ref:`depletion chain XML <io_depletion_chain>` file
  that contains decay data, fission product yields, and what neutron reactions
  may result in transmutation of a target nuclide. At startup, this is
  initialized with the value of the :envvar:`OPENMC_CHAIN_FILE` environment
  variable.

``"mg_cross_sections"``
  Indicates the path to an :ref:`HDF5 file <io_mgxs_library>` that contains
  multigroup cross sections. At startup, this is initialized with the value of
  the :envvar:`OPENMC_MG_CROSS_SECTIONS` environment variable. Note that the
  :attr:`openmc.Materials.cross_sections` attribute will override this if
  specified.

If you want to persistently set the environment variables used to initialized
the configuration, export them from your shell profile (``.profile`` or
``.bashrc`` in bash_).

.. _bash: https://www.linuxfromscratch.org/blfs/view/6.3/postlfs/profile.html

--------------------------------
Continuous-Energy Cross Sections
--------------------------------

Using Pregenerated Libraries
----------------------------

Various evaluated nuclear data libraries have been processed into the HDF5
format required by OpenMC and can be found at https://openmc.org. Unless you
have specific data needs, it is highly recommended to use one of the
pregenerated libraries. You can find both libraries generated by the OpenMC
development team as well as libraries based on ACE files distributed elsewhere.
To use these libraries, download the archive file, unpack it, and then specify
the path of the ``cross_sections.xml`` file contained in the unpacked directory
as described in :ref:`usersguide_data_runtime`.

.. _create_xs_library:

Manually Creating a Library from ACE files
------------------------------------------

.. currentmodule:: openmc.data

If you have ACE format data that was produced with NJOY_, such as that
distributed with MCNP_ or Serpent_, it can be converted to the HDF5 format using
the using the Python API. Several sources provide openly available ACE data
including the `ENDF/B`_, JEFF_, and TENDL_ libraries as well as the `LANL
Nuclear Data Team <https://nucleardata.lanl.gov/>`_.

The :mod:`openmc.data` module in the Python API enables users to directly
convert ACE data to OpenMC's HDF5 format and create a corresponding
:ref:`cross_sections.xml <io_cross_sections>` file. For those who prefer to use
the API directly, the :class:`openmc.data.IncidentNeutron` and
:class:`openmc.data.ThermalScattering` classes can be used to read ACE data and
convert it to HDF5. For continuous-energy incident neutron data, use the
:meth:`IncidentNeutron.from_ace` class method to read in an existing ACE file
and the :meth:`IncidentNeutron.export_to_hdf5` method to write the data to an
HDF5 file.

::

  u235 = openmc.data.IncidentNeutron.from_ace('92235.710nc')
  u235.export_to_hdf5('U235.h5')

If you have multiple ACE files for the same nuclide at different temperatures,
you can use the :meth:`IncidentNeutron.add_temperature_from_ace` method to
append cross sections to an existing :class:`IncidentNeutron` instance::

  u235 = openmc.data.IncidentNeutron.from_ace('92235.710nc')
  for suffix in [711, 712, 713, 714, 715, 716]:
      u235.add_temperature_from_ace('92235.{}nc'.format(suffix))
  u235.export_to_hdf5('U235.h5')

Similar methods exist for thermal scattering data:

::

  light_water = openmc.data.ThermalScattering.from_ace('lwtr.20t')
  for suffix in range(21, 28):
      light_water.add_temperature_from_ace('lwtr.{}t'.format(suffix))
  light_water.export_to_hdf5('lwtr.h5')

Once you have created corresponding HDF5 files for each of your ACE files, you
can create a library and export it to XML using the
:class:`openmc.data.DataLibrary` class::

  library = openmc.data.DataLibrary()
  library.register_file('U235.h5')
  library.register_file('lwtr.h5')
  ...
  library.export_to_xml()

At this point, you will have a ``cross_sections.xml`` file that you can use in
OpenMC.

.. hint:: The :class:`IncidentNeutron` class allows you to view/modify cross
          sections, secondary angle/energy distributions, probability tables,
          etc. For a more thorough overview of the capabilities of this class,
          see the `example notebook <https://nbviewer.jupyter.org/github/openmc-dev/openmc-notebooks/blob/main/nuclear-data.ipynb>`_.

Manually Creating a Library from ENDF files
-------------------------------------------

If you need to create a nuclear data library and you do not already have
suitable ACE files or you need to further customize the data (for example,
adding more temperatures), the :meth:`IncidentNeutron.from_njoy` and
:meth:`ThermalScattering.from_njoy` methods can be used to create data instances
by directly running NJOY_. Both methods require that you pass the name of ENDF
file(s) that are passed on to NJOY. For example, to generate data for Zr-92::

  zr92 = openmc.data.IncidentNeutron.from_njoy('n-040_Zr_092.endf')

By default, data is produced at room temperature, 293.6 K. You can also specify
a list of temperatures that you want data at::

  zr92 = openmc.data.IncidentNeutron.from_njoy(
      'n-040_Zr_092.endf', temperatures=[300., 600., 1000.])

The :meth:`IncidentNeutron.from_njoy` method assumes you have an executable
named ``njoy`` available on your path. If you want to explicitly name the
executable, the ``njoy_exec`` optional argument can be used. Additionally, the
``stdout`` argument can be used to show the progress of the NJOY run.

To generate a thermal scattering file, you need to specify both an ENDF incident
neutron sub-library file as well as a thermal neutron scattering sub-library
file; for example::

  light_water = openmc.data.ThermalScattering.from_njoy(
      'neutrons/n-001_H_001.endf', 'thermal_scatt/tsl-HinH2O.endf')

Once you have instances of :class:`IncidentNeutron` and
:class:`ThermalScattering`, a library can be created by using the
``export_to_hdf5()`` methods and the :class:`DataLibrary` class as described in
:ref:`create_xs_library`.

Enabling Resonance Scattering Treatments
----------------------------------------

In order for OpenMC to correctly treat elastic scattering in heavy nuclides
where low-lying resonances might be present (see
:ref:`energy_dependent_xs_model`), the elastic scattering cross section at 0 K
must be present. If the data you are using was generated via
:meth:`IncidentNeutron.from_njoy`, you will already have 0 K elastic scattering
cross sections available. Otherwise, to add 0 K elastic scattering cross
sections to an existing :class:`IncidentNeutron` instance, you can use the
:meth:`IncidentNeutron.add_elastic_0K_from_endf` method which requires an ENDF
file for the nuclide you are modifying::

  u238 = openmc.data.IncidentNeutron.from_hdf5('U238.h5')
  u238.add_elastic_0K_from_endf('n-092_U_238.endf')
  u238.export_to_hdf5('U238_with_0K.h5')

With 0 K elastic scattering data present, you can turn on a resonance scattering
method using :attr:`Settings.resonance_scattering`.

.. note:: The process of reconstructing resonances and generating tabulated 0 K
          cross sections can be computationally expensive, especially for
          nuclides like U-238 where thousands of resonances are present. Thus,
          running the :meth:`IncidentNeutron.add_elastic_0K_from_endf` method
          may take several minutes to complete.

Photon Cross Sections
---------------------

Photon interaction data is needed to run OpenMC with photon transport enabled.
Some of this data, namely bremsstrahlung cross sections from `Seltzer and
Berger`_, mean excitation energy from the `NIST ESTAR database`_, and Compton
profiles calculated by `Biggs et al.`_ and available in the Geant4 G4EMLOW data
file, is distributed with OpenMC. The rest is available from the NNDC_, which
provides ENDF data from the photo-atomic and atomic relaxation sublibraries of
the ENDF/B-VII.1 library.

Most of the pregenerated HDF5 libraries available at https://openmc.org
already have photon interaction data included. If you are building a data
library yourself, it is possible to use the Python API directly to convert
photon interaction data from an ENDF or ACE file to an HDF5 file. The
:class:`openmc.data.IncidentPhoton` class contains an
:meth:`IncidentPhoton.from_ace` method that will generate photon data from an
ACE table and an :meth:`IncidentPhoton.export_to_hdf5` method that writes the
data to an HDF5 file:

::

  u = openmc.data.IncidentPhoton.from_ace('92000.12p')
  u.export_to_hdf5('U.h5')

Similarly, the :meth:`IncidentPhoton.from_endf` method can be used to read
photon data from an ENDF file. In this case, both the photo-atomic and atomic
relaxation sublibrary files are required:

::

  u = openmc.data.IncidentPhoton.from_endf('photoat-092_U_000.endf',
                                           'atom-092_U_000.endf')

Once the HDF5 files have been generated, a library can be created using the
:class:`DataLibrary` class as described in :ref:`create_xs_library`.

-----------
Chain Files
-----------

Pregenerated depletion chain XML files can be found at https://openmc.org.
Additionally, depletion chains can be generated using the
:class:`openmc.deplete.Chain` class. In particular, the
:meth:`~openmc.deplete.Chain.from_endf` method allows a chain to be generated
starting from a set of ENDF incident neutron, decay, and fission product yield
sublibrary files. Once you've downloaded or generated a depletion chain XML
file, make sure to specify its path as described in
:ref:`usersguide_data_runtime`.

-----------------------
Windowed Multipole Data
-----------------------

OpenMC is capable of using windowed multipole data for on-the-fly Doppler
broadening. A comprehensive multipole data library containing all nuclides in
ENDF/B-VII.1 is available on `GitHub
<https://github.com/mit-crpg/WMP_Library>`_. To obtain this library, download
and unpack an archive (.zip or .tag.gz) from GitHub. Once unpacked, you can use
the :class:`openmc.data.DataLibrary` class to register the .h5 files as
described in :ref:`create_xs_library`.

The `official ENDF/B-VII.1 HDF5 library
<https://openmc.org/official-data-libraries/>`_ includes the windowed
multipole library, so if you are using this library, the windowed multipole data
will already be available to you.

.. _create_mgxs:

-------------------------
Multigroup Cross Sections
-------------------------

Multigroup cross section libraries are generally tailored to the specific
calculation to be performed.  Therefore, at this point in time, OpenMC is not
distributed with any pre-existing multigroup cross section libraries. However,
if a multigroup library file is downloaded or generated, the path to the file
needs to be specified as described in :ref:`usersguide_data_runtime`. For an
example of how to create a multigroup library, see this `MG mode notebook
<https://nbviewer.org/github/openmc-dev/openmc-notebooks/blob/main/mg-mode-part-i.ipynb>`_.

.. _NJOY: https://www.njoy21.io/
.. _NNDC: https://www.nndc.bnl.gov/endf
.. _MCNP: https://mcnp.lanl.gov
.. _Serpent: https://serpent.vtt.fi
.. _ENDF/B: https://www.nndc.bnl.gov/endf-b7.1/acefiles.html
.. _JEFF: https://www.oecd-nea.org/dbdata/jeff/jeff33/
.. _TENDL: https://tendl.web.psi.ch/tendl_2023/tendl2023.html
.. _Seltzer and Berger: https://doi.org/10.1016/0092-640X(86)90014-8
.. _NIST ESTAR database: https://physics.nist.gov/PhysRefData/Star/Text/ESTAR.html
.. _Biggs et al.: https://doi.org/10.1016/0092-640X(75)90030-3
