Remove xs conversion scripts and update documentation

This commit is contained in:
Paul Romano 2019-02-12 17:14:52 -06:00
parent cf65d9ed2e
commit 90568ba96c
10 changed files with 60 additions and 905 deletions

View file

@ -72,7 +72,7 @@ sub-elements:
default Gnome viewer, IrfanView, etc.). The "voxel" plot type produces a
binary datafile containing voxel grid positioning and the cell or material
(specified by the ``color`` tag) at the center of each voxel. These
datafiles can be processed into 3D SILO files using the :ref:`scripts_voxel`
datafiles can be processed into VTK files using the :ref:`scripts_voxel`
script provided with OpenMC, and subsequently viewed with a 3D viewer such
as VISIT or Paraview. See the :ref:`io_voxel` for information about the
datafile structure.
@ -82,7 +82,7 @@ sub-elements:
the PNG format can often times reduce the file size by orders of
magnitude without any loss of image quality. Likewise,
high-resolution voxel files produced by OpenMC can be quite large,
but the equivalent SILO files will be significantly smaller.
but the equivalent VTK files will be significantly smaller.
*Default*: "slice"

View file

@ -10,15 +10,16 @@ or multi-group mode.
In continuous-energy mode, OpenMC uses a native `HDF5
<https://support.hdfgroup.org/HDF5/>`_ format (see :ref:`io_nuclear_data`) to
store all nuclear 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 :ref:`scripts_ace` script (or :ref:`using the Python
API <create_xs_library>`). Several sources provide openly available ACE data as
described below and can be easily converted using the provided scripts. The
TALYS-based evaluated nuclear data library, TENDL_, is also available in ACE
format. In addition to tabulated cross sections in the HDF5 files, OpenMC relies
on :ref:`windowed multipole <windowed_multipole>` data to perform on-the-fly
Doppler broadening.
store all nuclear data. Pregenerated HDF5 libraries can be found at
https://openmc.mcs.anl.gov; unless you have specific data needs, it is highly
recommended to use one of the pregenerated libraries. Alternatively, 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 :ref:`using
the Python API <create_xs_library>`. Several sources provide openly available
ACE data including the `ENDF/B`_, JEFF_, and TENDL_
libraries. In addition to tabulated cross sections in the HDF5 files, OpenMC
relies on :ref:`windowed multipole <windowed_multipole>` data to perform
on-the-fly Doppler broadening.
In multi-group mode, OpenMC utilizes an HDF5-based library format which can be
used to describe nuclide- or material-specific quantities.
@ -56,85 +57,16 @@ profile (``.profile`` or ``.bashrc`` in bash_).
Continuous-Energy Cross Sections
--------------------------------
Using ENDF/B-VII.1 Cross Sections from NNDC
-------------------------------------------
Using Pregenerated Libraries
----------------------------
The NNDC_ provides ACE data from the ENDF/B-VII.1 neutron and thermal scattering
sublibraries at room temperature processed using NJOY_. To use this data with
OpenMC, the :ref:`scripts_nndc` script can be used to automatically download and
extract the ACE data, fix any deficiencies, and create an HDF5 library:
.. code-block:: sh
openmc-get-nndc-data
At this point, you should set the :envvar:`OPENMC_CROSS_SECTIONS` environment
variable to the absolute path of the file ``nndc_hdf5/cross_sections.xml``. This
cross section set is used by the test suite.
Using JEFF Cross Sections from OECD/NEA
---------------------------------------
The NEA_ provides processed ACE data from the JEFF_ library. To use this data
with OpenMC, the :ref:`scripts_jeff` script can be used to automatically
download and extract the ACE data, fix any deficiencies, and create an HDF5
library.
.. code-block:: sh
openmc-get-jeff-data
At this point, you should set the :envvar:`OPENMC_CROSS_SECTIONS` environment
variable to the absolute path of the file ``jeff-3.2-hdf5/cross_sections.xml``.
Using Cross Sections from MCNP
------------------------------
OpenMC provides two scripts (:ref:`scripts_mcnp70` and :ref:`scripts_mcnp71`)
that will automatically convert ENDF/B-VII.0 and ENDF/B-VII.1 ACE data that is
provided with MCNP5 or MCNP6. To convert the ENDF/B-VII.0 ACE files
(``endf70[a-k]`` and ``endf70sab``) into the native HDF5 format, run the
following:
.. code-block:: sh
openmc-convert-mcnp70-data /path/to/mcnpdata/
where ``/path/to/mcnpdata`` is the directory containing the ``endf70[a-k]``
files.
To convert the ENDF/B-VII.1 ACE files (the endf71x and ENDF71SaB libraries), use
the following script:
.. code-block:: sh
openmc-convert-mcnp71-data /path/to/mcnpdata
where ``/path/to/mcnpdata`` is the directory containing the ``endf71x`` and
``ENDF71SaB`` directories.
.. _other_cross_sections:
Using Other Cross Sections
--------------------------
If you have a library of ACE format cross sections other than those listed above
that you need to convert to OpenMC's HDF5 format, the :ref:`scripts_ace` script
can be used. There are four different ways you can specify ACE libraries that
are to be converted:
1. List each ACE library as a positional argument. This is very useful in
conjunction with the usual shell utilities (ls, find, etc.).
2. Use the ``--xml`` option to specify a pre-v0.9 cross_sections.xml file.
3. Use the ``--xsdir`` option to specify a MCNP xsdir file.
4. Use the ``--xsdata`` option to specify a Serpent xsdata file.
The script does not use any extra information from cross_sections.xml/ xsdir/
xsdata files to determine whether the nuclide is metastable. Instead, the
``--metastable`` argument can be used to specify whether the ZAID naming
convention follows the NNDC data convention (1000*Z + A + 300 + 100*m), or the
MCNP data convention (essentially the same as NNDC, except that the first
metastable state of Am242 is 95242 and the ground state is 95642).
Various evaluated nuclear data libraries have been processed into the HDF5
format required by OpenMC and can be found at https://openmc.mcs.anl.gov. 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 set your
:envvar:`OPENMC_CROSS_SECTIONS` environment variable to the absolute path of
the ``cross_sections.xml`` file contained in the unpacked directory.
.. _create_xs_library:
@ -201,7 +133,7 @@ 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
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')
@ -235,8 +167,10 @@ 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. To add the 0 K elastic scattering cross section to existing
:class:`IncidentNeutron` instance, you can use the
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::
@ -260,21 +194,15 @@ Photon interaction data is needed to run OpenMC with photon transport enabled.
Some of this data, namely bremsstrahlung cross sections from `Seltzer and
Berger`_, stopping powers 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
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. By default, the :ref:`scripts_nndc` script will download
the ENDF data in addition to the neutron and thermal scattering data, extract
it, combine it with the data from other sources, and convert it to an HDF5
library. Alternatively, the :ref:`scripts_photon` script can be used to
download the photon data on its own and create the HDF5 library:
ENDF/B-VII.1 library.
.. code-block:: sh
openmc-get-photon-data
As with neutrons and thermal scattering, 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
Most of the pregenerated HDF5 libraries available at https://openmc.mcs.anl.gov
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:
@ -285,7 +213,7 @@ data to an HDF5 file:
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 the case, both the photo-atomic and atomic
photon data from an ENDF file. In this case, both the photo-atomic and atomic
relaxation sublibrary files are required:
::
@ -308,6 +236,11 @@ 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.mcs.anl.gov/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.
--------------------------
Multi-Group Cross Sections
--------------------------
@ -322,13 +255,13 @@ to the absolute path of the file library expected to used most frequently.
For an example of how to create a multi-group library, see
:ref:`notebook_mg_mode_part_i`.
.. _NJOY: https://njoy.github.io/NJOY2016/
.. _NNDC: http://www.nndc.bnl.gov/endf/b7.1/acefiles.html
.. _NEA: http://www.oecd-nea.org
.. _JEFF: https://www.oecd-nea.org/dbforms/data/eva/evatapes/jeff_32/
.. _MCNP: http://mcnp.lanl.gov
.. _NJOY: http://www.njoy21.io/
.. _NNDC: https://www.nndc.bnl.gov/endf
.. _MCNP: https://mcnp.lanl.gov
.. _Serpent: http://montecarlo.vtt.fi
.. _TENDL: https://tendl.web.psi.ch/tendl_2015/tendl2015.html
.. _Seltzer and Berger: https://www.sciencedirect.com/science/article/pii/0092640X86900148?via%3Dihub
.. _ENDF/B: https://www.nndc.bnl.gov/endf/b7.1/acefiles.html
.. _JEFF: http://www.oecd-nea.org/dbdata/jeff/jeff33/
.. _TENDL: https://tendl.web.psi.ch/tendl_2017/tendl2017.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://www.sciencedirect.com/science/article/pii/0092640X75900303
.. _Biggs et al.: https://doi.org/10.1016/0092-640X(75)90030-3

