mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 14:15:42 -04:00
Merge pull request #1165 from paulromano/data-repo
Data-related updates, reduce CI matrix
This commit is contained in:
commit
b7d4fe4b6c
13 changed files with 135 additions and 965 deletions
27
.travis.yml
27
.travis.yml
|
|
@ -1,10 +1,6 @@
|
|||
sudo: required
|
||||
dist: xenial
|
||||
language: python
|
||||
python:
|
||||
- "3.5"
|
||||
- "3.6"
|
||||
- "3.7"
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
|
|
@ -34,13 +30,22 @@ env:
|
|||
- LD_LIBRARY_PATH=$HOME/MOAB/lib:$HOME/DAGMC/lib
|
||||
- PATH=$PATH:$HOME/NJOY2016/build
|
||||
- COVERALLS_PARALLEL=true
|
||||
matrix:
|
||||
- OMP=n MPI=n PHDF5=n
|
||||
- OMP=y MPI=n PHDF5=n
|
||||
- OMP=n MPI=y PHDF5=n
|
||||
- OMP=n MPI=y PHDF5=y
|
||||
- OMP=n MPI=y PHDF5=y DAGMC=y
|
||||
- OMP=y MPI=y PHDF5=y DAGMC=y
|
||||
matrix:
|
||||
include:
|
||||
- python: "3.5"
|
||||
env: OMP=n MPI=n PHDF5=n
|
||||
- python: "3.6"
|
||||
env: OMP=n MPI=n PHDF5=n
|
||||
- python: "3.7"
|
||||
env: OMP=n MPI=n PHDF5=n
|
||||
- python: "3.7"
|
||||
env: OMP=y MPI=n PHDF5=n
|
||||
- python: "3.7"
|
||||
env: OMP=n MPI=y PHDF5=n
|
||||
- python: "3.7"
|
||||
env: OMP=n MPI=y PHDF5=y
|
||||
- python: "3.7"
|
||||
env: OMP=y MPI=y PHDF5=y DAGMC=y
|
||||
notifications:
|
||||
webhooks: https://coveralls.io/webhook?repo_token=$COVERALLS_REPO_TOKEN
|
||||
install:
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -394,8 +394,14 @@ class Evaluation(object):
|
|||
self.projectile = {}
|
||||
self.reaction_list = []
|
||||
|
||||
# Determine MAT number for this evaluation
|
||||
# Skip TPID record. Evaluators sometimes put in TPID records that are
|
||||
# ill-formated because they lack MF/MT values or put them in the wrong
|
||||
# columns.
|
||||
if fh.tell() == 0:
|
||||
fh.readline()
|
||||
MF = 0
|
||||
|
||||
# Determine MAT number for this evaluation
|
||||
while MF == 0:
|
||||
position = fh.tell()
|
||||
line = fh.readline()
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ from numbers import Real
|
|||
import itertools
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import tempfile
|
||||
from warnings import warn
|
||||
|
||||
|
|
@ -13,6 +12,7 @@ import h5py
|
|||
|
||||
import openmc.checkvalue as cv
|
||||
from openmc.mixin import EqualityMixin
|
||||
from openmc.stats import Discrete, Tabular
|
||||
from . import HDF5_VERSION, HDF5_VERSION_MAJOR
|
||||
from .data import K_BOLTZMANN, ATOMIC_SYMBOL, EV_PER_MEV, NATURAL_ABUNDANCE
|
||||
from .ace import Table, get_table, Library
|
||||
|
|
@ -20,46 +20,50 @@ from .angle_energy import AngleEnergy
|
|||
from .function import Tabulated1D
|
||||
from .correlated import CorrelatedAngleEnergy
|
||||
from .njoy import make_ace_thermal
|
||||
from openmc.stats import Discrete, Tabular
|
||||
|
||||
|
||||
_THERMAL_NAMES = {
|
||||
'c_Al27': ('al', 'al27', 'al-27'),
|
||||
'c_Be': ('be', 'be-metal', 'be-met'),
|
||||
'c_Al_in_Sapphire': ('asap00',),
|
||||
'c_Be': ('be', 'be-metal', 'be-met', 'be00'),
|
||||
'c_BeO': ('beo',),
|
||||
'c_Be_in_BeO': ('bebeo', 'be-beo', 'be-o', 'be/o'),
|
||||
'c_Be_in_BeO': ('bebeo', 'be-beo', 'be-o', 'be/o', 'bbeo00'),
|
||||
'c_C6H6': ('benz', 'c6h6'),
|
||||
'c_C_in_SiC': ('csic', 'c-sic'),
|
||||
'c_Ca_in_CaH2': ('cah',),
|
||||
'c_D_in_D2O': ('dd2o', 'd-d2o', 'hwtr', 'hw'),
|
||||
'c_Ca_in_CaH2': ('cah', 'cah00'),
|
||||
'c_D_in_D2O': ('dd2o', 'd-d2o', 'hwtr', 'hw', 'dhw00'),
|
||||
'c_Fe56': ('fe', 'fe56', 'fe-56'),
|
||||
'c_Graphite': ('graph', 'grph', 'gr'),
|
||||
'c_Graphite': ('graph', 'grph', 'gr', 'gr00'),
|
||||
'c_Graphite_10p': ('grph10',),
|
||||
'c_Graphite_30p': ('grph30',),
|
||||
'c_H_in_CaH2': ('hcah2',),
|
||||
'c_H_in_CH2': ('hch2', 'poly', 'pol', 'h-poly'),
|
||||
'c_H_in_CaH2': ('hcah2', 'hca00'),
|
||||
'c_H_in_CH2': ('hch2', 'poly', 'pol', 'h-poly', 'pol00'),
|
||||
'c_H_in_CH4_liquid': ('lch4', 'lmeth'),
|
||||
'c_H_in_CH4_solid': ('sch4', 'smeth'),
|
||||
'c_H_in_H2O': ('hh2o', 'h-h2o', 'lwtr', 'lw'),
|
||||
'c_H_in_H2O_solid': ('hice', 'h-ice'),
|
||||
'c_H_in_H2O': ('hh2o', 'h-h2o', 'lwtr', 'lw', 'lw00'),
|
||||
'c_H_in_H2O_solid': ('hice', 'h-ice', 'ice00'),
|
||||
'c_H_in_C5O2H8': ('lucite', 'c5o2h8', 'h-luci'),
|
||||
'c_H_in_Mesitylene': ('mesi00',),
|
||||
'c_H_in_Toluene': ('tol00',),
|
||||
'c_H_in_YH2': ('hyh2', 'h-yh2'),
|
||||
'c_H_in_ZrH': ('hzrh', 'h-zrh', 'h-zr', 'h/zr', 'hzr'),
|
||||
'c_Mg24': ('mg', 'mg24'),
|
||||
'c_O_in_BeO': ('obeo', 'o-beo', 'o-be', 'o/be'),
|
||||
'c_O_in_D2O': ('od2o', 'o-d2o'),
|
||||
'c_H_in_ZrH': ('hzrh', 'h-zrh', 'h-zr', 'h/zr', 'hzr', 'hzr00'),
|
||||
'c_Mg24': ('mg', 'mg24', 'mg00'),
|
||||
'c_O_in_Sapphire': ('osap00',),
|
||||
'c_O_in_BeO': ('obeo', 'o-beo', 'o-be', 'o/be', 'obeo00'),
|
||||
'c_O_in_D2O': ('od2o', 'o-d2o', 'ohw00'),
|
||||
'c_O_in_H2O_ice': ('oice', 'o-ice'),
|
||||
'c_O_in_UO2': ('ouo2', 'o-uo2', 'o2-u', 'o2/u'),
|
||||
'c_O_in_UO2': ('ouo2', 'o-uo2', 'o2-u', 'o2/u', 'ouo200'),
|
||||
'c_N_in_UN': ('n-un',),
|
||||
'c_ortho_D': ('orthod', 'orthoD', 'dortho'),
|
||||
'c_ortho_H': ('orthoh', 'orthoH', 'hortho'),
|
||||
'c_ortho_D': ('orthod', 'orthoD', 'dortho', 'od200'),
|
||||
'c_ortho_H': ('orthoh', 'orthoH', 'hortho', 'oh200'),
|
||||
'c_Si28': ('si00',),
|
||||
'c_Si_in_SiC': ('sisic', 'si-sic'),
|
||||
'c_SiO2_alpha': ('sio2', 'sio2a'),
|
||||
'c_SiO2_beta': ('sio2b',),
|
||||
'c_para_D': ('parad', 'paraD', 'dpara'),
|
||||
'c_para_H': ('parah', 'paraH', 'hpara'),
|
||||
'c_para_D': ('parad', 'paraD', 'dpara', 'pd200'),
|
||||
'c_para_H': ('parah', 'paraH', 'hpara', 'ph200'),
|
||||
'c_U_in_UN': ('u-un',),
|
||||
'c_U_in_UO2': ('uuo2', 'u-uo2', 'u-o2', 'u/o2'),
|
||||
'c_U_in_UO2': ('uuo2', 'u-uo2', 'u-o2', 'u/o2', 'uuo200'),
|
||||
'c_Y_in_YH2': ('yyh2', 'y-yh2'),
|
||||
'c_Zr_in_ZrH': ('zrzrh', 'zr-zrh', 'zr-h', 'zr/h')
|
||||
}
|
||||
|
|
@ -85,34 +89,34 @@ def get_thermal_name(name):
|
|||
for proper_name, names in _THERMAL_NAMES.items():
|
||||
if name.lower() in names:
|
||||
return proper_name
|
||||
|
||||
# Make an educated guess?? This actually works well for
|
||||
# JEFF-3.2 which stupidly uses names like lw00.32t,
|
||||
# lw01.32t, etc. for different temperatures
|
||||
|
||||
# First, construct a list of all the values/keys in the names
|
||||
# dictionary
|
||||
all_names = itertools.chain(_THERMAL_NAMES.keys(),
|
||||
*_THERMAL_NAMES.values())
|
||||
|
||||
matches = get_close_matches(name, all_names, cutoff=0.5)
|
||||
if matches:
|
||||
# Figure out the key for the corresponding match
|
||||
match = matches[0]
|
||||
if match not in _THERMAL_NAMES:
|
||||
for key, value_list in _THERMAL_NAMES.items():
|
||||
if match in value_list:
|
||||
match = key
|
||||
break
|
||||
|
||||
warn('Thermal scattering material "{}" is not recognized. '
|
||||
'Assigning a name of {}.'.format(name, match))
|
||||
return match
|
||||
else:
|
||||
# Make an educated guess?? This actually works well for
|
||||
# JEFF-3.2 which stupidly uses names like lw00.32t,
|
||||
# lw01.32t, etc. for different temperatures
|
||||
|
||||
# First, construct a list of all the values/keys in the names
|
||||
# dictionary
|
||||
all_names = itertools.chain(_THERMAL_NAMES.keys(),
|
||||
*_THERMAL_NAMES.values())
|
||||
|
||||
matches = get_close_matches(name, all_names, cutoff=0.5)
|
||||
if len(matches) > 0:
|
||||
# Figure out the key for the corresponding match
|
||||
match = matches[0]
|
||||
if match not in _THERMAL_NAMES:
|
||||
for key, value_list in _THERMAL_NAMES.items():
|
||||
if match in value_list:
|
||||
match = key
|
||||
break
|
||||
|
||||
warn('Thermal scattering material "{}" is not recognized. '
|
||||
'Assigning a name of {}.'.format(name, match))
|
||||
return match
|
||||
else:
|
||||
# OK, we give up. Just use the ACE name.
|
||||
warn('Thermal scattering material "{0}" is not recognized. '
|
||||
'Assigning a name of c_{0}.'.format(name))
|
||||
return 'c_' + name
|
||||
# OK, we give up. Just use the ACE name.
|
||||
warn('Thermal scattering material "{0}" is not recognized. '
|
||||
'Assigning a name of c_{0}.'.format(name))
|
||||
return 'c_' + name
|
||||
|
||||
|
||||
class CoherentElastic(EqualityMixin):
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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')
|
||||
Loading…
Add table
Add a link
Reference in a new issue