-
Notifications
You must be signed in to change notification settings - Fork 29
/
convert_lib80x.py
executable file
·102 lines (80 loc) · 3.09 KB
/
convert_lib80x.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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
92
93
94
95
96
97
98
99
100
101
102
#!/usr/bin/env python3
"""
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'.
"""
import argparse
from collections import defaultdict
from pathlib import Path
import sys
import openmc.data
# Make sure Python version is sufficient
assert sys.version_info >= (3, 6), "Python 3.6+ is required"
class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter,
argparse.RawDescriptionHelpFormatter):
pass
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=CustomFormatter
)
parser.add_argument('-d', '--destination', type=Path, default=Path('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', type=Path,
help='Directory containing Lib80x and ENDF80SaB/ENDF80SaB2')
args = parser.parse_args()
assert args.datadir.is_dir()
# Get a list of all ACE files
lib80x = list(args.datadir.glob('Lib80x/**/*.80?nc'))
if (args.datadir / 'ENDF80SaB2').is_dir():
thermal_dir = args.datadir / 'ENDF80SaB2'
else:
thermal_dir = args.datadir / 'ENDF80SaB'
lib80sab = list(thermal_dir.glob('**/*.??t'))
# Find and fix B10 ACE files
b10files = list(args.datadir.glob('Lib80x/**/5010.80?nc'))
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
tables = defaultdict(list)
for p in sorted(lib80x + lib80sab):
tables[p.stem].append(p)
# Create output directory if it doesn't exist
args.destination.mkdir(parents=True, exist_ok=True)
library = openmc.data.DataLibrary()
for name, paths in sorted(tables.items()):
# Convert first temperature for the table
p = paths[0]
print(f'Converting: {p}')
if p.name.endswith('t'):
data = openmc.data.ThermalScattering.from_ace(p)
else:
data = openmc.data.IncidentNeutron.from_ace(p, 'mcnp')
# For each higher temperature, add cross sections to the existing table
for p in paths[1:]:
print(f'Adding: {p}')
if p.name.endswith('t'):
data.add_temperature_from_ace(p)
else:
data.add_temperature_from_ace(p, 'mcnp')
# Export HDF5 file
h5_file = args.destination / f'{data.name}.h5'
print(f'Writing {h5_file}...')
data.export_to_hdf5(h5_file, 'w', libver=args.libver)
# Register with library
library.register_file(h5_file)
# Write cross_sections.xml
library.export_to_xml(args.destination / 'cross_sections.xml')