View file

@ -167,7 +167,7 @@ Prerequisites
<https://svalinn.github.io/DAGMC/install/dag_multiple.html>`_). For use in
OpenMC, only the ``MOAB_DIR`` and ``BUILD_TALLY`` variables need to be
specified in the CMake configuration step.
|
* git_ version control software for obtaining source code
@ -478,10 +478,6 @@ as for OpenMC.
The Python VTK bindings are needed to convert voxel and track files to VTK
format.
`silomesh <https://github.com/nhorelik/silomesh>`_
The silomesh package is needed to convert voxel and track files to SILO
format.
`pytest <https://docs.pytest.org>`_
The pytest framework is used for unit testing the Python API.

View file

@ -125,10 +125,10 @@ can subsequently be converted into a standard mesh format that can be viewed in
`ParaView <http://www.paraview.org/>`_, `VisIt
<https://wci.llnl.gov/simulation/computer-codes/visit>`_, etc. This typically
will compress the size of the file significantly. The provided
:ref:`scripts_voxel` script can convert the HDF5 voxel file to VTK or SILO
formats. Once processed into a standard 3D file format, colors and masks can be
defined using the stored ID numbers to better explore the geometry. The process
for doing this will depend on the 3D viewer, but should be straightforward.
:ref:`scripts_voxel` script can convert the HDF5 voxel file to VTK formats. Once
processed into a standard 3D file format, colors and masks can be defined using
the stored ID numbers to better explore the geometry. The process for doing this
will depend on the 3D viewer, but should be straightforward.
.. note:: 3D voxel plotting can be very computer intensive for the viewing
program (Visit, ParaView, etc.) if the number of voxels is large (>10

View file

@ -95,94 +95,6 @@ otherwise.
--fission_energy_release FISSION_ENERGY_RELEASE
HDF5 file containing fission energy release data
.. _scripts_mcnp70:
------------------------------
``openmc-convert-mcnp70-data``
------------------------------
This script converts ENDF/B-VII.0 ACE data from the MCNP5/6 distribution into an
HDF5 library that can be used by OpenMC. This assumes that you have a directory
containing files named endf70a, endf70b, ..., endf70k, and endf70sab. The path
to the directory containing these files should be given as a positional
argument. The following optional arguments are available:
-d DESTINATION, --destination DESTINATION
Directory to create new library in (Default: mcnp_endfb70)
.. _scripts_mcnp71:
------------------------------
``openmc-convert-mcnp71-data``
------------------------------
This script converts ENDF/B-VII.1 ACE data from the MCNP6 distribution into an
HDF5 library that can be used by OpenMC. This assumes that you have a directory
containing subdirectories 'endf71x' and 'ENDF71SaB'. The path to the directory
containing these subdirectories should be given as a positional argument. The
following optional arguments are available:
-d DESTINATION, --destination DESTINATION
Directory to create new library in (Default: mcnp_endfb71)
-f FER, --fission_energy_release FER
HDF5 file containing fission energy release data
.. _scripts_jeff:
------------------------
``openmc-get-jeff-data``
------------------------
This script downloads `JEFF 3.2 ACE data
<https://www.oecd-nea.org/dbforms/data/eva/evatapes/jeff_32/>`_ from OECD/NEA
and converts it to a multi-temperature HDF5 library for use with OpenMC. It has
the following optional arguments:
-b, --batch
Suppress standard in
-d DESTINATION, --destination DESTINATION
Directory to create new library in (default: jeff-3.2-hdf5)
.. warning:: This script will download approximately 9 GB of data. Extracting
and processing the data may require as much as 40 GB of additional
free disk space.
.. _scripts_nndc:
------------------------
``openmc-get-nndc-data``
------------------------
This script downloads `ENDF/B-VII.1
<http://www.nndc.bnl.gov/endf/b7.1/acefiles.html>`_ incident neutron ACE data
and incident photon ENDF data from NNDC and converts it to an HDF5 library for
use with OpenMC. This script has the following optional arguments:
-b, --batch
Suppress standard in
-n, --neutron_only
Whether to exclude photon interaction/atomic data
.. _scripts_photon:
--------------------------
``openmc-get-photon-data``
--------------------------
This script downloads `ENDF data <http://www.nndc.bnl.gov/endf/b7.1/zips/>`_
from NNDC for photo-atomic and atomic relaxation sublibraries and converts it
to an HDF5 library for use with photon transport in OpenMC. This script has the
following optional arguments:
-b, --batch
Suppress standard in
-c, --cross-sections
cross_sections.xml file to append libraries to
.. _scripts_compton:
-----------------------
@ -294,24 +206,21 @@ Message Description
.. _scripts_voxel:
---------------------------
``openmc-voxel-to-silovtk``
``openmc-voxel-to-vtk``
---------------------------
When OpenMC generates :ref:`voxel plots <usersguide_voxel>`, they are in an
:ref:`HDF5 format <io_voxel>` that is not terribly useful by itself. The
``openmc-voxel-to-silovtk`` script converts a voxel HDF5 file to `VTK
<http://www.vtk.org/>`_ or `SILO
<https://wci.llnl.gov/simulation/computer-codes/silo>`_ file. For VTK, you need
to have the VTK Python bindings installed. For SILO, you need to have `silomesh
<https://github.com/nhorelik/silomesh>`_ installed. To convert a voxel file,
simply provide the path to the file:
``openmc-voxel-to-vtk`` script converts a voxel HDF5 file to a `VTK
<http://www.vtk.org/>`_ file. To run this script, you will need to have the VTK
Python bindings installed. To convert a voxel file, simply provide the path to
the file:
.. code-block:: sh
openmc-voxel-to-silovtk voxel_1.h5
openmc-voxel-to-vtk voxel_1.h5
The ``openmc-voxel-to-silovtk`` script also takes the following optional
The ``openmc-voxel-to-vtk`` script also takes the following optional
command-line arguments:
-o, --output Path to output VTK or SILO file
-s, --silo Flag to convert to SILO instead of VTK
-o, --output Path to output VTK file

View file

@ -1,99 +0,0 @@
#!/usr/bin/env python3
import argparse
from collections import defaultdict
import glob
import os
import openmc.data
description = """
Convert ENDF/B-VIII.0 ACE data from LANL into an HDF5 library
that can be used by OpenMC. This assumes that you have a directory containing
subdirectories 'Lib80x' and 'ENDF80SaB'.
"""
class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter,
argparse.RawDescriptionHelpFormatter):
pass
parser = argparse.ArgumentParser(
description=description,
formatter_class=CustomFormatter
)
parser.add_argument('-o', '--output_dir', default='lib80x_hdf5',
help='Directory to create new library in')
parser.add_argument('--libver', choices=['earliest', 'latest'],
default='earliest', help="Output HDF5 versioning. Use "
"'earliest' for backwards compatibility or 'latest' for "
"performance")
parser.add_argument('--datadir', help='Directory containing Lib80x and ENDF80SaB',
default=os.curdir)
args = parser.parse_args()
assert os.path.isdir(args.datadir)
# Get a list of all ACE files
lib80x = glob.glob(os.path.join(args.datadir, 'Lib80x', '**', '*.80?nc'), recursive=True)
lib80sab = glob.glob(os.path.join(args.datadir, 'ENDF80SaB', '**', '*.??t'), recursive=True)
# Find and fix B10 ACE files
b10files = glob.glob(os.path.join(args.datadir, 'Lib80x', '**', '5010.80?nc'), recursive=True)
nxs1_position = 523
for filename in b10files:
with open(filename, 'r+') as fh:
# Read NXS(1)
fh.seek(nxs1_position)
nxs1 = int(fh.read(5))
# Increase length to match actual length of XSS, but make sure this
# isn't done twice by checking the current length
if nxs1 < 86870:
fh.seek(nxs1_position)
fh.write(str(nxs1 + 53))
# Group together tables for the same nuclide
suffixes = defaultdict(list)
for filename in sorted(lib80x + lib80sab):
dirname, basename = os.path.split(filename)
zaid, xs = basename.split('.')
suffixes[os.path.join(dirname, zaid)].append(xs)
# Create output directory if it doesn't exist
if not os.path.isdir(args.output_dir):
os.mkdir(args.output_dir)
library = openmc.data.DataLibrary()
for basename, xs_list in sorted(suffixes.items()):
# Convert first temperature for the table
filename = '.'.join((basename, xs_list[0]))
print('Converting: ' + filename)
if filename.endswith('t'):
data = openmc.data.ThermalScattering.from_ace(filename)
else:
data = openmc.data.IncidentNeutron.from_ace(filename, 'mcnp')
# For each higher temperature, add cross sections to the existing table
for xs in xs_list[1:]:
filename = '.'.join((basename, xs))
print('Adding: ' + filename)
if filename.endswith('t'):
data.add_temperature_from_ace(filename)
else:
data.add_temperature_from_ace(filename, 'mcnp')
# Export HDF5 file
h5_file = os.path.join(args.output_dir, data.name + '.h5')
print('Writing {}...'.format(h5_file))
data.export_to_hdf5(h5_file, 'w', libver=args.libver)
# Register with library
library.register_file(h5_file)
# Write cross_sections.xml
libpath = os.path.join(args.output_dir, 'cross_sections.xml')
library.export_to_xml(libpath)

