diff --git a/README.md b/README.md index 78b921b..cd4432a 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ A few categories of scripts are available: | generate_endf | ENDF/B | VII.1
VIII.0 | NNDC | | generate_fendl | FENDL | 3.2b
3.2a
3.2
3.1d
3.1a
3.0 | | | generate_jendl | JENDL | 4.0
5.0 | | +| generate_tendl | TENDL | 2023 | | ### Download cross sections diff --git a/pyproject.toml b/pyproject.toml index 01a7eb7..000c2d3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,6 +59,7 @@ generate_endf = "openmc_data.generate.generate_endf:main" generate_jeff33 = "openmc_data.generate.generate_jeff33:main" generate_jendl = "openmc_data.generate.generate_jendl:main" generate_fendl = "openmc_data.generate.generate_fendl:main" +generate_tendl = "openmc_data.generate.generate_tendl:main" generate_endf71_chain_casl = "openmc_data.depletion.generate_endf71_chain_casl:main" generate_endf_chain = "openmc_data.depletion.generate_endf_chain:main" diff --git a/src/openmc_data/generate/generate_tendl.py b/src/openmc_data/generate/generate_tendl.py new file mode 100644 index 0000000..54cc0fc --- /dev/null +++ b/src/openmc_data/generate/generate_tendl.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python3 + +""" +Download TENDL data from PSI and convert it to a HDF5 library for +use with OpenMC. +""" + +import argparse +import ssl +from multiprocessing import Pool +from pathlib import Path +from urllib.parse import urljoin + +import openmc.data +from openmc_data import download, extract, process_neutron, state_download_size, all_release_details + + +class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter, + argparse.RawDescriptionHelpFormatter): + pass + + +parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=CustomFormatter +) +parser.add_argument('-d', '--destination', type=Path, default=None, + help='Directory to create new library in') +parser.add_argument('--download', action='store_true', + help='Download files') +parser.add_argument('--no-download', dest='download', action='store_false', + help='Do not download files') +parser.add_argument('--extract', action='store_true', + help='Extract tar/zip files') +parser.add_argument('--no-extract', dest='extract', action='store_false', + help='Do not extract tar/zip files') +parser.add_argument('--libver', choices=['earliest', 'latest'], + default='latest', help="Output HDF5 versioning. Use " + "'earliest' for backwards compatibility or 'latest' for " + "performance") +parser.add_argument('-r', '--release', choices=["2023"], default="2023", + help="The nuclear data library release version. " + "The options currently supported are 2023") +parser.add_argument('--cleanup', action='store_true', + help="Remove download directories when data has " + "been processed") +parser.add_argument('--no-cleanup', dest='cleanup', action='store_false', + help="Do not remove download directories when data has " + "been processed") +parser.set_defaults(download=True, extract=True, cleanup=False) +args = parser.parse_args() + + +def main(): + + library_name = 'tendl' + + cwd = Path.cwd() + + endf_files_dir = cwd.joinpath('-'.join([library_name, args.release, 'endf'])) + download_path = cwd.joinpath('-'.join([library_name, args.release, 'download'])) + # the destination is decided after the release is known + # to avoid putting the release in a folder with a misleading name + if args.destination is None: + args.destination = Path('-'.join([library_name, args.release, 'hdf5'])) + + # This dictionary contains all the unique information about each release. + # This can be exstened to accommodated new releases + details = all_release_details[library_name][args.release]['neutron']['endf'] + + # ============================================================================== + # DOWNLOAD FILES FROM WEBSITE + + if args.download: + state_download_size(details['compressed_file_size'], details['uncompressed_file_size'], 'GB') + for f in details['compressed_files']: + # Establish connection to URL + download( + urljoin(details['base_url'], f), + context=ssl._create_unverified_context(), + output_path=download_path, + as_browser=True + ) + + # ============================================================================== + # EXTRACT FILES FROM TGZ + if args.extract: + extract( + compressed_files=[download_path/ f for f in details['compressed_files']], + extraction_dir=endf_files_dir, + del_compressed_file=args.cleanup + ) + + # ============================================================================== + # GENERATE HDF5 LIBRARY -- NEUTRON FILES + + # Get a list of all ENDF files + neutron_files = endf_files_dir.glob('*.tendl') + + # Create output directory if it doesn't exist + args.destination.mkdir(parents=True, exist_ok=True) + + library = openmc.data.DataLibrary() + + with Pool() as pool: + results = [] + for filename in sorted(neutron_files): + func_args = (filename, args.destination, args.libver) + r = pool.apply_async(process_neutron, func_args) + results.append(r) + + for r in results: + r.wait() + + # Register with library + for p in sorted((args.destination).glob('*.h5')): + library.register_file(p) + + # Write cross_sections.xml + library.export_to_xml(args.destination / 'cross_sections.xml') + + +if __name__ == '__main__': + main() diff --git a/src/openmc_data/urls.py b/src/openmc_data/urls.py index 47669ef..c87cba8 100644 --- a/src/openmc_data/urls.py +++ b/src/openmc_data/urls.py @@ -48,6 +48,18 @@ } } }, + "2023": { + "neutron": { + "endf": { + "base_url": "https://tendl.web.psi.ch/tendl_2023/tar_files/", + "compressed_files": ["TENDL-n.2024new.tgz"], + "neutron_files": "tendl24c/*", + "metastables": "tendl24c/*m", + "compressed_file_size": 3.1, + "uncompressed_file_size": 20, + } + } + }, }, "fendl": { "3.2c": {