SCALE Multigroup Cross Section Reader

This example demonstrates how to read SCALE multigroup cross section libraries. This functionality relies on AMPX modules for creating text dumps of COVERX formatted libraries. More details are given here: Multigroup SCALE XS Library Reader.

A Disclaimer

The COVERX formatted cross section library referenced in this example dummy_56_v7.1 was created with AMPX using ExSite and publicly available cross section data from ENDF VII.1. This library is NOT intended for use in simulations, and only contains a small subset of nuclides and reactions. This library is included purely for demonstration purposes, and when using functionality in this package that requires nuclear data, please use the provided SCALE libraries.

Reading Multigroup Cross Sections

The following code snippet demonstrates how to read a SCALE multigroup cross section library. The function tsunami_ip_utils.xs.read_multigroup_xs() is used to read COVER formatted SCALE cross section libraries, and takes a pathlib.Path object to the multigroup library, and a dictionary of nuclide-reaction pairs to read. The function returns a nested dictionary of numpy.ndarray objects, where the outer dictionary keys are nuclides, and the inner dictionary keys are reactions. The values are the multigroup cross sections for the corresponding nuclide-reaction pair.

from tsunami_ip_utils.xs import read_multigroup_xs
from paths import EXAMPLES

nuclide_reaction_dict = {'92235': ['1', '18'], '5011': ['1', '27'], '94239': ['1', '18']}
multigroup_library_path = EXAMPLES / 'data' / 'dummy_56_v7.1'
out = read_multigroup_xs(multigroup_library_path, nuclide_reaction_dict)
print(len(out['92235']['1']))
56

This function is parallel, and reads cross section libraries on multiple cores, which can be useful for large libraries. This function isn’t the most user-friendly, and requires the user to input a nuclide_reaction_dict in terms of nuclide ZAID and reaction MT numbers, but it is primarily used by the tsunami_ip_utils.perturbations module for reading cross sections for perturbation calculations.

Caching a Multigroup Cross Section Library

If working with python-based applications that deal with SCALE multigroup cross section data, it may be useful to cache the cross section libary in a convenient format for reading into python, like a .pkl file. To avoid having to manually supply the list of all nuclides and reactions in the multigroup library, the tsunami_ip_utils.xs.read_multigroup_xs() function can be run with the return_available_nuclide_reactions flag set to True. This will return a dictionary of all nuclides and reactions in the library, which can then be used to read the library and cache it.

out, available_nuclide_reactions = read_multigroup_xs(
    multigroup_library_path,
    nuclide_reaction_dict,
    return_available_nuclide_reactions=True
)
print(available_nuclide_reactions)
{'5011': ['1099', '3099', '2', '4', '16', '22', '28', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '91', '102', '103', '105', '107', '1', '3002', '3102', '101', '27', '3', '1007'], '92235': ['1099', '3099', '2', '3', '4', '16', '17', '18', '1452', '452', '1456', '456', '1455', '455', '19', '1419', '4561', '20', '1420', '4562', '21', '1421', '4563', '37', '38', '1438', '4564', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '102', '1', '3002', '3018', '3102', '101', '27', '1018', '1056', '1055', '1019', '1020', '1021', '1038', '1007'], '94239': ['1099', '3099', '2', '3', '4', '16', '17', '18', '1452', '452', '1456', '456', '1455', '455', '19', '1419', '4561', '20', '1420', '4562', '21', '1421', '4563', '37', '38', '1438', '4564', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '102', '1', '3002', '3018', '3102', '101', '27', '1018', '1056', '1055', '1019', '1020', '1021', '1038', '1007']}

The list of all available nuclide reactions can then be supplied to the function to read the entire library.

out = read_multigroup_xs(multigroup_library_path, available_nuclide_reactions)

And the cross sections can be easily cached

import pickle

with open(EXAMPLES / 'data' / 'dummy_56_v7.1.pkl', 'wb') as f:
    pickle.dump(out, f)

Getting the Energy Structure

By default the reader doesn’t return the energy group structure (this is something that could be improved in the future), but if you’re examining SCALE built-in cross section libraries, the energy group structure can be obtained from the tsunami_ip_utils.xs.get_scale_multigroup_structure() function. This function scrapes the SCALE manual for the energy group structure of a given SCALE library.