View file

@ -1,104 +0,0 @@
#!/usr/bin/env python3
import argparse
from collections import defaultdict
import glob
import os
import openmc.data
description = """
Convert ENDF/B-VII.0 ACE data from the MCNP5/6 distribution into an HDF5 library
that can be used by OpenMC. This assumes that you have a directory containing
files named endf70a, endf70b, ..., endf70k, and endf70sab.
"""
class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter,
argparse.RawDescriptionHelpFormatter):
pass
parser = argparse.ArgumentParser(
description=description,
formatter_class=CustomFormatter
)
parser.add_argument('-d', '--destination', default='mcnp_endfb70',
help='Directory to create new library in')
parser.add_argument('--libver', choices=['earliest', 'latest'],
default='earliest', help="Output HDF5 versioning. Use "
"'earliest' for backwards compatibility or 'latest' for "
"performance")
parser.add_argument('mcnpdata', help='Directory containing endf70[a-k] and endf70sab')
args = parser.parse_args()
assert os.path.isdir(args.mcnpdata)
# Get a list of all neutron ACE files
endf70 = glob.glob(os.path.join(args.mcnpdata, 'endf70[a-k]'))
# Create output directory if it doesn't exist
if not os.path.isdir(args.destination):
os.mkdir(args.destination)
library = openmc.data.DataLibrary()
for path in sorted(endf70):
print('Loading data from {}...'.format(path))
lib = openmc.data.ace.Library(path)
# Group together tables for the same nuclide
tables = defaultdict(list)
for table in lib.tables:
zaid, xs = table.name.split('.')
tables[zaid].append(table)
for zaid, tables in sorted(tables.items()):
# Convert first temperature for the table
print('Converting: ' + tables[0].name)
data = openmc.data.IncidentNeutron.from_ace(tables[0], 'mcnp')
# For each higher temperature, add cross sections to the existing table
for table in tables[1:]:
print('Adding: ' + table.name)
data.add_temperature_from_ace(table, 'mcnp')
# Export HDF5 file
h5_file = os.path.join(args.destination, data.name + '.h5')
print('Writing {}...'.format(h5_file))
data.export_to_hdf5(h5_file, 'w', libver=args.libver)
# Register with library
library.register_file(h5_file)
# Handle S(a,b) tables
endf70sab = os.path.join(args.mcnpdata, 'endf70sab')
if os.path.exists(endf70sab):
lib = openmc.data.ace.Library(endf70sab)
# Group together tables for the same nuclide
tables = defaultdict(list)
for table in lib.tables:
name, xs = table.name.split('.')
tables[name].append(table)
for zaid, tables in sorted(tables.items()):
# Convert first temperature for the table
print('Converting: ' + tables[0].name)
data = openmc.data.ThermalScattering.from_ace(tables[0])
# For each higher temperature, add cross sections to the existing table
for table in tables[1:]:
print('Adding: ' + table.name)
data.add_temperature_from_ace(table)
# Export HDF5 file
h5_file = os.path.join(args.destination, data.name + '.h5')
print('Writing {}...'.format(h5_file))
data.export_to_hdf5(h5_file, 'w', libver=args.libver)
# Register with library
library.register_file(h5_file)
# Write cross_sections.xml
libpath = os.path.join(args.destination, 'cross_sections.xml')
library.export_to_xml(libpath)

