From 77eb53acf3ad298e192a3b9fc1ff6499073142bb Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 8 Oct 2018 14:08:38 -0500 Subject: [PATCH 01/62] Use retries: true for apt install on Travis --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0f5459734..4939f807c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,8 @@ addons: - libhdf5-mpich-dev - libblas-dev - liblapack-dev + config: + retries: true cache: directories: - $HOME/nndc_hdf5 @@ -39,7 +41,7 @@ env: - 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 + - OMP=y MPI=y PHDF5=y DAGMC=y notifications: webhooks: https://coveralls.io/webhook?repo_token=$COVERALLS_REPO_TOKEN install: From 6da03ba71a4e61872d3f8b90c033946f9a063a5e Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 31 Aug 2018 12:27:44 -0500 Subject: [PATCH 02/62] Add make-test-data script --- openmc/_utils.py | 14 +++- scripts/openmc-make-test-data | 149 ++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 1 deletion(-) create mode 100755 scripts/openmc-make-test-data diff --git a/openmc/_utils.py b/openmc/_utils.py index 83455c17a..d16f55623 100644 --- a/openmc/_utils.py +++ b/openmc/_utils.py @@ -1,3 +1,4 @@ +import hashlib import os.path from pathlib import Path from urllib.parse import urlparse @@ -6,13 +7,15 @@ from urllib.request import urlopen _BLOCK_SIZE = 16384 -def download(url): +def download(url, checksum=None): """Download file from a URL Parameters ---------- url : str URL from which to download + checksum : str or None + MD5 checksum to check against Returns ------- @@ -46,4 +49,13 @@ def download(url): downloaded, downloaded * 100. / file_size) print(status + '\b'*len(status), end='') print('') + + if checksum is not None: + downloadsum = hashlib.md5(open(basename, '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(basename)) + return basename diff --git a/scripts/openmc-make-test-data b/scripts/openmc-make-test-data new file mode 100755 index 000000000..f2ae118c1 --- /dev/null +++ b/scripts/openmc-make-test-data @@ -0,0 +1,149 @@ +#!/usr/bin/env python3 + +""" +Download ENDF/B-VII.1 ENDF and ACE files from NNDC and generate a full HDF5 +library with incident neutron, incident photon, and thermal scattering data. +This data is used for OpenMC's regression test suite. +""" + +import glob +import os +from pathlib import Path +import tarfile +import tempfile +from urllib.parse import urljoin +import zipfile + +import openmc.data +from openmc._utils import download + +base_ace = 'http://www.nndc.bnl.gov/endf/b7.1/aceFiles/' +base_endf = 'http://www.nndc.bnl.gov/endf/b7.1/zips/' +files = [ + (base_ace, 'ENDF-B-VII.1-neutron-293.6K.tar.gz', '9729a17eb62b75f285d8a7628ace1449'), + (base_ace, 'ENDF-B-VII.1-tsl.tar.gz', 'e17d827c92940a30f22f096d910ea186'), + (base_endf, 'ENDF-B-VII.1-neutrons.zip', 'e5d7f441fc4c92893322c24d1725e29c'), + (base_endf, 'ENDF-B-VII.1-photoat.zip', '5192f94e61f0b385cf536f448ffab4a4'), + (base_endf, 'ENDF-B-VII.1-atomic_relax.zip', 'fddb6035e7f2b6931e51a58fc754bd10') +] + + +def fix_zaid(table, old, new): + filename = os.path.join('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) + + +os.makedirs('nndc_hdf5/photon', exist_ok=True) + +with tempfile.TemporaryDirectory() as tmpdir: + # Save current working directory and temporarily change dir + pwd = os.getcwd() + os.chdir(tmpdir) + + # ========================================================================= + # Download files from NNDC server + for base, fname, checksum in files: + download(urljoin(base, fname), checksum) + + # ========================================================================= + # EXTRACT FILES FROM TGZ + + for _, f, _ in files: + print('Extracting {}...'.format(f)) + path = Path(f) + if path.suffix == '.gz': + with tarfile.open(f, 'r') as tgz: + if 'tsl' in f: + tgz.extractall(path='tsl') + else: + tgz.extractall() + elif path.suffix == '.zip': + zipfile.ZipFile(f).extractall() + + # ========================================================================= + # FIX ZAID ASSIGNMENTS FOR VARIOUS S(A,B) TABLES + + print('Fixing ZAIDs for S(a,b) tables') + fix_zaid('bebeo.acer', '8016', ' 0') + fix_zaid('obeo.acer', '4009', ' 0') + + library = openmc.data.DataLibrary() + + # ========================================================================= + # INCIDENT NEUTRON DATA + + neutron_files = sorted(glob.glob('ENDF-B-VII.1-neutron-293.6K/*.ace')) + for f in neutron_files: + print('Converting {}...'.format(os.path.basename(f))) + data = openmc.data.IncidentNeutron.from_ace(f) + + # Check for fission energy release data + endf_filename = 'neutrons/n-{:03}_{}_{:03}{}.endf'.format( + data.atomic_number, + data.atomic_symbol, + data.mass_number, + 'm{}'.format(data.metastable) if data.metastable else '' + ) + ev = openmc.data.endf.Evaluation(endf_filename) + if (1, 458) in ev.section: + endf_data = openmc.data.IncidentNeutron.from_endf(ev) + data.fission_energy = endf_data.fission_energy + + # Add 0K elastic scattering data for select nuclides + if data.name in ('U235', 'U238', 'Pu239'): + data.add_elastic_0K_from_endf(endf_filename) + + # Determine filename + outfile = os.path.join('nndc_hdf5', data.name + '.h5') + data.export_to_hdf5(outfile, 'w', 'earliest') + + # Register with library + library.register_file(outfile) + + # ========================================================================= + # THERMAL SCATTERING DATA + + thermal_files = sorted(glob.glob('tsl/*.acer')) + for f in thermal_files: + print('Converting {}...'.format(os.path.basename(f))) + data = openmc.data.ThermalScattering.from_ace(f) + + # Determine filename + outfile = os.path.join('nndc_hdf5', data.name + '.h5') + data.export_to_hdf5(outfile, 'w', 'earliest') + + # Register with library + library.register_file(outfile) + + # ========================================================================= + # INCIDENT PHOTON DATA + + for z in range(1, 101): + element = openmc.data.ATOMIC_SYMBOL[z] + print('Generating HDF5 file for Z={} ({})...'.format(z, element)) + + # Generate instance of IncidentPhoton + photo_file = os.path.join('photoat', 'photoat-{:03}_{}_000.endf'.format(z, element)) + atom_file = os.path.join('atomic_relax', 'atom-{:03}_{}_000.endf'.format(z, element)) + data = openmc.data.IncidentPhoton.from_endf(photo_file, atom_file) + + # Write HDF5 file and register it + outfile = os.path.join('nndc_hdf5', 'photon', element + '.h5') + data.export_to_hdf5(outfile, 'w', 'earliest') + library.register_file(outfile) + + library.export_to_xml(os.path.join('nndc_hdf5', 'cross_sections.xml')) + + # ========================================================================= + # CREATE TARBALL AND MOVE BACK + + test_tar = os.path.join(pwd, 'nndc_hdf5_test.tar.xz') + with tarfile.open(test_tar, 'w:xz') as txz: + txz.add('nndc_hdf5') + + # Change back to original directory + os.chdir(pwd) From 083d642760fc64a2dbe6937ad93558a1794658e1 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 8 Oct 2018 14:18:22 -0500 Subject: [PATCH 03/62] Add script for converting Lib80x data --- scripts/openmc-convert-lib80x-data | 99 ++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100755 scripts/openmc-convert-lib80x-data diff --git a/scripts/openmc-convert-lib80x-data b/scripts/openmc-convert-lib80x-data new file mode 100755 index 000000000..9a8acc68e --- /dev/null +++ b/scripts/openmc-convert-lib80x-data @@ -0,0 +1,99 @@ +#!/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) From 0bd34481938a45253347a706ca73472ac6d0c882 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 9 Oct 2018 16:23:42 -0500 Subject: [PATCH 04/62] Support registering a multipole library to cross_sections.xml --- openmc/data/library.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/openmc/data/library.py b/openmc/data/library.py index 8d821e49f..1a797aa53 100644 --- a/openmc/data/library.py +++ b/openmc/data/library.py @@ -53,16 +53,8 @@ class DataLibrary(EqualityMixin): """ with h5py.File(filename, 'r') as h5file: - - materials = [] - if 'filetype' in h5file.attrs: - filetype = h5file.attrs['filetype'].decode().lstrip('data_') - else: - filetype = 'neutron' - for name in h5file: - if name.startswith('c_'): - filetype = 'thermal' - materials.append(name) + filetype = h5file.attrs['filetype'].decode().lstrip('data_') + materials = list(h5file) library = {'path': filename, 'type': filetype, 'materials': materials} self.libraries.append(library) From 05e66155a2587b51460de4f9d4e04f9a50744762 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 2 Nov 2018 07:34:34 -0500 Subject: [PATCH 05/62] Support pathlib in openmc.data --- openmc/data/ace.py | 7 ++++--- openmc/data/endf.py | 2 +- openmc/data/library.py | 12 +++++++++--- openmc/data/multipole.py | 4 ++-- openmc/data/neutron.py | 4 ++-- openmc/data/njoy.py | 8 ++++---- openmc/data/photon.py | 2 +- openmc/data/thermal.py | 4 ++-- 8 files changed, 25 insertions(+), 18 deletions(-) diff --git a/openmc/data/ace.py b/openmc/data/ace.py index 41a7057ac..f44f8931c 100644 --- a/openmc/data/ace.py +++ b/openmc/data/ace.py @@ -106,7 +106,7 @@ def ascii_to_binary(ascii_file, binary_file): """ # Open ASCII file - ascii = open(ascii_file, 'r') + ascii = open(str(ascii_file), 'r') # Set default record length record_length = 4096 @@ -116,7 +116,7 @@ def ascii_to_binary(ascii_file, binary_file): ascii.close() # Open binary file - binary = open(binary_file, 'wb') + binary = open(str(binary_file), 'wb') idx = 0 @@ -228,8 +228,9 @@ class Library(EqualityMixin): self.tables = [] # Determine whether file is ASCII or binary + filename = str(filename) try: - fh = open(str(filename), 'rb') + fh = open(filename, 'rb') # Grab 10 lines of the library sb = b''.join([fh.readline() for i in range(10)]) diff --git a/openmc/data/endf.py b/openmc/data/endf.py index 4c3cb6d47..4340aeca0 100644 --- a/openmc/data/endf.py +++ b/openmc/data/endf.py @@ -348,7 +348,7 @@ def get_evaluations(filename): """ evaluations = [] - with open(filename, 'r') as fh: + with open(str(filename), 'r') as fh: while True: pos = fh.tell() line = fh.readline() diff --git a/openmc/data/library.py b/openmc/data/library.py index 1a797aa53..41bcd58a7 100644 --- a/openmc/data/library.py +++ b/openmc/data/library.py @@ -52,6 +52,10 @@ class DataLibrary(EqualityMixin): Path to the file to be registered. """ + # Support pathlib + # TODO: Remove when support is Python 3.6+ only + filename = str(filename) + with h5py.File(filename, 'r') as h5file: filetype = h5file.attrs['filetype'].decode().lstrip('data_') materials = list(h5file) @@ -76,7 +80,7 @@ class DataLibrary(EqualityMixin): if common_dir == '': common_dir = '.' - if os.path.relpath(common_dir, os.path.dirname(path)) != '.': + if os.path.relpath(common_dir, os.path.dirname(str(path))) != '.': dir_element = ET.SubElement(root, "directory") dir_element.text = os.path.realpath(common_dir) @@ -91,7 +95,7 @@ class DataLibrary(EqualityMixin): # Write XML file tree = ET.ElementTree(root) - tree.write(path, xml_declaration=True, encoding='utf-8', + tree.write(str(path), xml_declaration=True, encoding='utf-8', method='xml') @classmethod @@ -123,7 +127,9 @@ class DataLibrary(EqualityMixin): raise ValueError("Either path or OPENMC_CROSS_SECTIONS " "environmental variable must be set") - check_type('path', path, str) + # Convert to string to support pathlib + # TODO: Remove when support is Python 3.6+ only + path = str(path) tree = ET.parse(path) root = tree.getroot() diff --git a/openmc/data/multipole.py b/openmc/data/multipole.py index 5d34c9ff6..9022061a0 100644 --- a/openmc/data/multipole.py +++ b/openmc/data/multipole.py @@ -333,7 +333,7 @@ class WindowedMultipole(EqualityMixin): if isinstance(group_or_filename, h5py.Group): group = group_or_filename else: - h5file = h5py.File(group_or_filename, 'r') + h5file = h5py.File(str(group_or_filename), 'r') # Make sure version matches if 'version' in h5file.attrs: @@ -515,7 +515,7 @@ class WindowedMultipole(EqualityMixin): """ # Open file and write version. - with h5py.File(path, mode, libver=libver) as f: + with h5py.File(str(path), mode, libver=libver) as f: f.attrs['filetype'] = np.string_('data_wmp') f.attrs['version'] = np.array(WMP_VERSION) diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index fb00bccb9..1856a13d4 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -446,7 +446,7 @@ class IncidentNeutron(EqualityMixin): 'originated from an ENDF file.') # Open file and write version - f = h5py.File(path, mode, libver=libver) + f = h5py.File(str(path), mode, libver=libver) f.attrs['filetype'] = np.string_('data_neutron') f.attrs['version'] = np.array(HDF5_VERSION) @@ -520,7 +520,7 @@ class IncidentNeutron(EqualityMixin): if isinstance(group_or_filename, h5py.Group): group = group_or_filename else: - h5file = h5py.File(group_or_filename, 'r') + h5file = h5py.File(str(group_or_filename), 'r') # Make sure version matches if 'version' in h5file.attrs: diff --git a/openmc/data/njoy.py b/openmc/data/njoy.py index b2894b3d1..0c82f32f1 100644 --- a/openmc/data/njoy.py +++ b/openmc/data/njoy.py @@ -146,14 +146,14 @@ def run(commands, tapein, tapeout, input_filename=None, stdout=False, """ if input_filename is not None: - with open(input_filename, 'w') as f: + with open(str(input_filename), 'w') as f: f.write(commands) with tempfile.TemporaryDirectory() as tmpdir: # Copy evaluations to appropriates 'tapes' for tape_num, filename in tapein.items(): tmpfilename = os.path.join(tmpdir, 'tape{}'.format(tape_num)) - shutil.copy(filename, tmpfilename) + shutil.copy(str(filename), tmpfilename) # Start up NJOY process njoy = Popen([njoy_exec], cwd=tmpdir, stdin=PIPE, stdout=PIPE, @@ -182,7 +182,7 @@ def run(commands, tapein, tapeout, input_filename=None, stdout=False, for tape_num, filename in tapeout.items(): tmpfilename = os.path.join(tmpdir, 'tape{}'.format(tape_num)) if os.path.isfile(tmpfilename): - shutil.move(tmpfilename, filename) + shutil.move(tmpfilename, str(filename)) def make_pendf(filename, pendf='pendf', error=0.001, stdout=False): @@ -422,7 +422,7 @@ def make_ace_thermal(filename, filename_thermal, temperatures=None, commands = "" nendf, nthermal_endf, npendf = 20, 21, 22 - tapein = {nendf: filename, nthermal_endf:filename_thermal} + tapein = {nendf: filename, nthermal_endf: filename_thermal} tapeout = {} # reconr diff --git a/openmc/data/photon.py b/openmc/data/photon.py index e0f71d5ce..08f8f085d 100644 --- a/openmc/data/photon.py +++ b/openmc/data/photon.py @@ -668,7 +668,7 @@ class IncidentPhoton(EqualityMixin): """ # Open file and write version - f = h5py.File(path, mode, libver=libver) + f = h5py.File(str(path), mode, libver=libver) f.attrs['filetype'] = np.string_('data_photon') if 'version' not in f.attrs: f.attrs['version'] = np.array(HDF5_VERSION) diff --git a/openmc/data/thermal.py b/openmc/data/thermal.py index 23f02c90d..b1e4e015f 100644 --- a/openmc/data/thermal.py +++ b/openmc/data/thermal.py @@ -278,7 +278,7 @@ class ThermalScattering(EqualityMixin): """ # Open file and write version - f = h5py.File(path, mode, libver=libver) + f = h5py.File(str(path), mode, libver=libver) f.attrs['filetype'] = np.string_('data_thermal') f.attrs['version'] = np.array(HDF5_VERSION) @@ -387,7 +387,7 @@ class ThermalScattering(EqualityMixin): if isinstance(group_or_filename, h5py.Group): group = group_or_filename else: - h5file = h5py.File(group_or_filename, 'r') + h5file = h5py.File(str(group_or_filename), 'r') # Make sure version matches if 'version' in h5file.attrs: From dd9463c2882b9004c686b401c184570796e8dd63 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 2 Nov 2018 07:57:55 -0500 Subject: [PATCH 06/62] Make sure filetype gets set correctly for data libraries --- openmc/data/library.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmc/data/library.py b/openmc/data/library.py index 41bcd58a7..905dbbe4a 100644 --- a/openmc/data/library.py +++ b/openmc/data/library.py @@ -57,7 +57,7 @@ class DataLibrary(EqualityMixin): filename = str(filename) with h5py.File(filename, 'r') as h5file: - filetype = h5file.attrs['filetype'].decode().lstrip('data_') + filetype = h5file.attrs['filetype'].decode()[5:] materials = list(h5file) library = {'path': filename, 'type': filetype, 'materials': materials} From 16124d25694c16e25796d2dd005dac63df6f044c Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 2 Nov 2018 11:25:08 -0500 Subject: [PATCH 07/62] Support setting density in g/cm3 through C API --- docs/source/capi/index.rst | 6 ++- include/openmc/capi.h | 2 +- openmc/capi/material.py | 10 +++-- src/material_header.F90 | 70 +++++++++++++++++++++++------------ tests/unit_tests/test_capi.py | 3 ++ 5 files changed, 61 insertions(+), 30 deletions(-) diff --git a/docs/source/capi/index.rst b/docs/source/capi/index.rst index 85509f6f4..d7da3261e 100644 --- a/docs/source/capi/index.rst +++ b/docs/source/capi/index.rst @@ -333,12 +333,14 @@ Functions :return: Return status (negative if an error occurred) :rtype: int -.. c:function:: int openmc_material_set_density(int32_t index, double density) +.. c:function:: int openmc_material_set_density(int32_t index, double density, const char* units) Set the density of a material. :param int32_t index: Index in the materials array - :param double density: Density of the material in atom/b-cm + :param double density: Density of the material + :param units: Units for density + :type units: const char* :return: Return status (negative if an error occurs) :rtype: int diff --git a/include/openmc/capi.h b/include/openmc/capi.h index 3ead7d833..fd664b2a9 100644 --- a/include/openmc/capi.h +++ b/include/openmc/capi.h @@ -60,7 +60,7 @@ extern "C" { int openmc_material_get_id(int32_t index, int32_t* id); int openmc_material_get_fissionable(int32_t index, bool* fissionable); int openmc_material_get_volume(int32_t index, double* volume); - int openmc_material_set_density(int32_t index, double density); + int openmc_material_set_density(int32_t index, double density, const char* units); int openmc_material_set_densities(int32_t index, int n, const char** name, const double* density); int openmc_material_set_id(int32_t index, int32_t id); int openmc_material_set_volume(int32_t index, double volume); diff --git a/openmc/capi/material.py b/openmc/capi/material.py index 9548c0b79..4d40be04b 100644 --- a/openmc/capi/material.py +++ b/openmc/capi/material.py @@ -35,7 +35,7 @@ _dll.openmc_material_get_densities.errcheck = _error_handler _dll.openmc_material_get_volume.argtypes = [c_int32, POINTER(c_double)] _dll.openmc_material_get_volume.restype = c_int _dll.openmc_material_get_volume.errcheck = _error_handler -_dll.openmc_material_set_density.argtypes = [c_int32, c_double] +_dll.openmc_material_set_density.argtypes = [c_int32, c_double, c_char_p] _dll.openmc_material_set_density.restype = c_int _dll.openmc_material_set_density.errcheck = _error_handler _dll.openmc_material_set_densities.argtypes = [ @@ -178,16 +178,18 @@ class Material(_FortranObjectWithID): """ _dll.openmc_material_add_nuclide(self._index, name.encode(), density) - def set_density(self, density): + def set_density(self, density, units='atom/b-cm'): """Set density of a material. Parameters ---------- density : float - Density in atom/b-cm + Density + units : {'atom/b-cm', 'g/cm3'} + Units for density """ - _dll.openmc_material_set_density(self._index, density) + _dll.openmc_material_set_density(self._index, density, units.encode()) def set_densities(self, nuclides, densities): """Set the densities of a list of nuclides in a material diff --git a/src/material_header.F90 b/src/material_header.F90 index b4d061725..8a294dd04 100644 --- a/src/material_header.F90 +++ b/src/material_header.F90 @@ -12,7 +12,7 @@ module material_header use sab_header use simulation_header, only: log_spacing use stl_vector, only: VectorReal, VectorInt - use string, only: to_str + use string, only: to_str, to_f_string implicit none @@ -166,34 +166,52 @@ contains call material_set_fissionable_c(this % ptr, logical(fissionable, C_BOOL)) end subroutine material_set_fissionable - function material_set_density(this, density) result(err) + function material_set_density(this, density, units) result(err) class(Material), intent(inout) :: this real(8), intent(in) :: density + character(*), intent(in) :: units integer :: err integer :: i real(8) :: sum_percent real(8) :: awr + real(8) :: previous_density_gpcc + real(8) :: f if (allocated(this % atom_density)) then - ! Set total density based on value provided - this % density = density - - ! Determine normalized atom percents - sum_percent = sum(this % atom_density) - this % atom_density(:) = this % atom_density / sum_percent - - ! Recalculate nuclide atom densities based on given density - this % atom_density(:) = density * this % atom_density - - ! Calculate density in g/cm^3. - this % density_gpcc = ZERO - do i = 1, this % n_nuclides - awr = nuclides(this % nuclide(i)) % awr - this % density_gpcc = this % density_gpcc & - + this % atom_density(i) * awr * MASS_NEUTRON / N_AVOGADRO - end do err = 0 + select case (units) + case ('atom/b-cm') + ! Set total density based on value provided + this % density = density + + ! Determine normalized atom percents + sum_percent = sum(this % atom_density) + this % atom_density(:) = this % atom_density / sum_percent + + ! Recalculate nuclide atom densities based on given density + this % atom_density(:) = density * this % atom_density + + ! Calculate density in g/cm^3. + this % density_gpcc = ZERO + do i = 1, this % n_nuclides + awr = nuclides(this % nuclide(i)) % awr + this % density_gpcc = this % density_gpcc & + + this % atom_density(i) * awr * MASS_NEUTRON / N_AVOGADRO + end do + case ('g/cm3', 'g/cc') + ! Determine factor by which to change densities + previous_density_gpcc = this % density_gpcc + f = density / previous_density_gpcc + + ! Update densities + this % density_gpcc = density + this % density = f * this % density + this % atom_density(:) = f * this % atom_density(:) + case default + err = E_INVALID_ARGUMENT + call set_errmsg("Invalid units '" // trim(units) // "' specified.") + end select else err = E_ALLOCATE call set_errmsg("Material atom density array hasn't been allocated.") @@ -738,16 +756,22 @@ contains end function openmc_material_set_id - function openmc_material_set_density(index, density) result(err) bind(C) - ! Set the total density of a material in atom/b-cm + function openmc_material_set_density(index, density, units) result(err) bind(C) + ! Set the total density of a material integer(C_INT32_T), value, intent(in) :: index real(C_DOUBLE), value, intent(in) :: density + character(kind=C_CHAR), intent(in) :: units(*) integer(C_INT) :: err + character(:), allocatable :: units_ + + ! Convert C string to Fortran string + units_ = to_f_string(units) + err = E_UNASSIGNED if (index >= 1 .and. index <= size(materials)) then associate (m => materials(index)) - err = m % set_density(density) + err = m % set_density(density, units_) end associate else err = E_OUT_OF_BOUNDS @@ -794,7 +818,7 @@ contains m % n_nuclides = n ! Set total density to the sum of the vector - err = m % set_density(sum(density)) + err = m % set_density(sum(density), 'atom/b-cm') ! Assign S(a,b) tables call m % assign_sab_tables() diff --git a/tests/unit_tests/test_capi.py b/tests/unit_tests/test_capi.py index 059557dbf..f5185e23f 100644 --- a/tests/unit_tests/test_capi.py +++ b/tests/unit_tests/test_capi.py @@ -105,6 +105,9 @@ def test_material(capi_init): m.volume = 10.0 assert m.volume == 10.0 + with pytest.raises(exc.InvalidArgumentError): + m.set_density(1.0, 'goblins') + rho = 2.25e-2 m.set_density(rho) assert sum(m.densities) == pytest.approx(rho) From 029f4b9a26848fed6d336a0b9cf28b36be5ba5b5 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 5 Nov 2018 10:24:42 -0600 Subject: [PATCH 08/62] Remove use of material_temps in input_xml.F90 --- src/input_xml.F90 | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 74ca51223..04f53d168 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -123,15 +123,14 @@ contains type(VectorReal), allocatable :: nuc_temps(:) ! List of T to read for each nuclide type(VectorReal), allocatable :: sab_temps(:) ! List of T to read for each S(a,b) - real(8), allocatable :: material_temps(:) call read_settings_xml() call read_cross_sections_xml() - call read_materials_xml(material_temps) + call read_materials_xml() call read_geometry_xml() ! Set up neighbor lists, convert user IDs -> indices, assign temperatures - call finalize_geometry(material_temps, nuc_temps, sab_temps) + call finalize_geometry(nuc_temps, sab_temps) if (run_mode /= MODE_PLOTTING) then call time_read_xs % start() @@ -172,8 +171,7 @@ contains end subroutine read_input_xml - subroutine finalize_geometry(material_temps, nuc_temps, sab_temps) - real(8), intent(in) :: material_temps(:) + subroutine finalize_geometry(nuc_temps, sab_temps) type(VectorReal), allocatable, intent(out) :: nuc_temps(:) type(VectorReal), optional, allocatable, intent(out) :: sab_temps(:) @@ -660,9 +658,7 @@ contains end subroutine read_cross_sections_xml - subroutine read_materials_xml(material_temps) - real(8), allocatable, intent(out) :: material_temps(:) - + subroutine read_materials_xml() integer :: i ! loop index for materials integer :: j ! loop index for nuclides integer :: k ! loop index @@ -720,7 +716,6 @@ contains ! Allocate materials array n_materials = size(node_mat_list) allocate(materials(n_materials)) - allocate(material_temps(n_materials)) ! Initialize count for number of nuclides/S(a,b) tables index_nuclide = 0 @@ -745,13 +740,6 @@ contains call get_node_value(node_mat, "name", mat % name) end if - ! Get material default temperature - if (check_for_node(node_mat, "temperature")) then - call get_node_value(node_mat, "temperature", material_temps(i)) - else - material_temps(i) = -1.0 - end if - ! Get pointer to density element if (check_for_node(node_mat, "density")) then node_dens = node_mat % child("density") From b65ad3242222a9c1d7a8208ad260d1fb393aa56f Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 5 Nov 2018 21:35:41 -0600 Subject: [PATCH 09/62] Move libraries/library_dict to C++ (need to fix res_scat_nuclides) --- CMakeLists.txt | 1 + include/openmc/cross_sections.h | 43 +++++ include/openmc/string_utils.h | 7 + src/constants.F90 | 3 +- src/cross_sections.cpp | 221 +++++++++++++++++++++++++ src/input_xml.F90 | 282 ++------------------------------ src/nuclide_header.F90 | 69 +++++--- src/settings.cpp | 2 +- 8 files changed, 340 insertions(+), 288 deletions(-) create mode 100644 include/openmc/cross_sections.h create mode 100644 src/cross_sections.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fded5876c..e76ed9a9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -384,6 +384,7 @@ add_library(libopenmc SHARED src/dagmc.cpp src/cell.cpp src/cmfd_execute.cpp + src/cross_sections.cpp src/distribution.cpp src/distribution_angle.cpp src/distribution_energy.cpp diff --git a/include/openmc/cross_sections.h b/include/openmc/cross_sections.h new file mode 100644 index 000000000..eaa4f5632 --- /dev/null +++ b/include/openmc/cross_sections.h @@ -0,0 +1,43 @@ +#ifndef OPENMC_CROSS_SECTIONS_H +#define OPENMC_CROSS_SECTIONS_H + +#include "pugixml.hpp" + +#include +#include +#include + +namespace openmc { + +class Library { +public: + // Types, enums + enum class Type { + neutron = 1, photon = 3, thermal = 2, multigroup = 4, wmp = 5 + }; + + // Constructors + Library(pugi::xml_node node, const std::string& directory); + + // Comparison operator (for using in map) + bool operator<(const Library& other) { + return path_ < other.path_; + } + + // Data members + Type type_; + std::vector materials_; + std::string path_; +}; + +extern std::vector libraries; +using LibraryKey = std::pair; +extern std::map library_dict; + + +extern "C" void read_cross_sections_xml(); +void read_ce_cross_sections_xml(); + +} + +#endif // OPENMC_CROSS_SECTIONS_H diff --git a/include/openmc/string_utils.h b/include/openmc/string_utils.h index 9af50870d..73b1a28ec 100644 --- a/include/openmc/string_utils.h +++ b/include/openmc/string_utils.h @@ -38,5 +38,12 @@ ends_with(const std::string& value, const std::string& ending) return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); } +inline bool +starts_with(const std::string& value, const std::string& beginning) +{ + if (beginning.size() > value.size()) return false; + return std::equal(beginning.begin(), beginning.end(), value.begin()); +} + } // namespace openmc #endif // OPENMC_STRING_UTILS_H diff --git a/src/constants.F90 b/src/constants.F90 index 250b1ef37..857d6ae4a 100644 --- a/src/constants.F90 +++ b/src/constants.F90 @@ -238,7 +238,8 @@ module constants LIBRARY_NEUTRON = 1, & LIBRARY_THERMAL = 2, & LIBRARY_PHOTON = 3, & - LIBRARY_MULTIGROUP = 4 + LIBRARY_MULTIGROUP = 4, & + LIBRARY_WMP = 5 ! Probability table parameters integer, parameter :: & diff --git a/src/cross_sections.cpp b/src/cross_sections.cpp new file mode 100644 index 000000000..94172f162 --- /dev/null +++ b/src/cross_sections.cpp @@ -0,0 +1,221 @@ +#include "openmc/cross_sections.h" + +#include "openmc/constants.h" +#include "openmc/container_util.h" +#include "openmc/error.h" +#include "openmc/file_utils.h" +#include "openmc/settings.h" +#include "openmc/string_functions.h" +#include "openmc/string_utils.h" +#include "openmc/xml_interface.h" + +#include "pugixml.hpp" + +#include // for getenv + +namespace openmc { + +std::vector libraries; +std::map library_dict; + +extern "C" void read_mg_cross_sections_header(); + +Library::Library(pugi::xml_node node, const std::string& directory) +{ + // Get type of library + if (check_for_node(node, "type")) { + auto type = get_node_value(node, "type"); + if (type == "neutron") { + type_ = Type::neutron; + } else if (type == "thermal") { + type_ = Type::thermal; + } else if (type == "photon") { + type_ = Type::photon; + } else if (type == "wmp") { + type_ = Type::wmp; + } else { + fatal_error("Unrecognized library type: " + type); + } + } else { + fatal_error("Missing library type"); + } + + // Get list of materials + if (check_for_node(node, "materials")) { + materials_ = get_node_array(node, "materials"); + } + + // determine path of cross section table + if (!check_for_node(node, "path")) { + fatal_error("Missing library path"); + } + std::string path = get_node_value(node, "path"); + + if (starts_with(path, "/")) { + path_ = path; + } else if (ends_with(directory, "/")) { + path_ = directory + path; + } else { + path_ = directory + "/" + path; + } + + if (!file_exists(path_)) { + warning("Cross section library " + path_ + " does not exist."); + } +} + + +void read_cross_sections_xml() +{ + // Check if materials.xml exists + std::string filename = settings::path_input + "materials.xml"; + if (!file_exists(filename)) { + fatal_error("Material XML file '" + filename + "' does not exist."); + } + + // Parse materials.xml file + pugi::xml_document doc; + doc.load_file(filename.c_str()); + auto root = doc.document_element(); + + // Find cross_sections.xml file -- the first place to look is the + // materials.xml file. If no file is found there, then we check the + // OPENMC_CROSS_SECTIONS environment variable + if (!check_for_node(root, "cross_sections")) { + // No cross_sections.xml file specified in settings.xml, check + // environment variable + if (settings::run_CE) { + char* envvar = std::getenv("OPENMC_CROSS_SECTIONS"); + if (!envvar) { + fatal_error("No cross_sections.xml file was specified in " + "materials.xml or in the OPENMC_CROSS_SECTIONS" + " environment variable. OpenMC needs such a file to identify " + "where to find data libraries. Please consult the" + " user's guide at https://openmc.readthedocs.io for " + "information on how to set up data libraries."); + } + settings::path_cross_sections = envvar; + } else { + char* envvar = std::getenv("OPENMC_MG_CROSS_SECTIONS"); + if (!envvar) { + fatal_error("No mgxs.h5 file was specified in " + "materials.xml or in the OPENMC_MG_CROSS_SECTIONS environment " + "variable. OpenMC needs such a file to identify where to " + "find MG cross section libraries. Please consult the user's " + "guide at http://openmc.readthedocs.io for information on " + "how to set up MG cross section libraries."); + } + settings::path_cross_sections = envvar; + } + } else { + settings::path_cross_sections = get_node_value(root, "cross_sections"); + } + + // Find the windowed multipole library + if (settings::run_mode != RUN_MODE_PLOTTING) { + if (!check_for_node(root, "multipole_library")) { + // No library location specified in materials.xml, check + // environment variable + settings::path_multipole = std::getenv("OPENMC_MULTIPOLE_LIBRARY"); + } else { + settings::path_multipole = get_node_value(root, "multipole_library"); + } + if (!ends_with(settings::path_multipole, "/")) { + settings::path_multipole += "/"; + } + } + + // Now that the cross_sections.xml or mgxs.h5 has been located, read it in + if (settings::run_CE) { + read_ce_cross_sections_xml(); + } else { + read_mg_cross_sections_header(); + } + + // Establish mapping between (type, material) and index in libraries + int i = 0; + for (const auto& lib : libraries) { + for (const auto& name : lib.materials_) { + std::string lower_name = name; + to_lower(lower_name); + LibraryKey key {lib.type_, lower_name}; + library_dict.insert({key, i}); + } + ++i; + } + + // Check that 0K nuclides are listed in the cross_sections.xml file + // if (allocated(res_scat_nuclides)) { + // do i = 1, size(res_scat_nuclides) + // if (!library_dict % has(to_lower(res_scat_nuclides(i)))) { + // fatal_error("Could not find resonant scatterer " & + // // trim(res_scat_nuclides(i)) // " in cross_sections.xml file!") + // } + // end do + // } +} + +void read_ce_cross_sections_xml() +{ + // Check if cross_sections.xml exists + const auto& filename = settings::path_cross_sections; + if (!file_exists(filename)) { + // Could not find cross_sections.xml file + fatal_error("Cross sections XML file '" + filename + + "' does not exist."); + } + + write_message("Reading cross sections XML file...", 5); + + // Parse cross_sections.xml file + pugi::xml_document doc; + auto result = doc.load_file(filename.c_str()); + if (!result) { + fatal_error("Error processing cross_sections.xml file."); + } + auto root = doc.document_element(); + + std::string directory; + if (check_for_node(root, "directory")) { + // Copy directory information if present + directory = get_node_value(root, "directory"); + } else { + // If no directory is listed in cross_sections.xml, by default select the + // directory in which the cross_sections.xml file resides + auto pos = filename.rfind("/"); + directory = filename.substr(0, pos); + } + + for (const auto& node_library : root.children("library")) { + libraries.emplace_back(node_library, directory); + } + + // Make sure file was not empty + if (libraries.empty()) { + fatal_error("No cross section libraries present in cross_sections.xml file."); + } +} + +extern "C" void library_clear() { + libraries.clear(); + library_dict.clear(); +} + +extern "C" const char* library_path(int type, const char* name) { + auto lib_type = static_cast(type); + LibraryKey key {lib_type, name}; + if (library_dict.find(key) == library_dict.end()) { + return nullptr; + } else { + auto idx = library_dict[key]; + return libraries[idx].path_.c_str(); + } +} + +extern "C" bool library_present(int type, const char* name) { + auto lib_type = static_cast(type); + LibraryKey key {lib_type, name}; + return library_dict.find(key) != library_dict.end(); +} + +} // namespace openmc diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 04f53d168..fb8a8d772 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -72,6 +72,9 @@ module input_xml type(C_PTR) :: node_ptr end subroutine read_cells + subroutine read_cross_sections_xml() bind(C) + end subroutine + subroutine read_lattices(node_ptr) bind(C) import C_PTR type(C_PTR) :: node_ptr @@ -545,119 +548,6 @@ contains end do end subroutine allocate_cells -!=============================================================================== -! READ_MATERIAL_XML reads data from a materials.xml file and parses it, checking -! for errors and placing properly-formatted data in the right data structures -!=============================================================================== - - subroutine read_cross_sections_xml() - integer :: i, j - logical :: file_exists - character(MAX_FILE_LEN) :: env_variable - character(MAX_LINE_LEN) :: filename - type(XMLDocument) :: doc - type(XMLNode) :: root - - ! Check if materials.xml exists - filename = trim(path_input) // "materials.xml" - inquire(FILE=filename, EXIST=file_exists) - if (.not. file_exists) then - call fatal_error("Material XML file '" // trim(filename) // "' does not & - &exist!") - end if - - ! Parse materials.xml file - call doc % load_file(filename) - root = doc % document_element() - - ! Find cross_sections.xml file -- the first place to look is the - ! materials.xml file. If no file is found there, then we check the - ! OPENMC_CROSS_SECTIONS environment variable - if (.not. check_for_node(root, "cross_sections")) then - ! No cross_sections.xml file specified in settings.xml, check - ! environment variable - if (run_CE) then - call get_environment_variable("OPENMC_CROSS_SECTIONS", env_variable) - if (len_trim(env_variable) == 0) then - call get_environment_variable("CROSS_SECTIONS", env_variable) - ! FIXME: When deprecated option of setting the cross sections in - ! settings.xml is removed, remove ".and. path_cross_sections == ''" - if (len_trim(env_variable) == 0 .and. path_cross_sections == '') then - call fatal_error("No cross_sections.xml file was specified in & - &materials.xml, settings.xml, or in the OPENMC_CROSS_SECTIONS& - & environment variable. OpenMC needs such a file to identify & - &where to find ACE cross section libraries. Please consult the& - & user's guide at http://openmc.readthedocs.io for & - &information on how to set up ACE cross section libraries.") - else - call warning("The CROSS_SECTIONS environment variable is & - &deprecated. Please update your environment to use & - &OPENMC_CROSS_SECTIONS instead.") - end if - end if - path_cross_sections = trim(env_variable) - else - call get_environment_variable("OPENMC_MG_CROSS_SECTIONS", env_variable) - ! FIXME: When deprecated option of setting the mg cross sections in - ! settings.xml is removed, remove ".and. path_cross_sections == ''" - if (len_trim(env_variable) == 0 .and. path_cross_sections == '') then - call fatal_error("No mgxs.h5 file was specified in & - &materials.xml or in the OPENMC_MG_CROSS_SECTIONS environment & - &variable. OpenMC needs such a file to identify where to & - &find MG cross section libraries. Please consult the user's & - &guide at http://openmc.readthedocs.io for information on & - &how to set up MG cross section libraries.") - else if (len_trim(env_variable) /= 0) then - path_cross_sections = trim(env_variable) - end if - end if - else - call get_node_value(root, "cross_sections", path_cross_sections) - end if - - ! Find the windowed multipole library - if (run_mode /= MODE_PLOTTING) then - if (.not. check_for_node(root, "multipole_library")) then - ! No library location specified in materials.xml, check - ! environment variable - call get_environment_variable("OPENMC_MULTIPOLE_LIBRARY", env_variable) - path_multipole = trim(env_variable) - else - call get_node_value(root, "multipole_library", path_multipole) - end if - if (.not. ends_with(path_multipole, "/")) & - path_multipole = trim(path_multipole) // "/" - end if - - ! Close materials XML file - call doc % clear() - - ! Now that the cross_sections.xml or mgxs.h5 has been located, read it in - if (run_CE) then - call read_ce_cross_sections_xml() - else - call read_mg_cross_sections_header() - end if - - ! Creating dictionary that maps the name of the material to the entry - do i = 1, size(libraries) - do j = 1, size(libraries(i) % materials) - call library_dict % set(to_lower(libraries(i) % materials(j)), i) - end do - end do - - ! Check that 0K nuclides are listed in the cross_sections.xml file - if (allocated(res_scat_nuclides)) then - do i = 1, size(res_scat_nuclides) - if (.not. library_dict % has(to_lower(res_scat_nuclides(i)))) then - call fatal_error("Could not find resonant scatterer " & - // trim(res_scat_nuclides(i)) // " in cross_sections.xml file!") - end if - end do - end if - - end subroutine read_cross_sections_xml - subroutine read_materials_xml() integer :: i ! loop index for materials integer :: j ! loop index for nuclides @@ -928,19 +818,10 @@ contains ALL_NUCLIDES: do j = 1, mat % n_nuclides ! Check that this nuclide is listed in the cross_sections.xml file name = trim(names % data(j)) - if (.not. library_dict % has(to_lower(name))) then + if (.not. library_present(LIBRARY_NEUTRON, (to_lower(name)))) then call fatal_error("Could not find nuclide " // trim(name) & // " in cross_sections data file!") end if - i_library = library_dict % get(to_lower(name)) - - if (run_CE) then - ! Check to make sure cross-section is continuous energy neutron table - if (libraries(i_library) % type /= LIBRARY_NEUTRON) then - call fatal_error("Cross-section table " // trim(name) & - // " is not a continuous-energy neutron table.") - end if - end if ! If this nuclide hasn't been encountered yet, we need to add its name ! and alias to the nuclide_dict @@ -959,7 +840,7 @@ contains element = name(1:scan(name, '0123456789') - 1) ! Make sure photon cross section data is available - if (.not. library_dict % has(to_lower(element))) then + if (.not. library_present(LIBRARY_PHOTON, to_lower(element))) then call fatal_error("Could not find element " // trim(element) & // " in cross_sections data file!") end if @@ -1053,23 +934,11 @@ contains end if ! Check that this nuclide is listed in the cross_sections.xml file - if (.not. library_dict % has(to_lower(name))) then + if (.not. library_present(LIBRARY_THERMAL, to_lower(name))) then call fatal_error("Could not find S(a,b) table " // trim(name) & // " in cross_sections.xml file!") end if - ! Find index in xs_listing and set the name and alias according to the - ! listing - i_library = library_dict % get(to_lower(name)) - - if (run_CE) then - ! Check to make sure cross-section is continuous energy neutron table - if (libraries(i_library) % type /= LIBRARY_THERMAL) then - call fatal_error("Cross-section table " // trim(name) & - // " is not a S(a,b) table.") - end if - end if - ! If this S(a,b) table hasn't been encountered yet, we need to add its ! name and alias to the sab_dict if (.not. sab_dict % has(to_lower(name))) then @@ -2052,117 +1921,7 @@ contains end subroutine read_plots_xml -!=============================================================================== -! READ_*_CROSS_SECTIONS_XML reads information from a cross_sections.xml file. This -! file contains a listing of the CE and MG cross sections that may be used. -!=============================================================================== - - subroutine read_ce_cross_sections_xml() - integer :: i ! loop index - integer :: n - integer :: n_libraries - logical :: file_exists ! does cross_sections.xml exist? - character(MAX_WORD_LEN) :: directory ! directory with cross sections - character(MAX_WORD_LEN) :: words(MAX_WORDS) - character(10000) :: temp_str - type(XMLDocument) :: doc - type(XMLNode) :: root - type(XMLNode) :: node_library - type(XMLNode), allocatable :: node_library_list(:) - - ! Check if cross_sections.xml exists - inquire(FILE=path_cross_sections, EXIST=file_exists) - if (.not. file_exists) then - ! Could not find cross_sections.xml file - call fatal_error("Cross sections XML file '" & - // trim(path_cross_sections) // "' does not exist!") - end if - - call write_message("Reading cross sections XML file...", 5) - - ! Parse cross_sections.xml file - call doc % load_file(path_cross_sections) - root = doc % document_element() - - if (check_for_node(root, "directory")) then - ! Copy directory information if present - call get_node_value(root, "directory", directory) - else - ! If no directory is listed in cross_sections.xml, by default select the - ! directory in which the cross_sections.xml file resides - i = index(path_cross_sections, "/", BACK=.true.) - directory = path_cross_sections(1:i) - end if - - ! Get node list of all - call get_node_list(root, "library", node_library_list) - n_libraries = size(node_library_list) - - ! Allocate xs_listings array - if (n_libraries == 0) then - call fatal_error("No cross section libraries present in cross_sections.xml & - &file!") - else - allocate(libraries(n_libraries)) - end if - - do i = 1, n_libraries - ! Get pointer to ace table XML node - node_library = node_library_list(i) - - ! Get list of materials - if (check_for_node(node_library, "materials")) then - call get_node_value(node_library, "materials", temp_str) - call split_string(temp_str, words, n) - allocate(libraries(i) % materials(n)) - libraries(i) % materials(:) = words(1:n) - end if - - ! Get type of library - if (check_for_node(node_library, "type")) then - call get_node_value(node_library, "type", temp_str) - select case(to_lower(temp_str)) - case ('neutron') - libraries(i) % type = LIBRARY_NEUTRON - case ('thermal') - libraries(i) % type = LIBRARY_THERMAL - case ('photon') - libraries(i) % type = LIBRARY_PHOTON - end select - else - call fatal_error("Missing library type") - end if - - ! determine path of cross section table - if (check_for_node(node_library, "path")) then - call get_node_value(node_library, "path", temp_str) - else - call fatal_error("Missing library path") - end if - - if (starts_with(temp_str, '/')) then - libraries(i) % path = trim(temp_str) - else - if (ends_with(directory,'/')) then - libraries(i) % path = trim(directory) // trim(temp_str) - else - libraries(i) % path = trim(directory) // '/' // trim(temp_str) - end if - end if - - inquire(FILE=libraries(i) % path, EXIST=file_exists) - if (.not. file_exists) then - call warning("Cross section library " // trim(libraries(i) % path) // & - " does not exist.") - end if - end do - - ! Close cross sections XML file - call doc % clear() - - end subroutine read_ce_cross_sections_xml - - subroutine read_mg_cross_sections_header() + subroutine read_mg_cross_sections_header() bind(C) integer :: i ! loop index integer :: n_libraries logical :: file_exists ! does mgxs.h5 exist? @@ -2240,16 +1999,8 @@ contains if (n_libraries == 0) then call fatal_error("At least one MGXS data set must be present in & &mgxs library file!") - else - allocate(libraries(n_libraries)) end if - do i = 1, n_libraries - ! Get name of material - allocate(libraries(i) % materials(1)) - libraries(i) % materials(1) = names(i) - end do - ! Close MGXS HDF5 file call file_close(file_id) @@ -2346,6 +2097,7 @@ contains integer(HID_T) :: group_id logical :: mp_found ! if windowed multipole libraries were found character(MAX_WORD_LEN) :: name + character(MAX_FILE_LEN) :: filename character(3) :: element type(SetChar) :: already_read type(SetChar) :: element_already_read @@ -2363,14 +2115,14 @@ contains name = materials(i) % names(j) if (.not. already_read % contains(name)) then - i_library = library_dict % get(to_lower(name)) + filename = library_path(LIBRARY_NEUTRON, to_lower(name)) i_nuclide = nuclide_dict % get(to_lower(name)) call write_message('Reading ' // trim(name) // ' from ' // & - trim(libraries(i_library) % path), 6) + trim(filename), 6) ! Open file and make sure version is sufficient - file_id = file_open(libraries(i_library) % path, 'r') + file_id = file_open(filename, 'r') call check_data_version(file_id) ! Read nuclide data from HDF5 @@ -2403,13 +2155,13 @@ contains if (photon_transport) then if (.not. element_already_read % contains(element)) then ! Read photon interaction data from HDF5 photon library - i_library = library_dict % get(to_lower(element)) + filename = library_path(LIBRARY_PHOTON, to_lower(element)) i_element = element_dict % get(element) call write_message('Reading ' // trim(element) // ' from ' // & - trim(libraries(i_library) % path), 6) + trim(filename), 6) ! Open file and make sure version is sufficient - file_id = file_open(libraries(i_library) % path, 'r') + file_id = file_open(filename, 'r') call check_data_version(file_id) ! Read element data from HDF5 @@ -2493,14 +2245,14 @@ contains name = materials(i) % sab_names(j) if (.not. already_read % contains(name)) then - i_library = library_dict % get(to_lower(name)) + filename = library_path(LIBRARY_THERMAL, to_lower(name)) i_sab = sab_dict % get(to_lower(name)) call write_message('Reading ' // trim(name) // ' from ' // & - trim(libraries(i_library) % path), 6) + trim(filename), 6) ! Open file and make sure version matches - file_id = file_open(libraries(i_library) % path, 'r') + file_id = file_open(filename, 'r') call check_data_version(file_id) ! Read S(a,b) data from HDF5 diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index da66aea4a..a506b623c 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -176,20 +176,6 @@ module nuclide_header real(C_DOUBLE) :: pair_production ! macroscopic pair production xs end type MaterialMacroXS -!=============================================================================== -! LIBRARY contains data read from a cross_sections.xml file -!=============================================================================== - - type Library - integer :: type - character(MAX_WORD_LEN), allocatable :: materials(:) - character(MAX_FILE_LEN) :: path - end type Library - - ! Cross section libraries - type(Library), allocatable :: libraries(:) - type(DictCharInt) :: library_dict - ! Nuclear data for each nuclide type(Nuclide), allocatable, target :: nuclides(:) integer(C_INT), bind(C) :: n_nuclides @@ -204,8 +190,46 @@ module nuclide_header real(8) :: energy_min(2) = [ZERO, ZERO] real(8) :: energy_max(2) = [INFINITY, INFINITY] + + interface + function library_present_c(type, name) result(b) bind(C, name='library_present') + import C_INT, C_CHAR, C_BOOL + integer(C_INT), value :: type + character(kind=C_CHAR), intent(in) :: name(*) + logical(C_BOOL) :: b + end function + + function library_path_c(type, name) result(path) bind(C, name='library_path') + import C_INT, C_CHAR, C_PTR + integer(C_INT), value :: type + character(kind=C_CHAR), intent(in) :: name(*) + type(C_PTR) :: path + end function + end interface + contains + function library_path(type, name) result(path) + integer, intent(in) :: type + character(len=*), intent(in) :: name + character(MAX_FILE_LEN) :: path + + type(C_PTR) :: ptr + character(kind=C_CHAR), pointer :: string(:) + + ptr = library_path_c(type, to_c_string(name)) + call c_f_pointer(ptr, string, [255]) + path = to_f_string(string) + end function + + function library_present(type, name) result(b) + integer, intent(in) :: type + character(len=*), intent(in) :: name + logical :: b + + b = library_present_c(type, to_c_string(name)) + end function + !=============================================================================== ! ASSIGN_0K_ELASTIC_SCATTERING !=============================================================================== @@ -1540,6 +1564,11 @@ contains subroutine free_memory_nuclide() integer :: i + interface + subroutine library_clear() bind(C) + end subroutine + end interface + ! Deallocate cross section data, listings, and cache if (allocated(nuclides)) then ! First call the clear routines @@ -1550,10 +1579,8 @@ contains end if n_nuclides = 0 - if (allocated(libraries)) deallocate(libraries) - call nuclide_dict % clear() - call library_dict % clear() + call library_clear() end subroutine free_memory_nuclide @@ -1593,11 +1620,11 @@ contains character(kind=C_CHAR), intent(in) :: name(*) integer(C_INT) :: err - integer :: i_library integer :: n integer(HID_T) :: file_id integer(HID_T) :: group_id character(:), allocatable :: name_ + character(MAX_FILE_LEN) :: filename real(8) :: minmax(2) = [ZERO, INFINITY] type(VectorReal) :: temperature type(Nuclide), allocatable :: new_nuclides(:) @@ -1607,7 +1634,7 @@ contains err = 0 if (.not. nuclide_dict % has(to_lower(name_))) then - if (library_dict % has(to_lower(name_))) then + if (library_present(LIBRARY_NEUTRON, to_lower(name_))) then ! allocate extra space in nuclides array n = n_nuclides allocate(new_nuclides(n + 1)) @@ -1615,10 +1642,10 @@ contains call move_alloc(FROM=new_nuclides, TO=nuclides) n = n + 1 - i_library = library_dict % get(to_lower(name_)) + filename = library_path(LIBRARY_NEUTRON, to_lower(name_)) ! Open file and make sure version is sufficient - file_id = file_open(libraries(i_library) % path, 'r') + file_id = file_open(filename, 'r') call check_data_version(file_id) ! Read nuclide data from HDF5 diff --git a/src/settings.cpp b/src/settings.cpp index d4cea83bc..ce81c6b63 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -187,7 +187,7 @@ void read_settings_xml() using namespace pugi; // Check if settings.xml exists - std::string filename = std::string(path_input) + "settings.xml"; + std::string filename = path_input + "settings.xml"; if (!file_exists(filename)) { if (run_mode != RUN_MODE_PLOTTING) { std::stringstream msg; From a800f2976b2b98c9a04d8a5bf2ecc403fa0b90a9 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 6 Nov 2018 06:28:36 -0600 Subject: [PATCH 10/62] Move res_scat_nuclides to C++ --- include/openmc/cross_sections.h | 13 ++++++++++++- include/openmc/settings.h | 1 + src/api.F90 | 3 +++ src/cross_sections.cpp | 32 ++++++++++++++++++++++++-------- src/input_xml.F90 | 14 -------------- src/nuclide_header.F90 | 25 ++++++++++++++++++++++--- src/settings.F90 | 18 ------------------ src/settings.cpp | 21 +++++++++++++++++++-- 8 files changed, 81 insertions(+), 46 deletions(-) diff --git a/include/openmc/cross_sections.h b/include/openmc/cross_sections.h index eaa4f5632..2b7a94f80 100644 --- a/include/openmc/cross_sections.h +++ b/include/openmc/cross_sections.h @@ -9,6 +9,10 @@ namespace openmc { +//============================================================================== +// Library class +//============================================================================== + class Library { public: // Types, enums @@ -30,14 +34,21 @@ public: std::string path_; }; +//============================================================================== +// Global variable declarations +//============================================================================== + extern std::vector libraries; using LibraryKey = std::pair; extern std::map library_dict; +//============================================================================== +// Non-member functions +//============================================================================== extern "C" void read_cross_sections_xml(); void read_ce_cross_sections_xml(); -} +} // namespace openmc #endif // OPENMC_CROSS_SECTIONS_H diff --git a/include/openmc/settings.h b/include/openmc/settings.h index 47ca0f078..3296c5b20 100644 --- a/include/openmc/settings.h +++ b/include/openmc/settings.h @@ -77,6 +77,7 @@ extern "C" int n_max_batches; //!< Maximum number of batches extern "C" int res_scat_method; //!< resonance upscattering method extern "C" double res_scat_energy_min; //!< Min energy in [eV] for res. upscattering extern "C" double res_scat_energy_max; //!< Max energy in [eV] for res. upscattering +extern std::vector res_scat_nuclides; //!< Nuclides using res. upscattering treatment extern "C" int run_mode; //!< Run mode (eigenvalue, fixed src, etc.) extern std::unordered_set sourcepoint_batch; //!< Batches when source should be written extern std::unordered_set statepoint_batch; //!< Batches when state should be written diff --git a/src/api.F90 b/src/api.F90 index bb99180cc..efcfa16a6 100644 --- a/src/api.F90 +++ b/src/api.F90 @@ -79,6 +79,9 @@ contains subroutine free_memory_mesh() bind(C) end subroutine free_memory_mesh + + subroutine free_memory_settings() bind(C) + end subroutine free_memory_settings end interface call free_memory_geometry() diff --git a/src/cross_sections.cpp b/src/cross_sections.cpp index 94172f162..3cc4320fe 100644 --- a/src/cross_sections.cpp +++ b/src/cross_sections.cpp @@ -15,11 +15,19 @@ namespace openmc { +//============================================================================== +// Global variable declarations +//============================================================================== + std::vector libraries; std::map library_dict; extern "C" void read_mg_cross_sections_header(); +//============================================================================== +// Library methods +//============================================================================== + Library::Library(pugi::xml_node node, const std::string& directory) { // Get type of library @@ -64,6 +72,9 @@ Library::Library(pugi::xml_node node, const std::string& directory) } } +//============================================================================== +// Non-member functions +//============================================================================== void read_cross_sections_xml() { @@ -145,14 +156,15 @@ void read_cross_sections_xml() } // Check that 0K nuclides are listed in the cross_sections.xml file - // if (allocated(res_scat_nuclides)) { - // do i = 1, size(res_scat_nuclides) - // if (!library_dict % has(to_lower(res_scat_nuclides(i)))) { - // fatal_error("Could not find resonant scatterer " & - // // trim(res_scat_nuclides(i)) // " in cross_sections.xml file!") - // } - // end do - // } + for (const auto& name : settings::res_scat_nuclides) { + std::string lower_name = name; + to_lower(lower_name); + LibraryKey key {Library::Type::neutron, lower_name}; + if (library_dict.find(key) == library_dict.end()) { + fatal_error("Could not find resonant scatterer " + + name + " in cross_sections.xml file!"); + } + } } void read_ce_cross_sections_xml() @@ -196,6 +208,10 @@ void read_ce_cross_sections_xml() } } +//============================================================================== +// Fortran compatibility functions +//============================================================================== + extern "C" void library_clear() { libraries.clear(); library_dict.clear(); diff --git a/src/input_xml.F90 b/src/input_xml.F90 index fb8a8d772..fbd632906 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -223,20 +223,6 @@ contains ! Get proper XMLNode type given pointer root % ptr = root_ptr - ! Resonance scattering parameters - if (check_for_node(root, "resonance_scattering")) then - node_res_scat = root % child("resonance_scattering") - - ! Get nuclides that resonance scattering should be applied to - if (check_for_node(node_res_scat, "nuclides")) then - n = node_word_count(node_res_scat, "nuclides") - allocate(res_scat_nuclides(n)) - if (n > 0) then - call get_node_array(node_res_scat, "nuclides", res_scat_nuclides) - end if - end if - end if - call get_node_list(root, "volume_calc", node_vol_list) n = size(node_vol_list) allocate(volume_calcs(n)) diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index a506b623c..db4b13be6 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -240,11 +240,30 @@ contains integer :: i real(8) :: xs_cdf_sum + interface + function res_scat_nuclides_empty() result(empty) bind(C) + import C_BOOL + logical(C_BOOL) :: empty + end function + + function res_scat_nuclides_size() result(n) bind(C) + import C_INT + integer(C_INT) :: n + end function + + function res_scat_nuclides_cmp(i, name) result(b) bind(C) + import C_INT, C_CHAR, C_BOOL + integer(C_INT), value :: i + character(kind=C_CHAR), intent(in) :: name(*) + logical(C_BOOL) :: b + end function + end interface + this % resonant = .false. - if (allocated(res_scat_nuclides)) then + if (.not. res_scat_nuclides_empty()) then ! If resonant nuclides were specified, check the list explicitly - do i = 1, size(res_scat_nuclides) - if (this % name == res_scat_nuclides(i)) then + do i = 1, res_scat_nuclides_size() + if (res_scat_nuclides_cmp(i, to_c_string(this % name))) then this % resonant = .true. ! Make sure nuclide has 0K data diff --git a/src/settings.F90 b/src/settings.F90 index 19ec3f771..665c0e481 100644 --- a/src/settings.F90 +++ b/src/settings.F90 @@ -115,7 +115,6 @@ module settings integer(C_INT), bind(C) :: res_scat_method ! resonance scattering method real(C_DOUBLE), bind(C) :: res_scat_energy_min real(C_DOUBLE), bind(C) :: res_scat_energy_max - character(10), allocatable :: res_scat_nuclides(:) ! Is CMFD active logical(C_BOOL), bind(C) :: cmfd_run @@ -123,21 +122,4 @@ module settings ! No reduction at end of batch logical(C_BOOL), bind(C) :: reduce_tallies -contains - -!=============================================================================== -! FREE_MEMORY_SETTINGS deallocates global arrays defined in this module -!=============================================================================== - - subroutine free_memory_settings() - interface - subroutine free_memory_settings_c() bind(C) - end subroutine - end interface - - if (allocated(res_scat_nuclides)) deallocate(res_scat_nuclides) - - call free_memory_settings_c() - end subroutine free_memory_settings - end module settings diff --git a/src/settings.cpp b/src/settings.cpp index ce81c6b63..c1cd54c88 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -88,6 +88,7 @@ int n_max_batches; int res_scat_method {RES_SCAT_ARES}; double res_scat_energy_min {0.01}; double res_scat_energy_max {1000.0}; +std::vector res_scat_nuclides; int run_mode {-1}; std::unordered_set sourcepoint_batch; std::unordered_set statepoint_batch; @@ -749,7 +750,10 @@ void read_settings_xml() "lower resonance scattering energy bound."); } - // TODO: Get resonance scattering nuclides + // Get resonance scattering nuclides + if (check_for_node(node_res_scat, "nuclides")) { + res_scat_nuclides = get_node_array(node_res_scat, "nuclides"); + } } // TODO: Get volume calculations @@ -817,6 +821,18 @@ void read_settings_xml() //============================================================================== extern "C" { + bool res_scat_nuclides_empty() { + return settings::res_scat_nuclides.empty(); + } + + int res_scat_nuclides_size() { + return settings::res_scat_nuclides.size(); + } + + bool res_scat_nuclides_cmp(int i, const char* name) { + return settings::res_scat_nuclides[i - 1] == name; + } + const char* openmc_path_input() { return settings::path_input.c_str(); } @@ -830,9 +846,10 @@ extern "C" { return settings::path_particle_restart.c_str(); } - void free_memory_settings_c() { + void free_memory_settings() { settings::statepoint_batch.clear(); settings::sourcepoint_batch.clear(); + settings::res_scat_nuclides.clear(); } } From c2428608c1d7b894a3e1ad24ccb0e14f6a180381 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 6 Nov 2018 07:42:17 -0600 Subject: [PATCH 11/62] Support loading WMP using paths in cross_sections.xml --- src/cross_sections.cpp | 3 ++- src/initialize.F90 | 26 +++++++++++----------- src/input_xml.F90 | 49 +++++++++++++++++++++++++++++++----------- src/settings.cpp | 14 ++++++++---- 4 files changed, 62 insertions(+), 30 deletions(-) diff --git a/src/cross_sections.cpp b/src/cross_sections.cpp index 3cc4320fe..ebe9dc0e7 100644 --- a/src/cross_sections.cpp +++ b/src/cross_sections.cpp @@ -127,7 +127,8 @@ void read_cross_sections_xml() if (!check_for_node(root, "multipole_library")) { // No library location specified in materials.xml, check // environment variable - settings::path_multipole = std::getenv("OPENMC_MULTIPOLE_LIBRARY"); + char* envvar = std::getenv("OPENMC_MULTIPOLE_LIBRARY"); + if (envvar) settings::path_multipole = envvar; } else { settings::path_multipole = get_node_value(root, "multipole_library"); } diff --git a/src/initialize.F90 b/src/initialize.F90 index 4801a9064..45ed2047e 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -8,23 +8,23 @@ module initialize implicit none interface - function openmc_path_input() result(ptr) bind(C) + function path_input_c() result(ptr) bind(C) import C_PTR type(C_PTR) :: ptr end function - function openmc_path_output() result(ptr) bind(C) + function path_output_c() result(ptr) bind(C) import C_PTR type(C_PTR) :: ptr end function - function openmc_path_particle_restart() result(ptr) bind(C) + function path_particle_restart_c() result(ptr) bind(C) import C_PTR type(C_PTR) :: ptr end function - function openmc_path_statepoint() result(ptr) bind(C) + function path_statepoint_c() result(ptr) bind(C) import C_PTR type(C_PTR) :: ptr end function - function openmc_path_sourcepoint() result(ptr) bind(C) + function path_sourcepoint_c() result(ptr) bind(C) import C_PTR type(C_PTR) :: ptr end function @@ -49,22 +49,22 @@ contains end function is_null end interface - if (.not. is_null(openmc_path_input())) then - call c_f_pointer(openmc_path_input(), string, [255]) + if (.not. is_null(path_input_c())) then + call c_f_pointer(path_input_c(), string, [255]) path_input = to_f_string(string) else path_input = '' end if - if (.not. is_null(openmc_path_statepoint())) then - call c_f_pointer(openmc_path_statepoint(), string, [255]) + if (.not. is_null(path_statepoint_c())) then + call c_f_pointer(path_statepoint_c(), string, [255]) path_state_point = to_f_string(string) end if - if (.not. is_null(openmc_path_sourcepoint())) then - call c_f_pointer(openmc_path_sourcepoint(), string, [255]) + if (.not. is_null(path_sourcepoint_c())) then + call c_f_pointer(path_sourcepoint_c(), string, [255]) path_source_point = to_f_string(string) end if - if (.not. is_null(openmc_path_particle_restart())) then - call c_f_pointer(openmc_path_particle_restart(), string, [255]) + if (.not. is_null(path_particle_restart_c())) then + call c_f_pointer(path_particle_restart_c(), string, [255]) path_particle_restart = to_f_string(string) end if end subroutine read_command_line diff --git a/src/input_xml.F90 b/src/input_xml.F90 index fbd632906..06beee34e 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -216,7 +216,6 @@ contains integer :: i integer :: n type(XMLNode) :: root - type(XMLNode) :: node_res_scat type(XMLNode) :: node_vol type(XMLNode), allocatable :: node_vol_list(:) @@ -540,7 +539,6 @@ contains integer :: k ! loop index integer :: n ! number of nuclides integer :: n_sab ! number of sab tables for a material - integer :: i_library ! index in libraries array integer :: index_nuclide ! index in nuclides integer :: index_element ! index in elements integer :: index_sab ! index in sab_tables @@ -1913,14 +1911,23 @@ contains logical :: file_exists ! does mgxs.h5 exist? integer(HID_T) :: file_id character(len=MAX_WORD_LEN), allocatable :: names(:) + character(kind=C_CHAR), pointer :: string(:) interface subroutine read_mg_cross_sections_header_c(file_id) bind(C) import HID_T integer(HID_T), value :: file_id end subroutine + + function path_cross_sections_c() result(ptr) bind(C) + import C_PTR + type(C_PTR) :: ptr + end function end interface + call c_f_pointer(path_cross_sections_c(), string, [255]) + path_cross_sections = to_f_string(string) + ! Check if MGXS Library exists inquire(FILE=path_cross_sections, EXIST=file_exists) if (.not. file_exists) then @@ -2075,7 +2082,6 @@ contains type(VectorReal), intent(in) :: sab_temps(:) integer :: i, j - integer :: i_library integer :: i_nuclide integer :: i_element integer :: i_sab @@ -2304,20 +2310,38 @@ contains logical :: file_exists ! Does multipole library exist? character(7) :: readable ! Is multipole library readable? character(MAX_FILE_LEN) :: filename ! Path to multipole xs library + character(kind=C_CHAR), pointer :: string(:) integer(HID_T) :: file_id integer(HID_T) :: group_id - ! For the time being, and I know this is a bit hacky, we just assume - ! that the file will be ZZZAAAmM.h5. + interface + function path_multipole_c() result(ptr) bind(C) + import C_PTR + type(C_PTR) :: ptr + end function + end interface + associate (nuc => nuclides(i_table)) - if (nuc % metastable > 0) then - filename = trim(path_multipole) // trim(zero_padded(nuc % Z, 3)) // & - trim(zero_padded(nuc % A, 3)) // 'm' // & - trim(to_str(nuc % metastable)) // ".h5" + if (library_present(LIBRARY_WMP, to_lower(nuc % name))) then + ! If WMP data is listed in cross_sections.xml, prefer that + filename = library_path(LIBRARY_WMP, to_lower(nuc % name)) else - filename = trim(path_multipole) // trim(zero_padded(nuc % Z, 3)) // & - trim(zero_padded(nuc % A, 3)) // ".h5" + ! Otherwise, we rely on the OPENMC_MULTIPOLE_LIBRARY environment + ! variable. This is a bit hacky, but we just assume that the file will be + ! ZZZAAAmM.h5. + + call c_f_pointer(path_multipole_c(), string, [255]) + path_multipole = to_f_string(string) + + if (nuc % metastable > 0) then + filename = trim(path_multipole) // trim(zero_padded(nuc % Z, 3)) // & + trim(zero_padded(nuc % A, 3)) // 'm' // & + trim(to_str(nuc % metastable)) // ".h5" + else + filename = trim(path_multipole) // trim(zero_padded(nuc % Z, 3)) // & + trim(zero_padded(nuc % A, 3)) // ".h5" + end if end if ! Check if Multipole library exists and is readable @@ -2331,7 +2355,8 @@ contains end if ! Display message - call write_message("Loading Windowed Multipole XS from " // filename, 6) + call write_message("Reading " // trim(nuc % name) // " WMP data from " & + // filename, 6) ! Open file and make sure version is sufficient file_id = file_open(filename, 'r') diff --git a/src/settings.cpp b/src/settings.cpp index c1cd54c88..0d67137bc 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -833,16 +833,22 @@ extern "C" { return settings::res_scat_nuclides[i - 1] == name; } - const char* openmc_path_input() { + const char* path_cross_sections_c() { + return settings::path_cross_sections.c_str(); + } + const char* path_input_c() { return settings::path_input.c_str(); } - const char* openmc_path_statepoint() { + const char* path_multipole_c() { + return settings::path_multipole.c_str(); + } + const char* path_statepoint_c() { return settings::path_statepoint.c_str(); } - const char* openmc_path_sourcepoint() { + const char* path_sourcepoint_c() { return settings::path_sourcepoint.c_str(); } - const char* openmc_path_particle_restart() { + const char* path_particle_restart_c() { return settings::path_particle_restart.c_str(); } From de666e3291a4804fa207ee1c884ddcbb1911998d Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 6 Nov 2018 09:52:18 -0600 Subject: [PATCH 12/62] Make sure MG materials get put in libraries --- include/openmc/cross_sections.h | 1 + src/hdf5_interface.cpp | 2 +- src/input_xml.F90 | 12 ------------ src/mgxs_interface.cpp | 15 +++++++++++++++ 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/include/openmc/cross_sections.h b/include/openmc/cross_sections.h index 2b7a94f80..72e89692c 100644 --- a/include/openmc/cross_sections.h +++ b/include/openmc/cross_sections.h @@ -21,6 +21,7 @@ public: }; // Constructors + Library() { }; Library(pugi::xml_node node, const std::string& directory); // Comparison operator (for using in map) diff --git a/src/hdf5_interface.cpp b/src/hdf5_interface.cpp index 4b0aedd0a..865b6eb20 100644 --- a/src/hdf5_interface.cpp +++ b/src/hdf5_interface.cpp @@ -362,7 +362,7 @@ member_names(hid_t group_id, H5O_type_t type) char buffer[size]; H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, i, buffer, size, H5P_DEFAULT); - names.emplace_back(&buffer[0], size); + names.emplace_back(&buffer[0]); } return names; } diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 06beee34e..8dc745203 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -1907,10 +1907,8 @@ contains subroutine read_mg_cross_sections_header() bind(C) integer :: i ! loop index - integer :: n_libraries logical :: file_exists ! does mgxs.h5 exist? integer(HID_T) :: file_id - character(len=MAX_WORD_LEN), allocatable :: names(:) character(kind=C_CHAR), pointer :: string(:) interface @@ -1984,16 +1982,6 @@ contains call set_particle_energy_bounds(NEUTRON, energy_min(NEUTRON), & energy_max(NEUTRON)) - ! Get the datasets present in the library - call get_groups(file_id, names) - n_libraries = size(names) - - ! Allocate libraries array - if (n_libraries == 0) then - call fatal_error("At least one MGXS data set must be present in & - &mgxs library file!") - end if - ! Close MGXS HDF5 file call file_close(file_id) diff --git a/src/mgxs_interface.cpp b/src/mgxs_interface.cpp index 0729e466c..9b320c4e1 100644 --- a/src/mgxs_interface.cpp +++ b/src/mgxs_interface.cpp @@ -2,6 +2,7 @@ #include +#include "openmc/cross_sections.h" #include "openmc/error.h" #include "openmc/math_functions.h" @@ -109,6 +110,20 @@ void read_mg_cross_sections_header_c(hid_t file_id) for (int i = 0; i < energy_bins.size() - 1; ++i) { energy_bin_avg.push_back(0.5*(energy_bins[i] + energy_bins[i+1])); } + + // Add entries into libraries for MG data + auto names = group_names(file_id); + if (names.empty()) { + fatal_error("At least one MGXS data set must be present in mgxs " + "library file!"); + } + + for (auto& name : names) { + Library lib {}; + lib.type_ = Library::Type::neutron; + lib.materials_.push_back(name); + libraries.push_back(lib); + } } //============================================================================== From 7d6ab8d72d7a4d78ea85825a124b6b69e7d00590 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 6 Nov 2018 10:11:48 -0600 Subject: [PATCH 13/62] Put library and library_map in data namespace --- include/openmc/cross_sections.h | 22 +++++++++++++++++----- src/cross_sections.cpp | 32 ++++++++++++++++++-------------- src/mgxs_interface.cpp | 2 +- 3 files changed, 36 insertions(+), 20 deletions(-) diff --git a/include/openmc/cross_sections.h b/include/openmc/cross_sections.h index 72e89692c..d8a3799c5 100644 --- a/include/openmc/cross_sections.h +++ b/include/openmc/cross_sections.h @@ -30,24 +30,36 @@ public: } // Data members - Type type_; - std::vector materials_; - std::string path_; + Type type_; //!< Type of data library + std::vector materials_; //!< Materials contained in library + std::string path_; //!< File path to library }; +using LibraryKey = std::pair; + //============================================================================== // Global variable declarations //============================================================================== +namespace data { + +//!< Data libraries extern std::vector libraries; -using LibraryKey = std::pair; -extern std::map library_dict; + +//! Maps (type, name) to index in libraries +extern std::map library_map; + +} // namespace data //============================================================================== // Non-member functions //============================================================================== +//! Read cross sections file (either XML or multigroup H5) and populate data +//! libraries extern "C" void read_cross_sections_xml(); + +//! Read cross_sections.xml and populate data libraries void read_ce_cross_sections_xml(); } // namespace openmc diff --git a/src/cross_sections.cpp b/src/cross_sections.cpp index ebe9dc0e7..aca46a5b9 100644 --- a/src/cross_sections.cpp +++ b/src/cross_sections.cpp @@ -19,10 +19,12 @@ namespace openmc { // Global variable declarations //============================================================================== -std::vector libraries; -std::map library_dict; +namespace data { -extern "C" void read_mg_cross_sections_header(); +std::vector libraries; +std::map library_map; + +} //============================================================================== // Library methods @@ -76,6 +78,8 @@ Library::Library(pugi::xml_node node, const std::string& directory) // Non-member functions //============================================================================== +extern "C" void read_mg_cross_sections_header(); + void read_cross_sections_xml() { // Check if materials.xml exists @@ -146,12 +150,12 @@ void read_cross_sections_xml() // Establish mapping between (type, material) and index in libraries int i = 0; - for (const auto& lib : libraries) { + for (const auto& lib : data::libraries) { for (const auto& name : lib.materials_) { std::string lower_name = name; to_lower(lower_name); LibraryKey key {lib.type_, lower_name}; - library_dict.insert({key, i}); + data::library_map.insert({key, i}); } ++i; } @@ -161,7 +165,7 @@ void read_cross_sections_xml() std::string lower_name = name; to_lower(lower_name); LibraryKey key {Library::Type::neutron, lower_name}; - if (library_dict.find(key) == library_dict.end()) { + if (data::library_map.find(key) == data::library_map.end()) { fatal_error("Could not find resonant scatterer " + name + " in cross_sections.xml file!"); } @@ -200,11 +204,11 @@ void read_ce_cross_sections_xml() } for (const auto& node_library : root.children("library")) { - libraries.emplace_back(node_library, directory); + data::libraries.emplace_back(node_library, directory); } // Make sure file was not empty - if (libraries.empty()) { + if (data::libraries.empty()) { fatal_error("No cross section libraries present in cross_sections.xml file."); } } @@ -214,25 +218,25 @@ void read_ce_cross_sections_xml() //============================================================================== extern "C" void library_clear() { - libraries.clear(); - library_dict.clear(); + data::libraries.clear(); + data::library_map.clear(); } extern "C" const char* library_path(int type, const char* name) { auto lib_type = static_cast(type); LibraryKey key {lib_type, name}; - if (library_dict.find(key) == library_dict.end()) { + if (data::library_map.find(key) == data::library_map.end()) { return nullptr; } else { - auto idx = library_dict[key]; - return libraries[idx].path_.c_str(); + auto idx = data::library_map[key]; + return data::libraries[idx].path_.c_str(); } } extern "C" bool library_present(int type, const char* name) { auto lib_type = static_cast(type); LibraryKey key {lib_type, name}; - return library_dict.find(key) != library_dict.end(); + return data::library_map.find(key) != data::library_map.end(); } } // namespace openmc diff --git a/src/mgxs_interface.cpp b/src/mgxs_interface.cpp index 9b320c4e1..80aa66621 100644 --- a/src/mgxs_interface.cpp +++ b/src/mgxs_interface.cpp @@ -122,7 +122,7 @@ void read_mg_cross_sections_header_c(hid_t file_id) Library lib {}; lib.type_ = Library::Type::neutron; lib.materials_.push_back(name); - libraries.push_back(lib); + data::libraries.push_back(lib); } } From 97634d59ad430fca171b9577ad95189c2aaa79e7 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 6 Nov 2018 10:23:11 -0600 Subject: [PATCH 14/62] Combined string_functions.h and string_utils.h --- CMakeLists.txt | 2 +- include/openmc/string_functions.h | 20 -------- include/openmc/string_utils.h | 39 +++------------- src/cross_sections.cpp | 1 - src/dagmc.cpp | 2 +- src/mgxs.cpp | 2 +- src/plot.cpp | 2 +- src/string_functions.cpp | 40 ---------------- src/string_utils.cpp | 78 +++++++++++++++++++++++++++++++ src/surface.cpp | 2 +- 10 files changed, 90 insertions(+), 98 deletions(-) delete mode 100644 include/openmc/string_functions.h delete mode 100644 src/string_functions.cpp create mode 100644 src/string_utils.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e76ed9a9e..bb5c45c42 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -426,7 +426,7 @@ add_library(libopenmc SHARED src/simulation.cpp src/source.cpp src/state_point.cpp - src/string_functions.cpp + src/string_utils.cpp src/summary.cpp src/surface.cpp src/tallies/filter.cpp diff --git a/include/openmc/string_functions.h b/include/openmc/string_functions.h deleted file mode 100644 index a653d1e77..000000000 --- a/include/openmc/string_functions.h +++ /dev/null @@ -1,20 +0,0 @@ -//! \file string_functions.h -//! A collection of helper routines for C-strings and STL strings - -#ifndef OPENMC_STRING_FUNCTIONS_H -#define OPENMC_STRING_FUNCTIONS_H - -#include - -namespace openmc { - -std::string& strtrim(std::string& s); - -char* strtrim(char* c_str); - -void to_lower(std::string& str); - -int word_count(std::string const& str); - -} // namespace openmc -#endif // STRING_FUNCTIONS_H diff --git a/include/openmc/string_utils.h b/include/openmc/string_utils.h index 73b1a28ec..35c25e548 100644 --- a/include/openmc/string_utils.h +++ b/include/openmc/string_utils.h @@ -1,49 +1,24 @@ #ifndef OPENMC_STRING_UTILS_H #define OPENMC_STRING_UTILS_H -#include #include #include namespace openmc { -inline std::vector -split(const std::string& in) -{ - std::vector out; +std::string& strtrim(std::string& s); - for (int i = 0; i < in.size(); ) { - // Increment i until we find a non-whitespace character. - if (std::isspace(in[i])) { - i++; +char* strtrim(char* c_str); - } else { - // Find the next whitespace character at j. - int j = i + 1; - while (j < in.size() && std::isspace(in[j]) == 0) {j++;} +void to_lower(std::string& str); - // Push-back everything between i and j. - out.push_back(in.substr(i, j-i)); - i = j + 1; // j is whitespace so leapfrog to j+1 - } - } +int word_count(std::string const& str); - return out; -} +std::vector split(const std::string& in); -inline bool -ends_with(const std::string& value, const std::string& ending) -{ - if (ending.size() > value.size()) return false; - return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); -} +bool ends_with(const std::string& value, const std::string& ending); -inline bool -starts_with(const std::string& value, const std::string& beginning) -{ - if (beginning.size() > value.size()) return false; - return std::equal(beginning.begin(), beginning.end(), value.begin()); -} +bool starts_with(const std::string& value, const std::string& beginning); } // namespace openmc #endif // OPENMC_STRING_UTILS_H diff --git a/src/cross_sections.cpp b/src/cross_sections.cpp index aca46a5b9..dbfe41679 100644 --- a/src/cross_sections.cpp +++ b/src/cross_sections.cpp @@ -5,7 +5,6 @@ #include "openmc/error.h" #include "openmc/file_utils.h" #include "openmc/settings.h" -#include "openmc/string_functions.h" #include "openmc/string_utils.h" #include "openmc/xml_interface.h" diff --git a/src/dagmc.cpp b/src/dagmc.cpp index d4e113977..7c1127867 100644 --- a/src/dagmc.cpp +++ b/src/dagmc.cpp @@ -1,7 +1,7 @@ #include "openmc/dagmc.h" #include "openmc/error.h" -#include "openmc/string_functions.h" +#include "openmc/string_utils.h" #include "openmc/settings.h" #include "openmc/geometry.h" diff --git a/src/mgxs.cpp b/src/mgxs.cpp index 1b6e85ffb..8c14f324e 100644 --- a/src/mgxs.cpp +++ b/src/mgxs.cpp @@ -17,7 +17,7 @@ #include "openmc/error.h" #include "openmc/math_functions.h" #include "openmc/random_lcg.h" -#include "openmc/string_functions.h" +#include "openmc/string_utils.h" namespace openmc { diff --git a/src/plot.cpp b/src/plot.cpp index 7b0cddb63..9a8aba139 100644 --- a/src/plot.cpp +++ b/src/plot.cpp @@ -9,7 +9,7 @@ #include "openmc/geometry.h" #include "openmc/cell.h" #include "openmc/material.h" -#include "openmc/string_functions.h" +#include "openmc/string_utils.h" #include "openmc/mesh.h" #include "openmc/output.h" #include "openmc/hdf5_interface.h" diff --git a/src/string_functions.cpp b/src/string_functions.cpp deleted file mode 100644 index 27e14c9ba..000000000 --- a/src/string_functions.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "openmc/string_functions.h" -#include - -namespace openmc { - -std::string& strtrim(std::string& s) -{ - const char* t = " \t\n\r\f\v"; - s.erase(s.find_last_not_of(t) + 1); - s.erase(0, s.find_first_not_of(t)); - return s; -} - - -char* strtrim(char* c_str) -{ - std::string std_str; - std_str.assign(c_str); - strtrim(std_str); - int length = std_str.copy(c_str, std_str.size()); - c_str[length] = '\0'; - return c_str; -} - - -void to_lower(std::string& str) -{ - for (int i = 0; i < str.size(); i++) str[i] = std::tolower(str[i]); -} - -int word_count(std::string const& str) -{ - std::stringstream stream(str); - std::string dum; - int count = 0; - while (stream >> dum) {count++;} - return count; -} - -} // namespace openmc diff --git a/src/string_utils.cpp b/src/string_utils.cpp new file mode 100644 index 000000000..c1a203e48 --- /dev/null +++ b/src/string_utils.cpp @@ -0,0 +1,78 @@ +#include "openmc/string_utils.h" + +#include // for equal +#include // for tolower, isspace +#include + +namespace openmc { + +std::string& strtrim(std::string& s) +{ + const char* t = " \t\n\r\f\v"; + s.erase(s.find_last_not_of(t) + 1); + s.erase(0, s.find_first_not_of(t)); + return s; +} + + +char* strtrim(char* c_str) +{ + std::string std_str; + std_str.assign(c_str); + strtrim(std_str); + int length = std_str.copy(c_str, std_str.size()); + c_str[length] = '\0'; + return c_str; +} + + +void to_lower(std::string& str) +{ + for (int i = 0; i < str.size(); i++) str[i] = std::tolower(str[i]); +} + +int word_count(std::string const& str) +{ + std::stringstream stream(str); + std::string dum; + int count = 0; + while (stream >> dum) {count++;} + return count; +} + +std::vector split(const std::string& in) +{ + std::vector out; + + for (int i = 0; i < in.size(); ) { + // Increment i until we find a non-whitespace character. + if (std::isspace(in[i])) { + i++; + + } else { + // Find the next whitespace character at j. + int j = i + 1; + while (j < in.size() && std::isspace(in[j]) == 0) {j++;} + + // Push-back everything between i and j. + out.push_back(in.substr(i, j-i)); + i = j + 1; // j is whitespace so leapfrog to j+1 + } + } + + return out; +} + +bool ends_with(const std::string& value, const std::string& ending) +{ + if (ending.size() > value.size()) return false; + return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); +} + +bool starts_with(const std::string& value, const std::string& beginning) +{ + if (beginning.size() > value.size()) return false; + return std::equal(beginning.begin(), beginning.end(), value.begin()); +} + +} // namespace openmc diff --git a/src/surface.cpp b/src/surface.cpp index 265a2f02c..66217a58b 100644 --- a/src/surface.cpp +++ b/src/surface.cpp @@ -8,7 +8,7 @@ #include "openmc/error.h" #include "openmc/hdf5_interface.h" #include "openmc/xml_interface.h" -#include "openmc/string_functions.h" +#include "openmc/string_utils.h" namespace openmc { From e5f3fa675efbde3744feb6529b9408c7f1a4596a Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 6 Nov 2018 11:12:39 -0600 Subject: [PATCH 15/62] Fix indentation in Fortran files --- src/input_xml.F90 | 6 +++--- src/material_header.F90 | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 8dc745203..d9f451e4f 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -2324,11 +2324,11 @@ contains if (nuc % metastable > 0) then filename = trim(path_multipole) // trim(zero_padded(nuc % Z, 3)) // & - trim(zero_padded(nuc % A, 3)) // 'm' // & - trim(to_str(nuc % metastable)) // ".h5" + trim(zero_padded(nuc % A, 3)) // 'm' // & + trim(to_str(nuc % metastable)) // ".h5" else filename = trim(path_multipole) // trim(zero_padded(nuc % Z, 3)) // & - trim(zero_padded(nuc % A, 3)) // ".h5" + trim(zero_padded(nuc % A, 3)) // ".h5" end if end if diff --git a/src/material_header.F90 b/src/material_header.F90 index 8a294dd04..3bcf96db8 100644 --- a/src/material_header.F90 +++ b/src/material_header.F90 @@ -197,7 +197,7 @@ contains do i = 1, this % n_nuclides awr = nuclides(this % nuclide(i)) % awr this % density_gpcc = this % density_gpcc & - + this % atom_density(i) * awr * MASS_NEUTRON / N_AVOGADRO + + this % atom_density(i) * awr * MASS_NEUTRON / N_AVOGADRO end do case ('g/cm3', 'g/cc') ! Determine factor by which to change densities From ffdd37c16317781cc1d8791de66ac44e0fba700b Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 6 Nov 2018 13:20:33 -0600 Subject: [PATCH 16/62] Create redundant transmutation reactions when converting ACE files --- openmc/data/neutron.py | 62 +++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index 1856a13d4..c3f925152 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -480,9 +480,12 @@ class IncidentNeutron(EqualityMixin): tgroup = g.create_group('total_nu') rx.derived_products[0].to_hdf5(tgroup) - # Write redundant reaction data only for reactions with photon production + # Write redundant reaction data only for reactions with photon + # production or transmutation reactions for rx in self.redundant_reactions.values(): - if any(p.particle == 'photon' for p in rx.products): + photon_rx = any(p.particle == 'photon' for p in rx.products) + transmutation_rx = (rx.mt in (16, 103, 104, 105, 106, 107)) + if photon_rx or transmutation_rx: rx_group = rxs_group.create_group('reaction_{:03}'.format(rx.mt)) rx.to_hdf5(rx_group) @@ -683,22 +686,31 @@ class IncidentNeutron(EqualityMixin): continue # Create redundant reaction with appropriate cross section - rx = Reaction(mt) mts = data.get_reaction_components(mt) if len(mts) == 0: warn('Photon production is present for MT={} but no ' 'reaction components exist.'.format(mt)) continue - xss = [data.reactions[mt_i].xs[strT] for mt_i in mts] - idx = min([xs._threshold_idx if hasattr(xs, '_threshold_idx') - else 0 for xs in xss]) - rx.xs[strT] = Tabulated1D(energy[idx:], Sum(xss)(energy[idx:])) - rx.xs[strT]._threshold_idx = idx - rx.redundant = True + # Determine redundant cross section + rx = data._get_redundant_reaction(mt, mts) + rx.products += _get_photon_products_ace(ace, rx) + data.redundant_reactions[mt] = rx + + # For transmutation reactions, sometimes only individual levels are + # present in an ACE file, e.g. MT=600-649 instead of the summation + # MT=103. In this case, if a user wants to tally (n,p), OpenMC doesn't + # know about the total cross section. Here, we explicitly create a + # redundant reaction for this purpose. + for mt in (16, 103, 104, 105, 106, 107): + if mt not in data: + # Determine if any individual levels are present + mts = data.get_reaction_components(mt) + if len(mts) == 0: + continue # Determine redundant cross section - rx.products += _get_photon_products_ace(ace, rx) + rx = data._get_redundant_reaction(mt, mts) data.redundant_reactions[mt] = rx # Read unresolved resonance probability tables @@ -842,3 +854,33 @@ class IncidentNeutron(EqualityMixin): data[2].xs['0K'] = xs return data + + def _get_redundant_reaction(self, mt, mts): + """Create redundant reaction from its components + + Parameters + ---------- + mt : int + MT value of the desired reaction + mts : iterable of int + MT values of its components + + Returns + ------- + openmc.Reaction + Redundant reaction + + """ + # Get energy grid + strT = self.temperatures[0] + energy = self.energy[strT] + + rx = Reaction(mt) + xss = [self.reactions[mt_i].xs[strT] for mt_i in mts] + idx = min([xs._threshold_idx if hasattr(xs, '_threshold_idx') + else 0 for xs in xss]) + rx.xs[strT] = Tabulated1D(energy[idx:], Sum(xss)(energy[idx:])) + rx.xs[strT]._threshold_idx = idx + rx.redundant = True + + return rx From 3246a9320edba7f9b9108dcfadaf3a820343358d Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 9 Nov 2018 16:39:19 -0600 Subject: [PATCH 17/62] Remove option to specify multipole library outside of cross_sections.xml --- .travis.yml | 1 - docs/source/devguide/tests.rst | 10 ++--- docs/source/io_formats/materials.rst | 15 -------- docs/source/usersguide/cross_sections.rst | 17 +++----- include/openmc/settings.h | 3 +- man/man1/openmc.1 | 5 --- openmc/material.py | 24 ------------ openmc/settings.py | 1 - scripts/openmc-make-test-data | 47 +++++++++++++++-------- src/cross_sections.cpp | 15 -------- src/input_xml.F90 | 31 +++------------ src/relaxng/materials.rnc | 4 +- src/relaxng/materials.rng | 7 ---- src/settings.F90 | 1 - src/settings.cpp | 21 +--------- tests/regression_tests/diff_tally/test.py | 3 -- tests/regression_tests/multipole/test.py | 3 -- tests/unit_tests/test_data_multipole.py | 16 ++++---- tests/unit_tests/test_material.py | 2 - tests/unit_tests/test_settings.py | 1 - 20 files changed, 57 insertions(+), 170 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4939f807c..eacf3bb43 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,7 +30,6 @@ env: - OMP_NUM_THREADS=2 - OPENMC_CROSS_SECTIONS=$HOME/nndc_hdf5/cross_sections.xml - OPENMC_ENDF_DATA=$HOME/endf-b-vii.1 - - OPENMC_MULTIPOLE_LIBRARY=$HOME/WMP_Library - LD_LIBRARY_PATH=$HOME/MOAB/lib:$HOME/DAGMC/lib - PATH=$PATH:$HOME/NJOY2016/build - DISPLAY=:99.0 diff --git a/docs/source/devguide/tests.rst b/docs/source/devguide/tests.rst index 749737b5c..475d0f69b 100644 --- a/docs/source/devguide/tests.rst +++ b/docs/source/devguide/tests.rst @@ -30,11 +30,11 @@ or using pip (recommended):: pip install -e .[test] It is also assumed that you have cross section data available that is pointed to -by the :envvar:`OPENMC_CROSS_SECTIONS` and :envvar:`OPENMC_MULTIPOLE_LIBRARY` -environment variables. Furthermore, to run unit tests for the :mod:`openmc.data` -module, it is necessary to have ENDF/B-VII.1 data available and pointed to by -the :envvar:`OPENMC_ENDF_DATA` environment variable. All data sources can be -obtained using the ``tools/ci/travis-before-script.sh`` script. +by the :envvar:`OPENMC_CROSS_SECTIONS` environment variables. Furthermore, to +run unit tests for the :mod:`openmc.data` module, it is necessary to have +ENDF/B-VII.1 data available and pointed to by the :envvar:`OPENMC_ENDF_DATA` +environment variable. All data sources can be obtained using the +``tools/ci/travis-before-script.sh`` script. To execute the test suite, go to the ``tests/`` directory and run:: diff --git a/docs/source/io_formats/materials.rst b/docs/source/io_formats/materials.rst index 322b9c999..cd198d006 100644 --- a/docs/source/io_formats/materials.rst +++ b/docs/source/io_formats/materials.rst @@ -18,21 +18,6 @@ path to the XML cross section listing when in continuous-energy mode, and the :envvar:`OPENMC_MG_CROSS_SECTIONS` environment variable will be used in multi-group mode. -.. _multipole_library: - -------------------------------- -```` Element -------------------------------- - -The ```` element indicates the directory containing a -windowed multipole library. If a windowed multipole library is available, -OpenMC can use it for on-the-fly Doppler-broadening of resolved resonance range -cross sections. If this element is absent from the settings.xml file, the -:envvar:`OPENMC_MULTIPOLE_LIBRARY` environment variable will be used. - - .. note:: The element must also be set to "true" for - windowed multipole functionality. - .. _material: ---------------------- diff --git a/docs/source/usersguide/cross_sections.rst b/docs/source/usersguide/cross_sections.rst index 7e596c72f..a5adb3dcc 100644 --- a/docs/source/usersguide/cross_sections.rst +++ b/docs/source/usersguide/cross_sections.rst @@ -41,11 +41,6 @@ following environment variables are used: user has not specified :attr:`Materials.cross_sections` (equivalently, the :ref:`cross_sections` in :ref:`materials.xml `). -:envvar:`OPENMC_MULTIPOLE_LIBRARY` - Indicates the path to a directory containing windowed multipole data if the - user has not specified :attr:`Materials.multipole_library` (equivalently, the - :ref:`multipole_library` in :ref:`materials.xml `) - :envvar:`OPENMC_MG_CROSS_SECTIONS` Indicates the path to the an :ref:`HDF5 file ` that contains multi-group cross sections if the user has not specified @@ -306,12 +301,12 @@ Windowed Multipole Data ----------------------- OpenMC is capable of using windowed multipole data for on-the-fly Doppler -broadening. While such data is not yet available for all nuclides, an -experimental multipole library is available that contains data for 70 -nuclides. To obtain this library, you can run :ref:`scripts_multipole` which -will download and extract it into a ``wmp`` directory. Once the library has been -downloaded, set the :envvar:`OPENMC_MULTIPOLE_LIBRARY` environment variable (or -the :attr:`Materials.multipole_library` attribute) to the ``wmp`` directory. +broadening. A comprehensive multipole data library containing all nuclides in +ENDF/B-VII.1 is available on `GitHub +`_. To obtain this library, download +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`. -------------------------- Multi-Group Cross Sections diff --git a/include/openmc/settings.h b/include/openmc/settings.h index 3296c5b20..06cc1ab90 100644 --- a/include/openmc/settings.h +++ b/include/openmc/settings.h @@ -52,7 +52,6 @@ extern "C" bool dagmc; //!< indicator of DAGMC geometry // Paths to various files extern std::string path_cross_sections; //!< path to cross_sections.xml extern std::string path_input; //!< directory where main .xml files resides -extern std::string path_multipole; //!< directory containing multipole files extern std::string path_output; //!< directory where output files are written extern std::string path_particle_restart; //!< path to a particle restart file extern std::string path_source; @@ -62,7 +61,7 @@ extern std::string path_statepoint; //!< path to a statepoint file extern "C" int32_t index_entropy_mesh; //!< Index of entropy mesh in global mesh array extern "C" int32_t index_ufs_mesh; //!< Index of UFS mesh in global mesh array extern "C" int32_t index_cmfd_mesh; //!< Index of CMFD mesh in global mesh array - + extern "C" int32_t n_batches; //!< number of (inactive+active) batches extern "C" int32_t n_inactive; //!< number of inactive batches extern "C" int32_t gen_per_batch; //!< number of generations per batch diff --git a/man/man1/openmc.1 b/man/man1/openmc.1 index eb5c857f7..f574ea10a 100644 --- a/man/man1/openmc.1 +++ b/man/man1/openmc.1 @@ -53,11 +53,6 @@ to locate HDF5 format cross section libraries if the user has not specified the Indicates the default path to an HDF5 file that contains multi-group cross section libraries if the user has not specified the tag in .I materials.xml\fP. -.TP -.B OPENMC_MULTIPOLE_LIBRARY -Indicates the default path to a directory containing windowed multipole data if -the user has not specified the tag in -.I materials.xml\fP. .SH LICENSE Copyright \(co 2011-2018 Massachusetts Institute of Technology and OpenMC contributors. diff --git a/openmc/material.py b/openmc/material.py index d11f9de49..612a7dfb6 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -989,18 +989,12 @@ class Materials(cv.CheckedList): continuous-energy calculations and :envvar:`OPENMC_MG_CROSS_SECTIONS` will be used for multi-group calculations to find the path to the HDF5 cross section file. - multipole_library : str - Indicates the path to a directory containing a windowed multipole - cross section library. If it is not set, the - :envvar:`OPENMC_MULTIPOLE_LIBRARY` environment variable will be used. A - multipole library is optional. """ def __init__(self, materials=None): super().__init__(Material, 'materials collection') self._cross_sections = None - self._multipole_library = None if materials is not None: self += materials @@ -1009,20 +1003,11 @@ class Materials(cv.CheckedList): def cross_sections(self): return self._cross_sections - @property - def multipole_library(self): - return self._multipole_library - @cross_sections.setter def cross_sections(self, cross_sections): cv.check_type('cross sections', cross_sections, str) self._cross_sections = cross_sections - @multipole_library.setter - def multipole_library(self, multipole_library): - cv.check_type('cross sections', multipole_library, str) - self._multipole_library = multipole_library - def append(self, material): """Append material to collection @@ -1060,11 +1045,6 @@ class Materials(cv.CheckedList): element = ET.SubElement(root_element, "cross_sections") element.text = str(self._cross_sections) - def _create_multipole_library_subelement(self, root_element): - if self._multipole_library is not None: - element = ET.SubElement(root_element, "multipole_library") - element.text = str(self._multipole_library) - def export_to_xml(self, path='materials.xml'): """Export material collection to an XML file. @@ -1077,7 +1057,6 @@ class Materials(cv.CheckedList): root_element = ET.Element("materials") self._create_cross_sections_subelement(root_element) - self._create_multipole_library_subelement(root_element) self._create_material_subelements(root_element) # Clean the indentation in the file to be user-readable @@ -1114,8 +1093,5 @@ class Materials(cv.CheckedList): xs = tree.find('cross_sections') if xs is not None: materials.cross_sections = xs.text - mpl = tree.find('multipole_library') - if mpl is not None: - materials.multipole_library = mpl.text return materials diff --git a/openmc/settings.py b/openmc/settings.py index e0f3634e7..578a8171e 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -180,7 +180,6 @@ class Settings(object): self._confidence_intervals = None self._cross_sections = None self._electron_treatment = None - self._multipole_library = None self._photon_transport = None self._ptables = None self._run_cmfd = None diff --git a/scripts/openmc-make-test-data b/scripts/openmc-make-test-data index f2ae118c1..a37a78fa9 100755 --- a/scripts/openmc-make-test-data +++ b/scripts/openmc-make-test-data @@ -1,9 +1,10 @@ #!/usr/bin/env python3 """ -Download ENDF/B-VII.1 ENDF and ACE files from NNDC and generate a full HDF5 -library with incident neutron, incident photon, and thermal scattering data. -This data is used for OpenMC's regression test suite. +Download ENDF/B-VII.1 ENDF and ACE files from NNDC and WMP files from GitHub and +generate a full HDF5 library with incident neutron, incident photon, thermal +scattering data, and windowed multipole data. This data is used for OpenMC's +regression test suite. """ import glob @@ -19,12 +20,14 @@ from openmc._utils import download base_ace = 'http://www.nndc.bnl.gov/endf/b7.1/aceFiles/' base_endf = 'http://www.nndc.bnl.gov/endf/b7.1/zips/' +base_wmp = 'https://github.com/mit-crpg/WMP_Library/releases/download/v1.1/' files = [ (base_ace, 'ENDF-B-VII.1-neutron-293.6K.tar.gz', '9729a17eb62b75f285d8a7628ace1449'), (base_ace, 'ENDF-B-VII.1-tsl.tar.gz', 'e17d827c92940a30f22f096d910ea186'), (base_endf, 'ENDF-B-VII.1-neutrons.zip', 'e5d7f441fc4c92893322c24d1725e29c'), (base_endf, 'ENDF-B-VII.1-photoat.zip', '5192f94e61f0b385cf536f448ffab4a4'), - (base_endf, 'ENDF-B-VII.1-atomic_relax.zip', 'fddb6035e7f2b6931e51a58fc754bd10') + (base_endf, 'ENDF-B-VII.1-atomic_relax.zip', 'fddb6035e7f2b6931e51a58fc754bd10'), + (base_wmp, 'WMP_Library_v1.1.tar.gz', '8523895928dd6ba63fba803e3a45d4f3') ] @@ -36,12 +39,12 @@ def fix_zaid(table, old, new): with open(filename, 'w') as fh: fh.write(text) - +pwd = Path.cwd() +output_dir = pwd / 'nndc_hdf5' os.makedirs('nndc_hdf5/photon', exist_ok=True) with tempfile.TemporaryDirectory() as tmpdir: - # Save current working directory and temporarily change dir - pwd = os.getcwd() + # Temporarily change dir os.chdir(tmpdir) # ========================================================================= @@ -98,7 +101,7 @@ with tempfile.TemporaryDirectory() as tmpdir: data.add_elastic_0K_from_endf(endf_filename) # Determine filename - outfile = os.path.join('nndc_hdf5', data.name + '.h5') + outfile = output_dir / (data.name + '.h5') data.export_to_hdf5(outfile, 'w', 'earliest') # Register with library @@ -113,7 +116,7 @@ with tempfile.TemporaryDirectory() as tmpdir: data = openmc.data.ThermalScattering.from_ace(f) # Determine filename - outfile = os.path.join('nndc_hdf5', data.name + '.h5') + outfile = output_dir / (data.name + '.h5') data.export_to_hdf5(outfile, 'w', 'earliest') # Register with library @@ -127,23 +130,35 @@ with tempfile.TemporaryDirectory() as tmpdir: print('Generating HDF5 file for Z={} ({})...'.format(z, element)) # Generate instance of IncidentPhoton - photo_file = os.path.join('photoat', 'photoat-{:03}_{}_000.endf'.format(z, element)) - atom_file = os.path.join('atomic_relax', 'atom-{:03}_{}_000.endf'.format(z, element)) + photo_file = Path('photoat') / 'photoat-{:03}_{}_000.endf'.format(z, element) + atom_file = Path('atomic_relax') / 'atom-{:03}_{}_000.endf'.format(z, element) data = openmc.data.IncidentPhoton.from_endf(photo_file, atom_file) # Write HDF5 file and register it - outfile = os.path.join('nndc_hdf5', 'photon', element + '.h5') + outfile = output_dir / 'photon' / (element + '.h5') data.export_to_hdf5(outfile, 'w', 'earliest') library.register_file(outfile) - library.export_to_xml(os.path.join('nndc_hdf5', 'cross_sections.xml')) + # ========================================================================= + # WINDOWED MULTIPOLE DATA + + # Move data into output directory + os.rename('WMP_Library', str(output_dir / 'wmp')) + + # Add multipole data to library + for f in sorted(glob.glob('{}/wmp/*.h5'.format(output_dir))): + print('Registering WMP file {}...'.format(f)) + library.register_file(f) + + library.export_to_xml(output_dir / 'cross_sections.xml') # ========================================================================= # CREATE TARBALL AND MOVE BACK - test_tar = os.path.join(pwd, 'nndc_hdf5_test.tar.xz') - with tarfile.open(test_tar, 'w:xz') as txz: + print('Creating compressed archive...') + test_tar = pwd / 'nndc_hdf5_test.tar.xz' + with tarfile.open(str(test_tar), 'w:xz') as txz: txz.add('nndc_hdf5') # Change back to original directory - os.chdir(pwd) + os.chdir(str(pwd)) diff --git a/src/cross_sections.cpp b/src/cross_sections.cpp index dbfe41679..ed963b23f 100644 --- a/src/cross_sections.cpp +++ b/src/cross_sections.cpp @@ -125,21 +125,6 @@ void read_cross_sections_xml() settings::path_cross_sections = get_node_value(root, "cross_sections"); } - // Find the windowed multipole library - if (settings::run_mode != RUN_MODE_PLOTTING) { - if (!check_for_node(root, "multipole_library")) { - // No library location specified in materials.xml, check - // environment variable - char* envvar = std::getenv("OPENMC_MULTIPOLE_LIBRARY"); - if (envvar) settings::path_multipole = envvar; - } else { - settings::path_multipole = get_node_value(root, "multipole_library"); - } - if (!ends_with(settings::path_multipole, "/")) { - settings::path_multipole += "/"; - } - } - // Now that the cross_sections.xml or mgxs.h5 has been located, read it in if (settings::run_CE) { read_ce_cross_sections_xml(); diff --git a/src/input_xml.F90 b/src/input_xml.F90 index d9f451e4f..e2bf633b0 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -2276,9 +2276,8 @@ contains end if end do if (.not. mp_found) call warning("Windowed multipole functionality is & - &turned on, but no multipole libraries were found. Set the & - & element in settings.xml or the & - &OPENMC_MULTIPOLE_LIBRARY environment variable.") + &turned on, but no multipole libraries were found. Make sure that & + &windowed multipole data is present in your cross_sections.xml file.") end if call already_read % clear() @@ -2302,34 +2301,14 @@ contains integer(HID_T) :: file_id integer(HID_T) :: group_id - interface - function path_multipole_c() result(ptr) bind(C) - import C_PTR - type(C_PTR) :: ptr - end function - end interface - associate (nuc => nuclides(i_table)) + ! Look for WMP data in cross_sections.xml if (library_present(LIBRARY_WMP, to_lower(nuc % name))) then - ! If WMP data is listed in cross_sections.xml, prefer that filename = library_path(LIBRARY_WMP, to_lower(nuc % name)) else - ! Otherwise, we rely on the OPENMC_MULTIPOLE_LIBRARY environment - ! variable. This is a bit hacky, but we just assume that the file will be - ! ZZZAAAmM.h5. - - call c_f_pointer(path_multipole_c(), string, [255]) - path_multipole = to_f_string(string) - - if (nuc % metastable > 0) then - filename = trim(path_multipole) // trim(zero_padded(nuc % Z, 3)) // & - trim(zero_padded(nuc % A, 3)) // 'm' // & - trim(to_str(nuc % metastable)) // ".h5" - else - filename = trim(path_multipole) // trim(zero_padded(nuc % Z, 3)) // & - trim(zero_padded(nuc % A, 3)) // ".h5" - end if + nuc % mp_present = .false. + return end if ! Check if Multipole library exists and is readable diff --git a/src/relaxng/materials.rnc b/src/relaxng/materials.rnc index d2a84418e..c82ecfeaa 100644 --- a/src/relaxng/materials.rnc +++ b/src/relaxng/materials.rnc @@ -37,7 +37,5 @@ element materials { }* }+ & - element cross_sections { xsd:string { maxLength = "255" } }? & - - element multipole_library { xsd:string { maxLength = "255" } }? + element cross_sections { xsd:string { maxLength = "255" } }? } diff --git a/src/relaxng/materials.rng b/src/relaxng/materials.rng index 90d6ec5c6..e99fb7adf 100644 --- a/src/relaxng/materials.rng +++ b/src/relaxng/materials.rng @@ -161,12 +161,5 @@ - - - - 255 - - - diff --git a/src/settings.F90 b/src/settings.F90 index 665c0e481..6c8a61036 100644 --- a/src/settings.F90 +++ b/src/settings.F90 @@ -101,7 +101,6 @@ module settings character(MAX_FILE_LEN) :: path_input ! Path to input file character(MAX_FILE_LEN) :: path_cross_sections = '' ! Path to cross_sections.xml - character(MAX_FILE_LEN) :: path_multipole ! Path to wmp library character(MAX_FILE_LEN) :: path_state_point ! Path to binary state point character(MAX_FILE_LEN) :: path_source_point ! Path to binary source point character(MAX_FILE_LEN) :: path_particle_restart ! Path to particle restart diff --git a/src/settings.cpp b/src/settings.cpp index 0d67137bc..459d7115d 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -63,7 +63,6 @@ bool dagmc {false}; std::string path_cross_sections; std::string path_input; -std::string path_multipole; std::string path_output; std::string path_particle_restart; std::string path_source; @@ -73,7 +72,7 @@ std::string path_statepoint; int32_t index_entropy_mesh {-1}; int32_t index_ufs_mesh {-1}; int32_t index_cmfd_mesh {-1}; - + int32_t n_batches; int32_t n_inactive {0}; int32_t gen_per_batch {1}; @@ -257,21 +256,6 @@ void read_settings_xml() path_cross_sections = get_node_value(root, "cross_sections"); } - // Look for deprecated windowed_multipole file in settings.xml - if (run_mode != RUN_MODE_PLOTTING) { - if (check_for_node(root, "multipole_library")) { - warning("Setting multipole_library in settings.xml has been " - "deprecated. The multipole_library is now set in materials.xml and" - " the multipole_library input to materials.xml and the " - "OPENMC_MULTIPOLE_LIBRARY environment variable will take " - "precendent over setting multipole_library in settings.xml."); - path_multipole = get_node_value(root, "multipole_library"); - } - if (!ends_with(path_multipole, "/")) { - path_multipole += "/"; - } - } - if (!run_CE) { // Scattering Treatments if (check_for_node(root, "max_order")) { @@ -839,9 +823,6 @@ extern "C" { const char* path_input_c() { return settings::path_input.c_str(); } - const char* path_multipole_c() { - return settings::path_multipole.c_str(); - } const char* path_statepoint_c() { return settings::path_statepoint.c_str(); } diff --git a/tests/regression_tests/diff_tally/test.py b/tests/regression_tests/diff_tally/test.py index de5423fd9..b688e6d23 100644 --- a/tests/regression_tests/diff_tally/test.py +++ b/tests/regression_tests/diff_tally/test.py @@ -113,9 +113,6 @@ class DiffTallyTestHarness(PyAPITestHarness): return df.to_csv(None, columns=cols, index=False, float_format='%.7e') -@pytest.mark.skipif('OPENMC_MULTIPOLE_LIBRARY' not in os.environ, - reason='OPENMC_MULTIPOLE_LIBRARY environment variable ' - 'must be set') def test_diff_tally(): harness = DiffTallyTestHarness('statepoint.3.h5') harness.main() diff --git a/tests/regression_tests/multipole/test.py b/tests/regression_tests/multipole/test.py index ef797a1bc..c826ff0d7 100644 --- a/tests/regression_tests/multipole/test.py +++ b/tests/regression_tests/multipole/test.py @@ -74,9 +74,6 @@ class MultipoleTestHarness(PyAPITestHarness): return outstr -@pytest.mark.skipif('OPENMC_MULTIPOLE_LIBRARY' not in os.environ, - reason='OPENMC_MULTIPOLE_LIBRARY environment variable ' - 'must be set') def test_multipole(): model = make_model() harness = MultipoleTestHarness('statepoint.5.h5', model) diff --git a/tests/unit_tests/test_data_multipole.py b/tests/unit_tests/test_data_multipole.py index 4683dcd3a..02147bf0e 100644 --- a/tests/unit_tests/test_data_multipole.py +++ b/tests/unit_tests/test_data_multipole.py @@ -1,25 +1,23 @@ import os +import pathlib import numpy as np import pytest import openmc.data -pytestmark = pytest.mark.skipif( - 'OPENMC_MULTIPOLE_LIBRARY' not in os.environ, - reason='OPENMC_MULTIPOLE_LIBRARY environment variable must be set') @pytest.fixture(scope='module') def u235(): - directory = os.environ['OPENMC_MULTIPOLE_LIBRARY'] - filename = os.path.join(directory, '092235.h5') - return openmc.data.WindowedMultipole.from_hdf5(filename) + directory = pathlib.Path(os.environ['OPENMC_CROSS_SECTIONS']).parent + u235 = directory / 'wmp' / '092235.h5' + return openmc.data.WindowedMultipole.from_hdf5(u235) @pytest.fixture(scope='module') def b10(): - directory = os.environ['OPENMC_MULTIPOLE_LIBRARY'] - filename = os.path.join(directory, '005010.h5') - return openmc.data.WindowedMultipole.from_hdf5(filename) + directory = pathlib.Path(os.environ['OPENMC_CROSS_SECTIONS']).parent + b10 = directory / 'wmp' / '005010.h5' + return openmc.data.WindowedMultipole.from_hdf5(b10) def test_evaluate(u235): diff --git a/tests/unit_tests/test_material.py b/tests/unit_tests/test_material.py index 7cedd8dee..30a3e2498 100644 --- a/tests/unit_tests/test_material.py +++ b/tests/unit_tests/test_material.py @@ -154,7 +154,6 @@ def test_materials(run_in_tmpdir): mats = openmc.Materials([m1, m2]) mats.cross_sections = '/some/fake/cross_sections.xml' - mats.multipole_library = '/some/awesome/mp_lib/' mats.export_to_xml() @@ -200,7 +199,6 @@ def test_from_xml(run_in_tmpdir): mats = openmc.Materials([m1, m2, m3]) mats.cross_sections = 'fake_path.xml' - mats.multipole_library = 'fake_multipole/' mats.export_to_xml() # Regenerate materials from XML diff --git a/tests/unit_tests/test_settings.py b/tests/unit_tests/test_settings.py index e3bfc697e..30ec0e683 100644 --- a/tests/unit_tests/test_settings.py +++ b/tests/unit_tests/test_settings.py @@ -20,7 +20,6 @@ def test_export_to_xml(run_in_tmpdir): s.statepoint = {'batches': [50, 150, 500, 1000]} s.confidence_intervals = True s.cross_sections = '/path/to/cross_sections.xml' - s.multipole_library = '/path/to/wmp/' s.ptables = True s.run_cmfd = False s.seed = 17 From 4ff0ccd83ba51466a36e30ec13baf8690d447a41 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 9 Nov 2018 20:21:11 -0600 Subject: [PATCH 18/62] Don't use redundant_reactions for IncidentNeutron anymore --- openmc/data/neutron.py | 53 ++++++++++++++---------------------------- openmc/data/photon.py | 8 +------ 2 files changed, 18 insertions(+), 43 deletions(-) diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index c3f925152..f1a2acc53 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -2,7 +2,6 @@ import sys from collections import OrderedDict from collections.abc import Iterable, Mapping, MutableMapping from io import StringIO -from itertools import chain from math import log10 from numbers import Integral, Real import os @@ -86,9 +85,6 @@ class IncidentNeutron(EqualityMixin): Resonance parameters resonance_covariance : openmc.data.ResonanceCovariance or None Covariance for resonance parameters - redundant_reactions : collections.OrderedDict - Contains redundant cross sections, e.g., the total cross section. The keys - are the MT values and the values are Reaction objects. temperatures : list of str List of string representations the temperatures of the target nuclide in the data set. The temperatures are strings of the temperature, @@ -113,18 +109,15 @@ class IncidentNeutron(EqualityMixin): self.energy = {} self._fission_energy = None self.reactions = OrderedDict() - self.redundant_reactions = OrderedDict() self._urr = {} self._resonances = None def __contains__(self, mt): - return mt in self.reactions or mt in self.redundant_reactions + return mt in self.reactions def __getitem__(self, mt): if mt in self.reactions: return self.reactions[mt] - elif mt in self.redundant_reactions: - return self.redundant_reactions[mt] else: raise KeyError('No reaction with MT={}.'.format(mt)) @@ -170,10 +163,6 @@ class IncidentNeutron(EqualityMixin): def resonance_covariance(self): return self._resonance_covariance - @property - def redundant_reactions(self): - return self._redundant_reactions - @property def urr(self): return self._urr @@ -237,11 +226,6 @@ class IncidentNeutron(EqualityMixin): res_cov.ResonanceCovariances) self._resonance_covariance = resonance_covariance - @redundant_reactions.setter - def redundant_reactions(self, redundant_reactions): - cv.check_type('redundant reactions', redundant_reactions, Mapping) - self._redundant_reactions = redundant_reactions - @urr.setter def urr(self, urr): cv.check_type('probability table dictionary', urr, MutableMapping) @@ -288,7 +272,7 @@ class IncidentNeutron(EqualityMixin): self.energy[strT] = data.energy[strT] # Add normal and redundant reactions - for mt in chain(data.reactions, data.redundant_reactions): + for mt in data.reactions: if mt in self: self[mt].xs[strT] = data[mt].xs[strT] else: @@ -472,6 +456,14 @@ class IncidentNeutron(EqualityMixin): # Write reaction data rxs_group = g.create_group('reactions') for rx in self.reactions.values(): + # Skip writing redundant reaction if it doesn't have photon + # production or is a summed transmutation reaction + if rx.redundant: + photon_rx = any(p.particle == 'photon' for p in rx.products) + transmutation_rx = (rx.mt in (16, 103, 104, 105, 106, 107)) + if not (photon_rx or transmutation_rx): + continue + rx_group = rxs_group.create_group('reaction_{:03}'.format(rx.mt)) rx.to_hdf5(rx_group) @@ -480,15 +472,6 @@ class IncidentNeutron(EqualityMixin): tgroup = g.create_group('total_nu') rx.derived_products[0].to_hdf5(tgroup) - # Write redundant reaction data only for reactions with photon - # production or transmutation reactions - for rx in self.redundant_reactions.values(): - photon_rx = any(p.particle == 'photon' for p in rx.products) - transmutation_rx = (rx.mt in (16, 103, 104, 105, 106, 107)) - if photon_rx or transmutation_rx: - rx_group = rxs_group.create_group('reaction_{:03}'.format(rx.mt)) - rx.to_hdf5(rx_group) - # Write unresolved resonance probability tables if self.urr: urr_group = g.create_group('urr') @@ -564,10 +547,7 @@ class IncidentNeutron(EqualityMixin): for name, obj in sorted(rxs_group.items()): if name.startswith('reaction_'): rx = Reaction.from_hdf5(obj, data.energy) - if rx.redundant: - data.redundant_reactions[rx.mt] = rx - else: - data.reactions[rx.mt] = rx + data.reactions[rx.mt] = rx # Read total nu data if available if rx.mt in (18, 19, 20, 21, 38) and 'total_nu' in group: @@ -580,7 +560,8 @@ class IncidentNeutron(EqualityMixin): if mt_sum not in data: rxs = [data[mt] for mt in SUM_RULES[mt_sum] if mt in data] if len(rxs) > 0: - data.redundant_reactions[mt_sum] = rx = Reaction(mt_sum) + data.reactions[mt_sum] = rx = Reaction(mt_sum) + rx.redundant = True if rx.mt == 18 and 'total_nu' in group: tgroup = group['total_nu'] rx.derived_products.append(Product.from_hdf5(tgroup)) @@ -657,13 +638,13 @@ class IncidentNeutron(EqualityMixin): total = Reaction(1) total.xs[strT] = Tabulated1D(energy, total_xs) total.redundant = True - data.redundant_reactions[1] = total + data.reactions[1] = total if np.count_nonzero(absorption_xs) > 0: absorption = Reaction(27) absorption.xs[strT] = Tabulated1D(energy, absorption_xs) absorption.redundant = True - data.redundant_reactions[27] = absorption + data.reactions[27] = absorption # Read each reaction n_reaction = ace.nxs[4] + 1 @@ -695,7 +676,7 @@ class IncidentNeutron(EqualityMixin): # Determine redundant cross section rx = data._get_redundant_reaction(mt, mts) rx.products += _get_photon_products_ace(ace, rx) - data.redundant_reactions[mt] = rx + data.reactions[mt] = rx # For transmutation reactions, sometimes only individual levels are # present in an ACE file, e.g. MT=600-649 instead of the summation @@ -711,7 +692,7 @@ class IncidentNeutron(EqualityMixin): # Determine redundant cross section rx = data._get_redundant_reaction(mt, mts) - data.redundant_reactions[mt] = rx + data.reactions[mt] = rx # Read unresolved resonance probability tables urr = ProbabilityTables.from_ace(ace) diff --git a/openmc/data/photon.py b/openmc/data/photon.py index 08f8f085d..273234c36 100644 --- a/openmc/data/photon.py +++ b/openmc/data/photon.py @@ -373,9 +373,6 @@ class IncidentPhoton(EqualityMixin): excitation energy), 's_collision' (collision stopping power in [eV cm\ :sup:`2`/g]), and 's_radiative' (radiative stopping power in [eV cm\ :sup:`2`/g]) - redundant_reactions : collections.OrderedDict - Contains redundant cross sections. The keys are MT values and the values - are instances of :class:`PhotonReaction`. """ @@ -383,19 +380,16 @@ class IncidentPhoton(EqualityMixin): self.atomic_number = atomic_number self._atomic_relaxation = None self.reactions = OrderedDict() - self.redundant_reactions = OrderedDict() self.compton_profiles = {} self.stopping_powers = {} self.bremsstrahlung = {} def __contains__(self, mt): - return mt in self.reactions or mt in self.redundant_reactions + return mt in self.reactions def __getitem__(self, mt): if mt in self.reactions: return self.reactions[mt] - elif mt in self.redundant_reactions: - return self.redundant_reactions[mt] else: raise KeyError('No reaction with MT={}.'.format(mt)) From d8db9918c17bf17ef7d609bb0fffa7dcbf3b00d7 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 9 Nov 2018 20:31:00 -0600 Subject: [PATCH 19/62] Remove openmc-get-multipole-data script (since we will provide data) --- docs/source/usersguide/scripts.rst | 11 --- scripts/openmc-get-multipole-data | 120 ----------------------------- 2 files changed, 131 deletions(-) delete mode 100755 scripts/openmc-get-multipole-data diff --git a/docs/source/usersguide/scripts.rst b/docs/source/usersguide/scripts.rst index 5ae28fac2..3246a0e67 100644 --- a/docs/source/usersguide/scripts.rst +++ b/docs/source/usersguide/scripts.rst @@ -149,17 +149,6 @@ the following optional arguments: and processing the data may require as much as 40 GB of additional free disk space. -.. _scripts_multipole: - ------------------------------ -``openmc-get-multipole-data`` ------------------------------ - -This script downloads and extracts windowed multipole data based on -ENDF/B-VII.1. It has the following optional arguments: - --b, --batch Suppress standard in - .. _scripts_nndc: ------------------------ diff --git a/scripts/openmc-get-multipole-data b/scripts/openmc-get-multipole-data deleted file mode 100755 index 554a18428..000000000 --- a/scripts/openmc-get-multipole-data +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env python3 - -import os -import shutil -import subprocess -import sys -import tarfile -import glob -import hashlib -import argparse -from urllib.request import urlopen - - -description = """ -Download and extract windowed multipole data based on ENDF/B-VII.1. - -""" - -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') -args = parser.parse_args() - - -baseUrl = 'https://github.com/mit-crpg/WMP_Library/releases/download/v1.1/' -files = ['WMP_Library_v1.1.tar.gz'] -checksums = ['8523895928dd6ba63fba803e3a45d4f3'] -block_size = 16384 - -# ============================================================================== -# DOWNLOAD FILES FROM GITHUB REPO - -filesComplete = [] -for f in files: - # Establish connection to URL - url = baseUrl + 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 - - # Remove GitHub junk from the file name. - fname = f[:-9] if f.endswith('?raw=true') else f - - # Check if file already downloaded - if os.path.exists(fname): - if os.path.getsize(fname) == file_size: - print('Skipping ' + fname) - filesComplete.append(fname) - continue - else: - overwrite = input('Overwrite {0}? ([y]/n) '.format(fname)) - if overwrite.lower().startswith('n'): - continue - - # Copy file to disk - print('Downloading {0}... '.format(f), end='') - with open(fname, '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('') - filesComplete.append(fname) - -# ============================================================================== -# VERIFY MD5 CHECKSUMS - -print('Verifying MD5 checksums...') -for f, checksum in zip(files, checksums): - fname = f[:-9] if f.endswith('?raw=true') else f - downloadsum = hashlib.md5(open(fname, '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: - fname = f[:-9] if f.endswith('?raw=true') else f - if fname not in filesComplete: - continue - - # Extract files - with tarfile.open(fname, 'r') as tgz: - print('Extracting {0}...'.format(fname)) - tgz.extractall(path='') - -# ============================================================================== -# 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 {0}...'.format(f)) - os.remove(f) From a6a95b2d338360d09fd8c9b926d0f5a6f39e898d Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 9 Nov 2018 20:31:28 -0600 Subject: [PATCH 20/62] Update nuclear data Jupyter notebook --- examples/jupyter/nuclear-data.ipynb | 524 +++++++++++----------------- 1 file changed, 204 insertions(+), 320 deletions(-) diff --git a/examples/jupyter/nuclear-data.ipynb b/examples/jupyter/nuclear-data.ipynb index f1c4c2b2a..aace5e9d2 100644 --- a/examples/jupyter/nuclear-data.ipynb +++ b/examples/jupyter/nuclear-data.ipynb @@ -10,9 +10,7 @@ { "cell_type": "code", "execution_count": 1, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", @@ -43,9 +41,7 @@ { "cell_type": "code", "execution_count": 2, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -65,9 +61,7 @@ { "cell_type": "code", "execution_count": 3, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -87,9 +81,7 @@ { "cell_type": "code", "execution_count": 4, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -118,9 +110,7 @@ { "cell_type": "code", "execution_count": 5, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "url = 'https://anl.box.com/shared/static/kxm7s57z3xgfbeq29h54n7q6js8rd11c.ace'\n", @@ -130,9 +120,7 @@ { "cell_type": "code", "execution_count": 6, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -168,9 +156,7 @@ { "cell_type": "code", "execution_count": 7, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -198,14 +184,12 @@ { "cell_type": "code", "execution_count": 8, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{'294K': }" + "{'294K': }" ] }, "execution_count": 8, @@ -227,9 +211,7 @@ { "cell_type": "code", "execution_count": 9, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -256,14 +238,12 @@ { "cell_type": "code", "execution_count": 10, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "array([ 142.64747 , 38.6541761 , 175.40019642])" + "array([142.64747 , 38.6541761 , 175.40019642])" ] }, "execution_count": 10, @@ -285,15 +265,13 @@ { "cell_type": "code", "execution_count": 11, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{'294K': array([ 1.00000000e-05, 1.03250000e-05, 1.06500000e-05, ...,\n", - " 1.95000000e+07, 1.99000000e+07, 2.00000000e+07])}" + "{'294K': array([1.0000e-05, 1.0325e-05, 1.0650e-05, ..., 1.9500e+07, 1.9900e+07,\n", + " 2.0000e+07])}" ] }, "execution_count": 11, @@ -308,14 +286,12 @@ { "cell_type": "code", "execution_count": 12, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "" + "Text(0,0.5,'Cross section (b)')" ] }, "execution_count": 12, @@ -324,12 +300,14 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiYAAAGBCAYAAABSP3qNAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzs3Xl8VOX1x/HPAdlBFFFURMGiuCOgVgTUivsSYlVo6tZi\ntRZtNXWttm51r4q1rVatLdrWuNQqcSnuWjdE2VQEqxXUHwruuLDIcn5/PDPNECbJzGRm7p2Z7/v1\nmtdkbm7uPSQhOXme85zH3B0RERGROGgTdQAiIiIiSUpMREREJDaUmIiIiEhsKDERERGR2FBiIiIi\nIrGhxERERERiQ4mJiIiIxIYSExEREYkNJSYiIiISG0pMREREJDaUmIiIiEhslE1iYmZbmtl0M5uW\neF5sZlVRxyUiIiKZs3LcxM/MugBzgc3cfUnU8YiIiEhmymbEpJEq4HElJSIiIqWlXBOT0cCdUQch\nIiIi2YlFYmJmI8ys3szmm9mqdLUhZnaSmc01syVmNtnMdm7iWt2AocBDhY5bRERE8isWiQnQBZgB\njAPWKHoxszHA1cD5wCBgJvCwmfVMc61RwCPu/k3hwhUREZFCiF3xq5mtAqrdvT7l2GTgRXc/JfHa\ngPeA69z9ykYfXw/c6O4PNnOP9YD9gHnA0rz/I0RERMpXR6Av8LC7f5Lvi6+V7wvmm5m1A4YAlyaP\nubub2WOEKZvUc9cGdga+28Jl9wP+nudQRUREKsmRwO35vmjsExOgJ9AWWNjo+EJgQOoBd/8C2CiD\na84D6NHjb3z11db86Edw9NHQvn0eos3RPvvsw6OPPhpdAI0onubFKZ44xQKKpyVxiidOsYDiaUlc\n4pk9ezZHHXUUJH6X5lspJCaFsBRg4sStqa8fzDXXwBNPwA03wJ57RhNQu3btGDx4cDQ3T0PxNC9O\n8cQpFlA8LYlTPHGKBRRPS+IWDwUqhYhL8WtzPgZWAr0aHe8FLGjNhTt3hiuvhOnToUcP+M534Nhj\n4cMPW3PV3PTu3bv4N22G4mlenOKJUyygeFoSp3jiFAsonpbELZ5CiX1i4u7LganAyOSxRPHrSOD5\n1ly7traWqqoqXnutjmeegT/9CR54ALbaCm6+GVatal3s2YjbN5ziaV6c4olTLKB4WhKneOIUCyie\nlkQdT11dHVVVVdTW1hb0PrFITMysi5kNNLMdE4c2T7zuk3h9DXC8mR1jZlsBfwQ6AxNac9/x48dT\nX19PTU0NbdrAccfBnDkwahSccAIMHw6vvNKaO4iIiJSHmpoa6uvrGT9+fEHvE4vEBNgJmE4YGXFC\nz5JpwIUA7n4XcDpwUeK8HYD93P2jfAey/vrwl7/AU0/B55/D4MFwxhnw1Vf5vtPqampqCnuDLCme\n5sUpnjjFAoqnJXGKJ06xgOJpSdziKZTY9TEpBjMbDEydOnVqs4VE33wD11wDF10EPXvC734XRlNE\nREQq1bRp0xgyZAjAEHeflu/rx2XEJJbat4ezz4ZZs2D77aG6Gqqq4J13oo5MRESkPCkxyUC/fqEo\n9p57YNo02GabsJpn+fKoIxMRESkvFZ2YJFfl1NXVtXiuGXz3uzB7Nvz4x/CLX8CgQfDss0UIVERE\nJGLFWpWjGpMcm9VMnw4nnghTpsDYsXDFFaEORUREpJypxiSmBg2C558P3WLvuSf0PvnLX6AC8zwR\nEZG8UWLSCm3bhlGTN96A/fcPIyd77BGKZUVERCR7SkzyoFcv+Nvf4LHHYOFC2HHHUIOyeHHUkYmI\niJQWJSZ5NHJk6BR73nkwfjxsuy08+GDUUYmIiJQOJSZ51qED/OpX8NprsOWWcPDBYTXPe+9FHZmI\niEj8KTEpkP79YdIkuOMOeOEF2Hrr0EV2xYqoIxMREYmvik5MsuljkgszGDMmbAw4diycfjrstBNM\nnlyQ24mIiBSM+pgUUD76mOTi5ZfDKp5p08LuxZddBuuuW7Tbi4iItJr6mJSRnXaCF1+E666D22+H\nAQPCap4KzA1FRETSUmJSZG3bwsknh+mdvfaCo48Oq3nmzIk6MhERkegpMYnIxhuHwthJk+Ddd2GH\nHcJqniVLoo5MREQkOkpMIrbffvDqq3D22WHH4u22g4cfjjoqERGRaCgxiYFOneCii0Jztr59Q3v7\nMWPg/fejjkxERKS4lJjEyIABoa393/4GTz0VNga87jpYuTLqyERERIpDiUnMmMGRR4Zi2COPhFNP\nhV12gZdeijoyERGRwlNiElPrrgs33ADPPx9GTL797bCaZ9GiqCMTEREpHCUmMbfrrqEx2zXXwK23\nhumdO+5Q7xMRESlPSkxKwFprhSmd2bNh2DCoqQmred58M+rIRERE8kuJSQnZZBP4xz/ggQdCUrL9\n9mE1z7JlUUcmIiKSHxWdmBR6E79COeggmDULfv5z+PWvQ3O2xx+POioRESln2sSvgKLaxK8QZs2C\ncePg3/+G738frr4aNtww6qhERKRcaRM/ada224aeJxMmwCOPhOLYG25Q7xMRESlNSkzKgBkce2zo\nfXLEEWEEZbfdYPr0qCMTERHJjhKTMrLeenDzzfDss7B4Mey0U1jN88UXUUcmIiKSGSUmZWjYMJg2\nDS6/PCQqW28dVvNUYDmRiIiUmLJKTMysr5k9YWazzGymmXWKOqaotGsHZ5wBr78eRk6OOAIOOEC9\nT0REJN7KKjEBJgC/dPdtgT2Aiu/wsdlmMHEi1NfDG2/AdtvBL38ZpnpERETipmwSEzPbBvjG3Z8H\ncPfP3X1VxGHFxiGHhNGTs8+Gq64K0zv33afpHRERiZeySUyALYCvzazezF42s19EHVDcdOoEF14I\nr70Wlhkfemho1vbWW1FHJiIiEsQiMTGzEYmEYr6ZrTKzqjTnnGRmc81siZlNNrOdG52yFjAcOBHY\nDdjHzEYWIfyS078/PPgg3HtvGEXZdls47zxYsiTqyEREpNLFIjEBugAzgHHAGpMLZjYGuBo4HxgE\nzAQeNrOeKafNB1529/fd/RvgIWDHQgdeqsygujokJmecAVdcAdtsA/ffH3VkIiJSyWKRmLj7JHc/\nz90nApbmlFrgRne/zd3nEEZFFgNjU855CdjAzLqbWRtgd2B2oWMvdZ07w8UXw6uvwpZbQlVVqEd5\n++2oIxMRkUq0VtQBtMTM2gFDgEuTx9zdzewxYGjKsZVmdg7wTOLQI+7+UHPXrq2tpXv37qsdq6mp\noaamJl/hl4wtt4RJk8L0zqmnhtGTX/wCzjwz1KaIiEjlqaurW2Oj20WLFhX0nrHbxM/MVgHV7l6f\neL0RYZpmqLu/mHLeFcDu7j40/ZWavUfZbOJXCF9/HUZRrr4a+vSB664LRbIiIiLaxE+KrksXuOyy\nML2z+eZw8MGhHmXevKgjExGRclcKicnHwEqgV6PjvYAFxQ+ncgwYEHYsvusuePnl0PvkggvUnE1E\nRAon9omJuy8HpgL/W/prZpZ4/XxUcVUKs9DOfs6cUHty2WWw1VZw551qziYiIvkXi8TEzLqY2UAz\nSy7v3Tzxuk/i9TXA8WZ2jJltBfwR6ExoQZ+z2tpaqqqq1ijskTV17RqSklmzYPBg+N73YI89YPr0\nqCMTEZFiqKuro6qqitra2oLeJxbFr2a2B/Aka/YwudXdxybOGQecSZjCmQH81N1fzvF+Kn5tpUcf\nDSMos2fD8ceHYtn11486KhERKbSKKH5196fdvY27t230GJtyzvXu3tfdO7n70FyTEsmPffaBGTPg\n2mtDDcoWW4S3ly+POjIRESllsUhMpDS1awc/+xm8+SbU1MBpp8EOO4R+KCIiIrlQYiKt1rMn3HAD\nTJsGvXrBAQeEJcavvx51ZCIiUmoqOjFR8Wt+DRwITz4ZpnZefx223x5+/GNYoEXdIiIlr6KKX4tN\nxa+Ft2wZXH89/PrX8M03YaPA008PzdtERKR0VUTxq5SfDh2gthb++1/4yU/g0kuhf3+4+WZYsSLq\n6EREJK6UmEhBrbsu/OY38MYbsNdecMIJsOOO8MADatAmIiJrUmIiRdG3L/z97/DSS6HfySGHwLBh\n8MQTUUcmIiJxosREimqnnUIy8vDDYUpn5MgwkvLcc1FHJiIicaDERIrODPbdF158ESZOhE8+geHD\n4cADYerUqKMTEZEoKTGRyJhBVVXYb+fOO2Hu3DCiUlUFkydHHZ2IiEShohMT9TGJhzZtYPRoeO01\nuO220El26NAwxfPooyqSFRGJA/UxKSD1MYm3VavgvvvCEuOpU8MoyjnnwKhRIYkREZHoqI+JVJw2\nbeC73w0reB55BLp1C6+33RZuvBEWL446QhERKRQlJhJbZmEX4yeegBdegG22gXHjoE+fMILyf/8X\ndYQiIpJvSkykJOy6K9xzD7z1FvzgB/CHP0C/fmFX4xdfjDo6ERHJFyUmUlL69YOrrw6jJVdfHaZ7\ndt01FMveeafa3YuIlDolJlKSunWDn/0stLqfOBE6dYLvfS/sx/O738HXX0cdoYiI5EKJiZS0tm1D\n35MnnoBp00Kb+9pa2HRTOP98+OijqCMUEZFsKDGRsjFoUNiP56234Kij4KqrwtTP+efDl19GHZ2I\niGRCiYmUnb594be/hXffhZNOgiuuCFM8EyaoWZuISNwpMZGytd56ISl5882w7PiHP4QDDoB33ok6\nMhERaYoSEyl7ffrA3/4GDz0Es2bBjjvCpElRRyUiIukoMZGKccAB8OqroUD2wAPh2mujjkhERBpb\nK+oAolRbW0v37t2pqamhpqYm6nCkCNZZB+rr4Re/CKt3vvoKfvnLqKMSEYm/uro66urqWLRoUUHv\no038tIlfxbr4YvjVr+Cyy+Dss6OORkSkNBR6E7+KHjGRyvbLX8I334TRk803h9Gjo45IRESUmEhF\nu/BC+O9/4ZhjYMAAGDgw6ohERCqbil+lopnBLbfAVlvBmDFqZS8iEjUlJlLxOnYMGwC+9x6cdVbU\n0YiIVLaySkzMbJ6ZzTCz6Wb2eNTxSOkYMAAuuQSuvx6mTIk6GhGRylVWiQmwChjq7oPcfWTUwUhp\nOfnk0HzthBNgxYqooxERqUzllpgY5fdvkiJZay246SZ45ZXwLCIixVduv8QdeMrMXjSz70cdjJSe\nnXaCI4+EX/9ahbAiIlGIRWJiZiPMrN7M5pvZKjOrSnPOSWY218yWmNlkM9s5zaWGufvOwCjgHDPb\nruDBS9m56CL45BP43e+ijkREpPLEIjEBugAzgHGEUY/VmNkY4GrgfGAQMBN42Mx6pp7n7h8knhcA\nDwFq6ypZ69cPTjwRLr8cPv886mhERCpLLBITd5/k7ue5+0RCnUhjtcCN7n6bu88BTgQWA2OTJ5hZ\nZzPrmni7K7AXMKvw0Us5OuccWLIEbrwx6khERCpLLBKT5phZO2AI8L/lvx42+HkMGJpyai/gWTOb\nDjwPTHD3qcWMVcrHhhuGbrDXXgvLlkUdjYhI5SiFlvQ9gbbAwkbHFwIDki/cfS6wYzYXTu4unEo7\nDUvS6aeHrrB/+xscd1zU0YiIFF9yR+FUFbe7sJmtAqrdvT7xeiNgPqE/yYsp510B7O7uQ9Nfqdl7\naHdhycihh8Ls2fD669Am9uOLIiKFV+jdhUvhR+3HwErCVE2qXsCC4ocjlaS2Ft54A558MupIREQq\nQ+wTE3dfDkwF/tfJ1cws8fr5qOKSyjBiBGyzDfzxj1FHIiJSGWJRY2JmXYD+NKzI2dzMBgKfuvt7\nwDXABDObCkwhrNLpDExozX2TNSaqK5GmmIWlwz//OXzwAWy0UdQRiYhEI1lvUhE1Jma2B/Aka/Yw\nudXdxybOGQecSZjCmQH81N1fzvF+qjGRjC1aBBtvHJYQn3tu1NGIiESrImpM3P1pd2/j7m0bPcam\nnHO9u/d1907uPjTXpEQkW927Q01N2D9n5cqooxERKW+xSExE4u6EE+Ddd+GJJ6KORESkvCkxEcnA\nzjvDVlvBbbdFHYmISHmr6MSktraWqqqqNZrHiDRmFjrB/vOf8OWXUUcjIlJ8dXV1VFVVUVtbW9D7\nZF38amYdgG8DmxFWxnwETE90Xi0JKn6VXLz7Lmy2GUyYAMceG3U0IiLRKHTxa8bLhc1sGHAKcAjQ\nDlgELAF6AB3M7G3gJuCP7q6/KaXsbLopfOc78Ne/KjERESmUjKZyzKweuBOYB+wLdHP39dx9E3fv\nDGwBXExoevYfM9unQPGKROqYY0IB7HvvRR2JiEh5yrTG5EGgn7uf6e7PuPuS1He6+9vufqu7709I\nTlblO1CRODjsMOjYEW6/PepIRETKU0aJibvfmGgNn8m5r7v7460LSySeunWDgw+Gu+6KOhIRkfKU\n86ocM9vJzI5OPHbKZ1AicTZ6NEybBm+9FXUkIiLlJ+vExMw2MbNnCHvW/DbxmGJmz5rZJvkOUCRu\nDjwQunSBu++OOhIRkfKTy4jJnwircrZ29x7u3gPYOnGtP+UzuEJTHxPJRefOcMghms4RkcoS5z4m\nS4Dd3H16o+NDgGcSq3RiTX1MpLXuvRe++1144w3YcsuooxERKZ44buL3HmHEpLG2wPutC0ekNOy/\nP3TtqlETEZF8yyUxOQP4XWrBa+Lt3wKn5yswkTjr1AmqqpSYiIjkW0adX83sMyB1zqcL8KKZrUi5\nzgrgz8B9eY1QJKZGjw79TGbPhq23jjoaEZHykGlL+lMLGoVICdpvv9DX5B//gF/9KupoRETKQ0aJ\nibvfWuhAREpNx45w0EGhEFaJiYhIfmS6V06XbC6a7fkiperQQ2H6dJg3L+pIRETKQ6bFr2+Z2dlm\ntlFTJ1iwj5n9C/hZfsITibcDDoAOHeA+VVaJiORFpjUmewKXAheY2UzgZcLS4KXAusA2wFBCAexl\nwI15j1Qkhrp1g733DtM5p6oSS0Sk1TKtMXkDOMzMNgWOAEYAuwGdgI+B6cDxwL/cfWWBYhWJpUMP\nheOPhw8/hA02iDoaEZHSllUfE3d/192vdvdqdx/k7lu5+3B3/6m7P6CkRCpRVRWYQX191JGIiJS+\nnHcXFpFg/fVh+PAwnSMiIq2TaY1JWaqtraV79+7U1NRQU1MTdThSwg49FM46C774AtZeO+poRETy\nr66ujrq6OhYtWlTQ+2S9iV850CZ+km/z5kG/fnDHHTBmTNTRiIgUThw38RORRvr2hUGDNJ0jItJa\nSkxE8uTQQ+Ghh2DZsqgjEREpXTnVmJjZOsAuwAY0Sm7c/bY8xCVScg49FM47Dx5/HA48MOpoRERK\nU9aJiZkdAvwd6Ap8weq7DjugxEQq0rbbQv/+oQusEhMRkdzkMpVzNfBnoKu7r+Pu66Y8euQ5vqyZ\nWSczm2dmV0Ydi1QWM6iuDv1MVq2KOhoRkdKUS2LSG7jO3RfnO5g8ORd4IeogpDJVV8PChfDii1FH\nIiJSmnJJTB4Gdsp3IPlgZv2BAcC/oo5FKtOuu4a29NrUT0QkN7kUvz4I/MbMtgFeBZanvtPdo2zM\nfRVwOjAswhikgrVtC4ccEpYNX355mN4REZHM5TJicjPQBzgPuBu4L+WRUxcHMxthZvVmNt/MVplZ\nVZpzTjKzuWa2xMwmm9nOjd5fBbzh7m8lD+USi0hrVVfDm2/CnDlRRyIiUnqyTkzcvU0zj7Y5xtEF\nmAGMY/VVPgCY2RhC0e35wCBgJvCwmfVMOW1X4Htm9jZh5ORHZvbLHOMRydnIkdClC0ycGHUkIiKl\nJxYN1tx9kruf5+4TST/SUQvc6O63ufsc4ERgMTA25RrnuPtm7r45YTrnZne/uBjxi6Tq1An22091\nJiIiucgpMTGzPczsfjN7K/GoN7MR+Q4uca92wBDg8eQxDxv8PAYMLcQ9RVqrujqszHn//agjEREp\nLbk0WDsK+AvwT+C6xOFhwONm9gN3vz2P8QH0BNoCCxsdX0hYgbMGd781kwsndxdOpZ2GJR8OOigU\nwt5/P/z4x1FHIyKSm+SOwqlit7uwmc0GbnL38Y2O/xw43t23blVAZquA6uTqHjPbCJgPDHX3F1PO\nuwLY3d2zHjXR7sJSDCNHQvv28C8tXheRMhLH3YU3B+5Pc7we6Ne6cNL6GFgJ9Gp0vBewoAD3E8mL\nUaPCvjlffBF1JCIipSOXxOQ9YGSa43sn3pdX7r4cmJp6TzOzxOvn830/kXwZNQqWL9eIiYhINnJp\nsHY1cJ2Z7UhDYjAM+AFwSi5BmFkXoD8NK3I2N7OBwKfu/h5wDTDBzKYCUwirdDoDE3K5X1KyxkR1\nJVIIm20GgwaFZcNjxkQdjYhI6yTrTWJXYwJgZocCpwHJepLZwG8Sy31zud4ewJOs2cPkVncfmzhn\nHHAmYQpnBvBTd385x/upxkSK4sIL4Zpr4KOPQr2JiEipi2ONCe5+r7sPd/f1Eo/huSYlies9nWzQ\n1uiR2qfkenfv6+6d3H1orkmJSDFVV4cak6eeijqSeHjiCbjuupbPE5HKFYsGayLlaocdoG9fdYFN\nGjkSTslpwldEKkVGiYmZfZps/25mnyVep30UNlyR0mIWRk0mToRVq6KORkQk/jItfq0Fvkx5O/vC\nFJEKNWoUXHstTJ0KO+/c8vkiIpUso8QktZOqu08oWDRFplU5UgzDh0OPHmHvHCUmIlKqYrsqx8xW\nAhu5+4eNjq8HfNiKHYaLRqtypNh+8AN4+WV47bWoI4mWJRoC5LAYUERiIo6rctLt/gvQAfimFbGI\nlK3qapg1C958M+pIRETiLeMGa2b2s8SbDvzIzL5KeXdbYHdgTh5jEykb++wDHTuGItjTT486GhGR\n+Mqm82tt4tmAEwn71yR9A8xLHBeRRrp0gX33DXUmSkyCJ5+Es8+GF19s+VwRqRwZJybu3g/AzJ4E\nvuvunxUsKpEyVF0Nxx0HH34IG2wQdTTRO/10mJb32WkRKXVZ15i4+3eUlIhk7+CDQ/Hn/en25q5A\nKoQVkXSyTkzM7B4zOyvN8TPN7O78hFUctbW1VFVVUVdXF3UoUgHWXx+GDQvTOVL8xOSFF2DBguLc\nS6Qc1dXVUVVVRW1tbcsnt0Iuy4U/AvZy91cbHd8eeMzde+UxvoLQcmGJyjXXwDnnwMcfQ9euUUdT\nfKnJyC67wEsvwfLlsFYu+5zncO/NNoN58wp/L5FyFsflwl1Jvyx4ObB268IRKW+jRsGyZfDII1FH\nEr1kkrJyZfPn5dM77xTvXiKSm1wSk1eBMWmOfw94vXXhiJS3b30LtttO0zkAbRI/fbSHkIikymUA\n9dfAP83sW8ATiWMjgRrgiHwFJlKuqqvhD38IUxjt2kUdTXSSIyZKTEQkVS6rcu4HqoH+wPXA1cAm\nwN7urr8DRVpQXQ2ffQbPPht1JPGQbWKyaFFxp39EpLhymcrB3R9092Hu3sXde7r7Xu7+dL6DEylH\ngwfDJptoOifXEZN11oGz1lgXKCLlIqfExMzWMbMfmdmlZtYjcWywmfXOb3gi5ccsFMHed19l9/Bo\nTfHrv/6V31hEJD5y6WOyA/Af4CzgDGCdxLu+C1yWv9BEyld1Nbz7LsycGXUk0WlNHxP3MB22555h\n6bWIlI9cRkyuASa4+xbA0pTjDxE28hORFuyxB3TvrukcyD0xue8+ePppuOee/MckItHJJTHZGbgx\nzfH5wIatC0ekMrRrBwcdVNmJiVbliEg6uSQmy0jfSG1L4KPWhSNSOaqrw1TO3LlRRxKtXEdMWvPx\nIhJfuSQm9cB5ZpbswOBmtilwBaBBVZEM7b8/tG8P9fVRRxKtXEdMkiMuIlJecklMTiO0pf8Q6AQ8\nDbwFfAmcm7/QRMpbt26w996VPZ0DrR8xEZHyknXnV3dfBOxjZsOAgYQkZZq7P5bv4AqttraW7t27\nU1NTQ01NTdThSAUaNQp+8hP45BNYb72ooymu1tSYuBd/d2KRSldXV0ddXR2LFi0q6H1y3tPT3Z8D\nnoPQ1yRvERXR+PHjtbuwRKqqCk48ER58EI45JupooqHEQqQ0JP+IT9lduCBy6WNylpmNSXl9F/CJ\nmc03s4F5jU6kzG24Iey6a7TTOXPmRHPfYq7K0cofkdKRS43JicB7AGa2D7APcADwL+A3+QtNpDJU\nV8OkSbB4cfHvPXEibL01TJ1a/HsnZTNiksvoykMPQdu2qx/74IPsryMixZFLYrIhicQEOBi4y90f\nAa4k9DgRkSyMGgVLlsBjEVRpJUdL3nmn+PdOymY0I5mYZJOgPP74mq833hgmT179+HvvwQ03hM0V\nzeDDDzO/h4jkTy6JyWdAn8Tb+wPJH6cGtE37ESLSpAEDYKutwuhFsbVvH56XLy/uffPRhyTT4tfG\no0FTpoTn//539eOHHQbjxjV8Hd58M7e4RKR1cklM/gncbmaPAusRpnAABhGWDUfCzLqb2UtmNs3M\nXjGzH0UVi0i2qqtDP5NcNrRrjTaJnwDFLkBdtSq3GpNs41yyJLStT3XOOemvtWRJdtcWkcLIJTGp\nBX4PvA7s4+5fJY5vBFyfr8By8AUwwt0HA98GzjGzdSOMRyRjo0aFzeief764903+ci52s7JcRky+\n+qqhS26mH79iRW4xiUh0culjshy4Ks3x8XmJKEfu7jRsKtgp8azekFISdtklrNC57z4YMaJ4902O\nVmTzCzyf9238dnP23x+ee67hdSbJ1OefN/0+dY4ViadcRkxiKzGdMwN4F/iNu38adUwimWjTJoya\nTJxY3L/ck/f65pvi3TN532wbpKUmJZnadNPmYxCR+IlFYmJmI8ysPtELZZWZVaU55yQzm2tmS8xs\nspmtsQLI3Re5+45AP+BIM1u/GPGL5EN1dSjInDWrePdMjpQUu/g1lxGTYlPiIhKNWCQmQBdgBjAO\nWOPHQaKh29XA+YQi25nAw2bWM93F3P2jxDlFHBQXaZ3vfCfsn1PMZmvJkZIoVuW0pqW8kgaR8hWL\nxMTdJ7n7ee4+kfR1IbXAje5+m7vPITR5WwyMTZ5gZhuYWdfE292B3YE3Ch+9SH506AAHHFDcZcPJ\nxKTYUzn5GDHRXjki5Snr4lcz60OoNf2/xOtdgO8Dr7v7TXmODzNrBwwBLk0ec3c3s8eAoSmnbgbc\nZOGnlQEFzj/MAAAgAElEQVS/dfdmB8WTm/il0oZ+EqXqavj+90Ozrz59Wj6/tZYtC8+l2MdERAov\nuXFfqjhu4nc7cBPwVzPbEHgUmEWo6djQ3S/KZ4BAT0LjtoWNji8EBiRfuPtLhGmejGkTP4mbAw+E\ndu1CT5OTTir8/aKaymntiIkSG5HiSPfHeuw28QO2AxK9ExkNvObuuwFHAj/IU1wiFal7d9hzz+LV\nmUQ5YtLaqZh8L/dVgiMSD7kkJu2AxI8z9gbqE2/PITRZy7ePgZVAr0bHewELCnA/kUhVV8NTTzXf\ngyNfSrnGRETKUy6JySzgRDMbQdhZeFLi+MbAJ/kKLCnR0G0qMDJ5zEIhyUigVX0ya2trqaqqWmP+\nTCRKVVVhGe9DDxX+XqW0Kid1hCT14wGmTWvdiMdpp8Hrr+f+8SKVoK6ujqqqKmprawt6n1wSk7OA\nHwNPAXXuPjNxvIqGKZ6smFkXMxtoZjsmDm2eeJ0s/7sGON7MjjGzrYA/Ap2BCbncL2n8+PHU19er\n2FViZZNNYKedijOdk0xISq3GJNUrr8CQIXDLLdl9XGoic801rYtBpBLU1NRQX1/P+PGFbfSeS0v6\npxL9Q9Z2989S3nUTYQlvLnYCniT0MHFCzxKAW4Gx7n5X4p4XEaZwZgD7JfqViJSd6mq4/PJQA9Kh\nQ+HuE1WDtXwWr36U+Cnw9tshyWnbFv76VzjqqNZdV0SikfWIiZl1AjokkxIz28zMTgUGuPuHuQTh\n7k+7ext3b9voMTblnOvdva+7d3L3oe7+ci73EikF1dVh07onnijsfUppxKSpYtfUxCa5O/ONN+Z+\nPRGJVi5TOROBYwDMbB3gReA04D4z+0keYxOpWNtsA/37F346J6rEJA6dX7UKRySecklMBgPPJN4+\nnNBPZDNCsvKzPMUlUtHMwqZ+9fWFXbUShxET9/C47jpYnMVkcHMjHko6REpXLolJZ+DLxNv7Av90\n91XAZEKCUjK0KkfirLoaFiyAKTmVlGcmDiMmq1bBSy/BKafAZZc1/TEtTb00TkY+yqACbcGCwk+X\niZSLYq3KyaXz61tAtZndC+wHJMtzNwC+yFdgxaDOrxJnQ4fC+uuH6Zxddy3MPZIJSZR9TNwb4liy\nJLOPb7xcuLHnnoN99235OnvtBbNnZ3ZPkUqX7AIbx86vFwFXAfOAKe7+QuL4vsD0PMUlUvHatg09\nTQpZZxLliEnSqlWtK0RtaoXPjBktf+y8ec1fT0SKL+vExN3/AWxKWOK7X8q7HifsAiwieTJqFLzx\nBsyZU5jrR1ljkq74tbmkoHHyknyda1JzzDGZj9CISPHkMmKCuy9w9+nAxma2SeLYFHcv0I9Pkcq0\n997QuTNMnFiY68dtxKQ1oxXJIloRKW259DFpY2bnmdki4B3gHTP73Mx+ZWY5JToikl6nTrD//oWb\nzomqwVrjGpN0bzenkLsLK7kRiVYuicQlwMnA2cCgxOMc4KfAr/MXmohAmM6ZPBk++CD/147LiEkm\nmtsrJ911W0sJikg0cklMjgV+5O43uPsricf1wPHAD/IanYhw0EGhEPb++/N/7bjVmGRaL1Ksrq1n\nnAEFXhkpIo3ksly4B5CulmRO4n0lo7a2lu7du/9vCZRIHK23Huy+e5jOOeGE/F67lEZMGn98oUdM\nAK66KjwfeyzsuGPz54qUu7q6Ourq6li0aFFB75PLiMlMwlROYycn3lcytLuwlIrqanjsMfj88/xe\nN24jJs0p1ihJunh+//vi3Fskzoq1u3AuicmZwFgze93Mbkk8XidM45yR1+hEBIDDDgvJQ319fq+7\nfDmstVZ8RkziuirnkUcKc10RWVMufUyeBrYE7gXWSTz+Sdhd+JnmPlZEctO7NwwbBnffnd/rLl8e\nliNHvSonl9EQ7Q4sUp6yqjExs7UIK3D+7O7nFiYkEUnniCPgzDPDdM466+TnmsuXw9prl8aISeNV\nOS1dN1fprvHee62/rohkJqsRE3dfQZjKyaVoVkRa4fDDw542+ZrOcQ99TKIaMUmtMdHoh4gk5VJj\n8jiwR74DEZHm5Xs6Z+XK8BxFYlJqNSYiUjy5jHz8C7jczLYHpgJfp77T3fNcniciSaNHw+mn52c6\nJ5mMxGHEpE2bhreb0tReOUn5SkqU3IhEK5fE5PrE88/TvM+BtrmHIyLNOewwOOWUMJ1zzDGtu9Y3\n34TnYiUmjUdGkglALiMm6c4zU1IhUg5yWZXTppmHkhKRAsrndM6yZeG5W7eQmBT6l3rqTr5NJSm5\nxKC9ckTKizbdEykxo0fDww+3vtna0qXhuVu38Jzc0K9QmhsxySQZyGQqR0mFSOnLODExs70STdXW\nTvO+7mY2y8x2z294ItJYvpqtNU5MCj2dkyy2hfyOmGTbQVZE4i2bEZNTgZvd/YvG73D3RcCNgLa7\nEimw3r1h+HC4667WXSeZmKyd+FOj0IlJa0dMUhVrrxwRKb5sEpOBwKRm3v8IMKR14RRXbW0tVVVV\n1NXVRR2KSFaOOCK0SW/NdE6pjZi01OtEq3JECquuro6qqipqC7zldjaJSS+guR9dK4D1WxdOcWkT\nPylVyemciRNzv0YyMenaNTxHOWKSejxThR4xUYIisro4buI3H9iumffvAHzQunBEJBPJ6ZzWrM6J\ny4jJhx82xBKnGhMlJiLRyCYxeQj4tZl1bPwOM+sEXAg8kK/ARKR5rZ3OKXZi0tSIyZlnwsiRDceb\nkknb+nwmE3vumb9riUjmsklMLgZ6AP8xszPNbFTicRbwRuJ9lxQiSBFZU2unc1L7mEB0Iya5KORo\nhvbtEYlWxomJuy8EdgNeAy4D7k08Lk0cG544R0SKIDmdc8cduX18lCMmK1emT05a22BN0y8ipS/b\n3YXfcfcDgZ7At4FdgZ7ufqC7zy1EgJkys03M7MlEP5UZZnZ4lPGIFMP3vw+PPhrqNLK1dGkYHUgm\nJskRlEJJHTFZsSL7UZOW9sZRUiJSHnLq/Orun7n7S+4+xd0/y3dQOVoBnOLu2wL7Adcmal9EytYR\nR4Rf2LkUwS5dCh07QqfE/5LUlvGFkJqINJWYNJVcvPpqwwhP43NTE5Z8JCdKcESiVTYt6d19gbu/\nknh7IfAxoe5FpGz17An77Qd//3v2H7t0KXToEDbxA1i8OL+xNZbJiElToyg77LB6y/x0yYP6mIiU\nh7JJTFKZ2RCgjbvPjzoWkUI78kh44QV4++3sPu6rr0IPkziNmKTTVKKQrimbkgqR0heLxMTMRphZ\nvZnNN7NVZlaV5pyTzGyumS0xs8lmtnMT1+oB3AocX+i4ReKgqgq6dIFsGxh/+WWoLylWYpI6YrJ8\neeZTOS0lJlpFI1JeYpGYAF2AGcA4YI0fQ2Y2BrgaOB8YBMwEHjazno3Oa09ipZC7v1jooEXioEsX\nqK4O0znZjBg0TkwKPZVTqBGTfNeYvPNO668hIrmLRWLi7pPc/Tx3nwik+/unFrjR3W9z9znAicBi\nYGyj824FHnf32wsbsUi8fP/7MHs2zJyZ+cd8+WWYymnbFtq3L+6ISTbFr00dK9SqnPvvz891RCQ3\na0UdQEvMrB1hc8BLk8fc3c3sMWBoynnDgCOAV8zsUMLIy9HuPqupa9fW1tK9e/fVjtXU1GjvHCk5\n++wTCmH//nfYccfMPiY5YgJh1KSYIyZNTeWk09KISSbnikhu6urq1tjodtGiRQW9Z+wTE0LPlLZA\n4+ZtC4EByRfu/hxZ/nvGjx/P4MGDWx2gSNTatYPRo0OdyeWXh1GQlnz5JWy2WXi7c+fSGjFJPV6o\nvXJEJP0f69OmTWPIkCEFu2cspnJEpPWOOQbmz4fHH8/s/MYjJnFITLLpbZI8N981JiISrVJITD4G\nVgK9Gh3vBSwofjgi8bTLLrDNNvCXv2R2/ldfNSQmnTuXVvFrao2JRkxEykvsExN3Xw5MBUYmj5mZ\nJV4/H1VcInFjBj/8Idx7L3z6acvnRzliks/lwupjIlJeYpGYmFkXMxtoZsmyvc0Tr/skXl8DHG9m\nx5jZVsAfgc7AhNbct7a2lqqqqjUKe0RK1dFHh9GIlr6l3eGTT2C99cLrYhe/5nO5sIgUR11dHVVV\nVdTW1hb0PnEpft0JeJKwksYJPUsgLP8d6+53JXqWXESYwpkB7OfuH7Xmpip+lXLTqxccdFCYzjnp\npKbPW7QoJAc9E52Aoih+TX2dpBETkfhKFsIWuvg1FomJuz9NC6M37n49cH1xIhIpXWPHhoZrM2fC\nwIHpz/kokdKvv3547tIFvviisHEl97pp1671y4UL2cdERKIVi6kcEcmfAw+EDTaAW25p+pxkYpIc\nMenePYyiFFIyMenYMb/LhTViIlJelJiIlJl27eC44+DWW8PKm3Q+/jg8J0dMipmYdOoU3l6+fM1z\nslkuXOwRk6VLC3t9EQkqOjFR8auUqxNPDEnJX/+a/v0LF4ZVPD16hNdRjJisWAF9+7b8cS31Mcnk\n3HzYYgv4858b/h0ilaZYxa8VnZiMHz+e+vp6taCXsrPppqHO5Pe/T//L+p13oHfvMLoCITEpVo1J\nx45htGT5cujQYfVzctkrJ92UTiHstlsYidpuO7jzzsxrZETKRU1NDfX19YwfP76g96noxESknJ18\nMrz+Ojz55Jrvmzdv9dGK7t3DcuF00yv50ngqZ8WKkKTkqtg1JnfeCS+/DJtvDt/7HgwaBPX1qmsR\nyTclJiJlas89Yfvt4Te/WfN98+ZBv34Nr5N7WRZy1CQ1MVm2rHUjJqnHizlyMWQIPPQQPPtsmAYb\nNQp23RUee0wJiki+KDERKVNmcO65MGkSTJnScNw9jKRsuWXDsWRiUsg6k2Ri0qVLSExWrID27Vc/\np1RW5QwbBk88AY8+Gl7vsw985zvw3HPFub9IOVNiIlLGDj8cttoKzj+/4di8efDZZ+Gv/6RiJSZr\nrdXQ/n7FivzUmCRHTNL1NikkM9h7b5g8OUzpfPYZDB8elmtPnVq8OETKjRITkTLWti1cckkYNbnv\nvnDsmWfC8047NZyXTEw+/7xwsSQTk44dW5+YpB4vVvFrU8zgkENg+vRQh/L22+Fze9hh4ZiIZEeJ\niUiZO/TQ8Ff8SSfB/Pnw97+HuohkDxNoaLSW7G9SCKkjJl9/HY5lUvyaLuEwW32kJHksyjqPNm1g\n9Gh47TWYMAFmzIDBg2H//eGpp1SDIpKpik5M1MdEKoEZ3HRTSAq23BIeeQR+/vPVz1lnnbB0+MMP\nCxdH6ojJl1+GY7mOmLRpk34qJw7WWguOPRbeeANuvx0++CDUnwwdGnZ+1jJjKVXqY1IE6mMilaJ3\n7zCFM25c+Gv+8MNXf79ZaGO/cGHhYkiXmDQufk2nqRGT5PHUzQDjkpxA+LfW1ISRk4ceCv/u734X\ntt02bLL4zTdRRyiSHfUxEZG82nTTsHT42GPDL/bGevUq7IjJ8uUNUznJxKTxVE6mIyapiUkhe6/k\ngxkccECYznn+eRgwIGy0+K1vwfjxTW8bIFKplJiICBASk0KOmCxbFhKRfEzlpK7ASY48RF1jkomh\nQ0MR8qxZMHIknHlmSBjPP7+w9T0ipUSJiYgAYSqnkCMmS5Y0JCbJZCLXxGTlytIZMUlnm23ClNp/\n/wvHHANXXRUSlFNOgXffjTo6kWgpMRERIIyYLFhQuOsvXRqSkk6dGo516bL6OW3S/ERKl5isWrXm\niElT58bZppvCtdeGvYvOPBP+9rcwxXPssWFURaQSKTERESD8knzvvdWLSfNp6dKQlKTWlXTtuvo5\n6WpfWkpMSnHEpLGePeGCC0KC8pvfhK6y220XWt6/8ELU0YkUlxITEQHC3jnLl8P77xfm+skRk9Rk\nJNfEZOXKhmW3pTxi0ljXrnDqqWGK5y9/gf/8J+xqvPvuobtsoZJGkThRYiIiQMOmfnPnFub6ycRk\nnXUajjWeyskmMSmnEZPG2reHH/wgTOfce29IvkaNCtM8l18OH30UdYQihaPEREQA6Ns3PBc6MVl3\n3YZjjUdM0skmMSn1EZPG2rSB6uqwH8+UKWHH6AsugE02gaOPDsfL7d8sosRERIBQ/7HRRmGvl0JI\nN2KywQarn5OuK2ol1JhkYuedw0qe+fPh4ovDTsZDh4bNGG++Gb74IuoIRfJDiYmI/E///qGVeiGk\nGzHZeOPVz2ltYlIJowfrrQdnnAFvvgkPPhiSyR//ODwfcww8+aTa3ktpU2IiIv8zcCDMnFmYa6cb\nMdlww9XPybSPyapV5Vn8mo22bcPmjA8+GFbznHNO6Cy7114hwbzoonBcpNRUdGKiTfxEVjdwYFgJ\nsmRJ/q+dro9J45b0mY6YQMMKlUobMUmnTx8499wwivLvf4dalCuvDAXNe+8ddpRevDjqKKXUaRO/\nItAmfiKrGzgwJAevvZb/ay9ZEpISs7DCZPfdw/H+/RvOySaxSCYmqR9T6VMYZjBiBPz5z6FZ3i23\nhBGlo44Ko1NHHhlW+RQi8ZTyp038RKTottsubLQ3ZUr+r/3ll9CtW3j77rtDLQSEze2SshkxWbEi\n83MrUdeu8MMfhhGUN9+E006DV18NOxyvvz6MGRO+Dl9/HXWkIqtTYiIi/9OpU1j98e9/5//aX3zR\nkJi0a9fQfj61DX2mNSawem1JUqWPmDSlf/+wUeArr8CcOaEe5c03YfTokKQcfjjccUfD5ooiUVJi\nIiKr2XPPMIqRz9GHZctCLcjaa6/5vvbtG97OZsRk6dLMz5UGAwaExGTaNHjrrZCwvPMO1NSEJKW6\nOuzZs2hR1JFKpVJiIiKrGTky7DI8fXr+rpnssZEcMUmVeiybxKRxMaeZRkyy9a1vwVlnwUsvhcZ6\nl1wCCxeG5m3rrw/77gu/+13hmu6JpFNWiYmZ/dPMPjWzu6KORaRU7b479OgB//hH/q6ZnCJIl5ik\njpika5bWVGKSrqGYRkxy17dvqEN54QV491246qpw/LTTYPPNYZttwj4+Dz4IX30VaahS5soqMQGu\nBY6OOgiRUtauXRjOv/vu/P2iTyYm6aZyUqX7hZdpYuKuEZN86dMHfvYzeOQR+OSTkKTutltY0XPw\nwSFx3XPPMMIyZYo2F5T8KqvExN3/DSiXF2ml0aND/cELL+Tnes1N5UDDZn7ZJCaNayDcNWJSCN26\nwWGHwZ/+BPPmhc7A11wD3bvDFVfAt78dpn2OOAJuuAFmz9bXQVqnrBITEcmPffYJw/d/+EN+rvfp\np+G5R4/07587F045pXWJyfLlGjEpNDPYcks4+WSYODGMpjzzDPz0p2EPn5/+NEz5bLhhSFT+8IfQ\nE0dfF8lGLBITMxthZvVmNt/MVplZVZpzTjKzuWa2xMwmm9nOUcQqUgnatIGTTgrTOfloa/7hh+GX\n2nrrpX//+utD797pl6tmOpWTuuOwFEe7djB8OFx4YWiH//nn8PDD8KMfwQcfQG0tbL992Kzxnnui\njlZKRSwSE6ALMAMYB6zxo8XMxgBXA+cDg4CZwMNm1rOYQYpUkhNOCBvuXXhh66/14YchKWnbtulz\nunULIyaNk4tMR0xWrMj8L/O11srsvKTm4pYGXbuGlTyXXALPPhsSlccfD5/v55+POjopFbFITNx9\nkruf5+4TAUtzSi1wo7vf5u5zgBOBxcDYNOdaE9cQkSx07Qq//CXcemtozNUaH30U/mpuTo8eYdTj\n889XP95UYvLVV6vvtbNiReYjJr16ZXZe0rx52Z0vQefOYVPB1B2lRVoSi8SkOWbWDhgCPJ485u4O\nPAYMbXTuo8CdwAFm9q6ZfbuYsYqUmx//GLbaCo47Ln0L+Ex9+GGYrmlOnz7h+b33Vj+eLtlIJiTJ\nj4HmR0wOPnj11126wGefwXnnNR9T0iabZHaeiLRelgOakegJtAUWNjq+EBiQesDd98nmwrW1tXTv\n3n21YzU1NdrUTyShffuwEdxuu8Gll2b+i7yx+fNh442bPyc1Mdlhh4bj6RKTDTYIvTY22yy0VofQ\nXbapEZMLLghNw8aMCa/btIF11gnTVA89BC+/vObHzJkTkjLJj+nT4a67wpYHffuGmiOJv7q6Ourq\n6lY7tqjAbYFLITEpmPHjxzN48OCowxCJtV13DW3LL7gg/FI54IDsr/Hf/4Zdb5uz0UZhJOP11+Gg\ngxqOp+uR0atXSEzWWafh2NKlTY+YdO4clkAnE5PUBObhh9MX5fZUBVveDB8ekpLk53/99WHbbUN7\n/C23DM8DBoSEJdv6HymsdH+sT5s2jSFDhhTsnrGfygE+BlYCjWeFewELih+OSOX51a9CsjBmTPY7\nDy9ZEkZMvvWt5s9r2xZ22glefHH146lTSKeeGpKcZI1Iao3JJ580PWKS3CgwOSVz7LEN70v2UGms\nqaXNkr2bbw7FygsXwv33w09+Eka9Jk8OdUwHHwxbbBEKoHfZJUwh3nhjaJW/bFnU0UuxxT43dffl\nZjYVGAnUA5iZJV5fF2VsIpWiTRuoq4P99guPxx6DTP9gSk619O/f8rkjRoTeF99809CqPjUx2XHH\n0F8lWUjbsWNYPXTTTeGXXksdSDfaCP7v/1avOUltiQ+hP8fChWGqYa+9wi9JyY8NNgif+9TP/6pV\nIXH9z39Cz5Pp00Njv1tuCV/Pdu1g4EAYPDgkt/36NTx69NCUUDmKRWJiZl2A/jSsptnczAYCn7r7\ne8A1wIREgjKFsEqnMzChNfdN1piorkSkZV27hnqM/fYL++nU1UHVGh2H1vTyyyGxGTSo5XNHj4aL\nL4Z//QtGjQrHUhOTTp3Cc79+4blLF7j22lCTcuqpIaFJJ5mwpGuJbxamFY4+OjxSa2Eef3zN8yW/\n2rQJ9UV9+oQNJJOWLoVXXw2jJlOmhMcdd6zev6Zbt4YkJXmNPn0apgW7dAnTeF26QIcO4Wvdps2a\nz23bNoyqSdOS9SaVUmOyE/AkoYeJE3qWANwKjHX3uxI9Sy4iTOHMAPZz949ac1PVmIhkp3t3eOKJ\n8Au8uhrOPjsUkLZr1/THPPNM6AbatWvL199++1DTcuWVIekxS5+YJItjk/1FNt88nJccnWksWXuS\nTEwa/5X92mstxybF1bFjqGnaeWcYNy4ccw+rqebOXfPx5JNhNCzX35lmob4l+ejYMSQ+XbuG5402\nCsXWffuG5y22CPUxlZTQJP+IL3SNSSwSE3d/mhbqXdz9euD64kQkIk3p3Dl0hL3iirBK58EH4Xe/\nC6MojS1bBvfd1/CLJRPnnx8KbO++O4ygpCYmnTuH5+HDYehQOPLI8DqZqEydGp4PPTRsOJeULKhM\n7tWj4f/SZBamb3r0aHoq8csvw1Tc11+v/kiu2ko+Vq1qeF65MjxWrAiP5ctDbdRXX4XrffEFvP9+\nmGZ6992GXbCTNTF77RVGe4YMUfFuPuhTKCJZa9MGfvGL0OXzpJNgjz3C1Mvpp8OwYQ2/+H/72/BD\n/egs9vzef/+wadzJJ4cdbFOLH5MrZXr0WL2T6MYbh/c991x4PXRoSEw22SSMvCQLb5OFriqoLF/d\nujW9WWQ+rFoFCxaEzQqnTAnfh5dfDueeG0bkvvOdkKTsvXdYbq4kOHsVNAglIvk2ZEj4wXzrrWHX\n2REjQhJw1FEhITj7bPj5z7PvB/L734fkZ/TosNomqXfv9OcnC1Xfeiu83mij8LzuuqGYNjnVdMgh\n4Tnbzq8iSW3ahER45MiQnN9/f/geff75kJh//jmcdlqYvuzdG048MYy0SObMK3DXKzMbDEzdfffd\nVfwqkierVoXVOhMnwsyZYbXLEUeEVS25zMM/80xINpJTOfX1DYlFOrfcEjaPgxDH3nvDppuuuQnh\nsmWhEFKkUL7+OuwV9NhjoUh8/vxQO3XWWSFhL9W6lNTi13//+98AQ9x9Wr7vU9GJydSpU1X8KhJj\nN90UEpshQ9J3Z001f35Dn5KZM8MS0+7d19x7R6SYVqyABx4Iq8eefjoUeJ97Lhx+eOluDplS/FqQ\nxEQ1JiISWyecEHqXpO6J05TevUOdy+LFDX1OUpeWikRhrbXCCrbq6jAKeMkl8L3vhb4+J5wQ6qn6\n9cuuFsUdPvggTF2++WZIvtu0CTUuG28cVjKVcudiJSYiEmu77JL5uffcE35oJ/8S3XDDwsQkkosR\nI2DSpNCbZfz40PX2zDPD1gqDB4fHNtuEBKN9+9CXZ9myUMMyb154vPVWeCxeHK5pFpY0u4cpJPeQ\npEyZknkTxLhRYiIiZSN1aPypp0KNiUjc7Lwz3H576MkyeXJY5j5tWlgi37gmCkKSstlm4bHbbmFL\nhf79Qy+Vfv0atmZYvjxMaT7xxOobYZYaJSYiUpb22CPqCESat+66oWdP6saY33zT0HelQ4fw6Ngx\ns4LZdu1CA7ixYwsWclEoMREREYmJ9u3X3L+p0pTooiUREREpRxU9YqJN/ERERDJTrE381MdEfUxE\nREQyVug+JprKERERkdhQYiIiIiKxocREREREYkOJiYiIiMSGEhMRERGJDSUmIiIiEhtKTERERCQ2\nlJiIiIhIbCgxERERkdhQYiIiIiKxocREREREYkOJiYiIiMSGdhfW7sIiIiIt0u7CBaTdhUVERHKj\n3YVFRESkYigxERERkdhQYiIiIiKxocREREREYqOsEhMzO9jM5pjZG2Z2XNTxiIiISHbKJjExs7bA\n1cCewGDgDDNbN9KgslBXVxd1CKtRPM2LUzxxigUUT0viFE+cYgHF05K4xVMoZZOYALsAr7n7Anf/\nGngI2DfimDIWt284xdO8OMUTp1hA8bQkTvHEKRZQPC2JWzyFUk6JycbA/JTX7wO9I4pFREREchCL\nxMTMRphZvZnNN7NVZlaV5pyTzGyumS0xs8lmtnMUsRbK/PnzWz6piBRP8+IUT5xiAcXTkjjFE6dY\nQPG0JG7xFEosEhOgCzADGAes0YrWzMYQ6kfOBwYBM4GHzaxnymnvA5ukvO6dOFYS4vYNp3iaF6d4\n4o6O6dUAAAzaSURBVBQLKJ6WxCmeOMUCiqclcYunUGKxV467TwImAZiZpTmlFrjR3W9LnHMicBAw\nFrgycc4UYFsz2wj4EtgfuKiJW3YEmD17dr7+Ca22fPlypk3Le2ffnCme5sUpnjjFAoqnJXGKJ06x\ngOJpSVziSfnd2bEQ14/dXjlmtgqodvf6xOt2wGLgsOSxxPEJQHd3PzTl2MGEkRUDrnD3W5q4x/eB\nvxfsHyEiIlL+jnT32/N90ViMmLSgJ9AWWNjo+EJgQOoBd38AeCCDaz4MHAnMA5a2PkQREZGK0RHo\nS/hdmnelkJjknbt/AuQ9yxMREakQzxfqwnEpfm3Ox8BKoFej472ABcUPR0RERAol9omJuy8HpgIj\nk8cSBbIjKWDGJiIiIsUXi6kcM+sC9CcUrQJsbmYDgU/d/T3gGmCCmU0lrL6pBToDEyIIV0RERAok\nFqtyzGwP4EnW7GFyq7uPTZwzDjiTMIUzA/ipu79c1EBFRESkoGKRmIiIiIhACdSYRMnM5pnZDDOb\nbmaPRx0PgJl1SsR1ZctnFyyG7mb2kplNM7NXzOxHUcWSiGcTM3vSzGYlvl6HRxlPIqZ/mtmnZnZX\nxHEcbGZzzOwNMzsuylgS8cTi85KIJVbfN3H7f5WIKfKfNymxxOrnsZn1NbMnEt8/M82sU4SxbJn4\nvExLPC9Ot7VLkWOqNbPXEo9rs/pYjZg0zczeBrZ19yVRx5JkZhcD3wLec/czI4rBgA7uvjTxn3EW\nMMTdP4song2BDdz9FTPrRSiW3iLKr5uZ7Q50A45199ERxdAWeB3Yg9ANeSowNKqvUyKmyD8vKbHE\n6vsmbv+vEjFF/vMmJZZY/Tw2s6eAc9z9eTNbB/jC3VdFHFayZnMusFmE38s9gcnA1sAK4BngNHd/\nMZOP14hJ84wYfY7MrD+hqdy/oozDg2RjuuRfCem2EihWPAvc/ZXE2wsJS8x7RBVPIo5/A19FGQOw\nC/Ba4vPzNfAQsG+UAcXk8wLE7/smbv+v4vLzJkVsfh6b2TbAN+7+PIC7fx6HpCShCng8BglcW8Ii\nlQ6EhTYfZvqBsfgix5gDT5nZi4k29lG7CvgFEf6wSkoMO88A3gV+4+6fRh0TgJkNAdq4e2XsdtW8\njYHUz8P7hM0tpZG4fN/E7P9VbH7eJMTp5/EWwNdmVm9mL5vZLyKOJ9Vo4M4oA3D3jwnbw7wL/B/w\nmLvPzfTjyyYxMbMRiW+S+Wa2Kt38mpmdZGZzzWyJmU02s51buOwwd98ZGAWcY2bbRRVP4uPfcPe3\nkoeiigXA3Re5+45AP+BIM1s/yngSH9MDuBU4PtNYChlPa8QtpnKOJ9fvm0LE05r/V/mMpTU/bwoR\nT0LOP48LEM9awHDgRGA3YB8zG9n4OkWMJ3leN2AoYXQ0J3n6/lkHOBjYlPDH0DAzG55pDGWTmABd\nCMuIx7HmsmPMbAwhgzsfGATMBB62MBeWPGecNRQQdXD3DyAM+RK+0IOjiodQJ/A9C/OsVwE/MrNf\nRhGLmXVIHnf3jxLnj8gwloLEY2btgXuBSzOdxyxkPFnevyAxEUZINkl53TtxLKp48ikv8bTy+ybv\n8STl+P8qn7HsSu4/bwoRD638eZzveOYDL7v7++7+TSKeHSOMJ2kU8EgiplzlI569gTcTifYy4EHC\n91Rm3L3sHsAqoKrRscnAb1NeG2GI6cwmrtEZ6Jp4uyvwMqEQLZJ4Gn3sscCVEX5uNkj53HQHXiUU\npUX2uQHqgPPi8L2Tct6ewN1RxUSY430D2CjxPTwbWDfqz1G+Pi/5iCdf3zd5+nrl7f9VPr+fW/Pz\nJo+fm7z9PM5TPG0JxdLdCX/g1wMHRvm9nHhfPXBQDL6Xv534/LRPfK4eAA7J9L7lNGLSJDNrBwwB\n/rfEzMNn7zHCsFc6vYBnzWw6ofX9BHefGmE8BZFjLJsBzyQ+N08TvklnRRWPmQ0DjgCqU0Ytto0q\nnsTHPUqY5z3AzN41s2/nI55sYnL3lcBpwFPANOAqL8AKj2w+R4X8vGQbTyG/b3KJhwL+v8ohlqLI\nIp6C/TzOJZ7E/61zCKtNZgD/cfecp09aG0/i3LWBnSnQjr/ZxONh9PEhwudmBmH05P5M7xOLlvRF\n0JOQtS1sdHwhoep8DR4KdXIdmst7PKnc/dYoY3H3lwhDeIWQSzzPUbjv5Zy+Vu6+T4HiySqm/2/v\nXkOlqOMwjn+f0C5kVy0rsotZFGWCmZDdqOhCYElUJJRdjJCoF0WEVPai7EURFURvwlt3iQqpsERT\nsosg6aEyulhWGpUa5iUzM8+vF/9Zz5xhj+tZdz1z3OcDg7sz/5l5Vjx7fv7mP7sR8S7pfyvN1J08\nzfx76VaeJv+7qSdPM3+uupUlr8HvN3XlafL7cbfzZJnm0MQioI48G0nd0bLkmQRMquckLdExMTMz\ns96hVQqTP4DtpHZg3kDg9z0fp1R5ypQFnGdXlC2T8+xcmfKUKQs4Ty0tmaclCpOI2EaaiLPjdi5J\nyp5/2sp5ypTFeXpnJufpPXnKlMV5nKcre80cE6WP4R1Cx/32gyUNA9ZFxCrgKWCGpCXAYuAe0kzv\nGXt7njJlcZ7emcl5ek+eMmVxHuepS6NuK+rphfQ5H+2kNlN+mZYbcyfwE7AFWASMaIU8ZcriPL0z\nk/P0njxlyuI8zlPP4i/xMzMzs9JoiTkmZmZm1ju4MDEzM7PScGFiZmZmpeHCxMzMzErDhYmZmZmV\nhgsTMzMzKw0XJmZmZlYaLkzMzMysNFyYmJmZWWm4MDEzM7PScGFiZnsdSR9KuqHBx+wr6UdJwxt5\nXDPrzIWJWYuSNF1Su6Tt2Z+Vx7N7OtvukHQVcGREzNzF8fdKWidp3yrbDpC0QdJdkb7y/UngiQZH\nNrMcFyZmre094KjccjQwtpknlNS3mccH7gamd2P8S6Svbb+myrbrgL7Ay9nzV4DzJJ22WwnNrEsu\nTMxa29aIWBsRa3LLhsrGrIsyXtJbkjZL+k7S6PwBJJ0habakTZJ+l/SipP657QskPSvpaUlrgfez\n9adK+ljSFknLJF2Sne+qbPsHkp4tnGuApK2SLqr2YiQNAC4G3imsP0TSFElrsg7IPElnAkTEWuBd\n4LYqh7wVmBUR67Ox64FPgIZeJjKzDi5MzKyWh4GZwFBgNvCKpEMh/cIHPgCWAMOBy4EjgdcLxxgH\nbAVGARMk7QPMAjYBZwN3AI8BkdtnCjC20GG5CfglIhZ0kfU8YHNEfF1Y/wbQP8s3HFgKzKu8DmAq\ncLGkQZUdJA0GLshy5C0Gzu/i/Ga2m1yYmLW20Vmno7JslDSxMGZ6RLweESuAB4B+wMhs213A0oiY\nFBHLI+Jz4HbgIklDcsdYHhETszHLgcuAE4FxEbEsIj4FHgSU2+et7PnVuXU3s/PLNMcDq/MrJJ0L\njACuj4i2iPghIu4HNgDXZsPmAL+ROiQVtwArI2J+4Ry/Zucxsybo09MBzKxHzQcm0LkgWFcY82Xl\nQUT8LWkjqSsCMIzUadhU2CeAk4Dvs+dLCttPAVZll1EqFnc6QMRWSS+RLrG8kd0NczrQ6VJSwQHA\nP4V1w4CDgHVS/mWyf5aRiGiX9AKpGHlEaeA4UielaAtpToqZNYELE7PWtjkifqwxZlvhedDRbe0H\nvA3cT+fiBlIHYsd56sw3BWiTdAypmzE/IlbtZPwfwGGFdf1IXY4Lq2Rcn3s8DZiYzV/pAxwLzKhy\njsOBtVXWm1kDuDAxs92xlHQ3y88R0d6N/b4FBkk6Itc1GVkcFBHLJH1GmoMyFrizxnHbgKMkHZKb\nxLuUdMfR9ohY2dWOEbFC0kJgPKmAmddFEXRGdh4zawLPMTFrbftJGlhY+tfebYfnSB2EmZJGSBos\n6XJJ01S4blIwF1gBvChpaDYP5FFSNyYKY6cClXkvs2rkaSN1Tc6trIiIecAiYJakSyUdL2mUpMlV\nPixtKqnQGkP1yziQJr7OqZHDzOrkwsSstV1BusyRXz7KbS8WCZ3WRcRvpCJgH9Iv6y+Ap4A/IyKK\n43P7tZMmtR5ImlvyPDCZ1KkozhF5DfgPeDUi/t3Zi8mOOwO4sbDpSmAh6XLNt8CrwHEUJsoCb5Lu\nHtpMlSJI0jnAwdk4M2sCdbx3mJn1nKxrshAYkp/3IukE0iTas7K7fmodZyCwDBheYz5KPRlnAm0R\n8Xgjj2tmHTzHxMx6hKQxwF/AcuBk4Bng40pRIqkPMIDUSVm0K0UJQESsljSe1BFpWGGSfZ7KF1lO\nM2sSd0zMrEdIugl4CBhEmhcyF7gvIv7Mtl8ILAC+Aa6LiK96KquZ7TkuTMzMzKw0PPnVzMzMSsOF\niZmZmZWGCxMzMzMrDRcmZmZmVhouTMzMzKw0XJiYmZlZabgwMTMzs9JwYWJmZmal8T8F+C7M3zCE\n1QAAAABJRU5ErkJggg==\n", + "image/png": "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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], @@ -353,24 +331,22 @@ { "cell_type": "code", "execution_count": 13, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[,\n", + "[,\n", + " ,\n", + " ,\n", " ,\n", " ,\n", " ,\n", " ,\n", " ,\n", " ,\n", - " ,\n", - " ,\n", - " ]\n" + " ]\n" ] } ], @@ -388,9 +364,7 @@ { "cell_type": "code", "execution_count": 14, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -415,14 +389,12 @@ { "cell_type": "code", "execution_count": 15, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{'294K': }" + "{'294K': }" ] }, "execution_count": 15, @@ -437,9 +409,7 @@ { "cell_type": "code", "execution_count": 16, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -453,12 +423,14 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], @@ -480,9 +452,7 @@ { "cell_type": "code", "execution_count": 17, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -503,14 +473,12 @@ { "cell_type": "code", "execution_count": 18, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[]" + "[]" ] }, "execution_count": 18, @@ -533,43 +501,41 @@ { "cell_type": "code", "execution_count": 19, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ]" + "[,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ]" ] }, "execution_count": 19, @@ -592,18 +558,18 @@ { "cell_type": "code", "execution_count": 20, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n2oFEPhuJq6XrnVymJEmSJN2xhk5Ad9scKZJutidsp/+a/vg4+hDxdMStg5YtW2DKFHj+eZg3r9rh\n/0tPZ8Dhw7yYkECz/ft5JymJnJKSfyqMGgXff1++vDR6NNYqU7aHbkdRFB5b9xiXCy430BVKkiRJ\n0v1BBi53aP2x9QwJH0J/z/5sD92OlbGV9op79kBQEDzxBHz2Gdxwh5FaCOacPcvk06eZ0rQpZ7t2\nZYyjIx+mpOC+bx+vJCSQXlRUXnnECPjxR9i2DZ58EhcjO7aHbq/KyltYWq/PspIkSZKk+4oMXO7A\nioMrCPkhhOD2wfww6gdMDEy0Vzx2DIYMgW7d4LvvNPK0FKnVhMbH82FKCp94efG5tzceJiZ85u1N\ncrduzHR15euMDDz272fyqVMkFhTA4MGwdWv5pt1hw2hj3pyfg38mKi2KhbsX3qWrlyRJ0s3q1atR\nqVRaX3p6ehw4cKBe+snMzGTy5Mm4urpiYmKCh4cHz2lZkq/JwoULUalU+PhoubkCiIyMpFevXpiZ\nmeHs7MyMGTPIy8ursd3k5OSq6160aJHWOqGhoahUKiwtLWs9bh8fH5o3b37bOj179sTZ2Rm1Wl3r\n9u8Xco+LDrRtzt15difTfpnGzK4z+WTgJ6iUW8SAKSnw6KPQrBn89FP5rc0VsktKGHHsGAevX+f7\ndu140t5e41R7Q0Pe8/TkVXd3vkxPZ0lqKl9nZDDawYHXe/bEZ9u28oBo8GC6b93KnF5zWPT3IkI6\nhMjNupIk3VcURWHBggVaf7G2aNHijts/f/48PXr0QKVSMXXqVFxcXEhPT691UJSWlsb777+Pubm5\n1uNxcXH079+ftm3bsnTpUs6fP8/ixYtJSEhg27ZtOvVhYmJCeHg4c+fO1SjPz89n69atmJjc4kNw\nDcaMGcOcOXPYs2cPvXr1qnY8OTmZ/fv3M336dFSqhpu3aOjNuQgh5OsWL8APEDExMeJms3+fLVw+\ncRFqtbrasSqFhUJ06iRE8+ZCpKdrHErMzxct9+8Xdnv2iMgrV7SefmXPFRE3IE4kvJYgSq6WiPzS\nUvHF+fOiWWSkICJCzE5IEOq//hLCzEyIwEBRcC1HeC/zFoHfBt5+XJIk3XdiYmLErX7eNHarVq0S\nKpWqQa/tscceE15eXuLy5ct31M7o0aNF//79RZ8+fUSHDh209uPi4iJyc3Oryr7++muhUqnE77//\n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\n+APeIHSDgel4A791B147yK4J6bpxnXj55ZfVOLcJirOVuETdqFFe4hLBmEuJ7PjCQt4ZPJiXjjqK\nFbt2MaS8nIvmzWO5P7uuiMSneGqcG2occKVz7hq8cVvucc6NwBtqPyqDz8WTzHTNUdRUxTnFbNy5\nMegwksuoUbBqFcydG3Qkzc7M+HrbtswdOpRHe/dm6qZN9PngA360eDGV1TGfWURE4lCkkyx2Bd7z\nf64C6icb+SMwDbj6MOOKK5ktlLg0VX1VkXNO3Tuj5eSTITfXK3Xx51tJNRlpaVzVqRMXtGvHb1at\n4t4VK3hy7Vp+3q0bV3fuTFZa8jTXa2wuH5F4FNRnNdLEZR1QDCwHVgDHARVAKZB031Yt8hpOQC0H\n0jq3NbWulm17ttGyRcugw0kOLVrA6ad7icuNNwYdTaDyMzK4taSEqzp25Lbly/nR4sU8vmYNE3r2\n5KzWrYMO77C0adOG3Nxcxo4dG3QoIk2Wm5tLmzZtmvWckSYubwGjgVl4bV0mmNk3gWPwxnJJKr++\n512eemY0Y8aMUTuXQwgd9l+JSxSNGgU/+AFs3gytkn8m4UPp0KIFj/buzbhOnfifRYsY9dFHjCou\nZkLPnvTOzQ06vIh07dqVefPm8fnnn4e9766Vu1h681J2zN1Bx8s70vHyjqRlJE8pVDxzzlFZ+Sar\nVt1PdfVG2re/iI4dLyM9/fBmWE4Ubdq0oWvXrvusi/Xs0JFOspgGpDnnavzX5wMnAAuBx5xzUZuv\nKEj1kyy+/vrdnH76j4MOJyHMXDuTssfLKL+ynCEdNVFc1KxYAd26wQsvwLe+FXQ0ccU5x4uff871\nixaxZs8eru3cmZtLSijMiPS5LDHV1dSx4tcrWHbbMgrKCuj3p37k9krMJC4R1dbuZMWKu1ix4h6y\nstrRq9dDtGnztaDDClRcTbLonKurT1r818855651zj2ULElLqMzMdkGHkDA00WKMdO0K/funVLfo\npjIzvtG2LfOGDeOWbt14dM0aen/wAU+uXUtdCvXESstIo+TmEoa8N4SaTTXMOHoGax5fQyQPpxK+\n9PRcSkt/ybBhn5CXN5C5c7/OggXfo7Z2Z9ChJZ3DGcelyMxuMLMn/eV6MyuOZnDxIitLjXObSolL\nDI0aBa+9BnV1QUcSl3LS0/l5SQkLhg3j9KIiLl+wgGHl5bwbo+LqeNVyWEvKZpXRfmx7Pr3qU+Zd\n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\nNnoOAAAAAElFTkSuQmCC\n", + "image/png": "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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], @@ -617,61 +583,6 @@ "plt.show()" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There is also `redundant_reactions` attribute for cross sections (like total) which are built from summing up other cross sections." - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[, ]\n" - ] - } - ], - "source": [ - "pprint(list(gd157.redundant_reactions.values()))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that the cross sections for these reactions are represented by the `Sum` class rather than `Tabulated1D`. They do not support the `x` and `y` attributes." - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'294K': }" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "gd157[27].xs" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -683,29 +594,29 @@ }, { "cell_type": "code", - "execution_count": 23, - "metadata": { - "collapsed": false - }, + "execution_count": 21, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "" + "Text(0,0.5,'Cross section(b)')" ] }, - "execution_count": 23, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\nln8MOElr/feVGtxCwDAMrr76atatW8f73/9+fve73/H5z3+eN73pTfj9fiYmJrj88st59NFHue++\n+zJapBfCunXr2LdvH5OTkzniZzEwPT1NIBDIKPfu7OxkdHR0/nk0Gs0QKdX2pOSb9ThdpBSa7ikm\nklLN6p56iJR6yaKAMjl1yVLOXLoUgH3RKPcMDvKHgQG+/fJL3BR/jhbTxyldvWzsWsLGrl5eEWms\nz2AorDjxlAjxuPtVTMQ1wwN2TtVQtSq2o3sm+OnRWwlmtepvP6KbM267sKRjBkwwwLUAuiVs0xJ2\n/1wbpvv10YZCZ8VMFDplVnHFqbdKOtJnpTBKeRu+Bvisw/I7SU462LRUorrHjXe84x1s3LiRD3/4\nw2zatIn29nZWrlzJSy+9RCKR4Ac/+AEnnXRS0cdNTUL4l7/8hRNOOKGiY24GotFoRhQFoKurK0Ok\nuEVSapXuyY6kJBKJ+fF4iZTsEmmnY2cvr3Z1T6Ole6rpb7UTiskRY76wo40Wzmtt4bzWlViv0Dw3\nM869w/3cMzzAF557krjWLA2EOKm9h9UznRzr72aJGfY+SQ0IhgyCHrMHzMY04yM6p2ooWfGmMYzM\n5bbtXvBSKNO7JpjeldmqX0/G0LOJkjrZRnyKsw/xMeuQYRmJabbvLTH1EtSO6sfyFVLW7M1C6LPS\nUNU9abTiXGocx3teqYanUtU9bqxdu5Y77riDxx9/nDvuuIP+/n6WL1/O29/+9vmeJ6UcExavSJme\nns7p7tvZ2ZlhJs4WKW6RlGqle5wiKam+Ll7N3CqV7imGQiMp9eiX4nRTNBS0thuO6YxwK5Bnajml\n5la7XCptK8dVhlIc097JMe2dvGfVOqatBI+MDnP/yAD3Dw/y86k9aOAgI8KxgW6O83dzjL+bbrN5\n/CyJBLz0fAwzS7wEggqfL+AoEE0fdPSUdudO9E/Q9w+3YbQnhV3cF+SQz70J31xaKNY3jd1qYQSd\nUygRnyLicEcrpM+Kz6cxlMbO6jWjwgr/2QY66443GzPYu7MF06HznC9msWTfZM5yJ/bsyb25N1Ma\nqNGqe1L8GXgr8Lms5W8DdpQ9okXA+vXrWb9+fUWO1d3dTU9PD88++2xFjtdsOEVSstM9hXpSap3u\nAfdIimEYJRtns89XDU9KLSMpSs3NeWMoWlpNZ/+E0w3TANOvPSfKCYZhxSEBxzb1fo+usNnWyYjp\n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\n", + "image/png": "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6urqsGzZMlx77bUhC+CLL77AjBl9tRnPPPMMfvGLX8jO4fF4cPjwYZEVEYRSiqlTp6KjowPbt2/HhRdeiH379mHLli2oq6sLxUYGDRqETZs2obS0FB999BFTnILzUvP3ECl75l8KX2vfor99L+Bq7HscCJ6LURKUCccyBOULdsDVbFGXIThkgh3eVvld+aCh4gXyUJMOnpa+hT233Axfq1ygJ52tARxykWtpt4N2iI/X5BsAwZj9pV/KXkcUEkq7ve2yMbOu78YoKCjeCASl22NArlG+MLuaGmET6OdhsxEWgVV381fs741eyx53Mqw1KacOlQvz9y3yue0/3GctvXJu9B03CCGbKKUxZeaoDco/SAj5FH0W1ZWU0m9juXAiyDaXV39MnDgREydOxL333ovNmzdj1apVePfdd3HnnXeGgpWjR4/G6NGjMWzYMJSUlECj0aC2thaffvoptmzZggkTJuC9995LiJgAgSynTZs24YorrsD111+PVatW4dFHH8WQIUPQ0tIiOnb8eHaNr16vZ4oJ0LcT5oIFC7By5Uo4HI6QtVFSUgKtVgufzxdqr9KfWJx00klYu3at4vOxUPHiFaLHlTqxu+SrGY/C0yRegI1FFria5Iuy1m6Gr128+BuKTXCrcN8YikxwN8mPm/4Fu2hz78//DX9b3/HT1i8SPd/jUxAyPdsNm+eVb23gp+oCz2rp8lDk9GZbBX93eCiskgws4XFCfv0RO+U5P18sQGVWqVXHtg48bgK9Qd1Nis8FaAV/it1OAotZRZaeGyAGAGmwi3VYC6W3JcoPlNLRyZlS7FRVVdGNGzemehopob29HRs2bMDXX3+N9evXY+/evdi/f3/IxWSxWDBp0iRcdtllWLRoUcLERIjf78fDDz+M//u//4NGo8Ff//pXOBwO3HbbbXjuuefw/fff4/77748q0cDr9WLSpElwu90wGAwYMWIE3norsHXq4MGDcejQIYwaNQo//vhjv+epra1FbW1tzKnTTDzviR9LBMXHcBEF766lsKqxW9zs7HqLTuyaU1q8LURu9QBAu0+cgmXSit2iSoJiUxAUhwpB6fFpRHf+AODwEObi3+hsh1USi7hzc99nG+xiYmXcNjcrlMq0trL/HvLzxS8ok3xke5o00DGEY/vH8mQTADhqarvs+IOrxSeljASIo89oh17iof3hmb64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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], @@ -776,10 +687,8 @@ }, { "cell_type": "code", - "execution_count": 24, - "metadata": { - "collapsed": false - }, + "execution_count": 22, + "metadata": {}, "outputs": [], "source": [ "gd157.export_to_hdf5('gd157.h5', 'w')" @@ -794,10 +703,8 @@ }, { "cell_type": "code", - "execution_count": 25, - "metadata": { - "collapsed": false - }, + "execution_count": 23, + "metadata": {}, "outputs": [ { "data": { @@ -805,7 +712,7 @@ "True" ] }, - "execution_count": 25, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -824,10 +731,8 @@ }, { "cell_type": "code", - "execution_count": 26, - "metadata": { - "collapsed": false - }, + "execution_count": 24, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -856,10 +761,8 @@ }, { "cell_type": "code", - "execution_count": 27, - "metadata": { - "collapsed": false - }, + "execution_count": 25, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -885,31 +788,27 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 26, "metadata": { - "collapsed": false, "scrolled": true }, "outputs": [ { "data": { "text/plain": [ - "array([ 0.00000000e+00, 3.02679600e-13, 1.29110100e-02,\n", - " 6.51111000e-02, 3.92627000e-01, 5.75226800e-01,\n", - " 6.96960000e-01, 7.39937800e-01, 9.63545000e-01,\n", - " 1.14213000e+00, 1.30802000e+00, 1.46350000e+00,\n", - " 1.55760000e+00, 1.64055000e+00, 1.68896000e+00,\n", - " 1.71140000e+00, 1.73945000e+00, 1.78207000e+00,\n", - " 1.81665000e+00, 1.84528000e+00, 1.86540900e+00,\n", - " 1.86724000e+00, 1.88155800e+00, 1.88156000e+00,\n", - " 1.88180000e+00, 1.89447000e+00, 1.86957000e+00,\n", - " 1.82120000e+00, 1.71600000e+00, 1.60054000e+00,\n", - " 1.43162000e+00, 1.28346000e+00, 1.10166000e+00,\n", - " 1.06530000e+00, 9.30730000e-01, 8.02980000e-01,\n", - " 7.77740000e-01])" + "array([0.000000e+00, 3.026796e-13, 1.291101e-02, 6.511110e-02,\n", + " 3.926270e-01, 5.752268e-01, 6.969600e-01, 7.399378e-01,\n", + " 9.635450e-01, 1.142130e+00, 1.308020e+00, 1.463500e+00,\n", + " 1.557600e+00, 1.640550e+00, 1.688960e+00, 1.711400e+00,\n", + " 1.739450e+00, 1.782070e+00, 1.816650e+00, 1.845280e+00,\n", + " 1.865409e+00, 1.867240e+00, 1.881558e+00, 1.881560e+00,\n", + " 1.881800e+00, 1.894470e+00, 1.869570e+00, 1.821200e+00,\n", + " 1.716000e+00, 1.600540e+00, 1.431620e+00, 1.283460e+00,\n", + " 1.101660e+00, 1.065300e+00, 9.307300e-01, 8.029800e-01,\n", + " 7.777400e-01])" ] }, - "execution_count": 28, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -929,10 +828,8 @@ }, { "cell_type": "code", - "execution_count": 29, - "metadata": { - "collapsed": false - }, + "execution_count": 27, + "metadata": {}, "outputs": [ { "data": { @@ -940,7 +837,7 @@ "" ] }, - "execution_count": 29, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } @@ -964,10 +861,8 @@ }, { "cell_type": "code", - "execution_count": 30, - "metadata": { - "collapsed": true - }, + "execution_count": 28, + "metadata": {}, "outputs": [], "source": [ "elastic = gd157_endf[2]" @@ -982,18 +877,16 @@ }, { "cell_type": "code", - "execution_count": 31, - "metadata": { - "collapsed": false - }, + "execution_count": 29, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{'0K': }" + "{'0K': }" ] }, - "execution_count": 31, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } @@ -1011,18 +904,16 @@ }, { "cell_type": "code", - "execution_count": 32, - "metadata": { - "collapsed": false - }, + "execution_count": 30, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "998.78711745214866" + "998.7871174521487" ] }, - "execution_count": 32, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -1040,19 +931,17 @@ }, { "cell_type": "code", - "execution_count": 33, - "metadata": { - "collapsed": false - }, + "execution_count": 31, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[,\n", - " ]" + "[,\n", + " ]" ] }, - "execution_count": 33, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -1070,10 +959,8 @@ }, { "cell_type": "code", - "execution_count": 34, - "metadata": { - "collapsed": false - }, + "execution_count": 32, + "metadata": {}, "outputs": [ { "data": { @@ -1081,7 +968,7 @@ "[(1e-05, 306.6), (306.6, 54881.1)]" ] }, - "execution_count": 34, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -1099,29 +986,29 @@ }, { "cell_type": "code", - "execution_count": 35, - "metadata": { - "collapsed": false - }, + "execution_count": 33, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "" + "Text(0,0.5,'Cross section (b)')" ] }, - "execution_count": 35, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiYAAAGBCAYAAABSP3qNAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzt3WmYHGX19/HvyWQShiQkhEDYFQQhRogkhLAF5I+AoIwg\n6zzsixACAqOAyqqIqCxOAAmCLAGBgaCoQTYFEUQ2SVhkFQQkskSWZIAkkGXu58Xd5dT09D5VXdXd\nv8919dXd1dVVpzJJ6sy5N3POISIiIpIGA5IOQERERCSgxERERERSQ4mJiIiIpIYSExEREUkNJSYi\nIiKSGkpMREREJDWUmIiIiEhqKDERERGR1FBiIiIiIqmhxERERERSQ4mJiIiIpEbdJSZm1mJmr5nZ\neUnHIiIiIuWpu8QEOA14OOkgREREpHx1lZiY2QbARsCdScciIiIi5aurxAS4APgeYEkHIiIiIuVL\nRWJiZpPNbJaZvWFm3WbWmmOfY83sVTNbbGaPmNnErM9bgRedcy8Hm6oRu4iIiEQnFYkJMAR4EpgK\nuOwPzWw/4ELgLGAz4CngbjMbFdptS2B/M3sFXzk50sxOjztwERERiY451ycPSJSZdQN7OOdmhbY9\nAjzqnDsh896AucDFzrk+o2/M7BBgrHPulDznWAXYBXgN+DjyixAREalfKwCfBu52zr0X9cEHRn3A\nqJlZMzABODfY5pxzZnYPsFWFh90FuCGC8ERERBrVAcCNUR809YkJMApoAuZlbZ+HH4HTh3Pu2iLH\nfA3g+uuvZ8yYMf0Krr29nY6Ojqodo9C++T6rdoxRHEfXqevUdcYTYxTHKLZfrs91nfHEGNUxyvm7\n+/zzz3PggQdC5l4atVpITOLwMcCYMWMYP358vw40fPjwqh6j0L75Pqt2jFEcR9ep69R1xhNjFMco\ntl+uz3Wd8cQY1TEq+btLTF0haiExeRdYDozO2j4aeLs/B25vb2f48OG0tbXR1tZW0TEq/V6lxyi0\nbxSxxH3sUo+j69R1RqFRrjOq40dxnVHFEuexdZ3l7Rt81tnZSWdnJ11dXf2OrSDnXKoeQDfQmrXt\nEeCi0Pug8+vJFZ5jPOBmz57tGsHuu++edAhVoeusL7rO+qLrrB+zZ892+BG0410MeUAqKiZmNgTY\ngJ65R9Y3s3HA+865ucDPgBlmNht4DGgHVgRmJBCuiIiIxCQViQmwOXAfPgNz+DlLAK4FDnfOzczM\nWXI2vgnnSWAX59w7SQRba+IuIaeFrrO+6Drri65TSpW6eUyqwczGA7O32267fvcxERERaQThPiYP\nPPAAwATn3Jyoz9PQicns2bMj6T0tIiLSKObMmcOECRMgpsQkLVPSi4iIiCgxERERkfRQYiIiIiKp\nkZZROYmIYoI1ERGRRlCtCdbU+VWdX0VEREqmzq8iIiLSMJSYiIiISGooMREREZHUUOdXdX4VEREp\nSp1fY6TOryIiIpVR51cRERFpGEpMREREJDWUmIiIiEhqKDERERGR1NCoHI3KERERKUqjcmKkUTki\nIiKV0agcERERaRhKTERERCQ1lJiIiIhIaigxERERkdRQYiIiIiKpocREREREUkPzmGgeExERkaI0\nj0mMNI+JiIhIZTSPiYiIiDQMJSYiIiKSGkpMREREJDWUmIiIiEhqKDERERGR1FBiIiIiIqmhxERE\nRERSQxOsaYI1ERGRojTBWow0wZqIiEhlNMGaiIiINAwlJiIiIpIaSkxEREQkNZSYiIiISGooMRER\nEZHUUGIiIiIiqaHERERERFJDiYmIiIikhhITERERSQ0lJiIiIpIaSkxEREQkNZSYiIiISGpodWGt\nLiwiIlKUVheOkVYXFhERqYxWFxYREZGGocREREREUkOJiYiIiKSGEhMRERFJDSUmIiIikhpKTERE\nRGLy2GNw881JR1FbGnoeExERkThNmuSf99sv2ThqiSomIiIikhpKTERERCQ1lJiIiIhIaigxERER\nkdRQYiIiIiKpocREREREUkOJiYiISBW9+WbSEaRb3SQmZjbczP5uZnPM7GkzOzLpmERERML++EdY\nay14/PGkI0mvuklMgA+Ayc658cAk4FQzWznhmERERP7n2Wf986uvJhtHmtXNzK/OOQd8nHnbknm2\nhMIRERHJy7mkI0iveqqYBM05TwKvA+c7595POiYREREpXSoSEzObbGazzOwNM+s2s9Yc+xxrZq+a\n2WIze8TMJmbv45zrcs59AVgPOMDMVq1G/CIiIuUw1fPzSkViAgwBngSmAn0KXGa2H3AhcBawGfAU\ncLeZjcp1MOfcO5l9JscVsEijcA4WLYIPPvAPlaBFJE6p6GPinLsLuAvALGce2Q5c7py7LrPPFOAr\nwOHAeZltqwGLnHMfmdlwYDtgehXCF6kL8+fD7Nm+c96zz8Jzz8Ebb8Dbb8PHH/fs19wMo0fDmDEw\n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\nRU5ErkJggg==\n", + "image/png": "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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], @@ -1149,15 +1036,26 @@ }, { "cell_type": "code", - "execution_count": 36, - "metadata": { - "collapsed": false - }, + "execution_count": 34, + "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", + "\n", "\n", " \n", " \n", @@ -1290,7 +1188,7 @@ "9 44.2200 0 2.0 0.008960 0.0960 0.0 0.0" ] }, - "execution_count": 36, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" } @@ -1310,10 +1208,8 @@ }, { "cell_type": "code", - "execution_count": 37, - "metadata": { - "collapsed": true - }, + "execution_count": 35, + "metadata": {}, "outputs": [], "source": [ "gd157.add_elastic_0K_from_endf('gd157.endf')" @@ -1328,19 +1224,17 @@ }, { "cell_type": "code", - "execution_count": 38, - "metadata": { - "collapsed": false - }, + "execution_count": 36, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{'0K': ,\n", - " '294K': }" + "{'294K': ,\n", + " '0K': }" ] }, - "execution_count": 38, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } @@ -1362,41 +1256,39 @@ }, { "cell_type": "code", - "execution_count": 39, - "metadata": { - "collapsed": false - }, + "execution_count": 37, + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", - " njoy 2016.12 02Apr17 05/01/17 12:33:17\n", + " njoy 2016.44 11Oct18 11/09/18 20:25:51\n", " *****************************************************************************\n", "\n", " reconr... 0.0s\n", "\n", - " broadr... 0.0s\n", - " 300.0 deg 0.0s\n", + " broadr... 0.1s\n", + " 300.0 deg 0.1s\n", " 400.0 deg 0.2s\n", " 500.0 deg 0.3s\n", "\n", " heatr... 0.4s\n", "\n", - " purr... 0.6s\n", + " purr... 0.9s\n", "\n", - " mat = 128 0.6s\n", + " mat = 128 0.9s\n", "\n", " ---message from purr---mat 128 has no resonance parameters\n", " copy as is to nout\n", "\n", - " acer... 0.6s\n", + " acer... 0.9s\n", "\n", - " acer... 0.7s\n", + " acer... 1.1s\n", "\n", - " acer... 0.8s\n", - " 0.8s\n", + " acer... 1.3s\n", + " 1.4s\n", " *****************************************************************************\n" ] } @@ -1419,21 +1311,19 @@ }, { "cell_type": "code", - "execution_count": 40, - "metadata": { - "collapsed": false - }, + "execution_count": 38, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{'0K': ,\n", - " '300K': ,\n", - " '400K': ,\n", - " '500K': }" + "{'300K': ,\n", + " '400K': ,\n", + " '500K': ,\n", + " '0K': }" ] }, - "execution_count": 40, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" } @@ -1460,10 +1350,8 @@ }, { "cell_type": "code", - "execution_count": 41, - "metadata": { - "collapsed": true - }, + "execution_count": 39, + "metadata": {}, "outputs": [], "source": [ "url = 'https://github.com/mit-crpg/WMP_Library/releases/download/v1.1/092238.h5'\n", @@ -1472,10 +1360,8 @@ }, { "cell_type": "code", - "execution_count": 42, - "metadata": { - "collapsed": true - }, + "execution_count": 40, + "metadata": {}, "outputs": [], "source": [ "u238_multipole = openmc.data.WindowedMultipole.from_hdf5('092238.h5')" @@ -1490,10 +1376,8 @@ }, { "cell_type": "code", - "execution_count": 43, - "metadata": { - "collapsed": false - }, + "execution_count": 41, + "metadata": {}, "outputs": [ { "data": { @@ -1501,7 +1385,7 @@ "(array(9.13284265), array(0.50530278), array(2.9316765e-06))" ] }, - "execution_count": 43, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } @@ -1519,29 +1403,29 @@ }, { "cell_type": "code", - "execution_count": 44, - "metadata": { - "collapsed": false - }, + "execution_count": 42, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[]" + "[]" ] }, - "execution_count": 44, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAD8CAYAAAB5Pm/hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzt3Xl8XHW9+P/Xe/bse7okTfeFrrQNZfeiIBQVUBalghsKihe338/rxav3qle/bvdevcLVCyiIC18QFZAqiKCsUqCllC6UtmnpktA2SdPss8/n+8fMpNOQmUwyZzLJ5P18PPpI5uTMzJvJyZv3eX8+53PEGINSSqn8Zct1AEoppbJLE71SSuU5TfRKKZXnNNErpVSe00SvlFJ5ThO9UkrlOU30SimV5zTRK6VUnstKoheRIhHZJCLvycbrK6WUSp8jnZ1E5C7gPUCrMWZpwva1wI8AO/AzY8x3Yz/6Z+D+dIOorq42s2bNSnd3pZRSwMsvv9xujKkZbr+0Ej1wN/A/wC/jG0TEDvwYeCfQDGwUkYeBOuA1wJNusLNmzWLTpk3p7q6UUgoQkQPp7JdWojfGPCMiswZtXgM0GWP2xd7wPuAyoBgoAhYDXhF5xBgTSTNupZRSFku3oh9KHXAo4XEzcLox5iYAEfko0J4syYvIDcANAA0NDRmEoZRSKpWszboxxtxtjPljip/fYYxpNMY01tQM22JSSik1Spkk+hZgRsLj+ti2tInIJSJyR1dXVwZhKKWUSiWTRL8RmC8is0XEBVwNPDySFzDGrDfG3FBWVpZBGEoppVJJK9GLyL3ABmChiDSLyMeNMSHgJuAxYCdwvzFmR/ZCVUopNRrpzrpZl2T7I8Ajo31zEbkEuGTevHmjfQmllFLDyOkSCBOldfPn7Ydpau3JdRhK5SVvIEw4orc0zaacJvqJMBi7t62XT/16M199aHuuQ1Eq73T7gqz65uP8+3rt+maTVvTDeLPTC8C25vH7PyOlJqqXDxzHGwzziw1pXeCpRklXrxxGlzcIgJ5ZKmW9pqO9A9/7guEcRpLftHUzjHiiDxvN9EpZ7c0u78D3LZ3eFHuqTGjrZhid/dFELzmOQ6l81NrjH/j+aLcvh5HkN23dDKPPH8p1CErlrbYePyXu6Czv7tjZs7KeJvph+ILRNdn8oQgRbdQrZanjfQFmVRcBJ9qkynraox+GN2GAyBfSwSKlrNTjCzGjsgA40SZV1tMe/TD8CYneG9BEr5SVenxBppYWYLeJVvRZpK2bYSRW8V6d/qWUZcIRQ18gTInHQXmBUxN9FmmiH0ZiFa/zfJWyTq8vOtGhxOOgrMBJpyb6rNEe/TDig7EA/dq6Ucoy3b5oYi/1OCkrdOqsmyzSHv0wEls3gZDe+lYpq/QMqui1dZM92roZhi8YocQTnecbCGuiV8oqPbGKvsTjpMTjHEj8ynqa6IcRDEcojl3QoRW9UtaJJ/bSAgdFLjv9AU302aKJfhjBcISiWKIPhvWCKaWs0uM/UdEXuOz0+3UMLFs00Q8jGIpQ5LIDWtErZaX4rJtit4Mil4P+YBijiwdmhc66GUYgHKHQFa/oNdErZZX4dSmFLjsFLjvhiMGvxVRW6KybYQRCJ1o3WtErZR1vIPr35HHaB86a9erz7NDWzTCCYUOxO9a60YpeKct4g2FcDht2mwycNffrRYlZoYl+GImDsVrRK2UdXzBMgTNaRBXGiql+XRY8KzTRpxCJGEIRkzDrRhO9UlbxBsIUxlo28a969Xl2aKJPIRiJJvYiHYxVynL9CRV9gTP6N9anc+mzQhN9CvF58wWu6MekrRulrOMNhPHEEn2RWwdjs0kTfQrxxO6y23A5bAT0gimlLOMLhikY1Lrp00SfFTqPPoV4q8bpsOGy27SiV8pC3sTB2Fh71Kutm6zQefQpDK7otUevlHUSWzcDFb0ug5AV2rpJIZ7YXQ4bTrtoRa+UhRJbN/Gvel/m7NBEn0J8MNZpt+G0a0WvlJW8wTCFsYreZbdhE/Bpjz4rNNGnMNCjj7Vu/JrolbJMf+BERS8iFDjtel/mLNFEn0J8gSWnXXDZbQS1daOUZbzBEz16iK55o4k+OzTRpzDQox+YXqmJXikrhCOGQCgyMOsGYok+oH9j2aCJPoXE6ZXao1fKOr5Y5R6/GDH6vX1gu7KWJvoUTqro7TaCIb1gSikrxFs0iRW99uizx/JELyKniMhtIvI7EbnR6tcfS4FQwqwbHYxVyjLxpQ48gxO9zrrJirQSvYjcJSKtIrJ90Pa1IrJLRJpE5GYAY8xOY8yngPcDZ1sf8tg5MY9eB2OVspJv4O5SjoFtHpdW9NmSbkV/N7A2cYOI2IEfAxcDi4F1IrI49rNLgT8Bj1gWaQ6cPL1SdDBWKYvElyM+qUfvtGmPPkvSSvTGmGeAjkGb1wBNxph9xpgAcB9wWWz/h40xFwPXWBnsWAuETiR6HYxVyjrxyn1w60YTfXY4ht8lqTrgUMLjZuB0ETkPuBxwk6KiF5EbgBsAGhoaMggje06q6LV1o5RlhhyM1dZN1mSS6IdkjHkKeCqN/e4A7gBobGwcl9NZ4ssSuxzRwVht3ShlDd8Qg7EeHYzNmkxm3bQAMxIe18e2pW2iLFMcn16pi5opZQ3vwGDsyYneF9S/sWzIJNFvBOaLyGwRcQFXAw+P5AXG+zLFwcQlEBy2gUXOlFKZSTaPPhCOENIzZ8ulO73yXmADsFBEmkXk48aYEHAT8BiwE7jfGLNjJG8+ESp6EbDbJLpMsR6ASlkiXrl7XCcnegCfnjlbLq0evTFmXZLtj5DBFEpjzHpgfWNj4/WjfY1s8ocjOO02RASn3UY4YghHDHab5Do0pSY03xAVfTzpewNhit2WDx9OaroEQgrBkMFlj35ELkf0q06xVCpz3kA4dqacOI8+VtHrzBvL6T1jUwiGIzjt0eo9nvC1faNU5hLvFxsXf6xTLK2n94xNIRiODFTy8cpD59IrlbnBa9HDiatkdYql9bR1k0Ig1qOHxNaNzrxRKlO+QPik5Q/gxJx6bd1YT1s3KQTDJ3r08YSvc+mVypy2bsaWtm5SCITCAwk+3qvXHr1SmfMNkei1os8ebd2kEAwbnI5ognfrrBulLOMNhnFrRT9mtHWTQjChR6+tG6Ws4w1G3tq6GZhHr39jVtPWTQr+YASPI3rwDcy60YpeqYz5AslbN1rRW09bNyn4Q2HczpNn3WiPXqnMeYPhgQo+Ti+Yyh5N9Cn4gpGB3ry2bpSyzlDz6J12wW4TnUefBZroU/CHwrhjrRuXXefRK2WVoWbdiEj0BuFa0VtOB2NT8IdOVPS61o1S1vEFw3icb00/Hk30WaGDsSn4Q5GB08uBefTaulEqI8FwhGDYvKWih+gyCNqjt562blLwB8Nv7dFrRa9URgaWKHYNkej1BuFZoYk+BV8oMjDrRi+YUsoa8dbM4MHY+DYdjLWeJvokQuEI4YgZGIzVWTdKWcMXuyBqqNaN9uizQwdjk/DHEnq8kj+xDocmeqUy4Qulbt149W/McjoYm0Q80ccTfHyGgFYbSmUm3poZcjDWacenrRvLaesmCX+s6ohX9PE5vjpQpFRm+gPJe/QFLm3dZIMm+iTiLRp3wlzfAped/kAoVyEplRd6/dG/oRLPW28Arj367NBEn8SJiv5E1VHgtOvKekplqNcfBKDY/dZEr62b7NBEn4Q/ePJgLET79Nq6USozvb5oRV80RKIvdNnpC4QwRpcasZIm+iQGD8aC9g+VskKvP/o3NFTrpsTjIGJO9PGVNTTRJzF4MBbirRs9AJXKRK8/iMMmJ/1txZV4nAD0+HQszEo6jz6JgcHYhB69DhQplbleX4hijwMRecvPimNVfo8vONZh5TWdR59EvBefOOum0KXTK5XKVI8/NORALJxo5/T4taK3krZukuiLHWiJB2SB0669Q6Uy1OtLnuhLByp6TfRW0kSfRHyub+LMAB2MVSpzvSkr+niPXls3VtJEn0TvEBW9R+f4KpWxPn9ooBc/WIlW9FmhiT6JXl+IQpcdu+3EgJHe5kypzPWkaN3Et2tFby1N9EkMdXpZ4LQTihhdk16pDBzvD1BR6BryZ0UuByJa0VtNE30SQ80MKIw97tWDUKlRCUcMnd4gFYXOIX9uswklbocmeotpok9iqD6izghQKjNd3iDGQEXR0BU9RH/W0RcYw6jynyb6JIaaAlZaEK1CurV/qNSoHO+PJvDKFIm+UhO95bKS6EXkvSLyUxH5jYhcmI33yLahevSlHk30SmXieCyBJ+vRA1QWujimid5SaSd6EblLRFpFZPug7WtFZJeINInIzQDGmIeMMdcDnwI+YG3IY2OomQHxqV/dXm3dKDUaHekk+iIXHX3+sQppUhhJRX83sDZxg4jYgR8DFwOLgXUisjhhl6/Gfj7h9PpDb1lGtaxAL+ZQKhPx1k1F0dCDsQCVxdHWjS5VbJ20E70x5hmgY9DmNUCTMWafMSYA3AdcJlHfAx41xmy2LtyxEYkYenxBygfNDDjRutGKXqnRiLdkUvXoq4pcBMNG17uxUKY9+jrgUMLj5ti2zwAXAFeKyKeGeqKI3CAim0RkU1tbW4ZhWKvbFyRioHzQ6WXxQOtGK3qlRuNol48St4NC19AXTAFUFrkB6OjVPr1Vkn/aGTDG3ALcMsw+dwB3ADQ2No6rc7Tj/dFEPniur90mFOscX6VG7Ui3j6llnpT71JREE31rj59Z1UVjEVbey7SibwFmJDyuj21Ly3hdj36gjzjEgFGpx0GXVvRKjcqRbv+wiX5a7OdHun1jEdKkkGmi3wjMF5HZIuICrgYeTvfJ43U9+s5Yoh/cowcoK3TR5dVTSqVG42iXjymlqRN9/H8ER7q8YxHSpDCS6ZX3AhuAhSLSLCIfN8aEgJuAx4CdwP3GmB0jeM3xWdH3xVs3b63oq4tdtGvvUKkRC0cMbb1+pg6T6EvcDopcdg53aUVvlbR79MaYdUm2PwI8Mpo3N8asB9Y3NjZeP5rnZ0uq1k1VkYsDx/rHOiSlJrz2Xj/hiGHKMK0bEWFqmYcjmugto0sgDKGzP4hNhr5LfWWRm2O9ejGHUiMVT9zThqnoAaaVFWhFbyG9OfgQjvX5qSxyYbO99ebFVcUu+gJhvXesUiMUT9zDDcbG99GK3jp6c/AhtPX4qSkZ+mCsLo62c3QtDqVGpqUzOrg6LY1EP63MQ2uPj5De+8ES2roZQmuPn9rYXN7B4hdzaPtGqZE51NFPsduR8qrYuOnlBUQMHO3RvzMraOtmCK3dyRN9lVb0So3KgWN9NFQWIvLWluhgMysLo89p78t2WJOCtm4GiUQM7b3+gavzBqseqOg10Ss1Egc6+plZVZjWvjNjV8Tu1xlultDWzSDH+wOEIiZ56yZe0WvrRqm0RSKG5g4vDZXpJfpppR5cDhv7j2lFbwVt3QzSGusJJhuMLXLZcTts2rpRagSOdPsIhCM0pFnR22zCzMpC9mvrxhLauhkknuhrS4eu6EWE2lI3R3UdDqXSFr/IMN2KHmBWdZFW9BbR1s0gbfFEn6R1AzCtVC/mUGokmtp6AZhbU5z2c2ZVFXLgWD+RyLha3HZC0kQ/SLxSTzYYC3oxh1IjtedoD8VuR1pz6ONmVRfhD0V0FUsLaKIfpKXTS0WhM+WNEabFEr3e6kyp9Ow52su82uK0plbGzaqKzbzRPn3GdDB2kJbjXuoqClLuM7XMQyAcGbjRsVIqtT2tPSyYkn7bBk60efa09mYjpElFB2MHaen0Ul+eesAofvqpfXqlhtfRF6C9N8CCKSUjet6UUjdlBU5eP9KTpcgmD23dJDDGpFnRR3+ufXqlhrf7aDRRz6sdWUUvIiyaWsKuI93ZCGtS0USfoKMvgDcYpq48daI/UdHrHXCUGk689TLSih6IJfoenXmTIU30CeKr69UPU9FXF7tx2W00d2qiV2o4r73ZTYlnZDNu4hZOLaUvEB7421Sjo4OxCVqORw+m4Vo3dptQX1HAQV2HQ6lhbW/pYnl92Yhm3MQtmhY9C9A+fWZ0MDZBfAGlGWlcvTezqlAXXFJqGP5QmNePdLO0bnR/4/F2z87D2qfPhLZuEuxr66WmxE2pxznsvjOrijh4rE/n0iuVwu4jvQTDhuV15aN6frHbwZzqIrY2j4+z/olKE32Cfe19zIktjzqchspC+gJhXdxMqRS2tnQCsLx+9Gftp84oZ8uhTi2qMqCJPsEb7X3MSXMtjlnVsRsj6KJLSiW1vaWLsgLnsBMcUlkxo5z2Xj9v6nTmUdNEH9PZH6CjL8DcmnQr+uh+B7RPr1RSmw90jnogNu7UGdG2z5aDnVaFNelooo/Z2xatzGen2bqZUVmAiCZ6pZLp7A+w62gPa2ZVZvQ6p0wrxeWwseXQcYsim3w00cfsiy2jmm7rxu2wM72sQFs3SiWxaX80MZ82O7NE73LYWDK9lC2HtKIfLZ1HH7OvvQ+nXZgxgl7i7OqigTMBpdTJNu7vwGmXgdZLJk6dUc62li6C4YgFkU0+Oo8+ZveRHmZXF+Gwp/+RLJhSwp5WvTxbqaG8tL+D5fXleJz2jF9r9cwKfMEI21pyXxRORNq6idl5uJvF00pH9JwFU4rxBSMcOq59eqUSeQNhtjV3cVqG/fm4M+ZUAbBh7zFLXm+y0URPdNDozS4fp4w00U+NXrW3+6iul61Uos0HjxOKGNbMrrDk9aqL3SycUsIL+zTRj4YmeuC12OXVi6ePLNHPjy27Gl+GVSkV9czuNpx24fTZVZa95plzq9i4vwN/KGzZa04WmuiJrq4HjLiiL/E4qSsv0ESv1CBP727jtFmVFLmT35JzpM6cW4UvGOHVQ9qnHylN9EQr+toSN9XFyW8InsyCKcXs0pX1lBpwpMvH60d6+IcFNZa+7hmzqxCB5/e2W/q6k4EmeqIV/Uir+biFU0vZ29arp5NKxTyzuw2Af1hobaIvK3SyvL6cp2Ovr9I36RN9rz/E7qM9o57ru6yujGDYaFWvVMxTu1uZUhodPLXa+Ytq2XKok/Zev+Wvnc8mfaLf2txJxMDKhtEl+viqfDq/VynwBcM8vauNty+szWh9m2TesagWY+CpXVrVj4TliV5E5ojInSLyO6tfOxteiS2UtHLG6KaB1VcUUF7oZJuul60Uz+1ppy8QZu3SqVl5/SXTS5lS6uZvrx/Nyuvnq7QSvYjcJSKtIrJ90Pa1IrJLRJpE5GYAY8w+Y8zHsxFsNrxy8Dhza4ooKxz+ZiNDERGW1ZXpjRGUAh7dfoQSj4Oz5lZn5fVFhHcsquWZ3e0EQrocQrrSrejvBtYmbhARO/Bj4GJgMbBORBZbGl2WGWN45WAnKxsyu6hjWV0Zu4/24AvqgKyavILhCE/sPMo7T5mCy5G9rvAFp0yh1x/i7006+yZdaf02jDHPAB2DNq8BmmIVfAC4D7jM4viyam9bH8f6AqyemVmiXzGjnFDEsONNrerV5PX83mN0eYNZa9vEnTO/mlKPg/Vb38zq++STTP63WwccSnjcDNSJSJWI3AasFJEvJ3uyiNwgIptEZFNbW24GVuLzcc+am9nVe42x/1G89Iaul60mrwc2N1PqcfA2i+fPD+Z22LloyVT+suOonkWnyfLzK2PMMWPMp4wxc40x30mx3x3GmEZjTGNNTXYPjGSebzpGXXkBDZWFGb1OVbGbuTVFbNw/+KRHqcmhxxfksR1HuGTFdEtWqxzOe1ZMp9cf0jn1acok0bcAMxIe18e2pS2X69FHIoYN+45x1twqS6aBrZldyab9HbpksZqUHt12BF8wwhWr68fk/c6aW0VFoZM/bj08Ju830WWS6DcC80Vktoi4gKuBh0fyArlcj/61w910eYOcNc+aRZcaZ1bS7QuxS9e9UZPQ7zY3M6e6iJUW3GQkHU67jYuXTeOJ147S4wuOyXtOZOlOr7wX2AAsFJFmEfm4MSYE3AQ8BuwE7jfG7BjJm+eyoj/Rn7dmGtia2O3StH2jJpv97X289EYHl6+qy8pFUslctboebzDM+le1qh9OurNu1hljphljnMaYemPMnbHtjxhjFsT68f9npG+ey4r+ydfbWDClmCmlHkter76igGllHl7cp4leTS6/fuEADptwVeOM4Xe20Kkzylk4pYTfbDo0/M6T3KS8Z2xXf5CX9ndwwSlTLHtNEeGsudU819ROWPv0apLwBsLcv+kQFy2dalnRlC4R4f2nzeDVQ53sjN1TQg1tUt4z9qndrYQjhvMtTPQQXa2vyxtka7PerV5NDn/Y0kK3L8RHzpyVk/d/38o6XHYbv9moVX0qk3JRs7/ubKW62GXJ3ekTnTuvGhF4Zrdesafyky8Y5g9bWujsDxCOGO54dh+nTCvltFnW3DJwpCqLXKxdOpXfv9xMrz+UkxgmgknXugmGIzy5q5W3L6zFbrN24KiiyMXyujKe2aNze1V++v6fd/G5+7Zw/S838dArLexr6+Mz75g3poOwg113zmx6/CF+q736pCZd6+a5Pe30+EJcuCQ7l2m/bUENrxw8Tle/TvlS+cUYwx+2RC+V2bj/OP//b19laV0pa7P0t5SuU2eUs3pmBXf9/Q0dH0ti0rVuHn71zdhl2tlZXe+8hbVETHQcYLzbc7SHlw/oLCGVnv3H+jnWF+A7ly/js+fPZ83sSm5dtwqbxWfGo/Hxc2ZzqMPL46/p8sVDse7OvROANxDmL7HLtN2O7FymvXJGObUlbh7bcYTLTq3LyntY5Z0/fAaA/d99d44jURPB5gPRtZxWNpSzburobr2ZLRcunkJ9RQF3Prcv64uqTUSTqkf/19eP0hcIc+mK6Vl7D5tNuHDJFJ58vW1cL7jUHzgxcKXreqt0vNrcSZHLzvxa628RmCmH3cYnzpnNxv3H2bD3WK7DGXcmVY/+wc0t1Ja4OX2ONcseJHPRkql4g+GBmySPR+09gYHv3+z05jASNVFsbe5iSV2Z5ZMYrHL1mgZqS9z89xO7cx3KuDNpevRvdnp5clcrVzXWZ/1APWNOFaUeB3/efiSr75OJ1h7fwPddXh04VqkFwxF2Hu5med3YX8WeLo/TzqfPm8uLb3RoVT/IpEn09286hAGuPq0h6+/ltNu4eOk0/rzjCH3jdG5vZ8KsIE30ajh7jvbiD0VYVj9+Ez2cqOp/+MRujNEZOHGTokcfjhh+s/EQ586vYUaGa8+n66rGevoDYf60bXwuuJR4cUm3rv6nhhG/2nvpOK7oIVrV/+Pb5/HSGx08tWv8tk7H2qTo0T+1q5XDXT4+uGbsFl1aPbOCOdVF/G5T85i950j0JCR6rejVcJ7Z00ZtiZvZVUW5DmVY69Y0MLu6iG/96TWCYZ1oAJOkdfOzZ99gaqnH8rVtUhGJrub30v4OmlrH3xr1vb4Tib7HNz7bS2p88AXDPLO7nfNPqR0Xc+aH43LY+PLFi9jb1sd9Lx3MdTjjQt4n+m3NXWzYd4zrzpmF0z62/7nvb6zHZbfxqw0HxvR909HrDxK/an08TwNVufeHLS30+kNcsjx705Kt9s7FUzhjTiU/fGKPnrEyCRL9Hc/uo8TtYN2a7A/CDlZV7Obdy6fx+80t425QttcXosTtwO2w4Q1ooldD8wXD3PLXJpZML+XMudmdlmwlEeGr717M8f4AP3xcp1vmdaI/1NHPI9sO88HTGyjxOHMSwzWnN9DrD427QVlvMEyhy0GBy45XK3qVxE+ebKKl08tX3704pwuXjcbSujKuPX0mv9iwny2HJvfS4Xk96+aWv+7BbhM+dvbsrLx+OlbPrGBOTRH3j7P1sr3BCAUuOwVOu1b0akjbW7r4yVN7ee+p0ydUNZ/on9YupLbEzZcf2DapB2bzdtbNvrZefr+5mQ+dMZOpZWN755tEIsL7G2ew6cBxmlp7cxbHYN5AGI/TToHLTr9W9GoQfyjM/3f/FiqLXHzj0qW5DmfUSj1OvnHpUnYe7ubO597IdTg5k7etmx8+sQe3w86N583NdShcvqoOu024fxytl+0Lhilw2ihw2vFpRa8G+cHju9l9tJfvXbGcssLctD2tsnbpVC5cPIUfPr6bPUfH3wy4sZCXiX5bcxd/3PomHzt7FtXF7lyHQ22Jh7VLpnLvSwfpGScXJ/mCsYreqT16dbInX2/l9qf3sW5NA29fVJvrcCzxf963jGK3g8/dt2VSLuKXd4neGMPXHt5OVZGLT42Daj7uU/8wlx5fiF+/MD7m9XqDYQpirRtN9CqupdPLF+7fwinTSvnaJYtzHY5lakrcfPeK5bx2uJsfTMJZOHmX6B/a0sLmg518ae0iSnM002Yoy+rLOHd+NXc+98a4mLfuDYbx6GCsShAIRfjM/91MKGz4yTWr8Dizc8+GXHnn4imsW9PA7c/s5fmmyXVf57xK9L3+EN955HVW1Jdx5ar6XIfzFjeeN5f2Xv+4uLelL6AVvTrBGMNXHtzG5oOdfO+K5cyuHv9LHYzGv77nFObWFPOZe1/hcNfkWZ47rxL9dx/dSVuvn69fumRcXqp95pwqTptVwS1/a8p5Fe0LRfDEBmNzHYvKvZ8+u4/fvtzMZ8+fz7uXT8t1OFlT6HJw27Wr8QXDfPqezZOmX5838+if39vOr184yHVnz2ZlQ4UF0VlPRPjS2kW09fj5+fO5nerljVX0Hh2MnfQef+0o33n0dd69bBqfP39+rsPJunm1xfzHVSt45WAn3/zja7kOZ0zkxTz6/kCIm3+/jVlVhXzxwoUWRZcdp82q5PxFtdz21F66+nMzA8cYMzAYW+jSin4ye/lAB5+99xWW1ZXxn1etGJdnwtnwrmXTuP7c2fzqhQP8+oXxtxaV1fKidfONh1/j0PF+vnfFcgpc438A6YsXLaTHH+LHTzXl5P39sdPV+GBsKGIm9VWDk9XOw9187OcbmVLq5s6PnDYh/nas9M9rF/GORbX82x+28+Su1lyHk1UTPtE/9EoLv9l0iE+fNzfr94K1yinTSrlyVT13PfdGTpYwjs/68TjsA3/c/VrVTyr72/v40J0vUehy8OtPnE5NSe6vNxlrDruNW9et5JRppdx0z2Zee7M71yFlzYRO9G+2ERL3AAAUnUlEQVS09/GVB7fROLOCL1ywINfhjMg/X7yIApedrz28Y8xveRbvyRe47ANT6Pzap580DnX0c83PXiQcifDrT6yhvmJs7ro2HhW5Hdz10dMoLXDy0Z+/xP72vlyHlBUTOtE/+EoLToeNW9atxDHGa81nqrrYzRcvXMjfm47xyLaxvYl4vCdfELsyFtAB2UnijfY+3n/7Bnr9IX553enMqy3JdUg5N6XUwy+vW0MwHOGan71I8/H+XIdkuYmVHQf5wgXz+dNnz2V6eUGuQxmVa05vYPG0Ur6xfseYDszGk7rHaRto3Wiiz39NrT28//YN+EMR7r3+jHF/o++xNH9KCb/6+Ol0+4Jc+7MXae325TokS03oRC8i1E3QJA/RHuH3r1zOsb4A31i/Y8zed6CidzlOVPSj6NF39AV4cd8xS2NT2bHlUCcfuP0FAH5zwxksnl6a44jGn6V1ZfziujW09fhZ99MXONKVP8l+Qif6fLC0rox/fPs8Hnilhb/sGJsWTnzgtTChRz+aiv6//rKLD9zxAq8cPG5pfMpaj792lKvv2ECR28H9nzyT+VO0XZPMqoYKfv6xNRzt9nPV7c9z8Fh+tHE00Y8DN719HqdMK+VfHtzOsV5/1t+vP7FHH2vdjGb9nQ17o9X8a4fzd7bCRPerDfv55K82sXBKCQ98+qy8XdrASmtmV/J/rz+dHl+IK297nt15sLSx5YleRIpE5Bci8lMRucbq189HLoeNH7x/Bd2+IF+4/1UikezOwvEGo/evLXSdGIz1BUc+jz4cmy2UL1VPPgmGI3z94R386x928I5Ftdx7wxnjYsnuiWJ5fTn3f/JMAK66bcNAUTNRpZXoReQuEWkVke2Dtq8VkV0i0iQiN8c2Xw78zhhzPXCpxfHmrfiysM/sbuMnWb6QKl7RF7kz69F3e6MDyG1jcBai0tfa4+Oan77I3c/v5+PnzOa2a1dT6HLkOqwJZ8GUEn5/41nUlLj58F0vjqsbB41UuhX93cDaxA0iYgd+DFwMLAbWichioB6IfyI6lWMEPrimgctOnc4PHt/N83uzt4zqicFYOx5n9BAYaY/eGEO3L3pmEE/4Kvc2HzzOJbc+x9aWTn509an863sWT7ipx+PJjMpCfn/jWZwxp4ov/W4r33309ayfcWdDWkeAMeYZoGPQ5jVAkzFmnzEmANwHXAY0E032KV9fRG4QkU0isqmtrW3kkechEeHb71vG7Ooi/vGezRw4lp2LNwYGY512PKPs0ff6Q4RjB3yXJvqci0QMtz+9lw/cvgGXw8YDN57NZafW5TqsvFBW4OSuj57GNac3cNvTe/no3RvHZCzNSpn8r76OE5U7RBN8HfAAcIWI/C+wPtmTjTF3GGMajTGNNTU1GYSRX4rcDu78yGkY4Lq7N2YlifYHwrjsNhx226hbN4lxdeZocTYV1drt48N3vcR3Hn2d8xdNYf1N5+j0SYs57Ta+9d6lfPt9y3hh3zHefctzbNo/uPYdvyw/pzPG9BljPmaMudEYc0+qfa1cpjifzKou4rZrV3Owo59P3/Oy5WtmewOhgdk2TrsNh01G3LqJJ/qyAqdW9Dn02I4jrP3Rs2w60MF3Ll/G/167ivJCV67DyksiwgdPb+DBT5+F22njA3e8wC1/3UMgFMEYw2M7jvCzZ/fRHwjlOtS3yGSEpgWYkfC4PrYtbcaY9cD6xsbG6zOIIy+dMaeKb79vGf/0u618/jevcMvV1i3z0B8IU5iwUuFobhAeT+4NlYV5Mf1somnr8fP19Tv409bDLJ5Wyi3rVjKvtjjXYU0KS6aXsf4z5/CVB7fzg8d38/CrbzK11MNzsdsTbm3u4pZ1K3Mc5ckySfQbgfkiMptogr8a+KAlUSkArmqcQZc3yLf+tJMC5zb+48rllqwX3h8Mn7QkrcdlH3GPvjsh0W9r6cIXDOfdPUbHI2MMD21p4RvrX6PfH+aLFy7gk/8wF6cOuI6pUo+TW9et5LIV0/nhE7vZ19bLzRcvot8f4pa/NbFuTQNnzh0/q+mmlehF5F7gPKBaRJqBrxlj7hSRm4DHADtwlzFmRNfxi8glwCXz5s0bWdSTyCfOnUOvP8R/P7EHj9PGNy9bmnGy9w5V0Y+yRz+jMrryYbc3qIk+y5pae/jG+td4dk87KxvK+f4Vy/Uq1xy7YPEULlg8ZeCxLxjm/k3NfP+x13ngxrMQGR83ckkr0Rtj1iXZ/gjwyGjfXFs36fnc+fPxBsPc/vQ+vIEw379yeUZtnP5AiELniV99octOr3/0rZv449pSz6hjUsn1+IL86Ik93P38fgpcdr5+yWI+dOYs7JPkblATicdp5/MXzOfmB7bx25ebeX/jjOGfNAZyehWFVvTpERFuXruIYpeD/3p8Nz3+ELeuWznqCtobCJ80YFfqcdLjG9mAapc3iN0mTC/3DDxW1gqFIzywuYXvP7aLY31+PtA4gy9etFCvcB3nrlxdz0NbWvjyA9vo7A9w3dmzc34tQ17cM3YyEBE+c/58vnHpEh5/7SjX/uxF2kc5l/d4f5CKQufA4xKPgx7fyGYKdHmDlHoclBVEX2ekz1fJRSKGR7Yd5qL/foYv/X4rMyoLeOjTZ/PdK5Zrkp8AHHYbP/1wI+9YVMu3H3mdd93yLE/tah3zGwwl0hGcCeYjZ83i1nUr2dbSxWX/83d2jmJBseN9ASqKEir6Aic9/pFW9CHKCpyUxhJ99wjPCNRbGWN4alcrl/74OT59z2ZEhNuuXcUDN57FihnluQ5PjUCJx8kdH1rN7R9ajS8Y4aM/38gV//s8z+5py0nC19bNBHTJiunMrCrk+l9u4vKfPM8337uUK1fXD/9EwB8K0+MPUZnQuinxOOj2jryiLytwUuqJJXpt3YyaMYandrfxkyeb2Lj/OPUVBfzXVSt478o67cNPYCLCRUum8vaFtfz25UP8+G9NfOjOlzhtVgU3njeX8xbUWjKLLh05TfQ6GDt6y+vLWX/TOXz2vlf44m9f5fmmdr753qUUuVP/So/1BgCoLD6R6MsLnHT7goQjJu3E0uUNUlrgpMQTfb9ubd2MWCgc4Y9bD3Pb03t5/UgP08o8/PtlS7j6tAZcDj3Zzhcuh41rTp/JlavruX/jIX7y1F6uu3sTc2uK+MS5c3jfyrqsz1jTJe0msNpSD/d84gxu/dsefvTXPWw6cJxvv28Z58yvTvqcgx3RJYXjs2UAakrcGAPHev1pz5zp9gaZUVGAx2nH7bBpRT8Cvf4Qv3+5mZ8+u4/m417m1Rbzn1et4NIV0zXB5zG3w86HzpzF1Wsa+NPWw/z02X18+YFt+INhPnr27Ky+tyb6Cc5uEz5/wQLOnFPFzQ9s49o7X+TK1fX8y7tOobLorZfC723rBWBW1YkbUNSURJN7a0/6iT7euoFoj1979MPbdaSHX79wgAdfaaHXH2JVQzlfu2QJ5y8au1N4lXtOu433rqzjslOn88K+DpbWZX9dIu3R54nT51Tx6OfO5da/7eH2p/fx5+1HuOFtc7junNkUJ7Rznm86Rk2Jm/qKE/fanVYWTe4tnV6W1g0/A8oYc3KiH0WPf7IIhCL8eccRfv3CAV56owOXw8Z7lk3jmjNmsqqhfNxcUKPGnoiM2dWz2qPPIx6nnX+6aBHvW1nHfzy2ix88vpvbn97LpadO59z5NXR7gzy24wjXnjHzpAQzN7ZGSlNrLxctGf594ksUa0U/NGMMmw8e58FXWvjj1sN09gdpqCzkX961iCtXzxjyTEupbNLWTR6aV1vC7R9qZGtzJ7/cEG0V3PtSdEXpJdNL+fwF80/av9jtYHZ1ERvTXHY1PqAbn9Nd4nHS1R+w8L9gYtrb1ssfXmnhoS1vcrCjH4/TxoWLp3L5qjreNr9G2zMqZzTR57Hl9eX851XlfOu9S9lztBeDYen0siETzjsW1fKrDQfo8QUp8TiHeLUT4hdqVcVm7lQVudgX6/1PJsYYdh3t4S87jvLYjiPseLMbm8DZ86r53PnzuWjp1JPaZkrlivboJwGP086y+tS990tXTOfO597gZ8++wRfeuSDlvvFEH6/oa0vctPb4Mcbkfc85HIm2Zf6y4wh/ee0oB471IwKrGir46rtP4dIV03XNHzXuaI9eAbBiRjmXrJjO/zzZxCnTSlm7dGrSfeNTNGdURKdo1pS4CYQidHtDlBWmPhuYiA4c6+PZPe08t6ed5/e20+0L4bLbOGteFZ9821wuWFxLbYkmdzV+6XmlGvDdy5dxsKOfG+95mQ+fMZPPnj+fqiHWVtnb2kdlkWsgqdeVR2fwHDreT1nhxF+3qKXTy6b9Hbyw7xjPNbVzqMMLwPQyD2uXTuXc+TWct7Bm2BaXUuOFJno1oMjt4L7rz+A7j+7kVy8c4N6Nh1i7ZCqXrJjO6XMqKfU4CYUj/H1vOysT1l6J39lo99GetKZnjieBUITXj3Tz8oHjbDpwnM0HjnO4ywdAidvBGXOruP7cOZw9r5o51UV535pS+UkTvTpJgcvOv1+2lA+fOYtfbdjPg6+08PCrb2ITqK8oJBSO8GaXj6+865SB58yuLqLU4+DZPe1cviq9NXdyoas/SFNbDzsP97DjzS62t3Sz60gPgXD0nrzTyzw0zqpkdUM5jbMqWTS1JOfLyyplBcnl0plxjY2NZtOmTbkOQw3BHwqz+UAnG/Yd4432PgDOW1DDFYMWUfv6wzv4xYb9fCu2wJrbkZu7TQVCEQ53eTnU4eWN9l72tPbS1Br92tZzYlnn8kInS6eXsWR6KUvrylg9s4Lp5QUpXlmp8UdEXjbGNA67Xy4TfcKsm+v37NmTszhU5nr9Ia77+UZe2t9BocvOqoYK5k8pZlZVETMqC6gqclNZ5KKiyEWRy552C8QYgz8Uoc8fotcfotsbor3XT1uvP/q1x097b4AjXV6aj3s50u0j8ZAudjuYV1vMvNpi5se+LphSQn1FgbZh1IQ3IRJ9nFb0+SESMTzX1M4TO4/y8oHjvNHeR/8Q96J12AS3w4Y7tiCa22FDRAhHDOGIIWKiX+MJPhRJfowWuexUl7iZUuKhvrKAGRWF1FcUUF9RyKzqQqaWejShq7yVbqLXHr2yjM0mvG1BDW9bUANEq/G2Xj+HOrwc7wvQ0R/geF+ALm8QfyiCPxTGH4zgD0UwgF2ir2EXwW4TXA4bxW4HRW7HwNcSj4OaEjc1xW6qi90UuPSG5EoNRxO9yhoRobbEo3PMlcoxnVKglFJ5ThO9UkrlOU30SimV5zTRK6VUnstpoheRS0Tkjq6urlyGoZRSeS2nid4Ys94Yc0NZ2cRaH0UppSYSbd0opVSe00SvlFJ5blwsgSAibcCBUT69Gmi3MByraFwjo3GNzHiNC8ZvbPkY10xjTM1wO42LRJ8JEdmUzloPY03jGhmNa2TGa1wwfmObzHFp60YppfKcJnqllMpz+ZDo78h1AEloXCOjcY3MeI0Lxm9skzauCd+jV0oplVo+VPRKKaVSmDCJXkT2i8g2EdkiIm+5HZVE3SIiTSKyVURWjUFMC2PxxP91i8jnB+1znoh0Jezzb1mK5S4RaRWR7QnbKkXkcRHZE/takeS5H4nts0dEPjIGcf2HiLwe+z09KCLlSZ6b8neehbi+LiItCb+rdyV57loR2RU71m4eg7h+kxDTfhHZkuS52fy8ZojIkyLymojsEJHPxbbn9BhLEVdOj7EUceXmGDPGTIh/wH6gOsXP3wU8CghwBvDiGMdnB44QndeauP084I9j8P5vA1YB2xO2fR+4Ofb9zcD3hnheJbAv9rUi9n1FluO6EHDEvv/eUHGl8zvPQlxfB76Yxu95LzAHcAGvAouzGdegn/8X8G85+LymAati35cAu4HFuT7GUsSV02MsRVw5OcYmTEWfhsuAX5qoF4ByEZk2hu9/PrDXGDPaC78yYox5BugYtPky4Bex738BvHeIp14EPG6M6TDGHAceB9ZmMy5jzF+MMaHYwxeAeqveL5O40rQGaDLG7DPGBID7iH7OWY9LRAR4P3CvVe+XLmPMYWPM5tj3PcBOoI4cH2PJ4sr1MZbi80qH5cfYREr0BviLiLwsIjcM8fM64FDC42bS/2CtcDXJ/wDPFJFXReRREVkyhjFNMcYcjn1/BJgyxD65/tyuI3omNpThfufZcFPsdP+uJG2IXH5e5wJHjTF7kvx8TD4vEZkFrAReZBwdY4PiSpTTY2yIuMb8GJtIif4cY8wq4GLgH0XkbbkOKE5EXMClwG+H+PFmou2cFcCtwENjGVuciZ4TjqspViLyFSAE3JNkl7H+nf8vMBc4FThMtE0ynqwjdTWf9c9LRIqB3wOfN8Z0J/4sl8dYsrhyfYwNEVdOjrEJk+iNMS2xr63Ag0RPbxK1ADMSHtfHto2Fi4HNxpijg39gjOk2xvTGvn8EcIpI9RjFdTTevop9bR1in5x8biLyUeA9wDWxBPEWafzOLWWMOWqMCRtjIsBPk7xfrj4vB3A58Jtk+2T78xIRJ9GkdY8x5oHY5pwfY0niyvkxNlRcuTrGJkSiF5EiESmJf090oGX7oN0eBj4sUWcAXQmnlNmWtNISkamx3ioisoboZ35sjOJ6GIjPcPgI8Ich9nkMuFBEKmKnkRfGtmWNiKwFvgRcaozpT7JPOr9zq+NKHNN5X5L32wjMF5HZsTO5q4l+ztl2AfC6MaZ5qB9m+/OKHcN3AjuNMT9I+FFOj7FkceX6GEsRV26OMatHm7Pxj+jo86uxfzuAr8S2fwr4VOx7AX5MdLR6G9A4RrEVEU3cZQnbEuO6KRbzq0QHhc7KUhz3Ej0VDBLt6X0cqAL+CuwBngAqY/s2Aj9LeO51QFPs38fGIK4moj3ILbF/t8X2nQ48kup3nuW4fhU7drYS/cOaNjiu2ON3EZ1FsXcs4optvzt+TCXsO5af1zlE2zJbE35v78r1MZYirpweYyniyskxplfGKqVUnpsQrRullFKjp4leKaXynCZ6pZTKc5rolVIqz2miV0qpPKeJXiml8pwmeqWUynOa6JVSKs/9P5C1CbudEwAzAAAAAElFTkSuQmCC\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], @@ -1559,29 +1443,29 @@ }, { "cell_type": "code", - "execution_count": 45, - "metadata": { - "collapsed": false - }, + "execution_count": 43, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[]" + "[]" ] }, - "execution_count": 45, + "execution_count": 43, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\nAAAAAElFTkSuQmCC\n", + "image/png": "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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], @@ -1609,9 +1493,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.2" + "version": "3.7.0" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } From d1e427ed9aa3c256e57b635bf47160754bdf410a Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 12 Nov 2018 07:52:07 -0600 Subject: [PATCH 21/62] Use MT=101 for "absorption" in ESZ block for IncidentNeutron.from_ace --- openmc/data/neutron.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index f1a2acc53..589318aab 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -641,10 +641,10 @@ class IncidentNeutron(EqualityMixin): data.reactions[1] = total if np.count_nonzero(absorption_xs) > 0: - absorption = Reaction(27) + absorption = Reaction(101) absorption.xs[strT] = Tabulated1D(energy, absorption_xs) absorption.redundant = True - data.reactions[27] = absorption + data.reactions[101] = absorption # Read each reaction n_reaction = ace.nxs[4] + 1 From 98e7f31a06028441f542329a56d68d0f980361c2 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 12 Nov 2018 09:21:35 -0600 Subject: [PATCH 22/62] Make sure summed levels get marked as redundant --- openmc/data/neutron.py | 14 ++++++++++++-- src/nuclide_header.F90 | 14 ++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index 589318aab..7fc65c913 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -375,13 +375,15 @@ class IncidentNeutron(EqualityMixin): self.energy['0K'] = x self[2].xs['0K'] = Tabulated1D(x, y) - def get_reaction_components(self, mt): + def get_reaction_components(self, mt, exclude_self=False): """Determine what reactions make up redundant reaction. Parameters ---------- mt : int ENDF MT number of the reaction to find components of. + exclude_self : bool + Whether to exclude the original MT number when finding components Returns ------- @@ -390,7 +392,7 @@ class IncidentNeutron(EqualityMixin): have cross sections provided. """ - if mt in self.reactions: + if mt in self.reactions and not exclude_self: return [mt] elif mt in SUM_RULES: mts = SUM_RULES[mt] @@ -694,6 +696,14 @@ class IncidentNeutron(EqualityMixin): rx = data._get_redundant_reaction(mt, mts) data.reactions[mt] = rx + + # Make sure redundant cross sections that are present in an ACE file get + # marked as such + for rx in data: + mts = data.get_reaction_components(rx.mt, exclude_self=True) + if mts: + rx.redundant = True + # Read unresolved resonance probability tables urr = ProbabilityTables.from_ace(ace) if urr is not None: diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index db4b13be6..af66e4974 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -696,20 +696,10 @@ contains end if end do - ! Skip total inelastic level scattering, gas production cross sections - ! (MT=200+), etc. - if (rx % MT == N_LEVEL .or. rx % MT == N_NONELASTIC) cycle + ! Skip gas production cross sections (MT=200+), etc. if (rx % MT > N_5N2P .and. rx % MT < N_P0) cycle - ! Skip level cross sections if total is available - if (rx % MT >= N_P0 .and. rx % MT <= N_PC .and. find(MTs, N_P) /= -1) cycle - if (rx % MT >= N_D0 .and. rx % MT <= N_DC .and. find(MTs, N_D) /= -1) cycle - if (rx % MT >= N_T0 .and. rx % MT <= N_TC .and. find(MTs, N_T) /= -1) cycle - if (rx % MT >= N_3HE0 .and. rx % MT <= N_3HEC .and. find(MTs, N_3HE) /= -1) cycle - if (rx % MT >= N_A0 .and. rx % MT <= N_AC .and. find(MTs, N_A) /= -1) cycle - if (rx % MT >= N_2N0 .and. rx % MT <= N_2NC .and. find(MTs, N_2N) /= -1) cycle - - ! Skip redundant reactions, which are used for photon production + ! Skip any reaction that has been marked as redundant if (rx % redundant) cycle ! Add contribution to total cross section From fb8e10f50a4982c7746a3a5323da80286cd822b0 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 12 Nov 2018 11:13:16 -0600 Subject: [PATCH 23/62] Make sure Sum stores a list of functions --- openmc/data/function.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmc/data/function.py b/openmc/data/function.py index 3362040dc..36443e761 100644 --- a/openmc/data/function.py +++ b/openmc/data/function.py @@ -518,7 +518,7 @@ class Sum(EqualityMixin): """ def __init__(self, functions): - self.functions = functions + self.functions = list(functions) def __call__(self, x): return sum(f(x) for f in self.functions) From d6d77d2962cd66f2a9b74d81fc91c60845af9069 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 12 Nov 2018 14:00:53 -0600 Subject: [PATCH 24/62] Fix list of inelastic scattering reactions --- src/endf.F90 | 22 ++++++++++++---------- src/nuclide_header.F90 | 10 +++------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/endf.F90 b/src/endf.F90 index 66f2d53e1..0d458a0ab 100644 --- a/src/endf.F90 +++ b/src/endf.F90 @@ -229,7 +229,7 @@ contains integer, intent(in) :: MT logical :: dis - if (MT >= N_GAMMA .and. MT <= N_DA) then + if (MT >= N_DISAPPEAR .and. MT <= N_DA) then dis = .true. elseif (MT >= N_P0 .and. MT <= N_AC) then dis = .true. @@ -242,25 +242,27 @@ contains end function is_disappearance !=============================================================================== -! IS_SCATTER determines if a given MT number is that of a scattering event +! IS_INELASTIC_SCATTER determines if a given MT number is that of an inelastic +! scattering event !=============================================================================== - function is_scatter(MT) result(scatter_event) + function is_inelastic_scatter(MT) result(retval) integer, intent(in) :: MT - logical :: scatter_event + logical :: retval if (MT < 100) then - if (MT == N_FISSION .or. MT == N_F .or. MT == N_NF .or. MT == N_2NF & - .or. MT == N_3NF) then - scatter_event = .false. + if (is_fission(MT)) then + retval = .false. else - scatter_event = .true. + retval = (MT >= MISC .and. MT /= 27) end if + elseif (MT < 200) then + retval = (.not. is_disappearance(MT)) else - scatter_event = .false. + retval = .false. end if - end function is_scatter + end function end module endf diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index af66e4974..dcd01da17 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -6,7 +6,8 @@ module nuclide_header use algorithm, only: sort, find, binary_search use constants use dict_header, only: DictIntInt, DictCharInt - use endf, only: reaction_name, is_fission, is_disappearance + use endf, only: reaction_name, is_fission, is_disappearance, & + is_inelastic_scatter use endf_header, only: Function1D, Polynomial, Tabulated1D use error use hdf5_interface @@ -529,12 +530,7 @@ contains ! Add the reaction index to the scattering array if this is an inelastic ! scatter reaction - if (MTs % data(i) /= N_FISSION .and. MTs % data(i) /= N_F .and. & - MTs % data(i) /= N_NF .and. MTs % data(i) /= N_2NF .and. & - MTs % data(i) /= N_3NF .and. MTs % data(i) < 200 .and. & - MTs % data(i) /= N_LEVEL .and. MTs % data(i) /= ELASTIC .and. & - .not. this % reactions(i) % redundant) then - + if (is_inelastic_scatter(MTs % data(i))) then call index_inelastic_scatter % push_back(i) end if From 8280946b7cf8eea88bb4a9a686365d9659512b52 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 12 Nov 2018 14:01:19 -0600 Subject: [PATCH 25/62] Make sure MT=4 gets written to HDF5 file (needed for ptables) --- openmc/data/neutron.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index 7fc65c913..e91ba0a68 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -459,11 +459,12 @@ class IncidentNeutron(EqualityMixin): rxs_group = g.create_group('reactions') for rx in self.reactions.values(): # Skip writing redundant reaction if it doesn't have photon - # production or is a summed transmutation reaction + # production or is a summed transmutation reaction. MT=4 is also + # sometimes needed for probability tables. if rx.redundant: photon_rx = any(p.particle == 'photon' for p in rx.products) transmutation_rx = (rx.mt in (16, 103, 104, 105, 106, 107)) - if not (photon_rx or transmutation_rx): + if not (photon_rx or transmutation_rx or rx.mt == 4): continue rx_group = rxs_group.create_group('reaction_{:03}'.format(rx.mt)) From f4e4304b1309e120020c7cba9e3cca1058f6fa34 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 12 Nov 2018 14:06:25 -0600 Subject: [PATCH 26/62] Fix list --- src/endf.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/endf.F90 b/src/endf.F90 index 0d458a0ab..58b554997 100644 --- a/src/endf.F90 +++ b/src/endf.F90 @@ -257,7 +257,7 @@ contains else retval = (MT >= MISC .and. MT /= 27) end if - elseif (MT < 200) then + elseif (MT <= 200) then retval = (.not. is_disappearance(MT)) else retval = .false. From 15d2feb6fbdfde9a2f70ac1251c6b9c48c404eb8 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 12 Nov 2018 14:06:32 -0600 Subject: [PATCH 27/62] Omit gas production and damage xs from HDF5 files --- openmc/data/neutron.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index e91ba0a68..a161cc5af 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -653,6 +653,9 @@ class IncidentNeutron(EqualityMixin): n_reaction = ace.nxs[4] + 1 for i in range(n_reaction): rx = Reaction.from_ace(ace, i) + # Don't include gas production / damage cross sections + if 200 < rx.mt < 219 or rx.mt == 444: + continue data.reactions[rx.mt] = rx # Some photon production reactions may be assigned to MTs that don't From 12867987766b7a6c4f6447158dd47319c2e34c6b Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 12 Nov 2018 14:54:51 -0600 Subject: [PATCH 28/62] Increment HDF5 data version --- include/openmc/constants.h | 2 +- openmc/data/__init__.py | 2 +- src/constants.F90 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/openmc/constants.h b/include/openmc/constants.h index 75da02c0a..206425203 100644 --- a/include/openmc/constants.h +++ b/include/openmc/constants.h @@ -25,7 +25,7 @@ constexpr int VERSION_RELEASE {0}; constexpr std::array VERSION {VERSION_MAJOR, VERSION_MINOR, VERSION_RELEASE}; // HDF5 data format -constexpr int HDF5_VERSION[] {1, 0}; +constexpr int HDF5_VERSION[] {2, 0}; // Version numbers for binary files constexpr std::array VERSION_PARTICLE_RESTART {2, 0}; diff --git a/openmc/data/__init__.py b/openmc/data/__init__.py index 9aff59444..f52c3be75 100644 --- a/openmc/data/__init__.py +++ b/openmc/data/__init__.py @@ -1,5 +1,5 @@ # Version of HDF5 nuclear data format -HDF5_VERSION_MAJOR = 1 +HDF5_VERSION_MAJOR = 2 HDF5_VERSION_MINOR = 0 HDF5_VERSION = (HDF5_VERSION_MAJOR, HDF5_VERSION_MINOR) diff --git a/src/constants.F90 b/src/constants.F90 index 857d6ae4a..a9812e468 100644 --- a/src/constants.F90 +++ b/src/constants.F90 @@ -15,7 +15,7 @@ module constants VERSION(3) = [VERSION_MAJOR, VERSION_MINOR, VERSION_RELEASE] ! HDF5 data format - integer, parameter :: HDF5_VERSION(2) = [1, 0] + integer, parameter :: HDF5_VERSION(2) = [2, 0] ! WMP data format integer, parameter :: WMP_VERSION(2) = [1, 1] From 62edb23fd3169e8722ab3de7470ff8e7d2ff352b Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 12 Nov 2018 14:55:30 -0600 Subject: [PATCH 29/62] Update test results to reflect slightly different summing of total xs --- .../asymmetric_lattice/results_true.dat | 2 +- .../cmfd_nofeed/results_true.dat | 2 +- .../deplete/test_reference.h5 | Bin 162944 -> 162944 bytes .../diff_tally/results_true.dat | 44 +++--- .../case-3/results_true.dat | 2 +- .../filter_mesh/results_true.dat | 2 +- .../lattice_hex/results_true.dat | 2 +- .../lattice_mixed/results_true.dat | 2 +- .../mgxs_library_condense/results_true.dat | 2 +- .../mgxs_library_distribcell/results_true.dat | 4 +- .../mgxs_library_hdf5/results_true.dat | 142 +++++++++--------- .../mgxs_library_mesh/results_true.dat | 8 +- .../mgxs_library_no_nuclides/results_true.dat | 4 +- .../mgxs_library_nuclides/results_true.dat | 2 +- .../periodic/results_true.dat | 2 +- .../regression_tests/tallies/results_true.dat | 2 +- .../tally_aggregation/results_true.dat | 2 +- 17 files changed, 112 insertions(+), 112 deletions(-) diff --git a/tests/regression_tests/asymmetric_lattice/results_true.dat b/tests/regression_tests/asymmetric_lattice/results_true.dat index f60cfa64f..ecc30a056 100644 --- a/tests/regression_tests/asymmetric_lattice/results_true.dat +++ b/tests/regression_tests/asymmetric_lattice/results_true.dat @@ -1 +1 @@ -bd3fd10177bc0c7b8542f15228decf8608de013872d201e6ae885cf9b5b6d7516ddb32044ee2f7fd5b207e7d37d5ce3f03e347a2e850953bba4fc26b150c89d2 \ No newline at end of file +4b75e203d06d0fc1b4c4dfcb8c180d6f3df8fa2bc44e9775b59bbfd8f7a3785f956f9a9f301526f69c0f8a963ce2e553e0c62c7f6c696656ce1d47b415af6076 \ No newline at end of file diff --git a/tests/regression_tests/cmfd_nofeed/results_true.dat b/tests/regression_tests/cmfd_nofeed/results_true.dat index 1636af364..23368457d 100644 --- a/tests/regression_tests/cmfd_nofeed/results_true.dat +++ b/tests/regression_tests/cmfd_nofeed/results_true.dat @@ -438,7 +438,7 @@ cmfd balance 0.000000E+00 0.000000E+00 4.009062E-03 -4.869662E-03 +4.869661E-03 2.997290E-03 2.711191E-03 1.688329E-03 diff --git a/tests/regression_tests/deplete/test_reference.h5 b/tests/regression_tests/deplete/test_reference.h5 index 8c35778fa5a15406f0c80ad71f9e5dddd465b65c..8750924b113a357b3c880dc04000a5eb1a077710 100644 GIT binary patch literal 162944 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

JF|%HB(*jv~T<5j?Q{??FF-W8zxHU7Q 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 tXh#pD@Xg7-?c+hKP-x{{aAOy`=yE literal 162944 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%0D`NSD(r|gyt*# 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 diff --git a/tests/regression_tests/diff_tally/results_true.dat b/tests/regression_tests/diff_tally/results_true.dat index e3cff4ca0..41f3ac4f7 100644 --- a/tests/regression_tests/diff_tally/results_true.dat +++ b/tests/regression_tests/diff_tally/results_true.dat @@ -1,5 +1,5 @@ d_material,d_nuclide,d_variable,score,mean,std. dev. -3,,density,flux,-4.7291290e+00,8.8503902e-01 +3,,density,flux,-4.7291290e+00,8.8503901e-01 3,,density,flux,-1.0533184e+01,3.0256001e+00 1,,density,flux,-4.9634223e-01,1.3190338e-01 1,,density,flux,-4.7458622e-01,5.6426916e-02 @@ -11,16 +11,16 @@ d_material,d_nuclide,d_variable,score,mean,std. dev. 1,,temperature,flux,-4.4294257e-04,5.4687257e-04 3,,density,total,-1.5555916e+00,5.3353204e-01 3,,density,absorption,1.4925823e-01,2.3501173e-01 -3,,density,scatter,-1.7048498e+00,3.3363896e-01 -3,,density,fission,1.3210039e-01,1.6377610e-01 +3,,density,scatter,-1.7048499e+00,3.3363896e-01 +3,,density,fission,1.3210038e-01,1.6377610e-01 3,,density,nu-fission,3.1732288e-01,3.9893191e-01 3,,density,total,1.4744448e-01,2.0435075e-01 3,,density,absorption,1.6665433e-01,1.9696442e-01 -3,,density,scatter,-1.9209851e-02,7.8974770e-03 +3,,density,scatter,-1.9209851e-02,7.8974769e-03 3,,density,fission,1.4878594e-01,1.6616312e-01 3,,density,nu-fission,3.6225815e-01,4.0486140e-01 3,,density,total,1.2662462e+01,6.2596594e+00 -3,,density,absorption,2.2864288e-01,1.3031728e-01 +3,,density,absorption,2.2864287e-01,1.3031728e-01 3,,density,scatter,1.2433820e+01,6.1294912e+00 3,,density,fission,0.0000000e+00,0.0000000e+00 3,,density,nu-fission,0.0000000e+00,0.0000000e+00 @@ -31,17 +31,17 @@ d_material,d_nuclide,d_variable,score,mean,std. dev. 3,,density,nu-fission,0.0000000e+00,0.0000000e+00 1,,density,total,2.9404312e-01,7.0116815e-02 1,,density,absorption,-1.1851195e-03,1.6943078e-03 -1,,density,scatter,2.9522824e-01,6.8519873e-02 -1,,density,fission,-4.4865588e-03,2.3660449e-03 +1,,density,scatter,2.9522824e-01,6.8519874e-02 +1,,density,fission,-4.4865589e-03,2.3660449e-03 1,,density,nu-fission,-1.0266898e-02,5.7956130e-03 -1,,density,total,-3.6990351e-03,3.5138725e-03 +1,,density,total,-3.6990352e-03,3.5138725e-03 1,,density,absorption,-7.0064347e-03,2.7205092e-03 -1,,density,scatter,3.3073996e-03,7.9802045e-04 -1,,density,fission,-6.3630708e-03,2.3832611e-03 +1,,density,scatter,3.3073996e-03,7.9802046e-04 +1,,density,fission,-6.3630709e-03,2.3832611e-03 1,,density,nu-fission,-1.5466339e-02,5.8086647e-03 1,,density,total,-5.5743331e-01,6.1625011e-02 -1,,density,absorption,-9.1430498e-03,4.0831822e-03 -1,,density,scatter,-5.4829026e-01,5.7756112e-02 +1,,density,absorption,-9.1430499e-03,4.0831822e-03 +1,,density,scatter,-5.4829026e-01,5.7756113e-02 1,,density,fission,0.0000000e+00,0.0000000e+00 1,,density,nu-fission,0.0000000e+00,0.0000000e+00 1,,density,total,0.0000000e+00,0.0000000e+00 @@ -50,17 +50,17 @@ d_material,d_nuclide,d_variable,score,mean,std. dev. 1,,density,fission,0.0000000e+00,0.0000000e+00 1,,density,nu-fission,0.0000000e+00,0.0000000e+00 1,O16,nuclide_density,total,3.9360816e+01,6.1390337e+00 -1,O16,nuclide_density,absorption,-6.8169613e-01,4.5302455e-01 +1,O16,nuclide_density,absorption,-6.8169613e-01,4.5302456e-01 1,O16,nuclide_density,scatter,4.0042512e+01,6.4069240e+00 1,O16,nuclide_density,fission,-6.1275244e-01,2.5764187e-01 1,O16,nuclide_density,nu-fission,-1.5090099e+00,6.3048791e-01 1,O16,nuclide_density,total,-7.5872288e-01,3.4843447e-01 -1,O16,nuclide_density,absorption,-6.7382098e-01,3.1002267e-01 +1,O16,nuclide_density,absorption,-6.7382099e-01,3.1002267e-01 1,O16,nuclide_density,scatter,-8.4901894e-02,6.5286818e-02 1,O16,nuclide_density,fission,-5.5597011e-01,2.7085418e-01 1,O16,nuclide_density,nu-fission,-1.3555055e+00,6.6014209e-01 -1,O16,nuclide_density,total,-1.5539605e+01,2.3345398e+01 -1,O16,nuclide_density,absorption,-8.5880168e-02,5.0677339e-01 +1,O16,nuclide_density,total,-1.5539606e+01,2.3345398e+01 +1,O16,nuclide_density,absorption,-8.5880170e-02,5.0677339e-01 1,O16,nuclide_density,scatter,-1.5453725e+01,2.2838892e+01 1,O16,nuclide_density,fission,0.0000000e+00,0.0000000e+00 1,O16,nuclide_density,nu-fission,0.0000000e+00,0.0000000e+00 @@ -78,10 +78,10 @@ d_material,d_nuclide,d_variable,score,mean,std. dev. 1,U235,nuclide_density,absorption,3.8860811e+02,3.5290173e+01 1,U235,nuclide_density,scatter,1.0782853e+02,1.9206965e+00 1,U235,nuclide_density,fission,3.0827647e+02,2.4266512e+01 -1,U235,nuclide_density,nu-fission,7.5228268e+02,5.9109738e+01 +1,U235,nuclide_density,nu-fission,7.5228267e+02,5.9109738e+01 1,U235,nuclide_density,total,-4.7231732e+03,7.5353357e+02 1,U235,nuclide_density,absorption,-1.1580370e+02,1.8531790e+01 -1,U235,nuclide_density,scatter,-4.6073695e+03,7.3502263e+02 +1,U235,nuclide_density,scatter,-4.6073695e+03,7.3502264e+02 1,U235,nuclide_density,fission,0.0000000e+00,0.0000000e+00 1,U235,nuclide_density,nu-fission,0.0000000e+00,0.0000000e+00 1,U235,nuclide_density,total,0.0000000e+00,0.0000000e+00 @@ -109,11 +109,11 @@ d_material,d_nuclide,d_variable,score,mean,std. dev. 1,,temperature,scatter,0.0000000e+00,0.0000000e+00 1,,temperature,fission,0.0000000e+00,0.0000000e+00 1,,temperature,nu-fission,0.0000000e+00,0.0000000e+00 -3,,density,absorption,3.1512672e-02,2.4627803e-01 +3,,density,absorption,3.1512670e-02,2.4627803e-01 3,,density,absorption,1.1452915e-01,1.5733776e-01 1,,density,absorption,-1.4010827e-03,5.7414887e-03 1,,density,absorption,-8.9116087e-03,7.6054344e-03 -1,O16,nuclide_density,absorption,-1.0238428e+00,3.5596763e-01 +1,O16,nuclide_density,absorption,-1.0238429e+00,3.5596764e-01 1,O16,nuclide_density,absorption,-5.4386638e-01,6.3275232e-01 1,U235,nuclide_density,absorption,1.9740455e+02,1.1770740e+02 1,U235,nuclide_density,absorption,-1.3873202e+02,3.0030411e+01 @@ -139,7 +139,7 @@ d_material,d_nuclide,d_variable,score,mean,std. dev. 1,,density,scatter,-1.4155379e-02,7.8989014e-03 1,,density,nu-fission,0.0000000e+00,0.0000000e+00 1,,density,scatter,1.0449664e-03,5.7043392e-04 -1,,density,nu-fission,-1.3723982e-02,1.5246898e-02 +1,,density,nu-fission,-1.3723983e-02,1.5246898e-02 1,,density,scatter,3.0959958e-01,5.7651589e-02 1,,density,nu-fission,-1.9529210e-02,1.4804175e-02 1,,density,scatter,5.1063052e-04,1.7748731e-03 @@ -153,7 +153,7 @@ d_material,d_nuclide,d_variable,score,mean,std. dev. 1,,density,scatter,0.0000000e+00,0.0000000e+00 1,O16,nuclide_density,nu-fission,0.0000000e+00,0.0000000e+00 1,O16,nuclide_density,scatter,1.4017611e-01,9.5507870e-02 -1,O16,nuclide_density,nu-fission,-8.8199870e-01,1.6570982e+00 +1,O16,nuclide_density,nu-fission,-8.8199871e-01,1.6570982e+00 1,O16,nuclide_density,scatter,-1.5442745e-01,1.3136597e-01 1,O16,nuclide_density,nu-fission,0.0000000e+00,0.0000000e+00 1,O16,nuclide_density,scatter,0.0000000e+00,0.0000000e+00 diff --git a/tests/regression_tests/filter_distribcell/case-3/results_true.dat b/tests/regression_tests/filter_distribcell/case-3/results_true.dat index acd74781d..0a4dd9dc7 100644 --- a/tests/regression_tests/filter_distribcell/case-3/results_true.dat +++ b/tests/regression_tests/filter_distribcell/case-3/results_true.dat @@ -1 +1 @@ -a1f6ccf0bef1075ffc12e7fa058a44c83360801ba6e2c76f00e1bd7e9543fe1832777b122321dcb1cfb5fc1165ce84f711a65ca83903dd57cd09652e003daf62 \ No newline at end of file +11755ecac8355b5e79384f5d72974e618b6f95500c0a5718c01bb340c5d1c8ceafc33de65b9e94b7e9d78f16ec209f8a0fdf6a531eab5430657688d0125db7ef \ No newline at end of file diff --git a/tests/regression_tests/filter_mesh/results_true.dat b/tests/regression_tests/filter_mesh/results_true.dat index f331238b7..227d0d608 100644 --- a/tests/regression_tests/filter_mesh/results_true.dat +++ b/tests/regression_tests/filter_mesh/results_true.dat @@ -1 +1 @@ -46950c046648faaa5ff3cb7b4fdd03667ae3c6da96a7ed8121761291de452cf88481f53e967ed52407d77d90109ae24839967a22ae216531a0e1491f5051ea72 \ No newline at end of file +cc306dfd3e3669827cb2f3bdc38005c0616f6faecb9277f3b0f869fdecf826ae662c65d67a402705956f100d2e13c7c11332364fa41ccc2e215ab100709b627f \ No newline at end of file diff --git a/tests/regression_tests/lattice_hex/results_true.dat b/tests/regression_tests/lattice_hex/results_true.dat index d0da117e6..d83501bcf 100644 --- a/tests/regression_tests/lattice_hex/results_true.dat +++ b/tests/regression_tests/lattice_hex/results_true.dat @@ -1,2 +1,2 @@ k-combined: -2.546817E-01 1.509389E-02 +2.562946E-01 1.530982E-02 diff --git a/tests/regression_tests/lattice_mixed/results_true.dat b/tests/regression_tests/lattice_mixed/results_true.dat index 837ea92dd..09af26768 100644 --- a/tests/regression_tests/lattice_mixed/results_true.dat +++ b/tests/regression_tests/lattice_mixed/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.006646E+00 1.477915E-02 +9.877395E-01 1.744626E-02 diff --git a/tests/regression_tests/mgxs_library_condense/results_true.dat b/tests/regression_tests/mgxs_library_condense/results_true.dat index 32d3d2e1a..d4aa6b811 100644 --- a/tests/regression_tests/mgxs_library_condense/results_true.dat +++ b/tests/regression_tests/mgxs_library_condense/results_true.dat @@ -13,7 +13,7 @@ material group in nuclide mean std. dev. 0 1 1 total 0.090649 0.00641 material group in nuclide mean std. dev. -0 1 1 total 7.137954e+06 507363.468222 +0 1 1 total 7.137954e+06 507363.467231 material group in nuclide mean std. dev. 0 1 1 total 0.388721 0.01783 material group in nuclide mean std. dev. diff --git a/tests/regression_tests/mgxs_library_distribcell/results_true.dat b/tests/regression_tests/mgxs_library_distribcell/results_true.dat index d5496362c..9f58621c1 100644 --- a/tests/regression_tests/mgxs_library_distribcell/results_true.dat +++ b/tests/regression_tests/mgxs_library_distribcell/results_true.dat @@ -12,8 +12,8 @@ 0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.037577 0.001487 sum(distribcell) group in nuclide mean std. dev. 0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.092377 0.003628 - sum(distribcell) group in nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 7.276706e+06 287579.24765 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 7.276706e+06 287579.247699 sum(distribcell) group in nuclide mean std. dev. 0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.390797 0.008717 sum(distribcell) group in nuclide mean std. dev. diff --git a/tests/regression_tests/mgxs_library_hdf5/results_true.dat b/tests/regression_tests/mgxs_library_hdf5/results_true.dat index 18873664f..7ef172574 100644 --- a/tests/regression_tests/mgxs_library_hdf5/results_true.dat +++ b/tests/regression_tests/mgxs_library_hdf5/results_true.dat @@ -1,35 +1,35 @@ domain=1 type=total [4.14825464e-01 6.60169863e-01] -[2.27929105e-02 4.75188999e-02] +[2.27929104e-02 4.75189000e-02] domain=1 type=transport [3.63092031e-01 6.44850709e-01] -[2.38384843e-02 4.76746408e-02] +[2.38384842e-02 4.76746410e-02] domain=1 type=nu-transport [3.63092031e-01 6.44850709e-01] -[2.38384843e-02 4.76746408e-02] +[2.38384842e-02 4.76746410e-02] domain=1 type=absorption [2.74078431e-02 2.64510714e-01] [2.69249666e-03 2.33670618e-02] domain=1 type=capture -[1.98445483e-02 7.17193458e-02] +[1.98445482e-02 7.17193458e-02] [2.64330389e-03 2.52078411e-02] domain=1 type=fission -[7.56329483e-03 1.92791369e-01] -[5.08483896e-04 1.71059103e-02] +[7.56329484e-03 1.92791369e-01] +[5.08483893e-04 1.71059103e-02] domain=1 type=nu-fission [1.94317397e-02 4.69774728e-01] -[1.32297611e-03 4.16819716e-02] +[1.32297610e-03 4.16819717e-02] domain=1 type=kappa-fission [1.47456979e+06 3.72868925e+07] -[9.92353629e+04 3.30837549e+06] +[9.92353624e+04 3.30837549e+06] domain=1 type=scatter [3.87417621e-01 3.95659148e-01] -[2.06257343e-02 2.51250447e-02] +[2.06257342e-02 2.51250448e-02] domain=1 type=nu-scatter [3.85188361e-01 4.12389370e-01] [2.69456191e-02 1.54252759e-02] domain=1 type=scatter matrix -[[[3.84199430e-01 5.18702806e-02 2.00688439e-02 9.47771503e-03] +[[[3.84199430e-01 5.18702806e-02 2.00688439e-02 9.47771502e-03] [9.88930322e-04 -2.07234582e-04 -1.03366173e-04 2.34290606e-04]] [[9.24639842e-04 -7.67704913e-04 4.93788836e-04 -1.71497217e-04] @@ -40,7 +40,7 @@ domain=1 type=scatter matrix [[9.24883397e-04 7.67907131e-04 4.93918903e-04 1.71542390e-04] [1.52449343e-02 4.50172764e-03 1.05507486e-02 1.04381870e-02]]] domain=1 type=nu-scatter matrix -[[[3.84199430e-01 5.18702806e-02 2.00688439e-02 9.47771503e-03] +[[[3.84199430e-01 5.18702806e-02 2.00688439e-02 9.47771502e-03] [9.88930322e-04 -2.07234582e-04 -1.03366173e-04 2.34290606e-04]] [[9.24639842e-04 -7.67704913e-04 4.93788836e-04 -1.71497217e-04] @@ -59,7 +59,7 @@ domain=1 type=nu-fission matrix [[2.01424221e-02 0.00000000e+00] [4.54366342e-01 0.00000000e+00]] [[3.14909051e-03 0.00000000e+00] - [2.74255162e-02 0.00000000e+00]] + [2.74255160e-02 0.00000000e+00]] domain=1 type=scatter probability matrix [[9.97432606e-01 2.56739409e-03] [2.24215247e-03 9.97757848e-01]] @@ -71,52 +71,52 @@ domain=1 type=consistent scatter matrix [[8.87128136e-04 -7.36559899e-04 4.73756321e-04 -1.64539748e-04] [3.94772020e-01 1.58130798e-02 6.11300510e-03 -1.00731826e-02]]] -[[[3.66286904e-02 7.76748968e-03 3.13767806e-03 2.32683668e-03] - [4.89318749e-04 1.50458419e-04 1.85500930e-04 1.29783344e-04]] +[[[3.66286904e-02 7.76748967e-03 3.13767805e-03 2.32683668e-03] + [4.89318749e-04 1.50458419e-04 1.85500930e-04 1.29783343e-04]] [[8.89289900e-04 7.38354757e-04 4.74910776e-04 1.64940700e-04] - [2.98710064e-02 4.44330993e-03 1.01307463e-02 1.00367467e-02]]] + [2.98710065e-02 4.44330993e-03 1.01307463e-02 1.00367467e-02]]] domain=1 type=consistent nu-scatter matrix [[[3.86422967e-01 5.21704775e-02 2.01849914e-02 9.53256688e-03] [9.94653712e-04 -2.08433942e-04 -1.03964400e-04 2.35646553e-04]] [[8.87128136e-04 -7.36559899e-04 4.73756321e-04 -1.64539748e-04] [3.94772020e-01 1.58130798e-02 6.11300510e-03 -1.00731826e-02]]] -[[[4.75627021e-02 8.78140568e-03 3.51522200e-03 2.44425169e-03] +[[[4.75627021e-02 8.78140568e-03 3.51522199e-03 2.44425169e-03] [8.40606499e-04 2.07733706e-04 1.98782933e-04 2.07523215e-04]] [[1.53780011e-03 1.27679627e-03 8.21237084e-04 2.85222881e-04] - [3.39988352e-02 4.49065920e-03 1.01338659e-02 1.00452944e-02]]] + [3.39988353e-02 4.49065920e-03 1.01338659e-02 1.00452944e-02]]] domain=1 type=chi [1.00000000e+00 0.00000000e+00] -[4.60705493e-02 0.00000000e+00] +[4.60705491e-02 0.00000000e+00] domain=1 type=chi-prompt [1.00000000e+00 0.00000000e+00] -[5.14714845e-02 0.00000000e+00] +[5.14714842e-02 0.00000000e+00] domain=1 type=inverse-velocity [5.70932437e-08 2.85573948e-06] -[4.68793810e-09 2.44216368e-07] +[4.68793809e-09 2.44216369e-07] domain=1 type=prompt-nu-fission [1.92392209e-02 4.66718979e-01] -[1.30950644e-03 4.14108424e-02] +[1.30950644e-03 4.14108425e-02] domain=1 type=prompt-nu-fission matrix [[2.01424221e-02 0.00000000e+00] - [4.45819055e-01 0.00000000e+00]] + [4.45819054e-01 0.00000000e+00]] [[3.14909051e-03 0.00000000e+00] - [2.86750878e-02 0.00000000e+00]] + [2.86750876e-02 0.00000000e+00]] domain=1 type=delayed-nu-fission [[4.31687649e-06 1.06974147e-04] [2.69760050e-05 5.52167849e-04] [2.84366794e-05 5.27147626e-04] [7.42603126e-05 1.18190938e-03] [4.14908415e-05 4.84567103e-04] - [1.70015984e-05 2.02983423e-04]] -[[2.89748553e-07 9.49155601e-06] - [1.85003751e-06 4.89925095e-05] - [1.97097930e-06 4.67725251e-05] - [5.22610330e-06 1.04867938e-04] - [2.99830756e-06 4.29944539e-05] - [1.22654681e-06 1.80102228e-05]] + [1.70015984e-05 2.02983424e-04]] +[[2.89748551e-07 9.49155602e-06] + [1.85003750e-06 4.89925096e-05] + [1.97097929e-06 4.67725252e-05] + [5.22610328e-06 1.04867938e-04] + [2.99830754e-06 4.29944540e-05] + [1.22654681e-06 1.80102229e-05]] domain=1 type=chi-delayed [[0.00000000e+00 0.00000000e+00] [1.00000000e+00 0.00000000e+00] @@ -136,13 +136,13 @@ domain=1 type=beta [1.46341397e-03 1.12212853e-03] [3.82159878e-03 2.51590670e-03] [2.13520982e-03 1.03148823e-03] - [8.74939593e-04 4.32086725e-04]] -[[1.80847602e-05 2.46946655e-05] + [8.74939592e-04 4.32086725e-04]] +[[1.80847601e-05 2.46946655e-05] [1.14688936e-04 1.27466313e-04] - [1.21787672e-04 1.21690467e-04] - [3.21434953e-04 2.72840272e-04] - [1.82980531e-04 1.11860871e-04] - [7.48900067e-05 4.68581181e-05]] + [1.21787671e-04 1.21690467e-04] + [3.21434951e-04 2.72840272e-04] + [1.82980530e-04 1.11860871e-04] + [7.48900063e-05 4.68581181e-05]] domain=1 type=decay-rate [[1.34450193e-02 1.33360001e-02] [3.20638663e-02 3.27389978e-02] @@ -150,12 +150,12 @@ domain=1 type=decay-rate [3.15269336e-01 3.02780066e-01] [8.89232587e-01 8.49490287e-01] [2.98940409e+00 2.85300088e+00]] -[[1.08439456e-03 1.44623725e-03] - [2.65795039e-03 3.55041661e-03] - [1.02955037e-02 1.30981202e-02] - [2.71748572e-02 3.28353145e-02] - [7.93682892e-02 9.21238900e-02] - [2.66253284e-01 3.09396760e-01]] +[[1.08439455e-03 1.44623725e-03] + [2.65795038e-03 3.55041661e-03] + [1.02955036e-02 1.30981202e-02] + [2.71748571e-02 3.28353145e-02] + [7.93682889e-02 9.21238900e-02] + [2.66253283e-01 3.09396760e-01]] domain=1 type=delayed-nu-fission matrix [[[0.00000000e+00 0.00000000e+00] [0.00000000e+00 0.00000000e+00]] @@ -178,7 +178,7 @@ domain=1 type=delayed-nu-fission matrix [0.00000000e+00 0.00000000e+00]] [[0.00000000e+00 0.00000000e+00] - [1.56094522e-03 0.00000000e+00]] + [1.56094521e-03 0.00000000e+00]] [[0.00000000e+00 0.00000000e+00] [1.18610370e-03 0.00000000e+00]] @@ -192,20 +192,20 @@ domain=1 type=delayed-nu-fission matrix [[0.00000000e+00 0.00000000e+00] [0.00000000e+00 0.00000000e+00]]] domain=2 type=total -[3.13737666e-01 3.00821380e-01] -[1.55819223e-02 2.80524816e-02] +[3.13737667e-01 3.00821380e-01] +[1.55819228e-02 2.80524816e-02] domain=2 type=transport [2.75508079e-01 3.12035015e-01] -[1.77418855e-02 3.23843473e-02] +[1.77418859e-02 3.23843473e-02] domain=2 type=nu-transport [2.75508079e-01 3.12035015e-01] -[1.77418855e-02 3.23843473e-02] +[1.77418859e-02 3.23843473e-02] domain=2 type=absorption -[1.57499139e-03 5.40037826e-03] -[3.22547919e-04 6.18139027e-04] +[1.57499139e-03 5.40037825e-03] +[3.22547917e-04 6.18139027e-04] domain=2 type=capture -[1.57499139e-03 5.40037826e-03] -[3.22547919e-04 6.18139027e-04] +[1.57499139e-03 5.40037825e-03] +[3.22547917e-04 6.18139027e-04] domain=2 type=fission [0.00000000e+00 0.00000000e+00] [0.00000000e+00 0.00000000e+00] @@ -217,7 +217,7 @@ domain=2 type=kappa-fission [0.00000000e+00 0.00000000e+00] domain=2 type=scatter [3.12162675e-01 2.95421002e-01] -[1.53219430e-02 2.74455213e-02] +[1.53219435e-02 2.74455213e-02] domain=2 type=nu-scatter [3.10120713e-01 2.96264249e-01] [3.37881037e-02 4.37922226e-02] @@ -264,7 +264,7 @@ domain=2 type=consistent scatter matrix [[0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [2.95421002e-01 -1.11817183e-02 8.81141444e-03 -3.26075959e-03]]] -[[[3.72534018e-02 8.74305413e-03 4.83468235e-03 3.77642682e-03] +[[[3.72534020e-02 8.74305414e-03 4.83468236e-03 3.77642683e-03] [0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]] [[0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] @@ -275,7 +275,7 @@ domain=2 type=consistent nu-scatter matrix [[0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [2.95421002e-01 -1.11817183e-02 8.81141444e-03 -3.26075959e-03]]] -[[[5.04070427e-02 9.69345877e-03 5.34169555e-03 3.87580585e-03] +[[[5.04070429e-02 9.69345878e-03 5.34169556e-03 3.87580585e-03] [0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]] [[0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] @@ -287,8 +287,8 @@ domain=2 type=chi-prompt [0.00000000e+00 0.00000000e+00] [0.00000000e+00 0.00000000e+00] domain=2 type=inverse-velocity -[5.99597929e-08 2.98549016e-06] -[4.55308445e-09 3.41701982e-07] +[5.99597928e-08 2.98549016e-06] +[4.55308451e-09 3.41701982e-07] domain=2 type=prompt-nu-fission [0.00000000e+00 0.00000000e+00] [0.00000000e+00 0.00000000e+00] @@ -385,8 +385,8 @@ domain=2 type=delayed-nu-fission matrix [[0.00000000e+00 0.00000000e+00] [0.00000000e+00 0.00000000e+00]]] domain=3 type=total -[6.64572195e-01 2.05238389e+00] -[3.12147473e-02 2.24342891e-01] +[6.64572194e-01 2.05238389e+00] +[3.12147473e-02 2.24342890e-01] domain=3 type=transport [2.83322749e-01 1.49973953e+00] [3.52061127e-02 2.30902118e-01] @@ -394,11 +394,11 @@ domain=3 type=nu-transport [2.83322749e-01 1.49973953e+00] [3.52061127e-02 2.30902118e-01] domain=3 type=absorption -[6.90399495e-04 3.16872549e-02] -[4.41475663e-05 3.74655831e-03] +[6.90399488e-04 3.16872537e-02] +[4.41475703e-05 3.74655812e-03] domain=3 type=capture -[6.90399495e-04 3.16872549e-02] -[4.41475663e-05 3.74655831e-03] +[6.90399488e-04 3.16872537e-02] +[4.41475703e-05 3.74655812e-03] domain=3 type=fission [0.00000000e+00 0.00000000e+00] [0.00000000e+00 0.00000000e+00] @@ -418,24 +418,24 @@ domain=3 type=scatter matrix [[[6.39901439e-01 3.81167422e-01 1.52391887e-01 9.14802163e-03] [3.13677176e-02 8.75772258e-03 -2.56790088e-03 -3.78480261e-03]] - [[4.43343102e-04 3.99960386e-04 3.19562684e-04 2.13846954e-04] - [2.03494484e+00 5.09940477e-01 1.11174601e-01 2.49884339e-02]]] -[[[2.47091210e-02 1.62432638e-02 8.15627712e-03 3.88856186e-03] + [[4.43343102e-04 3.99960385e-04 3.19562684e-04 2.13846954e-04] + [2.03494484e+00 5.09940476e-01 1.11174601e-01 2.49884339e-02]]] +[[[2.47091210e-02 1.62432637e-02 8.15627711e-03 3.88856186e-03] [1.72811278e-03 9.25670435e-04 1.01398468e-03 8.17075512e-04]] [[4.44850361e-04 4.01320154e-04 3.20649120e-04 2.14573982e-04] - [2.57799870e-01 5.12359026e-02 1.30198161e-02 8.31235197e-03]]] + [2.57799870e-01 5.12359026e-02 1.30198161e-02 8.31235196e-03]]] domain=3 type=nu-scatter matrix [[[6.39901439e-01 3.81167422e-01 1.52391887e-01 9.14802163e-03] [3.13677176e-02 8.75772258e-03 -2.56790088e-03 -3.78480261e-03]] - [[4.43343102e-04 3.99960386e-04 3.19562684e-04 2.13846954e-04] - [2.03494484e+00 5.09940477e-01 1.11174601e-01 2.49884339e-02]]] -[[[2.47091210e-02 1.62432638e-02 8.15627712e-03 3.88856186e-03] + [[4.43343102e-04 3.99960385e-04 3.19562684e-04 2.13846954e-04] + [2.03494484e+00 5.09940476e-01 1.11174601e-01 2.49884339e-02]]] +[[[2.47091210e-02 1.62432637e-02 8.15627711e-03 3.88856186e-03] [1.72811278e-03 9.25670435e-04 1.01398468e-03 8.17075512e-04]] [[4.44850361e-04 4.01320154e-04 3.20649120e-04 2.14573982e-04] - [2.57799870e-01 5.12359026e-02 1.30198161e-02 8.31235197e-03]]] + [2.57799870e-01 5.12359026e-02 1.30198161e-02 8.31235196e-03]]] domain=3 type=multiplicity matrix [[1.00000000e+00 1.00000000e+00] [1.00000000e+00 1.00000000e+00]] @@ -469,7 +469,7 @@ domain=3 type=consistent nu-scatter matrix [[4.40143026e-04 3.97073448e-04 3.17256062e-04 2.12303394e-04] [2.02025649e+00 5.06259696e-01 1.10372136e-01 2.48080660e-02]]] [[[4.52974133e-02 2.78247077e-02 1.21478698e-02 3.88422859e-03] - [3.06407542e-03 1.15855775e-03 1.02420876e-03 8.64382873e-04]] + [3.06407542e-03 1.15855774e-03 1.02420876e-03 8.64382873e-04]] [[7.65033031e-04 6.90171798e-04 5.51437493e-04 3.69014387e-04] [4.46600759e-01 1.04874946e-01 2.38091367e-02 9.39676938e-03]]] diff --git a/tests/regression_tests/mgxs_library_mesh/results_true.dat b/tests/regression_tests/mgxs_library_mesh/results_true.dat index 27c1ffdc9..829edde9f 100644 --- a/tests/regression_tests/mgxs_library_mesh/results_true.dat +++ b/tests/regression_tests/mgxs_library_mesh/results_true.dat @@ -42,10 +42,10 @@ 3 2 2 1 1 total 0.020469 0.002617 mesh 1 group in nuclide mean std. dev. x y z -0 1 1 1 1 total 2.177345e+06 589804.299388 -2 1 2 1 1 total 1.404096e+06 236476.851953 -1 2 1 1 1 total 1.413154e+06 347806.623417 -3 2 2 1 1 total 1.608259e+06 206502.707865 +0 1 1 1 1 total 2.177345e+06 589804.301157 +2 1 2 1 1 total 1.404096e+06 236476.852674 +1 2 1 1 1 total 1.413154e+06 347806.623478 +3 2 2 1 1 total 1.608259e+06 206502.707123 mesh 1 group in nuclide mean std. dev. x y z 0 1 1 1 1 total 0.735256 0.080216 diff --git a/tests/regression_tests/mgxs_library_no_nuclides/results_true.dat b/tests/regression_tests/mgxs_library_no_nuclides/results_true.dat index d4c87378e..dc98a2263 100644 --- a/tests/regression_tests/mgxs_library_no_nuclides/results_true.dat +++ b/tests/regression_tests/mgxs_library_no_nuclides/results_true.dat @@ -130,7 +130,7 @@ 0 1 2 2 total 0.000000 0.000000 material delayedgroup group in nuclide mean std. dev. 1 1 1 1 total 0.000004 2.897486e-07 -3 1 2 1 total 0.000027 1.850038e-06 +3 1 2 1 total 0.000027 1.850037e-06 5 1 3 1 total 0.000028 1.970979e-06 7 1 4 1 total 0.000074 5.226103e-06 9 1 5 1 total 0.000041 2.998308e-06 @@ -325,7 +325,7 @@ 1 2 1 total 0.0 0.0 0 2 2 total 0.0 0.0 material group in nuclide mean std. dev. -1 2 1 total 5.995979e-08 4.553084e-09 +1 2 1 total 5.995979e-08 4.553085e-09 0 2 2 total 2.985490e-06 3.417020e-07 material group in nuclide mean std. dev. 1 2 1 total 0.0 0.0 diff --git a/tests/regression_tests/mgxs_library_nuclides/results_true.dat b/tests/regression_tests/mgxs_library_nuclides/results_true.dat index 577694cfa..27272239c 100644 --- a/tests/regression_tests/mgxs_library_nuclides/results_true.dat +++ b/tests/regression_tests/mgxs_library_nuclides/results_true.dat @@ -1 +1 @@ -0edd3036c0b5b1eebad90dc8fba25006f14745ceb51dd109e70d0c610d66071f32128facdbc6d4e5077534fe96fff9a8e0ddeefb4a18d6c578f8e805bab7aa22 \ No newline at end of file +185e6f1f7ba94b0cdfae5b2519865efec84055d341bd490b856f9786ef1c91a3cb007d6b22811ffa30d4665256aad8a2982548e6c96e8d8d9c5f569475e52cfe \ No newline at end of file diff --git a/tests/regression_tests/periodic/results_true.dat b/tests/regression_tests/periodic/results_true.dat index 96f4735b0..5a9820dd3 100644 --- a/tests/regression_tests/periodic/results_true.dat +++ b/tests/regression_tests/periodic/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.040109E+00 6.527468E-02 +1.040109E+00 6.527466E-02 diff --git a/tests/regression_tests/tallies/results_true.dat b/tests/regression_tests/tallies/results_true.dat index b1cef30fe..c245bc8a1 100644 --- a/tests/regression_tests/tallies/results_true.dat +++ b/tests/regression_tests/tallies/results_true.dat @@ -1 +1 @@ -8cf1936c565c6a09bffe2f7a0623ded1405bae37c1de8159551e64b86ca4f6bce82890a630b9428bcf8353f6de8e5cfc1f1a4263fd51a1c6b5cddb0a9c2ff368 \ No newline at end of file +aa7f79718620c122e3a13bfa0e200a41b642b09a5d10a6e43e1584181b0314fbeb73c165fe55ddd34c1e9546e381019dd8e3889ca7d99bfe1ab489631bec15d1 \ No newline at end of file diff --git a/tests/regression_tests/tally_aggregation/results_true.dat b/tests/regression_tests/tally_aggregation/results_true.dat index 3caeceec9..f1738ddfd 100644 --- a/tests/regression_tests/tally_aggregation/results_true.dat +++ b/tests/regression_tests/tally_aggregation/results_true.dat @@ -1 +1 @@ -c8fb043c5321e698040544dbb0baa9ce82df0e189738fb6013b4f3ff7e05a989a7a59b9b55034b8c9de6bc604ba9f969dc08ad2752fc74da205c19ff5974c9a2 \ No newline at end of file +eac8fb56a8146b9e186ac9fb003753f4a0a18d4159d10e6fa51da4856baef66a10a0f5fb10c5727b51c6e44d81c147a8a7348ad9c9f7119a6ec33e0361082376 \ No newline at end of file From 7c3c0bb73159cec0e62c815f426f9eb066eb9b39 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 12 Nov 2018 15:19:04 -0600 Subject: [PATCH 30/62] Improve logic for determining redundant reactions --- openmc/data/neutron.py | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index a161cc5af..61bea997b 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -375,15 +375,13 @@ class IncidentNeutron(EqualityMixin): self.energy['0K'] = x self[2].xs['0K'] = Tabulated1D(x, y) - def get_reaction_components(self, mt, exclude_self=False): + def get_reaction_components(self, mt): """Determine what reactions make up redundant reaction. Parameters ---------- mt : int ENDF MT number of the reaction to find components of. - exclude_self : bool - Whether to exclude the original MT number when finding components Returns ------- @@ -392,24 +390,14 @@ class IncidentNeutron(EqualityMixin): have cross sections provided. """ - if mt in self.reactions and not exclude_self: - return [mt] - elif mt in SUM_RULES: - mts = SUM_RULES[mt] + mts = [] + if mt in SUM_RULES: + for mt_i in SUM_RULES[mt]: + mts += self.get_reaction_components(mt_i) + if mts: + return mts else: - return [] - complete = False - while not complete: - new_mts = [] - complete = True - for i, mt_i in enumerate(mts): - if mt_i in self.reactions: - new_mts.append(mt_i) - elif mt_i in SUM_RULES: - new_mts += SUM_RULES[mt_i] - complete = False - mts = new_mts - return mts + return [mt] if mt in self else [] def export_to_hdf5(self, path, mode='a', libver='earliest'): """Export incident neutron data to an HDF5 file. @@ -700,12 +688,11 @@ class IncidentNeutron(EqualityMixin): rx = data._get_redundant_reaction(mt, mts) data.reactions[mt] = rx - # Make sure redundant cross sections that are present in an ACE file get # marked as such for rx in data: - mts = data.get_reaction_components(rx.mt, exclude_self=True) - if mts: + mts = data.get_reaction_components(rx.mt) + if mts != [rx.mt]: rx.redundant = True # Read unresolved resonance probability tables From 3079afa3d8e71af59c346ddb5f99034e27c6a447 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 13 Nov 2018 06:51:03 -0600 Subject: [PATCH 31/62] Support older versions of HDF5 data for IncidentNeutron.from_hdf5 --- openmc/data/neutron.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index 61bea997b..eec083602 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -502,11 +502,7 @@ class IncidentNeutron(EqualityMixin): # Make sure version matches if 'version' in h5file.attrs: major, minor = h5file.attrs['version'] - if major != HDF5_VERSION_MAJOR: - raise IOError( - 'HDF5 data format uses version {}.{} whereas your ' - 'installation of the OpenMC Python API expects version ' - '{}.x.'.format(major, minor, HDF5_VERSION_MAJOR)) + # For now all versions of HDF5 data can be read else: raise IOError( 'HDF5 data does not indicate a version. Your installation of ' From 1b075217048f70ff9485e0f301e37af5d038b702 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 13 Nov 2018 07:33:00 -0600 Subject: [PATCH 32/62] Update test data used on Travis --- .travis.yml | 1 - tools/ci/download-xs.sh | 10 ++-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index eacf3bb43..2c3a50559 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,6 @@ cache: directories: - $HOME/nndc_hdf5 - $HOME/endf-b-vii.1 - - $HOME/WMP_Library env: global: - FC=gfortran diff --git a/tools/ci/download-xs.sh b/tools/ci/download-xs.sh index eed9e23c4..5fbe93c71 100755 --- a/tools/ci/download-xs.sh +++ b/tools/ci/download-xs.sh @@ -1,9 +1,9 @@ #!/bin/bash set -ex -# Download NNDC HDF5 data +# Download HDF5 data if [[ ! -e $HOME/nndc_hdf5/cross_sections.xml ]]; then - wget -q -O - https://anl.box.com/shared/static/a0eflty17atnpd0pp7460exagr3nuhm7.xz | tar -C $HOME -xJ + wget -q -O - https://anl.box.com/shared/static/snrluuy79o2fffpvpng9bsuis5kl811d.xz | tar -C $HOME -xJ fi # Download ENDF/B-VII.1 distribution @@ -11,9 +11,3 @@ ENDF=$HOME/endf-b-vii.1/ if [[ ! -d $ENDF/neutrons || ! -d $ENDF/photoat || ! -d $ENDF/atomic_relax ]]; then wget -q -O - https://anl.box.com/shared/static/4kd2gxnf4gtk4w1c8eua5fsua22kvgjb.xz | tar -C $HOME -xJ fi - -# Download multipole library -if [[ ! -e $HOME/WMP_Library/092235.h5 ]]; then - wget -q https://github.com/mit-crpg/WMP_Library/releases/download/v1.1/WMP_Library_v1.1.tar.gz - tar -C $HOME -xzf WMP_Library_v1.1.tar.gz -fi From 927cbdac14d2324c6d87f9f762355c47cc6870e0 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 13 Nov 2018 10:49:04 -0600 Subject: [PATCH 33/62] Find nu properly for nuclides with first-, second-, etc. chance fission --- openmc/data/fission_energy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openmc/data/fission_energy.py b/openmc/data/fission_energy.py index ee2d95078..95915650b 100644 --- a/openmc/data/fission_energy.py +++ b/openmc/data/fission_energy.py @@ -279,11 +279,11 @@ class FissionEnergyRelease(EqualityMixin): # the delayed neutron fraction is so small that the difference # is negligible. MT=18 (n, fission) might not be available so # try MT=19 (n, f) as well. - if 18 in incident_neutron.reactions: + if 18 in incident_neutron and not incident_neutron[18].redundant: nu = [p.yield_ for p in incident_neutron[18].products if p.particle == 'neutron' and p.emission_mode in ('prompt', 'total')] - elif 19 in incident_neutron.reactions: + elif 19 in incident_neutron: nu = [p.yield_ for p in incident_neutron[19].products if p.particle == 'neutron' and p.emission_mode in ('prompt', 'total')] From 0abb03fdc990b72d0f028692154a65ee7cee6503 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 13 Nov 2018 10:52:53 -0600 Subject: [PATCH 34/62] Changes suggested by @liangjg --- Dockerfile | 3 +-- docs/source/io_formats/cross_sections.rst | 10 ++++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index c29e1321c..6466c7685 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,6 @@ ENV FC=/usr/bin/mpif90 CC=/usr/bin/mpicc CXX=/usr/bin/mpicxx \ PATH=/opt/openmc/bin:/opt/NJOY2016/build:$PATH \ LD_LIBRARY_PATH=/opt/openmc/lib:$LD_LIBRARY_PATH \ OPENMC_CROSS_SECTIONS=/root/nndc_hdf5/cross_sections.xml \ - OPENMC_MULTIPOLE_LIBRARY=/root/WMP_Library \ OPENMC_ENDF_DATA=/root/endf-b-vii.1 # Install dependencies from Debian package manager @@ -36,4 +35,4 @@ RUN git clone https://github.com/openmc-dev/openmc.git /opt/openmc && \ cd .. && pip install -e .[test] # Download cross sections (NNDC and WMP) and ENDF data needed by test suite -RUN ./opt/openmc/tools/ci/download-xs.sh \ No newline at end of file +RUN ./opt/openmc/tools/ci/download-xs.sh diff --git a/docs/source/io_formats/cross_sections.rst b/docs/source/io_formats/cross_sections.rst index 956b3fa5d..60f1d4f50 100644 --- a/docs/source/io_formats/cross_sections.rst +++ b/docs/source/io_formats/cross_sections.rst @@ -25,9 +25,10 @@ node. For example, ```` Element --------------------- -The ```` element indicates where an HDF5 cross section file is located, -whether it contains incident neutron or thermal scattering data, and what -materials are listed within. It has the following attributes: +The ```` element indicates where an HDF5 data file is located, whether +it contains incident neutron, incident photon, thermal scattering, or windowed +multipole data, and what materials are listed within. It has the following +attributes: :materials: @@ -48,4 +49,5 @@ materials are listed within. It has the following attributes: directory containing the ``cross_sections.xml`` file. :type: - The type of data contained in the file, either 'neutron' or 'thermal'. + The type of data contained in the file. Accepted values are 'neutron', + 'thermal', 'photon', and 'wmp'. From 833eb560308d3770a8b7c198583c1abfa27a65d7 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 8 Nov 2018 12:46:12 -0600 Subject: [PATCH 35/62] Use simulation namespace for globals in eigenvalue.h --- include/openmc/eigenvalue.h | 4 +++ src/eigenvalue.cpp | 60 ++++++++++++++++++++----------------- src/finalize.cpp | 2 +- src/physics_mg.cpp | 2 +- src/settings.cpp | 2 +- src/simulation.cpp | 6 ++-- src/state_point.cpp | 6 ++-- 7 files changed, 45 insertions(+), 37 deletions(-) diff --git a/include/openmc/eigenvalue.h b/include/openmc/eigenvalue.h index b7a75becb..6d918eb40 100644 --- a/include/openmc/eigenvalue.h +++ b/include/openmc/eigenvalue.h @@ -18,6 +18,8 @@ namespace openmc { // Global variables //============================================================================== +namespace simulation { + extern double keff_generation; //!< Single-generation k on each processor extern std::array k_sum; //!< Used to reduce sum and sum_sq extern std::vector entropy; //!< Shannon entropy at each generation @@ -26,6 +28,8 @@ extern xt::xtensor source_frac; //!< Source fraction for UFS extern "C" int64_t n_bank; #pragma omp threadprivate(n_bank) +} // namespace simulation + //============================================================================== // Non-member functions //============================================================================== diff --git a/src/eigenvalue.cpp b/src/eigenvalue.cpp index 927b014b5..89e25dbcf 100644 --- a/src/eigenvalue.cpp +++ b/src/eigenvalue.cpp @@ -30,11 +30,15 @@ namespace openmc { // Global variables //============================================================================== +namespace simulation { + double keff_generation; std::array k_sum; std::vector entropy; xt::xtensor source_frac; +} // namespace simulation + //============================================================================== // Non-member functions //============================================================================== @@ -44,15 +48,15 @@ void calculate_generation_keff() auto gt = global_tallies(); // Get keff for this generation by subtracting off the starting value - keff_generation = gt(K_TRACKLENGTH, RESULT_VALUE) - keff_generation; + simulation::keff_generation = gt(K_TRACKLENGTH, RESULT_VALUE) - simulation::keff_generation; double keff_reduced; #ifdef OPENMC_MPI // Combine values across all processors - MPI_Allreduce(&keff_generation, &keff_reduced, 1, MPI_DOUBLE, + MPI_Allreduce(&simulation::keff_generation, &keff_reduced, 1, MPI_DOUBLE, MPI_SUM, mpi::intracomm); #else - keff_reduced = keff_generation; + keff_reduced = simulation::keff_generation; #endif // Normalize single batch estimate of k @@ -83,21 +87,21 @@ void synchronize_bank() #ifdef OPENMC_MPI int64_t start = 0; - MPI_Exscan(&n_bank, &start, 1, MPI_INT64_T, MPI_SUM, mpi::intracomm); + MPI_Exscan(&simulation::n_bank, &start, 1, MPI_INT64_T, MPI_SUM, mpi::intracomm); // While we would expect the value of start on rank 0 to be 0, the MPI // standard says that the receive buffer on rank 0 is undefined and not // significant if (mpi::rank == 0) start = 0; - int64_t finish = start + n_bank; + int64_t finish = start + simulation::n_bank; int64_t total = finish; MPI_Bcast(&total, 1, MPI_INT64_T, mpi::n_procs - 1, mpi::intracomm); #else int64_t start = 0; - int64_t finish = n_bank; - int64_t total = n_bank; + int64_t finish = simulation::n_bank; + int64_t total = simulation::n_bank; #endif // If there are not that many particles per generation, it's possible that no @@ -105,7 +109,7 @@ void synchronize_bank() // extra logic to treat this circumstance, we really want to ensure the user // runs enough particles to avoid this in the first place. - if (n_bank == 0) { + if (simulation::n_bank == 0) { fatal_error("No fission sites banked on MPI rank " + std::to_string(mpi::rank)); } @@ -136,7 +140,7 @@ void synchronize_bank() int64_t index_temp = 0; std::vector temp_sites(3*simulation::work); - for (int64_t i = 0; i < n_bank; ++i) { + for (int64_t i = 0; i < simulation::n_bank; ++i) { // If there are less than n_particles particles banked, automatically add // int(n_particles/total) sites to temp_sites. For example, if you need // 1000 and 300 were banked, this would add 3 source sites per banked site @@ -191,7 +195,7 @@ void synchronize_bank() // fission bank sites_needed = settings::n_particles - finish; for (int i = 0; i < sites_needed; ++i) { - temp_sites[index_temp] = fission_bank[n_bank - sites_needed + i]; + temp_sites[index_temp] = fission_bank[simulation::n_bank - sites_needed + i]; ++index_temp; } } @@ -320,11 +324,11 @@ void calculate_average_keff() simulation::keff = simulation::k_generation[i]; } else { // Sample mean of keff - k_sum[0] += simulation::k_generation[i]; - k_sum[1] += std::pow(simulation::k_generation[i], 2); + simulation::k_sum[0] += simulation::k_generation[i]; + simulation::k_sum[1] += std::pow(simulation::k_generation[i], 2); // Determine mean - simulation::keff = k_sum[0] / n; + simulation::keff = simulation::k_sum[0] / n; if (n > 1) { double t_value; @@ -337,7 +341,7 @@ void calculate_average_keff() } // Standard deviation of the sample mean of k - simulation::keff_std = t_value * std::sqrt((k_sum[1]/n - + simulation::keff_std = t_value * std::sqrt((simulation::k_sum[1]/n - std::pow(simulation::keff, 2)) / (n - 1)); } } @@ -503,7 +507,7 @@ void shannon_entropy() // Get source weight in each mesh bin bool sites_outside; xt::xtensor p = m->count_sites( - n_bank, fission_bank, 0, nullptr, &sites_outside); + simulation::n_bank, fission_bank, 0, nullptr, &sites_outside); // display warning message if there were sites outside entropy box if (sites_outside) { @@ -523,7 +527,7 @@ void shannon_entropy() } // Add value to vector - entropy.push_back(H); + simulation::entropy.push_back(H); } } @@ -536,7 +540,7 @@ void ufs_count_sites() // distributed so that effectively the production of fission sites is not // biased - auto s = xt::view(source_frac, xt::all()); + auto s = xt::view(simulation::source_frac, xt::all()); s = m->volume_frac_; } else { @@ -547,7 +551,7 @@ void ufs_count_sites() // count number of source sites in each ufs mesh cell bool sites_outside; - source_frac = m->count_sites(simulation::work, source_bank, 0, nullptr, + simulation::source_frac = m->count_sites(simulation::work, source_bank, 0, nullptr, &sites_outside); // Check for sites outside of the mesh @@ -558,12 +562,12 @@ void ufs_count_sites() #ifdef OPENMC_MPI // Send source fraction to all processors int n_bins = xt::prod(m->shape_)(); - MPI_Bcast(source_frac.data(), n_bins, MPI_DOUBLE, 0, mpi::intracomm); + MPI_Bcast(simulation::source_frac.data(), n_bins, MPI_DOUBLE, 0, mpi::intracomm); #endif // Normalize to total weight to get fraction of source in each cell - double total = xt::sum(source_frac)(); - source_frac /= total; + double total = xt::sum(simulation::source_frac)(); + simulation::source_frac /= total; // Since the total starting weight is not equal to n_particles, we need to // renormalize the weight of the source sites @@ -585,8 +589,8 @@ double ufs_get_weight(const Particle* p) fatal_error("Source site outside UFS mesh!"); } - if (source_frac(mesh_bin) != 0.0) { - return m->volume_frac_ / source_frac(mesh_bin); + if (simulation::source_frac(mesh_bin) != 0.0) { + return m->volume_frac_ / simulation::source_frac(mesh_bin); } else { return 1.0; } @@ -598,7 +602,7 @@ extern "C" void write_eigenvalue_hdf5(hid_t group) write_dataset(group, "generations_per_batch", settings::gen_per_batch); write_dataset(group, "k_generation", simulation::k_generation); if (settings::entropy_on) { - write_dataset(group, "entropy", entropy); + write_dataset(group, "entropy", simulation::entropy); } write_dataset(group, "k_col_abs", simulation::k_col_abs); write_dataset(group, "k_col_tra", simulation::k_col_tra); @@ -615,7 +619,7 @@ extern "C" void read_eigenvalue_hdf5(hid_t group) simulation::k_generation.resize(n); read_dataset(group, "k_generation", simulation::k_generation); if (settings::entropy_on) { - read_dataset(group, "entropy", entropy); + read_dataset(group, "entropy", simulation::entropy); } read_dataset(group, "k_col_abs", simulation::k_col_abs); read_dataset(group, "k_col_tra", simulation::k_col_tra); @@ -628,14 +632,14 @@ extern "C" void read_eigenvalue_hdf5(hid_t group) extern "C" double entropy_c(int i) { - return entropy.at(i - 1); + return simulation::entropy.at(i - 1); } extern "C" void entropy_clear() { - entropy.clear(); + simulation::entropy.clear(); } -extern "C" void k_sum_reset() { k_sum.fill(0.0); } +extern "C" void k_sum_reset() { simulation::k_sum.fill(0.0); } } // namespace openmc diff --git a/src/finalize.cpp b/src/finalize.cpp index 94e3d1a7f..b9d17eac3 100644 --- a/src/finalize.cpp +++ b/src/finalize.cpp @@ -113,7 +113,7 @@ int openmc_reset() simulation::k_col_abs = 0.0; simulation::k_col_tra = 0.0; simulation::k_abs_tra = 0.0; - k_sum = {0.0, 0.0}; + simulation::k_sum = {0.0, 0.0}; // Reset timers reset_timers(); diff --git a/src/physics_mg.cpp b/src/physics_mg.cpp index 40e5ba1ae..ff41221ba 100644 --- a/src/physics_mg.cpp +++ b/src/physics_mg.cpp @@ -53,7 +53,7 @@ sample_reaction(Particle* p, const double* energy_bin_avg, int64_t result_bank_size; // Get pointer to fission bank from Fortran side openmc_fission_bank(&result_bank, &result_bank_size); - create_fission_sites(p, result_bank, &n_bank, result_bank_size, + create_fission_sites(p, result_bank, &simulation::n_bank, result_bank_size, material_xs); } else if ((settings::run_mode == RUN_MODE_FIXEDSOURCE) && (settings::create_fission_neutrons)) { diff --git a/src/settings.cpp b/src/settings.cpp index 459d7115d..bf9ef82de 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -150,7 +150,7 @@ void get_run_parameters(pugi::xml_node node_base) // Preallocate space for keff and entropy by generation int m = settings::n_max_batches * settings::gen_per_batch; simulation::k_generation.reserve(m); - entropy.reserve(m); + simulation::entropy.reserve(m); // Get the trigger information for keff if (check_for_node(node_base, "keff_trigger")) { diff --git a/src/simulation.cpp b/src/simulation.cpp index 84ebb0192..55b825a18 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -104,7 +104,7 @@ int openmc_simulation_init() // will potentially populate k_generation and entropy) simulation::current_batch = 0; simulation::k_generation.clear(); - entropy.clear(); + simulation::entropy.clear(); simulation::need_depletion_rx = false; // If this is a restart run, load the state point data and binary source @@ -384,13 +384,13 @@ void initialize_generation() { if (settings::run_mode == RUN_MODE_EIGENVALUE) { // Reset number of fission bank sites - n_bank = 0; + simulation::n_bank = 0; // Count source sites if using uniform fission source weighting if (settings::ufs_on) ufs_count_sites(); // Store current value of tracklength k - keff_generation = global_tallies()(K_TRACKLENGTH, RESULT_VALUE); + simulation::keff_generation = global_tallies()(K_TRACKLENGTH, RESULT_VALUE); } } diff --git a/src/state_point.cpp b/src/state_point.cpp index 620b5f71a..5b4384f91 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -320,11 +320,11 @@ void restart_set_keff() { if (simulation::restart_batch > settings::n_inactive) { for (int i = settings::n_inactive; i < simulation::restart_batch; ++i) { - k_sum[0] += simulation::k_generation[i]; - k_sum[1] += std::pow(simulation::k_generation[i], 2); + simulation::k_sum[0] += simulation::k_generation[i]; + simulation::k_sum[1] += std::pow(simulation::k_generation[i], 2); } int n = settings::gen_per_batch*n_realizations; - simulation::keff = k_sum[0] / n; + simulation::keff = simulation::k_sum[0] / n; } else { simulation::keff = simulation::k_generation.back(); } From 995905bd1cf29dd51a40f6c18d26b9fde7bcbf2c Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 8 Nov 2018 12:59:10 -0600 Subject: [PATCH 36/62] Use mpi::master instead of openmc_master on C++ side --- src/initialize.cpp | 2 +- src/main.cpp | 24 +++++++++++++----------- src/output.cpp | 14 +++++++------- src/plot.cpp | 7 ++++--- src/settings.cpp | 5 +++-- src/state_point.cpp | 2 +- 6 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/initialize.cpp b/src/initialize.cpp index e04ac2922..2250a6ac8 100644 --- a/src/initialize.cpp +++ b/src/initialize.cpp @@ -210,7 +210,7 @@ parse_command_line(int argc, char* argv[]) } omp_set_num_threads(simulation::n_threads); #else - if (openmc_master) + if (mpi::master) warning("Ignoring number of threads specified on command line."); #endif diff --git a/src/main.cpp b/src/main.cpp index f4e2d3f8e..b757c67ff 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,13 +1,15 @@ #ifdef OPENMC_MPI -#include "mpi.h" +#include #endif #include "openmc/capi.h" #include "openmc/constants.h" #include "openmc/error.h" +#include "openmc/message_passing.h" #include "openmc/settings.h" int main(int argc, char* argv[]) { + using namespace openmc; int err; // Initialize run -- when run with MPI, pass communicator @@ -21,30 +23,30 @@ int main(int argc, char* argv[]) { // This happens for the -h and -v flags return 0; } else if (err) { - openmc::fatal_error(openmc_err_msg); + fatal_error(openmc_err_msg); } // start problem based on mode - switch (openmc::settings::run_mode) { - case openmc::RUN_MODE_FIXEDSOURCE: - case openmc::RUN_MODE_EIGENVALUE: + switch (settings::run_mode) { + case RUN_MODE_FIXEDSOURCE: + case RUN_MODE_EIGENVALUE: err = openmc_run(); break; - case openmc::RUN_MODE_PLOTTING: + case RUN_MODE_PLOTTING: err = openmc_plot_geometry(); break; - case openmc::RUN_MODE_PARTICLE: - if (openmc_master) err = openmc_particle_restart(); + case RUN_MODE_PARTICLE: + if (mpi::master) err = openmc_particle_restart(); break; - case openmc::RUN_MODE_VOLUME: + case RUN_MODE_VOLUME: err = openmc_calculate_volumes(); break; } - if (err) openmc::fatal_error(openmc_err_msg); + if (err) fatal_error(openmc_err_msg); // Finalize and free up memory err = openmc_finalize(); - if (err) openmc::fatal_error(openmc_err_msg); + if (err) fatal_error(openmc_err_msg); // If MPI is in use and enabled, terminate it #ifdef OPENMC_MPI diff --git a/src/output.cpp b/src/output.cpp index 79800e21a..13db31144 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -51,7 +51,7 @@ std::string time_stamp() << ":" << now->tm_min << ":" << now->tm_sec; return ts.str(); } - + //============================================================================== //=============================================================================== @@ -74,7 +74,7 @@ void print_plot() { if (PlotType::slice == pl.type_) { std::cout << "Plot Type: Slice" << "\n"; } else if (PlotType::voxel == pl.type_) { - std::cout << "Plot Type: Voxel" << "\n"; + std::cout << "Plot Type: Voxel" << "\n"; } // Plot parameters @@ -98,9 +98,9 @@ void print_plot() { if (PlotColorBy::cells == pl.color_by_) { std::cout << "Coloring: Cells" << "\n"; } else if (PlotColorBy::mats == pl.color_by_) { - std::cout << "Coloring: Materials" << "\n"; + std::cout << "Coloring: Materials" << "\n"; } - + if (PlotType::slice == pl.type_) { switch(pl.basis_) { case PlotBasis::xy: @@ -122,10 +122,10 @@ void print_plot() { } std::cout << "\n"; - + } } - + void print_overlap_check() { #ifdef OPENMC_MPI @@ -135,7 +135,7 @@ print_overlap_check() { mpi::intracomm); #endif - if (openmc_master) { + if (mpi::master) { header("cell overlap check summary", 1); std::cout << " Cell ID No. Overlap Checks\n"; diff --git a/src/plot.cpp b/src/plot.cpp index 9a8aba139..45529ba97 100644 --- a/src/plot.cpp +++ b/src/plot.cpp @@ -9,6 +9,7 @@ #include "openmc/geometry.h" #include "openmc/cell.h" #include "openmc/material.h" +#include "openmc/message_passing.h" #include "openmc/string_utils.h" #include "openmc/mesh.h" #include "openmc/output.h" @@ -243,7 +244,7 @@ Plot::set_bg_color(pugi::xml_node plot_node) if (check_for_node(plot_node, "background")) { std::vector bg_rgb = get_node_array(plot_node, "background"); if (PlotType::voxel == type_) { - if (openmc_master) { + if (mpi::master) { std::stringstream err_msg; err_msg << "Background color ignored in voxel plot " << id_; @@ -384,7 +385,7 @@ void Plot::set_user_colors(pugi::xml_node plot_node) { if (!plot_node.select_nodes("color").empty() && PlotType::voxel == type_) { - if (openmc_master) { + if (mpi::master) { std::stringstream err_msg; err_msg << "Color specifications ignored in voxel plot " << id_; @@ -552,7 +553,7 @@ Plot::set_mask(pugi::xml_node plot_node) if (!mask_nodes.empty()) { if (PlotType::voxel == type_) { - if (openmc_master) { + if (mpi::master) { std::stringstream wrn_msg; wrn_msg << "Mask ignored in voxel plot " << id_; warning(wrn_msg); diff --git a/src/settings.cpp b/src/settings.cpp index bf9ef82de..227ebca5c 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -17,6 +17,7 @@ #include "openmc/error.h" #include "openmc/file_utils.h" #include "openmc/mesh.h" +#include "openmc/message_passing.h" #include "openmc/output.h" #include "openmc/random_lcg.h" #include "openmc/simulation.h" @@ -231,7 +232,7 @@ void read_settings_xml() // To this point, we haven't displayed any output since we didn't know what // the verbosity is. Now that we checked for it, show the title if necessary - if (openmc_master) { + if (mpi::master) { if (verbosity >= 2) title(); } write_message("Reading settings XML file...", 5); @@ -398,7 +399,7 @@ void read_settings_xml() omp_set_num_threads(simulation::n_threads); } #else - if (openmc_master) warning("OpenMC was not compiled with OpenMP support; " + if (mpi::master) warning("OpenMC was not compiled with OpenMP support; " "ignoring number of threads."); #endif } diff --git a/src/state_point.cpp b/src/state_point.cpp index 5b4384f91..fdf700c44 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -113,7 +113,7 @@ write_source_bank(hid_t group_id, Bank* source_bank) #else - if (openmc_master) { + if (mpi::master) { // Create dataset big enough to hold all source sites hsize_t dims[] {static_cast(settings::n_particles)}; hid_t dspace = H5Screate_simple(1, dims, nullptr); From 3cfe71621bb0f6bbb6cd45b448c2370396db4070 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 8 Nov 2018 13:21:37 -0600 Subject: [PATCH 37/62] Put global variables in cell.h in model namespace --- include/openmc/capi.h | 1 - include/openmc/cell.h | 17 ++++-- src/cell.cpp | 88 ++++++++++++++++-------------- src/dagmc.cpp | 27 ++++----- src/geometry.cpp | 20 +++---- src/geometry_aux.cpp | 78 +++++++++++++------------- src/lattice.cpp | 16 +++--- src/output.cpp | 6 +- src/plot.cpp | 16 +++--- src/source.cpp | 2 +- src/summary.cpp | 10 ++-- src/tallies/filter_cell.cpp | 8 +-- src/tallies/filter_cellborn.cpp | 2 +- src/tallies/filter_cellfrom.cpp | 2 +- src/tallies/filter_distribcell.cpp | 14 ++--- src/tallies/filter_universe.cpp | 8 +-- 16 files changed, 162 insertions(+), 153 deletions(-) diff --git a/include/openmc/capi.h b/include/openmc/capi.h index fd664b2a9..91d038d46 100644 --- a/include/openmc/capi.h +++ b/include/openmc/capi.h @@ -135,7 +135,6 @@ extern "C" { // Global variables extern char openmc_err_msg[256]; - extern int32_t n_cells; extern int32_t n_lattices; extern int32_t n_materials; extern int n_nuclides; diff --git a/include/openmc/cell.h b/include/openmc/cell.h index 5a889023b..f2c8f0f71 100644 --- a/include/openmc/cell.h +++ b/include/openmc/cell.h @@ -39,16 +39,21 @@ constexpr int32_t OP_UNION {std::numeric_limits::max() - 4}; // Global variables //============================================================================== +class Cell; +class Universe; + +namespace model { + extern "C" int32_t n_cells; -class Cell; extern std::vector cells; extern std::unordered_map cell_map; -class Universe; extern std::vector universes; extern std::unordered_map universe_map; +} // namespace model + //============================================================================== //! A geometry primitive that fills all space and contains cells. //============================================================================== @@ -145,13 +150,13 @@ public: virtual ~Cell() {} }; - + class CSGCell : public Cell { public: CSGCell(); - + explicit CSGCell(pugi::xml_node cell_node); bool @@ -163,7 +168,7 @@ public: void to_hdf5(hid_t group_id) const; - + protected: bool contains_simple(Position r, Direction u, int32_t on_surface) const; bool contains_complex(Position r, Direction u, int32_t on_surface) const; @@ -183,6 +188,6 @@ public: }; #endif - + } // namespace openmc #endif // OPENMC_CELL_H diff --git a/src/cell.cpp b/src/cell.cpp index 65582d780..2e4c0144a 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -21,6 +21,8 @@ namespace openmc { // Global variables //============================================================================== +namespace model { + int32_t n_cells {0}; std::vector cells; @@ -29,6 +31,8 @@ std::unordered_map cell_map; std::vector universes; std::unordered_map universe_map; +} // namespace model + //============================================================================== //! Convert region specification string to integer tokens. //! @@ -197,7 +201,7 @@ Universe::to_hdf5(hid_t universes_group) const // Write the contained cells. if (cells_.size() > 0) { std::vector cell_ids; - for (auto i_cell : cells_) cell_ids.push_back(cells[i_cell]->id_); + for (auto i_cell : cells_) cell_ids.push_back(model::cells[i_cell]->id_); write_dataset(group, "cells", cell_ids); } @@ -209,7 +213,7 @@ Universe::to_hdf5(hid_t universes_group) const //============================================================================== CSGCell::CSGCell() {} // empty constructor - + CSGCell::CSGCell(pugi::xml_node cell_node) { if (check_for_node(cell_node, "id")) { @@ -446,7 +450,7 @@ CSGCell::to_hdf5(hid_t cell_group) const write_string(group, "name", name_, false); } - write_dataset(group, "universe", universes[universe_]->id_); + write_dataset(group, "universe", model::universes[universe_]->id_); // Write the region specification. if (!region_.empty()) { @@ -494,7 +498,7 @@ CSGCell::to_hdf5(hid_t cell_group) const } else if (type_ == FILL_UNIVERSE) { write_dataset(group, "fill_type", "universe"); - write_dataset(group, "fill", universes[fill_]->id_); + write_dataset(group, "fill", model::universes[fill_]->id_); if (translation_ != Position(0, 0, 0)) { write_dataset(group, "translation", translation_); } @@ -609,10 +613,10 @@ DAGCell::distance(Position r, Direction u, int32_t on_surface) const } else { // indicate that particle is lost surf_idx = -1; } - + return {dist, surf_idx}; } - + bool DAGCell::contains(Position r, Direction u, int32_t on_surface) const { moab::ErrorCode rval; @@ -622,7 +626,7 @@ bool DAGCell::contains(Position r, Direction u, int32_t on_surface) const double pnt[3] = {r.x, r.y, r.z}; double dir[3] = {u.x, u.y, u.z}; rval = dagmc_ptr_->point_in_volume(vol, pnt, result, dir); - MB_CHK_ERR_CONT(rval); + MB_CHK_ERR_CONT(rval); return result; } @@ -638,23 +642,23 @@ extern "C" void read_cells(pugi::xml_node* node) { // Count the number of cells. - for (pugi::xml_node cell_node: node->children("cell")) {n_cells++;} - if (n_cells == 0) { + for (pugi::xml_node cell_node: node->children("cell")) {model::n_cells++;} + if (model::n_cells == 0) { fatal_error("No cells found in geometry.xml!"); } // Loop over XML cell elements and populate the array. - cells.reserve(n_cells); + model::cells.reserve(model::n_cells); for (pugi::xml_node cell_node: node->children("cell")) { - cells.push_back(new CSGCell(cell_node)); + model::cells.push_back(new CSGCell(cell_node)); } // Fill the cell map. - for (int i = 0; i < cells.size(); i++) { - int32_t id = cells[i]->id_; - auto search = cell_map.find(id); - if (search == cell_map.end()) { - cell_map[id] = i; + for (int i = 0; i < model::cells.size(); i++) { + int32_t id = model::cells[i]->id_; + auto search = model::cell_map.find(id); + if (search == model::cell_map.end()) { + model::cell_map[id] = i; } else { std::stringstream err_msg; err_msg << "Two or more cells use the same unique ID: " << id; @@ -663,22 +667,22 @@ read_cells(pugi::xml_node* node) } // Populate the Universe vector and map. - for (int i = 0; i < cells.size(); i++) { - int32_t uid = cells[i]->universe_; - auto it = universe_map.find(uid); - if (it == universe_map.end()) { - universes.push_back(new Universe()); - universes.back()->id_ = uid; - universes.back()->cells_.push_back(i); - universe_map[uid] = universes.size() - 1; + for (int i = 0; i < model::cells.size(); i++) { + int32_t uid = model::cells[i]->universe_; + auto it = model::universe_map.find(uid); + if (it == model::universe_map.end()) { + model::universes.push_back(new Universe()); + model::universes.back()->id_ = uid; + model::universes.back()->cells_.push_back(i); + model::universe_map[uid] = model::universes.size() - 1; } else { - universes[it->second]->cells_.push_back(i); + model::universes[it->second]->cells_.push_back(i); } } - universes.shrink_to_fit(); + model::universes.shrink_to_fit(); // Allocate the cell overlap count if necessary. - if (settings::check_overlaps) overlap_check_count.resize(n_cells, 0); + if (settings::check_overlaps) overlap_check_count.resize(model::n_cells, 0); } //============================================================================== @@ -688,9 +692,9 @@ read_cells(pugi::xml_node* node) extern "C" int openmc_cell_get_fill(int32_t index, int* type, int32_t** indices, int32_t* n) { - if (index >= 1 && index <= cells.size()) { + if (index >= 1 && index <= model::cells.size()) { //TODO: off-by-one - Cell& c {*cells[index - 1]}; + Cell& c {*model::cells[index - 1]}; *type = c.type_; if (c.type_ == FILL_MATERIAL) { *indices = c.material_.data(); @@ -710,9 +714,9 @@ extern "C" int openmc_cell_set_fill(int32_t index, int type, int32_t n, const int32_t* indices) { - if (index >= 1 && index <= cells.size()) { + if (index >= 1 && index <= model::cells.size()) { //TODO: off-by-one - Cell& c {*cells[index - 1]}; + Cell& c {*model::cells[index - 1]}; if (type == FILL_MATERIAL) { c.type_ = FILL_MATERIAL; c.material_.clear(); @@ -745,9 +749,9 @@ openmc_cell_set_fill(int32_t index, int type, int32_t n, extern "C" int openmc_cell_set_temperature(int32_t index, double T, const int32_t* instance) { - if (index >= 1 && index <= cells.size()) { + if (index >= 1 && index <= model::cells.size()) { //TODO: off-by-one - Cell& c {*cells[index - 1]}; + Cell& c {*model::cells[index - 1]}; if (instance) { if (*instance >= 0 && *instance < c.sqrtkT_.size()) { @@ -775,7 +779,7 @@ openmc_cell_set_temperature(int32_t index, double T, const int32_t* instance) //============================================================================== extern "C" { - Cell* cell_pointer(int32_t cell_ind) {return cells[cell_ind];} + Cell* cell_pointer(int32_t cell_ind) {return model::cells[cell_ind];} int32_t cell_id(Cell* c) {return c->id_;} @@ -785,9 +789,9 @@ extern "C" { c->id_ = id; // Find the index of this cell and update the cell map. - for (int i = 0; i < cells.size(); i++) { - if (cells[i] == c) { - cell_map[id] = i; + for (int i = 0; i < model::cells.size(); i++) { + if (model::cells[i] == c) { + model::cell_map[id] = i; break; } } @@ -830,17 +834,17 @@ extern "C" { void extend_cells_c(int32_t n) { - cells.reserve(cells.size() + n); + model::cells.reserve(model::cells.size() + n); for (int32_t i = 0; i < n; i++) { - cells.push_back(new CSGCell()); + model::cells.push_back(new CSGCell()); } - n_cells = cells.size(); + model::n_cells = model::cells.size(); } - int32_t universe_id(int i_univ) {return universes[i_univ]->id_;} + int32_t universe_id(int i_univ) {return model::universes[i_univ]->id_;} void universes_to_hdf5(hid_t universes_group) - {for (Universe* u : universes) u->to_hdf5(universes_group);} + {for (Universe* u : model::universes) u->to_hdf5(universes_group);} } diff --git a/src/dagmc.cpp b/src/dagmc.cpp index 7c1127867..f11fbe203 100644 --- a/src/dagmc.cpp +++ b/src/dagmc.cpp @@ -1,5 +1,6 @@ - #include "openmc/dagmc.h" + +#include "openmc/cell.h" #include "openmc/error.h" #include "openmc/string_utils.h" #include "openmc/settings.h" @@ -38,12 +39,12 @@ void load_dagmc_geometry() MB_CHK_ERR_CONT(rval); // initialize cell objects - n_cells = DAG->num_entities(3); + model::n_cells = DAG->num_entities(3); // Allocate the cell overlap count if necessary. - if (settings::check_overlaps) overlap_check_count.resize(n_cells, 0); + if (settings::check_overlaps) overlap_check_count.resize(model::n_cells, 0); - for (int i = 0; i < n_cells; i++) { + for (int i = 0; i < model::n_cells; i++) { moab::EntityHandle vol_handle = DAG->entity_by_index(3, i+1); // set cell ids using global IDs @@ -53,18 +54,18 @@ void load_dagmc_geometry() c->universe_ = dagmc_univ_id; // set to zero for now c->fill_ = C_NONE; // no fill, single universe - cells.push_back(c); - cell_map[c->id_] = i; + model::cells.push_back(c); + model::cell_map[c->id_] = i; // Populate the Universe vector and dict - auto it = universe_map.find(dagmc_univ_id); - if (it == universe_map.end()) { - universes.push_back(new Universe()); - universes.back()-> id_ = dagmc_univ_id; - universes.back()->cells_.push_back(i); - universe_map[dagmc_univ_id] = universes.size() - 1; + auto it = model::universe_map.find(dagmc_univ_id); + if (it == model::universe_map.end()) { + model::universes.push_back(new Universe()); + model::universes.back()-> id_ = dagmc_univ_id; + model::universes.back()->cells_.push_back(i); + model::universe_map[dagmc_univ_id] = model::universes.size() - 1; } else { - universes[it->second]->cells_.push_back(i); + model::universes[it->second]->cells_.push_back(i); } if (DAG->is_implicit_complement(vol_handle)) { diff --git a/src/geometry.cpp b/src/geometry.cpp index cff5657a5..e4591cf9e 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -24,17 +24,17 @@ check_cell_overlap(Particle* p) { // Loop through each coordinate level for (int j = 0; j < n_coord; j++) { - Universe& univ = *universes[p->coord[j].universe]; + Universe& univ = *model::universes[p->coord[j].universe]; int n = univ.cells_.size(); // Loop through each cell on this level for (auto index_cell : univ.cells_) { - Cell& c = *cells[index_cell]; + Cell& c = *model::cells[index_cell]; if (c.contains(p->coord[j].xyz, p->coord[j].uvw, p->surface)) { if (index_cell != p->coord[j].cell) { std::stringstream err_msg; err_msg << "Overlapping cells detected: " << c.id_ << ", " - << cells[p->coord[j].cell]->id_ << " on universe " + << model::cells[p->coord[j].cell]->id_ << " on universe " << univ.id_; fatal_error(err_msg); } @@ -71,7 +71,7 @@ find_cell(Particle* p, int search_surf) { search_cells = &surfaces[-search_surf-1]->neighbor_neg_; } else { // No surface was indicated, search all cells in the universe. - search_cells = &universes[i_universe]->cells_; + search_cells = &model::universes[i_universe]->cells_; } // Find which cell of this universe the particle is in. @@ -81,17 +81,17 @@ find_cell(Particle* p, int search_surf) { i_cell = (*search_cells)[i]; // Make sure the search cell is in the same universe. - if (cells[i_cell]->universe_ != i_universe) continue; + if (model::cells[i_cell]->universe_ != i_universe) continue; Position r {p->coord[p->n_coord-1].xyz}; Direction u {p->coord[p->n_coord-1].uvw}; int32_t surf = p->surface; - if (cells[i_cell]->contains(r, u, surf)) { + if (model::cells[i_cell]->contains(r, u, surf)) { p->coord[p->n_coord-1].cell = i_cell; if (settings::verbosity >= 10 || simulation::trace) { std::stringstream msg; - msg << " Entering cell " << cells[i_cell]->id_; + msg << " Entering cell " << model::cells[i_cell]->id_; write_message(msg, 1); } found = true; @@ -100,7 +100,7 @@ find_cell(Particle* p, int search_surf) { } if (found) { - Cell& c {*cells[i_cell]}; + Cell& c {*model::cells[i_cell]}; if (c.type_ == FILL_MATERIAL) { //======================================================================= //! Found a material cell which means this is the lowest coord level. @@ -109,7 +109,7 @@ find_cell(Particle* p, int search_surf) { if (c.material_.size() > 1 || c.sqrtkT_.size() > 1) { int offset = 0; for (int i = 0; i < p->n_coord; i++) { - Cell& c_i {*cells[p->coord[i].cell]}; + Cell& c_i {*model::cells[p->coord[i].cell]}; if (c_i.type_ == FILL_UNIVERSE) { offset += c_i.offset_[c.distribcell_index_]; } else if (c_i.type_ == FILL_LATTICE) { @@ -326,7 +326,7 @@ distance_to_boundary(Particle* p, double* dist, int* surface_crossed, for (int i = 0; i < p->n_coord; i++) { Position r {p->coord[i].xyz}; Direction u {p->coord[i].uvw}; - Cell& c {*cells[p->coord[i].cell]}; + Cell& c {*model::cells[p->coord[i].cell]}; // Find the oncoming surface in this cell and the distance to it. auto surface_distance = c.distance(r, u, p->surface); diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index e3934480b..5662bd8de 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -24,12 +24,12 @@ void adjust_indices() { // Adjust material/fill idices. - for (Cell* c : cells) { + for (Cell* c : model::cells) { if (c->fill_ != C_NONE) { int32_t id = c->fill_; - auto search_univ = universe_map.find(id); + auto search_univ = model::universe_map.find(id); auto search_lat = lattice_map.find(id); - if (search_univ != universe_map.end()) { + if (search_univ != model::universe_map.end()) { c->type_ = FILL_UNIVERSE; c->fill_ = search_univ->second; } else if (search_lat != lattice_map.end()) { @@ -61,9 +61,9 @@ adjust_indices() } // Change cell.universe values from IDs to indices. - for (Cell* c : cells) { - auto search = universe_map.find(c->universe_); - if (search != universe_map.end()) { + for (Cell* c : model::cells) { + auto search = model::universe_map.find(c->universe_); + if (search != model::universe_map.end()) { c->universe_ = search->second; } else { std::stringstream err_msg; @@ -84,7 +84,7 @@ adjust_indices() void assign_temperatures() { - for (Cell* c : cells) { + for (Cell* c : model::cells) { // Ignore non-material cells and cells with defined temperature. if (c->material_.size() == 0) continue; if (c->sqrtkT_.size() > 0) continue; @@ -117,7 +117,7 @@ find_root_universe() { // Find all the universes listed as a cell fill. std::unordered_set fill_univ_ids; - for (Cell* c : cells) { + for (Cell* c : model::cells) { fill_univ_ids.insert(c->fill_); } @@ -134,8 +134,8 @@ find_root_universe() // Figure out which universe is not in the set. This is the root universe. bool root_found {false}; int32_t root_univ; - for (int32_t i = 0; i < universes.size(); i++) { - auto search = fill_univ_ids.find(universes[i]->id_); + for (int32_t i = 0; i < model::universes.size(); i++) { + auto search = fill_univ_ids.find(model::universes[i]->id_); if (search == fill_univ_ids.end()) { if (root_found) { fatal_error("Two or more universes are not used as fill universes, so " @@ -160,8 +160,8 @@ neighbor_lists() { write_message("Building neighboring cells lists for each surface...", 6); - for (int i = 0; i < cells.size(); i++) { - for (auto token : cells[i]->region_) { + for (int i = 0; i < model::cells.size(); i++) { + for (auto token : model::cells[i]->region_) { // Skip operator tokens. if (std::abs(token) >= OP_UNION) continue; @@ -196,8 +196,8 @@ prepare_distribcell() // Find all cells with distributed materials or temperatures. Make sure that // the number of materials/temperatures matches the number of cell instances. - for (int i = 0; i < cells.size(); i++) { - Cell& c {*cells[i]}; + for (int i = 0; i < model::cells.size(); i++) { + Cell& c {*model::cells[i]}; if (c.material_.size() > 1) { if (c.material_.size() != c.n_instances_) { @@ -228,10 +228,10 @@ prepare_distribcell() // unique distribcell array index. int distribcell_index = 0; std::vector target_univ_ids; - for (Universe* u : universes) { + for (Universe* u : model::universes) { for (auto cell_indx : u->cells_) { if (distribcells.find(cell_indx) != distribcells.end()) { - cells[cell_indx]->distribcell_index_ = distribcell_index; + model::cells[cell_indx]->distribcell_index_ = distribcell_index; target_univ_ids.push_back(u->id_); ++distribcell_index; } @@ -240,7 +240,7 @@ prepare_distribcell() // Allocate the cell and lattice offset tables. int n_maps = target_univ_ids.size(); - for (Cell* c : cells) { + for (Cell* c : model::cells) { if (c->type_ != FILL_MATERIAL) { c->offset_.resize(n_maps, C_NONE); } @@ -252,10 +252,10 @@ prepare_distribcell() // Fill the cell and lattice offset tables. for (int map = 0; map < target_univ_ids.size(); map++) { auto target_univ_id = target_univ_ids[map]; - for (Universe* univ : universes) { + for (Universe* univ : model::universes) { int32_t offset {0}; // TODO: is this a bug? It matches F90 implementation. for (int32_t cell_indx : univ->cells_) { - Cell& c = *cells[cell_indx]; + Cell& c = *model::cells[cell_indx]; if (c.type_ == FILL_UNIVERSE) { c.offset_[map] = offset; @@ -276,8 +276,8 @@ prepare_distribcell() void count_cell_instances(int32_t univ_indx) { - for (int32_t cell_indx : universes[univ_indx]->cells_) { - Cell& c = *cells[cell_indx]; + for (int32_t cell_indx : model::universes[univ_indx]->cells_) { + Cell& c = *model::cells[cell_indx]; ++c.n_instances_; if (c.type_ == FILL_UNIVERSE) { @@ -300,13 +300,13 @@ int count_universe_instances(int32_t search_univ, int32_t target_univ_id) { // If this is the target, it can't contain itself. - if (universes[search_univ]->id_ == target_univ_id) { + if (model::universes[search_univ]->id_ == target_univ_id) { return 1; } int count {0}; - for (int32_t cell_indx : universes[search_univ]->cells_) { - Cell& c = *cells[cell_indx]; + for (int32_t cell_indx : model::universes[search_univ]->cells_) { + Cell& c = *model::cells[cell_indx]; if (c.type_ == FILL_UNIVERSE) { int32_t next_univ = c.fill_; @@ -338,7 +338,7 @@ distribcell_path_inner(int32_t target_cell, int32_t map, int32_t target_offset, // write to the path and return. for (int32_t cell_indx : search_univ.cells_) { if ((cell_indx == target_cell) && (offset == target_offset)) { - Cell& c = *cells[cell_indx]; + Cell& c = *model::cells[cell_indx]; path << "c" << c.id_; return path.str(); } @@ -350,7 +350,7 @@ distribcell_path_inner(int32_t target_cell, int32_t map, int32_t target_offset, std::vector::const_reverse_iterator cell_it {search_univ.cells_.crbegin()}; for (; cell_it != search_univ.cells_.crend(); ++cell_it) { - Cell& c = *cells[*cell_it]; + Cell& c = *model::cells[*cell_it]; // Material cells don't contain other cells so ignore them. if (c.type_ != FILL_MATERIAL) { @@ -370,14 +370,14 @@ distribcell_path_inner(int32_t target_cell, int32_t map, int32_t target_offset, } // Add the cell to the path string. - Cell& c = *cells[*cell_it]; + Cell& c = *model::cells[*cell_it]; path << "c" << c.id_ << "->"; if (c.type_ == FILL_UNIVERSE) { // Recurse into the fill cell. offset += c.offset_[map]; path << distribcell_path_inner(target_cell, map, target_offset, - *universes[c.fill_], offset); + *model::universes[c.fill_], offset); return path.str(); } else { // Recurse into the lattice cell. @@ -390,7 +390,7 @@ distribcell_path_inner(int32_t target_cell, int32_t map, int32_t target_offset, offset = temp_offset; path << "(" << lat.index_to_string(it.indx_) << ")->"; path << distribcell_path_inner(target_cell, map, target_offset, - *universes[*it], offset); + *model::universes[*it], offset); return path.str(); } } @@ -401,7 +401,7 @@ distribcell_path_inner(int32_t target_cell, int32_t map, int32_t target_offset, std::string distribcell_path(int32_t target_cell, int32_t map, int32_t target_offset) { - auto& root_univ = *universes[openmc_root_universe]; + auto& root_univ = *model::universes[openmc_root_universe]; return distribcell_path_inner(target_cell, map, target_offset, root_univ, 0); } @@ -412,8 +412,8 @@ maximum_levels(int32_t univ) { int levels_below {0}; - for (int32_t cell_indx : universes[univ]->cells_) { - Cell& c = *cells[cell_indx]; + for (int32_t cell_indx : model::universes[univ]->cells_) { + Cell& c = *model::cells[cell_indx]; if (c.type_ == FILL_UNIVERSE) { int32_t next_univ = c.fill_; levels_below = std::max(levels_below, maximum_levels(next_univ)); @@ -435,14 +435,14 @@ maximum_levels(int32_t univ) void free_memory_geometry_c() { - for (Cell* c : cells) {delete c;} - cells.clear(); - cell_map.clear(); - n_cells = 0; + for (Cell* c : model::cells) {delete c;} + model::cells.clear(); + model::cell_map.clear(); + model::n_cells = 0; - for (Universe* u : universes) {delete u;} - universes.clear(); - universe_map.clear(); + for (Universe* u : model::universes) {delete u;} + model::universes.clear(); + model::universe_map.clear(); for (Lattice* lat : lattices) {delete lat;} lattices.clear(); diff --git a/src/lattice.cpp b/src/lattice.cpp index 14b679903..1df21774f 100644 --- a/src/lattice.cpp +++ b/src/lattice.cpp @@ -65,8 +65,8 @@ Lattice::adjust_indices() // Adjust the indices for the universes array. for (LatticeIter it = begin(); it != end(); ++it) { int uid = *it; - auto search = universe_map.find(uid); - if (search != universe_map.end()) { + auto search = model::universe_map.find(uid); + if (search != model::universe_map.end()) { *it = search->second; } else { std::stringstream err_msg; @@ -78,8 +78,8 @@ Lattice::adjust_indices() // Adjust the index for the outer universe. if (outer_ != NO_OUTER_UNIVERSE) { - auto search = universe_map.find(outer_); - if (search != universe_map.end()) { + auto search = model::universe_map.find(outer_); + if (search != model::universe_map.end()) { outer_ = search->second; } else { std::stringstream err_msg; @@ -118,7 +118,7 @@ Lattice::to_hdf5(hid_t lattices_group) const } if (outer_ != NO_OUTER_UNIVERSE) { - int32_t outer_id = universes[outer_]->id_; + int32_t outer_id = model::universes[outer_]->id_; write_dataset(lat_group, "outer", outer_id); } else { write_dataset(lat_group, "outer", outer_); @@ -370,7 +370,7 @@ RectLattice::to_hdf5_inner(hid_t lat_group) const for (int j = 0; j < nx; j++) { int indx1 = nx*ny*m + nx*k + j; int indx2 = nx*ny*m + nx*(ny-k-1) + j; - out[indx2] = universes[universes_[indx1]]->id_; + out[indx2] = model::universes[universes_[indx1]]->id_; } } } @@ -387,7 +387,7 @@ RectLattice::to_hdf5_inner(hid_t lat_group) const for (int j = 0; j < nx; j++) { int indx1 = nx*k + j; int indx2 = nx*(ny-k-1) + j; - out[indx2] = universes[universes_[indx1]]->id_; + out[indx2] = model::universes[universes_[indx1]]->id_; } } @@ -847,7 +847,7 @@ HexLattice::to_hdf5_inner(hid_t lat_group) const // This array position is never used; put a -1 to indicate this. out[indx] = -1; } else { - out[indx] = universes[universes_[indx]]->id_; + out[indx] = model::universes[universes_[indx]]->id_; } } } diff --git a/src/output.cpp b/src/output.cpp index 13db31144..79c3f7f0b 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -140,11 +140,11 @@ print_overlap_check() { std::cout << " Cell ID No. Overlap Checks\n"; std::vector sparse_cell_ids; - for (int i = 0; i < n_cells; i++) { - std::cout << " " << std::setw(8) << cells[i]->id_ << std::setw(17) + for (int i = 0; i < model::n_cells; i++) { + std::cout << " " << std::setw(8) << model::cells[i]->id_ << std::setw(17) << overlap_check_count[i] << "\n"; if (overlap_check_count[i] < 10) { - sparse_cell_ids.push_back(cells[i]->id_); + sparse_cell_ids.push_back(model::cells[i]->id_); } } diff --git a/src/plot.cpp b/src/plot.cpp index 45529ba97..403b27884 100644 --- a/src/plot.cpp +++ b/src/plot.cpp @@ -362,8 +362,8 @@ Plot::set_default_colors(pugi::xml_node plot_node) } if ("cell" == pl_color_by) { color_by_ = PlotColorBy::cells; - colors_.resize(n_cells); - for (int i = 0; i < n_cells; i++) { + colors_.resize(model::n_cells); + for (int i = 0; i < model::n_cells; i++) { colors_[i] = random_color(); } @@ -413,8 +413,8 @@ Plot::set_user_colors(pugi::xml_node plot_node) } // Add RGB if (PlotColorBy::cells == color_by_) { - if (cell_map.find(col_id) != cell_map.end()) { - col_id = cell_map[col_id]; + if (model::cell_map.find(col_id) != model::cell_map.end()) { + col_id = model::cell_map[col_id]; colors_[col_id] = user_rgb; } else { std::stringstream err_msg; @@ -576,8 +576,8 @@ Plot::set_mask(pugi::xml_node plot_node) // in the cell and material arrays for (auto& col_id : iarray) { if (PlotColorBy::cells == color_by_) { - if (cell_map.find(col_id) != cell_map.end()) { - col_id = cell_map[col_id]; + if (model::cell_map.find(col_id) != model::cell_map.end()) { + col_id = model::cell_map[col_id]; } else { std::stringstream err_msg; @@ -661,7 +661,7 @@ void position_rgb(Particle p, Plot pl, RGBColor& rgb, int& id) } else { if (PlotColorBy::mats == pl.color_by_) { // Assign color based on material - Cell* c = cells[p.coord[j].cell]; + Cell* c = model::cells[p.coord[j].cell]; if (c->type_ == FILL_UNIVERSE) { // If we stopped on a middle universe level, treat as if not found rgb = pl.not_found_; @@ -677,7 +677,7 @@ void position_rgb(Particle p, Plot pl, RGBColor& rgb, int& id) } else if (PlotColorBy::cells == pl.color_by_) { // Assign color based on cell rgb = pl.colors_[p.coord[j].cell]; - id = cells[p.coord[j].cell]->id_; + id = model::cells[p.coord[j].cell]->id_; } } // endif found_cell } diff --git a/src/source.cpp b/src/source.cpp index 315ff2cdd..782fb97a2 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -167,7 +167,7 @@ Bank SourceDistribution::sample() const if (space_box) { if (space_box->only_fissionable()) { // Determine material - auto c = cells[cell_index - 1]; + auto c = model::cells[cell_index - 1]; int32_t mat_index = c->material_[instance]; auto m = materials[mat_index]; diff --git a/src/summary.cpp b/src/summary.cpp index d2f083657..8431e2a5f 100644 --- a/src/summary.cpp +++ b/src/summary.cpp @@ -10,7 +10,7 @@ extern "C" void write_geometry(hid_t file_id) { auto geom_group = create_group(file_id, "geometry"); - + #ifdef DAGMC if (settings::dagmc) { write_attribute(geom_group, "dagmc", 1); @@ -18,13 +18,13 @@ write_geometry(hid_t file_id) { } #endif - write_attribute(geom_group, "n_cells", cells.size()); + write_attribute(geom_group, "n_cells", model::cells.size()); write_attribute(geom_group, "n_surfaces", surfaces.size()); - write_attribute(geom_group, "n_universes", universes.size()); + write_attribute(geom_group, "n_universes", model::universes.size()); write_attribute(geom_group, "n_lattices", lattices.size()); auto cells_group = create_group(geom_group, "cells"); - for (Cell* c : cells) c->to_hdf5(cells_group); + for (Cell* c : model::cells) c->to_hdf5(cells_group); close_group(cells_group); auto surfaces_group = create_group(geom_group, "surfaces"); @@ -32,7 +32,7 @@ write_geometry(hid_t file_id) { close_group(surfaces_group); auto universes_group = create_group(geom_group, "universes"); - for (Universe* u : universes) u->to_hdf5(universes_group); + for (Universe* u : model::universes) u->to_hdf5(universes_group); close_group(universes_group); auto lattices_group = create_group(geom_group, "lattices"); diff --git a/src/tallies/filter_cell.cpp b/src/tallies/filter_cell.cpp index 9e0a6721e..12dc38df1 100644 --- a/src/tallies/filter_cell.cpp +++ b/src/tallies/filter_cell.cpp @@ -21,8 +21,8 @@ CellFilter::initialize() { // Convert cell IDs to indices of the global array. for (auto& c : cells_) { - auto search = cell_map.find(c); - if (search != cell_map.end()) { + auto search = model::cell_map.find(c); + if (search != model::cell_map.end()) { c = search->second; } else { std::stringstream err_msg; @@ -56,7 +56,7 @@ CellFilter::to_statepoint(hid_t filter_group) const { Filter::to_statepoint(filter_group); std::vector cell_ids; - for (auto c : cells_) cell_ids.push_back(cells[c]->id_); + for (auto c : cells_) cell_ids.push_back(model::cells[c]->id_); write_dataset(filter_group, "bins", cell_ids); } @@ -64,7 +64,7 @@ std::string CellFilter::text_label(int bin) const { //TODO: off-by-one - return "Cell " + std::to_string(cells[cells_[bin-1]]->id_); + return "Cell " + std::to_string(model::cells[cells_[bin-1]]->id_); } //============================================================================== diff --git a/src/tallies/filter_cellborn.cpp b/src/tallies/filter_cellborn.cpp index 4f86ad34c..b173b2e39 100644 --- a/src/tallies/filter_cellborn.cpp +++ b/src/tallies/filter_cellborn.cpp @@ -20,7 +20,7 @@ std::string CellbornFilter::text_label(int bin) const { //TODO: off-by-one - return "Birth Cell " + std::to_string(cells[cells_[bin-1]]->id_); + return "Birth Cell " + std::to_string(model::cells[cells_[bin-1]]->id_); } } // namespace openmc diff --git a/src/tallies/filter_cellfrom.cpp b/src/tallies/filter_cellfrom.cpp index b4b1a57ef..1262ebecd 100644 --- a/src/tallies/filter_cellfrom.cpp +++ b/src/tallies/filter_cellfrom.cpp @@ -22,7 +22,7 @@ std::string CellFromFilter::text_label(int bin) const { //TODO: off-by-one - return "Cell from " + std::to_string(cells[cells_[bin-1]]->id_); + return "Cell from " + std::to_string(model::cells[cells_[bin-1]]->id_); } } // namespace openmc diff --git a/src/tallies/filter_distribcell.cpp b/src/tallies/filter_distribcell.cpp index 39459672f..8af01b906 100644 --- a/src/tallies/filter_distribcell.cpp +++ b/src/tallies/filter_distribcell.cpp @@ -22,10 +22,10 @@ void DistribcellFilter::initialize() { // Convert the cell ID to an index of the global array. - auto search = cell_map.find(cell_); - if (search != cell_map.end()) { + auto search = model::cell_map.find(cell_); + if (search != model::cell_map.end()) { cell_ = search->second; - n_bins_ = cells[cell_]->n_instances_; + n_bins_ = model::cells[cell_]->n_instances_; } else { std::stringstream err_msg; err_msg << "Could not find cell " << cell_ @@ -39,9 +39,9 @@ DistribcellFilter::get_all_bins(const Particle* p, int estimator, FilterMatch& match) const { int offset = 0; - auto distribcell_index = cells[cell_]->distribcell_index_; + auto distribcell_index = model::cells[cell_]->distribcell_index_; for (int i = 0; i < p->n_coord; i++) { - auto& c {*cells[p->coord[i].cell]}; + auto& c {*model::cells[p->coord[i].cell]}; if (c.type_ == FILL_UNIVERSE) { offset += c.offset_[distribcell_index]; } else if (c.type_ == FILL_LATTICE) { @@ -66,13 +66,13 @@ void DistribcellFilter::to_statepoint(hid_t filter_group) const { Filter::to_statepoint(filter_group); - write_dataset(filter_group, "bins", cells[cell_]->id_); + write_dataset(filter_group, "bins", model::cells[cell_]->id_); } std::string DistribcellFilter::text_label(int bin) const { - auto map = cells[cell_]->distribcell_index_; + auto map = model::cells[cell_]->distribcell_index_; //TODO: off-by-one auto path = distribcell_path(cell_, map, bin-1); return "Distributed Cell " + path; diff --git a/src/tallies/filter_universe.cpp b/src/tallies/filter_universe.cpp index 05d8c3e0d..ecd12b237 100644 --- a/src/tallies/filter_universe.cpp +++ b/src/tallies/filter_universe.cpp @@ -20,8 +20,8 @@ UniverseFilter::initialize() { // Convert universe IDs to indices of the global array. for (auto& u : universes_) { - auto search = universe_map.find(u); - if (search != universe_map.end()) { + auto search = model::universe_map.find(u); + if (search != model::universe_map.end()) { u = search->second; } else { std::stringstream err_msg; @@ -56,7 +56,7 @@ UniverseFilter::to_statepoint(hid_t filter_group) const { Filter::to_statepoint(filter_group); std::vector universe_ids; - for (auto u : universes_) universe_ids.push_back(universes[u]->id_); + for (auto u : universes_) universe_ids.push_back(model::universes[u]->id_); write_dataset(filter_group, "bins", universe_ids); } @@ -64,7 +64,7 @@ std::string UniverseFilter::text_label(int bin) const { //TODO: off-by-one - return "Universe " + std::to_string(universes[universes_[bin-1]]->id_); + return "Universe " + std::to_string(model::universes[universes_[bin-1]]->id_); } } // namespace openmc From 6436cab30206e41bed29e44e88a5743a68a3fadc Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 8 Nov 2018 13:41:23 -0600 Subject: [PATCH 38/62] More namespacing for global variables --- include/openmc/capi.h | 2 -- include/openmc/dagmc.h | 14 ++++++++++- include/openmc/geometry.h | 6 ++++- include/openmc/lattice.h | 6 ++++- src/cell.cpp | 4 +-- src/dagmc.cpp | 40 +++++++++++++++--------------- src/finalize.cpp | 2 +- src/geometry.cpp | 27 ++++++++++++++------ src/geometry_aux.cpp | 32 ++++++++++++------------ src/geometry_header.F90 | 2 +- src/lattice.cpp | 21 +++++++++------- src/output.cpp | 10 ++++---- src/plot.cpp | 4 +-- src/summary.cpp | 4 +-- src/tallies/filter_distribcell.cpp | 2 +- 15 files changed, 105 insertions(+), 71 deletions(-) diff --git a/include/openmc/capi.h b/include/openmc/capi.h index 91d038d46..a04f1a622 100644 --- a/include/openmc/capi.h +++ b/include/openmc/capi.h @@ -135,14 +135,12 @@ extern "C" { // Global variables extern char openmc_err_msg[256]; - extern int32_t n_lattices; extern int32_t n_materials; extern int n_nuclides; extern int32_t n_plots; extern int32_t n_realizations; extern int32_t n_sab_tables; extern int32_t n_sources; - extern int32_t n_surfaces; extern int32_t n_tallies; extern int32_t n_universes; diff --git a/include/openmc/dagmc.h b/include/openmc/dagmc.h index afbd9cbc6..51d97d737 100644 --- a/include/openmc/dagmc.h +++ b/include/openmc/dagmc.h @@ -10,12 +10,24 @@ namespace openmc { +//============================================================================== +// Global variables +//============================================================================== + +namespace model { + extern moab::DagMC* DAG; +} // namespace model + +//============================================================================== +// Non-member functions +//============================================================================== + extern "C" void load_dagmc_geometry(); extern "C" void free_memory_dagmc(); -} +} // namespace openmc #endif // DAGMC diff --git a/include/openmc/geometry.h b/include/openmc/geometry.h index f045209ee..2f0853e0c 100644 --- a/include/openmc/geometry.h +++ b/include/openmc/geometry.h @@ -13,10 +13,14 @@ namespace openmc { // Global variables //============================================================================== -extern "C" int openmc_root_universe; +namespace model { + +extern "C" int root_universe; extern std::vector overlap_check_count; +} // namespace model + //============================================================================== //! Check for overlapping cells at a particle's position. //============================================================================== diff --git a/include/openmc/lattice.h b/include/openmc/lattice.h index cacb87abe..5a5eff0b4 100644 --- a/include/openmc/lattice.h +++ b/include/openmc/lattice.h @@ -31,10 +31,14 @@ enum class LatticeType { //============================================================================== class Lattice; -extern std::vector lattices; +namespace model { + +extern std::vector lattices; extern std::unordered_map lattice_map; +} // namespace model + //============================================================================== //! \class Lattice //! \brief Abstract type for ordered array of universes. diff --git a/src/cell.cpp b/src/cell.cpp index 2e4c0144a..8c5aaf29c 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -509,7 +509,7 @@ CSGCell::to_hdf5(hid_t cell_group) const } else if (type_ == FILL_LATTICE) { write_dataset(group, "fill_type", "lattice"); - write_dataset(group, "lattice", lattices[fill_]->id_); + write_dataset(group, "lattice", model::lattices[fill_]->id_); } close_group(group); @@ -682,7 +682,7 @@ read_cells(pugi::xml_node* node) model::universes.shrink_to_fit(); // Allocate the cell overlap count if necessary. - if (settings::check_overlaps) overlap_check_count.resize(model::n_cells, 0); + if (settings::check_overlaps) model::overlap_check_count.resize(model::n_cells, 0); } //============================================================================== diff --git a/src/dagmc.cpp b/src/dagmc.cpp index f11fbe203..e6f086605 100644 --- a/src/dagmc.cpp +++ b/src/dagmc.cpp @@ -18,16 +18,16 @@ moab::DagMC* DAG; void load_dagmc_geometry() { - if (!DAG) { - DAG = new moab::DagMC(); + if (!model::DAG) { + model::DAG = new moab::DagMC(); } int32_t dagmc_univ_id = 0; // universe is always 0 for DAGMC - moab::ErrorCode rval = DAG->load_file("dagmc.h5m"); + moab::ErrorCode rval = model::DAG->load_file("dagmc.h5m"); MB_CHK_ERR_CONT(rval); - rval = DAG->init_OBBTree(); + rval = model::DAG->init_OBBTree(); MB_CHK_ERR_CONT(rval); std::vector prop_keywords; @@ -35,22 +35,22 @@ void load_dagmc_geometry() prop_keywords.push_back("boundary"); std::map ph; - DAG->parse_properties(prop_keywords, ph, ":"); + model::DAG->parse_properties(prop_keywords, ph, ":"); MB_CHK_ERR_CONT(rval); // initialize cell objects - model::n_cells = DAG->num_entities(3); + model::n_cells = model::DAG->num_entities(3); // Allocate the cell overlap count if necessary. - if (settings::check_overlaps) overlap_check_count.resize(model::n_cells, 0); + if (settings::check_overlaps) model::overlap_check_count.resize(model::n_cells, 0); for (int i = 0; i < model::n_cells; i++) { - moab::EntityHandle vol_handle = DAG->entity_by_index(3, i+1); + moab::EntityHandle vol_handle = model::DAG->entity_by_index(3, i+1); // set cell ids using global IDs DAGCell* c = new DAGCell(); - c->id_ = DAG->id_by_index(3, i+1); - c->dagmc_ptr_ = DAG; + c->id_ = model::DAG->id_by_index(3, i+1); + c->dagmc_ptr_ = model::DAG; c->universe_ = dagmc_univ_id; // set to zero for now c->fill_ = C_NONE; // no fill, single universe @@ -68,15 +68,15 @@ void load_dagmc_geometry() model::universes[it->second]->cells_.push_back(i); } - if (DAG->is_implicit_complement(vol_handle)) { + if (model::DAG->is_implicit_complement(vol_handle)) { // assuming implicit complement is void for now c->material_.push_back(MATERIAL_VOID); continue; } - if (DAG->has_prop(vol_handle, "mat")){ + if (model::DAG->has_prop(vol_handle, "mat")){ std::string mat_value; - rval = DAG->prop_value(vol_handle, "mat", mat_value); + rval = model::DAG->prop_value(vol_handle, "mat", mat_value); MB_CHK_ERR_CONT(rval); to_lower(mat_value); @@ -93,20 +93,20 @@ void load_dagmc_geometry() } // initialize surface objects - n_surfaces = DAG->num_entities(2); + n_surfaces = model::DAG->num_entities(2); surfaces.resize(n_surfaces); for (int i = 0; i < n_surfaces; i++) { - moab::EntityHandle surf_handle = DAG->entity_by_index(2, i+1); + moab::EntityHandle surf_handle = model::DAG->entity_by_index(2, i+1); // set cell ids using global IDs DAGSurface* s = new DAGSurface(); - s->id_ = DAG->id_by_index(2, i+1); - s->dagmc_ptr_ = DAG; + s->id_ = model::DAG->id_by_index(2, i+1); + s->dagmc_ptr_ = model::DAG; - if (DAG->has_prop(surf_handle, "boundary")) { + if (model::DAG->has_prop(surf_handle, "boundary")) { std::string bc_value; - rval = DAG->prop_value(surf_handle, "boundary", bc_value); + rval = model::DAG->prop_value(surf_handle, "boundary", bc_value); MB_CHK_ERR_CONT(rval); to_lower(bc_value); @@ -138,7 +138,7 @@ void load_dagmc_geometry() void free_memory_dagmc() { - delete DAG; + delete model::DAG; } } diff --git a/src/finalize.cpp b/src/finalize.cpp index b9d17eac3..7439e7bdb 100644 --- a/src/finalize.cpp +++ b/src/finalize.cpp @@ -78,7 +78,7 @@ int openmc_finalize() energy_max = {INFTY, INFTY}; energy_min = {0.0, 0.0}; n_tallies = 0; - openmc_root_universe = -1; + model::root_universe = -1; openmc_set_seed(DEFAULT_SEED); // Deallocate arrays diff --git a/src/geometry.cpp b/src/geometry.cpp index e4591cf9e..87c61ebfa 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -14,8 +14,21 @@ namespace openmc { +//============================================================================== +// Global variables +//============================================================================== + + +namespace model { + +int root_universe {-1}; + std::vector overlap_check_count; +} // namespace model + +//============================================================================== +// Non-member functions //============================================================================== extern "C" bool @@ -38,7 +51,7 @@ check_cell_overlap(Particle* p) { << univ.id_; fatal_error(err_msg); } - ++overlap_check_count[index_cell]; + ++model::overlap_check_count[index_cell]; } } } @@ -57,8 +70,8 @@ find_cell(Particle* p, int search_surf) { // Determine universe (if not yet set, use root universe) int i_universe = p->coord[p->n_coord-1].universe; if (i_universe == C_NONE) { - p->coord[p->n_coord-1].universe = openmc_root_universe; - i_universe = openmc_root_universe; + p->coord[p->n_coord-1].universe = model::root_universe; + i_universe = model::root_universe; } // If a surface was indicated, only search cells from the neighbor list of @@ -113,7 +126,7 @@ find_cell(Particle* p, int search_surf) { if (c_i.type_ == FILL_UNIVERSE) { offset += c_i.offset_[c.distribcell_index_]; } else if (c_i.type_ == FILL_LATTICE) { - Lattice& lat {*lattices[p->coord[i+1].lattice-1]}; + Lattice& lat {*model::lattices[p->coord[i+1].lattice-1]}; int i_xyz[3] {p->coord[i+1].lattice_x, p->coord[i+1].lattice_y, p->coord[i+1].lattice_z}; @@ -198,7 +211,7 @@ find_cell(Particle* p, int search_surf) { //======================================================================== //! Found a lower lattice, update this coord level then search the next. - Lattice& lat {*lattices[c.fill_]}; + Lattice& lat {*model::lattices[c.fill_]}; // Determine lattice indices. Position r {p->coord[p->n_coord-1].xyz}; @@ -251,7 +264,7 @@ find_cell(Particle* p, int search_surf) { extern "C" void cross_lattice(Particle* p, int lattice_translation[3]) { - Lattice& lat {*lattices[p->coord[p->n_coord-1].lattice-1]}; + Lattice& lat {*model::lattices[p->coord[p->n_coord-1].lattice-1]}; if (settings::verbosity >= 10 || simulation::trace) { std::stringstream msg; @@ -335,7 +348,7 @@ distance_to_boundary(Particle* p, double* dist, int* surface_crossed, // Find the distance to the next lattice tile crossing. if (p->coord[i].lattice != F90_NONE) { - Lattice& lat {*lattices[p->coord[i].lattice-1]}; + Lattice& lat {*model::lattices[p->coord[i].lattice-1]}; std::array i_xyz {p->coord[i].lattice_x, p->coord[i].lattice_y, p->coord[i].lattice_z}; //TODO: refactor so both lattice use the same position argument (which diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index 5662bd8de..2a3cf1db9 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -28,11 +28,11 @@ adjust_indices() if (c->fill_ != C_NONE) { int32_t id = c->fill_; auto search_univ = model::universe_map.find(id); - auto search_lat = lattice_map.find(id); + auto search_lat = model::lattice_map.find(id); if (search_univ != model::universe_map.end()) { c->type_ = FILL_UNIVERSE; c->fill_ = search_univ->second; - } else if (search_lat != lattice_map.end()) { + } else if (search_lat != model::lattice_map.end()) { c->type_ = FILL_LATTICE; c->fill_ = search_lat->second; } else { @@ -74,7 +74,7 @@ adjust_indices() } // Change all lattice universe values from IDs to indices. - for (Lattice* l : lattices) { + for (Lattice* l : model::lattices) { l->adjust_indices(); } } @@ -122,7 +122,7 @@ find_root_universe() } // Find all the universes contained in a lattice. - for (Lattice* lat : lattices) { + for (Lattice* lat : model::lattices) { for (auto it = lat->begin(); it != lat->end(); ++it) { fill_univ_ids.insert(*it); } @@ -245,7 +245,7 @@ prepare_distribcell() c->offset_.resize(n_maps, C_NONE); } } - for (Lattice* lat : lattices) { + for (Lattice* lat : model::lattices) { lat->allocate_offset_table(n_maps); } @@ -263,7 +263,7 @@ prepare_distribcell() offset += count_universe_instances(search_univ, target_univ_id); } else if (c.type_ == FILL_LATTICE) { - Lattice& lat = *lattices[c.fill_]; + Lattice& lat = *model::lattices[c.fill_]; offset = lat.fill_offset_table(offset, target_univ_id, map); } } @@ -286,7 +286,7 @@ count_cell_instances(int32_t univ_indx) } else if (c.type_ == FILL_LATTICE) { // This cell contains a lattice. Recurse into the lattice universes. - Lattice& lat = *lattices[c.fill_]; + Lattice& lat = *model::lattices[c.fill_]; for (auto it = lat.begin(); it != lat.end(); ++it) { count_cell_instances(*it); } @@ -313,7 +313,7 @@ count_universe_instances(int32_t search_univ, int32_t target_univ_id) count += count_universe_instances(next_univ, target_univ_id); } else if (c.type_ == FILL_LATTICE) { - Lattice& lat = *lattices[c.fill_]; + Lattice& lat = *model::lattices[c.fill_]; for (auto it = lat.begin(); it != lat.end(); ++it) { int32_t next_univ = *it; count += count_universe_instances(next_univ, target_univ_id); @@ -358,7 +358,7 @@ distribcell_path_inner(int32_t target_cell, int32_t map, int32_t target_offset, if (c.type_ == FILL_UNIVERSE) { temp_offset = offset + c.offset_[map]; } else { - Lattice& lat = *lattices[c.fill_]; + Lattice& lat = *model::lattices[c.fill_]; int32_t indx = lat.universes_.size()*map + lat.begin().indx_; temp_offset = offset + lat.offsets_[indx]; } @@ -381,7 +381,7 @@ distribcell_path_inner(int32_t target_cell, int32_t map, int32_t target_offset, return path.str(); } else { // Recurse into the lattice cell. - Lattice& lat = *lattices[c.fill_]; + Lattice& lat = *model::lattices[c.fill_]; path << "l" << lat.id_; for (ReverseLatticeIter it = lat.rbegin(); it != lat.rend(); ++it) { int32_t indx = lat.universes_.size()*map + it.indx_; @@ -401,7 +401,7 @@ distribcell_path_inner(int32_t target_cell, int32_t map, int32_t target_offset, std::string distribcell_path(int32_t target_cell, int32_t map, int32_t target_offset) { - auto& root_univ = *model::universes[openmc_root_universe]; + auto& root_univ = *model::universes[model::root_universe]; return distribcell_path_inner(target_cell, map, target_offset, root_univ, 0); } @@ -418,7 +418,7 @@ maximum_levels(int32_t univ) int32_t next_univ = c.fill_; levels_below = std::max(levels_below, maximum_levels(next_univ)); } else if (c.type_ == FILL_LATTICE) { - Lattice& lat = *lattices[c.fill_]; + Lattice& lat = *model::lattices[c.fill_]; for (auto it = lat.begin(); it != lat.end(); ++it) { int32_t next_univ = *it; levels_below = std::max(levels_below, maximum_levels(next_univ)); @@ -444,11 +444,11 @@ free_memory_geometry_c() model::universes.clear(); model::universe_map.clear(); - for (Lattice* lat : lattices) {delete lat;} - lattices.clear(); - lattice_map.clear(); + for (Lattice* lat : model::lattices) {delete lat;} + model::lattices.clear(); + model::lattice_map.clear(); - overlap_check_count.clear(); + model::overlap_check_count.clear(); } } // namespace openmc diff --git a/src/geometry_header.F90 b/src/geometry_header.F90 index 9af1fcbaa..df2819382 100644 --- a/src/geometry_header.F90 +++ b/src/geometry_header.F90 @@ -143,7 +143,7 @@ module geometry_header end type Cell ! array index of the root universe - integer(C_INT), bind(C, name='openmc_root_universe') :: root_universe = -1 + integer(C_INT), bind(C) :: root_universe integer(C_INT32_T), bind(C) :: n_cells ! # of cells integer(C_INT32_T), bind(C) :: n_universes ! # of universes diff --git a/src/lattice.cpp b/src/lattice.cpp index 1df21774f..a8966f898 100644 --- a/src/lattice.cpp +++ b/src/lattice.cpp @@ -18,10 +18,13 @@ namespace openmc { // Global variables //============================================================================== -std::vector lattices; +namespace model { +std::vector lattices; std::unordered_map lattice_map; +} + //============================================================================== // Lattice implementation //============================================================================== @@ -865,18 +868,18 @@ extern "C" void read_lattices(pugi::xml_node *node) { for (pugi::xml_node lat_node : node->children("lattice")) { - lattices.push_back(new RectLattice(lat_node)); + model::lattices.push_back(new RectLattice(lat_node)); } for (pugi::xml_node lat_node : node->children("hex_lattice")) { - lattices.push_back(new HexLattice(lat_node)); + model::lattices.push_back(new HexLattice(lat_node)); } // Fill the lattice map. - for (int i_lat = 0; i_lat < lattices.size(); i_lat++) { - int id = lattices[i_lat]->id_; - auto in_map = lattice_map.find(id); - if (in_map == lattice_map.end()) { - lattice_map[id] = i_lat; + for (int i_lat = 0; i_lat < model::lattices.size(); i_lat++) { + int id = model::lattices[i_lat]->id_; + auto in_map = model::lattice_map.find(id); + if (in_map == model::lattice_map.end()) { + model::lattice_map[id] = i_lat; } else { std::stringstream err_msg; err_msg << "Two or more lattices use the same unique ID: " << id; @@ -890,7 +893,7 @@ read_lattices(pugi::xml_node *node) //============================================================================== extern "C" { - Lattice* lattice_pointer(int lat_ind) {return lattices[lat_ind];} + Lattice* lattice_pointer(int lat_ind) {return model::lattices[lat_ind];} int32_t lattice_id(Lattice *lat) {return lat->id_;} } diff --git a/src/output.cpp b/src/output.cpp index 79c3f7f0b..6e07e2456 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -129,9 +129,9 @@ void print_plot() { void print_overlap_check() { #ifdef OPENMC_MPI - std::vector temp(overlap_check_count); - int err = MPI_Reduce(temp.data(), overlap_check_count.data(), - overlap_check_count.size(), MPI_INT64_T, MPI_SUM, 0, + std::vector temp(model::overlap_check_count); + int err = MPI_Reduce(temp.data(), model::overlap_check_count.data(), + model::overlap_check_count.size(), MPI_INT64_T, MPI_SUM, 0, mpi::intracomm); #endif @@ -142,8 +142,8 @@ print_overlap_check() { std::vector sparse_cell_ids; for (int i = 0; i < model::n_cells; i++) { std::cout << " " << std::setw(8) << model::cells[i]->id_ << std::setw(17) - << overlap_check_count[i] << "\n"; - if (overlap_check_count[i] < 10) { + << model::overlap_check_count[i] << "\n"; + if (model::overlap_check_count[i] < 10) { sparse_cell_ids.push_back(model::cells[i]->id_); } } diff --git a/src/plot.cpp b/src/plot.cpp index 403b27884..d325919e4 100644 --- a/src/plot.cpp +++ b/src/plot.cpp @@ -123,7 +123,7 @@ void create_ppm(Plot pl) p.initialize(); std::copy(xyz, xyz+3, p.coord[0].xyz); std::copy(dir, dir+3, p.coord[0].uvw); - p.coord[0].universe = openmc_root_universe; + p.coord[0].universe = model::root_universe; #pragma omp for for (int y = 0; y < height; y++) { @@ -852,7 +852,7 @@ void create_voxel(Plot pl) p.initialize(); std::copy(ll.begin(), ll.begin()+ll.size(), p.coord[0].xyz); std::copy(dir, dir+3, p.coord[0].uvw); - p.coord[0].universe = openmc_root_universe; + p.coord[0].universe = model::root_universe; // Open binary plot file for writing std::ofstream of; diff --git a/src/summary.cpp b/src/summary.cpp index 8431e2a5f..185ad9cce 100644 --- a/src/summary.cpp +++ b/src/summary.cpp @@ -21,7 +21,7 @@ write_geometry(hid_t file_id) { write_attribute(geom_group, "n_cells", model::cells.size()); write_attribute(geom_group, "n_surfaces", surfaces.size()); write_attribute(geom_group, "n_universes", model::universes.size()); - write_attribute(geom_group, "n_lattices", lattices.size()); + write_attribute(geom_group, "n_lattices", model::lattices.size()); auto cells_group = create_group(geom_group, "cells"); for (Cell* c : model::cells) c->to_hdf5(cells_group); @@ -36,7 +36,7 @@ write_geometry(hid_t file_id) { close_group(universes_group); auto lattices_group = create_group(geom_group, "lattices"); - for (Lattice* lat : lattices) lat->to_hdf5(lattices_group); + for (Lattice* lat : model::lattices) lat->to_hdf5(lattices_group); close_group(lattices_group); close_group(geom_group); diff --git a/src/tallies/filter_distribcell.cpp b/src/tallies/filter_distribcell.cpp index 8af01b906..ee4f08dd4 100644 --- a/src/tallies/filter_distribcell.cpp +++ b/src/tallies/filter_distribcell.cpp @@ -45,7 +45,7 @@ DistribcellFilter::get_all_bins(const Particle* p, int estimator, if (c.type_ == FILL_UNIVERSE) { offset += c.offset_[distribcell_index]; } else if (c.type_ == FILL_LATTICE) { - auto& lat {*lattices[p->coord[i+1].lattice-1]}; + auto& lat {*model::lattices[p->coord[i+1].lattice-1]}; int i_xyz[3] {p->coord[i+1].lattice_x, p->coord[i+1].lattice_y, p->coord[i+1].lattice_z}; From 5fae5ffa9ead8c89c783dbf68e0e37d49b9710d0 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 8 Nov 2018 14:03:09 -0600 Subject: [PATCH 39/62] Namespacing for mesh/material global variables --- include/openmc/capi.h | 1 - include/openmc/material.h | 5 +++ include/openmc/mesh.h | 22 ++++++----- src/cell.cpp | 4 +- src/cmfd_execute.cpp | 2 +- src/eigenvalue.cpp | 6 +-- src/geometry_aux.cpp | 8 ++-- src/material.cpp | 40 +++++++++++--------- src/mesh.cpp | 61 ++++++++++++++++-------------- src/physics_mg.cpp | 2 +- src/plot.cpp | 27 ++++++------- src/settings.cpp | 26 ++++++------- src/source.cpp | 2 +- src/tallies/filter_material.cpp | 8 ++-- src/tallies/filter_mesh.cpp | 16 ++++---- src/tallies/filter_meshsurface.cpp | 8 ++-- 16 files changed, 125 insertions(+), 113 deletions(-) diff --git a/include/openmc/capi.h b/include/openmc/capi.h index a04f1a622..ace061f54 100644 --- a/include/openmc/capi.h +++ b/include/openmc/capi.h @@ -135,7 +135,6 @@ extern "C" { // Global variables extern char openmc_err_msg[256]; - extern int32_t n_materials; extern int n_nuclides; extern int32_t n_plots; extern int32_t n_realizations; diff --git a/include/openmc/material.h b/include/openmc/material.h index b6d7e19cd..fcab023a5 100644 --- a/include/openmc/material.h +++ b/include/openmc/material.h @@ -14,9 +14,14 @@ namespace openmc { //============================================================================== class Material; + +namespace model { + extern std::vector materials; extern std::unordered_map material_map; +} // namespace model + //============================================================================== //! A substance with constituent nuclides and thermal scattering data //============================================================================== diff --git a/include/openmc/mesh.h b/include/openmc/mesh.h index 3d31fb489..7fcd58a06 100644 --- a/include/openmc/mesh.h +++ b/include/openmc/mesh.h @@ -17,6 +17,19 @@ namespace openmc { +//============================================================================== +// Global variables +//============================================================================== + +class RegularMesh; + +namespace model { + +extern std::vector> meshes; +extern std::unordered_map mesh_map; + +} // namespace model + //============================================================================== //! Tessellation of n-dimensional Euclidean space by congruent squares or cubes //============================================================================== @@ -117,15 +130,6 @@ extern "C" void read_meshes(pugi::xml_node* root); //! \param[in] group HDF5 group extern "C" void meshes_to_hdf5(hid_t group); -//============================================================================== -// Global variables -//============================================================================== - -extern std::vector> meshes; - -extern std::unordered_map mesh_map; - - } // namespace openmc #endif // OPENMC_MESH_H diff --git a/src/cell.cpp b/src/cell.cpp index 8c5aaf29c..5c341eb15 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -480,7 +480,7 @@ CSGCell::to_hdf5(hid_t cell_group) const std::vector mat_ids; for (auto i_mat : material_) { if (i_mat != MATERIAL_VOID) { - mat_ids.push_back(materials[i_mat]->id_); + mat_ids.push_back(model::materials[i_mat]->id_); } else { mat_ids.push_back(MATERIAL_VOID); } @@ -724,7 +724,7 @@ openmc_cell_set_fill(int32_t index, int type, int32_t n, int i_mat = indices[i]; if (i_mat == MATERIAL_VOID) { c.material_.push_back(MATERIAL_VOID); - } else if (i_mat >= 1 && i_mat <= materials.size()) { + } else if (i_mat >= 1 && i_mat <= model::materials.size()) { //TODO: off-by-one c.material_.push_back(i_mat - 1); } else { diff --git a/src/cmfd_execute.cpp b/src/cmfd_execute.cpp index 46371601b..0af584c1b 100644 --- a/src/cmfd_execute.cpp +++ b/src/cmfd_execute.cpp @@ -24,7 +24,7 @@ cmfd_populate_sourcecounts(int n_energy, const double* energies, openmc_source_bank(&source_bank, &n); // Get source counts in each mesh bin / energy bin - auto& m = meshes.at(settings::index_cmfd_mesh); + auto& m = model::meshes.at(settings::index_cmfd_mesh); xt::xarray counts = m->count_sites(simulation::work, source_bank, n_energy, energies, outside); // Copy data from the xarray into the source counts array diff --git a/src/eigenvalue.cpp b/src/eigenvalue.cpp index 89e25dbcf..4d9196ea0 100644 --- a/src/eigenvalue.cpp +++ b/src/eigenvalue.cpp @@ -497,7 +497,7 @@ int openmc_get_keff(double* k_combined) void shannon_entropy() { // Get pointer to entropy mesh - auto& m = meshes[settings::index_entropy_mesh]; + auto& m = model::meshes[settings::index_entropy_mesh]; // Get pointer to fission bank Bank* fission_bank; @@ -533,7 +533,7 @@ void shannon_entropy() void ufs_count_sites() { - auto &m = meshes[settings::index_ufs_mesh]; + auto &m = model::meshes[settings::index_ufs_mesh]; if (simulation::current_batch == 1 && simulation::current_gen == 1) { // On the first generation, just assume that the source is already evenly @@ -579,7 +579,7 @@ void ufs_count_sites() double ufs_get_weight(const Particle* p) { - auto& m = meshes[settings::index_ufs_mesh]; + auto& m = model::meshes[settings::index_ufs_mesh]; // Determine indices on ufs mesh for current location // TODO: off by one diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index 2a3cf1db9..52d0ae92a 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -46,8 +46,8 @@ adjust_indices() for (auto it = c->material_.begin(); it != c->material_.end(); it++) { int32_t mid = *it; if (mid != MATERIAL_VOID) { - auto search = material_map.find(mid); - if (search != material_map.end()) { + auto search = model::material_map.find(mid); + if (search != model::material_map.end()) { *it = search->second; } else { std::stringstream err_msg; @@ -96,9 +96,9 @@ assign_temperatures() c->sqrtkT_.push_back(0); } else { - if (materials[i_mat]->temperature_ >= 0) { + if (model::materials[i_mat]->temperature_ >= 0) { // This material has a default temperature; use that value. - auto T = materials[i_mat]->temperature_; + auto T = model::materials[i_mat]->temperature_; c->sqrtkT_.push_back(std::sqrt(K_BOLTZMANN * T)); } else { // Use the global default temperature. diff --git a/src/material.cpp b/src/material.cpp index ecc6eed2b..7f8cfc50b 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -13,9 +13,13 @@ namespace openmc { // Global variables //============================================================================== +namespace model { + std::vector materials; std::unordered_map material_map; +} // namespace model + //============================================================================== // Material implementation //============================================================================== @@ -46,16 +50,16 @@ read_materials(pugi::xml_node* node) { // Loop over XML material elements and populate the array. for (pugi::xml_node material_node : node->children("material")) { - materials.push_back(new Material(material_node)); + model::materials.push_back(new Material(material_node)); } - materials.shrink_to_fit(); + model::materials.shrink_to_fit(); // Populate the material map. - for (int i = 0; i < materials.size(); i++) { - int32_t mid = materials[i]->id_; - auto search = material_map.find(mid); - if (search == material_map.end()) { - material_map[mid] = i; + for (int i = 0; i < model::materials.size(); i++) { + int32_t mid = model::materials[i]->id_; + auto search = model::material_map.find(mid); + if (search == model::material_map.end()) { + model::material_map[mid] = i; } else { std::stringstream err_msg; err_msg << "Two or more materials use the same unique ID: " << mid; @@ -71,8 +75,8 @@ read_materials(pugi::xml_node* node) extern "C" int openmc_material_get_volume(int32_t index, double* volume) { - if (index >= 1 && index <= materials.size()) { - Material* m = materials[index - 1]; + if (index >= 1 && index <= model::materials.size()) { + Material* m = model::materials[index - 1]; if (m->volume_ >= 0.0) { *volume = m->volume_; return 0; @@ -91,8 +95,8 @@ openmc_material_get_volume(int32_t index, double* volume) extern "C" int openmc_material_set_volume(int32_t index, double volume) { - if (index >= 1 && index <= materials.size()) { - Material* m = materials[index - 1]; + if (index >= 1 && index <= model::materials.size()) { + Material* m = model::materials[index - 1]; if (volume >= 0.0) { m->volume_ = volume; return 0; @@ -111,7 +115,7 @@ openmc_material_set_volume(int32_t index, double volume) //============================================================================== extern "C" { - Material* material_pointer(int32_t indx) {return materials[indx];} + Material* material_pointer(int32_t indx) {return model::materials[indx];} int32_t material_id(Material* mat) {return mat->id_;} @@ -119,7 +123,7 @@ extern "C" { { mat->id_ = id; //TODO: off-by-one - material_map[id] = index - 1; + model::material_map[id] = index - 1; } bool material_fissionable(Material* mat) {return mat->fissionable;} @@ -131,17 +135,17 @@ extern "C" { void extend_materials_c(int32_t n) { - materials.reserve(materials.size() + n); + model::materials.reserve(model::materials.size() + n); for (int32_t i = 0; i < n; i++) { - materials.push_back(new Material()); + model::materials.push_back(new Material()); } } void free_memory_material_c() { - for (Material *mat : materials) {delete mat;} - materials.clear(); - material_map.clear(); + for (Material *mat : model::materials) {delete mat;} + model::materials.clear(); + model::material_map.clear(); } } diff --git a/src/mesh.cpp b/src/mesh.cpp index 2c3e508fe..6ec298a78 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -29,10 +29,13 @@ namespace openmc { // Global variables //============================================================================== -std::vector> meshes; +namespace model { +std::vector> meshes; std::unordered_map mesh_map; +} // namespace model + //============================================================================== // RegularMesh implementation //============================================================================== @@ -44,7 +47,7 @@ RegularMesh::RegularMesh(pugi::xml_node node) id_ = std::stoi(get_node_value(node, "id")); // Check to make sure 'id' hasn't been used - if (mesh_map.find(id_) != mesh_map.end()) { + if (model::mesh_map.find(id_) != model::mesh_map.end()) { fatal_error("Two or more meshes use the same unique ID: " + std::to_string(id_)); } @@ -724,11 +727,11 @@ xt::xarray RegularMesh::count_sites(int64_t n, const Bank* bank, extern "C" int openmc_extend_meshes(int32_t n, int32_t* index_start, int32_t* index_end) { - if (index_start) *index_start = meshes.size(); + if (index_start) *index_start = model::meshes.size(); for (int i = 0; i < n; ++i) { - meshes.emplace_back(new RegularMesh{}); + model::meshes.emplace_back(new RegularMesh{}); } - if (index_end) *index_end = meshes.size() - 1; + if (index_end) *index_end = model::meshes.size() - 1; return 0; } @@ -737,8 +740,8 @@ openmc_extend_meshes(int32_t n, int32_t* index_start, int32_t* index_end) extern "C" int openmc_get_mesh_index(int32_t id, int32_t* index) { - auto pair = mesh_map.find(id); - if (pair == mesh_map.end()) { + auto pair = model::mesh_map.find(id); + if (pair == model::mesh_map.end()) { set_errmsg("No mesh exists with ID=" + std::to_string(id) + "."); return OPENMC_E_INVALID_ID; } @@ -750,11 +753,11 @@ openmc_get_mesh_index(int32_t id, int32_t* index) extern "C" int openmc_mesh_get_id(int32_t index, int32_t* id) { - if (index < 0 || index >= meshes.size()) { + if (index < 0 || index >= model::meshes.size()) { set_errmsg("Index in meshes array is out of bounds."); return OPENMC_E_OUT_OF_BOUNDS; } - *id = meshes[index]->id_; + *id = model::meshes[index]->id_; return 0; } @@ -762,12 +765,12 @@ openmc_mesh_get_id(int32_t index, int32_t* id) extern "C" int openmc_mesh_set_id(int32_t index, int32_t id) { - if (index < 0 || index >= meshes.size()) { + if (index < 0 || index >= model::meshes.size()) { set_errmsg("Index in meshes array is out of bounds."); return OPENMC_E_OUT_OF_BOUNDS; } - meshes[index]->id_ = id; - mesh_map[id] = index; + model::meshes[index]->id_ = id; + model::mesh_map[id] = index; return 0; } @@ -775,12 +778,12 @@ openmc_mesh_set_id(int32_t index, int32_t id) extern "C" int openmc_mesh_get_dimension(int32_t index, int** dims, int* n) { - if (index < 0 || index >= meshes.size()) { + if (index < 0 || index >= model::meshes.size()) { set_errmsg("Index in meshes array is out of bounds."); return OPENMC_E_OUT_OF_BOUNDS; } - *dims = meshes[index]->shape_.data(); - *n = meshes[index]->n_dimension_; + *dims = model::meshes[index]->shape_.data(); + *n = model::meshes[index]->n_dimension_; return 0; } @@ -788,14 +791,14 @@ openmc_mesh_get_dimension(int32_t index, int** dims, int* n) extern "C" int openmc_mesh_set_dimension(int32_t index, int n, const int* dims) { - if (index < 0 || index >= meshes.size()) { + if (index < 0 || index >= model::meshes.size()) { set_errmsg("Index in meshes array is out of bounds."); return OPENMC_E_OUT_OF_BOUNDS; } // Copy dimension std::vector shape = {static_cast(n)}; - auto& m = meshes[index]; + auto& m = model::meshes[index]; m->shape_ = xt::adapt(dims, n, xt::no_ownership(), shape); m->n_dimension_ = m->shape_.size(); @@ -806,12 +809,12 @@ openmc_mesh_set_dimension(int32_t index, int n, const int* dims) extern "C" int openmc_mesh_get_params(int32_t index, double** ll, double** ur, double** width, int* n) { - if (index < 0 || index >= meshes.size()) { + if (index < 0 || index >= model::meshes.size()) { set_errmsg("Index in meshes array is out of bounds."); return OPENMC_E_OUT_OF_BOUNDS; } - auto& m = meshes[index]; + auto& m = model::meshes[index]; if (m->lower_left_.dimension() == 0) { set_errmsg("Mesh parameters have not been set."); return OPENMC_E_ALLOCATE; @@ -829,12 +832,12 @@ extern "C" int openmc_mesh_set_params(int32_t index, int n, const double* ll, const double* ur, const double* width) { - if (index < 0 || index >= meshes.size()) { + if (index < 0 || index >= model::meshes.size()) { set_errmsg("Index in meshes array is out of bounds."); return OPENMC_E_OUT_OF_BOUNDS; } - auto& m = meshes[index]; + auto& m = model::meshes[index]; std::vector shape = {static_cast(n)}; if (ll && ur) { m->lower_left_ = xt::adapt(ll, n, xt::no_ownership(), shape); @@ -864,10 +867,10 @@ void read_meshes(pugi::xml_node* root) { for (auto node : root->children("mesh")) { // Read mesh and add to vector - meshes.emplace_back(new RegularMesh{node}); + model::meshes.emplace_back(new RegularMesh{node}); // Map ID to position in vector - mesh_map[meshes.back()->id_] = meshes.size() - 1; + model::mesh_map[model::meshes.back()->id_] = model::meshes.size() - 1; } } @@ -875,13 +878,13 @@ void meshes_to_hdf5(hid_t group) { // Write number of meshes hid_t meshes_group = create_group(group, "meshes"); - int32_t n_meshes = meshes.size(); + int32_t n_meshes = model::meshes.size(); write_attribute(meshes_group, "n_meshes", n_meshes); if (n_meshes > 0) { // Write IDs of meshes std::vector ids; - for (const auto& m : meshes) { + for (const auto& m : model::meshes) { m->to_hdf5(meshes_group); ids.push_back(m->id_); } @@ -896,9 +899,9 @@ void meshes_to_hdf5(hid_t group) //============================================================================== extern "C" { - int n_meshes() { return meshes.size(); } + int n_meshes() { return model::meshes.size(); } - RegularMesh* mesh_ptr(int i) { return meshes.at(i).get(); } + RegularMesh* mesh_ptr(int i) { return model::meshes.at(i).get(); } int32_t mesh_id(RegularMesh* m) { return m->id_; } @@ -936,8 +939,8 @@ extern "C" { void free_memory_mesh() { - meshes.clear(); - mesh_map.clear(); + model::meshes.clear(); + model::mesh_map.clear(); } } diff --git a/src/physics_mg.cpp b/src/physics_mg.cpp index ff41221ba..4ce64b61a 100644 --- a/src/physics_mg.cpp +++ b/src/physics_mg.cpp @@ -47,7 +47,7 @@ sample_reaction(Particle* p, const double* energy_bin_avg, // change when sampling fission sites. The following block handles all // absorption (including fission) - if (materials[p->material - 1]->fissionable) { + if (model::materials[p->material - 1]->fissionable) { if (settings::run_mode == RUN_MODE_EIGENVALUE) { Bank* result_bank; int64_t result_bank_size; diff --git a/src/plot.cpp b/src/plot.cpp index d325919e4..e372a678e 100644 --- a/src/plot.cpp +++ b/src/plot.cpp @@ -362,23 +362,20 @@ Plot::set_default_colors(pugi::xml_node plot_node) } if ("cell" == pl_color_by) { color_by_ = PlotColorBy::cells; - colors_.resize(model::n_cells); - for (int i = 0; i < model::n_cells; i++) { - colors_[i] = random_color(); - } - + colors_.resize(model::cells.size()); } else if("material" == pl_color_by) { color_by_ = PlotColorBy::mats; - colors_.resize(n_materials); - for (int i = 0; i < materials.size(); i++) { - colors_[i] = random_color(); - } + colors_.resize(model::materials.size()); } else { std::stringstream err_msg; err_msg << "Unsupported plot color type '" << pl_color_by << "' in plot " << id_; fatal_error(err_msg); } + + for (auto& c : colors_) { + c = random_color(); + } } void @@ -423,8 +420,8 @@ Plot::set_user_colors(pugi::xml_node plot_node) fatal_error(err_msg); } } else if (PlotColorBy::mats == color_by_) { - if (material_map.find(col_id) != material_map.end()) { - col_id = material_map[col_id]; + if (model::material_map.find(col_id) != model::material_map.end()) { + col_id = model::material_map[col_id]; colors_[col_id] = user_rgb; } else { std::stringstream err_msg; @@ -586,8 +583,8 @@ Plot::set_mask(pugi::xml_node plot_node) fatal_error(err_msg); } } else if (PlotColorBy::mats == color_by_) { - if (material_map.find(col_id) != material_map.end()) { - col_id = material_map[col_id]; + if (model::material_map.find(col_id) != model::material_map.end()) { + col_id = model::material_map[col_id]; } else { std::stringstream err_msg; @@ -672,7 +669,7 @@ void position_rgb(Particle p, Plot pl, RGBColor& rgb, int& id) id = -1; } else { rgb = pl.colors_[p.material - 1]; - id = materials[p.material - 1]->id_; + id = model::materials[p.material - 1]->id_; } } else if (PlotColorBy::cells == pl.color_by_) { // Assign color based on cell @@ -760,7 +757,7 @@ void draw_mesh_lines(Plot pl, ImageData& data) width[1] = xyz_ur_plot[1] - xyz_ll_plot[1]; width[2] = xyz_ur_plot[2] - xyz_ll_plot[2]; - auto& m = meshes[pl.index_meshlines_mesh_]; + auto& m = model::meshes[pl.index_meshlines_mesh_]; int ijk_ll[3], ijk_ur[3]; bool in_mesh; diff --git a/src/settings.cpp b/src/settings.cpp index 227ebca5c..b5bb4fe80 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -507,12 +507,12 @@ void read_settings_xml() // Shannon Entropy mesh if (check_for_node(root, "entropy_mesh")) { int temp = std::stoi(get_node_value(root, "entropy_mesh")); - if (mesh_map.find(temp) == mesh_map.end()) { + if (model::mesh_map.find(temp) == model::mesh_map.end()) { std::stringstream msg; msg << "Mesh " << temp << " specified for Shannon entropy does not exist."; fatal_error(msg); } - index_entropy_mesh = mesh_map.at(temp); + index_entropy_mesh = model::mesh_map.at(temp); } else if (check_for_node(root, "entropy")) { warning("Specifying a Shannon entropy mesh via the element " @@ -521,18 +521,18 @@ void read_settings_xml() // Read entropy mesh from auto node_entropy = root.child("entropy"); - meshes.emplace_back(new RegularMesh{node_entropy}); + model::meshes.emplace_back(new RegularMesh{node_entropy}); // Set entropy mesh index - index_entropy_mesh = meshes.size() - 1; + index_entropy_mesh = model::meshes.size() - 1; // Assign ID and set mapping - meshes.back()->id_ = 10000; - mesh_map[10000] = index_entropy_mesh; + model::meshes.back()->id_ = 10000; + model::mesh_map[10000] = index_entropy_mesh; } if (index_entropy_mesh >= 0) { - auto& m = *meshes[index_entropy_mesh]; + auto& m = *model::meshes[index_entropy_mesh]; if (m.shape_.dimension() == 0) { // If the user did not specify how many mesh cells are to be used in // each direction, we automatically determine an appropriate number of @@ -552,13 +552,13 @@ void read_settings_xml() // Uniform fission source weighting mesh if (check_for_node(root, "ufs_mesh")) { auto temp = std::stoi(get_node_value(root, "ufs_mesh")); - if (mesh_map.find(temp) == mesh_map.end()) { + if (model::mesh_map.find(temp) == model::mesh_map.end()) { std::stringstream msg; msg << "Mesh " << temp << " specified for uniform fission site method " "does not exist."; fatal_error(msg); } - index_ufs_mesh = mesh_map.at(temp); + index_ufs_mesh = model::mesh_map.at(temp); } else if (check_for_node(root, "uniform_fs")) { warning("Specifying a UFS mesh via the element " @@ -567,14 +567,14 @@ void read_settings_xml() // Read entropy mesh from auto node_ufs = root.child("uniform_fs"); - meshes.emplace_back(new RegularMesh{node_ufs}); + model::meshes.emplace_back(new RegularMesh{node_ufs}); // Set entropy mesh index - index_ufs_mesh = meshes.size() - 1; + index_ufs_mesh = model::meshes.size() - 1; // Assign ID and set mapping - meshes.back()->id_ = 10001; - mesh_map[10001] = index_entropy_mesh; + model::meshes.back()->id_ = 10001; + model::mesh_map[10001] = index_entropy_mesh; } if (index_ufs_mesh >= 0) { diff --git a/src/source.cpp b/src/source.cpp index 782fb97a2..6610e7f4d 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -169,7 +169,7 @@ Bank SourceDistribution::sample() const // Determine material auto c = model::cells[cell_index - 1]; int32_t mat_index = c->material_[instance]; - auto m = materials[mat_index]; + auto m = model::materials[mat_index]; if (mat_index == MATERIAL_VOID) { found = false; diff --git a/src/tallies/filter_material.cpp b/src/tallies/filter_material.cpp index d36175e9b..be462b915 100644 --- a/src/tallies/filter_material.cpp +++ b/src/tallies/filter_material.cpp @@ -21,8 +21,8 @@ MaterialFilter::initialize() { // Convert material IDs to indices of the global array. for (auto& m : materials_) { - auto search = material_map.find(m); - if (search != material_map.end()) { + auto search = model::material_map.find(m); + if (search != model::material_map.end()) { m = search->second; } else { std::stringstream err_msg; @@ -55,7 +55,7 @@ MaterialFilter::to_statepoint(hid_t filter_group) const { Filter::to_statepoint(filter_group); std::vector material_ids; - for (auto c : materials_) material_ids.push_back(materials[c]->id_); + for (auto c : materials_) material_ids.push_back(model::materials[c]->id_); write_dataset(filter_group, "bins", material_ids); } @@ -63,7 +63,7 @@ std::string MaterialFilter::text_label(int bin) const { //TODO: off-by-one - return "Material " + std::to_string(materials[materials_[bin-1]]->id_); + return "Material " + std::to_string(model::materials[materials_[bin-1]]->id_); } //============================================================================== diff --git a/src/tallies/filter_mesh.cpp b/src/tallies/filter_mesh.cpp index 5ff54bcf5..7f2b0d60c 100644 --- a/src/tallies/filter_mesh.cpp +++ b/src/tallies/filter_mesh.cpp @@ -20,8 +20,8 @@ MeshFilter::from_xml(pugi::xml_node node) } auto id = bins_[0]; - auto search = mesh_map.find(id); - if (search != mesh_map.end()) { + auto search = model::mesh_map.find(id); + if (search != model::mesh_map.end()) { set_mesh(search->second); } else{ std::stringstream err_msg; @@ -35,14 +35,14 @@ MeshFilter::get_all_bins(const Particle* p, int estimator, FilterMatch& match) const { if (estimator != ESTIMATOR_TRACKLENGTH) { - auto bin = meshes[mesh_]->get_bin(p->coord[0].xyz); + auto bin = model::meshes[mesh_]->get_bin(p->coord[0].xyz); if (bin >= 0) { //TODO: off-by-one match.bins_.push_back(bin); match.weights_.push_back(1.0); } } else { - meshes[mesh_]->bins_crossed(p, match.bins_, match.weights_); + model::meshes[mesh_]->bins_crossed(p, match.bins_, match.weights_); } } @@ -50,13 +50,13 @@ void MeshFilter::to_statepoint(hid_t filter_group) const { Filter::to_statepoint(filter_group); - write_dataset(filter_group, "bins", meshes[mesh_]->id_); + write_dataset(filter_group, "bins", model::meshes[mesh_]->id_); } std::string MeshFilter::text_label(int bin) const { - auto& mesh = *meshes[mesh_]; + auto& mesh = *model::meshes[mesh_]; int n_dim = mesh.n_dimension_; int ijk[n_dim]; @@ -76,7 +76,7 @@ MeshFilter::set_mesh(int32_t mesh) { mesh_ = mesh; n_bins_ = 1; - for (auto dim : meshes[mesh_]->shape_) n_bins_ *= dim; + for (auto dim : model::meshes[mesh_]->shape_) n_bins_ *= dim; } //============================================================================== @@ -123,7 +123,7 @@ openmc_mesh_filter_set_mesh(int32_t index, int32_t index_mesh) } // Check the mesh index. - if (index_mesh < 0 || index_mesh >= meshes.size()) { + if (index_mesh < 0 || index_mesh >= model::meshes.size()) { set_errmsg("Index in 'meshes' array is out of bounds."); return OPENMC_E_OUT_OF_BOUNDS; } diff --git a/src/tallies/filter_meshsurface.cpp b/src/tallies/filter_meshsurface.cpp index af9bc5321..a8854c7ec 100644 --- a/src/tallies/filter_meshsurface.cpp +++ b/src/tallies/filter_meshsurface.cpp @@ -11,14 +11,14 @@ void MeshSurfaceFilter::get_all_bins(const Particle* p, int estimator, FilterMatch& match) const { - meshes[mesh_]->surface_bins_crossed(p, match.bins_); + model::meshes[mesh_]->surface_bins_crossed(p, match.bins_); for (auto b : match.bins_) match.weights_.push_back(1.0); } std::string MeshSurfaceFilter::text_label(int bin) const { - auto& mesh = *meshes[mesh_]; + auto& mesh = *model::meshes[mesh_]; int n_dim = mesh.n_dimension_; // Get flattend mesh index and surface index. @@ -76,8 +76,8 @@ void MeshSurfaceFilter::set_mesh(int32_t mesh) { mesh_ = mesh; - n_bins_ = 4 * meshes[mesh_]->n_dimension_; - for (auto dim : meshes[mesh_]->shape_) n_bins_ *= dim; + n_bins_ = 4 * model::meshes[mesh_]->n_dimension_; + for (auto dim : model::meshes[mesh_]->shape_) n_bins_ *= dim; } //============================================================================== From c301612ca22b6b85deba136f60cdac22bcf7df7b Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 8 Nov 2018 15:00:40 -0600 Subject: [PATCH 40/62] Namespace mgxs-related global variables --- include/openmc/mgxs_interface.h | 4 ++++ include/openmc/physics_mg.h | 13 ++++------ src/mgxs.cpp | 8 +++++++ src/mgxs_interface.cpp | 42 ++++++++++++++++++--------------- src/particle.cpp | 2 +- src/physics_mg.cpp | 18 +++++++------- src/source.cpp | 6 ++--- src/tallies/filter_energy.cpp | 10 ++++---- src/tracking.F90 | 5 ++-- 9 files changed, 58 insertions(+), 50 deletions(-) diff --git a/include/openmc/mgxs_interface.h b/include/openmc/mgxs_interface.h index c81375511..17be1a18e 100644 --- a/include/openmc/mgxs_interface.h +++ b/include/openmc/mgxs_interface.h @@ -15,6 +15,8 @@ namespace openmc { // Global variables //============================================================================== +namespace data { + extern std::vector nuclides_MG; extern std::vector macro_xs; extern "C" int num_energy_groups; @@ -22,6 +24,8 @@ extern std::vector energy_bins; extern std::vector energy_bin_avg; extern std::vector rev_energy_bins; +} // namespace data + //============================================================================== // Mgxs data loading interface methods //============================================================================== diff --git a/include/openmc/physics_mg.h b/include/openmc/physics_mg.h index 14b7e6cbd..e5648c4a5 100644 --- a/include/openmc/physics_mg.h +++ b/include/openmc/physics_mg.h @@ -10,34 +10,29 @@ namespace openmc { -//TODO: Remove energy_bin_avg and material_xs parameters when they reside on +//TODO: Remove material_xs parameters when they reside on // the C-side this should happen after materials, physics, input, and tallies // are brought over //! \brief samples particle behavior after a collision event. //! \param p Particle to operate on -//! \param energy_bin_avg Average energy within each energy bin //! \param material_xs The cross section cache for the current material extern "C" void -collision_mg(Particle* p, const double* energy_bin_avg, - const MaterialMacroXS* material_xs); +collision_mg(Particle* p, const MaterialMacroXS* material_xs); //! \brief samples a reaction type. //! //! Note that there is special logic when suvival biasing is turned on since //! fission and disappearance are treated implicitly. //! \param p Particle to operate on -//! \param energy_bin_avg Average energy within each energy bin //! \param material_xs The cross section cache for the current material void -sample_reaction(Particle* p, const double* energy_bin_avg, - const MaterialMacroXS* material_xs); +sample_reaction(Particle* p, const MaterialMacroXS* material_xs); //! \brief Samples the scattering event //! \param p Particle to operate on -//! \param energy_bin_avg Average energy within each energy bin void -scatter(Particle* p, const double* energy_bin_avg); +scatter(Particle* p); //! \brief Determines the average total, prompt and delayed neutrons produced //! from fission and creates the appropriate bank sites. diff --git a/src/mgxs.cpp b/src/mgxs.cpp index 8c14f324e..85107cbf9 100644 --- a/src/mgxs.cpp +++ b/src/mgxs.cpp @@ -22,10 +22,18 @@ namespace openmc { +//============================================================================== +// Global variables +//============================================================================== + +namespace data { + // Storage for the MGXS data std::vector nuclides_MG; std::vector macro_xs; +} // namespace data + //============================================================================== // Mgxs base-class methods //============================================================================== diff --git a/src/mgxs_interface.cpp b/src/mgxs_interface.cpp index 80aa66621..710d76a52 100644 --- a/src/mgxs_interface.cpp +++ b/src/mgxs_interface.cpp @@ -13,10 +13,14 @@ namespace openmc { // Global variable definitions //============================================================================== +namespace data { + std::vector energy_bins; std::vector energy_bin_avg; std::vector rev_energy_bins; +} // namesapce data + //============================================================================== // Mgxs data loading interface methods //============================================================================== @@ -44,7 +48,7 @@ add_mgxs_c(hid_t file_id, const char* name, int energy_groups, Mgxs mg(xs_grp, energy_groups, delayed_groups, temperature, tolerance, max_order, legendre_to_tabular, legendre_to_tabular_points, method); - nuclides_MG.push_back(mg); + data::nuclides_MG.push_back(mg); close_group(xs_grp); } @@ -55,7 +59,7 @@ query_fissionable_c(int n_nuclides, const int i_nuclides[]) { bool result = false; for (int n = 0; n < n_nuclides; n++) { - if (nuclides_MG[i_nuclides[n] - 1].fissionable) result = true; + if (data::nuclides_MG[i_nuclides[n] - 1].fissionable) result = true; } return result; } @@ -79,16 +83,16 @@ create_macro_xs_c(const char* mat_name, int n_nuclides, const int i_nuclides[], // material std::vector mgxs_ptr(n_nuclides); for (int n = 0; n < n_nuclides; n++) { - mgxs_ptr[n] = &nuclides_MG[i_nuclides[n] - 1]; + mgxs_ptr[n] = &data::nuclides_MG[i_nuclides[n] - 1]; } Mgxs macro(mat_name, temperature, mgxs_ptr, atom_densities_vec, tolerance, method); - macro_xs.emplace_back(macro); + data::macro_xs.emplace_back(macro); } else { // Preserve the ordering of materials by including a blank entry Mgxs macro; - macro_xs.emplace_back(macro); + data::macro_xs.emplace_back(macro); } } @@ -97,18 +101,18 @@ create_macro_xs_c(const char* mat_name, int n_nuclides, const int i_nuclides[], void read_mg_cross_sections_header_c(hid_t file_id) { ensure_exists(file_id, "energy_groups", true); - read_attribute(file_id, "energy_groups", num_energy_groups); + read_attribute(file_id, "energy_groups", data::num_energy_groups); ensure_exists(file_id, "group structure", true); - read_attribute(file_id, "group structure", rev_energy_bins); + read_attribute(file_id, "group structure", data::rev_energy_bins); // Reverse energy bins - std::copy(rev_energy_bins.crbegin(), rev_energy_bins.crend(), - std::back_inserter(energy_bins)); + std::copy(data::rev_energy_bins.crbegin(), data::rev_energy_bins.crend(), + std::back_inserter(data::energy_bins)); // Create average energies - for (int i = 0; i < energy_bins.size() - 1; ++i) { - energy_bin_avg.push_back(0.5*(energy_bins[i] + energy_bins[i+1])); + for (int i = 0; i < data::energy_bins.size() - 1; ++i) { + data::energy_bin_avg.push_back(0.5*(data::energy_bins[i] + data::energy_bins[i+1])); } // Add entries into libraries for MG data @@ -134,7 +138,7 @@ void calculate_xs_c(int i_mat, int gin, double sqrtkT, const double uvw[3], double& total_xs, double& abs_xs, double& nu_fiss_xs) { - macro_xs[i_mat - 1].calculate_xs(gin - 1, sqrtkT, uvw, total_xs, abs_xs, + data::macro_xs[i_mat - 1].calculate_xs(gin - 1, sqrtkT, uvw, total_xs, abs_xs, nu_fiss_xs); } @@ -159,7 +163,7 @@ get_nuclide_xs_c(int index, int xstype, int gin, int* gout, double* mu, int* dg) } else { dg_c_p = dg; } - return nuclides_MG[index - 1].get_xs(xstype, gin - 1, gout_c_p, mu, dg_c_p); + return data::nuclides_MG[index - 1].get_xs(xstype, gin - 1, gout_c_p, mu, dg_c_p); } //============================================================================== @@ -183,7 +187,7 @@ get_macro_xs_c(int index, int xstype, int gin, int* gout, double* mu, int* dg) } else { dg_c_p = dg; } - return macro_xs[index - 1].get_xs(xstype, gin - 1, gout_c_p, mu, dg_c_p); + return data::macro_xs[index - 1].get_xs(xstype, gin - 1, gout_c_p, mu, dg_c_p); } //============================================================================== @@ -192,7 +196,7 @@ void set_nuclide_angle_index_c(int index, const double uvw[3]) { // Update the values - nuclides_MG[index - 1].set_angle_index(uvw); + data::nuclides_MG[index - 1].set_angle_index(uvw); } //============================================================================== @@ -201,7 +205,7 @@ void set_macro_angle_index_c(int index, const double uvw[3]) { // Update the values - macro_xs[index - 1].set_angle_index(uvw); + data::macro_xs[index - 1].set_angle_index(uvw); } //============================================================================== @@ -210,7 +214,7 @@ void set_nuclide_temperature_index_c(int index, double sqrtkT) { // Update the values - nuclides_MG[index - 1].set_temperature_index(sqrtkT); + data::nuclides_MG[index - 1].set_temperature_index(sqrtkT); } //============================================================================== @@ -225,7 +229,7 @@ get_name_c(int index, int name_len, char* name) std::strcpy(name, str.c_str()); // Now get the data and copy to the C-string - str = nuclides_MG[index - 1].name; + str = data::nuclides_MG[index - 1].name; std::strcpy(name, str.c_str()); // Finally, remove the null terminator @@ -237,7 +241,7 @@ get_name_c(int index, int name_len, char* name) double get_awr_c(int index) { - return nuclides_MG[index - 1].awr; + return data::nuclides_MG[index - 1].awr; } } // namespace openmc diff --git a/src/particle.cpp b/src/particle.cpp index c8a5a1b56..f87ff3066 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -113,7 +113,7 @@ Particle::from_source(const Bank* src) } else { g = static_cast(src->E); last_g = static_cast(src->E); - E = energy_bin_avg[g - 1]; + E = data::energy_bin_avg[g - 1]; } last_E = E; } diff --git a/src/physics_mg.cpp b/src/physics_mg.cpp index 4ce64b61a..a4795f82a 100644 --- a/src/physics_mg.cpp +++ b/src/physics_mg.cpp @@ -21,14 +21,13 @@ namespace openmc { void -collision_mg(Particle* p, const double* energy_bin_avg, - const MaterialMacroXS* material_xs) +collision_mg(Particle* p, const MaterialMacroXS* material_xs) { // Add to the collision counter for the particle p->n_collision++; // Sample the reaction type - sample_reaction(p, energy_bin_avg, material_xs); + sample_reaction(p, material_xs); // Display information about collision if ((settings::verbosity >= 10) || (simulation::trace)) { @@ -39,8 +38,7 @@ collision_mg(Particle* p, const double* energy_bin_avg, } void -sample_reaction(Particle* p, const double* energy_bin_avg, - const MaterialMacroXS* material_xs) +sample_reaction(Particle* p, const MaterialMacroXS* material_xs) { // Create fission bank sites. Note that while a fission reaction is sampled, // it never actually "happens", i.e. the weight of the particle does not @@ -72,7 +70,7 @@ sample_reaction(Particle* p, const double* energy_bin_avg, if (!p->alive) return; // Sample a scattering event to determine the energy of the exiting neutron - scatter(p, energy_bin_avg); + scatter(p); // Play Russian roulette if survival biasing is turned on if (settings::survival_biasing) { @@ -82,14 +80,14 @@ sample_reaction(Particle* p, const double* energy_bin_avg, } void -scatter(Particle* p, const double* energy_bin_avg) +scatter(Particle* p) { // Adjust indices for Fortran to C++ indexing // TODO: Remove when no longer needed int gin = p->last_g - 1; int gout = p->g - 1; int i_mat = p->material - 1; - macro_xs[i_mat].sample_scatter(gin, gout, p->mu, p->wgt); + data::macro_xs[i_mat].sample_scatter(gin, gout, p->mu, p->wgt); // Adjust return value for fortran indexing // TODO: Remove when no longer needed @@ -99,7 +97,7 @@ scatter(Particle* p, const double* energy_bin_avg) rotate_angle_c(p->coord[0].uvw, p->mu, nullptr); // Update energy value for downstream compatability (in tallying) - p->E = energy_bin_avg[gout]; + p->E = data::energy_bin_avg[gout]; // Set event component p->event = EVENT_SCATTER; @@ -180,7 +178,7 @@ create_fission_sites(Particle* p, Bank* bank_array, int64_t* size_bank, // the energy in the fission bank int dg; int gout; - macro_xs[p->material - 1].sample_fission_energy(p->g - 1, dg, gout); + data::macro_xs[p->material - 1].sample_fission_energy(p->g - 1, dg, gout); bank_array[i].E = static_cast(gout + 1); bank_array[i].delayed_group = dg + 1; diff --git a/src/source.cpp b/src/source.cpp index 6610e7f4d..80bafe945 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -318,9 +318,9 @@ Bank sample_external_source() // If running in MG, convert site % E to group if (!settings::run_CE) { - site.E = lower_bound_index(rev_energy_bins.begin(), rev_energy_bins.end(), - site.E); - site.E = num_energy_groups - site.E; + site.E = lower_bound_index(data::rev_energy_bins.begin(), + data::rev_energy_bins.end(), site.E); + site.E = data::num_energy_groups - site.E; } // Set the random number generator back to the tracking stream. diff --git a/src/tallies/filter_energy.cpp b/src/tallies/filter_energy.cpp index 4c983b267..65339b519 100644 --- a/src/tallies/filter_energy.cpp +++ b/src/tallies/filter_energy.cpp @@ -25,10 +25,10 @@ EnergyFilter::from_xml(pugi::xml_node node) // (after flipping for the different ordering of the library and tallying // systems). if (!settings::run_CE) { - if (n_bins_ == num_energy_groups) { + if (n_bins_ == data::num_energy_groups) { matches_transport_groups_ = true; for (auto i = 0; i < n_bins_ + 1; i++) { - if (rev_energy_bins[i] != bins_[i]) { + if (data::rev_energy_bins[i] != bins_[i]) { matches_transport_groups_ = false; break; } @@ -44,10 +44,10 @@ const if (p->g != F90_NONE && matches_transport_groups_) { if (estimator == ESTIMATOR_TRACKLENGTH) { //TODO: off-by-one - match.bins_.push_back(num_energy_groups - p->g + 1); + match.bins_.push_back(data::num_energy_groups - p->g + 1); } else { //TODO: off-by-one - match.bins_.push_back(num_energy_groups - p->last_g + 1); + match.bins_.push_back(data::num_energy_groups - p->last_g + 1); } match.weights_.push_back(1.0); @@ -90,7 +90,7 @@ EnergyoutFilter::get_all_bins(const Particle* p, int estimator, FilterMatch& match) const { if (p->g != F90_NONE && matches_transport_groups_) { - match.bins_.push_back(num_energy_groups - p->g + 1); + match.bins_.push_back(data::num_energy_groups - p->g + 1); match.weights_.push_back(1.0); } else { diff --git a/src/tracking.F90 b/src/tracking.F90 index 038c7fdb5..e322f31f2 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -33,10 +33,9 @@ module tracking implicit none interface - subroutine collision_mg(p, energy_bin_avg, material_xs) bind(C) + subroutine collision_mg(p, material_xs) bind(C) import Particle, C_DOUBLE, MaterialMacroXS type(Particle), intent(inout) :: p - real(C_DOUBLE), intent(in) :: energy_bin_avg(*) type(MaterialMacroXS), intent(in) :: material_xs end subroutine collision_mg @@ -235,7 +234,7 @@ contains if (run_CE) then call collision(p) else - call collision_mg(p, energy_bin_avg, material_xs) + call collision_mg(p, material_xs) end if ! Score collision estimator tallies -- this is done after a collision From c9bd707f044c3fb2d4a4fddfeb101e0d61687169 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 8 Nov 2018 15:04:24 -0600 Subject: [PATCH 41/62] Namespace energy_min and energy_max --- include/openmc/nuclide.h | 4 ++++ src/finalize.cpp | 4 ++-- src/nuclide.cpp | 8 ++++++-- src/source.cpp | 6 +++--- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/include/openmc/nuclide.h b/include/openmc/nuclide.h index e3d43450d..db30a1a50 100644 --- a/include/openmc/nuclide.h +++ b/include/openmc/nuclide.h @@ -14,11 +14,15 @@ namespace openmc { // Global variables //============================================================================== +namespace data { + // Minimum/maximum transport energy for each particle type. Order corresponds to // that of the ParticleType enum extern std::array energy_min; extern std::array energy_max; +} // namespace data + //=============================================================================== //! Cached microscopic cross sections for a particular nuclide at the current //! energy diff --git a/src/finalize.cpp b/src/finalize.cpp index 7439e7bdb..5885470c1 100644 --- a/src/finalize.cpp +++ b/src/finalize.cpp @@ -75,8 +75,8 @@ int openmc_finalize() simulation::satisfy_triggers = false; simulation::total_gen = 0; - energy_max = {INFTY, INFTY}; - energy_min = {0.0, 0.0}; + data::energy_max = {INFTY, INFTY}; + data::energy_min = {0.0, 0.0}; n_tallies = 0; model::root_universe = -1; openmc_set_seed(DEFAULT_SEED); diff --git a/src/nuclide.cpp b/src/nuclide.cpp index 79e2289ae..18e7e5a7e 100644 --- a/src/nuclide.cpp +++ b/src/nuclide.cpp @@ -6,9 +6,13 @@ namespace openmc { // Global variables //============================================================================== +namespace data { + std::array energy_min {0.0, 0.0}; std::array energy_max {INFTY, INFTY}; +} // namespace data + //============================================================================== // Fortran compatibility functions //============================================================================== @@ -16,8 +20,8 @@ std::array energy_max {INFTY, INFTY}; extern "C" void set_particle_energy_bounds(int particle, double E_min, double E_max) { - energy_min[particle - 1] = E_min; - energy_max[particle - 1] = E_max; + data::energy_min[particle - 1] = E_min; + data::energy_max[particle - 1] = E_max; } } // namespace openmc diff --git a/src/source.cpp b/src/source.cpp index 80bafe945..1cb844ec9 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -207,10 +207,10 @@ Bank SourceDistribution::sample() const auto energy_ptr = dynamic_cast(energy_.get()); if (energy_ptr) { auto energies = xt::adapt(energy_ptr->x()); - if (xt::any(energies > energy_max[p-1])) { + if (xt::any(energies > data::energy_max[p-1])) { fatal_error("Source energy above range of energies of at least " "one cross section table"); - } else if (xt::any(energies < energy_min[p-1])) { + } else if (xt::any(energies < data::energy_min[p-1])) { fatal_error("Source energy below range of energies of at least " "one cross section table"); } @@ -221,7 +221,7 @@ Bank SourceDistribution::sample() const site.E = energy_->sample(); // Resample if energy falls outside minimum or maximum particle energy - if (site.E < energy_max[p-1] && site.E > energy_min[p-1]) break; + if (site.E < data::energy_max[p-1] && site.E > data::energy_min[p-1]) break; } // Set delayed group From 6393db8daa42b3d4f98dbd4212f1ad242ff3d194 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 8 Nov 2018 15:14:01 -0600 Subject: [PATCH 42/62] Put plots in model namespace --- include/openmc/capi.h | 1 - include/openmc/plot.h | 18 +++++++++--------- src/output.cpp | 2 +- src/plot.cpp | 25 ++++++++++++++----------- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/include/openmc/capi.h b/include/openmc/capi.h index ace061f54..a9c1a88f9 100644 --- a/include/openmc/capi.h +++ b/include/openmc/capi.h @@ -136,7 +136,6 @@ extern "C" { // Global variables extern char openmc_err_msg[256]; extern int n_nuclides; - extern int32_t n_plots; extern int32_t n_realizations; extern int32_t n_sab_tables; extern int32_t n_sources; diff --git a/include/openmc/plot.h b/include/openmc/plot.h index 64c092ce8..1096d2484 100644 --- a/include/openmc/plot.h +++ b/include/openmc/plot.h @@ -18,14 +18,14 @@ namespace openmc { // Global variables //=============================================================================== -extern int PLOT_LEVEL_LOWEST; //!< lower bound on plot universe level +class Plot; +namespace model { + +extern std::vector plots; //!< Plot instance container extern std::unordered_map plot_map; //!< map of plot ids to index -extern "C" int32_t n_plots; //!< number of plots in openmc run - -class Plot; -extern std::vector plots; //!< Plot instance container +} // namespace model //=============================================================================== // RGBColor holds color information for plotted objects @@ -124,8 +124,7 @@ void draw_mesh_lines(Plot pl, ImageData& data); //! Write a ppm image to file using a plot object's image data //! \param[in] plot object //! \param[out] image data associated with the plot object -void output_ppm(Plot pl, - const ImageData& data); +void output_ppm(Plot pl, const ImageData& data); //! Get the rgb color for a given particle position in a plot //! \param[in] particle with position for current pixel @@ -141,7 +140,7 @@ void position_rgb(Particle p, Plot pl, RGBColor& rgb, int& id); //! \param[out] dataset pointer to voxesl data //! \param[out] pointer to memory space of voxel data void voxel_init(hid_t file_id, const hsize_t* dims, hid_t* dspace, - hid_t* dset, hid_t* memspace); + hid_t* dset, hid_t* memspace); //! Write a section of the voxel data to hdf5 //! \param[in] voxel slice @@ -149,7 +148,8 @@ void voxel_init(hid_t file_id, const hsize_t* dims, hid_t* dspace, //! \param[out] dataset pointer to voxesl data //! \param[out] pointer to data to write void voxel_write_slice(int x, hid_t dspace, hid_t dset, - hid_t memspace, void* buf); + hid_t memspace, void* buf); + //! Close voxel file entities //! \param[in] data space to close //! \param[in] dataset to close diff --git a/src/output.cpp b/src/output.cpp index 6e07e2456..a3424a62f 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -62,7 +62,7 @@ void print_plot() { header("PLOTTING SUMMARY", 5); - for (auto pl : plots) { + for (auto pl : model::plots) { // Plot id std::cout << "Plot ID: " << pl.id_ << "\n"; // Plot filename diff --git a/src/plot.cpp b/src/plot.cpp index e372a678e..70dcd11b5 100644 --- a/src/plot.cpp +++ b/src/plot.cpp @@ -20,19 +20,23 @@ namespace openmc { +//============================================================================== +// Constants +//============================================================================== + +const RGBColor WHITE {255, 255, 255}; +constexpr int PLOT_LEVEL_LOWEST {-1}; //!< lower bound on plot universe level + //============================================================================== // Global variables //============================================================================== -int PLOT_LEVEL_LOWEST = -1; - -std::unordered_map plot_map; - -int n_plots; +namespace model { std::vector plots; +std::unordered_map plot_map; -const RGBColor WHITE = {255, 255, 255}; +} // namespace model //============================================================================== // RUN_PLOT controls the logic for making one or many plots @@ -43,7 +47,7 @@ int openmc_plot_geometry() { int err; - for (auto pl : plots) { + for (auto pl : model::plots) { std::stringstream ss; ss << "Processing plot " << pl.id_ << ": " << pl.path_plot_ << "..."; @@ -64,11 +68,10 @@ int openmc_plot_geometry() void read_plots(pugi::xml_node* plots_node) { - n_plots = 0; for (auto node : plots_node->children("plot")) { Plot pl(node); - plots.push_back(pl); - plot_map[pl.id_] = n_plots++; + model::plots.push_back(pl); + model::plot_map[pl.id_] = model::plots.size() - 1; } } @@ -156,7 +159,7 @@ Plot::set_id(pugi::xml_node plot_node) } // Check to make sure 'id' hasn't been used - if (plot_map.find(id_) != plot_map.end()) { + if (model::plot_map.find(id_) != model::plot_map.end()) { std::stringstream err_msg; err_msg << "Two or more plots use the same unique ID: " << id_; fatal_error(err_msg.str()); From 624e9875d6a487d356aed9fe1063093275e01119 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 8 Nov 2018 15:29:46 -0600 Subject: [PATCH 43/62] Namespacing for sources and surfaces --- include/openmc/capi.h | 2 - include/openmc/source.h | 18 ++++++--- include/openmc/surface.h | 8 ++-- src/cell.cpp | 10 ++--- src/dagmc.cpp | 6 +-- src/geometry.cpp | 6 +-- src/geometry_aux.cpp | 6 +-- src/settings.cpp | 6 +-- src/source.cpp | 18 +++++---- src/summary.cpp | 4 +- src/surface.cpp | 71 +++++++++++++++++----------------- src/tallies/filter_surface.cpp | 8 ++-- 12 files changed, 87 insertions(+), 76 deletions(-) diff --git a/include/openmc/capi.h b/include/openmc/capi.h index a9c1a88f9..fdea48e9e 100644 --- a/include/openmc/capi.h +++ b/include/openmc/capi.h @@ -138,9 +138,7 @@ extern "C" { extern int n_nuclides; extern int32_t n_realizations; extern int32_t n_sab_tables; - extern int32_t n_sources; extern int32_t n_tallies; - extern int32_t n_universes; // Variables that are shared by necessity (can be removed from public header // later) diff --git a/include/openmc/source.h b/include/openmc/source.h index efc6f12a6..45f4896b4 100644 --- a/include/openmc/source.h +++ b/include/openmc/source.h @@ -16,6 +16,18 @@ namespace openmc { +//============================================================================== +// Global variables +//============================================================================== + +class SourceDistribution; + +namespace model { + +extern std::vector external_sources; + +} // namespace model + //============================================================================== //! External source distribution //============================================================================== @@ -40,12 +52,6 @@ private: UPtrDist energy_; //!< Energy distribution }; -//============================================================================== -// Global variables -//============================================================================== - -extern std::vector external_sources; - //============================================================================== // Functions //============================================================================== diff --git a/include/openmc/surface.h b/include/openmc/surface.h index 23c3b61ec..d0ada79ea 100644 --- a/include/openmc/surface.h +++ b/include/openmc/surface.h @@ -32,13 +32,15 @@ extern "C" const int BC_PERIODIC; // Global variables //============================================================================== -extern "C" int32_t n_surfaces; - class Surface; -extern std::vector surfaces; +namespace model { + +extern std::vector surfaces; extern std::map surface_map; +} // namespace model + //============================================================================== //! Coordinates for an axis-aligned cube that bounds a geometric object. //============================================================================== diff --git a/src/cell.cpp b/src/cell.cpp index 5c341eb15..f30758b38 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -318,7 +318,7 @@ CSGCell::CSGCell(pugi::xml_node cell_node) // Convert user IDs to surface indices. for (auto& r : region_) { if (r < OP_UNION) { - r = copysign(surface_map[abs(r)] + 1, r); + r = copysign(model::surface_map[abs(r)] + 1, r); } } @@ -422,7 +422,7 @@ CSGCell::distance(Position r, Direction u, int32_t on_surface) const // Calculate the distance to this surface. // Note the off-by-one indexing bool coincident {token == on_surface}; - double d {surfaces[abs(token)-1]->distance(r, u, coincident)}; + double d {model::surfaces[abs(token)-1]->distance(r, u, coincident)}; // Check if this distance is the new minimum. if (d < min_dist) { @@ -468,7 +468,7 @@ CSGCell::to_hdf5(hid_t cell_group) const } else { // Note the off-by-one indexing region_spec << " " - << copysign(surfaces[abs(token)-1]->id_, token); + << copysign(model::surfaces[abs(token)-1]->id_, token); } } write_string(group, "region", region_spec.str(), false); @@ -531,7 +531,7 @@ CSGCell::contains_simple(Position r, Direction u, int32_t on_surface) const return false; } else { // Note the off-by-one indexing - bool sense = surfaces[abs(token)-1]->sense(r, u); + bool sense = model::surfaces[abs(token)-1]->sense(r, u); if (sense != (token > 0)) {return false;} } } @@ -573,7 +573,7 @@ CSGCell::contains_complex(Position r, Direction u, int32_t on_surface) const stack[i_stack] = false; } else { // Note the off-by-one indexing - bool sense = surfaces[abs(token)-1]->sense(r, u); + bool sense = model::surfaces[abs(token)-1]->sense(r, u); stack[i_stack] = (sense == (token > 0)); } } diff --git a/src/dagmc.cpp b/src/dagmc.cpp index e6f086605..11b169489 100644 --- a/src/dagmc.cpp +++ b/src/dagmc.cpp @@ -93,7 +93,7 @@ void load_dagmc_geometry() } // initialize surface objects - n_surfaces = model::DAG->num_entities(2); + int n_surfaces = model::DAG->num_entities(2); surfaces.resize(n_surfaces); for (int i = 0; i < n_surfaces; i++) { @@ -129,8 +129,8 @@ void load_dagmc_geometry() } // add to global array and map - surfaces[i] = s; - surface_map[s->id_] = s->id_; + model::surfaces[i] = s; + model::surface_map[s->id_] = s->id_; } return; diff --git a/src/geometry.cpp b/src/geometry.cpp index 87c61ebfa..fe3d52c68 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -79,9 +79,9 @@ find_cell(Particle* p, int search_surf) { // the positive or negative side of the surface should be searched. const std::vector* search_cells; if (search_surf > 0) { - search_cells = &surfaces[search_surf-1]->neighbor_pos_; + search_cells = &model::surfaces[search_surf-1]->neighbor_pos_; } else if (search_surf < 0) { - search_cells = &surfaces[-search_surf-1]->neighbor_neg_; + search_cells = &model::surfaces[-search_surf-1]->neighbor_neg_; } else { // No surface was indicated, search all cells in the universe. search_cells = &model::universes[i_universe]->cells_; @@ -390,7 +390,7 @@ distance_to_boundary(Particle* p, double* dist, int* surface_crossed, *surface_crossed = level_surf_cross; } else { Position r_hit = r + d_surf * u; - Surface& surf {*surfaces[std::abs(level_surf_cross)-1]}; + Surface& surf {*model::surfaces[std::abs(level_surf_cross)-1]}; Direction norm = surf.normal(r_hit); if (u.dot(norm) > 0) { *surface_crossed = std::abs(level_surf_cross); diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index 52d0ae92a..8ebb70eb7 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -167,14 +167,14 @@ neighbor_lists() // This token is a surface index. Add the cell to the surface's list. if (token > 0) { - surfaces[std::abs(token)-1]->neighbor_pos_.push_back(i); + model::surfaces[std::abs(token)-1]->neighbor_pos_.push_back(i); } else { - surfaces[std::abs(token)-1]->neighbor_neg_.push_back(i); + model::surfaces[std::abs(token)-1]->neighbor_neg_.push_back(i); } } } - for (Surface* surf : surfaces) { + for (Surface* surf : model::surfaces) { surf->neighbor_pos_.shrink_to_fit(); surf->neighbor_neg_.shrink_to_fit(); } diff --git a/src/settings.cpp b/src/settings.cpp index b5bb4fe80..36657c6c6 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -416,17 +416,17 @@ void read_settings_xml() // Get point to list of elements and make sure there is at least one for (pugi::xml_node node : root.children("source")) { - external_sources.emplace_back(node); + model::external_sources.emplace_back(node); } // If no source specified, default to isotropic point source at origin with Watt spectrum - if (external_sources.empty()) { + if (model::external_sources.empty()) { SourceDistribution source { UPtrSpace{new SpatialPoint({0.0, 0.0, 0.0})}, UPtrAngle{new Isotropic()}, UPtrDist{new Watt(0.988, 2.249e-6)} }; - external_sources.push_back(std::move(source)); + model::external_sources.push_back(std::move(source)); } // Check if we want to write out source diff --git a/src/source.cpp b/src/source.cpp index 1cb844ec9..6d071c0c7 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -27,8 +27,12 @@ namespace openmc { // Global variables //============================================================================== +namespace model { + std::vector external_sources; +} + //============================================================================== // SourceDistribution implementation //============================================================================== @@ -299,22 +303,22 @@ Bank sample_external_source() // Determine total source strength double total_strength = 0.0; - for (auto& s : external_sources) + for (auto& s : model::external_sources) total_strength += s.strength(); // Sample from among multiple source distributions int i = 0; - if (external_sources.size() > 1) { + if (model::external_sources.size() > 1) { double xi = prn()*total_strength; double c = 0.0; - for (; i < external_sources.size(); ++i) { - c += external_sources[i].strength(); + for (; i < model::external_sources.size(); ++i) { + c += model::external_sources[i].strength(); if (xi < c) break; } } // Sample source site from i-th source distribution - Bank site {external_sources[i].sample()}; + Bank site {model::external_sources[i].sample()}; // If running in MG, convert site % E to group if (!settings::run_CE) { @@ -335,13 +339,13 @@ Bank sample_external_source() extern "C" void free_memory_source() { - external_sources.clear(); + model::external_sources.clear(); } extern "C" double total_source_strength() { double strength = 0.0; - for (const auto& s : external_sources) { + for (const auto& s : model::external_sources) { strength += s.strength(); } return strength; diff --git a/src/summary.cpp b/src/summary.cpp index 185ad9cce..398f304fb 100644 --- a/src/summary.cpp +++ b/src/summary.cpp @@ -19,7 +19,7 @@ write_geometry(hid_t file_id) { #endif write_attribute(geom_group, "n_cells", model::cells.size()); - write_attribute(geom_group, "n_surfaces", surfaces.size()); + write_attribute(geom_group, "n_surfaces", model::surfaces.size()); write_attribute(geom_group, "n_universes", model::universes.size()); write_attribute(geom_group, "n_lattices", model::lattices.size()); @@ -28,7 +28,7 @@ write_geometry(hid_t file_id) { close_group(cells_group); auto surfaces_group = create_group(geom_group, "surfaces"); - for (Surface* surf : surfaces) surf->to_hdf5(surfaces_group); + for (Surface* surf : model::surfaces) surf->to_hdf5(surfaces_group); close_group(surfaces_group); auto universes_group = create_group(geom_group, "universes"); diff --git a/src/surface.cpp b/src/surface.cpp index 66217a58b..806a2b92d 100644 --- a/src/surface.cpp +++ b/src/surface.cpp @@ -25,12 +25,13 @@ extern "C" const int BC_PERIODIC {3}; // Global variables //============================================================================== -int32_t n_surfaces; +namespace model { std::vector surfaces; - std::map surface_map; +} // namespace model + //============================================================================== // Helper functions for reading the "coeffs" node of an XML surface element //============================================================================== @@ -1063,13 +1064,14 @@ extern "C" void read_surfaces(pugi::xml_node* node) { // Count the number of surfaces. - for (pugi::xml_node surf_node: node->children("surface")) {n_surfaces++;} + int n_surfaces = 0; + for (pugi::xml_node surf_node : node->children("surface")) {n_surfaces++;} if (n_surfaces == 0) { fatal_error("No surfaces found in geometry.xml!"); } // Loop over XML surface elements and populate the array. - surfaces.reserve(n_surfaces); + model::surfaces.reserve(n_surfaces); { pugi::xml_node surf_node; int i_surf; @@ -1078,40 +1080,40 @@ read_surfaces(pugi::xml_node* node) std::string surf_type = get_node_value(surf_node, "type", true, true); if (surf_type == "x-plane") { - surfaces.push_back(new SurfaceXPlane(surf_node)); + model::surfaces.push_back(new SurfaceXPlane(surf_node)); } else if (surf_type == "y-plane") { - surfaces.push_back(new SurfaceYPlane(surf_node)); + model::surfaces.push_back(new SurfaceYPlane(surf_node)); } else if (surf_type == "z-plane") { - surfaces.push_back(new SurfaceZPlane(surf_node)); + model::surfaces.push_back(new SurfaceZPlane(surf_node)); } else if (surf_type == "plane") { - surfaces.push_back(new SurfacePlane(surf_node)); + model::surfaces.push_back(new SurfacePlane(surf_node)); } else if (surf_type == "x-cylinder") { - surfaces.push_back(new SurfaceXCylinder(surf_node)); + model::surfaces.push_back(new SurfaceXCylinder(surf_node)); } else if (surf_type == "y-cylinder") { - surfaces.push_back(new SurfaceYCylinder(surf_node)); + model::surfaces.push_back(new SurfaceYCylinder(surf_node)); } else if (surf_type == "z-cylinder") { - surfaces.push_back(new SurfaceZCylinder(surf_node)); + model::surfaces.push_back(new SurfaceZCylinder(surf_node)); } else if (surf_type == "sphere") { - surfaces.push_back(new SurfaceSphere(surf_node)); + model::surfaces.push_back(new SurfaceSphere(surf_node)); } else if (surf_type == "x-cone") { - surfaces.push_back(new SurfaceXCone(surf_node)); + model::surfaces.push_back(new SurfaceXCone(surf_node)); } else if (surf_type == "y-cone") { - surfaces.push_back(new SurfaceYCone(surf_node)); + model::surfaces.push_back(new SurfaceYCone(surf_node)); } else if (surf_type == "z-cone") { - surfaces.push_back(new SurfaceZCone(surf_node)); + model::surfaces.push_back(new SurfaceZCone(surf_node)); } else if (surf_type == "quadric") { - surfaces.push_back(new SurfaceQuadric(surf_node)); + model::surfaces.push_back(new SurfaceQuadric(surf_node)); } else { std::stringstream err_msg; @@ -1122,11 +1124,11 @@ read_surfaces(pugi::xml_node* node) } // Fill the surface map. - for (int i_surf = 0; i_surf < n_surfaces; i_surf++) { - int id = surfaces[i_surf]->id_; - auto in_map = surface_map.find(id); - if (in_map == surface_map.end()) { - surface_map[id] = i_surf; + for (int i_surf = 0; i_surf < model::surfaces.size(); i_surf++) { + int id = model::surfaces[i_surf]->id_; + auto in_map = model::surface_map.find(id); + if (in_map == model::surface_map.end()) { + model::surface_map[id] = i_surf; } else { std::stringstream err_msg; err_msg << "Two or more surfaces use the same unique ID: " << id; @@ -1138,10 +1140,10 @@ read_surfaces(pugi::xml_node* node) double xmin {INFTY}, xmax {-INFTY}, ymin {INFTY}, ymax {-INFTY}, zmin {INFTY}, zmax {-INFTY}; int i_xmin, i_xmax, i_ymin, i_ymax, i_zmin, i_zmax; - for (int i_surf = 0; i_surf < n_surfaces; i_surf++) { - if (surfaces[i_surf]->bc_ == BC_PERIODIC) { + for (int i_surf = 0; i_surf < model::surfaces.size(); i_surf++) { + if (model::surfaces[i_surf]->bc_ == BC_PERIODIC) { // Downcast to the PeriodicSurface type. - Surface* surf_base = surfaces[i_surf]; + Surface* surf_base = model::surfaces[i_surf]; PeriodicSurface* surf = dynamic_cast(surf_base); // Make sure this surface inherits from PeriodicSurface. @@ -1183,10 +1185,10 @@ read_surfaces(pugi::xml_node* node) } // Set i_periodic for periodic BC surfaces. - for (int i_surf = 0; i_surf < n_surfaces; i_surf++) { - if (surfaces[i_surf]->bc_ == BC_PERIODIC) { + for (int i_surf = 0; i_surf < model::surfaces.size(); i_surf++) { + if (model::surfaces[i_surf]->bc_ == BC_PERIODIC) { // Downcast to the PeriodicSurface type. - Surface* surf_base = surfaces[i_surf]; + Surface* surf_base = model::surfaces[i_surf]; PeriodicSurface* surf = dynamic_cast(surf_base); // Also try downcasting to the SurfacePlane type (which must be handled @@ -1216,7 +1218,7 @@ read_surfaces(pugi::xml_node* node) } } else { // Convert the surface id to an index. - surf->i_periodic_ = surface_map[surf->i_periodic_]; + surf->i_periodic_ = model::surface_map[surf->i_periodic_]; } } else { // This is a SurfacePlane. We won't try to find it's partner if the @@ -1228,12 +1230,12 @@ read_surfaces(pugi::xml_node* node) fatal_error(err_msg); } else { // Convert the surface id to an index. - surf->i_periodic_ = surface_map[surf->i_periodic_]; + surf->i_periodic_ = model::surface_map[surf->i_periodic_]; } } // Make sure the opposite surface is also periodic. - if (surfaces[surf->i_periodic_]->bc_ != BC_PERIODIC) { + if (model::surfaces[surf->i_periodic_]->bc_ != BC_PERIODIC) { std::stringstream err_msg; err_msg << "Could not find matching surface for periodic boundary " "condition on surface " << surf->id_; @@ -1248,7 +1250,7 @@ read_surfaces(pugi::xml_node* node) //============================================================================== extern "C" { - Surface* surface_pointer(int surf_ind) {return surfaces[surf_ind];} + Surface* surface_pointer(int surf_ind) {return model::surfaces[surf_ind];} int surface_id(Surface* surf) {return surf->id_;} @@ -1288,10 +1290,9 @@ extern "C" { void free_memory_surfaces_c() { - for (Surface* surf : surfaces) {delete surf;} - surfaces.clear(); - n_surfaces = 0; - surface_map.clear(); + for (Surface* surf : model::surfaces) {delete surf;} + model::surfaces.clear(); + model::surface_map.clear(); } } diff --git a/src/tallies/filter_surface.cpp b/src/tallies/filter_surface.cpp index 5458d2051..5b175ca70 100644 --- a/src/tallies/filter_surface.cpp +++ b/src/tallies/filter_surface.cpp @@ -20,8 +20,8 @@ SurfaceFilter::initialize() { // Convert surface IDs to indices of the global array. for (auto& s : surfaces_) { - auto search = surface_map.find(s); - if (search != surface_map.end()) { + auto search = model::surface_map.find(s); + if (search != model::surface_map.end()) { s = search->second; } else { std::stringstream err_msg; @@ -58,7 +58,7 @@ SurfaceFilter::to_statepoint(hid_t filter_group) const { Filter::to_statepoint(filter_group); std::vector surface_ids; - for (auto c : surfaces_) surface_ids.push_back(surfaces[c]->id_); + for (auto c : surfaces_) surface_ids.push_back(model::surfaces[c]->id_); write_dataset(filter_group, "bins", surface_ids); } @@ -66,7 +66,7 @@ std::string SurfaceFilter::text_label(int bin) const { //TODO: off-by-one - return "Surface " + std::to_string(surfaces[surfaces_[bin-1]]->id_); + return "Surface " + std::to_string(model::surfaces[surfaces_[bin-1]]->id_); } } // namespace openmc From a63a89f9d65bca3e73b899a8601e2a4bb314a8fd Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 8 Nov 2018 15:36:19 -0600 Subject: [PATCH 44/62] Put timers in simulation namespace --- include/openmc/timer.h | 36 +++++++++++--------- src/eigenvalue.cpp | 12 +++---- src/initialize.cpp | 6 ++-- src/simulation.cpp | 22 ++++++------- src/timer.cpp | 74 ++++++++++++++++++++++-------------------- 5 files changed, 80 insertions(+), 70 deletions(-) diff --git a/include/openmc/timer.h b/include/openmc/timer.h index 48b3a9e75..8fbcee46b 100644 --- a/include/openmc/timer.h +++ b/include/openmc/timer.h @@ -5,6 +5,27 @@ namespace openmc { +//============================================================================== +// Global variables +//============================================================================== + +class Timer; + +namespace simulation { + +extern Timer time_active; +extern Timer time_bank; +extern Timer time_bank_sample; +extern Timer time_bank_sendrecv; +extern Timer time_finalize; +extern Timer time_inactive; +extern Timer time_initialize; +extern Timer time_tallies; +extern Timer time_total; +extern Timer time_transport; + +} // namespace simulation + //============================================================================== //! Class for measuring time elapsed //============================================================================== @@ -34,21 +55,6 @@ private: double elapsed_ {0.0}; //!< elasped time in [s] }; -//============================================================================== -// Global variables -//============================================================================== - -extern Timer time_active; -extern Timer time_bank; -extern Timer time_bank_sample; -extern Timer time_bank_sendrecv; -extern Timer time_finalize; -extern Timer time_inactive; -extern Timer time_initialize; -extern Timer time_tallies; -extern Timer time_total; -extern Timer time_transport; - //============================================================================== // Non-member functions //============================================================================== diff --git a/src/eigenvalue.cpp b/src/eigenvalue.cpp index 4d9196ea0..64e0c4e42 100644 --- a/src/eigenvalue.cpp +++ b/src/eigenvalue.cpp @@ -67,7 +67,7 @@ void calculate_generation_keff() void synchronize_bank() { - time_bank.start(); + simulation::time_bank.start(); // Get pointers to source/fission bank Bank* source_bank; @@ -131,7 +131,7 @@ void synchronize_bank() } double p_sample = static_cast(sites_needed) / total; - time_bank_sample.start(); + simulation::time_bank_sample.start(); // ========================================================================== // SAMPLE N_PARTICLES FROM FISSION BANK AND PLACE IN TEMP_SITES @@ -204,8 +204,8 @@ void synchronize_bank() finish = simulation::work_index[mpi::rank + 1]; } - time_bank_sample.stop(); - time_bank_sendrecv.start(); + simulation::time_bank_sample.stop(); + simulation::time_bank_sendrecv.start(); #ifdef OPENMC_MPI // ========================================================================== @@ -303,8 +303,8 @@ void synchronize_bank() std::copy(temp_sites.data(), temp_sites.data() + settings::n_particles, source_bank); #endif - time_bank_sendrecv.stop(); - time_bank.stop(); + simulation::time_bank_sendrecv.stop(); + simulation::time_bank.stop(); } void calculate_average_keff() diff --git a/src/initialize.cpp b/src/initialize.cpp index 2250a6ac8..3a4a3a480 100644 --- a/src/initialize.cpp +++ b/src/initialize.cpp @@ -54,8 +54,8 @@ int openmc_init(int argc, char* argv[], const void* intracomm) if (err) return err; // Start total and initialization timer - time_total.start(); - time_initialize.start(); + simulation::time_total.start(); + simulation::time_initialize.start(); #ifdef _OPENMP // If OMP_SCHEDULE is not set, default to a static schedule @@ -79,7 +79,7 @@ int openmc_init(int argc, char* argv[], const void* intracomm) if (settings::particle_restart_run) settings::run_mode = RUN_MODE_PARTICLE; // Stop initialization timer - time_initialize.stop(); + simulation::time_initialize.stop(); return 0; } diff --git a/src/simulation.cpp b/src/simulation.cpp index 55b825a18..b1b657623 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -139,8 +139,8 @@ int openmc_simulation_finalize() if (!simulation::initialized) return 0; // Stop active batch timer and start finalization timer - time_active.stop(); - time_finalize.start(); + simulation::time_active.stop(); + simulation::time_finalize.start(); #pragma omp parallel { @@ -166,8 +166,8 @@ int openmc_simulation_finalize() } // Stop timers and show timing statistics - time_finalize.stop(); - time_total.stop(); + simulation::time_finalize.stop(); + simulation::time_total.stop(); if (mpi::master) { if (settings::verbosity >= 6) print_runtime(); if (settings::verbosity >= 4) print_results(); @@ -200,7 +200,7 @@ int openmc_next_batch(int* status) initialize_generation(); // Start timer for transport - time_transport.start(); + simulation::time_transport.start(); // ==================================================================== // LOOP OVER PARTICLES @@ -218,7 +218,7 @@ int openmc_next_batch(int* status) } // Accumulate time for transport - time_transport.stop(); + simulation::time_transport.stop(); finalize_generation(); } @@ -305,10 +305,10 @@ void initialize_batch() // Manage active/inactive timers and activate tallies if necessary. if (first_inactive) { - time_inactive.start(); + simulation::time_inactive.start(); } else if (first_active) { - time_inactive.stop(); - time_active.start(); + simulation::time_inactive.stop(); + simulation::time_active.start(); for (int i = 1; i <= n_tallies; ++i) { // TODO: change one-based index openmc_tally_set_active(i, true); @@ -327,9 +327,9 @@ void initialize_batch() void finalize_batch() { // Reduce tallies onto master process and accumulate - time_tallies.start(); + simulation::time_tallies.start(); accumulate_tallies(); - time_tallies.stop(); + simulation::time_tallies.stop(); // Reset global tally results if (simulation::current_batch <= settings::n_inactive) { diff --git a/src/timer.cpp b/src/timer.cpp index f1c211446..7dab802b0 100644 --- a/src/timer.cpp +++ b/src/timer.cpp @@ -2,6 +2,25 @@ namespace openmc { +//============================================================================== +// Global variables +//============================================================================== + +namespace simulation { + +Timer time_active; +Timer time_bank; +Timer time_bank_sample; +Timer time_bank_sendrecv; +Timer time_finalize; +Timer time_inactive; +Timer time_initialize; +Timer time_tallies; +Timer time_total; +Timer time_transport; + +} // namespace simulation + //============================================================================== // Timer implementation //============================================================================== @@ -34,35 +53,20 @@ double Timer::elapsed() } } -//============================================================================== -// Global variables -//============================================================================== - -Timer time_active; -Timer time_bank; -Timer time_bank_sample; -Timer time_bank_sendrecv; -Timer time_finalize; -Timer time_inactive; -Timer time_initialize; -Timer time_tallies; -Timer time_total; -Timer time_transport; - //============================================================================== // Fortran compatibility //============================================================================== -extern "C" double time_active_elapsed() { return time_active.elapsed(); } -extern "C" double time_bank_elapsed() { return time_bank.elapsed(); } -extern "C" double time_bank_sample_elapsed() { return time_bank_sample.elapsed(); } -extern "C" double time_bank_sendrecv_elapsed() { return time_bank_sendrecv.elapsed(); } -extern "C" double time_finalize_elapsed() { return time_finalize.elapsed(); } -extern "C" double time_inactive_elapsed() { return time_inactive.elapsed(); } -extern "C" double time_initialize_elapsed() { return time_initialize.elapsed(); } -extern "C" double time_tallies_elapsed() { return time_tallies.elapsed(); } -extern "C" double time_total_elapsed() { return time_total.elapsed(); } -extern "C" double time_transport_elapsed() { return time_transport.elapsed(); } +extern "C" double time_active_elapsed() { return simulation::time_active.elapsed(); } +extern "C" double time_bank_elapsed() { return simulation::time_bank.elapsed(); } +extern "C" double time_bank_sample_elapsed() { return simulation::time_bank_sample.elapsed(); } +extern "C" double time_bank_sendrecv_elapsed() { return simulation::time_bank_sendrecv.elapsed(); } +extern "C" double time_finalize_elapsed() { return simulation::time_finalize.elapsed(); } +extern "C" double time_inactive_elapsed() { return simulation::time_inactive.elapsed(); } +extern "C" double time_initialize_elapsed() { return simulation::time_initialize.elapsed(); } +extern "C" double time_tallies_elapsed() { return simulation::time_tallies.elapsed(); } +extern "C" double time_total_elapsed() { return simulation::time_total.elapsed(); } +extern "C" double time_transport_elapsed() { return simulation::time_transport.elapsed(); } //============================================================================== // Non-member functions @@ -70,16 +74,16 @@ extern "C" double time_transport_elapsed() { return time_transport.elapsed(); } void reset_timers() { - time_active.reset(); - time_bank.reset(); - time_bank_sample.reset(); - time_bank_sendrecv.reset(); - time_finalize.reset(); - time_inactive.reset(); - time_initialize.reset(); - time_tallies.reset(); - time_total.reset(); - time_transport.reset(); + simulation::time_active.reset(); + simulation::time_bank.reset(); + simulation::time_bank_sample.reset(); + simulation::time_bank_sendrecv.reset(); + simulation::time_finalize.reset(); + simulation::time_inactive.reset(); + simulation::time_initialize.reset(); + simulation::time_tallies.reset(); + simulation::time_total.reset(); + simulation::time_transport.reset(); } } // namespace openmc From 24613a6799cdc1805a596133869e47171efbcdc0 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 8 Nov 2018 15:46:06 -0600 Subject: [PATCH 45/62] Namespace filter_matches and tally_filters --- include/openmc/tallies/filter.h | 9 +++++- src/geometry_aux.cpp | 2 +- src/simulation.cpp | 4 +-- src/tallies/filter.cpp | 57 ++++++++++++++++++--------------- 4 files changed, 42 insertions(+), 30 deletions(-) diff --git a/include/openmc/tallies/filter.h b/include/openmc/tallies/filter.h index 24ce5cb89..5590a0767 100644 --- a/include/openmc/tallies/filter.h +++ b/include/openmc/tallies/filter.h @@ -77,13 +77,20 @@ public: // Global variables //============================================================================== -extern "C" int32_t n_filters; +namespace simulation { extern std::vector filter_matches; #pragma omp threadprivate(filter_matches) +} // namespace simulation + +namespace model { + +extern "C" int32_t n_filters; extern std::vector> tally_filters; +} // namespace model + //============================================================================== extern "C" void free_memory_tally_c(); diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index 8ebb70eb7..c326744eb 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -187,7 +187,7 @@ prepare_distribcell() { // Find all cells listed in a DistribcellFilter. std::unordered_set distribcells; - for (auto& filt : tally_filters) { + for (auto& filt : model::tally_filters) { auto* distrib_filt = dynamic_cast(filt.get()); if (distrib_filt) { distribcells.insert(distrib_filt->cell_); diff --git a/src/simulation.cpp b/src/simulation.cpp index b1b657623..df7897d3f 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -81,7 +81,7 @@ int openmc_simulation_init() // Allocate array for matching filter bins #pragma omp parallel { - filter_matches.resize(n_filters); + simulation::filter_matches.resize(model::tally_filters.size()); } // Set up tally procedure pointers @@ -144,7 +144,7 @@ int openmc_simulation_finalize() #pragma omp parallel { - filter_matches.clear(); + simulation::filter_matches.clear(); } // Deallocate Fortran variables, set tallies to inactive diff --git a/src/tallies/filter.cpp b/src/tallies/filter.cpp index ef4ab345d..aa5d19607 100644 --- a/src/tallies/filter.cpp +++ b/src/tallies/filter.cpp @@ -33,8 +33,13 @@ namespace openmc { // Global variables //============================================================================== +namespace simulation { std::vector filter_matches; +} // namespace simulation + +namespace model { std::vector> tally_filters; +} // namespace model //============================================================================== // Non-member functions @@ -45,10 +50,10 @@ free_memory_tally_c() { #pragma omp parallel { - filter_matches.clear(); + simulation::filter_matches.clear(); } - tally_filters.clear(); + model::tally_filters.clear(); } //============================================================================== @@ -57,7 +62,7 @@ free_memory_tally_c() extern "C" { FilterMatch* filter_match_pointer(int indx) - {return &filter_matches[indx];} + {return &simulation::filter_matches[indx];} void filter_match_bins_push_back(FilterMatch* match, int val) @@ -96,53 +101,53 @@ extern "C" { { std::string type_ {type}; if (type_ == "azimuthal") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "cell") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "cellborn") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "cellfrom") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "distribcell") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "delayedgroup") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "energyfunction") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "energy") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "energyout") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "legendre") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "material") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "mesh") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "meshsurface") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "mu") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "particle") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "polar") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "surface") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "spatiallegendre") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "sphericalharmonics") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "universe") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "zernike") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else if (type_ == "zernikeradial") { - tally_filters.push_back(std::make_unique()); + model::tally_filters.push_back(std::make_unique()); } else { return nullptr; } - return tally_filters.back().get(); + return model::tally_filters.back().get(); } void filter_from_xml(Filter* filt, pugi::xml_node* node) From 62cc2519143042d65176a506fbe2b38a586b6b29 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 9 Nov 2018 07:00:15 -0600 Subject: [PATCH 46/62] Fix use of n_surfaces on Fortran side --- src/cell.cpp | 6 ++++-- src/dagmc.cpp | 8 +++++--- src/input_xml.F90 | 8 ++++---- src/output.cpp | 2 +- src/surface.cpp | 2 ++ src/surface_header.F90 | 9 +++++++-- 6 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/cell.cpp b/src/cell.cpp index f30758b38..c3d806aef 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -649,7 +649,7 @@ read_cells(pugi::xml_node* node) // Loop over XML cell elements and populate the array. model::cells.reserve(model::n_cells); - for (pugi::xml_node cell_node: node->children("cell")) { + for (pugi::xml_node cell_node : node->children("cell")) { model::cells.push_back(new CSGCell(cell_node)); } @@ -682,7 +682,9 @@ read_cells(pugi::xml_node* node) model::universes.shrink_to_fit(); // Allocate the cell overlap count if necessary. - if (settings::check_overlaps) model::overlap_check_count.resize(model::n_cells, 0); + if (settings::check_overlaps) { + model::overlap_check_count.resize(model::cells.size(), 0); + } } //============================================================================== diff --git a/src/dagmc.cpp b/src/dagmc.cpp index 11b169489..b5f327d06 100644 --- a/src/dagmc.cpp +++ b/src/dagmc.cpp @@ -41,9 +41,6 @@ void load_dagmc_geometry() // initialize cell objects model::n_cells = model::DAG->num_entities(3); - // Allocate the cell overlap count if necessary. - if (settings::check_overlaps) model::overlap_check_count.resize(model::n_cells, 0); - for (int i = 0; i < model::n_cells; i++) { moab::EntityHandle vol_handle = model::DAG->entity_by_index(3, i+1); @@ -92,6 +89,11 @@ void load_dagmc_geometry() } } + // Allocate the cell overlap count if necessary. + if (settings::check_overlaps) { + model::overlap_check_count.resize(model::cells.size(), 0); + } + // initialize surface objects int n_surfaces = model::DAG->num_entities(2); surfaces.resize(n_surfaces); diff --git a/src/input_xml.F90 b/src/input_xml.F90 index e2bf633b0..1da1bf9df 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -347,8 +347,8 @@ contains call read_surfaces(root % ptr) ! Allocate surfaces array - allocate(surfaces(n_surfaces)) - do i = 1, n_surfaces + allocate(surfaces(surfaces_size())) + do i = 1, size(surfaces) surfaces(i) % ptr = surface_pointer(i - 1); if (surfaces(i) % bc() /= BC_TRANSMIT) boundary_exists = .true. @@ -505,9 +505,9 @@ contains integer :: i ! Allocate surfaces array - allocate(surfaces(n_surfaces)) + allocate(surfaces(surfaces_size())) - do i = 1, n_surfaces + do i = 1, size(surfaces) surfaces(i) % ptr = surface_pointer(i - 1); end do diff --git a/src/output.cpp b/src/output.cpp index a3424a62f..1b197a29e 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -140,7 +140,7 @@ print_overlap_check() { std::cout << " Cell ID No. Overlap Checks\n"; std::vector sparse_cell_ids; - for (int i = 0; i < model::n_cells; i++) { + for (int i = 0; i < model::cells.size(); i++) { std::cout << " " << std::setw(8) << model::cells[i]->id_ << std::setw(17) << model::overlap_check_count[i] << "\n"; if (model::overlap_check_count[i] < 10) { diff --git a/src/surface.cpp b/src/surface.cpp index 806a2b92d..3ffbb3277 100644 --- a/src/surface.cpp +++ b/src/surface.cpp @@ -1294,6 +1294,8 @@ extern "C" { model::surfaces.clear(); model::surface_map.clear(); } + + int surfaces_size() { return model::surfaces.size(); } } } // namespace openmc diff --git a/src/surface_header.F90 b/src/surface_header.F90 index a2ef9c056..17f9515f3 100644 --- a/src/surface_header.F90 +++ b/src/surface_header.F90 @@ -78,10 +78,15 @@ module surface_header end type Surface - integer(C_INT32_T), bind(C) :: n_surfaces ! # of surfaces - type(Surface), allocatable, target :: surfaces(:) + interface + function surfaces_size() result(sz) bind(C) + import C_INT + integer(C_INT) :: sz + end function + end interface + contains pure function surface_id(this) result(id) From 5d4c39cc7dc0514a53ae12b2a615a567a9076faf Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 9 Nov 2018 07:39:26 -0600 Subject: [PATCH 47/62] Call openmc_reset during openmc_simulation_init --- src/simulation.cpp | 5 +++-- src/tallies/tally_header.F90 | 13 +++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/simulation.cpp b/src/simulation.cpp index df7897d3f..c3d1c17b4 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -25,10 +25,10 @@ extern "C" bool cmfd_on; extern "C" void accumulate_tallies(); extern "C" void allocate_banks(); +extern "C" void allocate_tally_results(); extern "C" void check_triggers(); extern "C" void cmfd_init_batch(); extern "C" void cmfd_tally_init(); -extern "C" void configure_tallies(); extern "C" void execute_cmfd(); extern "C" void init_tally_routines(); extern "C" void join_bank_from_threads(); @@ -92,7 +92,7 @@ int openmc_simulation_init() allocate_banks(); // Allocate tally results arrays if they're not allocated yet - configure_tallies(); + allocate_tally_results(); // Activate the CMFD tallies cmfd_tally_init(); @@ -106,6 +106,7 @@ int openmc_simulation_init() simulation::k_generation.clear(); simulation::entropy.clear(); simulation::need_depletion_rx = false; + openmc_reset(); // If this is a restart run, load the state point data and binary source // file diff --git a/src/tallies/tally_header.F90 b/src/tallies/tally_header.F90 index 0b80255d5..08d3588a5 100644 --- a/src/tallies/tally_header.F90 +++ b/src/tallies/tally_header.F90 @@ -17,7 +17,7 @@ module tally_header implicit none private - public :: configure_tallies + public :: allocate_tally_results public :: free_memory_tally public :: openmc_extend_tallies public :: openmc_get_tally_index @@ -275,9 +275,6 @@ contains allocate(this % results(3, this % total_score_bins, this % n_filter_bins)) end if - ! Initialize results array to zero - this % results(:,:,:) = ZERO - end subroutine tally_allocate_results @@ -392,21 +389,21 @@ contains ! tallies.xml file. !=============================================================================== - subroutine configure_tallies() bind(C) + subroutine allocate_tally_results() bind(C) integer :: i - ! Allocate and initialize global tallies + ! Allocate global tallies if (.not. allocated(global_tallies)) then allocate(global_tallies(3, N_GLOBAL_TALLIES)) end if - global_tallies(:,:) = ZERO + ! Allocate results arrays for tallies do i = 1, n_tallies call tallies(i) % obj % allocate_results() end do - end subroutine configure_tallies + end subroutine allocate_tally_results !=============================================================================== ! FREE_MEMORY_TALLY deallocates global arrays defined in this module From 0bf2d0c4a9559561fc63c458d779946f0d759cb1 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 9 Nov 2018 07:56:14 -0600 Subject: [PATCH 48/62] Make sure Tally % n_realizations is available on all ranks --- src/tallies/tally.F90 | 10 +++++----- src/tallies/tally_header.F90 | 36 +++++++++++++++++++----------------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/tallies/tally.F90 b/src/tallies/tally.F90 index 475c6a60c..b82837ea1 100644 --- a/src/tallies/tally.F90 +++ b/src/tallies/tally.F90 @@ -3792,11 +3792,6 @@ contains ! Accumulate on master only unless run is not reduced then do it on all if (master .or. (.not. reduce_tallies)) then - ! Accumulate results for each tally - do i = 1, active_tallies % size() - call tallies(active_tallies % data(i)) % obj % accumulate() - end do - if (run_mode == MODE_EIGENVALUE) then if (current_batch > n_inactive) then ! Accumulate products of different estimators of k @@ -3820,6 +3815,11 @@ contains end do end if + ! Accumulate results for each tally + do i = 1, active_tallies % size() + call tallies(active_tallies % data(i)) % obj % accumulate() + end do + end subroutine accumulate_tallies !=============================================================================== diff --git a/src/tallies/tally_header.F90 b/src/tallies/tally_header.F90 index 08d3588a5..f2339d85d 100644 --- a/src/tallies/tally_header.F90 +++ b/src/tallies/tally_header.F90 @@ -6,7 +6,7 @@ module tally_header use error use dict_header, only: DictIntInt use hdf5_interface, only: HID_T, HSIZE_T - use message_passing, only: n_procs + use message_passing, only: n_procs, master use nuclide_header, only: nuclide_dict use settings, only: reduce_tallies, run_mode use stl_vector, only: VectorInt @@ -182,25 +182,27 @@ contains this % n_realizations = this % n_realizations + n_procs end if - ! Calculate total source strength for normalization - if (run_mode == MODE_FIXEDSOURCE) then - total_source = total_source_strength() - else - total_source = ONE - end if + if (master .or. (.not. reduce_tallies)) then + ! Calculate total source strength for normalization + if (run_mode == MODE_FIXEDSOURCE) then + total_source = total_source_strength() + else + total_source = ONE + end if - ! Accumulate each result - do j = 1, size(this % results, 3) - do i = 1, size(this % results, 2) - val = this % results(RESULT_VALUE, i, j)/total_weight * total_source - this % results(RESULT_VALUE, i, j) = ZERO + ! Accumulate each result + do j = 1, size(this % results, 3) + do i = 1, size(this % results, 2) + val = this % results(RESULT_VALUE, i, j)/total_weight * total_source + this % results(RESULT_VALUE, i, j) = ZERO - this % results(RESULT_SUM, i, j) = & - this % results(RESULT_SUM, i, j) + val - this % results(RESULT_SUM_SQ, i, j) = & - this % results(RESULT_SUM_SQ, i, j) + val*val + this % results(RESULT_SUM, i, j) = & + this % results(RESULT_SUM, i, j) + val + this % results(RESULT_SUM_SQ, i, j) = & + this % results(RESULT_SUM_SQ, i, j) + val*val + end do end do - end do + end if end subroutine tally_accumulate subroutine tally_write_results_hdf5(this, group_id) From fdde61540bfb5a0c9915a3159dca2d801c5ec297 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 9 Nov 2018 10:24:54 -0600 Subject: [PATCH 49/62] Fix DAGMC builds --- src/dagmc.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/dagmc.cpp b/src/dagmc.cpp index b5f327d06..e6ccee24d 100644 --- a/src/dagmc.cpp +++ b/src/dagmc.cpp @@ -14,8 +14,12 @@ namespace openmc { +namespace model { + moab::DagMC* DAG; +} // namespace model + void load_dagmc_geometry() { if (!model::DAG) { @@ -96,7 +100,7 @@ void load_dagmc_geometry() // initialize surface objects int n_surfaces = model::DAG->num_entities(2); - surfaces.resize(n_surfaces); + model::surfaces.resize(n_surfaces); for (int i = 0; i < n_surfaces; i++) { moab::EntityHandle surf_handle = model::DAG->entity_by_index(2, i+1); From db5f9ca59e201c9b567ca71fac146528096d3132 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 13 Nov 2018 13:08:41 -0600 Subject: [PATCH 50/62] Add conventions in style guide for namespaces and short variable names --- docs/source/devguide/styleguide.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/source/devguide/styleguide.rst b/docs/source/devguide/styleguide.rst index 2b366c191..52c6bc3e0 100644 --- a/docs/source/devguide/styleguide.rst +++ b/docs/source/devguide/styleguide.rst @@ -237,6 +237,26 @@ are written differently by convention (e.g., ``E`` for energy). Data members of classes (but not structs) additionally have trailing underscores (e.g., ``a_class_member_``). +The following conventions are used for variables with short names: + +- ``d`` stands for "distance" +- ``E`` stands for "energy" +- ``p`` stands for "particle" +- ``r`` stands for "position" +- ``rx`` stands for "reaction" +- ``u`` stands for "direction" +- ``xs`` stands for "cross section" + +All classes and non-member functions should be declared within the ``openmc`` +namespace. Global variables must be declared in a namespace nested within the +``openmc`` namespace. The following sub-namespaces are in use: + +- ``openmc::data``: Fundamental nuclear data (cross sections, multigroup data, + decay constants, etc.) +- ``openmc::model``: Variables related to geometry, materials, and tallies +- ``openmc::settings``: Global settings / options +- ``openmc::simulation``: Variables used only during a simulation + Accessors and mutators (get and set functions) may be named like variables. These often correspond to actual member variables, but this is not required. For example, ``int count()`` and ``void set_count(int count)``. From 1fe775574edc474c3c6afb17ff2cb1013d9c9d25 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 14 Nov 2018 08:34:14 -0600 Subject: [PATCH 51/62] Have openmc_statepoint_write accept a const char* instead of const char** --- docs/source/capi/index.rst | 4 +++- openmc/capi/core.py | 2 +- src/state_point.F90 | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/source/capi/index.rst b/docs/source/capi/index.rst index d7da3261e..85e5c8ced 100644 --- a/docs/source/capi/index.rst +++ b/docs/source/capi/index.rst @@ -465,13 +465,15 @@ Functions :return: Return status (negative if an error occurred) :rtype: int -.. c:function:: int openmc_statepoint_write(const char filename[]) +.. c:function:: int openmc_statepoint_write(const char filename[], const bool* write_source) Write a statepoint file :param filename: Name of file to create. If a null pointer is passed, a filename is assigned automatically. :type filename: const char[] + :param write_source: Whether to include the source bank + :type write_source: const bool* :return: Return status (negative if an error occurs) :rtype: int diff --git a/openmc/capi/core.py b/openmc/capi/core.py index 5be31ce86..bedde6e16 100644 --- a/openmc/capi/core.py +++ b/openmc/capi/core.py @@ -52,7 +52,7 @@ _dll.openmc_simulation_init.restype = c_int _dll.openmc_simulation_init.errcheck = _error_handler _dll.openmc_simulation_finalize.restype = c_int _dll.openmc_simulation_finalize.errcheck = _error_handler -_dll.openmc_statepoint_write.argtypes = [POINTER(c_char_p), POINTER(c_bool)] +_dll.openmc_statepoint_write.argtypes = [c_char_p, POINTER(c_bool)] _dll.openmc_statepoint_write.restype = c_int _dll.openmc_statepoint_write.errcheck = _error_handler diff --git a/src/state_point.F90 b/src/state_point.F90 index 1286bb63d..2692856dc 100644 --- a/src/state_point.F90 +++ b/src/state_point.F90 @@ -55,7 +55,7 @@ contains !=============================================================================== function openmc_statepoint_write(filename, write_source) result(err) bind(C) - type(C_PTR), intent(in), optional :: filename + type(C_PTR), value :: filename logical(C_BOOL), intent(in), optional :: write_source integer(C_INT) :: err @@ -91,7 +91,7 @@ contains err = 0 ! Set the filename - if (present(filename)) then + if (c_associated(filename)) then call c_f_pointer(filename, string, [MAX_FILE_LEN]) filename_ = to_f_string(string) else From d0b1287b2ef273ee142a6ebb11030ffdbf580bf1 Mon Sep 17 00:00:00 2001 From: amandalund Date: Thu, 13 Sep 2018 20:10:45 -0500 Subject: [PATCH 52/62] Added spherical shell domain --- openmc/model/triso.py | 147 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 139 insertions(+), 8 deletions(-) diff --git a/openmc/model/triso.py b/openmc/model/triso.py index 1e4b4aa9b..50ad70680 100644 --- a/openmc/model/triso.py +++ b/openmc/model/triso.py @@ -387,7 +387,7 @@ class _CylindricalDomain(_Domain): @property def volume(self): - return self.length * pi * self.radius**2 + return self.length*pi*self.radius**2 @length.setter def length(self, length): @@ -493,7 +493,7 @@ class _SphericalDomain(_Domain): @property def volume(self): - return 4/3 * pi * self.radius**3 + return 4/3*pi*self.radius**3 @radius.setter def radius(self, radius): @@ -535,6 +535,125 @@ class _SphericalDomain(_Domain): q *= r_max/r +class _SphericalShellDomain(_Domain): + """Spherical shell container in which to pack particles. + + Parameters + ---------- + radius : float + Outer radius of the spherical shell container. + inner_radius : float + Inner radius of the spherical shell container. + center : Iterable of float + Cartesian coordinates of the center of the container. Default is + [0., 0., 0.] + + Attributes + ---------- + radius : float + Outer radius of the spherical shell container. + inner_radius : float + Inner radius of the spherical shell container. + particle_radius : float + Radius of particles to be packed in container. + center : list of float + Cartesian coordinates of the center of the container. Default is + [0., 0., 0.] + cell_length : list of float + Length in x-, y-, and z- directions of each cell in mesh overlaid on + domain. + limits : list of float + Maximum radial distance and minimum radial distance where particle + center can be placed. + volume : float + Volume of the container. + + """ + + def __init__(self, radius, inner_radius, particle_radius, + center=[0., 0., 0.]): + super().__init__(particle_radius, center) + self.radius = radius + self.inner_radius = inner_radius + + @property + def radius(self): + return self._radius + + @property + def inner_radius(self): + return self._inner_radius + + @property + def limits(self): + if self._limits is None: + self._limits = [self.radius - self.particle_radius, + self.inner_radius + self.particle_radius] + return self._limits + + @property + def cell_length(self): + if self._cell_length is None: + mesh_length = 3*[2*self.radius] + self._cell_length = [x/int(x/(4*self.particle_radius)) + for x in mesh_length] + return self._cell_length + + @property + def volume(self): + return 4/3*pi*(self.radius**3 - self.inner_radius**3) + + @radius.setter + def radius(self, radius): + self._radius = float(radius) + self._limits = None + self._cell_length = None + + @inner_radius.setter + def inner_radius(self, inner_radius): + self._inner_radius = float(inner_radius) + self._limits = None + + @limits.setter + def limits(self, limits): + self._limits = limits + + def random_point(self): + r_max = self.limits[0] + r_min = self.limits[1] + x = (gauss(0, 1), gauss(0, 1), gauss(0, 1)) + r = (uniform(r_min**3, r_max**3)**(1/3)/sqrt(x[0]**2 + x[1]**2 + x[2]**2)) + return [r*s for s in x] + + def repel_particles(self, p, q, d, d_new): + # Moving each particle distance 's' away from the other along the line + # joining the particle centers will ensure their final distance is + # equal to the outer diameter + s = (d_new - d)/2 + + v = (p - q)/d + p += s*v + q -= s*v + + # Enforce the rigid boundary by moving each particle back along the + # surface normal until it is completely within the container if it + # overlaps the surface + r_max = self.limits[0] + r_min = self.limits[1] + + r = sqrt(p[0]**2 + p[1]**2 + p[2]**2) + if r > r_max: + p *= r_max/r + elif r < r_min: + p *= r_min/r + + r = sqrt(q[0]**2 + q[1]**2 + q[2]**2) + if r > r_max: + q *= r_max/r + elif r < r_min: + q *= r_min/r + + def create_triso_lattice(trisos, lower_left, pitch, shape, background): """Create a lattice containing TRISO particles for optimized tracking. @@ -937,9 +1056,10 @@ def _close_random_pack(domain, particles, contraction_rate): def pack_trisos(radius, fill, domain_shape='cylinder', domain_length=None, - domain_radius=None, domain_center=[0., 0., 0.], - n_particles=None, packing_fraction=None, - initial_packing_fraction=0.3, contraction_rate=1.e-3, seed=1): + domain_radius=None, domain_inner_radius=None, + domain_center=[0., 0., 0.], n_particles=None, + packing_fraction=None, initial_packing_fraction=0.3, + contraction_rate=1.e-3, seed=1): """Generate a random, non-overlapping configuration of TRISO particles within a container. @@ -955,6 +1075,8 @@ def pack_trisos(radius, fill, domain_shape='cylinder', domain_length=None, Length of the container (if cube or cylinder). domain_radius : float Radius of the container (if cylinder or sphere). + domain_inner_radius : float + Inner radius of the container (if spherical shell). domain_center : Iterable of float Cartesian coordinates of the center of the container. n_particles : int @@ -1018,16 +1140,20 @@ def pack_trisos(radius, fill, domain_shape='cylinder', domain_length=None, """ # Check for valid container geometry and dimensions - if domain_shape not in ['cube', 'cylinder', 'sphere']: + if domain_shape not in ['cube', 'cylinder', 'sphere', 'spherical shell']: raise ValueError('Unable to set domain_shape to "{}". Only "cube", ' - '"cylinder", and "sphere" are ' + '"cylinder", "sphere", and "spherical shell" are ' 'supported."'.format(domain_shape)) if not domain_length and domain_shape in ['cube', 'cylinder']: raise ValueError('"domain_length" must be specified for {} domain ' 'geometry '.format(domain_shape)) - if not domain_radius and domain_shape in ['cylinder', 'sphere']: + if not domain_radius and domain_shape in ['cylinder', 'sphere', + 'spherical shell']: raise ValueError('"domain_radius" must be specified for {} domain ' 'geometry '.format(domain_shape)) + if not domain_inner_radius and domain_shape in ['spherical shell']: + raise ValueError('"domain_inner_radius" must be specified for {} domain ' + 'geometry '.format(domain_shape)) if domain_shape == 'cube': domain = _CubicDomain(length=domain_length, particle_radius=radius, @@ -1038,6 +1164,11 @@ def pack_trisos(radius, fill, domain_shape='cylinder', domain_length=None, elif domain_shape == 'sphere': domain = _SphericalDomain(radius=domain_radius, particle_radius=radius, center=domain_center) + elif domain_shape == 'spherical shell': + domain = _SphericalShellDomain(radius=domain_radius, + inner_radius=domain_inner_radius, + particle_radius=radius, + center=domain_center) # Calculate the packing fraction if the number of particles is specified; # otherwise, calculate the number of particles from the packing fraction. From 8d6541951bdeec065531b72bc55080ecc63eb441 Mon Sep 17 00:00:00 2001 From: amandalund Date: Mon, 17 Sep 2018 17:48:05 -0500 Subject: [PATCH 53/62] SphericalShellDomain extends SphericalDomain --- openmc/model/triso.py | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/openmc/model/triso.py b/openmc/model/triso.py index 50ad70680..0d77ad670 100644 --- a/openmc/model/triso.py +++ b/openmc/model/triso.py @@ -486,7 +486,7 @@ class _SphericalDomain(_Domain): @property def cell_length(self): if self._cell_length is None: - mesh_length = [2*self.radius, 2*self.radius, 2*self.radius] + mesh_length = 3*[2*self.radius] self._cell_length = [x/int(x/(4*self.particle_radius)) for x in mesh_length] return self._cell_length @@ -535,7 +535,7 @@ class _SphericalDomain(_Domain): q *= r_max/r -class _SphericalShellDomain(_Domain): +class _SphericalShellDomain(_SphericalDomain): """Spherical shell container in which to pack particles. Parameters @@ -572,14 +572,9 @@ class _SphericalShellDomain(_Domain): def __init__(self, radius, inner_radius, particle_radius, center=[0., 0., 0.]): - super().__init__(particle_radius, center) - self.radius = radius + super().__init__(radius, particle_radius, center) self.inner_radius = inner_radius - @property - def radius(self): - return self._radius - @property def inner_radius(self): return self._inner_radius @@ -591,24 +586,10 @@ class _SphericalShellDomain(_Domain): self.inner_radius + self.particle_radius] return self._limits - @property - def cell_length(self): - if self._cell_length is None: - mesh_length = 3*[2*self.radius] - self._cell_length = [x/int(x/(4*self.particle_radius)) - for x in mesh_length] - return self._cell_length - @property def volume(self): return 4/3*pi*(self.radius**3 - self.inner_radius**3) - @radius.setter - def radius(self, radius): - self._radius = float(radius) - self._limits = None - self._cell_length = None - @inner_radius.setter def inner_radius(self, inner_radius): self._inner_radius = float(inner_radius) From 1107457a90176886f28abe903e9c368f4cf8d99f Mon Sep 17 00:00:00 2001 From: amandalund Date: Thu, 25 Oct 2018 23:45:05 -0500 Subject: [PATCH 54/62] Separate functions for packing spheres and creating TRISOs --- openmc/model/triso.py | 47 ++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/openmc/model/triso.py b/openmc/model/triso.py index 0d77ad670..adbfe15a7 100644 --- a/openmc/model/triso.py +++ b/openmc/model/triso.py @@ -1036,20 +1036,18 @@ def _close_random_pack(domain, particles, contraction_rate): break -def pack_trisos(radius, fill, domain_shape='cylinder', domain_length=None, - domain_radius=None, domain_inner_radius=None, - domain_center=[0., 0., 0.], n_particles=None, - packing_fraction=None, initial_packing_fraction=0.3, - contraction_rate=1.e-3, seed=1): - """Generate a random, non-overlapping configuration of TRISO particles - within a container. +def pack_spheres(radius, domain_shape='cylinder', domain_length=None, + domain_radius=None, domain_inner_radius=None, + domain_center=[0., 0., 0.], n_particles=None, + packing_fraction=None, initial_packing_fraction=0.3, + contraction_rate=1.e-3, seed=1): + """Generate a random, non-overlapping configuration of spheres within a + container. Parameters ---------- radius : float Outer radius of TRISO particles. - fill : openmc.Universe - Universe which contains all layers of the TRISO particle. domain_shape : {'cube', 'cylinder', or 'sphere'} Geometry of the container in which the TRISO particles are packed. domain_length : float @@ -1080,9 +1078,9 @@ def pack_trisos(radius, fill, domain_shape='cylinder', domain_length=None, RNG seed. Returns - ------- - trisos : list of openmc.model.TRISO - List of TRISO particles in the domain. + ------ + numpy.ndarray + Cartesian coordinates of sphere centers. Notes ----- @@ -1202,7 +1200,24 @@ def pack_trisos(radius, fill, domain_shape='cylinder', domain_length=None, domain.particle_radius = radius _close_random_pack(domain, particles, contraction_rate) - trisos = [] - for p in particles: - trisos.append(TRISO(radius, fill, [x + c for x, c in zip(p, domain.center)])) - return trisos + return particles + domain.center + +def create_trisos(outer_radius, fill, centers): + """Create TRISO particles at the given coordinates. + + Parameters + ---------- + outer_radius : float + Outer radius of TRISO particle + fill : openmc.Universe + Universe which contains all layers of the TRISO particle + centers : Iterable of float + Cartesian coordinates of the centers of the TRISO particles in cm + + Returns + ------- + list of openmc.model.TRISO + List of TRISO particles in the domain. + + """ + return [TRISO(outer_radius, fill, c) for c in centers] From c443208e21a1b245243455e84cc89f5af6946b16 Mon Sep 17 00:00:00 2001 From: amandalund Date: Thu, 8 Nov 2018 13:07:42 -0800 Subject: [PATCH 55/62] Generate sphere packing container from openmc.Region --- openmc/model/triso.py | 851 ++++++++++++++++++++++++++---------------- openmc/region.py | 2 +- openmc/surface.py | 4 +- 3 files changed, 540 insertions(+), 317 deletions(-) diff --git a/openmc/model/triso.py b/openmc/model/triso.py index adbfe15a7..03ca6f5e0 100644 --- a/openmc/model/triso.py +++ b/openmc/model/triso.py @@ -2,19 +2,24 @@ import copy import warnings import itertools import random -from collections import defaultdict +from abc import ABCMeta, abstractproperty, abstractmethod +from collections import Counter, defaultdict from collections.abc import Iterable -from numbers import Real -from random import uniform, gauss from heapq import heappush, heappop from math import pi, sin, cos, floor, log10, sqrt -from abc import ABCMeta, abstractproperty, abstractmethod +from numbers import Real +from operator import attrgetter +from random import uniform, gauss import numpy as np import scipy.spatial import openmc -import openmc.checkvalue as cv +from openmc.checkvalue import check_type + + +MAX_PF_RSP = 0.38 +MAX_PF_CRP = 0.64 class TRISO(openmc.Cell): @@ -55,7 +60,7 @@ class TRISO(openmc.Cell): @center.setter def center(self, center): - cv.check_type('TRISO center', center, Iterable, Real) + check_type('TRISO center', center, Iterable, Real) self._surface.x0 = center[0] self._surface.y0 = center[1] self._surface.z0 = center[2] @@ -91,43 +96,43 @@ class TRISO(openmc.Cell): k_min:k_max+1, j_min:j_max+1, i_min:i_max+1])) -class _Domain(metaclass=ABCMeta): - """Container in which to pack particles. +class _Container(metaclass=ABCMeta): + """Container in which to pack spheres. Parameters ---------- - particle_radius : float - Radius of particles to be packed in container. + sphere_radius : float + Radius of spheres to be packed in container. center : Iterable of float Cartesian coordinates of the center of the container. Default is - [0., 0., 0.] + (0., 0., 0.) Attributes ---------- - particle_radius : float - Radius of particles to be packed in container. + sphere_radius : float + Radius of spheres to be packed in container. center : list of float Cartesian coordinates of the center of the container. Default is - [0., 0., 0.] + (0., 0., 0.) cell_length : list of float Length in x-, y-, and z- directions of each cell in mesh overlaid on domain. limits : list of float - Constraint on where particle center can be placed. + Constraint on where sphere center can be placed. volume : float Volume of the container. """ - def __init__(self, particle_radius, center=[0., 0., 0.]): + def __init__(self, sphere_radius, center=(0., 0., 0.)): self._cell_length = None self._limits = None - self.particle_radius = particle_radius + self.sphere_radius = sphere_radius self.center = center @property - def particle_radius(self): - return self._particle_radius + def sphere_radius(self): + return self._sphere_radius @property def center(self): @@ -145,9 +150,9 @@ class _Domain(metaclass=ABCMeta): def volume(self): pass - @particle_radius.setter - def particle_radius(self, particle_radius): - self._particle_radius = float(particle_radius) + @sphere_radius.setter + def sphere_radius(self, sphere_radius): + self._sphere_radius = float(sphere_radius) self._limits = None self._cell_length = None @@ -160,12 +165,12 @@ class _Domain(metaclass=ABCMeta): def mesh_cell(self, p): """Calculate the index of the cell in a mesh overlaid on the domain in - which the given particle center falls. + which the given sphere center falls. Parameters ---------- p : Iterable of float - Cartesian coordinates of particle center. + Cartesian coordinates of sphere center. Returns ------- @@ -177,12 +182,12 @@ class _Domain(metaclass=ABCMeta): def nearby_mesh_cells(self, p): """Calculates the indices of all cells in a mesh overlaid on the domain - within one diameter of the given particle. + within one diameter of the given sphere. Parameters ---------- p : Iterable of float - Cartesian coordinates of particle center. + Cartesian coordinates of sphere center. Returns ------- @@ -190,27 +195,27 @@ class _Domain(metaclass=ABCMeta): Indices of mesh cells. """ - d = 2*self.particle_radius + d = 2*self.sphere_radius r = [[a/self.cell_length[i] for a in [p[i]-d, p[i], p[i]+d]] for i in range(3)] return list(itertools.product(*({int(x) for x in y} for y in r))) @abstractmethod def random_point(self): - """Generate Cartesian coordinates of center of a particle that is + """Generate Cartesian coordinates of center of a sphere that is contained entirely within the domain with uniform probability. Returns ------- list of float - Cartesian coordinates of particle center. + Cartesian coordinates of sphere center. """ pass @abstractmethod - def repel_particles(self, p, q, d, d_new): - """Move particles p and q apart according to the following + def repel_spheres(self, p, q, d, d_new): + """Move spheres p and q apart according to the following transformation (accounting for boundary conditions on domain): r_i^(n+1) = r_i^(n) + 1/2(d_out^(n+1) - d^(n)) @@ -219,78 +224,110 @@ class _Domain(metaclass=ABCMeta): Parameters ---------- p, q : numpy.ndarray - Cartesian coordinates of particle center. + Cartesian coordinates of sphere center. d : float - distance between centers of particles i and j. + distance between centers of spheres i and j. d_new : float - final distance between centers of particles i and j. + final distance between centers of spheres i and j. """ pass -class _CubicDomain(_Domain): - """Cubic container in which to pack particles. +class _RectangularPrism(_Container): + """Rectangular prism container in which to pack spheres. Parameters ---------- - length : float - Length of each side of the cubic container. - particle_radius : float - Radius of particles to be packed in container. + width : float + Prism length along the x-axis + depth : float + Prism length along the y-axis + height : float + Prism length along the z-axis + sphere_radius : float + Radius of spheres to be packed in container. center : Iterable of float Cartesian coordinates of the center of the container. Default is - [0., 0., 0.] + (0., 0., 0.) Attributes ---------- - length : float - Length of each side of the cubic container. - particle_radius : float - Radius of particles to be packed in container. + width : float + Prism length along the x-axis + depth : float + Prism length along the y-axis + height : float + Prism length along the z-axis + sphere_radius : float + Radius of spheres to be packed in container. center : list of float Cartesian coordinates of the center of the container. Default is - [0., 0., 0.] + (0., 0., 0.) cell_length : list of float Length in x-, y-, and z- directions of each cell in mesh overlaid on domain. limits : list of float - Maximum distance from center in x-, y-, or z-direction where particle + Maximum distance from center in x-, y-, or z-direction where sphere center can be placed. volume : float Volume of the container. """ - def __init__(self, length, particle_radius, center=[0., 0., 0.]): - super().__init__(particle_radius, center) - self.length = length + def __init__(self, width, depth, height, sphere_radius, center=(0., 0., 0.)): + super().__init__(sphere_radius, center) + self.width = width + self.depth = depth + self.height = height @property - def length(self): - return self._length + def width(self): + return self._width + + @property + def depth(self): + return self._depth + + @property + def height(self): + return self._height @property def limits(self): if self._limits is None: - self._limits = [self.length/2 - self.particle_radius] + self._limits = [self.width/2 - self.sphere_radius, + self.depth/2 - self.sphere_radius, + self.height/2 - self.sphere_radius] return self._limits @property def cell_length(self): if self._cell_length is None: - mesh_length = [self.length, self.length, self.length] - self._cell_length = [x/int(x/(4*self.particle_radius)) + mesh_length = [self.width, self.depth, self.height] + self._cell_length = [x/int(x/(4*self.sphere_radius)) for x in mesh_length] return self._cell_length @property def volume(self): - return self.length**3 + return self.width*self.depth*self.height - @length.setter - def length(self, length): - self._length = float(length) + @width.setter + def width(self, width): + self._width = float(width) + self._limits = None + self._cell_length = None + + @depth.setter + def depth(self, depth): + self._depth = float(depth) + self._limits = None + self._cell_length = None + + @height.setter + def height(self, height): + self._height = float(height) self._limits = None self._cell_length = None @@ -299,14 +336,14 @@ class _CubicDomain(_Domain): self._limits = limits def random_point(self): - x_max = self.limits[0] + x_max, y_max, z_max = self.limits return [uniform(-x_max, x_max), - uniform(-x_max, x_max), - uniform(-x_max, x_max)] + uniform(-y_max, y_max), + uniform(-z_max, z_max)] - def repel_particles(self, p, q, d, d_new): - # Moving each particle distance 's' away from the other along the line - # joining the particle centers will ensure their final distance is + def repel_spheres(self, p, q, d, d_new): + # Moving each sphere distance 's' away from the other along the line + # joining the sphere centers will ensure their final distance is # equal to the outer diameter s = (d_new - d)/2 @@ -314,53 +351,64 @@ class _CubicDomain(_Domain): p += s*v q -= s*v - # Enforce the rigid boundary by moving each particle back along the + # Enforce the rigid boundary by moving each sphere back along the # surface normal until it is completely within the container if it # overlaps the surface - x_max = self.limits[0] - p[:] = np.clip(p, -x_max, x_max) - q[:] = np.clip(q, -x_max, x_max) + p[:] = np.clip(p, [-x for x in self.limits], self.limits) + q[:] = np.clip(q, [-x for x in self.limits], self.limits) -class _CylindricalDomain(_Domain): - """Cylindrical container in which to pack particles. +class _Cylinder(_Container): + """Cylindrical container in which to pack spheres. Parameters ---------- length : float - Length along z-axis of the cylindrical container. + Length of the cylindrical container. radius : float Radius of the cylindrical container. + axis : string + Axis along which the length of the cylinder is aligned. + sphere_radius : float + Radius of spheres to be packed in container. center : Iterable of float Cartesian coordinates of the center of the container. Default is - [0., 0., 0.] + (0., 0., 0.) Attributes ---------- length : float - Length along z-axis of the cylindrical container. + Length of the cylindrical container. radius : float Radius of the cylindrical container. - particle_radius : float - Radius of particles to be packed in container. + axis : string + Axis along which the length of the cylinder is aligned. + sphere_radius : float + Radius of spheres to be packed in container. center : list of float Cartesian coordinates of the center of the container. Default is - [0., 0., 0.] + (0., 0., 0.) + shift : list of int + Rolled indices of the x-, y-, and z- coordinates of a sphere so the + configuration is aligned with the correct axis. No shift corresponds to + a cylinder along the z-axis. cell_length : list of float Length in x-, y-, and z- directions of each cell in mesh overlaid on domain. limits : list of float Maximum radial distance and maximum distance from center in z-direction - where particle center can be placed. + where sphere center can be placed. volume : float Volume of the container. """ - def __init__(self, length, radius, particle_radius, center=[0., 0., 0.]): - super().__init__(particle_radius, center) + def __init__(self, length, radius, axis, sphere_radius, center=(0., 0., 0.)): + super().__init__(sphere_radius, center) + self._shift = None self.length = length self.radius = radius + self.axis = axis @property def length(self): @@ -370,19 +418,37 @@ class _CylindricalDomain(_Domain): def radius(self): return self._radius + @property + def axis(self): + return self._axis + + @property + def shift(self): + if self._shift is None: + if self.axis == 'x': + self._shift = [1, 2, 0] + elif self.axis == 'y': + self._shift = [2, 0, 1] + else: + self._shift = [0, 1, 2] + return self._shift + @property def limits(self): if self._limits is None: - self._limits = [self.radius - self.particle_radius, - self.length/2 - self.particle_radius] + self._limits = [self.radius - self.sphere_radius, + self.length/2 - self.sphere_radius] return self._limits @property def cell_length(self): if self._cell_length is None: - mesh_length = [2*self.radius, 2*self.radius, self.length] - self._cell_length = [x/int(x/(4*self.particle_radius)) - for x in mesh_length] + h = 4*self.sphere_radius + i, j, k = self.shift + self._cell_length = [None]*3 + self._cell_length[i] = 2*self.radius/int(2*self.radius/h) + self._cell_length[j] = 2*self.radius/int(2*self.radius/h) + self._cell_length[k] = self.length/int(self.length/h) return self._cell_length @property @@ -401,20 +467,29 @@ class _CylindricalDomain(_Domain): self._limits = None self._cell_length = None + @axis.setter + def axis(self, axis): + self._axis = axis + self._shift = None + @limits.setter def limits(self, limits): self._limits = limits def random_point(self): - r_max = self.limits[0] - z_max = self.limits[1] + r_max, z_max = self.limits r = sqrt(uniform(0, r_max**2)) t = uniform(0, 2*pi) - return [r*cos(t), r*sin(t), uniform(-z_max, z_max)] + i, j, k = self.shift + p = [None]*3 + p[i] = r*cos(t) + p[j] = r*sin(t) + p[k] = uniform(-z_max, z_max) + return p - def repel_particles(self, p, q, d, d_new): - # Moving each particle distance 's' away from the other along the line - # joining the particle centers will ensure their final distance is + def repel_spheres(self, p, q, d, d_new): + # Moving each sphere distance 's' away from the other along the line + # joining the sphere centers will ensure their final distance is # equal to the outer diameter s = (d_new - d)/2 @@ -422,25 +497,27 @@ class _CylindricalDomain(_Domain): p += s*v q -= s*v - # Enforce the rigid boundary by moving each particle back along the + # Enforce the rigid boundary by moving each sphere back along the # surface normal until it is completely within the container if it # overlaps the surface - r_max = self.limits[0] - z_max = self.limits[1] + r_max, z_max = self.limits + i, j, k = self.shift - r = sqrt(p[0]**2 + p[1]**2) + r = sqrt(p[i]**2 + p[j]**2) if r > r_max: - p[0:2] *= r_max/r - p[2] = np.clip(p[2], -z_max, z_max) + p[i] *= r_max/r + p[j] *= r_max/r + p[k] = np.clip(p[k], -z_max, z_max) - r = sqrt(q[0]**2 + q[1]**2) + r = sqrt(q[i]**2 + q[j]**2) if r > r_max: - q[0:2] *= r_max/r - q[2] = np.clip(q[2], -z_max, z_max) + q[i] *= r_max/r + q[j] *= r_max/r + q[k] = np.clip(q[k], -z_max, z_max) -class _SphericalDomain(_Domain): - """Spherical container in which to pack particles. +class _Sphere(_Container): + """Spherical container in which to pack spheres. Parameters ---------- @@ -448,29 +525,29 @@ class _SphericalDomain(_Domain): Radius of the spherical container. center : Iterable of float Cartesian coordinates of the center of the container. Default is - [0., 0., 0.] + (0., 0., 0.) Attributes ---------- radius : float Radius of the spherical container. - particle_radius : float - Radius of particles to be packed in container. + sphere_radius : float + Radius of spheres to be packed in container. center : list of float Cartesian coordinates of the center of the container. Default is - [0., 0., 0.] + (0., 0., 0.) cell_length : list of float Length in x-, y-, and z- directions of each cell in mesh overlaid on domain. limits : list of float - Maximum radial distance where particle center can be placed. + Maximum radial distance where sphere center can be placed. volume : float Volume of the container. """ - def __init__(self, radius, particle_radius, center=[0., 0., 0.]): - super().__init__(particle_radius, center) + def __init__(self, radius, sphere_radius, center=(0., 0., 0.)): + super().__init__(sphere_radius, center) self.radius = radius @property @@ -480,14 +557,14 @@ class _SphericalDomain(_Domain): @property def limits(self): if self._limits is None: - self._limits = [self.radius - self.particle_radius] + self._limits = [self.radius - self.sphere_radius] return self._limits @property def cell_length(self): if self._cell_length is None: mesh_length = 3*[2*self.radius] - self._cell_length = [x/int(x/(4*self.particle_radius)) + self._cell_length = [x/int(x/(4*self.sphere_radius)) for x in mesh_length] return self._cell_length @@ -511,9 +588,9 @@ class _SphericalDomain(_Domain): r = (uniform(0, r_max**3)**(1/3) / sqrt(x[0]**2 + x[1]**2 + x[2]**2)) return [r*s for s in x] - def repel_particles(self, p, q, d, d_new): - # Moving each particle distance 's' away from the other along the line - # joining the particle centers will ensure their final distance is + def repel_spheres(self, p, q, d, d_new): + # Moving each sphere distance 's' away from the other along the line + # joining the sphere centers will ensure their final distance is # equal to the outer diameter s = (d_new - d)/2 @@ -521,7 +598,7 @@ class _SphericalDomain(_Domain): p += s*v q -= s*v - # Enforce the rigid boundary by moving each particle back along the + # Enforce the rigid boundary by moving each sphere back along the # surface normal until it is completely within the container if it # overlaps the surface r_max = self.limits[0] @@ -535,8 +612,8 @@ class _SphericalDomain(_Domain): q *= r_max/r -class _SphericalShellDomain(_SphericalDomain): - """Spherical shell container in which to pack particles. +class _SphericalShell(_Sphere): + """Spherical shell container in which to pack spheres. Parameters ---------- @@ -546,7 +623,7 @@ class _SphericalShellDomain(_SphericalDomain): Inner radius of the spherical shell container. center : Iterable of float Cartesian coordinates of the center of the container. Default is - [0., 0., 0.] + (0., 0., 0.) Attributes ---------- @@ -554,25 +631,25 @@ class _SphericalShellDomain(_SphericalDomain): Outer radius of the spherical shell container. inner_radius : float Inner radius of the spherical shell container. - particle_radius : float - Radius of particles to be packed in container. + sphere_radius : float + Radius of spheres to be packed in container. center : list of float Cartesian coordinates of the center of the container. Default is - [0., 0., 0.] + (0., 0., 0.) cell_length : list of float Length in x-, y-, and z- directions of each cell in mesh overlaid on domain. limits : list of float - Maximum radial distance and minimum radial distance where particle + Maximum radial distance and minimum radial distance where sphere center can be placed. volume : float Volume of the container. """ - def __init__(self, radius, inner_radius, particle_radius, - center=[0., 0., 0.]): - super().__init__(radius, particle_radius, center) + def __init__(self, radius, inner_radius, sphere_radius, + center=(0., 0., 0.)): + super().__init__(radius, sphere_radius, center) self.inner_radius = inner_radius @property @@ -582,8 +659,8 @@ class _SphericalShellDomain(_SphericalDomain): @property def limits(self): if self._limits is None: - self._limits = [self.radius - self.particle_radius, - self.inner_radius + self.particle_radius] + self._limits = [self.radius - self.sphere_radius, + self.inner_radius + self.sphere_radius] return self._limits @property @@ -600,15 +677,14 @@ class _SphericalShellDomain(_SphericalDomain): self._limits = limits def random_point(self): - r_max = self.limits[0] - r_min = self.limits[1] + r_max, r_min = self.limits x = (gauss(0, 1), gauss(0, 1), gauss(0, 1)) r = (uniform(r_min**3, r_max**3)**(1/3)/sqrt(x[0]**2 + x[1]**2 + x[2]**2)) return [r*s for s in x] - def repel_particles(self, p, q, d, d_new): - # Moving each particle distance 's' away from the other along the line - # joining the particle centers will ensure their final distance is + def repel_spheres(self, p, q, d, d_new): + # Moving each sphere distance 's' away from the other along the line + # joining the sphere centers will ensure their final distance is # equal to the outer diameter s = (d_new - d)/2 @@ -616,11 +692,10 @@ class _SphericalShellDomain(_SphericalDomain): p += s*v q -= s*v - # Enforce the rigid boundary by moving each particle back along the + # Enforce the rigid boundary by moving each sphere back along the # surface normal until it is completely within the container if it # overlaps the surface - r_max = self.limits[0] - r_min = self.limits[1] + r_max, r_min = self.limits r = sqrt(p[0]**2 + p[1]**2 + p[2]**2) if r > r_max: @@ -708,28 +783,215 @@ def create_triso_lattice(trisos, lower_left, pitch, shape, background): return lattice -def _random_sequential_pack(domain, n_particles): - """Random sequential packing of particles within a container. +def _create_container(region, sphere_radius): + """Create a container to pack spheres in using the region to determine the + container shape. Parameters ---------- - domain : openmc.model._Domain - Container in which to pack particles. - n_particles : int - Number of particles to pack. + region : openmc.Region + Container in which the spheres are packed. Supported shapes are + rectangular_prism, cylinder, sphere, and spherical shell. + sphere_radius : float + Outer radius of spheres. + + Returns + ------- + domain : openmc.model._Container + Container in which to pack spheres. + + """ + + def rectangular_prism(): + # Assume the simplest case where the prism volume is the intersection + # of the half-spaces of six planes + if not isinstance(region, openmc.Intersection): + return None + + if any(not isinstance(node, openmc.Halfspace) for node in region): + return None + + if len(region) != 6: + return None + + # Sort half-spaces by surface type + px1, px2, py1, py2, pz1, pz2 = sorted(region, key=attrgetter('surface.type')) + + # Make sure the region consists of the correct surfaces + if (not isinstance(px1.surface, openmc.XPlane) or + not isinstance(px2.surface, openmc.XPlane) or + not isinstance(py1.surface, openmc.YPlane) or + not isinstance(py2.surface, openmc.YPlane) or + not isinstance(pz1.surface, openmc.ZPlane) or + not isinstance(pz2.surface, openmc.ZPlane)): + return None + + # Secondary sorting by location of the plane + if px1.surface.x0 > px2.surface.x0: + px1, px2 = px2, px1 + + if py1.surface.y0 > py2.surface.y0: + py1, py2 = py2, py1 + + if pz1.surface.z0 > pz2.surface.z0: + pz1, pz2 = pz2, pz1 + + # Make sure the half-spaces are on the correct side of the surfaces + if (px1.side != '+' or px2.side != '-' or + py1.side != '+' or py2.side != '-' or + pz1.side != '+' or pz2.side != '-'): + return None + + # Calculate the parameters for the container + width = px2.surface.x0 - px1.surface.x0 + depth = py2.surface.y0 - py1.surface.y0 + height = pz2.surface.z0 - pz1.surface.z0 + center = (px1.surface.x0 + width/2, + py1.surface.y0 + depth/2, + pz1.surface.z0 + height/2) + + # The region is the volume of a rectangular prism, so create container + return _RectangularPrism(width, depth, height, sphere_radius, center) + + def cylinder(): + # Assume the simplest case where the cylinder volume is the + # intersection of the half-spaces of a cylinder and two planes + if not isinstance(region, openmc.Intersection): + return None + + if any(not isinstance(node, openmc.Halfspace) for node in region): + return None + + if len(region) != 3: + return None + + # Identify the axis that the cylinder lies along + axis = region[0].surface.type[0] + + # Make sure the region is composed of a cylinder and two planes on the + # same axis + count = Counter((node.surface.type for node in region)) + if count[axis + '-cylinder'] != 1 or count[axis + '-plane'] != 2: + return None + + # Sort the half-spaces by surface type + cyl, p1, p2 = sorted(region, key=attrgetter('surface.type')) + + # Calculate the parameters for a cylinder along the x-axis + if axis == 'x': + if p1.surface.x0 > p2.surface.x0: + p1, p2 = p2, p1 + length = p2.surface.x0 - p1.surface.x0 + center = (length/2, cyl.surface.y0, cyl.surface.z0) + + # Calculate the parameters for a cylinder along the y-axis + elif axis == 'y': + if p1.surface.y0 > p2.surface.y0: + p1, p2 = p2, p1 + length = p2.surface.y0 - p1.surface.y0 + center = (cyl.surface.x0, length/2, cyl.surface.z0) + + # Calculate the parameters for a cylinder along the z-axis + else: + if p1.surface.z0 > p2.surface.z0: + p1, p2 = p2, p1 + length = p2.surface.z0 - p1.surface.z0 + center = (cyl.surface.x0, cyl.surface.y0, length/2) + + # Make sure the half-spaces are on the correct side of the surfaces + if cyl.side != '-' or p1.side != '+' or p2.side != '-': + return None + + radius = cyl.surface.r + + # The region is the volume of a cylinder, so create container + return _Cylinder(length, radius, axis, sphere_radius, center) + + def sphere(): + # Assume the simplest case where the sphere volume is the negative + # half-space of a sphere + if not isinstance(region, openmc.Halfspace): + return None + + if not isinstance(region.surface, openmc.Sphere): + return None + + if region.side != '-': + return None + + radius = region.surface.r + center = (region.surface.x0, region.surface.y0, region.surface.z0) + + # The region is the volume of a sphere, so create container + return _Sphere(radius, sphere_radius, center) + + def spherical_shell(): + # Assume the simplest case where the spherical shell volume is the + # intersection of the half-spaces of two spheres + if not isinstance(region, openmc.Intersection): + return None + + if any(not isinstance(node, openmc.Halfspace) for node in region): + return None + + if len(region) != 2: + return None + + if any(not isinstance(node.surface, openmc.Sphere) for node in region): + return None + + s1, s2 = sorted(region, key=attrgetter('surface.r')) + radius = s2.surface.r + inner_radius = s1.surface.r + center = (s1.surface.x0, s1.surface.y0, s1.surface.z0) + + if center != (s2.surface.x0, s2.surface.y0, s2.surface.z0): + return None + + if s1.side != '+' or s2.side != '-': + return None + + # The region is the volume of a spherical shell, so create container + return _SphericalShell(radius, inner_radius, sphere_radius, center) + + check_type('region', region, openmc.Region) + + # Check whether the region matches any of the supported container shapes + # and create the container if it does + shapes = [rectangular_prism, cylinder, sphere, spherical_shell] + for shape in shapes: + container = shape() + if container: + return container + + msg = ('Could not translate region {} into a container: supported ' + 'container shapes are rectangular prism, cylinder, sphere, ' + 'and spherical shell.'.format(region)) + raise ValueError(msg) + + +def _random_sequential_pack(domain, num_spheres): + """Random sequential packing of spheres within a container. + + Parameters + ---------- + domain : openmc.model._Container + Container in which to pack spheres. + num_spheres : int + Number of spheres to pack. Returns ------ numpy.ndarray - Cartesian coordinates of centers of particles. + Cartesian coordinates of centers of spheres. """ - sqd = (2*domain.particle_radius)**2 - particles = [] + sqd = (2*domain.sphere_radius)**2 + spheres = [] mesh = defaultdict(list) - for i in range(n_particles): + for i in range(num_spheres): # Randomly sample new center coordinates while there are any overlaps while True: p = domain.random_point() @@ -739,23 +1001,23 @@ def _random_sequential_pack(domain, n_particles): continue else: break - particles.append(p) + spheres.append(p) for idx in domain.nearby_mesh_cells(p): mesh[idx].append(p) - return np.array(particles) + return np.array(spheres) -def _close_random_pack(domain, particles, contraction_rate): - """Close random packing of particles using the Jodrey-Tory algorithm. +def _close_random_pack(domain, spheres, contraction_rate): + """Close random packing of spheres using the Jodrey-Tory algorithm. Parameters ---------- - domain : openmc.model._Domain - Container in which to pack particles. - particles : numpy.ndarray - Initial Cartesian coordinates of centers of particles. + domain : openmc.model._Container + Container in which to pack spheres. + spheres : numpy.ndarray + Initial Cartesian coordinates of centers of spheres. contraction_rate : float Contraction rate of outer diameter. @@ -767,9 +1029,9 @@ def _close_random_pack(domain, particles, contraction_rate): Parameters ---------- d : float - distance between centers of particles i and j. + distance between centers of spheres i and j. i, j : int - Index of particles in particles array. + Index of spheres in spheres array. """ @@ -779,12 +1041,12 @@ def _close_random_pack(domain, particles, contraction_rate): heappush(rods, rod) def remove_rod(i): - """Mark the rod containing particle i as removed. + """Mark the rod containing sphere i as removed. Parameters ---------- i : int - Index of particle in particles array. + Index of sphere in spheres array. """ @@ -800,9 +1062,9 @@ def _close_random_pack(domain, particles, contraction_rate): Returns ------- d : float - distance between centers of particles i and j. + distance between centers of spheres i and j. i, j : int - Index of particles in particles array. + Index of spheres in spheres array. """ @@ -815,15 +1077,15 @@ def _close_random_pack(domain, particles, contraction_rate): return None, None, None def create_rod_list(): - """Generate sorted list of rods (distances between particle centers). + """Generate sorted list of rods (distances between sphere centers). Rods are arranged in a heap where each element contains the rod length - and the particle indices. A rod between particles p and q is only + and the sphere indices. A rod between spheres p and q is only included if the distance between p and q could not be changed by the elimination of a greater overlap, i.e. q has no nearer neighbors than p. - A mapping of particle ids to rods is maintained in 'rods_map'. Each key - in the dict is the id of a particle that is in the rod list, and the + A mapping of sphere ids to rods is maintained in 'rods_map'. Each key + in the dict is the id of a sphere that is in the rod list, and the value is the id of its nearest neighbor and the rod that contains them. The dict is used to find rods in the priority queue and to mark removed rods so rods can be "removed" without breaking the heap structure @@ -832,25 +1094,25 @@ def _close_random_pack(domain, particles, contraction_rate): """ # Create KD tree for quick nearest neighbor search - tree = scipy.spatial.cKDTree(particles) + tree = scipy.spatial.cKDTree(spheres) # Find distance to nearest neighbor and index of nearest neighbor for - # all particles - d, n = tree.query(particles, k=2) + # all spheres + d, n = tree.query(spheres, k=2) d = d[:, 1] n = n[:, 1] - # Array of particle indices, indices of nearest neighbors, and + # Array of sphere indices, indices of nearest neighbors, and # distances to nearest neighbors a = np.vstack((list(range(n.size)), n, d)).T # Sort along second column and swap first and second columns to create - # array of nearest neighbor indices, indices of particles they are + # array of nearest neighbor indices, indices of spheres they are # nearest neighbors of, and distances between them b = a[a[:, 1].argsort()] b[:, [0, 1]] = b[:, [1, 0]] - # Find the intersection between 'a' and 'b': a list of particles who + # Find the intersection between 'a' and 'b': a list of spheres who # are each other's nearest neighbors and the distance between them r = list({tuple(x) for x in a} & {tuple(x) for x in b}) @@ -866,30 +1128,30 @@ def _close_random_pack(domain, particles, contraction_rate): add_rod(d, i, j) def update_mesh(i): - """Update which mesh cells the particle is in based on new particle + """Update which mesh cells the sphere is in based on new sphere center coordinates. 'mesh'/'mesh_map' is a two way dictionary used to look up which - particles are located within one diameter of a given mesh cell and - which mesh cells a given particle center is within one diameter of. + spheres are located within one diameter of a given mesh cell and + which mesh cells a given sphere center is within one diameter of. This is used to speed up the nearest neighbor search. Parameters ---------- i : int - Index of particle in particles array. + Index of sphere in spheres array. """ - # Determine which mesh cells the particle is in and remove the - # particle id from those cells + # Determine which mesh cells the sphere is in and remove the + # sphere id from those cells for idx in mesh_map[i]: mesh[idx].remove(i) del mesh_map[i] - # Determine which mesh cells are within one diameter of particle's - # center and add this particle to the list of particles in those cells - for idx in domain.nearby_mesh_cells(particles[i]): + # Determine which mesh cells are within one diameter of sphere's + # center and add this sphere to the list of spheres in those cells + for idx in domain.nearby_mesh_cells(spheres[i]): mesh[idx].add(i) mesh_map[i].add(idx) @@ -898,7 +1160,7 @@ def _close_random_pack(domain, particles, contraction_rate): d_out^(i+1) = d_out^(i) - (1/2)^(j) * d_out0 * k / n, - where k is the contraction rate, n is the number of particles, and + where k is the contraction rate, n is the number of spheres, and j = floor(-log10(pf_out - pf_in)). @@ -909,26 +1171,26 @@ def _close_random_pack(domain, particles, contraction_rate): """ - inner_pf = 4/3*pi*(inner_diameter/2)**3*n_particles/domain.volume - outer_pf = 4/3*pi*(outer_diameter/2)**3*n_particles/domain.volume + inner_pf = 4/3*pi*(inner_diameter/2)**3*num_spheres/domain.volume + outer_pf = 4/3*pi*(outer_diameter/2)**3*num_spheres/domain.volume j = floor(-log10(outer_pf - inner_pf)) return (outer_diameter - 0.5**j * contraction_rate * - initial_outer_diameter / n_particles) + initial_outer_diameter / num_spheres) def nearest(i): - """Find index of nearest neighbor of particle i. + """Find index of nearest neighbor of sphere i. Parameters ---------- i : int - Index in particles array of particle for which to find nearest + Index in spheres array of sphere for which to find nearest neighbor. Returns ------- int - Index in particles array of nearest neighbor of i + Index in spheres array of nearest neighbor of i float distance between i and nearest neighbor. @@ -937,8 +1199,8 @@ def _close_random_pack(domain, particles, contraction_rate): # Need the second nearest neighbor of i since the nearest neighbor # will be itself. Using argpartition, the k-th nearest neighbor is # placed at index k. - idx = list(mesh[domain.mesh_cell(particles[i])]) - dists = scipy.spatial.distance.cdist([particles[i]], particles[idx])[0] + idx = list(mesh[domain.mesh_cell(spheres[i])]) + dists = scipy.spatial.distance.cdist([spheres[i]], spheres[idx])[0] if dists.size > 1: j = dists.argpartition(1)[1] return idx[j], dists[j] @@ -946,17 +1208,17 @@ def _close_random_pack(domain, particles, contraction_rate): return None, None def update_rod_list(i): - """Update the rod list with the new nearest neighbors of particle since + """Update the rod list with the new nearest neighbors of sphere since its overlap was eliminated. Parameters ---------- i : int - Index of particle in particles array. + Index of sphere in spheres array. """ - # If the nearest neighbor k of particle i has no nearer neighbors, + # If the nearest neighbor k of sphere i has no nearer neighbors, # remove the rod currently containing k from the rod list and add rod # k-i, keeping the rod list sorted k, d_ik = nearest(i) @@ -965,57 +1227,57 @@ def _close_random_pack(domain, particles, contraction_rate): remove_rod(k) add_rod(d_ik, i, k) - n_particles = len(particles) - diameter = 2*domain.particle_radius + num_spheres = len(spheres) + diameter = 2*domain.sphere_radius # Flag for marking rods that have been removed from priority queue removed = -1 # Outer diameter initially set to arbitrary value that yields pf of 1 - initial_outer_diameter = 2*(domain.volume/(n_particles*4/3*pi))**(1/3) + initial_outer_diameter = 2*(domain.volume/(num_spheres*4/3*pi))**(1/3) - # Inner and outer diameter of particles will change during packing + # Inner and outer diameter of spheres will change during packing outer_diameter = initial_outer_diameter inner_diameter = 0. - # List of rods arranged in a heap and mapping of particle ids to rods + # List of rods arranged in a heap and mapping of sphere ids to rods rods = [] rods_map = {} - # Initialize two-way dictionary that identifies which particles are near a - # given mesh cell and which mesh cells a particle is near + # Initialize two-way dictionary that identifies which spheres are near a + # given mesh cell and which mesh cells a sphere is near mesh = defaultdict(set) mesh_map = defaultdict(set) - for i in range(n_particles): - for idx in domain.nearby_mesh_cells(particles[i]): + for i in range(num_spheres): + for idx in domain.nearby_mesh_cells(spheres[i]): mesh[idx].add(i) mesh_map[i].add(idx) while True: - # Rebuild the sorted list of rods according to the current particle + # Rebuild the sorted list of rods according to the current sphere # configuration create_rod_list() # Set the inner diameter to the shortest center-to-center distance - # between any two particles + # between any two spheres if rods: inner_diameter = rods[0][0] - # Reached the desired particle radius + # Reached the desired sphere radius if inner_diameter >= diameter: break - # The algorithm converged before reaching the desired particle radius. + # The algorithm converged before reaching the desired sphere radius. # This can happen when the desired packing fraction is close to the # packing fraction limit. The packing fraction is a random variable - # that is determined by the particle locations and the contraction + # that is determined by the sphere locations and the contraction # rate. A higher packing fraction can be achieved with a smaller # contraction rate, though at the cost of a longer simulation time -- # the number of iterations needed to remove all overlaps is inversely # proportional to the contraction rate. if inner_diameter >= outer_diameter or not rods: warnings.warn('Close random pack converged before reaching true ' - 'particle radius; some particles may overlap. Try ' + 'sphere radius; some spheres may overlap. Try ' 'reducing contraction rate or packing fraction.') break @@ -1024,7 +1286,7 @@ def _close_random_pack(domain, particles, contraction_rate): if not d: break outer_diameter = reduce_outer_diameter() - domain.repel_particles(particles[i], particles[j], d, outer_diameter) + domain.repel_spheres(spheres[i], spheres[j], d, outer_diameter) update_mesh(i) update_mesh(j) update_rod_list(i) @@ -1036,10 +1298,7 @@ def _close_random_pack(domain, particles, contraction_rate): break -def pack_spheres(radius, domain_shape='cylinder', domain_length=None, - domain_radius=None, domain_inner_radius=None, - domain_center=[0., 0., 0.], n_particles=None, - packing_fraction=None, initial_packing_fraction=0.3, +def pack_spheres(radius, region, pf=None, num_spheres=None, initial_pf=0.3, contraction_rate=1.e-3, seed=1): """Generate a random, non-overlapping configuration of spheres within a container. @@ -1047,33 +1306,27 @@ def pack_spheres(radius, domain_shape='cylinder', domain_length=None, Parameters ---------- radius : float - Outer radius of TRISO particles. - domain_shape : {'cube', 'cylinder', or 'sphere'} - Geometry of the container in which the TRISO particles are packed. - domain_length : float - Length of the container (if cube or cylinder). - domain_radius : float - Radius of the container (if cylinder or sphere). - domain_inner_radius : float - Inner radius of the container (if spherical shell). - domain_center : Iterable of float - Cartesian coordinates of the center of the container. - n_particles : int - Number of TRISO particles to pack in the domain. Exactly one of - 'n_particles' and 'packing_fraction' should be specified -- the other - will be calculated. - packing_fraction : float - Packing fraction of particles. Exactly one of 'n_particles' and - 'packing_fraction' should be specified -- the other will be calculated. - initial_packing_fraction : float, optional - Packing fraction used to initialize the configuration of particles in + Outer radius of spheres. + region : openmc.Region + Container in which the spheres are packed. Supported shapes are + rectangular prism, cylinder, sphere, and spherical shell. + pf : float + Packing fraction of the spheres. One of 'pf' and 'num_spheres' must + be specified; the other will be calculated. If both are specified, 'pf' + takes precedence over 'num_spheres'. + num_spheres : int + Number of spheres to pack in the domain. One of 'num_spheres' and 'pf' + must be specified; the other will be calculated. + initial_pf : float, optional + Packing fraction used to initialize the configuration of spheres in the domain. Default value is 0.3. It is not recommended to set the initial packing fraction much higher than 0.3 as the random sequential packing algorithm becomes prohibitively slow as it approaches its limit (~0.38). contraction_rate : float, optional - Contraction rate of outer diameter. This can affect the speed of the - close random packing algorithm. Default value is 1/400. + Contraction rate of the outer diameter. Higher packing fractions can be + reached using a smaller contraction rate, but the algorithm will take + longer to converge. seed : int, optional RNG seed. @@ -1084,7 +1337,7 @@ def pack_spheres(radius, domain_shape='cylinder', domain_length=None, Notes ----- - The particle configuration is generated using a combination of random + The sphere configuration is generated using a combination of random sequential packing (RSP) and close random packing (CRP). RSP performs better than CRP for lower packing fractions (pf), but it becomes prohibitively slow as it approaches its packing limit (~0.38). CRP can @@ -1092,23 +1345,23 @@ def pack_spheres(radius, domain_shape='cylinder', domain_length=None, If the desired pf is below some threshold for which RSP will be faster than CRP ('initial_packing_fraction'), only RSP is used. If a higher pf is - required, particles with a radius smaller than the desired final radius + required, spheres with a radius smaller than the desired final radius (and therefore with a smaller pf) are initialized within the domain using - RSP. This initial configuration of particles is then used as a starting + RSP. This initial configuration of spheres is then used as a starting point for CRP using Jodrey and Tory's algorithm [1]_. - In RSP, particle centers are placed one by one at random, and placement - attempts for a particle are made until the particle is not overlapping any + In RSP, sphere centers are placed one by one at random, and placement + attempts for a sphere are made until the sphere is not overlapping any others. This implementation of the algorithm uses a mesh over the domain - to speed up the nearest neighbor search by only searching for a particle's + to speed up the nearest neighbor search by only searching for a sphere's neighbors within that mesh cell. - In CRP, each particle is assigned two diameters, an inner and an outer, + In CRP, each sphere is assigned two diameters, an inner and an outer, which approach each other during the simulation. The inner diameter, defined as the minimum center-to-center distance, is the true diameter of - the particles and defines the pf. At each iteration the worst overlap - between particles based on outer diameter is eliminated by moving the - particles apart along the line joining their centers. Iterations continue + the spheres and defines the pf. At each iteration the worst overlap + between spheres based on outer diameter is eliminated by moving the + spheres apart along the line joining their centers. Iterations continue until the two diameters converge or until the desired pf is reached. References @@ -1117,90 +1370,60 @@ def pack_spheres(radius, domain_shape='cylinder', domain_length=None, packing of equal spheres", Phys. Rev. A 32 (1985) 2347-2351. """ - - # Check for valid container geometry and dimensions - if domain_shape not in ['cube', 'cylinder', 'sphere', 'spherical shell']: - raise ValueError('Unable to set domain_shape to "{}". Only "cube", ' - '"cylinder", "sphere", and "spherical shell" are ' - 'supported."'.format(domain_shape)) - if not domain_length and domain_shape in ['cube', 'cylinder']: - raise ValueError('"domain_length" must be specified for {} domain ' - 'geometry '.format(domain_shape)) - if not domain_radius and domain_shape in ['cylinder', 'sphere', - 'spherical shell']: - raise ValueError('"domain_radius" must be specified for {} domain ' - 'geometry '.format(domain_shape)) - if not domain_inner_radius and domain_shape in ['spherical shell']: - raise ValueError('"domain_inner_radius" must be specified for {} domain ' - 'geometry '.format(domain_shape)) - - if domain_shape == 'cube': - domain = _CubicDomain(length=domain_length, particle_radius=radius, - center=domain_center) - elif domain_shape == 'cylinder': - domain = _CylindricalDomain(length=domain_length, radius=domain_radius, - particle_radius=radius, center=domain_center) - elif domain_shape == 'sphere': - domain = _SphericalDomain(radius=domain_radius, particle_radius=radius, - center=domain_center) - elif domain_shape == 'spherical shell': - domain = _SphericalShellDomain(radius=domain_radius, - inner_radius=domain_inner_radius, - particle_radius=radius, - center=domain_center) - - # Calculate the packing fraction if the number of particles is specified; - # otherwise, calculate the number of particles from the packing fraction. - if ((n_particles is None and packing_fraction is None) or - (n_particles is not None and packing_fraction is not None)): - raise ValueError('Exactly one of "n_particles" and "packing_fraction" ' - 'must be specified.') - elif packing_fraction is None: - n_particles = int(n_particles) - packing_fraction = 4/3*pi*radius**3*n_particles / domain.volume - elif n_particles is None: - packing_fraction = float(packing_fraction) - n_particles = int(packing_fraction*domain.volume // (4/3*pi*radius**3)) - - # Check for valid packing fractions for each algorithm - if packing_fraction >= 0.64: - raise ValueError('Packing fraction of {} is greater than the ' - 'packing fraction limit for close random ' - 'packing (0.64)'.format(packing_fraction)) - if initial_packing_fraction >= 0.38: - raise ValueError('Initial packing fraction of {} is greater than the ' - 'packing fraction limit for random sequential' - 'packing (0.38)'.format(initial_packing_fraction)) - if initial_packing_fraction > packing_fraction: - initial_packing_fraction = packing_fraction - if packing_fraction > 0.3: - initial_packing_fraction = 0.3 - + # Seed RNG random.seed(seed) - # Calculate the particle radius used in the initial random sequential + # Create container with the correct shape based on the supplied region + domain = _create_container(region, radius) + + # Determine the packing fraction/number of spheres + volume = 4/3*pi*radius**3 + if pf is None and num_spheres is None: + raise ValueError('`pf` or `num_spheres` must be specified.') + elif pf is None: + num_spheres = int(num_spheres) + pf = volume*num_spheres/domain.volume + else: + pf = float(pf) + num_spheres = int(pf*domain.volume//volume) + + # Make sure initial packing fraction is less than packing fraction + if initial_pf > pf: + initial_pf = pf + + # Check packing fraction for close random packing + if pf > MAX_PF_CRP: + raise ValueError('Packing fraction {0} is greater than the limit for ' + 'close random packing, {1}'.format(pf, MAX_PF_CRP)) + + # Check packing fraction for random sequential packing + if initial_pf > MAX_PF_RSP: + raise ValueError('Initial packing fraction {0} is greater than the ' + 'limit for random sequential packing, ' + '{1}'.format(initial_pf, MAX_PF_RSP)) + + # Calculate the sphere radius used in the initial random sequential # packing from the initial packing fraction - initial_radius = (3/4 * initial_packing_fraction * domain.volume / - (pi * n_particles))**(1/3) - domain.particle_radius = initial_radius + initial_radius = (3/4*initial_pf*domain.volume/(pi*num_spheres))**(1/3) + domain.sphere_radius = initial_radius # Recalculate the limits for the initial random sequential packing using - # the desired final particle radius to ensure particles are fully contained + # the desired final sphere radius to ensure spheres are fully contained # within the domain during the close random pack domain.limits = [x + initial_radius - radius for x in domain.limits] - # Generate non-overlapping particles for an initial inner radius using + # Generate non-overlapping spheres for an initial inner radius using # random sequential packing algorithm - particles = _random_sequential_pack(domain, n_particles) + spheres = _random_sequential_pack(domain, num_spheres) - # Use the particle configuration produced in random sequential packing as a - # starting point for close random pack with the desired final particle + # Use the sphere configuration produced in random sequential packing as a + # starting point for close random pack with the desired final sphere # radius - if initial_packing_fraction != packing_fraction: - domain.particle_radius = radius - _close_random_pack(domain, particles, contraction_rate) + if initial_pf != pf: + domain.sphere_radius = radius + _close_random_pack(domain, spheres, contraction_rate) - return particles + domain.center + return spheres + domain.center def create_trisos(outer_radius, fill, centers): """Create TRISO particles at the given coordinates. diff --git a/openmc/region.py b/openmc/region.py index f82db8553..ceffadbe3 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -475,7 +475,7 @@ class Complement(Region): >>> xr = openmc.XPlane(x0=10.0) >>> yl = openmc.YPlane(y0=-10.0) >>> yr = openmc.YPlane(y0=10.0) - >>> inside_box = +xl & -xr & +yl & -yl + >>> inside_box = +xl & -xr & +yl & -yr >>> outside_box = ~inside_box >>> type(outside_box) diff --git a/openmc/surface.py b/openmc/surface.py index 826ac5cc8..c861880c5 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -62,7 +62,7 @@ class Surface(IDManagerMixin): self.boundary_type = boundary_type # A dictionary of the quadratic surface coefficients - # Key - coefficeint name + # Key - coefficient name # Value - coefficient value self._coefficients = {} @@ -1661,7 +1661,7 @@ class Quadric(Surface): a, b, c, d, e, f, g, h, j, k : float, optional coefficients for the surface. All default to 0. name : str, optional - Name of the sphere. If not specified, the name will be the empty string. + Name of the surface. If not specified, the name will be the empty string. Attributes ---------- From 66fe2185f37a0a98ba66a3ddd31caed3ecb0a7a5 Mon Sep 17 00:00:00 2001 From: amandalund Date: Wed, 14 Nov 2018 10:54:24 -0600 Subject: [PATCH 56/62] Update TRISO tests --- openmc/model/triso.py | 26 +-- tests/regression_tests/triso/inputs_true.dat | 14 +- tests/regression_tests/triso/results_true.dat | 2 +- tests/regression_tests/triso/test.py | 16 +- tests/unit_tests/test_model_triso.py | 193 +++++++++--------- 5 files changed, 121 insertions(+), 130 deletions(-) diff --git a/openmc/model/triso.py b/openmc/model/triso.py index 03ca6f5e0..a99f136bb 100644 --- a/openmc/model/triso.py +++ b/openmc/model/triso.py @@ -882,21 +882,21 @@ def _create_container(region, sphere_radius): if p1.surface.x0 > p2.surface.x0: p1, p2 = p2, p1 length = p2.surface.x0 - p1.surface.x0 - center = (length/2, cyl.surface.y0, cyl.surface.z0) + center = (p1.surface.x0 + length/2, cyl.surface.y0, cyl.surface.z0) # Calculate the parameters for a cylinder along the y-axis elif axis == 'y': if p1.surface.y0 > p2.surface.y0: p1, p2 = p2, p1 length = p2.surface.y0 - p1.surface.y0 - center = (cyl.surface.x0, length/2, cyl.surface.z0) + center = (cyl.surface.x0, p1.surface.y0 + length/2, cyl.surface.z0) # Calculate the parameters for a cylinder along the z-axis else: if p1.surface.z0 > p2.surface.z0: p1, p2 = p2, p1 length = p2.surface.z0 - p1.surface.z0 - center = (cyl.surface.x0, cyl.surface.y0, length/2) + center = (cyl.surface.x0, cyl.surface.y0, p1.surface.z0 + length/2) # Make sure the half-spaces are on the correct side of the surfaces if cyl.side != '-' or p1.side != '+' or p2.side != '-': @@ -1424,23 +1424,3 @@ def pack_spheres(radius, region, pf=None, num_spheres=None, initial_pf=0.3, _close_random_pack(domain, spheres, contraction_rate) return spheres + domain.center - -def create_trisos(outer_radius, fill, centers): - """Create TRISO particles at the given coordinates. - - Parameters - ---------- - outer_radius : float - Outer radius of TRISO particle - fill : openmc.Universe - Universe which contains all layers of the TRISO particle - centers : Iterable of float - Cartesian coordinates of the centers of the TRISO particles in cm - - Returns - ------- - list of openmc.model.TRISO - List of TRISO particles in the domain. - - """ - return [TRISO(outer_radius, fill, c) for c in centers] diff --git a/tests/regression_tests/triso/inputs_true.dat b/tests/regression_tests/triso/inputs_true.dat index a13187628..7e5007eca 100644 --- a/tests/regression_tests/triso/inputs_true.dat +++ b/tests/regression_tests/triso/inputs_true.dat @@ -5,7 +5,7 @@ - + @@ -220,12 +220,12 @@ - - - - - - + + + + + + diff --git a/tests/regression_tests/triso/results_true.dat b/tests/regression_tests/triso/results_true.dat index dfc700c05..2bbecb4a9 100644 --- a/tests/regression_tests/triso/results_true.dat +++ b/tests/regression_tests/triso/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.683226E+00 7.383559E-02 +1.683227E+00 7.383566E-02 diff --git a/tests/regression_tests/triso/test.py b/tests/regression_tests/triso/test.py index 174bba94f..9ede6dbb0 100644 --- a/tests/regression_tests/triso/test.py +++ b/tests/regression_tests/triso/test.py @@ -53,19 +53,21 @@ class TRISOTestHarness(PyAPITestHarness): c5 = openmc.Cell(fill=opyc, region=+spheres[3]) inner_univ = openmc.Universe(cells=[c1, c2, c3, c4, c5]) - outer_radius = 422.5*1e-4 - trisos = openmc.model.pack_trisos( - radius=outer_radius, fill=inner_univ, domain_shape='cube', - domain_length=1., domain_center=(0., 0., 0.), n_particles=100) - - # Define box to contain lattice + # Define box to contain lattice and to pack TRISO particles in min_x = openmc.XPlane(x0=-0.5, boundary_type='reflective') max_x = openmc.XPlane(x0=0.5, boundary_type='reflective') min_y = openmc.YPlane(y0=-0.5, boundary_type='reflective') max_y = openmc.YPlane(y0=0.5, boundary_type='reflective') min_z = openmc.ZPlane(z0=-0.5, boundary_type='reflective') max_z = openmc.ZPlane(z0=0.5, boundary_type='reflective') - box = openmc.Cell(region=+min_x & -max_x & +min_y & -max_y & +min_z & -max_z) + box_region = +min_x & -max_x & +min_y & -max_y & +min_z & -max_z + box = openmc.Cell(region=box_region) + + outer_radius = 422.5*1e-4 + centers = openmc.model.pack_spheres(radius=outer_radius, + region=box_region, num_spheres=100) + trisos = [openmc.model.TRISO(outer_radius, inner_univ, c) + for c in centers] # Create lattice ll, ur = box.region.bounding_box diff --git a/tests/unit_tests/test_model_triso.py b/tests/unit_tests/test_model_triso.py index 19c4f9081..3c261ed6f 100644 --- a/tests/unit_tests/test_model_triso.py +++ b/tests/unit_tests/test_model_triso.py @@ -10,19 +10,54 @@ import pytest import scipy.spatial +_RADIUS = 0.1 _PACKING_FRACTION = 0.35 -_RADIUS = 4.25e-2 -domain_params = [ - {'shape': 'cube', 'length': 0.75, 'radius': 0., 'volume': 0.75**3}, - {'shape': 'cylinder', 'length': 0.5, 'radius': 0.5, 'volume': 0.5*pi*0.5**2}, - {'shape': 'sphere', 'length': 0., 'radius': 0.5, 'volume': 4/3*pi*0.5**3} -] +_SHAPES = ['rectangular_prism', 'cylinder', 'sphere', 'spherical_shell'] +_VOLUMES = [1.**3, 1.*pi*1.**2, 4/3*pi*1.**3, 4/3*pi*(1.**3 - 0.5**3)] -@pytest.fixture(scope='module', params=domain_params, - ids=['cube', 'cylinder', 'sphere']) -def domain(request): - return request.param +@pytest.fixture(scope='module') +def container(request): + return request.getfixturevalue(request.param) + + +@pytest.fixture(scope='module') +def centers(request): + container = request.getfixturevalue(request.param) + return openmc.model.pack_spheres(radius=_RADIUS, region=container, + pf=_PACKING_FRACTION, initial_pf=0.2) + + +@pytest.fixture(scope='module') +def rectangular_prism(): + min_x = openmc.XPlane(x0=-0.5) + max_x = openmc.XPlane(x0=0.5) + min_y = openmc.YPlane(y0=-0.5) + max_y = openmc.YPlane(y0=0.5) + min_z = openmc.ZPlane(z0=-0.5) + max_z = openmc.ZPlane(z0=0.5) + return +min_x & -max_x & +min_y & -max_y & +min_z & -max_z + + +@pytest.fixture(scope='module') +def cylinder(): + cylinder = openmc.ZCylinder(R=1.) + min_z = openmc.ZPlane(z0=-0.5) + max_z = openmc.ZPlane(z0=0.5) + return +min_z & -max_z & -cylinder + + +@pytest.fixture(scope='module') +def sphere(): + sphere = openmc.Sphere(R=1.) + return -sphere + + +@pytest.fixture(scope='module') +def spherical_shell(): + sphere = openmc.Sphere(R=1.) + inner_sphere = openmc.Sphere(R=0.5) + return -sphere & +inner_sphere @pytest.fixture(scope='module') @@ -33,73 +68,68 @@ def triso_universe(): return univ -@pytest.fixture(scope='module') -def trisos(domain, triso_universe): - trisos = openmc.model.pack_trisos( - radius=_RADIUS, - fill=triso_universe, - domain_shape=domain['shape'], - domain_length=domain['length'], - domain_radius=domain['radius'], - domain_center=(0., 0., 0.), - initial_packing_fraction=0.2, - packing_fraction=_PACKING_FRACTION - ) - return trisos - - -def test_overlap(trisos): - """Check that no TRISO particles overlap.""" - centers = [t.center for t in trisos] - +@pytest.mark.parametrize('centers', _SHAPES, indirect=True) +def test_overlap(centers): + """Check that none of the spheres in the packed configuration overlap.""" # Create KD tree for quick nearest neighbor search tree = scipy.spatial.cKDTree(centers) - # Find distance to nearest neighbor for all particles + # Find distance to nearest neighbor for all spheres d = tree.query(centers, k=2)[0] - # Get the smallest distance between any two particles + # Get the smallest distance between any two spheres d_min = min(d[:, 1]) assert d_min > 2*_RADIUS or d_min == pytest.approx(2*_RADIUS) -def test_contained(trisos, domain): - """Make sure all particles are entirely contained within the domain.""" - if domain['shape'] == 'cube': - x = max(np.hstack([abs(t.center) for t in trisos])) + _RADIUS - assert x < 0.5*domain['length'] or x == pytest.approx(0.5*domain['length']) +@pytest.mark.parametrize('centers,shape', zip(_SHAPES, _SHAPES), + indirect=['centers']) +def test_contained(centers, shape): + """Make sure all spheres are entirely contained within the domain.""" + if shape == 'rectangular_prism': + x = np.amax(abs(centers)) + _RADIUS + assert x < 0.5 or x == pytest.approx(0.5) - elif domain['shape'] == 'cylinder': - r = max([norm(t.center[0:2]) for t in trisos]) + _RADIUS - z = max([abs(t.center[2]) for t in trisos]) + _RADIUS - assert r < domain['radius'] or r == pytest.approx(domain['radius']) - assert z < 0.5*domain['length'] or z == pytest.approx(0.5*domain['length']) + elif shape == 'cylinder': + r = max(np.linalg.norm(centers[:,0:2], axis=1)) + _RADIUS + z = max(abs(centers[:,2])) + _RADIUS + assert r < 1. or r == pytest.approx(1.) + assert z < 0.5 or z == pytest.approx(0.5) - elif domain['shape'] == 'sphere': - r = max([norm(t.center) for t in trisos]) + _RADIUS - assert r < domain['radius'] or r == pytest.approx(domain['radius']) + elif shape == 'sphere': + r = max(np.linalg.norm(centers, axis=1)) + _RADIUS + assert r < 1. or r == pytest.approx(1.) + + elif shape == 'spherical_shell': + d = np.linalg.norm(centers, axis=1) + r_max = max(d) + _RADIUS + r_min = min(d) - _RADIUS + assert r_max < 1. or r_max == pytest.approx(1.) + assert r_min > 0.5 or r_min == pytest.approx(0.5) -def test_packing_fraction(trisos, domain): +@pytest.mark.parametrize('centers,volume', zip(_SHAPES, _VOLUMES), + indirect=['centers']) +def test_packing_fraction(centers, volume): """Check that the actual PF is close to the requested PF.""" - pf = len(trisos)*4/3*pi*_RADIUS**3/domain['volume'] + pf = len(centers) * 4/3 * pi *_RADIUS**3 / volume assert pf == pytest.approx(_PACKING_FRACTION, rel=1e-2) -def test_n_particles(triso_universe): - """Check that the function returns the correct number of particles""" - trisos = openmc.model.pack_trisos( - radius=_RADIUS, fill=triso_universe, domain_shape='cube', - domain_length=1.0, n_particles=800 +@pytest.mark.parametrize('container', _SHAPES, indirect=True) +def test_num_spheres(container): + """Check that the function returns the correct number of spheres""" + centers = openmc.model.pack_spheres( + radius=_RADIUS, region=container, num_spheres=50 ) - assert len(trisos) == 800 + assert len(centers) == 50 -def test_triso_lattice(triso_universe): - trisos = openmc.model.pack_trisos( - radius=_RADIUS, fill=triso_universe, domain_shape='cube', - domain_length=1.0, domain_center=(0., 0., 0.), packing_fraction=0.2 +def test_triso_lattice(triso_universe, rectangular_prism): + centers = openmc.model.pack_spheres( + radius=_RADIUS, region=rectangular_prism, pf=0.2 ) + trisos = [openmc.model.TRISO(_RADIUS, triso_universe, c) for c in centers] lower_left = np.array((-.5, -.5, -.5)) upper_right = np.array((.5, .5, .5)) @@ -112,50 +142,29 @@ def test_triso_lattice(triso_universe): ) -def test_domain_input(triso_universe): - # Invalid domain shape +def test_container_input(triso_universe): + # Invalid container shape with pytest.raises(ValueError): - trisos = openmc.model.pack_trisos( - radius=1, fill=triso_universe, n_particles=100, - domain_shape='circle' + centers = openmc.model.pack_spheres( + radius=_RADIUS, region=+openmc.Sphere(R=1.), num_spheres=100 ) - # Don't specify domain length on a cube - with pytest.raises(ValueError): - trisos = openmc.model.pack_trisos( - radius=1, fill=triso_universe, n_particles=100, - domain_shape='cube' - ) - # Don't specify domain radius on a sphere - with pytest.raises(ValueError): - trisos = openmc.model.pack_trisos( - radius=1, fill=triso_universe, n_particles=100, - domain_shape='sphere' - ) - -def test_packing_fraction_input(triso_universe): - # Provide neither packing fraction nor number of particles + +def test_packing_fraction_input(sphere): + # Provide neither packing fraction nor number of spheres with pytest.raises(ValueError): - trisos = openmc.model.pack_trisos( - radius=1, fill=triso_universe, domain_shape='cube', - domain_length=10 - ) - # Provide both packing fraction and number of particles - with pytest.raises(ValueError): - trisos = openmc.model.pack_trisos( - radius=1, fill=triso_universe, domain_shape='cube', - domain_length=10, n_particles=100, packing_fraction=0.2 + centers = openmc.model.pack_spheres( + radius=_RADIUS, region=sphere ) + # Specify a packing fraction that is too high for CRP with pytest.raises(ValueError): - trisos = openmc.model.pack_trisos( - radius=1, fill=triso_universe, domain_shape='cube', - domain_length=10, packing_fraction=1 + centers = openmc.model.pack_spheres( + radius=_RADIUS, region=sphere, pf=1. ) + # Specify a packing fraction that is too high for RSP with pytest.raises(ValueError): - trisos = openmc.model.pack_trisos( - radius=1, fill=triso_universe, domain_shape='cube', - domain_length=10, packing_fraction=0.5, - initial_packing_fraction=0.4 + centers = openmc.model.pack_spheres( + radius=_RADIUS, region=sphere, pf=0.5, initial_pf=0.4 ) From bbaad4ed93f0c6351d31aebe69afeee601815681 Mon Sep 17 00:00:00 2001 From: amandalund Date: Wed, 14 Nov 2018 16:03:44 -0600 Subject: [PATCH 57/62] Updated TRISO example notebook --- docs/source/pythonapi/index.rst | 2 +- docs/source/pythonapi/model.rst | 2 +- examples/jupyter/triso.ipynb | 115 +++++++++++++++++--------------- 3 files changed, 63 insertions(+), 56 deletions(-) diff --git a/docs/source/pythonapi/index.rst b/docs/source/pythonapi/index.rst index 3c28a2185..8abb52528 100644 --- a/docs/source/pythonapi/index.rst +++ b/docs/source/pythonapi/index.rst @@ -22,7 +22,7 @@ there are many substantial benefits to using the Python API, including: - Ability to plot individual universes as geometry is being created - A :math:`k_\text{eff}` search function (:func:`openmc.search_for_keff`) - Random sphere packing for generating TRISO particle locations - (:func:`openmc.model.pack_trisos`) + (:func:`openmc.model.pack_spheres`) - Ability to create materials based on natural elements or uranium enrichment For those new to Python, there are many good tutorials available online. We diff --git a/docs/source/pythonapi/model.rst b/docs/source/pythonapi/model.rst index 9ed77f366..90e8b779d 100644 --- a/docs/source/pythonapi/model.rst +++ b/docs/source/pythonapi/model.rst @@ -37,7 +37,7 @@ Functions :template: myfunction.rst openmc.model.create_triso_lattice - openmc.model.pack_trisos + openmc.model.pack_spheres Model Container --------------- diff --git a/examples/jupyter/triso.ipynb b/examples/jupyter/triso.ipynb index bc7801e2d..36e0c1f14 100644 --- a/examples/jupyter/triso.ipynb +++ b/examples/jupyter/triso.ipynb @@ -101,7 +101,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now that we have a universe that can be used for each TRISO particle, we need to randomly select locations. In this example, we will select locations at random within a 1 cm x 1 cm x 1 cm box centered at the origin with a packing fraction of 30%. Note that `pack_trisos` can handle up to the theoretical maximum of 60% (it will just be slow)." + "Next, we need a region to pack the TRISO particles in. We will use a 1 cm x 1 cm x 1 cm box centered at the origin." ] }, { @@ -111,16 +111,49 @@ "collapsed": false }, "outputs": [], + "source": [ + "min_x = openmc.XPlane(x0=-0.5, boundary_type='reflective')\n", + "max_x = openmc.XPlane(x0=0.5, boundary_type='reflective')\n", + "min_y = openmc.YPlane(y0=-0.5, boundary_type='reflective')\n", + "max_y = openmc.YPlane(y0=0.5, boundary_type='reflective')\n", + "min_z = openmc.ZPlane(z0=-0.5, boundary_type='reflective')\n", + "max_z = openmc.ZPlane(z0=0.5, boundary_type='reflective')\n", + "region = +min_x & -max_x & +min_y & -max_y & +min_z & -max_z" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we need to randomly select locations for the TRISO particles. In this example, we will select locations at random within the box with a packing fraction of 30%. Note that `pack_spheres` can handle up to the theoretical maximum of 60% (it will just be slow)." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], "source": [ "outer_radius = 425.*1e-4\n", - "\n", - "trisos = openmc.model.pack_trisos(\n", - " radius=outer_radius,\n", - " fill=triso_univ,\n", - " domain_shape='cube',\n", - " domain_length=1,\n", - " packing_fraction=0.3\n", - ")" + "centers = openmc.model.pack_spheres(radius=outer_radius, region=region, pf=0.3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that we have the locations of the TRISO particles determined and a universe that can be used for each particle, we can create the TRISO particles." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "trisos = [openmc.model.TRISO(outer_radius, triso_univ, c) for c in centers]" ] }, { @@ -132,7 +165,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": { "collapsed": false }, @@ -142,10 +175,10 @@ "output_type": "stream", "text": [ "Cell\n", - "\tID =\t10005\n", + "\tID =\t6\n", "\tName =\t\n", - "\tFill =\t10000\n", - "\tRegion =\t-10004\n", + "\tFill =\t1\n", + "\tRegion =\t-11\n", "\tRotation =\tNone\n", "\tTranslation =\t[-0.33455672 0.31790187 0.24135378]\n", "\n" @@ -165,7 +198,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "metadata": { "collapsed": false }, @@ -175,7 +208,7 @@ "output_type": "stream", "text": [ "[-0.45718713 -0.45730405 -0.45725048]\n", - "[ 0.45705454 0.45743843 0.45741142]\n" + "[0.45705454 0.45743843 0.45741142]\n" ] } ], @@ -194,7 +227,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 9, "metadata": { "collapsed": false }, @@ -205,7 +238,7 @@ "0.2996893513959326" ] }, - "execution_count": 7, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -218,42 +251,16 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now that we have our TRISO particles created, we need to place them in a lattice to provide optimal tracking performance in OpenMC. We'll start by creating a box that the lattice will be placed within." + "Now that we have our TRISO particles created, we need to place them in a lattice to provide optimal tracking performance in OpenMC. We can use the box we created above to place the lattice in. Actually creating a lattice containing TRISO particles can be done with the `model.create_triso_lattice()` function. This function requires that we give it a list of TRISO particles, the lower-left coordinates of the lattice, the pitch of each lattice cell, the overall shape of the lattice (number of cells in each direction), and a background material." ] }, { "cell_type": "code", - "execution_count": 8, - "metadata": { - "collapsed": false, - "scrolled": true - }, - "outputs": [], - "source": [ - "min_x = openmc.XPlane(x0=-0.5, boundary_type='reflective')\n", - "max_x = openmc.XPlane(x0=0.5, boundary_type='reflective')\n", - "min_y = openmc.YPlane(y0=-0.5, boundary_type='reflective')\n", - "max_y = openmc.YPlane(y0=0.5, boundary_type='reflective')\n", - "min_z = openmc.ZPlane(z0=-0.5, boundary_type='reflective')\n", - "max_z = openmc.ZPlane(z0=0.5, boundary_type='reflective')\n", - "box = openmc.Cell(region=+min_x & -max_x & +min_y & -max_y & +min_z & -max_z)" - ] - }, - { - "cell_type": "markdown", + "execution_count": 10, "metadata": {}, - "source": [ - "Our last step is to actually create a lattice containing TRISO particles which can be done with `model.create_triso_lattice()` function. This function requires that we give it a list of TRISO particles, the lower-left coordinates of the lattice, the pitch of each lattice cell, the overall shape of the lattice (number of cells in each direction), and a background material." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "collapsed": false - }, "outputs": [], "source": [ + "box = openmc.Cell(region=region)\n", "lower_left, upper_right = box.region.bounding_box\n", "shape = (3, 3, 3)\n", "pitch = (upper_right - lower_left)/shape\n", @@ -270,7 +277,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": { "collapsed": true }, @@ -288,14 +295,14 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "" ] @@ -330,14 +337,14 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQBAMAAABykSv/AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAFVBMVEX///+AgIA4vPKTUVDpgJFyEhJNv8S4mNHKAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+ILDgkoD8Jk3r8AAB1WSURBVHja7V3pWePKEiUFKwPLGWAywGQAZAD5h/CwpO6u5dTSLZmZud/TrxljSzq9VNd66unpv3Kd/iPX/4H8bdf/gfxt1z8JZJrn+b8AZF6u8z8PZJ6vP9ezQPLvAZl+cNxudyT/NpAfHC+3+3V9Pv/TQObLy+3t4+Pj9nplU/LvAbnePpbr9sqm5FeAIHE5eqvLy9vHhoRNyXFAprOH4ygkdUI+Pt5fnx8AZHZeFsr90efUCfn4YGvrICCLbH/GSKb7H5+PmZJ1ZX1+f38va+twIPPlulxw2PEBNgrkvrJ+cHx//awtuklGgbABLrL9FSLZUB4D5L5F7hNyn5L31zwQa93zNX/Hcd99PxJRf30qQI5YW/P1bZ2QFQjZ7T6QydikE9vZPwv3ViXiWX93XXbPBwP5uu/2LJDZA3Jud781ifhgIC/jQNDzGRByRolDagSIf+IcDWTmQO4T8rlIRDAlfUCCE+ehMzJXSXKfEgCkZ7MHSsCePRIDeaGSRK8tT/xO4tMpUAImLrXS4nfOSK3LSxHt8ublJvaBKO8fArkkzhHw+ylxjkwEyBcCsq4tc2bP4r4BkJd2st/gyY6PjMm6aXuvZZC+4bptd352hEYnkLcFyZfcj0/mPbMXBfKNgDhvpx4aLS2hxgMg4R3yQPRNzFvvAoINq3kenRIB5AaAnKx3mzAQ92lFHXrnit3hQNCM2L9Vwx++xc+ULHrEu3CjECDXg4D0/Fg9MjTvp8v19vPAm9S0G5DLoBUXSi0fSeIT8fc7Em370BkZNEejc+Sgq8yVofLs3yOhinIcjoIE+QCOAHLd/AHraXt+DBByGEHR5pwj2ZOlOgS+PjqFVsc13TexN9I2kEXXyyChhtXDtshsK2wciBLg25bKeHHM09YB37uMQ5/SE/kq8/BcVg9PxrBrU/KeXFndTtRNVKWAiBFYPTwqDIGf0k7b1NtN3U7UKXSOGUCqSpN6t+WMerulUC/fjxb8cUDasr9lVssSDfs5bLOekmidBEAmMJ8YCPPwJIDES5h/+9rre2RAoCg2gKwTspwMqbO6a9Ub4czsSOFlhoHUw/orLYk6xNC8SsQuvzYRv/jnGMilqk9fubXVdW36ayeQIh/uMvKmTwYIZGIensPVJ0MRd6+2L7aDYZGn5PcGkGZi3DfJXwCkKo13w8pzPphAHmBiDAEpyoAV1sVAmmPygUA6g1ibemb5g/4QkG6pVa91Qj6/ZVj3TwC5nyMvfedI++3iMwVh3V8Aonw+Ayc7AWKEdY3NfiQQZHsOB6zNsG5K/JpAMsc58Ab0a78EiBEgSRyI9jmSclggj9l4UgcLWdH49B4V5e4LC636VcV7lrtkl8sGeQMNpbFkfHw7jpFNC41cnDPa2DmbfdJwe4FcaaB2th5zDay25VbzuIQCK9BMfUgYVtZev09IbFaMA9kGiq/KqXoDM5s9SmYo37km/CzVrTSCQ9/fjIZaQMqU2M6HkhIUrK1hIPcszNvP87lHw4yGWl6UzcPzbvse/Nym9j6DS8vwMZnRUNOvtWqoMimVPql94xFAZsPrt+z2rPZ7WmXry89L2m9ZgNx8IPAcyQAx/LDW52bmQ3hKpIFkneHi7oZnnPhnc0CKFHcelVpag5GX1SGFYhVl7wjXoZeLEgSKc5t9MIJvR4/uA/i2iKGDEpiJ+A3eaUSvcuJ5eAB3pMuuFmvC4TuiHzoRVpzJtg/I9eX1oPRRcS3nHol5x+bMDiBQFzoMiBe8R+KjEwi7w3rWPWJCwnQKLT36gPDMq/7A02FAtG3WBUSqG+Ox+d1AJmlB9wDZFGuitjxoPuIEF53H0QOklGm9jnjWjgWinZUdQLYjVWVKPeTyM3XWGMk7HdMOIFXJef+FKfEzdeZLjZGUMc0DmUik96AUIEdUuJk67VXamHYAaYp1NsGhvRb6uiu9q/aLHFIoRpIHQiyazhwg/L5+SJvbI2KvoxhJN5Dv7rW1qEYaSRE8Yr+VlGkvU2crffumaQAdQDar/zsbe684oEq22mXvAkkzXqpo0QtZlL7NnUDqr7+60rImI72DOknO7cuXYhfXoKd2SDGXUHmVTiDf3UBmbNrD1KiJOsFWvxbKT4JOujSQNgzfPUCqe0roA3ALFNALksn0ZAogz78DxMiXmplQOm/fXXKTP7bZM+0dErVq6ksPkJGlZexZHtPc/vCjyzH/yJaLLHGsQL5HgQxudrqEKJA6qC2mqVWHCR+Y+2akBX96xK8Vn5hBKDCtOuzbI5vT9XP1HiMgaPzWJaQdhvdR+RSrg6oOtw4gveI3es6EVrSoUayfMy1903jSJ+7OcySYeaw6Uc8n/RUBUopn8tJk58neamngylrPAHmAz4YLl7itGhCyYPzqjX26FjGsUEVuPcDZZI0B+Qr0633ab50SaOrO61km6Up6gLDTIdjte+yRzWv9DqNYtKSdhfw69gjJ5ImA7LIQqwWB4giW0t0htTqA7LPZT16E1jKDOs6RHiCrF+Vj0IvihNESgbLwZO/YIzv9Wic7GWYbeFCbP7/AqQK6VofU2utpXO8AP70QnwcbTCOFAmi/8hxxgeiKsWMIXtoASyBtbXET8aLskU6DZ5c33ryc0GWzEK+BhTikXv8aECOlhNvss8Q2kMb+cCA1+Bt6Ufa4Mn8BSPFrXZFfixUPB1rpLwG52S5ng7JKJ5bvcvcfKLWg+F2RoNNHF+aUAEyU3vJIIEWlEkpufWeDguPC1QTm1/pDQICbKv6VNPIXT9ZtLHR/FHVbIpkzBW0suetAIHYQYOoJYI+TgTyBGw3cxizX7X6z0cA9BzKcy2CV65a18vDgKQdSXTpwqM7eBxvFqKShW5KcwWn4YCCruQKR6DXH1z7Op6vylFmND8lgoUCcLEXMpHBm/9WayLT5VpjfZdpO+oORUCAOSyGsZkFlOqK6H+Rzu+SUhwBxonYoMovZcoCfkcuyPad3EkjLfVZ55Ej4ANe7LAoDnge42o4G0sbvBoGIdRPKVFRMnqge2A3EqRmpsXL2YTSiqJg8U8+xE4hHbwKBhFfL8CGukmOUMh/IzfBNDQIhtXPV45aqeToEyCdkFRgEclNFgKkqtL1AzLT6PUC+G5AZT9LjgIDBylXqOUC2dD40SX8ASKdagYAwj/uhXFy5pWXlXI0A+eQfPQCIs9mHqlnAHpl/B8hLO4dlUHVE9QYbgsR3dBHCgUDMA3HIBgakJL8CJPKE9KvdugabA3nQ0jpeDdKn369sdhqTOQiI0kceyIqRNKyGLq0hPpACR5q6bx8GIX/25alsa5HQGl6jguxBKsqpEuj1ceEIGKx2qaYRlDl+HE2UdActpfaj/rRJOCBKnKClmM4sn/C5od8NCTnohv2CS0EfdZAsAUQ6x8X6JbN0UKXWQS7T7ddyaao0bBAnPKh27iAn9nIRYXGu9xMJCiyT9Ny+sdvNdWDXJJirLLXN+qWybUooca+b60AgONVJzvE6be8lTmhk3v1pIAkHybaRyrYxvPh/EgjTnh3VgNv/vTSovwLEbUNCkcyXstwaNd7etXUckBna/EgMks9ILuRORfVIIG8k+6EUIAQHUz9V8C8AYWrUqtiG/jCQJPQXAamenimkzyUie+duzwHJuFAuzYwtQNqZYRMp/SqQrXb87H5JA0nQOP8ukBwhk15aCSfAr272OUdYzjb73YrNxEJ+E0iJ+kVZVLM0/krA5cuJhfzmOdKifq/uKm7nyBafYh8YrznBAtEHAUkSltMWC8s6SdnnhYZ4zabdYfWGQNKE5dLlKlkr8WzOJUfzvgP3GKghEOZl89cW39s59mNqHveRtncDIX7Pd7/yiUtb7lU0HdaESinHlzgIpCPqJxpVUj+v04So2exZwq5RIHknZ6uzehbRKa+b0hIMu2eHkO2SASISRkIg3O3sbxKWJkVDCA0I0NqKe8KoNzNh9FUrZIJltQKCUYdBIDNql7X+mhqL4dqalDcsBBLHmErBkkglREvLI23simpoudAD5BsCofwG9CAAQFZWb4P80WGrAKBVrl8vEL1lGZ09Nce1+HWTzno6/YDtxJoNjQDZyife1RbVB+Kifr6Br/YCQarmU1kfhnIQLi2D//EEVBS3RrYHCPrq04bDUg6iOKxTvaL0er8+JA8EBtJXIHaTgCgOO1mtL09ajW8VtjD83QEE5Gg8rX9ZFi/iMpNpMGf1+Do4UoHZDKtPog67BfFpILx+iAJxrJsgfAmL/cEKWNVhtxisAwgiEXs6ccNZ3YKWOWo7r5WEgipIEgtd1OEskPebr/9yfw3hfGAF+yp12aVDcfkNqtKxmX8aCKWPz/shRA15A2K19Fjvz8ocnS30BbK87rHQt0KAtO0Z8qqsTDXth8CMgU+yYlhuZ39BzG4ROneZaiDs8Ep3jMNklE8nm1O+vKuM+ouF9/ltywKqJOoh4QHGbPAK9799OjnN27fftai/mvEACDMbFBBRyp3lpjZnZGZEEmj51Ki/umkEhNYCUO6MNVeo8ZttU5JiQjaBAGoPtT5eDMb+GAgbEX4gziJ3NRlyl6TGBYgA+G6y6cxQZX1LM05QXWsDIhS8ar77F6QHFUC+oH9BGcjtL674lUBIssAZAUny7s74QEwAsasDIdWVdQlqNrW0TrqWxgRC/P5dQOx3AwxR9htsYqNY9WKzpx+KGCZ2Ajk5SiN4g5lZC4pJo2v0RIFIZrP7g2yq8ejbLPY1jeR3L7cBEaSE+A1GxzSs4JQwqptR5zuK6SUOxACIYy3pl+Sp6dPYhEgvcwPiqijx6LxhnRWPN3vzaTAaAko/Y6UxHB3DHZRr6DYCA1YGh2p8PDq43+S8qPDpnsH9DxXaDDGsvqBhlRidC3DoTu3MOOtf7M+OVRwloambQQKOA8JJJt/6mPRYFFbYm6IDhI/Va7WM5cB5rqGwO0TuoMHrZ9+9Yam8p8+md0UOutHRMrpNEXmDWUT3AdnXVxVc1W/3JTWXzTCH8TXLj55ahpETexSIpvPd3so8Pw2e4impj0VhhbFrtjp7Wu20TpYdmq47iAI9g0Asrcdx8KpShxXH1SQGMYAcepk+CcTp3V5Zh+XmpIvI6b63a34AVen6tqYQwF4ti4ovD2RULSVAkK3G+hQL/vW1ZoPrNJW3PA5ZWx0qHwTE6lMs8z/Kh3liBQfIjrVlATGlWXPMUmlmUbr+3UBQFY1Xmf5rQNBmNxsuQ+tVx4XVOz4aiCV+basacp66yYTiCH/MZpe8xKkZqUBqyYaXTCj9xI8Rv9ZecPeImhGvK5diebQPxB04TKXRFr9sj9Rv23kwa54TcQk8RkUR4fdz+9zSilHptgvkKlweBwBBvgTDsOLEyxEvsADC2n7MteqP5aLsxAHccIaWa0fCgc/NAdICp1kC/NirCQ2ftuRlw2XLVdxi8kShEUuLALk2J00KiAqGKXJvwySjTyJ/Q80Eyn2q87B+ZO8R7S7xgejwJKrFQ0GOSQR1KhDbTaRiutPlzRK/2mJ2gUxKNmixDHvDnoB8dGfqRCrk6sf2gdiaK+SAgFwETaRs+arxH7S44T9gy5irKONApjaBTW1IA7HCCnaynhIbqLRxCEjGlepEDyYk7zSDNEfC7m3VBHUCSeW0xWEQ8X4dnier6Qfd7NcYSJmQrw8vPhgC0RHPFccUGwp23ZyWGS4Qj3q8vZUfLLfKdVMORLOSUXtePSBXS8Nj3/KD5YJQgHyeSTsxa0s1fb4DxDYeBBBvyQuKB4Yjwb0BnUSnEwiIeUBAGzP0NQ9IG1LR7OKSizBanRm0FHeAyIZA5rOcxW4UMebLqeh5T4P0VXlKGFaXZCKBI36sIkbc+dRAUoINE6NultIyDWSIeqkUMS4SnPYacsI9aJw25hGqwcq9GQAZzlHZXpgXMdY7jAQtZRWNWNIHLC1nMK0iRiduZU+M6kXOVvT+ze4CwdSljlViT0hxzBv5zfvFrwfEKGK0DGF3TF6MQz4HJD4QIyCfDcgrARKr1RKIl6KPgDRddWZZQyPUElYR4wCQ1b/0bVM3SyDzSuxzPp32Zg0JINR7wJZWDkir8jciDIrxjBykl60b6cfHIO1zCoi874QUhbiIW3LQ0dDqzqwhB4g28DgO0NY2KuLmQHgHbtsJtRMIMPAaDtg5JOYO5fSG3JNM6pnHuD7MimXTKWR3c4+KuDnhpKj7LdljqQpzcJlFjFvoEyRCGgkCcRH3k/w6XUv7yAu4q5DHSYxEQaube6L2mXOZUjLpUhjx8jqcJSaKGMkW1f3Rto9x98ROIIB8bSetZSti/FLxDeSTsJ0NfUAgZ9me+C7iYN3+grxIjvuna4/gaPCeMLUuYizjAo8LmzapS2rlqGX6gIhCN5Lkj0z9qlApPaTrHPGiwaOXqA+rZRfnE/CHO5kOXSc7FZbfWSCBE5dzsEaNhi6W971P18pSy7AXjSQBKWI8E8oxrCg4KRtzh/brxB6dCYmmpOgc8zm0Vj0iq3o0JOyRgRmZQiCE0yW0Vu0IFU/diizEgT2SANLCCsxa7QYy5232AamVqy3awDJrFQ2qy5GG1iXdofvOkcyM1Itaq7j20gMCWpKxM5X3VjBnFgxBvVcSSIJy7ML8NrI9r5TdXMvBula7z0TfU6sVHYpYgnIsSP2jp2mJTFQFmmu/zVNbGmjxajvdcii/shKUYz6zIy9irCbNZrlwe0QywGw+fYpj2DhJNFGZWJ8PvYvosJLapwWxMKy4Fs15vWp525D9ngKS7wQ3Sf4eabNzXZXyeq1z+XEbNeBjyjFB8uIOF9Or7+8nvCgs+ZbLCZ9UKj5SkkCKqRsV+RNLZ/nqk/wzSVDnrBUBqVQYbs4AaYnl0bSr8vMndaPqNil3XadgktQTYj5EbNIHYp63q4fwPeRq1JxFT/JGq9tk8/0SW8JlrMn4jVJAzHC0/N71JlK6tTe+Jk21tVQ5Vi0gOlcSPZsBsdhmVfoZ/hojzbgLhid9pxpFZWtJ7S4+jrFvNUkmmmuPp5PvQcSqHjkmEEV2ZNeyCSC+rtVGMsAhgNxH5Uneggxz4w74GeeZddfhD8rFH8JYTcdFWRG+JBDBDi8MutWa+KRtgsSERBGhMHrWcdEcAAlEJlb1AEnF6Hg8c9eEeEBqYlUteoBLC71Gkmsh4KDrupylpcmn0pud1ek4i4bL851ArM3Oj3EAxGOWTGYWgGeMln7b4hfY9vJANBdGOo0IeBqnDhuTTa51IKpGWY6KIhdGOo1oMc1uItd+qAhK0yqWMnAw3mIl2Eyk+XwoZSxnq9U1EMkiVYGArcwtqRKJ1WpIR2LXJGZguI5+3o6uL6HG83O7bBJhWK0TpLte9GWoiSK8mjHSCUTKngqEnLrX6m1gFNa4IuS0K2fw7t0YohZRW7YAgYyl3PmwOdZ1sq5VPpkCEuu6+M8zyV0zgTzT5zT7FXLrnE576KDiGbF8AdOW31mSJ3wg0kHHcJHBeRvNUGvJsDaOyxUiESs9AMJdpsbo2GWS4RVKrbK6z+CnjPLG3SPoxuhtSpnk10fnXg/PEY+gh7MjUiAfCSAYncmtAV6N/zkA4no3UVgBpUzn5XsHnbV8bz/CIj3V+nb1p/xAJO/Sozyk019Baos7XPYhrC6ta62r3MhkM6dEVpyaOLqSjWy1KAGk5JyluHfLyM2ZFqb96V++mxYBAbkWXc1VU7h5z6okEEPjtoFw46O7J2mCzLC/HVrA/Q+B8I5uc5rDnSCJ9PGeBiMVyFsvEK6z9z8zk5bScdrsAEJ1dtgXY+81cP4PAaE6+wQ7y+4FkiprlEC698iJ1qKaVct7rgEdeRBIY3WJUyBGgAzU1RDraYQobIJ85nuvkZKtjlosDOTWnxN4ChJTppEiutmPJMdA3jiQzDOjk0SMTlZstdMt+CoEYhOruDgu3tkuydBzQEzPzeOAGEni+4CU2uKEmjkORBjwER3qGKt7NDwHAJk4H0q4CIb2SEoZdYBcYiByqEyO73oNlv7OSUt1VPxuVWVVLMaCUlbMJoFk6fAiIF9GM8dSx32rjuHo6GInu9sYY8g/D0tcYxWF2qAFCHPFop/kdK27EHnuj5lAIKqxN5gQrl8TP4rd+JvxmJpDnqW1EEsOA0ENPtQXqI2UsByyaQU5VmvIG4+e+VGeCY258k417StjAqUSPao/xnebYCZ/8D0/SVJH8DJAUqk3OTUR91bAg+c5Hwjd4mZapIC0ZCjzJadYaKzvVxxLAU8jYk1k93kTUW7TlmOJ3HEPtJyVTpNIA6aa7ZmGg07nHRAWB/oC08xDuNdr4Gm0WQPxt0JWQEy13YDIlBZ2jrTnq2B01DpsJjyOphbjND/FSExtTScZtRQQerIrj/60hgy9NfNWs2BtAimS+l4FuUleMTkRcAFkbWLMY5NtQjrCIbK/Fw8/tH/WtCpytNosHE66CwCydTHmCedhqDMA0vQx9jJm89PuCwBR6vAKJJMxSoGI1nF0SBoSo2ndfiDL5E5bTx66kxn9UuaajR54LPhr9gztv4DUQukEUxJIe0cLCMu8N1ttjgAB3N2TJqPjfcSMi6YEGEB4ywtswI4Bge0cZQpTbo+wpks+kG1usUthCIjWtSoSDjiRxMTUdmOz84P0SCDJLoiJEHcT28+zeY7MO4BM7kgqe8QD4k/IlartzIo0gXTtEf8VcrpdwgMiTGSjubgE0iG1Am9SOiYWVomTfleLptPoU2n/FRNIdI6EJ0BHJN+95NTiqRZac8fJHvYqUn6twUsS5eOpFt2pOnQtixKWDuVLT2aEPR5ic1t2DR3XDu1XOyn0nGXd5D4QKW5x1z5eHNhhjyyn1KvrWxptistvog5A7NXnGYN5C9Frmy1uvgcG8mLUzpaCBIk9LGezz2c7w/foC2mfOCLCy78yXpR7PccfBZLpYJnxa/0AOaeW1sOAJNrRZDyNdyArDcHrnwKS+eFFdrizgXRaqcNAxGbP/jL2xs9z5kA8CEhPn3r5mon4SK28eTQQ0Xyopzzg58fsf6b2mzFSh0pYyk/vv3Qccr2X08cqOO7mwP0ZDcFcwyrK/jgQSMIkCh3SHo4iSbD9cSSQqNBxDxclESVZU3MHkOhl4qCNMwZVb9jN+7oXCOFr7bZIZGKuDkek7xSK38TL1CDjrXdK1vLGd071MUAbw6XmKJC+xGCqPQkC+BqO650QUdU0BoQG4hMHMvPJ8BLgcVNT1KIMAqHJyGFiMK/QreUE74UUdMjUlOJ/DEgfpTxXQVXB+ZipKQs9xoEoz5I5diUv8bnQrbwJgTv1C151jo0BsdsugMijIGEAQAauSVbqDHrjrfzEWdupkiDhGCDqQD4WCIrO81qhw4DIMqdBIG8whxfmS0jujYjRNAtkYwG/7QXyCYBw/vz2SKZNSfE7dOkisCOBwJwiVRgoDsQ/DATuEZjlpYHMgB3laCDJG2MgmJxQ83swpXGY4cUDEjvG2suB4BfnGH9u35VAOCfGmAe50f5pIK6qwMcNHoiYwFMD4Q7Z2D9qABFteFWxGL6nwAh1LVxiBqhjqNesp0ibvZAUkLDqDc0Hw8hiRiX4hfO3ARAaoezOhCpvJNtiNCAllwTdc0thILfRPR8N3mNI5tOGbItF9QMpZ6+OjzghKBXk5TEjBKRpkoBeqYmVSflws9dK93sFavxk10jpIC8o5rVIzl16sDB87E4Jfd8UEO3TnnR5tVUHNHsn+TgQyZ6aA6KjDLrg3QICec7aQ4cbnAh5NwpEGTZ2ZZZmt5NAxtz+/CgVUgtvdhR2V+QIZkeDmZu64ta9+ZvWxYBcjLGB+QNyUZiNACYv/nUX7CPniAPEORDxm4iv240AnEU7fLJ7QOw0MSMSN7FvO40AvKSpQV3LA2LHRDhhmHU5DQUcFXdQ+3WBnKxb5kKKPg+/eY3ZIz4Q+x0zsqX2OvlKOYQPvrJAElvyIdwdBwNJ0iIPsKn8NpCUFUw6tf36yhqOIWK0tXfer0/IoUAIB9Sjk1geDKSTlesvBrLDvPi7gBynOv1pID1cgn85kD91/R/I33b9D2BqKIQldvOpAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTExLTE0VDE1OjQwOjE1LTA2OjAwf3H3CgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0xMS0xNFQxNTo0MDoxNS0wNjowMA4sT7YAAAAASUVORK5CYII=\n", "text/plain": [ "" ] @@ -356,7 +363,7 @@ "metadata": { "anaconda-cloud": {}, "kernelspec": { - "display_name": "Python [default]", + "display_name": "Python 3", "language": "python", "name": "python3" }, @@ -370,9 +377,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.2" + "version": "3.6.5" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } From fc5bbd6a9bcb138c48e7114e64325b29119ba4e2 Mon Sep 17 00:00:00 2001 From: amandalund Date: Thu, 15 Nov 2018 10:46:18 -0600 Subject: [PATCH 58/62] Fix TRISO regression test --- tests/regression_tests/triso/results_true.dat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/regression_tests/triso/results_true.dat b/tests/regression_tests/triso/results_true.dat index 2bbecb4a9..dfc700c05 100644 --- a/tests/regression_tests/triso/results_true.dat +++ b/tests/regression_tests/triso/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.683227E+00 7.383566E-02 +1.683226E+00 7.383559E-02 From d624265ef85692f738eb8df18ada4a6b4f8dc299 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 15 Nov 2018 13:04:35 -0600 Subject: [PATCH 59/62] Make explicit template instantiation definition a declaration in filter.h --- include/openmc/tallies/filter.h | 2 +- src/tallies/filter.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/openmc/tallies/filter.h b/include/openmc/tallies/filter.h index 5590a0767..fd3be0aaf 100644 --- a/include/openmc/tallies/filter.h +++ b/include/openmc/tallies/filter.h @@ -29,7 +29,7 @@ public: // Without an explicit instantiation of vector, the Intel compiler // will complain about the threadprivate directive on filter_matches. Note that // this has to happen *outside* of the openmc namespace -template class std::vector; +extern template class std::vector; namespace openmc { diff --git a/src/tallies/filter.cpp b/src/tallies/filter.cpp index aa5d19607..7cf54165d 100644 --- a/src/tallies/filter.cpp +++ b/src/tallies/filter.cpp @@ -26,6 +26,8 @@ #include "openmc/tallies/filter_universe.h" #include "openmc/tallies/filter_zernike.h" +// explicit template instantiation definition +template class std::vector; namespace openmc { From c4e60db2e442b1ef699494b614c79b20075b3d57 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 16 Nov 2018 08:53:14 -0600 Subject: [PATCH 60/62] Move filter_match_pointer to simulation.cpp to get around macOS bug --- src/simulation.cpp | 6 ++++++ src/tallies/filter.cpp | 3 +-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/simulation.cpp b/src/simulation.cpp index c3d1c17b4..50bf12521 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -565,4 +565,10 @@ extern "C" void k_generation_clear() { simulation::k_generation.clear(); } extern "C" void k_generation_reserve(int i) { simulation::k_generation.reserve(i); } extern "C" int64_t work_index(int rank) { return simulation::work_index[rank]; } +// This function was moved here to get around a bug on macOS whereby an invalid +// pointer is returned for the threadprivate filter_matches +extern "C" FilterMatch* filter_match_pointer(int indx) { + return &simulation::filter_matches[indx]; +} + } // namespace openmc diff --git a/src/tallies/filter.cpp b/src/tallies/filter.cpp index 7cf54165d..fd5e38f7e 100644 --- a/src/tallies/filter.cpp +++ b/src/tallies/filter.cpp @@ -63,8 +63,7 @@ free_memory_tally_c() //============================================================================== extern "C" { - FilterMatch* filter_match_pointer(int indx) - {return &simulation::filter_matches[indx];} + // filter_match_point moved to simulation.cpp void filter_match_bins_push_back(FilterMatch* match, int val) From 9b00c61a03fa4cdc76870ab2a34d94f2e6329ba7 Mon Sep 17 00:00:00 2001 From: amandalund Date: Mon, 19 Nov 2018 21:55:53 -0600 Subject: [PATCH 61/62] Address @paulromano comments on #1121 --- openmc/model/triso.py | 593 ++++++++++++++++++------------------------ 1 file changed, 251 insertions(+), 342 deletions(-) diff --git a/openmc/model/triso.py b/openmc/model/triso.py index a99f136bb..e04d7f589 100644 --- a/openmc/model/triso.py +++ b/openmc/model/triso.py @@ -8,7 +8,6 @@ from collections.abc import Iterable from heapq import heappush, heappop from math import pi, sin, cos, floor, log10, sqrt from numbers import Real -from operator import attrgetter from random import uniform, gauss import numpy as np @@ -158,10 +157,7 @@ class _Container(metaclass=ABCMeta): @center.setter def center(self, center): - if np.asarray(center).size != 3: - raise ValueError('Unable to set domain center to {} since it must ' - 'be of length 3'.format(center)) - self._center = [float(x) for x in center] + self._center = center def mesh_cell(self, p): """Calculate the index of the cell in a mesh overlaid on the domain in @@ -200,6 +196,20 @@ class _Container(metaclass=ABCMeta): for i in range(3)] return list(itertools.product(*({int(x) for x in y} for y in r))) + @abstractmethod + def from_region(self, region, sphere_radius): + """Create a container to pack spheres in based on a region. + + Parameters + ---------- + region : openmc.Region + Region to create container from. + sphere_radius : float + Outer radius of spheres. + + """ + pass + @abstractmethod def random_point(self): """Generate Cartesian coordinates of center of a sphere that is @@ -268,7 +278,7 @@ class _RectangularPrism(_Container): Length in x-, y-, and z- directions of each cell in mesh overlaid on domain. limits : list of float - Maximum distance from center in x-, y-, or z-direction where sphere + Minimum and maximum distance in x-, y-, and z-direction where sphere center can be placed. volume : float Volume of the container. @@ -296,9 +306,11 @@ class _RectangularPrism(_Container): @property def limits(self): if self._limits is None: - self._limits = [self.width/2 - self.sphere_radius, - self.depth/2 - self.sphere_radius, - self.height/2 - self.sphere_radius] + c = self.center + r = self.sphere_radius + x, y, z = self.width/2, self.depth/2, self.height/2 + self._limits = [[c[0] - x + r, c[1] - y + r, c[2] - z + r], + [c[0] + x - r, c[1] + y - r, c[2] + z - r]] return self._limits @property @@ -335,11 +347,50 @@ class _RectangularPrism(_Container): def limits(self, limits): self._limits = limits + @classmethod + def from_region(self, region, sphere_radius): + check_type('region', region, openmc.Region) + + # Assume the simplest case where the prism volume is the intersection + # of the half-spaces of six planes + if not isinstance(region, openmc.Intersection): + raise ValueError + + if any(not isinstance(node, openmc.Halfspace) for node in region): + raise ValueError + + if len(region) != 6: + raise ValueError + + # Sort half-spaces by surface type + px1, px2, py1, py2, pz1, pz2 = sorted(region, key=lambda x: x.surface.type) + + # Make sure the region consists of the correct surfaces + if (not isinstance(px1.surface, openmc.XPlane) or + not isinstance(px2.surface, openmc.XPlane) or + not isinstance(py1.surface, openmc.YPlane) or + not isinstance(py2.surface, openmc.YPlane) or + not isinstance(pz1.surface, openmc.ZPlane) or + not isinstance(pz2.surface, openmc.ZPlane)): + raise ValueError + + # Make sure the half-spaces are on the correct side of the surfaces + ll, ur = region.bounding_box + if any(x in ll or x in ur for x in (-np.inf, np.inf)): + raise ValueError + + # Calculate the parameters for the container + width, depth, height = ur - ll + center = ll + [width/2, depth/2, height/2] + + # The region is the volume of a rectangular prism, so create container + return _RectangularPrism(width, depth, height, sphere_radius, center) + def random_point(self): - x_max, y_max, z_max = self.limits - return [uniform(-x_max, x_max), - uniform(-y_max, y_max), - uniform(-z_max, z_max)] + ll, ul = self.limits + return [uniform(ll[0], ul[0]), + uniform(ll[1], ul[1]), + uniform(ll[2], ul[2])] def repel_spheres(self, p, q, d, d_new): # Moving each sphere distance 's' away from the other along the line @@ -354,8 +405,8 @@ class _RectangularPrism(_Container): # Enforce the rigid boundary by moving each sphere back along the # surface normal until it is completely within the container if it # overlaps the surface - p[:] = np.clip(p, [-x for x in self.limits], self.limits) - q[:] = np.clip(q, [-x for x in self.limits], self.limits) + p[:] = np.clip(p, self.limits[0], self.limits[1]) + q[:] = np.clip(q, self.limits[0], self.limits[1]) class _Cylinder(_Container): @@ -396,8 +447,8 @@ class _Cylinder(_Container): Length in x-, y-, and z- directions of each cell in mesh overlaid on domain. limits : list of float - Maximum radial distance and maximum distance from center in z-direction - where sphere center can be placed. + Maximum radial distance and minimum and maximum distance in the + direction parallel to the axis where sphere center can be placed. volume : float Volume of the container. @@ -436,8 +487,10 @@ class _Cylinder(_Container): @property def limits(self): if self._limits is None: - self._limits = [self.radius - self.sphere_radius, - self.length/2 - self.sphere_radius] + z0 = self.center[self.shift[2]] + z = self.length/2 + r = self.sphere_radius + self._limits = [[z0 - z + r], [z0 + z - r, self.radius - r]] return self._limits @property @@ -476,15 +529,72 @@ class _Cylinder(_Container): def limits(self, limits): self._limits = limits + @classmethod + def from_region(self, region, sphere_radius): + check_type('region', region, openmc.Region) + + # Assume the simplest case where the cylinder volume is the + # intersection of the half-spaces of a cylinder and two planes + if not isinstance(region, openmc.Intersection): + raise ValueError + + if any(not isinstance(node, openmc.Halfspace) for node in region): + raise ValueError + + if len(region) != 3: + raise ValueError + + # Identify the axis that the cylinder lies along + axis = region[0].surface.type[0] + + # Make sure the region is composed of a cylinder and two planes on the + # same axis + count = Counter(node.surface.type for node in region) + if count[axis + '-cylinder'] != 1 or count[axis + '-plane'] != 2: + raise ValueError + + # Sort the half-spaces by surface type + cyl, p1, p2 = sorted(region, key=lambda x: x.surface.type) + + # Calculate the parameters for a cylinder along the x-axis + if axis == 'x': + if p1.surface.x0 > p2.surface.x0: + p1, p2 = p2, p1 + length = p2.surface.x0 - p1.surface.x0 + center = (p1.surface.x0 + length/2, cyl.surface.y0, cyl.surface.z0) + + # Calculate the parameters for a cylinder along the y-axis + elif axis == 'y': + if p1.surface.y0 > p2.surface.y0: + p1, p2 = p2, p1 + length = p2.surface.y0 - p1.surface.y0 + center = (cyl.surface.x0, p1.surface.y0 + length/2, cyl.surface.z0) + + # Calculate the parameters for a cylinder along the z-axis + else: + if p1.surface.z0 > p2.surface.z0: + p1, p2 = p2, p1 + length = p2.surface.z0 - p1.surface.z0 + center = (cyl.surface.x0, cyl.surface.y0, p1.surface.z0 + length/2) + + # Make sure the half-spaces are on the correct side of the surfaces + if cyl.side != '-' or p1.side != '+' or p2.side != '-': + raise ValueError + + radius = cyl.surface.r + + # The region is the volume of a cylinder, so create container + return _Cylinder(length, radius, axis, sphere_radius, center) + def random_point(self): - r_max, z_max = self.limits - r = sqrt(uniform(0, r_max**2)) + ll, ul = self.limits + r = sqrt(uniform(0, ul[1]**2)) t = uniform(0, 2*pi) i, j, k = self.shift p = [None]*3 - p[i] = r*cos(t) - p[j] = r*sin(t) - p[k] = uniform(-z_max, z_max) + p[i] = r*cos(t) + self.center[i] + p[j] = r*sin(t) + self.center[j] + p[k] = uniform(ll[0], ul[0]) return p def repel_spheres(self, p, q, d, d_new): @@ -500,119 +610,24 @@ class _Cylinder(_Container): # Enforce the rigid boundary by moving each sphere back along the # surface normal until it is completely within the container if it # overlaps the surface - r_max, z_max = self.limits + ll, ul = self.limits + c = self.center i, j, k = self.shift - r = sqrt(p[i]**2 + p[j]**2) - if r > r_max: - p[i] *= r_max/r - p[j] *= r_max/r - p[k] = np.clip(p[k], -z_max, z_max) + r = sqrt((p[i] - c[i])**2 + (p[j] - c[j])**2) + if r > ul[1]: + p[i] = (p[i] - c[i])*ul[1]/r + c[i] + p[j] = (p[j] - c[j])*ul[1]/r + c[j] + p[k] = np.clip(p[k], ll[0], ul[0]) - r = sqrt(q[i]**2 + q[j]**2) - if r > r_max: - q[i] *= r_max/r - q[j] *= r_max/r - q[k] = np.clip(q[k], -z_max, z_max) + r = sqrt((q[i] - c[i])**2 + (q[j] - c[j])**2) + if r > ul[1]: + q[i] = (q[i] - c[i])*ul[1]/r + c[i] + q[j] = (q[j] - c[j])*ul[1]/r + c[j] + q[k] = np.clip(q[k], ll[0], ul[0]) -class _Sphere(_Container): - """Spherical container in which to pack spheres. - - Parameters - ---------- - radius : float - Radius of the spherical container. - center : Iterable of float - Cartesian coordinates of the center of the container. Default is - (0., 0., 0.) - - Attributes - ---------- - radius : float - Radius of the spherical container. - sphere_radius : float - Radius of spheres to be packed in container. - center : list of float - Cartesian coordinates of the center of the container. Default is - (0., 0., 0.) - cell_length : list of float - Length in x-, y-, and z- directions of each cell in mesh overlaid on - domain. - limits : list of float - Maximum radial distance where sphere center can be placed. - volume : float - Volume of the container. - - """ - - def __init__(self, radius, sphere_radius, center=(0., 0., 0.)): - super().__init__(sphere_radius, center) - self.radius = radius - - @property - def radius(self): - return self._radius - - @property - def limits(self): - if self._limits is None: - self._limits = [self.radius - self.sphere_radius] - return self._limits - - @property - def cell_length(self): - if self._cell_length is None: - mesh_length = 3*[2*self.radius] - self._cell_length = [x/int(x/(4*self.sphere_radius)) - for x in mesh_length] - return self._cell_length - - @property - def volume(self): - return 4/3*pi*self.radius**3 - - @radius.setter - def radius(self, radius): - self._radius = float(radius) - self._limits = None - self._cell_length = None - - @limits.setter - def limits(self, limits): - self._limits = limits - - def random_point(self): - r_max = self.limits[0] - x = (gauss(0, 1), gauss(0, 1), gauss(0, 1)) - r = (uniform(0, r_max**3)**(1/3) / sqrt(x[0]**2 + x[1]**2 + x[2]**2)) - return [r*s for s in x] - - def repel_spheres(self, p, q, d, d_new): - # Moving each sphere distance 's' away from the other along the line - # joining the sphere centers will ensure their final distance is - # equal to the outer diameter - s = (d_new - d)/2 - - v = (p - q)/d - p += s*v - q -= s*v - - # Enforce the rigid boundary by moving each sphere back along the - # surface normal until it is completely within the container if it - # overlaps the surface - r_max = self.limits[0] - - r = sqrt(p[0]**2 + p[1]**2 + p[2]**2) - if r > r_max: - p *= r_max/r - - r = sqrt(q[0]**2 + q[1]**2 + q[2]**2) - if r > r_max: - q *= r_max/r - - -class _SphericalShell(_Sphere): +class _SphericalShell(_Container): """Spherical shell container in which to pack spheres. Parameters @@ -640,8 +655,7 @@ class _SphericalShell(_Sphere): Length in x-, y-, and z- directions of each cell in mesh overlaid on domain. limits : list of float - Maximum radial distance and minimum radial distance where sphere - center can be placed. + Minimum and maximum radial distance where sphere center can be placed. volume : float Volume of the container. @@ -649,9 +663,14 @@ class _SphericalShell(_Sphere): def __init__(self, radius, inner_radius, sphere_radius, center=(0., 0., 0.)): - super().__init__(radius, sphere_radius, center) + super().__init__(sphere_radius, center) + self.radius = radius self.inner_radius = inner_radius + @property + def radius(self): + return self._radius + @property def inner_radius(self): return self._inner_radius @@ -659,14 +678,32 @@ class _SphericalShell(_Sphere): @property def limits(self): if self._limits is None: - self._limits = [self.radius - self.sphere_radius, - self.inner_radius + self.sphere_radius] + r_max = self.radius - self.sphere_radius + if self.inner_radius == 0: + r_min = 0 + else: + r_min = self.inner_radius + self.sphere_radius + self._limits = [[r_min], [r_max]] return self._limits + @property + def cell_length(self): + if self._cell_length is None: + mesh_length = 3*[2*self.radius] + self._cell_length = [x/int(x/(4*self.sphere_radius)) + for x in mesh_length] + return self._cell_length + @property def volume(self): return 4/3*pi*(self.radius**3 - self.inner_radius**3) + @radius.setter + def radius(self, radius): + self._radius = float(radius) + self._limits = None + self._cell_length = None + @inner_radius.setter def inner_radius(self, inner_radius): self._inner_radius = float(inner_radius) @@ -676,11 +713,58 @@ class _SphericalShell(_Sphere): def limits(self, limits): self._limits = limits + @classmethod + def from_region(self, region, sphere_radius): + check_type('region', region, openmc.Region) + + # First check if the region is the volume inside a sphere. Assume the + # simplest case where the sphere volume is the negative half-space of a + # sphere. + if (isinstance(region, openmc.Halfspace) + and isinstance(region.surface, openmc.Sphere) + and region.side == '-'): + + # The region is the volume of a sphere, so create container + radius = region.surface.r + center = (region.surface.x0, region.surface.y0, region.surface.z0) + + return _SphericalShell(radius, 0., sphere_radius, center) + + # Next check for a spherical shell volume. Assume the simplest case + # where the spherical shell volume is the intersection of the + # half-spaces of two spheres. + if not isinstance(region, openmc.Intersection): + raise ValueError + + if any(not isinstance(node, openmc.Halfspace) for node in region): + raise ValueError + + if len(region) != 2: + raise ValueError + + if any(not isinstance(node.surface, openmc.Sphere) for node in region): + raise ValueError + + s1, s2 = sorted(region, key=lambda x: x.surface.r) + radius = s2.surface.r + inner_radius = s1.surface.r + center = (s1.surface.x0, s1.surface.y0, s1.surface.z0) + + if center != (s2.surface.x0, s2.surface.y0, s2.surface.z0): + raise ValueError + + if s1.side != '+' or s2.side != '-': + raise ValueError + + # The region is the volume of a spherical shell, so create container + return _SphericalShell(radius, inner_radius, sphere_radius, center) + def random_point(self): - r_max, r_min = self.limits - x = (gauss(0, 1), gauss(0, 1), gauss(0, 1)) - r = (uniform(r_min**3, r_max**3)**(1/3)/sqrt(x[0]**2 + x[1]**2 + x[2]**2)) - return [r*s for s in x] + c = self.center + ll, ul = self.limits + x, y, z = (gauss(0, 1), gauss(0, 1), gauss(0, 1)) + r = (uniform(ll[0]**3, ul[0]**3)**(1/3)/sqrt(x**2 + y**2 + z**2)) + return [r*x + c[0], r*y + c[1], r*z + c[2]] def repel_spheres(self, p, q, d, d_new): # Moving each sphere distance 's' away from the other along the line @@ -695,19 +779,20 @@ class _SphericalShell(_Sphere): # Enforce the rigid boundary by moving each sphere back along the # surface normal until it is completely within the container if it # overlaps the surface - r_max, r_min = self.limits + c = self.center + ll, ul = self.limits - r = sqrt(p[0]**2 + p[1]**2 + p[2]**2) - if r > r_max: - p *= r_max/r - elif r < r_min: - p *= r_min/r + r = sqrt((p[0] - c[0])**2 + (p[1] - c[1])**2 + (p[2] - c[2])**2) + if r > ul[0]: + p[:] = (p - c)*ul[0]/r + c + elif r < ll[0]: + p[:] = (p - c)*ll[0]/r + c - r = sqrt(q[0]**2 + q[1]**2 + q[2]**2) - if r > r_max: - q *= r_max/r - elif r < r_min: - q *= r_min/r + r = sqrt((q[0] - c[0])**2 + (q[1] - c[1])**2 + (q[2] - c[2])**2) + if r > ul[0]: + q[:] = (q - c)*ul[0]/r + c + elif r < ll[0]: + q[:] = (q - c)*ll[0]/r + c def create_triso_lattice(trisos, lower_left, pitch, shape, background): @@ -783,193 +868,6 @@ def create_triso_lattice(trisos, lower_left, pitch, shape, background): return lattice -def _create_container(region, sphere_radius): - """Create a container to pack spheres in using the region to determine the - container shape. - - Parameters - ---------- - region : openmc.Region - Container in which the spheres are packed. Supported shapes are - rectangular_prism, cylinder, sphere, and spherical shell. - sphere_radius : float - Outer radius of spheres. - - Returns - ------- - domain : openmc.model._Container - Container in which to pack spheres. - - """ - - def rectangular_prism(): - # Assume the simplest case where the prism volume is the intersection - # of the half-spaces of six planes - if not isinstance(region, openmc.Intersection): - return None - - if any(not isinstance(node, openmc.Halfspace) for node in region): - return None - - if len(region) != 6: - return None - - # Sort half-spaces by surface type - px1, px2, py1, py2, pz1, pz2 = sorted(region, key=attrgetter('surface.type')) - - # Make sure the region consists of the correct surfaces - if (not isinstance(px1.surface, openmc.XPlane) or - not isinstance(px2.surface, openmc.XPlane) or - not isinstance(py1.surface, openmc.YPlane) or - not isinstance(py2.surface, openmc.YPlane) or - not isinstance(pz1.surface, openmc.ZPlane) or - not isinstance(pz2.surface, openmc.ZPlane)): - return None - - # Secondary sorting by location of the plane - if px1.surface.x0 > px2.surface.x0: - px1, px2 = px2, px1 - - if py1.surface.y0 > py2.surface.y0: - py1, py2 = py2, py1 - - if pz1.surface.z0 > pz2.surface.z0: - pz1, pz2 = pz2, pz1 - - # Make sure the half-spaces are on the correct side of the surfaces - if (px1.side != '+' or px2.side != '-' or - py1.side != '+' or py2.side != '-' or - pz1.side != '+' or pz2.side != '-'): - return None - - # Calculate the parameters for the container - width = px2.surface.x0 - px1.surface.x0 - depth = py2.surface.y0 - py1.surface.y0 - height = pz2.surface.z0 - pz1.surface.z0 - center = (px1.surface.x0 + width/2, - py1.surface.y0 + depth/2, - pz1.surface.z0 + height/2) - - # The region is the volume of a rectangular prism, so create container - return _RectangularPrism(width, depth, height, sphere_radius, center) - - def cylinder(): - # Assume the simplest case where the cylinder volume is the - # intersection of the half-spaces of a cylinder and two planes - if not isinstance(region, openmc.Intersection): - return None - - if any(not isinstance(node, openmc.Halfspace) for node in region): - return None - - if len(region) != 3: - return None - - # Identify the axis that the cylinder lies along - axis = region[0].surface.type[0] - - # Make sure the region is composed of a cylinder and two planes on the - # same axis - count = Counter((node.surface.type for node in region)) - if count[axis + '-cylinder'] != 1 or count[axis + '-plane'] != 2: - return None - - # Sort the half-spaces by surface type - cyl, p1, p2 = sorted(region, key=attrgetter('surface.type')) - - # Calculate the parameters for a cylinder along the x-axis - if axis == 'x': - if p1.surface.x0 > p2.surface.x0: - p1, p2 = p2, p1 - length = p2.surface.x0 - p1.surface.x0 - center = (p1.surface.x0 + length/2, cyl.surface.y0, cyl.surface.z0) - - # Calculate the parameters for a cylinder along the y-axis - elif axis == 'y': - if p1.surface.y0 > p2.surface.y0: - p1, p2 = p2, p1 - length = p2.surface.y0 - p1.surface.y0 - center = (cyl.surface.x0, p1.surface.y0 + length/2, cyl.surface.z0) - - # Calculate the parameters for a cylinder along the z-axis - else: - if p1.surface.z0 > p2.surface.z0: - p1, p2 = p2, p1 - length = p2.surface.z0 - p1.surface.z0 - center = (cyl.surface.x0, cyl.surface.y0, p1.surface.z0 + length/2) - - # Make sure the half-spaces are on the correct side of the surfaces - if cyl.side != '-' or p1.side != '+' or p2.side != '-': - return None - - radius = cyl.surface.r - - # The region is the volume of a cylinder, so create container - return _Cylinder(length, radius, axis, sphere_radius, center) - - def sphere(): - # Assume the simplest case where the sphere volume is the negative - # half-space of a sphere - if not isinstance(region, openmc.Halfspace): - return None - - if not isinstance(region.surface, openmc.Sphere): - return None - - if region.side != '-': - return None - - radius = region.surface.r - center = (region.surface.x0, region.surface.y0, region.surface.z0) - - # The region is the volume of a sphere, so create container - return _Sphere(radius, sphere_radius, center) - - def spherical_shell(): - # Assume the simplest case where the spherical shell volume is the - # intersection of the half-spaces of two spheres - if not isinstance(region, openmc.Intersection): - return None - - if any(not isinstance(node, openmc.Halfspace) for node in region): - return None - - if len(region) != 2: - return None - - if any(not isinstance(node.surface, openmc.Sphere) for node in region): - return None - - s1, s2 = sorted(region, key=attrgetter('surface.r')) - radius = s2.surface.r - inner_radius = s1.surface.r - center = (s1.surface.x0, s1.surface.y0, s1.surface.z0) - - if center != (s2.surface.x0, s2.surface.y0, s2.surface.z0): - return None - - if s1.side != '+' or s2.side != '-': - return None - - # The region is the volume of a spherical shell, so create container - return _SphericalShell(radius, inner_radius, sphere_radius, center) - - check_type('region', region, openmc.Region) - - # Check whether the region matches any of the supported container shapes - # and create the container if it does - shapes = [rectangular_prism, cylinder, sphere, spherical_shell] - for shape in shapes: - container = shape() - if container: - return container - - msg = ('Could not translate region {} into a container: supported ' - 'container shapes are rectangular prism, cylinder, sphere, ' - 'and spherical shell.'.format(region)) - raise ValueError(msg) - - def _random_sequential_pack(domain, num_spheres): """Random sequential packing of spheres within a container. @@ -1374,7 +1272,17 @@ def pack_spheres(radius, region, pf=None, num_spheres=None, initial_pf=0.3, random.seed(seed) # Create container with the correct shape based on the supplied region - domain = _create_container(region, radius) + domain = None + for cls in _Container.__subclasses__(): + try: + domain = cls.from_region(region, radius) + except ValueError: + pass + + if not domain: + raise ValueError('Could not map region {} to a container: supported ' + 'container shapes are rectangular prism, cylinder, ' + 'sphere, and spherical shell.'.format(region)) # Determine the packing fraction/number of spheres volume = 4/3*pi*radius**3 @@ -1410,7 +1318,8 @@ def pack_spheres(radius, region, pf=None, num_spheres=None, initial_pf=0.3, # Recalculate the limits for the initial random sequential packing using # the desired final sphere radius to ensure spheres are fully contained # within the domain during the close random pack - domain.limits = [x + initial_radius - radius for x in domain.limits] + domain.limits = [[x - initial_radius + radius for x in domain.limits[0]], + [x + initial_radius - radius for x in domain.limits[1]]] # Generate non-overlapping spheres for an initial inner radius using # random sequential packing algorithm @@ -1423,4 +1332,4 @@ def pack_spheres(radius, region, pf=None, num_spheres=None, initial_pf=0.3, domain.sphere_radius = radius _close_random_pack(domain, spheres, contraction_rate) - return spheres + domain.center + return spheres From b7b410975b5254e7b775f4722bade0a322cfbe31 Mon Sep 17 00:00:00 2001 From: amandalund Date: Mon, 19 Nov 2018 21:56:36 -0600 Subject: [PATCH 62/62] Update TRISO unit tests --- tests/unit_tests/test_model_triso.py | 197 +++++++++++++++++---------- 1 file changed, 127 insertions(+), 70 deletions(-) diff --git a/tests/unit_tests/test_model_triso.py b/tests/unit_tests/test_model_triso.py index 3c261ed6f..1d2e0905c 100644 --- a/tests/unit_tests/test_model_triso.py +++ b/tests/unit_tests/test_model_triso.py @@ -12,52 +12,84 @@ import scipy.spatial _RADIUS = 0.1 _PACKING_FRACTION = 0.35 -_SHAPES = ['rectangular_prism', 'cylinder', 'sphere', 'spherical_shell'] -_VOLUMES = [1.**3, 1.*pi*1.**2, 4/3*pi*1.**3, 4/3*pi*(1.**3 - 0.5**3)] +_PARAMS = [ + {'shape': 'rectangular_prism', 'volume': 1**3}, + {'shape': 'x_cylinder', 'volume': 1*pi*1**2}, + {'shape': 'y_cylinder', 'volume': 1*pi*1**2}, + {'shape': 'z_cylinder', 'volume': 1*pi*1**2}, + {'shape': 'sphere', 'volume': 4/3*pi*1**3}, + {'shape': 'spherical_shell', 'volume': 4/3*pi*(1**3 - 0.5**3)} +] -@pytest.fixture(scope='module') +@pytest.fixture(scope='module', params=_PARAMS) def container(request): - return request.getfixturevalue(request.param) + return request.param @pytest.fixture(scope='module') -def centers(request): - container = request.getfixturevalue(request.param) - return openmc.model.pack_spheres(radius=_RADIUS, region=container, +def centers(request, container): + return request.getfixturevalue('centers_' + container['shape']) + + +@pytest.fixture(scope='module') +def centers_rectangular_prism(): + min_x = openmc.XPlane(x0=0) + max_x = openmc.XPlane(x0=1) + min_y = openmc.YPlane(y0=0) + max_y = openmc.YPlane(y0=1) + min_z = openmc.ZPlane(z0=0) + max_z = openmc.ZPlane(z0=1) + region = +min_x & -max_x & +min_y & -max_y & +min_z & -max_z + return openmc.model.pack_spheres(radius=_RADIUS, region=region, pf=_PACKING_FRACTION, initial_pf=0.2) @pytest.fixture(scope='module') -def rectangular_prism(): - min_x = openmc.XPlane(x0=-0.5) - max_x = openmc.XPlane(x0=0.5) - min_y = openmc.YPlane(y0=-0.5) - max_y = openmc.YPlane(y0=0.5) - min_z = openmc.ZPlane(z0=-0.5) - max_z = openmc.ZPlane(z0=0.5) - return +min_x & -max_x & +min_y & -max_y & +min_z & -max_z +def centers_x_cylinder(): + cylinder = openmc.XCylinder(R=1, y0=1, z0=2) + min_x = openmc.XPlane(x0=0) + max_x = openmc.XPlane(x0=1) + region = +min_x & -max_x & -cylinder + return openmc.model.pack_spheres(radius=_RADIUS, region=region, + pf=_PACKING_FRACTION, initial_pf=0.2) @pytest.fixture(scope='module') -def cylinder(): - cylinder = openmc.ZCylinder(R=1.) - min_z = openmc.ZPlane(z0=-0.5) - max_z = openmc.ZPlane(z0=0.5) - return +min_z & -max_z & -cylinder +def centers_y_cylinder(): + cylinder = openmc.YCylinder(R=1, x0=1, z0=2) + min_y = openmc.YPlane(y0=0) + max_y = openmc.YPlane(y0=1) + region = +min_y & -max_y & -cylinder + return openmc.model.pack_spheres(radius=_RADIUS, region=region, + pf=_PACKING_FRACTION, initial_pf=0.2) @pytest.fixture(scope='module') -def sphere(): - sphere = openmc.Sphere(R=1.) - return -sphere +def centers_z_cylinder(): + cylinder = openmc.ZCylinder(R=1, x0=1, y0=2) + min_z = openmc.ZPlane(z0=0) + max_z = openmc.ZPlane(z0=1) + region = +min_z & -max_z & -cylinder + return openmc.model.pack_spheres(radius=_RADIUS, region=region, + pf=_PACKING_FRACTION, initial_pf=0.2) @pytest.fixture(scope='module') -def spherical_shell(): - sphere = openmc.Sphere(R=1.) - inner_sphere = openmc.Sphere(R=0.5) - return -sphere & +inner_sphere +def centers_sphere(): + sphere = openmc.Sphere(R=1, x0=1, y0=2, z0=3) + region = -sphere + return openmc.model.pack_spheres(radius=_RADIUS, region=region, + pf=_PACKING_FRACTION, initial_pf=0.2) + + +@pytest.fixture(scope='module') +def centers_spherical_shell(): + sphere = openmc.Sphere(R=1, x0=1, y0=2, z0=3) + inner_sphere = openmc.Sphere(R=0.5, x0=1, y0=2, z0=3) + region = -sphere & +inner_sphere + return openmc.model.pack_spheres(radius=_RADIUS, region=region, + pf=_PACKING_FRACTION, initial_pf=0.2) @pytest.fixture(scope='module') @@ -68,7 +100,6 @@ def triso_universe(): return univ -@pytest.mark.parametrize('centers', _SHAPES, indirect=True) def test_overlap(centers): """Check that none of the spheres in the packed configuration overlap.""" # Create KD tree for quick nearest neighbor search @@ -82,57 +113,83 @@ def test_overlap(centers): assert d_min > 2*_RADIUS or d_min == pytest.approx(2*_RADIUS) -@pytest.mark.parametrize('centers,shape', zip(_SHAPES, _SHAPES), - indirect=['centers']) -def test_contained(centers, shape): +def test_contained_rectangular_prism(centers_rectangular_prism): """Make sure all spheres are entirely contained within the domain.""" - if shape == 'rectangular_prism': - x = np.amax(abs(centers)) + _RADIUS - assert x < 0.5 or x == pytest.approx(0.5) - - elif shape == 'cylinder': - r = max(np.linalg.norm(centers[:,0:2], axis=1)) + _RADIUS - z = max(abs(centers[:,2])) + _RADIUS - assert r < 1. or r == pytest.approx(1.) - assert z < 0.5 or z == pytest.approx(0.5) - - elif shape == 'sphere': - r = max(np.linalg.norm(centers, axis=1)) + _RADIUS - assert r < 1. or r == pytest.approx(1.) - - elif shape == 'spherical_shell': - d = np.linalg.norm(centers, axis=1) - r_max = max(d) + _RADIUS - r_min = min(d) - _RADIUS - assert r_max < 1. or r_max == pytest.approx(1.) - assert r_min > 0.5 or r_min == pytest.approx(0.5) + d_max = np.amax(centers_rectangular_prism) + _RADIUS + d_min = np.amin(centers_rectangular_prism) - _RADIUS + assert d_max < 1 or d_max == pytest.approx(1) + assert d_min > 0 or d_min == pytest.approx(0) -@pytest.mark.parametrize('centers,volume', zip(_SHAPES, _VOLUMES), - indirect=['centers']) -def test_packing_fraction(centers, volume): +def test_contained_x_cylinder(centers_x_cylinder): + """Make sure all spheres are entirely contained within the domain.""" + d = np.linalg.norm(centers_x_cylinder[:,[1,2]] - [1, 2], axis=1) + r_max = max(d) + _RADIUS + x_max = max(centers_x_cylinder[:,0]) + _RADIUS + x_min = min(centers_x_cylinder[:,0]) - _RADIUS + assert r_max < 1 or r_max == pytest.approx(1) + assert x_max < 1 or x_max == pytest.approx(1) + assert x_min > 0 or x_min == pytest.approx(0) + + +def test_contained_y_cylinder(centers_y_cylinder): + """Make sure all spheres are entirely contained within the domain.""" + d = np.linalg.norm(centers_y_cylinder[:,[0,2]] - [1, 2], axis=1) + r_max = max(d) + _RADIUS + y_max = max(centers_y_cylinder[:,1]) + _RADIUS + y_min = min(centers_y_cylinder[:,1]) - _RADIUS + assert r_max < 1 or r_max == pytest.approx(1) + assert y_max < 1 or y_max == pytest.approx(1) + assert y_min > 0 or y_min == pytest.approx(0) + + +def test_contained_z_cylinder(centers_z_cylinder): + """Make sure all spheres are entirely contained within the domain.""" + d = np.linalg.norm(centers_z_cylinder[:,[0,1]] - [1, 2], axis=1) + r_max = max(d) + _RADIUS + z_max = max(centers_z_cylinder[:,2]) + _RADIUS + z_min = min(centers_z_cylinder[:,2]) - _RADIUS + assert r_max < 1 or r_max == pytest.approx(1) + assert z_max < 1 or z_max == pytest.approx(1) + assert z_min > 0 or z_min == pytest.approx(0) + + +def test_contained_sphere(centers_sphere): + """Make sure all spheres are entirely contained within the domain.""" + d = np.linalg.norm(centers_sphere - [1, 2, 3], axis=1) + r_max = max(d) + _RADIUS + assert r_max < 1 or r_max == pytest.approx(1) + + +def test_contained_spherical_shell(centers_spherical_shell): + """Make sure all spheres are entirely contained within the domain.""" + d = np.linalg.norm(centers_spherical_shell - [1, 2, 3], axis=1) + r_max = max(d) + _RADIUS + r_min = min(d) - _RADIUS + assert r_max < 1 or r_max == pytest.approx(1) + assert r_min > 0.5 or r_min == pytest.approx(0.5) + + +def test_packing_fraction(container, centers): """Check that the actual PF is close to the requested PF.""" - pf = len(centers) * 4/3 * pi *_RADIUS**3 / volume + pf = len(centers) * 4/3 * pi *_RADIUS**3 / container['volume'] assert pf == pytest.approx(_PACKING_FRACTION, rel=1e-2) -@pytest.mark.parametrize('container', _SHAPES, indirect=True) -def test_num_spheres(container): +def test_num_spheres(): """Check that the function returns the correct number of spheres""" centers = openmc.model.pack_spheres( - radius=_RADIUS, region=container, num_spheres=50 + radius=_RADIUS, region=-openmc.Sphere(R=1), num_spheres=50 ) assert len(centers) == 50 -def test_triso_lattice(triso_universe, rectangular_prism): - centers = openmc.model.pack_spheres( - radius=_RADIUS, region=rectangular_prism, pf=0.2 - ) - trisos = [openmc.model.TRISO(_RADIUS, triso_universe, c) for c in centers] +def test_triso_lattice(triso_universe, centers_rectangular_prism): + trisos = [openmc.model.TRISO(_RADIUS, triso_universe, c) + for c in centers_rectangular_prism] - lower_left = np.array((-.5, -.5, -.5)) - upper_right = np.array((.5, .5, .5)) + lower_left = np.array((0, 0, 0)) + upper_right = np.array((1, 1, 1)) shape = (3, 3, 3) pitch = (upper_right - lower_left)/shape background = openmc.Material() @@ -146,25 +203,25 @@ def test_container_input(triso_universe): # Invalid container shape with pytest.raises(ValueError): centers = openmc.model.pack_spheres( - radius=_RADIUS, region=+openmc.Sphere(R=1.), num_spheres=100 + radius=_RADIUS, region=+openmc.Sphere(R=1), num_spheres=100 ) -def test_packing_fraction_input(sphere): +def test_packing_fraction_input(): # Provide neither packing fraction nor number of spheres with pytest.raises(ValueError): centers = openmc.model.pack_spheres( - radius=_RADIUS, region=sphere + radius=_RADIUS, region=-openmc.Sphere(R=1) ) # Specify a packing fraction that is too high for CRP with pytest.raises(ValueError): centers = openmc.model.pack_spheres( - radius=_RADIUS, region=sphere, pf=1. + radius=_RADIUS, region=-openmc.Sphere(R=1), pf=1 ) # Specify a packing fraction that is too high for RSP with pytest.raises(ValueError): centers = openmc.model.pack_spheres( - radius=_RADIUS, region=sphere, pf=0.5, initial_pf=0.4 + radius=_RADIUS, region=-openmc.Sphere(R=1), pf=0.5, initial_pf=0.4 )