from tsunami_ip_utils.xs import get_scale_multigroup_structure

num_groups = 56
multigroup_structure = get_scale_multigroup_structure(num_groups)

print(multigroup_structure)
[[5.600e+01 4.000e-03]
 [5.500e+01 1.000e-02]
 [5.400e+01 2.530e-02]
 [5.300e+01 4.000e-02]
 [5.200e+01 5.000e-02]
 [5.100e+01 6.000e-02]
 [5.000e+01 8.000e-02]
 [4.900e+01 1.000e-01]
 [4.800e+01 1.500e-01]
 [4.700e+01 2.000e-01]
 [4.600e+01 2.500e-01]
 [4.500e+01 3.250e-01]
 [4.400e+01 3.500e-01]
 [4.300e+01 3.750e-01]
 [4.200e+01 4.500e-01]
 [4.100e+01 6.250e-01]
 [4.000e+01 1.010e+00]
 [3.900e+01 1.080e+00]
 [3.800e+01 1.130e+00]
 [3.700e+01 5.000e+00]
 [3.600e+01 6.250e+00]
 [3.500e+01 6.500e+00]
 [3.400e+01 6.875e+00]
 [3.300e+01 7.000e+00]
 [3.200e+01 2.050e+01]
 [3.100e+01 2.120e+01]
 [3.000e+01 2.175e+01]
 [2.900e+01 3.600e+01]
 [2.800e+01 3.713e+01]
 [2.700e+01 6.500e+01]
 [2.600e+01 6.750e+01]
 [2.500e+01 1.012e+02]
 [2.400e+01 1.050e+02]
 [2.300e+01 1.160e+02]
 [2.200e+01 1.175e+02]
 [2.100e+01 1.877e+02]
 [2.000e+01 1.915e+02]
 [1.900e+01 2.250e+03]
 [1.800e+01 3.740e+03]
 [1.700e+01 1.700e+04]
 [1.600e+01 2.000e+04]
 [1.500e+01 5.000e+04]
 [1.400e+01 2.000e+05]
 [1.300e+01 2.700e+05]
 [1.200e+01 3.300e+05]
 [1.100e+01 4.700e+05]
 [1.000e+01 6.000e+05]
 [9.000e+00 7.500e+05]
 [8.000e+00 8.611e+05]
 [7.000e+00 1.200e+06]
 [6.000e+00 1.500e+06]
 [5.000e+00 1.850e+06]
 [4.000e+00 3.000e+06]
 [3.000e+00 4.304e+06]
 [2.000e+00 6.434e+06]
 [1.000e+00 2.000e+07]]

We can easily plot cross section data using the energy group structure. The following code snippet demonstrates how to plot the u-235 fission cross section

import matplotlib.pyplot as plt
import numpy as np

u235_fission_xs = out['92235']['18']

# To get the cross sections to be visually constant within each energy group, we need to repeat the cross sections and add in the
# implied lower energy bound of 1E-05 eV
u235_fission_xs = u235_fission_xs.repeat(2)
modified_energies = np.zeros_like(u235_fission_xs)

energies = multigroup_structure[:, 1]
modified_energies[0] = 1E-05
modified_energies[-1] = energies[-1]
modified_energies[1:] = np.repeat(energies, 2)[:-1]

plt.plot(modified_energies, u235_fission_xs)
plt.xscale('log')
plt.yscale('log')
plt.xlabel('Energy (eV)')
plt.ylabel('Cross Section (b)')
plt.grid()
plt.show()
multigroup xs reader

A Future Improvement

It is unfortunate that to cache a cross section library, the library must be read twice (the most consuming part is making the text dump again). This is a limitation of the current implementation, and may be improved in the future. To avoid this, the text dump just needs to be saved so that it can be read by the second function call. This could all be implemented by adding an additional flag to the tsunami_ip_utils.xs.read_multigroup_xs() that does this under the hood.

Total running time of the script: (0 minutes 9.919 seconds)

Gallery generated by Sphinx-Gallery