View file

@ -1,84 +0,0 @@
#!/usr/bin/env python3
import argparse
from collections import defaultdict
import glob
import os
import openmc.data
description = """
Convert ENDF/B-VII.1 ACE data from the MCNP6 distribution into an HDF5 library
that can be used by OpenMC. This assumes that you have a directory containing
subdirectories 'endf71x' and 'ENDF71SaB'.
"""
class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter,
argparse.RawDescriptionHelpFormatter):
pass
parser = argparse.ArgumentParser(
description=description,
formatter_class=CustomFormatter
)
parser.add_argument('-d', '--destination', default='mcnp_endfb71',
help='Directory to create new library in')
parser.add_argument('--libver', choices=['earliest', 'latest'],
default='earliest', help="Output HDF5 versioning. Use "
"'earliest' for backwards compatibility or 'latest' for "
"performance")
parser.add_argument('mcnpdata', help='Directory containing endf71x and ENDF71SaB')
args = parser.parse_args()
assert os.path.isdir(args.mcnpdata)
# Get a list of all ACE files
endf71x = glob.glob(os.path.join(args.mcnpdata, 'endf71x', '*', '*.71?nc'))
endf71sab = glob.glob(os.path.join(args.mcnpdata, 'ENDF71SaB' , '*.2?t'))
# There's a bug in H-Zr at 1200 K
endf71sab.remove(os.path.join(args.mcnpdata, 'ENDF71SaB' , 'h-zr.27t'))
# Group together tables for the same nuclide
suffixes = defaultdict(list)
for filename in sorted(endf71x + endf71sab):
dirname, basename = os.path.split(filename)
zaid, xs = basename.split('.')
suffixes[os.path.join(dirname, zaid)].append(xs)
# Create output directory if it doesn't exist
if not os.path.isdir(args.destination):
os.mkdir(args.destination)
library = openmc.data.DataLibrary()
for basename, xs_list in sorted(suffixes.items()):
# Convert first temperature for the table
filename = '.'.join((basename, xs_list[0]))
print('Converting: ' + filename)
if filename.endswith('t'):
data = openmc.data.ThermalScattering.from_ace(filename)
else:
data = openmc.data.IncidentNeutron.from_ace(filename, 'mcnp')
# For each higher temperature, add cross sections to the existing table
for xs in xs_list[1:]:
filename = '.'.join((basename, xs))
print('Adding: ' + filename)
if filename.endswith('t'):
data.add_temperature_from_ace(filename)
else:
data.add_temperature_from_ace(filename, 'mcnp')
# Export HDF5 file
h5_file = os.path.join(args.destination, data.name + '.h5')
print('Writing {}...'.format(h5_file))
data.export_to_hdf5(h5_file, 'w', libver=args.libver)
# Register with library
library.register_file(h5_file)
# Write cross_sections.xml
libpath = os.path.join(args.destination, 'cross_sections.xml')
library.export_to_xml(libpath)

View file

@ -1,233 +0,0 @@
#!/usr/bin/env python3
import os
from collections import defaultdict
import sys
import tarfile
import zipfile
import glob
import argparse
from string import digits
from urllib.request import urlopen
import openmc.data
description = """
Download JEFF 3.2 ACE data from OECD/NEA and convert it to a multi-temperature
HDF5 library for use with OpenMC.
"""
download_warning = """
WARNING: This script will download approximately 9 GB of data. Extracting and
processing the data may require as much as 40 GB of additional free disk
space. Note that if you don't need all 11 temperatures, you can modify the
'files' list in the script to download only the data you want.
Are you sure you want to continue? ([y]/n)
"""
class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter,
argparse.RawDescriptionHelpFormatter):
pass
parser = argparse.ArgumentParser(
description=description,
formatter_class=CustomFormatter
)
parser.add_argument('-b', '--batch', action='store_true',
help='supresses standard in')
parser.add_argument('-d', '--destination', default='jeff-3.2-hdf5',
help='Directory to create new library in')
parser.add_argument('--libver', choices=['earliest', 'latest'],
default='latest', help="Output HDF5 versioning. Use "
"'earliest' for backwards compatibility or 'latest' for "
"performance")
args = parser.parse_args()
response = input(download_warning) if not args.batch else 'y'
if response.lower().startswith('n'):
sys.exit()
base_url = 'https://www.oecd-nea.org/dbforms/data/eva/evatapes/jeff_32/Processed/'
files = ['JEFF32-ACE-293K.tar.gz',
'JEFF32-ACE-400K.tar.gz',
'JEFF32-ACE-500K.tar.gz',
'JEFF32-ACE-600K.tar.gz',
'JEFF32-ACE-700K.tar.gz',
'JEFF32-ACE-800K.zip',
'JEFF32-ACE-900K.tar.gz',
'JEFF32-ACE-1000K.tar.gz',
'JEFF32-ACE-1200K.tar.gz',
'JEFF32-ACE-1500K.tar.gz',
'JEFF32-ACE-1800K.tar.gz',
'TSLs.tar.gz']
block_size = 16384
# ==============================================================================
# DOWNLOAD FILES FROM OECD SITE
files_complete = []
for f in files:
# Establish connection to URL
url = base_url + f
req = urlopen(url)
# Get file size from header
if sys.version_info[0] < 3:
file_size = int(req.info().getheaders('Content-Length')[0])
else:
file_size = req.length
downloaded = 0
# Check if file already downloaded
if os.path.exists(f):
if os.path.getsize(f) == file_size:
print('Skipping {}, already downloaded'.format(f))
files_complete.append(f)
continue
else:
overwrite = input('Overwrite {}? ([y]/n) '.format(f))
if overwrite.lower().startswith('n'):
continue
# Copy file to disk
print('Downloading {}... '.format(f), end='')
with open(f, 'wb') as fh:
while True:
chunk = req.read(block_size)
if not chunk: break
fh.write(chunk)
downloaded += len(chunk)
status = '{:10} [{:3.2f}%]'.format(downloaded, downloaded * 100. / file_size)
print(status + chr(8)*len(status), end='')
print('')
files_complete.append(f)
# ==============================================================================
# EXTRACT FILES FROM TGZ
for f in files:
if f not in files_complete:
continue
# Extract files
if f.endswith('.zip'):
with zipfile.ZipFile(f, 'r') as zipf:
print('Extracting {}...'.format(f))
zipf.extractall('jeff-3.2')
else:
suffix = 'ACEs_293K' if '293' in f else ''
with tarfile.open(f, 'r') as tgz:
print('Extracting {}...'.format(f))
tgz.extractall(os.path.join('jeff-3.2', suffix))
# Remove thermal scattering tables from 293K data since they are
# redundant
if '293' in f:
for path in glob.glob(os.path.join('jeff-3.2', 'ACEs_293K', '*-293.ACE')):
os.remove(path)
# ==============================================================================
# CHANGE ZAID FOR METASTABLES
metastables = glob.glob(os.path.join('jeff-3.2', '**', '*M.ACE'))
for path in metastables:
print(' Fixing {} (ensure metastable)...'.format(path))
text = open(path, 'r').read()
mass_first_digit = int(text[3])
if mass_first_digit <= 2:
text = text[:3] + str(mass_first_digit + 4) + text[4:]
open(path, 'w').write(text)
# ==============================================================================
# GENERATE HDF5 LIBRARY -- NEUTRON FILES
# Get a list of all ACE files
neutron_files = glob.glob(os.path.join('jeff-3.2', '*', '*.ACE'))
# Group together tables for same nuclide
tables = defaultdict(list)
for filename in sorted(neutron_files):
dirname, basename = os.path.split(filename)
name = basename.split('.')[0]
tables[name].append(filename)
# Sort temperatures from lowest to highest
for name, filenames in sorted(tables.items()):
filenames.sort(key=lambda x: int(
x.split(os.path.sep)[1].split('_')[1][:-1]))
# Create output directory if it doesn't exist
if not os.path.isdir(args.destination):
os.mkdir(args.destination)
library = openmc.data.DataLibrary()
for name, filenames in sorted(tables.items()):
# Convert first temperature for the table
print('Converting: ' + filenames[0])
data = openmc.data.IncidentNeutron.from_ace(filenames[0])
# For each higher temperature, add cross sections to the existing table
for filename in filenames[1:]:
print('Adding: ' + filename)
data.add_temperature_from_ace(filename)
# Export HDF5 file
h5_file = os.path.join(args.destination, data.name + '.h5')
print('Writing {}...'.format(h5_file))
data.export_to_hdf5(h5_file, 'w', libver=args.libver)
# Register with library
library.register_file(h5_file)
# ==============================================================================
# GENERATE HDF5 LIBRARY -- S(A,B) FILES
sab_files = glob.glob(os.path.join('jeff-3.2', 'ANNEX_6_3_STLs', '*', '*.ace'))
# Group together tables for same nuclide
tables = defaultdict(list)
for filename in sorted(sab_files):
dirname, basename = os.path.split(filename)
name = basename.split('-')[0]
tables[name].append(filename)
# Sort temperatures from lowest to highest
for name, filenames in sorted(tables.items()):
filenames.sort(key=lambda x: int(
os.path.split(x)[1].split('-')[1].split('.')[0]))
for name, filenames in sorted(tables.items()):
# Convert first temperature for the table
print('Converting: ' + filenames[0])
# Take numbers out of table name, e.g. lw10.32t -> lw.32t
table = openmc.data.ace.get_table(filenames[0])
name, xs = table.name.split('.')
table.name = '.'.join((name.strip(digits), xs))
data = openmc.data.ThermalScattering.from_ace(table)
# For each higher temperature, add cross sections to the existing table
for filename in filenames[1:]:
print('Adding: ' + filename)
table = openmc.data.ace.get_table(filename)
name, xs = table.name.split('.')
table.name = '.'.join((name.strip(digits), xs))
data.add_temperature_from_ace(table)
# Export HDF5 file
h5_file = os.path.join(args.destination, data.name + '.h5')
print('Writing {}...'.format(h5_file))
data.export_to_hdf5(h5_file, 'w', libver=args.libver)
# Register with library
library.register_file(h5_file)
# Write cross_sections.xml
libpath = os.path.join(args.destination, 'cross_sections.xml')
library.export_to_xml(libpath)

View file

@ -1,163 +0,0 @@
#!/usr/bin/env python
"""
Download ENDF/B-VII.1 incident neutron ACE data and incident photon ENDF data
from NNDC and convert it to an HDF5 library for use with OpenMC. This data is
used for OpenMC's regression test suite.
"""
import os
import shutil
import subprocess
import sys
import tarfile
import glob
import hashlib
import argparse
from urllib.request import urlopen
import openmc.data
class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter,
argparse.RawDescriptionHelpFormatter):
pass
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=CustomFormatter
)
parser.add_argument('-b', '--batch', action='store_true',
help='supresses standard in')
parser.add_argument('-n', '--neutron-only', action='store_true',
help='Whether to exclude photon interaction/atomic data')
parser.add_argument('--libver', choices=['earliest', 'latest'],
default='earliest', help="Output HDF5 versioning. Use "
"'earliest' for backwards compatibility or 'latest' for "
"performance")
args = parser.parse_args()
base_url = 'http://www.nndc.bnl.gov/endf/b7.1/aceFiles/'
files = ['ENDF-B-VII.1-neutron-293.6K.tar.gz',
'ENDF-B-VII.1-tsl.tar.gz']
checksums = ['9729a17eb62b75f285d8a7628ace1449',
'e17d827c92940a30f22f096d910ea186']
block_size = 16384
# ==============================================================================
# DOWNLOAD FILES FROM NNDC SITE
files_complete = []
for f in files:
# Establish connection to URL
url = base_url + f
req = urlopen(url)
# Get file size from header
file_size = req.length
downloaded = 0
# Check if file already downloaded
if os.path.exists(f):
if os.path.getsize(f) == file_size:
print('Skipping ' + f)
files_complete.append(f)
continue
else:
overwrite = input('Overwrite {}? ([y]/n) '.format(f))
if overwrite.lower().startswith('n'):
continue
# Copy file to disk
print('Downloading {}... '.format(f), end='')
with open(f, 'wb') as fh:
while True:
chunk = req.read(block_size)
if not chunk: break
fh.write(chunk)
downloaded += len(chunk)
status = '{0:10} [{1:3.2f}%]'.format(
downloaded, downloaded * 100. / file_size)
print(status + chr(8)*len(status), end='')
print('')
files_complete.append(f)
# ==============================================================================
# VERIFY MD5 CHECKSUMS
print('Verifying MD5 checksums...')
for f, checksum in zip(files, checksums):
downloadsum = hashlib.md5(open(f, 'rb').read()).hexdigest()
if downloadsum != checksum:
raise IOError("MD5 checksum for {} does not match. If this is your first "
"time receiving this message, please re-run the script. "
"Otherwise, please contact OpenMC developers by emailing "
"openmc-users@googlegroups.com.".format(f))
# ==============================================================================
# EXTRACT FILES FROM TGZ
for f in files:
if f not in files_complete:
continue
# Extract files
suffix = f[f.rindex('-') + 1:].rstrip('.tar.gz')
with tarfile.open(f, 'r') as tgz:
print('Extracting {}...'.format(f))
tgz.extractall(path='nndc/' + suffix)
# Move ACE files down one level
for filename in glob.glob('nndc/293.6K/ENDF-B-VII.1-neutron-293.6K/*'):
shutil.move(filename, 'nndc/293.6K/' + os.path.basename(filename))
# ==============================================================================
# FIX ZAID ASSIGNMENTS FOR VARIOUS S(A,B) TABLES
def fix_zaid(table, old, new):
filename = os.path.join('nndc', 'tsl', table)
with open(filename, 'r') as fh:
text = fh.read()
text = text.replace(old, new, 1)
with open(filename, 'w') as fh:
fh.write(text)
print('Fixing ZAIDs for S(a,b) tables')
fix_zaid('bebeo.acer', '8016', ' 0')
fix_zaid('obeo.acer', '4009', ' 0')
# ==============================================================================
# PROMPT USER TO DELETE .TAR.GZ FILES
# Ask user to delete
if not args.batch:
response = input('Delete *.tar.gz files? ([y]/n) ')
else:
response = 'y'
# Delete files if requested
if not response or response.lower().startswith('y'):
for f in files:
if os.path.exists(f):
print('Removing {}...'.format(f))
os.remove(f)
# ==============================================================================
# GENERATE HDF5 LIBRARY
# get a list of all ACE files
ace_files = sorted(glob.glob(os.path.join('nndc', '**', '*.ace*')))
# Call the ace-to-hdf5 conversion script
pwd = os.path.dirname(os.path.realpath(__file__))
ace2hdf5 = os.path.join(pwd, 'openmc-ace-to-hdf5')
subprocess.call([ace2hdf5,
'-d', 'nndc_hdf5',
'--libver', args.libver] + ace_files)
# Generate photo interaction library files
if not args.neutron_only:
pwd = os.path.dirname(os.path.realpath(__file__))
photo_endf = os.path.join(pwd, 'openmc-get-photon-data')
subprocess.call([photo_endf, '-c', 'cross_sections.xml'],
cwd='nndc_hdf5')